From 922ac41a4a753a9f7d4e094092375bd877f67446 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 31 Mar 2022 14:41:08 -0400 Subject: [PATCH 001/679] voxels --- .../Voxel/VoxelBox3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelBox3DTiles/schema.json | 1 + .../Voxel/VoxelBox3DTiles/tileset.json | 1 + .../Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../VoxelCylinder3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelCylinder3DTiles/schema.json | 1 + .../Voxel/VoxelCylinder3DTiles/tileset.json | 1 + .../Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelEllipsoid3DTiles/schema.json | 1 + .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 1 + Apps/Sandcastle/gallery/Voxels.html | 507 ++++ Source/Core/PrimitiveType.js | 29 +- Source/Renderer/Pass.js | 5 +- Source/Scene/Cesium3DTilesVoxelProvider.js | 632 ++++ Source/Scene/DerivedCommand.js | 7 + Source/Scene/GltfLoader.js | 15 + Source/Scene/GltfVoxelProvider.js | 404 +++ Source/Scene/MetadataComponentType.js | 82 + Source/Scene/ModelComponents.js | 48 + Source/Scene/Scene.js | 17 + Source/Scene/VoxelBoxShape.js | 325 ++ Source/Scene/VoxelCylinderShape.js | 529 ++++ Source/Scene/VoxelEllipsoidShape.js | 1027 +++++++ Source/Scene/VoxelPrimitive.js | 2695 +++++++++++++++++ Source/Scene/VoxelProvider.js | 191 ++ Source/Scene/VoxelShape.js | 129 + Source/Scene/VoxelShapeType.js | 90 + Source/Scene/VoxelTraversal.js | 2020 ++++++++++++ .../Builtin/Constants/passOverlay.glsl | 2 +- .../Shaders/Builtin/Constants/passVoxels.glsl | 9 + .../Functions/windowToEyeCoordinates.glsl | 2 +- Source/Shaders/VoxelFS.glsl | 1484 +++++++++ Source/Shaders/VoxelVS.glsl | 11 + .../CesiumInspector/CesiumInspector.css | 2 +- Source/Widgets/Viewer/Viewer.css | 11 + Source/Widgets/Viewer/Viewer.js | 60 +- .../Viewer/viewerVoxelInspectorMixin.js | 34 + .../Widgets/VoxelInspector/VoxelInspector.css | 121 + .../Widgets/VoxelInspector/VoxelInspector.js | 422 +++ .../VoxelInspector/VoxelInspectorViewModel.js | 1130 +++++++ Source/Widgets/widgets.css | 1 + .../Voxel/VoxelBox3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelBox3DTiles/schema.json | 1 + .../Voxel/VoxelBox3DTiles/tileset.json | 1 + .../Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../VoxelCylinder3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelCylinder3DTiles/schema.json | 1 + .../Voxel/VoxelCylinder3DTiles/tileset.json | 1 + .../Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin | Bin 0 -> 32 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin | Bin 0 -> 312 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 1 + .../Voxel/VoxelEllipsoid3DTiles/schema.json | 1 + .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 1 + Specs/Scene/Cesium3DTilesVoxelProviderSpec.js | 123 + Specs/Scene/GltfVoxelProviderSpec.js | 137 + Specs/Scene/VoxelBoxShapeSpec.js | 696 +++++ Specs/Scene/VoxelCylinderShapeSpec.js | 214 ++ Specs/Scene/VoxelEllipsoidShapeSpec.js | 179 ++ Specs/Scene/VoxelPrimitiveSpec.js | 224 ++ Specs/Scene/VoxelShapeTypeSpec.js | 43 + Specs/Scene/VoxelTraversalSpec.js | 396 +++ Specs/Widgets/Viewer/ViewerSpec.js | 159 + 70 files changed, 14175 insertions(+), 55 deletions(-) create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json create mode 100644 Apps/Sandcastle/gallery/Voxels.html create mode 100644 Source/Scene/Cesium3DTilesVoxelProvider.js create mode 100644 Source/Scene/GltfVoxelProvider.js create mode 100644 Source/Scene/VoxelBoxShape.js create mode 100644 Source/Scene/VoxelCylinderShape.js create mode 100644 Source/Scene/VoxelEllipsoidShape.js create mode 100644 Source/Scene/VoxelPrimitive.js create mode 100644 Source/Scene/VoxelProvider.js create mode 100644 Source/Scene/VoxelShape.js create mode 100644 Source/Scene/VoxelShapeType.js create mode 100644 Source/Scene/VoxelTraversal.js create mode 100644 Source/Shaders/Builtin/Constants/passVoxels.glsl create mode 100644 Source/Shaders/VoxelFS.glsl create mode 100644 Source/Shaders/VoxelVS.glsl create mode 100644 Source/Widgets/Viewer/viewerVoxelInspectorMixin.js create mode 100644 Source/Widgets/VoxelInspector/VoxelInspector.css create mode 100644 Source/Widgets/VoxelInspector/VoxelInspector.js create mode 100644 Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json create mode 100644 Specs/Scene/Cesium3DTilesVoxelProviderSpec.js create mode 100644 Specs/Scene/GltfVoxelProviderSpec.js create mode 100644 Specs/Scene/VoxelBoxShapeSpec.js create mode 100644 Specs/Scene/VoxelCylinderShapeSpec.js create mode 100644 Specs/Scene/VoxelEllipsoidShapeSpec.js create mode 100644 Specs/Scene/VoxelPrimitiveSpec.js create mode 100644 Specs/Scene/VoxelShapeTypeSpec.js create mode 100644 Specs/Scene/VoxelTraversalSpec.js diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..227fd904003 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483648,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxel":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxel","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxel","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json new file mode 100644 index 00000000000..39e46626920 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..bf65877f714 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483650,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json new file mode 100644 index 00000000000..39e46626920 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..90e35e2f214 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483649,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2],"bounds":{"min":[0.0,0.0,-1.0],"max":[1.0,1.0,0.0]}}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json new file mode 100644 index 00000000000..f68ae62e2ab --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"region":[0.0,0.0,1.0,1.0,-1.0,0.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[6378137.0,0.0,0.0,0.0,0.0,6378137.0,0.0,0.0,0.0,0.0,6356752.314245179,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html new file mode 100644 index 00000000000..8ec79d69033 --- /dev/null +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -0,0 +1,507 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/Source/Core/PrimitiveType.js b/Source/Core/PrimitiveType.js index 639c0955a9d..eb86d821493 100644 --- a/Source/Core/PrimitiveType.js +++ b/Source/Core/PrimitiveType.js @@ -65,6 +65,30 @@ const PrimitiveType = { * @constant */ TRIANGLE_FAN: WebGLConstants.TRIANGLE_FAN, + + /** + * Box voxel primitive from EXT_primitive_voxels. + * + * @type {Number} + * @constant + */ + VOXEL_BOX: 0x80000000, + + /** + * Ellipsoid voxel primitive from EXT_primitive_voxels. + * + * @type {Number} + * @constant + */ + VOXEL_ELLIPSOID: 0x80000001, + + /** + * Cylinder voxel primitive from EXT_primitive_voxels. + * + * @type {Number} + * @constant + */ + VOXEL_CYLINDER: 0x80000002, }; /** @@ -78,7 +102,10 @@ PrimitiveType.validate = function (primitiveType) { primitiveType === PrimitiveType.LINE_STRIP || primitiveType === PrimitiveType.TRIANGLES || primitiveType === PrimitiveType.TRIANGLE_STRIP || - primitiveType === PrimitiveType.TRIANGLE_FAN + primitiveType === PrimitiveType.TRIANGLE_FAN || + primitiveType === PrimitiveType.VOXEL_BOX || + primitiveType === PrimitiveType.VOXEL_CYLINDER || + primitiveType === PrimitiveType.VOXEL_ELLIPSOID ); }; diff --git a/Source/Renderer/Pass.js b/Source/Renderer/Pass.js index f965d1ea75f..bdfe61dc156 100644 --- a/Source/Renderer/Pass.js +++ b/Source/Renderer/Pass.js @@ -20,7 +20,8 @@ const Pass = { CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW: 6, OPAQUE: 7, TRANSLUCENT: 8, - OVERLAY: 9, - NUMBER_OF_PASSES: 10, + VOXELS: 9, + OVERLAY: 10, + NUMBER_OF_PASSES: 11, }; export default Object.freeze(Pass); diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js new file mode 100644 index 00000000000..7b5037b3167 --- /dev/null +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -0,0 +1,632 @@ +import Cartesian3 from "../Core/Cartesian3.js"; +import Check from "../Core/Check.js"; +import ComponentDatatype from "../Core/ComponentDatatype.js"; +import defaultValue from "../Core/defaultValue.js"; +import defer from "../Core/defer.js"; +import defined from "../Core/defined.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; +import Matrix4 from "../Core/Matrix4.js"; +import Resource from "../Core/Resource.js"; +import Cesium3DTilesetMetadata from "./Cesium3DTilesetMetadata.js"; +import GltfLoader from "./GltfLoader.js"; +import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js"; +import ImplicitSubtree from "./ImplicitSubtree.js"; +import ImplicitTileCoordinates from "./ImplicitTileCoordinates.js"; +import ImplicitTileset from "./ImplicitTileset.js"; +import MetadataComponentType from "./MetadataComponentType.js"; +import MetadataType from "./MetadataType.js"; +import ResourceCache from "./ResourceCache.js"; +import VoxelShapeType from "./VoxelShapeType.js"; + +/** + * A {@link VoxelProvider} that fetches voxel data from a 3D Tiles tileset. + * + * @alias Cesium3DTilesVoxelProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {String|Resource|Uint8Array} options.url The URL to the tileset directory + * + * @see VoxelProvider + */ +function Cesium3DTilesVoxelProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + //>>includeStart('debug', pragmas.debug) + Check.defined("options.url", options.url); + //>>includeEnd('debug'); + + /** + * Gets a value indicating whether or not the provider is ready for use. + * @type {Boolean} + * @readonly + */ + this.ready = false; + + this._readyPromise = defer(); + + /** + * Gets the promise that will be resolved when the provider is ready for use. + * @type {Promise.} + * @readonly + */ + this.readyPromise = this._readyPromise.promise; + + /** + * An optional model matrix that is applied to all tiles + * @type {Matrix4} + * @readonly + */ + this.modelMatrix = undefined; + + /** + * Gets the {@link VoxelShapeType} + * @type {VoxelShapeType} + * @readonly + */ + this.shape = undefined; + + /** + * Gets the minimum bounds. + * If undefined, the shape's default minimum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.minBounds = undefined; + + /** + * Gets the maximum bounds. + * If undefined, the shape's default maximum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.maxBounds = undefined; + + /** + * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.dimensions = undefined; + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * TODO: mark this optional + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Number} + * @readonly + */ + this.paddingBefore = undefined; + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * This should not be called before {@link VoxelProvider#ready} returns true. + * TODO: mark this optional + * @type {Number} + * @readonly + */ + this.paddingAfter = undefined; + + // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use + + /** + * Gets stuff + * @type {String[]} + */ + this.names = new Array(); + + /** + * Gets stuff + * @type {MetadataType[]} + */ + this.types = new Array(); + + /** + * Gets stuff + * @type {MetadataComponentType[]} + */ + this.componentTypes = new Array(); + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the minimum value + * @type {Number[]} + */ + this.minimumValues = undefined; + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the maximum value + * @type {Number[][]} + */ + this.maximumValues = undefined; + + /** + * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. + * @type {Number} + */ + this.maximumTileCount = undefined; + + /** + * @type {ImplicitTileset} + */ + this._implicitTileset = undefined; + + /** + * @type {ImplicitSubtreeCache} + */ + this._subtreeCache = new ImplicitSubtreeCache(); + + /** + * glTFs that are in the process of being loaded. + * @type {GltfLoader[]} + */ + this._gltfLoaders = new Array(); + + /** + * Subtrees that are in the process of being loaded. + * This member exists for unit test purposes only. See _doneLoading. + * @type {Subtree[]} + */ + this._subtreeLoaders = new Array(); + + /** + * Subtree resources that are in the process of being loaded. + * This member exists for unit test purposes only. See _doneLoading. + * @type {Resource[]} + */ + this._subtreeResourceLoaders = new Array(); + + const that = this; + let tilesetJson; + let tileJson; + let metadata; + let implicitTileset; + + // 1. Load tileset.json + // 2. Load schema.json + // 3. Load root glTF to get provider properties + const resource = Resource.createIfNeeded(options.url); + const tilesetPromise = resource.fetchJson(); + tilesetPromise + .then(function (tileset) { + tilesetJson = tileset; + tileJson = tilesetJson.root; + + let metadataSchemaLoader; + if (defined(tilesetJson.schemaUri)) { + metadataSchemaLoader = ResourceCache.loadSchema({ + resource: resource.getDerivedResource({ + url: tilesetJson.schemaUri, + preserveQueryParameters: true, + }), + }); + } else { + metadataSchemaLoader = ResourceCache.loadSchema({ + schema: tilesetJson.schema, + }); + } + return metadataSchemaLoader.promise; + }) + .then(function (schemaLoader) { + const metadataSchema = schemaLoader.schema; + metadata = new Cesium3DTilesetMetadata({ + metadataJson: tilesetJson, + schema: metadataSchema, + }); + implicitTileset = new ImplicitTileset(resource, tileJson, metadataSchema); + + // TODO make sure this fails when root tile is not available? + const rootCoord = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: 0, + x: 0, + y: 0, + z: 0, + }); + const rootGltfLoader = getGltfLoader(implicitTileset, rootCoord); + that._gltfLoaders.push(rootGltfLoader); + return rootGltfLoader.promise; + }) + .then(function (rootGltfLoader) { + that._gltfLoaders.splice(that._gltfLoaders.indexOf(rootGltfLoader)); + const gltfPrimitive = rootGltfLoader.components.nodes[0].primitives[0]; + const voxel = gltfPrimitive.voxel; + const primitiveType = gltfPrimitive.primitiveType; + const attributes = gltfPrimitive.attributes; + + const attributesLength = attributes.length; + const names = new Array(attributesLength); + const types = new Array(attributesLength); + const componentTypes = new Array(attributesLength); + const minimumValues = new Array(attributesLength); + const maximumValues = new Array(attributesLength); + + const schema = metadata.schema; + const statistics = metadata.statistics; + const classNames = Object.keys(schema.classes); + const classNamesLength = classNames.length; + for (let i = 0; i < classNamesLength; i++) { + const className = classNames[i]; + const classStatistics = statistics.classes[className]; + const classInfo = schema.classes[className]; + const properties = classInfo.properties; + const propertyNames = Object.keys(properties); + const propertyNamesLength = propertyNames.length; + for (let i = 0; i < propertyNamesLength; i++) { + const propertyName = propertyNames[i]; + const property = properties[propertyName]; + const propertyStatistics = classStatistics.properties[propertyName]; + const propertyMin = Array.isArray(propertyStatistics.min) + ? propertyStatistics.min + : [propertyStatistics.min]; + const propertyMax = Array.isArray(propertyStatistics.max) + ? propertyStatistics.max + : [propertyStatistics.max]; + const metadataType = property.type; + const metadataComponentType = property.componentType; + const metadataComponentCount = MetadataType.getComponentCount( + metadataType + ); + + names[i] = propertyName; + types[i] = metadataType; + componentTypes[i] = metadataComponentType; + minimumValues[i] = new Array(metadataComponentCount); + maximumValues[i] = new Array(metadataComponentCount); + + for (let j = 0; j < metadataComponentCount; j++) { + minimumValues[i][j] = propertyMin[j]; + maximumValues[i][j] = propertyMax[j]; + } + } + } + + that.shape = VoxelShapeType.fromPrimitiveType(primitiveType); + that.minBounds = Cartesian3.clone(voxel.minBounds); + that.maxBounds = Cartesian3.clone(voxel.maxBounds); + that.dimensions = Cartesian3.clone(voxel.dimensions); + that.paddingBefore = Cartesian3.clone(voxel.paddingBefore); + that.paddingAfter = Cartesian3.clone(voxel.paddingAfter); + that.maximumTileCount = defined(statistics.classes.tile) + ? statistics.classes.tile.count + : undefined; + that.modelMatrix = Matrix4.clone(tileJson.transform); + that.names = names; + that.types = types; + that.componentTypes = componentTypes; + that.minimumValues = minimumValues; + that.maximumValues = maximumValues; + that.ready = true; + that._readyPromise.resolve(that); + that._implicitTileset = implicitTileset; + }) + .catch(function (error) { + that._readyPromise.reject(error); + }); +} + +const scratchImplicitTileCoordinates = new ImplicitTileCoordinates({ + subdivisionScheme: ImplicitSubdivisionScheme.OCTREE, // not known yet + subtreeLevels: 1, // not known yet + level: 0, + x: 0, + y: 0, + z: 0, +}); + +/** + * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. + * This function should not be called before {@link VoxelProvider#ready} returns true. + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.tileLevel=0] The tile's level. + * @param {Number} [options.tileX=0] The tile's X coordinate. + * @param {Number} [options.tileY=0] The tile's Y coordinate. + * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const tileLevel = defaultValue(options.tileLevel, 0); + const tileX = defaultValue(options.tileX, 0); + const tileY = defaultValue(options.tileY, 0); + const tileZ = defaultValue(options.tileZ, 0); + + //>>includeStart('debug', pragmas.debug); + if (!this.ready) { + throw new DeveloperError( + "The provider is not ready. Use Cesium3DTilesVoxelProvider.readyPromise or wait for Cesium3DTilesVoxelProvider.ready to be true." + ); + } + //>>includeEnd('debug'); + + // 1. Load the subtree that the tile belongs to (possibly from the subtree cache) + // 1a. If not in the cache, load the subtree resource + // 1b. If not in the cache, load the subtree object + // 2. Load the glTF if available + + const implicitTileset = this._implicitTileset; + const subtreeCache = this._subtreeCache; + const types = this.types; + const componentTypes = this.componentTypes; + + const tileCoordinates = scratchImplicitTileCoordinates; + tileCoordinates.subdivisionScheme = implicitTileset.subdivisionScheme; + tileCoordinates.subtreeLevels = implicitTileset.subtreeLevels; + tileCoordinates.level = tileLevel; + tileCoordinates.x = tileX; + tileCoordinates.y = tileY; + tileCoordinates.z = tileZ; + + // First load the subtree to check if the tile is available. + // If the subtree has been requested previously it might still be in the cache. + const subtreeCoord = tileCoordinates.getSubtreeCoordinates(); + let subtree = subtreeCache.find(subtreeCoord); + + const that = this; + let subtreePromise; + if (defined(subtree)) { + subtreePromise = subtree.readyPromise; + } else { + const subtreeRelative = implicitTileset.subtreeUriTemplate.getDerivedResource( + { + templateValues: subtreeCoord.getTemplateValues(), + } + ); + const subtreeResource = implicitTileset.baseResource.getDerivedResource({ + url: subtreeRelative.url, + }); + this._subtreeResourceLoaders.push(subtreeResource); + subtreePromise = subtreeResource + .fetchArrayBuffer() + .then(function (arrayBuffer) { + // Check one more time if the subtree is in the cache. + // This could happen if there are two in-flight tile requests from the same subtree and one finishes before the other. + subtree = subtreeCache.find(subtreeCoord); + if (!defined(subtree)) { + const bufferU8 = new Uint8Array(arrayBuffer); + subtree = new ImplicitSubtree( + subtreeResource, + undefined, + bufferU8, + implicitTileset, + subtreeCoord + ); + subtreeCache.addSubtree(subtree); + that._subtreeLoaders.push(subtree); + } + that._subtreeResourceLoaders.splice( + that._subtreeResourceLoaders.indexOf(subtreeResource) + ); + return subtree.readyPromise; + }); + } + + return subtreePromise + .then(function (subtree) { + const subtreeLoaderIndex = that._subtreeLoaders.indexOf(subtree); + if (!subtree.tileIsAvailableAtCoordinates(tileCoordinates)) { + if (subtreeLoaderIndex !== -1) { + that._subtreeLoaders.splice(subtreeLoaderIndex); + } + return Promise.reject("Tile is not available"); + } + + const gltfLoader = getGltfLoader(implicitTileset, tileCoordinates); + that._gltfLoaders.push(gltfLoader); + + if (subtreeLoaderIndex !== -1) { + that._subtreeLoaders.splice(subtreeLoaderIndex); + } + + return gltfLoader.promise; + }) + .then(function (gltfLoader) { + const node = gltfLoader.components.scene.nodes[0]; + const primitive = node.primitives[0]; + const attributes = primitive.attributes; + const attributesLength = attributes.length; + + const data = new Array(attributesLength); + for (let i = 0; i < attributesLength; i++) { + const attribute = attributes[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const componentDatatype = MetadataComponentType.toComponentDatatype( + componentType + ); + const componentCount = MetadataType.getComponentCount(type); + const totalCount = attribute.count * componentCount; + data[i] = ComponentDatatype.createArrayBufferView( + componentDatatype, + attribute.typedArray.buffer, + attribute.typedArray.byteOffset + attribute.byteOffset, + totalCount + ); + } + + that._gltfLoaders.splice(that._gltfLoaders.indexOf(gltfLoader)); + return Promise.resolve(data); + }); +}; + +/** + * Optional per-frame processing. Not all {@link VoxelProvder} need to do this. + * + * @param {FrameState} frameState + */ +Cesium3DTilesVoxelProvider.prototype.update = function (frameState) { + const loaders = this._gltfLoaders; + const loaderLength = loaders.length; + for (let i = 0; i < loaderLength; i++) { + loaders[i].process(frameState); + } +}; + +/** + * Check if anything is still being loaded. + * This is intended to be used for unit tests only. + * @returns {Boolean} + * @private + */ +Cesium3DTilesVoxelProvider.prototype._doneLoading = function () { + return ( + this._gltfLoaders.length === 0 && + this._subtreeLoaders.length === 0 && + this._subtreeResourceLoaders.length === 0 + ); +}; + +/** + * @param {ArrayBuffer} gltfBuffer The buffer that comes when the promise from gltfResource.fetchArrayBuffer() resolves. + * @param {Resource} gltfResource Resource derived from base that points to gltf. + * @returns {GltfLoader} + */ +function getGltfLoader(implicitTileset, tileCoord) { + const gltfRelative = implicitTileset.contentUriTemplates[0].getDerivedResource( + { + templateValues: tileCoord.getTemplateValues(), + } + ); + const gltfResource = implicitTileset.baseResource.getDerivedResource({ + url: gltfRelative.url, + }); + + const gltfLoader = new GltfLoader({ + gltfResource: gltfResource, + releaseGltfJson: false, + loadAsTypedArray: true, + }); + + gltfLoader.load(); + return gltfLoader; +} + +/** + * @constructor + * @param {ImplicitSubtree} subtree + * @param {Number} stamp + * + * @private + */ +function ImplicitSubtreeCacheNode(subtree, stamp) { + this.subtree = subtree; + this.stamp = stamp; +} + +/** + * @constructor + * @param {Object} [options] Object with the following properties + * @param {Number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. + * + * @private + */ +function ImplicitSubtreeCache(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + /** + * @type {Number} + * @private + */ + this._maximumSubtreeCount = defaultValue(options.maximumSubtreeCount, 0); + + /** + * A counter that goes up whenever a subtree is added. Used to sort subtrees by recency. + * @type {Number} + * @private + */ + this._subtreeRequestCounter = 0; + + /** + * @type {DoubleEndedPriorityQueue} + * @private + */ + this._queue = new DoubleEndedPriorityQueue({ + comparator: ImplicitSubtreeCache.comparator, + }); +} + +/** + * @param {ImplicitSubtree} subtree + */ +ImplicitSubtreeCache.prototype.addSubtree = function (subtree) { + const cacheNode = new ImplicitSubtreeCacheNode( + subtree, + this._subtreeRequestCounter + ); + this._subtreeRequestCounter++; + this._queue.insert(cacheNode); + + // Make sure the parent subtree exists in the cache + const subtreeCoord = subtree.implicitCoordinates; + if (subtreeCoord.level > 0) { + const parentCoord = subtreeCoord.deriveParentSubtreeCoordinates(); + const parentNode = this.find(parentCoord); + + //>>includeStart('debug', pragmas.debug) + if (parentNode === undefined) { + throw new DeveloperError("parent node needs to exist"); + } + //>>includeEnd('debug'); + } + + if (this._maximumSubtreeCount > 0) { + while (this._queue.length > this._maximumSubtreeCount) { + const lowestPriorityNode = this._queue.getMinimum(); + if (lowestPriorityNode === cacheNode) { + // Don't remove itself + break; + } + + this._queue.removeMinimum(); + } + } +}; + +/** + * @param {ImplicitTileCoordinates} subtreeCoord + * @returns {ImplicitSubtree|undefined} + */ +ImplicitSubtreeCache.prototype.find = function (subtreeCoord) { + const queue = this._queue; + const array = queue.internalArray; + const arrayLength = queue.length; + + for (let i = 0; i < arrayLength; i++) { + const other = array[i]; + const otherSubtree = other.subtree; + const otherCoord = otherSubtree.implicitCoordinates; + if (subtreeCoord.isEqual(otherCoord)) { + return other.subtree; + } + } + return undefined; +}; + +/** + * @param {ImplicitSubtreeCacheNode} a + * @param {ImplicitSubtreeCacheNode} b + * @returns {Number} + * + * @private + */ +ImplicitSubtreeCache.comparator = function (a, b) { + const aCoord = a.subtree.implicitCoordinates; + const bCoord = b.subtree.implicitCoordinates; + if (aCoord.isAncestorOf(bCoord)) { + // Technically this shouldn't happen because the ancestor subtree was supposed to be added to the cache first. + return +1.0; + } else if (bCoord.isAncestorOf(aCoord)) { + return -1.0; + } + return a.stamp - b.stamp; +}; + +export default Cesium3DTilesVoxelProvider; diff --git a/Source/Scene/DerivedCommand.js b/Source/Scene/DerivedCommand.js index 8d0e058ff89..d5a30d837e8 100644 --- a/Source/Scene/DerivedCommand.js +++ b/Source/Scene/DerivedCommand.js @@ -148,6 +148,13 @@ const vertexlogDepthRegex = /\s+czm_vertexLogDepth\(/; const extensionRegex = /\s*#extension\s+GL_EXT_frag_depth\s*:\s*enable/; function getLogDepthShaderProgram(context, shaderProgram) { + const disableLogDepthWrite = + shaderProgram.fragmentShaderSource.defines.indexOf("LOG_DEPTH_READ_ONLY") >= + 0; + if (disableLogDepthWrite) { + return shaderProgram; + } + let shader = context.shaderCache.getDerivedShaderProgram( shaderProgram, "logDepth" diff --git a/Source/Scene/GltfLoader.js b/Source/Scene/GltfLoader.js index 5696e6b3352..28c81eabc96 100644 --- a/Source/Scene/GltfLoader.js +++ b/Source/Scene/GltfLoader.js @@ -985,6 +985,21 @@ function loadPrimitive( ); const draco = extensions.KHR_draco_mesh_compression; + const extVox = extensions.EXT_primitive_voxels; + if (defined(extVox)) { + const voxel = new ModelComponents.Voxel(); + voxel.dimensions = fromArray(Cartesian3, extVox.dimensions); + if (defined(extVox.bounds)) { + voxel.minBounds = fromArray(Cartesian3, extVox.bounds.min); + voxel.maxBounds = fromArray(Cartesian3, extVox.bounds.max); + } + if (defined(extVox.padding)) { + voxel.paddingBefore = fromArray(Cartesian3, extVox.padding.before); + voxel.paddingAfter = fromArray(Cartesian3, extVox.padding.after); + } + primitive.voxel = voxel; + } + const attributes = gltfPrimitive.attributes; if (defined(attributes)) { for (const semantic in attributes) { diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js new file mode 100644 index 00000000000..a795aae74c4 --- /dev/null +++ b/Source/Scene/GltfVoxelProvider.js @@ -0,0 +1,404 @@ +import Cartesian3 from "../Core/Cartesian3.js"; +import Check from "../Core/Check.js"; +import ComponentDatatype from "../Core/ComponentDatatype.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import defaultValue from "../Core/defaultValue.js"; +import defer from "../Core/defer.js"; +import defined from "../Core/defined.js"; +import Resource from "../Core/Resource.js"; +import GltfLoader from "./GltfLoader.js"; +import MetadataComponentType from "./MetadataComponentType.js"; +import MetadataType from "./MetadataType.js"; +import ModelExperimentalUtility from "./ModelExperimental/ModelExperimentalUtility.js"; +import VoxelShapeType from "./VoxelShapeType.js"; + +/** + * A {@link VoxelProvider} that fetches voxel data from a glTF. + * + * @alias GltfVoxelProvider + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {String|Resource|Uint8Array|Object|GltfLoader} options.gltf A Resource/URL to a glTF/glb file, a binary glTF buffer, or a JSON object containing the glTF contents + * + * @see VoxelProvider + * @see Cesium3DTilesVoxelProvider + * @see VoxelPrimitive + */ +function GltfVoxelProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + //>>includeStart('debug', pragmas.debug); + Check.defined("options.gltf", options.gltf); + //>>includeEnd('debug'); + + /** + * Gets a value indicating whether or not the provider is ready for use. + * @type {Boolean} + * @readonly + */ + this.ready = false; + + this._readyPromise = defer(); + + /** + * Gets the promise that will be resolved when the provider is ready for use. + * @type {Promise.} + * @readonly + */ + this.readyPromise = this._readyPromise.promise; + + /** + * An optional model matrix that is applied to all tiles + * @type {Matrix4} + * @readonly + */ + this.modelMatrix = undefined; + + /** + * Gets the {@link VoxelShapeType} + * @type {VoxelShapeType} + * @readonly + */ + this.shape = undefined; + + /** + * Gets the minimum bounds. + * If undefined, the shape's default minimum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.minBounds = undefined; + + /** + * Gets the maximum bounds. + * If undefined, the shape's default maximum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.maxBounds = undefined; + + /** + * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + this.dimensions = undefined; + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * TODO: mark this optional + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Number} + * @readonly + */ + this.paddingBefore = undefined; + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * This should not be called before {@link VoxelProvider#ready} returns true. + * TODO: mark this optional + * @type {Number} + * @readonly + */ + this.paddingAfter = undefined; + + // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use + + /** + * Gets stuff + * @type {String[]} + */ + this.names = new Array(); + + /** + * Gets stuff + * @type {MetadataType[]} + */ + this.types = new Array(); + + /** + * Gets stuff + * @type {MetadataComponentType[]} + */ + this.componentTypes = new Array(); + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the minimum value + * @type {Number[]} + */ + this.minimumValues = undefined; + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the maximum value + * @type {Number[][]} + */ + this.maximumValues = undefined; + + /** + * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. + * @type {Number} + */ + this.maximumTileCount = undefined; + + /** + * A {@link GltfLoader} that is processed each frame until ready. + * @type {GltfLoader} + * @private + */ + this._loader = undefined; + + const gltf = options.gltf; + let promise; + if (defined(gltf.components) && defined(gltf.components.asset)) { + promise = gltf.promise; + } else { + const gltfResource = Resource.createIfNeeded(gltf); + const loader = new GltfLoader({ + gltfResource: gltfResource, + releaseGltfJson: true, + loadAsTypedArray: true, + }); + loader.load(); + promise = loader.promise; + this._loader = loader; + } + + const that = this; + promise + .then(function (loader) { + const gltf = loader.components; + const node = gltf.nodes[0]; + const modelMatrix = ModelExperimentalUtility.getNodeTransform(node); + const gltfPrimitive = node.primitives[0]; + const voxel = gltfPrimitive.voxel; + const primitiveType = gltfPrimitive.primitiveType; + const shape = VoxelShapeType.fromPrimitiveType(primitiveType); + const attributes = gltfPrimitive.attributes; + const attributesLength = attributes.length; + const names = new Array(attributesLength); + const types = new Array(attributesLength); + const componentTypes = new Array(attributesLength); + const minimumValues = undefined; //new Array(length); + const maximumValues = undefined; //new Array(length); + + for (let i = 0; i < attributesLength; i++) { + const attribute = attributes[i]; + const name = attribute.name; + const type = attribute.type; + const componentDatatype = attribute.componentDatatype; + let nameFixed = name.toLowerCase(); + if (nameFixed.charAt(0) === "_") { + nameFixed = nameFixed.slice(1); + } + + names[i] = nameFixed; + types[i] = type; + componentTypes[i] = MetadataComponentType.fromComponentDatatype( + componentDatatype + ); + } + + that.ready = true; + that._readyPromise = Promise.resolve(that); + + /** + * An optional model matrix that is applied to all tiles + * @type {Matrix4} + * @readonly + */ + that.modelMatrix = modelMatrix; + + /** + * Gets the {@link VoxelShapeType} + * @type {VoxelShapeType} + * @readonly + */ + that.shape = shape; + + /** + * Gets the minimum bounds. + * This should not be called before {@link GltfVoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + that.minBounds = defined(voxel.minBounds) + ? Cartesian3.clone(voxel.minBounds, new Cartesian3()) + : undefined; + + /** + * Gets the maximum bounds. + * This should not be called before {@link GltfVoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + that.maxBounds = defined(voxel.maxBounds) + ? Cartesian3.clone(voxel.maxBounds, new Cartesian3()) + : undefined; + + /** + * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. + * This should not be called before {@link GltfVoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + that.dimensions = Cartesian3.clone(voxel.dimensions, new Cartesian3()); + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * TODO: mark this optional + * This should not be called before {@link GltfVoxelProvider#ready} returns true. + * @type {Number} + * @readonly + */ + that.paddingBefore = defined(voxel.paddingBefore) + ? Cartesian3.clone(voxel.paddingBefore, new Cartesian3()) + : undefined; + + /** + * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. + * This should not be called before {@link GltfVoxelProvider#ready} returns true. + * TODO: mark this optional + * @type {Number} + * @readonly + */ + that.paddingAfter = defined(voxel.paddingAfter) + ? Cartesian3.clone(voxel.paddingAfter, new Cartesian3()) + : undefined; + + // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use + + /** + * Gets stuff + * @type {String[]} + */ + that.names = names; + + /** + * Gets stuff + * @type {MetadataType[]} + */ + that.types = types; + + /** + * Gets stuff + * @type {MetadataComponentType[]} + */ + that.componentTypes = componentTypes; + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the minimum value + * @type {Number[]} + */ + that.minimumValues = minimumValues; + + /** + * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array + * Gets the maximum value + * @type {Number[][]} + */ + that.maximumValues = maximumValues; + + /** + * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. + * @type {Number} + */ + that.maximumTileCount = 1; + + /** + * @private + * @type {Float32Array|Uint16Array|Uint8Array} + */ + that._data = new Array(attributesLength); + for (let i = 0; i < attributesLength; i++) { + const attribute = attributes[i]; + const typedArray = attribute.typedArray; + const type = attribute.type; + const componentDatatype = attribute.componentDatatype; + const componentCount = MetadataType.getComponentCount(type); + const totalCount = attribute.count * componentCount; + + that._data[i] = ComponentDatatype.createArrayBufferView( + componentDatatype, + typedArray.buffer, + typedArray.byteOffset + attribute.byteOffset, + totalCount + ); + } + + // Now that the data is loaded there's no need to keep around the loader. + that._loader = undefined; + }) + .catch(function (error) { + that.readyPromise = Promise.reject(error); + }); +} + +/** + * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. + * If the provider doesn't need this functionality it should leave this function undefined. + * @function + * @param {FrameState} frameState + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +GltfVoxelProvider.prototype.update = function (frameState) { + const loader = this._loader; + if (defined(loader)) { + loader.process(frameState); + } +}; + +/** + * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. + * Note that there is only one "tile" for a glTF so the only valid input is the "root" tile coordinates. + * This function should not be called before {@link GltfVoxelProvider#ready} returns true. + * @function + * + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.tileLevel=0] The tile's level. + * @param {Number} [options.tileX=0] The tile's X coordinate. + * @param {Number} [options.tileY=0] The tile's Y coordinate. + * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * + * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. + */ +GltfVoxelProvider.prototype.requestData = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const tileX = defaultValue(options.tileX, 0); + const tileY = defaultValue(options.tileY, 0); + const tileZ = defaultValue(options.tileZ, 0); + const tileLevel = defaultValue(options.tileLevel, 0); + + //>>includeStart('debug', pragmas.debug); + if (!this.ready) { + throw new DeveloperError( + "requestData must not be called before the provider is ready." + ); + } + if (!(tileLevel === 0 && tileX === 0 && tileY === 0 && tileZ === 0)) { + throw new DeveloperError("GltfVoxelProvider can only have one tile"); + } + //>>includeEnd('debug'); + + return Promise.resolve(this._data); +}; + +/** + * Check if the data is still being loaded. + * This is intended to be used for unit tests only. + * @returns {Boolean} + * @private + */ +GltfVoxelProvider.prototype._doneLoading = function () { + return !defined(this._loader); +}; + +export default GltfVoxelProvider; diff --git a/Source/Scene/MetadataComponentType.js b/Source/Scene/MetadataComponentType.js index f14f1ca69a0..cd0d2fc35b5 100644 --- a/Source/Scene/MetadataComponentType.js +++ b/Source/Scene/MetadataComponentType.js @@ -1,5 +1,6 @@ import CesiumMath from "../Core/Math.js"; import Check from "../Core/Check.js"; +import ComponentDatatype from "../Core/ComponentDatatype.js"; import DeveloperError from "../Core/DeveloperError.js"; import FeatureDetection from "../Core/FeatureDetection.js"; @@ -445,4 +446,85 @@ MetadataComponentType.getSizeInBytes = function (type) { } }; +/** + * Gets the type from a {@link ComponentDatatype}. + * + * @param {ComponentDatatype} componentDatatype The component datatype. + * @returns {MetadataComponentType} The metadata component type. + * + * @private + */ +MetadataComponentType.fromComponentDatatype = function (componentDatatype) { + switch (componentDatatype) { + case ComponentDatatype.BYTE: + return MetadataComponentType.INT8; + case ComponentDatatype.UNSIGNED_BYTE: + return MetadataComponentType.UINT8; + case ComponentDatatype.SHORT: + return MetadataComponentType.INT16; + case ComponentDatatype.UNSIGNED_SHORT: + return MetadataComponentType.UINT16; + case ComponentDatatype.INT: + return MetadataComponentType.INT32; + case ComponentDatatype.UNSIGNED_INT: + return MetadataComponentType.UINT32; + case ComponentDatatype.FLOAT: + return MetadataComponentType.FLOAT32; + case ComponentDatatype.DOUBLE: + return MetadataComponentType.FLOAT64; + } +}; + +MetadataComponentType.toComponentDatatype = function (type) { + //>>includeStart('debug', pragmas.debug); + if (!MetadataComponentType.isNumericType(type)) { + throw new DeveloperError("type must be a numeric type"); + } + //>>includeEnd('debug'); + switch (type) { + case MetadataComponentType.INT8: + return ComponentDatatype.BYTE; + case MetadataComponentType.UINT8: + return ComponentDatatype.UNSIGNED_BYTE; + case MetadataComponentType.INT16: + return ComponentDatatype.SHORT; + case MetadataComponentType.UINT16: + return ComponentDatatype.UNSIGNED_SHORT; + case MetadataComponentType.INT32: + return ComponentDatatype.INT; + case MetadataComponentType.UINT32: + return ComponentDatatype.UNSIGNED_INT; + case MetadataComponentType.FLOAT32: + return ComponentDatatype.FLOAT; + case MetadataComponentType.FLOAT64: + return ComponentDatatype.DOUBLE; + } +}; + +MetadataComponentType.toTypedArrayType = function (type) { + //>>includeStart('debug', pragmas.debug); + if (!MetadataComponentType.isNumericType(type)) { + throw new DeveloperError("type must be a numeric type"); + } + //>>includeEnd('debug'); + switch (type) { + case MetadataComponentType.INT8: + return Int8Array; + case MetadataComponentType.UINT8: + return Uint8Array; + case MetadataComponentType.INT16: + return Int16Array; + case MetadataComponentType.UINT16: + return Uint16Array; + case MetadataComponentType.INT32: + return Int32Array; + case MetadataComponentType.UINT32: + return Uint32Array; + case MetadataComponentType.FLOAT32: + return Float32Array; + case MetadataComponentType.FLOAT64: + return Float64Array; + } +}; + export default Object.freeze(MetadataComponentType); diff --git a/Source/Scene/ModelComponents.js b/Source/Scene/ModelComponents.js index 1b52a8e92b9..2ce5fb6eba7 100644 --- a/Source/Scene/ModelComponents.js +++ b/Source/Scene/ModelComponents.js @@ -542,6 +542,46 @@ function MorphTarget() { this.attributes = []; } +/** + * Properties from EXT_primitive_voxels + * + * @alias ModelComponents.Voxel + * @constructor + * + * @private + */ +function Voxel() { + /** + * @type {Cartesian3} + * @private + */ + this.minBounds = undefined; + + /** + * @type {Cartesian3} + * @private + */ + this.maxBounds = undefined; + + /** + * @type {Cartesian3} + * @private + */ + this.dimensions = undefined; + + /** + * @type {Cartesian3} + * @private + */ + this.paddingBefore = undefined; + + /** + * @type {Cartesian3} + * @private + */ + this.paddingAfter = undefined; +} + /** * Geometry to be rendered with a material. * @@ -625,6 +665,13 @@ function Primitive() { * @private */ this.propertyAttributeIds = []; + + /** + * Properties from EXT_primitive_voxels. + * @type {ModelComponents.Voxel} + * @private + */ + this.voxel = undefined; } /** @@ -1163,6 +1210,7 @@ function Material() { Material.DEFAULT_EMISSIVE_FACTOR = Cartesian3.ZERO; ModelComponents.Quantization = Quantization; +ModelComponents.Voxel = Voxel; ModelComponents.Attribute = Attribute; ModelComponents.Indices = Indices; ModelComponents.FeatureIdAttribute = FeatureIdAttribute; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 70d57cb90d8..0bb323707bc 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2287,6 +2287,17 @@ function executeTranslucentCommandsFrontToBack( } } +function executeVoxelCommands(scene, executeFunction, passState, commands) { + const context = scene.context; + + mergeSort(commands, backToFront, scene.camera.positionWC); + + const length = commands.length; + for (let i = 0; i < length; ++i) { + executeFunction(commands[i], scene, context, passState); + } +} + const scratchPerspectiveFrustum = new PerspectiveFrustum(); const scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum(); const scratchOrthographicFrustum = new OrthographicFrustum(); @@ -2695,6 +2706,12 @@ function executeCommands(scene, passState) { pickDepth.executeCopyDepth(context, passState); } + us.updatePass(Pass.VOXELS); + commands = frustumCommands.commands[Pass.VOXELS]; + length = frustumCommands.indices[Pass.VOXELS]; + commands.length = length; + executeVoxelCommands(scene, executeCommand, passState, commands); + if (picking || !usePostProcessSelected) { continue; } diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js new file mode 100644 index 00000000000..a66e5cf3073 --- /dev/null +++ b/Source/Scene/VoxelBoxShape.js @@ -0,0 +1,325 @@ +import BoundingSphere from "../Core/BoundingSphere.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import CesiumMath from "../Core/Math.js"; +import Check from "../Core/Check.js"; +import Matrix3 from "../Core/Matrix3.js"; +import Matrix4 from "../Core/Matrix4.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; + +/** + * A box {@link VoxelShape}. + * + * @alias VoxelBoxShape + * @constructor + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * + * @see VoxelShape + * @see VoxelEllipsoidShape + * @see VoxelCylinderShape + * @see VoxelShapeType + */ +function VoxelBoxShape() { + /** + * An oriented bounding box containing the bounded shape. + * The update function must be called before accessing this value. + * @type {OrientedBoundingBox} + */ + this.orientedBoundingBox = new OrientedBoundingBox(); + + /** + * A bounding sphere containing the bounded shape. + * The update function must be called before accessing this value. + * @type {BoundingSphere} + */ + this.boundingSphere = new BoundingSphere(); + + /** + * A transformation matrix containing the bounded shape. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + this.boundTransform = new Matrix4(); + + /** + * A transformation matrix containing the shape, ignoring the bounds. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + this.shapeTransform = new Matrix4(); + + /** + * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. + * The update function must be called before accessing this value. + * @type {Boolean} + */ + this.isVisible = false; + + this._minBounds = Cartesian3.clone( + VoxelBoxShape.DefaultMinBounds, + new Cartesian3() + ); + this._maxBounds = Cartesian3.clone( + VoxelBoxShape.DefaultMaxBounds, + new Cartesian3() + ); +} + +const scratchTranslation = new Cartesian3(); +const scratchScale = new Cartesian3(); +const scratchRotation = new Matrix3(); + +/** + * @param {Cartesian3} minimumX + * @param {Cartesian3} maximumX + * @param {Cartesian3} minimumY + * @param {Cartesian3} maximumY + * @param {Cartesian3} minimumZ + * @param {Cartesian3} maximumZ + * @param {Matrix4} matrix + * @param {OrientedBoundingBox} result + * @returns {OrientedBoundingBox} + */ +function getBoxChunkObb( + minimumX, + maximumX, + minimumY, + maximumY, + minimumZ, + maximumZ, + matrix, + result +) { + const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; + const defaultMaxBounds = VoxelBoxShape.DefaultMaxBounds; + + const isDefaultBounds = + minimumX === defaultMinBounds.x && + minimumY === defaultMinBounds.y && + minimumZ === defaultMinBounds.z && + maximumX === defaultMaxBounds.x && + maximumY === defaultMaxBounds.y && + maximumZ === defaultMaxBounds.z; + + if (isDefaultBounds) { + result.center = Matrix4.getTranslation(matrix, result.center); + result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); + } else { + let scale = Matrix4.getScale(matrix, scratchScale); + const translation = Matrix4.getTranslation(matrix, scratchTranslation); + result.center = Cartesian3.fromElements( + translation.x + scale.x * 0.5 * (minimumX + maximumX), + translation.y + scale.y * 0.5 * (maximumY + minimumY), + translation.z + scale.z * 0.5 * (maximumZ + minimumZ), + result.center + ); + + scale = Cartesian3.fromElements( + scale.x * 0.5 * (maximumX - minimumX), + scale.y * 0.5 * (maximumY - minimumY), + scale.z * 0.5 * (maximumZ - minimumZ), + scratchScale + ); + const rotation = Matrix4.getRotation(matrix, scratchRotation); + result.halfAxes = Matrix3.setScale(rotation, scale, result.halfAxes); + } + + return result; +} + +/** + * Update the shape's state. + * @function + * @param {Matrix4} modelMatrix The model matrix. + * @param {Cartesian3} minBounds The minimum bounds. + * @param {Cartesian3} maxBounds The maximum bounds. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("modelMatrix", modelMatrix); + Check.typeOf.object("minBounds", minBounds); + Check.typeOf.object("maxBounds", maxBounds); + //>>includeEnd('debug'); + + // Don't render if any of the min bounds exceed the max bounds. + // Don't render if two of the min bounds equal the max bounds because it would be an invisible line. + // Don't render if all of the min bounds equal the max bounds because it would be an invisible point. + // Still render if one of the min bounds is equal to the max bounds because it will be a square/rectangle. + if ( + minBounds.x > maxBounds.x || + minBounds.y > maxBounds.y || + minBounds.z > maxBounds.z || + (minBounds.x === maxBounds.x) + + (minBounds.y === maxBounds.y) + + (minBounds.z === maxBounds.z) >= + 2 + ) { + this.isVisible = false; + return; + } + + // If two or more of the scales are 0 the shape will not render. + // If one of the scales is 0 it will still be visible but will appear as a square/rectangle. + const scale = Matrix4.getScale(modelMatrix, scratchScale); + if ((scale.x === 0.0) + (scale.y === 0.0) + (scale.z === 0.0) >= 2) { + this.isVisible = false; + return; + } + + this._minBounds = Cartesian3.clone(minBounds, this._minBounds); + this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); + + this.orientedBoundingBox = getBoxChunkObb( + minBounds.x, + maxBounds.x, + minBounds.y, + maxBounds.y, + minBounds.z, + maxBounds.z, + modelMatrix, + this.orientedBoundingBox + ); + + this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); + + // All of the box bounds go from -1 to +1, so the model matrix scale can be + // used as the oriented bounding box half axes. + this.boundTransform = Matrix4.fromRotationTranslation( + this.orientedBoundingBox.halfAxes, + this.orientedBoundingBox.center, + this.boundTransform + ); + + this.boundingSphere = BoundingSphere.fromOrientedBoundingBox( + this.orientedBoundingBox, + this.boundingSphere + ); + + this.isVisible = true; +}; + +/** + * Computes an oriented bounding box for a specified tile. + * The update function must be called before calling this function. + * @function + * @param {Number} tileLevel The tile's level. + * @param {Number} tileX The tile's x coordinate. + * @param {Number} tileY The tile's y coordinate. + * @param {Number} tileZ The tile's z coordinate. + * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile + * @returns {OrientedBoundingBox} The oriented bounding box. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( + tileLevel, + tileX, + tileY, + tileZ, + result +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("tileLevel", tileLevel); + Check.typeOf.number("tileX", tileX); + Check.typeOf.number("tileY", tileY); + Check.typeOf.number("tileZ", tileZ); + Check.typeOf.object("result", result); + //>>includeEnd('debug'); + + const rootTransform = this.shapeTransform; + const sizeAtLevel = 1.0 / Math.pow(2, tileLevel); + + const minBounds = this._minBounds; + const maxBounds = this._maxBounds; + + const minimumX = CesiumMath.lerp( + minBounds.x, + maxBounds.x, + sizeAtLevel * tileX + ); + const minimumY = CesiumMath.lerp( + minBounds.y, + maxBounds.y, + sizeAtLevel * tileY + ); + const minimumZ = CesiumMath.lerp( + minBounds.z, + maxBounds.z, + sizeAtLevel * tileZ + ); + const maximumX = CesiumMath.lerp( + minBounds.x, + maxBounds.x, + sizeAtLevel * (tileX + 1) + ); + const maximumY = CesiumMath.lerp( + minBounds.y, + maxBounds.y, + sizeAtLevel * (tileY + 1) + ); + const maximumZ = CesiumMath.lerp( + minBounds.z, + maxBounds.z, + sizeAtLevel * (tileZ + 1) + ); + + return getBoxChunkObb( + minimumX, + maximumX, + minimumY, + maximumY, + minimumZ, + maximumZ, + rootTransform, + result + ); +}; + +/** + * Computes an approximate step size for raymarching the root tile of a voxel grid. + * The update function must be called before calling this function. + * @function + * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. + * @returns {Number} The step size. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelBoxShape.prototype.computeApproximateStepSize = function (dimensions) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("dimensions", dimensions); + //>>includeEnd('debug'); + + return 1.0 / Cartesian3.maximumComponent(dimensions); +}; + +/** + * Defines the minimum bounds of the shape. Corresponds to minimum X, Y, Z. + * @type {Cartesian3} + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelBoxShape.DefaultMinBounds = Cartesian3.negate( + Cartesian3.ONE, + new Cartesian3() +); + +/** + * Defines the maximum bounds of the shape. Corresponds to maximum X, Y, Z. + * @type {Cartesian3} + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelBoxShape.DefaultMaxBounds = Cartesian3.clone( + Cartesian3.ONE, + new Cartesian3() +); + +export default VoxelBoxShape; diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js new file mode 100644 index 00000000000..e379a8b0b11 --- /dev/null +++ b/Source/Scene/VoxelCylinderShape.js @@ -0,0 +1,529 @@ +import BoundingSphere from "../Core/BoundingSphere.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import Check from "../Core/Check.js"; +import CesiumMath from "../Core/Math.js"; +import Matrix3 from "../Core/Matrix3.js"; +import Matrix4 from "../Core/Matrix4.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; + +/** + * A cylinder {@link VoxelShape}. + * + * @alias VoxelCylinderShape + * @constructor + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * + * @see VoxelShape + * @see VoxelCylinderShape + * @see VoxelEllipsoidShape + * @see VoxelShapeType + */ +function VoxelCylinderShape() { + /** + * An oriented bounding box containing the bounded shape. + * The update function must be called before accessing this value. + * @type {OrientedBoundingBox} + */ + this.orientedBoundingBox = new OrientedBoundingBox(); + + /** + * A bounding sphere containing the bounded shape. + * The update function must be called before accessing this value. + * @type {BoundingSphere} + */ + this.boundingSphere = new BoundingSphere(); + + /** + * A transformation matrix containing the bounded shape. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + this.boundTransform = new Matrix4(); + + /** + * A transformation matrix containing the shape, ignoring the bounds. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + this.shapeTransform = new Matrix4(); + + /** + * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. + * The update function must be called before accessing this value. + * @type {Boolean} + */ + this.isVisible = false; + + this._minimumRadius = VoxelCylinderShape.DefaultMinBounds.x; + this._maximumRadius = VoxelCylinderShape.DefaultMaxBounds.x; + this._minimumHeight = VoxelCylinderShape.DefaultMinBounds.y; + this._maximumHeight = VoxelCylinderShape.DefaultMaxBounds.y; + this._minimumAngle = VoxelCylinderShape.DefaultMinBounds.z; + this._maximumAngle = VoxelCylinderShape.DefaultMaxBounds.z; +} + +const scratchTestAngles = new Array(6); + +// Preallocated arrays for all of the possible test angle counts +const scratchPositions = [ + new Array(), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), +]; + +/** + * @function + * @param {Number} radiusStart + * @param {Number} radiusEnd + * @param {Number} heightStart + * @param {Number} heightEnd + * @param {Number} angleStart + * @param {Number} angleEnd + * @param {Matrix4} matrix + * @param {OrientedBoundingBox} result + * @returns {OrientedBoundingBox} + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +function getCylinderChunkObb( + radiusStart, + radiusEnd, + heightStart, + heightEnd, + angleStart, + angleEnd, + matrix, + result +) { + const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; + const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; + const defaultMinRadius = defaultMinBounds.x; // 0 + const defaultMaxRadius = defaultMaxBounds.x; // 1 + const defaultMinHeight = defaultMinBounds.y; // -1 + const defaultMaxHeight = defaultMaxBounds.y; // +1 + const defaultMinAngle = defaultMinBounds.z; // -pi/2 + const defaultMaxAngle = defaultMaxBounds.z; // +pi/2 + + // Return early if using the default bounds + if ( + radiusStart === defaultMinRadius && + radiusEnd === defaultMaxRadius && + heightStart === defaultMinHeight && + heightEnd === defaultMaxHeight && + angleStart === defaultMinAngle && + angleEnd === defaultMaxAngle + ) { + result.center = Matrix4.getTranslation(matrix, result.center); + result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); + return result; + } + + let testAngleCount = 0; + const testAngles = scratchTestAngles; + const halfPi = CesiumMath.PI_OVER_TWO; + + testAngles[testAngleCount++] = angleStart; + testAngles[testAngleCount++] = angleEnd; + + if (angleStart > angleEnd) { + if (angleStart > 0.0 && angleEnd > 0.0) { + testAngles[testAngleCount++] = 0.0; + } + if (angleStart > +halfPi && angleEnd > +halfPi) { + testAngles[testAngleCount++] = +halfPi; + } + if (angleStart > -halfPi && angleEnd > -halfPi) { + testAngles[testAngleCount++] = -halfPi; + } + // It will always cross the 180th meridian + testAngles[testAngleCount++] = CesiumMath.PI; + } else { + if (angleStart < 0.0 && angleEnd > 0.0) { + testAngles[testAngleCount++] = 0.0; + } + if (angleStart < +halfPi && angleEnd > +halfPi) { + testAngles[testAngleCount++] = +halfPi; + } + if (angleStart < -halfPi && angleEnd > -halfPi) { + testAngles[testAngleCount++] = -halfPi; + } + } + + const positions = scratchPositions[testAngleCount]; + + for (let i = 0; i < testAngleCount; i++) { + const angle = testAngles[i]; + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + + positions[i * 4 + 0] = Cartesian3.fromElements( + cosAngle * radiusStart, + sinAngle * radiusStart, + heightStart, + positions[i * 4 + 0] + ); + positions[i * 4 + 1] = Cartesian3.fromElements( + cosAngle * radiusEnd, + sinAngle * radiusEnd, + heightStart, + positions[i * 4 + 1] + ); + positions[i * 4 + 2] = Cartesian3.fromElements( + cosAngle * radiusStart, + sinAngle * radiusStart, + heightEnd, + positions[i * 4 + 2] + ); + positions[i * 4 + 3] = Cartesian3.fromElements( + cosAngle * radiusEnd, + sinAngle * radiusEnd, + heightEnd, + positions[i * 4 + 3] + ); + } + + for (let i = 0; i < testAngleCount * 4; i++) { + positions[i] = Matrix4.multiplyByPoint(matrix, positions[i], positions[i]); + } + + return OrientedBoundingBox.fromPoints(positions, result); +} + +const scratchScale = new Cartesian3(); + +/** + * Update the shape's state. + * @function + * @param {Matrix4} modelMatrix The model matrix. + * @param {Cartesian3} minBounds The minimum bounds. + * @param {Cartesian3} maxBounds The maximum bounds. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelCylinderShape.prototype.update = function ( + modelMatrix, + minBounds, + maxBounds +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("modelMatrix", modelMatrix); + Check.typeOf.object("minBounds", minBounds); + Check.typeOf.object("maxBounds", maxBounds); + //>>includeEnd('debug'); + + // Don't let the scale be 0, it will screw up a bunch of math + const scaleEps = CesiumMath.EPSILON8; + const scale = Matrix4.getScale(modelMatrix, scratchScale); + if (Math.abs(scale.x) < scaleEps) { + scale.x = CesiumMath.signNotZero(scale.x) * scaleEps; + } + if (Math.abs(scale.y) < scaleEps) { + scale.y = CesiumMath.signNotZero(scale.y) * scaleEps; + } + if (Math.abs(scale.z) < scaleEps) { + scale.z = CesiumMath.signNotZero(scale.z) * scaleEps; + } + + // // If two or more of the scales are 0 the shape will not render. + // // If the X scale or Y scale is 0 the shape will appear as a square/rectangle. + // // If the Z scale is 0 the shape will appear as an circle/ellipse. + // const xIsZero = scale.x === 0.0; + // const yIsZero = scale.y === 0.0; + // const zIsZero = scale.z === 0.0; + // if (xIsZero + yIsZero + zIsZero >= 2) { + // this.isVisible = false; + // return; + // } + + this._minimumRadius = minBounds.x; // [0,1] + this._maximumRadius = maxBounds.x; // [0,1] + this._minimumHeight = minBounds.y; // [-1,+1] + this._maximumHeight = maxBounds.y; // [-1,+1] + this._minimumAngle = CesiumMath.negativePiToPi(minBounds.z); // [-halfPi,+halfPi] + this._maximumAngle = CesiumMath.negativePiToPi(maxBounds.z); // [-halfPi,+halfPi] + + const minRadius = this._minimumRadius; + const maxRadius = this._maximumRadius; + const minHeight = this._minimumHeight; + const maxHeight = this._maximumHeight; + const minAngle = this._minimumAngle; + const maxAngle = this._maximumAngle; + + // Exit early if the bounds make the shape invisible. + // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. + if (minRadius > maxRadius || minHeight > maxHeight) { + this.isVisible = false; + return; + } + + this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); + + this.orientedBoundingBox = getCylinderChunkObb( + minRadius, + maxRadius, + minHeight, + maxHeight, + minAngle, + maxAngle, + this.shapeTransform, + this.orientedBoundingBox + ); + + this.boundTransform = Matrix4.fromRotationTranslation( + this.orientedBoundingBox.halfAxes, + this.orientedBoundingBox.center, + this.boundTransform + ); + + this.boundingSphere = BoundingSphere.fromOrientedBoundingBox( + this.orientedBoundingBox, + this.boundingSphere + ); + + this.isVisible = true; +}; + +/** + * Computes an oriented bounding box for a specified tile. + * The update function must be called before calling this function. + * @function + * @param {Number} tileLevel The tile's level. + * @param {Number} tileX The tile's x coordinate. + * @param {Number} tileY The tile's y coordinate. + * @param {Number} tileZ The tile's z coordinate. + * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile + * @returns {OrientedBoundingBox} The oriented bounding box. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelCylinderShape.prototype.computeOrientedBoundingBoxForTile = function ( + tileLevel, + tileX, + tileY, + tileZ, + result +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("tileLevel", tileLevel); + Check.typeOf.number("tileX", tileX); + Check.typeOf.number("tileY", tileY); + Check.typeOf.number("tileZ", tileZ); + Check.typeOf.object("result", result); + //>>includeEnd('debug'); + + const rootTransform = this.shapeTransform; + const minimumRadius = this._minimumRadius; + const maximumRadius = this._maximumRadius; + const minimumHeight = this._minimumHeight; + const maximumHeight = this._maximumHeight; + const minimumAngle = this._minimumAngle; + const maximumAngle = this._maximumAngle; + + const sizeAtLevel = 1.0 / Math.pow(2.0, tileLevel); + + const radiusStart = CesiumMath.lerp( + minimumRadius, + maximumRadius, + tileX * sizeAtLevel + ); + const radiusEnd = CesiumMath.lerp( + minimumRadius, + maximumRadius, + (tileX + 1) * sizeAtLevel + ); + const heightStart = CesiumMath.lerp( + minimumHeight, + maximumHeight, + tileY * sizeAtLevel + ); + const heightEnd = CesiumMath.lerp( + minimumHeight, + maximumHeight, + (tileY + 1) * sizeAtLevel + ); + const angleStart = CesiumMath.lerp( + minimumAngle, + maximumAngle, + tileZ * sizeAtLevel + ); + const angleEnd = CesiumMath.lerp( + minimumAngle, + maximumAngle, + (tileZ + 1) * sizeAtLevel + ); + + return getCylinderChunkObb( + radiusStart, + radiusEnd, + heightStart, + heightEnd, + angleStart, + angleEnd, + rootTransform, + result + ); +}; + +const scratchOrientedBoundingBox = new OrientedBoundingBox(); +const scratchVoxelScale = new Cartesian3(); +const scratchRootScale = new Cartesian3(); +const scratchScaleRatio = new Cartesian3(); + +VoxelCylinderShape.prototype.computeApproximateStepSize = function ( + voxelDimensions +) { + const rootTransform = this.shapeTransform; + + const minRadius = this._minimumRadius; + const maxRadius = this._maximumRadius; + const minHeight = this._minimumHeight; + const maxHeight = this._maximumHeight; + const minAngle = this._minimumAngle; + const maxAngle = this._maximumAngle; + + const lerpRadius = 1.0 - 1.0 / voxelDimensions.x; + const lerpHeight = 1.0 - 1.0 / voxelDimensions.y; + const lerpAngle = 1.0 - 1.0 / voxelDimensions.z; + + // Compare the size of an outermost cylinder voxel to the total cylinder + const voxelMinimumRadius = CesiumMath.lerp(minRadius, maxRadius, lerpRadius); + const voxelMinimumHeight = CesiumMath.lerp(minHeight, maxHeight, lerpHeight); + const voxelMinimumAngle = CesiumMath.lerp(minAngle, maxAngle, lerpAngle); + const voxelMaximumRadius = maxRadius; + const voxelMaximumHeight = maxHeight; + const voxelMaximumAngle = maxAngle; + + const voxelObb = getCylinderChunkObb( + voxelMinimumRadius, + voxelMaximumRadius, + voxelMinimumHeight, + voxelMaximumHeight, + voxelMinimumAngle, + voxelMaximumAngle, + rootTransform, + scratchOrientedBoundingBox + ); + + const voxelScale = Matrix3.getScale(voxelObb.halfAxes, scratchVoxelScale); + const rootScale = Matrix4.getScale(rootTransform, scratchRootScale); + const scaleRatio = Cartesian3.divideComponents( + voxelScale, + rootScale, + scratchScaleRatio + ); + const stepSize = Cartesian3.minimumComponent(scaleRatio); + return stepSize; +}; + +/** + * @private + * @type {Cartesian3} + */ +VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); + +/** + * @private + * @type {Cartesian3} + */ +VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); + +export default VoxelCylinderShape; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js new file mode 100644 index 00000000000..d6aeb46fda0 --- /dev/null +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -0,0 +1,1027 @@ +import BoundingSphere from "../Core/BoundingSphere.js"; +import Cartesian2 from "../Core/Cartesian2.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import Check from "../Core/Check.js"; +import defaultValue from "../Core/defaultValue.js"; +import defined from "../Core/defined.js"; +import Ellipsoid from "../Core/Ellipsoid.js"; +import CesiumMath from "../Core/Math.js"; +import Matrix3 from "../Core/Matrix3.js"; +import Matrix4 from "../Core/Matrix4.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; +import Ray from "../Core/Ray.js"; +import Rectangle from "../Core/Rectangle.js"; +import VoxelShapeType from "./VoxelShapeType.js"; + +/** + * A {@link VoxelShape} for an ellipsoid. + * + * @alias VoxelEllipsoidShape + * @constructor + * + * @param {Object} [options] + * @param {Ellipsoid} [options.ellipsoid] + * @param {Rectangle} [options.rectangle] + * @param {Number} [options.minimumHeight] + * @param {Number} [options.maximumHeight] + * @param {Cartesian3} [options.translation] + * @param {Cartesian3} [options.scale] + * @param {Matrix3} [options.rotation] + * + * @see VoxelShape + * @see VoxelShapeType + */ +function VoxelEllipsoidShape(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + this._ellipsoid = Ellipsoid.clone( + defaultValue(options.ellipsoid, Ellipsoid.WGS84) + ); + this._rectangle = Rectangle.clone( + defaultValue(options.rectangle, Rectangle.MAX_VALUE) + ); + this._minimumHeight = defaultValue(options.minimumHeight, 0.0); + this._maximumHeight = defaultValue(options.maximumHeight, 1.0); + this._translation = Cartesian3.clone( + defaultValue(options.translation, Cartesian3.ZERO) + ); + this._scale = Cartesian3.clone(defaultValue(options.scale, Cartesian3.ONE)); + this._rotation = Matrix3.clone( + defaultValue(options.rotation, Matrix3.IDENTITY) + ); + + this._firstUpdate = true; + this._ellipsoidOld = Ellipsoid.clone(this._ellipsoid); + this._rectangleOld = Rectangle.clone(this._rectangle); + this._minimumHeightOld = this._minimumHeight; + this._maximumHeightOld = this._maximumHeight; + this._translationOld = Cartesian3.clone(this._translation); + this._scaleOld = Cartesian3.clone(this._scale); + this._rotationOld = Matrix3.clone(this._rotation); + + this._boundTransform = Matrix4.clone(Matrix4.IDENTITY); + this._shapeTransform = Matrix4.clone(Matrix4.IDENTITY); + this._orientedBoundingBox = new OrientedBoundingBox(); + this._boundingSphere = new BoundingSphere(); + + this._ellipsoidHeightDifferenceUv = 1.0; + this._ellipsoidOuterRadiiLocal = new Cartesian3(); + this._ellipsoidLongitudeBounds = new Cartesian3(); + this._ellipsoidLatitudeBounds = new Cartesian3(); + + this._type = VoxelShapeType.ELLIPSOID; + + this._phiMin = undefined; + this._phiMax = undefined; + this._thetaMin = undefined; + this._thetaMax = undefined; + setThetaAndPhiExtrema(this); +} + +function setThetaAndPhiExtrema(that) { + const rectangle = that.rectangle; + // Converting from cartographic lat, lon, height to spherical theta, phi, and radius for math + + // phi is the angle with the x axis in the counter clockwise direction. It is like + // longitude, but when it gets halfway around the globe, instead of going to negative + // pi it continues to positive 2 pi. [0, 2pi] + that._phiMin = rectangle.west; + if (rectangle.west < 0) { + // from [-pi, pi] to [0, 2pi] + that._phiMin = CesiumMath.TWO_PI + rectangle.west; + } + that._phiMax = that._phiMin + rectangle.width; + if (that._phiMax > CesiumMath.TWO_PI) { + that._phiMax -= CesiumMath.TWO_PI; + } + + // theta is angle from z axis to point. It is like latitude except zero is the north pole + // and it increases as it points more and more south. + // From [-pi/2, pi/2] centered on equator to [0, pi] from z axis. This swaps min/max + that._thetaMin = CesiumMath.PI_OVER_TWO - rectangle.north; + that._thetaMax = that._thetaMin + rectangle.height; +} + +Object.defineProperties(VoxelEllipsoidShape.prototype, { + /** + * Gets or sets the ellipsoid. + * @memberof VoxelEllipsoidShape.prototype + * @type {Ellipsoid} + */ + ellipsoid: { + get: function () { + return this._ellipsoid; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("ellipsoid", value); + //>>includeEnd('debug'); + + this._ellipsoid = Ellipsoid.clone(value, this._translation); + }, + }, + /** + * Gets or sets the rectangle relative to the ellipsoid. + * @memberof VoxelEllipsoidShape.prototype + * @type {Rectangle} + */ + rectangle: { + get: function () { + return this._rectangle; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("rectangle", value); + //>>includeEnd('debug'); + + this._rectangle = Rectangle.clone(value, this._rectangle); + setThetaAndPhiExtrema(this); + }, + }, + /** + * Gets or sets the minimum height relative to the ellipsoid surface. + * @memberof VoxelEllipsoidShape.prototype + * @type {Number} + */ + minimumHeight: { + get: function () { + return this._minimumHeight; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("minimumHeight", value); + //>>includeEnd('debug'); + + this._minimumHeight = value; + }, + }, + /** + * Gets or sets the maximum height relative to the ellipsoid surface. + * @memberof VoxelEllipsoidShape.prototype + * @type {Number} + */ + maximumHeight: { + get: function () { + return this._maximumHeight; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("maximumHeight", value); + //>>includeEnd('debug'); + + this._maximumHeight = value; + }, + }, + /** + * Gets or sets the translation. + * @memberof VoxelEllipsoidShape.prototype + * @type {Cartesian3} + */ + translation: { + get: function () { + return this._translation; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("translation", value); + //>>includeEnd('debug'); + + this._translation = Cartesian3.clone(value, this._translation); + }, + }, + /** + * Gets or sets the scale. + * @memberof VoxelEllipsoidShape.prototype + * @type {Cartesian3} + */ + scale: { + get: function () { + return this._scale; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("scale", value); + //>>includeEnd('debug'); + + this._scale = Cartesian3.clone(value, this._scale); + }, + }, + /** + * Gets or sets the rotation. + * @memberof VoxelEllipsoidShape.prototype + * @type {Matrix3} + */ + rotation: { + get: function () { + return this._rotation; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.defined("rotation", value); + //>>includeEnd('debug'); + + this._rotation = Matrix3.clone(value, this._rotation); + }, + }, + /** + * Gets the bounding sphere. + * @memberof VoxelEllipsoidShape.prototype + * @type {BoundingSphere} + * @readonly + */ + boundingSphere: { + get: function () { + if (isDirty(this)) { + computeTransforms(this); + } + return this._boundingSphere; + }, + }, + /** + * Gets the oriented bounding box. + * @memberof VoxelEllipsoidShape.prototype + * @type {OrientedBoundingBox} + * @readonly + */ + orientedBoundingBox: { + get: function () { + if (isDirty(this)) { + computeTransforms(this); + } + return this._orientedBoundingBox; + }, + }, +}); + +VoxelEllipsoidShape.clone = function (shape, result) { + if (!defined(shape)) { + return undefined; + } + + if (!defined(result)) { + result = new VoxelEllipsoidShape(); + } + + result._minimumHeight = shape._minimumHeight; + result._maximumHeight = shape._maximumHeight; + result._ellipsoid = shape._ellipsoid; + result._rectangle = shape._rectangle; + + result._translation = Cartesian3.clone(shape._translation); + result._scale = Cartesian3.clone(shape._scale); + result._rotation = Matrix3.clone(shape._rotation); + + result._firstUpdate = shape._firstUpdate; + + result._minimumHeightOld = shape._minimumHeightOld; + result._maximumHeightOld = shape._maximumHeightOld; + result._ellipsoidOld = shape._ellipsoidOld; + result._rectangleOld = shape._rectangleOld; + result._translationOld = Cartesian3.clone(shape._translationOld); + result._scaleOld = Cartesian3.clone(shape._scaleOld); + result._rotationOld = Matrix3.clone(shape._rotationOld); + + result._boundTransform = Matrix4.clone(shape._boundTransform); + result._shapeTransform = Matrix4.clone(shape._shapeTransform); + result._orientedBoundingBox = OrientedBoundingBox.clone( + shape._orientedBoundingBox + ); + result._boundingSphere = BoundingSphere.clone(shape._boundingSphere); + + result._type = shape._type; + + return result; +}; + +VoxelEllipsoidShape.prototype.clone = function (result) { + return VoxelEllipsoidShape.clone(this, result); +}; + +const scratchScale = new Cartesian3(); +const scratchOrientedBoundingBox = new OrientedBoundingBox(); +const scratchRectangle = new Rectangle(); + +function isDirty(that) { + const dirtyEllipsoid = !that._ellipsoid.equals(that._ellipsoidOld); + const dirtyRectangle = !Rectangle.equals(that._rectangle, that._rectangleOld); + const dirtyMinimumHeight = that._minimumHeight !== that._minimumHeightOld; + const dirtyMaximumHeight = that._maximumHeight !== that._maximumHeightOld; + const dirtyTranslation = !Cartesian3.equals( + that._translation, + that._translationOld + ); + const dirtyScale = !Cartesian3.equals(that._scale, that._scaleOld); + const dirtyRotation = !Matrix3.equals(that._rotation, that._rotationOld); + + return ( + that._firstUpdate || + dirtyEllipsoid || + dirtyRectangle || + dirtyMinimumHeight || + dirtyMaximumHeight || + dirtyTranslation || + dirtyScale || + dirtyRotation + ); +} + +function computeTransforms(that) { + const ellipsoid = that._ellipsoid; + const minimumHeight = that._minimumHeight; + const maximumHeight = that._maximumHeight; + const rectangle = that._rectangle; + + const radii = ellipsoid.radii; + const scaleX = 2.0 * (radii.x + maximumHeight); + const scaleY = 2.0 * (radii.y + maximumHeight); + const scaleZ = 2.0 * (radii.z + maximumHeight); + const scale = Cartesian3.fromElements(scaleX, scaleY, scaleZ, scratchScale); + + that._shapeTransform = Matrix4.fromScale(scale, that._shapeTransform); + + if (rectangle.equals(Rectangle.MAX_VALUE)) { + that._boundTransform = Matrix4.clone( + that._shapeTransform, + that._boundTransform + ); + } else { + // Convert the obb to a model matrix + const obb = OrientedBoundingBox.fromRectangle( + rectangle, + minimumHeight, + maximumHeight, + ellipsoid, + scratchOrientedBoundingBox + ); + that._boundTransform = OrientedBoundingBox.computeTransformation( + obb, + that._boundTransform + ); + } + + that._orientedBoundingBox = OrientedBoundingBox.fromTransformation( + that._boundTransform, + that._orientedBoundingBox + ); + that._boundingSphere = BoundingSphere.fromTransformation( + that._boundTransform, + that._boundingSphere + ); + + const boundedWest = rectangle.west; + const boundedEast = rectangle.east; + const boundedSouth = rectangle.south; + const boundedNorth = rectangle.north; + const longitudeRange = rectangle.width; + const latitudeRange = rectangle.height; + + const ellipsoidRadii = ellipsoid.radii; + const ellipsoidMaximumRadius = ellipsoid.maximumRadius; + that._ellipsoidHeightDifferenceUv = + 1.0 - + (ellipsoidMaximumRadius + minimumHeight) / + (ellipsoidMaximumRadius + maximumHeight); + that._ellipsoidOuterRadiiLocal = Cartesian3.divideByScalar( + ellipsoidRadii, + ellipsoidMaximumRadius, + that._ellipsoidOuterRadiiLocal + ); + that._ellipsoidLongitudeBounds = Cartesian3.fromElements( + boundedWest, + boundedEast, + longitudeRange, + that._ellipsoidLongitudeBounds + ); + that._ellipsoidLatitudeBounds = Cartesian3.fromElements( + boundedSouth, + boundedNorth, + latitudeRange, + that._ellipsoidLatitudeBounds + ); +} + +VoxelEllipsoidShape.prototype.update = function () { + if (isDirty(this)) { + computeTransforms(this); + this._firstUpdate = false; + this._ellipsoidOld = Ellipsoid.clone(this._ellipsoid, this._ellipsoidOld); + this._rectangleOld = Rectangle.clone(this._rectangle, this._rectangleOld); + this._minimumHeightOld = this._minimumHeight; + this._maximumHeightOld = this._maximumHeight; + this._translationOld = Cartesian3.clone( + this._translation, + this._translationOld + ); + this._scaleOld = Cartesian3.clone(this._scale, this._scaleOld); + this._rotationOld = Matrix3.clone(this._rotation, this._rotationOld); + return true; + } + + return false; +}; + +VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( + tileLevel, + tileX, + tileY, + tileZ, + result +) { + const ellipsoid = this._ellipsoid; + const rectangle = this._rectangle; + const minimumHeight = this._minimumHeight; + const maximumHeight = this._maximumHeight; + + const sizeAtLevel = 1.0 / Math.pow(2, tileLevel); + const tileMinimumHeight = CesiumMath.lerp( + minimumHeight, + maximumHeight, + tileZ * sizeAtLevel + ); + const tileMaximumHeight = CesiumMath.lerp( + minimumHeight, + maximumHeight, + (tileZ + 1) * sizeAtLevel + ); + + const westLerp = tileX * sizeAtLevel; + const eastLerp = (tileX + 1) * sizeAtLevel; + const southLerp = tileY * sizeAtLevel; + const northLerp = (tileY + 1) * sizeAtLevel; + const tileRectangle = Rectangle.subsection( + rectangle, + westLerp, + southLerp, + eastLerp, + northLerp, + scratchRectangle + ); + return OrientedBoundingBox.fromRectangle( + tileRectangle, + tileMinimumHeight, + tileMaximumHeight, + ellipsoid, + result + ); +}; + +VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( + voxelDimensions +) { + const ellipsoid = this._ellipsoid; + const ellipsoidMaximumRadius = ellipsoid.maximumRadius; + const minimumHeight = this._minimumHeight; + const maximumHeight = this._maximumHeight; + + const shellToEllipsoidRatio = + (maximumHeight - minimumHeight) / (ellipsoidMaximumRadius + maximumHeight); + const stepSize = (0.5 * shellToEllipsoidRatio) / voxelDimensions.z; + return stepSize; +}; + +const scratchSphericalMinima = new Cartesian3(); +const scratchSphericalMaxima = new Cartesian3(); +VoxelEllipsoidShape.prototype.localPointInsideShape = function ( + point, + clippingMinimum, + clippingMaximum +) { + const pointUv = Cartesian3.multiplyByScalar(point, 2.0, new Cartesian3()); + const pointEllipsoidSpace = Cartesian3.multiplyComponents( + pointUv, + this._ellipsoidOuterRadiiLocal, + new Cartesian3() + ); // now we work as if the ellipsoid is a sphere + + getSphericalExtremaFromClippingExtrema( + this, + clippingMinimum, + clippingMaximum, + scratchSphericalMinima, + scratchSphericalMaxima + ); + return pointIsWithinClippingParameters( + pointEllipsoidSpace, + scratchSphericalMinima.z, + scratchSphericalMaxima.z, + scratchSphericalMinima.y, + scratchSphericalMaxima.y, + scratchSphericalMinima.x, + scratchSphericalMaxima.x, + this._ellipsoidLongitudeBounds + ); +}; + +VoxelEllipsoidShape.prototype.transformFromLocalToShapeSpace = function ( + localCartesian, + result +) { + const pos3D = new Cartesian3(); + pos3D.x = localCartesian.x * 2.0; + pos3D.y = localCartesian.y * 2.0; + pos3D.z = localCartesian.z * 2.0; + const ellipsoidRadiiLocal = this._ellipsoidOuterRadiiLocal; + Cartesian3.multiplyComponents(pos3D, ellipsoidRadiiLocal, pos3D); + + const cartographic = Ellipsoid.fromCartesian3( + Cartesian3.fromElements(1.0, 1.0, 1.0) + ).cartesianToCartographic(pos3D); + let longitudeMin = this._ellipsoidLongitudeBounds.x; + const longitudeMax = this._ellipsoidLongitudeBounds.y; + const longitudeWidth = this._ellipsoidLongitudeBounds.z; + + const latitudeMin = this._ellipsoidLatitudeBounds.x; + const latitudeWidth = this._ellipsoidLatitudeBounds.z; + + if (longitudeMin > longitudeMax) { + longitudeMin -= CesiumMath.TWO_PI; + if (cartographic.longitude > longitudeMax) { + cartographic.longitude -= CesiumMath.TWO_PI; + } + } + + // normalize to be within min and max of ellipsoid slice + const distMin = -this._ellipsoidHeightDifferenceUv; + cartographic.longitude = + (cartographic.longitude - longitudeMin) / longitudeWidth; + cartographic.latitude = (cartographic.latitude - latitudeMin) / latitudeWidth; + cartographic.height = (cartographic.height - distMin) / -distMin; + result.x = cartographic.longitude; + result.y = cartographic.latitude; + result.z = cartographic.height; + return result; +}; + +const scratchIntersectionTs = new Cartesian2(); +VoxelEllipsoidShape.prototype.intersectRay = function ( + ray, + clippingMinimum, + clippingMaximum +) { + if (!defined(clippingMinimum)) { + clippingMinimum = Cartesian3.ZERO; + } + if (!defined(clippingMaximum)) { + clippingMinimum = Cartesian3.fromElements(1.0, 1.0, 1.0); + } + + const epsilon = CesiumMath.EPSILON6; + + getSphericalExtremaFromClippingExtrema( + this, + clippingMinimum, + clippingMaximum, + scratchSphericalMinima, + scratchSphericalMaxima + ); + const phiMinClipping = scratchSphericalMinima.x; + const phiMaxClipping = scratchSphericalMaxima.x; + const thetaMinClipping = scratchSphericalMinima.y; + const thetaMaxClipping = scratchSphericalMaxima.y; + const radiusMinClipping = scratchSphericalMinima.z; + const radiusMaxClipping = scratchSphericalMaxima.z; + + // convert to ellipsoid space. This simplifies analytical solutions since in ellipsoid space we are working with a sphere. + const ellipsoidRadiiLocal = this._ellipsoidOuterRadiiLocal; + const origin = Cartesian3.multiplyComponents( + ray.origin, + ellipsoidRadiiLocal, + new Cartesian3() + ); + let direction = Cartesian3.multiplyComponents( + ray.direction, + ellipsoidRadiiLocal, + new Cartesian3() + ); + direction = Cartesian3.normalize(direction, direction); + const rayEllipsoidSpace = new Ray(origin, direction); + + const a = Cartesian3.dot(direction, direction); + const b = Cartesian3.dot(origin, direction); + const originDot = Cartesian3.dot(origin, origin); + + let returnT = Number.MAX_VALUE; + + const tsOuter = findTsAtRadus( + radiusMaxClipping, + a, + b, + originDot, + scratchIntersectionTs + ); + + const ellipsoidLongitudeBounds = this._ellipsoidLongitudeBounds; + if ( + tsOuter.x >= 0.0 && + tIsWithinClippingPlanes( + tsOuter.x, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = tsOuter.x; + } + const tsInner = findTsAtRadus( + radiusMinClipping, + a, + b, + originDot, + scratchIntersectionTs + ); + if ( + tsInner.y >= 0.0 && + tIsWithinClippingPlanes( + tsInner.y, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tsInner.y); + } + + const tPhiMinClipping = findTAtPhi(phiMinClipping, rayEllipsoidSpace); + if ( + tPhiMinClipping >= 0 && + tIsWithinClippingPlanes( + tPhiMinClipping, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tPhiMinClipping); + } + const tPhiMaxClipping = findTAtPhi(phiMaxClipping, rayEllipsoidSpace); + if ( + tPhiMinClipping >= 0 && + tIsWithinClippingPlanes( + tPhiMaxClipping, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tPhiMaxClipping); + } + + if (phiMinClipping < phiMaxClipping) { + const tPhiMinAbsolute = findTAtPhi(this._phiMin, rayEllipsoidSpace); + if ( + tPhiMinClipping >= 0 && + tIsWithinClippingPlanes( + tPhiMinAbsolute, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tPhiMinAbsolute); + } + const tPhiMaxAbsolute = findTAtPhi(this._phiMax, rayEllipsoidSpace); + if ( + tPhiMinAbsolute >= 0 && + tIsWithinClippingPlanes( + tPhiMaxAbsolute, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tPhiMaxAbsolute); + } + } + + const tsThetaMin = findTAtTheta( + thetaMinClipping, + rayEllipsoidSpace, + scratchIntersectionTs + ); + if ( + tsThetaMin.x >= 0.0 && + tIsWithinClippingPlanes( + tsThetaMin.x, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tsThetaMin.x); + } + if ( + tsThetaMin.y >= 0.0 && + tIsWithinClippingPlanes( + tsThetaMin.y, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tsThetaMin.y); + } + const tsThetaMax = findTAtTheta( + thetaMaxClipping, + rayEllipsoidSpace, + scratchIntersectionTs + ); + if ( + tsThetaMax.x >= 0.0 && + tIsWithinClippingPlanes( + tsThetaMax.x, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tsThetaMax.x); + } + if ( + tsThetaMax.y >= 0.0 && + tIsWithinClippingPlanes( + tsThetaMax.y, + rayEllipsoidSpace, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ) + ) { + returnT = Math.min(returnT, tsThetaMax.y); + } + if (returnT === Number.MAX_VALUE) { + return -1.0; + } + + const intersection = Ray.getPoint(rayEllipsoidSpace, returnT); + // transfor point to non ellipsoid space + Cartesian3.divideComponents(intersection, ellipsoidRadiiLocal, intersection); + // get t for non ellipsoid space + let t; + if (ray.direction.x !== 0) { + t = (intersection.x - ray.origin.x) / ray.direction.x; + } else if (ray.direction.y !== 0) { + t = (intersection.y - ray.origin.y) / ray.direction.y; + } else if (ray.direction.z !== 0) { + t = (intersection.z - ray.origin.z) / ray.direction.z; + } + return t + epsilon; +}; + +function pointIsWithinClippingParameters( + point, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds +) { + const radius = Math.sqrt(Cartesian3.dot(point, point)); + let phi = Math.atan2(point.y, point.x); + if (phi < 0.0) { + phi += CesiumMath.TWO_PI; + } + let theta = Math.atan( + Math.abs(Math.sqrt(point.x * point.x + point.y * point.y) / point.z) + ); + if (point.z < 0) { + theta = CesiumMath.PI - theta; + } + + let absolutePhiMin = ellipsoidLongitudeBounds.x; + if (absolutePhiMin < 0.0) { + absolutePhiMin += CesiumMath.TWO_PI; + } + let absolutePhiMax = ellipsoidLongitudeBounds.y; + if (absolutePhiMax < 0.0) { + absolutePhiMax += CesiumMath.TWO_PI; + } + let withinAbsolutePhiBounds = phi >= absolutePhiMin && phi <= absolutePhiMax; + if (absolutePhiMin >= absolutePhiMax) { + withinAbsolutePhiBounds = phi >= absolutePhiMin || phi <= absolutePhiMax; + } + let withinPhiRange = phi >= phiMinClipping && phi <= phiMaxClipping; + if (phiMinClipping >= phiMaxClipping) { + // wrap around zero + withinPhiRange = phi >= phiMinClipping || phi <= phiMaxClipping; + } + return ( + radius >= radiusMinClipping && + radius <= radiusMaxClipping && + withinPhiRange && + withinAbsolutePhiBounds && + theta >= thetaMinClipping && + theta <= thetaMaxClipping + ); +} + +/** + * Takes the clipping minima and maxima and converts them to spherical minima and maxima + * (phi in radians, theta in radians, radius) for the ellipsoid + * @param {VoxelEllipsoidShape} that + * @param {Cartesian3} clippingMinimum The minimum values for shape parameters that the shader renders. Shape space [0, 1]. + * @param {Cartesian3} clippingMaximum The minimum values for shape parameters that the shader renders. Shape space [0, 1]. + * @param {Cartesian3} sphericalMinimum Result parameter. The minimum values in unit sphere space. (phi [0, 2pi], theta [0, pi], radius [0, inf]). + * @param {Cartesian3} sphericalMaximum Result parameter. The maximum values in unit sphere space. (phi [0, 2pi], theta [0, pi], radius [0, inf]). + * @private + */ +function getSphericalExtremaFromClippingExtrema( + that, + clippingMinimum, + clippingMaximum, + sphericalMinimum, + sphericalMaximum +) { + const rectangle = that._rectangle; + const phiWidth = rectangle.width; + let phiMin = that._phiMin + phiWidth * clippingMinimum.x; + if (phiMin >= CesiumMath.TWO_PI) { + // wrap around zero + phiMin -= CesiumMath.TWO_PI; + } + sphericalMinimum.x = phiMin; + let phiMax = that._phiMin + phiWidth * clippingMaximum.x; + if (phiMax >= CesiumMath.TWO_PI) { + // wrap around zero + phiMax -= CesiumMath.TWO_PI; + } + sphericalMaximum.x = phiMax; + + const thetaWidth = rectangle.height; + sphericalMinimum.y = that._thetaMin + thetaWidth * (1 - clippingMaximum.y); + sphericalMaximum.y = that._thetaMin + thetaWidth * (1 - clippingMinimum.y); + + const radiusWidth = that._ellipsoidHeightDifferenceUv; + sphericalMinimum.z = 1.0 + (clippingMinimum.z - 1.0) * radiusWidth; + sphericalMaximum.z = 1.0 + (clippingMaximum.z - 1.0) * radiusWidth; +} + +/** + * Get the ray parameter t of the intersection with a sphere of given radius + * @param {Number} radius The radius of the sphere you are intersecting with + * @param {Number} a The first coefficient of the quadratic equation that we are solving. This should be ray direction dot ray direction. + * @param {Number} b The second coefficient of the quadratic equation that we are solving. This should be ray direction dot ray origin. + * @param {Number} c The third coefficient of the quadratic equation that we are solving. This should be ray origin dot ray origin. + * @param {Cartesian2} tsAtRadius Return parameter. The first intersection will be stored in x while the second will be stored in y. + * @returns {Cartesian2} The return parameter tsAtRadius with the ts for the intersections in order first to second in x and y. + * @private + */ +function findTsAtRadus(radius, a, b, c, tsAtRadius) { + // no 2 in quadratic formula because it cancels out by taking 2 out of b + c -= radius * radius; + let discrim = b * b - a * c; + tsAtRadius.x = -1.0; + tsAtRadius.y = -1.0; + if (discrim >= 0.0) { + discrim = Math.sqrt(discrim); + tsAtRadius.x = (-b - discrim) / a; + tsAtRadius.y = (-b + discrim) / a; + } + return tsAtRadius; +} + +const epsilon = CesiumMath.EPSILON6; +function tIsWithinClippingPlanes( + t, + ray, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds +) { + const intersectionPoint = Ray.getPoint(ray, t + epsilon); + return pointIsWithinClippingParameters( + intersectionPoint, + radiusMinClipping, + radiusMaxClipping, + thetaMinClipping, + thetaMaxClipping, + phiMinClipping, + phiMaxClipping, + ellipsoidLongitudeBounds + ); +} + +/** + * Finds the ray parameter t for the intersection with a plane created by a constant phi and a ray + * @param {Number} phi The angle that your want to intersect with. [0, 2pi] + * @param {Ray} ray The ray you are intersecting + * @returns {Number} The ray parameter that of the intersection of the ray and the angle phi + * @private + */ +function findTAtPhi(phi, ray) { + // tan(phi) = y/x, solve for t + const tanPhi = Math.tan(phi); + const origin = ray.origin; + const numerator = tanPhi * origin.x - origin.y; + const direction = ray.direction; + const denominator = direction.y - tanPhi * direction.x; + return numerator / denominator; +} + +/** + * Finds the ray parameters t for the intersections with a ray and the cone created by a constant theta angle + * @param {Number} theta The theta angle that you want to intersect with. [0, pi] + * @param {Ray} ray The ray you are intersecting + * @param {Cartesian2} returnTs Return parameter. The first intersection will be stored in x while the second will be stored in y. + * @returns {Cartesian2} The return parameter tsAtRadius with the ts for the intersections in order first to second in x and y. + * @private + */ +function findTAtTheta(theta, ray, returnTs) { + const d = ray.direction; + const o = ray.origin; + if (theta === CesiumMath.PI_OVER_TWO) { + // intersect with z = 0 + const intersectionT = -o.z / d.z; + returnTs.x = intersectionT; + returnTs.y = intersectionT; + } else { + // tan(theta) = sqrt(x^2 + y^2) / z, solve for t + const tanTheta = Math.tan(theta); + const tan2Theta = tanTheta * tanTheta; + const a = d.x * d.x + d.y * d.y - tan2Theta * d.z * d.z; + const b = o.x * d.x + o.y * d.y - o.z * d.z * tan2Theta; + const c = o.x * o.x + o.y * o.y - o.z * o.z * tan2Theta; + let discrim = b * b - a * c; + if (discrim >= 0.0) { + discrim = Math.sqrt(discrim); + returnTs.x = (-b - discrim) / a; + returnTs.y = (-b + discrim) / a; + } + } + return returnTs; +} + +/** + * @type {Cartesian3} + * @private + */ +VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( + -CesiumMath.PI, + -CesiumMath.PI_OVER_TWO, + 0.0 +); + +/** + * @type {Cartesian3} + * @private + */ +VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( + +CesiumMath.PI, + +CesiumMath.PI_OVER_TWO, + 1.0 +); + +export default VoxelEllipsoidShape; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js new file mode 100644 index 00000000000..5742baf92bf --- /dev/null +++ b/Source/Scene/VoxelPrimitive.js @@ -0,0 +1,2695 @@ +import Cartesian2 from "../Core/Cartesian2.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import Cartesian4 from "../Core/Cartesian4.js"; +import CesiumMath from "../Core/Math.js"; +import Check from "../Core/Check.js"; +import Color from "../Core/Color.js"; +import defaultValue from "../Core/defaultValue.js"; +import defer from "../Core/defer.js"; +import defined from "../Core/defined.js"; +import destroyObject from "../Core/destroyObject.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import Event from "../Core/Event.js"; +import JulianDate from "../Core/JulianDate.js"; +import Matrix3 from "../Core/Matrix3.js"; +import Matrix4 from "../Core/Matrix4.js"; +import PrimitiveType from "../Core/PrimitiveType.js"; +import RenderState from "../Renderer/RenderState.js"; +import ShaderDestination from "../Renderer/ShaderDestination.js"; +import BlendingState from "./BlendingState.js"; +import CullFace from "./CullFace.js"; +import CustomShader from "./ModelExperimental/CustomShader.js"; +import CustomShaderPipelineStage from "./ModelExperimental/CustomShaderPipelineStage.js"; +import Material from "./Material.js"; +import PolylineCollection from "./PolylineCollection.js"; +import VoxelShapeType from "./VoxelShapeType.js"; +import VoxelTraversal from "./VoxelTraversal.js"; +import DrawCommand from "../Renderer/DrawCommand.js"; +import Pass from "../Renderer/Pass.js"; +import ShaderBuilder from "../Renderer/ShaderBuilder.js"; +// import VoxelFS from "../Shaders/VoxelFS.js"; +import VoxelFS_String from "./VoxelFS_String.js"; +import VoxelVS from "../Shaders/VoxelVS.js"; +import MetadataType from "./MetadataType.js"; +/** + * A primitive that renders voxel data from a {@link VoxelProvider}. + * + * TODO: make sure the following terms/definitions are consistent across all files + * world space: Cartesian WGS84 + * local space: Cartesian [-0.5, 0.5] aligned with shape. + * For box, the origin is the center of the box, and the six sides sit on the planes x = -0.5, x = 0.5 etc. + * For cylinder, the origin is the center of the cylinder with the cylinder enclosed by the [-0.5, 0.5] box on xy-plane. Positive x-axis points to theta = 0. The top and bottom caps sit at planes z = -0.5, z = 0.5. Positive y points to theta = pi/2 + * For ellipsoid, the origin is the center of the ellipsoid. The maximum height of the ellipsoid touches -0.5, 0.5 in xyz directions. + * intersection space: local space times 2 to be [-1, 1]. Used for ray intersection calculation + * UV space: local space plus 0.5 to be [0, 1]. + * shape space: In the coordinate system of the shape [0, 1] + * For box, this is the same as UV space + * For cylinder, the coordinate system is (radius, theta, z). theta = 0 is aligned with x axis + * For ellipsoid, the coordinate system is (longitude, latitude, height). where 0 is the minimum value in each dimension, and 1 is the max. + * + * @alias VoxelPrimitive + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {VoxelProvider} options.provider The voxel provider that supplies the primitive with tile data. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix used to transform the primitive. + * @param {CustomShader} [options.customShader] The custom shader used to style the primitive. + * @param {Clock} [options.clock] The clock used to control time dynamic behavior. + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * + * @see VoxelProvider + * @see Cesium3DTilesVoxelProvider + * @see GltfVoxelProvider + * @see VoxelShapeType + */ +function VoxelPrimitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + //>>includeStart('debug', pragmas.debug); + Check.defined("options.provider", options.provider); + //>>includeEnd('debug'); + + /** + * @type {Boolean} + * @private + */ + this._ready = false; + + /** + * @type {Promise.} + * @private + */ + this._readyPromise = defer(); + + /** + * @type {VoxelProvider} + * @private + */ + this._provider = options.provider; + + // If the provider fails to initialize the primitive will fail too. + const that = this; + this._provider.readyPromise.catch(function (error) { + that._readyPromise.reject(`provider failed with error:\n${error}`); + }); + + /** + * This member is not created until the provider and shape are ready. + * @type {VoxelTraversal} + * @private + */ + this._traversal = undefined; + + /** + * This member is not created until the provider is ready. + * @type {VoxelShape} + * @private + */ + this._shape = undefined; + + /** + * This member is not created until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._paddingBefore = new Cartesian3(); + + /** + * This member is not created until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._paddingAfter = new Cartesian3(); + + /** + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._minBounds = new Cartesian3(); + + /** + * Used to detect if the shape is dirty. + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._minBoundsOld = new Cartesian3(); + + /** + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._maxBounds = new Cartesian3(); + + /** + * Used to detect if the shape is dirty. + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._maxBoundsOld = new Cartesian3(); + + /** + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._minClippingBounds = new Cartesian3(); + + /** + * Used to detect if the clipping is dirty. + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._minClippingBoundsOld = new Cartesian3(); + + /** + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._maxClippingBounds = new Cartesian3(); + + /** + * Used to detect if the clipping is dirty. + * This member is not known until the provider is ready. + * @type {Cartesian3} + * @private + */ + this._maxClippingBoundsOld = new Cartesian3(); + + /** + * The primitive's model matrix + * @type {Matrix4} + * @private + */ + this._modelMatrix = defaultValue( + options.modelMatrix, + Matrix4.clone(Matrix4.IDENTITY, new Matrix4()) + ); + + /** + * The primitive's model matrix multiplied by the provider's model matrix. + * This member is not known until the provider is ready. + * @type {Matrix4} + * @private + */ + this._compoundModelMatrix = new Matrix4(); + + /** + * Used to detect if the shape is dirty. + * This member is not known until the provider is ready. + * @type {Matrix4} + * @private + */ + this._compoundModelMatrixOld = new Matrix4(); + + /** + * @type {CustomShader} + * @private + */ + this._customShader = defaultValue( + options.customShader, + VoxelPrimitive.DefaultCustomShader + ); + + /** + * @type {Event} + * @private + */ + this._customShaderCompilationEvent = new Event(); + + /** + * @type {Boolean} + * @private + */ + this._shaderDirty = true; + + /** + * @type {DrawCommand} + * @private + */ + this._drawCommand = undefined; + + /** + * @type {DrawCommand} + * @private + */ + this._drawCommandPick = undefined; + + /** + * @type {Object} + * @private + */ + this._pickId = undefined; + + // /** + // * @private + // * @type {TimeIntervalCollection} + // */ + // this._timeIntervalCollection = undefined; + + // /** + // * @private + // * @type {Clock} + // */ + // this._clock = options.clock; + + // /** + // * @private + // * @type {Number} + // */ + // this._keyframeCount = 1; + + // Transforms and other values that are computed when the shape changes + + /** + * @type {Matrix4} + */ + this._transformPositionWorldToUv = new Matrix4(); + + /** + * @type {Matrix4} + */ + this._transformPositionUvToWorld = new Matrix4(); + + /** + * @type {Matrix3} + */ + this._transformDirectionWorldToLocal = new Matrix3(); + + /** + * @type {Matrix3} + */ + this._transformNormalLocalToWorld = new Matrix3(); + + /** + * @type {Number} + */ + this._stepSizeUv = 1.0; + + // Rendering + this._jitter = true; + this._nearestSampling = false; + this._stepSizeMultiplier = 1.0; + this._despeckle = false; + this._depthTest = true; + this._useLogDepth = undefined; + this._screenSpaceError = 4.0; // in pixels + + // Debug / statistics + this._debugPolylines = new PolylineCollection(); + this._debugDraw = false; + this._disableRender = false; + this._disableUpdate = false; + + // Uniforms + this._uniformMapValues = { + /** + * @ignore + * @type {Texture} + */ + octreeInternalNodeTexture: undefined, + octreeInternalNodeTilesPerRow: 0, + octreeInternalNodeTexelSizeUv: new Cartesian2(), + /** + * @ignore + * @type {Texture} + */ + octreeLeafNodeTexture: undefined, + octreeLeafNodeTilesPerRow: 0, + octreeLeafNodeTexelSizeUv: new Cartesian2(), + /** + * @ignore + * @type {Texture[]} + */ + megatextureTextures: [], + megatextureSliceDimensions: new Cartesian2(), + megatextureTileDimensions: new Cartesian2(), + megatextureVoxelSizeUv: new Cartesian2(), + megatextureSliceSizeUv: new Cartesian2(), + megatextureTileSizeUv: new Cartesian2(), + dimensions: new Cartesian3(), + paddingBefore: new Cartesian3(), + paddingAfter: new Cartesian3(), + minimumValues: [], + maximumValues: [], + transformPositionViewToUv: new Matrix4(), + transformPositionUvToView: new Matrix4(), + transformDirectionViewToLocal: new Matrix3(), + transformNormalLocalToWorld: new Matrix3(), + cameraPositionUv: new Cartesian3(), + ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), + stepSize: 1.0, + ellipsoidHeightDifferenceUv: 1.0, + ellipsoidOuterRadiiLocal: new Cartesian3(), + ellipsoidInverseRadiiSquaredLocal: new Cartesian3(), + minBounds: new Cartesian3(), + maxBounds: new Cartesian3(), + minBoundsUv: new Cartesian3(), + maxBoundsUv: new Cartesian3(), + inverseBounds: new Cartesian3(), + inverseBoundsUv: new Cartesian3(), + minClippingBounds: new Cartesian3(), + maxClippingBounds: new Cartesian3(), + pickColor: new Color(), + }; + + // Automatically generate uniform map from the uniform values + /** + * @private + * @type {Object.} + */ + this._uniformMap = {}; + const uniformMapValues = this._uniformMapValues; + function getUniformFunction(key) { + return function () { + return uniformMapValues[key]; + }; + } + for (const key in uniformMapValues) { + if (uniformMapValues.hasOwnProperty(key)) { + this._uniformMap[`u_${key}`] = getUniformFunction(key); + } + } +} + +Object.defineProperties(VoxelPrimitive.prototype, { + /** + * Gets a value indicating whether or not the primitive is ready for use. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + * @readonly + */ + ready: { + get: function () { + return this._ready; + }, + }, + + /** + * Gets the promise that will be resolved when the primitive is ready for use. + * @memberof VoxelPrimitive.prototype + * @type {Promise.} + * @readonly + */ + readyPromise: { + get: function () { + return this._readyPromise.promise; + }, + }, + + /** + * Gets the {@link VoxelProvider} associated with this primitive. + * @type {VoxelProvider} + * @readonly + */ + provider: { + get: function () { + return this._provider; + }, + }, + + /** + * Gets the bounding sphere. + * @memberof VoxelPrimitive.prototype + * @type {BoundingSphere} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + boundingSphere: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "boundingSphere must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._shape.boundingSphere; + }, + }, + + /** + * Gets the oriented bounding box. + * @memberof VoxelPrimitive.prototype + * @type {OrientedBoundingBox} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + orientedBoundingBox: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "orientedBoudingBox must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._shape.orientedBoudingBox; + }, + }, + + /** + * @memberof VoxelPrimitive.prototype + * @type {Matrix4} + * @readonly + */ + modelMatrix: { + get: function () { + return this._modelMatrix; + }, + set: function (modelMatrix) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("modelMatrix", modelMatrix); + //>>includeEnd('debug'); + + this._modelMatrix = Matrix4.clone(modelMatrix, new Matrix4()); + }, + }, + + /** + * @memberof VoxelPrimitive.prototype + * @type {Matrix4} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + compoundModelMatrix: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "compoundModelMatrix must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._compoundModelMatrix; + }, + }, + + /** + * Gets the shape type. + * @memberof VoxelPrimitive.prototype + * @type {VoxelShapeType} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + shape: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "shape must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._provider.shape; + }, + }, + + /** + * @memberof VoxelPrimitive.prototype + * @type {Cartesian3} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + dimensions: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "dimensions must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._provider.dimensions; + }, + }, + + /** + * Gets the minimum value per channel of the voxel data. + * @memberof VoxelPrimitive.prototype + * @type {Number[]} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + minimumValues: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "minimumValues must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._provider.minimumValues; + }, + }, + + /** + * Gets the maximum value per channel of the voxel data. + * @memberof VoxelPrimitive.prototype + * @type {Number[]} + * @throws {DeveloperError} If the primitive is not ready. + * @readonly + */ + maximumValues: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "maximumValues must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._provider.maximumValues; + }, + }, + + /** + * Gets or sets whether or not this primitive should be displayed. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + show: { + get: function () { + return !this._disableRender; + }, + set: function (show) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("show", show); + //>>includeEnd('debug'); + + this._disableRender = !show; + }, + }, + + /** + * Gets or sets whether or not the primitive should update when the view changes. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + disableUpdate: { + get: function () { + return this._disableUpdate; + }, + set: function (disableUpdate) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("disableUpdate", disableUpdate); + //>>includeEnd('debug'); + + this._disableUpdate = disableUpdate; + }, + }, + + /** + * Gets or sets whether or not to render debug visualizations. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + debugDraw: { + get: function () { + return this._debugDraw; + }, + set: function (debugDraw) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("debugDraw", debugDraw); + //>>includeEnd('debug'); + + this._debugDraw = debugDraw; + }, + }, + + /** + * Gets or sets whether or not to test against depth when rendering. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + depthTest: { + get: function () { + return this._depthTest; + }, + set: function (depthTest) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("depthTest", depthTest); + //>>includeEnd('debug'); + + if (this._depthTest !== depthTest) { + this._depthTest = depthTest; + this._shaderDirty = true; + } + }, + }, + + /** + * Gets or sets whether or not to jitter the view ray during the raymarch. + * This reduces stair-step artifacts but introduces noise. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + jitter: { + get: function () { + return this._jitter; + }, + set: function (jitter) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("jitter", jitter); + //>>includeEnd('debug'); + + if (this._jitter !== jitter) { + this._jitter = jitter; + this._shaderDirty = true; + } + }, + }, + + /** + * + */ + nearestSampling: { + get: function () { + return this._nearestSampling; + }, + set: function (nearestSampling) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("nearestSampling", nearestSampling); + //>>includeEnd('debug'); + + if (this._nearestSampling !== nearestSampling) { + this._nearestSampling = nearestSampling; + this._shaderDirty = true; + } + }, + }, + + /** + * Gets or sets the screen space error in pixels. If the screen space size + * of a voxel is greater than the screen space error, the tile is subdivided. + * Lower screen space error corresponds with higher detail rendering, but could + * result in worse performance and higher memory consumption. + * @memberof VoxelPrimitive.prototype + * @type {Number} + */ + screenSpaceError: { + get: function () { + return this._screenSpaceError; + }, + set: function (screenSpaceError) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("screenSpaceError", screenSpaceError); + //>>includeEnd('debug'); + + this._screenSpaceError = screenSpaceError; + }, + }, + + /** + * Gets or sets the step size multiplier used during raymarching. + * The lower the value, the higher the rendering quality, but + * also the worse the performance. + * @memberof VoxelPrimitive.prototype + * @type {Number} + */ + stepSize: { + get: function () { + return this._stepSizeMultiplier; + }, + set: function (stepSize) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("stepSize", stepSize); + //>>includeEnd('debug'); + + this._stepSizeMultiplier = stepSize; + }, + }, + + /** + * Gets or sets whether to reduce thin and noisy details. + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + despeckle: { + get: function () { + return this._despeckle; + }, + set: function (despeckle) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("despeckle", despeckle); + //>>includeEnd('debug'); + + if (this._despeckle !== despeckle) { + this._despeckle = despeckle; + this._shaderDirty = true; + } + }, + }, + + /** + * Gets or sets the minimum bounds. TODO: fill in the rest later + * @memberof VoxelPrimitive.prototype + * @type {Cartesian3} + * @throws {DeveloperError} If the primitive is not ready. + */ + minBounds: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "minBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._minBounds; + }, + set: function (minBounds) { + //>>includeStart('debug', pragmas.debug); + Check.defined("minBounds", minBounds); + if (!this._ready) { + throw new DeveloperError( + "minBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + this._minBounds = Cartesian3.clone(minBounds, this._minBounds); + }, + }, + + /** + * Gets or sets the maximum bounds. TODO: fill in the rest later + * @memberof VoxelPrimitive.prototype + * @type {Cartesian3} + * @throws {DeveloperError} If the primitive is not ready. + */ + maxBounds: { + get: function () { + //>>includeStart('debug', pragmas.debug); + if (!this._ready) { + throw new DeveloperError( + "maxBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._maxBounds; + }, + set: function (maxBounds) { + //>>includeStart('debug', pragmas.debug); + Check.defined("maxBounds", maxBounds); + if (!this._ready) { + throw new DeveloperError( + "maxBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); + }, + }, + + /** + * Gets or sets the minimum clipping location in the shape's local coordinate system. + * Any voxel content outside the range is clipped. + * The minimum value is 0 and the maximum value is 1. + * @memberof VoxelPrimitive.prototype + * @type {Cartesian3} + * @throws {DeveloperError} If the primitive is not ready. + */ + minClippingBounds: { + get: function () { + //>>includeStart('debug', pragmas.debug) + if (!this._ready) { + throw new DeveloperError( + "minClippingBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._minClippingBounds; + }, + set: function (minClippingBounds) { + //>>includeStart('debug', pragmas.debug); + Check.defined("minClippingBounds", minClippingBounds); + if (!this._ready) { + throw new DeveloperError( + "minClippingBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + this._minClippingBounds = Cartesian3.clone( + minClippingBounds, + this._minClippingBounds + ); + }, + }, + + /** + * Gets or sets the maximum clipping location in the shape's local coordinate system. + * Any voxel content outside the range is clipped. + * The minimum value is 0 and the maximum value is 1. + * @memberof VoxelPrimitive.prototype + * @type {Cartesian3} + * @throws {DeveloperError} If the primitive is not ready. + */ + maxClippingBounds: { + get: function () { + //>>includeStart('debug', pragmas.debug) + if (!this._ready) { + throw new DeveloperError( + "maxClippingBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + return this._maxClippingBounds; + }, + set: function (maxClippingBounds) { + //>>includeStart('debug', pragmas.debug); + Check.defined("maxClippingBounds", maxClippingBounds); + if (!this._ready) { + throw new DeveloperError( + "maxClippingBounds must not be called before the primitive is ready." + ); + } + //>>includeEnd('debug'); + + this._maxClippingBounds = Cartesian3.clone( + maxClippingBounds, + this._maxClippingBounds + ); + }, + }, + + /** + * Gets or sets the custom shader. If undefined, {@link VoxelPrimitive.DefaultCustomShader} is set. + * @memberof VoxelPrimitive.prototype + * @type {CustomShader} + */ + customShader: { + get: function () { + return this._customShader; + }, + set: function (customShader) { + if (this._customShader !== customShader) { + if (!defined(customShader)) { + this._customShader = VoxelPrimitive.DefaultCustomShader; + } else { + this._customShader = customShader; + } + this._shaderDirty = true; + } + }, + }, + + /** + * Gets an event that is raised whenever a custom shader is compiled. + * @memberof VoxelPrimitive.prototype + * @type {Event} + * @readonly + */ + customShaderCompilationEvent: { + get: function () { + return this._customShaderCompilationEvent; + }, + }, +}); + +// TODO 3-channel + 1-channel metadata is a problem right now +// Individually, they both work, but together the 1-channel is messed up + +const scratchTotalDimensions = new Cartesian3(); +const scratchIntersect = new Cartesian4(); +const scratchNdcAabb = new Cartesian4(); +const scratchScale = new Cartesian3(); +const scratchLocalScale = new Cartesian3(); +const scratchInverseLocalScale = new Cartesian3(); +const scratchRotation = new Matrix3(); +const scratchInverseRotation = new Matrix3(); +const scratchRotationAndLocalScale = new Matrix3(); +const scratchTransformPositionWorldToLocal = new Matrix4(); +const scratchTransformPositionLocalToWorld = new Matrix4(); +const scratchTransformPositionLocalToProjection = new Matrix4(); + +const transformPositionLocalToUv = Matrix4.fromRotationTranslation( + Matrix3.fromUniformScale(0.5, new Matrix3()), + new Cartesian3(0.5, 0.5, 0.5), + new Matrix4() +); +const transformPositionUvToLocal = Matrix4.fromRotationTranslation( + Matrix3.fromUniformScale(2.0, new Matrix3()), + new Cartesian3(-1.0, -1.0, -1.0), + new Matrix4() +); + +/** + * @private + * @param {FrameState} frameState + */ +VoxelPrimitive.prototype.update = function (frameState) { + const context = frameState.context; + const provider = this._provider; + const uniforms = this._uniformMapValues; + + // Update the provider, if applicable. + if (defined(provider.update)) { + provider.update(frameState); + } + + // Exit early if it's not ready yet. + if (!this._ready && !provider.ready) { + return; + } + + // Initialize from the ready provider. This only happens once. + if (!this._ready) { + // Don't make the primitive ready until after its first update because + // external code may want to change some of its properties before it's rendered. + const that = this; + frameState.afterRender.push(function () { + that._ready = true; + that._readyPromise.resolve(that); + }); + + // Create pickId here instead of the constructor because it needs the context object. + this._pickId = context.createPickId({ + primitive: this, + }); + + // Set uniforms for picking + uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); + + // Set member variables that come from the provider. + + // const keyframeCount = defaultValue(provider.keyframeCount, 1); + // // TODO remove? + // that._keyframeCount = defaultValue( + // provider.keyframeCount, + // that._keyframeCount + // ); + // // TODO remove? + // that._timeIntervalCollection = defaultValue( + // provider.timeIntervalCollection, + // that._timeIntervalCollection + // ); + + const dimensions = provider.dimensions; + const shapeType = provider.shape; + const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); + const minBounds = defaultValue( + provider.minBounds, + ShapeConstructor.DefaultMinBounds + ); + const maxBounds = defaultValue( + provider.maxBounds, + ShapeConstructor.DefaultMaxBounds + ); + const minimumValues = provider.minimumValues; + const maximumValues = provider.maximumValues; + + this._shape = new ShapeConstructor(); + this._minBounds = Cartesian3.clone(minBounds, this._minBounds); + this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); + this._minClippingBounds = Cartesian3.clone( + ShapeConstructor.DefaultMinBounds, + this._minClippingBounds + ); + this._maxClippingBounds = Cartesian3.clone( + ShapeConstructor.DefaultMaxBounds, + this._maxClippingBounds + ); + this._paddingBefore = Cartesian3.clone( + defaultValue(provider.paddingBefore, Cartesian3.ZERO), + this._paddingBefore + ); + this._paddingAfter = Cartesian3.clone( + defaultValue(provider.paddingAfter, Cartesian3.ZERO), + this._paddingBefore + ); + + // Set uniforms that come from the provider. + // Note that minBounds and maxBounds can be set dynamically, so their uniforms aren't set here. + uniforms.dimensions = Cartesian3.clone(dimensions, uniforms.dimensions); + uniforms.paddingBefore = Cartesian3.clone( + this._paddingBefore, + uniforms.paddingBefore + ); + uniforms.paddingAfter = Cartesian3.clone( + this._paddingAfter, + uniforms.paddingAfter + ); + if (defined(minimumValues) && defined(maximumValues)) { + uniforms.minimumValues = minimumValues.slice(); + uniforms.maximumValues = maximumValues.slice(); + } + } + + // Check if the shape is dirty before updating it. This needs to happen every + // frame because the member variables can be modified externally via the + // getters. + const primitiveModelMatrix = this._modelMatrix; + const providerModelMatrix = defaultValue( + provider.modelMatrix, + Matrix4.IDENTITY + ); + const compoundModelMatrix = Matrix4.multiplyTransformation( + providerModelMatrix, + primitiveModelMatrix, + this._compoundModelMatrix + ); + const compoundModelMatrixOld = this._compoundModelMatrixOld; + const compoundModelMatrixDirty = !Matrix4.equals( + compoundModelMatrix, + compoundModelMatrixOld + ); + const shape = this._shape; + const shapeType = provider.shape; + + const minBounds = this._minBounds; + const maxBounds = this._maxBounds; + const minBoundsOld = this._minBoundsOld; + const maxBoundsOld = this._maxBoundsOld; + const minBoundsDirty = !Cartesian3.equals(minBounds, minBoundsOld); + const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); + const shapeIsDirty = + compoundModelMatrixDirty || minBoundsDirty || maxBoundsDirty; + + // Update the shape if dirty or the first frame. + if (!this._ready || shapeIsDirty) { + shape.update(compoundModelMatrix, minBounds, maxBounds); + + if (compoundModelMatrixDirty) { + this._compoundModelMatrixOld = Matrix4.clone( + compoundModelMatrix, + this._compoundModelMatrixOld + ); + } + + if (minBoundsDirty || maxBoundsDirty) { + const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); + const defaultMinBounds = ShapeConstructor.DefaultMinBounds; + const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + const isDefaultBoundsMinX = minBounds.x === defaultMinBounds.x; + const isDefaultBoundsMinY = minBounds.y === defaultMinBounds.y; + const isDefaultBoundsMinZ = minBounds.z === defaultMinBounds.z; + const isDefaultBoundsMaxX = maxBounds.x === defaultMaxBounds.x; + const isDefaultBoundsMaxY = maxBounds.y === defaultMaxBounds.y; + const isDefaultBoundsMaxZ = maxBounds.z === defaultMaxBounds.z; + + if (minBoundsDirty) { + const isDefaultOldBoundsMinX = minBoundsOld.x === defaultMinBounds.x; + const isDefaultOldBoundsMinY = minBoundsOld.y === defaultMinBounds.y; + const isDefaultOldBoundsMinZ = minBoundsOld.z === defaultMinBounds.z; + if ( + isDefaultBoundsMinX !== isDefaultOldBoundsMinX || + isDefaultBoundsMinY !== isDefaultOldBoundsMinY || + isDefaultBoundsMinZ !== isDefaultOldBoundsMinZ + ) { + this._shaderDirty = true; + } + this._minBoundsOld = Cartesian3.clone(minBounds, this._minBoundsOld); + } + + if (maxBoundsDirty) { + const isDefaultOldBoundsMaxX = maxBoundsOld.x === defaultMaxBounds.x; + const isDefaultOldBoundsMaxY = maxBoundsOld.y === defaultMaxBounds.y; + const isDefaultOldBoundsMaxZ = maxBoundsOld.z === defaultMaxBounds.z; + if ( + isDefaultBoundsMaxX !== isDefaultOldBoundsMaxX || + isDefaultBoundsMaxY !== isDefaultOldBoundsMaxY || + isDefaultBoundsMaxZ !== isDefaultOldBoundsMaxZ + ) { + this._shaderDirty = true; + } + this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); + } + + // Set uniforms for bounds. + if ( + !isDefaultBoundsMinX || + !isDefaultBoundsMinY || + !isDefaultBoundsMinZ || + !isDefaultBoundsMaxX || + !isDefaultBoundsMaxY || + !isDefaultBoundsMaxZ + ) { + uniforms.minBounds = Cartesian3.clone(minBounds, uniforms.minBounds); + uniforms.maxBounds = Cartesian3.clone(maxBounds, uniforms.maxBounds); + uniforms.inverseBounds = Cartesian3.divideComponents( + Cartesian3.ONE, + Cartesian3.subtract(maxBounds, minBounds, uniforms.inverseBounds), + uniforms.inverseBounds + ); + + if (shapeType === VoxelShapeType.BOX) { + const minXUv = minBounds.x * 0.5 + 0.5; + const maxXUv = maxBounds.x * 0.5 + 0.5; + const minYUv = minBounds.y * 0.5 + 0.5; + const maxYUv = maxBounds.y * 0.5 + 0.5; + const minZUv = minBounds.z * 0.5 + 0.5; + const maxZUv = maxBounds.z * 0.5 + 0.5; + uniforms.minBoundsUv = Cartesian3.fromElements( + minXUv, + minYUv, + minZUv, + uniforms.minBoundsUv + ); + uniforms.maxBoundsUv = Cartesian3.fromElements( + maxXUv, + maxYUv, + maxZUv, + uniforms.maxBoundsUv + ); + } else if (shapeType === VoxelShapeType.ELLIPSOID) { + uniforms.minBoundsUv = Cartesian3.clone( + minBounds, + uniforms.minBoundsUv + ); + uniforms.maxBoundsUv = Cartesian3.clone( + maxBounds, + uniforms.maxBoundsUv + ); + } else if (shapeType === VoxelShapeType.CYLINDER) { + const minRadiusUv = minBounds.x; + const maxRadiusUv = maxBounds.x; + const minHeightUv = minBounds.y * 0.5 + 0.5; + const maxHeightUv = maxBounds.y * 0.5 + 0.5; + const minAngleUv = (minBounds.z + CesiumMath.PI) / CesiumMath.TWO_PI; + const maxAngleUv = (maxBounds.z + CesiumMath.PI) / CesiumMath.TWO_PI; + uniforms.minBoundsUv = Cartesian3.fromElements( + minRadiusUv, + minHeightUv, + minAngleUv, + uniforms.minBoundsUv + ); + uniforms.maxBoundsUv = Cartesian3.fromElements( + maxRadiusUv, + maxHeightUv, + maxAngleUv, + uniforms.maxBoundsUv + ); + } + + uniforms.inverseBoundsUv = Cartesian3.divideComponents( + Cartesian3.ONE, + Cartesian3.subtract( + uniforms.maxBoundsUv, + uniforms.minBoundsUv, + uniforms.inverseBoundsUv + ), + uniforms.inverseBoundsUv + ); + } + } + + // Set other uniforms when the shape is dirty + if (shapeType === VoxelShapeType.ELLIPSOID) { + uniforms.ellipsoidHeightDifferenceUv = shape._ellipsoidHeightDifferenceUv; + uniforms.ellipsoidOuterRadiiLocal = Cartesian3.clone( + shape._ellipsoidOuterRadiiLocal, + uniforms.ellipsoidOuterRadiiLocal + ); + uniforms.ellipsoidInverseRadiiSquaredLocal = Cartesian3.multiplyComponents( + shape._ellipsoidOuterRadiiLocal, + shape._ellipsoidOuterRadiiLocal, + uniforms.ellipsoidInverseRadiiSquaredLocal + ); + } + + // Math that's only valid if the shape is visible. + if (shape.isVisible) { + const transformPositionLocalToWorld = shape.shapeTransform; + const transformPositionWorldToLocal = Matrix4.inverse( + transformPositionLocalToWorld, + scratchTransformPositionWorldToLocal + ); + const rotation = Matrix4.getRotation( + transformPositionLocalToWorld, + scratchRotation + ); + // Note that inverse(rotation) is the same as transpose(rotation) + const inverseRotation = Matrix3.transpose( + rotation, + scratchInverseRotation + ); + const scale = Matrix4.getScale( + transformPositionLocalToWorld, + scratchScale + ); + const maximumScaleComponent = Cartesian3.maximumComponent(scale); + const localScale = Cartesian3.divideByScalar( + scale, + maximumScaleComponent, + scratchLocalScale + ); + const inverseLocalScale = Cartesian3.divideComponents( + Cartesian3.ONE, + localScale, + scratchInverseLocalScale + ); + const rotationAndLocalScale = Matrix3.multiplyByScale( + rotation, + localScale, + scratchRotationAndLocalScale + ); + + // Set member variables when the shape is dirty + const dimensions = provider.dimensions; + this._stepSizeUv = shape.computeApproximateStepSize(dimensions); + this._transformPositionWorldToUv = Matrix4.multiply( + transformPositionLocalToUv, + transformPositionWorldToLocal, + this._transformPositionWorldToUv + ); + this._transformPositionUvToWorld = Matrix4.multiply( + transformPositionLocalToWorld, + transformPositionUvToLocal, + this._transformPositionUvToWorld + ); + this._transformDirectionWorldToLocal = Matrix3.setScale( + inverseRotation, + inverseLocalScale, + this._transformDirectionWorldToLocal + ); + this._transformNormalLocalToWorld = Matrix3.inverseTranspose( + rotationAndLocalScale, + this._transformNormalLocalToWorld + ); + } + } + + // Initialize the voxel traversal now that the shape is ready to use. This only happens once. + if (!this._ready) { + const dimensions = provider.dimensions; + const paddingBefore = this._paddingBefore; + const paddingAfter = this._paddingAfter; + const totalDimensions = Cartesian3.clone( + dimensions, + scratchTotalDimensions + ); + Cartesian3.add(totalDimensions, paddingBefore, totalDimensions); + Cartesian3.add(totalDimensions, paddingAfter, totalDimensions); + + const types = provider.types; + const componentTypes = provider.componentTypes; + const keyframeCount = 1; //this._keyframeCount; + + // Traversal setup + // It's ok for memory byte length to be undefined. + // The system will choose a default memory size. + const maximumTileCount = provider.maximumTileCount; + const maximumTextureMemoryByteLength = defined(maximumTileCount) + ? VoxelTraversal.getApproximateTextureMemoryByteLength( + maximumTileCount, + totalDimensions, + types, + componentTypes + ) + : undefined; + + this._traversal = new VoxelTraversal( + this, + context, + totalDimensions, + types, + componentTypes, + keyframeCount, + maximumTextureMemoryByteLength + ); + + // Set uniforms that come from the traversal. + const traversal = this._traversal; + + uniforms.octreeInternalNodeTexture = traversal.internalNodeTexture; + uniforms.octreeInternalNodeTilesPerRow = traversal.internalNodeTilesPerRow; + uniforms.octreeInternalNodeTexelSizeUv = traversal.internalNodeTexelSizeUv; + uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; + uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; + uniforms.octreeLeafNodeTexelSizeUv = traversal.leafNodeTexelSizeUv; + + uniforms.megatextureTextures = []; + const megatextures = traversal.megatextures; + const megatexture = megatextures[0]; + const megatextureLength = megatextures.length; + for (let i = 0; i < megatextureLength; i++) { + uniforms.megatextureTextures.push(megatextures[i].texture); + } + + uniforms.megatextureSliceDimensions = Cartesian2.clone( + megatexture.sliceCountPerRegion, + uniforms.megatextureSliceDimensions + ); + uniforms.megatextureTileDimensions = Cartesian2.clone( + megatexture.regionCountPerMegatexture, + uniforms.megatextureTileDimensions + ); + uniforms.megatextureVoxelSizeUv = Cartesian2.clone( + megatexture.voxelSizeUv, + uniforms.megatextureVoxelSizeUv + ); + uniforms.megatextureSliceSizeUv = Cartesian2.clone( + megatexture.sliceSizeUv, + uniforms.megatextureSliceSizeUv + ); + uniforms.megatextureTileSizeUv = Cartesian2.clone( + megatexture.regionSizeUv, + uniforms.megatextureTileSizeUv + ); + } else { + // Update the voxel traversal + const traversal = this._traversal; + if (shape.isVisible) { + // Find the keyframe location to render at. Doesn't need to be a whole number. + let keyframeLocation = 0.0; + const clock = this._clock; + const timeIntervalCollection = this._timeIntervalCollection; + if (defined(timeIntervalCollection) && defined(clock)) { + let date = clock.currentTime; + let timeInterval; + let timeIntervalIndex = timeIntervalCollection.indexOf(date); + if (timeIntervalIndex >= 0) { + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + } else { + // Date fell outside the range + timeIntervalIndex = ~timeIntervalIndex; + if (timeIntervalIndex === timeIntervalCollection.length) { + // Date past range + timeIntervalIndex = timeIntervalCollection.length - 1; + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.stop; + } else { + // Date before range + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.start; + } + } + + // De-lerp between the start and end of the interval + const totalSeconds = JulianDate.secondsDifference( + timeInterval.stop, + timeInterval.start + ); + const secondsDifferenceStart = JulianDate.secondsDifference( + date, + timeInterval.start + ); + const t = secondsDifferenceStart / totalSeconds; + keyframeLocation = timeIntervalIndex + t; + } + + traversal.update( + frameState, + keyframeLocation, + shapeIsDirty, // recomputeBoundingVolumes + this._disableUpdate // pauseUpdate + ); + } + + // Debug draw bounding boxes and other things. Must go after traversal update + // because that's what updates the tile bounding boxes. + if (this._debugDraw) { + debugDraw(this, frameState); + } + + const rootNodeLoaded = traversal.rootNode.isRenderable( + traversal.frameNumber + ); + + if (shape.isVisible && !this._disableRender && rootNodeLoaded) { + // Process clipping bounds. + const minClip = this._minClippingBounds; + const maxClip = this._maxClippingBounds; + const minClipOld = this._minClippingBoundsOld; + const maxClipOld = this._maxClippingBoundsOld; + const minClipDirty = !Cartesian3.equals(minClip, minClipOld); + const maxClipDirty = !Cartesian3.equals(maxClip, maxClipOld); + const clippingBoundsDirty = minClipDirty || maxClipDirty; + if (clippingBoundsDirty) { + const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); + const defaultMinBounds = ShapeConstructor.DefaultMinBounds; + const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + const isDefaultClippingBoundsMinX = minClip.x === defaultMinBounds.x; + const isDefaultClippingBoundsMinY = minClip.y === defaultMinBounds.y; + const isDefaultClippingBoundsMinZ = minClip.z === defaultMinBounds.z; + const isDefaultClippingBoundsMaxX = maxClip.x === defaultMaxBounds.x; + const isDefaultClippingBoundsMaxY = maxClip.y === defaultMaxBounds.y; + const isDefaultClippingBoundsMaxZ = maxClip.z === defaultMaxBounds.z; + + if (minClipDirty) { + const isDefaultOldClipMinX = minClipOld.x === defaultMinBounds.x; + const isDefaultOldClipMinY = minClipOld.y === defaultMinBounds.y; + const isDefaultOldClipMinZ = minClipOld.z === defaultMinBounds.z; + if ( + isDefaultClippingBoundsMinX !== isDefaultOldClipMinX || + isDefaultClippingBoundsMinY !== isDefaultOldClipMinY || + isDefaultClippingBoundsMinZ !== isDefaultOldClipMinZ + ) { + this._shaderDirty = true; + } + this._minClippingBoundsOld = Cartesian3.clone( + minClip, + this._minClippingBoundsOld + ); + } + if (maxClipDirty) { + const isDefaultOldClipMaxX = maxClipOld.x === defaultMaxBounds.x; + const isDefaultOldClipMaxY = maxClipOld.y === defaultMaxBounds.y; + const isDefaultOldClipMaxZ = maxClipOld.z === defaultMaxBounds.z; + if ( + isDefaultClippingBoundsMaxX !== isDefaultOldClipMaxX || + isDefaultClippingBoundsMaxY !== isDefaultOldClipMaxY || + isDefaultClippingBoundsMaxZ !== isDefaultOldClipMaxZ + ) { + this._shaderDirty = true; + } + this._maxClippingBoundsOld = Cartesian3.clone( + maxClip, + this._maxClippingBoundsOld + ); + } + if ( + !isDefaultClippingBoundsMinX || + !isDefaultClippingBoundsMinY || + !isDefaultClippingBoundsMinZ || + !isDefaultClippingBoundsMaxX || + !isDefaultClippingBoundsMaxY || + !isDefaultClippingBoundsMaxZ + ) { + // Set clipping uniforms + uniforms.minClippingBounds = Cartesian3.clone( + minClip, + uniforms.minClippingBounds + ); + uniforms.maxClippingBounds = Cartesian3.clone( + maxClip, + uniforms.maxClippingBounds + ); + } + } + + // Check if log depth changed + if (this._useLogDepth !== frameState.useLogDepth) { + this._useLogDepth = frameState.useLogDepth; + this._shaderDirty = true; + } + + // Rebuild shaders + if (this._shaderDirty) { + buildDrawCommands(this, context); + this._shaderDirty = false; + } + + // Calculate the NDC-space AABB to "scissor" the fullscreen quad + const transformPositionWorldToProjection = + context.uniformState.viewProjection; + const orientedBoundingBox = shape.orientedBoundingBox; + const ndcAabb = orientedBoundingBoxToNdcAabb( + orientedBoundingBox, + transformPositionWorldToProjection, + scratchNdcAabb + ); + + // If the object is offscreen, don't render it. + const offscreen = + ndcAabb.x === +1.0 || + ndcAabb.y === +1.0 || + ndcAabb.z === -1.0 || + ndcAabb.w === -1.0; + + if (!offscreen) { + const transformPositionWorldToView = context.uniformState.view; + const transformPositionViewToWorld = context.uniformState.inverseView; + const transformDirectionViewToWorld = + context.uniformState.inverseViewRotation; + const transformDirectionWorldToLocal = this + ._transformDirectionWorldToLocal; + const transformPositionUvToWorld = this._transformPositionUvToWorld; + const transformPositionWorldToUv = this._transformPositionWorldToUv; + const transformNormalLocalToWorld = this._transformNormalLocalToWorld; + const cameraPositionWorld = frameState.camera.positionWC; + + // Update uniforms that can change every frame + const uniforms = this._uniformMapValues; + uniforms.transformPositionViewToUv = Matrix4.multiply( + transformPositionWorldToUv, + transformPositionViewToWorld, + uniforms.transformPositionViewToUv + ); + uniforms.transformPositionUvToView = Matrix4.multiply( + transformPositionWorldToView, + transformPositionUvToWorld, + uniforms.transformPositionUvToView + ); + uniforms.transformDirectionViewToLocal = Matrix3.multiply( + transformDirectionWorldToLocal, + transformDirectionViewToWorld, + uniforms.transformDirectionViewToLocal + ); + uniforms.transformNormalLocalToWorld = Matrix3.clone( + transformNormalLocalToWorld, + uniforms.transformNormalLocalToWorld + ); + uniforms.cameraPositionUv = Matrix4.multiplyByPoint( + transformPositionWorldToUv, + cameraPositionWorld, + uniforms.cameraPositionUv + ); + uniforms.stepSize = this._stepSizeUv * this._stepSizeMultiplier; + + // Using a uniform instead of going through RenderState's scissor because the viewport is not accessible here, and the scissor command needs pixel coordinates. + uniforms.ndcSpaceAxisAlignedBoundingBox = Cartesian4.clone( + ndcAabb, + uniforms.ndcSpaceAxisAlignedBoundingBox + ); + + // Render the primitive + const command = frameState.passes.pick + ? this._drawCommandPick + : this._drawCommand; + command.boundingVolume = shape.boundingSphere; + frameState.commandList.push(command); + } + } + } +}; + +/** + * @param {VoxelPrimitive} that + * @param {Context} context + * @private + */ +function buildDrawCommands(that, context) { + // const renderResources + // CustomShaderPipelineStage.process(renderResources, primitive); + + // TODO: questions about custom shaders: + // - where should attribute min/max go? + // - should shader builder call `fromCache` or `replaceCache` + + // return; + + const provider = that._provider; + const shapeType = provider.shape; + const names = provider.names; + const types = provider.types; + const componentTypes = provider.componentTypes; + const depthTest = that._depthTest; + const useLogDepth = that._useLogDepth; + const paddingBefore = that.paddingBefore; + const paddingAfter = that.paddingAfter; + const minBounds = that._minBounds; + const maxBounds = that._maxBounds; + const minimumValues = provider.minimumValues; + const maximumValues = provider.maximumValues; + const minClippingBounds = that._minClippingBounds; + const maxClippingBounds = that._maxClippingBounds; + const keyframeCount = that._keyframeCount; + const despeckle = that._despeckle; + const jitter = that._jitter; + const nearestSampling = that._nearestSampling; + const customShader = that._customShader; + const attributeLength = types.length; + + // Vertex shader + + const shaderBuilder = new ShaderBuilder(); + shaderBuilder.addVertexLines([VoxelVS]); + + // Fragment shader + + const fragmentStructId = CustomShaderPipelineStage.STRUCT_ID_FRAGMENT_INPUT; + const fragmentStructName = + CustomShaderPipelineStage.STRUCT_NAME_FRAGMENT_INPUT; + + const attributeStructId = CustomShaderPipelineStage.STRUCT_ID_ATTRIBUTES_FS; + const attributeStructName = CustomShaderPipelineStage.STRUCT_NAME_ATTRIBUTES; + const attributeFieldName = "attributes"; + + const voxelStructId = "VoxelFS"; + const voxelStructName = "Voxel"; + const voxelFieldName = "voxel"; + + // Attribute struct + shaderBuilder.addStruct( + attributeStructId, + attributeStructName, + ShaderDestination.FRAGMENT + ); + + /** + * + * @param {MetadataType} type + */ + function getGlslType(type) { + if (type === MetadataType.SCALAR) { + return "float"; + } else if (type === MetadataType.VEC2) { + return "vec2"; + } else if (type === MetadataType.VEC3) { + return "vec3"; + } else if (type === MetadataType.VEC4) { + return "vec4"; + } + return "vec4"; + } + /** + * @param {MetadataType} type + */ + function getGlslTextureSwizzle(type) { + if (type === MetadataType.SCALAR) { + return ".r"; + } else if (type === MetadataType.VEC2) { + return ".ra"; + } else if (type === MetadataType.VEC3) { + return ".rgb"; + } else if (type === MetadataType.VEC4) { + return ""; + } + return ""; + } + + /** + * @param {MetadataType} type + * @param {Number} index + */ + function getGlslField(type, index) { + if (type === MetadataType.SCALAR) { + return ""; + } + return `.[${index}]`; + } + + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(attributeStructId, glslType, name); + } + + // Voxel struct + shaderBuilder.addStruct( + voxelStructId, + voxelStructName, + ShaderDestination.FRAGMENT + ); + + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(voxelStructId, glslType, `${name}Minimum`); + shaderBuilder.addStructField(voxelStructId, glslType, `${name}Maximum`); + shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalLocal`); + shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalWorld`); + shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalView`); + shaderBuilder.addStructField(voxelStructId, "bool", `${name}NormalValid`); + } + + shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvShapeSpace"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); + shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); + + // FragmentInput struct + shaderBuilder.addStruct( + fragmentStructId, + fragmentStructName, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addStructField( + fragmentStructId, + attributeStructName, + attributeFieldName + ); + + shaderBuilder.addStructField( + fragmentStructId, + voxelStructName, + voxelFieldName + ); + + // Custom shader + shaderBuilder.addFragmentLines([customShader.fragmentShaderText]); + + // Voxel shader + shaderBuilder.addFragmentLines(["#line 0", VoxelFS_String]); + shaderBuilder.addDefine( + "METADATA_COUNT", + attributeLength, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addUniform( + "sampler2D", + "u_megatextureTextures[METADATA_COUNT]", + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addDefine( + `SHAPE_${shapeType}`, + undefined, + ShaderDestination.FRAGMENT + ); + + if ( + !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || + !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) + ) { + shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); + } + + if (depthTest) { + shaderBuilder.addDefine( + "DEPTH_TEST", + undefined, + ShaderDestination.FRAGMENT + ); + } + + // Allow reading from log depth texture, but don't write log depth anywhere. + // Note: This needs to be set even if depthTest is off because it affects the + // derived command system. + if (useLogDepth) { + shaderBuilder.addDefine( + "LOG_DEPTH_READ_ONLY", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (jitter) { + shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); + } + + if (nearestSampling) { + shaderBuilder.addDefine( + "NEAREST_SAMPLING", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (despeckle) { + shaderBuilder.addDefine("DESPECKLE", undefined, ShaderDestination.FRAGMENT); + } + + const sampleCount = keyframeCount > 1 ? 2 : 1; + shaderBuilder.addDefine( + "SAMPLE_COUNT", + `${sampleCount}`, + ShaderDestination.FRAGMENT + ); + + const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); + const defaultMinBounds = ShapeConstructor.DefaultMinBounds; + const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + + const isDefaultMinX = minBounds.x === defaultMinBounds.x; + const isDefaultMinY = minBounds.y === defaultMinBounds.y; + const isDefaultMinZ = minBounds.z === defaultMinBounds.z; + const isDefaultMaxX = maxBounds.x === defaultMaxBounds.x; + const isDefaultMaxY = maxBounds.y === defaultMaxBounds.y; + const isDefaultMaxZ = maxBounds.z === defaultMaxBounds.z; + + if ( + !isDefaultMinX || + !isDefaultMinY || + !isDefaultMinZ || + !isDefaultMaxX || + !isDefaultMaxY || + !isDefaultMaxZ + ) { + shaderBuilder.addDefine("BOUNDS", undefined, ShaderDestination.FRAGMENT); + } + + if (!isDefaultMinX) { + shaderBuilder.addDefine( + "BOUNDS_0_MIN", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (!isDefaultMaxX) { + shaderBuilder.addDefine( + "BOUNDS_0_MAX", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (!isDefaultMinY) { + shaderBuilder.addDefine( + "BOUNDS_1_MIN", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (!isDefaultMaxY) { + shaderBuilder.addDefine( + "BOUNDS_1_MAX", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (!isDefaultMinZ) { + shaderBuilder.addDefine( + "BOUNDS_2_MIN", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (!isDefaultMaxZ) { + shaderBuilder.addDefine( + "BOUNDS_2_MAX", + undefined, + ShaderDestination.FRAGMENT + ); + } + + let intersectionCount = 0; + if (shapeType === VoxelShapeType.BOX) { + // A bounded box is still a box, so it has the same number of shape intersections: 1 + intersectionCount = 1; + } else if (shapeType === VoxelShapeType.ELLIPSOID) { + // Intersects an outer ellipsoid for the max radius + { + shaderBuilder.addDefine( + "BOUNDS_2_MAX_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects an inner ellipsoid for the min radius + if (!isDefaultMinZ) { + shaderBuilder.addDefine( + "BOUNDS_2_MIN_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects a cone for min latitude + if (!isDefaultMinY) { + shaderBuilder.addDefine( + "BOUNDS_1_MIN_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects a cone for max latitude + if (!isDefaultMaxY) { + shaderBuilder.addDefine( + "BOUNDS_1_MAX_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects a wedge for the min and max longitude + if (!isDefaultMinX || !isDefaultMaxX) { + shaderBuilder.addDefine( + "BOUNDS_0_MIN_MAX_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + } else if (shapeType === VoxelShapeType.CYLINDER) { + // Intersects a capped cylinder for the max radius + // The min and max height are handled as part of the capped cylinder intersection + { + shaderBuilder.addDefine( + "BOUNDS_0_MAX_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects an inner infinite cylinder for the min radius + if (!isDefaultMinX) { + shaderBuilder.addDefine( + "BOUNDS_0_MIN_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + + // Intersects a wedge for the min and max theta + if (!isDefaultMinZ || !isDefaultMaxZ) { + shaderBuilder.addDefine( + "BOUNDS_2_MIN_MAX_IDX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount++; + } + } + + // The intersection count is multiplied by 2 because there is an enter and exit for each intersection + shaderBuilder.addDefine( + "SHAPE_INTERSECTION_COUNT", + intersectionCount * 2, + ShaderDestination.FRAGMENT + ); + + if ( + minClippingBounds.x !== defaultMinBounds.x || + minClippingBounds.y !== defaultMinBounds.y || + minClippingBounds.z !== defaultMinBounds.z || + maxClippingBounds.x !== defaultMaxBounds.x || + maxClippingBounds.y !== defaultMaxBounds.y || + maxClippingBounds.z !== defaultMaxBounds.z + ) { + shaderBuilder.addDefine( + "CLIPPING_BOUNDS", + undefined, + ShaderDestination.FRAGMENT + ); + } + + // clearAttributes function + { + const clearAttributesFunctionId = "clearAttributes"; + const clearAttributesFunctionName = "clearAttributes"; + + shaderBuilder.addFunction( + clearAttributesFunctionId, + `${attributeStructName} ${clearAttributesFunctionName}()`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslType = getGlslType(type, componentType); + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `attributes.${name} = ${glslType}(0.0);`, + ]); + } + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // sumAttributes function + { + const sumAttributesFunctionId = "sumAttributes"; + const sumAttributesFunctionName = "sumAttributes"; + const sumAttributesFunctionDeclaration = `${attributeStructName} ${sumAttributesFunctionName}(${attributeStructName} attributesA, ${attributeStructName} attributesB)`; + + shaderBuilder.addFunction( + sumAttributesFunctionId, + sumAttributesFunctionDeclaration, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `${attributeFieldName}.${name} = attributesA.${name} + attributesB.${name};`, + ]); + } + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // mixAttributes + { + const mixAttributesFunctionId = "mixAttributes"; + const mixAttributesFunctionName = "mixAttributes"; + const mixAttributesFieldAttributesA = "attributesA"; + const mixAttributesFieldAttributesB = "attributesB"; + const mixAttributesFieldMixAmount = "mixFactor"; + shaderBuilder.addFunction( + mixAttributesFunctionId, + `${attributeStructName} ${mixAttributesFunctionName}(${attributeStructName} ${mixAttributesFieldAttributesA}, ${attributeStructName} ${mixAttributesFieldAttributesB}, float ${mixAttributesFieldMixAmount})`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `attributes.${name} = mix(${mixAttributesFieldAttributesA}.${name}, ${mixAttributesFieldAttributesB}.${name}, ${mixAttributesFieldMixAmount});`, + ]); + } + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // setMinMaxAttributes function + if (defined(minimumValues) && defined(maximumValues)) { + shaderBuilder.addDefine( + "HAS_MIN_MAX", + undefined, + ShaderDestination.FRAGMENT + ); + const minMaxAttributesFunctionId = "setMinMaxAttributes"; + const minMaxAttributesFunctionName = "setMinMaxAttributes"; + shaderBuilder.addFunction( + minMaxAttributesFunctionId, + `void ${minMaxAttributesFunctionName}(inout ${voxelStructName} ${voxelFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + for (let j = 0; j < componentCount; j++) { + const minimumValue = minimumValues[i][j]; + const maximumValue = maximumValues[i][j]; + + // glsl needs to have `.0` at the end of whole numbers floats. + let minimumValueString = minimumValue.toString(); + if (minimumValueString.indexOf(".") === -1) { + minimumValueString = `${minimumValue}.0`; + } + let maximumValueString = maximumValue.toString(); + if (maximumValueString.indexOf(".") === -1) { + maximumValueString = `${maximumValue}.0`; + } + + const glslField = getGlslField(type, j); + const minLine = `${voxelFieldName}.${name}Minimum${glslField} = ${minimumValueString};`; + const maxLine = `${voxelFieldName}.${name}Maximum${glslField} = ${maximumValueString};`; + shaderBuilder.addFunctionLines(minMaxAttributesFunctionId, [ + minLine, + maxLine, + ]); + } + } + } + + // for (i = 0; i < propertiesLength; i++) { + // property = properties[i]; + // type = property.type; + // name = property.name; + // channelCount = AttributeType.getNumberOfComponents(type); + // minValue = property.min; + // maxValue = property.max; + // sampleType = getStyleInputSampleType(property); + // sampleScale = getTypeScale(property); + + // const mins = []; + // const maxs = []; + + // if (channelCount === 1) { + // mins.push(`${sampleScale} * ${toTypedString(minValue, property)}`); + // maxs.push(`${sampleScale} * ${toTypedString(maxValue, property)}`); + // } else { + // mins.push(`${sampleScale} * ${toTypedString(minValue.x, property)}`); + // maxs.push(`${sampleScale} * ${toTypedString(maxValue.x, property)}`); + + // mins.push(`${sampleScale} * ${toTypedString(minValue.y, property)}`); + // maxs.push(`${sampleScale} * ${toTypedString(maxValue.y, property)}`); + + // if (channelCount >= 3) { + // mins.push(`${sampleScale} * ${toTypedString(minValue.z, property)}`); + // maxs.push(`${sampleScale} * ${toTypedString(maxValue.z, property)}`); + // } + // if (channelCount >= 4) { + // mins.push(`${sampleScale} * ${toTypedString(minValue.w, property)}`); + // maxs.push(`${sampleScale} * ${toTypedString(maxValue.w, property)}`); + // } + // } + + // const minVec = `${sampleType}(${mins.join(", ")})`; + // const maxVec = `${sampleType}(${maxs.join(", ")})`; + + // shaderBuilder.addFunctionLines("setMinMax", [ + // `styleInput.${name}Minimum = ${minVec};`, + // `styleInput.${name}Maximum = ${maxVec};`, + // ]); + // } + + // const styleShaderSource = primitive._styleMaterial.shaderSource; + // shaderBuilder.addDefine("STYLE_USE_NORMAL"); + // if (styleShaderSource.includes("styleInput.positionEC")) { + // shaderBuilder.addDefine("STYLE_USE_POSITION_EC"); + // } + // shaderBuilder.addFragmentLines([styleShaderSource]); + + // Generate shaders + shaderBuilder.setPositionAttribute("vec4", "a_position"); + + // // set normals + // const setNormalsArgs = [ + // `in vec3 normalLocal[${propertiesLength}]`, + // `in vec3 normalWorld[${propertiesLength}]`, + // `in vec3 normalView[${propertiesLength}]`, + // `in bool normalValid[${propertiesLength}]`, + // "inout StyleInput styleInput", + // ]; + + // const setNormalsSig = `void setStyleInputNormals(${setNormalsArgs.join( + // ", " + // )})`; + + // shaderBuilder.addFunction( + // "setNormals", + // setNormalsSig, + // ShaderDestination.FRAGMENT + // ); + + // for (i = 0; i < propertiesLength; i++) { + // property = properties[i]; + // name = property.name; + // shaderBuilder.addFunctionLines("setNormals", [ + // `styleInput.${name}NormalLocal` + ` = normalLocal[${i}];`, + // `styleInput.${name}NormalWorld` + ` = normalWorld[${i}];`, + // `styleInput.${name}NormalView` + ` = normalView[${i}];`, + // `styleInput.${name}NormalValid` + ` = normalValid[${i}];`, + // ]); + // } + + // // set samples + // const setSamplesFunctionId = "setSamples"; + // const setSamplesDefinition = `void setSamples(in vec4 samples[${attributeLength}], inout ${CustomShaderPipelineStage.STRUCT_NAME_ATTRIBUTES} ${attributesFieldName})`; + + // shaderBuilder.addFunction( + // setSamplesFunctionId, + // setSamplesDefinition, + // ShaderDestination.FRAGMENT + // ); + + // for (let i = 0; i < attributeLength; i++) { + // const name = names[i]; + // // const scaleVar = `scale_${name}`; + + // shaderBuilder.addFunctionLines(setSamplesFunctionId, [ + // // `vec4 ${scaleVar} = vec4(${sampleScale});`, + // // `attributes.${name} = ${sampleType}(${scaleVar} * samples[${i}]${swizzler});`, + // `${attributesFieldName}.${name} = `, + // ]); + // } + + // shaderBuilder.addFunction( + // "decodeSamples", + // "void decodeTextureSamples(inout vec4 samples[METADATA_COUNT])", + // ShaderDestination.FRAGMENT + // ); + + // shaderBuilder.addFunctionLines("decodeSamples", ["vec4 sample;"]); + + // for (i = 0; i < propertiesLength; i++) { + // property = properties[i]; + // type = property.type; + // channelCount = AttributeType.getNumberOfComponents(type); + + // shaderBuilder.addFunctionLines("decodeSamples", [ + // `sample = samples[${i}];`, + // ]); + + // if (!defined(channelCount) || channelCount === 1) { + // shaderBuilder.addFunctionLines("decodeSamples", [ + // "sample = vec4(1.0, 1.0, 1.0, sample.r);", + // ]); + // } else if (channelCount === 2) { + // shaderBuilder.addFunctionLines("decodeSamples", [ + // "sample = vec4(sample.r, sample.a, 1.0, 1.0);", + // ]); + // } + + // if (type === MetadataType.UINT8) { + // shaderBuilder.addFunctionLines("decodeSamples", [ + // `sample = mix(u_minimumValues[${i}], u_maximumValues[${i}], sample);`, + // ]); + // } + + // shaderBuilder.addFunctionLines("decodeSamples", [ + // `samples[${i}] = sample;`, + // ]); + // } + + // Looping over the sampler array was causing strange rendering artifacts even though the shader compiled fine. + // Unroling the for loop fixed the problem. + // for (int i = 0; i < METADATA_COUNT; i++) + // { + // vec4 value0 = texture2D(u_megatextureTextures[i], uv0); + // vec4 value1 = texture2D(u_megatextureTextures[i], uv1); + // samples[i] = mix(value0, value1, lerp); + // } + + const sampleFrom2DMegatextureId = "sampleFrom2DMegatextureAtUv"; + const sampleFrom2DMegatextureName = "sampleFrom2DMegatextureAtUv"; + shaderBuilder.addFunction( + sampleFrom2DMegatextureId, + `${attributeStructName} ${sampleFrom2DMegatextureName}(vec2 uv)`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `attributes.${name} = texture2D(u_megatextureTextures[${i}], uv)${glslTextureSwizzle};`, + ]); + } + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `return attributes;`, + ]); + + // shaderBuilder.addFunctionLines("sampleUv", [ + // "decodeTextureSamples(samples);", + // ]); + + // const voxelPrimitive = renderResources.model.voxelPrimitive; + // addRuntimeVoxelProperties(shaderBuilder, voxelPrimitive); + // // primitive.update(frameState); + const shaderBuilderPick = shaderBuilder.clone(); + shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); + + const shaderProgram = shaderBuilder.buildShaderProgram(context); + const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context); + + const renderState = RenderState.fromCache({ + cull: { + enabled: true, + face: CullFace.BACK, + }, + depthTest: { + enabled: false, + }, + depthMask: false, + blending: BlendingState.ALPHA_BLEND, + }); + + // var baseUniformMap = that._uniformMap; + // var uniformMap = combine(baseUniformMap, styleUniformMap); + const uniformMap = that._uniformMap; + + const viewportQuadVertexArray = context.getViewportQuadVertexArray(); + const drawCommand = new DrawCommand({ + vertexArray: viewportQuadVertexArray, + primitiveType: PrimitiveType.TRIANGLES, + renderState: renderState, + shaderProgram: shaderProgram, + uniformMap: uniformMap, + pass: Pass.VOXELS, + executeInClosestFrustum: true, + owner: this, + // boundingVolume: primitiveRenderResources.boundingSphere, + // modelMatrix: primitiveRenderResources.modelMatrix, + // debugShowBoundingVolume : true + }); + + const drawCommandPick = DrawCommand.shallowClone( + drawCommand, + new DrawCommand() + ); + drawCommandPick.shaderProgram = shaderProgramPick; + drawCommandPick.pickOnly = true; + + // Delete the old shader programs + if (defined(that._drawCommand)) { + const command = that._drawCommand; + command.shaderProgram = + command.shaderProgram && command.shaderProgram.destroy(); + } + if (defined(that._drawCommandPick)) { + const command = that._drawCommandPick; + command.shaderProgram = + command.shaderProgram && command.shaderProgram.destroy(); + } + + that._drawCommand = drawCommand; + that._drawCommandPick = drawCommandPick; + + console.log(drawCommand.shaderProgram._fragmentShaderText); +} + +/** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see VoxelPrimitive#destroy + */ +VoxelPrimitive.prototype.isDestroyed = function () { + return false; +}; + +/** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * voxelPrimitive = voxelPrimitive && voxelPrimitive.destroy(); + * + * @see VoxelPrimitive#isDestroyed + */ +VoxelPrimitive.prototype.destroy = function () { + const drawCommand = this._drawCommand; + if (defined(drawCommand)) { + drawCommand.shaderProgram = + drawCommand.shaderProgram && drawCommand.shaderProgram.destroy(); + } + const drawCommandPick = this._drawCommandPick; + if (defined(drawCommandPick)) { + drawCommandPick.shaderProgram = + drawCommandPick.shaderProgram && drawCommandPick.shaderProgram.destroy(); + } + + this._pickId = this._pickId && this._pickId.destroy(); + + if (defined(this._traversal)) { + const megatextures = this._traversal.megatextures; + const length = megatextures.length; + for (let i = 0; i < length; i++) { + const megatexture = megatextures[i]; + // TODO: when would megatexture not be defined? + if (defined(megatexture)) { + megatexture.destroy(); + } + } + this._traversal = undefined; + } + + // TODO: I assume the custom shader does not have to be destroyed + + return destroyObject(this); +}; + +VoxelPrimitive.prototype.queryMetadataAtCartographic = function ( + cartographic, + metadata +) { + return this._traversal.getMetadataAtCartographic(cartographic, metadata); +}; + +VoxelPrimitive.prototype.queryMetadataAtCartesian = function ( + cartesian, + metadata +) { + return this._traversal.getMetadataAtWorldCartesian(cartesian, metadata); +}; + +const corners = new Array( + new Cartesian4(-1.0, -1.0, -1.0, 1.0), + new Cartesian4(+1.0, -1.0, -1.0, 1.0), + new Cartesian4(-1.0, +1.0, -1.0, 1.0), + new Cartesian4(+1.0, +1.0, -1.0, 1.0), + new Cartesian4(-1.0, -1.0, +1.0, 1.0), + new Cartesian4(+1.0, -1.0, +1.0, 1.0), + new Cartesian4(-1.0, +1.0, +1.0, 1.0), + new Cartesian4(+1.0, +1.0, +1.0, 1.0) +); +const vertexNeighborIndices = new Array( + 1, + 2, + 4, + 0, + 3, + 5, + 0, + 3, + 6, + 1, + 2, + 7, + 0, + 5, + 6, + 1, + 4, + 7, + 2, + 4, + 7, + 3, + 5, + 6 +); + +const scratchCornersClipSpace = new Array( + new Cartesian4(), + new Cartesian4(), + new Cartesian4(), + new Cartesian4(), + new Cartesian4(), + new Cartesian4(), + new Cartesian4(), + new Cartesian4() +); + +/** + * Projects all 8 corners of the oriented bounding box to NDC space and finds the + * resulting NDC axis aligned bounding box. To avoid projecting a vertex that is + * behind the near plane, it uses the intersection point of each of the vertex's + * edges against the near plane as part of the AABB calculation. This is done in + * clip space prior to perspective division. + * + * @function + * @param {OrientedBoundingBox} orientedBoundingBox + * @param {Matrix4} worldToProjection + * @param {Cartesian4} result + * @returns {Cartesian4} + * + * @private + */ +function orientedBoundingBoxToNdcAabb( + orientedBoundingBox, + worldToProjection, + result +) { + const transformPositionLocalToWorld = Matrix4.fromRotationTranslation( + orientedBoundingBox.halfAxes, + orientedBoundingBox.center, + scratchTransformPositionLocalToWorld + ); + const transformPositionLocalToProjection = Matrix4.multiply( + worldToProjection, + transformPositionLocalToWorld, + scratchTransformPositionLocalToProjection + ); + + let ndcMinX = +Number.MAX_VALUE; + let ndcMaxX = -Number.MAX_VALUE; + let ndcMinY = +Number.MAX_VALUE; + let ndcMaxY = -Number.MAX_VALUE; + let cornerIndex; + + // Convert all points to clip space + const cornersClipSpace = scratchCornersClipSpace; + const cornersLength = corners.length; + for (cornerIndex = 0; cornerIndex < cornersLength; cornerIndex++) { + Matrix4.multiplyByVector( + transformPositionLocalToProjection, + corners[cornerIndex], + cornersClipSpace[cornerIndex] + ); + } + + for (cornerIndex = 0; cornerIndex < cornersLength; cornerIndex++) { + const position = cornersClipSpace[cornerIndex]; + if (position.z >= -position.w) { + // Position is past near plane, so there's no need to clip. + const ndcX = position.x / position.w; + const ndcY = position.y / position.w; + ndcMinX = Math.min(ndcMinX, ndcX); + ndcMaxX = Math.max(ndcMaxX, ndcX); + ndcMinY = Math.min(ndcMinY, ndcY); + ndcMaxY = Math.max(ndcMaxY, ndcY); + } else { + for (let neighborIndex = 0; neighborIndex < 3; neighborIndex++) { + const neighborVertexIndex = + vertexNeighborIndices[cornerIndex * 3 + neighborIndex]; + const neighborPosition = cornersClipSpace[neighborVertexIndex]; + if (neighborPosition.z >= -neighborPosition.w) { + // Position is behind the near plane and neighbor is after, so get intersection point on the near plane. + const distanceToPlaneFromPosition = position.z + position.w; + const distanceToPlaneFromNeighbor = + neighborPosition.z + neighborPosition.w; + const t = + distanceToPlaneFromPosition / + (distanceToPlaneFromPosition - distanceToPlaneFromNeighbor); + + const intersect = Cartesian4.lerp( + position, + neighborPosition, + t, + scratchIntersect + ); + const intersectNdcX = intersect.x / intersect.w; + const intersectNdcY = intersect.y / intersect.w; + ndcMinX = Math.min(ndcMinX, intersectNdcX); + ndcMaxX = Math.max(ndcMaxX, intersectNdcX); + ndcMinY = Math.min(ndcMinY, intersectNdcY); + ndcMaxY = Math.max(ndcMaxY, intersectNdcY); + } + } + } + } + + // Clamp the NDC values to -1 to +1 range even if they extend much further. + ndcMinX = CesiumMath.clamp(ndcMinX, -1.0, +1.0); + ndcMinY = CesiumMath.clamp(ndcMinY, -1.0, +1.0); + ndcMaxX = CesiumMath.clamp(ndcMaxX, -1.0, +1.0); + ndcMaxY = CesiumMath.clamp(ndcMaxY, -1.0, +1.0); + result = Cartesian4.fromElements(ndcMinX, ndcMinY, ndcMaxX, ndcMaxY, result); + + return result; +} + +const colorRed = new Color(1.0, 0.0, 0.0); +const colorGreen = new Color(0.0, 1.0, 0.0); +const colorBlue = new Color(0.0, 0.0, 1.0); + +const polylineAxisDistance = 30000000.0; +const polylineXAxis = new Cartesian3(polylineAxisDistance, 0.0, 0.0); +const polylineYAxis = new Cartesian3(0.0, polylineAxisDistance, 0.0); +const polylineZAxis = new Cartesian3(0.0, 0.0, polylineAxisDistance); + +/** + * @ignore + * @param {VoxelPrimitive} that + * @param {FrameState} frameState + */ +function debugDraw(that, frameState) { + const traversal = that._traversal; + const polylines = that._debugPolylines; + const shapeVisible = that._shape.isVisible; + polylines.removeAll(); + + function makePolylineLineSegment(startPos, endPos, color, thickness) { + polylines.add({ + positions: [startPos, endPos], + width: thickness, + material: Material.fromType("Color", { + color: color, + }), + }); + } + + function makePolylineBox(orientedBoundingBox, color, thickness) { + // Normally would want to use a scratch variable to store the corners, but + // polylines don't clone the positions. + const corners = orientedBoundingBox.computeCorners(); + makePolylineLineSegment(corners[0], corners[1], color, thickness); + makePolylineLineSegment(corners[2], corners[3], color, thickness); + makePolylineLineSegment(corners[4], corners[5], color, thickness); + makePolylineLineSegment(corners[6], corners[7], color, thickness); + makePolylineLineSegment(corners[0], corners[2], color, thickness); + makePolylineLineSegment(corners[4], corners[6], color, thickness); + makePolylineLineSegment(corners[1], corners[3], color, thickness); + makePolylineLineSegment(corners[5], corners[7], color, thickness); + makePolylineLineSegment(corners[0], corners[4], color, thickness); + makePolylineLineSegment(corners[2], corners[6], color, thickness); + makePolylineLineSegment(corners[1], corners[5], color, thickness); + makePolylineLineSegment(corners[3], corners[7], color, thickness); + } + + function drawTile(tile) { + const frameNumber = traversal.frameNumber; + if (!tile.isRenderable(frameNumber)) { + return; + } + + const level = tile.level; + const startThickness = 5.0; + const thickness = Math.max(1.0, startThickness / Math.pow(2.0, level)); + const colors = [colorRed, colorGreen, colorBlue]; + const color = colors[level % 3]; + + makePolylineBox(tile.orientedBoundingBox, color, thickness); + + if (defined(tile.children)) { + for (let i = 0; i < 8; i++) { + drawTile(tile.children[i]); + } + } + } + + if (shapeVisible) { + drawTile(traversal.rootNode); + } + + const axisThickness = 10.0; + makePolylineLineSegment( + Cartesian3.ZERO, + polylineXAxis, + colorRed, + axisThickness + ); + makePolylineLineSegment( + Cartesian3.ZERO, + polylineYAxis, + colorGreen, + axisThickness + ); + makePolylineLineSegment( + Cartesian3.ZERO, + polylineZAxis, + colorBlue, + axisThickness + ); + + polylines.update(frameState); +} + +/** + * The default custom shader used by the primitive. + * @private + * @type {CustomShader} + */ +VoxelPrimitive.DefaultCustomShader = new CustomShader({ + // TODO what should happen when lightingModel undefined? + // lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) +{ + material.diffuse = vec3(1.0); + material.alpha = 1.0; +}`, +}); + +export default VoxelPrimitive; diff --git a/Source/Scene/VoxelProvider.js b/Source/Scene/VoxelProvider.js new file mode 100644 index 00000000000..ece761b2dce --- /dev/null +++ b/Source/Scene/VoxelProvider.js @@ -0,0 +1,191 @@ +import DeveloperError from "../Core/DeveloperError.js"; + +/** + * Provides voxel data. Intended to be used with {@link VoxelPrimitive}. + * This type describes an interface and is not intended to be instantiated directly. + * + * @alias VoxelProvider + * @constructor + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * + * @see Cesium3DTilesVoxelProvider + * @see GltfVoxelProvider + * @see VoxelPrimitive + * @see VoxelShapeType + */ +function VoxelProvider() { + DeveloperError.throwInstantiationError(); +} + +Object.defineProperties(VoxelProvider.prototype, { + /** + * Gets a value indicating whether or not the provider is ready for use. + * @type {Boolean} + * @readonly + */ + ready: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the promise that will be resolved when the provider is ready for use. + * @type {Promise.} + * @readonly + */ + readyPromise: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * A model matrix that is applied to all tiles. If undefined, the identity matrix will be used instead. + * @type {Matrix4} + * @readonly + */ + modelMatrix: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the {@link VoxelShapeType} + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {VoxelShapeType} + * @readonly + */ + shape: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the minimum bounds. + * If undefined, the shape's default minimum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + minBounds: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the maximum bounds. + * If undefined, the shape's default maximum bounds will be used instead. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + maxBounds: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + dimensions: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + paddingBefore: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Cartesian3} + * @readonly + */ + paddingAfter: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the metadata names. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {String[]} + */ + names: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the metadata types + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {MetadataType[]} + */ + types: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the metadata component types + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {MetadataComponentType[]} + */ + componentTypes: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the metadata minimum values. + * @type {Number[]} + */ + minimumValues: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the metadata maximum values. + * @type {Number[]} + */ + maximumValues: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be undefined. + * This should not be called before {@link VoxelProvider#ready} returns true. + * @type {Number} + */ + maximumTileCount: { + get: DeveloperError.throwInstantiationError, + }, +}); + +/** + * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. + * If the provider doesn't need this functionality it should leave this function undefined. + * @function + * @param {FrameState} frameState + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; + +/** + * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. + * This function should not be called before {@link VoxelProvider#ready} returns true. + * @function + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.tileLevel=0] The tile's level. + * @param {Number} [options.tileX=0] The tile's X coordinate. + * @param {Number} [options.tileY=0] The tile's Y coordinate. + * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelProvider.prototype.requestData = DeveloperError.throwInstantiationError; + +export default VoxelProvider; diff --git a/Source/Scene/VoxelShape.js b/Source/Scene/VoxelShape.js new file mode 100644 index 00000000000..6588258a7db --- /dev/null +++ b/Source/Scene/VoxelShape.js @@ -0,0 +1,129 @@ +import DeveloperError from "../Core/DeveloperError.js"; + +/** + * Controls per-shape behavior for culling and rendering voxel grids. + * This type describes an interface and is not intended to be instantiated directly. + * + * @alias VoxelShape + * @constructor + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * + * @see VoxelBoxShape + * @see VoxelEllipsoidShape + * @see VoxelCylinderShape + * @see VoxelShapeType + */ +function VoxelShape() { + DeveloperError.throwInstantiationError(); +} + +Object.defineProperties(VoxelShape.prototype, { + /** + * An oriented bounding box containing the bounded shape. + * The update function must be called before accessing this value. + * @type {OrientedBoundingBox} + */ + orientedBoundingBox: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * A bounding sphere containing the bounded shape. + * The update function must be called before accessing this value. + * @type {BoundingSphere} + */ + boundingSphere: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * A transformation matrix containing the bounded shape. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + boundTransform: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * A transformation matrix containing the shape, ignoring the bounds. + * The update function must be called before accessing this value. + * @type {Matrix4} + */ + shapeTransform: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. + * The update function must be called before accessing this value. + * @type {Boolean} + */ + isVisible: { + get: DeveloperError.throwInstantiationError, + }, +}); + +/** + * Update the shape's state. + * @function + * @param {Matrix4} modelMatrix The model matrix. + * @param {Cartesian3} minBounds The minimum bounds. + * @param {Cartesian3} maxBounds The maximum bounds. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelShape.prototype.update = DeveloperError.throwInstantiationError; + +/** + * Computes an oriented bounding box for a specified tile. + * The update function must be called before calling this function. + * @function + * @param {Number} tileLevel The tile's level. + * @param {Number} tileX The tile's x coordinate. + * @param {Number} tileY The tile's y coordinate. + * @param {Number} tileZ The tile's z coordinate. + * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile. + * @returns {OrientedBoundingBox} The oriented bounding box. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelShape.prototype.computeOrientedBoundingBoxForTile = + DeveloperError.throwInstantiationError; + +/** + * Computes an approximate step size for raymarching the root tile of a voxel grid. + * The update function must be called before calling this function. + * @function + * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. + * @returns {Number} The step size. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelShape.prototype.computeApproximateStepSize = + DeveloperError.throwInstantiationError; + +/** + * Defines the minimum bounds of the shape. This can vary per-shape. + * @type {Cartesian3} + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelShape.DefaultMinBounds = DeveloperError.throwInstantiationError; + +/** + * Defines the maximum bounds of the shape. This can vary per-shape. + * @type {Cartesian3} + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +VoxelShape.DefaultMaxBounds = DeveloperError.throwInstantiationError; + +export default VoxelShape; diff --git a/Source/Scene/VoxelShapeType.js b/Source/Scene/VoxelShapeType.js new file mode 100644 index 00000000000..8b0c4f6a515 --- /dev/null +++ b/Source/Scene/VoxelShapeType.js @@ -0,0 +1,90 @@ +import DeveloperError from "../Core/DeveloperError.js"; +import PrimitiveType from "../Core/PrimitiveType.js"; +import VoxelBoxShape from "./VoxelBoxShape.js"; +import VoxelCylinderShape from "./VoxelCylinderShape.js"; +import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; + +/** + * An enum of voxel shapes. The shape controls how the voxel grid is mapped to + * 3D space. + * + * @enum VoxelShapeType + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * @see VoxelShape + * @see VoxelBoxShape + * @see VoxelEllipsoidShape + * @see VoxelCylinderShape + */ +const VoxelShapeType = { + /** + * A box shape. + * + * @type {String} + * @constant + * @private + */ + BOX: "BOX", + /** + * An ellipsoid shape. + * + * @type {String} + * @constant + * @private + */ + ELLIPSOID: "ELLIPSOID", + /** + * A cylinder shape. + * + * @type {String} + * @constant + * @private + */ + CYLINDER: "CYLINDER", +}; + +/** + * Converts a primitive type to a voxel shape. glTF voxel primitive types are + * defined in EXT_primitive_voxels. + * @param {PrimitiveType} primitiveType The primitive type. + * @returns {VoxelShapeType} The shape type. + * @private + */ +VoxelShapeType.fromPrimitiveType = function (primitiveType) { + switch (primitiveType) { + case PrimitiveType.VOXEL_BOX: + return VoxelShapeType.BOX; + case PrimitiveType.VOXEL_CYLINDER: + return VoxelShapeType.CYLINDER; + case PrimitiveType.VOXEL_ELLIPSOID: + return VoxelShapeType.ELLIPSOID; + //>>includeStart('debug', pragmas.debug); + default: + throw new DeveloperError(`Invalid primitive type ${primitiveType}`); + //>>includeEnd('debug'); + } +}; + +/** + * Converts a shape type to a constructor that can be used to create a shape + * object or get per-shape properties like DefaultMinBounds and + * DefaultMaxBounds. + * @param {VoxelShapeType} shapeType The shape type. + * @returns {Function} The shape's constructor. + * @private + */ +VoxelShapeType.toShapeConstructor = function (shapeType) { + switch (shapeType) { + case VoxelShapeType.BOX: + return VoxelBoxShape; + case VoxelShapeType.CYLINDER: + return VoxelCylinderShape; + case VoxelShapeType.ELLIPSOID: + return VoxelEllipsoidShape; + //>>includeStart('debug', pragmas.debug); + default: + throw new DeveloperError(`Invalid shape type ${shapeType}`); + //>>includeEnd('debug'); + } +}; + +export default Object.freeze(VoxelShapeType); diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js new file mode 100644 index 00000000000..320b75538ad --- /dev/null +++ b/Source/Scene/VoxelTraversal.js @@ -0,0 +1,2020 @@ +import binarySearch from "../Core/binarySearch.js"; +import Cartesian2 from "../Core/Cartesian2.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import CesiumMath from "../Core/Math.js"; +import CullingVolume from "../Core/CullingVolume.js"; +import defaultValue from "../Core/defaultValue.js"; +import defined from "../Core/defined.js"; +import destroyObject from "../Core/destroyObject.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; +import getTimestamp from "../Core/getTimestamp.js"; +import Matrix3 from "../Core/Matrix3.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; +import PixelFormat from "../Core/PixelFormat.js"; +import RuntimeError from "../Core/RuntimeError.js"; +import ContextLimits from "../Renderer/ContextLimits.js"; +import PixelDatatype from "../Renderer/PixelDatatype.js"; +import Sampler from "../Renderer/Sampler.js"; +import Texture from "../Renderer/Texture.js"; +import TextureWrap from "../Renderer/TextureWrap.js"; +import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js"; +import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; +import MetadataType from "./MetadataType.js"; +import MetadataComponentType from "./MetadataComponentType.js"; + +/** + * Handles tileset traversal, tile requests, and GPU resources. Intended to be + * private and paired with a {@link VoxelPrimitive}, which has a user-facing API. + * @alias VoxelTraversal + * @constructor + * + * @param {VoxelPrimitive} primitive + * @param {Context} context + * @param {Cartesian3} dimensions + * @param {MetadataType[]} types + * @param {MetadataComponentType[]} componentTypes + * @param {Number} keyframeCount + * @param {Number} [maximumTextureMemoryByteLength] + * + * @private + */ +function VoxelTraversal( + primitive, + context, + dimensions, + types, + componentTypes, + keyframeCount, + maximumTextureMemoryByteLength +) { + /** + * @private + * @type {VoxelPrimitive} + */ + this.primitive = primitive; + + const length = types.length; + + /** + * @private + * @type {Megatexture[]} + */ + this.megatextures = new Array(length); + + // TODO make sure to split the maximumTextureMemoryByteLength across all the megatextures + for (let i = 0; i < length; i++) { + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + const componentType = componentTypes[i]; + + this.megatextures[i] = new Megatexture( + context, + dimensions, + componentCount, + componentType, + maximumTextureMemoryByteLength + ); + } + + const maximumTileCount = this.megatextures[0].maximumTileCount; + + /** + * @private + * @type {Number} + */ + this.simultaneousRequestCount = 0; + + /** + * @private + * @type {Boolean} + */ + this.debugPrint = false; + + const shape = primitive._shape; + const rootLevel = 0; + const rootX = 0; + const rootY = 0; + const rootZ = 0; + const rootParent = undefined; + + /** + * @private + * @type {SpatialNode} + */ + this.rootNode = new SpatialNode( + rootLevel, + rootX, + rootY, + rootZ, + rootParent, + shape, + dimensions + ); + + /** + * @private + * @type {DoubleEndedPriorityQueue} + */ + this.priorityQueue = new DoubleEndedPriorityQueue({ + maximumLength: maximumTileCount, + comparator: KeyframeNode.priorityComparator, + }); + + /** + * @private + * @type {KeyframeNode[]} + */ + this.highPriorityKeyframeNodes = new Array(maximumTileCount); + + /** + * @private + * @type {KeyframeNode[]} + */ + this.keyframeNodesInMegatexture = new Array(maximumTileCount); + + /** + * @private + * @type {Number} + */ + this.keyframeCount = keyframeCount; + + /** + * @private + * @type {Number} + */ + this.keyframeLocation = 0; + + /** + * @private + * @type {Number} + */ + this.frameNumber = -1; + + function binaryTreeWeightingRecursive(arr, start, end, depth) { + if (start > end) { + return; + } + const mid = Math.floor((start + end) / 2); + arr[mid] = depth; + binaryTreeWeightingRecursive(arr, start, mid - 1, depth + 1); + binaryTreeWeightingRecursive(arr, mid + 1, end, depth + 1); + } + this.binaryTreeKeyframeWeighting = new Array(keyframeCount); + this.binaryTreeKeyframeWeighting[0] = 0; + this.binaryTreeKeyframeWeighting[keyframeCount - 1] = 0; + binaryTreeWeightingRecursive( + this.binaryTreeKeyframeWeighting, + 1, + keyframeCount - 2, + 0 + ); + + const internalNodeTexelCount = 9; + const internalNodeTextureDimensionX = 1024; + const internalNodeTilesPerRow = Math.floor( + internalNodeTextureDimensionX / internalNodeTexelCount + ); + const internalNodeTextureDimensionY = Math.ceil( + maximumTileCount / internalNodeTilesPerRow + ); + + this.internalNodeTexture = new Texture({ + context: context, + pixelFormat: PixelFormat.RGBA, + pixelDatatype: PixelDatatype.UNSIGNED_BYTE, + flipY: false, + width: internalNodeTextureDimensionX, + height: internalNodeTextureDimensionY, + sampler: new Sampler({ + minificationFilter: TextureMinificationFilter.NEAREST, + magnificationFilter: TextureMagnificationFilter.NEAREST, + }), + }); + this.internalNodeTexelSizeUv = new Cartesian2( + 1.0 / internalNodeTextureDimensionX, + 1.0 / internalNodeTextureDimensionY + ); + this.internalNodeTilesPerRow = internalNodeTilesPerRow; + + this.useLeafNodeTexture = keyframeCount > 1; + if (this.useLeafNodeTexture) { + const leafNodeTexelCount = 2; + const leafNodeTextureDimensionX = 1024; + const leafNodeTilesPerRow = Math.floor( + leafNodeTextureDimensionX / leafNodeTexelCount + ); + const leafNodeTextureDimensionY = Math.ceil( + maximumTileCount / leafNodeTilesPerRow + ); + + this.leafNodeTexture = new Texture({ + context: context, + pixelFormat: PixelFormat.RGBA, + pixelDatatype: PixelDatatype.UNSIGNED_BYTE, + flipY: false, + width: leafNodeTextureDimensionX, + height: leafNodeTextureDimensionY, + sampler: new Sampler({ + minificationFilter: TextureMinificationFilter.NEAREST, + magnificationFilter: TextureMagnificationFilter.NEAREST, + }), + }); + this.leafNodeTexelSizeUv = new Cartesian2( + 1.0 / leafNodeTextureDimensionX, + 1.0 / leafNodeTextureDimensionY + ); + this.leafNodeTilesPerRow = leafNodeTilesPerRow; + } else { + this.leafNodeTexture = undefined; + this.leafNodeTexelSizeUv = undefined; + this.leafNodeTilesPerRow = undefined; + } +} + +VoxelTraversal.simultaneousRequestCountMaximum = 50; + +/** + * @private + * @param {FrameState} frameState + * @param {Number} keyframeLocation + * @param {Boolean} recomputeBoundingVolumes + * @param {Boolean} pauseUpdate + */ +VoxelTraversal.prototype.update = function ( + frameState, + keyframeLocation, + recomputeBoundingVolumes, + pauseUpdate +) { + const that = this; + + const keyframeCount = that.keyframeCount; + that.keyframeLocation = CesiumMath.clamp( + keyframeLocation, + 0.0, + keyframeCount - 1 + ); + + if (recomputeBoundingVolumes) { + recomputeBoundingVolumesRecursive(that, that.rootNode); + } + + if (!pauseUpdate) { + that.frameNumber = frameState.frameNumber; + + const timestamp0 = getTimestamp(); + loadAndUnload(that, frameState); + const timestamp1 = getTimestamp(); + generateOctree(that); + const timestamp2 = getTimestamp(); + + const debugStatistics = that.debugPrint; + if (debugStatistics) { + const loadAndUnloadTimeMs = timestamp1 - timestamp0; + const generateOctreeTimeMs = timestamp2 - timestamp1; + const totalTimeMs = timestamp2 - timestamp0; + printDebugInformation( + that, + loadAndUnloadTimeMs, + generateOctreeTimeMs, + totalTimeMs + ); + } + } +}; + +/** + * @ignore + * @param {VoxelTraversal} that + * @param {SpatialNode} node + */ +function recomputeBoundingVolumesRecursive(that, node) { + const shape = that.primitive._shape; + const dimensions = that.primitive._provider.dimensions; + node.computeBoundingVolumes(shape, dimensions); + if (defined(node.children)) { + for (let i = 0; i < 8; i++) { + const child = node.children[i]; + recomputeBoundingVolumesRecursive(that, child); + } + } +} + +/** + * Call requestData for each metadata + * @ignore + * @param {VoxelTraversal} that + * @param {KeyframeNode} keyframeNode + */ +function requestTiles(that, keyframeNode) { + const keys = Object.keys(that.megatextures); + const length = keys.length; + for (let i = 0; i < length; i++) { + const metadataName = keys[i]; + requestData(that, keyframeNode, metadataName); + } +} +/** + * @ignore + * @param {VoxelTraversal} that + * @param {KeyframeNode} keyframeNode + * @param {String} metadataName + */ +function requestData(that, keyframeNode, metadataName) { + if ( + that.simultaneousRequestCount >= + VoxelTraversal.simultaneousRequestCountMaximum + ) { + return; + } + + const primitive = that.primitive; + const provider = primitive._provider; + const keyframe = keyframeNode.keyframe; + const spatialNode = keyframeNode.spatialNode; + const tileLevel = spatialNode.level; + const tileX = spatialNode.x; + const tileY = spatialNode.y; + const tileZ = spatialNode.z; + + const postRequestSuccess = function (result) { + that.simultaneousRequestCount--; + const length = primitive._provider.types.length; + + if (!defined(result)) { + keyframeNode.state = VoxelTraversal.LoadState.UNAVAILABLE; + } else if (result === VoxelTraversal.LoadState.FAILED) { + keyframeNode.state = VoxelTraversal.LoadState.FAILED; + } else if (!Array.isArray(result) || result.length !== length) { + // TODO should this throw runtime error? + keyframeNode.state = VoxelTraversal.LoadState.FAILED; + } else { + const megatextures = that.megatextures; + for (let i = 0; i < length; i++) { + const megatexture = megatextures[i]; + const tileVoxelCount = + megatexture.voxelCountPerTile.x * + megatexture.voxelCountPerTile.y * + megatexture.voxelCountPerTile.z; + + const data = result[i]; + const expectedLength = tileVoxelCount * megatexture.channelCount; + if (data.length === expectedLength) { + keyframeNode.metadatas[i] = data; + // State is received only when all metadata requests have been received + keyframeNode.state = VoxelTraversal.LoadState.RECEIVED; + } else { + keyframeNode.state = VoxelTraversal.LoadState.FAILED; + break; + } + } + } + }; + + const postRequestFailure = function () { + that.simultaneousRequestCount--; + keyframeNode.state = VoxelTraversal.LoadState.FAILED; + }; + + const promise = provider.requestData({ + tileLevel: tileLevel, + tileX: tileX, + tileY: tileY, + tileZ: tileZ, + keyframe: keyframe, + metadataName: metadataName, + }); + + if (defined(promise)) { + that.simultaneousRequestCount++; + keyframeNode.state = VoxelTraversal.LoadState.RECEIVING; + promise.then(postRequestSuccess).catch(postRequestFailure); + } else { + keyframeNode.state = VoxelTraversal.LoadState.FAILED; + } +} + +/** + * @ignore + * @param {Number} x + * @returns {Number} + */ +function mapInfiniteRangeToZeroOne(x) { + return x / (1.0 + x); +} + +/** + * @ignore + * @param {VoxelTraversal} that + * @param {FrameState} frameState + */ +function loadAndUnload(that, frameState) { + const frameNumber = that.frameNumber; + const primitive = that.primitive; + const shape = primitive._shape; + const voxelDimensions = primitive._provider.dimensions; + const targetScreenSpaceError = primitive._screenSpaceError; + const priorityQueue = that.priorityQueue; + const keyframeLocation = that.keyframeLocation; + const keyframeCount = that.keyframeCount; + const rootNode = that.rootNode; + + const cameraPosition = frameState.camera.positionWC; + const screenSpaceErrorDenominator = frameState.camera.frustum.sseDenominator; + const screenHeight = + frameState.context.drawingBufferHeight / frameState.pixelRatio; + const screenSpaceErrorMultiplier = screenHeight / screenSpaceErrorDenominator; + + /** + * @ignore + * @param {SpatialNode} spatialNode + * @param {Number} visibilityPlaneMask + */ + function addToQueueRecursive(spatialNode, visibilityPlaneMask) { + spatialNode.computeScreenSpaceError( + cameraPosition, + screenSpaceErrorMultiplier + ); + + visibilityPlaneMask = spatialNode.visibility( + frameState, + visibilityPlaneMask + ); + if (visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) { + return; + } + spatialNode.visitedFrameNumber = frameNumber; + + const previousKeyframe = CesiumMath.clamp( + Math.floor(keyframeLocation), + 0, + keyframeCount - 2 + ); + const nextKeyframe = previousKeyframe + 1; + + // Create keyframe nodes at the playhead. + // If they already exist, nothing will be created. + if (keyframeCount === 1) { + spatialNode.createKeyframeNode(0); + } else { + // // Always keep two keyframes loaded even if the playhead is directly on a keyframe. + // spatialNode.createKeyframeNode(previousKeyframe); + // spatialNode.createKeyframeNode(nextKeyframe); + + // Create all keyframes + // eslint-disable-next-line no-lonely-if + if (spatialNode.keyframeNodes.length !== keyframeCount) { + for (let k = 0; k < keyframeCount; k++) { + spatialNode.createKeyframeNode(k); + } + } + } + const ssePriority = mapInfiniteRangeToZeroOne(spatialNode.screenSpaceError); + + let hasLoadedKeyframe = false; + const keyframeNodes = spatialNode.keyframeNodes; + for ( + let keyframeIndex = 0; + keyframeIndex < keyframeNodes.length; + keyframeIndex++ + ) { + const keyframeNode = keyframeNodes[keyframeIndex]; + const keyframe = keyframeNode.keyframe; + + // // Prioritize all keyframes equally + // keyframeNode.priority = ssePriority; + + // // Prioritize ONLY keyframes adjacent to the playhead + // keyframeNode.priority = ssePriority; + // if (keyframe !== previousKeyframe && keyframe !== nextKeyframe) { + // keyframeNode.priority = -Number.MAX_VALUE; + // } + + // // Prioritize keyframes closest to the playhead + // keyframeNode.priority = ssePriority; + // const keyframeDifference = Math.min(Math.abs(keyframe - previousKeyframe), Math.abs(keyframe - nextKeyframe)); + // keyframeNode.priority -= keyframeDifference; + + // Balanced prioritization + const keyframeDifference = Math.min( + Math.abs(keyframe - previousKeyframe), + Math.abs(keyframe - nextKeyframe) + ); + const maxKeyframeDifference = Math.max( + previousKeyframe, + keyframeCount - nextKeyframe - 1, + 1 + ); + const keyframeFactor = Math.pow( + 1.0 - keyframeDifference / maxKeyframeDifference, + 4.0 + ); + const binaryTreeFactor = Math.exp( + -that.binaryTreeKeyframeWeighting[keyframe] + ); + keyframeNode.priority = 10.0 * ssePriority; + keyframeNode.priority += CesiumMath.lerp( + binaryTreeFactor, + keyframeFactor, + 0.15 + 0.85 * keyframeFactor + ); + + if ( + keyframeNode.state !== VoxelTraversal.LoadState.UNAVAILABLE && + keyframeNode.state !== VoxelTraversal.LoadState.FAILED && + keyframeNode.priority !== -Number.MAX_VALUE + ) { + priorityQueue.insert(keyframeNode); + } + if (keyframeNode.state === VoxelTraversal.LoadState.LOADED) { + hasLoadedKeyframe = true; + } + } + + const meetsScreenSpaceError = + spatialNode.screenSpaceError < targetScreenSpaceError; + if (!meetsScreenSpaceError && hasLoadedKeyframe) { + if (!defined(spatialNode.children)) { + const childLevel = spatialNode.level + 1; + const childXMin = spatialNode.x * 2 + 0; + const childXMax = spatialNode.x * 2 + 1; + const childYMin = spatialNode.y * 2 + 0; + const childYMax = spatialNode.y * 2 + 1; + const childZMin = spatialNode.z * 2 + 0; + const childZMax = spatialNode.z * 2 + 1; + + spatialNode.children = new Array( + new SpatialNode( + childLevel, + childXMin, + childYMin, + childZMin, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMax, + childYMin, + childZMin, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMin, + childYMax, + childZMin, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMax, + childYMax, + childZMin, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMin, + childYMin, + childZMax, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMax, + childYMin, + childZMax, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMin, + childYMax, + childZMax, + spatialNode, + shape, + voxelDimensions + ), + new SpatialNode( + childLevel, + childXMax, + childYMax, + childZMax, + spatialNode, + shape, + voxelDimensions + ) + ); + } + for (let childIndex = 0; childIndex < 8; childIndex++) { + const child = spatialNode.children[childIndex]; + addToQueueRecursive(child, visibilityPlaneMask); + } + } else { + // Free up memory + spatialNode.children = undefined; + } + } + + priorityQueue.reset(); + addToQueueRecursive(rootNode, CullingVolume.MASK_INDETERMINATE); + + const highPriorityKeyframeNodes = that.highPriorityKeyframeNodes; + let highPriorityKeyframeNodeCount = 0; + let highPriorityKeyframeNode; + while (priorityQueue.length > 0) { + highPriorityKeyframeNode = priorityQueue.removeMaximum(); + highPriorityKeyframeNode.highPriorityFrameNumber = frameNumber; + highPriorityKeyframeNodes[ + highPriorityKeyframeNodeCount + ] = highPriorityKeyframeNode; + highPriorityKeyframeNodeCount++; + } + + const keyframeNodesInMegatexture = that.keyframeNodesInMegatexture; + // TODO: some of the megatexture state should be stored once, not duplicate for each megatexture + const megatexture = that.megatextures[0]; + const keyframeNodesInMegatextureCount = megatexture.occupiedCount; + keyframeNodesInMegatexture.length = keyframeNodesInMegatextureCount; + keyframeNodesInMegatexture.sort(function (a, b) { + if (a.highPriorityFrameNumber === b.highPriorityFrameNumber) { + return b.priority - a.priority; + } + return b.highPriorityFrameNumber - a.highPriorityFrameNumber; + }); + + let destroyedCount = 0; + let addedCount = 0; + + for ( + let highPriorityKeyframeNodeIndex = 0; + highPriorityKeyframeNodeIndex < highPriorityKeyframeNodeCount; + highPriorityKeyframeNodeIndex++ + ) { + highPriorityKeyframeNode = + highPriorityKeyframeNodes[highPriorityKeyframeNodeIndex]; + + if ( + highPriorityKeyframeNode.state === VoxelTraversal.LoadState.LOADED || + highPriorityKeyframeNode.spatialNode === undefined + ) { + // Already loaded, so nothing to do. + // Or destroyed when adding a higher priority node + continue; + } + if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.UNLOADED) { + requestTiles(that, highPriorityKeyframeNode); + } + if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.RECEIVED) { + let addNodeIndex = 0; + if (megatexture.isFull()) { + // If the megatexture is full, try removing a discardable node with the lowest priority. + addNodeIndex = keyframeNodesInMegatextureCount - 1 - destroyedCount; + destroyedCount++; + + const discardNode = keyframeNodesInMegatexture[addNodeIndex]; + discardNode.spatialNode.destroyKeyframeNode( + discardNode, + that.megatextures + ); + } else { + addNodeIndex = keyframeNodesInMegatextureCount + addedCount; + addedCount++; + } + highPriorityKeyframeNode.spatialNode.addKeyframeNodeToMegatextures( + highPriorityKeyframeNode, + that.megatextures + ); + keyframeNodesInMegatexture[addNodeIndex] = highPriorityKeyframeNode; + } + } +} + +/** + * @ignore + * @param {VoxelTraversal} that + */ +function printDebugInformation( + that, + loadAndUnloadTimeMs, + generateOctreeTimeMs, + totalTimeMs +) { + const keyframeCount = that.keyframeCount; + const rootNode = that.rootNode; + + const loadStateCount = Object.keys(VoxelTraversal.LoadState).length; + const loadStatesByKeyframe = new Array(loadStateCount); + const loadStateByCount = new Array(loadStateCount); + let nodeCountTotal = 0; + + for ( + let loadStateIndex = 0; + loadStateIndex < loadStateCount; + loadStateIndex++ + ) { + const keyframeArray = new Array(keyframeCount); + loadStatesByKeyframe[loadStateIndex] = keyframeArray; + for (let i = 0; i < keyframeCount; i++) { + keyframeArray[i] = 0; + } + loadStateByCount[loadStateIndex] = 0; + } + + /** + * @ignore + * @param {SpatialNode} node + */ + function traverseRecursive(node) { + const keyframeNodes = node.keyframeNodes; + for ( + let keyframeIndex = 0; + keyframeIndex < keyframeNodes.length; + keyframeIndex++ + ) { + const keyframeNode = keyframeNodes[keyframeIndex]; + const keyframe = keyframeNode.keyframe; + const state = keyframeNode.state; + loadStatesByKeyframe[state][keyframe] += 1; + loadStateByCount[state] += 1; + nodeCountTotal++; + } + + if (defined(node.children)) { + for (let childIndex = 0; childIndex < 8; childIndex++) { + const child = node.children[childIndex]; + traverseRecursive(child); + } + } + } + traverseRecursive(rootNode); + + const loadedKeyframeStatistics = `KEYFRAMES: ${ + loadStatesByKeyframe[VoxelTraversal.LoadState.LOADED] + }`; + const loadStateStatistics = + `UNLOADED: ${loadStateByCount[VoxelTraversal.LoadState.UNLOADED]} | ` + + `RECEIVING: ${loadStateByCount[VoxelTraversal.LoadState.RECEIVING]} | ` + + `RECEIVED: ${loadStateByCount[VoxelTraversal.LoadState.RECEIVED]} | ` + + `LOADED: ${loadStateByCount[VoxelTraversal.LoadState.LOADED]} | ` + + `FAILED: ${loadStateByCount[VoxelTraversal.LoadState.FAILED]} | ` + + `UNAVAILABLE: ${ + loadStateByCount[VoxelTraversal.LoadState.UNAVAILABLE] + } | ` + + `TOTAL: ${nodeCountTotal}`; + + const loadAndUnloadTimeMsRounded = + Math.round(loadAndUnloadTimeMs * 100) / 100; + const generateOctreeTimeMsRounded = + Math.round(generateOctreeTimeMs * 100) / 100; + const totalTimeMsRounded = Math.round(totalTimeMs * 100) / 100; + + const timerStatistics = + `LOAD: ${loadAndUnloadTimeMsRounded} | ` + + `OCT: ${generateOctreeTimeMsRounded} | ` + + `ALL: ${totalTimeMsRounded}`; + + console.log( + `${loadedKeyframeStatistics} || ${loadStateStatistics} || ${timerStatistics}` + ); +} + +VoxelTraversal.LoadState = { + UNLOADED: 0, // Has no data and is in dormant state + RECEIVING: 1, // Is waiting on data from the provider + RECEIVED: 2, // Received data from the provider + LOADED: 3, // Processed data from provider + FAILED: 4, // Failed to receive data from the provider + UNAVAILABLE: 5, // No data available for this tile +}; + +/** + * @ignore + * @constructor + * @param {Number} level + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {SpatialNode} parent + * @param {VoxelShapeType} shape + */ +function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { + /** + * @ignore + * @type {SpatialNode[]} + */ + this.children = undefined; + this.parent = parent; + + this.level = level; + this.x = x; + this.y = y; + this.z = z; + + /** + * @ignore + * @type {KeyframeNode[]} + */ + this.keyframeNodes = []; + /** + * @ignore + * @type {KeyframeNode[]} + */ + this.renderableKeyframeNodes = []; + + this.renderableKeyframeNodeLerp = 0.0; + /** + * @ignore + * @type {KeyframeNode} + */ + this.renderableKeyframeNodePrevious = undefined; + /** + * @ignore + * @type {KeyframeNode} + */ + this.renderableKeyframeNodeNext = undefined; + + this.orientedBoundingBox = new OrientedBoundingBox(); + this.approximateVoxelSize = 0.0; + this.screenSpaceError = 0.0; + this.visitedFrameNumber = -1; + + this.computeBoundingVolumes(shape, voxelDimensions); +} + +SpatialNode.spatialComparator = function (a, b) { + // The higher of the two screen space errors is prioritized + return b.screenSpaceError - a.screenSpaceError; +}; + +const scratchObbHalfScale = new Cartesian3(); + +/** + * @ignore + * @param {VoxelShape} shape + * @param {Cartesian3} voxelDimensions + */ +SpatialNode.prototype.computeBoundingVolumes = function ( + shape, + voxelDimensions +) { + this.orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + this.level, + this.x, + this.y, + this.z, + this.orientedBoundingBox + ); + + const halfScale = Matrix3.getScale( + this.orientedBoundingBox.halfAxes, + scratchObbHalfScale + ); + const maximumScale = 2.0 * Cartesian3.maximumComponent(halfScale); + this.approximateVoxelSize = + maximumScale / Cartesian3.minimumComponent(voxelDimensions); +}; + +/** + * @ignore + * @param {FrameState} frameState + * @param {Number} visibilityPlaneMask + * @returns {Number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. + */ +SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { + const that = this; + const obb = that.orientedBoundingBox; + const cullingVolume = frameState.cullingVolume; + return cullingVolume.computeVisibilityWithPlaneMask(obb, visibilityPlaneMask); +}; + +/** + * @ignore + * @param {Cartesian3} cameraPosition + * @param {Number} screenSpaceErrorMultiplier + */ +SpatialNode.prototype.computeScreenSpaceError = function ( + cameraPosition, + screenSpaceErrorMultiplier +) { + const that = this; + const obb = that.orientedBoundingBox; + + let distance = Math.sqrt(obb.distanceSquaredTo(cameraPosition)); + // Avoid divide-by-zero when viewer is inside the tile. + distance = Math.max(distance, CesiumMath.EPSILON7); + const approximateVoxelSize = that.approximateVoxelSize; + const error = screenSpaceErrorMultiplier * (approximateVoxelSize / distance); + that.screenSpaceError = error; +}; + +// This object imitates a KeyframeNode. Only used for binary search function. +const scratchBinarySearchKeyframeNode = { + keyframe: 0, +}; + +/** + * Finds the index of the keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. + * @ignore + * @param {Number} keyframe + * @returns {Number} + */ +SpatialNode.prototype.findKeyframeIndex = function (keyframe) { + const that = this; + const keyframeNodes = that.keyframeNodes; + scratchBinarySearchKeyframeNode.keyframe = keyframe; + const index = binarySearch( + keyframeNodes, + scratchBinarySearchKeyframeNode, + KeyframeNode.searchComparator + ); + return index; +}; +/** + * Finds the index of the renderable keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. + * @ignore + * @param {Number} keyframe + * @returns {Number} + */ +SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { + const that = this; + const renderableKeyframeNodes = that.renderableKeyframeNodes; + scratchBinarySearchKeyframeNode.keyframe = keyframe; + const index = binarySearch( + renderableKeyframeNodes, + scratchBinarySearchKeyframeNode, + KeyframeNode.searchComparator + ); + return index; +}; + +/** + * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. + * @ignore + * @param {Number} keyframeLocation + */ +SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( + keyframeLocation +) { + const that = this; + + let spatialNode = that; + const startLevel = spatialNode.level; + + const targetKeyframePrev = Math.floor(keyframeLocation); + const targetKeyframeNext = Math.ceil(keyframeLocation); + + let bestKeyframeNodePrev; + let bestKeyframeNodeNext; + let minimumDistancePrev = +Number.MAX_VALUE; + let minimumDistanceNext = +Number.MAX_VALUE; + + while (defined(spatialNode)) { + const renderableKeyframeNodes = spatialNode.renderableKeyframeNodes; + + if (renderableKeyframeNodes.length >= 1) { + let keyframeNodeIndexPrev = spatialNode.findRenderableKeyframeIndex( + targetKeyframePrev + ); + if (keyframeNodeIndexPrev < 0) { + keyframeNodeIndexPrev = CesiumMath.clamp( + ~keyframeNodeIndexPrev - 1, + 0, + renderableKeyframeNodes.length - 1 + ); + } + const keyframeNodePrev = renderableKeyframeNodes[keyframeNodeIndexPrev]; + const keyframePrev = keyframeNodePrev.keyframe; + + let keyframeNodeNext; + if ( + targetKeyframeNext === targetKeyframePrev || + targetKeyframePrev < keyframePrev + ) { + keyframeNodeNext = keyframeNodePrev; + } else { + const keyframeNodeIndexNext = Math.min( + keyframeNodeIndexPrev + 1, + renderableKeyframeNodes.length - 1 + ); + keyframeNodeNext = renderableKeyframeNodes[keyframeNodeIndexNext]; + } + const keyframeNext = keyframeNodeNext.keyframe; + + const keyframeDistancePrev = targetKeyframePrev - keyframePrev; + const keyframeDistanceNext = keyframeNext - targetKeyframeNext; + const levelDistance = startLevel - spatialNode.level; + + // Balance temporal and visual quality + const levelWeight = Math.exp(levelDistance * 4.0); + const normalKeyframeWeight = 1.0; + const reverseKeyframeWeight = 200.0; // Keyframes on the opposite of the desired direction are deprioritized. + const distancePrev = + levelDistance * levelWeight + + (keyframeDistancePrev >= 0 + ? keyframeDistancePrev * normalKeyframeWeight + : -keyframeDistancePrev * reverseKeyframeWeight); + const distanceNext = + levelDistance * levelWeight + + (keyframeDistanceNext >= 0 + ? keyframeDistanceNext * normalKeyframeWeight + : -keyframeDistanceNext * reverseKeyframeWeight); + + // // Prioritize visual quality + // const distancePrev = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; + // const distanceNext = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; + + // // Prioritize temporal quality + // const distancePrev = keyframeDistancePrev >= 0 ? keyframeDistancePrev : Number.MAX_VALUE + keyframeDistancePrev; + // const distanceNext = keyframeDistanceNext >= 0 ? keyframeDistanceNext : Number.MAX_VALUE + keyframeDistanceNext; + + if (distancePrev < minimumDistancePrev) { + minimumDistancePrev = distancePrev; + bestKeyframeNodePrev = keyframeNodePrev; + } + if (distanceNext < minimumDistanceNext) { + minimumDistanceNext = distanceNext; + bestKeyframeNodeNext = keyframeNodeNext; + } + if (keyframeDistancePrev === 0 && keyframeDistanceNext === 0) { + // Nothing higher up will be better, so break early. + break; + } + } + + spatialNode = spatialNode.parent; + } + + that.renderableKeyframeNodePrevious = bestKeyframeNodePrev; + that.renderableKeyframeNodeNext = bestKeyframeNodeNext; + if (defined(bestKeyframeNodePrev) && defined(bestKeyframeNodeNext)) { + const bestKeyframePrev = bestKeyframeNodePrev.keyframe; + const bestKeyframeNext = bestKeyframeNodeNext.keyframe; + that.renderableKeyframeNodeLerp = + bestKeyframePrev === bestKeyframeNext + ? 0.0 + : CesiumMath.clamp( + (keyframeLocation - bestKeyframePrev) / + (bestKeyframeNext - bestKeyframePrev), + 0.0, + 1.0 + ); + } +}; + +/** + * @ignore + * @param {Number} frameNumber + * @returns {Boolean} + */ +SpatialNode.prototype.isVisited = function (frameNumber) { + const that = this; + return that.visitedFrameNumber === frameNumber; +}; + +/** + * @ignore + * @param {Number} keyframe + */ +SpatialNode.prototype.createKeyframeNode = function (keyframe) { + const that = this; + let index = that.findKeyframeIndex(keyframe); + if (index < 0) { + index = ~index; // convert to insertion index + const keyframeNode = new KeyframeNode(that, keyframe); + that.keyframeNodes.splice(index, 0, keyframeNode); + } +}; +/** + * @ignore + * @param {KeyframeNode} keyframeNode + * @param {Megatexture} megatexture + */ +SpatialNode.prototype.destroyKeyframeNode = function ( + keyframeNode, + megatextures +) { + const that = this; + + const keyframe = keyframeNode.keyframe; + const keyframeIndex = that.findKeyframeIndex(keyframe); + if (keyframeIndex < 0) { + throw new DeveloperError("Keyframe node does not exist."); + } + + const keyframeNodes = that.keyframeNodes; + keyframeNodes.splice(keyframeIndex, 1); + + if (keyframeNode.megatextureIndex !== -1) { + const megatextureArray = Object.keys(megatextures).map(function (key) { + return megatextures[key]; + }); // Object.values workaround + const numberOfMegatextures = megatextureArray.length; + for (let i = 0; i < numberOfMegatextures; i++) { + megatextureArray[i].remove(keyframeNode.megatextureIndex); + } + + const renderableKeyframeNodeIndex = that.findRenderableKeyframeIndex( + keyframe + ); + if (renderableKeyframeNodeIndex < 0) { + throw new DeveloperError("Renderable keyframe node does not exist."); + } + + const renderableKeyframeNodes = that.renderableKeyframeNodes; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); + } + + keyframeNode.spatialNode = undefined; + keyframeNode.state = VoxelTraversal.LoadState.UNLOADED; + keyframeNode.metadatas = {}; + keyframeNode.megatextureIndex = -1; + keyframeNode.priority = -Number.MAX_VALUE; + keyframeNode.highPriorityFrameNumber = -1; +}; + +SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( + keyframeNode, + megatextures +) { + if ( + keyframeNode.state !== VoxelTraversal.LoadState.RECEIVED || + keyframeNode.megatextureIndex !== -1 || + keyframeNode.metadatas.length !== megatextures.length + ) { + throw new DeveloperError("Keyframe node cannot be added to megatexture"); + } + + const length = megatextures.length; + for (let i = 0; i < length; i++) { + const megatexture = megatextures[i]; + keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadatas[i]); + keyframeNode.metadatas[i] = undefined; // data is in megatexture so no need to hold onto it + } + + keyframeNode.state = VoxelTraversal.LoadState.LOADED; + + const renderableKeyframeNodes = this.renderableKeyframeNodes; + let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( + keyframeNode.keyframe + ); + if (renderableKeyframeNodeIndex >= 0) { + throw new DeveloperError("Keyframe already renderable"); + } + renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); +}; +/** + * @ignore + * @param {KeyframeNode} keyframeNode + * @param {Megatexture} megatexture + */ +SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( + keyframeNode, + megatexture +) { + const that = this; + + if ( + keyframeNode.state !== VoxelTraversal.LoadState.RECEIVED || + keyframeNode.megatextureIndex !== -1 || + !defined(keyframeNode.metadatas[megatexture.metadataName]) + ) { + throw new DeveloperError("Keyframe node cannot be added to megatexture"); + } + + keyframeNode.megatextureIndex = megatexture.add( + keyframeNode.metadatas[megatexture.metadataName] + ); + keyframeNode.metadatas[megatexture.metadataName] = undefined; // data is in megatexture so no need to hold onto it + keyframeNode.state = VoxelTraversal.LoadState.LOADED; + + const renderableKeyframeNodes = that.renderableKeyframeNodes; + let renderableKeyframeNodeIndex = that.findRenderableKeyframeIndex( + keyframeNode.keyframe + ); + if (renderableKeyframeNodeIndex >= 0) { + throw new DeveloperError("Keyframe already renderable"); + } + renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); +}; + +/** + * @ignore + * @param {Number} frameNumber + */ +SpatialNode.prototype.isRenderable = function (frameNumber) { + const that = this; + + const previousNode = that.renderableKeyframeNodePrevious; + const nextNode = that.renderableKeyframeNodeNext; + const level = that.level; + + return ( + defined(previousNode) && + defined(nextNode) && + (previousNode.spatialNode.level === level || + nextNode.spatialNode.level === level) && + that.visitedFrameNumber === frameNumber + ); +}; + +/** + * @ignore + * @constructor + * @param {SpatialNode} spatialNode + * @param {Number} keyframe + */ +function KeyframeNode(spatialNode, keyframe) { + this.spatialNode = spatialNode; + this.keyframe = keyframe; + this.state = VoxelTraversal.LoadState.UNLOADED; + this.metadatas = []; + this.megatextureIndex = -1; + this.priority = -Number.MAX_VALUE; + this.highPriorityFrameNumber = -1; +} + +/** + * @ignore + * @param {KeyframeNode} a + * @param {KeyframeNode} b + */ +KeyframeNode.priorityComparator = function (a, b) { + return a.priority - b.priority; +}; +/** + * @ignore + * @param {KeyframeNode} a + * @param {KeyframeNode} b + */ +KeyframeNode.searchComparator = function (a, b) { + return a.keyframe - b.keyframe; +}; + +// GPU Octree Layout +// (shown as binary tree instead of octree for demonstration purposes) +// +// Tree representation: +// 0 +// / \ +// / \ +// / \ +// 1 3 +// / \ / \ +// L0 2 L3 L4 +// / \ +// L1 L2 +// +// +// Array representation: +// L = leaf index +// * = index to parent node +// index: 0_______ 1________ 2________ 3_________ +// array: [*0, 1, 3, *0, L0, 2, *1 L1, L2, *0, L3, L4] +// +// The array is generated from a depth-first traversal. The end result could be an unbalanced tree, +// so the parent index is stored at each node to make it possible to traverse upwards. + +const GpuOctreeFlag = { + // Data is an octree index. + INTERNAL: 0, + // Data is a leaf node. + LEAF: 1, + // When leaf data is packed in the octree and there's a node that is forced to + // render but has no data of its own (such as when its siblings are renderable but it + // is not), signal that it's using its parent's data. + PACKED_LEAF_FROM_PARENT: 2, +}; + +/** + * @ignore + * @param {VoxelTraversal} that + */ +function generateOctree(that) { + const keyframeLocation = that.keyframeLocation; + const useLeafNodes = that.useLeafNodeTexture; + const frameNumber = that.frameNumber; + + let internalNodeCount = 0; + let leafNodeCount = 0; + const internalNodeOctreeData = []; + const leafNodeOctreeData = []; + + /** + * @ignore + * @param {SpatialNode} node + * @param {Number} childOctreeIndex + * @param {Number} childEntryIndex + * @param {Number} parentOctreeIndex + * @param {Number} parentEntryIndex + */ + function buildOctree( + node, + childOctreeIndex, + childEntryIndex, + parentOctreeIndex, + parentEntryIndex + ) { + let hasRenderableChildren = false; + if (defined(node.children)) { + for (let c = 0; c < 8; c++) { + const childNode = node.children[c]; + childNode.computeSurroundingRenderableKeyframeNodes(keyframeLocation); + if (childNode.isRenderable(frameNumber)) { + hasRenderableChildren = true; + } + } + } + + if (hasRenderableChildren) { + // Point the parent and child octree indexes at each other + internalNodeOctreeData[parentEntryIndex] = + (GpuOctreeFlag.INTERNAL << 16) | childOctreeIndex; + internalNodeOctreeData[childEntryIndex] = parentOctreeIndex; + internalNodeCount++; + + // Recurse over children + parentOctreeIndex = childOctreeIndex; + parentEntryIndex = parentOctreeIndex * 9 + 1; + for (let cc = 0; cc < 8; cc++) { + const child = node.children[cc]; + childOctreeIndex = internalNodeCount; + childEntryIndex = childOctreeIndex * 9 + 0; + buildOctree( + child, + childOctreeIndex, + childEntryIndex, + parentOctreeIndex, + parentEntryIndex + cc + ); + } + } else { + // Store the leaf node information instead + // Recursion stops here because there are no renderable children + if (useLeafNodes) { + const previousKeyframeNode = node.renderableKeyframeNodePrevious; + const nextKeyframeNode = node.renderableKeyframeNodeNext; + leafNodeOctreeData[leafNodeCount * 5 + 0] = + node.renderableKeyframeNodeLerp; + leafNodeOctreeData[leafNodeCount * 5 + 1] = + node.level - previousKeyframeNode.spatialNode.level; + leafNodeOctreeData[leafNodeCount * 5 + 2] = + node.level - nextKeyframeNode.spatialNode.level; + leafNodeOctreeData[leafNodeCount * 5 + 3] = + previousKeyframeNode.megatextureIndex; + leafNodeOctreeData[leafNodeCount * 5 + 4] = + nextKeyframeNode.megatextureIndex; + internalNodeOctreeData[parentEntryIndex] = + (GpuOctreeFlag.LEAF << 16) | leafNodeCount; + } else { + const keyframeNode = node.renderableKeyframeNodePrevious; + const levelDifference = node.level - keyframeNode.spatialNode.level; + const flag = + levelDifference === 0 + ? GpuOctreeFlag.LEAF + : GpuOctreeFlag.PACKED_LEAF_FROM_PARENT; + internalNodeOctreeData[parentEntryIndex] = + (flag << 16) | keyframeNode.megatextureIndex; + } + leafNodeCount++; + } + } + + const rootNode = that.rootNode; + rootNode.computeSurroundingRenderableKeyframeNodes(keyframeLocation); + if (rootNode.isRenderable(frameNumber)) { + buildOctree(rootNode, 0, 0, 0, 0); + } + + /** + * @ignore + * @param {Number[]} data + * @param {Number} texelsPerTile + * @param {Number} tilesPerRow + * @param {Texture} texture + */ + function copyToInternalNodeTexture( + data, + texelsPerTile, + tilesPerRow, + texture + ) { + const channelCount = PixelFormat.componentsLength(texture.pixelFormat); + const tileCount = Math.ceil(data.length / texelsPerTile); + const copyWidth = Math.max( + 1, + texelsPerTile * Math.min(tileCount, tilesPerRow) + ); + const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); + + const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); + for (let i = 0; i < data.length; i++) { + const val = data[i]; + const startIndex = i * channelCount; + for (let j = 0; j < channelCount; j++) { + textureData[startIndex + j] = (val >>> (j * 8)) & 0xff; + } + } + + const source = { + arrayBufferView: textureData, + width: copyWidth, + height: copyHeight, + }; + + const copyOptions = { + source: source, + xOffset: 0, + yOffset: 0, + }; + + texture.copyFrom(copyOptions); + } + + /** + * @ignore + * @param {Number[]} data + * @param {Number} texelsPerTile + * @param {Number} tilesPerRow + * @param {Texture} texture + */ + function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) { + const channelCount = PixelFormat.componentsLength(texture.pixelFormat); + const datasPerTile = 5; + const tileCount = Math.ceil(data.length / datasPerTile); + const copyWidth = Math.max( + 1, + texelsPerTile * Math.min(tileCount, tilesPerRow) + ); + const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); + + const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); + for (let tileIndex = 0; tileIndex < tileCount; tileIndex++) { + const timeLerp = data[tileIndex * datasPerTile + 0]; + const previousKeyframeLevelsAbove = data[tileIndex * datasPerTile + 1]; + const nextKeyframeLevelsAbove = data[tileIndex * datasPerTile + 2]; + const previousKeyframeMegatextureIndex = + data[tileIndex * datasPerTile + 3]; + const nextKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 4]; + + const timeLerpCompressed = CesiumMath.clamp( + Math.floor(65536 * timeLerp), + 0, + 65535 + ); + textureData[tileIndex * 8 + 0] = (timeLerpCompressed >>> 0) & 0xff; + textureData[tileIndex * 8 + 1] = (timeLerpCompressed >>> 8) & 0xff; + textureData[tileIndex * 8 + 2] = previousKeyframeLevelsAbove & 0xff; + textureData[tileIndex * 8 + 3] = nextKeyframeLevelsAbove & 0xff; + textureData[tileIndex * 8 + 4] = + (previousKeyframeMegatextureIndex >>> 0) & 0xff; + textureData[tileIndex * 8 + 5] = + (previousKeyframeMegatextureIndex >>> 8) & 0xff; + textureData[tileIndex * 8 + 6] = + (nextKeyframeMegatextureIndex >>> 0) & 0xff; + textureData[tileIndex * 8 + 7] = + (nextKeyframeMegatextureIndex >>> 8) & 0xff; + } + + const source = { + arrayBufferView: textureData, + width: copyWidth, + height: copyHeight, + }; + + const copyOptions = { + source: source, + xOffset: 0, + yOffset: 0, + }; + + texture.copyFrom(copyOptions); + } + + copyToInternalNodeTexture( + internalNodeOctreeData, + 9, + that.internalNodeTilesPerRow, + that.internalNodeTexture + ); + if (useLeafNodes) { + copyToLeafNodeTexture( + leafNodeOctreeData, + 2, + that.leafNodeTilesPerRow, + that.leafNodeTexture + ); + } +} + +/** + * @private + * @param {Number} tileCount + * @param {Cartesian3} dimensions + * @param {MetadataType[]} types + * @param {MetadataComponentType[]} componentTypes + */ +VoxelTraversal.getApproximateTextureMemoryByteLength = function ( + tileCount, + dimensions, + types, + componentTypes +) { + let textureMemoryByteLength = 0; + + const length = types.length; + for (let i = 0; i < length; i++) { + const type = types[i]; + const componentType = componentTypes[i]; + const componentCount = MetadataType.getComponentCount(type); + + textureMemoryByteLength += Megatexture.getApproximateTextureMemoryByteLength( + tileCount, + dimensions, + componentCount, + componentType + ); + } + + return textureMemoryByteLength; +}; + +/** + * @ignore + * @constructor + * @param {Context} context + * @param {Cartesian3} dimensions + * @param {Number} channelCount + * @param {MetadataComponentType} componentType + * @param {Number} [textureMemoryByteLength] + */ +function Megatexture( + context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength +) { + // TODO there are a lot of texture packing rules, see https://github.com/CesiumGS/cesium/issues/9572 + // Unsigned short textures not allowed in webgl 1, so treat as float + if (componentType === MetadataComponentType.UNSIGNED_SHORT) { + componentType = MetadataComponentType.FLOAT32; + } + + const supportsFloatingPointTexture = context.floatingPointTexture; + if ( + componentType === MetadataComponentType.FLOAT32 && + !supportsFloatingPointTexture + ) { + throw new RuntimeError("Floating point texture not supported"); + } + + // TODO support more + let pixelType; + if ( + componentType === MetadataComponentType.FLOAT32 || + componentType === MetadataComponentType.FLOAT64 + ) { + pixelType = PixelDatatype.FLOAT; + } else if (componentType === MetadataComponentType.UINT8) { + pixelType = PixelDatatype.UNSIGNED_BYTE; + } + + let pixelFormat; + if (channelCount === 1) { + pixelFormat = PixelFormat.LUMINANCE; + } else if (channelCount === 2) { + pixelFormat = PixelFormat.LUMINANCE_ALPHA; + } else if (channelCount === 3) { + pixelFormat = PixelFormat.RGB; + } else if (channelCount === 4) { + pixelFormat = PixelFormat.RGBA; + } + + const maximumTextureMemoryByteLength = 512 * 1024 * 1024; + const defaultTextureMemoryByteLength = 128 * 1024 * 1024; + textureMemoryByteLength = Math.min( + defaultValue(textureMemoryByteLength, defaultTextureMemoryByteLength), + maximumTextureMemoryByteLength + ); + const maximumTextureDimensionContext = ContextLimits.maximumTextureSize; + const componentTypeByteLength = MetadataComponentType.getSizeInBytes( + componentType + ); + const texelCount = Math.floor( + textureMemoryByteLength / (channelCount * componentTypeByteLength) + ); + const textureDimension = Math.min( + maximumTextureDimensionContext, + CesiumMath.previousPowerOfTwo(Math.floor(Math.sqrt(texelCount))) + ); + + const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.x)); + const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); + const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; + const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; + const regionCountPerMegatextureX = Math.floor( + textureDimension / voxelCountPerRegionX + ); + const regionCountPerMegatextureY = Math.floor( + textureDimension / voxelCountPerRegionY + ); + + // TODO can this happen? + if (regionCountPerMegatextureX === 0 || regionCountPerMegatextureY === 0) { + throw new RuntimeError("Tileset is too large to fit into megatexture"); + } + + /** + * @type {Number} + * @private + */ + this.channelCount = channelCount; + + /** + * @type {MetadataComponentType} + * @private + */ + this.componentType = componentType; + + /** + * @type {Cartesian3} + * @private + */ + this.voxelCountPerTile = Cartesian3.clone(dimensions, new Cartesian3()); + + /** + * @type {Number} + * @private + */ + this.maximumTileCount = + regionCountPerMegatextureX * regionCountPerMegatextureY; + + /** + * @type {Cartesian2} + * @private + */ + this.regionCountPerMegatexture = new Cartesian2( + regionCountPerMegatextureX, + regionCountPerMegatextureY + ); + + /** + * @type {Cartesian2} + * @private + */ + this.voxelCountPerRegion = new Cartesian2( + voxelCountPerRegionX, + voxelCountPerRegionY + ); + + /** + * @type {Cartesian2} + * @private + */ + this.sliceCountPerRegion = new Cartesian2( + sliceCountPerRegionX, + sliceCountPerRegionY + ); + + /** + * @type {Cartesian2} + * @private + */ + this.voxelSizeUv = new Cartesian2( + 1.0 / textureDimension, + 1.0 / textureDimension + ); + + /** + * @type {Cartesian2} + * @private + */ + this.sliceSizeUv = new Cartesian2( + dimensions.x / textureDimension, + dimensions.y / textureDimension + ); + + /** + * @type {Cartesian2} + * @private + */ + this.regionSizeUv = new Cartesian2( + voxelCountPerRegionX / textureDimension, + voxelCountPerRegionY / textureDimension + ); + + /** + * @type {Texture} + * @private + */ + this.texture = new Texture({ + context: context, + pixelFormat: pixelFormat, + pixelDatatype: pixelType, + flipY: false, + width: textureDimension, + height: textureDimension, + sampler: new Sampler({ + wrapS: TextureWrap.CLAMP_TO_EDGE, + wrapT: TextureWrap.CLAMP_TO_EDGE, + minificationFilter: TextureMinificationFilter.LINEAR, + magnificationFilter: TextureMagnificationFilter.LINEAR, + }), + }); + + const ArrayType = MetadataComponentType.toTypedArrayType(componentType); + this.tileVoxelDataTemp = new ArrayType( + voxelCountPerRegionX * voxelCountPerRegionY * channelCount + ); + + /** + * @type {MegatextureNode[]} + * @private + */ + this.nodes = new Array(this.maximumTileCount); + for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { + this.nodes[tileIndex] = new MegatextureNode(tileIndex); + } + for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { + const node = this.nodes[tileIndex]; + node.previousNode = tileIndex > 0 ? this.nodes[tileIndex - 1] : undefined; + node.nextNode = + tileIndex < this.maximumTileCount - 1 + ? this.nodes[tileIndex + 1] + : undefined; + } + + /** + * @type {MegatextureNode} + * @private + */ + this.occupiedList = undefined; + + /** + * @type {MegatextureNode} + * @private + */ + this.emptyList = this.nodes[0]; + + /** + * @type {Number} + * @private + */ + this.occupiedCount = 0; +} + +/** + * @ignore + * @constructor + * @param {Number} index + */ +function MegatextureNode(index) { + this.index = index; + + /** + * @ignore + * @type {MegatextureNode} + */ + this.nextNode = undefined; + + /** + * @ignore + * @type {MegatextureNode} + */ + this.previousNode = undefined; +} + +/** + * @ignore + * @param {Array} data + * @returns {Number} + */ +Megatexture.prototype.add = function (data) { + const that = this; + + if (that.isFull()) { + throw new DeveloperError("Trying to add when there are no empty spots"); + } + + // remove head of empty list + const node = that.emptyList; + that.emptyList = that.emptyList.nextNode; + if (defined(that.emptyList)) { + that.emptyList.previousNode = undefined; + } + + // make head of occupied list + node.nextNode = that.occupiedList; + if (defined(node.nextNode)) { + node.nextNode.previousNode = node; + } + that.occupiedList = node; + + const index = node.index; + that.writeDataToTexture(index, data); + + that.occupiedCount++; + return index; +}; + +/** + * @ignore + * @param {Number} index + */ +Megatexture.prototype.remove = function (index) { + const that = this; + if (index < 0 || index >= that.maximumTileCount) { + throw new DeveloperError("Megatexture index out of bounds"); + } + + // remove from list + const node = that.nodes[index]; + if (defined(node.previousNode)) { + node.previousNode.nextNode = node.nextNode; + } + if (defined(node.nextNode)) { + node.nextNode.previousNode = node.previousNode; + } + + // make head of empty list + node.nextNode = that.emptyList; + if (defined(node.nextNode)) { + node.nextNode.previousNode = node; + } + node.previousNode = undefined; + that.emptyList = node; + that.occupiedCount--; +}; + +/** + * @ignore + * @returns {Boolean} + */ +Megatexture.prototype.isFull = function () { + const that = this; + return that.emptyList === undefined; +}; + +/** + * @ignore + * @param {Number} tileCount + * @param {Cartesian3} dimensions + * @param {Number} channelCount number of channels in the metadata. Must be 1 to 4. + * @param {MetadataComponentType} componentType + * @returns {Number} + */ +Megatexture.getApproximateTextureMemoryByteLength = function ( + tileCount, + dimensions, + channelCount, + componentType +) { + // TODO there's a lot of code duplicate with Megatexture constructor + + // Unsigned short textures not allowed in webgl 1, so treat as float + if (componentType === MetadataComponentType.UNSIGNED_SHORT) { + componentType = MetadataComponentType.FLOAT32; + } + + const datatypeSizeInBytes = MetadataComponentType.getSizeInBytes( + componentType + ); + const voxelCountTotal = + tileCount * dimensions.x * dimensions.y * dimensions.z; + + const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.z)); + const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); + const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; + const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; + + // Find the power of two that can fit all tile data, accounting for slices. + // There's probably a non-iterative solution for this, but this is good enough for now. + let textureDimension = CesiumMath.previousPowerOfTwo( + Math.floor(Math.sqrt(voxelCountTotal)) + ); + for (;;) { + const regionCountX = Math.floor(textureDimension / voxelCountPerRegionX); + const regionCountY = Math.floor(textureDimension / voxelCountPerRegionY); + const regionCount = regionCountX * regionCountY; + if (regionCount >= tileCount) { + break; + } else { + textureDimension *= 2; + } + } + + const textureMemoryByteLength = + textureDimension * textureDimension * channelCount * datatypeSizeInBytes; + return textureMemoryByteLength; +}; + +/** + * @ignore + * @param {Number} index + * @param {Float32Array|Uint16Array|Uint8Array} data + */ +Megatexture.prototype.writeDataToTexture = function (index, data) { + const that = this; + const texture = that.texture; + const channelCount = that.channelCount; + const regionDimensionsPerMegatexture = that.regionCountPerMegatexture; + const voxelDimensionsPerRegion = that.voxelCountPerRegion; + const voxelDimensionsPerTile = that.voxelCountPerTile; + const sliceDimensionsPerRegion = that.sliceCountPerRegion; + + let tileData = data; + + // Unsigned short textures not allowed in webgl 1, so treat as float + if (data.constructor === Uint16Array) { + const elementCount = data.length; + tileData = new Float32Array(elementCount); + for (let i = 0; i < elementCount / channelCount; i++) { + for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) { + const dataIndex = i * channelCount + channelIndex; + const minimumValue = that.minimumValues[channelIndex]; + const maximumValue = that.maximumValues[channelIndex]; + // TODO extrema are unnormalized, but we are normalizing to [0, 1] here. what do we want to do? will the user expect to get normalized samples and extrema in the style function? + tileData[dataIndex] = + (data[dataIndex] - minimumValue) / (maximumValue - minimumValue); + // tileData[dataIndex] = CesiumMath.lerp( + // minimumValue, + // maximumValue, + // data[dataIndex] / 65535 + // ); + } + } + } + + const tileVoxelData = that.tileVoxelDataTemp; + for (let z = 0; z < voxelDimensionsPerTile.z; z++) { + const sliceVoxelOffsetX = + (z % sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.x; + const sliceVoxelOffsetY = + Math.floor(z / sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.y; + for (let y = 0; y < voxelDimensionsPerTile.y; y++) { + for (let x = 0; x < voxelDimensionsPerTile.x; x++) { + const readIndex = + z * voxelDimensionsPerTile.y * voxelDimensionsPerTile.x + + y * voxelDimensionsPerTile.x + + x; + const writeIndex = + (sliceVoxelOffsetY + y) * voxelDimensionsPerRegion.x + + (sliceVoxelOffsetX + x); + for (let c = 0; c < channelCount; c++) { + tileVoxelData[writeIndex * channelCount + c] = + tileData[readIndex * channelCount + c]; + } + } + } + } + + const voxelWidth = voxelDimensionsPerRegion.x; + const voxelHeight = voxelDimensionsPerRegion.y; + const voxelOffsetX = + (index % regionDimensionsPerMegatexture.x) * voxelDimensionsPerRegion.x; + const voxelOffsetY = + Math.floor(index / regionDimensionsPerMegatexture.x) * + voxelDimensionsPerRegion.y; + + const source = { + arrayBufferView: tileVoxelData, + width: voxelWidth, + height: voxelHeight, + }; + + const copyOptions = { + source: source, + xOffset: voxelOffsetX, + yOffset: voxelOffsetY, + }; + + texture.copyFrom(copyOptions); +}; + +Megatexture.prototype.isDestroyed = function () { + return false; +}; + +Megatexture.prototype.destroy = function () { + const that = this; + that.texture = that.texture && that.texture.destroy(); + return destroyObject(that); +}; + +export default VoxelTraversal; diff --git a/Source/Shaders/Builtin/Constants/passOverlay.glsl b/Source/Shaders/Builtin/Constants/passOverlay.glsl index e104cb08dd7..6aea11eb1ee 100644 --- a/Source/Shaders/Builtin/Constants/passOverlay.glsl +++ b/Source/Shaders/Builtin/Constants/passOverlay.glsl @@ -6,4 +6,4 @@ * * @see czm_pass */ -const float czm_passOverlay = 9.0; +const float czm_passOverlay = 10.0; diff --git a/Source/Shaders/Builtin/Constants/passVoxels.glsl b/Source/Shaders/Builtin/Constants/passVoxels.glsl new file mode 100644 index 00000000000..80c50735e88 --- /dev/null +++ b/Source/Shaders/Builtin/Constants/passVoxels.glsl @@ -0,0 +1,9 @@ +/** + * The automatic GLSL constant for {@link Pass#VOXELS} + * + * @name czm_passVoxels + * @glslConstant + * + * @see czm_pass + */ +const float czm_passVoxels = 9.0; diff --git a/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl b/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl index 00bdd392994..b049c51f4ac 100644 --- a/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +++ b/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl @@ -81,7 +81,7 @@ vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth) { // See reverseLogDepth.glsl. This is separate to re-use the pow. -#ifdef LOG_DEPTH +#if defined(LOG_DEPTH) || defined(LOG_DEPTH_READ_ONLY) float near = czm_currentFrustum.x; float far = czm_currentFrustum.y; float log2Depth = depthOrLogDepth * czm_log2FarDepthFromNearPlusOne; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl new file mode 100644 index 00000000000..3ff9e885c75 --- /dev/null +++ b/Source/Shaders/VoxelFS.glsl @@ -0,0 +1,1484 @@ +// world space: Cartesian WGS84 +// local space: Cartesian [-0.5, 0.5] aligned with shape. +// For box, the origin is the center of the box, and the six sides sit on the planes x = -0.5, x = 0.5 etc. +// For cylinder, the origin is the center of the cylinder with the cylinder enclosed by the [-0.5, 0.5] box on xy-plane. Positive x-axis points to theta = 0. The top and bottom caps sit at planes z = -0.5, z = 0.5. Positive y points to theta = pi/2 +// For ellipsoid, the origin is the center of the ellipsoid. The maximum height of the ellipsoid touches -0.5, 0.5 in xyz directions. +// intersection space: local space times 2 to be [-1, 1]. Used for ray intersection calculation +// UV space: local space plus 0.5 to be [0, 1]. +// shape space: In the coordinate system of the shape [0, 1] +// For box, this is the same as UV space +// For cylinder, the coordinate system is (radius, theta, z). theta = 0 is aligned with x axis +// For ellipsoid, the coordinate system is (longitude, latitude, height). where 0 is the minimum value in each dimension, and 1 is the max. + + +// TODO is this necessary? Or should it go somewhere else? +precision highp int; + +// Defines that are filled in from VoxelPrimitive.js +// #define METADATA_COUNT XYZ +// #define SAMPLE_COUNT XYZ +// #define NEAREST_SAMPLING + +// Uniforms that are filled in from VoxelPrimitive.js +// uniform sampler2D u_megatextureTextures[METADATA_COUNT]; + +// Functions that are filled in from VoxelPrimitive.js +// Attributes sampleFrom2DMegatextureAtUv(vec2 uv); +// Attributes clearAttributes(); +// Attributes sumAttributes(Attributes attributesA, Attributes attributesB); +// Attributes mixAttributes(Attributes attributesA, Attributes attributesB, float mixFactor); +// void setMinMaxAttributes(inout Voxel voxel); + +#define OCTREE_MAX_LEVELS 32 + +#define OCTREE_FLAG_INTERNAL 0 +#define OCTREE_FLAG_LEAF 1 +#define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2 + +struct OctreeNodeData { + int data; + int flag; +}; + +struct SampleData { + int megatextureIndex; + int levelsAbove; + #if (SAMPLE_COUNT > 1) + float weight; + #endif +}; + +#if defined(SHAPE_ELLIPSOID) +uniform float u_ellipsoidHeightDifferenceUv; +uniform vec3 u_ellipsoidOuterRadiiLocal; // [0,1] +uniform vec3 u_ellipsoidInverseRadiiSquaredLocal; +#endif + +// 2D megatexture +uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions +uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions +uniform vec2 u_megatextureVoxelSizeUv; +uniform vec2 u_megatextureSliceSizeUv; +uniform vec2 u_megatextureTileSizeUv; + +uniform ivec3 u_dimensions; // does not include padding +#if defined(PADDING) +uniform ivec3 u_paddingBefore; +uniform ivec3 u_paddingAfter; +#endif + +uniform vec4 u_minimumValues[METADATA_COUNT]; +uniform vec4 u_maximumValues[METADATA_COUNT]; +// uniform bool u_voxelQuantization[METADATA_COUNT]; +uniform int u_channelCount[METADATA_COUNT]; + +uniform float u_stepSize; + +uniform sampler2D u_octreeInternalNodeTexture; +uniform vec2 u_octreeInternalNodeTexelSizeUv; +uniform int u_octreeInternalNodeTilesPerRow; +uniform sampler2D u_octreeLeafNodeTexture; +uniform vec2 u_octreeLeafNodeTexelSizeUv; +uniform int u_octreeLeafNodeTilesPerRow; + +uniform mat4 u_transformPositionViewToUv; +uniform mat4 u_transformPositionUvToView; +uniform mat3 u_transformDirectionViewToLocal; +uniform mat3 u_transformNormalLocalToWorld; +uniform vec3 u_cameraPositionUv; + +#if defined(BOUNDS) +uniform vec3 u_minBounds; // Bounds from the voxel primitive +uniform vec3 u_maxBounds; // Bounds from the voxel primitive +uniform vec3 u_minBoundsUv; // Similar to u_minBounds but relative to UV space [0,1] +uniform vec3 u_maxBoundsUv; // Similar to u_maxBounds but relative to UV space [0,1] +uniform vec3 u_inverseBounds; // Equal to 1.0 / (u_maxBounds - u_minBounds) +uniform vec3 u_inverseBoundsUv; // Equal to 1.0 / (u_maxBoundsUv - u_minBoundsUv) +#endif + +#if defined(CLIPPING_BOUNDS) +uniform vec3 u_minClippingBounds; +uniform vec3 u_maxClippingBounds; +#endif + +#if defined(PICKING) +uniform vec4 u_pickColor; +#endif + +// -------------------------------------------------------- +// Misc math +// -------------------------------------------------------- + +#if defined(JITTER) +#define HASHSCALE1 50.0 +float hash12(vec2 p) +{ + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); +} +#endif + +int intMod(int a, int b) { + return a - (b * (a / b)); +} +int intMin(int a, int b) { + return a <= b ? a : b; +} +int intMax(int a, int b) { + return a >= b ? a : b; +} +float safeMod(float a, float m) { + return mod(mod(a, m) + m, m); +} +bool inRange(float v, float minVal, float maxVal) { + return clamp(v, minVal, maxVal) == v; +} +bool inRange(vec3 v, vec3 minVal, vec3 maxVal) { + return clamp(v, minVal, maxVal) == v; +} +int normU8_toInt(float value) { + return int(value * 255.0); +} +int normU8x2_toInt(vec2 value) { + return int(value.x * 255.0) + 256 * int(value.y * 255.0); +} +float normU8x2_toFloat(vec2 value) { + return float(normU8x2_toInt(value)) / 65535.0; +} + +// -------------------------------------------------------- +// Intersection tests, coordinate conversions, etc +// -------------------------------------------------------- + +struct Ray +{ + vec3 pos; + vec3 dir; +}; + +const float NoHit = -czm_infinity; +const float InfHit = czm_infinity; + +#if (defined(SHAPE_CYLINDER) && defined(BOUNDS)) || (defined(SHAPE_ELLIPSOID) && defined(BOUNDS)) +vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) +{ + // TODO: completely skip shape if both of its Ts are below 0.0? + vec2 tEntryExit = vec2(NoHit, NoHit); + + // Sort the intersections from min T to max T with bubble sort. + // Note: If this sorting function changes, some of the intersection test may + // need to be updated. Search for "bubble sort" to find those areas. + + const int sortPasses = SHAPE_INTERSECTION_COUNT - 1; + for (int n = sortPasses; n > 0; --n) + { + for (int i = 0; i < sortPasses; ++i) + { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + + vec2 intersect0 = intersections[i]; + vec2 intersect1 = intersections[i+1]; + + float idx0 = intersect0.x; + float idx1 = intersect1.x; + float t0 = intersect0.y; + float t1 = intersect1.y; + + float tmin = min(t0, t1); + float tmax = max(t0, t1); + float idxmin = tmin == t0 ? idx0 : idx1; + float idxmax = tmin == t0 ? idx1 : idx0; + + intersections[i] = vec2(idxmin, tmin); + intersections[i+1] = vec2(idxmax, tmax); + } + } + + int surroundCount = 0; + bool surroundIsPositive = false; + for (int i = 0; i < SHAPE_INTERSECTION_COUNT; i++) + { + vec2 entry = intersections[i]; + float idx = entry.x; + float t = entry.y; + + bool currShapeIsPositive = idx <= 1.0; + bool enter = mod(idx, 2.0) == 0.0; + + surroundCount += enter ? +1 : -1; + surroundIsPositive = currShapeIsPositive ? enter : surroundIsPositive; + + // entering positive or exiting negative + if (surroundCount == 1 && surroundIsPositive && enter == currShapeIsPositive) { + tEntryExit.x = t; + } + + // exiting positive or entering negative after being inside positive + // TODO: Can this be simplified? + if ((!enter && currShapeIsPositive && surroundCount == 0) || (enter && !currShapeIsPositive && surroundCount == 2 && surroundIsPositive)) { + tEntryExit.y = t; + + // entry and exit have been found, so the loop can stop + break; + } + } + return tEntryExit; +} +#endif + +#if defined(SHAPE_BOX) +// Unit cube from [-1, +1] +vec2 intersectUnitCube(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + vec3 dInv = 1.0 / d; + vec3 od = -o * dInv; + vec3 t0 = od - dInv; + vec3 t1 = od + dInv; + vec3 m0 = min(t0, t1); + vec3 m1 = max(t0, t1); + float tMin = max(max(m0.x, m0.y), m0.z); + float tMax = min(min(m1.x, m1.y), m1.z); + + if (tMin >= tMax) { + return vec2(NoHit, NoHit); + } + + return vec2(tMin, tMax); +} +#endif + +#if defined(SHAPE_BOX) +vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float t = -o.z / d.z; + vec2 planePos = o.xy + d.xy * t; + if (any(greaterThan(abs(planePos), vec2(1.0)))) { + return vec2(NoHit, NoHit); + } + + return vec2(t, t); +} +#endif + +#if defined(SHAPE_BOX) +vec2 intersectBoxShape(Ray ray) +{ + #if defined(BOUNDS) + vec3 pos = 0.5 * (u_minBounds + u_maxBounds); + vec3 scale = 0.5 * (u_maxBounds - u_minBounds); + + if (any(equal(scale, vec3(0.0)))) { + // Transform the ray into unit space on Z plane + Ray flatRay; + if (scale.x == 0.0) { + flatRay = Ray( + (ray.pos.yzx - pos.yzx) / vec3(scale.yz, 1.0), + ray.dir.yzx / vec3(scale.yz, 1.0) + ); + } else if (scale.y == 0.0) { + flatRay = Ray( + (ray.pos.xzy - pos.xzy) / vec3(scale.xz, 1.0), + ray.dir.xzy / vec3(scale.xz, 1.0) + ); + } else if (scale.z == 0.0) { + flatRay = Ray( + (ray.pos.xyz - pos.xyz) / vec3(scale.xy, 1.0), + ray.dir.xyz / vec3(scale.xy, 1.0) + ); + } + return intersectUnitSquare(flatRay); + } else { + // Transform the ray into "unit space" + Ray unitRay = Ray((ray.pos - pos) / scale, ray.dir / scale); + return intersectUnitCube(unitRay); + } + #else + return intersectUnitCube(ray); + #endif +} +#endif + +#if (defined(SHAPE_CYLINDER) && (defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX))) || (defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX))) +vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); + vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); + + float a1 = dot(o, n1); + float a2 = dot(o, n2); + float b1 = dot(d, n1); + float b2 = dot(d, n2); + + float t1 = -a1 / b1; + float t2 = -a2 / b2; + float s1 = sign(a1); + float s2 = sign(a2); + + float tmin = min(t1, t2); + float tmax = max(t1, t2); + float smin = tmin == t1 ? s1 : s2; + float smax = tmin == t1 ? s2 : s1; + + bool e = tmin >= 0.0; + bool f = tmax >= 0.0; + bool g = smin >= 0.0; + bool h = smax >= 0.0; + + // if () return vec2(tmin, tmax); + // else if () return vec2(NoHitNeg, tmin); + // else if () return vec2(NoHitNeg, tmax); + // else if () return vec2(tmax, NoHitPos); + // else return vec2(NoHit, NoHit); + + if (e != g && f == h) return vec2(tmin, tmax); + else if (e == g && f == h) return vec2(-InfHit, tmin); + else if (e != g && f != h) return vec2(tmax, +InfHit); + else return vec2(NoHit, NoHit); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec2 intersectUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NoHit, NoHit); + } + + det = sqrt(det); + float ta = (-b - det) / a; + float tb = (-b + det) / a; + float t1 = min(ta, tb); + float t2 = max(ta, tb); + + float z1 = o.z + t1 * d.z; + float z2 = o.z + t2 * d.z; + + if (abs(z1) >= 1.0) + { + float tCap = (sign(z1) - o.z) / d.z; + t1 = abs(b + a * tCap) < det ? tCap : NoHit; + } + + if (abs(z2) >= 1.0) + { + float tCap = (sign(z2) - o.z) / d.z; + t2 = abs(b + a * tCap) < det ? tCap : NoHit; + } + + return vec2(t1, t2); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec2 intersectUnitCircle(Ray ray) { + vec3 o = ray.pos; + vec3 d = ray.dir; + + float t = -o.z / d.z; + vec2 zPlanePos = o.xy + d.xy * t; + float distSqr = dot(zPlanePos, zPlanePos); + + if (distSqr > 1.0) { + return vec2(NoHit, NoHit); + } + + return vec2(t, t); +} +#endif + +#if defined(SHAPE_CYLINDER) && defined(BOUNDS_0_MIN) +vec2 intersectInfiniteUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NoHit, NoHit); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec2 intersectCylinderShape(Ray ray) +{ + #if !defined(BOUNDS) + return intersectUnitCylinder(ray); + #else + float minRadius = u_minBounds.x; // [0,1] + float maxRadius = u_maxBounds.x; // [0,1] + float minHeight = u_minBounds.y; // [-1,+1] + float maxHeight = u_maxBounds.y; // [-1,+1] + float minAngle = u_minBounds.z; // [-pi,+pi] + float maxAngle = u_maxBounds.z; // [-pi,+pi] + + float posZ = 0.5 * (minHeight + maxHeight); + vec3 pos = vec3(0.0, 0.0, posZ); + float scaleZ = 0.5 * (maxHeight - minHeight); + + vec2 outerIntersect; + + // TODO: use define instead of branch + if (scaleZ == 0.0) { + vec3 outerScale = vec3(maxRadius, maxRadius, 1.0); + Ray outerRay = Ray((ray.pos - pos) / outerScale, ray.dir / outerScale); + outerIntersect = intersectUnitCircle(outerRay); + } else { + vec3 outerScale = vec3(maxRadius, maxRadius, scaleZ); + Ray outerRay = Ray((ray.pos - pos) / outerScale, ray.dir / outerScale); + outerIntersect = intersectUnitCylinder(outerRay); + } + + if (outerIntersect == vec2(NoHit, NoHit)) { + return vec2(NoHit, NoHit); + } + + vec2 intersections[SHAPE_INTERSECTION_COUNT]; + intersections[0] = vec2(float(0), outerIntersect.x); + intersections[1] = vec2(float(1), outerIntersect.y); + + #if defined(BOUNDS_0_MIN) + vec3 innerScale = vec3(minRadius, minRadius, 1.0); + Ray innerRay = Ray((ray.pos - pos) / innerScale, ray.dir / innerScale); + vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + + // TODO: use define instead of branch + if (minRadius != maxRadius) { + intersections[2] = vec2(float(2), innerIntersect.x); + intersections[3] = vec2(float(3), innerIntersect.y); + } else { + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If resolveIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + + intersections[0] = vec2(float(0), outerIntersect.x); + intersections[1] = vec2(float(2), innerIntersect.x); + intersections[2] = vec2(float(3), innerIntersect.y); + intersections[3] = vec2(float(1), outerIntersect.y); + } + #endif + + #if defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX) + vec2 wedgeIntersect = intersectWedge(ray, minAngle, maxAngle); + intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); + intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); + #endif + + return resolveIntersections(intersections); + #endif +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec2 intersectUnitSphere(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - c; + + if (det < 0.0) { + return vec2(NoHit, NoHit); + } + + det = sqrt(det); + float t1 = -b - det; + float t2 = -b + det; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && defined(BOUNDS_2_MIN) +vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d, d); + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NoHit, NoHit); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) +// TODO: can angle and direction be folded into the same parameter +vec2 intersectUncappedCone(Ray ray, float angle, float direction) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + float s = direction; + float h = max(0.01, angle); // float fix + + float hh = h * h; + float ds = d[2] * s; + float os = o[2] * s; + float od = dot(o, d); + float oo = dot(o, o); + + float a = ds * ds - hh; + float b = ds * os - od * hh; + float c = os * os - oo * hh; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NoHit, NoHit); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + float h1 = (o[2] + tmin * d[2]) * s; + float h2 = (o[2] + tmax * d[2]) * s; + + if (h1 < 0.0 && h2 < 0.0) { + return vec2(NoHit, NoHit); + } + + else if (h1 < 0.0) return vec2(tmax, NoHitPos); + else if (h2 < 0.0) return vec2(NoHitNeg, tmin); + else return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && defined(BOUNDS) +vec2 intersectClippedEllipsoid(Ray ray, vec3 minBounds, vec3 maxBounds) +{ + float lonMin = minBounds.x + 0.5 * czm_pi; // [-pi,+pi] + float lonMax = maxBounds.x + 0.5 * czm_pi; // [-pi,+pi] + float latMin = minBounds.y; // [-halfPi,+halfPi] + float latMax = maxBounds.y; // [-halfPi,+halfPi] + float heightMin = minBounds.z; // [-inf,+inf] + float heightMax = maxBounds.z; // [-inf,+inf] + + vec2 outerIntersect = intersectUnitSphere(ray); + if (outerIntersect == vec2(NoHit, NoHit)) { + return vec2(NoHit, NoHit); + } + + float intersections[SHAPE_INTERSECTION_COUNT]; + intersections[BOUNDS_2_MAX_IDX * 2 + 0] = outerIntersect.x; + intersections[BOUNDS_2_MAX_IDX * 2 + 1] = outerIntersect.y; + + #if defined(BOUNDS_2_MIN) + float innerScale = heightMin; + Ray innerRay = Ray(ray.pos / innerScale, ray.dir / innerScale); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + intersections[BOUNDS_2_MIN_IDX * 2 + 0] = innerIntersect.x; + intersections[BOUNDS_2_MIN_IDX * 2 + 1] = innerIntersect.y; + #endif + + #if defined(BOUNDS_1_MIN) + vec2 botConeIntersect = intersectUncappedCone(ray, abs(latMin), sign(latMin)); + intersections[BOUNDS_1_MIN_IDX * 2 + 0] = botConeIntersect.x; + intersections[BOUNDS_1_MIN_IDX * 2 + 1] = botConeIntersect.y; + #endif + + #if defined(BOUNDS_1_MAX) + vec2 topConeIntersect = intersectUncappedCone(ray, abs(latMax), sign(latMax)); + intersections[BOUNDS_1_MAX_IDX * 2 + 0] = topConeIntersect.x; + intersections[BOUNDS_1_MAX_IDX * 2 + 1] = topConeIntersect.y; + #endif + + #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) + vec3 planeNormal1 = -vec3(cos(lonMin), sin(lonMin), 0.0); + vec3 planeNormal2 = vec3(cos(lonMax), sin(lonMax), 0.0); + vec2 wedgeIntersect = intersectWedge(ray, planeNormal1, planeNormal2); + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = wedgeIntersect.x; + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = wedgeIntersect.y; + #endif + + return resolveIntersections(intersections); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +// robust iterative solution without trig functions +// https://github.com/0xfaded/ellipse_demo/issues/1 +// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse + +float ellipseDistanceIterative (vec2 p, in vec2 ab) { + float px = abs(p[0]); + float py = abs(p[1]); + + float tx = 0.707; + float ty = 0.707; + + float a = ab.x; + float b = ab.y; + + for (int i = 0; i < 3; i++) { + float x = a * tx; + float y = b * ty; + + float ex = (a*a - b*b) * pow(tx, 3.0) / a; + float ey = (b*b - a*a) * pow(ty, 3.0) / b; + + float rx = x - ex; + float ry = y - ey; + + float qx = px - ex; + float qy = py - ey; + + float r = sqrt(ry * ry + rx * rx); + float q = sqrt(qy * qy + qx * qx); + + tx = clamp((qx * r / q + ex) / a, 0.0, 1.0); + ty = clamp((qy * r / q + ey) / b, 0.0, 1.0); + float t = sqrt(ty * ty + tx * tx); + tx /= t; + ty /= t; + } + + float cX = a * tx; + float cY = b * ty; + vec2 pos = vec2(cX * sign(p[0]), cY * sign(p[1])); + return length(pos - p) * sign(py - cY); +} +#endif + +#if defined(SHAPE_BOX) +vec3 transformFromUvToBoxSpace(in vec3 positionUv) { + return positionUv; +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { + // 1) Convert positionUv [0,1] to unit space [-1, +1] in ellipsoid scale space. + // 2) Convert to non-ellipsoid space. Max ellipsoid axis has value 1, anything shorter is < 1. + // 3) Convert 3d position to 2D point relative to ellipse (since radii.x and radii.y are assumed to be equal for WGS84). + // 4) Find closest distance. if distance > 1, it's outside the outer shell, if distance < u_ellipsoidMinimumHeightUv, it's inside the inner shell. + // 5) Compute geodetic surface normal. + // 6) Compute longitude and latitude from geodetic surface normal. + + vec3 posLocal = positionUv * 2.0 - 1.0; // 1 + vec3 pos3D = posLocal * u_ellipsoidOuterRadiiLocal; // 2 + vec2 pos2D = vec2(length(pos3D.xy), pos3D.z); // 3 + float dist = ellipseDistanceIterative(pos2D, u_ellipsoidOuterRadiiLocal.xz); // 4 + vec3 normal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredLocal); // 5 + float longitude = atan(normal.y, normal.x); // 6 + float latitude = asin(normal.z); // 6 + + #if defined(BOUNDS) + float longitudeMin = u_minBounds.x; + float longitudeMax = u_maxBounds.x; + float latitudeMin = u_minBounds.x; + float latitudeMax = u_minBounds.y; + if (longitudeMin > longitudeMax) { + longitudeMin -= czm_twoPi; + if (longitude > longitudeMax) { + longitude -= czm_twoPi; + } + } + float shapeX = (longitude - longitudeMin) * u_boundsLengthInverse.x; // [0, 1] + float shapeY = (latitude - latitudeMin) * u_boundsLengthInverse.y; // [0, 1] + #else + float shapeX = (longitude / czm_pi) * 0.5 + 0.5; + float shapeY = (latitude / czm_piOverTwo) * 0.5 + 0.5; + #endif + + float distMax = 0.0; + float distMin = -u_ellipsoidHeightDifferenceUv; + float shapeZ = (dist - distMin) / (distMax - distMin); + return vec3(shapeX, shapeY, shapeZ); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { + vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] + float radius = length(positionLocal.xy); // [0,1] + float height = positionUv.z; // [0,1] + float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] + return vec3(radius, height, angle); +} +#endif + +vec3 transformFromUvToShapeSpace(in vec3 positionUv) { + #if defined(SHAPE_BOX) + vec3 positionShape = transformFromUvToBoxSpace(positionUv); + #elif defined(SHAPE_ELLIPSOID) + vec3 positionShape = transformFromUvToEllipsoidSpace(positionUv); + #elif defined(SHAPE_CYLINDER) + vec3 positionShape = transformFromUvToCylinderSpace(positionUv); + #endif + + #if defined(BOUNDS) + positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of a shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + #endif + + return positionShape; +} + +#if defined(SHAPE_ELLIPSOID) +vec3 geodeticSurfaceNormalCartographic(float longitude, float latitude) { + float cosLatitude = cos(latitude); + float x = cosLatitude * cos(longitude); + float y = cosLatitude * sin(longitude); + float z = sin(latitude); + return normalize(vec3(x, y, z)); +} +vec3 cartographicToCartesianUv(float longitude, float latitude, float height) { + vec3 normal = geodeticSurfaceNormalCartographic(longitude, latitude); + vec3 k = normal * u_ellipsoidOuterRadiiLocal * u_ellipsoidOuterRadiiLocal; + k /= sqrt(dot(normal, k)); + vec3 final = normal * height + k; + return final * 0.5 + 0.5; +} +#endif + +vec3 transformFromShapeSpaceToUv(in vec3 positionUvShapeSpace) { + #if defined(SHAPE_CYLINDER) + float dist = positionUvShapeSpace.x; + float angle = czm_twoPi * safeMod(positionUvShapeSpace.y, 1.0); + float slice = positionUvShapeSpace.z; + float x = 0.5 + 0.5 * dist * cos(angle); + float y = 0.5 + 0.5 * dist * sin(angle); + float z = slice; + return vec3(x, y, z); + #elif defined(SHAPE_ELLIPSOID) + #if defined(BOUNDS) + float longitudeMin = u_minBounds.x; + float longitudeMax = u_maxBounds.x; + float latitudeMin = u_minBounds.y; + float latitudeMax = u_maxBounds.y; + float longitude = mix(longitudeMin, longitudeMax, positionUvShapeSpace.x); + float latitude = mix(latitudeMin, latitudeMax, positionUvShapeSpace.y); + float height = mix(-u_ellipsoidHeightDifferenceUv, 0.0, positionUvShapeSpace.z); + #else + float longitude = positionUvShapeSpace.x * czm_twoPi - czm_pi; + float latitude = positionUvShapeSpace.y * czm_pi - czm_piOverTwo; + float height = positionUvShapeSpace.z; + #endif + return cartographicToCartesianUv(longitude, latitude, height); + #else + return positionUvShapeSpace; + #endif +} + +// -------------------------------------------------------- +// Megatexture +// -------------------------------------------------------- + +#if defined(MEGATEXTURE_IS_3D) +// TODO: 3D textures have not been implemented yet + +void sampleFrom3DMegatextureAtUv(vec3 uv, out Attributes attributes) +{ + // Looping over the sampler array was causing strange rendering artifacts even though the shader compiled fine. + // Unroling the for loop fixed the problem. + + // for (int i = 0; i < METADATA_COUNT; i++) + // { + // samples[i] = texture3D(u_megatextureTextures[i], uv); + // } + + #if (METADATA_COUNT >= 1) + samples[0] = texture3D(u_megatextureTextures[0], uv); + #endif + #if (METADATA_COUNT >= 2) + samples[1] = texture3D(u_megatextureTextures[1], uv); + #endif + #if (METADATA_COUNT >= 3) + samples[2] = texture3D(u_megatextureTextures[2], uv); + #endif + #if (METADATA_COUNT >= 4) + samples[3] = texture3D(u_megatextureTextures[3], uv); + #endif + + decodeTextureSamples(samples); +} + +// TODO: this function has not been implemented +vec3 indexToUv3D(int index, ivec3 dimensions, vec3 uvScale) +{ + return vec3(0.0); +} + +// TODO: this function has not been tested +void sampleFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex, out Attributes attributes) +{ + // Tile location + vec3 tileUvOffset = indexToUv3d(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + + // Voxel location + vec3 voxelUvOffset = clamp(voxelCoord, vec3(0.5), vec3(voxelDims) - vec2(0.5)) * u_megatextureVoxelSizeUv; + + // Final location in the megatexture + vec3 uv = tileUvOffset + voxelUvOffset; + + for (int i = 0; i < METADATA_COUNT; i++) { + vec4 sample = texture3D(u_megatextureTextures[i], uv); + samples[i] = decodeTextureSample(sample); + } +} + +#else // MEGATEXTURE_IS_2D +/* + How 3D data is stored in a 2D megatexture + + 2D megatexture with a single 2x2x2 voxel tile: + The tile is split into two "slices" by Z: + + 0 1 2 3 + +---+---+---+---+ + | | | | | 3 + +---+---+---+---+ + | | | | | 2 + +---+---+---+---+ + |010|110|011|111| 1 + +---+---+---+---+ + |000|100|001|101| 0 + +---+---+---+---+ + + (The megatexture likes to be power of two even if it means some empty space) + + When the 3D coordinate's Z value is between two slices: + + 2 +---+ + |001| + 1 +-z-+ + |000| + 0 +---+ + + The interpolation between the bottom and the top voxel is 0.5 + More generally, the interpolation is: fract(coord.z - 0.5) +*/ + +vec2 indexToUv2D(int index, ivec2 dimensions, vec2 uvScale) { + int indexX = intMod(index, dimensions.x); + int indexY = index / dimensions.x; + return vec2(indexX, indexY) * uvScale; +} +Attributes sampleFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) +{ + #if defined(NEAREST_SAMPLING) + // Round to the center of the nearest voxel + voxelCoord = floor(voxelCoord) + vec3(0.5); + #endif + + // Tile location + vec2 tileUvOffset = indexToUv2D(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + + // Slice locations + float slice = voxelCoord.z - 0.5; + float sliceLerp = fract(slice); + int sliceIndex = int(floor(slice)); + int sliceIndex0 = intMax(sliceIndex, 0); + int sliceIndex1 = intMin(sliceIndex + 1, voxelDims.z - 1); + vec2 sliceUvOffset0 = indexToUv2D(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 sliceUvOffset1 = indexToUv2D(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + + // Voxel location + vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDims.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; + + // Final location in the megatexture + vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; + vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; + + #if defined(NEAREST_SAMPLING) + return sampleFrom2DMegatextureAtUv(uv0); + #else + Attributes attributes0 = sampleFrom2DMegatextureAtUv(uv0); + Attributes attributes1 = sampleFrom2DMegatextureAtUv(uv1); + return mixAttributes(attributes0, attributes1, sliceLerp); + #endif +} +#endif + +Attributes sampleFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { + vec3 voxelCoord = tileUv * vec3(u_dimensions); + ivec3 dimensions = u_dimensions; + + #if defined(PADDING) + dimensions += u_paddingBefore + u_paddingAfter; + voxelCoord += vec3(u_paddingBefore); + #endif + + #if defined(MEGATEXTURE_IS_3D) + return sampleFrom3DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + #else + return sampleFrom2DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + #endif +} + +// -------------------------------------------------------- +// Octree traversal +// -------------------------------------------------------- + +void getOctreeLeafData(OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { + #if (SAMPLE_COUNT == 1) + sampleDatas[0].megatextureIndex = data.data; + sampleDatas[0].levelsAbove = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT ? 1 : 0; + #else + int leafIndex = data.data; + int leafNodeTexelCount = 2; + // Adding 0.5 moves to the center of the texel + float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; + float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; + + vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); + vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); + vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); + vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); + + float lerp = normU8x2_toFloat(leafData0.xy); + + sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); + sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); + sampleDatas[0].levelsAbove = normU8_toInt(leafData0.z); + sampleDatas[1].levelsAbove = normU8_toInt(leafData0.w); + sampleDatas[0].weight = 1.0 - lerp; + sampleDatas[1].weight = lerp; + #endif +} + +OctreeNodeData getOctreeRootData() { + vec4 rootData = texture2D(u_octreeInternalNodeTexture, vec2(0.0)); + + OctreeNodeData data; + data.data = normU8x2_toInt(rootData.xy); + data.flag = normU8x2_toInt(rootData.zw); + return data; +} + +OctreeNodeData getOctreeChildData(int parentOctreeIndex, ivec3 childCoord) { + int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x; + int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex; + int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow; + vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); + vec4 childData = texture2D(u_octreeInternalNodeTexture, octreeUv); + + OctreeNodeData data; + data.data = normU8x2_toInt(childData.xy); + data.flag = normU8x2_toInt(childData.zw); + return data; +} + +int getOctreeParentIndex(int octreeIndex) { + int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9; + int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow; + vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); + vec4 parentData = texture2D(u_octreeInternalNodeTexture, octreeUv); + int parentOctreeIndex = normU8x2_toInt(parentData.xy); + return parentOctreeIndex; +} + +void traverseOctreeDownwards(in vec3 positionUv, inout ivec4 octreeCoords, inout int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { + float sizeAtLevel = 1.0 / pow(2.0, float(octreeCoords.w)); + vec3 start = vec3(octreeCoords.xyz) * sizeAtLevel; + vec3 end = start + vec3(sizeAtLevel); + + for (int i = 0; i < OCTREE_MAX_LEVELS; i++) { + // Find out which octree child contains the position + // 0 if before center, 1 if after + vec3 center = 0.5 * (start + end); + vec3 childCoord = step(center, positionUv); + + // Get octree coords for the next level down + octreeCoords.xyz = octreeCoords.xyz * 2 + ivec3(childCoord); + octreeCoords.w += 1; + + OctreeNodeData childData = getOctreeChildData(parentOctreeIndex, ivec3(childCoord)); + + if (childData.flag == OCTREE_FLAG_INTERNAL) { + // keep going deeper + start = mix(start, center, childCoord); + end = mix(center, end, childCoord); + parentOctreeIndex = childData.data; + } else { + getOctreeLeafData(childData, sampleDatas); + return; + } + } +} + +void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, out float levelStepMult, out ivec4 octreeCoords, out int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { + levelStepMult = 1.0; + octreeCoords = ivec4(0); + parentOctreeIndex = 0; + + // TODO: is it possible for this to be out of bounds, and does it matter? + positionUvShapeSpace = transformFromUvToShapeSpace(positionUv); + positionUvLocal = positionUvShapeSpace; + + OctreeNodeData rootData = getOctreeRootData(); + if (rootData.flag == OCTREE_FLAG_LEAF) { + // No child data, only the root tile has data + getOctreeLeafData(rootData, sampleDatas); + } + else + { + traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); + levelStepMult = 1.0 / pow(2.0, float(octreeCoords.w)); + vec3 boxStart = vec3(octreeCoords.xyz) * levelStepMult; + positionUvLocal = (positionUvShapeSpace - boxStart) / levelStepMult; + } +} + +void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, inout float levelStepMult, inout ivec4 octreeCoords, inout int parentOctreeIndex, inout SampleData sampleDatas[SAMPLE_COUNT]) { + float dimAtLevel = pow(2.0, float(octreeCoords.w)); + positionUvShapeSpace = transformFromUvToShapeSpace(positionUv); + positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); + + // Note: This code assumes the position is always inside the root tile. + bool insideTile = octreeCoords.w == 0 || inRange(positionUvLocal, vec3(0.0), vec3(1.0)); + + if (!insideTile) + { + // Go up tree + for (int i = 0; i < OCTREE_MAX_LEVELS; i++) + { + octreeCoords.xyz /= ivec3(2); + octreeCoords.w -= 1; + dimAtLevel /= 2.0; + + positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); + insideTile = octreeCoords.w == 0 || inRange(positionUvLocal, vec3(0.0), vec3(1.0)); + + if (!insideTile) { + parentOctreeIndex = getOctreeParentIndex(parentOctreeIndex); + } else { + break; + } + } + + // Go down tree + traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); + levelStepMult = 1.0 / pow(2.0, float(octreeCoords.w)); + positionUvLocal = positionUvShapeSpace / levelStepMult - vec3(octreeCoords.xyz); + } +} + +// Convert an array of mixed-resolution sample datas to a final weighted sample. +Attributes getSamplesAtLocalPosition(in vec3 positionUvLocal, in ivec4 octreeCoords, in SampleData sampleDatas[SAMPLE_COUNT]) { + // In some cases positionUvLocal goes outside the 0 to 1 bounds, such as when sampling neighbor voxels on the edge of a tile. + // This needs to be handled carefully, especially for mixed resolution, or else the wrong part of the tile is read. + // https://www.wolframalpha.com/input/?i=sign%28x%29+*+max%280%2C+%28abs%28x-0.5%29-0.5%29%29 + vec3 overflow = sign(positionUvLocal) * max(abs(positionUvLocal - vec3(0.5)) - vec3(0.5), vec3(0.0)); + positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0 - czm_epsilon6)); // epsilon to avoid fract(1) = 0 situation + + Attributes attributes; + + // When more than one sample is taken the accumulator needs to start at 0 + #if (SAMPLE_COUNT > 1) + attributes = clearAttributes(); + #endif + + for (int i = 0; i < SAMPLE_COUNT; i++) { + SampleData sampleData = sampleDatas[i]; + vec3 actualUvLocal = positionUvLocal; + int levelsAbove = sampleData.levelsAbove; + if (levelsAbove > 0) { + // Calcuate a new local uv relative to the ancestor tile. + float levelsAboveFactor = 1.0 / pow(2.0, float(levelsAbove)); + actualUvLocal = fract((vec3(octreeCoords.xyz) + positionUvLocal) * levelsAboveFactor) + overflow * levelsAboveFactor; + } + + Attributes tempAttributes = sampleFromMegatextureAtTileUv(actualUvLocal, sampleData.megatextureIndex); + + #if (SAMPLE_COUNT == 1) + attributes = tempAttributes; + #else + attributes = sumAttributes(attributes, tempAttributes) + #endif + } + return attributes; +} + +Attributes getSamplesAtPosition(vec3 positionUv, vec4 outOfBoundsValue) { + vec3 positionUvShapeSpace; + vec3 positionUvLocal; + float levelStepMult; + ivec4 octreeCoords; + int parentOctreeIndex; + SampleData sampleDatas[SAMPLE_COUNT]; + traverseOctree(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); + return getSamplesAtLocalPosition(positionUvLocal, octreeCoords, sampleDatas); +} +Attributes getSamplesAtPosition(vec3 positionUv) { + return getSamplesAtPosition(positionUv, vec4(0.0)); +} + +// void getNormalAtPosition(ivec4 octreeCoords, vec3 positionUvShapeSpace, vec3 positionUvLocal, SampleData sampleDatas[SAMPLE_COUNT], out vec3 normalLocalSpace[METADATA_COUNT], out vec3 normalWorldSpace[METADATA_COUNT], out vec3 normalViewSpace[METADATA_COUNT], out bool valid[METADATA_COUNT]) { +// for (int i = 0; i < METADATA_COUNT; i++){ +// valid[i] = true; +// } + +// Attributes attributes; +// #define USE_SIMPLE_NORMALS +// #if defined(NEIGHBORS_INCLUDED_ON_TILE_EDGES) || defined(USE_SIMPLE_NORMALS) +// // There might be small seam artifacts when the edge count is 1 or less. +// float sampleL[METADATA_COUNT]; +// float sampleR[METADATA_COUNT]; +// float sampleD[METADATA_COUNT]; +// float sampleU[METADATA_COUNT]; +// float sampleB[METADATA_COUNT]; +// float sampleF[METADATA_COUNT]; +// getSamplesAtLocalPosition(positionUvLocal + vec3(-1.0, 0.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleL[i] = attributes[i].a; +// } +// getSamplesAtLocalPosition(positionUvLocal + vec3(+1.0, 0.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleR[i] = attributes[i].a; +// } +// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, -1.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleD[i] = attributes[i].a; +// } +// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, +1.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleU[i] = attributes[i].a; +// } +// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, 0.0, -1.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleB[i] = attributes[i].a; +// } +// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, 0.0, +1.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); +// for(int i = 0; i < METADATA_COUNT; i++) { +// sampleF[i] = attributes[i].a; +// } +// #else +// float dimAtLevel = pow(2.0, float(octreeCoords.w)); +// vec3 voxelSizeShapeSpace = 1.0 / (dimAtLevel * vec3(u_dimensions)); + +// // There might be small seam artifacts when the edge count is 0 +// float sampleL[METADATA_COUNT]; +// float sampleR[METADATA_COUNT]; +// float sampleD[METADATA_COUNT]; +// float sampleU[METADATA_COUNT]; +// float sampleB[METADATA_COUNT]; +// float sampleF[METADATA_COUNT]; +// getSamplesAtPosition(transformFromShapeSpaceToUv(positionUvShapeSpace - vec3(voxelSizeShapeSpace.x, 0.0, 0.0), attributes)); +// for(int i; i= nonZeroMax) { + colorAccum.a = colorAccumTemp.a; + colorAccum.rgb += colorAccumTemp.rgb; + colorAccumTemp = vec4(0.0); + nonZeroCount = 0; + } + } + #else + colorAccum += (1.0 - colorAccum.a) * vec4(finalSample.rgb * finalSample.a, finalSample.a); + #endif + + // Stop traversing if the alpha has been fully saturated + if (colorAccum.a > alphaAccumMax) { + colorAccum.a = alphaAccumMax; + break; + } + + // Keep raymarching + currT += stepT; + positionUv += stepT * viewDirUv; + + // Check if the ray is occluded by the depth + #if defined(DEPTH_TEST) + if (currT >= depthT) { + break; + } + #endif + + // Check if the ray has entered empty space. If so, do another intersection test + // to see if there is more of the shape to intersect. If there isn't, the raymarch is over. + if (currT > endT) { + vec2 tEntryExit = intersectShape(positionUv, viewDirUv); + if (tEntryExit == vec2(NoHit, NoHit)) { + break; + } + currT += tEntryExit.x; + endT += tEntryExit.y; + positionUv += tEntryExit.x * viewDirUv; + } + + // Traverse the octree from the current ray position. + // This is an optimized alternative to traverseOctree that expects the + // ray to stay in the same tile on average. Otherwise it will traverse + // upwards and back downwards. + traverseOctreeFromExisting(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); + stepT = u_stepSize * levelStepMult; + } + + // Convert the alpha from [0,alphaAccumMax] to [0,1] + colorAccum.a /= alphaAccumMax; + + #if defined(PICKING) + // If alpha is 0.0, there is nothing to pick + if (colorAccum.a == 0.0) { + discard; + } + gl_FragColor = u_pickColor; + #else + gl_FragColor = colorAccum; + #endif +} \ No newline at end of file diff --git a/Source/Shaders/VoxelVS.glsl b/Source/Shaders/VoxelVS.glsl new file mode 100644 index 00000000000..6c29c959b1c --- /dev/null +++ b/Source/Shaders/VoxelVS.glsl @@ -0,0 +1,11 @@ +attribute vec2 position; + +uniform vec4 u_ndcSpaceAxisAlignedBoundingBox; + +void main() { + vec2 aabbMin = u_ndcSpaceAxisAlignedBoundingBox.xy; + vec2 aabbMax = u_ndcSpaceAxisAlignedBoundingBox.zw; + vec2 translation = 0.5 * (aabbMax + aabbMin); + vec2 scale = 0.5 * (aabbMax - aabbMin); + gl_Position = vec4(position * scale + translation, 0.0, 1.0); +} diff --git a/Source/Widgets/CesiumInspector/CesiumInspector.css b/Source/Widgets/CesiumInspector/CesiumInspector.css index ca721ca1929..cea597ff95d 100644 --- a/Source/Widgets/CesiumInspector/CesiumInspector.css +++ b/Source/Widgets/CesiumInspector/CesiumInspector.css @@ -54,7 +54,7 @@ margin: 5px 0; font-family: sans-serif; font-size: 10pt; - width: 185px; + width: 100%; } .cesium-cesiumInspector-frustumStatistics { diff --git a/Source/Widgets/Viewer/Viewer.css b/Source/Widgets/Viewer/Viewer.css index e5a5644fb3f..bbae808bbdf 100644 --- a/Source/Widgets/Viewer/Viewer.css +++ b/Source/Widgets/Viewer/Viewer.css @@ -105,3 +105,14 @@ overflow-y: auto; overflow-x: hidden; } + +.cesium-viewer-voxelInspectorContainer { + display: block; + position: absolute; + top: 50px; + right: 10px; + max-height: calc(100% - 120px); + box-sizing: border-box; + overflow-y: auto; + overflow-x: hidden; +} diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js index a24bdfc313e..5319e2eb7df 100644 --- a/Source/Widgets/Viewer/Viewer.js +++ b/Source/Widgets/Viewer/Viewer.js @@ -24,6 +24,7 @@ import computeFlyToLocationForRectangle from "../../Scene/computeFlyToLocationFo import ImageryLayer from "../../Scene/ImageryLayer.js"; import SceneMode from "../../Scene/SceneMode.js"; import TimeDynamicPointCloud from "../../Scene/TimeDynamicPointCloud.js"; +import VoxelPrimitive from "../../Scene/VoxelPrimitive.js"; import knockout from "../../ThirdParty/knockout.js"; import Animation from "../Animation/Animation.js"; import AnimationViewModel from "../Animation/AnimationViewModel.js"; @@ -2103,14 +2104,11 @@ function zoomToOrFly(that, zoomTarget, options, isFlight) { return; } - //If the zoom target is a Cesium3DTileset - if (zoomTarget instanceof Cesium3DTileset) { - that._zoomTarget = zoomTarget; - return; - } - - //If the zoom target is a TimeDynamicPointCloud - if (zoomTarget instanceof TimeDynamicPointCloud) { + if ( + zoomTarget instanceof Cesium3DTileset || + zoomTarget instanceof TimeDynamicPointCloud || + zoomTarget instanceof VoxelPrimitive + ) { that._zoomTarget = zoomTarget; return; } @@ -2189,47 +2187,11 @@ function updateZoomTarget(viewer) { const zoomOptions = defaultValue(viewer._zoomOptions, {}); let options; - // If zoomTarget was Cesium3DTileset - if (target instanceof Cesium3DTileset) { - return target.readyPromise.then(function () { - const boundingSphere = target.boundingSphere; - // If offset was originally undefined then give it base value instead of empty object - if (!defined(zoomOptions.offset)) { - zoomOptions.offset = new HeadingPitchRange( - 0.0, - -0.5, - boundingSphere.radius - ); - } - - options = { - offset: zoomOptions.offset, - duration: zoomOptions.duration, - maximumHeight: zoomOptions.maximumHeight, - complete: function () { - zoomPromise.resolve(true); - }, - cancel: function () { - zoomPromise.resolve(false); - }, - }; - - if (viewer._zoomIsFlight) { - camera.flyToBoundingSphere(target.boundingSphere, options); - } else { - camera.viewBoundingSphere(boundingSphere, zoomOptions.offset); - camera.lookAtTransform(Matrix4.IDENTITY); - - // Finish the promise - zoomPromise.resolve(true); - } - - clearZoom(viewer); - }); - } - - // If zoomTarget was TimeDynamicPointCloud - if (target instanceof TimeDynamicPointCloud) { + if ( + target instanceof Cesium3DTileset || + target instanceof TimeDynamicPointCloud || + target instanceof VoxelPrimitive + ) { return target.readyPromise.then(function () { const boundingSphere = target.boundingSphere; // If offset was originally undefined then give it base value instead of empty object diff --git a/Source/Widgets/Viewer/viewerVoxelInspectorMixin.js b/Source/Widgets/Viewer/viewerVoxelInspectorMixin.js new file mode 100644 index 00000000000..1c4b963adbe --- /dev/null +++ b/Source/Widgets/Viewer/viewerVoxelInspectorMixin.js @@ -0,0 +1,34 @@ +import Check from "../../Core/Check.js"; +import VoxelInspector from "../VoxelInspector/VoxelInspector.js"; + +/** + * A mixin which adds the {@link VoxelInspector} widget to the {@link Viewer} widget. + * Rather than being called directly, this function is normally passed as + * a parameter to {@link Viewer#extend}, as shown in the example below. + * @function + * + * @param {Viewer} viewer The viewer instance. + * + * @example + * var viewer = new Cesium.Viewer('cesiumContainer'); + * viewer.extend(Cesium.viewerVoxelInspectorMixin); + */ +function viewerVoxelInspectorMixin(viewer) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("viewer", viewer); + //>>includeEnd('debug'); + + const container = document.createElement("div"); + container.className = "cesium-viewer-voxelInspectorContainer"; + viewer.container.appendChild(container); + const voxelInspector = new VoxelInspector(container, viewer.scene); + + Object.defineProperties(viewer, { + voxelInspector: { + get: function () { + return voxelInspector; + }, + }, + }); +} +export default viewerVoxelInspectorMixin; diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.css b/Source/Widgets/VoxelInspector/VoxelInspector.css new file mode 100644 index 00000000000..60cae4fd30d --- /dev/null +++ b/Source/Widgets/VoxelInspector/VoxelInspector.css @@ -0,0 +1,121 @@ +ul.cesium-cesiumInspector-statistics { + margin: 0; + padding-top: 3px; + padding-bottom: 3px; +} + +ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { + border-top: 1px solid #aaa; +} + +.cesium-cesiumInspector-slider { + margin-top: 5px; +} + +.cesium-cesiumInspector-visible { + width: 400px; + height: auto; +} + +.cesium-cesiumInspector-slider input[type="number"] { + text-align: left; + background-color: #222; + outline: none; + border: 1px solid #444; + color: #edffff; + width: 100px; + border-radius: 3px; + padding: 1px; + margin-left: 10px; + cursor: auto; +} + +.cesium-cesiumInspector-slider input[type="number"]::-webkit-outer-spin-button, +.cesium-cesiumInspector-slider input[type="number"]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.cesium-cesiumInspector-slider input[type="range"] { + margin-left: 5px; + vertical-align: middle; +} + +.cesium-cesiumInspector-hide .cesium-cesiumInspector-styleEditor { + display: none; +} + +.cesium-cesiumInspector-styleEditor { + padding: 10px; + border-radius: 5px; + background: rgba(48, 51, 54, 0.8); + border: 1px solid #444; +} + +.cesium-cesiumInspector-styleEditor textarea { + width: 100%; + height: 300px; + background: transparent; + color: #edffff; + border: none; + padding: 1px; + white-space: pre; + overflow-wrap: normal; + overflow-x: auto; +} + +.cesium-3DTilesInspector { + width: 300px; + pointer-events: all; +} + +.cesium-3DTilesInspector-statistics { + font-size: 11px; +} + +.cesium-3DTilesInspector div, +.cesium-3DTilesInspector input[type="range"] { + width: 100%; + box-sizing: border-box; +} + +.cesium-cesiumInspector-error { + color: #ff9e9e; + overflow: auto; +} + +.cesium-3DTilesInspector .cesium-cesiumInspector-section { + margin-top: 3px; +} + +.cesium-3DTilesInspector + .cesium-cesiumInspector-sectionHeader + + .cesium-cesiumInspector-show { + border-top: 1px solid white; +} + +input.cesium-cesiumInspector-url { + overflow: hidden; + white-space: nowrap; + overflow-x: scroll; + background-color: transparent; + color: white; + outline: none; + border: none; + height: 1em; + width: 100%; +} + +.cesium-cesiumInspector .field-group { + display: table; +} + +.cesium-cesiumInspector .field-group > label { + display: table-cell; + font-weight: bold; +} + +.cesium-cesiumInspector .field-group > .field { + display: table-cell; + width: 100%; +} diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js new file mode 100644 index 00000000000..1f360e67ef2 --- /dev/null +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -0,0 +1,422 @@ +import CesiumMath from "../../Core/Math.js"; +import Check from "../../Core/Check.js"; +import defaultValue from "../../Core/defaultValue.js"; +import defined from "../../Core/defined.js"; +import destroyObject from "../../Core/destroyObject.js"; +import knockout from "../../ThirdParty/knockout.js"; +import getElement from "../getElement.js"; +import InspectorShared from "../InspectorShared.js"; +import VoxelInspectorViewModel from "./VoxelInspectorViewModel.js"; +import VoxelBoxShape from "../../Scene/VoxelBoxShape.js"; +import VoxelCylinderShape from "../../Scene/VoxelCylinderShape.js"; +import VoxelEllipsoidShape from "../../Scene/VoxelEllipsoidShape.js"; + +/** + * Inspector widget to aid in debugging voxels + * + * @alias VoxelInspector + * @constructor + * + * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Scene} scene the Scene instance to use. + */ +function VoxelInspector(container, scene) { + //>>includeStart('debug', pragmas.debug); + Check.defined("container", container); + Check.typeOf.object("scene", scene); + //>>includeEnd('debug'); + + container = getElement(container); + const element = document.createElement("div"); + const viewModel = new VoxelInspectorViewModel(scene); + + const text = document.createElement("div"); + text.textContent = "Voxel Inspector"; + text.className = "cesium-cesiumInspector-button"; + text.setAttribute("data-bind", "click: inspectorVisibleToggle"); + element.appendChild(text); + element.className = "cesium-cesiumInspector cesium-VoxelInspector"; + element.setAttribute( + "data-bind", + 'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}' + ); + container.appendChild(element); + + const panel = document.createElement("div"); + panel.className = "cesium-cesiumInspector-dropDown"; + element.appendChild(panel); + + const createSection = InspectorShared.createSection; + const createCheckbox = InspectorShared.createCheckbox; + + // Display + const displayPanelContents = createSection( + panel, + "Display", + "displayVisible", + "displayVisibleToggle" + ); + + displayPanelContents.appendChild(createCheckbox("Depth Test", "depthTest")); + displayPanelContents.appendChild(createCheckbox("Show", "show")); + displayPanelContents.appendChild( + createCheckbox("Disable Update", "disableUpdate") + ); + displayPanelContents.appendChild(createCheckbox("Debug Draw", "debugDraw")); + displayPanelContents.appendChild(createCheckbox("Jitter", "jitter")); + displayPanelContents.appendChild( + createCheckbox("Nearest Sampling", "nearestSampling") + ); + displayPanelContents.appendChild(createCheckbox("Despeckle", "despeckle")); + + const screenSpaceErrorContainer = document.createElement("div"); + screenSpaceErrorContainer.appendChild( + makeRangeInput("Screen Space Error", "screenSpaceError", 0, 128) + ); + displayPanelContents.appendChild(screenSpaceErrorContainer); + + const stepSizeContainer = document.createElement("div"); + stepSizeContainer.appendChild( + makeRangeInput("Step Size", "stepSize", 0.0, 2.0) + ); + displayPanelContents.appendChild(stepSizeContainer); + + // Transform + const transformPanelContents = createSection( + panel, + "Transform", + "transformVisible", + "transformVisibleToggle" + ); + + const maxTrans = 20000000.0; + const maxScale = 20000000.0; + const maxAngle = CesiumMath.PI; + + transformPanelContents.appendChild( + makeRangeInput("Translation X", "translationX", -maxTrans, +maxTrans) + ); + transformPanelContents.appendChild( + makeRangeInput("Translation Y", "translationY", -maxTrans, +maxTrans) + ); + transformPanelContents.appendChild( + makeRangeInput("Translation Z", "translationZ", -maxTrans, +maxTrans) + ); + transformPanelContents.appendChild( + makeRangeInput("Scale X", "scaleX", -maxScale, +maxScale) + ); + transformPanelContents.appendChild( + makeRangeInput("Scale Y", "scaleY", -maxScale, +maxScale) + ); + transformPanelContents.appendChild( + makeRangeInput("Scale Z", "scaleZ", -maxScale, +maxScale) + ); + transformPanelContents.appendChild( + makeRangeInput("Heading", "angleX", -maxAngle, +maxAngle) + ); + transformPanelContents.appendChild( + makeRangeInput("Pitch", "angleY", -maxAngle, +maxAngle) + ); + transformPanelContents.appendChild( + makeRangeInput("Roll", "angleZ", -maxAngle, +maxAngle) + ); + + // Bounds + const boundsPanelContents = createSection( + panel, + "Bounds", + "boundsVisible", + "boundsVisibleToggle" + ); + + makeCoordinateRange( + "Max X", + "Min X", + "Max Y", + "Min Y", + "Max Z", + "Min Z", + "boundsBoxMaxX", + "boundsBoxMinX", + "boundsBoxMaxY", + "boundsBoxMinY", + "boundsBoxMaxZ", + "boundsBoxMinZ", + VoxelBoxShape.DefaultMinBounds, + VoxelBoxShape.DefaultMaxBounds, + "shapeIsBox", + boundsPanelContents + ); + + makeCoordinateRange( + "Max Longitude", + "Min Longitude", + "Max Latitude", + "Min Latitude", + "Max Height", + "Min Height", + "boundsEllipsoidMaxLongitude", + "boundsEllipsoidMinLongitude", + "boundsEllipsoidMaxLatitude", + "boundsEllipsoidMinLatitude", + "boundsEllipsoidMaxHeight", + "boundsEllipsoidMinHeight", + VoxelEllipsoidShape.DefaultMinBounds, + VoxelEllipsoidShape.DefaultMaxBounds, + "shapeIsEllipsoid", + boundsPanelContents + ); + + makeCoordinateRange( + "Max Radius", + "Min Radius", + "Max Height", + "Min Height", + "Max Angle", + "Min Angle", + "boundsCylinderMaxRadius", + "boundsCylinderMinRadius", + "boundsCylinderMaxHeight", + "boundsCylinderMinHeight", + "boundsCylinderMaxAngle", + "boundsCylinderMinAngle", + VoxelCylinderShape.DefaultMinBounds, + VoxelCylinderShape.DefaultMaxBounds, + "shapeIsCylinder", + boundsPanelContents + ); + + // Clipping + const clippingPanelContents = createSection( + panel, + "Clipping", + "clippingVisible", + "clippingVisibleToggle" + ); + + makeCoordinateRange( + "Max X", + "Min X", + "Max Y", + "Min Y", + "Max Z", + "Min Z", + "clippingBoxMaxX", + "clippingBoxMinX", + "clippingBoxMaxY", + "clippingBoxMinY", + "clippingBoxMaxZ", + "clippingBoxMinZ", + VoxelBoxShape.DefaultMinBounds, + VoxelBoxShape.DefaultMaxBounds, + "shapeIsBox", + clippingPanelContents + ); + + makeCoordinateRange( + "Max Longitude", + "Min Longitude", + "Max Latitude", + "Min Latitude", + "Max Height", + "Min Height", + "clippingEllipsoidMaxLongitude", + "clippingEllipsoidMinLongitude", + "clippingEllipsoidMaxLatitude", + "clippingEllipsoidMinLatitude", + "clippingEllipsoidMaxHeight", + "clippingEllipsoidMinHeight", + VoxelEllipsoidShape.DefaultMinBounds, + VoxelEllipsoidShape.DefaultMaxBounds, + "shapeIsEllipsoid", + clippingPanelContents + ); + + makeCoordinateRange( + "Max Radius", + "Min Radius", + "Max Height", + "Min Height", + "Max Angle", + "Min Angle", + "clippingCylinderMaxRadius", + "clippingCylinderMinRadius", + "clippingCylinderMaxHeight", + "clippingCylinderMinHeight", + "clippingCylinderMaxAngle", + "clippingCylinderMinAngle", + VoxelCylinderShape.DefaultMinBounds, + VoxelCylinderShape.DefaultMaxBounds, + "shapeIsCylinder", + clippingPanelContents + ); + + // Style + const stylePanelContents = createSection( + panel, + "Style", + "styleVisible", + "styleVisibleToggle" + ); + const stylePanelEditor = document.createElement("div"); + stylePanelContents.appendChild(stylePanelEditor); + + const styleEditor = document.createElement("textarea"); + styleEditor.setAttribute( + "data-bind", + "textInput: styleString, event: { keydown: styleEditorKeyPress }" + ); + stylePanelEditor.className = "cesium-cesiumInspector-styleEditor"; + stylePanelEditor.appendChild(styleEditor); + const compileStyleButton = makeButton("compileStyle", "Compile (Ctrl+Enter)"); + stylePanelEditor.appendChild(compileStyleButton); + + const compilationText = document.createElement("label"); + compilationText.style.display = "block"; + compilationText.setAttribute( + "data-bind", + "text: styleCompilationMessage, style: {color: styleCompilationSuccess ? 'green' : 'red'}" + ); + stylePanelEditor.appendChild(compilationText); + + knockout.applyBindings(viewModel, element); + + this._viewModel = viewModel; + this._container = container; + this._element = element; + this._panel = panel; +} + +Object.defineProperties(VoxelInspector.prototype, { + /** + * Gets the view model. + * @memberof VoxelInspector.prototype + * + * @type {VoxelInspectorViewModel} + */ + viewModel: { + get: function () { + return this._viewModel; + }, + }, +}); + +/** + * @returns {Boolean} true if the object has been destroyed, false otherwise. + */ +VoxelInspector.prototype.isDestroyed = function () { + return false; +}; + +/** + * Destroys the widget. Should be called if permanently + * removing the widget from layout. + */ +VoxelInspector.prototype.destroy = function () { + knockout.cleanNode(this._element); + this._container.removeChild(this._element); + this.viewModel.destroy(); + + return destroyObject(this); +}; + +function makeRangeInput(text, property, min, max, step, displayProperty) { + step = defaultValue(step, 0.01); + displayProperty = defaultValue(displayProperty, property); + const input = document.createElement("input"); + input.setAttribute("data-bind", `value: ${displayProperty}`); + input.type = "number"; + + const slider = document.createElement("input"); + slider.type = "range"; + slider.min = min; + slider.max = max; + slider.step = step; + slider.setAttribute("data-bind", `valueUpdate: "input", value: ${property}`); + + const wrapper = document.createElement("div"); + wrapper.appendChild(slider); + + const container = document.createElement("div"); + container.className = "cesium-cesiumInspector-slider"; + container.appendChild(document.createTextNode(text)); + container.appendChild(input); + container.appendChild(wrapper); + + return container; +} + +// function makeTestSlider(text, property, min, max, step, displayProperty) { +// displayProperty = defaultValue(displayProperty, property); +// const input = document.createElement('input'); +// // input.setAttribute('data-bind', 'value: ' + displayProperty); +// input.setAttribute('data-bind', 'attr: {min: 1, max: MaxPage}, value: ' + displayProperty); + +// input.type = 'number'; + +// const slider = document.createElement('input'); +// slider.type = 'range'; +// slider.min = min; +// slider.max = max; +// slider.step = step; +// slider.setAttribute('data-bind', 'valueUpdate: "input", value: ' + property); + +// const wrapper = document.createElement('div'); +// wrapper.appendChild(slider); + +// const container = document.createElement('div'); +// container.className = 'cesium-cesiumInspector-slider'; +// container.appendChild(document.createTextNode(text)); +// container.appendChild(input); +// container.appendChild(wrapper); + +// return container; +// } + +function makeButton(action, text, active) { + const button = document.createElement("button"); + button.type = "button"; + button.textContent = text; + button.className = "cesium-cesiumInspector-pickButton"; + let binding = `click: ${action}`; + if (defined(active)) { + binding += `, css: {"cesium-cesiumInspector-pickButtonHighlight" : ${active}}`; + } + button.setAttribute("data-bind", binding); + + return button; +} + +function makeCoordinateRange( + maxXTitle, + minXTitle, + maxYTitle, + minYTitle, + maxZTitle, + minZTitle, + maxXVar, + minXVar, + maxYVar, + minYVar, + maxZVar, + minZVar, + defaultMinBounds, + defaultMaxBounds, + allowedShape, + parentContainer +) { + const min = defaultMinBounds; + const max = defaultMaxBounds; + const boundsElement = parentContainer.appendChild( + document.createElement("div") + ); + boundsElement.setAttribute("data-bind", `if: ${allowedShape}`); + boundsElement.appendChild(makeRangeInput(maxXTitle, maxXVar, min.x, max.x)); + boundsElement.appendChild(makeRangeInput(minXTitle, minXVar, min.x, max.x)); + boundsElement.appendChild(makeRangeInput(maxYTitle, maxYVar, min.y, max.y)); + boundsElement.appendChild(makeRangeInput(minYTitle, minYVar, min.y, max.y)); + boundsElement.appendChild(makeRangeInput(maxZTitle, maxZVar, min.z, max.z)); + boundsElement.appendChild(makeRangeInput(minZTitle, minZVar, min.z, max.z)); +} + +export default VoxelInspector; diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js new file mode 100644 index 00000000000..8414b50a1d7 --- /dev/null +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -0,0 +1,1130 @@ +import Cartesian3 from "../../Core/Cartesian3.js"; +import Check from "../../Core/Check.js"; +import defaultValue from "../../Core/defaultValue.js"; +import defined from "../../Core/defined.js"; +import destroyObject from "../../Core/destroyObject.js"; +import HeadingPitchRoll from "../../Core/HeadingPitchRoll.js"; +import Matrix3 from "../../Core/Matrix3.js"; +import Matrix4 from "../../Core/Matrix4.js"; +import CustomShader from "../../Scene/ModelExperimental/CustomShader.js"; +import VoxelShapeType from "../../Scene/VoxelShapeType.js"; +import knockout from "../../ThirdParty/knockout.js"; + +function formatShaderString(str) { + // This function: + // A) removes whitespace lines at the beginning of the string + // B) removes unnecessary spaces from the beginning of each line + + const lines = str.split("\n"); + let firstLineIdx; + for (firstLineIdx = 0; firstLineIdx < lines.length; firstLineIdx++) { + if (lines[firstLineIdx].match(/\S/)) { + // Found the first line that's not entirely whitespace + break; + } + } + if (firstLineIdx === lines.length) { + // All lines are empty + return ""; + } + + let finalStr = ""; + const pattern = /^\s*/; + const firstLine = lines[firstLineIdx]; + const spacesInFrontOfFirstLine = firstLine.match(pattern)[0].length; + for (let i = firstLineIdx; i < lines.length; i++) { + let line = lines[i]; + const spacesInFront = line.match(pattern)[0].length; + if (spacesInFront >= spacesInFrontOfFirstLine) { + line = line.slice(spacesInFrontOfFirstLine); + } + finalStr += `${line}\n`; + } + return finalStr; +} + +/** + * The view model for {@link VoxelInspector}. + * @alias VoxelInspectorViewModel + * @constructor + * + * @param {Scene} scene The scene instance to use. + */ +function VoxelInspectorViewModel(scene) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("scene", scene); + //>>includeEnd('debug'); + + this._scene = scene; + this._voxelPrimitive = undefined; + this._customShaderCompilationRemoveCallback = undefined; + + this._definedProperties = []; + this._getPrimitiveFunctions = []; + + const that = this; + function addProperty(options) { + const name = options.name; + const initialValue = options.initialValue; + const toggle = defaultValue(options.toggle, false); + let setPrimitiveFunction = options.setPrimitiveFunction; + let getPrimitiveFunction = options.getPrimitiveFunction; + + that[name] = initialValue; + that._definedProperties.push(name); + + if (setPrimitiveFunction === true) { + setPrimitiveFunction = function (value) { + that._voxelPrimitive[name] = value; + }; + } + if (getPrimitiveFunction === true) { + getPrimitiveFunction = function () { + that[name] = that._voxelPrimitive[name]; + }; + } + if (defined(getPrimitiveFunction)) { + that._getPrimitiveFunctions.push(getPrimitiveFunction); + } + + if (toggle) { + that.constructor.prototype[`${name}Toggle`] = function () { + that[name] = !that[name]; + }; + } + + const knock = knockout.observable(); + knockout.defineProperty(that, name, { + get: function () { + return knock(); + }, + set: function (value) { + // Convert input values to the correct type + if (typeof initialValue === "number" && typeof value === "string") { + value = Number(value); + if (isNaN(value)) { + value = initialValue; + } + } + if (typeof initialValue === "boolean" && typeof value === "number") { + value = value === 1 ? true : false; + } + knock(value); + if (defined(setPrimitiveFunction) && defined(that._voxelPrimitive)) { + setPrimitiveFunction(value); + scene.requestRender(); + } + }, + }); + return knock; + } + + addProperty({ + name: "inspectorVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "displayVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "styleVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "styleString", + initialValue: "", + getPrimitiveFunction: function () { + const shaderString = that._voxelPrimitive.customShader.fragmentShaderText; + that.styleString = formatShaderString(shaderString); + }, + }); + addProperty({ + name: "styleCompilationMessage", + initialValue: "", + }); + addProperty({ + name: "styleCompilationSuccess", + initialValue: true, + }); + addProperty({ + name: "transformVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "boundsVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "clippingVisible", + initialValue: false, + toggle: true, + }); + addProperty({ + name: "depthTest", + initialValue: false, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "show", + initialValue: true, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "disableUpdate", + initialValue: false, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "debugDraw", + initialValue: false, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "jitter", + initialValue: true, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "nearestSampling", + initialValue: true, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "despeckle", + initialValue: false, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "screenSpaceError", + initialValue: 4.0, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "stepSize", + initialValue: 1.0, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); + addProperty({ + name: "shapeIsBox", + getPrimitiveFunction: function () { + const shapeType = that._voxelPrimitive.shape; + that.shapeIsBox = shapeType === VoxelShapeType.BOX; + }, + }); + addProperty({ + name: "shapeIsEllipsoid", + getPrimitiveFunction: function () { + const shapeType = that._voxelPrimitive.shape; + that.shapeIsEllipsoid = shapeType === VoxelShapeType.ELLIPSOID; + }, + }); + addProperty({ + name: "shapeIsCylinder", + getPrimitiveFunction: function () { + const shapeType = that._voxelPrimitive.shape; + that.shapeIsCylinder = shapeType === VoxelShapeType.CYLINDER; + }, + }); + addProperty({ + name: "boundsBoxMaxX", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + value, + maxBounds.y, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsBoxMaxX = maxBounds.x; + }, + }); + addProperty({ + name: "boundsBoxMinX", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + value, + minBounds.y, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsBoxMinX = minBounds.x; + }, + }); + addProperty({ + name: "boundsBoxMaxY", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + value, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsBoxMaxY = maxBounds.y; + }, + }); + addProperty({ + name: "boundsBoxMinY", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + value, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsBoxMinY = minBounds.y; + }, + }); + addProperty({ + name: "boundsBoxMaxZ", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + maxBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsBoxMaxZ = maxBounds.z; + }, + }); + addProperty({ + name: "boundsBoxMinZ", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + minBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsBoxMinZ = minBounds.z; + }, + }); + addProperty({ + name: "boundsEllipsoidMaxLongitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + value, + maxBounds.y, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsEllipsoidMaxLongitude = maxBounds.x; + }, + }); + addProperty({ + name: "boundsEllipsoidMinLongitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + value, + minBounds.y, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsEllipsoidMinLongitude = minBounds.x; + }, + }); + addProperty({ + name: "boundsEllipsoidMaxLatitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + value, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsEllipsoidMaxLatitude = maxBounds.y; + }, + }); + addProperty({ + name: "boundsEllipsoidMinLatitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + value, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsEllipsoidMinLatitude = minBounds.y; + }, + }); + addProperty({ + name: "boundsEllipsoidMaxHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + maxBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsEllipsoidMaxHeight = maxBounds.z; + }, + }); + addProperty({ + name: "boundsEllipsoidMinHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + minBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsEllipsoidMinHeight = minBounds.z; + }, + }); + addProperty({ + name: "boundsCylinderMaxRadius", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + value, + maxBounds.y, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsCylinderMaxRadius = maxBounds.x; + }, + }); + addProperty({ + name: "boundsCylinderMinRadius", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + value, + minBounds.y, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsCylinderMinRadius = minBounds.x; + }, + }); + addProperty({ + name: "boundsCylinderMaxHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + value, + maxBounds.z + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsCylinderMaxHeight = maxBounds.y; + }, + }); + addProperty({ + name: "boundsCylinderMinHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + value, + minBounds.z + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsCylinderMinHeight = minBounds.y; + }, + }); + addProperty({ + name: "boundsCylinderMaxAngle", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxBounds = that._voxelPrimitive.maxBounds; + that._voxelPrimitive.maxBounds = new Cartesian3( + maxBounds.x, + maxBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const maxBounds = that._voxelPrimitive.maxBounds; + that.boundsCylinderMaxAngle = maxBounds.z; + }, + }); + addProperty({ + name: "boundsCylinderMinAngle", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minBounds = that._voxelPrimitive.minBounds; + that._voxelPrimitive.minBounds = new Cartesian3( + minBounds.x, + minBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + const minBounds = that._voxelPrimitive.minBounds; + that.boundsCylinderMinAngle = minBounds.z; + }, + }); + addProperty({ + name: "clippingBoxMaxX", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + value, + maxClippingBounds.y, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMaxX = that._voxelPrimitive.maxClippingBounds.x; + }, + }); + addProperty({ + name: "clippingBoxMinX", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + value, + minClippingBounds.y, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMinX = that._voxelPrimitive.minClippingBounds.x; + }, + }); + addProperty({ + name: "clippingBoxMaxY", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + value, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMaxY = that._voxelPrimitive.maxClippingBounds.y; + }, + }); + addProperty({ + name: "clippingBoxMinY", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + value, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMinY = that._voxelPrimitive.minClippingBounds.y; + }, + }); + addProperty({ + name: "clippingBoxMaxZ", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + maxClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMaxZ = that._voxelPrimitive.maxClippingBounds.z; + }, + }); + addProperty({ + name: "clippingBoxMinZ", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + minClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMinZ = that._voxelPrimitive.minClippingBounds.z; + }, + }); + addProperty({ + name: "clippingEllipsoidMaxLongitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + value, + maxClippingBounds.y, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingEllipsoidMaxLongitude = + that._voxelPrimitive.maxClippingBounds.x; + }, + }); + addProperty({ + name: "clippingEllipsoidMinLongitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + value, + minClippingBounds.y, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingEllipsoidMinLongitude = + that._voxelPrimitive.minClippingBounds.x; + }, + }); + addProperty({ + name: "clippingEllipsoidMaxLatitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + value, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingEllipsoidMaxLatitude = + that._voxelPrimitive.maxClippingBounds.y; + }, + }); + addProperty({ + name: "clippingEllipsoidMinLatitude", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + value, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingBoxMinY = that._voxelPrimitive.minClippingBounds.y; + }, + }); + addProperty({ + name: "clippingEllipsoidMaxHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + maxClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingEllipsoidMaxHeight = + that._voxelPrimitive.maxClippingBounds.z; + }, + }); + addProperty({ + name: "clippingEllipsoidMinHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + minClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingEllipsoidMinHeight = + that._voxelPrimitive.minClippingBounds.z; + }, + }); + addProperty({ + name: "clippingCylinderMaxRadius", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + value, + maxClippingBounds.y, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMaxRadius = that._voxelPrimitive.maxClippingBounds.x; + }, + }); + addProperty({ + name: "clippingCylinderMinRadius", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + value, + minClippingBounds.y, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMinRadius = that._voxelPrimitive.minClippingBounds.x; + }, + }); + addProperty({ + name: "clippingCylinderMaxHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + value, + maxClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMaxHeight = that._voxelPrimitive.maxClippingBounds.y; + }, + }); + addProperty({ + name: "clippingCylinderMinHeight", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + value, + minClippingBounds.z + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMinHeight = that._voxelPrimitive.minClippingBounds.y; + }, + }); + addProperty({ + name: "clippingCylinderMaxAngle", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; + that._voxelPrimitive.maxClippingBounds = new Cartesian3( + maxClippingBounds.x, + maxClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMaxAngle = that._voxelPrimitive.maxClippingBounds.z; + }, + }); + addProperty({ + name: "clippingCylinderMinAngle", + initialValue: 0.0, + setPrimitiveFunction: function (value) { + const minClippingBounds = that._voxelPrimitive.minClippingBounds; + that._voxelPrimitive.minClippingBounds = new Cartesian3( + minClippingBounds.x, + minClippingBounds.y, + value + ); + }, + getPrimitiveFunction: function () { + that.clippingCylinderMinAngle = that._voxelPrimitive.minClippingBounds.z; + }, + }); + + addProperty({ + name: "translationX", + initialValue: 0.0, + setPrimitiveFunction: function (translationX) { + const originalTranslation = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3( + translationX, + originalTranslation.y, + originalTranslation.z + ), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.translationX = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).x; + }, + }); + addProperty({ + name: "translationY", + initialValue: 0.0, + setPrimitiveFunction: function (translationY) { + const originalTranslation = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + + that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3( + originalTranslation.x, + translationY, + originalTranslation.z + ), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.translationY = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).y; + }, + }); + addProperty({ + name: "translationZ", + initialValue: 0.0, + setPrimitiveFunction: function (translationZ) { + const originalTranslation = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + + that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3( + originalTranslation.x, + originalTranslation.y, + translationZ + ), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.translationZ = Matrix4.getTranslation( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).z; + }, + }); + + addProperty({ + name: "scaleX", + initialValue: 0.0, + setPrimitiveFunction: function (scaleX) { + const originalScale = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + that._voxelPrimitive.modelMatrix = Matrix4.setScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3(scaleX, originalScale.y, originalScale.z), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.scaleX = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).x; + }, + }); + addProperty({ + name: "scaleY", + initialValue: 0.0, + setPrimitiveFunction: function (scaleY) { + const originalScale = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + that._voxelPrimitive.modelMatrix = Matrix4.setScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3(originalScale.x, scaleY, originalScale.z), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.scaleY = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).y; + }, + }); + addProperty({ + name: "scaleZ", + initialValue: 0.0, + setPrimitiveFunction: function (scaleZ) { + const originalScale = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ); + that._voxelPrimitive.modelMatrix = Matrix4.setScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3(originalScale.x, originalScale.y, scaleZ), + that._voxelPrimitive.modelMatrix + ); + }, + getPrimitiveFunction: function () { + that.scaleZ = Matrix4.getScale( + that._voxelPrimitive.modelMatrix, + new Cartesian3() + ).z; + }, + }); + + addProperty({ + name: "angleX", + initialValue: 0.0, + setPrimitiveFunction: function () { + that._voxelPrimitive.modelMatrix = Matrix4.setRotation( + that._voxelPrimitive.modelMatrix, + Matrix3.fromHeadingPitchRoll( + new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) + ), + that._voxelPrimitive.modelMatrix + ); + }, + }); + + addProperty({ + name: "angleY", + initialValue: 0.0, + setPrimitiveFunction: function () { + that._voxelPrimitive.modelMatrix = Matrix4.setRotation( + that._voxelPrimitive.modelMatrix, + Matrix3.fromHeadingPitchRoll( + new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) + ), + that._voxelPrimitive.modelMatrix + ); + }, + }); + + addProperty({ + name: "angleZ", + initialValue: 0.0, + setPrimitiveFunction: function () { + that._voxelPrimitive.modelMatrix = Matrix4.setRotation( + that._voxelPrimitive.modelMatrix, + Matrix3.fromHeadingPitchRoll( + new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) + ), + that._voxelPrimitive.modelMatrix + ); + }, + }); +} + +Object.defineProperties(VoxelInspectorViewModel.prototype, { + /** + * Gets the scene + * @memberof VoxelInspectorViewModel.prototype + * @type {Scene} + * @readonly + */ + scene: { + get: function () { + return this._scene; + }, + }, + + /** + * Gets or sets the primitive of the view model. + * @memberof VoxelInspectorViewModel.prototype + * @type {VoxelPrimitive} + */ + voxelPrimitive: { + get: function () { + return this._voxelPrimitive; + }, + set: function (voxelPrimitive) { + if (defined(this._customShaderCompilationRemoveCallback)) { + this._customShaderCompilationRemoveCallback(); + } + + // Update properties from the new primitive + if (defined(voxelPrimitive)) { + this._voxelPrimitive = voxelPrimitive; + + const that = this; + that._voxelPrimitive.readyPromise.then(function () { + that._customShaderCompilationRemoveCallback = that._voxelPrimitive.customShaderCompilationEvent.addEventListener( + function (error) { + const shaderString = + that._voxelPrimitive.customShader.fragmentShaderText; + that.styleString = formatShaderString(shaderString); + + if (!defined(error)) { + that.styleCompilationMessage = "Shader compiled successfully!"; + that.styleCompilationSuccess = true; + } else { + that.styleCompilationMessage = error.message; + that.styleCompilationSuccess = false; + } + } + ); + for (let i = 0; i < that._getPrimitiveFunctions.length; i++) { + that._getPrimitiveFunctions[i](); + } + }); + } + }, + }, +}); + +/** + * Compiles the style in the style editor. + * @private + */ +VoxelInspectorViewModel.prototype.compileStyle = function () { + if (defined(this._voxelPrimitive)) { + this._voxelPrimitive.customShader = new CustomShader({ + fragmentShaderText: this.styleString, + }); + } +}; + +/** + * Handles key press events on the style editor. + * @private + */ +VoxelInspectorViewModel.prototype.styleEditorKeyPress = function ( + sender, + event +) { + if (event.keyCode === 9) { + //tab + event.preventDefault(); + const textArea = event.target; + const start = textArea.selectionStart; + const end = textArea.selectionEnd; + let newEnd = end; + const selected = textArea.value.slice(start, end); + const lines = selected.split("\n"); + const length = lines.length; + let i; + if (!event.shiftKey) { + for (i = 0; i < length; ++i) { + lines[i] = ` ${lines[i]}`; + newEnd += 2; + } + } else { + for (i = 0; i < length; ++i) { + if (lines[i][0] === " ") { + if (lines[i][1] === " ") { + lines[i] = lines[i].substr(2); + newEnd -= 2; + } else { + lines[i] = lines[i].substr(1); + newEnd -= 1; + } + } + } + } + const newText = lines.join("\n"); + textArea.value = + textArea.value.slice(0, start) + newText + textArea.value.slice(end); + textArea.selectionStart = start !== end ? start : newEnd; + textArea.selectionEnd = newEnd; + } else if (event.ctrlKey && (event.keyCode === 10 || event.keyCode === 13)) { + //ctrl + enter + this.compileStyle(); + } + return true; +}; + +/** + * @returns {Boolean} true if the object has been destroyed, false otherwise. + */ +VoxelInspectorViewModel.prototype.isDestroyed = function () { + return false; +}; + +/** + * Destroys the widget. Should be called if permanently + * removing the widget from layout. + */ +VoxelInspectorViewModel.prototype.destroy = function () { + const that = this; + this._definedProperties.forEach(function (property) { + knockout.getObservable(that, property).dispose(); + }); + + return destroyObject(this); +}; + +export default VoxelInspectorViewModel; diff --git a/Source/Widgets/widgets.css b/Source/Widgets/widgets.css index b6584d2e5cf..885a32f81e1 100644 --- a/Source/Widgets/widgets.css +++ b/Source/Widgets/widgets.css @@ -4,6 +4,7 @@ @import url(./CesiumWidget/CesiumWidget.css); @import url(./CesiumInspector/CesiumInspector.css); @import url(./Cesium3DTilesInspector/Cesium3DTilesInspector.css); +@import url(./VoxelInspector/VoxelInspector.css); @import url(./FullscreenButton/FullscreenButton.css); @import url(./VRButton/VRButton.css); @import url(./Geocoder/Geocoder.css); diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..227fd904003 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483648,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxel":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxel","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxel","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json new file mode 100644 index 00000000000..39e46626920 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..bf65877f714 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483650,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json new file mode 100644 index 00000000000..39e46626920 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin new file mode 100644 index 0000000000000000000000000000000000000000..2518924ca56aa3fb60ed2c89e2e765ead97fb28a GIT binary patch literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf new file mode 100644 index 00000000000..90e35e2f214 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483649,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2],"bounds":{"min":[0.0,0.0,-1.0],"max":[1.0,1.0,0.0]}}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json new file mode 100644 index 00000000000..74b24b34572 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json @@ -0,0 +1 @@ +{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json new file mode 100644 index 00000000000..f68ae62e2ab --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -0,0 +1 @@ +{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"region":[0.0,0.0,1.0,1.0,-1.0,0.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[6378137.0,0.0,0.0,0.0,0.0,6378137.0,0.0,0.0,0.0,0.0,6356752.314245179,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file diff --git a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js new file mode 100644 index 00000000000..5eaaf1f26ba --- /dev/null +++ b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -0,0 +1,123 @@ +import { + Cartesian3, + Cesium3DTilesVoxelProvider, + Ellipsoid, + Math as CesiumMath, + Matrix4, + MetadataComponentType, + MetadataType, + ResourceCache, + VoxelProvider, + VoxelShapeType, +} from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; +import pollToPromise from "../pollToPromise.js"; + +describe( + "Scene/Cesium3DTilesVoxelProvider", + function () { + let scene; + + beforeAll(function () { + scene = createScene(); + }); + + afterAll(function () { + scene.destroyForSpecs(); + }); + + afterEach(function () { + scene.primitives.removeAll(); + ResourceCache.clearForSpecs(); + }); + + it("conforms to VoxelProvider interface", function () { + expect(Cesium3DTilesVoxelProvider).toConformToInterface(VoxelProvider); + }); + + it("constructor works", function () { + const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const provider = new Cesium3DTilesVoxelProvider({ + url: url, + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(function () { + expect(provider).toBeDefined(); + expect(provider.ready).toBeTrue(); + expect(provider.modelMatrix).toEqualEpsilon( + Matrix4.fromScale(Ellipsoid.WGS84.radii), + CesiumMath.EPSILON10 + ); + expect(provider.shape).toEqual(VoxelShapeType.ELLIPSOID); + expect(provider.minBounds).toEqual(new Cartesian3(0.0, 0.0, -1.0)); + expect(provider.maxBounds).toEqual(new Cartesian3(1.0, 1.0, 0.0)); + expect(provider.dimensions).toEqual(new Cartesian3(2, 2, 2)); + expect(provider.paddingBefore).toBeUndefined(); + expect(provider.paddingAfter).toBeUndefined(); + expect(provider.names).toEqual(["a"]); + expect(provider.types).toEqual([MetadataType.SCALAR]); + expect(provider.componentTypes).toEqual([ + MetadataComponentType.FLOAT32, + ]); + expect(provider.minimumValues).toEqual([[0]]); + expect(provider.maximumValues).toEqual([[1]]); + expect(provider.maximumTileCount).toEqual(1); + }); + }); + + it("constructor throws when url option is missing", function () { + expect(function () { + return new Cesium3DTilesVoxelProvider({ + url: undefined, + }); + }).toThrowDeveloperError(); + }); + + it("requestData works for root tile", function () { + const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const provider = new Cesium3DTilesVoxelProvider({ + url: url, + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(function () { + const requestTilePromise = provider.requestData(); + // need to call update until the promise is ready + return pollToPromise(function () { + provider.update(scene.frameState); + return provider._doneLoading(); + }) + .then(function () { + return requestTilePromise; + }) + .then(function (data) { + expect(data.length).toEqual(1); + + const dimensions = provider.dimensions; + const voxelCount = dimensions.x * dimensions.y * dimensions.z; + const componentCount = MetadataType.getComponentCount( + provider.types[0] + ); + const expectedLength = voxelCount * componentCount; + expect(data[0].length).toEqual(expectedLength); + }); + }); + }); + + it("requestData throws if the provider is not ready", function () { + const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const provider = new Cesium3DTilesVoxelProvider({ + url: url, + }); + expect(function () { + return provider.requestData(); + }).toThrowDeveloperError(); + }); + }, + "WebGL" +); diff --git a/Specs/Scene/GltfVoxelProviderSpec.js b/Specs/Scene/GltfVoxelProviderSpec.js new file mode 100644 index 00000000000..ef9f736648f --- /dev/null +++ b/Specs/Scene/GltfVoxelProviderSpec.js @@ -0,0 +1,137 @@ +import { + Cartesian3, + GltfVoxelProvider, + Matrix4, + MetadataComponentType, + MetadataType, + ResourceCache, + VoxelProvider, + VoxelShapeType, +} from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; +import pollToPromise from "../pollToPromise.js"; + +describe( + "Scene/GltfVoxelProvider", + function () { + let scene; + + beforeAll(function () { + scene = createScene(); + }); + + afterAll(function () { + scene.destroyForSpecs(); + }); + + afterEach(function () { + scene.primitives.removeAll(); + ResourceCache.clearForSpecs(); + }); + + it("conforms to VoxelProvider interface", function () { + expect(GltfVoxelProvider).toConformToInterface(VoxelProvider); + }); + + it("constructor works", function () { + const url = + "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + const provider = new GltfVoxelProvider({ + gltf: url, + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(function () { + expect(provider).toBeDefined(); + expect(provider.ready).toBeTrue(); + expect(provider.modelMatrix).toEqual(Matrix4.IDENTITY); + expect(provider.shape).toEqual(VoxelShapeType.ELLIPSOID); + expect(provider.minBounds).toEqual(new Cartesian3(0.0, 0.0, -1.0)); + expect(provider.maxBounds).toEqual(new Cartesian3(1.0, 1.0, 0.0)); + expect(provider.dimensions).toEqual(new Cartesian3(2, 2, 2)); + expect(provider.paddingBefore).toBeUndefined(); + expect(provider.paddingAfter).toBeUndefined(); + expect(provider.names).toEqual(["a"]); + expect(provider.types).toEqual([MetadataType.SCALAR]); + expect(provider.componentTypes).toEqual([ + MetadataComponentType.FLOAT32, + ]); + expect(provider.minimumValues).toBeUndefined(); + expect(provider.maximumValues).toBeUndefined(); + expect(provider.maximumTileCount).toEqual(1); + }); + }); + + it("constructor throws when gltf option is missing", function () { + expect(function () { + return new GltfVoxelProvider({ + gltf: undefined, + }); + }).toThrowDeveloperError(); + }); + + it("requestData works", function () { + const url = + "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + const provider = new GltfVoxelProvider({ + gltf: url, + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(function () { + const requestTilePromise = provider.requestData(); + + // need to call update until the promise is ready + return pollToPromise(function () { + provider.update(scene.frameState); + return provider._doneLoading(); + }) + .then(function () { + return requestTilePromise; + }) + .then(function (data) { + expect(data.length).toEqual(1); + + const dimensions = provider.dimensions; + const voxelCount = dimensions.x * dimensions.y * dimensions.z; + const componentCount = MetadataType.getComponentCount( + provider.types[0] + ); + const expectedLength = voxelCount * componentCount; + expect(data[0].length).toEqual(expectedLength); + }); + }); + }); + + it("requestData throws for non-root tiles", function () { + const url = + "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + const provider = new GltfVoxelProvider({ + gltf: url, + }); + expect(function () { + return provider.requestData({ + x: 0, + y: 0, + z: 0, + level: 1, + }); + }).toThrowDeveloperError(); + }); + + it("requestData throws if the provider is not ready", function () { + const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const provider = new GltfVoxelProvider({ + gltf: url, + }); + expect(function () { + return provider.requestData(); + }).toThrowDeveloperError(); + }); + }, + "WebGL" +); diff --git a/Specs/Scene/VoxelBoxShapeSpec.js b/Specs/Scene/VoxelBoxShapeSpec.js new file mode 100644 index 00000000000..c162dd4b896 --- /dev/null +++ b/Specs/Scene/VoxelBoxShapeSpec.js @@ -0,0 +1,696 @@ +import { + BoundingSphere, + Cartesian3, + Math as CesiumMath, + Matrix3, + Matrix4, + OrientedBoundingBox, + Quaternion, + VoxelBoxShape, +} from "../../Source/Cesium.js"; + +describe("Scene/VoxelBoxShape", function () { + it("constructs", function () { + const shape = new VoxelBoxShape(); + expect(shape.isVisible).toEqual(false); + }); + + it("update works with model matrix", function () { + const shape = new VoxelBoxShape(); + + const translation = new Cartesian3(1.0, 2.0, 3.0); + const scale = new Cartesian3(2.0, 3.0, 4.0); + const angle = CesiumMath.PI_OVER_FOUR; + const rotation = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, angle); + + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + + const expectedOrientedBoundingBox = new OrientedBoundingBox( + translation, + Matrix3.fromColumnMajorArray([ + scale.x * Math.cos(angle), + scale.x * Math.sin(angle), + 0.0, + scale.y * Math.cos(angle + CesiumMath.PI_OVER_TWO), + scale.y * Math.sin(angle + CesiumMath.PI_OVER_TWO), + 0.0, + 0.0, + 0.0, + scale.z, + ]) + ); + + const expectedBoundingSphere = new BoundingSphere( + translation, + Cartesian3.magnitude(scale) + ); + + shape.update(modelMatrix, minBounds, maxBounds); + + expect(shape.orientedBoundingBox.center).toEqual( + expectedOrientedBoundingBox.center + ); + expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + expect(shape.boundTransform).toEqual(modelMatrix); + expect(shape.shapeTransform).toEqual(modelMatrix); + expect(shape.isVisible).toBeTrue(); + }); + + it("update works with non-default minimum and maximum bounds", function () { + const shape = new VoxelBoxShape(); + const translation = new Cartesian3(1.0, 2.0, 3.0); + const scale = new Cartesian3(2.0, 3.0, 4.0); + const rotation = Quaternion.IDENTITY; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale, + new Matrix4() + ); + const minBounds = new Cartesian3(-0.75, -0.75, -0.75); + const maxBounds = new Cartesian3(-0.25, -0.25, -0.25); + shape.update(modelMatrix, minBounds, maxBounds); + + const expectedTranslation = new Cartesian3(0.75, 1.75, 2.75); + const expectedScale = new Cartesian3(0.5, 0.75, 1.0); + const expectedRotation = rotation; + const expectedModelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + expectedTranslation, + expectedRotation, + expectedScale, + new Matrix4() + ); + const expectedOrientedBoundingBox = new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale) + ); + const expectedBoundingSphere = new BoundingSphere( + expectedTranslation, + Cartesian3.magnitude(expectedScale) + ); + + expect(shape.orientedBoundingBox).toEqual(expectedOrientedBoundingBox); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + expect(shape.boundTransform).toEqual(expectedModelMatrix); + expect(shape.shapeTransform).toEqual(expectedModelMatrix); + expect(shape.isVisible).toBeTrue(); + }); + + it("update is visible with zero scale for one component", function () { + const shape = new VoxelBoxShape(); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + const translation = new Cartesian3(1.0, 2.0, 3.0); + const rotation = Quaternion.IDENTITY; + + let scale; + let modelMatrix; + + // 0 scale for X + scale = new Cartesian3(0.0, 2.0, 2.0); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeTrue(); + + // 0 scale for Y + scale = Cartesian3.fromElements(2.0, 0.0, 2.0, scale); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeTrue(); + + // 0 scale for Z + scale = Cartesian3.fromElements(2.0, 2.0, 0.0, scale); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeTrue(); + }); + + it("update is invisible with zero scale for two or more components", function () { + const shape = new VoxelBoxShape(); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + const translation = new Cartesian3(1.0, 2.0, 3.0); + const rotation = Quaternion.IDENTITY; + + let scale; + let modelMatrix; + + // 0 scale for X and Y + scale = new Cartesian3(0.0, 0.0, 2.0); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 scale for X and Z + scale = Cartesian3.fromElements(0.0, 2.0, 0.0, scale); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 scale for Y and Z + scale = Cartesian3.fromElements(2.0, 0.0, 0.0, scale); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 scale for X, Y, and Z + scale = Cartesian3.fromElements(0.0, 0.0, 0.0, scale); + modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + }); + + it("update is visible with zero bounds for one component", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + + let minBounds; + let maxBounds; + let expectedScale; + let actualScale; + let actualTranslation; + + // 0 in X bound + minBounds = new Cartesian3(0.0, -1.0, -1.0); + maxBounds = new Cartesian3(0.0, +1.0, +1.0); + expectedScale = new Cartesian3(0.0, 1.0, 1.0); + + shape.update(modelMatrix, minBounds, maxBounds); + actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualTranslation = Matrix4.getTranslation( + shape.shapeTransform, + new Cartesian3() + ); + expect(shape.isVisible).toBeTrue(); + expect(actualScale).toEqual(expectedScale); + expect(actualTranslation).toEqual(translation); + + // 0 in Y bound + minBounds = new Cartesian3(-1.0, 0.0, -1.0); + maxBounds = new Cartesian3(+1.0, 0.0, +1.0); + expectedScale = new Cartesian3(1.0, 0.0, 1.0); + + shape.update(modelMatrix, minBounds, maxBounds); + actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualTranslation = Matrix4.getTranslation( + shape.shapeTransform, + new Cartesian3() + ); + expect(shape.isVisible).toBeTrue(); + expect(actualScale).toEqual(expectedScale); + expect(actualTranslation).toEqual(translation); + + // 0 in Z bound + minBounds = new Cartesian3(-1.0, -1.0, 0.0); + maxBounds = new Cartesian3(+1.0, +1.0, 0.0); + expectedScale = new Cartesian3(1.0, 1.0, 0.0); + + shape.update(modelMatrix, minBounds, maxBounds); + actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualTranslation = Matrix4.getTranslation( + shape.shapeTransform, + new Cartesian3() + ); + expect(shape.isVisible).toBeTrue(); + expect(actualScale).toEqual(expectedScale); + expect(actualTranslation).toEqual(translation); + }); + + it("update is invisible with zero bounds for two or more components", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + + let minBounds; + let maxBounds; + + // 0 in X and Y bounds + minBounds = new Cartesian3(0.0, 0.0, -1.0); + maxBounds = new Cartesian3(0.0, 0.0, +1.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 in X and Z bounds + minBounds = new Cartesian3(0.0, -1.0, 0.0); + maxBounds = new Cartesian3(0.0, +1.0, 0.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 in Y and Z bounds + minBounds = new Cartesian3(-1.0, 0.0, 0.0); + maxBounds = new Cartesian3(+1.0, 0.0, 0.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // 0 in X, Y, and Z bounds + minBounds = new Cartesian3(0.0, 0.0, 0.0); + maxBounds = new Cartesian3(0.0, 0.0, 0.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + }); + + it("update is invisible when minimum bounds exceed maximum bounds", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + + let minBounds; + let maxBounds; + + // Exceeds X + minBounds = new Cartesian3(+2.0, -1.0, -1.0); + maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // Exceeds Y + minBounds = new Cartesian3(-1.0, +2.0, -1.0); + maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + + // Exceeds Z + minBounds = new Cartesian3(-1.0, -1.0, +2.0); + maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + shape.update(modelMatrix, minBounds, maxBounds); + expect(shape.isVisible).toBeFalse(); + }); + + it("update throws with no model matrix parameter", function () { + const shape = new VoxelBoxShape(); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + + expect(function () { + return shape.update(undefined, minBounds, maxBounds); + }).toThrowDeveloperError(); + }); + + it("update throws with no minimum bounds parameter", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + + expect(function () { + return shape.update(modelMatrix, undefined, maxBounds); + }).toThrowDeveloperError(); + }); + + it("update throws with no maximum bounds parameter", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + + expect(function () { + return shape.update(modelMatrix, minBounds, undefined); + }).toThrowDeveloperError(); + }); + + it("computeOrientedBoundingBoxForTile works for root tile", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + const tileLevel = 0; + const tileX = 0; + const tileY = 0; + const tileZ = 0; + const orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + + const expectedOrientedBoundingBox = shape.orientedBoundingBox; + expect(orientedBoundingBox).toEqual(expectedOrientedBoundingBox); + }); + + it("computeOrientedBoundingBoxForTile works for children of root tile", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + const expectedScale = new Cartesian3(0.5, 0.5, 0.5); + let expectedTranslation; + + const tileLevel = 1; + let tileX; + let tileY; + let tileZ; + let orientedBoundingBox; + + tileX = 0; + tileY = 0; + tileZ = 0; + + // Child (0, 0, 0) + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(-0.5, -0.5, -0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (1, 0, 0) + tileX = 1; + tileY = 0; + tileZ = 0; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(+0.5, -0.5, -0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (0, 1, 0) + tileX = 0; + tileY = 1; + tileZ = 0; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(-0.5, +0.5, -0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (0, 0, 1) + tileX = 0; + tileY = 0; + tileZ = 1; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(-0.5, -0.5, +0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (1, 1, 0) + tileX = 1; + tileY = 1; + tileZ = 0; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(+0.5, +0.5, -0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (1, 0, 1) + tileX = 1; + tileY = 0; + tileZ = 1; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(+0.5, -0.5, +0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + + // Child (1, 1, 1) + tileX = 1; + tileY = 1; + tileZ = 1; + orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + expectedTranslation = new Cartesian3(+0.5, +0.5, +0.5); + expect(orientedBoundingBox).toEqual( + new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedScale, new Matrix3()) + ) + ); + }); + + it("computeOrientedBoundingBoxForTile throws with no tile coordinates parameter", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + const tileLevel = 0; + const tileX = 0; + const tileY = 0; + const tileZ = 0; + + expect(function () { + return shape.computeOrientedBoundingBoxForTile( + undefined, + tileX, + tileY, + tileZ, + new OrientedBoundingBox() + ); + }).toThrowDeveloperError(); + + expect(function () { + return shape.computeOrientedBoundingBoxForTile( + tileLevel, + undefined, + tileY, + tileZ, + new OrientedBoundingBox() + ); + }).toThrowDeveloperError(); + + expect(function () { + return shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + undefined, + tileZ, + new OrientedBoundingBox() + ); + }).toThrowDeveloperError(); + + expect(function () { + return shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + undefined, + new OrientedBoundingBox() + ); + }).toThrowDeveloperError(); + }); + + it("computeOrientedBoundingBoxForTile throws with no result parameter", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + const tileLevel = 0; + const tileX = 0; + const tileY = 0; + const tileZ = 0; + + expect(function () { + return shape.computeOrientedBoundingBoxForTile( + tileLevel, + tileX, + tileY, + tileZ, + undefined + ); + }).toThrowDeveloperError(); + }); + + it("computeApproximateStepSize works", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + const dimensions = new Cartesian3(32, 32, 16); + const stepSize = shape.computeApproximateStepSize(dimensions); + expect(stepSize).toBeGreaterThan(0.0); + expect(stepSize).toBeLessThan(1.0); + }); + + it("computeApproximateStepSize throws with no dimensions parameter", function () { + const shape = new VoxelBoxShape(); + const translation = Cartesian3.ZERO; + const rotation = Quaternion.IDENTITY; + const scale = Cartesian3.ONE; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; + shape.update(modelMatrix, minBounds, maxBounds); + + expect(function () { + return shape.computeApproximateStepSize(undefined); + }).toThrowDeveloperError(); + }); +}); diff --git a/Specs/Scene/VoxelCylinderShapeSpec.js b/Specs/Scene/VoxelCylinderShapeSpec.js new file mode 100644 index 00000000000..481f3a18c6c --- /dev/null +++ b/Specs/Scene/VoxelCylinderShapeSpec.js @@ -0,0 +1,214 @@ +import { + BoundingSphere, + Cartesian3, + Math as CesiumMath, + Matrix3, + Matrix4, + OrientedBoundingBox, + Quaternion, + VoxelCylinderShape, +} from "../../Source/Cesium.js"; + +describe( + "Scene/VoxelCylinderShape", + function () { + it("constructs", function () { + const shape = new VoxelCylinderShape(); + expect(shape.isVisible).toEqual(false); + }); + + it("update works with model matrix", function () { + const shape = new VoxelCylinderShape(); + + const translation = new Cartesian3(1.0, 2.0, 3.0); + const scale = new Cartesian3(2.0, 3.0, 4.0); + const halfScale = Cartesian3.multiplyByScalar( + scale, + 0.5, + new Cartesian3() + ); + const angle = CesiumMath.PI_OVER_FOUR; + const rotation = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, angle); + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + const minBounds = VoxelCylinderShape.DefaultMinBounds; + const maxBounds = VoxelCylinderShape.DefaultMaxBounds; + + shape.update(modelMatrix, minBounds, maxBounds); + + const expectedOrientedBoundingBox = new OrientedBoundingBox( + translation, + Matrix3.fromColumnMajorArray([ + halfScale.x * Math.cos(angle), + halfScale.x * Math.sin(angle), + 0.0, + halfScale.y * Math.cos(angle + CesiumMath.PI_OVER_TWO), + halfScale.y * Math.sin(angle + CesiumMath.PI_OVER_TWO), + 0.0, + 0.0, + 0.0, + halfScale.z, + ]) + ); + const expectedBoundingSphere = new BoundingSphere( + translation, + Cartesian3.magnitude(halfScale) + ); + + expect(shape.orientedBoundingBox.center).toEqual( + expectedOrientedBoundingBox.center + ); + expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + expect(shape.boundTransform).toEqual(modelMatrix); + expect(shape.shapeTransform).toEqual(modelMatrix); + expect(shape.isVisible).toBeTrue(); + }); + + it("update works with non-default minimum and maximum bounds", function () { + const shape = new VoxelCylinderShape(); + const translation = new Cartesian3(1.0, 2.0, 3.0); + const scale = new Cartesian3(2.0, 3.0, 4.0); + const rotation = Quaternion.IDENTITY; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale, + new Matrix4() + ); + + // Half revolution + const minRadius = 0.25; + const maxRadius = 0.75; + const minHeight = -0.5; + const maxHeight = +0.5; + const minAngle = -CesiumMath.PI; + const maxAngle = 0.0; + const minBounds = new Cartesian3(minRadius, minHeight, minAngle); + const maxBounds = new Cartesian3(maxRadius, maxHeight, maxAngle); + shape.update(modelMatrix, minBounds, maxBounds); + + const expectedMinX = translation.x - maxRadius * scale.x; + const expectedMaxX = translation.x + maxRadius * scale.x; + const expectedMinY = translation.y + minHeight * scale.y; + const expectedMaxY = translation.y + maxHeight * scale.y; + const expectedMinZ = translation.z - maxRadius * scale.z; + const expectedMaxZ = translation.z; + + const expectedScale = new Cartesian3( + expectedMaxX - expectedMinX, + expectedMaxY - expectedMinY, + expectedMaxZ - expectedMinZ + ); + const expectedTranslation = new Cartesian3( + 0.5 * (expectedMaxX + expectedMinX), + 0.5 * (expectedMaxY + expectedMinY), + 0.5 * (expectedMaxZ + expectedMinZ) + ); + + const expectedHalfScale = Cartesian3.multiplyByScalar( + expectedScale, + 0.5, + new Cartesian3() + ); + const expectedOrientedBoundingBox = new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedHalfScale) + ); + const expectedBoundingSphere = new BoundingSphere( + expectedTranslation, + Cartesian3.magnitude(expectedHalfScale) + ); + const expectedBoundTransform = Matrix4.setTranslation( + Matrix4.fromScale(expectedScale, new Matrix4()), + expectedTranslation, + new Matrix4() + ); + + expect(shape.orientedBoundingBox.center).toEqualEpsilon( + expectedOrientedBoundingBox.center, + CesiumMath.EPSILON12 + ); + expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + expect(shape.boundTransform).toEqual(expectedBoundTransform); + expect(shape.shapeTransform).toEqual(modelMatrix); + expect(shape.isVisible).toBeTrue(); + }); + + it("update works with minimum and maximum bounds that cross the 180th meridian", function () { + const shape = new VoxelCylinderShape(); + const translation = Cartesian3.ZERO; + const scale = Cartesian3.ONE; + const rotation = Quaternion.IDENTITY; + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale, + new Matrix4() + ); + + // Half revolution around 180th meridian + const minAngle = +CesiumMath.PI_OVER_TWO; + const maxAngle = -CesiumMath.PI_OVER_TWO; + const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; + const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; + const minBounds = new Cartesian3( + defaultMinBounds.x, + defaultMinBounds.y, + minAngle + ); + const maxBounds = new Cartesian3( + defaultMaxBounds.x, + defaultMaxBounds.y, + maxAngle + ); + shape.update(modelMatrix, minBounds, maxBounds); + + const expectedScale = new Cartesian3(0.5, 1.0, 1.0); + const expectedTranslation = new Cartesian3(-0.5, 0.0, 0.0); + + const expectedHalfScale = Cartesian3.multiplyByScalar( + expectedScale, + 0.5, + new Cartesian3() + ); + const expectedOrientedBoundingBox = new OrientedBoundingBox( + expectedTranslation, + Matrix3.fromScale(expectedHalfScale) + ); + const expectedBoundingSphere = new BoundingSphere( + expectedTranslation, + Cartesian3.magnitude(expectedHalfScale) + ); + const expectedBoundTransform = Matrix4.setTranslation( + Matrix4.fromScale(expectedScale, new Matrix4()), + expectedTranslation, + new Matrix4() + ); + + expect(shape.orientedBoundingBox.center).toEqualEpsilon( + expectedOrientedBoundingBox.center, + CesiumMath.EPSILON12 + ); + expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + expect(shape.boundTransform).toEqual(expectedBoundTransform); + expect(shape.shapeTransform).toEqual(modelMatrix); + expect(shape.isVisible).toBeTrue(); + }); + }, + "WebGL" +); diff --git a/Specs/Scene/VoxelEllipsoidShapeSpec.js b/Specs/Scene/VoxelEllipsoidShapeSpec.js new file mode 100644 index 00000000000..e80c0ecd79b --- /dev/null +++ b/Specs/Scene/VoxelEllipsoidShapeSpec.js @@ -0,0 +1,179 @@ +import { + Cartesian3, + Math as CesiumMath, + Ellipsoid, + OrientedBoundingBox, + Matrix4, + Ray, + Rectangle, + VoxelEllipsoidShape, + VoxelShapeType, +} from "../../Source/Cesium.js"; + +describe( + "Scene/VoxelEllipsoidShape", + function () { + const PI_OVER_TWO = CesiumMath.PI_OVER_TWO; + const west = -PI_OVER_TWO; + const east = PI_OVER_TWO; + const south = -PI_OVER_TWO; + const north = PI_OVER_TWO; + const rectangle = new Rectangle(west, south, east, north); + const minimumHeight = 0.0; + const maximumHeight = 1000000.0; + let ellipsoid; + const scratchCartesian3 = new Cartesian3(); + beforeEach(function () { + ellipsoid = new VoxelEllipsoidShape({ + rectangle: rectangle, + minimumHeight: minimumHeight, + maximumHeight: maximumHeight, + }); + ellipsoid.update(); // compute transforms + }); + + it("constructs with arguments", function () { + expect(ellipsoid.ellipsoid.equals(Ellipsoid.WGS84)).toBe(true); + expect(ellipsoid.rectangle.equals(rectangle)).toBe(true); + expect(ellipsoid.minimumHeight).toBe(minimumHeight); + expect(ellipsoid.maximumHeight).toBe(maximumHeight); + expect(ellipsoid._type).toBe(VoxelShapeType.ELLIPSOID); + }); + + it("updates bounding shapes upon changes to ellipsoid", function () { + const oldObb = ellipsoid.orientedBoundingBox.clone(); + const oldSphere = ellipsoid.boundingSphere.clone(); + ellipsoid.ellipsoid = Ellipsoid.MOON; + expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + }); + + it("updates bounding shapes upon changes to rectangle", function () { + const oldObb = ellipsoid.orientedBoundingBox.clone(); + const oldSphere = ellipsoid.boundingSphere.clone(); + ellipsoid.rectangle = new Rectangle( + west + CesiumMath.EPSILON7, + south, + east, + north + ); + expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + }); + + it("updates bounding shapes upon changes to minimum height", function () { + const oldObb = ellipsoid.orientedBoundingBox.clone(); + const oldSphere = ellipsoid.boundingSphere.clone(); + ellipsoid.minimumHeight += 1; + expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(true); + expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(true); + }); + + it("updates bounding shapes upon changes to maximum height", function () { + const oldObb = ellipsoid.orientedBoundingBox.clone(); + const oldSphere = ellipsoid.boundingSphere.clone(); + ellipsoid.maximumHeight += 1; + expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + }); + + it("computes shape transform", function () { + const radii = Ellipsoid.WGS84._radii; + const scaleX = 2.0 * (radii.x + maximumHeight); + const scaleY = 2.0 * (radii.y + maximumHeight); + const scaleZ = 2.0 * (radii.z + maximumHeight); + const scale = Cartesian3.fromElements(scaleX, scaleY, scaleZ); + const shapeTransform = Matrix4.fromScale(scale, new Matrix4()); + expect(shapeTransform.equals(ellipsoid._shapeTransform)).toBe(true); + }); + + it("can clone itself", function () { + const ellipsoidClone = ellipsoid.clone(); + expect(ellipsoidClone).not.toBe(ellipsoid); + expect(ellipsoid.ellipsoid.equals(ellipsoidClone.ellipsoid)).toBe(true); + expect(ellipsoid.rectangle.equals(ellipsoidClone.rectangle)).toBe(true); + expect(ellipsoid.minimumHeight).toBe(ellipsoidClone.minimumHeight); + expect(ellipsoid.maximumHeight).toBe(ellipsoidClone.maximumHeight); + }); + + it("computes bounding volume for root tile", function () { + const result = new OrientedBoundingBox(); + ellipsoid.computeOrientedBoundingBoxForTile(0, 0, 0, 0, result); + expect(result.equals(ellipsoid.orientedBoundingBox)).toBe(true); + }); + + it("indicates when a point in local space is outside the shape", function () { + const clippingMinimum = Cartesian3.ZERO; + const clippingMaximum = Cartesian3.fromElements(1.0, 1.0, 1.0); + expect( + ellipsoid.localPointInsideShape( + Cartesian3.ZERO, + clippingMinimum, + clippingMaximum + ) + ).toBe(false); + expect( + ellipsoid.localPointInsideShape( + Cartesian3.fromElements(0.49, 0.0, 0.0), + clippingMinimum, + clippingMaximum + ) + ).toBe(true); + }); + + it("transforms from local to shape space", function () { + const point = Cartesian3.fromElements(0.5, 0.0, 0.0); + expect( + ellipsoid + .transformFromLocalToShapeSpace(point, scratchCartesian3) + .equals(Cartesian3.fromElements(0.5, 0.5, 1.0)) + ).toBe(true); + }); + + it("intersects ray with outer shell", function () { + const origin = Cartesian3.fromElements(2.0, 0.0, 0.0); + const direction = Cartesian3.fromElements(-1.0, 0.0, 0.0); + const ray = new Ray(origin, direction); + const minClipping = Cartesian3.ZERO; + const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + }); + + it("intersects ray with inner shell", function () { + const origin = Cartesian3.ZERO; + const direction = Cartesian3.fromElements(1.0, 0.0, 0.0); + const ray = new Ray(origin, direction); + const minClipping = Cartesian3.ZERO; + const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + expect(t).toEqualEpsilon( + 1.0 - ellipsoid._ellipsoidHeightDifferenceUv, + CesiumMath.EPSILON4 + ); + }); + + it("intersects ray with longitude face", function () { + ellipsoid.rectangle = new Rectangle(west, south, 0.0, north); + const origin = Cartesian3.fromElements(0.99, 1.0, 0.0); + const direction = Cartesian3.fromElements(0.0, -1.0, 0.0); + const ray = new Ray(origin, direction); + const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); + const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + }); + + it("intersects ray with latitude face", function () { + ellipsoid.rectangle = new Rectangle(west, south, east, 0.0); + const origin = Cartesian3.fromElements(0.99, 0.0, 1.0); + const direction = Cartesian3.fromElements(0.0, 0.0, -1.0); + const ray = new Ray(origin, direction); + const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); + const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + }); + }, + "WebGL" +); diff --git a/Specs/Scene/VoxelPrimitiveSpec.js b/Specs/Scene/VoxelPrimitiveSpec.js new file mode 100644 index 00000000000..e45fb36ecf4 --- /dev/null +++ b/Specs/Scene/VoxelPrimitiveSpec.js @@ -0,0 +1,224 @@ +import { + AttributeType, + Cartesian3, + ComponentDatatype, + defined, + Matrix3, + Matrix4, + Pass, + VoxelBoxShape, + VoxelPrimitive, +} from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; + +const metadataName = "dummyMetadataName"; +function DummyVoxelProvider() { + this.shape = new VoxelBoxShape(); + this.voxelDimensions = new Cartesian3(2, 2, 2); + this.voxelsPerTile = 2 * 2 * 2; + this.ready = true; + this.readyPromise = Promise.resolve(this); + this._tileCount = 4096; + this.neighborEdgeCount = 0; + this.metadataNames = [metadataName]; + this.numberOfLevels = 16; + + this.properties = {}; + + this.properties[metadataName] = { + type: AttributeType.VEC4, + componentType: ComponentDatatype.FLOAT, + componentCount: 4, + min: 0, + max: 1, + count: this.voxelsPerTile * this._tileCount, + }; +} +DummyVoxelProvider.prototype.requestData = function (options) { + const maxIndex = Math.pow(2, options.level) - 1; + const requestOutsideOfShape = + options.x < 0 || + options.x > maxIndex || + options.y < 0 || + options.y > maxIndex || + options.z < 0 || + options.z > maxIndex; + if (options.level >= this.numberOfLevels || requestOutsideOfShape) { + return Promise.resolve(undefined); + } + const returnArray = new Uint32Array(this.voxelsPerTile); + return Promise.resolve(returnArray); +}; + +describe( + "Scene/VoxelPrimitive", + function () { + const scene = createScene(); + const provider = new DummyVoxelProvider(); + let primitive; + beforeEach(function () { + scene.primitives.removeAll(); + primitive = new VoxelPrimitive({ + provider: provider, + }); + scene._primitives.add(primitive); + scene.renderForSpecs(); + }); + + it("constructs a primitive", function () { + const command = scene.frameState.commandList[0]; + expect(command).toBeDefined(); + expect(command.pass).toBe(Pass.VOXELS); + }); + + it("constructs with options", function () { + expect(primitive.provider).toBe(provider); + return primitive.readyPromise.then(function () { + const property = provider.properties[metadataName]; + expect(primitive.shape._type).toBe(provider.shape._type); + expect( + primitive._voxelDimensions.equals(provider.voxelDimensions) + ).toBe(true); + expect(primitive._voxelNeighborEdgeCount).toBe( + provider.neighborEdgeCount + ); + // Object.values workaround is Object.keys.map + const minimumValues = primitive.minimumValues[0]; + expect( + Object.keys(minimumValues) + .map(function (key) { + return minimumValues[key]; + }) + .every(function (value) { + return value === property.min; + }) + ).toBe(true); + const maximumValues = primitive.maximumValues[0]; + expect( + Object.keys(maximumValues) + .map(function (key) { + return maximumValues[key]; + }) + .every(function (value) { + return value === property.max; + }) + ).toBe(true); + expect(primitive._tileCount).toBe(provider._tileCount); + expect(defined(primitive._traversal)).toBe(true); + // TODO should we test writing glsl functions? i.e. sample functions, setting style input values for each metadata + }); + }); + + it("sets clipping range extrema when given valid range between 0 and 1", function () { + const setValue = Cartesian3.fromElements(0.1, 0.5, 0.3); + expect(primitive.minClippingBounds.equals(setValue)).toBe(false); + primitive.minClippingBounds = setValue; + expect(primitive.minClippingBounds.equals(setValue)).toBe(true); + expect(primitive.maxClippingBounds.equals(setValue)).toBe(false); + primitive.maxClippingBounds = setValue; + expect(primitive.maxClippingBounds.equals(setValue)).toBe(true); + }); + + it("clamps clipping range extrema when given values outside [0, 1]", function () { + const setValue = Cartesian3.fromElements(-1.0, 0.5, 2.0); + const clampedValue = Cartesian3.fromElements(0.0, 0.5, 1.0); + primitive.minClippingBounds = setValue; + expect(primitive.minClippingBounds.equals(clampedValue)).toBe(true); + primitive.maxClippingBounds = setValue; + expect(primitive.maxClippingBounds.equals(clampedValue)).toBe(true); + }); + + it("uses default style", function () { + primitive.style = undefined; + expect(primitive.style).toBe(VoxelPrimitive.DefaultStyle); + }); + + it("creates style", function () { + const options = { + type: "VoxelPrimitiveStyle", + source: + "vec4 style(StyleInput styleInput) {\n" + + " return vec4(1.0);\n" + + "}", + uniforms: { dummyUniform: 0 }, + }; + const material = VoxelPrimitive.CreateStyle(options); + expect(material._template.type).toBe(options.type); + expect(material._template.source).toBe(options.source); + expect(material._template.uniforms.dummyUniform).toBe( + options.uniforms.dummyUniform + ); + }); + + it("updates transform matrices", function () { + const shape = primitive._shape; + shape.translation = new Cartesian3(2.382, -3.643, 1.084); + return primitive.readyPromise.then(function () { + primitive.update(scene.frameState); + const worldToBoundTransform = Matrix4.inverse( + shape._boundTransform, + new Matrix4() + ); + expect( + primitive._worldToBoundTransform.equals(worldToBoundTransform) + ).toBe(true); + + const shapeTransform = shape._shapeTransform; + const worldToShapeTransform = Matrix4.inverse( + shape._shapeTransform, + new Matrix4() + ); + expect( + primitive._worldToShapeTransform.equals(worldToShapeTransform) + ).toBe(true); + + const shapeScale = Matrix4.getScale(shapeTransform, new Matrix4()); + const shapeRotation = Matrix4.getRotation( + shapeTransform, + new Matrix4() + ); + const shapeScaleMaximum = Cartesian3.maximumComponent(shapeScale); + const shapeNormalizedScale = Cartesian3.divideByScalar( + shapeScale, + shapeScaleMaximum, + new Matrix4() + ); + const scaleAndRotation = Matrix3.multiplyByScale( + shapeRotation, + shapeNormalizedScale, + new Matrix4() + ); + const worldToUvTransformDirection = Matrix3.inverse( + scaleAndRotation, + new Matrix3() + ); + expect( + primitive._worldToUvTransformDirection.equals( + worldToUvTransformDirection + ) + ).toBe(true); + + const shapeToWorldNormal = Matrix4.getRotation( + shapeTransform, + new Matrix4() + ); + Matrix3.multiplyByScale( + shapeToWorldNormal, + shapeNormalizedScale, + shapeToWorldNormal + ); + Matrix3.transpose(shapeToWorldNormal, shapeToWorldNormal); + Matrix3.inverse(shapeToWorldNormal, shapeToWorldNormal); + expect(primitive._shapeToWorldNormal.equals(shapeToWorldNormal)).toBe( + true + ); + + const stepSizeUv = shape.computeApproximateStepSize( + primitive._voxelDimensions + ); + expect(primitive._stepSizeUv).toBe(stepSizeUv); + }); + }); + }, + "WebGL" +); diff --git a/Specs/Scene/VoxelShapeTypeSpec.js b/Specs/Scene/VoxelShapeTypeSpec.js new file mode 100644 index 00000000000..240f2815997 --- /dev/null +++ b/Specs/Scene/VoxelShapeTypeSpec.js @@ -0,0 +1,43 @@ +import { + PrimitiveType, + VoxelBoxShape, + VoxelCylinderShape, + VoxelEllipsoidShape, + VoxelShapeType, +} from "../../Source/Cesium.js"; + +describe("Scene/VoxelShapeType", function () { + it("fromPrimitiveType works", function () { + expect(VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_BOX)).toBe( + VoxelShapeType.BOX + ); + expect( + VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_ELLIPSOID) + ).toBe(VoxelShapeType.ELLIPSOID); + expect(VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_CYLINDER)).toBe( + VoxelShapeType.CYLINDER + ); + }); + it("fromPrimitiveType throws for invalid type", function () { + expect(function () { + return VoxelShapeType.fromPrimitiveType("NOT_A_PRIMITIVE_TYPE"); + }).toThrowDeveloperError(); + }); + + it("toShapeConstructor works", function () { + expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.BOX)).toBe( + VoxelBoxShape + ); + expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.ELLIPSOID)).toBe( + VoxelEllipsoidShape + ); + expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.CYLINDER)).toBe( + VoxelCylinderShape + ); + }); + it("toShapeConstructor throws for invalid type", function () { + expect(function () { + return VoxelShapeType.toShapeConstructor("NOT_A_SHAPE_TYPE"); + }).toThrowDeveloperError(); + }); +}); diff --git a/Specs/Scene/VoxelTraversalSpec.js b/Specs/Scene/VoxelTraversalSpec.js new file mode 100644 index 00000000000..de7f2b2e48a --- /dev/null +++ b/Specs/Scene/VoxelTraversalSpec.js @@ -0,0 +1,396 @@ +import { + AttributeType, + ComponentDatatype, + defer, + VoxelTraversal, + VoxelPrimitive, + VoxelBoxShape, + Cartesian3, + OrientedBoundingBox, + Math as CesiumMath, + CullingVolume, +} from "../../Source/Cesium.js"; +import MetadataType from "../../Source/Scene/MetadataType.js"; +import createScene from "../createScene.js"; + +const randomNumber = CesiumMath.nextRandomNumber; +const testQueryCoords = Cartesian3.fromElements( + randomNumber() - 0.5, // get in the same interval as the shape [-0.5, 0.5] + randomNumber() - 0.5, + randomNumber() - 0.5 +); +const numberOfLevels = 15; +const numberOfBins = Math.pow(2, numberOfLevels - 1); +const maxIndex = numberOfBins - 1; +const testQueryTileCoords = Cartesian3.fromElements( + Math.floor((testQueryCoords.x + 0.5) * numberOfBins), + Math.floor((testQueryCoords.y + 0.5) * numberOfBins), + Math.floor((testQueryCoords.z + 0.5) * numberOfBins) +); +if (testQueryCoords.x > maxIndex) { + testQueryCoords.x = maxIndex; +} +if (testQueryCoords.y > maxIndex) { + testQueryCoords.y = maxIndex; +} +if (testQueryCoords.z > maxIndex) { + testQueryCoords.z = maxIndex; +} +const metadataName = "dummyMetadataName"; +function DummyVoxelProvider() { + this.shape = new VoxelBoxShape(); + const voxelDimension = 64; + this.voxelDimensions = new Cartesian3( + voxelDimension, + voxelDimension, + voxelDimension + ); + const channelCount = 4; + this.voxelsPerTile = voxelDimension * voxelDimension * voxelDimension; + this.floatsPerTile = channelCount * this.voxelsPerTile; + this.ready = true; + this.readyPromise = Promise.resolve(this); + this._tileCount = 4096; + this.neighborEdgeCount = 0; + this.numberOfLevels = numberOfLevels; + + this.properties = {}; + this.properties[metadataName] = { + type: AttributeType.VEC4, + componentType: ComponentDatatype.FLOAT, + componentCount: 4, + min: 0, + max: 1, + count: this.voxelsPerTile * this._tileCount, + }; +} +DummyVoxelProvider.prototype.requestData = function (options) { + const maxIndex = Math.pow(2, options.level) - 1; + const requestOutsideOfShape = + options.x < 0 || + options.x > maxIndex || + options.y < 0 || + options.y > maxIndex || + options.z < 0 || + options.z > maxIndex; + if (options.level >= this.numberOfLevels || requestOutsideOfShape) { + return Promise.resolve(undefined); + } + const returnArray = new Uint32Array(this.floatsPerTile); + if ( + (options.x === testQueryTileCoords.x && + options.y === testQueryTileCoords.y && + options.z === testQueryTileCoords.z && + options.level === this.numberOfLevels - 1) || + this.numberOfLevels === 1 // voxel index test + ) { + for (let i = 0; i < this.floatsPerTile; i++) { + returnArray[i] = i; + } + } + return Promise.resolve(returnArray); +}; + +const towardPrimitive = Cartesian3.fromElements(1.0, 1.0, 1.0); + +function turnCameraAround(scene) { + scene.camera.direction = Cartesian3.negate(towardPrimitive, new Cartesian3()); + scene.renderForSpecs(); +} + +describe( + "Scene/VoxelTraversal", + function () { + const provider = new DummyVoxelProvider(); + const scene = createScene(); + const frameState = scene.frameState; + const camera = frameState.camera; + const context = scene.context; + const keyframeCount = 1; + const voxelDimensions = provider.voxelDimensions; + const neighborEdgeCount = provider.neighborEdgeCount; + const channelCount = provider.channelCount; + const minimumValues = provider.minimumValues; + const maximumValues = provider.maximumValues; + const datatypes = provider.datatypes; + const textureMemory = 500; + + let traversalPromise = defer(); + let primitive; + beforeEach(function () { + camera.position = Cartesian3.fromElements(-10, -10, -10); + camera.direction = Cartesian3.fromElements(1, 1, 1); + camera.frustum.fov = CesiumMath.PI_OVER_TWO; + scene.primitives.removeAll(); + primitive = new VoxelPrimitive({ + voxelProvider: provider, + }); + scene.primitives.add(primitive); + scene.renderForSpecs(); + traversalPromise = primitive.readyPromise.then(function () { + return new VoxelTraversal( + primitive, + context, + keyframeCount, + voxelDimensions, + neighborEdgeCount, + channelCount, + minimumValues, + maximumValues, + datatypes, + textureMemory + ); + }); + }); + + it("constructs with arguments", function () { + return traversalPromise.then(function (traversal) { + expect(traversal.primitive).toBe(primitive); + const megatextureKeys = Object.keys(traversal.megatextures); + expect(megatextureKeys.length).toBe(1); + expect(megatextureKeys).toEqual( + jasmine.arrayContaining([metadataName]) + ); + const megatexture = traversal.megatexture; + expect(megatexture.channelCount).toBe( + provider.properties[metadataName].componentCount + ); + expect(megatexture.datatype).toBe(MetadataType.FLOAT); + const twiceNeighborEdgeCount = 2 * neighborEdgeCount; + expect( + megatexture.voxelCountPerTile.equals( + Cartesian3.add( + voxelDimensions, + Cartesian3.fromElements( + twiceNeighborEdgeCount, + twiceNeighborEdgeCount, + twiceNeighborEdgeCount + ), + new Cartesian3() + ) + ) + ).toBe(true); + expect(megatexture.metadataName).toBe(metadataName); + }); + }); + + it("recomputes bounding volume when shape moves", function () { + return traversalPromise.then(function (traversal) { + const rootNode = traversal.rootNode; + const oldOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); + const shape = traversal.primitive._shape; + const translation = Cartesian3.fromElements(1, 1, 1); + shape.translation = translation; + shape.update(); + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + const newOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); + expect( + OrientedBoundingBox.equals( + oldOrientedBoundingBox, + newOrientedBoundingBox + ) + ).toBe(false); + expect(newOrientedBoundingBox.center.equals(translation)).toBe(true); + }); + }); + + it("computes screen space error for root tile", function () { + return traversalPromise.then(function (traversal) { + const rootNode = traversal.rootNode; + const cameraPosition = frameState.camera.positionWC; + const screenSpaceErrorDenominator = + frameState.camera.frustum.sseDenominator; + const screenHeight = + frameState.context.drawingBufferHeight / frameState.pixelRatio; + const screenSpaceErrorMultiplier = + screenHeight / screenSpaceErrorDenominator; + rootNode.computeScreenSpaceError( + cameraPosition, + screenSpaceErrorMultiplier + ); + + let distanceToCamera = Math.sqrt( + rootNode.orientedBoundingBox.distanceSquaredTo(cameraPosition) + ); + distanceToCamera = Math.max(distanceToCamera, CesiumMath.EPSILON7); + const error = + screenSpaceErrorMultiplier * + (rootNode.approximateVoxelSize / distanceToCamera); + expect(rootNode.screenSpaceError).toBe(error); + }); + }); + + it("computes visibility for root tile", function () { + return traversalPromise.then(function (traversal) { + const rootNode = traversal.rootNode; + const visibilityPlaneMask = CullingVolume.MASK_INDETERMINATE; + + const visibilityWhenLookingAtRoot = rootNode.visibility( + frameState, + visibilityPlaneMask + ); + expect(visibilityWhenLookingAtRoot).toBe(CullingVolume.MASK_INSIDE); + + turnCameraAround(scene); + const visibilityWhenLookingAway = rootNode.visibility( + frameState, + visibilityPlaneMask + ); + expect(visibilityWhenLookingAway).toBe(CullingVolume.MASK_OUTSIDE); + }); + }); + + it("loads tiles into megatexture", function () { + return traversalPromise.then(function (traversal) { + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + + const megatexture = traversal.megatextures[metadataName]; + let tilesInMegatextureCount = megatexture.occupiedCount; + const tileInQueueWhenLookingAtRoot = tilesInMegatextureCount === 1; + expect(tileInQueueWhenLookingAtRoot).toBe(true); + + traversal.megatexture.remove(0); + turnCameraAround(scene); + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + tilesInMegatextureCount = traversal.megatexture.occupiedCount; + const tileNotInQueueWhenLookingAway = tilesInMegatextureCount === 0; + expect(tileNotInQueueWhenLookingAway).toBe(true); + }); + }); + + it("unloads tiles in megatexture", function () { + return traversalPromise.then(function (traversal) { + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + function updateTraversalTenTimes() { + // to fully fetch data and copy to texture + function updateTraversal() { + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + } + for (let i = 0; i < 10; i++) { + updateTraversal(); + } + } + + const eps = CesiumMath.EPSILON7; + const bottomLeftNearCorner = Cartesian3.fromElements( + -0.5 - eps, + -0.5 - eps, + -0.5 - eps + ); + const topRightFarCorner = Cartesian3.fromElements( + 0.5 + eps, + 0.5 + eps, + 0.5 + eps + ); + scene.camera.position = bottomLeftNearCorner; + updateTraversalTenTimes(); + const numberOfNodesOnGPU = traversal.keyframeNodesInMegatexture.length; + const deepestNode = + traversal.keyframeNodesInMegatexture[numberOfNodesOnGPU - 1]; + const deepestSpatialNode = deepestNode.spatialNode; + const nodeIsInMegatexture = + deepestNode.state === VoxelTraversal.LoadState.LOADED; + expect(nodeIsInMegatexture).toBe(true); + + scene.camera.position = topRightFarCorner; + turnCameraAround(scene); + updateTraversalTenTimes(); + const nodeNoLongerInMegatexture = + traversal.keyframeNodesInMegatexture.filter(function (keyFrameNode) { + const spatialNode = keyFrameNode.spatialNode; + return ( + spatialNode.level === deepestSpatialNode.level && + spatialNode.x === deepestSpatialNode.x && + spatialNode.y === deepestSpatialNode.y && + spatialNode.x === deepestSpatialNode.z + ); + }).length === 0; + expect(nodeNoLongerInMegatexture).toBe(true); + }); + }); + + it("gets tile metadata at a world cartesian coordiate", function () { + return traversalPromise + .then(function (traversal) { + return traversal.getMetadataAtWorldCartesian( + testQueryCoords, + metadataName + ); + }) + .then(function (queryValue) { + expect(queryValue[1]).not.toBe(0); + }); + }); + + it("gives undefined when querying metadata outside of bounds", function () { + return traversalPromise + .then(function (traversal) { + return traversal.getMetadataAtWorldCartesian( + Cartesian3.fromElements(1, 1, 1), + metadataName + ); + }) + .then(function (queryValue) { + expect(queryValue).toBe(undefined); + }); + }); + + it("returns right voxel within tile when querying", function () { + return traversalPromise.then(function (traversal) { + traversal.primitive.provider.numberOfLevels = 1; + const voxelsPerTile = provider.voxelsPerTile; + const queryPromises = new Array(voxelsPerTile); + const queryPointCoords = [ + [-0.5, -0.5, -0.5], + [0, -0.5, -0.5], + [-0.5, 0, -0.5], + [0, 0, -0.5], + [-0.5, -0.5, 0], + [0, -0.5, 0], + [-0.5, 0, 0], + [0, 0, 0], + ]; + queryPointCoords.forEach(function (coord, index) { + queryPromises[index] = traversal.getMetadataAtWorldCartesian( + Cartesian3.fromArray(coord), + metadataName + ); + }); + return Promise.all(queryPromises).then(function (queryValues) { + queryValues.forEach(function (value, index) { + expect(value[0]).toBe(index); + }); + }); + }); + }); + }, + "WebGL" +); diff --git a/Specs/Widgets/Viewer/ViewerSpec.js b/Specs/Widgets/Viewer/ViewerSpec.js index e0f816ae470..140a3e88636 100644 --- a/Specs/Widgets/Viewer/ViewerSpec.js +++ b/Specs/Widgets/Viewer/ViewerSpec.js @@ -25,6 +25,7 @@ import { ImageryLayerCollection } from "../../../Source/Cesium.js"; import { SceneMode } from "../../../Source/Cesium.js"; import { ShadowMode } from "../../../Source/Cesium.js"; import { TimeDynamicPointCloud } from "../../../Source/Cesium.js"; +import { VoxelPrimitive } from "../../../Source/Cesium.js"; import createViewer from "../../createViewer.js"; import DomEventSimulator from "../../DomEventSimulator.js"; import MockDataSource from "../../MockDataSource.js"; @@ -36,6 +37,7 @@ import { CesiumWidget } from "../../../Source/Cesium.js"; import { ClockViewModel } from "../../../Source/Cesium.js"; import { FullscreenButton } from "../../../Source/Cesium.js"; import { Geocoder } from "../../../Source/Cesium.js"; +import { GltfVoxelProvider } from "../../../Source/Cesium.js"; import { HomeButton } from "../../../Source/Cesium.js"; import { NavigationHelpButton } from "../../../Source/Cesium.js"; import { SceneModePicker } from "../../../Source/Cesium.js"; @@ -1375,6 +1377,77 @@ describe( }); }); + function loadVoxelPrimitive(viewer) { + const voxelPrimitive = new VoxelPrimitive({ + provider: new GltfVoxelProvider({ + url: + "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf", + }), + }); + viewer.scene.primitives.add(voxelPrimitive); + return voxelPrimitive.readyPromise; + } + + it("zoomTo zooms to VoxelPrimitive with default offset when offset not defined", function () { + viewer = createViewer(container); + + return loadVoxelPrimitive(viewer).then(function (voxelPrimitive) { + const expectedBoundingSphere = voxelPrimitive.boundingSphere; + const expectedOffset = new HeadingPitchRange( + 0.0, + -0.5, + expectedBoundingSphere.radius + ); + + const promise = viewer.zoomTo(voxelPrimitive); + let wasCompleted = false; + spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( + boundingSphere, + offset + ) { + expect(boundingSphere).toEqual(expectedBoundingSphere); + expect(offset).toEqual(expectedOffset); + wasCompleted = true; + }); + + viewer._postRender(); + + return promise.then(function () { + expect(wasCompleted).toEqual(true); + }); + }); + }); + + it("zoomTo zooms to VoxelPrimitive with offset", function () { + viewer = createViewer(container); + + return loadVoxelPrimitive(viewer).then(function (voxelPrimitive) { + const expectedBoundingSphere = voxelPrimitive.boundingSphere; + const expectedOffset = new HeadingPitchRange( + 0.4, + 1.2, + 4.0 * expectedBoundingSphere.radius + ); + + const promise = viewer.zoomTo(voxelPrimitive, expectedOffset); + let wasCompleted = false; + spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( + boundingSphere, + offset + ) { + expect(boundingSphere).toEqual(expectedBoundingSphere); + expect(offset).toEqual(expectedOffset); + wasCompleted = true; + }); + + viewer._postRender(); + + return promise.then(function () { + expect(wasCompleted).toEqual(true); + }); + }); + }); + it("zoomTo zooms to entity with undefined offset when offset not defined", function () { viewer = createViewer(container); viewer.entities.add({ @@ -1649,6 +1722,92 @@ describe( }); }); + it("flyTo flies to VoxelPrimitive with default offset when options not defined", function () { + viewer = createViewer(container); + + return loadVoxelPrimitive(viewer).then(function (voxelPrimitive) { + const promise = viewer.flyTo(voxelPrimitive); + let wasCompleted = false; + + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.offset).toBeDefined(); + expect(options.duration).toBeUndefined(); + expect(options.maximumHeight).toBeUndefined(); + wasCompleted = true; + options.complete(); + }); + + viewer._postRender(); + + return promise.then(function () { + expect(wasCompleted).toEqual(true); + }); + }); + }); + + it("flyTo flies to VoxelPrimitive with default offset when offset not defined", function () { + viewer = createViewer(container); + const options = {}; + + return loadVoxelPrimitive(viewer).then(function (voxelPrimitive) { + const promise = viewer.flyTo(voxelPrimitive, options); + let wasCompleted = false; + + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.offset).toBeDefined(); + expect(options.duration).toBeUndefined(); + expect(options.maximumHeight).toBeUndefined(); + wasCompleted = true; + options.complete(); + }); + + viewer._postRender(); + + return promise.then(function () { + expect(wasCompleted).toEqual(true); + }); + }); + }); + + it("flyTo flies to VoxelPrimitive when options are defined", function () { + viewer = createViewer(container); + + // load tileset to test + return loadVoxelPrimitive(viewer).then(function (voxelPrimitive) { + const offsetVal = new HeadingPitchRange(3.0, 0.2, 2.3); + const options = { + offset: offsetVal, + duration: 3.0, + maximumHeight: 5.0, + }; + + const promise = viewer.flyTo(voxelPrimitive, options); + let wasCompleted = false; + + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.duration).toBeDefined(); + expect(options.maximumHeight).toBeDefined(); + wasCompleted = true; + options.complete(); + }); + + viewer._postRender(); + + return promise.then(function () { + expect(wasCompleted).toEqual(true); + }); + }); + }); + it("flyTo flies to entity with default offset when options not defined", function () { viewer = createViewer(container); From 2a6e026ff9b847fb06a133f5aa8695d749667db8 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 31 Mar 2022 15:24:03 -0400 Subject: [PATCH 002/679] cleaned up buildDrawCommands --- Source/Scene/VoxelPrimitive.js | 623 ++++++++++++--------------------- 1 file changed, 221 insertions(+), 402 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 5742baf92bf..838ccb3b3e7 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -19,7 +19,6 @@ import ShaderDestination from "../Renderer/ShaderDestination.js"; import BlendingState from "./BlendingState.js"; import CullFace from "./CullFace.js"; import CustomShader from "./ModelExperimental/CustomShader.js"; -import CustomShaderPipelineStage from "./ModelExperimental/CustomShaderPipelineStage.js"; import Material from "./Material.js"; import PolylineCollection from "./PolylineCollection.js"; import VoxelShapeType from "./VoxelShapeType.js"; @@ -27,8 +26,7 @@ import VoxelTraversal from "./VoxelTraversal.js"; import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; import ShaderBuilder from "../Renderer/ShaderBuilder.js"; -// import VoxelFS from "../Shaders/VoxelFS.js"; -import VoxelFS_String from "./VoxelFS_String.js"; +import VoxelFS from "../Shaders/VoxelFS.js"; import VoxelVS from "../Shaders/VoxelVS.js"; import MetadataType from "./MetadataType.js"; /** @@ -1339,12 +1337,12 @@ VoxelPrimitive.prototype.update = function (frameState) { uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; uniforms.octreeLeafNodeTexelSizeUv = traversal.leafNodeTexelSizeUv; - uniforms.megatextureTextures = []; const megatextures = traversal.megatextures; const megatexture = megatextures[0]; const megatextureLength = megatextures.length; + uniforms.megatextureTextures = new Array(megatextureLength); for (let i = 0; i < megatextureLength; i++) { - uniforms.megatextureTextures.push(megatextures[i].texture); + uniforms.megatextureTextures[i] = megatextures[i].texture; } uniforms.megatextureSliceDimensions = Cartesian2.clone( @@ -1585,21 +1583,54 @@ VoxelPrimitive.prototype.update = function (frameState) { } }; +/** + * @param {MetadataType} type + */ +function getGlslType(type) { + if (type === MetadataType.SCALAR) { + return "float"; + } else if (type === MetadataType.VEC2) { + return "vec2"; + } else if (type === MetadataType.VEC3) { + return "vec3"; + } else if (type === MetadataType.VEC4) { + return "vec4"; + } + return "vec4"; +} +/** + * @param {MetadataType} type + */ +function getGlslTextureSwizzle(type) { + if (type === MetadataType.SCALAR) { + return ".r"; + } else if (type === MetadataType.VEC2) { + return ".ra"; + } else if (type === MetadataType.VEC3) { + return ".rgb"; + } else if (type === MetadataType.VEC4) { + return ""; + } + return ""; +} + +/** + * @param {MetadataType} type + * @param {Number} index + */ +function getGlslField(type, index) { + if (type === MetadataType.SCALAR) { + return ""; + } + return `.[${index}]`; +} + /** * @param {VoxelPrimitive} that * @param {Context} context * @private */ function buildDrawCommands(that, context) { - // const renderResources - // CustomShaderPipelineStage.process(renderResources, primitive); - - // TODO: questions about custom shaders: - // - where should attribute min/max go? - // - should shader builder call `fromCache` or `replaceCache` - - // return; - const provider = that._provider; const shapeType = provider.shape; const names = provider.names; @@ -1622,22 +1653,25 @@ function buildDrawCommands(that, context) { const customShader = that._customShader; const attributeLength = types.length; - // Vertex shader - const shaderBuilder = new ShaderBuilder(); - shaderBuilder.addVertexLines([VoxelVS]); - // Fragment shader + // Vertex shader + shaderBuilder.addVertexLines(["#line 0", VoxelVS]); + shaderBuilder.setPositionAttribute("vec4", "a_position"); - const fragmentStructId = CustomShaderPipelineStage.STRUCT_ID_FRAGMENT_INPUT; - const fragmentStructName = - CustomShaderPipelineStage.STRUCT_NAME_FRAGMENT_INPUT; + // Fragment shader + shaderBuilder.addFragmentLines([ + customShader.fragmentShaderText, + "#line 0", + VoxelFS, + ]); - const attributeStructId = CustomShaderPipelineStage.STRUCT_ID_ATTRIBUTES_FS; - const attributeStructName = CustomShaderPipelineStage.STRUCT_NAME_ATTRIBUTES; + const fragmentStructId = "FragmentInput"; + const fragmentStructName = "FragmentInput"; + const attributeStructId = "Attributes"; + const attributeStructName = "Attributes"; const attributeFieldName = "attributes"; - - const voxelStructId = "VoxelFS"; + const voxelStructId = "Voxel"; const voxelStructName = "Voxel"; const voxelFieldName = "voxel"; @@ -1648,49 +1682,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - /** - * - * @param {MetadataType} type - */ - function getGlslType(type) { - if (type === MetadataType.SCALAR) { - return "float"; - } else if (type === MetadataType.VEC2) { - return "vec2"; - } else if (type === MetadataType.VEC3) { - return "vec3"; - } else if (type === MetadataType.VEC4) { - return "vec4"; - } - return "vec4"; - } - /** - * @param {MetadataType} type - */ - function getGlslTextureSwizzle(type) { - if (type === MetadataType.SCALAR) { - return ".r"; - } else if (type === MetadataType.VEC2) { - return ".ra"; - } else if (type === MetadataType.VEC3) { - return ".rgb"; - } else if (type === MetadataType.VEC4) { - return ""; - } - return ""; - } - - /** - * @param {MetadataType} type - * @param {Number} index - */ - function getGlslField(type, index) { - if (type === MetadataType.SCALAR) { - return ""; - } - return `.[${index}]`; - } - for (let i = 0; i < attributeLength; i++) { const name = names[i]; const type = types[i]; @@ -1731,34 +1722,177 @@ function buildDrawCommands(that, context) { fragmentStructName, ShaderDestination.FRAGMENT ); - shaderBuilder.addStructField( fragmentStructId, attributeStructName, attributeFieldName ); - shaderBuilder.addStructField( fragmentStructId, voxelStructName, voxelFieldName ); - // Custom shader - shaderBuilder.addFragmentLines([customShader.fragmentShaderText]); + shaderBuilder.addUniform( + "sampler2D", + "u_megatextureTextures[METADATA_COUNT]", + ShaderDestination.FRAGMENT + ); + + // clearAttributes function + { + const clearAttributesFunctionId = "clearAttributes"; + const clearAttributesFunctionName = "clearAttributes"; + + shaderBuilder.addFunction( + clearAttributesFunctionId, + `${attributeStructName} ${clearAttributesFunctionName}()`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslType = getGlslType(type, componentType); + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `attributes.${name} = ${glslType}(0.0);`, + ]); + } + shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // sumAttributes function + { + const sumAttributesFunctionId = "sumAttributes"; + const sumAttributesFunctionName = "sumAttributes"; + const sumAttributesFunctionDeclaration = `${attributeStructName} ${sumAttributesFunctionName}(${attributeStructName} attributesA, ${attributeStructName} attributesB)`; + + shaderBuilder.addFunction( + sumAttributesFunctionId, + sumAttributesFunctionDeclaration, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `${attributeFieldName}.${name} = attributesA.${name} + attributesB.${name};`, + ]); + } + shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // mixAttributes + { + const mixAttributesFunctionId = "mixAttributes"; + const mixAttributesFunctionName = "mixAttributes"; + const mixAttributesFieldAttributesA = "attributesA"; + const mixAttributesFieldAttributesB = "attributesB"; + const mixAttributesFieldMixAmount = "mixFactor"; + shaderBuilder.addFunction( + mixAttributesFunctionId, + `${attributeStructName} ${mixAttributesFunctionName}(${attributeStructName} ${mixAttributesFieldAttributesA}, ${attributeStructName} ${mixAttributesFieldAttributesB}, float ${mixAttributesFieldMixAmount})`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `attributes.${name} = mix(${mixAttributesFieldAttributesA}.${name}, ${mixAttributesFieldAttributesB}.${name}, ${mixAttributesFieldMixAmount});`, + ]); + } + shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ + `return attributes;`, + ]); + } + + // setMinMaxAttributes function + if (defined(minimumValues) && defined(maximumValues)) { + shaderBuilder.addDefine( + "HAS_MIN_MAX", + undefined, + ShaderDestination.FRAGMENT + ); + const minMaxAttributesFunctionId = "setMinMaxAttributes"; + const minMaxAttributesFunctionName = "setMinMaxAttributes"; + shaderBuilder.addFunction( + minMaxAttributesFunctionId, + `void ${minMaxAttributesFunctionName}(inout ${voxelStructName} ${voxelFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + for (let j = 0; j < componentCount; j++) { + const minimumValue = minimumValues[i][j]; + const maximumValue = maximumValues[i][j]; + + // glsl needs to have `.0` at the end of whole numbers floats. + let minimumValueString = minimumValue.toString(); + if (minimumValueString.indexOf(".") === -1) { + minimumValueString = `${minimumValue}.0`; + } + let maximumValueString = maximumValue.toString(); + if (maximumValueString.indexOf(".") === -1) { + maximumValueString = `${maximumValue}.0`; + } + + const glslField = getGlslField(type, j); + const minLine = `${voxelFieldName}.${name}Minimum${glslField} = ${minimumValueString};`; + const maxLine = `${voxelFieldName}.${name}Maximum${glslField} = ${maximumValueString};`; + shaderBuilder.addFunctionLines(minMaxAttributesFunctionId, [ + minLine, + maxLine, + ]); + } + } + } + + const sampleFrom2DMegatextureId = "sampleFrom2DMegatextureAtUv"; + const sampleFrom2DMegatextureName = "sampleFrom2DMegatextureAtUv"; + shaderBuilder.addFunction( + sampleFrom2DMegatextureId, + `${attributeStructName} ${sampleFrom2DMegatextureName}(vec2 uv)`, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `${attributeStructName} attributes;`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `attributes.${name} = texture2D(u_megatextureTextures[${i}], uv)${glslTextureSwizzle};`, + ]); + } + shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ + `return attributes;`, + ]); - // Voxel shader - shaderBuilder.addFragmentLines(["#line 0", VoxelFS_String]); shaderBuilder.addDefine( "METADATA_COUNT", attributeLength, ShaderDestination.FRAGMENT ); - shaderBuilder.addUniform( - "sampler2D", - "u_megatextureTextures[METADATA_COUNT]", - ShaderDestination.FRAGMENT - ); shaderBuilder.addDefine( `SHAPE_${shapeType}`, @@ -1825,15 +1959,15 @@ function buildDrawCommands(that, context) { const isDefaultMaxX = maxBounds.x === defaultMaxBounds.x; const isDefaultMaxY = maxBounds.y === defaultMaxBounds.y; const isDefaultMaxZ = maxBounds.z === defaultMaxBounds.z; - - if ( + const useBounds = !isDefaultMinX || !isDefaultMinY || !isDefaultMinZ || !isDefaultMaxX || !isDefaultMaxY || - !isDefaultMaxZ - ) { + !isDefaultMaxZ; + + if (useBounds) { shaderBuilder.addDefine("BOUNDS", undefined, ShaderDestination.FRAGMENT); } @@ -1851,7 +1985,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - if (!isDefaultMinY) { shaderBuilder.addDefine( "BOUNDS_1_MIN", @@ -1866,7 +1999,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - if (!isDefaultMinZ) { shaderBuilder.addDefine( "BOUNDS_2_MIN", @@ -1976,327 +2108,22 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - if ( + const useClippingBounds = minClippingBounds.x !== defaultMinBounds.x || minClippingBounds.y !== defaultMinBounds.y || minClippingBounds.z !== defaultMinBounds.z || maxClippingBounds.x !== defaultMaxBounds.x || maxClippingBounds.y !== defaultMaxBounds.y || - maxClippingBounds.z !== defaultMaxBounds.z - ) { - shaderBuilder.addDefine( - "CLIPPING_BOUNDS", - undefined, - ShaderDestination.FRAGMENT - ); - } + maxClippingBounds.z !== defaultMaxBounds.z; - // clearAttributes function - { - const clearAttributesFunctionId = "clearAttributes"; - const clearAttributesFunctionName = "clearAttributes"; - - shaderBuilder.addFunction( - clearAttributesFunctionId, - `${attributeStructName} ${clearAttributesFunctionName}()`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslType = getGlslType(type, componentType); - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `attributes.${name} = ${glslType}(0.0);`, - ]); - } - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // sumAttributes function - { - const sumAttributesFunctionId = "sumAttributes"; - const sumAttributesFunctionName = "sumAttributes"; - const sumAttributesFunctionDeclaration = `${attributeStructName} ${sumAttributesFunctionName}(${attributeStructName} attributesA, ${attributeStructName} attributesB)`; - - shaderBuilder.addFunction( - sumAttributesFunctionId, - sumAttributesFunctionDeclaration, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `${attributeFieldName}.${name} = attributesA.${name} + attributesB.${name};`, - ]); - } - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // mixAttributes - { - const mixAttributesFunctionId = "mixAttributes"; - const mixAttributesFunctionName = "mixAttributes"; - const mixAttributesFieldAttributesA = "attributesA"; - const mixAttributesFieldAttributesB = "attributesB"; - const mixAttributesFieldMixAmount = "mixFactor"; - shaderBuilder.addFunction( - mixAttributesFunctionId, - `${attributeStructName} ${mixAttributesFunctionName}(${attributeStructName} ${mixAttributesFieldAttributesA}, ${attributeStructName} ${mixAttributesFieldAttributesB}, float ${mixAttributesFieldMixAmount})`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `attributes.${name} = mix(${mixAttributesFieldAttributesA}.${name}, ${mixAttributesFieldAttributesB}.${name}, ${mixAttributesFieldMixAmount});`, - ]); - } - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // setMinMaxAttributes function - if (defined(minimumValues) && defined(maximumValues)) { + if (useClippingBounds) { shaderBuilder.addDefine( - "HAS_MIN_MAX", + "CLIPPING_BOUNDS", undefined, ShaderDestination.FRAGMENT ); - const minMaxAttributesFunctionId = "setMinMaxAttributes"; - const minMaxAttributesFunctionName = "setMinMaxAttributes"; - shaderBuilder.addFunction( - minMaxAttributesFunctionId, - `void ${minMaxAttributesFunctionName}(inout ${voxelStructName} ${voxelFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentCount = MetadataType.getComponentCount(type); - for (let j = 0; j < componentCount; j++) { - const minimumValue = minimumValues[i][j]; - const maximumValue = maximumValues[i][j]; - - // glsl needs to have `.0` at the end of whole numbers floats. - let minimumValueString = minimumValue.toString(); - if (minimumValueString.indexOf(".") === -1) { - minimumValueString = `${minimumValue}.0`; - } - let maximumValueString = maximumValue.toString(); - if (maximumValueString.indexOf(".") === -1) { - maximumValueString = `${maximumValue}.0`; - } - - const glslField = getGlslField(type, j); - const minLine = `${voxelFieldName}.${name}Minimum${glslField} = ${minimumValueString};`; - const maxLine = `${voxelFieldName}.${name}Maximum${glslField} = ${maximumValueString};`; - shaderBuilder.addFunctionLines(minMaxAttributesFunctionId, [ - minLine, - maxLine, - ]); - } - } - } - - // for (i = 0; i < propertiesLength; i++) { - // property = properties[i]; - // type = property.type; - // name = property.name; - // channelCount = AttributeType.getNumberOfComponents(type); - // minValue = property.min; - // maxValue = property.max; - // sampleType = getStyleInputSampleType(property); - // sampleScale = getTypeScale(property); - - // const mins = []; - // const maxs = []; - - // if (channelCount === 1) { - // mins.push(`${sampleScale} * ${toTypedString(minValue, property)}`); - // maxs.push(`${sampleScale} * ${toTypedString(maxValue, property)}`); - // } else { - // mins.push(`${sampleScale} * ${toTypedString(minValue.x, property)}`); - // maxs.push(`${sampleScale} * ${toTypedString(maxValue.x, property)}`); - - // mins.push(`${sampleScale} * ${toTypedString(minValue.y, property)}`); - // maxs.push(`${sampleScale} * ${toTypedString(maxValue.y, property)}`); - - // if (channelCount >= 3) { - // mins.push(`${sampleScale} * ${toTypedString(minValue.z, property)}`); - // maxs.push(`${sampleScale} * ${toTypedString(maxValue.z, property)}`); - // } - // if (channelCount >= 4) { - // mins.push(`${sampleScale} * ${toTypedString(minValue.w, property)}`); - // maxs.push(`${sampleScale} * ${toTypedString(maxValue.w, property)}`); - // } - // } - - // const minVec = `${sampleType}(${mins.join(", ")})`; - // const maxVec = `${sampleType}(${maxs.join(", ")})`; - - // shaderBuilder.addFunctionLines("setMinMax", [ - // `styleInput.${name}Minimum = ${minVec};`, - // `styleInput.${name}Maximum = ${maxVec};`, - // ]); - // } - - // const styleShaderSource = primitive._styleMaterial.shaderSource; - // shaderBuilder.addDefine("STYLE_USE_NORMAL"); - // if (styleShaderSource.includes("styleInput.positionEC")) { - // shaderBuilder.addDefine("STYLE_USE_POSITION_EC"); - // } - // shaderBuilder.addFragmentLines([styleShaderSource]); - - // Generate shaders - shaderBuilder.setPositionAttribute("vec4", "a_position"); - - // // set normals - // const setNormalsArgs = [ - // `in vec3 normalLocal[${propertiesLength}]`, - // `in vec3 normalWorld[${propertiesLength}]`, - // `in vec3 normalView[${propertiesLength}]`, - // `in bool normalValid[${propertiesLength}]`, - // "inout StyleInput styleInput", - // ]; - - // const setNormalsSig = `void setStyleInputNormals(${setNormalsArgs.join( - // ", " - // )})`; - - // shaderBuilder.addFunction( - // "setNormals", - // setNormalsSig, - // ShaderDestination.FRAGMENT - // ); - - // for (i = 0; i < propertiesLength; i++) { - // property = properties[i]; - // name = property.name; - // shaderBuilder.addFunctionLines("setNormals", [ - // `styleInput.${name}NormalLocal` + ` = normalLocal[${i}];`, - // `styleInput.${name}NormalWorld` + ` = normalWorld[${i}];`, - // `styleInput.${name}NormalView` + ` = normalView[${i}];`, - // `styleInput.${name}NormalValid` + ` = normalValid[${i}];`, - // ]); - // } - - // // set samples - // const setSamplesFunctionId = "setSamples"; - // const setSamplesDefinition = `void setSamples(in vec4 samples[${attributeLength}], inout ${CustomShaderPipelineStage.STRUCT_NAME_ATTRIBUTES} ${attributesFieldName})`; - - // shaderBuilder.addFunction( - // setSamplesFunctionId, - // setSamplesDefinition, - // ShaderDestination.FRAGMENT - // ); - - // for (let i = 0; i < attributeLength; i++) { - // const name = names[i]; - // // const scaleVar = `scale_${name}`; - - // shaderBuilder.addFunctionLines(setSamplesFunctionId, [ - // // `vec4 ${scaleVar} = vec4(${sampleScale});`, - // // `attributes.${name} = ${sampleType}(${scaleVar} * samples[${i}]${swizzler});`, - // `${attributesFieldName}.${name} = `, - // ]); - // } - - // shaderBuilder.addFunction( - // "decodeSamples", - // "void decodeTextureSamples(inout vec4 samples[METADATA_COUNT])", - // ShaderDestination.FRAGMENT - // ); - - // shaderBuilder.addFunctionLines("decodeSamples", ["vec4 sample;"]); - - // for (i = 0; i < propertiesLength; i++) { - // property = properties[i]; - // type = property.type; - // channelCount = AttributeType.getNumberOfComponents(type); - - // shaderBuilder.addFunctionLines("decodeSamples", [ - // `sample = samples[${i}];`, - // ]); - - // if (!defined(channelCount) || channelCount === 1) { - // shaderBuilder.addFunctionLines("decodeSamples", [ - // "sample = vec4(1.0, 1.0, 1.0, sample.r);", - // ]); - // } else if (channelCount === 2) { - // shaderBuilder.addFunctionLines("decodeSamples", [ - // "sample = vec4(sample.r, sample.a, 1.0, 1.0);", - // ]); - // } - - // if (type === MetadataType.UINT8) { - // shaderBuilder.addFunctionLines("decodeSamples", [ - // `sample = mix(u_minimumValues[${i}], u_maximumValues[${i}], sample);`, - // ]); - // } - - // shaderBuilder.addFunctionLines("decodeSamples", [ - // `samples[${i}] = sample;`, - // ]); - // } - - // Looping over the sampler array was causing strange rendering artifacts even though the shader compiled fine. - // Unroling the for loop fixed the problem. - // for (int i = 0; i < METADATA_COUNT; i++) - // { - // vec4 value0 = texture2D(u_megatextureTextures[i], uv0); - // vec4 value1 = texture2D(u_megatextureTextures[i], uv1); - // samples[i] = mix(value0, value1, lerp); - // } - - const sampleFrom2DMegatextureId = "sampleFrom2DMegatextureAtUv"; - const sampleFrom2DMegatextureName = "sampleFrom2DMegatextureAtUv"; - shaderBuilder.addFunction( - sampleFrom2DMegatextureId, - `${attributeStructName} ${sampleFrom2DMegatextureName}(vec2 uv)`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `attributes.${name} = texture2D(u_megatextureTextures[${i}], uv)${glslTextureSwizzle};`, - ]); } - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `return attributes;`, - ]); - - // shaderBuilder.addFunctionLines("sampleUv", [ - // "decodeTextureSamples(samples);", - // ]); - // const voxelPrimitive = renderResources.model.voxelPrimitive; - // addRuntimeVoxelProperties(shaderBuilder, voxelPrimitive); - // // primitive.update(frameState); const shaderBuilderPick = shaderBuilder.clone(); shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); @@ -2315,10 +2142,7 @@ function buildDrawCommands(that, context) { blending: BlendingState.ALPHA_BLEND, }); - // var baseUniformMap = that._uniformMap; - // var uniformMap = combine(baseUniformMap, styleUniformMap); const uniformMap = that._uniformMap; - const viewportQuadVertexArray = context.getViewportQuadVertexArray(); const drawCommand = new DrawCommand({ vertexArray: viewportQuadVertexArray, @@ -2329,9 +2153,6 @@ function buildDrawCommands(that, context) { pass: Pass.VOXELS, executeInClosestFrustum: true, owner: this, - // boundingVolume: primitiveRenderResources.boundingSphere, - // modelMatrix: primitiveRenderResources.modelMatrix, - // debugShowBoundingVolume : true }); const drawCommandPick = DrawCommand.shallowClone( @@ -2355,8 +2176,6 @@ function buildDrawCommands(that, context) { that._drawCommand = drawCommand; that._drawCommandPick = drawCommandPick; - - console.log(drawCommand.shaderProgram._fragmentShaderText); } /** From ea60548c3834c23b849a5040b547a7808119292f Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 31 Mar 2022 22:03:09 -0400 Subject: [PATCH 003/679] custom shader improvements and relatively large shader cleanup --- Apps/Sandcastle/gallery/Voxels.html | 4 +- CHANGES.md | 1 + Source/Scene/VoxelPrimitive.js | 621 +++++++++++++---------- Source/Shaders/VoxelFS.glsl | 735 +++++++++++++--------------- 4 files changed, 704 insertions(+), 657 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 8ec79d69033..a55ffc38e8a 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -356,7 +356,7 @@ const customShaderColor = new Cesium.CustomShader({ fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - material.diffuse = fsInput.attributes.color.rgb; + material.diffuse = fsInput.metadata.color.rgb; material.alpha = 1.0; }`, }); @@ -364,7 +364,7 @@ const customShaderAlpha = new Cesium.CustomShader({ fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - material.diffuse = vec3(1.0);//fsInput.attributes.a); + material.diffuse = vec3(1.0);//fsInput.metadata.a); material.alpha = 1.0; }`, }); diff --git a/CHANGES.md b/CHANGES.md index 371ed97dd90..666a47bddc5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ - Refactored metadata API so `tileset.metadata` and `content.group.metadata` are more symmetric with `content.metadata` and `tile.metadata`. [#10224](https://github.com/CesiumGS/cesium/pull/10224) - Added support for `EXT_structural_metadata` property attributes in `CustomShader` [#10228](https://github.com/CesiumGS/cesium/pull/10228) - Added partial support for `EXT_structural_metadata` property textures in `CustomShader` [#10247](https://github.com/CesiumGS/cesium/pull/10247) +- Added experimental voxel rendering that supports glTF with EXT_primitive_voxels, 3D Tiles, and procedural data. [#10253](https://github.com/CesiumGS/cesium/pull/10253). ##### Fixes :wrench: diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 838ccb3b3e7..034777b6919 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1583,8 +1583,12 @@ VoxelPrimitive.prototype.update = function (frameState) { } }; +// Shader builder helpers + /** * @param {MetadataType} type + * @returns {String} + * @private */ function getGlslType(type) { if (type === MetadataType.SCALAR) { @@ -1596,10 +1600,11 @@ function getGlslType(type) { } else if (type === MetadataType.VEC4) { return "vec4"; } - return "vec4"; } /** * @param {MetadataType} type + * @returns {String} + * @private */ function getGlslTextureSwizzle(type) { if (type === MetadataType.SCALAR) { @@ -1611,12 +1616,45 @@ function getGlslTextureSwizzle(type) { } else if (type === MetadataType.VEC4) { return ""; } - return ""; +} + +/** + * @param {MetadataType} type + * @returns {String} + * @private + */ +function getGlslPartialDerivativeType(type) { + if (type === MetadataType.SCALAR) { + return "vec3"; + } else if (type === MetadataType.VEC2) { + return "mat2"; + } else if (type === MetadataType.VEC3) { + return "mat3"; + } else if (type === MetadataType.VEC4) { + return "mat4"; + } +} + +/** + * GLSL needs to have `.0` at the end of whole number floats or else it's + * treated like an integer. + * @param {Number} number + * @returns {String} + * @private + */ +function getGlslNumberAsFloat(number) { + let numberString = number.toString(); + if (numberString.indexOf(".") === -1) { + numberString = `${number}.0`; + } + return numberString; } /** * @param {MetadataType} type * @param {Number} index + * @returns {String} + * @private */ function getGlslField(type, index) { if (type === MetadataType.SCALAR) { @@ -1652,261 +1690,49 @@ function buildDrawCommands(that, context) { const nearestSampling = that._nearestSampling; const customShader = that._customShader; const attributeLength = types.length; + const hasStatistics = defined(minimumValues) && defined(maximumValues); + + // Build shader const shaderBuilder = new ShaderBuilder(); // Vertex shader - shaderBuilder.addVertexLines(["#line 0", VoxelVS]); - shaderBuilder.setPositionAttribute("vec4", "a_position"); + + shaderBuilder.addVertexLines([VoxelVS]); // Fragment shader + shaderBuilder.addFragmentLines([ customShader.fragmentShaderText, "#line 0", VoxelFS, ]); - const fragmentStructId = "FragmentInput"; - const fragmentStructName = "FragmentInput"; - const attributeStructId = "Attributes"; - const attributeStructName = "Attributes"; - const attributeFieldName = "attributes"; - const voxelStructId = "Voxel"; - const voxelStructName = "Voxel"; - const voxelFieldName = "voxel"; - - // Attribute struct - shaderBuilder.addStruct( - attributeStructId, - attributeStructName, - ShaderDestination.FRAGMENT - ); - - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(attributeStructId, glslType, name); - } - - // Voxel struct - shaderBuilder.addStruct( - voxelStructId, - voxelStructName, - ShaderDestination.FRAGMENT - ); - - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(voxelStructId, glslType, `${name}Minimum`); - shaderBuilder.addStructField(voxelStructId, glslType, `${name}Maximum`); - shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalLocal`); - shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalWorld`); - shaderBuilder.addStructField(voxelStructId, "vec3", `${name}NormalView`); - shaderBuilder.addStructField(voxelStructId, "bool", `${name}NormalValid`); - } - - shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvShapeSpace"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); - shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); - - // FragmentInput struct - shaderBuilder.addStruct( - fragmentStructId, - fragmentStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - fragmentStructId, - attributeStructName, - attributeFieldName - ); - shaderBuilder.addStructField( - fragmentStructId, - voxelStructName, - voxelFieldName - ); - - shaderBuilder.addUniform( - "sampler2D", - "u_megatextureTextures[METADATA_COUNT]", - ShaderDestination.FRAGMENT - ); - - // clearAttributes function - { - const clearAttributesFunctionId = "clearAttributes"; - const clearAttributesFunctionName = "clearAttributes"; - - shaderBuilder.addFunction( - clearAttributesFunctionId, - `${attributeStructName} ${clearAttributesFunctionName}()`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslType = getGlslType(type, componentType); - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `attributes.${name} = ${glslType}(0.0);`, - ]); - } - shaderBuilder.addFunctionLines(clearAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // sumAttributes function - { - const sumAttributesFunctionId = "sumAttributes"; - const sumAttributesFunctionName = "sumAttributes"; - const sumAttributesFunctionDeclaration = `${attributeStructName} ${sumAttributesFunctionName}(${attributeStructName} attributesA, ${attributeStructName} attributesB)`; - - shaderBuilder.addFunction( - sumAttributesFunctionId, - sumAttributesFunctionDeclaration, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `${attributeFieldName}.${name} = attributesA.${name} + attributesB.${name};`, - ]); - } - shaderBuilder.addFunctionLines(sumAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // mixAttributes - { - const mixAttributesFunctionId = "mixAttributes"; - const mixAttributesFunctionName = "mixAttributes"; - const mixAttributesFieldAttributesA = "attributesA"; - const mixAttributesFieldAttributesB = "attributesB"; - const mixAttributesFieldMixAmount = "mixFactor"; - shaderBuilder.addFunction( - mixAttributesFunctionId, - `${attributeStructName} ${mixAttributesFunctionName}(${attributeStructName} ${mixAttributesFieldAttributesA}, ${attributeStructName} ${mixAttributesFieldAttributesB}, float ${mixAttributesFieldMixAmount})`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `attributes.${name} = mix(${mixAttributesFieldAttributesA}.${name}, ${mixAttributesFieldAttributesB}.${name}, ${mixAttributesFieldMixAmount});`, - ]); - } - shaderBuilder.addFunctionLines(mixAttributesFunctionId, [ - `return attributes;`, - ]); - } - - // setMinMaxAttributes function - if (defined(minimumValues) && defined(maximumValues)) { - shaderBuilder.addDefine( - "HAS_MIN_MAX", - undefined, - ShaderDestination.FRAGMENT - ); - const minMaxAttributesFunctionId = "setMinMaxAttributes"; - const minMaxAttributesFunctionName = "setMinMaxAttributes"; - shaderBuilder.addFunction( - minMaxAttributesFunctionId, - `void ${minMaxAttributesFunctionName}(inout ${voxelStructName} ${voxelFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentCount = MetadataType.getComponentCount(type); - for (let j = 0; j < componentCount; j++) { - const minimumValue = minimumValues[i][j]; - const maximumValue = maximumValues[i][j]; - - // glsl needs to have `.0` at the end of whole numbers floats. - let minimumValueString = minimumValue.toString(); - if (minimumValueString.indexOf(".") === -1) { - minimumValueString = `${minimumValue}.0`; - } - let maximumValueString = maximumValue.toString(); - if (maximumValueString.indexOf(".") === -1) { - maximumValueString = `${maximumValue}.0`; - } - - const glslField = getGlslField(type, j); - const minLine = `${voxelFieldName}.${name}Minimum${glslField} = ${minimumValueString};`; - const maxLine = `${voxelFieldName}.${name}Maximum${glslField} = ${maximumValueString};`; - shaderBuilder.addFunctionLines(minMaxAttributesFunctionId, [ - minLine, - maxLine, - ]); - } - } - } - - const sampleFrom2DMegatextureId = "sampleFrom2DMegatextureAtUv"; - const sampleFrom2DMegatextureName = "sampleFrom2DMegatextureAtUv"; - shaderBuilder.addFunction( - sampleFrom2DMegatextureId, - `${attributeStructName} ${sampleFrom2DMegatextureName}(vec2 uv)`, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `${attributeStructName} attributes;`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `attributes.${name} = texture2D(u_megatextureTextures[${i}], uv)${glslTextureSwizzle};`, - ]); - } - shaderBuilder.addFunctionLines(sampleFrom2DMegatextureId, [ - `return attributes;`, - ]); + // Fragment shader defines shaderBuilder.addDefine( "METADATA_COUNT", attributeLength, ShaderDestination.FRAGMENT ); - shaderBuilder.addDefine( `SHAPE_${shapeType}`, undefined, ShaderDestination.FRAGMENT ); + shaderBuilder.addDefine( + "MEGATEXTURE_2D", + undefined, + ShaderDestination.FRAGMENT + ); + if ( !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) ) { shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); } - if (depthTest) { shaderBuilder.addDefine( "DEPTH_TEST", @@ -1925,7 +1751,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - if (jitter) { shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); } @@ -1937,10 +1762,16 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - if (despeckle) { shaderBuilder.addDefine("DESPECKLE", undefined, ShaderDestination.FRAGMENT); } + if (hasStatistics) { + shaderBuilder.addDefine( + "STATISTICS", + undefined, + ShaderDestination.FRAGMENT + ); + } const sampleCount = keyframeCount > 1 ? 2 : 1; shaderBuilder.addDefine( @@ -1952,7 +1783,6 @@ function buildDrawCommands(that, context) { const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); const defaultMinBounds = ShapeConstructor.DefaultMinBounds; const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; - const isDefaultMinX = minBounds.x === defaultMinBounds.x; const isDefaultMinY = minBounds.y === defaultMinBounds.y; const isDefaultMinZ = minBounds.z === defaultMinBounds.z; @@ -1966,11 +1796,9 @@ function buildDrawCommands(that, context) { !isDefaultMaxX || !isDefaultMaxY || !isDefaultMaxZ; - if (useBounds) { shaderBuilder.addDefine("BOUNDS", undefined, ShaderDestination.FRAGMENT); } - if (!isDefaultMinX) { shaderBuilder.addDefine( "BOUNDS_0_MIN", @@ -2013,7 +1841,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - let intersectionCount = 0; if (shapeType === VoxelShapeType.BOX) { // A bounded box is still a box, so it has the same number of shape intersections: 1 @@ -2028,7 +1855,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects an inner ellipsoid for the min radius if (!isDefaultMinZ) { shaderBuilder.addDefine( @@ -2038,7 +1864,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects a cone for min latitude if (!isDefaultMinY) { shaderBuilder.addDefine( @@ -2048,7 +1873,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects a cone for max latitude if (!isDefaultMaxY) { shaderBuilder.addDefine( @@ -2058,7 +1882,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects a wedge for the min and max longitude if (!isDefaultMinX || !isDefaultMaxX) { shaderBuilder.addDefine( @@ -2079,7 +1902,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects an inner infinite cylinder for the min radius if (!isDefaultMinX) { shaderBuilder.addDefine( @@ -2089,7 +1911,6 @@ function buildDrawCommands(that, context) { ); intersectionCount++; } - // Intersects a wedge for the min and max theta if (!isDefaultMinZ || !isDefaultMaxZ) { shaderBuilder.addDefine( @@ -2100,14 +1921,12 @@ function buildDrawCommands(that, context) { intersectionCount++; } } - // The intersection count is multiplied by 2 because there is an enter and exit for each intersection shaderBuilder.addDefine( "SHAPE_INTERSECTION_COUNT", intersectionCount * 2, ShaderDestination.FRAGMENT ); - const useClippingBounds = minClippingBounds.x !== defaultMinBounds.x || minClippingBounds.y !== defaultMinBounds.y || @@ -2115,7 +1934,6 @@ function buildDrawCommands(that, context) { maxClippingBounds.x !== defaultMaxBounds.x || maxClippingBounds.y !== defaultMaxBounds.y || maxClippingBounds.z !== defaultMaxBounds.z; - if (useClippingBounds) { shaderBuilder.addDefine( "CLIPPING_BOUNDS", @@ -2124,12 +1942,309 @@ function buildDrawCommands(that, context) { ); } + // Fragment shader uniforms + + shaderBuilder.addUniform( + "sampler2D", + "u_megatextureTextures[METADATA_COUNT]", + ShaderDestination.FRAGMENT + ); + + // Fragment shader structs + + // PropertyStatistics structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const propertyStatisticsStructId = `PropertyStatistics_${name}`; + const propertyStatisticsStructName = `PropertyStatistics_${name}`; + shaderBuilder.addStruct( + propertyStatisticsStructId, + propertyStatisticsStructName, + ShaderDestination.FRAGMENT + ); + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "min"); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "max"); + } + + // Statistics struct + const statisticsStructId = "Statistics"; + const statisticsStructName = "Statistics"; + const statisticsFieldName = "statistics"; + shaderBuilder.addStruct( + statisticsStructId, + statisticsStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const propertyStructName = `PropertyStatistics_${name}`; + const propertyFieldName = name; + shaderBuilder.addStructField( + statisticsStructId, + propertyStructName, + propertyFieldName + ); + } + + // Metadata struct + const metadataStructId = "Metadata"; + const metadataStructName = "Metadata"; + const metadataFieldName = "metadata"; + shaderBuilder.addStruct( + metadataStructId, + metadataStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + metadataStructId, + statisticsStructName, + statisticsFieldName + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(metadataStructId, glslType, name); + } + + // VoxelProperty structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslPartialDerivativeType(type); + const voxelPropertyStructId = `VoxelProperty_${name}`; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStruct( + voxelPropertyStructId, + voxelPropertyStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeLocal" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeWorld" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeView" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeValid" + ); + } + + // Voxel struct + const voxelStructId = "Voxel"; + const voxelStructName = "Voxel"; + const voxelFieldName = "voxel"; + shaderBuilder.addStruct( + voxelStructId, + voxelStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStructField(voxelStructId, voxelPropertyStructName, name); + } + shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvShapeSpace"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); + shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); + + // FragmentInput struct + const fragmentInputStructId = "FragmentInput"; + const fragmentInputStructName = "FragmentInput"; + shaderBuilder.addStruct( + fragmentInputStructId, + fragmentInputStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + fragmentInputStructId, + metadataStructName, + metadataFieldName + ); + shaderBuilder.addStructField( + fragmentInputStructId, + voxelStructName, + voxelFieldName + ); + + // Properties struct + const propertiesStructId = "Properties"; + const propertiesStructName = "Properties"; + const propertiesFieldName = "properties"; + shaderBuilder.addStruct( + propertiesStructId, + propertiesStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertiesStructId, glslType, name); + } + + // Fragment shader functions + + // clearProperties function + { + const functionId = "clearProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} clearProperties()`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslType = getGlslType(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = ${glslType}(0.0);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // sumProperties function + { + const functionId = "sumProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} sumProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = propertiesA.${name} + propertiesB.${name};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // mixProperties + { + const functionId = "mixProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} mixProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB, float mixFactor)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = mix(propertiesA.${name}, propertiesB.${name}, mixFactor);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // copyPropertiesToMetadata + { + const functionId = "copyPropertiesToMetadata"; + shaderBuilder.addFunction( + functionId, + `void copyPropertiesToMetadata(in ${propertiesStructName} ${propertiesFieldName}, inout ${metadataStructName} ${metadataFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${metadataFieldName}.${name} = ${propertiesFieldName}.${name};`, + ]); + } + } + + // setStatistics function + if (hasStatistics) { + const functionId = "setStatistics"; + shaderBuilder.addFunction( + functionId, + `void setStatistics(inout ${statisticsStructName} ${statisticsFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + for (let j = 0; j < componentCount; j++) { + const glslField = getGlslField(type, j); + const minimumValue = minimumValues[i][j]; + const maximumValue = maximumValues[i][j]; + shaderBuilder.addFunctionLines(functionId, [ + `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat( + minimumValue + )};`, + `${statisticsFieldName}.${name}.max${glslField} = ${getGlslNumberAsFloat( + maximumValue + )};`, + ]); + } + } + } + + // getPropertiesFrom2DMegatextureAtUv + { + const functionId = "getPropertiesFrom2DMegatextureAtUv"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} getPropertiesFrom2DMegatextureAtUv(vec2 texcoord)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `properties.${name} = texture2D(u_megatextureTextures[${i}], texcoord)${glslTextureSwizzle};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // Compile shaders const shaderBuilderPick = shaderBuilder.clone(); shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); - const shaderProgram = shaderBuilder.buildShaderProgram(context); const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context); - const renderState = RenderState.fromCache({ cull: { enabled: true, @@ -2142,6 +2257,7 @@ function buildDrawCommands(that, context) { blending: BlendingState.ALPHA_BLEND, }); + // Create the draw commands const uniformMap = that._uniformMap; const viewportQuadVertexArray = context.getViewportQuadVertexArray(); const drawCommand = new DrawCommand({ @@ -2155,6 +2271,7 @@ function buildDrawCommands(that, context) { owner: this, }); + // Create the pick draw command const drawCommandPick = DrawCommand.shallowClone( drawCommand, new DrawCommand() @@ -2176,6 +2293,8 @@ function buildDrawCommands(that, context) { that._drawCommand = drawCommand; that._drawCommandPick = drawCommandPick; + + // console.log(drawCommand.shaderProgram._fragmentShaderText); } /** @@ -2239,20 +2358,6 @@ VoxelPrimitive.prototype.destroy = function () { return destroyObject(this); }; -VoxelPrimitive.prototype.queryMetadataAtCartographic = function ( - cartographic, - metadata -) { - return this._traversal.getMetadataAtCartographic(cartographic, metadata); -}; - -VoxelPrimitive.prototype.queryMetadataAtCartesian = function ( - cartesian, - metadata -) { - return this._traversal.getMetadataAtWorldCartesian(cartesian, metadata); -}; - const corners = new Array( new Cartesian4(-1.0, -1.0, -1.0, 1.0), new Cartesian4(+1.0, -1.0, -1.0, 1.0), diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 3ff9e885c75..ee2650d6b04 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1,65 +1,149 @@ -// world space: Cartesian WGS84 -// local space: Cartesian [-0.5, 0.5] aligned with shape. -// For box, the origin is the center of the box, and the six sides sit on the planes x = -0.5, x = 0.5 etc. -// For cylinder, the origin is the center of the cylinder with the cylinder enclosed by the [-0.5, 0.5] box on xy-plane. Positive x-axis points to theta = 0. The top and bottom caps sit at planes z = -0.5, z = 0.5. Positive y points to theta = pi/2 -// For ellipsoid, the origin is the center of the ellipsoid. The maximum height of the ellipsoid touches -0.5, 0.5 in xyz directions. -// intersection space: local space times 2 to be [-1, 1]. Used for ray intersection calculation -// UV space: local space plus 0.5 to be [0, 1]. -// shape space: In the coordinate system of the shape [0, 1] -// For box, this is the same as UV space -// For cylinder, the coordinate system is (radius, theta, z). theta = 0 is aligned with x axis -// For ellipsoid, the coordinate system is (longitude, latitude, height). where 0 is the minimum value in each dimension, and 1 is the max. - - -// TODO is this necessary? Or should it go somewhere else? -precision highp int; - -// Defines that are filled in from VoxelPrimitive.js -// #define METADATA_COUNT XYZ -// #define SAMPLE_COUNT XYZ -// #define NEAREST_SAMPLING - -// Uniforms that are filled in from VoxelPrimitive.js -// uniform sampler2D u_megatextureTextures[METADATA_COUNT]; - -// Functions that are filled in from VoxelPrimitive.js -// Attributes sampleFrom2DMegatextureAtUv(vec2 uv); -// Attributes clearAttributes(); -// Attributes sumAttributes(Attributes attributesA, Attributes attributesB); -// Attributes mixAttributes(Attributes attributesA, Attributes attributesB, float mixFactor); -// void setMinMaxAttributes(inout Voxel voxel); - -#define OCTREE_MAX_LEVELS 32 +/* +Don't delete this comment! +Some shader code is dynamically generated in VoxelPrimitive.js to support custom shaders with arbitrary metadata. +Below is an example of how this code might look. Properties like "temperature" and "direction" are just examples. + +// Defines +#define PROPERTY_COUNT ### +#define SAMPLE_COUNT ### +#define SHAPE_BOX +#define SHAPE_ELLIPSOID +#define SHAPE_CYLINDER +#define SHAPE_INTERSECTION_COUNT ### +#define MEGATEXTURE_2D +#define MEGATEXTURE_3D +#define DEPTH_TEST +#define JITTER +#define NEAREST_SAMPLING +#define DESPECKLE +#define STATISTICS +#define PADDING +#define BOUNDS +#define CLIPPING_BOUNDS +#define PICKING + +// Uniforms +uniform sampler2D u_megatextureTextures[PROPERTY_COUNT]; + +// Structs +struct PropertyStatistics_temperature { + float min; + float max; +}; +struct PropertyStatistics_direction { + vec3 min; + vec3 max; +}; +struct Statistics { + PropertyStatistics_temperature temperature; + PropertyStatistics_direction direction; +}; +struct Metadata { + Statistics statistics; + float temperature; + vec3 direction; +}; +struct VoxelProperty_temperature { + vec3 partialDerivativeLocal; + vec3 partialDerivativeWorld; + vec3 partialDerivativeView; + bool partialDerivativeValid; +}; +struct VoxelProperty_direction { + mat3 partialDerivativeLocal; + mat3 partialDerivativeWorld; + mat3 partialDerivativeView; + bool partialDerivativeValid; +}; +struct Voxel { + VoxelProperty_temperature temperature; + VoxelProperty_direction direction; + vec3 positionEC; + vec3 positionUv; + vec3 positionUvShapeSpace; + vec3 positionUvLocal; + vec3 viewDirUv; + vec3 viewDirWorld; + float travelDistance; +}; +struct FragmentInput { + Metadata metadata; + Voxel voxel; +}; +struct Properties { + // This struct is similar to Metadata but is not part of the custom shader API and + // is intended to be used internally as a lightweight way to pass around properties. + float temperature; + vec3 direction; +}; +// Functions +Properties clearProperties() { + Properties properties; + properties.temperature = 0.0; + properties.direction = vec3(0.0); + return properties; +} +Properties sumProperties(Properties propertiesA, Properties propertiesB) { + Properties properties; + properties.temperature = propertiesA.temperature + propertiesB.temperature; + properties.direction = propertiesA.direction + propertiesB.direction; + return properties; +} +Properties mixProperties(Properties propertiesA, Properties propertiesB, float mixFactor) { + Properties properties; + properties.temperature = mix(propertiesA.temperature, propertiesB.temperature, mixFactor); + properties.direction = mix(propertiesA.direction, propertiesB.direction, mixFactor); + return properties; +} +void copyPropertiesToMetadata(in Properties properties, inout Metadata metadata) { + metadata.temperature = properties.temperature; + metadata.direction = properties.direction; +} +void setStatistics(inout Statistics statistics) { + // Assume the "direction" property has no min/max + statistics.temperature.min = 20.0; + statistics.temperature.max = 50.0; +} +Properties getPropertiesFrom2DMegatextureAtUv(vec2 texcoord) { + Properties properties; + properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; + properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; + return properties; +} +Properties getPropertiesFrom3DMegatextureAtUv(vec3 texcoord) { + Properties properties; + properties.temperature = texture3D(u_megatextureTextures[0], texcoord).r; + properties.direction = texture3D(u_megatextureTextures[1], texcoord).rgb; + return properties; +} +void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { + vec3 direction = fsInput.metadata.direction; + float temperature = fsInput.metadata.temperature; + float minTemperature = fsInput.metadata.statistics.temperature.min; + float maxTemperature = fsInput.metadata.statistics.temperature.max; + + material.diffuse = abs(direction); + material.alpha = (temperature - minTemperature) / (maxTemperature - minTemperature); +} +*/ + +// These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js #define OCTREE_FLAG_INTERNAL 0 #define OCTREE_FLAG_LEAF 1 #define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2 -struct OctreeNodeData { - int data; - int flag; -}; - -struct SampleData { - int megatextureIndex; - int levelsAbove; - #if (SAMPLE_COUNT > 1) - float weight; - #endif -}; +#define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops +#define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops +#define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0 -#if defined(SHAPE_ELLIPSOID) -uniform float u_ellipsoidHeightDifferenceUv; -uniform vec3 u_ellipsoidOuterRadiiLocal; // [0,1] -uniform vec3 u_ellipsoidInverseRadiiSquaredLocal; -#endif - -// 2D megatexture +#if defined(MEGATEXTURE_2D) uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions uniform vec2 u_megatextureVoxelSizeUv; uniform vec2 u_megatextureSliceSizeUv; uniform vec2 u_megatextureTileSizeUv; +#endif uniform ivec3 u_dimensions; // does not include padding #if defined(PADDING) @@ -67,13 +151,6 @@ uniform ivec3 u_paddingBefore; uniform ivec3 u_paddingAfter; #endif -uniform vec4 u_minimumValues[METADATA_COUNT]; -uniform vec4 u_maximumValues[METADATA_COUNT]; -// uniform bool u_voxelQuantization[METADATA_COUNT]; -uniform int u_channelCount[METADATA_COUNT]; - -uniform float u_stepSize; - uniform sampler2D u_octreeInternalNodeTexture; uniform vec2 u_octreeInternalNodeTexelSizeUv; uniform int u_octreeInternalNodeTilesPerRow; @@ -86,6 +163,7 @@ uniform mat4 u_transformPositionUvToView; uniform mat3 u_transformDirectionViewToLocal; uniform mat3 u_transformNormalLocalToWorld; uniform vec3 u_cameraPositionUv; +uniform float u_stepSize; #if defined(BOUNDS) uniform vec3 u_minBounds; // Bounds from the voxel primitive @@ -101,19 +179,38 @@ uniform vec3 u_minClippingBounds; uniform vec3 u_maxClippingBounds; #endif +#if defined(SHAPE_ELLIPSOID) +uniform float u_ellipsoidHeightDifferenceUv; +uniform vec3 u_ellipsoidOuterRadiiLocal; // [0,1] +uniform vec3 u_ellipsoidInverseRadiiSquaredLocal; +#endif + #if defined(PICKING) uniform vec4 u_pickColor; #endif +struct OctreeNodeData { + int data; + int flag; +}; + +struct SampleData { + int megatextureIndex; + int levelsAbove; + #if (SAMPLE_COUNT > 1) + float weight; + #endif +}; + // -------------------------------------------------------- // Misc math // -------------------------------------------------------- #if defined(JITTER) -#define HASHSCALE1 50.0 -float hash12(vec2 p) +#define HASHSCALE 50.0 +float hash(vec2 p) { - vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1); + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE); p3 += dot(p3, p3.yzx + 19.19); return fract((p3.x + p3.y) * p3.z); } @@ -146,9 +243,15 @@ int normU8x2_toInt(vec2 value) { float normU8x2_toFloat(vec2 value) { return float(normU8x2_toInt(value)) / 65535.0; } +vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) +{ + int indexX = intMod(index, dimensions.x); + int indexY = index / dimensions.x; + return vec2(indexX, indexY) * uvScale; +} // -------------------------------------------------------- -// Intersection tests, coordinate conversions, etc +// Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- struct Ray @@ -164,7 +267,7 @@ const float InfHit = czm_infinity; vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) { // TODO: completely skip shape if both of its Ts are below 0.0? - vec2 tEntryExit = vec2(NoHit, NoHit); + vec2 entryExitT = vec2(NoHit, NoHit); // Sort the intersections from min T to max T with bubble sort. // Note: If this sorting function changes, some of the intersection test may @@ -213,19 +316,19 @@ vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) // entering positive or exiting negative if (surroundCount == 1 && surroundIsPositive && enter == currShapeIsPositive) { - tEntryExit.x = t; + entryExitT.x = t; } // exiting positive or entering negative after being inside positive // TODO: Can this be simplified? if ((!enter && currShapeIsPositive && surroundCount == 0) || (enter && !currShapeIsPositive && surroundCount == 2 && surroundIsPositive)) { - tEntryExit.y = t; + entryExitT.y = t; // entry and exit have been found, so the loop can stop break; } } - return tEntryExit; + return entryExitT; } #endif @@ -701,6 +804,47 @@ float ellipseDistanceIterative (vec2 p, in vec2 ab) { } #endif +vec2 intersectShape(vec3 positionUv, vec3 directionUv) { + // Do a ray-shape intersection to find the exact starting and ending points. + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); + + #if defined(SHAPE_BOX) + vec2 entryExitT = intersectBoxShape(ray); + #elif defined(SHAPE_CYLINDER) + vec2 entryExitT = intersectCylinderShape(ray); + #elif defined(SHAPE_ELLIPSOID) + vec2 entryExitT = intersectEllipsoidShape(ray); + #endif + + if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { + // Intersection is invalid when start and end are behind the ray. + return vec2(NoHit, NoHit); + } + + // Set start to 0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + + return entryExitT; +} + +#if defined(DEPTH_TEST) +float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDirUv) { + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); + if (logDepthOrDepth != 0.0) { + // Calculate how far the ray must travel before it hits the depth buffer. + vec4 eyeCoordinateDepth = czm_windowToEyeCoordinates(fragCoord, logDepthOrDepth); + eyeCoordinateDepth /= eyeCoordinateDepth.w; + vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); + return dot(viewDirUv, depthPositionUv - viewPosUv); + } else { + // There's no depth at this position so set it to some really far value. + return czm_infinity; + } +} +#endif + #if defined(SHAPE_BOX) vec3 transformFromUvToBoxSpace(in vec3 positionUv) { return positionUv; @@ -771,7 +915,7 @@ vec3 transformFromUvToShapeSpace(in vec3 positionUv) { #if defined(BOUNDS) positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of a shape + // function would have to know if ray is intersecting the front or back of the shape // and set the shape space position to 1 (front) or 0 (back) accordingly. #endif @@ -828,43 +972,9 @@ vec3 transformFromShapeSpaceToUv(in vec3 positionUvShapeSpace) { // Megatexture // -------------------------------------------------------- -#if defined(MEGATEXTURE_IS_3D) -// TODO: 3D textures have not been implemented yet - -void sampleFrom3DMegatextureAtUv(vec3 uv, out Attributes attributes) -{ - // Looping over the sampler array was causing strange rendering artifacts even though the shader compiled fine. - // Unroling the for loop fixed the problem. - - // for (int i = 0; i < METADATA_COUNT; i++) - // { - // samples[i] = texture3D(u_megatextureTextures[i], uv); - // } - - #if (METADATA_COUNT >= 1) - samples[0] = texture3D(u_megatextureTextures[0], uv); - #endif - #if (METADATA_COUNT >= 2) - samples[1] = texture3D(u_megatextureTextures[1], uv); - #endif - #if (METADATA_COUNT >= 3) - samples[2] = texture3D(u_megatextureTextures[2], uv); - #endif - #if (METADATA_COUNT >= 4) - samples[3] = texture3D(u_megatextureTextures[3], uv); - #endif - - decodeTextureSamples(samples); -} - -// TODO: this function has not been implemented -vec3 indexToUv3D(int index, ivec3 dimensions, vec3 uvScale) -{ - return vec3(0.0); -} - -// TODO: this function has not been tested -void sampleFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex, out Attributes attributes) +// TODO: 3D megatexture has not been implemented yet +#if defined(MEGATEXTURE_3D) +Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) { // Tile location vec3 tileUvOffset = indexToUv3d(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); @@ -875,33 +985,36 @@ void sampleFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int til // Final location in the megatexture vec3 uv = tileUvOffset + voxelUvOffset; - for (int i = 0; i < METADATA_COUNT; i++) { + for (int i = 0; i < PROPERTY_COUNT; i++) { vec4 sample = texture3D(u_megatextureTextures[i], uv); samples[i] = decodeTextureSample(sample); } } - -#else // MEGATEXTURE_IS_2D +#elif defined(MEGATEXTURE_2D) /* - How 3D data is stored in a 2D megatexture + How is 3D data stored in a 2D megatexture? - 2D megatexture with a single 2x2x2 voxel tile: - The tile is split into two "slices" by Z: + In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total). + The data is sliced by Z. The data at Z = 0 is placed in texels (0,0), (0,1), (1,0), (1,1) and + the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1). + Note that there could be empty space in the megatexture because it's a power of two. 0 1 2 3 +---+---+---+---+ | | | | | 3 +---+---+---+---+ | | | | | 2 - +---+---+---+---+ + +-------+-------+ |010|110|011|111| 1 - +---+---+---+---+ + |--- ---|--- ---| |000|100|001|101| 0 - +---+---+---+---+ + +-------+-------+ - (The megatexture likes to be power of two even if it means some empty space) - - When the 3D coordinate's Z value is between two slices: + When doing linear interpolation the megatexture needs to be sampled twice: once for + the Z slice above the voxel coordinate and once for the slice below. The two slices + are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is + halfway between two Z slices so the interpolation factor is 0.5. Below is a side view + of the 3D voxel grid with voxel coordinates on the left side. 2 +---+ |001| @@ -909,16 +1022,9 @@ void sampleFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int til |000| 0 +---+ - The interpolation between the bottom and the top voxel is 0.5 - More generally, the interpolation is: fract(coord.z - 0.5) + When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice. */ - -vec2 indexToUv2D(int index, ivec2 dimensions, vec2 uvScale) { - int indexX = intMod(index, dimensions.x); - int indexY = index / dimensions.x; - return vec2(indexX, indexY) * uvScale; -} -Attributes sampleFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) +Properties getPropertiesFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) { #if defined(NEAREST_SAMPLING) // Round to the center of the nearest voxel @@ -926,35 +1032,35 @@ Attributes sampleFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, #endif // Tile location - vec2 tileUvOffset = indexToUv2D(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - // Slice locations + // Slice location float slice = voxelCoord.z - 0.5; - float sliceLerp = fract(slice); int sliceIndex = int(floor(slice)); int sliceIndex0 = intMax(sliceIndex, 0); - int sliceIndex1 = intMin(sliceIndex + 1, voxelDims.z - 1); - vec2 sliceUvOffset0 = indexToUv2D(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - vec2 sliceUvOffset1 = indexToUv2D(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); // Voxel location vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDims.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; // Final location in the megatexture vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; - vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; #if defined(NEAREST_SAMPLING) - return sampleFrom2DMegatextureAtUv(uv0); + return getPropertiesFrom2DMegatextureAtUv(uv0); #else - Attributes attributes0 = sampleFrom2DMegatextureAtUv(uv0); - Attributes attributes1 = sampleFrom2DMegatextureAtUv(uv1); - return mixAttributes(attributes0, attributes1, sliceLerp); + float sliceLerp = fract(slice); + int sliceIndex1 = intMin(sliceIndex + 1, voxelDims.z - 1); + vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; + Properties properties0 = getPropertiesFrom2DMegatextureAtUv(uv0); + Properties properties1 = getPropertiesFrom2DMegatextureAtUv(uv1); + return mixProperties(properties0, properties1, sliceLerp); #endif } #endif -Attributes sampleFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { +Properties getPropertiesFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { vec3 voxelCoord = tileUv * vec3(u_dimensions); ivec3 dimensions = u_dimensions; @@ -963,15 +1069,49 @@ Attributes sampleFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { voxelCoord += vec3(u_paddingBefore); #endif - #if defined(MEGATEXTURE_IS_3D) - return sampleFrom3DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + #if defined(MEGATEXTURE_3D) + return getPropertiesFrom3DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + #elif defined(MEGATEXTURE_2D) + return getPropertiesFrom2DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + #endif +} + +vec3 computeAncestorUv(vec3 positionUvLocal, int levelsAbove, ivec4 octreeCoords) { + if (levelsAbove > 0) { + // In some cases positionUvLocal goes outside the 0 to 1 bounds, such as when sampling neighbor voxels on the edge of a tile. + // This needs to be handled carefully, especially for mixed resolution, or else the wrong part of the tile is read. + // https://www.wolframalpha.com/input/?i=sign%28x%29+*+max%280%2C+%28abs%28x-0.5%29-0.5%29%29 + vec3 overflow = sign(positionUvLocal) * max(abs(positionUvLocal - vec3(0.5)) - vec3(0.5), vec3(0.0)); + positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0 - czm_epsilon6)); // epsilon to avoid fract(1) = 0 situation + + // Calcuate a new local uv relative to the ancestor tile. + float levelsAboveFactor = 1.0 / pow(2.0, float(levelsAbove)); + positionUvLocal = fract((vec3(octreeCoords.xyz) + positionUvLocal) * levelsAboveFactor) + overflow * levelsAboveFactor; + } else { + positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0)); + } + return positionUvLocal; +} + +// Convert an array of mixed-resolution sample datas to a final weighted properties. +Properties getPropertiesFromMegatextureAtLocalPosition(vec3 positionUvLocal, ivec4 octreeCoords, SampleData sampleDatas[SAMPLE_COUNT]) { + #if (SAMPLE_COUNT == 1) + vec3 actualUv = computeAncestorUv(positionUvLocal, sampleDatas[0].levelsAbove, octreeCoords); + return getPropertiesFromMegatextureAtTileUv(actualUv, sampleDatas[0].megatextureIndex); #else - return sampleFrom2DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + // When more than one sample is taken the accumulator needs to start at 0 + Properties properties = clearProperties(); + for (int i = 0; i < SAMPLE_COUNT; i++) { + vec3 actualUv = computeAncestorUv(positionUvLocal, sampleDatas[i].levelsAbove, octreeCoords); + Properties tempProperties = getPropertiesFromMegatextureAtTileUv(actualUvLocal, sampleDatas[i].megatextureIndex); + properties = sumProperties(properties, tempProperties) + } + return properties; #endif } // -------------------------------------------------------- -// Octree traversal +// Tree traversal // -------------------------------------------------------- void getOctreeLeafData(OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { @@ -1118,236 +1258,36 @@ void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpac } } -// Convert an array of mixed-resolution sample datas to a final weighted sample. -Attributes getSamplesAtLocalPosition(in vec3 positionUvLocal, in ivec4 octreeCoords, in SampleData sampleDatas[SAMPLE_COUNT]) { - // In some cases positionUvLocal goes outside the 0 to 1 bounds, such as when sampling neighbor voxels on the edge of a tile. - // This needs to be handled carefully, especially for mixed resolution, or else the wrong part of the tile is read. - // https://www.wolframalpha.com/input/?i=sign%28x%29+*+max%280%2C+%28abs%28x-0.5%29-0.5%29%29 - vec3 overflow = sign(positionUvLocal) * max(abs(positionUvLocal - vec3(0.5)) - vec3(0.5), vec3(0.0)); - positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0 - czm_epsilon6)); // epsilon to avoid fract(1) = 0 situation - - Attributes attributes; - - // When more than one sample is taken the accumulator needs to start at 0 - #if (SAMPLE_COUNT > 1) - attributes = clearAttributes(); - #endif - - for (int i = 0; i < SAMPLE_COUNT; i++) { - SampleData sampleData = sampleDatas[i]; - vec3 actualUvLocal = positionUvLocal; - int levelsAbove = sampleData.levelsAbove; - if (levelsAbove > 0) { - // Calcuate a new local uv relative to the ancestor tile. - float levelsAboveFactor = 1.0 / pow(2.0, float(levelsAbove)); - actualUvLocal = fract((vec3(octreeCoords.xyz) + positionUvLocal) * levelsAboveFactor) + overflow * levelsAboveFactor; - } - - Attributes tempAttributes = sampleFromMegatextureAtTileUv(actualUvLocal, sampleData.megatextureIndex); - - #if (SAMPLE_COUNT == 1) - attributes = tempAttributes; - #else - attributes = sumAttributes(attributes, tempAttributes) - #endif - } - return attributes; -} - -Attributes getSamplesAtPosition(vec3 positionUv, vec4 outOfBoundsValue) { - vec3 positionUvShapeSpace; - vec3 positionUvLocal; - float levelStepMult; - ivec4 octreeCoords; - int parentOctreeIndex; - SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctree(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); - return getSamplesAtLocalPosition(positionUvLocal, octreeCoords, sampleDatas); -} -Attributes getSamplesAtPosition(vec3 positionUv) { - return getSamplesAtPosition(positionUv, vec4(0.0)); -} - -// void getNormalAtPosition(ivec4 octreeCoords, vec3 positionUvShapeSpace, vec3 positionUvLocal, SampleData sampleDatas[SAMPLE_COUNT], out vec3 normalLocalSpace[METADATA_COUNT], out vec3 normalWorldSpace[METADATA_COUNT], out vec3 normalViewSpace[METADATA_COUNT], out bool valid[METADATA_COUNT]) { -// for (int i = 0; i < METADATA_COUNT; i++){ -// valid[i] = true; -// } - -// Attributes attributes; -// #define USE_SIMPLE_NORMALS -// #if defined(NEIGHBORS_INCLUDED_ON_TILE_EDGES) || defined(USE_SIMPLE_NORMALS) -// // There might be small seam artifacts when the edge count is 1 or less. -// float sampleL[METADATA_COUNT]; -// float sampleR[METADATA_COUNT]; -// float sampleD[METADATA_COUNT]; -// float sampleU[METADATA_COUNT]; -// float sampleB[METADATA_COUNT]; -// float sampleF[METADATA_COUNT]; -// getSamplesAtLocalPosition(positionUvLocal + vec3(-1.0, 0.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleL[i] = attributes[i].a; -// } -// getSamplesAtLocalPosition(positionUvLocal + vec3(+1.0, 0.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleR[i] = attributes[i].a; -// } -// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, -1.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleD[i] = attributes[i].a; -// } -// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, +1.0, 0.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleU[i] = attributes[i].a; -// } -// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, 0.0, -1.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleB[i] = attributes[i].a; -// } -// getSamplesAtLocalPosition(positionUvLocal + vec3(0.0, 0.0, +1.0) / vec3(u_dimensions), octreeCoords, sampleDatas, attributes); -// for(int i = 0; i < METADATA_COUNT; i++) { -// sampleF[i] = attributes[i].a; -// } -// #else -// float dimAtLevel = pow(2.0, float(octreeCoords.w)); -// vec3 voxelSizeShapeSpace = 1.0 / (dimAtLevel * vec3(u_dimensions)); - -// // There might be small seam artifacts when the edge count is 0 -// float sampleL[METADATA_COUNT]; -// float sampleR[METADATA_COUNT]; -// float sampleD[METADATA_COUNT]; -// float sampleU[METADATA_COUNT]; -// float sampleB[METADATA_COUNT]; -// float sampleF[METADATA_COUNT]; -// getSamplesAtPosition(transformFromShapeSpaceToUv(positionUvShapeSpace - vec3(voxelSizeShapeSpace.x, 0.0, 0.0), attributes)); -// for(int i; i= nonZeroMax) { colorAccum.a = colorAccumTemp.a; @@ -1429,12 +1366,13 @@ void main() } } #else - colorAccum += (1.0 - colorAccum.a) * vec4(finalSample.rgb * finalSample.a, finalSample.a); + // Pre-multiplied alpha blend + colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a); #endif // Stop traversing if the alpha has been fully saturated - if (colorAccum.a > alphaAccumMax) { - colorAccum.a = alphaAccumMax; + if (colorAccum.a > ALPHA_ACCUM_MAX) { + colorAccum.a = ALPHA_ACCUM_MAX; break; } @@ -1442,38 +1380,41 @@ void main() currT += stepT; positionUv += stepT * viewDirUv; - // Check if the ray is occluded by the depth + // Exit early if the ray is occluded by depth texture #if defined(DEPTH_TEST) if (currT >= depthT) { break; } #endif - // Check if the ray has entered empty space. If so, do another intersection test - // to see if there is more of the shape to intersect. If there isn't, the raymarch is over. + // Do another intersection test against the shape if the ray has entered empty space if (currT > endT) { - vec2 tEntryExit = intersectShape(positionUv, viewDirUv); - if (tEntryExit == vec2(NoHit, NoHit)) { + vec2 entryExitT = intersectShape(positionUv, viewDirUv); + + // Stop raymarching if it doesn't hit anything + if (entryExitT == vec2(NoHit, NoHit)) { break; - } - currT += tEntryExit.x; - endT += tEntryExit.y; - positionUv += tEntryExit.x * viewDirUv; + } + + currT += entryExitT.x; + endT += entryExitT.y; + positionUv += entryExitT.x * viewDirUv; } - // Traverse the octree from the current ray position. - // This is an optimized alternative to traverseOctree that expects the - // ray to stay in the same tile on average. Otherwise it will traverse - // upwards and back downwards. + // Traverse the tree from the current ray position. + // This is similar to traverseOctree but is optimized for the common + // case where the ray is in the same tile as the previous step. traverseOctreeFromExisting(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); + + // Adjust the step size based on the level in the tree stepT = u_stepSize * levelStepMult; } - // Convert the alpha from [0,alphaAccumMax] to [0,1] - colorAccum.a /= alphaAccumMax; + // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] + colorAccum.a /= ALPHA_ACCUM_MAX; #if defined(PICKING) - // If alpha is 0.0, there is nothing to pick + // If alpha is 0.0 there is nothing to pick if (colorAccum.a == 0.0) { discard; } From 47ca8ea7e1230d761f520657ff849d610be6f258 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 1 Apr 2022 09:25:48 -0400 Subject: [PATCH 004/679] pretty printing sample data --- .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 89 ++++++++++++++- .../Voxel/VoxelBox3DTiles/schema.json | 15 ++- .../Voxel/VoxelBox3DTiles/tileset.json | 72 ++++++++++++- .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 89 ++++++++++++++- .../Voxel/VoxelCylinder3DTiles/schema.json | 15 ++- .../Voxel/VoxelCylinder3DTiles/tileset.json | 72 ++++++++++++- .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 101 +++++++++++++++++- .../Voxel/VoxelEllipsoid3DTiles/schema.json | 15 ++- .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 66 +++++++++++- .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 89 ++++++++++++++- .../Voxel/VoxelBox3DTiles/schema.json | 15 ++- .../Voxel/VoxelBox3DTiles/tileset.json | 72 ++++++++++++- .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 89 ++++++++++++++- .../Voxel/VoxelCylinder3DTiles/schema.json | 15 ++- .../Voxel/VoxelCylinder3DTiles/tileset.json | 72 ++++++++++++- .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 101 +++++++++++++++++- .../Voxel/VoxelEllipsoid3DTiles/schema.json | 15 ++- .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 66 +++++++++++- 18 files changed, 1050 insertions(+), 18 deletions(-) diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf index 227fd904003..1cb53f70a4d 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf @@ -1 +1,88 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483648,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxel":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxel","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxel","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483648, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 39e46626920..529913b1cb2 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -1 +1,71 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "box": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf index bf65877f714..d7247ac82e1 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf @@ -1 +1,88 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483650,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483650, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 39e46626920..529913b1cb2 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -1 +1,71 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "box": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf index 90e35e2f214..5a1815f6d10 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf @@ -1 +1,100 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483649,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2],"bounds":{"min":[0.0,0.0,-1.0],"max":[1.0,1.0,0.0]}}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483649, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "bounds": { + "min": [ + 0.0, + 0.0, + -1.0 + ], + "max": [ + 1.0, + 1.0, + 0.0 + ] + } + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index f68ae62e2ab..a3e86ab1444 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -1 +1,65 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"region":[0.0,0.0,1.0,1.0,-1.0,0.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[6378137.0,0.0,0.0,0.0,0.0,6378137.0,0.0,0.0,0.0,0.0,6356752.314245179,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "region": [ + 0.0, + 0.0, + 1.0, + 1.0, + -1.0, + 0.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 6378137.0, + 0.0, + 0.0, + 0.0, + 0.0, + 6378137.0, + 0.0, + 0.0, + 0.0, + 0.0, + 6356752.314245179, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf index 227fd904003..1cb53f70a4d 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf @@ -1 +1,88 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483648,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxel":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxel","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxel","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483648, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 39e46626920..529913b1cb2 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -1 +1,71 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "box": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf index bf65877f714..d7247ac82e1 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf @@ -1 +1,88 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483650,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2]}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483650, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 39e46626920..529913b1cb2 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -1 +1,71 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"box":[0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "box": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf index 90e35e2f214..5a1815f6d10 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf @@ -1 +1,100 @@ -{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"mode":2147483649,"attributes":{"_a":0},"extensions":{"EXT_primitive_voxels":{"dimensions":[2,2,2],"bounds":{"min":[0.0,0.0,-1.0],"max":[1.0,1.0,0.0]}}}}]}],"extensionsUsed":["EXT_primitive_voxels","EXT_structural_metadata"],"extensionsRequired":["EXT_primitive_voxels","EXT_structural_metadata"],"extensions":{"EXT_structural_metadata":{"schemaUri":"../../../../schema.json","propertyAttributes":[{"class":"voxel","properties":{"a":{"attribute":"_a"}}}]}},"accessors":[{"bufferView":0,"type":"SCALAR","componentType":5126,"min":[0.0],"max":[1.0],"count":8}],"bufferViews":[{"buffer":0,"byteLength":32}],"buffers":[{"uri":"a.bin","byteLength":32}]} \ No newline at end of file +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483649, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "bounds": { + "min": [ + 0.0, + 0.0, + -1.0 + ], + "max": [ + 1.0, + 1.0, + 0.0 + ] + } + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json index 74b24b34572..d6b1e9d87f0 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json @@ -1 +1,14 @@ -{"classes":{"voxel":{"properties":{"a":{"type":"FLOAT32","required":false}}},"tile":{}}} \ No newline at end of file +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index f68ae62e2ab..a3e86ab1444 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -1 +1,65 @@ -{"asset":{"version":"1.1"},"schemaUri":"schema.json","statistics":{"classes":{"voxel":{"properties":{"a":{"min":0.0,"max":1.0}}},"tile":{"count":1}}},"geometricError":0.0,"root":{"geometricError":0.0,"refine":"REPLACE","boundingVolume":{"region":[0.0,0.0,1.0,1.0,-1.0,0.0]},"content":{"uri":"{level}/{x}/{y}/{z}/tile.gltf"},"implicitTiling":{"subdivisionScheme":"OCTREE","subtreeLevels":3,"availableLevels":1,"subtrees":{"uri":"{level}/{x}/{y}/{z}/subtree.bin"}},"transform":[6378137.0,0.0,0.0,0.0,0.0,6378137.0,0.0,0.0,0.0,0.0,6356752.314245179,0.0,0.0,0.0,0.0,1.0]}} \ No newline at end of file +{ + "asset": { + "version": "1.1" + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "properties": { + "a": { + "min": 0.0, + "max": 1.0 + } + } + }, + "tile": { + "count": 1 + } + } + }, + "geometricError": 0.0, + "root": { + "geometricError": 0.0, + "refine": "REPLACE", + "boundingVolume": { + "region": [ + 0.0, + 0.0, + 1.0, + 1.0, + -1.0, + 0.0 + ] + }, + "content": { + "uri": "{level}/{x}/{y}/{z}/tile.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 3, + "availableLevels": 1, + "subtrees": { + "uri": "{level}/{x}/{y}/{z}/subtree.bin" + } + }, + "transform": [ + 6378137.0, + 0.0, + 0.0, + 0.0, + 0.0, + 6378137.0, + 0.0, + 0.0, + 0.0, + 0.0, + 6356752.314245179, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } +} \ No newline at end of file From 68be4e6ffe15e2c908d545fbf13f485efa5874ee Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 1 Apr 2022 09:50:52 -0400 Subject: [PATCH 005/679] fixed some doc for ext_primitive_voxels --- Source/Core/PrimitiveType.js | 6 +++--- Source/Scene/ModelComponents.js | 4 ++-- Source/Scene/VoxelPrimitive.js | 4 ---- Source/Scene/VoxelShapeType.js | 6 +++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Source/Core/PrimitiveType.js b/Source/Core/PrimitiveType.js index eb86d821493..2b53747c613 100644 --- a/Source/Core/PrimitiveType.js +++ b/Source/Core/PrimitiveType.js @@ -67,7 +67,7 @@ const PrimitiveType = { TRIANGLE_FAN: WebGLConstants.TRIANGLE_FAN, /** - * Box voxel primitive from EXT_primitive_voxels. + * Box voxel primitive from EXT_primitive_voxels. * * @type {Number} * @constant @@ -75,7 +75,7 @@ const PrimitiveType = { VOXEL_BOX: 0x80000000, /** - * Ellipsoid voxel primitive from EXT_primitive_voxels. + * Ellipsoid voxel primitive from EXT_primitive_voxels. * * @type {Number} * @constant @@ -83,7 +83,7 @@ const PrimitiveType = { VOXEL_ELLIPSOID: 0x80000001, /** - * Cylinder voxel primitive from EXT_primitive_voxels. + * Cylinder voxel primitive from EXT_primitive_voxels. * * @type {Number} * @constant diff --git a/Source/Scene/ModelComponents.js b/Source/Scene/ModelComponents.js index 2ce5fb6eba7..31e955441a9 100644 --- a/Source/Scene/ModelComponents.js +++ b/Source/Scene/ModelComponents.js @@ -543,7 +543,7 @@ function MorphTarget() { } /** - * Properties from EXT_primitive_voxels + * Properties from EXT_primitive_voxels * * @alias ModelComponents.Voxel * @constructor @@ -667,7 +667,7 @@ function Primitive() { this.propertyAttributeIds = []; /** - * Properties from EXT_primitive_voxels. + * Properties from EXT_primitive_voxels. * @type {ModelComponents.Voxel} * @private */ diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 034777b6919..24b5bf805bf 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -2353,8 +2353,6 @@ VoxelPrimitive.prototype.destroy = function () { this._traversal = undefined; } - // TODO: I assume the custom shader does not have to be destroyed - return destroyObject(this); }; @@ -2607,8 +2605,6 @@ function debugDraw(that, frameState) { * @type {CustomShader} */ VoxelPrimitive.DefaultCustomShader = new CustomShader({ - // TODO what should happen when lightingModel undefined? - // lightingModel: Cesium.LightingModel.UNLIT, fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { material.diffuse = vec3(1.0); diff --git a/Source/Scene/VoxelShapeType.js b/Source/Scene/VoxelShapeType.js index 8b0c4f6a515..15742bfca39 100644 --- a/Source/Scene/VoxelShapeType.js +++ b/Source/Scene/VoxelShapeType.js @@ -5,8 +5,8 @@ import VoxelCylinderShape from "./VoxelCylinderShape.js"; import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; /** - * An enum of voxel shapes. The shape controls how the voxel grid is mapped to - * 3D space. + * An enum of voxel shapes supported by EXT_primitive_voxels. The shape controls + * how the voxel grid is mapped to 3D space. * * @enum VoxelShapeType * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. @@ -44,7 +44,7 @@ const VoxelShapeType = { /** * Converts a primitive type to a voxel shape. glTF voxel primitive types are - * defined in EXT_primitive_voxels. + * defined in EXT_primitive_voxels. * @param {PrimitiveType} primitiveType The primitive type. * @returns {VoxelShapeType} The shape type. * @private From 9e39196c54248d3b00bb5859f15fe497b685459b Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 1 Apr 2022 11:16:06 -0400 Subject: [PATCH 006/679] made shape bounds retrievable from VoxelShapeType --- Source/Scene/VoxelPrimitive.js | 33 +++++------ Source/Scene/VoxelShapeType.js | 57 +++++++++++++++---- .../Widgets/VoxelInspector/VoxelInspector.js | 28 +++++---- Specs/Scene/VoxelShapeTypeSpec.js | 50 ++++++++++++++-- 4 files changed, 117 insertions(+), 51 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 24b5bf805bf..82e1f5c6118 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1005,27 +1005,23 @@ VoxelPrimitive.prototype.update = function (frameState) { const dimensions = provider.dimensions; const shapeType = provider.shape; - const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); - const minBounds = defaultValue( - provider.minBounds, - ShapeConstructor.DefaultMinBounds - ); - const maxBounds = defaultValue( - provider.maxBounds, - ShapeConstructor.DefaultMaxBounds - ); + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); + const minBounds = defaultValue(provider.minBounds, defaultMinBounds); + const maxBounds = defaultValue(provider.maxBounds, defaultMaxBounds); const minimumValues = provider.minimumValues; const maximumValues = provider.maximumValues; + const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); this._shape = new ShapeConstructor(); this._minBounds = Cartesian3.clone(minBounds, this._minBounds); this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); this._minClippingBounds = Cartesian3.clone( - ShapeConstructor.DefaultMinBounds, + defaultMinBounds, this._minClippingBounds ); this._maxClippingBounds = Cartesian3.clone( - ShapeConstructor.DefaultMaxBounds, + defaultMaxBounds, this._maxClippingBounds ); this._paddingBefore = Cartesian3.clone( @@ -1096,9 +1092,8 @@ VoxelPrimitive.prototype.update = function (frameState) { } if (minBoundsDirty || maxBoundsDirty) { - const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); - const defaultMinBounds = ShapeConstructor.DefaultMinBounds; - const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const isDefaultBoundsMinX = minBounds.x === defaultMinBounds.x; const isDefaultBoundsMinY = minBounds.y === defaultMinBounds.y; const isDefaultBoundsMinZ = minBounds.z === defaultMinBounds.z; @@ -1435,9 +1430,8 @@ VoxelPrimitive.prototype.update = function (frameState) { const maxClipDirty = !Cartesian3.equals(maxClip, maxClipOld); const clippingBoundsDirty = minClipDirty || maxClipDirty; if (clippingBoundsDirty) { - const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); - const defaultMinBounds = ShapeConstructor.DefaultMinBounds; - const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const isDefaultClippingBoundsMinX = minClip.x === defaultMinBounds.x; const isDefaultClippingBoundsMinY = minClip.y === defaultMinBounds.y; const isDefaultClippingBoundsMinZ = minClip.z === defaultMinBounds.z; @@ -1780,9 +1774,8 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - const ShapeConstructor = VoxelShapeType.toShapeConstructor(shapeType); - const defaultMinBounds = ShapeConstructor.DefaultMinBounds; - const defaultMaxBounds = ShapeConstructor.DefaultMaxBounds; + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const isDefaultMinX = minBounds.x === defaultMinBounds.x; const isDefaultMinY = minBounds.y === defaultMinBounds.y; const isDefaultMinZ = minBounds.z === defaultMinBounds.z; diff --git a/Source/Scene/VoxelShapeType.js b/Source/Scene/VoxelShapeType.js index 15742bfca39..fa256157039 100644 --- a/Source/Scene/VoxelShapeType.js +++ b/Source/Scene/VoxelShapeType.js @@ -8,12 +8,9 @@ import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; * An enum of voxel shapes supported by EXT_primitive_voxels. The shape controls * how the voxel grid is mapped to 3D space. * + * @namespace * @enum VoxelShapeType * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * @see VoxelShape - * @see VoxelBoxShape - * @see VoxelEllipsoidShape - * @see VoxelCylinderShape */ const VoxelShapeType = { /** @@ -42,9 +39,49 @@ const VoxelShapeType = { CYLINDER: "CYLINDER", }; +/** + * Gets the minimum bounds as defined by EXT_primitive_voxels. + * @param {VoxelShapeType} shapeType The voxel shape type. + * @returns {Cartesian3} The minimum bounds. + */ +VoxelShapeType.getMinBounds = function (shapeType) { + switch (shapeType) { + case VoxelShapeType.BOX: + return VoxelBoxShape.DefaultMinBounds; + case VoxelShapeType.ELLIPSOID: + return VoxelEllipsoidShape.DefaultMinBounds; + case VoxelShapeType.CYLINDER: + return VoxelCylinderShape.DefaultMinBounds; + //>>includeStart('debug', pragmas.debug); + default: + throw new DeveloperError(`Invalid shape type ${shapeType}`); + //>>includeEnd('debug'); + } +}; + +/** + * Gets the maximum bounds as defined by EXT_primitive_voxels. + * @param {VoxelShapeType} shapeType The voxel shape type. + * @returns {Cartesian3} The maximum bounds. + */ +VoxelShapeType.getMaxBounds = function (shapeType) { + switch (shapeType) { + case VoxelShapeType.BOX: + return VoxelBoxShape.DefaultMaxBounds; + case VoxelShapeType.ELLIPSOID: + return VoxelEllipsoidShape.DefaultMaxBounds; + case VoxelShapeType.CYLINDER: + return VoxelCylinderShape.DefaultMaxBounds; + //>>includeStart('debug', pragmas.debug); + default: + throw new DeveloperError(`Invalid shape type ${shapeType}`); + //>>includeEnd('debug'); + } +}; + /** * Converts a primitive type to a voxel shape. glTF voxel primitive types are - * defined in EXT_primitive_voxels. + * defined by EXT_primitive_voxels. * @param {PrimitiveType} primitiveType The primitive type. * @returns {VoxelShapeType} The shape type. * @private @@ -53,10 +90,10 @@ VoxelShapeType.fromPrimitiveType = function (primitiveType) { switch (primitiveType) { case PrimitiveType.VOXEL_BOX: return VoxelShapeType.BOX; - case PrimitiveType.VOXEL_CYLINDER: - return VoxelShapeType.CYLINDER; case PrimitiveType.VOXEL_ELLIPSOID: return VoxelShapeType.ELLIPSOID; + case PrimitiveType.VOXEL_CYLINDER: + return VoxelShapeType.CYLINDER; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError(`Invalid primitive type ${primitiveType}`); @@ -72,14 +109,14 @@ VoxelShapeType.fromPrimitiveType = function (primitiveType) { * @returns {Function} The shape's constructor. * @private */ -VoxelShapeType.toShapeConstructor = function (shapeType) { +VoxelShapeType.getShapeConstructor = function (shapeType) { switch (shapeType) { case VoxelShapeType.BOX: return VoxelBoxShape; - case VoxelShapeType.CYLINDER: - return VoxelCylinderShape; case VoxelShapeType.ELLIPSOID: return VoxelEllipsoidShape; + case VoxelShapeType.CYLINDER: + return VoxelCylinderShape; //>>includeStart('debug', pragmas.debug); default: throw new DeveloperError(`Invalid shape type ${shapeType}`); diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index 1f360e67ef2..c1eed5c1631 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -7,9 +7,7 @@ import knockout from "../../ThirdParty/knockout.js"; import getElement from "../getElement.js"; import InspectorShared from "../InspectorShared.js"; import VoxelInspectorViewModel from "./VoxelInspectorViewModel.js"; -import VoxelBoxShape from "../../Scene/VoxelBoxShape.js"; -import VoxelCylinderShape from "../../Scene/VoxelCylinderShape.js"; -import VoxelEllipsoidShape from "../../Scene/VoxelEllipsoidShape.js"; +import VoxelShapeType from "../../Scene/VoxelShapeType.js"; /** * Inspector widget to aid in debugging voxels @@ -142,8 +140,8 @@ function VoxelInspector(container, scene) { "boundsBoxMinY", "boundsBoxMaxZ", "boundsBoxMinZ", - VoxelBoxShape.DefaultMinBounds, - VoxelBoxShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.BOX), + VoxelShapeType.getMaxBounds(VoxelShapeType.BOX), "shapeIsBox", boundsPanelContents ); @@ -161,8 +159,8 @@ function VoxelInspector(container, scene) { "boundsEllipsoidMinLatitude", "boundsEllipsoidMaxHeight", "boundsEllipsoidMinHeight", - VoxelEllipsoidShape.DefaultMinBounds, - VoxelEllipsoidShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID), + VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID), "shapeIsEllipsoid", boundsPanelContents ); @@ -180,8 +178,8 @@ function VoxelInspector(container, scene) { "boundsCylinderMinHeight", "boundsCylinderMaxAngle", "boundsCylinderMinAngle", - VoxelCylinderShape.DefaultMinBounds, - VoxelCylinderShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.CYLINDER), + VoxelShapeType.getMaxBounds(VoxelShapeType.CYLINDER), "shapeIsCylinder", boundsPanelContents ); @@ -207,8 +205,8 @@ function VoxelInspector(container, scene) { "clippingBoxMinY", "clippingBoxMaxZ", "clippingBoxMinZ", - VoxelBoxShape.DefaultMinBounds, - VoxelBoxShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.BOX), + VoxelShapeType.getMaxBounds(VoxelShapeType.BOX), "shapeIsBox", clippingPanelContents ); @@ -226,8 +224,8 @@ function VoxelInspector(container, scene) { "clippingEllipsoidMinLatitude", "clippingEllipsoidMaxHeight", "clippingEllipsoidMinHeight", - VoxelEllipsoidShape.DefaultMinBounds, - VoxelEllipsoidShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID), + VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID), "shapeIsEllipsoid", clippingPanelContents ); @@ -245,8 +243,8 @@ function VoxelInspector(container, scene) { "clippingCylinderMinHeight", "clippingCylinderMaxAngle", "clippingCylinderMinAngle", - VoxelCylinderShape.DefaultMinBounds, - VoxelCylinderShape.DefaultMaxBounds, + VoxelShapeType.getMinBounds(VoxelShapeType.CYLINDER), + VoxelShapeType.getMaxBounds(VoxelShapeType.CYLINDER), "shapeIsCylinder", clippingPanelContents ); diff --git a/Specs/Scene/VoxelShapeTypeSpec.js b/Specs/Scene/VoxelShapeTypeSpec.js index 240f2815997..242d3caabd7 100644 --- a/Specs/Scene/VoxelShapeTypeSpec.js +++ b/Specs/Scene/VoxelShapeTypeSpec.js @@ -7,6 +7,42 @@ import { } from "../../Source/Cesium.js"; describe("Scene/VoxelShapeType", function () { + it("getMinBounds works", function () { + expect(VoxelShapeType.getMinBounds(VoxelShapeType.BOX)).toEqual( + VoxelBoxShape.DefaultMinBounds + ); + expect(VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID)).toEqual( + VoxelEllipsoidShape.DefaultMinBounds + ); + expect(VoxelShapeType.getMinBounds(VoxelShapeType.CYLINDER)).toEqual( + VoxelCylinderShape.DefaultMinBounds + ); + }); + + it("getMinBounds throws for invalid type", function () { + expect(function () { + return VoxelShapeType.getMinBounds("NOT_A_SHAPE_TYPE"); + }).toThrowDeveloperError(); + }); + + it("getMaxBounds works", function () { + expect(VoxelShapeType.getMaxBounds(VoxelShapeType.BOX)).toEqual( + VoxelBoxShape.DefaultMaxBounds + ); + expect(VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID)).toEqual( + VoxelEllipsoidShape.DefaultMaxBounds + ); + expect(VoxelShapeType.getMaxBounds(VoxelShapeType.CYLINDER)).toEqual( + VoxelCylinderShape.DefaultMaxBounds + ); + }); + + it("getMaxBounds throws for invalid type", function () { + expect(function () { + return VoxelShapeType.getMaxBounds("NOT_A_SHAPE_TYPE"); + }).toThrowDeveloperError(); + }); + it("fromPrimitiveType works", function () { expect(VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_BOX)).toBe( VoxelShapeType.BOX @@ -18,26 +54,28 @@ describe("Scene/VoxelShapeType", function () { VoxelShapeType.CYLINDER ); }); + it("fromPrimitiveType throws for invalid type", function () { expect(function () { return VoxelShapeType.fromPrimitiveType("NOT_A_PRIMITIVE_TYPE"); }).toThrowDeveloperError(); }); - it("toShapeConstructor works", function () { - expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.BOX)).toBe( + it("getShapeConstructor works", function () { + expect(VoxelShapeType.getShapeConstructor(VoxelShapeType.BOX)).toBe( VoxelBoxShape ); - expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.ELLIPSOID)).toBe( + expect(VoxelShapeType.getShapeConstructor(VoxelShapeType.ELLIPSOID)).toBe( VoxelEllipsoidShape ); - expect(VoxelShapeType.toShapeConstructor(VoxelShapeType.CYLINDER)).toBe( + expect(VoxelShapeType.getShapeConstructor(VoxelShapeType.CYLINDER)).toBe( VoxelCylinderShape ); }); - it("toShapeConstructor throws for invalid type", function () { + + it("getShapeConstructor throws for invalid type", function () { expect(function () { - return VoxelShapeType.toShapeConstructor("NOT_A_SHAPE_TYPE"); + return VoxelShapeType.getShapeConstructor("NOT_A_SHAPE_TYPE"); }).toThrowDeveloperError(); }); }); From 1a90c229091d14329fe092203c425acfd303be1b Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 1 Apr 2022 16:59:05 -0400 Subject: [PATCH 007/679] documentation passthrough --- CHANGES.md | 1 + Source/Scene/Cesium3DTilesVoxelProvider.js | 80 ++- Source/Scene/GltfVoxelProvider.js | 160 +++--- Source/Scene/VoxelBoxShape.js | 174 +++---- Source/Scene/VoxelCylinderShape.js | 312 +++++++----- Source/Scene/VoxelEllipsoidShape.js | 13 +- Source/Scene/VoxelPrimitive.js | 373 ++++++++++---- Source/Scene/VoxelProvider.js | 80 ++- Source/Scene/VoxelShape.js | 47 +- Source/Scene/VoxelShapeType.js | 6 +- Source/Scene/VoxelTraversal.js | 479 +++++++++++------- Specs/Scene/Cesium3DTilesVoxelProviderSpec.js | 2 +- Specs/Scene/GltfVoxelProviderSpec.js | 2 +- 13 files changed, 1047 insertions(+), 682 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bd2e064f38e..98777b9bb17 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ### 1.93 - 2022-05-02 ##### Additions :tada: + - Added experimental voxel rendering that supports glTF with EXT_primitive_voxels extension, 3D Tiles, and procedural data. [#10253](https://github.com/CesiumGS/cesium/pull/10253). ### 1.92 - 2022-04-01 diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 7b5037b3167..4611faf0bd0 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -28,7 +28,12 @@ import VoxelShapeType from "./VoxelShapeType.js"; * @param {Object} options Object with the following properties: * @param {String|Resource|Uint8Array} options.url The URL to the tileset directory * + * @see GltfVoxelProvider * @see VoxelProvider + * @see VoxelPrimitive + * @see VoxelShapeType + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ function Cesium3DTilesVoxelProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -38,15 +43,21 @@ function Cesium3DTilesVoxelProvider(options) { /** * Gets a value indicating whether or not the provider is ready for use. + * * @type {Boolean} * @readonly */ this.ready = false; + /** + * @type {Promise.} + * @private + */ this._readyPromise = defer(); /** * Gets the promise that will be resolved when the provider is ready for use. + * * @type {Promise.} * @readonly */ @@ -54,13 +65,15 @@ function Cesium3DTilesVoxelProvider(options) { /** * An optional model matrix that is applied to all tiles - * @type {Matrix4} + * + * @type {Matrix4|undefined} * @readonly */ this.modelMatrix = undefined; /** * Gets the {@link VoxelShapeType} + * * @type {VoxelShapeType} * @readonly */ @@ -70,7 +83,8 @@ function Cesium3DTilesVoxelProvider(options) { * Gets the minimum bounds. * If undefined, the shape's default minimum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @type {Cartesian3|undefined} * @readonly */ this.minBounds = undefined; @@ -79,7 +93,8 @@ function Cesium3DTilesVoxelProvider(options) { * Gets the maximum bounds. * If undefined, the shape's default maximum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @type {Cartesian3|undefined} * @readonly */ this.maxBounds = undefined; @@ -87,6 +102,7 @@ function Cesium3DTilesVoxelProvider(options) { /** * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. * This should not be called before {@link VoxelProvider#ready} returns true. + * * @type {Cartesian3} * @readonly */ @@ -96,7 +112,8 @@ function Cesium3DTilesVoxelProvider(options) { * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * TODO: mark this optional * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Number} + * + * @type {Number|undefined} * @readonly */ this.paddingBefore = undefined; @@ -105,7 +122,8 @@ function Cesium3DTilesVoxelProvider(options) { * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * This should not be called before {@link VoxelProvider#ready} returns true. * TODO: mark this optional - * @type {Number} + * + * @type {Number|undefined} * @readonly */ this.paddingAfter = undefined; @@ -114,69 +132,89 @@ function Cesium3DTilesVoxelProvider(options) { /** * Gets stuff + * * @type {String[]} + * @readonly */ this.names = new Array(); /** * Gets stuff + * * @type {MetadataType[]} + * @readonly */ this.types = new Array(); /** * Gets stuff + * * @type {MetadataComponentType[]} + * @readonly */ this.componentTypes = new Array(); /** * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the minimum value - * @type {Number[]} + * + * @type {Number[][]|undefined} + * @readonly */ this.minimumValues = undefined; /** * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the maximum value - * @type {Number[][]} + * + * @type {Number[][]|undefined} + * @readonly */ this.maximumValues = undefined; /** * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. - * @type {Number} + * + * @type {Number|undefined} + * @readonly */ this.maximumTileCount = undefined; /** * @type {ImplicitTileset} + * @private */ this._implicitTileset = undefined; /** * @type {ImplicitSubtreeCache} + * @private */ this._subtreeCache = new ImplicitSubtreeCache(); /** * glTFs that are in the process of being loaded. + * * @type {GltfLoader[]} + * @private */ this._gltfLoaders = new Array(); /** * Subtrees that are in the process of being loaded. - * This member exists for unit test purposes only. See _doneLoading. + * This member exists for unit test purposes only. See doneLoading. + * * @type {Subtree[]} + * @private */ this._subtreeLoaders = new Array(); /** * Subtree resources that are in the process of being loaded. - * This member exists for unit test purposes only. See _doneLoading. + * This member exists for unit test purposes only. See doneLoading. + * * @type {Resource[]} + * @private */ this._subtreeResourceLoaders = new Array(); @@ -322,6 +360,7 @@ const scratchImplicitTileCoordinates = new ImplicitTileCoordinates({ /** * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * This function should not be called before {@link VoxelProvider#ready} returns true. + * * @param {Object} [options] Object with the following properties: * @param {Number} [options.tileLevel=0] The tile's level. * @param {Number} [options.tileX=0] The tile's X coordinate. @@ -329,8 +368,7 @@ const scratchImplicitTileCoordinates = new ImplicitTileCoordinates({ * @param {Number} [options.tileZ=0] The tile's Z coordinate. * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * @exception {DeveloperError} The provider must be ready. */ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -458,7 +496,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { }; /** - * Optional per-frame processing. Not all {@link VoxelProvder} need to do this. + * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. * * @param {FrameState} frameState */ @@ -472,11 +510,13 @@ Cesium3DTilesVoxelProvider.prototype.update = function (frameState) { /** * Check if anything is still being loaded. - * This is intended to be used for unit tests only. + * This is intended for unit test purposes only. + * * @returns {Boolean} + * * @private */ -Cesium3DTilesVoxelProvider.prototype._doneLoading = function () { +Cesium3DTilesVoxelProvider.prototype.doneLoading = function () { return ( this._gltfLoaders.length === 0 && this._subtreeLoaders.length === 0 && @@ -485,9 +525,13 @@ Cesium3DTilesVoxelProvider.prototype._doneLoading = function () { }; /** + * @function + * * @param {ArrayBuffer} gltfBuffer The buffer that comes when the promise from gltfResource.fetchArrayBuffer() resolves. * @param {Resource} gltfResource Resource derived from base that points to gltf. * @returns {GltfLoader} + * + * @private */ function getGltfLoader(implicitTileset, tileCoord) { const gltfRelative = implicitTileset.contentUriTemplates[0].getDerivedResource( @@ -510,7 +554,9 @@ function getGltfLoader(implicitTileset, tileCoord) { } /** + * @alias ImplicitSubtreeCacheNode * @constructor + * * @param {ImplicitSubtree} subtree * @param {Number} stamp * @@ -522,7 +568,9 @@ function ImplicitSubtreeCacheNode(subtree, stamp) { } /** + * @alias ImplicitSubtreeCache * @constructor + * * @param {Object} [options] Object with the following properties * @param {Number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. * @@ -614,8 +662,6 @@ ImplicitSubtreeCache.prototype.find = function (subtreeCoord) { * @param {ImplicitSubtreeCacheNode} a * @param {ImplicitSubtreeCacheNode} b * @returns {Number} - * - * @private */ ImplicitSubtreeCache.comparator = function (a, b) { const aCoord = a.subtree.implicitCoordinates; diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index a795aae74c4..60536d7dc03 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -21,9 +21,12 @@ import VoxelShapeType from "./VoxelShapeType.js"; * @param {Object} options Object with the following properties: * @param {String|Resource|Uint8Array|Object|GltfLoader} options.gltf A Resource/URL to a glTF/glb file, a binary glTF buffer, or a JSON object containing the glTF contents * - * @see VoxelProvider * @see Cesium3DTilesVoxelProvider + * @see VoxelProvider * @see VoxelPrimitive + * @see VoxelShapeType + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ function GltfVoxelProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -34,15 +37,21 @@ function GltfVoxelProvider(options) { /** * Gets a value indicating whether or not the provider is ready for use. + * * @type {Boolean} * @readonly */ this.ready = false; + /** + * @type {Promise.} + * @private + */ this._readyPromise = defer(); /** * Gets the promise that will be resolved when the provider is ready for use. + * * @type {Promise.} * @readonly */ @@ -50,13 +59,15 @@ function GltfVoxelProvider(options) { /** * An optional model matrix that is applied to all tiles - * @type {Matrix4} + * + * @type {Matrix4|undefined} * @readonly */ this.modelMatrix = undefined; /** * Gets the {@link VoxelShapeType} + * * @type {VoxelShapeType} * @readonly */ @@ -66,7 +77,8 @@ function GltfVoxelProvider(options) { * Gets the minimum bounds. * If undefined, the shape's default minimum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @type {Cartesian3|undefined} * @readonly */ this.minBounds = undefined; @@ -75,7 +87,8 @@ function GltfVoxelProvider(options) { * Gets the maximum bounds. * If undefined, the shape's default maximum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @type {Cartesian3|undefined} * @readonly */ this.maxBounds = undefined; @@ -83,6 +96,7 @@ function GltfVoxelProvider(options) { /** * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. * This should not be called before {@link VoxelProvider#ready} returns true. + * * @type {Cartesian3} * @readonly */ @@ -92,7 +106,8 @@ function GltfVoxelProvider(options) { * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * TODO: mark this optional * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Number} + * + * @type {Number|undefined} * @readonly */ this.paddingBefore = undefined; @@ -101,7 +116,8 @@ function GltfVoxelProvider(options) { * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * This should not be called before {@link VoxelProvider#ready} returns true. * TODO: mark this optional - * @type {Number} + * + * @type {Number|undefined} * @readonly */ this.paddingAfter = undefined; @@ -110,49 +126,70 @@ function GltfVoxelProvider(options) { /** * Gets stuff + * * @type {String[]} + * @readonly */ this.names = new Array(); /** * Gets stuff + * * @type {MetadataType[]} + * @readonly */ this.types = new Array(); /** * Gets stuff + * * @type {MetadataComponentType[]} + * @readonly */ this.componentTypes = new Array(); /** * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the minimum value - * @type {Number[]} + * + * @type {Number[][]|undefined} + * @readonly */ this.minimumValues = undefined; /** * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the maximum value - * @type {Number[][]} + * + * @type {Number[][]|undefined} + * @readonly */ this.maximumValues = undefined; /** * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. - * @type {Number} + * + * @type {Number|undefined} + * @readonly */ - this.maximumTileCount = undefined; + this.maximumTileCount = 1; /** * A {@link GltfLoader} that is processed each frame until ready. + * * @type {GltfLoader} * @private */ this._loader = undefined; + /** + * The voxel data. + * + * @type {Array[]} + * @private + */ + this._data = undefined; + const gltf = options.gltf; let promise; if (defined(gltf.components) && defined(gltf.components.asset)) { @@ -207,114 +244,30 @@ function GltfVoxelProvider(options) { that.ready = true; that._readyPromise = Promise.resolve(that); - /** - * An optional model matrix that is applied to all tiles - * @type {Matrix4} - * @readonly - */ that.modelMatrix = modelMatrix; - - /** - * Gets the {@link VoxelShapeType} - * @type {VoxelShapeType} - * @readonly - */ that.shape = shape; - - /** - * Gets the minimum bounds. - * This should not be called before {@link GltfVoxelProvider#ready} returns true. - * @type {Cartesian3} - * @readonly - */ that.minBounds = defined(voxel.minBounds) ? Cartesian3.clone(voxel.minBounds, new Cartesian3()) : undefined; - - /** - * Gets the maximum bounds. - * This should not be called before {@link GltfVoxelProvider#ready} returns true. - * @type {Cartesian3} - * @readonly - */ that.maxBounds = defined(voxel.maxBounds) ? Cartesian3.clone(voxel.maxBounds, new Cartesian3()) : undefined; - - /** - * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. - * This should not be called before {@link GltfVoxelProvider#ready} returns true. - * @type {Cartesian3} - * @readonly - */ that.dimensions = Cartesian3.clone(voxel.dimensions, new Cartesian3()); - - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * TODO: mark this optional - * This should not be called before {@link GltfVoxelProvider#ready} returns true. - * @type {Number} - * @readonly - */ that.paddingBefore = defined(voxel.paddingBefore) ? Cartesian3.clone(voxel.paddingBefore, new Cartesian3()) : undefined; - - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * This should not be called before {@link GltfVoxelProvider#ready} returns true. - * TODO: mark this optional - * @type {Number} - * @readonly - */ that.paddingAfter = defined(voxel.paddingAfter) ? Cartesian3.clone(voxel.paddingAfter, new Cartesian3()) : undefined; // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use - /** - * Gets stuff - * @type {String[]} - */ that.names = names; - - /** - * Gets stuff - * @type {MetadataType[]} - */ that.types = types; - - /** - * Gets stuff - * @type {MetadataComponentType[]} - */ that.componentTypes = componentTypes; - - /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array - * Gets the minimum value - * @type {Number[]} - */ that.minimumValues = minimumValues; - - /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array - * Gets the maximum value - * @type {Number[][]} - */ that.maximumValues = maximumValues; - /** - * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. - * @type {Number} - */ - that.maximumTileCount = 1; - - /** - * @private - * @type {Float32Array|Uint16Array|Uint8Array} - */ that._data = new Array(attributesLength); for (let i = 0; i < attributesLength; i++) { const attribute = attributes[i]; @@ -332,7 +285,8 @@ function GltfVoxelProvider(options) { ); } - // Now that the data is loaded there's no need to keep around the loader. + // Now that the data is loaded the loader can be unloaded. + that._loader.unload(); that._loader = undefined; }) .catch(function (error) { @@ -343,11 +297,8 @@ function GltfVoxelProvider(options) { /** * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. * If the provider doesn't need this functionality it should leave this function undefined. - * @function - * @param {FrameState} frameState * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * @param {FrameState} frameState */ GltfVoxelProvider.prototype.update = function (frameState) { const loader = this._loader; @@ -360,15 +311,16 @@ GltfVoxelProvider.prototype.update = function (frameState) { * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * Note that there is only one "tile" for a glTF so the only valid input is the "root" tile coordinates. * This function should not be called before {@link GltfVoxelProvider#ready} returns true. - * @function * * @param {Object} [options] Object with the following properties: * @param {Number} [options.tileLevel=0] The tile's level. * @param {Number} [options.tileX=0] The tile's X coordinate. * @param {Number} [options.tileY=0] The tile's Y coordinate. * @param {Number} [options.tileZ=0] The tile's Z coordinate. - * * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. + * + * @exception {DeveloperError} The provider must be ready. + * @exception {DeveloperError} Only level 0 can be requested. */ GltfVoxelProvider.prototype.requestData = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -394,11 +346,13 @@ GltfVoxelProvider.prototype.requestData = function (options) { /** * Check if the data is still being loaded. * This is intended to be used for unit tests only. + * * @returns {Boolean} + * * @private */ -GltfVoxelProvider.prototype._doneLoading = function () { - return !defined(this._loader); +GltfVoxelProvider.prototype.doneLoading = function () { + return defined(this._data); }; export default GltfVoxelProvider; diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index a66e5cf3073..0f7cbec3b08 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -12,19 +12,19 @@ import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; * @alias VoxelBoxShape * @constructor * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * * @see VoxelShape * @see VoxelEllipsoidShape * @see VoxelCylinderShape * @see VoxelShapeType + * + * @private */ function VoxelBoxShape() { /** * An oriented bounding box containing the bounded shape. * The update function must be called before accessing this value. * @type {OrientedBoundingBox} + * @readonly */ this.orientedBoundingBox = new OrientedBoundingBox(); @@ -32,6 +32,7 @@ function VoxelBoxShape() { * A bounding sphere containing the bounded shape. * The update function must be called before accessing this value. * @type {BoundingSphere} + * @readonly */ this.boundingSphere = new BoundingSphere(); @@ -39,6 +40,7 @@ function VoxelBoxShape() { * A transformation matrix containing the bounded shape. * The update function must be called before accessing this value. * @type {Matrix4} + * @readonly */ this.boundTransform = new Matrix4(); @@ -46,6 +48,7 @@ function VoxelBoxShape() { * A transformation matrix containing the shape, ignoring the bounds. * The update function must be called before accessing this value. * @type {Matrix4} + * @readonly */ this.shapeTransform = new Matrix4(); @@ -53,13 +56,23 @@ function VoxelBoxShape() { * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. * The update function must be called before accessing this value. * @type {Boolean} + * @readonly */ this.isVisible = false; + /** + * @type {Cartesian3} + * @private + */ this._minBounds = Cartesian3.clone( VoxelBoxShape.DefaultMinBounds, new Cartesian3() ); + + /** + * @type {Cartesian3} + * @private + */ this._maxBounds = Cartesian3.clone( VoxelBoxShape.DefaultMaxBounds, new Cartesian3() @@ -70,73 +83,12 @@ const scratchTranslation = new Cartesian3(); const scratchScale = new Cartesian3(); const scratchRotation = new Matrix3(); -/** - * @param {Cartesian3} minimumX - * @param {Cartesian3} maximumX - * @param {Cartesian3} minimumY - * @param {Cartesian3} maximumY - * @param {Cartesian3} minimumZ - * @param {Cartesian3} maximumZ - * @param {Matrix4} matrix - * @param {OrientedBoundingBox} result - * @returns {OrientedBoundingBox} - */ -function getBoxChunkObb( - minimumX, - maximumX, - minimumY, - maximumY, - minimumZ, - maximumZ, - matrix, - result -) { - const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; - const defaultMaxBounds = VoxelBoxShape.DefaultMaxBounds; - - const isDefaultBounds = - minimumX === defaultMinBounds.x && - minimumY === defaultMinBounds.y && - minimumZ === defaultMinBounds.z && - maximumX === defaultMaxBounds.x && - maximumY === defaultMaxBounds.y && - maximumZ === defaultMaxBounds.z; - - if (isDefaultBounds) { - result.center = Matrix4.getTranslation(matrix, result.center); - result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); - } else { - let scale = Matrix4.getScale(matrix, scratchScale); - const translation = Matrix4.getTranslation(matrix, scratchTranslation); - result.center = Cartesian3.fromElements( - translation.x + scale.x * 0.5 * (minimumX + maximumX), - translation.y + scale.y * 0.5 * (maximumY + minimumY), - translation.z + scale.z * 0.5 * (maximumZ + minimumZ), - result.center - ); - - scale = Cartesian3.fromElements( - scale.x * 0.5 * (maximumX - minimumX), - scale.y * 0.5 * (maximumY - minimumY), - scale.z * 0.5 * (maximumZ - minimumZ), - scratchScale - ); - const rotation = Matrix4.getRotation(matrix, scratchRotation); - result.halfAxes = Matrix3.setScale(rotation, scale, result.halfAxes); - } - - return result; -} - /** * Update the shape's state. - * @function + * * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { //>>includeStart('debug', pragmas.debug); @@ -205,16 +157,13 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { /** * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. - * @function + * * @param {Number} tileLevel The tile's level. * @param {Number} tileX The tile's x coordinate. * @param {Number} tileY The tile's y coordinate. * @param {Number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile * @returns {OrientedBoundingBox} The oriented bounding box. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( tileLevel, @@ -283,12 +232,9 @@ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( /** * Computes an approximate step size for raymarching the root tile of a voxel grid. * The update function must be called before calling this function. - * @function + * * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. * @returns {Number} The step size. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelBoxShape.prototype.computeApproximateStepSize = function (dimensions) { //>>includeStart('debug', pragmas.debug); @@ -300,26 +246,84 @@ VoxelBoxShape.prototype.computeApproximateStepSize = function (dimensions) { /** * Defines the minimum bounds of the shape. Corresponds to minimum X, Y, Z. - * @type {Cartesian3} * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * @type {Cartesian3} + * @constant + * @readonly */ -VoxelBoxShape.DefaultMinBounds = Cartesian3.negate( - Cartesian3.ONE, - new Cartesian3() -); +VoxelBoxShape.DefaultMinBounds = new Cartesian3(-1.0, -1.0, -1.0); /** * Defines the maximum bounds of the shape. Corresponds to maximum X, Y, Z. + * * @type {Cartesian3} + * @constant + * @readonly + */ +VoxelBoxShape.DefaultMaxBounds = new Cartesian3(+1.0, +1.0, +1.0); + +/** + * Computes an {@link OrientedBoundingBox} for a subregion of the shape. + * + * @function + * + * @param {Cartesian3} minimumX The minimumX. + * @param {Cartesian3} maximumX The maximumX. + * @param {Cartesian3} minimumY The minimumY. + * @param {Cartesian3} maximumY The maximumY. + * @param {Cartesian3} minimumZ The minimumZ. + * @param {Cartesian3} maximumZ The maximumZ. + * @param {Matrix4} matrix The matrix to transform the points. + * @param {OrientedBoundingBox} result The object onto which to store the result. + * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. * * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ -VoxelBoxShape.DefaultMaxBounds = Cartesian3.clone( - Cartesian3.ONE, - new Cartesian3() -); +function getBoxChunkObb( + minimumX, + maximumX, + minimumY, + maximumY, + minimumZ, + maximumZ, + matrix, + result +) { + const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; + const defaultMaxBounds = VoxelBoxShape.DefaultMaxBounds; + + const isDefaultBounds = + minimumX === defaultMinBounds.x && + minimumY === defaultMinBounds.y && + minimumZ === defaultMinBounds.z && + maximumX === defaultMaxBounds.x && + maximumY === defaultMaxBounds.y && + maximumZ === defaultMaxBounds.z; + + if (isDefaultBounds) { + result.center = Matrix4.getTranslation(matrix, result.center); + result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); + } else { + let scale = Matrix4.getScale(matrix, scratchScale); + const translation = Matrix4.getTranslation(matrix, scratchTranslation); + result.center = Cartesian3.fromElements( + translation.x + scale.x * 0.5 * (minimumX + maximumX), + translation.y + scale.y * 0.5 * (maximumY + minimumY), + translation.z + scale.z * 0.5 * (maximumZ + minimumZ), + result.center + ); + + scale = Cartesian3.fromElements( + scale.x * 0.5 * (maximumX - minimumX), + scale.y * 0.5 * (maximumY - minimumY), + scale.z * 0.5 * (maximumZ - minimumZ), + scratchScale + ); + const rotation = Matrix4.getRotation(matrix, scratchRotation); + result.halfAxes = Matrix3.setScale(rotation, scale, result.halfAxes); + } + + return result; +} export default VoxelBoxShape; diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index e379a8b0b11..bf9f0a748ce 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -12,19 +12,19 @@ import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; * @alias VoxelCylinderShape * @constructor * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * * @see VoxelShape - * @see VoxelCylinderShape + * @see VoxelBoxShape * @see VoxelEllipsoidShape * @see VoxelShapeType + * + * @private */ function VoxelCylinderShape() { /** * An oriented bounding box containing the bounded shape. * The update function must be called before accessing this value. * @type {OrientedBoundingBox} + * @readonly */ this.orientedBoundingBox = new OrientedBoundingBox(); @@ -32,6 +32,7 @@ function VoxelCylinderShape() { * A bounding sphere containing the bounded shape. * The update function must be called before accessing this value. * @type {BoundingSphere} + * @readonly */ this.boundingSphere = new BoundingSphere(); @@ -39,6 +40,7 @@ function VoxelCylinderShape() { * A transformation matrix containing the bounded shape. * The update function must be called before accessing this value. * @type {Matrix4} + * @readonly */ this.boundTransform = new Matrix4(); @@ -46,6 +48,7 @@ function VoxelCylinderShape() { * A transformation matrix containing the shape, ignoring the bounds. * The update function must be called before accessing this value. * @type {Matrix4} + * @readonly */ this.shapeTransform = new Matrix4(); @@ -53,14 +56,44 @@ function VoxelCylinderShape() { * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. * The update function must be called before accessing this value. * @type {Boolean} + * @readonly */ this.isVisible = false; + /** + * @type {Number} + * @private + */ this._minimumRadius = VoxelCylinderShape.DefaultMinBounds.x; + + /** + * @type {Number} + * @private + */ this._maximumRadius = VoxelCylinderShape.DefaultMaxBounds.x; + + /** + * @type {Number} + * @private + */ this._minimumHeight = VoxelCylinderShape.DefaultMinBounds.y; + + /** + * @type {Number} + * @private + */ this._maximumHeight = VoxelCylinderShape.DefaultMaxBounds.y; + + /** + * @type {Number} + * @private + */ this._minimumAngle = VoxelCylinderShape.DefaultMinBounds.z; + + /** + * @type {Number} + * @private + */ this._maximumAngle = VoxelCylinderShape.DefaultMaxBounds.z; } @@ -167,136 +200,14 @@ const scratchPositions = [ ), ]; -/** - * @function - * @param {Number} radiusStart - * @param {Number} radiusEnd - * @param {Number} heightStart - * @param {Number} heightEnd - * @param {Number} angleStart - * @param {Number} angleEnd - * @param {Matrix4} matrix - * @param {OrientedBoundingBox} result - * @returns {OrientedBoundingBox} - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - */ -function getCylinderChunkObb( - radiusStart, - radiusEnd, - heightStart, - heightEnd, - angleStart, - angleEnd, - matrix, - result -) { - const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; - const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; - const defaultMinRadius = defaultMinBounds.x; // 0 - const defaultMaxRadius = defaultMaxBounds.x; // 1 - const defaultMinHeight = defaultMinBounds.y; // -1 - const defaultMaxHeight = defaultMaxBounds.y; // +1 - const defaultMinAngle = defaultMinBounds.z; // -pi/2 - const defaultMaxAngle = defaultMaxBounds.z; // +pi/2 - - // Return early if using the default bounds - if ( - radiusStart === defaultMinRadius && - radiusEnd === defaultMaxRadius && - heightStart === defaultMinHeight && - heightEnd === defaultMaxHeight && - angleStart === defaultMinAngle && - angleEnd === defaultMaxAngle - ) { - result.center = Matrix4.getTranslation(matrix, result.center); - result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); - return result; - } - - let testAngleCount = 0; - const testAngles = scratchTestAngles; - const halfPi = CesiumMath.PI_OVER_TWO; - - testAngles[testAngleCount++] = angleStart; - testAngles[testAngleCount++] = angleEnd; - - if (angleStart > angleEnd) { - if (angleStart > 0.0 && angleEnd > 0.0) { - testAngles[testAngleCount++] = 0.0; - } - if (angleStart > +halfPi && angleEnd > +halfPi) { - testAngles[testAngleCount++] = +halfPi; - } - if (angleStart > -halfPi && angleEnd > -halfPi) { - testAngles[testAngleCount++] = -halfPi; - } - // It will always cross the 180th meridian - testAngles[testAngleCount++] = CesiumMath.PI; - } else { - if (angleStart < 0.0 && angleEnd > 0.0) { - testAngles[testAngleCount++] = 0.0; - } - if (angleStart < +halfPi && angleEnd > +halfPi) { - testAngles[testAngleCount++] = +halfPi; - } - if (angleStart < -halfPi && angleEnd > -halfPi) { - testAngles[testAngleCount++] = -halfPi; - } - } - - const positions = scratchPositions[testAngleCount]; - - for (let i = 0; i < testAngleCount; i++) { - const angle = testAngles[i]; - const cosAngle = Math.cos(angle); - const sinAngle = Math.sin(angle); - - positions[i * 4 + 0] = Cartesian3.fromElements( - cosAngle * radiusStart, - sinAngle * radiusStart, - heightStart, - positions[i * 4 + 0] - ); - positions[i * 4 + 1] = Cartesian3.fromElements( - cosAngle * radiusEnd, - sinAngle * radiusEnd, - heightStart, - positions[i * 4 + 1] - ); - positions[i * 4 + 2] = Cartesian3.fromElements( - cosAngle * radiusStart, - sinAngle * radiusStart, - heightEnd, - positions[i * 4 + 2] - ); - positions[i * 4 + 3] = Cartesian3.fromElements( - cosAngle * radiusEnd, - sinAngle * radiusEnd, - heightEnd, - positions[i * 4 + 3] - ); - } - - for (let i = 0; i < testAngleCount * 4; i++) { - positions[i] = Matrix4.multiplyByPoint(matrix, positions[i], positions[i]); - } - - return OrientedBoundingBox.fromPoints(positions, result); -} - const scratchScale = new Cartesian3(); /** * Update the shape's state. - * @function + * * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelCylinderShape.prototype.update = function ( modelMatrix, @@ -384,16 +295,13 @@ VoxelCylinderShape.prototype.update = function ( /** * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. - * @function + * * @param {Number} tileLevel The tile's level. * @param {Number} tileX The tile's x coordinate. * @param {Number} tileY The tile's y coordinate. * @param {Number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile * @returns {OrientedBoundingBox} The oriented bounding box. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelCylinderShape.prototype.computeOrientedBoundingBoxForTile = function ( tileLevel, @@ -468,6 +376,13 @@ const scratchVoxelScale = new Cartesian3(); const scratchRootScale = new Cartesian3(); const scratchScaleRatio = new Cartesian3(); +/** + * Computes an approximate step size for raymarching the root tile of a voxel grid. + * The update function must be called before calling this function. + * + * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. + * @returns {Number} The step size. + */ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( voxelDimensions ) { @@ -515,15 +430,146 @@ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( }; /** - * @private + * Defines the minimum bounds of the shape. Corresponds to minimum radius, height, angle. + * * @type {Cartesian3} + * @constant + * @readonly + * + * @private */ VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); /** - * @private + * Defines the maximum bounds of the shape. Corresponds to maximum radius, height, angle. + * * @type {Cartesian3} + * @constant + * @readonly + * + * @private */ VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); +/** + * Computes an {@link OrientedBoundingBox} for a subregion of the shape. + * + * @function + * + * @param {Number} radiusStart The radiusStart. + * @param {Number} radiusEnd The radiusEnd. + * @param {Number} heightStart The heightStart. + * @param {Number} heightEnd The heightEnd. + * @param {Number} angleStart The angleStart. + * @param {Number} angleEnd The angleEnd. + * @param {Matrix4} matrix The matrix to transform the points. + * @param {OrientedBoundingBox} result The object onto which to store the result. + * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. + * + * @private + */ +function getCylinderChunkObb( + radiusStart, + radiusEnd, + heightStart, + heightEnd, + angleStart, + angleEnd, + matrix, + result +) { + const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; + const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; + const defaultMinRadius = defaultMinBounds.x; // 0 + const defaultMaxRadius = defaultMaxBounds.x; // 1 + const defaultMinHeight = defaultMinBounds.y; // -1 + const defaultMaxHeight = defaultMaxBounds.y; // +1 + const defaultMinAngle = defaultMinBounds.z; // -pi/2 + const defaultMaxAngle = defaultMaxBounds.z; // +pi/2 + + // Return early if using the default bounds + if ( + radiusStart === defaultMinRadius && + radiusEnd === defaultMaxRadius && + heightStart === defaultMinHeight && + heightEnd === defaultMaxHeight && + angleStart === defaultMinAngle && + angleEnd === defaultMaxAngle + ) { + result.center = Matrix4.getTranslation(matrix, result.center); + result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); + return result; + } + + let testAngleCount = 0; + const testAngles = scratchTestAngles; + const halfPi = CesiumMath.PI_OVER_TWO; + + testAngles[testAngleCount++] = angleStart; + testAngles[testAngleCount++] = angleEnd; + + if (angleStart > angleEnd) { + if (angleStart > 0.0 && angleEnd > 0.0) { + testAngles[testAngleCount++] = 0.0; + } + if (angleStart > +halfPi && angleEnd > +halfPi) { + testAngles[testAngleCount++] = +halfPi; + } + if (angleStart > -halfPi && angleEnd > -halfPi) { + testAngles[testAngleCount++] = -halfPi; + } + // It will always cross the 180th meridian + testAngles[testAngleCount++] = CesiumMath.PI; + } else { + if (angleStart < 0.0 && angleEnd > 0.0) { + testAngles[testAngleCount++] = 0.0; + } + if (angleStart < +halfPi && angleEnd > +halfPi) { + testAngles[testAngleCount++] = +halfPi; + } + if (angleStart < -halfPi && angleEnd > -halfPi) { + testAngles[testAngleCount++] = -halfPi; + } + } + + const positions = scratchPositions[testAngleCount]; + + for (let i = 0; i < testAngleCount; i++) { + const angle = testAngles[i]; + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + + positions[i * 4 + 0] = Cartesian3.fromElements( + cosAngle * radiusStart, + sinAngle * radiusStart, + heightStart, + positions[i * 4 + 0] + ); + positions[i * 4 + 1] = Cartesian3.fromElements( + cosAngle * radiusEnd, + sinAngle * radiusEnd, + heightStart, + positions[i * 4 + 1] + ); + positions[i * 4 + 2] = Cartesian3.fromElements( + cosAngle * radiusStart, + sinAngle * radiusStart, + heightEnd, + positions[i * 4 + 2] + ); + positions[i * 4 + 3] = Cartesian3.fromElements( + cosAngle * radiusEnd, + sinAngle * radiusEnd, + heightEnd, + positions[i * 4 + 3] + ); + } + + for (let i = 0; i < testAngleCount * 4; i++) { + positions[i] = Matrix4.multiplyByPoint(matrix, positions[i], positions[i]); + } + + return OrientedBoundingBox.fromPoints(positions, result); +} + export default VoxelCylinderShape; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index d6aeb46fda0..ec374131da2 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -19,17 +19,12 @@ import VoxelShapeType from "./VoxelShapeType.js"; * @alias VoxelEllipsoidShape * @constructor * - * @param {Object} [options] - * @param {Ellipsoid} [options.ellipsoid] - * @param {Rectangle} [options.rectangle] - * @param {Number} [options.minimumHeight] - * @param {Number} [options.maximumHeight] - * @param {Cartesian3} [options.translation] - * @param {Cartesian3} [options.scale] - * @param {Matrix3} [options.rotation] - * * @see VoxelShape + * @see VoxelBoxShape + * @see VoxelCylinderShape * @see VoxelShapeType + * + * @private */ function VoxelEllipsoidShape(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 82e1f5c6118..17af662bfb9 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -54,12 +54,12 @@ import MetadataType from "./MetadataType.js"; * @param {CustomShader} [options.customShader] The custom shader used to style the primitive. * @param {Clock} [options.clock] The clock used to control time dynamic behavior. * - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * * @see VoxelProvider * @see Cesium3DTilesVoxelProvider * @see GltfVoxelProvider * @see VoxelShapeType + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ function VoxelPrimitive(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -86,14 +86,9 @@ function VoxelPrimitive(options) { */ this._provider = options.provider; - // If the provider fails to initialize the primitive will fail too. - const that = this; - this._provider.readyPromise.catch(function (error) { - that._readyPromise.reject(`provider failed with error:\n${error}`); - }); - /** * This member is not created until the provider and shape are ready. + * * @type {VoxelTraversal} * @private */ @@ -101,6 +96,7 @@ function VoxelPrimitive(options) { /** * This member is not created until the provider is ready. + * * @type {VoxelShape} * @private */ @@ -108,6 +104,7 @@ function VoxelPrimitive(options) { /** * This member is not created until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -115,6 +112,7 @@ function VoxelPrimitive(options) { /** * This member is not created until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -122,6 +120,7 @@ function VoxelPrimitive(options) { /** * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -130,6 +129,7 @@ function VoxelPrimitive(options) { /** * Used to detect if the shape is dirty. * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -137,6 +137,7 @@ function VoxelPrimitive(options) { /** * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -145,6 +146,7 @@ function VoxelPrimitive(options) { /** * Used to detect if the shape is dirty. * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -152,6 +154,7 @@ function VoxelPrimitive(options) { /** * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -160,6 +163,7 @@ function VoxelPrimitive(options) { /** * Used to detect if the clipping is dirty. * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -167,6 +171,7 @@ function VoxelPrimitive(options) { /** * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ @@ -175,13 +180,15 @@ function VoxelPrimitive(options) { /** * Used to detect if the clipping is dirty. * This member is not known until the provider is ready. + * * @type {Cartesian3} * @private */ this._maxClippingBoundsOld = new Cartesian3(); /** - * The primitive's model matrix + * The primitive's model matrix. + * * @type {Matrix4} * @private */ @@ -193,6 +200,7 @@ function VoxelPrimitive(options) { /** * The primitive's model matrix multiplied by the provider's model matrix. * This member is not known until the provider is ready. + * * @type {Matrix4} * @private */ @@ -201,6 +209,7 @@ function VoxelPrimitive(options) { /** * Used to detect if the shape is dirty. * This member is not known until the provider is ready. + * * @type {Matrix4} * @private */ @@ -246,20 +255,20 @@ function VoxelPrimitive(options) { this._pickId = undefined; // /** - // * @private // * @type {TimeIntervalCollection} + // * @private // */ // this._timeIntervalCollection = undefined; // /** - // * @private // * @type {Clock} + // * @private // */ // this._clock = options.clock; // /** - // * @private // * @type {Number} + // * @private // */ // this._keyframeCount = 1; @@ -267,45 +276,107 @@ function VoxelPrimitive(options) { /** * @type {Matrix4} + * @private */ this._transformPositionWorldToUv = new Matrix4(); /** * @type {Matrix4} + * @private */ this._transformPositionUvToWorld = new Matrix4(); /** * @type {Matrix3} + * @private */ this._transformDirectionWorldToLocal = new Matrix3(); /** * @type {Matrix3} + * @private */ this._transformNormalLocalToWorld = new Matrix3(); /** * @type {Number} + * @private */ this._stepSizeUv = 1.0; // Rendering + /** + * @type {Boolean} + * @private + */ this._jitter = true; + + /** + * @type {Boolean} + * @private + */ this._nearestSampling = false; + + /** + * @type {Number} + * @private + */ this._stepSizeMultiplier = 1.0; + + /** + * @type {Boolean} + * @private + */ this._despeckle = false; + + /** + * @type {Boolean} + * @private + */ this._depthTest = true; + + /** + * @type {Boolean} + * @private + */ this._useLogDepth = undefined; + + /** + * @type {Number} + * @private + */ this._screenSpaceError = 4.0; // in pixels // Debug / statistics + /** + * @type {PolylineCollection} + * @private + */ this._debugPolylines = new PolylineCollection(); + + /** + * @type {Boolean} + * @private + */ this._debugDraw = false; + + /** + * @type {Boolean} + * @private + */ this._disableRender = false; + + /** + * @type {Boolean} + * @private + */ this._disableUpdate = false; // Uniforms + /** + * @type {Object.} + * @private + */ this._uniformMapValues = { /** * @ignore @@ -359,8 +430,8 @@ function VoxelPrimitive(options) { // Automatically generate uniform map from the uniform values /** - * @private * @type {Object.} + * @private */ this._uniformMap = {}; const uniformMapValues = this._uniformMapValues; @@ -374,11 +445,19 @@ function VoxelPrimitive(options) { this._uniformMap[`u_${key}`] = getUniformFunction(key); } } + + // If the provider fails to initialize the primitive will fail too. + const provider = this._provider; + const primitive = this; + provider.readyPromise.catch(function (error) { + primitive._readyPromise.reject(`provider failed with error:\n${error}`); + }); } Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets a value indicating whether or not the primitive is ready for use. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} * @readonly @@ -391,6 +470,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the promise that will be resolved when the primitive is ready for use. + * * @memberof VoxelPrimitive.prototype * @type {Promise.} * @readonly @@ -403,6 +483,8 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the {@link VoxelProvider} associated with this primitive. + * + * @memberof VoxelPrimitive.prototype * @type {VoxelProvider} * @readonly */ @@ -414,10 +496,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the bounding sphere. + * * @memberof VoxelPrimitive.prototype * @type {BoundingSphere} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ boundingSphere: { get: function () { @@ -435,10 +519,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the oriented bounding box. + * * @memberof VoxelPrimitive.prototype * @type {OrientedBoundingBox} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ orientedBoundingBox: { get: function () { @@ -455,6 +541,8 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** + * Gets the model matrix. + * * @memberof VoxelPrimitive.prototype * @type {Matrix4} * @readonly @@ -473,10 +561,13 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** + * Gets the compound model matrix + * * @memberof VoxelPrimitive.prototype * @type {Matrix4} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ compoundModelMatrix: { get: function () { @@ -494,10 +585,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the shape type. + * * @memberof VoxelPrimitive.prototype * @type {VoxelShapeType} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ shape: { get: function () { @@ -514,10 +607,13 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** + * Gets the voxel dimensions. + * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ dimensions: { get: function () { @@ -535,10 +631,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the minimum value per channel of the voxel data. + * * @memberof VoxelPrimitive.prototype * @type {Number[]} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ minimumValues: { get: function () { @@ -556,10 +654,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets the maximum value per channel of the voxel data. + * * @memberof VoxelPrimitive.prototype * @type {Number[]} - * @throws {DeveloperError} If the primitive is not ready. * @readonly + * + * @exception {DeveloperError} If the primitive is not ready. */ maximumValues: { get: function () { @@ -577,6 +677,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether or not this primitive should be displayed. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -595,6 +696,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether or not the primitive should update when the view changes. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -613,6 +715,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether or not to render debug visualizations. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -631,6 +734,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether or not to test against depth when rendering. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -653,6 +757,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether or not to jitter the view ray during the raymarch. * This reduces stair-step artifacts but introduces noise. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -673,7 +778,10 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** + * Gets or sets the nearest sampling. * + * @memberof VoxelPrimitive.prototype + * @type {Boolean} */ nearestSampling: { get: function () { @@ -696,6 +804,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * of a voxel is greater than the screen space error, the tile is subdivided. * Lower screen space error corresponds with higher detail rendering, but could * result in worse performance and higher memory consumption. + * * @memberof VoxelPrimitive.prototype * @type {Number} */ @@ -716,6 +825,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets the step size multiplier used during raymarching. * The lower the value, the higher the rendering quality, but * also the worse the performance. + * * @memberof VoxelPrimitive.prototype * @type {Number} */ @@ -734,6 +844,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets whether to reduce thin and noisy details. + * * @memberof VoxelPrimitive.prototype * @type {Boolean} */ @@ -755,9 +866,11 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets the minimum bounds. TODO: fill in the rest later + * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * @throws {DeveloperError} If the primitive is not ready. + * + * @exception {DeveloperError} If the primitive is not ready. */ minBounds: { get: function () { @@ -786,10 +899,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** - * Gets or sets the maximum bounds. TODO: fill in the rest later + * Gets or sets the maximum bounds. TODO: fill in the rest later. + * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * @throws {DeveloperError} If the primitive is not ready. + * + * @exception {DeveloperError} If the primitive is not ready. */ maxBounds: { get: function () { @@ -821,9 +936,11 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets the minimum clipping location in the shape's local coordinate system. * Any voxel content outside the range is clipped. * The minimum value is 0 and the maximum value is 1. + * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * @throws {DeveloperError} If the primitive is not ready. + * + * @exception {DeveloperError} If the primitive is not ready. */ minClippingBounds: { get: function () { @@ -858,9 +975,11 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets the maximum clipping location in the shape's local coordinate system. * Any voxel content outside the range is clipped. * The minimum value is 0 and the maximum value is 1. + * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * @throws {DeveloperError} If the primitive is not ready. + * + * @exception {DeveloperError} If the primitive is not ready. */ maxClippingBounds: { get: function () { @@ -893,6 +1012,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets the custom shader. If undefined, {@link VoxelPrimitive.DefaultCustomShader} is set. + * * @memberof VoxelPrimitive.prototype * @type {CustomShader} */ @@ -914,6 +1034,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets an event that is raised whenever a custom shader is compiled. + * * @memberof VoxelPrimitive.prototype * @type {Event} * @readonly @@ -953,7 +1074,8 @@ const transformPositionUvToLocal = Matrix4.fromRotationTranslation( ); /** - * @private + * Updates the voxel primitive. + * * @param {FrameState} frameState */ VoxelPrimitive.prototype.update = function (frameState) { @@ -975,10 +1097,10 @@ VoxelPrimitive.prototype.update = function (frameState) { if (!this._ready) { // Don't make the primitive ready until after its first update because // external code may want to change some of its properties before it's rendered. - const that = this; + const primitive = this; frameState.afterRender.push(function () { - that._ready = true; - that._readyPromise.resolve(that); + primitive._ready = true; + primitive._readyPromise.resolve(primitive); }); // Create pickId here instead of the constructor because it needs the context object. @@ -1324,13 +1446,23 @@ VoxelPrimitive.prototype.update = function (frameState) { // Set uniforms that come from the traversal. const traversal = this._traversal; + const useLeafNodeTexture = traversal.useLeafNodeTexture; uniforms.octreeInternalNodeTexture = traversal.internalNodeTexture; + uniforms.octreeInternalNodeTexelSizeUv = Cartesian2.clone( + traversal.internalNodeTexelSizeUv, + uniforms.octreeInternalNodeTexelSizeUv + ); uniforms.octreeInternalNodeTilesPerRow = traversal.internalNodeTilesPerRow; - uniforms.octreeInternalNodeTexelSizeUv = traversal.internalNodeTexelSizeUv; - uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; - uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; - uniforms.octreeLeafNodeTexelSizeUv = traversal.leafNodeTexelSizeUv; + + if (useLeafNodeTexture) { + uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; + uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( + traversal.leafNodeTexelSizeUv, + uniforms.octreeLeafNodeTexelSizeUv + ); + uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; + } const megatextures = traversal.megatextures; const megatexture = megatextures[0]; @@ -1360,67 +1492,62 @@ VoxelPrimitive.prototype.update = function (frameState) { megatexture.regionSizeUv, uniforms.megatextureTileSizeUv ); - } else { - // Update the voxel traversal - const traversal = this._traversal; - if (shape.isVisible) { - // Find the keyframe location to render at. Doesn't need to be a whole number. - let keyframeLocation = 0.0; - const clock = this._clock; - const timeIntervalCollection = this._timeIntervalCollection; - if (defined(timeIntervalCollection) && defined(clock)) { - let date = clock.currentTime; - let timeInterval; - let timeIntervalIndex = timeIntervalCollection.indexOf(date); - if (timeIntervalIndex >= 0) { + } else if (shape.isVisible) { + // Find the keyframe location to render at. Doesn't need to be a whole number. + let keyframeLocation = 0.0; + const clock = this._clock; + const timeIntervalCollection = this._timeIntervalCollection; + if (defined(timeIntervalCollection) && defined(clock)) { + let date = clock.currentTime; + let timeInterval; + let timeIntervalIndex = timeIntervalCollection.indexOf(date); + if (timeIntervalIndex >= 0) { + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + } else { + // Date fell outside the range + timeIntervalIndex = ~timeIntervalIndex; + if (timeIntervalIndex === timeIntervalCollection.length) { + // Date past range + timeIntervalIndex = timeIntervalCollection.length - 1; timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.stop; } else { - // Date fell outside the range - timeIntervalIndex = ~timeIntervalIndex; - if (timeIntervalIndex === timeIntervalCollection.length) { - // Date past range - timeIntervalIndex = timeIntervalCollection.length - 1; - timeInterval = timeIntervalCollection.get(timeIntervalIndex); - date = timeInterval.stop; - } else { - // Date before range - timeInterval = timeIntervalCollection.get(timeIntervalIndex); - date = timeInterval.start; - } + // Date before range + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.start; } - - // De-lerp between the start and end of the interval - const totalSeconds = JulianDate.secondsDifference( - timeInterval.stop, - timeInterval.start - ); - const secondsDifferenceStart = JulianDate.secondsDifference( - date, - timeInterval.start - ); - const t = secondsDifferenceStart / totalSeconds; - keyframeLocation = timeIntervalIndex + t; } - traversal.update( - frameState, - keyframeLocation, - shapeIsDirty, // recomputeBoundingVolumes - this._disableUpdate // pauseUpdate + // De-lerp between the start and end of the interval + const totalSeconds = JulianDate.secondsDifference( + timeInterval.stop, + timeInterval.start ); + const secondsDifferenceStart = JulianDate.secondsDifference( + date, + timeInterval.start + ); + const t = secondsDifferenceStart / totalSeconds; + keyframeLocation = timeIntervalIndex + t; } - // Debug draw bounding boxes and other things. Must go after traversal update - // because that's what updates the tile bounding boxes. - if (this._debugDraw) { - debugDraw(this, frameState); - } + // Update the voxel traversal + const traversal = this._traversal; - const rootNodeLoaded = traversal.rootNode.isRenderable( - traversal.frameNumber + const hasLoadedData = traversal.update( + frameState, + keyframeLocation, + shapeIsDirty, // recomputeBoundingVolumes + this._disableUpdate // pauseUpdate ); - if (shape.isVisible && !this._disableRender && rootNodeLoaded) { + if (hasLoadedData && this._debugDraw) { + // Debug draw bounding boxes and other things. Must go after traversal update + // because that's what updates the tile bounding boxes. + debugDraw(this, frameState); + } + + if (hasLoadedData && !this._disableRender) { // Process clipping bounds. const minClip = this._minClippingBounds; const maxClip = this._maxClippingBounds; @@ -1580,8 +1707,13 @@ VoxelPrimitive.prototype.update = function (frameState) { // Shader builder helpers /** - * @param {MetadataType} type - * @returns {String} + * Converts a {@link MetadataType} to a GLSL type. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * * @private */ function getGlslType(type) { @@ -1595,9 +1727,15 @@ function getGlslType(type) { return "vec4"; } } + /** - * @param {MetadataType} type - * @returns {String} + * Gets the GLSL swizzle when reading data from a texture. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL swizzle. + * * @private */ function getGlslTextureSwizzle(type) { @@ -1613,8 +1751,13 @@ function getGlslTextureSwizzle(type) { } /** - * @param {MetadataType} type - * @returns {String} + * Gets the GLSL type of the partial derivative of {@link MetadataType}. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * * @private */ function getGlslPartialDerivativeType(type) { @@ -1632,8 +1775,12 @@ function getGlslPartialDerivativeType(type) { /** * GLSL needs to have `.0` at the end of whole number floats or else it's * treated like an integer. - * @param {Number} number - * @returns {String} + * + * @function + * + * @param {Number} number The number to convert. + * @returns {String} The number as floating point in GLSL. + * * @private */ function getGlslNumberAsFloat(number) { @@ -1645,21 +1792,29 @@ function getGlslNumberAsFloat(number) { } /** + * Gets the GLSL field + * + * @function + * * @param {MetadataType} type * @param {Number} index * @returns {String} + * * @private */ function getGlslField(type, index) { if (type === MetadataType.SCALAR) { return ""; } - return `.[${index}]`; + return `[${index}]`; } /** + * @function + * * @param {VoxelPrimitive} that * @param {Context} context + * * @private */ function buildDrawCommands(that, context) { @@ -2314,10 +2469,10 @@ VoxelPrimitive.prototype.isDestroyed = function () { * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * + * @see VoxelPrimitive#isDestroyed + * * @example * voxelPrimitive = voxelPrimitive && voxelPrimitive.destroy(); - * - * @see VoxelPrimitive#isDestroyed */ VoxelPrimitive.prototype.destroy = function () { const drawCommand = this._drawCommand; @@ -2332,19 +2487,7 @@ VoxelPrimitive.prototype.destroy = function () { } this._pickId = this._pickId && this._pickId.destroy(); - - if (defined(this._traversal)) { - const megatextures = this._traversal.megatextures; - const length = megatextures.length; - for (let i = 0; i < length; i++) { - const megatexture = megatextures[i]; - // TODO: when would megatexture not be defined? - if (defined(megatexture)) { - megatexture.destroy(); - } - } - this._traversal = undefined; - } + this._traversal = this._traversal && this._traversal.destroy(); return destroyObject(this); }; @@ -2405,6 +2548,7 @@ const scratchCornersClipSpace = new Array( * clip space prior to perspective division. * * @function + * * @param {OrientedBoundingBox} orientedBoundingBox * @param {Matrix4} worldToProjection * @param {Cartesian4} result @@ -2506,11 +2650,17 @@ const polylineYAxis = new Cartesian3(0.0, polylineAxisDistance, 0.0); const polylineZAxis = new Cartesian3(0.0, 0.0, polylineAxisDistance); /** - * @ignore + * Draws the tile bounding boxes and axes. + * + * @function + * * @param {VoxelPrimitive} that * @param {FrameState} frameState + * + * @private */ function debugDraw(that, frameState) { + const frameNumber = frameState.frameNumber; const traversal = that._traversal; const polylines = that._debugPolylines; const shapeVisible = that._shape.isVisible; @@ -2545,7 +2695,6 @@ function debugDraw(that, frameState) { } function drawTile(tile) { - const frameNumber = traversal.frameNumber; if (!tile.isRenderable(frameNumber)) { return; } @@ -2594,8 +2743,12 @@ function debugDraw(that, frameState) { /** * The default custom shader used by the primitive. - * @private + * * @type {CustomShader} + * @constant + * @readonly + * + * @private */ VoxelPrimitive.DefaultCustomShader = new CustomShader({ fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) diff --git a/Source/Scene/VoxelProvider.js b/Source/Scene/VoxelProvider.js index ece761b2dce..d4f59eeb3c3 100644 --- a/Source/Scene/VoxelProvider.js +++ b/Source/Scene/VoxelProvider.js @@ -7,12 +7,12 @@ import DeveloperError from "../Core/DeveloperError.js"; * @alias VoxelProvider * @constructor * - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * * @see Cesium3DTilesVoxelProvider * @see GltfVoxelProvider * @see VoxelPrimitive * @see VoxelShapeType + * + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ function VoxelProvider() { DeveloperError.throwInstantiationError(); @@ -21,6 +21,8 @@ function VoxelProvider() { Object.defineProperties(VoxelProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. + * + * @memberof VoxelProvider.prototype * @type {Boolean} * @readonly */ @@ -30,6 +32,8 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the promise that will be resolved when the provider is ready for use. + * + * @memberof VoxelProvider.prototype * @type {Promise.} * @readonly */ @@ -39,7 +43,9 @@ Object.defineProperties(VoxelProvider.prototype, { /** * A model matrix that is applied to all tiles. If undefined, the identity matrix will be used instead. - * @type {Matrix4} + * + * @memberof VoxelProvider.prototype + * @type {Matrix4|undefined} * @readonly */ modelMatrix: { @@ -49,6 +55,8 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the {@link VoxelShapeType} * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype * @type {VoxelShapeType} * @readonly */ @@ -60,7 +68,9 @@ Object.defineProperties(VoxelProvider.prototype, { * Gets the minimum bounds. * If undefined, the shape's default minimum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @memberof VoxelProvider.prototype + * @type {Cartesian3|undefined} * @readonly */ minBounds: { @@ -71,7 +81,9 @@ Object.defineProperties(VoxelProvider.prototype, { * Gets the maximum bounds. * If undefined, the shape's default maximum bounds will be used instead. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @memberof VoxelProvider.prototype + * @type {Cartesian3|undefined} * @readonly */ maxBounds: { @@ -81,6 +93,8 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype * @type {Cartesian3} * @readonly */ @@ -91,7 +105,9 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @memberof VoxelProvider.prototype + * @type {Cartesian3|undefined} * @readonly */ paddingBefore: { @@ -101,7 +117,9 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Cartesian3} + * + * @memberof VoxelProvider.prototype + * @type {Cartesian3|undefined} * @readonly */ paddingAfter: { @@ -111,7 +129,10 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata names. * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype * @type {String[]} + * @readonly */ names: { get: DeveloperError.throwInstantiationError, @@ -120,7 +141,10 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata types * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype * @type {MetadataType[]} + * @readonly */ types: { get: DeveloperError.throwInstantiationError, @@ -129,7 +153,10 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata component types * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype * @type {MetadataComponentType[]} + * @readonly */ componentTypes: { get: DeveloperError.throwInstantiationError, @@ -137,7 +164,10 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata minimum values. - * @type {Number[]} + * + * @memberof VoxelProvider.prototype + * @type {Number[][]|undefined} + * @readonly */ minimumValues: { get: DeveloperError.throwInstantiationError, @@ -145,7 +175,10 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata maximum values. - * @type {Number[]} + * + * @memberof VoxelProvider.prototype + * @type {Number[][]|undefined} + * @readonly */ maximumValues: { get: DeveloperError.throwInstantiationError, @@ -154,28 +187,20 @@ Object.defineProperties(VoxelProvider.prototype, { /** * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be undefined. * This should not be called before {@link VoxelProvider#ready} returns true. - * @type {Number} + * + * @memberof VoxelProvider.prototype + * @type {Number|undefined} + * @readonly */ maximumTileCount: { get: DeveloperError.throwInstantiationError, }, }); -/** - * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. - * If the provider doesn't need this functionality it should leave this function undefined. - * @function - * @param {FrameState} frameState - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - */ -VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; - /** * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * This function should not be called before {@link VoxelProvider#ready} returns true. - * @function + * * @param {Object} [options] Object with the following properties: * @param {Number} [options.tileLevel=0] The tile's level. * @param {Number} [options.tileX=0] The tile's X coordinate. @@ -183,9 +208,16 @@ VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; * @param {Number} [options.tileZ=0] The tile's Z coordinate. * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + * @exception {DeveloperError} The provider must be ready. */ VoxelProvider.prototype.requestData = DeveloperError.throwInstantiationError; +/** + * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. + * If the provider doesn't need this functionality it should leave this function undefined. + * + * @param {FrameState} frameState + */ +VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; + export default VoxelProvider; diff --git a/Source/Scene/VoxelShape.js b/Source/Scene/VoxelShape.js index 6588258a7db..0264d5a3b8b 100644 --- a/Source/Scene/VoxelShape.js +++ b/Source/Scene/VoxelShape.js @@ -7,13 +7,12 @@ import DeveloperError from "../Core/DeveloperError.js"; * @alias VoxelShape * @constructor * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - * * @see VoxelBoxShape * @see VoxelEllipsoidShape * @see VoxelCylinderShape * @see VoxelShapeType + * + * @private */ function VoxelShape() { DeveloperError.throwInstantiationError(); @@ -23,7 +22,10 @@ Object.defineProperties(VoxelShape.prototype, { /** * An oriented bounding box containing the bounded shape. * The update function must be called before accessing this value. + * + * @memberof VoxelShape.prototype * @type {OrientedBoundingBox} + * @readonly */ orientedBoundingBox: { get: DeveloperError.throwInstantiationError, @@ -32,7 +34,10 @@ Object.defineProperties(VoxelShape.prototype, { /** * A bounding sphere containing the bounded shape. * The update function must be called before accessing this value. + * + * @memberof VoxelShape.prototype * @type {BoundingSphere} + * @readonly */ boundingSphere: { get: DeveloperError.throwInstantiationError, @@ -41,7 +46,10 @@ Object.defineProperties(VoxelShape.prototype, { /** * A transformation matrix containing the bounded shape. * The update function must be called before accessing this value. + * + * @memberof VoxelShape.prototype * @type {Matrix4} + * @readonly */ boundTransform: { get: DeveloperError.throwInstantiationError, @@ -50,7 +58,10 @@ Object.defineProperties(VoxelShape.prototype, { /** * A transformation matrix containing the shape, ignoring the bounds. * The update function must be called before accessing this value. + * + * @memberof VoxelShape.prototype * @type {Matrix4} + * @readonly */ shapeTransform: { get: DeveloperError.throwInstantiationError, @@ -59,7 +70,10 @@ Object.defineProperties(VoxelShape.prototype, { /** * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. * The update function must be called before accessing this value. + * + * @memberof VoxelShape.prototype * @type {Boolean} + * @readonly */ isVisible: { get: DeveloperError.throwInstantiationError, @@ -68,29 +82,23 @@ Object.defineProperties(VoxelShape.prototype, { /** * Update the shape's state. - * @function + * * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelShape.prototype.update = DeveloperError.throwInstantiationError; /** * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. - * @function + * * @param {Number} tileLevel The tile's level. * @param {Number} tileX The tile's x coordinate. * @param {Number} tileY The tile's y coordinate. * @param {Number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile. * @returns {OrientedBoundingBox} The oriented bounding box. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelShape.prototype.computeOrientedBoundingBoxForTile = DeveloperError.throwInstantiationError; @@ -98,31 +106,32 @@ VoxelShape.prototype.computeOrientedBoundingBoxForTile = /** * Computes an approximate step size for raymarching the root tile of a voxel grid. * The update function must be called before calling this function. - * @function + * * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. * @returns {Number} The step size. - * - * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelShape.prototype.computeApproximateStepSize = DeveloperError.throwInstantiationError; /** - * Defines the minimum bounds of the shape. This can vary per-shape. + * Defines the minimum bounds of the shape. The meaning can vary per-shape. + * * @type {Cartesian3} + * @constant + * @readonly * * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelShape.DefaultMinBounds = DeveloperError.throwInstantiationError; /** - * Defines the maximum bounds of the shape. This can vary per-shape. + * Defines the maximum bounds of the shape. The meaning can vary per-shape. + * * @type {Cartesian3} + * @constant + * @readonly * * @private - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ VoxelShape.DefaultMaxBounds = DeveloperError.throwInstantiationError; diff --git a/Source/Scene/VoxelShapeType.js b/Source/Scene/VoxelShapeType.js index fa256157039..4e11072bd04 100644 --- a/Source/Scene/VoxelShapeType.js +++ b/Source/Scene/VoxelShapeType.js @@ -8,8 +8,8 @@ import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; * An enum of voxel shapes supported by EXT_primitive_voxels. The shape controls * how the voxel grid is mapped to 3D space. * - * @namespace * @enum VoxelShapeType + * * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ const VoxelShapeType = { @@ -82,8 +82,10 @@ VoxelShapeType.getMaxBounds = function (shapeType) { /** * Converts a primitive type to a voxel shape. glTF voxel primitive types are * defined by EXT_primitive_voxels. + * * @param {PrimitiveType} primitiveType The primitive type. * @returns {VoxelShapeType} The shape type. + * * @private */ VoxelShapeType.fromPrimitiveType = function (primitiveType) { @@ -105,8 +107,10 @@ VoxelShapeType.fromPrimitiveType = function (primitiveType) { * Converts a shape type to a constructor that can be used to create a shape * object or get per-shape properties like DefaultMinBounds and * DefaultMaxBounds. + * * @param {VoxelShapeType} shapeType The shape type. * @returns {Function} The shape's constructor. + * * @private */ VoxelShapeType.getShapeConstructor = function (shapeType) { diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index 320b75538ad..d99e412cf1a 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -26,6 +26,7 @@ import MetadataComponentType from "./MetadataComponentType.js"; /** * Handles tileset traversal, tile requests, and GPU resources. Intended to be * private and paired with a {@link VoxelPrimitive}, which has a user-facing API. + * * @alias VoxelTraversal * @constructor * @@ -49,16 +50,17 @@ function VoxelTraversal( maximumTextureMemoryByteLength ) { /** - * @private + * TODO: maybe this shouldn't be stored? * @type {VoxelPrimitive} + * @private */ - this.primitive = primitive; + this._primitive = primitive; const length = types.length; /** - * @private * @type {Megatexture[]} + * @readonly */ this.megatextures = new Array(length); @@ -80,16 +82,16 @@ function VoxelTraversal( const maximumTileCount = this.megatextures[0].maximumTileCount; /** - * @private * @type {Number} + * @private */ - this.simultaneousRequestCount = 0; + this._simultaneousRequestCount = 0; /** - * @private * @type {Boolean} + * @private */ - this.debugPrint = false; + this._debugPrint = false; const shape = primitive._shape; const rootLevel = 0; @@ -99,8 +101,8 @@ function VoxelTraversal( const rootParent = undefined; /** - * @private * @type {SpatialNode} + * @readonly */ this.rootNode = new SpatialNode( rootLevel, @@ -113,43 +115,43 @@ function VoxelTraversal( ); /** - * @private * @type {DoubleEndedPriorityQueue} + * @private */ - this.priorityQueue = new DoubleEndedPriorityQueue({ + this._priorityQueue = new DoubleEndedPriorityQueue({ maximumLength: maximumTileCount, comparator: KeyframeNode.priorityComparator, }); /** - * @private * @type {KeyframeNode[]} + * @private */ - this.highPriorityKeyframeNodes = new Array(maximumTileCount); + this._highPriorityKeyframeNodes = new Array(maximumTileCount); /** - * @private * @type {KeyframeNode[]} + * @private */ - this.keyframeNodesInMegatexture = new Array(maximumTileCount); + this._keyframeNodesInMegatexture = new Array(maximumTileCount); /** - * @private * @type {Number} + * @private */ - this.keyframeCount = keyframeCount; + this._keyframeCount = keyframeCount; /** - * @private * @type {Number} + * @private */ - this.keyframeLocation = 0; + this._keyframeLocation = 0; /** + * @type {Number[]} * @private - * @type {Number} */ - this.frameNumber = -1; + this._binaryTreeKeyframeWeighting = new Array(keyframeCount); function binaryTreeWeightingRecursive(arr, start, end, depth) { if (start > end) { @@ -160,11 +162,12 @@ function VoxelTraversal( binaryTreeWeightingRecursive(arr, start, mid - 1, depth + 1); binaryTreeWeightingRecursive(arr, mid + 1, end, depth + 1); } - this.binaryTreeKeyframeWeighting = new Array(keyframeCount); - this.binaryTreeKeyframeWeighting[0] = 0; - this.binaryTreeKeyframeWeighting[keyframeCount - 1] = 0; + + const binaryTreeKeyframeWeighting = this._binaryTreeKeyframeWeighting; + binaryTreeKeyframeWeighting[0] = 0; + binaryTreeKeyframeWeighting[keyframeCount - 1] = 0; binaryTreeWeightingRecursive( - this.binaryTreeKeyframeWeighting, + binaryTreeKeyframeWeighting, 1, keyframeCount - 2, 0 @@ -179,6 +182,10 @@ function VoxelTraversal( maximumTileCount / internalNodeTilesPerRow ); + /** + * @type {Texture} + * @readonly + */ this.internalNodeTexture = new Texture({ context: context, pixelFormat: PixelFormat.RGBA, @@ -191,14 +198,48 @@ function VoxelTraversal( magnificationFilter: TextureMagnificationFilter.NEAREST, }), }); + + /** + * @type {Number} + * @readonly + */ + this.internalNodeTilesPerRow = internalNodeTilesPerRow; + + /** + * @type {Cartesian2} + * @readonly + */ this.internalNodeTexelSizeUv = new Cartesian2( 1.0 / internalNodeTextureDimensionX, 1.0 / internalNodeTextureDimensionY ); - this.internalNodeTilesPerRow = internalNodeTilesPerRow; + /** + * @type {Boolean} + * @readonly + */ this.useLeafNodeTexture = keyframeCount > 1; - if (this.useLeafNodeTexture) { + + /** + * @type {Texture|undefined} + * @readonly + */ + this.leafNodeTexture = undefined; + + /** + * @type {Number|undefined} + * @readonly + */ + this.leafNodeTilesPerRow = undefined; + + /** + * @type {Cartesian2|undefined} + * @readonly + */ + this.leafNodeTexelSizeUv = undefined; + + const useLeafNodeTexture = this._useLeafNodeTexture; + if (useLeafNodeTexture) { const leafNodeTexelCount = 2; const leafNodeTextureDimensionX = 1024; const leafNodeTilesPerRow = Math.floor( @@ -225,21 +266,17 @@ function VoxelTraversal( 1.0 / leafNodeTextureDimensionY ); this.leafNodeTilesPerRow = leafNodeTilesPerRow; - } else { - this.leafNodeTexture = undefined; - this.leafNodeTexelSizeUv = undefined; - this.leafNodeTilesPerRow = undefined; } } VoxelTraversal.simultaneousRequestCountMaximum = 50; /** - * @private * @param {FrameState} frameState * @param {Number} keyframeLocation * @param {Boolean} recomputeBoundingVolumes * @param {Boolean} pauseUpdate + * @returns {Boolean} True if the voxel grid has any loaded data. */ VoxelTraversal.prototype.update = function ( frameState, @@ -247,51 +284,99 @@ VoxelTraversal.prototype.update = function ( recomputeBoundingVolumes, pauseUpdate ) { - const that = this; - - const keyframeCount = that.keyframeCount; - that.keyframeLocation = CesiumMath.clamp( + const keyframeCount = this._keyframeCount; + this._keyframeLocation = CesiumMath.clamp( keyframeLocation, 0.0, keyframeCount - 1 ); if (recomputeBoundingVolumes) { - recomputeBoundingVolumesRecursive(that, that.rootNode); + recomputeBoundingVolumesRecursive(this, this.rootNode); } if (!pauseUpdate) { - that.frameNumber = frameState.frameNumber; - const timestamp0 = getTimestamp(); - loadAndUnload(that, frameState); + loadAndUnload(this, frameState); const timestamp1 = getTimestamp(); - generateOctree(that); + generateOctree(this, frameState); const timestamp2 = getTimestamp(); - const debugStatistics = that.debugPrint; + const debugStatistics = this._debugPrint; if (debugStatistics) { const loadAndUnloadTimeMs = timestamp1 - timestamp0; const generateOctreeTimeMs = timestamp2 - timestamp1; const totalTimeMs = timestamp2 - timestamp0; printDebugInformation( - that, + this, loadAndUnloadTimeMs, generateOctreeTimeMs, totalTimeMs ); } } + + const rootNode = this.rootNode; + const frameNumber = frameState.frameNumber; + return rootNode.isRenderable(frameNumber); +}; + +/** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see VoxelTraversal#destroy + */ +VoxelTraversal.prototype.isDestroyed = function () { + return false; }; /** - * @ignore + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see VoxelTraversal#isDestroyed + * + * @example + * voxelTraversal = voxelTraversal && voxelTraversal.destroy(); + */ +VoxelTraversal.prototype.destroy = function () { + const megatextures = this.megatextures; + const megatextureLength = megatextures.length; + for (let i = 0; i < megatextureLength; i++) { + megatextures[i] = megatextures[i] && megatextures[i].destroy(); + } + + this.internalNodeTexture = + this.internalNodeTexture && this.internalNodeTexture.destroy(); + + this.leafNodeTexture = this.leafNodeTexture && this.leafNodeTexture.destroy(); + + return destroyObject(this); +}; + +/** + * @function + * * @param {VoxelTraversal} that * @param {SpatialNode} node + * + * @private */ function recomputeBoundingVolumesRecursive(that, node) { - const shape = that.primitive._shape; - const dimensions = that.primitive._provider.dimensions; + const primitive = that._primitive; + const shape = primitive._shape; + const dimensions = primitive._provider.dimensions; node.computeBoundingVolumes(shape, dimensions); if (defined(node.children)) { for (let i = 0; i < 8; i++) { @@ -303,9 +388,13 @@ function recomputeBoundingVolumesRecursive(that, node) { /** * Call requestData for each metadata - * @ignore + * + * @function + * * @param {VoxelTraversal} that * @param {KeyframeNode} keyframeNode + * + * @private */ function requestTiles(that, keyframeNode) { const keys = Object.keys(that.megatextures); @@ -316,20 +405,23 @@ function requestTiles(that, keyframeNode) { } } /** - * @ignore + * @function + * * @param {VoxelTraversal} that * @param {KeyframeNode} keyframeNode * @param {String} metadataName + * + * @private */ function requestData(that, keyframeNode, metadataName) { if ( - that.simultaneousRequestCount >= + that._simultaneousRequestCount >= VoxelTraversal.simultaneousRequestCountMaximum ) { return; } - const primitive = that.primitive; + const primitive = that._primitive; const provider = primitive._provider; const keyframe = keyframeNode.keyframe; const spatialNode = keyframeNode.spatialNode; @@ -339,7 +431,7 @@ function requestData(that, keyframeNode, metadataName) { const tileZ = spatialNode.z; const postRequestSuccess = function (result) { - that.simultaneousRequestCount--; + that._simultaneousRequestCount--; const length = primitive._provider.types.length; if (!defined(result)) { @@ -373,7 +465,7 @@ function requestData(that, keyframeNode, metadataName) { }; const postRequestFailure = function () { - that.simultaneousRequestCount--; + that._simultaneousRequestCount--; keyframeNode.state = VoxelTraversal.LoadState.FAILED; }; @@ -387,7 +479,7 @@ function requestData(that, keyframeNode, metadataName) { }); if (defined(promise)) { - that.simultaneousRequestCount++; + that._simultaneousRequestCount++; keyframeNode.state = VoxelTraversal.LoadState.RECEIVING; promise.then(postRequestSuccess).catch(postRequestFailure); } else { @@ -396,28 +488,34 @@ function requestData(that, keyframeNode, metadataName) { } /** - * @ignore + * @function + * * @param {Number} x * @returns {Number} + * + * @private */ function mapInfiniteRangeToZeroOne(x) { return x / (1.0 + x); } /** - * @ignore + * @function + * * @param {VoxelTraversal} that * @param {FrameState} frameState + * + * @private */ function loadAndUnload(that, frameState) { - const frameNumber = that.frameNumber; - const primitive = that.primitive; + const frameNumber = frameState.frameNumber; + const primitive = that._primitive; const shape = primitive._shape; const voxelDimensions = primitive._provider.dimensions; const targetScreenSpaceError = primitive._screenSpaceError; - const priorityQueue = that.priorityQueue; - const keyframeLocation = that.keyframeLocation; - const keyframeCount = that.keyframeCount; + const priorityQueue = that._priorityQueue; + const keyframeLocation = that._keyframeLocation; + const keyframeCount = that._keyframeCount; const rootNode = that.rootNode; const cameraPosition = frameState.camera.positionWC; @@ -511,7 +609,7 @@ function loadAndUnload(that, frameState) { 4.0 ); const binaryTreeFactor = Math.exp( - -that.binaryTreeKeyframeWeighting[keyframe] + -that._binaryTreeKeyframeWeighting[keyframe] ); keyframeNode.priority = 10.0 * ssePriority; keyframeNode.priority += CesiumMath.lerp( @@ -632,7 +730,7 @@ function loadAndUnload(that, frameState) { priorityQueue.reset(); addToQueueRecursive(rootNode, CullingVolume.MASK_INDETERMINATE); - const highPriorityKeyframeNodes = that.highPriorityKeyframeNodes; + const highPriorityKeyframeNodes = that._highPriorityKeyframeNodes; let highPriorityKeyframeNodeCount = 0; let highPriorityKeyframeNode; while (priorityQueue.length > 0) { @@ -644,7 +742,7 @@ function loadAndUnload(that, frameState) { highPriorityKeyframeNodeCount++; } - const keyframeNodesInMegatexture = that.keyframeNodesInMegatexture; + const keyframeNodesInMegatexture = that._keyframeNodesInMegatexture; // TODO: some of the megatexture state should be stored once, not duplicate for each megatexture const megatexture = that.megatextures[0]; const keyframeNodesInMegatextureCount = megatexture.occupiedCount; @@ -704,8 +802,11 @@ function loadAndUnload(that, frameState) { } /** - * @ignore + * @function + * * @param {VoxelTraversal} that + * + * @private */ function printDebugInformation( that, @@ -713,7 +814,7 @@ function printDebugInformation( generateOctreeTimeMs, totalTimeMs ) { - const keyframeCount = that.keyframeCount; + const keyframeCount = that._keyframeCount; const rootNode = that.rootNode; const loadStateCount = Object.keys(VoxelTraversal.LoadState).length; @@ -802,14 +903,17 @@ VoxelTraversal.LoadState = { }; /** - * @ignore + * @alias SpatialNode * @constructor + * * @param {Number} level * @param {Number} x * @param {Number} y * @param {Number} z * @param {SpatialNode} parent * @param {VoxelShapeType} shape + * + * @private */ function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { /** @@ -855,6 +959,11 @@ function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { this.computeBoundingVolumes(shape, voxelDimensions); } +/** + * @param {SpatialNode} a + * @param {SpatialNode} b + * @returns {Boolean} + */ SpatialNode.spatialComparator = function (a, b) { // The higher of the two screen space errors is prioritized return b.screenSpaceError - a.screenSpaceError; @@ -863,7 +972,6 @@ SpatialNode.spatialComparator = function (a, b) { const scratchObbHalfScale = new Cartesian3(); /** - * @ignore * @param {VoxelShape} shape * @param {Cartesian3} voxelDimensions */ @@ -889,20 +997,17 @@ SpatialNode.prototype.computeBoundingVolumes = function ( }; /** - * @ignore * @param {FrameState} frameState * @param {Number} visibilityPlaneMask * @returns {Number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. */ SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { - const that = this; - const obb = that.orientedBoundingBox; + const obb = this.orientedBoundingBox; const cullingVolume = frameState.cullingVolume; return cullingVolume.computeVisibilityWithPlaneMask(obb, visibilityPlaneMask); }; /** - * @ignore * @param {Cartesian3} cameraPosition * @param {Number} screenSpaceErrorMultiplier */ @@ -910,15 +1015,14 @@ SpatialNode.prototype.computeScreenSpaceError = function ( cameraPosition, screenSpaceErrorMultiplier ) { - const that = this; - const obb = that.orientedBoundingBox; + const obb = this.orientedBoundingBox; let distance = Math.sqrt(obb.distanceSquaredTo(cameraPosition)); // Avoid divide-by-zero when viewer is inside the tile. distance = Math.max(distance, CesiumMath.EPSILON7); - const approximateVoxelSize = that.approximateVoxelSize; + const approximateVoxelSize = this.approximateVoxelSize; const error = screenSpaceErrorMultiplier * (approximateVoxelSize / distance); - that.screenSpaceError = error; + this.screenSpaceError = error; }; // This object imitates a KeyframeNode. Only used for binary search function. @@ -928,13 +1032,12 @@ const scratchBinarySearchKeyframeNode = { /** * Finds the index of the keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * @ignore + * * @param {Number} keyframe * @returns {Number} */ SpatialNode.prototype.findKeyframeIndex = function (keyframe) { - const that = this; - const keyframeNodes = that.keyframeNodes; + const keyframeNodes = this.keyframeNodes; scratchBinarySearchKeyframeNode.keyframe = keyframe; const index = binarySearch( keyframeNodes, @@ -943,15 +1046,15 @@ SpatialNode.prototype.findKeyframeIndex = function (keyframe) { ); return index; }; + /** * Finds the index of the renderable keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * @ignore + * * @param {Number} keyframe * @returns {Number} */ SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { - const that = this; - const renderableKeyframeNodes = that.renderableKeyframeNodes; + const renderableKeyframeNodes = this.renderableKeyframeNodes; scratchBinarySearchKeyframeNode.keyframe = keyframe; const index = binarySearch( renderableKeyframeNodes, @@ -963,15 +1066,13 @@ SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { /** * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. - * @ignore + * * @param {Number} keyframeLocation */ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( keyframeLocation ) { - const that = this; - - let spatialNode = that; + let spatialNode = this; const startLevel = spatialNode.level; const targetKeyframePrev = Math.floor(keyframeLocation); @@ -1058,12 +1159,12 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( spatialNode = spatialNode.parent; } - that.renderableKeyframeNodePrevious = bestKeyframeNodePrev; - that.renderableKeyframeNodeNext = bestKeyframeNodeNext; + this.renderableKeyframeNodePrevious = bestKeyframeNodePrev; + this.renderableKeyframeNodeNext = bestKeyframeNodeNext; if (defined(bestKeyframeNodePrev) && defined(bestKeyframeNodeNext)) { const bestKeyframePrev = bestKeyframeNodePrev.keyframe; const bestKeyframeNext = bestKeyframeNodeNext.keyframe; - that.renderableKeyframeNodeLerp = + this.renderableKeyframeNodeLerp = bestKeyframePrev === bestKeyframeNext ? 0.0 : CesiumMath.clamp( @@ -1076,30 +1177,25 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( }; /** - * @ignore * @param {Number} frameNumber * @returns {Boolean} */ SpatialNode.prototype.isVisited = function (frameNumber) { - const that = this; - return that.visitedFrameNumber === frameNumber; + return this.visitedFrameNumber === frameNumber; }; /** - * @ignore * @param {Number} keyframe */ SpatialNode.prototype.createKeyframeNode = function (keyframe) { - const that = this; - let index = that.findKeyframeIndex(keyframe); + let index = this.findKeyframeIndex(keyframe); if (index < 0) { index = ~index; // convert to insertion index - const keyframeNode = new KeyframeNode(that, keyframe); - that.keyframeNodes.splice(index, 0, keyframeNode); + const keyframeNode = new KeyframeNode(this, keyframe); + this.keyframeNodes.splice(index, 0, keyframeNode); } }; /** - * @ignore * @param {KeyframeNode} keyframeNode * @param {Megatexture} megatexture */ @@ -1107,15 +1203,13 @@ SpatialNode.prototype.destroyKeyframeNode = function ( keyframeNode, megatextures ) { - const that = this; - const keyframe = keyframeNode.keyframe; - const keyframeIndex = that.findKeyframeIndex(keyframe); + const keyframeIndex = this.findKeyframeIndex(keyframe); if (keyframeIndex < 0) { throw new DeveloperError("Keyframe node does not exist."); } - const keyframeNodes = that.keyframeNodes; + const keyframeNodes = this.keyframeNodes; keyframeNodes.splice(keyframeIndex, 1); if (keyframeNode.megatextureIndex !== -1) { @@ -1127,14 +1221,14 @@ SpatialNode.prototype.destroyKeyframeNode = function ( megatextureArray[i].remove(keyframeNode.megatextureIndex); } - const renderableKeyframeNodeIndex = that.findRenderableKeyframeIndex( + const renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( keyframe ); if (renderableKeyframeNodeIndex < 0) { throw new DeveloperError("Renderable keyframe node does not exist."); } - const renderableKeyframeNodes = that.renderableKeyframeNodes; + const renderableKeyframeNodes = this.renderableKeyframeNodes; renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); } @@ -1146,6 +1240,10 @@ SpatialNode.prototype.destroyKeyframeNode = function ( keyframeNode.highPriorityFrameNumber = -1; }; +/** + * @param {KeyframeNode} keyframeNode + * @param {Megatexture[]} megatextures + */ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( keyframeNode, megatextures @@ -1177,8 +1275,8 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); }; + /** - * @ignore * @param {KeyframeNode} keyframeNode * @param {Megatexture} megatexture */ @@ -1186,8 +1284,6 @@ SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( keyframeNode, megatexture ) { - const that = this; - if ( keyframeNode.state !== VoxelTraversal.LoadState.RECEIVED || keyframeNode.megatextureIndex !== -1 || @@ -1202,8 +1298,8 @@ SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( keyframeNode.metadatas[megatexture.metadataName] = undefined; // data is in megatexture so no need to hold onto it keyframeNode.state = VoxelTraversal.LoadState.LOADED; - const renderableKeyframeNodes = that.renderableKeyframeNodes; - let renderableKeyframeNodeIndex = that.findRenderableKeyframeIndex( + const renderableKeyframeNodes = this.renderableKeyframeNodes; + let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( keyframeNode.keyframe ); if (renderableKeyframeNodeIndex >= 0) { @@ -1214,30 +1310,30 @@ SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( }; /** - * @ignore * @param {Number} frameNumber */ SpatialNode.prototype.isRenderable = function (frameNumber) { - const that = this; - - const previousNode = that.renderableKeyframeNodePrevious; - const nextNode = that.renderableKeyframeNodeNext; - const level = that.level; + const previousNode = this.renderableKeyframeNodePrevious; + const nextNode = this.renderableKeyframeNodeNext; + const level = this.level; return ( defined(previousNode) && defined(nextNode) && (previousNode.spatialNode.level === level || nextNode.spatialNode.level === level) && - that.visitedFrameNumber === frameNumber + this.visitedFrameNumber === frameNumber ); }; /** - * @ignore + * @alias KeyframeNode * @constructor + * * @param {SpatialNode} spatialNode * @param {Number} keyframe + * + * @private */ function KeyframeNode(spatialNode, keyframe) { this.spatialNode = spatialNode; @@ -1250,15 +1346,14 @@ function KeyframeNode(spatialNode, keyframe) { } /** - * @ignore * @param {KeyframeNode} a * @param {KeyframeNode} b */ KeyframeNode.priorityComparator = function (a, b) { return a.priority - b.priority; }; + /** - * @ignore * @param {KeyframeNode} a * @param {KeyframeNode} b */ @@ -1302,13 +1397,15 @@ const GpuOctreeFlag = { }; /** - * @ignore + * @function + * * @param {VoxelTraversal} that + * @param {FrameState} frameState */ -function generateOctree(that) { - const keyframeLocation = that.keyframeLocation; - const useLeafNodes = that.useLeafNodeTexture; - const frameNumber = that.frameNumber; +function generateOctree(that, frameState) { + const keyframeLocation = that._keyframeLocation; + const useLeafNodes = that._useLeafNodeTexture; + const frameNumber = frameState.frameNumber; let internalNodeCount = 0; let leafNodeCount = 0; @@ -1523,7 +1620,6 @@ function generateOctree(that) { } /** - * @private * @param {Number} tileCount * @param {Cartesian3} dimensions * @param {MetadataType[]} types @@ -1555,13 +1651,16 @@ VoxelTraversal.getApproximateTextureMemoryByteLength = function ( }; /** - * @ignore + * @alias Megatexture * @constructor + * * @param {Context} context * @param {Cartesian3} dimensions * @param {Number} channelCount * @param {MetadataComponentType} componentType * @param {Number} [textureMemoryByteLength] + * + * @private */ function Megatexture( context, @@ -1642,32 +1741,32 @@ function Megatexture( /** * @type {Number} - * @private + * @readonly */ this.channelCount = channelCount; /** * @type {MetadataComponentType} - * @private + * @readonly */ this.componentType = componentType; /** * @type {Cartesian3} - * @private + * @readonly */ this.voxelCountPerTile = Cartesian3.clone(dimensions, new Cartesian3()); /** * @type {Number} - * @private + * @readonly */ this.maximumTileCount = regionCountPerMegatextureX * regionCountPerMegatextureY; /** * @type {Cartesian2} - * @private + * @readonly */ this.regionCountPerMegatexture = new Cartesian2( regionCountPerMegatextureX, @@ -1676,7 +1775,7 @@ function Megatexture( /** * @type {Cartesian2} - * @private + * @readonly */ this.voxelCountPerRegion = new Cartesian2( voxelCountPerRegionX, @@ -1685,7 +1784,7 @@ function Megatexture( /** * @type {Cartesian2} - * @private + * @readonly */ this.sliceCountPerRegion = new Cartesian2( sliceCountPerRegionX, @@ -1694,7 +1793,7 @@ function Megatexture( /** * @type {Cartesian2} - * @private + * @readonly */ this.voxelSizeUv = new Cartesian2( 1.0 / textureDimension, @@ -1703,7 +1802,7 @@ function Megatexture( /** * @type {Cartesian2} - * @private + * @readonly */ this.sliceSizeUv = new Cartesian2( dimensions.x / textureDimension, @@ -1712,7 +1811,7 @@ function Megatexture( /** * @type {Cartesian2} - * @private + * @readonly */ this.regionSizeUv = new Cartesian2( voxelCountPerRegionX / textureDimension, @@ -1721,7 +1820,7 @@ function Megatexture( /** * @type {Texture} - * @private + * @readonly */ this.texture = new Texture({ context: context, @@ -1739,13 +1838,17 @@ function Megatexture( }); const ArrayType = MetadataComponentType.toTypedArrayType(componentType); + + /** + * @type {Array} + */ this.tileVoxelDataTemp = new ArrayType( voxelCountPerRegionX * voxelCountPerRegionY * channelCount ); /** * @type {MegatextureNode[]} - * @private + * @readonly */ this.nodes = new Array(this.maximumTileCount); for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { @@ -1762,89 +1865,88 @@ function Megatexture( /** * @type {MegatextureNode} - * @private + * @readonly */ this.occupiedList = undefined; /** * @type {MegatextureNode} - * @private + * @readonly */ this.emptyList = this.nodes[0]; /** * @type {Number} - * @private + * @readonly */ this.occupiedCount = 0; } /** - * @ignore + * @alias MegatextureNode * @constructor + * * @param {Number} index + * + * @private */ function MegatextureNode(index) { + /** + * @type {Number} + */ this.index = index; /** - * @ignore * @type {MegatextureNode} */ this.nextNode = undefined; /** - * @ignore * @type {MegatextureNode} */ this.previousNode = undefined; } /** - * @ignore * @param {Array} data * @returns {Number} */ Megatexture.prototype.add = function (data) { - const that = this; - - if (that.isFull()) { + if (this.isFull()) { throw new DeveloperError("Trying to add when there are no empty spots"); } // remove head of empty list - const node = that.emptyList; - that.emptyList = that.emptyList.nextNode; - if (defined(that.emptyList)) { - that.emptyList.previousNode = undefined; + const node = this.emptyList; + this.emptyList = this.emptyList.nextNode; + if (defined(this.emptyList)) { + this.emptyList.previousNode = undefined; } // make head of occupied list - node.nextNode = that.occupiedList; + node.nextNode = this.occupiedList; if (defined(node.nextNode)) { node.nextNode.previousNode = node; } - that.occupiedList = node; + this.occupiedList = node; const index = node.index; - that.writeDataToTexture(index, data); + this.writeDataToTexture(index, data); - that.occupiedCount++; + this.occupiedCount++; return index; }; /** - * @ignore * @param {Number} index */ Megatexture.prototype.remove = function (index) { - const that = this; - if (index < 0 || index >= that.maximumTileCount) { + if (index < 0 || index >= this.maximumTileCount) { throw new DeveloperError("Megatexture index out of bounds"); } // remove from list - const node = that.nodes[index]; + const node = this.nodes[index]; if (defined(node.previousNode)) { node.previousNode.nextNode = node.nextNode; } @@ -1853,26 +1955,23 @@ Megatexture.prototype.remove = function (index) { } // make head of empty list - node.nextNode = that.emptyList; + node.nextNode = this.emptyList; if (defined(node.nextNode)) { node.nextNode.previousNode = node; } node.previousNode = undefined; - that.emptyList = node; - that.occupiedCount--; + this.emptyList = node; + this.occupiedCount--; }; /** - * @ignore * @returns {Boolean} */ Megatexture.prototype.isFull = function () { - const that = this; - return that.emptyList === undefined; + return this.emptyList === undefined; }; /** - * @ignore * @param {Number} tileCount * @param {Cartesian3} dimensions * @param {Number} channelCount number of channels in the metadata. Must be 1 to 4. @@ -1925,18 +2024,16 @@ Megatexture.getApproximateTextureMemoryByteLength = function ( }; /** - * @ignore * @param {Number} index * @param {Float32Array|Uint16Array|Uint8Array} data */ Megatexture.prototype.writeDataToTexture = function (index, data) { - const that = this; - const texture = that.texture; - const channelCount = that.channelCount; - const regionDimensionsPerMegatexture = that.regionCountPerMegatexture; - const voxelDimensionsPerRegion = that.voxelCountPerRegion; - const voxelDimensionsPerTile = that.voxelCountPerTile; - const sliceDimensionsPerRegion = that.sliceCountPerRegion; + const texture = this.texture; + const channelCount = this.channelCount; + const regionDimensionsPerMegatexture = this.regionCountPerMegatexture; + const voxelDimensionsPerRegion = this.voxelCountPerRegion; + const voxelDimensionsPerTile = this.voxelCountPerTile; + const sliceDimensionsPerRegion = this.sliceCountPerRegion; let tileData = data; @@ -1947,8 +2044,8 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { for (let i = 0; i < elementCount / channelCount; i++) { for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) { const dataIndex = i * channelCount + channelIndex; - const minimumValue = that.minimumValues[channelIndex]; - const maximumValue = that.maximumValues[channelIndex]; + const minimumValue = this.minimumValues[channelIndex]; + const maximumValue = this.maximumValues[channelIndex]; // TODO extrema are unnormalized, but we are normalizing to [0, 1] here. what do we want to do? will the user expect to get normalized samples and extrema in the style function? tileData[dataIndex] = (data[dataIndex] - minimumValue) / (maximumValue - minimumValue); @@ -1961,7 +2058,7 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { } } - const tileVoxelData = that.tileVoxelDataTemp; + const tileVoxelData = this.tileVoxelDataTemp; for (let z = 0; z < voxelDimensionsPerTile.z; z++) { const sliceVoxelOffsetX = (z % sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.x; @@ -2007,14 +2104,38 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { texture.copyFrom(copyOptions); }; +/** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see Megatexture#destroy + */ Megatexture.prototype.isDestroyed = function () { return false; }; +/** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see Megatexture#isDestroyed + * + * @example + * megatexture = megatexture && megatexture.destroy(); + */ Megatexture.prototype.destroy = function () { - const that = this; - that.texture = that.texture && that.texture.destroy(); - return destroyObject(that); + this.texture = this.texture && this.texture.destroy(); + return destroyObject(this); }; export default VoxelTraversal; diff --git a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js index 5eaaf1f26ba..3d62e19ad39 100644 --- a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js +++ b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -90,7 +90,7 @@ describe( // need to call update until the promise is ready return pollToPromise(function () { provider.update(scene.frameState); - return provider._doneLoading(); + return provider.doneLoading(); }) .then(function () { return requestTilePromise; diff --git a/Specs/Scene/GltfVoxelProviderSpec.js b/Specs/Scene/GltfVoxelProviderSpec.js index ef9f736648f..adbf9367169 100644 --- a/Specs/Scene/GltfVoxelProviderSpec.js +++ b/Specs/Scene/GltfVoxelProviderSpec.js @@ -88,7 +88,7 @@ describe( // need to call update until the promise is ready return pollToPromise(function () { provider.update(scene.frameState); - return provider._doneLoading(); + return provider.doneLoading(); }) .then(function () { return requestTilePromise; From 52385b5aaba714a86d9377fbdc5e0740c46412e0 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Mon, 4 Apr 2022 20:21:37 -0400 Subject: [PATCH 008/679] getting non bounded ellipsoid working --- Apps/Sandcastle/gallery/Voxels.html | 115 ++- Source/Core/OrientedBoundingBox.js | 19 + Source/Scene/VoxelBoxShape.js | 14 +- Source/Scene/VoxelCylinderShape.js | 14 +- Source/Scene/VoxelEllipsoidShape.js | 1181 ++++++------------------ Source/Scene/VoxelPrimitive.js | 68 +- Source/Shaders/VoxelFS.glsl | 181 ++-- Specs/Scene/VoxelEllipsoidShapeSpec.js | 418 +++++---- 8 files changed, 749 insertions(+), 1261 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index a55ffc38e8a..db7b3216cd5 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -35,7 +35,13 @@ function startup(Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.TileMapServiceImageryProvider({ + url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), + }), + baseLayerPicker: false, + geocoder: false, + }); viewer.extend(Cesium.viewerVoxelInspectorMixin); viewer.scene.debugShowFramesPerSecond = true; let voxelPrimitive; @@ -46,21 +52,30 @@ break; } case Cesium.VoxelShapeType.ELLIPSOID: { - const west = -Cesium.Math.PI + 0.2; - const east = +Cesium.Math.PI; - const south = -Cesium.Math.PI_OVER_TWO; - const north = +Cesium.Math.PI_OVER_TWO; - const minimumHeight = -10.0; - const maximumHeight = +10.0; - this.minBounds = new Cesium.Cartesian3( + const minBounds = Cesium.VoxelShapeType.getMinBounds( + Cesium.VoxelShapeType.ELLIPSOID + ); + const maxBounds = Cesium.VoxelShapeType.getMaxBounds( + Cesium.VoxelShapeType.ELLIPSOID + ); + const west = minBounds.x; + const east = maxBounds.x; + const south = minBounds.y; + const north = maxBounds.y; + const minimumHeight = 0.0; + const maximumHeight = 2000000.0; + + this.minBounds = Cesium.Cartesian3.fromElements( west, south, - minimumHeight + minimumHeight, + new Cesium.Cartesian3() ); - this.maxBounds = new Cesium.Cartesian3( + this.maxBounds = Cesium.Cartesian3.fromElements( east, north, - maximumHeight + maximumHeight, + new Cesium.Cartesian3() ); break; } @@ -70,7 +85,7 @@ } this.shape = shape; - this.dimensions = new Cesium.Cartesian3(4, 4, 4); + this.dimensions = new Cesium.Cartesian3(8, 8, 8); // this.names = ["color", "shininess"]; // this.types = [Cesium.MetadataType.VEC4, Cesium.MetadataType.SCALAR]; // this.componentTypes = [ @@ -87,7 +102,7 @@ ProceduralSingleTileVoxelProvider.prototype.requestData = function ( options ) { - const tileLevel = options.level; + const tileLevel = options.tileLevel; const tileX = options.tileX; const tileY = options.tileY; const tileZ = options.tileZ; @@ -114,7 +129,7 @@ const lerperY = y / (dimensions.y - 1); const lerperZ = z / (dimensions.z - 1); - const h = hue + lerperX * 0.1; + const h = hue + lerperX * 0.5 - lerperY * 0.3 + lerperZ * 0.2; const s = 1.0 - lerperY * 0.2; const v = 0.5 + 2.0 * (lerperZ - 0.5) * 0.2; const color = Cesium.Color.fromHsl(h, s, v); @@ -122,17 +137,17 @@ const index = z * dimensions.y * dimensions.x + y * dimensions.x + x; - if (tileLevel === 0) { - dataColor[index * channelCount + 0] = Math.random(); - dataColor[index * channelCount + 1] = Math.random(); - dataColor[index * channelCount + 2] = Math.random(); - dataColor[index * channelCount + 3] = 1.0; - } else { - dataColor[index * channelCount + 0] = color.red; - dataColor[index * channelCount + 1] = color.green; - dataColor[index * channelCount + 2] = color.blue; - dataColor[index * channelCount + 3] = 0.75; - } + // if (tileLevel === 0) { + // dataColor[index * channelCount + 0] = Math.random(); + // dataColor[index * channelCount + 1] = Math.random(); + // dataColor[index * channelCount + 2] = Math.random(); + // dataColor[index * channelCount + 3] = 1.0; + // } else { + dataColor[index * channelCount + 0] = color.red; + dataColor[index * channelCount + 1] = color.green; + dataColor[index * channelCount + 2] = color.blue; + dataColor[index * channelCount + 3] = 0.75; + // } } } } @@ -336,6 +351,11 @@ customShader: customShader, modelMatrix: Cesium.Matrix4.fromScale( Cesium.Ellipsoid.WGS84.radii, + // Cesium.Cartesian3.fromElements( + // Cesium.Ellipsoid.WGS84.radii.x, + // Cesium.Ellipsoid.WGS84.radii.y, + // Cesium.Ellipsoid.WGS84.radii.z * 2.0 + // ), new Cesium.Matrix4() ), }) @@ -351,6 +371,8 @@ .catch(function (error) { console.log(error); }); + + return voxelPrimitive; } const customShaderColor = new Cesium.CustomShader({ @@ -376,7 +398,25 @@ const provider = new ProceduralSingleTileVoxelProvider( Cesium.VoxelShapeType.BOX ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); + primitive.readyPromise.then(function () { + viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { + duration: 0.0, + }); + // viewer.camera.position = new Cesium.Cartesian3( + // 20210315.04663869, + // 22200569.010404103, + // 16940652.047713447 + // ); + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 22489095.52149246, + 15457085.667961657, + 20334893.228182133 + ), + duration: 0.0, + }); + }); }, }, { @@ -385,7 +425,7 @@ const provider = new ProceduralMultiTileVoxelProvider( Cesium.VoxelShapeType.BOX ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); }, }, { @@ -395,7 +435,7 @@ gltf: "../../SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, { @@ -405,7 +445,7 @@ url: "../../SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, { @@ -414,7 +454,7 @@ const provider = new ProceduralSingleTileVoxelProvider( Cesium.VoxelShapeType.ELLIPSOID ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); }, }, { @@ -423,7 +463,7 @@ const provider = new ProceduralMultiTileVoxelProvider( Cesium.VoxelShapeType.ELLIPSOID ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); }, }, { @@ -433,7 +473,7 @@ gltf: "../../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, { @@ -443,7 +483,7 @@ url: "../../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, { @@ -452,7 +492,7 @@ const provider = new ProceduralSingleTileVoxelProvider( Cesium.VoxelShapeType.CYLINDER ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); }, }, { @@ -461,7 +501,7 @@ const provider = new ProceduralMultiTileVoxelProvider( Cesium.VoxelShapeType.CYLINDER ); - createPrimitive(provider, customShaderColor); + const primitive = createPrimitive(provider, customShaderColor); }, }, { @@ -471,7 +511,7 @@ gltf: "../../SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, { @@ -481,7 +521,7 @@ url: "../../SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json", }); - createPrimitive(provider, customShaderAlpha); + const primitive = createPrimitive(provider, customShaderAlpha); }, }, ]); @@ -493,6 +533,7 @@ const mousePosition = movement.position; const pickedPrimitive = scene.pick(mousePosition); console.log(pickedPrimitive); + console.log(camera.position); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); //Sandcastle_End diff --git a/Source/Core/OrientedBoundingBox.js b/Source/Core/OrientedBoundingBox.js index 50d5d679e4d..849402b023a 100644 --- a/Source/Core/OrientedBoundingBox.js +++ b/Source/Core/OrientedBoundingBox.js @@ -373,6 +373,25 @@ OrientedBoundingBox.fromRectangle = function ( maximumHeight = defaultValue(maximumHeight, 0.0); ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + if (rectangle.equals(Rectangle.MAX_VALUE)) { + if (!defined(result)) { + result = new OrientedBoundingBox(); + } + result.halfAxes = Matrix3.fromScale( + Cartesian3.add( + ellipsoid.radii, + Cartesian3.fromElements( + maximumHeight, + maximumHeight, + maximumHeight, + scratchScale + ), + scratchScale + ) + ); + return result; + } + let minX, maxX, minY, maxY, minZ, maxZ, plane; if (rectangle.width <= CesiumMath.PI) { diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index 0f7cbec3b08..e133f03881b 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -233,7 +233,7 @@ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( * Computes an approximate step size for raymarching the root tile of a voxel grid. * The update function must be called before calling this function. * - * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. + * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. * @returns {Number} The step size. */ VoxelBoxShape.prototype.computeApproximateStepSize = function (dimensions) { @@ -267,12 +267,12 @@ VoxelBoxShape.DefaultMaxBounds = new Cartesian3(+1.0, +1.0, +1.0); * * @function * - * @param {Cartesian3} minimumX The minimumX. - * @param {Cartesian3} maximumX The maximumX. - * @param {Cartesian3} minimumY The minimumY. - * @param {Cartesian3} maximumY The maximumY. - * @param {Cartesian3} minimumZ The minimumZ. - * @param {Cartesian3} maximumZ The maximumZ. + * @param {Number} minimumX The minimumX. + * @param {Number} maximumX The maximumX. + * @param {Number} minimumY The minimumY. + * @param {Number} maximumY The maximumY. + * @param {Number} minimumZ The minimumZ. + * @param {Number} maximumZ The maximumZ. * @param {Matrix4} matrix The matrix to transform the points. * @param {OrientedBoundingBox} result The object onto which to store the result. * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index bf9f0a748ce..520e6fc76d6 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -380,12 +380,16 @@ const scratchScaleRatio = new Cartesian3(); * Computes an approximate step size for raymarching the root tile of a voxel grid. * The update function must be called before calling this function. * - * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. + * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. * @returns {Number} The step size. */ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( - voxelDimensions + dimensions ) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("dimensions", dimensions); + //>>includeEnd('debug'); + const rootTransform = this.shapeTransform; const minRadius = this._minimumRadius; @@ -395,9 +399,9 @@ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( const minAngle = this._minimumAngle; const maxAngle = this._maximumAngle; - const lerpRadius = 1.0 - 1.0 / voxelDimensions.x; - const lerpHeight = 1.0 - 1.0 / voxelDimensions.y; - const lerpAngle = 1.0 - 1.0 / voxelDimensions.z; + const lerpRadius = 1.0 - 1.0 / dimensions.x; + const lerpHeight = 1.0 - 1.0 / dimensions.y; + const lerpAngle = 1.0 - 1.0 / dimensions.z; // Compare the size of an outermost cylinder voxel to the total cylinder const voxelMinimumRadius = CesiumMath.lerp(minRadius, maxRadius, lerpRadius); diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index ec374131da2..cbe85683d76 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -1,20 +1,15 @@ import BoundingSphere from "../Core/BoundingSphere.js"; -import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; -import defaultValue from "../Core/defaultValue.js"; -import defined from "../Core/defined.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import CesiumMath from "../Core/Math.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; -import Ray from "../Core/Ray.js"; import Rectangle from "../Core/Rectangle.js"; -import VoxelShapeType from "./VoxelShapeType.js"; /** - * A {@link VoxelShape} for an ellipsoid. + * An ellipsoid {@link VoxelShape}. * * @alias VoxelEllipsoidShape * @constructor @@ -26,394 +21,214 @@ import VoxelShapeType from "./VoxelShapeType.js"; * * @private */ -function VoxelEllipsoidShape(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - this._ellipsoid = Ellipsoid.clone( - defaultValue(options.ellipsoid, Ellipsoid.WGS84) - ); - this._rectangle = Rectangle.clone( - defaultValue(options.rectangle, Rectangle.MAX_VALUE) - ); - this._minimumHeight = defaultValue(options.minimumHeight, 0.0); - this._maximumHeight = defaultValue(options.maximumHeight, 1.0); - this._translation = Cartesian3.clone( - defaultValue(options.translation, Cartesian3.ZERO) - ); - this._scale = Cartesian3.clone(defaultValue(options.scale, Cartesian3.ONE)); - this._rotation = Matrix3.clone( - defaultValue(options.rotation, Matrix3.IDENTITY) - ); +function VoxelEllipsoidShape() { + /** + * An oriented bounding box containing the bounded shape. + * The update function must be called before accessing this value. + * @type {OrientedBoundingBox} + * @readonly + */ + this.orientedBoundingBox = new OrientedBoundingBox(); - this._firstUpdate = true; - this._ellipsoidOld = Ellipsoid.clone(this._ellipsoid); - this._rectangleOld = Rectangle.clone(this._rectangle); - this._minimumHeightOld = this._minimumHeight; - this._maximumHeightOld = this._maximumHeight; - this._translationOld = Cartesian3.clone(this._translation); - this._scaleOld = Cartesian3.clone(this._scale); - this._rotationOld = Matrix3.clone(this._rotation); - - this._boundTransform = Matrix4.clone(Matrix4.IDENTITY); - this._shapeTransform = Matrix4.clone(Matrix4.IDENTITY); - this._orientedBoundingBox = new OrientedBoundingBox(); - this._boundingSphere = new BoundingSphere(); - - this._ellipsoidHeightDifferenceUv = 1.0; - this._ellipsoidOuterRadiiLocal = new Cartesian3(); - this._ellipsoidLongitudeBounds = new Cartesian3(); - this._ellipsoidLatitudeBounds = new Cartesian3(); - - this._type = VoxelShapeType.ELLIPSOID; - - this._phiMin = undefined; - this._phiMax = undefined; - this._thetaMin = undefined; - this._thetaMax = undefined; - setThetaAndPhiExtrema(this); -} + /** + * A bounding sphere containing the bounded shape. + * The update function must be called before accessing this value. + * @type {BoundingSphere} + * @readonly + */ + this.boundingSphere = new BoundingSphere(); -function setThetaAndPhiExtrema(that) { - const rectangle = that.rectangle; - // Converting from cartographic lat, lon, height to spherical theta, phi, and radius for math - - // phi is the angle with the x axis in the counter clockwise direction. It is like - // longitude, but when it gets halfway around the globe, instead of going to negative - // pi it continues to positive 2 pi. [0, 2pi] - that._phiMin = rectangle.west; - if (rectangle.west < 0) { - // from [-pi, pi] to [0, 2pi] - that._phiMin = CesiumMath.TWO_PI + rectangle.west; - } - that._phiMax = that._phiMin + rectangle.width; - if (that._phiMax > CesiumMath.TWO_PI) { - that._phiMax -= CesiumMath.TWO_PI; - } + /** + * A transformation matrix containing the bounded shape. + * The update function must be called before accessing this value. + * @type {Matrix4} + * @readonly + */ + this.boundTransform = new Matrix4(); - // theta is angle from z axis to point. It is like latitude except zero is the north pole - // and it increases as it points more and more south. - // From [-pi/2, pi/2] centered on equator to [0, pi] from z axis. This swaps min/max - that._thetaMin = CesiumMath.PI_OVER_TWO - rectangle.north; - that._thetaMax = that._thetaMin + rectangle.height; -} + /** + * A transformation matrix containing the shape, ignoring the bounds. + * The update function must be called before accessing this value. + * @type {Matrix4} + * @readonly + */ + this.shapeTransform = new Matrix4(); -Object.defineProperties(VoxelEllipsoidShape.prototype, { /** - * Gets or sets the ellipsoid. - * @memberof VoxelEllipsoidShape.prototype - * @type {Ellipsoid} + * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. + * The update function must be called before accessing this value. + * @type {Boolean} + * @readonly */ - ellipsoid: { - get: function () { - return this._ellipsoid; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("ellipsoid", value); - //>>includeEnd('debug'); - - this._ellipsoid = Ellipsoid.clone(value, this._translation); - }, - }, + this.isVisible = false; + /** - * Gets or sets the rectangle relative to the ellipsoid. - * @memberof VoxelEllipsoidShape.prototype * @type {Rectangle} */ - rectangle: { - get: function () { - return this._rectangle; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("rectangle", value); - //>>includeEnd('debug'); - - this._rectangle = Rectangle.clone(value, this._rectangle); - setThetaAndPhiExtrema(this); - }, - }, + this._rectangle = new Rectangle(); + /** - * Gets or sets the minimum height relative to the ellipsoid surface. - * @memberof VoxelEllipsoidShape.prototype * @type {Number} + * @private */ - minimumHeight: { - get: function () { - return this._minimumHeight; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("minimumHeight", value); - //>>includeEnd('debug'); - - this._minimumHeight = value; - }, - }, + this._minimumHeight = VoxelEllipsoidShape.DefaultMinBounds.z; + /** - * Gets or sets the maximum height relative to the ellipsoid surface. - * @memberof VoxelEllipsoidShape.prototype * @type {Number} + * @private */ - maximumHeight: { - get: function () { - return this._maximumHeight; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("maximumHeight", value); - //>>includeEnd('debug'); - - this._maximumHeight = value; - }, - }, + this._maximumHeight = VoxelEllipsoidShape.DefaultMaxBounds.z; + /** - * Gets or sets the translation. - * @memberof VoxelEllipsoidShape.prototype - * @type {Cartesian3} + * @type {Ellipsoid} + * @private */ - translation: { - get: function () { - return this._translation; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("translation", value); - //>>includeEnd('debug'); - - this._translation = Cartesian3.clone(value, this._translation); - }, - }, + this._ellipsoid = new Ellipsoid(); + /** - * Gets or sets the scale. - * @memberof VoxelEllipsoidShape.prototype * @type {Cartesian3} */ - scale: { - get: function () { - return this._scale; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("scale", value); - //>>includeEnd('debug'); - - this._scale = Cartesian3.clone(value, this._scale); - }, - }, - /** - * Gets or sets the rotation. - * @memberof VoxelEllipsoidShape.prototype - * @type {Matrix3} - */ - rotation: { - get: function () { - return this._rotation; - }, - set: function (value) { - //>>includeStart('debug', pragmas.debug); - Check.defined("rotation", value); - //>>includeEnd('debug'); - - this._rotation = Matrix3.clone(value, this._rotation); - }, - }, - /** - * Gets the bounding sphere. - * @memberof VoxelEllipsoidShape.prototype - * @type {BoundingSphere} - * @readonly - */ - boundingSphere: { - get: function () { - if (isDirty(this)) { - computeTransforms(this); - } - return this._boundingSphere; - }, - }, + this._translation = new Cartesian3(); + /** - * Gets the oriented bounding box. - * @memberof VoxelEllipsoidShape.prototype - * @type {OrientedBoundingBox} - * @readonly + * @type {Matrix3 */ - orientedBoundingBox: { - get: function () { - if (isDirty(this)) { - computeTransforms(this); - } - return this._orientedBoundingBox; - }, - }, -}); - -VoxelEllipsoidShape.clone = function (shape, result) { - if (!defined(shape)) { - return undefined; - } - - if (!defined(result)) { - result = new VoxelEllipsoidShape(); - } - - result._minimumHeight = shape._minimumHeight; - result._maximumHeight = shape._maximumHeight; - result._ellipsoid = shape._ellipsoid; - result._rectangle = shape._rectangle; - - result._translation = Cartesian3.clone(shape._translation); - result._scale = Cartesian3.clone(shape._scale); - result._rotation = Matrix3.clone(shape._rotation); - - result._firstUpdate = shape._firstUpdate; - - result._minimumHeightOld = shape._minimumHeightOld; - result._maximumHeightOld = shape._maximumHeightOld; - result._ellipsoidOld = shape._ellipsoidOld; - result._rectangleOld = shape._rectangleOld; - result._translationOld = Cartesian3.clone(shape._translationOld); - result._scaleOld = Cartesian3.clone(shape._scaleOld); - result._rotationOld = Matrix3.clone(shape._rotationOld); - - result._boundTransform = Matrix4.clone(shape._boundTransform); - result._shapeTransform = Matrix4.clone(shape._shapeTransform); - result._orientedBoundingBox = OrientedBoundingBox.clone( - shape._orientedBoundingBox - ); - result._boundingSphere = BoundingSphere.clone(shape._boundingSphere); - - result._type = shape._type; + this._rotation = new Matrix3(); +} - return result; -}; +/** + * @type {Cartesian3} + * @private + */ +VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( + -CesiumMath.PI, + -CesiumMath.PI_OVER_TWO, + 0.0 +); -VoxelEllipsoidShape.prototype.clone = function (result) { - return VoxelEllipsoidShape.clone(this, result); -}; +/** + * @type {Cartesian3} + * @private + */ +VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( + +CesiumMath.PI, + +CesiumMath.PI_OVER_TWO, + 1.0 +); const scratchScale = new Cartesian3(); -const scratchOrientedBoundingBox = new OrientedBoundingBox(); -const scratchRectangle = new Rectangle(); +const scratchFullScale = new Cartesian3(); +const scratchRotationScale = new Matrix3(); -function isDirty(that) { - const dirtyEllipsoid = !that._ellipsoid.equals(that._ellipsoidOld); - const dirtyRectangle = !Rectangle.equals(that._rectangle, that._rectangleOld); - const dirtyMinimumHeight = that._minimumHeight !== that._minimumHeightOld; - const dirtyMaximumHeight = that._maximumHeight !== that._maximumHeightOld; - const dirtyTranslation = !Cartesian3.equals( - that._translation, - that._translationOld - ); - const dirtyScale = !Cartesian3.equals(that._scale, that._scaleOld); - const dirtyRotation = !Matrix3.equals(that._rotation, that._rotationOld); - - return ( - that._firstUpdate || - dirtyEllipsoid || - dirtyRectangle || - dirtyMinimumHeight || - dirtyMaximumHeight || - dirtyTranslation || - dirtyScale || - dirtyRotation +/** + * Update the shape's state. + * + * @param {Matrix4} modelMatrix The model matrix. + * @param {Cartesian3} minBounds The minimum bounds. + * @param {Cartesian3} maxBounds The maximum bounds. + */ +VoxelEllipsoidShape.prototype.update = function ( + modelMatrix, + minBounds, + maxBounds +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("modelMatrix", modelMatrix); + Check.typeOf.object("minBounds", minBounds); + Check.typeOf.object("maxBounds", maxBounds); + //>>includeEnd('debug'); + + // Don't let the scale be 0, it will screw up a bunch of math + const scaleEps = CesiumMath.EPSILON8; + const scale = Matrix4.getScale(modelMatrix, scratchScale); + if (Math.abs(scale.x) < scaleEps) { + scale.x = CesiumMath.signNotZero(scale.x) * scaleEps; + } + if (Math.abs(scale.y) < scaleEps) { + scale.y = CesiumMath.signNotZero(scale.y) * scaleEps; + } + if (Math.abs(scale.z) < scaleEps) { + scale.z = CesiumMath.signNotZero(scale.z) * scaleEps; + } + + this._rectangle = Rectangle.fromRadians( + minBounds.x, + minBounds.y, + maxBounds.x, + maxBounds.y ); -} -function computeTransforms(that) { - const ellipsoid = that._ellipsoid; - const minimumHeight = that._minimumHeight; - const maximumHeight = that._maximumHeight; - const rectangle = that._rectangle; - - const radii = ellipsoid.radii; - const scaleX = 2.0 * (radii.x + maximumHeight); - const scaleY = 2.0 * (radii.y + maximumHeight); - const scaleZ = 2.0 * (radii.z + maximumHeight); - const scale = Cartesian3.fromElements(scaleX, scaleY, scaleZ, scratchScale); - - that._shapeTransform = Matrix4.fromScale(scale, that._shapeTransform); - - if (rectangle.equals(Rectangle.MAX_VALUE)) { - that._boundTransform = Matrix4.clone( - that._shapeTransform, - that._boundTransform - ); - } else { - // Convert the obb to a model matrix - const obb = OrientedBoundingBox.fromRectangle( - rectangle, - minimumHeight, - maximumHeight, - ellipsoid, - scratchOrientedBoundingBox - ); - that._boundTransform = OrientedBoundingBox.computeTransformation( - obb, - that._boundTransform - ); + const minHeight = minBounds.z; + const maxHeight = maxBounds.z; + + // Exit early if the bounds make the shape invisible. + // Note that west may be greater than east when crossing the 180th meridian. + const rectangle = this._rectangle; + if (rectangle.south > rectangle.north || minHeight > maxHeight) { + this.isVisible = false; + return; } - that._orientedBoundingBox = OrientedBoundingBox.fromTransformation( - that._boundTransform, - that._orientedBoundingBox + this._translation = Matrix4.getTranslation(modelMatrix, this._translation); + this._rotation = Matrix4.getRotation(modelMatrix, this._rotation); + this._ellipsoid = Ellipsoid.fromCartesian3(scale, this._ellipsoid); + + const fullScale = Cartesian3.add( + scale, + Cartesian3.fromElements(maxHeight, maxHeight, maxHeight, scratchFullScale), + scratchFullScale ); - that._boundingSphere = BoundingSphere.fromTransformation( - that._boundTransform, - that._boundingSphere + const rotationScale = Matrix3.setScale( + this._rotation, + fullScale, + scratchRotationScale ); - - const boundedWest = rectangle.west; - const boundedEast = rectangle.east; - const boundedSouth = rectangle.south; - const boundedNorth = rectangle.north; - const longitudeRange = rectangle.width; - const latitudeRange = rectangle.height; - - const ellipsoidRadii = ellipsoid.radii; - const ellipsoidMaximumRadius = ellipsoid.maximumRadius; - that._ellipsoidHeightDifferenceUv = - 1.0 - - (ellipsoidMaximumRadius + minimumHeight) / - (ellipsoidMaximumRadius + maximumHeight); - that._ellipsoidOuterRadiiLocal = Cartesian3.divideByScalar( - ellipsoidRadii, - ellipsoidMaximumRadius, - that._ellipsoidOuterRadiiLocal + this.shapeTransform = Matrix4.fromRotationTranslation( + rotationScale, + this._translation, + this.shapeTransform ); - that._ellipsoidLongitudeBounds = Cartesian3.fromElements( - boundedWest, - boundedEast, - longitudeRange, - that._ellipsoidLongitudeBounds + + this.orientedBoundingBox = getEllipsoidChunkObb( + rectangle.west, + rectangle.east, + rectangle.south, + rectangle.north, + minHeight, + maxHeight, + this._ellipsoid, + this._translation, + this._rotation, + this.orientedBoundingBox ); - that._ellipsoidLatitudeBounds = Cartesian3.fromElements( - boundedSouth, - boundedNorth, - latitudeRange, - that._ellipsoidLatitudeBounds + + this.boundTransform = Matrix4.fromRotationTranslation( + this.orientedBoundingBox.halfAxes, + this.orientedBoundingBox.center, + this.boundTransform ); -} -VoxelEllipsoidShape.prototype.update = function () { - if (isDirty(this)) { - computeTransforms(this); - this._firstUpdate = false; - this._ellipsoidOld = Ellipsoid.clone(this._ellipsoid, this._ellipsoidOld); - this._rectangleOld = Rectangle.clone(this._rectangle, this._rectangleOld); - this._minimumHeightOld = this._minimumHeight; - this._maximumHeightOld = this._maximumHeight; - this._translationOld = Cartesian3.clone( - this._translation, - this._translationOld - ); - this._scaleOld = Cartesian3.clone(this._scale, this._scaleOld); - this._rotationOld = Matrix3.clone(this._rotation, this._rotationOld); - return true; - } + this.boundingSphere = BoundingSphere.fromOrientedBoundingBox( + this.orientedBoundingBox, + this.boundingSphere + ); - return false; + this.isVisible = true; }; +const scratchRectangle = new Rectangle(); + +/** + * Computes an oriented bounding box for a specified tile. + * The update function must be called before calling this function. + * + * @param {Number} tileLevel The tile's level. + * @param {Number} tileX The tile's x coordinate. + * @param {Number} tileY The tile's y coordinate. + * @param {Number} tileZ The tile's z coordinate. + * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile + * @returns {OrientedBoundingBox} The oriented bounding box. + */ VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( tileLevel, tileX, @@ -421,47 +236,71 @@ VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( tileZ, result ) { - const ellipsoid = this._ellipsoid; - const rectangle = this._rectangle; - const minimumHeight = this._minimumHeight; - const maximumHeight = this._maximumHeight; - - const sizeAtLevel = 1.0 / Math.pow(2, tileLevel); - const tileMinimumHeight = CesiumMath.lerp( - minimumHeight, - maximumHeight, - tileZ * sizeAtLevel - ); - const tileMaximumHeight = CesiumMath.lerp( - minimumHeight, - maximumHeight, - (tileZ + 1) * sizeAtLevel - ); - + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("tileLevel", tileLevel); + Check.typeOf.number("tileX", tileX); + Check.typeOf.number("tileY", tileY); + Check.typeOf.number("tileZ", tileZ); + Check.typeOf.object("result", result); + //>>includeEnd('debug'); + + const sizeAtLevel = 1.0 / Math.pow(2.0, tileLevel); const westLerp = tileX * sizeAtLevel; const eastLerp = (tileX + 1) * sizeAtLevel; const southLerp = tileY * sizeAtLevel; const northLerp = (tileY + 1) * sizeAtLevel; - const tileRectangle = Rectangle.subsection( - rectangle, + const minHeightLerp = tileZ * sizeAtLevel; + const maxHeightLerp = (tileZ + 1) * sizeAtLevel; + + const rectangle = Rectangle.subsection( + this._rectangle, westLerp, southLerp, eastLerp, northLerp, scratchRectangle ); - return OrientedBoundingBox.fromRectangle( - tileRectangle, - tileMinimumHeight, - tileMaximumHeight, - ellipsoid, + + const minHeight = CesiumMath.lerp( + this._minimumHeight, + this._maximumHeight, + minHeightLerp + ); + + const maxHeight = CesiumMath.lerp( + this._minimumHeight, + this._maximumHeight, + maxHeightLerp + ); + + return getEllipsoidChunkObb( + rectangle.west, + rectangle.east, + rectangle.south, + rectangle.north, + minHeight, + maxHeight, + this._ellipsoid, + this._translation, + this._rotation, result ); }; +/** + * Computes an approximate step size for raymarching the root tile of a voxel grid. + * The update function must be called before calling this function. + * + * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. + * @returns {Number} The step size. + */ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( - voxelDimensions + dimensions ) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("dimensions", dimensions); + //>>includeEnd('debug'); + const ellipsoid = this._ellipsoid; const ellipsoidMaximumRadius = ellipsoid.maximumRadius; const minimumHeight = this._minimumHeight; @@ -469,539 +308,16 @@ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( const shellToEllipsoidRatio = (maximumHeight - minimumHeight) / (ellipsoidMaximumRadius + maximumHeight); - const stepSize = (0.5 * shellToEllipsoidRatio) / voxelDimensions.z; + const stepSize = (0.5 * shellToEllipsoidRatio) / dimensions.z; return stepSize; }; -const scratchSphericalMinima = new Cartesian3(); -const scratchSphericalMaxima = new Cartesian3(); -VoxelEllipsoidShape.prototype.localPointInsideShape = function ( - point, - clippingMinimum, - clippingMaximum -) { - const pointUv = Cartesian3.multiplyByScalar(point, 2.0, new Cartesian3()); - const pointEllipsoidSpace = Cartesian3.multiplyComponents( - pointUv, - this._ellipsoidOuterRadiiLocal, - new Cartesian3() - ); // now we work as if the ellipsoid is a sphere - - getSphericalExtremaFromClippingExtrema( - this, - clippingMinimum, - clippingMaximum, - scratchSphericalMinima, - scratchSphericalMaxima - ); - return pointIsWithinClippingParameters( - pointEllipsoidSpace, - scratchSphericalMinima.z, - scratchSphericalMaxima.z, - scratchSphericalMinima.y, - scratchSphericalMaxima.y, - scratchSphericalMinima.x, - scratchSphericalMaxima.x, - this._ellipsoidLongitudeBounds - ); -}; - -VoxelEllipsoidShape.prototype.transformFromLocalToShapeSpace = function ( - localCartesian, - result -) { - const pos3D = new Cartesian3(); - pos3D.x = localCartesian.x * 2.0; - pos3D.y = localCartesian.y * 2.0; - pos3D.z = localCartesian.z * 2.0; - const ellipsoidRadiiLocal = this._ellipsoidOuterRadiiLocal; - Cartesian3.multiplyComponents(pos3D, ellipsoidRadiiLocal, pos3D); - - const cartographic = Ellipsoid.fromCartesian3( - Cartesian3.fromElements(1.0, 1.0, 1.0) - ).cartesianToCartographic(pos3D); - let longitudeMin = this._ellipsoidLongitudeBounds.x; - const longitudeMax = this._ellipsoidLongitudeBounds.y; - const longitudeWidth = this._ellipsoidLongitudeBounds.z; - - const latitudeMin = this._ellipsoidLatitudeBounds.x; - const latitudeWidth = this._ellipsoidLatitudeBounds.z; - - if (longitudeMin > longitudeMax) { - longitudeMin -= CesiumMath.TWO_PI; - if (cartographic.longitude > longitudeMax) { - cartographic.longitude -= CesiumMath.TWO_PI; - } - } - - // normalize to be within min and max of ellipsoid slice - const distMin = -this._ellipsoidHeightDifferenceUv; - cartographic.longitude = - (cartographic.longitude - longitudeMin) / longitudeWidth; - cartographic.latitude = (cartographic.latitude - latitudeMin) / latitudeWidth; - cartographic.height = (cartographic.height - distMin) / -distMin; - result.x = cartographic.longitude; - result.y = cartographic.latitude; - result.z = cartographic.height; - return result; -}; - -const scratchIntersectionTs = new Cartesian2(); -VoxelEllipsoidShape.prototype.intersectRay = function ( - ray, - clippingMinimum, - clippingMaximum -) { - if (!defined(clippingMinimum)) { - clippingMinimum = Cartesian3.ZERO; - } - if (!defined(clippingMaximum)) { - clippingMinimum = Cartesian3.fromElements(1.0, 1.0, 1.0); - } - - const epsilon = CesiumMath.EPSILON6; - - getSphericalExtremaFromClippingExtrema( - this, - clippingMinimum, - clippingMaximum, - scratchSphericalMinima, - scratchSphericalMaxima - ); - const phiMinClipping = scratchSphericalMinima.x; - const phiMaxClipping = scratchSphericalMaxima.x; - const thetaMinClipping = scratchSphericalMinima.y; - const thetaMaxClipping = scratchSphericalMaxima.y; - const radiusMinClipping = scratchSphericalMinima.z; - const radiusMaxClipping = scratchSphericalMaxima.z; - - // convert to ellipsoid space. This simplifies analytical solutions since in ellipsoid space we are working with a sphere. - const ellipsoidRadiiLocal = this._ellipsoidOuterRadiiLocal; - const origin = Cartesian3.multiplyComponents( - ray.origin, - ellipsoidRadiiLocal, - new Cartesian3() - ); - let direction = Cartesian3.multiplyComponents( - ray.direction, - ellipsoidRadiiLocal, - new Cartesian3() - ); - direction = Cartesian3.normalize(direction, direction); - const rayEllipsoidSpace = new Ray(origin, direction); - - const a = Cartesian3.dot(direction, direction); - const b = Cartesian3.dot(origin, direction); - const originDot = Cartesian3.dot(origin, origin); - - let returnT = Number.MAX_VALUE; - - const tsOuter = findTsAtRadus( - radiusMaxClipping, - a, - b, - originDot, - scratchIntersectionTs - ); - - const ellipsoidLongitudeBounds = this._ellipsoidLongitudeBounds; - if ( - tsOuter.x >= 0.0 && - tIsWithinClippingPlanes( - tsOuter.x, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = tsOuter.x; - } - const tsInner = findTsAtRadus( - radiusMinClipping, - a, - b, - originDot, - scratchIntersectionTs - ); - if ( - tsInner.y >= 0.0 && - tIsWithinClippingPlanes( - tsInner.y, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tsInner.y); - } - - const tPhiMinClipping = findTAtPhi(phiMinClipping, rayEllipsoidSpace); - if ( - tPhiMinClipping >= 0 && - tIsWithinClippingPlanes( - tPhiMinClipping, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tPhiMinClipping); - } - const tPhiMaxClipping = findTAtPhi(phiMaxClipping, rayEllipsoidSpace); - if ( - tPhiMinClipping >= 0 && - tIsWithinClippingPlanes( - tPhiMaxClipping, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tPhiMaxClipping); - } - - if (phiMinClipping < phiMaxClipping) { - const tPhiMinAbsolute = findTAtPhi(this._phiMin, rayEllipsoidSpace); - if ( - tPhiMinClipping >= 0 && - tIsWithinClippingPlanes( - tPhiMinAbsolute, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tPhiMinAbsolute); - } - const tPhiMaxAbsolute = findTAtPhi(this._phiMax, rayEllipsoidSpace); - if ( - tPhiMinAbsolute >= 0 && - tIsWithinClippingPlanes( - tPhiMaxAbsolute, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tPhiMaxAbsolute); - } - } - - const tsThetaMin = findTAtTheta( - thetaMinClipping, - rayEllipsoidSpace, - scratchIntersectionTs - ); - if ( - tsThetaMin.x >= 0.0 && - tIsWithinClippingPlanes( - tsThetaMin.x, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tsThetaMin.x); - } - if ( - tsThetaMin.y >= 0.0 && - tIsWithinClippingPlanes( - tsThetaMin.y, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tsThetaMin.y); - } - const tsThetaMax = findTAtTheta( - thetaMaxClipping, - rayEllipsoidSpace, - scratchIntersectionTs - ); - if ( - tsThetaMax.x >= 0.0 && - tIsWithinClippingPlanes( - tsThetaMax.x, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tsThetaMax.x); - } - if ( - tsThetaMax.y >= 0.0 && - tIsWithinClippingPlanes( - tsThetaMax.y, - rayEllipsoidSpace, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ) - ) { - returnT = Math.min(returnT, tsThetaMax.y); - } - if (returnT === Number.MAX_VALUE) { - return -1.0; - } - - const intersection = Ray.getPoint(rayEllipsoidSpace, returnT); - // transfor point to non ellipsoid space - Cartesian3.divideComponents(intersection, ellipsoidRadiiLocal, intersection); - // get t for non ellipsoid space - let t; - if (ray.direction.x !== 0) { - t = (intersection.x - ray.origin.x) / ray.direction.x; - } else if (ray.direction.y !== 0) { - t = (intersection.y - ray.origin.y) / ray.direction.y; - } else if (ray.direction.z !== 0) { - t = (intersection.z - ray.origin.z) / ray.direction.z; - } - return t + epsilon; -}; - -function pointIsWithinClippingParameters( - point, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds -) { - const radius = Math.sqrt(Cartesian3.dot(point, point)); - let phi = Math.atan2(point.y, point.x); - if (phi < 0.0) { - phi += CesiumMath.TWO_PI; - } - let theta = Math.atan( - Math.abs(Math.sqrt(point.x * point.x + point.y * point.y) / point.z) - ); - if (point.z < 0) { - theta = CesiumMath.PI - theta; - } - - let absolutePhiMin = ellipsoidLongitudeBounds.x; - if (absolutePhiMin < 0.0) { - absolutePhiMin += CesiumMath.TWO_PI; - } - let absolutePhiMax = ellipsoidLongitudeBounds.y; - if (absolutePhiMax < 0.0) { - absolutePhiMax += CesiumMath.TWO_PI; - } - let withinAbsolutePhiBounds = phi >= absolutePhiMin && phi <= absolutePhiMax; - if (absolutePhiMin >= absolutePhiMax) { - withinAbsolutePhiBounds = phi >= absolutePhiMin || phi <= absolutePhiMax; - } - let withinPhiRange = phi >= phiMinClipping && phi <= phiMaxClipping; - if (phiMinClipping >= phiMaxClipping) { - // wrap around zero - withinPhiRange = phi >= phiMinClipping || phi <= phiMaxClipping; - } - return ( - radius >= radiusMinClipping && - radius <= radiusMaxClipping && - withinPhiRange && - withinAbsolutePhiBounds && - theta >= thetaMinClipping && - theta <= thetaMaxClipping - ); -} - -/** - * Takes the clipping minima and maxima and converts them to spherical minima and maxima - * (phi in radians, theta in radians, radius) for the ellipsoid - * @param {VoxelEllipsoidShape} that - * @param {Cartesian3} clippingMinimum The minimum values for shape parameters that the shader renders. Shape space [0, 1]. - * @param {Cartesian3} clippingMaximum The minimum values for shape parameters that the shader renders. Shape space [0, 1]. - * @param {Cartesian3} sphericalMinimum Result parameter. The minimum values in unit sphere space. (phi [0, 2pi], theta [0, pi], radius [0, inf]). - * @param {Cartesian3} sphericalMaximum Result parameter. The maximum values in unit sphere space. (phi [0, 2pi], theta [0, pi], radius [0, inf]). - * @private - */ -function getSphericalExtremaFromClippingExtrema( - that, - clippingMinimum, - clippingMaximum, - sphericalMinimum, - sphericalMaximum -) { - const rectangle = that._rectangle; - const phiWidth = rectangle.width; - let phiMin = that._phiMin + phiWidth * clippingMinimum.x; - if (phiMin >= CesiumMath.TWO_PI) { - // wrap around zero - phiMin -= CesiumMath.TWO_PI; - } - sphericalMinimum.x = phiMin; - let phiMax = that._phiMin + phiWidth * clippingMaximum.x; - if (phiMax >= CesiumMath.TWO_PI) { - // wrap around zero - phiMax -= CesiumMath.TWO_PI; - } - sphericalMaximum.x = phiMax; - - const thetaWidth = rectangle.height; - sphericalMinimum.y = that._thetaMin + thetaWidth * (1 - clippingMaximum.y); - sphericalMaximum.y = that._thetaMin + thetaWidth * (1 - clippingMinimum.y); - - const radiusWidth = that._ellipsoidHeightDifferenceUv; - sphericalMinimum.z = 1.0 + (clippingMinimum.z - 1.0) * radiusWidth; - sphericalMaximum.z = 1.0 + (clippingMaximum.z - 1.0) * radiusWidth; -} - -/** - * Get the ray parameter t of the intersection with a sphere of given radius - * @param {Number} radius The radius of the sphere you are intersecting with - * @param {Number} a The first coefficient of the quadratic equation that we are solving. This should be ray direction dot ray direction. - * @param {Number} b The second coefficient of the quadratic equation that we are solving. This should be ray direction dot ray origin. - * @param {Number} c The third coefficient of the quadratic equation that we are solving. This should be ray origin dot ray origin. - * @param {Cartesian2} tsAtRadius Return parameter. The first intersection will be stored in x while the second will be stored in y. - * @returns {Cartesian2} The return parameter tsAtRadius with the ts for the intersections in order first to second in x and y. - * @private - */ -function findTsAtRadus(radius, a, b, c, tsAtRadius) { - // no 2 in quadratic formula because it cancels out by taking 2 out of b - c -= radius * radius; - let discrim = b * b - a * c; - tsAtRadius.x = -1.0; - tsAtRadius.y = -1.0; - if (discrim >= 0.0) { - discrim = Math.sqrt(discrim); - tsAtRadius.x = (-b - discrim) / a; - tsAtRadius.y = (-b + discrim) / a; - } - return tsAtRadius; -} - -const epsilon = CesiumMath.EPSILON6; -function tIsWithinClippingPlanes( - t, - ray, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds -) { - const intersectionPoint = Ray.getPoint(ray, t + epsilon); - return pointIsWithinClippingParameters( - intersectionPoint, - radiusMinClipping, - radiusMaxClipping, - thetaMinClipping, - thetaMaxClipping, - phiMinClipping, - phiMaxClipping, - ellipsoidLongitudeBounds - ); -} - -/** - * Finds the ray parameter t for the intersection with a plane created by a constant phi and a ray - * @param {Number} phi The angle that your want to intersect with. [0, 2pi] - * @param {Ray} ray The ray you are intersecting - * @returns {Number} The ray parameter that of the intersection of the ray and the angle phi - * @private - */ -function findTAtPhi(phi, ray) { - // tan(phi) = y/x, solve for t - const tanPhi = Math.tan(phi); - const origin = ray.origin; - const numerator = tanPhi * origin.x - origin.y; - const direction = ray.direction; - const denominator = direction.y - tanPhi * direction.x; - return numerator / denominator; -} - -/** - * Finds the ray parameters t for the intersections with a ray and the cone created by a constant theta angle - * @param {Number} theta The theta angle that you want to intersect with. [0, pi] - * @param {Ray} ray The ray you are intersecting - * @param {Cartesian2} returnTs Return parameter. The first intersection will be stored in x while the second will be stored in y. - * @returns {Cartesian2} The return parameter tsAtRadius with the ts for the intersections in order first to second in x and y. - * @private - */ -function findTAtTheta(theta, ray, returnTs) { - const d = ray.direction; - const o = ray.origin; - if (theta === CesiumMath.PI_OVER_TWO) { - // intersect with z = 0 - const intersectionT = -o.z / d.z; - returnTs.x = intersectionT; - returnTs.y = intersectionT; - } else { - // tan(theta) = sqrt(x^2 + y^2) / z, solve for t - const tanTheta = Math.tan(theta); - const tan2Theta = tanTheta * tanTheta; - const a = d.x * d.x + d.y * d.y - tan2Theta * d.z * d.z; - const b = o.x * d.x + o.y * d.y - o.z * d.z * tan2Theta; - const c = o.x * o.x + o.y * o.y - o.z * o.z * tan2Theta; - let discrim = b * b - a * c; - if (discrim >= 0.0) { - discrim = Math.sqrt(discrim); - returnTs.x = (-b - discrim) / a; - returnTs.y = (-b + discrim) / a; - } - } - return returnTs; -} - /** + * Defines the minimum bounds of the shape. Corresponds to minimum longitude, latitude, height. + * * @type {Cartesian3} - * @private + * @constant + * @readonly */ VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( -CesiumMath.PI, @@ -1010,8 +326,11 @@ VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( ); /** + * Defines the maximum bounds of the shape. Corresponds to maximum longitude, latitude, height. + * * @type {Cartesian3} - * @private + * @constant + * @readonly */ VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( +CesiumMath.PI, @@ -1019,4 +338,50 @@ VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( 1.0 ); +/** + * Computes an {@link OrientedBoundingBox} for a subregion of the shape. + * + * @function + * + * @param {Number} west The minimumX. + * @param {Number} east The maximumX. + * @param {Number} south The minimumY. + * @param {Number} north The maximumY. + * @param {Number} minHeight The minimumZ. + * @param {Number} maxHeight The maximumZ. + * @param {Ellipsoid} ellipsoid The ellipsoid. + * @param {Matrix4} matrix The matrix to transform the points. + * @param {OrientedBoundingBox} result The object onto which to store the result. + * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. + * + * @private + */ +function getEllipsoidChunkObb( + west, + east, + south, + north, + minHeight, + maxHeight, + ellipsoid, + translation, + rotation, + result +) { + result = OrientedBoundingBox.fromRectangle( + Rectangle.fromRadians(west, south, east, north, scratchRectangle), + minHeight, + maxHeight, + ellipsoid, + result + ); + result.center = Cartesian3.add(result.center, translation, result.center); + result.halfAxes = Matrix3.multiply( + result.halfAxes, + rotation, + result.halfAxes + ); + return result; +} + export default VoxelEllipsoidShape; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 17af662bfb9..c54287f6bd7 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -414,7 +414,7 @@ function VoxelPrimitive(options) { cameraPositionUv: new Cartesian3(), ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), stepSize: 1.0, - ellipsoidHeightDifferenceUv: 1.0, + ellipsoidInverseHeightDifferenceUv: 1.0, ellipsoidOuterRadiiLocal: new Cartesian3(), ellipsoidInverseRadiiSquaredLocal: new Cartesian3(), minBounds: new Cartesian3(), @@ -1053,6 +1053,7 @@ const scratchTotalDimensions = new Cartesian3(); const scratchIntersect = new Cartesian4(); const scratchNdcAabb = new Cartesian4(); const scratchScale = new Cartesian3(); +const scratchEllipsoidRadii = new Cartesian3(); const scratchLocalScale = new Cartesian3(); const scratchInverseLocalScale = new Cartesian3(); const scratchRotation = new Matrix3(); @@ -1331,16 +1332,35 @@ VoxelPrimitive.prototype.update = function (frameState) { // Set other uniforms when the shape is dirty if (shapeType === VoxelShapeType.ELLIPSOID) { - uniforms.ellipsoidHeightDifferenceUv = shape._ellipsoidHeightDifferenceUv; - uniforms.ellipsoidOuterRadiiLocal = Cartesian3.clone( - shape._ellipsoidOuterRadiiLocal, + const radii = Matrix4.getScale( + compoundModelMatrix, + scratchEllipsoidRadii + ); + const minHeight = minBounds.z; + const maxHeight = maxBounds.z; + // const minRadius = Cartesian3.minimumComponent(radii); + const maxRadius = Cartesian3.maximumComponent(radii); + uniforms.ellipsoidOuterRadiiLocal = Cartesian3.fromElements( + (radii.x + maxHeight) / (maxRadius + maxHeight), + (radii.y + maxHeight) / (maxRadius + maxHeight), + (radii.z + maxHeight) / (maxRadius + maxHeight), uniforms.ellipsoidOuterRadiiLocal ); - uniforms.ellipsoidInverseRadiiSquaredLocal = Cartesian3.multiplyComponents( - shape._ellipsoidOuterRadiiLocal, - shape._ellipsoidOuterRadiiLocal, + uniforms.ellipsoidInverseRadiiSquaredLocal = Cartesian3.divideComponents( + Cartesian3.ONE, + Cartesian3.multiplyComponents( + uniforms.ellipsoidOuterRadiiLocal, + uniforms.ellipsoidOuterRadiiLocal, + uniforms.ellipsoidInverseRadiiSquaredLocal + ), uniforms.ellipsoidInverseRadiiSquaredLocal ); + + // TODO: not sure if this is accurate. It could just as well be + // (minRadius + minHeight) / (minRadius + maxHeight). Better approach might + // be to get height relative to inner ellipsoid. + uniforms.ellipsoidInverseHeightDifferenceUv = + (maxRadius + maxHeight) / (maxRadius + minHeight); } // Math that's only valid if the shape is visible. @@ -1937,13 +1957,33 @@ function buildDrawCommands(that, context) { const isDefaultMaxX = maxBounds.x === defaultMaxBounds.x; const isDefaultMaxY = maxBounds.y === defaultMaxBounds.y; const isDefaultMaxZ = maxBounds.z === defaultMaxBounds.z; - const useBounds = - !isDefaultMinX || - !isDefaultMinY || - !isDefaultMinZ || - !isDefaultMaxX || - !isDefaultMaxY || - !isDefaultMaxZ; + + let useBounds = false; + if (shapeType === VoxelShapeType.BOX) { + useBounds = + !isDefaultMinX || + !isDefaultMinY || + !isDefaultMinZ || + !isDefaultMaxX || + !isDefaultMaxY || + !isDefaultMaxZ; + } else if (shapeType === VoxelShapeType.CYLINDER) { + useBounds = + !isDefaultMinX || + !isDefaultMinY || + !isDefaultMinZ || + !isDefaultMaxX || + !isDefaultMaxY || + !isDefaultMaxZ; + } else if (shapeType === shapeType.ELLIPSOID) { + useBounds = + !isDefaultMinX || + !isDefaultMinY || + !isDefaultMinZ || + !isDefaultMaxY || + !isDefaultMaxZ; + } + if (useBounds) { shaderBuilder.addDefine("BOUNDS", undefined, ShaderDestination.FRAGMENT); } diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index ee2650d6b04..f0a3fcccb2e 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -180,7 +180,7 @@ uniform vec3 u_maxClippingBounds; #endif #if defined(SHAPE_ELLIPSOID) -uniform float u_ellipsoidHeightDifferenceUv; +uniform float u_ellipsoidInverseHeightDifferenceUv; uniform vec3 u_ellipsoidOuterRadiiLocal; // [0,1] uniform vec3 u_ellipsoidInverseRadiiSquaredLocal; #endif @@ -225,6 +225,9 @@ int intMin(int a, int b) { int intMax(int a, int b) { return a >= b ? a : b; } +int intClamp(int v, int minVal, int maxVal) { + return intMin(intMax(v, minVal), maxVal); +} float safeMod(float a, float m) { return mod(mod(a, m) + m, m); } @@ -640,7 +643,7 @@ vec2 intersectUnitSphere(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) && defined(BOUNDS_2_MIN) +#if defined(SHAPE_ELLIPSOID) vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) { vec3 o = ray.pos; @@ -708,54 +711,58 @@ vec2 intersectUncappedCone(Ray ray, float angle, float direction) } #endif -#if defined(SHAPE_ELLIPSOID) && defined(BOUNDS) -vec2 intersectClippedEllipsoid(Ray ray, vec3 minBounds, vec3 maxBounds) +#if defined(SHAPE_ELLIPSOID) +vec2 intersectEllipsoidShape(Ray ray) { - float lonMin = minBounds.x + 0.5 * czm_pi; // [-pi,+pi] - float lonMax = maxBounds.x + 0.5 * czm_pi; // [-pi,+pi] - float latMin = minBounds.y; // [-halfPi,+halfPi] - float latMax = maxBounds.y; // [-halfPi,+halfPi] - float heightMin = minBounds.z; // [-inf,+inf] - float heightMax = maxBounds.z; // [-inf,+inf] - - vec2 outerIntersect = intersectUnitSphere(ray); - if (outerIntersect == vec2(NoHit, NoHit)) { - return vec2(NoHit, NoHit); - } - - float intersections[SHAPE_INTERSECTION_COUNT]; - intersections[BOUNDS_2_MAX_IDX * 2 + 0] = outerIntersect.x; - intersections[BOUNDS_2_MAX_IDX * 2 + 1] = outerIntersect.y; - - #if defined(BOUNDS_2_MIN) - float innerScale = heightMin; - Ray innerRay = Ray(ray.pos / innerScale, ray.dir / innerScale); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - intersections[BOUNDS_2_MIN_IDX * 2 + 0] = innerIntersect.x; - intersections[BOUNDS_2_MIN_IDX * 2 + 1] = innerIntersect.y; - #endif + #if !defined(BOUNDS) + return intersectUnitSphereUnnormalizedDirection(ray); + #else + float lonMin = u_minBounds.x; // [-pi,+pi] + float lonMax = u_maxBounds.x; // [-pi,+pi] + float latMin = u_minBounds.y; // [-halfPi,+halfPi] + float latMax = u_maxBounds.y; // [-halfPi,+halfPi] + float heightMin = u_minBounds.z; // [-inf,+inf] + float heightMax = u_maxBounds.z; // [-inf,+inf] - #if defined(BOUNDS_1_MIN) - vec2 botConeIntersect = intersectUncappedCone(ray, abs(latMin), sign(latMin)); - intersections[BOUNDS_1_MIN_IDX * 2 + 0] = botConeIntersect.x; - intersections[BOUNDS_1_MIN_IDX * 2 + 1] = botConeIntersect.y; - #endif - - #if defined(BOUNDS_1_MAX) - vec2 topConeIntersect = intersectUncappedCone(ray, abs(latMax), sign(latMax)); - intersections[BOUNDS_1_MAX_IDX * 2 + 0] = topConeIntersect.x; - intersections[BOUNDS_1_MAX_IDX * 2 + 1] = topConeIntersect.y; - #endif - - #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) - vec3 planeNormal1 = -vec3(cos(lonMin), sin(lonMin), 0.0); - vec3 planeNormal2 = vec3(cos(lonMax), sin(lonMax), 0.0); - vec2 wedgeIntersect = intersectWedge(ray, planeNormal1, planeNormal2); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = wedgeIntersect.x; - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = wedgeIntersect.y; + vec2 outerIntersect = intersectUnitSphere(ray); + if (outerIntersect == vec2(NoHit, NoHit)) { + return vec2(NoHit, NoHit); + } + + float intersections[SHAPE_INTERSECTION_COUNT]; + intersections[BOUNDS_2_MAX_IDX * 2 + 0] = outerIntersect.x; + intersections[BOUNDS_2_MAX_IDX * 2 + 1] = outerIntersect.y; + + #if defined(BOUNDS_2_MIN) + float innerScale = heightMin; + Ray innerRay = Ray(ray.pos / innerScale, ray.dir / innerScale); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + intersections[BOUNDS_2_MIN_IDX * 2 + 0] = innerIntersect.x; + intersections[BOUNDS_2_MIN_IDX * 2 + 1] = innerIntersect.y; + #endif + + #if defined(BOUNDS_1_MIN) + vec2 botConeIntersect = intersectUncappedCone(ray, abs(latMin), sign(latMin)); + intersections[BOUNDS_1_MIN_IDX * 2 + 0] = botConeIntersect.x; + intersections[BOUNDS_1_MIN_IDX * 2 + 1] = botConeIntersect.y; + #endif + + #if defined(BOUNDS_1_MAX) + vec2 topConeIntersect = intersectUncappedCone(ray, abs(latMax), sign(latMax)); + intersections[BOUNDS_1_MAX_IDX * 2 + 0] = topConeIntersect.x; + intersections[BOUNDS_1_MAX_IDX * 2 + 1] = topConeIntersect.y; + #endif + + #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) + vec3 planeNormal1 = -vec3(cos(lonMin), sin(lonMin), 0.0); + vec3 planeNormal2 = vec3(cos(lonMax), sin(lonMax), 0.0); + vec2 wedgeIntersect = intersectWedge(ray, planeNormal1, planeNormal2); + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = wedgeIntersect.x; + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = wedgeIntersect.y; + #endif + + return resolveIntersections(intersections); #endif - - return resolveIntersections(intersections); } #endif @@ -853,8 +860,8 @@ vec3 transformFromUvToBoxSpace(in vec3 positionUv) { #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { - // 1) Convert positionUv [0,1] to unit space [-1, +1] in ellipsoid scale space. - // 2) Convert to non-ellipsoid space. Max ellipsoid axis has value 1, anything shorter is < 1. + // 1) Convert positionUv [0,1] to unit ellipsoid space [-1,+1]. + // 2) Convert from unit ellipsoid space [-1,+1] to local space. Max ellipsoid axis has value 1, anything shorter is < 1. // 3) Convert 3d position to 2D point relative to ellipse (since radii.x and radii.y are assumed to be equal for WGS84). // 4) Find closest distance. if distance > 1, it's outside the outer shell, if distance < u_ellipsoidMinimumHeightUv, it's inside the inner shell. // 5) Compute geodetic surface normal. @@ -864,32 +871,13 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { vec3 pos3D = posLocal * u_ellipsoidOuterRadiiLocal; // 2 vec2 pos2D = vec2(length(pos3D.xy), pos3D.z); // 3 float dist = ellipseDistanceIterative(pos2D, u_ellipsoidOuterRadiiLocal.xz); // 4 - vec3 normal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredLocal); // 5 - float longitude = atan(normal.y, normal.x); // 6 - float latitude = asin(normal.z); // 6 + dist = 1.0 + dist * u_ellipsoidInverseHeightDifferenceUv; // same as delerp(dist, -u_ellipsoidHeightDifferenceUv, 0); - #if defined(BOUNDS) - float longitudeMin = u_minBounds.x; - float longitudeMax = u_maxBounds.x; - float latitudeMin = u_minBounds.x; - float latitudeMax = u_minBounds.y; - if (longitudeMin > longitudeMax) { - longitudeMin -= czm_twoPi; - if (longitude > longitudeMax) { - longitude -= czm_twoPi; - } - } - float shapeX = (longitude - longitudeMin) * u_boundsLengthInverse.x; // [0, 1] - float shapeY = (latitude - latitudeMin) * u_boundsLengthInverse.y; // [0, 1] - #else - float shapeX = (longitude / czm_pi) * 0.5 + 0.5; - float shapeY = (latitude / czm_piOverTwo) * 0.5 + 0.5; - #endif + vec3 normal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredLocal); // 5 + float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; // 6 + float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; // 6 - float distMax = 0.0; - float distMin = -u_ellipsoidHeightDifferenceUv; - float shapeZ = (dist - distMin) / (distMax - distMin); - return vec3(shapeX, shapeY, shapeZ); + return vec3(longitude, latitude, dist); } #endif @@ -922,51 +910,6 @@ vec3 transformFromUvToShapeSpace(in vec3 positionUv) { return positionShape; } -#if defined(SHAPE_ELLIPSOID) -vec3 geodeticSurfaceNormalCartographic(float longitude, float latitude) { - float cosLatitude = cos(latitude); - float x = cosLatitude * cos(longitude); - float y = cosLatitude * sin(longitude); - float z = sin(latitude); - return normalize(vec3(x, y, z)); -} -vec3 cartographicToCartesianUv(float longitude, float latitude, float height) { - vec3 normal = geodeticSurfaceNormalCartographic(longitude, latitude); - vec3 k = normal * u_ellipsoidOuterRadiiLocal * u_ellipsoidOuterRadiiLocal; - k /= sqrt(dot(normal, k)); - vec3 final = normal * height + k; - return final * 0.5 + 0.5; -} -#endif - -vec3 transformFromShapeSpaceToUv(in vec3 positionUvShapeSpace) { - #if defined(SHAPE_CYLINDER) - float dist = positionUvShapeSpace.x; - float angle = czm_twoPi * safeMod(positionUvShapeSpace.y, 1.0); - float slice = positionUvShapeSpace.z; - float x = 0.5 + 0.5 * dist * cos(angle); - float y = 0.5 + 0.5 * dist * sin(angle); - float z = slice; - return vec3(x, y, z); - #elif defined(SHAPE_ELLIPSOID) - #if defined(BOUNDS) - float longitudeMin = u_minBounds.x; - float longitudeMax = u_maxBounds.x; - float latitudeMin = u_minBounds.y; - float latitudeMax = u_maxBounds.y; - float longitude = mix(longitudeMin, longitudeMax, positionUvShapeSpace.x); - float latitude = mix(latitudeMin, latitudeMax, positionUvShapeSpace.y); - float height = mix(-u_ellipsoidHeightDifferenceUv, 0.0, positionUvShapeSpace.z); - #else - float longitude = positionUvShapeSpace.x * czm_twoPi - czm_pi; - float latitude = positionUvShapeSpace.y * czm_pi - czm_piOverTwo; - float height = positionUvShapeSpace.z; - #endif - return cartographicToCartesianUv(longitude, latitude, height); - #else - return positionUvShapeSpace; - #endif -} // -------------------------------------------------------- // Megatexture @@ -1037,7 +980,7 @@ Properties getPropertiesFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 vox // Slice location float slice = voxelCoord.z - 0.5; int sliceIndex = int(floor(slice)); - int sliceIndex0 = intMax(sliceIndex, 0); + int sliceIndex0 = intClamp(sliceIndex, 0, voxelDims.z - 1); vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); // Voxel location diff --git a/Specs/Scene/VoxelEllipsoidShapeSpec.js b/Specs/Scene/VoxelEllipsoidShapeSpec.js index e80c0ecd79b..57c55b57f31 100644 --- a/Specs/Scene/VoxelEllipsoidShapeSpec.js +++ b/Specs/Scene/VoxelEllipsoidShapeSpec.js @@ -1,179 +1,255 @@ import { + BoundingSphere, Cartesian3, Math as CesiumMath, - Ellipsoid, OrientedBoundingBox, + Matrix3, Matrix4, - Ray, - Rectangle, + Quaternion, VoxelEllipsoidShape, - VoxelShapeType, } from "../../Source/Cesium.js"; -describe( - "Scene/VoxelEllipsoidShape", - function () { - const PI_OVER_TWO = CesiumMath.PI_OVER_TWO; - const west = -PI_OVER_TWO; - const east = PI_OVER_TWO; - const south = -PI_OVER_TWO; - const north = PI_OVER_TWO; - const rectangle = new Rectangle(west, south, east, north); - const minimumHeight = 0.0; - const maximumHeight = 1000000.0; - let ellipsoid; - const scratchCartesian3 = new Cartesian3(); - beforeEach(function () { - ellipsoid = new VoxelEllipsoidShape({ - rectangle: rectangle, - minimumHeight: minimumHeight, - maximumHeight: maximumHeight, - }); - ellipsoid.update(); // compute transforms - }); - - it("constructs with arguments", function () { - expect(ellipsoid.ellipsoid.equals(Ellipsoid.WGS84)).toBe(true); - expect(ellipsoid.rectangle.equals(rectangle)).toBe(true); - expect(ellipsoid.minimumHeight).toBe(minimumHeight); - expect(ellipsoid.maximumHeight).toBe(maximumHeight); - expect(ellipsoid._type).toBe(VoxelShapeType.ELLIPSOID); - }); - - it("updates bounding shapes upon changes to ellipsoid", function () { - const oldObb = ellipsoid.orientedBoundingBox.clone(); - const oldSphere = ellipsoid.boundingSphere.clone(); - ellipsoid.ellipsoid = Ellipsoid.MOON; - expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); - expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); - }); - - it("updates bounding shapes upon changes to rectangle", function () { - const oldObb = ellipsoid.orientedBoundingBox.clone(); - const oldSphere = ellipsoid.boundingSphere.clone(); - ellipsoid.rectangle = new Rectangle( - west + CesiumMath.EPSILON7, - south, - east, - north - ); - expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); - expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); - }); - - it("updates bounding shapes upon changes to minimum height", function () { - const oldObb = ellipsoid.orientedBoundingBox.clone(); - const oldSphere = ellipsoid.boundingSphere.clone(); - ellipsoid.minimumHeight += 1; - expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(true); - expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(true); - }); - - it("updates bounding shapes upon changes to maximum height", function () { - const oldObb = ellipsoid.orientedBoundingBox.clone(); - const oldSphere = ellipsoid.boundingSphere.clone(); - ellipsoid.maximumHeight += 1; - expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); - expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); - }); - - it("computes shape transform", function () { - const radii = Ellipsoid.WGS84._radii; - const scaleX = 2.0 * (radii.x + maximumHeight); - const scaleY = 2.0 * (radii.y + maximumHeight); - const scaleZ = 2.0 * (radii.z + maximumHeight); - const scale = Cartesian3.fromElements(scaleX, scaleY, scaleZ); - const shapeTransform = Matrix4.fromScale(scale, new Matrix4()); - expect(shapeTransform.equals(ellipsoid._shapeTransform)).toBe(true); - }); - - it("can clone itself", function () { - const ellipsoidClone = ellipsoid.clone(); - expect(ellipsoidClone).not.toBe(ellipsoid); - expect(ellipsoid.ellipsoid.equals(ellipsoidClone.ellipsoid)).toBe(true); - expect(ellipsoid.rectangle.equals(ellipsoidClone.rectangle)).toBe(true); - expect(ellipsoid.minimumHeight).toBe(ellipsoidClone.minimumHeight); - expect(ellipsoid.maximumHeight).toBe(ellipsoidClone.maximumHeight); - }); - - it("computes bounding volume for root tile", function () { - const result = new OrientedBoundingBox(); - ellipsoid.computeOrientedBoundingBoxForTile(0, 0, 0, 0, result); - expect(result.equals(ellipsoid.orientedBoundingBox)).toBe(true); - }); - - it("indicates when a point in local space is outside the shape", function () { - const clippingMinimum = Cartesian3.ZERO; - const clippingMaximum = Cartesian3.fromElements(1.0, 1.0, 1.0); - expect( - ellipsoid.localPointInsideShape( - Cartesian3.ZERO, - clippingMinimum, - clippingMaximum - ) - ).toBe(false); - expect( - ellipsoid.localPointInsideShape( - Cartesian3.fromElements(0.49, 0.0, 0.0), - clippingMinimum, - clippingMaximum - ) - ).toBe(true); - }); - - it("transforms from local to shape space", function () { - const point = Cartesian3.fromElements(0.5, 0.0, 0.0); - expect( - ellipsoid - .transformFromLocalToShapeSpace(point, scratchCartesian3) - .equals(Cartesian3.fromElements(0.5, 0.5, 1.0)) - ).toBe(true); - }); - - it("intersects ray with outer shell", function () { - const origin = Cartesian3.fromElements(2.0, 0.0, 0.0); - const direction = Cartesian3.fromElements(-1.0, 0.0, 0.0); - const ray = new Ray(origin, direction); - const minClipping = Cartesian3.ZERO; - const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); - const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); - expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); - }); - - it("intersects ray with inner shell", function () { - const origin = Cartesian3.ZERO; - const direction = Cartesian3.fromElements(1.0, 0.0, 0.0); - const ray = new Ray(origin, direction); - const minClipping = Cartesian3.ZERO; - const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); - const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); - expect(t).toEqualEpsilon( - 1.0 - ellipsoid._ellipsoidHeightDifferenceUv, - CesiumMath.EPSILON4 - ); - }); - - it("intersects ray with longitude face", function () { - ellipsoid.rectangle = new Rectangle(west, south, 0.0, north); - const origin = Cartesian3.fromElements(0.99, 1.0, 0.0); - const direction = Cartesian3.fromElements(0.0, -1.0, 0.0); - const ray = new Ray(origin, direction); - const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); - const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); - const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); - expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); - }); - - it("intersects ray with latitude face", function () { - ellipsoid.rectangle = new Rectangle(west, south, east, 0.0); - const origin = Cartesian3.fromElements(0.99, 0.0, 1.0); - const direction = Cartesian3.fromElements(0.0, 0.0, -1.0); - const ray = new Ray(origin, direction); - const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); - const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); - const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); - expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); - }); - }, - "WebGL" -); +describe("Scene/VoxelEllipsoidShape", function () { + it("constructs", function () { + const shape = new VoxelEllipsoidShape(); + expect(shape.isVisible).toEqual(false); + }); + + it("update works with model matrix", function () { + const shape = new VoxelEllipsoidShape(); + const translation = new Cartesian3(1.0, 2.0, 3.0); + const scale = new Cartesian3(2.0, 2.0, 4.0); + const angle = CesiumMath.PI_OVER_FOUR; + const rotation = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, angle); + + const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); + + const minBounds = VoxelEllipsoidShape.DefaultMinBounds; + const maxBounds = VoxelEllipsoidShape.DefaultMaxBounds; + const maxHeight = maxBounds.z; + + const expectedOrientedBoundingBox = new OrientedBoundingBox( + translation, + Matrix3.fromColumnMajorArray([ + (scale.x + maxHeight) * Math.cos(angle), + (scale.x + maxHeight) * Math.sin(angle), + 0.0, + (scale.y + maxHeight) * Math.cos(angle + CesiumMath.PI_OVER_TWO), + (scale.y + maxHeight) * Math.sin(angle + CesiumMath.PI_OVER_TWO), + 0.0, + 0.0, + 0.0, + scale.z + maxHeight, + ]) + ); + + const expectedBoundingSphere = BoundingSphere.fromOrientedBoundingBox( + expectedOrientedBoundingBox, + new BoundingSphere() + ); + + shape.update(modelMatrix, minBounds, maxBounds); + + expect(shape.orientedBoundingBox.center).toEqual( + expectedOrientedBoundingBox.center + ); + expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + expect(shape.boundingSphere).toEqual(expectedBoundingSphere); + + expect( + Matrix4.getTranslation(shape.boundTransform, new Cartesian3()) + ).toEqualEpsilon(expectedOrientedBoundingBox.center, CesiumMath.EPSILON12); + + expect( + Matrix4.getMatrix3(shape.boundTransform, new Matrix3()) + ).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + + expect( + Matrix4.getTranslation(shape.shapeTransform, new Cartesian3()) + ).toEqualEpsilon(expectedOrientedBoundingBox.center, CesiumMath.EPSILON12); + + expect( + Matrix4.getMatrix3(shape.shapeTransform, new Matrix3()) + ).toEqualEpsilon( + expectedOrientedBoundingBox.halfAxes, + CesiumMath.EPSILON12 + ); + + // expect(shape.boundTransform).toEqual(modelMatrix); + // expect(shape.shapeTransform).toEqual(modelMatrix); + // expect(shape.isVisible).toBeTrue(); + }); + + // const PI_OVER_TWO = CesiumMath.PI_OVER_TWO; + // const west = -PI_OVER_TWO; + // const east = PI_OVER_TWO; + // const south = -PI_OVER_TWO; + // const north = PI_OVER_TWO; + // const rectangle = new Rectangle(west, south, east, north); + // const minimumHeight = 0.0; + // const maximumHeight = 1000000.0; + // let ellipsoid; + // const scratchCartesian3 = new Cartesian3(); + // beforeEach(function () { + // ellipsoid = new VoxelEllipsoidShape({ + // rectangle: rectangle, + // minimumHeight: minimumHeight, + // maximumHeight: maximumHeight, + // }); + // ellipsoid.update(); // compute transforms + // }); + + // it("constructs with arguments", function () { + // expect(ellipsoid.ellipsoid.equals(Ellipsoid.WGS84)).toBe(true); + // expect(ellipsoid.rectangle.equals(rectangle)).toBe(true); + // expect(ellipsoid.minimumHeight).toBe(minimumHeight); + // expect(ellipsoid.maximumHeight).toBe(maximumHeight); + // expect(ellipsoid._type).toBe(VoxelShapeType.ELLIPSOID); + // }); + + // it("updates bounding shapes upon changes to ellipsoid", function () { + // const oldObb = ellipsoid.orientedBoundingBox.clone(); + // const oldSphere = ellipsoid.boundingSphere.clone(); + // ellipsoid.ellipsoid = Ellipsoid.MOON; + // expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + // expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + // }); + + // it("updates bounding shapes upon changes to rectangle", function () { + // const oldObb = ellipsoid.orientedBoundingBox.clone(); + // const oldSphere = ellipsoid.boundingSphere.clone(); + // ellipsoid.rectangle = new Rectangle( + // west + CesiumMath.EPSILON7, + // south, + // east, + // north + // ); + // expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + // expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + // }); + + // it("updates bounding shapes upon changes to minimum height", function () { + // const oldObb = ellipsoid.orientedBoundingBox.clone(); + // const oldSphere = ellipsoid.boundingSphere.clone(); + // ellipsoid.minimumHeight += 1; + // expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(true); + // expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(true); + // }); + + // it("updates bounding shapes upon changes to maximum height", function () { + // const oldObb = ellipsoid.orientedBoundingBox.clone(); + // const oldSphere = ellipsoid.boundingSphere.clone(); + // ellipsoid.maximumHeight += 1; + // expect(oldObb.equals(ellipsoid.orientedBoundingBox)).toBe(false); + // expect(oldSphere.equals(ellipsoid.boundingSphere)).toBe(false); + // }); + + // it("computes shape transform", function () { + // const radii = Ellipsoid.WGS84._radii; + // const scaleX = 2.0 * (radii.x + maximumHeight); + // const scaleY = 2.0 * (radii.y + maximumHeight); + // const scaleZ = 2.0 * (radii.z + maximumHeight); + // const scale = Cartesian3.fromElements(scaleX, scaleY, scaleZ); + // const shapeTransform = Matrix4.fromScale(scale, new Matrix4()); + // expect(shapeTransform.equals(ellipsoid._shapeTransform)).toBe(true); + // }); + + // it("can clone itself", function () { + // const ellipsoidClone = ellipsoid.clone(); + // expect(ellipsoidClone).not.toBe(ellipsoid); + // expect(ellipsoid.ellipsoid.equals(ellipsoidClone.ellipsoid)).toBe(true); + // expect(ellipsoid.rectangle.equals(ellipsoidClone.rectangle)).toBe(true); + // expect(ellipsoid.minimumHeight).toBe(ellipsoidClone.minimumHeight); + // expect(ellipsoid.maximumHeight).toBe(ellipsoidClone.maximumHeight); + // }); + + // it("computes bounding volume for root tile", function () { + // const result = new OrientedBoundingBox(); + // ellipsoid.computeOrientedBoundingBoxForTile(0, 0, 0, 0, result); + // expect(result.equals(ellipsoid.orientedBoundingBox)).toBe(true); + // }); + + // it("indicates when a point in local space is outside the shape", function () { + // const clippingMinimum = Cartesian3.ZERO; + // const clippingMaximum = Cartesian3.fromElements(1.0, 1.0, 1.0); + // expect( + // ellipsoid.localPointInsideShape( + // Cartesian3.ZERO, + // clippingMinimum, + // clippingMaximum + // ) + // ).toBe(false); + // expect( + // ellipsoid.localPointInsideShape( + // Cartesian3.fromElements(0.49, 0.0, 0.0), + // clippingMinimum, + // clippingMaximum + // ) + // ).toBe(true); + // }); + + // it("transforms from local to shape space", function () { + // const point = Cartesian3.fromElements(0.5, 0.0, 0.0); + // expect( + // ellipsoid + // .transformFromLocalToShapeSpace(point, scratchCartesian3) + // .equals(Cartesian3.fromElements(0.5, 0.5, 1.0)) + // ).toBe(true); + // }); + + // it("intersects ray with outer shell", function () { + // const origin = Cartesian3.fromElements(2.0, 0.0, 0.0); + // const direction = Cartesian3.fromElements(-1.0, 0.0, 0.0); + // const ray = new Ray(origin, direction); + // const minClipping = Cartesian3.ZERO; + // const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + // const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + // expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + // }); + + // it("intersects ray with inner shell", function () { + // const origin = Cartesian3.ZERO; + // const direction = Cartesian3.fromElements(1.0, 0.0, 0.0); + // const ray = new Ray(origin, direction); + // const minClipping = Cartesian3.ZERO; + // const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + // const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + // expect(t).toEqualEpsilon( + // 1.0 - ellipsoid._ellipsoidHeightDifferenceUv, + // CesiumMath.EPSILON4 + // ); + // }); + + // it("intersects ray with longitude face", function () { + // ellipsoid.rectangle = new Rectangle(west, south, 0.0, north); + // const origin = Cartesian3.fromElements(0.99, 1.0, 0.0); + // const direction = Cartesian3.fromElements(0.0, -1.0, 0.0); + // const ray = new Ray(origin, direction); + // const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); + // const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + // const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + // expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + // }); + + // it("intersects ray with latitude face", function () { + // ellipsoid.rectangle = new Rectangle(west, south, east, 0.0); + // const origin = Cartesian3.fromElements(0.99, 0.0, 1.0); + // const direction = Cartesian3.fromElements(0.0, 0.0, -1.0); + // const ray = new Ray(origin, direction); + // const minClipping = Cartesian3.fromElements(-1.0, -1.0, -1.0); + // const maxClipping = Cartesian3.fromElements(1.0, 1.0, 1.0); + // const t = ellipsoid.intersectRay(ray, minClipping, maxClipping); + // expect(t).toEqualEpsilon(1.0, CesiumMath.EPSILON4); + // }); + // }), +}); From 1dfe3830e14dbe69596075e9a29546bff7222a29 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Tue, 5 Apr 2022 11:36:36 -0400 Subject: [PATCH 009/679] preparing for ellipsoid bounds --- Apps/Sandcastle/gallery/Voxels.html | 2 + Source/Scene/VoxelPrimitive.js | 47 ++++++++++++++----- Source/Shaders/VoxelFS.glsl | 73 ++++++++++++++++++----------- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index db7b3216cd5..689327164ad 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -60,6 +60,8 @@ ); const west = minBounds.x; const east = maxBounds.x; + // const south = -0.5; + // const north = +0.5; const south = minBounds.y; const north = maxBounds.y; const minimumHeight = 0.0; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index c54287f6bd7..bbb35a227fd 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1289,12 +1289,31 @@ VoxelPrimitive.prototype.update = function (frameState) { uniforms.maxBoundsUv ); } else if (shapeType === VoxelShapeType.ELLIPSOID) { - uniforms.minBoundsUv = Cartesian3.clone( - minBounds, + const minLongitudeUv = + (minBounds.x - defaultMinBounds.x) / + (defaultMaxBounds.x - defaultMinBounds.x); + const maxLongitudeUv = + (maxBounds.x - defaultMinBounds.x) / + (defaultMaxBounds.x - defaultMinBounds.x); + const minLatitudeUv = + (minBounds.y - defaultMinBounds.y) / + (defaultMaxBounds.y - defaultMinBounds.y); + const maxLatitudeUv = + (maxBounds.y - defaultMinBounds.y) / + (defaultMaxBounds.y - defaultMinBounds.y); + const minHeightUv = 0.0; // don't know what to do with these yet + const maxHeightUv = 0.0; // don't know what to do with these yet + + uniforms.minBoundsUv = Cartesian3.fromElements( + minLongitudeUv, + minLatitudeUv, + minHeightUv, uniforms.minBoundsUv ); - uniforms.maxBoundsUv = Cartesian3.clone( - maxBounds, + uniforms.maxBoundsUv = Cartesian3.fromElements( + maxLongitudeUv, + maxLatitudeUv, + maxHeightUv, uniforms.maxBoundsUv ); } else if (shapeType === VoxelShapeType.CYLINDER) { @@ -1962,26 +1981,32 @@ function buildDrawCommands(that, context) { if (shapeType === VoxelShapeType.BOX) { useBounds = !isDefaultMinX || - !isDefaultMinY || - !isDefaultMinZ || !isDefaultMaxX || + !isDefaultMinY || !isDefaultMaxY || + !isDefaultMinZ || !isDefaultMaxZ; } else if (shapeType === VoxelShapeType.CYLINDER) { useBounds = !isDefaultMinX || - !isDefaultMinY || - !isDefaultMinZ || !isDefaultMaxX || + !isDefaultMinY || !isDefaultMaxY || + !isDefaultMinZ || !isDefaultMaxZ; - } else if (shapeType === shapeType.ELLIPSOID) { + } else if (shapeType === VoxelShapeType.ELLIPSOID) { + const radii = Matrix4.getScale(that._compoundModelMatrix, scratchScale); + const hasInnerEllipsoid = !( + radii.x === radii.y && + radii.y === radii.z && + minBounds.z === -radii.x + ); useBounds = !isDefaultMinX || + !isDefaultMaxX || !isDefaultMinY || - !isDefaultMinZ || !isDefaultMaxY || - !isDefaultMaxZ; + hasInnerEllipsoid; } if (useBounds) { diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index f0a3fcccb2e..254aa9a7686 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -266,7 +266,7 @@ struct Ray const float NoHit = -czm_infinity; const float InfHit = czm_infinity; -#if (defined(SHAPE_CYLINDER) && defined(BOUNDS)) || (defined(SHAPE_ELLIPSOID) && defined(BOUNDS)) +#if (defined(SHAPE_CYLINDER) || defined(SHAPE_ELLIPSOID)) && defined(BOUNDS) vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) { // TODO: completely skip shape if both of its Ts are below 0.0? @@ -442,9 +442,9 @@ vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) bool h = smax >= 0.0; // if () return vec2(tmin, tmax); - // else if () return vec2(NoHitNeg, tmin); - // else if () return vec2(NoHitNeg, tmax); - // else if () return vec2(tmax, NoHitPos); + // else if () return vec2(-InfHit, tmin); + // else if () return vec2(-InfHit, tmax); + // else if () return vec2(tmax, +InfHit); // else return vec2(NoHit, NoHit); if (e != g && f == h) return vec2(tmin, tmax); @@ -705,8 +705,8 @@ vec2 intersectUncappedCone(Ray ray, float angle, float direction) return vec2(NoHit, NoHit); } - else if (h1 < 0.0) return vec2(tmax, NoHitPos); - else if (h2 < 0.0) return vec2(NoHitNeg, tmin); + else if (h1 < 0.0) return vec2(tmax, +InfHit); + else if (h2 < 0.0) return vec2(-InfHit, tmin); else return vec2(tmin, tmax); } #endif @@ -724,44 +724,46 @@ vec2 intersectEllipsoidShape(Ray ray) float heightMin = u_minBounds.z; // [-inf,+inf] float heightMax = u_maxBounds.z; // [-inf,+inf] - vec2 outerIntersect = intersectUnitSphere(ray); + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + return outerIntersect; if (outerIntersect == vec2(NoHit, NoHit)) { return vec2(NoHit, NoHit); } - float intersections[SHAPE_INTERSECTION_COUNT]; - intersections[BOUNDS_2_MAX_IDX * 2 + 0] = outerIntersect.x; - intersections[BOUNDS_2_MAX_IDX * 2 + 1] = outerIntersect.y; + vec2 intersections[SHAPE_INTERSECTION_COUNT]; + intersections[0] = vec2(float(0), outerIntersect.x); + intersections[1] = vec2(float(1), outerIntersect.y); #if defined(BOUNDS_2_MIN) float innerScale = heightMin; Ray innerRay = Ray(ray.pos / innerScale, ray.dir / innerScale); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - intersections[BOUNDS_2_MIN_IDX * 2 + 0] = innerIntersect.x; - intersections[BOUNDS_2_MIN_IDX * 2 + 1] = innerIntersect.y; + intersections[2] = vec2(float(2), innerIntersect.x); + intersections[3] = vec2(float(3), innerIntersect.y); #endif #if defined(BOUNDS_1_MIN) vec2 botConeIntersect = intersectUncappedCone(ray, abs(latMin), sign(latMin)); - intersections[BOUNDS_1_MIN_IDX * 2 + 0] = botConeIntersect.x; - intersections[BOUNDS_1_MIN_IDX * 2 + 1] = botConeIntersect.y; + intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); + intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); #endif #if defined(BOUNDS_1_MAX) vec2 topConeIntersect = intersectUncappedCone(ray, abs(latMax), sign(latMax)); - intersections[BOUNDS_1_MAX_IDX * 2 + 0] = topConeIntersect.x; - intersections[BOUNDS_1_MAX_IDX * 2 + 1] = topConeIntersect.y; + intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); + intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); #endif #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) vec3 planeNormal1 = -vec3(cos(lonMin), sin(lonMin), 0.0); vec3 planeNormal2 = vec3(cos(lonMax), sin(lonMax), 0.0); vec2 wedgeIntersect = intersectWedge(ray, planeNormal1, planeNormal2); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = wedgeIntersect.x; - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = wedgeIntersect.y; + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); #endif - return resolveIntersections(intersections); + return resolveIntersections(intersections); + // return vec2(0.0); #endif } #endif @@ -854,7 +856,11 @@ float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDir #if defined(SHAPE_BOX) vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - return positionUv; + vec3 positionShape = positionUv; + #if defined(BOUNDS) + positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] + #endif + return positionShape; } #endif @@ -877,6 +883,15 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; // 6 float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; // 6 + #if defined(BOUNDS) + float minLongitude = u_minBoundsUv.x; + float maxLongitude = u_maxBoundsUv.x; + float minLatitude = u_minBoundsUv.y; + float maxLatitude = u_minBoundsUv.y; + longitude = (longitude - minLongitude) / (maxLongitude - minLongitude); + latitude = (latitude - minLatitude) / (maxLatitude - minLatitude); + #endif + return vec3(longitude, latitude, dist); } #endif @@ -887,7 +902,16 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { float radius = length(positionLocal.xy); // [0,1] float height = positionUv.z; // [0,1] float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - return vec3(radius, height, angle); + vec3 positionShape = vec3(radius, height, angle); + + #if defined(BOUNDS) + positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + #endif + + return positionShape; } #endif @@ -900,13 +924,6 @@ vec3 transformFromUvToShapeSpace(in vec3 positionUv) { vec3 positionShape = transformFromUvToCylinderSpace(positionUv); #endif - #if defined(BOUNDS) - positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. - #endif - return positionShape; } From 94521adc27fd336461de7897f8bc11286693f75e Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Tue, 5 Apr 2022 12:00:18 -0400 Subject: [PATCH 010/679] disable cull and occlude if depth testing is off --- Source/Scene/VoxelEllipsoidShape.js | 4 +- Source/Scene/VoxelPrimitive.js | 2 + .../Widgets/VoxelInspector/VoxelInspector.js | 48 ++++++++++++++----- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index cbe85683d76..41a5f5cd728 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -322,7 +322,7 @@ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( -CesiumMath.PI, -CesiumMath.PI_OVER_TWO, - 0.0 + 0.0 // should be -1? ); /** @@ -335,7 +335,7 @@ VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( +CesiumMath.PI, +CesiumMath.PI_OVER_TWO, - 1.0 + 1.0 // should be 0? ); /** diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index bbb35a227fd..fb5b2834158 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -2482,6 +2482,8 @@ function buildDrawCommands(that, context) { pass: Pass.VOXELS, executeInClosestFrustum: true, owner: this, + cull: depthTest, // don't cull or occlude if depth testing is off + occlude: depthTest, // don't cull or occlude if depth testing is off }); // Create the pick draw command diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index c1eed5c1631..2c1e327db37 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -1,3 +1,4 @@ +import Cartesian3 from "../../Core/Cartesian3.js"; import CesiumMath from "../../Core/Math.js"; import Check from "../../Core/Check.js"; import defaultValue from "../../Core/defaultValue.js"; @@ -127,6 +128,29 @@ function VoxelInspector(container, scene) { "boundsVisibleToggle" ); + const boxMinBounds = VoxelShapeType.getMinBounds(VoxelShapeType.BOX); + const boxMaxBounds = VoxelShapeType.getMaxBounds(VoxelShapeType.BOX); + + const ellipsoidMinBounds = Cartesian3.fromElements( + VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).x, + VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).y, + -6356752.3142451793, // The deepest height for WGS84 + new Cartesian3() + ); + const ellipsoidMaxBounds = Cartesian3.fromElements( + VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID).x, + VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID).y, + +10000000.0, + new Cartesian3() + ); + + const cylinderMinBounds = VoxelShapeType.getMinBounds( + VoxelShapeType.CYLINDER + ); + const cylinderMaxBounds = VoxelShapeType.getMaxBounds( + VoxelShapeType.CYLINDER + ); + makeCoordinateRange( "Max X", "Min X", @@ -140,8 +164,8 @@ function VoxelInspector(container, scene) { "boundsBoxMinY", "boundsBoxMaxZ", "boundsBoxMinZ", - VoxelShapeType.getMinBounds(VoxelShapeType.BOX), - VoxelShapeType.getMaxBounds(VoxelShapeType.BOX), + boxMinBounds, + boxMaxBounds, "shapeIsBox", boundsPanelContents ); @@ -159,8 +183,8 @@ function VoxelInspector(container, scene) { "boundsEllipsoidMinLatitude", "boundsEllipsoidMaxHeight", "boundsEllipsoidMinHeight", - VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID), - VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID), + ellipsoidMinBounds, + ellipsoidMaxBounds, "shapeIsEllipsoid", boundsPanelContents ); @@ -178,8 +202,8 @@ function VoxelInspector(container, scene) { "boundsCylinderMinHeight", "boundsCylinderMaxAngle", "boundsCylinderMinAngle", - VoxelShapeType.getMinBounds(VoxelShapeType.CYLINDER), - VoxelShapeType.getMaxBounds(VoxelShapeType.CYLINDER), + cylinderMinBounds, + cylinderMaxBounds, "shapeIsCylinder", boundsPanelContents ); @@ -205,8 +229,8 @@ function VoxelInspector(container, scene) { "clippingBoxMinY", "clippingBoxMaxZ", "clippingBoxMinZ", - VoxelShapeType.getMinBounds(VoxelShapeType.BOX), - VoxelShapeType.getMaxBounds(VoxelShapeType.BOX), + boxMinBounds, + boxMaxBounds, "shapeIsBox", clippingPanelContents ); @@ -224,8 +248,8 @@ function VoxelInspector(container, scene) { "clippingEllipsoidMinLatitude", "clippingEllipsoidMaxHeight", "clippingEllipsoidMinHeight", - VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID), - VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID), + ellipsoidMinBounds, + ellipsoidMaxBounds, "shapeIsEllipsoid", clippingPanelContents ); @@ -243,8 +267,8 @@ function VoxelInspector(container, scene) { "clippingCylinderMinHeight", "clippingCylinderMaxAngle", "clippingCylinderMinAngle", - VoxelShapeType.getMinBounds(VoxelShapeType.CYLINDER), - VoxelShapeType.getMaxBounds(VoxelShapeType.CYLINDER), + cylinderMinBounds, + cylinderMaxBounds, "shapeIsCylinder", clippingPanelContents ); From d5597ba0e3902f7c0dc469eac1ee831f6112d7ea Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Tue, 5 Apr 2022 18:25:29 -0400 Subject: [PATCH 011/679] fixed cone intersection --- Apps/Sandcastle/gallery/Voxels.html | 21 +++++- Source/Shaders/VoxelFS.glsl | 110 ++++++++++++++-------------- Source/Widgets/Viewer/Viewer.js | 2 +- 3 files changed, 72 insertions(+), 61 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 689327164ad..46f75d97863 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -61,10 +61,10 @@ const west = minBounds.x; const east = maxBounds.x; // const south = -0.5; - // const north = +0.5; + const north = Cesium.Math.PI_OVER_TWO - 0.1; const south = minBounds.y; - const north = maxBounds.y; - const minimumHeight = 0.0; + // const north = maxBounds.y; + const minimumHeight = 1000000.0; const maximumHeight = 2000000.0; this.minBounds = Cesium.Cartesian3.fromElements( @@ -394,6 +394,21 @@ }); Sandcastle.addToolbarMenu([ + { + text: "Ellipsoid - Procedural Tile", + onselect: function () { + const provider = new ProceduralSingleTileVoxelProvider( + Cesium.VoxelShapeType.ELLIPSOID + ); + const primitive = createPrimitive(provider, customShaderColor); + primitive.readyPromise.then(function () { + console.log(primitive.boundingSphere.center); + viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { + duration: 0.0, + }); + }); + }, + }, { text: "Box - Procedural Tile", onselect: function () { diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 254aa9a7686..bc8933bc47b 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -136,6 +136,8 @@ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { #define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops #define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0 +#define NO_HIT -czm_infinity +#define INF_HIT czm_infinity #if defined(MEGATEXTURE_2D) uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions @@ -202,6 +204,11 @@ struct SampleData { #endif }; +struct Ray { + vec3 pos; + vec3 dir; +}; + // -------------------------------------------------------- // Misc math // -------------------------------------------------------- @@ -256,21 +263,11 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) // -------------------------------------------------------- // Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- - -struct Ray -{ - vec3 pos; - vec3 dir; -}; - -const float NoHit = -czm_infinity; -const float InfHit = czm_infinity; - #if (defined(SHAPE_CYLINDER) || defined(SHAPE_ELLIPSOID)) && defined(BOUNDS) vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) { // TODO: completely skip shape if both of its Ts are below 0.0? - vec2 entryExitT = vec2(NoHit, NoHit); + vec2 entryExitT = vec2(NO_HIT, NO_HIT); // Sort the intersections from min T to max T with bubble sort. // Note: If this sorting function changes, some of the intersection test may @@ -352,7 +349,7 @@ vec2 intersectUnitCube(Ray ray) float tMax = min(min(m1.x, m1.y), m1.z); if (tMin >= tMax) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } return vec2(tMin, tMax); @@ -368,7 +365,7 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] float t = -o.z / d.z; vec2 planePos = o.xy + d.xy * t; if (any(greaterThan(abs(planePos), vec2(1.0)))) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } return vec2(t, t); @@ -442,15 +439,15 @@ vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) bool h = smax >= 0.0; // if () return vec2(tmin, tmax); - // else if () return vec2(-InfHit, tmin); - // else if () return vec2(-InfHit, tmax); - // else if () return vec2(tmax, +InfHit); - // else return vec2(NoHit, NoHit); + // else if () return vec2(-INF_HIT, tmin); + // else if () return vec2(-INF_HIT, tmax); + // else if () return vec2(tmax, +INF_HIT); + // else return vec2(NO_HIT, NO_HIT); if (e != g && f == h) return vec2(tmin, tmax); - else if (e == g && f == h) return vec2(-InfHit, tmin); - else if (e != g && f != h) return vec2(tmax, +InfHit); - else return vec2(NoHit, NoHit); + else if (e == g && f == h) return vec2(-INF_HIT, tmin); + else if (e != g && f != h) return vec2(tmax, +INF_HIT); + else return vec2(NO_HIT, NO_HIT); } #endif @@ -466,7 +463,7 @@ vec2 intersectUnitCylinder(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } det = sqrt(det); @@ -481,13 +478,13 @@ vec2 intersectUnitCylinder(Ray ray) if (abs(z1) >= 1.0) { float tCap = (sign(z1) - o.z) / d.z; - t1 = abs(b + a * tCap) < det ? tCap : NoHit; + t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; } if (abs(z2) >= 1.0) { float tCap = (sign(z2) - o.z) / d.z; - t2 = abs(b + a * tCap) < det ? tCap : NoHit; + t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; } return vec2(t1, t2); @@ -504,7 +501,7 @@ vec2 intersectUnitCircle(Ray ray) { float distSqr = dot(zPlanePos, zPlanePos); if (distSqr > 1.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } return vec2(t, t); @@ -523,7 +520,7 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } det = sqrt(det); @@ -566,8 +563,8 @@ vec2 intersectCylinderShape(Ray ray) outerIntersect = intersectUnitCylinder(outerRay); } - if (outerIntersect == vec2(NoHit, NoHit)) { - return vec2(NoHit, NoHit); + if (outerIntersect == vec2(NO_HIT, NO_HIT)) { + return vec2(NO_HIT, NO_HIT); } vec2 intersections[SHAPE_INTERSECTION_COUNT]; @@ -630,7 +627,7 @@ vec2 intersectUnitSphere(Ray ray) float det = b * b - c; if (det < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } det = sqrt(det); @@ -655,7 +652,7 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } det = sqrt(det); @@ -670,26 +667,27 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) #if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) // TODO: can angle and direction be folded into the same parameter -vec2 intersectUncappedCone(Ray ray, float angle, float direction) +vec2 intersectUncappedCone(Ray ray, float angle) { vec3 o = ray.pos; vec3 d = ray.dir; - float s = direction; - float h = max(0.01, angle); // float fix - + float s = sign(angle); + float h = cos(abs(angle)); float hh = h * h; - float ds = d[2] * s; - float os = o[2] * s; + + float ds = d.z * s; + float os = o.z * s; + float dd = dot(d, d); float od = dot(o, d); float oo = dot(o, o); - - float a = ds * ds - hh; + + float a = ds * ds - dd * hh; float b = ds * os - od * hh; float c = os * os - oo * hh; float det = b * b - a * c; if (det < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } det = sqrt(det); @@ -698,15 +696,15 @@ vec2 intersectUncappedCone(Ray ray, float angle, float direction) float tmin = min(t1, t2); float tmax = max(t1, t2); - float h1 = (o[2] + tmin * d[2]) * s; - float h2 = (o[2] + tmax * d[2]) * s; + float h1 = (o.z + tmin * d.z) * s; + float h2 = (o.z + tmax * d.z) * s; if (h1 < 0.0 && h2 < 0.0) { - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } - else if (h1 < 0.0) return vec2(tmax, +InfHit); - else if (h2 < 0.0) return vec2(-InfHit, tmin); + else if (h1 < 0.0) return vec2(tmax, +INF_HIT); + else if (h2 < 0.0) return vec2(-INF_HIT, tmin); else return vec2(tmin, tmax); } #endif @@ -725,9 +723,8 @@ vec2 intersectEllipsoidShape(Ray ray) float heightMax = u_maxBounds.z; // [-inf,+inf] vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - return outerIntersect; - if (outerIntersect == vec2(NoHit, NoHit)) { - return vec2(NoHit, NoHit); + if (outerIntersect == vec2(NO_HIT, NO_HIT)) { + return vec2(NO_HIT, NO_HIT); } vec2 intersections[SHAPE_INTERSECTION_COUNT]; @@ -735,29 +732,28 @@ vec2 intersectEllipsoidShape(Ray ray) intersections[1] = vec2(float(1), outerIntersect.y); #if defined(BOUNDS_2_MIN) - float innerScale = heightMin; - Ray innerRay = Ray(ray.pos / innerScale, ray.dir / innerScale); + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseHeightDifferenceUv, ray.dir * u_ellipsoidInverseHeightDifferenceUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); intersections[2] = vec2(float(2), innerIntersect.x); intersections[3] = vec2(float(3), innerIntersect.y); #endif #if defined(BOUNDS_1_MIN) - vec2 botConeIntersect = intersectUncappedCone(ray, abs(latMin), sign(latMin)); + float halfAngleMin = sign(latMin) * (czm_piOverTwo - abs(latMin)); + vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin); intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); #endif #if defined(BOUNDS_1_MAX) - vec2 topConeIntersect = intersectUncappedCone(ray, abs(latMax), sign(latMax)); + float halfAngleMax = sign(latMax) * (czm_piOverTwo - abs(latMax)); + vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax); intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); #endif #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) - vec3 planeNormal1 = -vec3(cos(lonMin), sin(lonMin), 0.0); - vec3 planeNormal2 = vec3(cos(lonMax), sin(lonMax), 0.0); - vec2 wedgeIntersect = intersectWedge(ray, planeNormal1, planeNormal2); + vec2 wedgeIntersect = intersectWedge(ray, lonMin, lonMax); intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); #endif @@ -829,9 +825,9 @@ vec2 intersectShape(vec3 positionUv, vec3 directionUv) { if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { // Intersection is invalid when start and end are behind the ray. - return vec2(NoHit, NoHit); + return vec2(NO_HIT, NO_HIT); } - + // Set start to 0 when ray is inside the shape. entryExitT.x = max(entryExitT.x, 0.0); @@ -1230,7 +1226,7 @@ void main() vec2 entryExitT = intersectShape(viewPosUv, viewDirUv); // Exit early if the shape was completely missed. - if (entryExitT == vec2(NoHit, NoHit)) { + if (entryExitT == vec2(NO_HIT, NO_HIT)) { discard; } @@ -1352,7 +1348,7 @@ void main() vec2 entryExitT = intersectShape(positionUv, viewDirUv); // Stop raymarching if it doesn't hit anything - if (entryExitT == vec2(NoHit, NoHit)) { + if (entryExitT == vec2(NO_HIT, NO_HIT)) { break; } diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js index 5319e2eb7df..38795b77ed9 100644 --- a/Source/Widgets/Viewer/Viewer.js +++ b/Source/Widgets/Viewer/Viewer.js @@ -2027,7 +2027,7 @@ Viewer.prototype._onDataSourceRemoved = function ( * target will be the range. The heading will be determined from the offset. If the heading cannot be * determined from the offset, the heading will be north.

* - * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. + * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. * @param {HeadingPitchRange} [offset] The offset from the center of the entity in the local east-north-up reference frame. * @returns {Promise.} A Promise that resolves to true if the zoom was successful or false if the target is not currently visualized in the scene or the zoom was cancelled. */ From d3b992430150fe8999b830c2af75cd6347007c7d Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Tue, 5 Apr 2022 18:32:08 -0400 Subject: [PATCH 012/679] rearranged ellipsoid before cylinder --- Source/Shaders/VoxelFS.glsl | 376 ++++++++++++++++++------------------ 1 file changed, 187 insertions(+), 189 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index bc8933bc47b..30c942a9da1 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -263,7 +263,7 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) // -------------------------------------------------------- // Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- -#if (defined(SHAPE_CYLINDER) || defined(SHAPE_ELLIPSOID)) && defined(BOUNDS) +#if (defined(SHAPE_ELLIPSOID) || defined(SHAPE_CYLINDER)) && defined(BOUNDS) vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) { // TODO: completely skip shape if both of its Ts are below 0.0? @@ -410,7 +410,7 @@ vec2 intersectBoxShape(Ray ray) } #endif -#if (defined(SHAPE_CYLINDER) && (defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX))) || (defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX))) +#if ((defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX)) || defined(SHAPE_CYLINDER) && (defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX)))) vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) { vec2 o = ray.pos.xy; @@ -451,6 +451,154 @@ vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) } #endif +#if defined(SHAPE_ELLIPSOID) +vec2 intersectUnitSphere(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - c; + + if (det < 0.0) { + return vec2(NO_HIT, NO_HIT); + } + + det = sqrt(det); + float t1 = -b - det; + float t2 = -b + det; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d, d); + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT, NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) +// TODO: can angle and direction be folded into the same parameter +vec2 intersectUncappedCone(Ray ray, float angle) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + float s = sign(angle); + float h = cos(abs(angle)); + float hh = h * h; + + float ds = d.z * s; + float os = o.z * s; + float dd = dot(d, d); + float od = dot(o, d); + float oo = dot(o, o); + + float a = ds * ds - dd * hh; + float b = ds * os - od * hh; + float c = os * os - oo * hh; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT, NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + float h1 = (o.z + tmin * d.z) * s; + float h2 = (o.z + tmax * d.z) * s; + + if (h1 < 0.0 && h2 < 0.0) { + return vec2(NO_HIT, NO_HIT); + } + + else if (h1 < 0.0) return vec2(tmax, +INF_HIT); + else if (h2 < 0.0) return vec2(-INF_HIT, tmin); + else return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec2 intersectEllipsoidShape(Ray ray) +{ + #if !defined(BOUNDS) + return intersectUnitSphereUnnormalizedDirection(ray); + #else + float lonMin = u_minBounds.x; // [-pi,+pi] + float lonMax = u_maxBounds.x; // [-pi,+pi] + float latMin = u_minBounds.y; // [-halfPi,+halfPi] + float latMax = u_maxBounds.y; // [-halfPi,+halfPi] + float heightMin = u_minBounds.z; // [-inf,+inf] + float heightMax = u_maxBounds.z; // [-inf,+inf] + + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + if (outerIntersect == vec2(NO_HIT, NO_HIT)) { + return vec2(NO_HIT, NO_HIT); + } + + vec2 intersections[SHAPE_INTERSECTION_COUNT]; + intersections[0] = vec2(float(0), outerIntersect.x); + intersections[1] = vec2(float(1), outerIntersect.y); + + #if defined(BOUNDS_2_MIN) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseHeightDifferenceUv, ray.dir * u_ellipsoidInverseHeightDifferenceUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + intersections[2] = vec2(float(2), innerIntersect.x); + intersections[3] = vec2(float(3), innerIntersect.y); + #endif + + #if defined(BOUNDS_1_MIN) + float halfAngleMin = sign(latMin) * (czm_piOverTwo - abs(latMin)); + vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin); + intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); + intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); + #endif + + #if defined(BOUNDS_1_MAX) + float halfAngleMax = sign(latMax) * (czm_piOverTwo - abs(latMax)); + vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax); + intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); + intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); + #endif + + #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) + vec2 wedgeIntersect = intersectWedge(ray, lonMin, lonMax); + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); + intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); + #endif + + return resolveIntersections(intersections); + // return vec2(0.0); + #endif +} +#endif + #if defined(SHAPE_CYLINDER) vec2 intersectUnitCylinder(Ray ray) { @@ -616,151 +764,54 @@ vec2 intersectCylinderShape(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphere(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - c; - - if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); - } - - det = sqrt(det); - float t1 = -b - det; - float t2 = -b + det; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d, d); - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif +vec2 intersectShape(vec3 positionUv, vec3 directionUv) { + // Do a ray-shape intersection to find the exact starting and ending points. + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); -#if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) -// TODO: can angle and direction be folded into the same parameter -vec2 intersectUncappedCone(Ray ray, float angle) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - float s = sign(angle); - float h = cos(abs(angle)); - float hh = h * h; - - float ds = d.z * s; - float os = o.z * s; - float dd = dot(d, d); - float od = dot(o, d); - float oo = dot(o, o); + #if defined(SHAPE_BOX) + vec2 entryExitT = intersectBoxShape(ray); + #elif defined(SHAPE_ELLIPSOID) + vec2 entryExitT = intersectEllipsoidShape(ray); + #elif defined(SHAPE_CYLINDER) + vec2 entryExitT = intersectCylinderShape(ray); + #endif - float a = ds * ds - dd * hh; - float b = ds * os - od * hh; - float c = os * os - oo * hh; - float det = b * b - a * c; - - if (det < 0.0) { + if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { + // Intersection is invalid when start and end are behind the ray. return vec2(NO_HIT, NO_HIT); } - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); + // Set start to 0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); - float h1 = (o.z + tmin * d.z) * s; - float h2 = (o.z + tmax * d.z) * s; - - if (h1 < 0.0 && h2 < 0.0) { - return vec2(NO_HIT, NO_HIT); - } + return entryExitT; +} - else if (h1 < 0.0) return vec2(tmax, +INF_HIT); - else if (h2 < 0.0) return vec2(-INF_HIT, tmin); - else return vec2(tmin, tmax); +#if defined(DEPTH_TEST) +float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDirUv) { + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); + if (logDepthOrDepth != 0.0) { + // Calculate how far the ray must travel before it hits the depth buffer. + vec4 eyeCoordinateDepth = czm_windowToEyeCoordinates(fragCoord, logDepthOrDepth); + eyeCoordinateDepth /= eyeCoordinateDepth.w; + vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); + return dot(viewDirUv, depthPositionUv - viewPosUv); + } else { + // There's no depth at this position so set it to some really far value. + return czm_infinity; + } } #endif -#if defined(SHAPE_ELLIPSOID) -vec2 intersectEllipsoidShape(Ray ray) -{ - #if !defined(BOUNDS) - return intersectUnitSphereUnnormalizedDirection(ray); - #else - float lonMin = u_minBounds.x; // [-pi,+pi] - float lonMax = u_maxBounds.x; // [-pi,+pi] - float latMin = u_minBounds.y; // [-halfPi,+halfPi] - float latMax = u_maxBounds.y; // [-halfPi,+halfPi] - float heightMin = u_minBounds.z; // [-inf,+inf] - float heightMax = u_maxBounds.z; // [-inf,+inf] - - vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - if (outerIntersect == vec2(NO_HIT, NO_HIT)) { - return vec2(NO_HIT, NO_HIT); - } - - vec2 intersections[SHAPE_INTERSECTION_COUNT]; - intersections[0] = vec2(float(0), outerIntersect.x); - intersections[1] = vec2(float(1), outerIntersect.y); - - #if defined(BOUNDS_2_MIN) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseHeightDifferenceUv, ray.dir * u_ellipsoidInverseHeightDifferenceUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - intersections[2] = vec2(float(2), innerIntersect.x); - intersections[3] = vec2(float(3), innerIntersect.y); - #endif - - #if defined(BOUNDS_1_MIN) - float halfAngleMin = sign(latMin) * (czm_piOverTwo - abs(latMin)); - vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin); - intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); - intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); - #endif - - #if defined(BOUNDS_1_MAX) - float halfAngleMax = sign(latMax) * (czm_piOverTwo - abs(latMax)); - vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax); - intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); - intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); - #endif - - #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) - vec2 wedgeIntersect = intersectWedge(ray, lonMin, lonMax); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); - #endif - - return resolveIntersections(intersections); - // return vec2(0.0); +#if defined(SHAPE_BOX) +vec3 transformFromUvToBoxSpace(in vec3 positionUv) { + vec3 positionShape = positionUv; + #if defined(BOUNDS) + positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] #endif + return positionShape; } #endif @@ -768,7 +819,6 @@ vec2 intersectEllipsoidShape(Ray ray) // robust iterative solution without trig functions // https://github.com/0xfaded/ellipse_demo/issues/1 // https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse - float ellipseDistanceIterative (vec2 p, in vec2 ab) { float px = abs(p[0]); float py = abs(p[1]); @@ -809,57 +859,6 @@ float ellipseDistanceIterative (vec2 p, in vec2 ab) { } #endif -vec2 intersectShape(vec3 positionUv, vec3 directionUv) { - // Do a ray-shape intersection to find the exact starting and ending points. - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); - - #if defined(SHAPE_BOX) - vec2 entryExitT = intersectBoxShape(ray); - #elif defined(SHAPE_CYLINDER) - vec2 entryExitT = intersectCylinderShape(ray); - #elif defined(SHAPE_ELLIPSOID) - vec2 entryExitT = intersectEllipsoidShape(ray); - #endif - - if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { - // Intersection is invalid when start and end are behind the ray. - return vec2(NO_HIT, NO_HIT); - } - - // Set start to 0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); - - return entryExitT; -} - -#if defined(DEPTH_TEST) -float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDirUv) { - float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); - if (logDepthOrDepth != 0.0) { - // Calculate how far the ray must travel before it hits the depth buffer. - vec4 eyeCoordinateDepth = czm_windowToEyeCoordinates(fragCoord, logDepthOrDepth); - eyeCoordinateDepth /= eyeCoordinateDepth.w; - vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - return dot(viewDirUv, depthPositionUv - viewPosUv); - } else { - // There's no depth at this position so set it to some really far value. - return czm_infinity; - } -} -#endif - -#if defined(SHAPE_BOX) -vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - vec3 positionShape = positionUv; - #if defined(BOUNDS) - positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] - #endif - return positionShape; -} -#endif - #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { // 1) Convert positionUv [0,1] to unit ellipsoid space [-1,+1]. @@ -923,7 +922,6 @@ vec3 transformFromUvToShapeSpace(in vec3 positionUv) { return positionShape; } - // -------------------------------------------------------- // Megatexture // -------------------------------------------------------- From 1b76f5961437c4b46d0e7fc960f32312c237859e Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 6 Apr 2022 12:16:26 -0400 Subject: [PATCH 013/679] better overturned cone and also better uv to ellipsoid space --- Source/Scene/VoxelPrimitive.js | 53 +++++++++++++--------- Source/Shaders/VoxelFS.glsl | 82 +++++++++++++++++++--------------- 2 files changed, 78 insertions(+), 57 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index fb5b2834158..a97a02bd85e 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -415,8 +415,10 @@ function VoxelPrimitive(options) { ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), stepSize: 1.0, ellipsoidInverseHeightDifferenceUv: 1.0, - ellipsoidOuterRadiiLocal: new Cartesian3(), - ellipsoidInverseRadiiSquaredLocal: new Cartesian3(), + ellipsoidInverseInnerScaleUv: 1.0, + ellipsoidRadiiUv: new Cartesian3(), + ellipsoidInnerRadiiUv: new Cartesian3(), + ellipsoidInverseRadiiSquaredUv: new Cartesian3(), minBounds: new Cartesian3(), maxBounds: new Cartesian3(), minBoundsUv: new Cartesian3(), @@ -1357,29 +1359,40 @@ VoxelPrimitive.prototype.update = function (frameState) { ); const minHeight = minBounds.z; const maxHeight = maxBounds.z; - // const minRadius = Cartesian3.minimumComponent(radii); - const maxRadius = Cartesian3.maximumComponent(radii); - uniforms.ellipsoidOuterRadiiLocal = Cartesian3.fromElements( - (radii.x + maxHeight) / (maxRadius + maxHeight), - (radii.y + maxHeight) / (maxRadius + maxHeight), - (radii.z + maxHeight) / (maxRadius + maxHeight), - uniforms.ellipsoidOuterRadiiLocal + // The farthest distance a point can be from the center of the ellipsoid. + const maxExtent = Cartesian3.maximumComponent(radii) + maxHeight; + // The percent of space that is between the inner and outer ellipsoid + const thickness = (maxHeight - minHeight) / maxExtent; + // The percent of space that is taken up by the inner ellipsoid. + const innerScale = 1.0 - thickness; + + // The ellipsoid radii scaled to [0,1]. The max ellipsoid radius will be 1.0 and others will be less. + uniforms.ellipsoidRadiiUv = Cartesian3.fromElements( + (radii.x + maxHeight) / maxExtent, + (radii.y + maxHeight) / maxExtent, + (radii.z + maxHeight) / maxExtent, + uniforms.ellipsoidRadiiUv ); - uniforms.ellipsoidInverseRadiiSquaredLocal = Cartesian3.divideComponents( + + // The inner ellipsoid radii scaled to [0,innerScale]. The max inner ellipsoid radius will be innerScale and others will be less. + uniforms.ellipsoidInnerRadiiUv = Cartesian3.multiplyByScalar( + uniforms.ellipsoidRadiiUv, + innerScale, + uniforms.ellipsoidInnerRadiiUv + ); + + // Used to compute geodetic surface normal. + uniforms.ellipsoidInverseRadiiSquaredUv = Cartesian3.divideComponents( Cartesian3.ONE, Cartesian3.multiplyComponents( - uniforms.ellipsoidOuterRadiiLocal, - uniforms.ellipsoidOuterRadiiLocal, - uniforms.ellipsoidInverseRadiiSquaredLocal + uniforms.ellipsoidRadiiUv, + uniforms.ellipsoidRadiiUv, + uniforms.ellipsoidInverseRadiiSquaredUv ), - uniforms.ellipsoidInverseRadiiSquaredLocal + uniforms.ellipsoidInverseRadiiSquaredUv ); - - // TODO: not sure if this is accurate. It could just as well be - // (minRadius + minHeight) / (minRadius + maxHeight). Better approach might - // be to get height relative to inner ellipsoid. - uniforms.ellipsoidInverseHeightDifferenceUv = - (maxRadius + maxHeight) / (maxRadius + minHeight); + uniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; + uniforms.ellipsoidInverseInnerScaleUv = 1.0 / innerScale; } // Math that's only valid if the shape is visible. diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 30c942a9da1..37c3a0db361 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -183,8 +183,10 @@ uniform vec3 u_maxClippingBounds; #if defined(SHAPE_ELLIPSOID) uniform float u_ellipsoidInverseHeightDifferenceUv; -uniform vec3 u_ellipsoidOuterRadiiLocal; // [0,1] -uniform vec3 u_ellipsoidInverseRadiiSquaredLocal; +uniform float u_ellipsoidInverseInnerScaleUv; +uniform vec3 u_ellipsoidRadiiUv; // [0,1] +uniform vec3 u_ellipsoidInnerRadiiUv; // [0,1] +uniform vec3 u_ellipsoidInverseRadiiSquaredUv; #endif #if defined(PICKING) @@ -501,12 +503,14 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) #endif #if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) -// TODO: can angle and direction be folded into the same parameter -vec2 intersectUncappedCone(Ray ray, float angle) +vec2 intersectUncappedCone(Ray ray, float angle, float side) { + if (angle < 0.0) { + side *= -1.0; + } vec3 o = ray.pos; vec3 d = ray.dir; - float s = sign(angle); + float s = sign(side); float h = cos(abs(angle)); float hh = h * h; @@ -522,7 +526,11 @@ vec2 intersectUncappedCone(Ray ray, float angle) float det = b * b - a * c; if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); + if (angle > 0.0) { + return vec2(NO_HIT, NO_HIT); + } else { + return vec2(-INF_HIT, +INF_HIT); + } } det = sqrt(det); @@ -533,14 +541,19 @@ vec2 intersectUncappedCone(Ray ray, float angle) float h1 = (o.z + tmin * d.z) * s; float h2 = (o.z + tmax * d.z) * s; - - if (h1 < 0.0 && h2 < 0.0) { - return vec2(NO_HIT, NO_HIT); - } - else if (h1 < 0.0) return vec2(tmax, +INF_HIT); - else if (h2 < 0.0) return vec2(-INF_HIT, tmin); - else return vec2(tmin, tmax); + if (angle > 0.0) { + if (h1 < 0.0 && h2 < 0.0) return vec2(NO_HIT, NO_HIT); + else if (h1 < 0.0) return vec2(tmax, +INF_HIT); + else if (h2 < 0.0) return vec2(-INF_HIT, tmin); + else return vec2(tmin, tmax); + } else { + if (h1 < 0.0 && h2 < 0.0) return vec2(-INF_HIT, +INF_HIT); + else if (h1 < 0.0) return vec2(-INF_HIT, tmax); + else if (h2 < 0.0) return vec2(tmin, +INF_HIT); + else if (tmin < 0.0) return vec2(tmax, +INF_HIT); + else return vec2(-INF_HIT, tmin); + } } #endif @@ -567,7 +580,7 @@ vec2 intersectEllipsoidShape(Ray ray) intersections[1] = vec2(float(1), outerIntersect.y); #if defined(BOUNDS_2_MIN) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseHeightDifferenceUv, ray.dir * u_ellipsoidInverseHeightDifferenceUv); + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); intersections[2] = vec2(float(2), innerIntersect.x); intersections[3] = vec2(float(3), innerIntersect.y); @@ -575,14 +588,14 @@ vec2 intersectEllipsoidShape(Ray ray) #if defined(BOUNDS_1_MIN) float halfAngleMin = sign(latMin) * (czm_piOverTwo - abs(latMin)); - vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin); + vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin, -1.0); intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); #endif #if defined(BOUNDS_1_MAX) float halfAngleMax = sign(latMax) * (czm_piOverTwo - abs(latMax)); - vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax); + vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax, +1.0); intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); #endif @@ -861,33 +874,28 @@ float ellipseDistanceIterative (vec2 p, in vec2 ab) { #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { - // 1) Convert positionUv [0,1] to unit ellipsoid space [-1,+1]. - // 2) Convert from unit ellipsoid space [-1,+1] to local space. Max ellipsoid axis has value 1, anything shorter is < 1. - // 3) Convert 3d position to 2D point relative to ellipse (since radii.x and radii.y are assumed to be equal for WGS84). - // 4) Find closest distance. if distance > 1, it's outside the outer shell, if distance < u_ellipsoidMinimumHeightUv, it's inside the inner shell. - // 5) Compute geodetic surface normal. - // 6) Compute longitude and latitude from geodetic surface normal. - - vec3 posLocal = positionUv * 2.0 - 1.0; // 1 - vec3 pos3D = posLocal * u_ellipsoidOuterRadiiLocal; // 2 - vec2 pos2D = vec2(length(pos3D.xy), pos3D.z); // 3 - float dist = ellipseDistanceIterative(pos2D, u_ellipsoidOuterRadiiLocal.xz); // 4 - dist = 1.0 + dist * u_ellipsoidInverseHeightDifferenceUv; // same as delerp(dist, -u_ellipsoidHeightDifferenceUv, 0); - - vec3 normal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredLocal); // 5 - float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; // 6 - float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; // 6 + // 1) Convert positionUv [0,1] to local space [-1,+1] to normalized cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. + // 2) Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization to do math with ellipses instead of ellipsoids. + // 3) Compute height from inner ellipse. + // 4) Compute geodetic surface normal. + // 5) Compute longitude from geodetic surface normal. + // 6) Compute latitude from geodetic surface normal. + vec3 pos3D = (positionUv * 2.0 - 1.0) * u_ellipsoidRadiiUv; // 1 + vec2 pos2D = vec2(length(pos3D.xy), pos3D.z); // 2 + float height = ellipseDistanceIterative(pos2D, u_ellipsoidInnerRadiiUv.xz); // 3 + vec3 geodeticSurfaceNormal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredUv); // 4 + float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; // 5 + float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; // 6 #if defined(BOUNDS) + height *= u_ellipsoidInverseHeightDifferenceUv; float minLongitude = u_minBoundsUv.x; - float maxLongitude = u_maxBoundsUv.x; float minLatitude = u_minBoundsUv.y; - float maxLatitude = u_minBoundsUv.y; - longitude = (longitude - minLongitude) / (maxLongitude - minLongitude); - latitude = (latitude - minLatitude) / (maxLatitude - minLatitude); + longitude = (longitude - minLongitude) * u_inverseBoundsUv.x; + latitude = (latitude - minLatitude) * u_inverseBoundsUv.y; #endif - return vec3(longitude, latitude, dist); + return vec3(longitude, latitude, height); } #endif From 9e5adaeb153a61863cced475f42a2b6b8f3045dc Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 6 Apr 2022 15:00:33 -0400 Subject: [PATCH 014/679] simplified the iterative ellipse distance --- Source/Shaders/VoxelFS.glsl | 106 ++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 36 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 37c3a0db361..e7aadb7658f 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -224,7 +224,9 @@ float hash(vec2 p) return fract((p3.x + p3.y) * p3.z); } #endif - +float signNoZero(float v) { + return (v < 0.0) ? -1.0 : 1.0; +} int intMod(int a, int b) { return a - (b * (a / b)); } @@ -832,50 +834,82 @@ vec3 transformFromUvToBoxSpace(in vec3 positionUv) { // robust iterative solution without trig functions // https://github.com/0xfaded/ellipse_demo/issues/1 // https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse -float ellipseDistanceIterative (vec2 p, in vec2 ab) { - float px = abs(p[0]); - float py = abs(p[1]); - - float tx = 0.707; - float ty = 0.707; - - float a = ab.x; - float b = ab.y; - - for (int i = 0; i < 3; i++) { - float x = a * tx; - float y = b * ty; - - float ex = (a*a - b*b) * pow(tx, 3.0) / a; - float ey = (b*b - a*a) * pow(ty, 3.0) / b; - - float rx = x - ex; - float ry = y - ey; - - float qx = px - ex; - float qy = py - ey; - - float r = sqrt(ry * ry + rx * rx); - float q = sqrt(qy * qy + qx * qx); +// Pro: Good when radii.x ~= radii.y +// Con: Breaks at pos.x ~= 0.0, especially inside the ellipse +// Con: Inaccurate with exterior points and thin ellipses +float ellipseDistanceIterative (vec2 pos, vec2 radii) { + vec2 p = abs(pos); + vec2 invRadii = 1.0 / radii; + vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii; + vec2 t = vec2(0.70710678118); // sqrt(2) / 2 + vec2 v = radii * t; + + const int iterations = 3; + for (int i = 0; i < iterations; i++) { + vec2 e = a * pow(t, vec2(3.0)); + vec2 q = normalize(p - e) * length(v - e); + t = normalize((q + e) * invRadii); + v = radii * t; + } + return length(v * sign(pos) - pos) * sign(p.y - v.y); +} +#endif - tx = clamp((qx * r / q + ex) / a, 0.0, 1.0); - ty = clamp((qy * r / q + ey) / b, 0.0, 1.0); - float t = sqrt(ty * ty + tx * tx); - tx /= t; - ty /= t; +#if defined(SHAPE_ELLIPSOID) +// From: https://www.shadertoy.com/view/4sS3zz +// Pro: Accurate in most cases +// Con: Breaks if radii.x ~= radii.y +float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { + vec2 p = pos; + vec2 ab = radii; + + p = abs(p); + if (p.x > p.y) { + p = p.yx; + ab = ab.yx; + } + + float l = ab.y * ab.y - ab.x * ab.x; + float m = ab.x * p.x / l; + float n = ab.y * p.y / l; + float m2 = m * m; + float n2 = n * n; + float c = (m2 + n2 - 1.0) / 3.0; + float c3 = c * c * c; + float d = c3 + m2 * n2; + float q = d + m2 * n2; + float g = m + m * n2; + + float co; + + if (d < 0.0) { + float h = acos(q / c3) / 3.0; + float s = cos(h) + 2.0; + float t = sin(h) * sqrt(3.0); + float rx = sqrt(m2 - c * (s + t)); + float ry = sqrt(m2 - c * (s - t)); + co = ry + sign(l) * rx + abs(g) / (rx * ry); + } else { + float h = 2.0 * m * n * sqrt(d); + float s = signNoZero(q + h) * pow(abs(q + h), 1.0 / 3.0); + float t = signNoZero(q - h) * pow(abs(q - h), 1.0 / 3.0); + float rx = -(s + t) - c * 4.0 + 2.0 * m2; + float ry = (s - t) * sqrt(3.0); + float rm = sqrt(rx * rx + ry * ry); + co = ry / sqrt(rm - rx) + 2.0 * g / rm; } - float cX = a * tx; - float cY = b * ty; - vec2 pos = vec2(cX * sign(p[0]), cY * sign(p[1])); - return length(pos - p) * sign(py - cY); + co = (co - m) / 2.0; + float si = sqrt(max(1.0 - co * co, 0.0)); + vec2 r = ab * vec2(co, si); + return length(r - p) * signNoZero(p.y - r.y); } #endif #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { // 1) Convert positionUv [0,1] to local space [-1,+1] to normalized cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. - // 2) Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization to do math with ellipses instead of ellipsoids. + // 2) Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization so that math can be done with ellipses instead of ellipsoids. // 3) Compute height from inner ellipse. // 4) Compute geodetic surface normal. // 5) Compute longitude from geodetic surface normal. From 5743dc8258d8b0abd75d00e2ab9d04323ef500b0 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 6 Apr 2022 17:14:23 -0400 Subject: [PATCH 015/679] sanitizing bounds --- Source/Scene/VoxelPrimitive.js | 214 +++++++++++++----- .../Widgets/VoxelInspector/VoxelInspector.js | 3 +- 2 files changed, 156 insertions(+), 61 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index a97a02bd85e..e7a76ea8f5b 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1193,15 +1193,79 @@ VoxelPrimitive.prototype.update = function (frameState) { compoundModelMatrix, compoundModelMatrixOld ); + const shape = this._shape; const shapeType = provider.shape; - + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const minBounds = this._minBounds; const maxBounds = this._maxBounds; + + let isDefaultBoundsMin = + minBounds.x === defaultMinBounds.x && + minBounds.y === defaultMinBounds.y && + minBounds.z === defaultMinBounds.z; + + let isDefaultBoundsMax = + maxBounds.x === defaultMaxBounds.x && + maxBounds.y === defaultMaxBounds.y && + maxBounds.z === defaultMaxBounds.z; + + // Clamp the min bounds to the valid range. + if (!isDefaultBoundsMin) { + minBounds.x = CesiumMath.clamp( + minBounds.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); + minBounds.y = CesiumMath.clamp( + minBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + if (shapeType !== VoxelShapeType.ELLIPSOID) { + minBounds.z = CesiumMath.clamp( + minBounds.z, + defaultMinBounds.z, + defaultMaxBounds.z + ); + } + isDefaultBoundsMin = + minBounds.x === defaultMinBounds.x && + minBounds.y === defaultMinBounds.y && + minBounds.z === defaultMinBounds.z; + } + + // Clamp the max bounds to the valid range. + if (!isDefaultBoundsMax) { + maxBounds.x = CesiumMath.clamp( + maxBounds.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); + maxBounds.y = CesiumMath.clamp( + maxBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + if (shapeType !== VoxelShapeType.ELLIPSOID) { + maxBounds.z = CesiumMath.clamp( + maxBounds.z, + defaultMinBounds.z, + defaultMaxBounds.z + ); + } + isDefaultBoundsMax = + maxBounds.x === defaultMaxBounds.x && + maxBounds.y === defaultMaxBounds.y && + maxBounds.z === defaultMaxBounds.z; + } + const minBoundsOld = this._minBoundsOld; const maxBoundsOld = this._maxBoundsOld; const minBoundsDirty = !Cartesian3.equals(minBounds, minBoundsOld); const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); + const shapeIsDirty = compoundModelMatrixDirty || minBoundsDirty || maxBoundsDirty; @@ -1217,23 +1281,15 @@ VoxelPrimitive.prototype.update = function (frameState) { } if (minBoundsDirty || maxBoundsDirty) { - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); - const isDefaultBoundsMinX = minBounds.x === defaultMinBounds.x; - const isDefaultBoundsMinY = minBounds.y === defaultMinBounds.y; - const isDefaultBoundsMinZ = minBounds.z === defaultMinBounds.z; - const isDefaultBoundsMaxX = maxBounds.x === defaultMaxBounds.x; - const isDefaultBoundsMaxY = maxBounds.y === defaultMaxBounds.y; - const isDefaultBoundsMaxZ = maxBounds.z === defaultMaxBounds.z; - if (minBoundsDirty) { - const isDefaultOldBoundsMinX = minBoundsOld.x === defaultMinBounds.x; - const isDefaultOldBoundsMinY = minBoundsOld.y === defaultMinBounds.y; - const isDefaultOldBoundsMinZ = minBoundsOld.z === defaultMinBounds.z; + // Check if the min bounds became default or stopped being default if ( - isDefaultBoundsMinX !== isDefaultOldBoundsMinX || - isDefaultBoundsMinY !== isDefaultOldBoundsMinY || - isDefaultBoundsMinZ !== isDefaultOldBoundsMinZ + (minBounds.x === defaultMinBounds.x) !== + (minBoundsOld.x === defaultMinBounds.x) || + (minBounds.y === defaultMinBounds.y) !== + (minBoundsOld.y === defaultMinBounds.y) || + (minBounds.z === defaultMinBounds.z) !== + (minBoundsOld.z === defaultMinBounds.z) ) { this._shaderDirty = true; } @@ -1241,13 +1297,14 @@ VoxelPrimitive.prototype.update = function (frameState) { } if (maxBoundsDirty) { - const isDefaultOldBoundsMaxX = maxBoundsOld.x === defaultMaxBounds.x; - const isDefaultOldBoundsMaxY = maxBoundsOld.y === defaultMaxBounds.y; - const isDefaultOldBoundsMaxZ = maxBoundsOld.z === defaultMaxBounds.z; + // Check if the max bounds became default or stopped being default if ( - isDefaultBoundsMaxX !== isDefaultOldBoundsMaxX || - isDefaultBoundsMaxY !== isDefaultOldBoundsMaxY || - isDefaultBoundsMaxZ !== isDefaultOldBoundsMaxZ + (maxBounds.x === defaultMaxBounds.x) !== + (maxBoundsOld.x === defaultMaxBounds.x) || + (maxBounds.y === defaultMaxBounds.y) !== + (maxBoundsOld.y === defaultMaxBounds.y) || + (maxBounds.z === defaultMaxBounds.z) !== + (maxBoundsOld.z === defaultMaxBounds.z) ) { this._shaderDirty = true; } @@ -1255,14 +1312,7 @@ VoxelPrimitive.prototype.update = function (frameState) { } // Set uniforms for bounds. - if ( - !isDefaultBoundsMinX || - !isDefaultBoundsMinY || - !isDefaultBoundsMinZ || - !isDefaultBoundsMaxX || - !isDefaultBoundsMaxY || - !isDefaultBoundsMaxZ - ) { + if (!isDefaultBoundsMin || !isDefaultBoundsMax) { uniforms.minBounds = Cartesian3.clone(minBounds, uniforms.minBounds); uniforms.maxBounds = Cartesian3.clone(maxBounds, uniforms.maxBounds); uniforms.inverseBounds = Cartesian3.divideComponents( @@ -1603,29 +1653,82 @@ VoxelPrimitive.prototype.update = function (frameState) { // Process clipping bounds. const minClip = this._minClippingBounds; const maxClip = this._maxClippingBounds; + + let isDefaultClippingBoundsMin = + minClip.x === defaultMinBounds.x && + minClip.y === defaultMinBounds.y && + minClip.z === defaultMinBounds.z; + + let isDefaultClippingBoundsMax = + maxClip.x === defaultMaxBounds.x && + maxClip.y === defaultMaxBounds.y && + maxClip.z === defaultMaxBounds.z; + + // Clamp the min bounds to the valid range. + if (!isDefaultClippingBoundsMin) { + minClip.x = CesiumMath.clamp( + minClip.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); + minClip.y = CesiumMath.clamp( + minClip.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + if (shapeType !== VoxelShapeType.ELLIPSOID) { + minClip.z = CesiumMath.clamp( + minClip.z, + defaultMinBounds.z, + defaultMaxBounds.z + ); + } + isDefaultClippingBoundsMin = + minClip.x === defaultMinBounds.x && + minClip.y === defaultMinBounds.y && + minClip.z === defaultMinBounds.z; + } + + // Clamp the max bounds to the valid range. + if (!isDefaultClippingBoundsMax) { + maxClip.x = CesiumMath.clamp( + maxClip.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); + maxClip.y = CesiumMath.clamp( + maxClip.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + if (shapeType !== VoxelShapeType.ELLIPSOID) { + maxClip.z = CesiumMath.clamp( + maxClip.z, + defaultMinBounds.z, + defaultMaxBounds.z + ); + } + isDefaultClippingBoundsMax = + maxClip.x === defaultMaxBounds.x && + maxClip.y === defaultMaxBounds.y && + maxClip.z === defaultMaxBounds.z; + } + const minClipOld = this._minClippingBoundsOld; const maxClipOld = this._maxClippingBoundsOld; const minClipDirty = !Cartesian3.equals(minClip, minClipOld); const maxClipDirty = !Cartesian3.equals(maxClip, maxClipOld); const clippingBoundsDirty = minClipDirty || maxClipDirty; - if (clippingBoundsDirty) { - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); - const isDefaultClippingBoundsMinX = minClip.x === defaultMinBounds.x; - const isDefaultClippingBoundsMinY = minClip.y === defaultMinBounds.y; - const isDefaultClippingBoundsMinZ = minClip.z === defaultMinBounds.z; - const isDefaultClippingBoundsMaxX = maxClip.x === defaultMaxBounds.x; - const isDefaultClippingBoundsMaxY = maxClip.y === defaultMaxBounds.y; - const isDefaultClippingBoundsMaxZ = maxClip.z === defaultMaxBounds.z; + if (clippingBoundsDirty) { if (minClipDirty) { - const isDefaultOldClipMinX = minClipOld.x === defaultMinBounds.x; - const isDefaultOldClipMinY = minClipOld.y === defaultMinBounds.y; - const isDefaultOldClipMinZ = minClipOld.z === defaultMinBounds.z; if ( - isDefaultClippingBoundsMinX !== isDefaultOldClipMinX || - isDefaultClippingBoundsMinY !== isDefaultOldClipMinY || - isDefaultClippingBoundsMinZ !== isDefaultOldClipMinZ + (minClip.x === defaultMinBounds.x) !== + (minClipOld.x === defaultMinBounds.x) || + (minClip.y === defaultMinBounds.y) !== + (minClipOld.y === defaultMinBounds.y) || + (minClip.z === defaultMinBounds.z) !== + (minClipOld.z === defaultMinBounds.z) ) { this._shaderDirty = true; } @@ -1635,13 +1738,13 @@ VoxelPrimitive.prototype.update = function (frameState) { ); } if (maxClipDirty) { - const isDefaultOldClipMaxX = maxClipOld.x === defaultMaxBounds.x; - const isDefaultOldClipMaxY = maxClipOld.y === defaultMaxBounds.y; - const isDefaultOldClipMaxZ = maxClipOld.z === defaultMaxBounds.z; if ( - isDefaultClippingBoundsMaxX !== isDefaultOldClipMaxX || - isDefaultClippingBoundsMaxY !== isDefaultOldClipMaxY || - isDefaultClippingBoundsMaxZ !== isDefaultOldClipMaxZ + (maxClip.x === defaultMaxBounds.x) !== + (maxClipOld.x === defaultMaxBounds.x) || + (maxClip.y === defaultMaxBounds.y) !== + (maxClipOld.y === defaultMaxBounds.y) || + (maxClip.z === defaultMaxBounds.z) !== + (maxClipOld.z === defaultMaxBounds.z) ) { this._shaderDirty = true; } @@ -1650,14 +1753,7 @@ VoxelPrimitive.prototype.update = function (frameState) { this._maxClippingBoundsOld ); } - if ( - !isDefaultClippingBoundsMinX || - !isDefaultClippingBoundsMinY || - !isDefaultClippingBoundsMinZ || - !isDefaultClippingBoundsMaxX || - !isDefaultClippingBoundsMaxY || - !isDefaultClippingBoundsMaxZ - ) { + if (!isDefaultClippingBoundsMin || !isDefaultClippingBoundsMax) { // Set clipping uniforms uniforms.minClippingBounds = Cartesian3.clone( minClip, diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index 2c1e327db37..a72f841a50a 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -343,7 +343,6 @@ VoxelInspector.prototype.destroy = function () { }; function makeRangeInput(text, property, min, max, step, displayProperty) { - step = defaultValue(step, 0.01); displayProperty = defaultValue(displayProperty, property); const input = document.createElement("input"); input.setAttribute("data-bind", `value: ${displayProperty}`); @@ -353,7 +352,7 @@ function makeRangeInput(text, property, min, max, step, displayProperty) { slider.type = "range"; slider.min = min; slider.max = max; - slider.step = step; + slider.step = defaultValue(step, "any"); slider.setAttribute("data-bind", `valueUpdate: "input", value: ${property}`); const wrapper = document.createElement("div"); From f8558154dd49562fda69f6da93b6cc03e3a1dd3b Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 6 Apr 2022 18:20:24 -0400 Subject: [PATCH 016/679] fixed problem with min latitude --- Apps/Sandcastle/gallery/Voxels.html | 4 ++-- Source/Shaders/VoxelFS.glsl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 46f75d97863..75b43ae980f 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -60,9 +60,9 @@ ); const west = minBounds.x; const east = maxBounds.x; - // const south = -0.5; + const south = -Cesium.Math.PI_OVER_TWO + 0.1; const north = Cesium.Math.PI_OVER_TWO - 0.1; - const south = minBounds.y; + // const south = minBounds.y; // const north = maxBounds.y; const minimumHeight = 1000000.0; const maximumHeight = 2000000.0; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index e7aadb7658f..3a52d273176 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -589,7 +589,7 @@ vec2 intersectEllipsoidShape(Ray ray) #endif #if defined(BOUNDS_1_MIN) - float halfAngleMin = sign(latMin) * (czm_piOverTwo - abs(latMin)); + float halfAngleMin = -sign(latMin) * (czm_piOverTwo - abs(latMin)); vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin, -1.0); intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); From f846978bb27731098e1a497ff6faabbd3285138f Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 6 Apr 2022 20:54:01 -0400 Subject: [PATCH 017/679] one less param for cone intersect function --- Source/Shaders/VoxelFS.glsl | 58 ++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 3a52d273176..1d05d5024f0 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -505,30 +505,46 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) #endif #if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) -vec2 intersectUncappedCone(Ray ray, float angle, float side) +vec2 intersectUncappedCone(Ray ray, float latitude) { - if (angle < 0.0) { - side *= -1.0; - } + float side = sign(latitude); + float halfAngle = czm_piOverTwo - abs(latitude); + vec3 o = ray.pos; vec3 d = ray.dir; - float s = sign(side); - float h = cos(abs(angle)); + if (side < 0.0) { + o.z *= -1.0; + d.z *= -1.0; + } + + float h = cos(halfAngle); float hh = h * h; - - float ds = d.z * s; - float os = o.z * s; float dd = dot(d, d); float od = dot(o, d); float oo = dot(o, o); - float a = ds * ds - dd * hh; - float b = ds * os - od * hh; - float c = os * os - oo * hh; + // if (abs(normalize(o).z - h) < 0.1 && abs(d.z - h) < 0.1) { + // if (angle > 0.0) { + // // if (o.z * s < 0.0) { + // // return vec2(0.0, +INF_HIT); + // // } else { + // // return vec2(-o.z / d.z, 0.0); + // // // return (o.z + x * d.z) * s = 0 + // // } + // return vec2(-INF_HIT, +INF_HIT); + // } else { + // return vec2(NO_HIT, NO_HIT); + // } + // // return vec2(-10.0, +10.0); + // } + + float a = d.z * d.z - dd * hh; + float b = d.z * o.z - od * hh; + float c = o.z * o.z - oo * hh; float det = b * b - a * c; if (det < 0.0) { - if (angle > 0.0) { + if (side > 0.0) { return vec2(NO_HIT, NO_HIT); } else { return vec2(-INF_HIT, +INF_HIT); @@ -541,10 +557,10 @@ vec2 intersectUncappedCone(Ray ray, float angle, float side) float tmin = min(t1, t2); float tmax = max(t1, t2); - float h1 = (o.z + tmin * d.z) * s; - float h2 = (o.z + tmax * d.z) * s; + float h1 = o.z + tmin * d.z; + float h2 = o.z + tmax * d.z; - if (angle > 0.0) { + if (side > 0.0) { if (h1 < 0.0 && h2 < 0.0) return vec2(NO_HIT, NO_HIT); else if (h1 < 0.0) return vec2(tmax, +INF_HIT); else if (h2 < 0.0) return vec2(-INF_HIT, tmin); @@ -589,15 +605,17 @@ vec2 intersectEllipsoidShape(Ray ray) #endif #if defined(BOUNDS_1_MIN) - float halfAngleMin = -sign(latMin) * (czm_piOverTwo - abs(latMin)); - vec2 botConeIntersect = intersectUncappedCone(ray, halfAngleMin, -1.0); + // Flip the inputs because the intersection function expects a cone growing towards +Z. + Ray flippedRay = ray; + flippedRay.dir.z *= -1.0; + flippedRay.pos.z *= -1.0; + vec2 botConeIntersect = intersectUncappedCone(flippedRay, -latMin); intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); #endif #if defined(BOUNDS_1_MAX) - float halfAngleMax = sign(latMax) * (czm_piOverTwo - abs(latMax)); - vec2 topConeIntersect = intersectUncappedCone(ray, halfAngleMax, +1.0); + vec2 topConeIntersect = intersectUncappedCone(ray, latMax); intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); #endif From 3ddeeac7d2b9b15dab9d03179fdc8f1e19bfcc04 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 11 Apr 2022 09:22:43 -0400 Subject: [PATCH 018/679] temp2 --- Apps/Sandcastle/gallery/Voxels.html | 10 +- Source/Scene/VoxelBoxShape.js | 216 +++++---- Source/Scene/VoxelEllipsoidShape.js | 357 +++++++++----- Source/Scene/VoxelPrimitive.js | 719 ++++++++-------------------- Source/Scene/VoxelShape.js | 17 +- Source/Scene/VoxelTraversal.js | 2 +- Source/Shaders/VoxelFS.glsl | 691 +++++++++++++++----------- Source/Shaders/VoxelVS.glsl | 1 + 8 files changed, 968 insertions(+), 1045 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 75b43ae980f..5d247673b62 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -60,10 +60,12 @@ ); const west = minBounds.x; const east = maxBounds.x; - const south = -Cesium.Math.PI_OVER_TWO + 0.1; - const north = Cesium.Math.PI_OVER_TWO - 0.1; - // const south = minBounds.y; - // const north = maxBounds.y; + //const west = -Cesium.Math.PI + 0.4; + //const east = -Cesium.Math.PI + 0.7; + // const south = -Cesium.Math.PI_OVER_TWO + 0.1; + // const north = Cesium.Math.PI_OVER_TWO - 0.1; + const south = minBounds.y; + const north = maxBounds.y; const minimumHeight = 1000000.0; const maximumHeight = 2000000.0; diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index e133f03881b..47a5cb8e161 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -52,14 +52,6 @@ function VoxelBoxShape() { */ this.shapeTransform = new Matrix4(); - /** - * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. - * The update function must be called before accessing this value. - * @type {Boolean} - * @readonly - */ - this.isVisible = false; - /** * @type {Cartesian3} * @private @@ -77,6 +69,27 @@ function VoxelBoxShape() { VoxelBoxShape.DefaultMaxBounds, new Cartesian3() ); + + /** + * @type {Object.} + * @readonly + */ + this.shaderUniforms = { + boxMinBounds: new Cartesian3(), + boxMaxBounds: new Cartesian3(), + }; + + /** + * @type {Object.} + * @readonly + */ + this.shaderDefines = { + BOX_INTERSECTION_COUNT: 1, + BOX_BOUNDED: undefined, + BOX_XY_PLANE: undefined, + BOX_XZ_PLANE: undefined, + BOX_YZ_PLANE: undefined, + }; } const scratchTranslation = new Cartesian3(); @@ -89,6 +102,7 @@ const scratchRotation = new Matrix3(); * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @returns {Boolean} Whether the shape is visible. */ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { //>>includeStart('debug', pragmas.debug); @@ -97,10 +111,29 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { Check.typeOf.object("maxBounds", maxBounds); //>>includeEnd('debug'); - // Don't render if any of the min bounds exceed the max bounds. - // Don't render if two of the min bounds equal the max bounds because it would be an invisible line. - // Don't render if all of the min bounds equal the max bounds because it would be an invisible point. - // Still render if one of the min bounds is equal to the max bounds because it will be a square/rectangle. + const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; + const defaultMaxBounds = VoxelBoxShape.DefaultMaxBounds; + + minBounds = this._minBounds = Cartesian3.clamp( + minBounds, + defaultMinBounds, + defaultMaxBounds, + this._minBounds + ); + + maxBounds = this._maxBounds = Cartesian3.clamp( + maxBounds, + defaultMinBounds, + defaultMaxBounds, + this._maxBounds + ); + + const scale = Matrix4.getScale(modelMatrix, scratchScale); + + // Not visible if: + // - any of the min bounds exceed the max bounds + // - two or more of the min bounds equal the max bounds (line and point respectively) + // - scale is 0 for any component if ( minBounds.x > maxBounds.x || minBounds.y > maxBounds.y || @@ -108,36 +141,23 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { (minBounds.x === maxBounds.x) + (minBounds.y === maxBounds.y) + (minBounds.z === maxBounds.z) >= - 2 + 2 || + scale.x === 0.0 || + scale.y === 0.0 || + scale.z === 0.0 ) { - this.isVisible = false; - return; + return false; } - // If two or more of the scales are 0 the shape will not render. - // If one of the scales is 0 it will still be visible but will appear as a square/rectangle. - const scale = Matrix4.getScale(modelMatrix, scratchScale); - if ((scale.x === 0.0) + (scale.y === 0.0) + (scale.z === 0.0) >= 2) { - this.isVisible = false; - return; - } - - this._minBounds = Cartesian3.clone(minBounds, this._minBounds); - this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); + this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); this.orientedBoundingBox = getBoxChunkObb( - minBounds.x, - maxBounds.x, - minBounds.y, - maxBounds.y, - minBounds.z, - maxBounds.z, - modelMatrix, + this._minBounds, + this._maxBounds, + this.shapeTransform, this.orientedBoundingBox ); - this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); - // All of the box bounds go from -1 to +1, so the model matrix scale can be // used as the oriented bounding box half axes. this.boundTransform = Matrix4.fromRotationTranslation( @@ -151,9 +171,31 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { this.boundingSphere ); - this.isVisible = true; + const shaderUniforms = this.shaderUniforms; + const shaderDefines = this.shaderDefines; + + shaderUniforms.minBounds = Cartesian3.clone( + minBounds, + shaderUniforms.minBounds + ); + shaderUniforms.maxBounds = Cartesian3.clone( + maxBounds, + shaderUniforms.maxBounds + ); + + const hasBounds = + !Cartesian3.equals(minBounds, defaultMinBounds) && + !Cartesian3.equals(maxBounds, defaultMaxBounds); + shaderDefines.BOX_BOUNDS = hasBounds ? 1 : undefined; + + return true; }; +const scratchMinBounds = new Cartesian3(); +const scratchMaxBounds = new Cartesian3(); +const scratchMinLerp = new Cartesian3(); +const scratchMaxLerp = new Cartesian3(); + /** * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. @@ -180,53 +222,33 @@ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( Check.typeOf.object("result", result); //>>includeEnd('debug'); - const rootTransform = this.shapeTransform; const sizeAtLevel = 1.0 / Math.pow(2, tileLevel); - const minBounds = this._minBounds; - const maxBounds = this._maxBounds; - - const minimumX = CesiumMath.lerp( - minBounds.x, - maxBounds.x, - sizeAtLevel * tileX - ); - const minimumY = CesiumMath.lerp( - minBounds.y, - maxBounds.y, - sizeAtLevel * tileY - ); - const minimumZ = CesiumMath.lerp( - minBounds.z, - maxBounds.z, - sizeAtLevel * tileZ - ); - const maximumX = CesiumMath.lerp( - minBounds.x, - maxBounds.x, - sizeAtLevel * (tileX + 1) - ); - const maximumY = CesiumMath.lerp( - minBounds.y, - maxBounds.y, - sizeAtLevel * (tileY + 1) - ); - const maximumZ = CesiumMath.lerp( - minBounds.z, - maxBounds.z, - sizeAtLevel * (tileZ + 1) + const minBounds = Cartesian3.lerp( + this._minBounds, + this._maxBounds, + Cartesian3.fromElements( + sizeAtLevel * tileX, + sizeAtLevel * tileY, + sizeAtLevel * tileZ, + scratchMinLerp + ), + scratchMinBounds ); - return getBoxChunkObb( - minimumX, - maximumX, - minimumY, - maximumY, - minimumZ, - maximumZ, - rootTransform, - result + const maxBounds = Cartesian3.lerp( + this._minBounds, + this._maxBounds, + Cartesian3.fromElements( + sizeAtLevel * (tileX + 1), + sizeAtLevel * (tileY + 1), + sizeAtLevel * (tileZ + 1), + scratchMaxLerp + ), + scratchMaxBounds ); + + return getBoxChunkObb(minBounds, maxBounds, this.shapeTransform, result); }; /** @@ -267,38 +289,21 @@ VoxelBoxShape.DefaultMaxBounds = new Cartesian3(+1.0, +1.0, +1.0); * * @function * - * @param {Number} minimumX The minimumX. - * @param {Number} maximumX The maximumX. - * @param {Number} minimumY The minimumY. - * @param {Number} maximumY The maximumY. - * @param {Number} minimumZ The minimumZ. - * @param {Number} maximumZ The maximumZ. + * @param {Number} minimumBounds The minimum bounds. + * @param {Number} maximumBounds The maximum bounds. * @param {Matrix4} matrix The matrix to transform the points. * @param {OrientedBoundingBox} result The object onto which to store the result. * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. * * @private */ -function getBoxChunkObb( - minimumX, - maximumX, - minimumY, - maximumY, - minimumZ, - maximumZ, - matrix, - result -) { +function getBoxChunkObb(minimumBounds, maximumBounds, matrix, result) { const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; const defaultMaxBounds = VoxelBoxShape.DefaultMaxBounds; const isDefaultBounds = - minimumX === defaultMinBounds.x && - minimumY === defaultMinBounds.y && - minimumZ === defaultMinBounds.z && - maximumX === defaultMaxBounds.x && - maximumY === defaultMaxBounds.y && - maximumZ === defaultMaxBounds.z; + Cartesian3.equals(minimumBounds, defaultMinBounds) && + Cartesian3.equals(maximumBounds, defaultMaxBounds); if (isDefaultBounds) { result.center = Matrix4.getTranslation(matrix, result.center); @@ -307,16 +312,15 @@ function getBoxChunkObb( let scale = Matrix4.getScale(matrix, scratchScale); const translation = Matrix4.getTranslation(matrix, scratchTranslation); result.center = Cartesian3.fromElements( - translation.x + scale.x * 0.5 * (minimumX + maximumX), - translation.y + scale.y * 0.5 * (maximumY + minimumY), - translation.z + scale.z * 0.5 * (maximumZ + minimumZ), + translation.x + scale.x * 0.5 * (minimumBounds.x + maximumBounds.x), + translation.y + scale.y * 0.5 * (maximumBounds.y + minimumBounds.y), + translation.z + scale.z * 0.5 * (maximumBounds.z + minimumBounds.z), result.center ); - scale = Cartesian3.fromElements( - scale.x * 0.5 * (maximumX - minimumX), - scale.y * 0.5 * (maximumY - minimumY), - scale.z * 0.5 * (maximumZ - minimumZ), + scale.x * 0.5 * (maximumBounds.x - minimumBounds.x), + scale.y * 0.5 * (maximumBounds.y - minimumBounds.y), + scale.z * 0.5 * (maximumBounds.z - minimumBounds.z), scratchScale ); const rotation = Matrix4.getRotation(matrix, scratchRotation); diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 41a5f5cd728..b8271a59621 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -1,5 +1,7 @@ import BoundingSphere from "../Core/BoundingSphere.js"; +import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; +import Cartesian4 from "../Core/Cartesian4.js"; import Check from "../Core/Check.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import CesiumMath from "../Core/Math.js"; @@ -54,14 +56,6 @@ function VoxelEllipsoidShape() { */ this.shapeTransform = new Matrix4(); - /** - * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. - * The update function must be called before accessing this value. - * @type {Boolean} - * @readonly - */ - this.isVisible = false; - /** * @type {Rectangle} */ @@ -94,31 +88,48 @@ function VoxelEllipsoidShape() { * @type {Matrix3 */ this._rotation = new Matrix3(); -} -/** - * @type {Cartesian3} - * @private - */ -VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( - -CesiumMath.PI, - -CesiumMath.PI_OVER_TWO, - 0.0 -); + /** + * @type {Object.} + * @readonly + */ + this.shaderUniforms = { + ellipsoidRectangle: new Cartesian4(), + ellipsoidRadiiUv: new Cartesian3(), + ellipsoidInverseRadiiSquaredUv: new Cartesian3(), + // Wedge uniforms + ellipsoidWestUv: 0.0, + ellipsoidInverseLongitudeRangeUv: 0.0, + // Cone uniforms + ellipsoidSouthUv: 0.0, + ellipsoidInverseLatitudeRangeUv: 0.0, + // Inner ellipsoid uniforms + ellipsoidInverseHeightDifferenceUv: 0.0, + ellipsoidInverseInnerScaleUv: 0.0, + ellipsoidInnerRadiiUv: new Cartesian3(), + }; -/** - * @type {Cartesian3} - * @private - */ -VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( - +CesiumMath.PI, - +CesiumMath.PI_OVER_TWO, - 1.0 -); + /** + * @type {Object.} + * @readonly + */ + this.shaderDefines = { + ELLIPSOID_WEDGE_REGULAR: undefined, + ELLIPSOID_WEDGE_FLIPPED: undefined, + ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, + ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, + ELLIPSOID_CONE_TOP_REGULAR: undefined, + ELLIPSOID_CONE_TOP_FLIPPED: undefined, + ELLIPSOID_OUTER: undefined, + ELLIPSOID_INNER: undefined, + ELLIPSOID_INTERSECTION_COUNT: undefined, + }; +} const scratchScale = new Cartesian3(); -const scratchFullScale = new Cartesian3(); const scratchRotationScale = new Matrix3(); +const scratchOuter = new Cartesian3(); +const scratchInner = new Cartesian3(); /** * Update the shape's state. @@ -126,6 +137,7 @@ const scratchRotationScale = new Matrix3(); * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @returns {Boolean} Whether the shape is visible. */ VoxelEllipsoidShape.prototype.update = function ( modelMatrix, @@ -138,70 +150,85 @@ VoxelEllipsoidShape.prototype.update = function ( Check.typeOf.object("maxBounds", maxBounds); //>>includeEnd('debug'); - // Don't let the scale be 0, it will screw up a bunch of math - const scaleEps = CesiumMath.EPSILON8; - const scale = Matrix4.getScale(modelMatrix, scratchScale); - if (Math.abs(scale.x) < scaleEps) { - scale.x = CesiumMath.signNotZero(scale.x) * scaleEps; - } - if (Math.abs(scale.y) < scaleEps) { - scale.y = CesiumMath.signNotZero(scale.y) * scaleEps; - } - if (Math.abs(scale.z) < scaleEps) { - scale.z = CesiumMath.signNotZero(scale.z) * scaleEps; - } + const defaultMinBounds = VoxelEllipsoidShape.DefaultMinBounds; + const defaultMaxBounds = VoxelEllipsoidShape.DefaultMaxBounds; - this._rectangle = Rectangle.fromRadians( + const west = CesiumMath.clamp( minBounds.x, - minBounds.y, + defaultMinBounds.x, + defaultMaxBounds.x + ); + const east = CesiumMath.clamp( maxBounds.x, - maxBounds.y + defaultMinBounds.x, + defaultMaxBounds.x + ); + const south = CesiumMath.clamp( + minBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + const north = CesiumMath.clamp( + maxBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y ); - const minHeight = minBounds.z; - const maxHeight = maxBounds.z; + // Don't let the height go below the center of the ellipsoid. + const radii = Matrix4.getScale(modelMatrix, scratchScale); + const minRadius = Cartesian3.minimumComponent(radii); + const minHeight = Math.max(minBounds.z, -minRadius); + const maxHeight = Math.max(maxBounds.z, -minRadius); + + // The closest and farthest a point can be from the center of the ellipsoid. + const innerExtent = Cartesian3.add( + radii, + Cartesian3.fromElements(minHeight, minHeight, minHeight, scratchInner), + scratchInner + ); + const outerExtent = Cartesian3.add( + radii, + Cartesian3.fromElements(maxHeight, maxHeight, maxHeight, scratchOuter), + scratchOuter + ); + const maxExtent = Cartesian3.maximumComponent(outerExtent); - // Exit early if the bounds make the shape invisible. + // Exit early if the shape is not visible. // Note that west may be greater than east when crossing the 180th meridian. - const rectangle = this._rectangle; - if (rectangle.south > rectangle.north || minHeight > maxHeight) { - this.isVisible = false; - return; + const absEpsilon = CesiumMath.EPSILON10; + if ( + south > north || + minHeight > maxHeight || + CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, absEpsilon) + ) { + return false; } + this._rectangle = Rectangle.fromRadians(west, south, east, north); this._translation = Matrix4.getTranslation(modelMatrix, this._translation); this._rotation = Matrix4.getRotation(modelMatrix, this._rotation); - this._ellipsoid = Ellipsoid.fromCartesian3(scale, this._ellipsoid); - - const fullScale = Cartesian3.add( - scale, - Cartesian3.fromElements(maxHeight, maxHeight, maxHeight, scratchFullScale), - scratchFullScale - ); - const rotationScale = Matrix3.setScale( - this._rotation, - fullScale, - scratchRotationScale - ); - this.shapeTransform = Matrix4.fromRotationTranslation( - rotationScale, - this._translation, - this.shapeTransform - ); + this._ellipsoid = Ellipsoid.fromCartesian3(radii, this._ellipsoid); + this._minimumHeight = minHeight; + this._maximumHeight = maxHeight; this.orientedBoundingBox = getEllipsoidChunkObb( - rectangle.west, - rectangle.east, - rectangle.south, - rectangle.north, - minHeight, - maxHeight, + this._rectangle, + this._minimumHeight, + this._maximumHeight, this._ellipsoid, this._translation, this._rotation, this.orientedBoundingBox ); + this.shapeTransform = Matrix4.fromRotationTranslation( + Matrix3.setScale(this._rotation, outerExtent, scratchRotationScale), + this._translation, + this.shapeTransform + ); + this.boundTransform = Matrix4.fromRotationTranslation( this.orientedBoundingBox.halfAxes, this.orientedBoundingBox.center, @@ -213,7 +240,120 @@ VoxelEllipsoidShape.prototype.update = function ( this.boundingSphere ); - this.isVisible = true; + const shaderUniforms = this.shaderUniforms; + const shaderDefines = this.shaderDefines; + + shaderUniforms.ellipsoidRectangle = Cartesian4.fromElements( + west, + south, + east, + north, + shaderUniforms.ellipsoidRectangle + ); + + // The ellipsoid radii scaled to [0,1]. The max ellipsoid radius will be 1.0 and others will be less. + shaderUniforms.ellipsoidRadiiUv = Cartesian3.divideByScalar( + outerExtent, + maxExtent, + shaderUniforms.ellipsoidRadiiUv + ); + + // Used to compute geodetic surface normal. + shaderUniforms.ellipsoidInverseRadiiSquaredUv = Cartesian3.divideComponents( + Cartesian3.ONE, + Cartesian3.multiplyComponents( + shaderUniforms.ellipsoidRadiiUv, + shaderUniforms.ellipsoidRadiiUv, + shaderUniforms.ellipsoidInverseRadiiSquaredUv + ), + shaderUniforms.ellipsoidInverseRadiiSquaredUv + ); + + const rectangleWidth = Rectangle.computeWidth(this._rectangle); + const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); + const hasWedgeRegular = + rectangleWidth >= CesiumMath.PI && rectangleWidth < CesiumMath.TWO_PI; + const hasWedgeFlipped = rectangleWidth < CesiumMath.PI; + const hasTopConeRegular = north >= 0.0 && north < +CesiumMath.PI_OVER_TWO; + const hasTopConeFlipped = north < 0.0; + const hasBottomConeRegular = south <= 0.0 && south > -CesiumMath.PI_OVER_TWO; + const hasBottomConeFlipped = south > 0.0; + + // Determine how many intersections there are going to be. + let intersectionCount = 0; + + // Intersects an outer ellipsoid for the max height. + shaderDefines["ELLIPSOID_OUTER"] = intersectionCount * 2; + intersectionCount += 1; + + // Intersects an inner ellipsoid for the min height. + if (hasInnerEllipsoid) { + shaderDefines["ELLIPSOID_INNER"] = intersectionCount * 2; + intersectionCount += 1; + + // The percent of space that is between the inner and outer ellipsoid. + const thickness = (maxHeight - minHeight) / maxExtent; + shaderUniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; + + // The percent of space that is taken up by the inner ellipsoid. + const innerScale = 1.0 - thickness; + shaderUniforms.ellipsoidInverseInnerScaleUv = 1.0 / innerScale; + + // The inner ellipsoid radii scaled to [0,innerScale]. The max inner ellipsoid radius will equal innerScale and others will be less. + shaderUniforms.ellipsoidInnerRadiiUv = Cartesian3.multiplyByScalar( + shaderUniforms.ellipsoidRadiiUv, + innerScale, + shaderUniforms.ellipsoidInnerRadiiUv + ); + } else { + shaderDefines["ELLIPSOID_INNER"] = undefined; + } + + // Intersects a wedge for the min and max longitude. + if (hasWedgeRegular) { + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; + intersectionCount += 1; + } else if (hasWedgeFlipped) { + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = intersectionCount * 2; + intersectionCount += 2; + } else { + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; + } + + // Intersects a cone for min latitude + if (hasBottomConeRegular) { + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; + intersectionCount += 1; + } else if (hasBottomConeFlipped) { + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = intersectionCount * 2; + intersectionCount += 2; + } else { + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; + } + + // Intersects a cone for max latitude + if (hasTopConeRegular) { + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; + intersectionCount += 1; + } else if (hasTopConeFlipped) { + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = intersectionCount * 2; + intersectionCount += 2; + } else { + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; + } + + shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = intersectionCount; + + return true; }; const scratchRectangle = new Rectangle(); @@ -274,10 +414,7 @@ VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( ); return getEllipsoidChunkObb( - rectangle.west, - rectangle.east, - rectangle.south, - rectangle.north, + rectangle, minHeight, maxHeight, this._ellipsoid, @@ -312,41 +449,12 @@ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( return stepSize; }; -/** - * Defines the minimum bounds of the shape. Corresponds to minimum longitude, latitude, height. - * - * @type {Cartesian3} - * @constant - * @readonly - */ -VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( - -CesiumMath.PI, - -CesiumMath.PI_OVER_TWO, - 0.0 // should be -1? -); - -/** - * Defines the maximum bounds of the shape. Corresponds to maximum longitude, latitude, height. - * - * @type {Cartesian3} - * @constant - * @readonly - */ -VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( - +CesiumMath.PI, - +CesiumMath.PI_OVER_TWO, - 1.0 // should be 0? -); - /** * Computes an {@link OrientedBoundingBox} for a subregion of the shape. * * @function * - * @param {Number} west The minimumX. - * @param {Number} east The maximumX. - * @param {Number} south The minimumY. - * @param {Number} north The maximumY. + * @param {Rectangle} rectangle The rectangle. * @param {Number} minHeight The minimumZ. * @param {Number} maxHeight The maximumZ. * @param {Ellipsoid} ellipsoid The ellipsoid. @@ -357,10 +465,7 @@ VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( * @private */ function getEllipsoidChunkObb( - west, - east, - south, - north, + rectangle, minHeight, maxHeight, ellipsoid, @@ -369,7 +474,7 @@ function getEllipsoidChunkObb( result ) { result = OrientedBoundingBox.fromRectangle( - Rectangle.fromRadians(west, south, east, north, scratchRectangle), + rectangle, minHeight, maxHeight, ellipsoid, @@ -384,4 +489,30 @@ function getEllipsoidChunkObb( return result; } +/** + * Defines the minimum bounds of the shape. Corresponds to minimum longitude, latitude, height. + * + * @type {Cartesian3} + * @constant + * @readonly + */ +VoxelEllipsoidShape.DefaultMinBounds = new Cartesian3( + -CesiumMath.PI, + -CesiumMath.PI_OVER_TWO, + -Number.MAX_VALUE +); + +/** + * Defines the maximum bounds of the shape. Corresponds to maximum longitude, latitude, height. + * + * @type {Cartesian3} + * @constant + * @readonly + */ +VoxelEllipsoidShape.DefaultMaxBounds = new Cartesian3( + +CesiumMath.PI, + +CesiumMath.PI_OVER_TWO, + +Number.MAX_VALUE +); + export default VoxelEllipsoidShape; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index e7a76ea8f5b..b27bca23c64 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -3,6 +3,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import Cartesian4 from "../Core/Cartesian4.js"; import CesiumMath from "../Core/Math.js"; import Check from "../Core/Check.js"; +import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defer from "../Core/defer.js"; @@ -102,6 +103,12 @@ function VoxelPrimitive(options) { */ this._shape = undefined; + /** + * @type {Boolean} + * @private + */ + this._shapeVisible = false; + /** * This member is not created until the provider is ready. * @@ -372,12 +379,11 @@ function VoxelPrimitive(options) { */ this._disableUpdate = false; - // Uniforms /** * @type {Object.} * @private */ - this._uniformMapValues = { + this._uniforms = { /** * @ignore * @type {Texture} @@ -414,37 +420,33 @@ function VoxelPrimitive(options) { cameraPositionUv: new Cartesian3(), ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), stepSize: 1.0, - ellipsoidInverseHeightDifferenceUv: 1.0, - ellipsoidInverseInnerScaleUv: 1.0, - ellipsoidRadiiUv: new Cartesian3(), - ellipsoidInnerRadiiUv: new Cartesian3(), - ellipsoidInverseRadiiSquaredUv: new Cartesian3(), - minBounds: new Cartesian3(), - maxBounds: new Cartesian3(), - minBoundsUv: new Cartesian3(), - maxBoundsUv: new Cartesian3(), - inverseBounds: new Cartesian3(), - inverseBoundsUv: new Cartesian3(), minClippingBounds: new Cartesian3(), maxClippingBounds: new Cartesian3(), pickColor: new Color(), }; - // Automatically generate uniform map from the uniform values /** + * Shape specific shader defines from the previous shape update. Used to detect if the shader needs to be rebuilt. + * @type {Object.} + * @private + */ + this._shapeDefinesOld = {}; + + /** + * Map uniform names to functions that return the uniform values. * @type {Object.} * @private */ this._uniformMap = {}; - const uniformMapValues = this._uniformMapValues; - function getUniformFunction(key) { - return function () { - return uniformMapValues[key]; - }; - } - for (const key in uniformMapValues) { - if (uniformMapValues.hasOwnProperty(key)) { - this._uniformMap[`u_${key}`] = getUniformFunction(key); + + const uniforms = this._uniforms; + const uniformMap = this._uniformMap; + for (const key in uniforms) { + if (uniforms.hasOwnProperty(key)) { + const name = `u_${key}`; + uniformMap[name] = function () { + return uniforms[key]; + }; } } @@ -1055,7 +1057,6 @@ const scratchTotalDimensions = new Cartesian3(); const scratchIntersect = new Cartesian4(); const scratchNdcAabb = new Cartesian4(); const scratchScale = new Cartesian3(); -const scratchEllipsoidRadii = new Cartesian3(); const scratchLocalScale = new Cartesian3(); const scratchInverseLocalScale = new Cartesian3(); const scratchRotation = new Matrix3(); @@ -1084,7 +1085,7 @@ const transformPositionUvToLocal = Matrix4.fromRotationTranslation( VoxelPrimitive.prototype.update = function (frameState) { const context = frameState.context; const provider = this._provider; - const uniforms = this._uniformMapValues; + const uniforms = this._uniforms; // Update the provider, if applicable. if (defined(provider.update)) { @@ -1110,12 +1111,8 @@ VoxelPrimitive.prototype.update = function (frameState) { this._pickId = context.createPickId({ primitive: this, }); - - // Set uniforms for picking uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - // Set member variables that come from the provider. - // const keyframeCount = defaultValue(provider.keyframeCount, 1); // // TODO remove? // that._keyframeCount = defaultValue( @@ -1130,15 +1127,12 @@ VoxelPrimitive.prototype.update = function (frameState) { const dimensions = provider.dimensions; const shapeType = provider.shape; + + // Set the bounds const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const minBounds = defaultValue(provider.minBounds, defaultMinBounds); const maxBounds = defaultValue(provider.maxBounds, defaultMaxBounds); - const minimumValues = provider.minimumValues; - const maximumValues = provider.maximumValues; - - const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); - this._shape = new ShapeConstructor(); this._minBounds = Cartesian3.clone(minBounds, this._minBounds); this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); this._minClippingBounds = Cartesian3.clone( @@ -1149,6 +1143,34 @@ VoxelPrimitive.prototype.update = function (frameState) { defaultMaxBounds, this._maxClippingBounds ); + + // Create the shape object + const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); + this._shape = new ShapeConstructor(); + + const shape = this._shape; + const shapeDefines = shape.shaderDefines; + this._shapeDefinesOld = clone(shapeDefines, true); + + // Add shape uniforms to the uniform map + const shapeUniforms = shape.shaderUniforms; + const uniformMap = this._uniformMap; + for (const key in shapeUniforms) { + if (shapeUniforms.hasOwnProperty(key)) { + const name = `u_${key}`; + + //>>includeStart('debug', pragmas.debug); + if (defined(uniformMap[name])) { + throw new DeveloperError(`Uniform name "${name}" is already defined`); + } + //>>includeEnd('debug'); + + uniformMap[name] = function () { + return shapeUniforms[key]; + }; + } + } + this._paddingBefore = Cartesian3.clone( defaultValue(provider.paddingBefore, Cartesian3.ZERO), this._paddingBefore @@ -1169,6 +1191,9 @@ VoxelPrimitive.prototype.update = function (frameState) { this._paddingAfter, uniforms.paddingAfter ); + + const minimumValues = provider.minimumValues; + const maximumValues = provider.maximumValues; if (defined(minimumValues) && defined(maximumValues)) { uniforms.minimumValues = minimumValues.slice(); uniforms.maximumValues = maximumValues.slice(); @@ -1178,336 +1203,124 @@ VoxelPrimitive.prototype.update = function (frameState) { // Check if the shape is dirty before updating it. This needs to happen every // frame because the member variables can be modified externally via the // getters. - const primitiveModelMatrix = this._modelMatrix; - const providerModelMatrix = defaultValue( + const primitiveTransform = this._modelMatrix; + const providerTransform = defaultValue( provider.modelMatrix, Matrix4.IDENTITY ); - const compoundModelMatrix = Matrix4.multiplyTransformation( - providerModelMatrix, - primitiveModelMatrix, + const compoundTransform = Matrix4.multiplyTransformation( + providerTransform, + primitiveTransform, this._compoundModelMatrix ); - const compoundModelMatrixOld = this._compoundModelMatrixOld; - const compoundModelMatrixDirty = !Matrix4.equals( - compoundModelMatrix, - compoundModelMatrixOld + const compoundTransformOld = this._compoundModelMatrixOld; + const compoundTransformDirty = !Matrix4.equals( + compoundTransform, + compoundTransformOld ); const shape = this._shape; const shapeType = provider.shape; - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); const minBounds = this._minBounds; const maxBounds = this._maxBounds; - - let isDefaultBoundsMin = - minBounds.x === defaultMinBounds.x && - minBounds.y === defaultMinBounds.y && - minBounds.z === defaultMinBounds.z; - - let isDefaultBoundsMax = - maxBounds.x === defaultMaxBounds.x && - maxBounds.y === defaultMaxBounds.y && - maxBounds.z === defaultMaxBounds.z; - - // Clamp the min bounds to the valid range. - if (!isDefaultBoundsMin) { - minBounds.x = CesiumMath.clamp( - minBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x - ); - minBounds.y = CesiumMath.clamp( - minBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y - ); - if (shapeType !== VoxelShapeType.ELLIPSOID) { - minBounds.z = CesiumMath.clamp( - minBounds.z, - defaultMinBounds.z, - defaultMaxBounds.z - ); - } - isDefaultBoundsMin = - minBounds.x === defaultMinBounds.x && - minBounds.y === defaultMinBounds.y && - minBounds.z === defaultMinBounds.z; - } - - // Clamp the max bounds to the valid range. - if (!isDefaultBoundsMax) { - maxBounds.x = CesiumMath.clamp( - maxBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x - ); - maxBounds.y = CesiumMath.clamp( - maxBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y - ); - if (shapeType !== VoxelShapeType.ELLIPSOID) { - maxBounds.z = CesiumMath.clamp( - maxBounds.z, - defaultMinBounds.z, - defaultMaxBounds.z - ); - } - isDefaultBoundsMax = - maxBounds.x === defaultMaxBounds.x && - maxBounds.y === defaultMaxBounds.y && - maxBounds.z === defaultMaxBounds.z; - } - const minBoundsOld = this._minBoundsOld; const maxBoundsOld = this._maxBoundsOld; const minBoundsDirty = !Cartesian3.equals(minBounds, minBoundsOld); const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); + const shapeDirty = compoundTransformDirty || minBoundsDirty || maxBoundsDirty; - const shapeIsDirty = - compoundModelMatrixDirty || minBoundsDirty || maxBoundsDirty; - - // Update the shape if dirty or the first frame. - if (!this._ready || shapeIsDirty) { - shape.update(compoundModelMatrix, minBounds, maxBounds); - - if (compoundModelMatrixDirty) { + // Update the shape on the first frame or if it's dirty. + // If the shape is visible it will do some extra work. + if ( + (!this._ready || shapeDirty) && + (this._shapeVisible = shape.update(compoundTransform, minBounds, maxBounds)) + ) { + if (compoundTransformDirty) { this._compoundModelMatrixOld = Matrix4.clone( - compoundModelMatrix, + compoundTransform, this._compoundModelMatrixOld ); } + if (minBoundsDirty) { + this._minBoundsOld = Cartesian3.clone(minBounds, this._minBoundsOld); + } + if (maxBoundsDirty) { + this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); + } - if (minBoundsDirty || maxBoundsDirty) { - if (minBoundsDirty) { - // Check if the min bounds became default or stopped being default - if ( - (minBounds.x === defaultMinBounds.x) !== - (minBoundsOld.x === defaultMinBounds.x) || - (minBounds.y === defaultMinBounds.y) !== - (minBoundsOld.y === defaultMinBounds.y) || - (minBounds.z === defaultMinBounds.z) !== - (minBoundsOld.z === defaultMinBounds.z) - ) { - this._shaderDirty = true; - } - this._minBoundsOld = Cartesian3.clone(minBounds, this._minBoundsOld); - } - - if (maxBoundsDirty) { - // Check if the max bounds became default or stopped being default - if ( - (maxBounds.x === defaultMaxBounds.x) !== - (maxBoundsOld.x === defaultMaxBounds.x) || - (maxBounds.y === defaultMaxBounds.y) !== - (maxBoundsOld.y === defaultMaxBounds.y) || - (maxBounds.z === defaultMaxBounds.z) !== - (maxBoundsOld.z === defaultMaxBounds.z) - ) { - this._shaderDirty = true; - } - this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); - } - - // Set uniforms for bounds. - if (!isDefaultBoundsMin || !isDefaultBoundsMax) { - uniforms.minBounds = Cartesian3.clone(minBounds, uniforms.minBounds); - uniforms.maxBounds = Cartesian3.clone(maxBounds, uniforms.maxBounds); - uniforms.inverseBounds = Cartesian3.divideComponents( - Cartesian3.ONE, - Cartesian3.subtract(maxBounds, minBounds, uniforms.inverseBounds), - uniforms.inverseBounds - ); - - if (shapeType === VoxelShapeType.BOX) { - const minXUv = minBounds.x * 0.5 + 0.5; - const maxXUv = maxBounds.x * 0.5 + 0.5; - const minYUv = minBounds.y * 0.5 + 0.5; - const maxYUv = maxBounds.y * 0.5 + 0.5; - const minZUv = minBounds.z * 0.5 + 0.5; - const maxZUv = maxBounds.z * 0.5 + 0.5; - uniforms.minBoundsUv = Cartesian3.fromElements( - minXUv, - minYUv, - minZUv, - uniforms.minBoundsUv - ); - uniforms.maxBoundsUv = Cartesian3.fromElements( - maxXUv, - maxYUv, - maxZUv, - uniforms.maxBoundsUv - ); - } else if (shapeType === VoxelShapeType.ELLIPSOID) { - const minLongitudeUv = - (minBounds.x - defaultMinBounds.x) / - (defaultMaxBounds.x - defaultMinBounds.x); - const maxLongitudeUv = - (maxBounds.x - defaultMinBounds.x) / - (defaultMaxBounds.x - defaultMinBounds.x); - const minLatitudeUv = - (minBounds.y - defaultMinBounds.y) / - (defaultMaxBounds.y - defaultMinBounds.y); - const maxLatitudeUv = - (maxBounds.y - defaultMinBounds.y) / - (defaultMaxBounds.y - defaultMinBounds.y); - const minHeightUv = 0.0; // don't know what to do with these yet - const maxHeightUv = 0.0; // don't know what to do with these yet - - uniforms.minBoundsUv = Cartesian3.fromElements( - minLongitudeUv, - minLatitudeUv, - minHeightUv, - uniforms.minBoundsUv - ); - uniforms.maxBoundsUv = Cartesian3.fromElements( - maxLongitudeUv, - maxLatitudeUv, - maxHeightUv, - uniforms.maxBoundsUv - ); - } else if (shapeType === VoxelShapeType.CYLINDER) { - const minRadiusUv = minBounds.x; - const maxRadiusUv = maxBounds.x; - const minHeightUv = minBounds.y * 0.5 + 0.5; - const maxHeightUv = maxBounds.y * 0.5 + 0.5; - const minAngleUv = (minBounds.z + CesiumMath.PI) / CesiumMath.TWO_PI; - const maxAngleUv = (maxBounds.z + CesiumMath.PI) / CesiumMath.TWO_PI; - uniforms.minBoundsUv = Cartesian3.fromElements( - minRadiusUv, - minHeightUv, - minAngleUv, - uniforms.minBoundsUv - ); - uniforms.maxBoundsUv = Cartesian3.fromElements( - maxRadiusUv, - maxHeightUv, - maxAngleUv, - uniforms.maxBoundsUv - ); + // Rebuild the shader if any of the shape defines changed. + const shapeDefines = shape.shaderDefines; + const shapeDefinesOld = this._shapeDefinesOld; + let shapeDefinesChanged = false; + for (const property in shapeDefines) { + if (shapeDefines.hasOwnProperty(property)) { + const value = shapeDefines[property]; + const valueOld = shapeDefinesOld[property]; + if (value !== valueOld) { + shapeDefinesChanged = true; + break; } - - uniforms.inverseBoundsUv = Cartesian3.divideComponents( - Cartesian3.ONE, - Cartesian3.subtract( - uniforms.maxBoundsUv, - uniforms.minBoundsUv, - uniforms.inverseBoundsUv - ), - uniforms.inverseBoundsUv - ); } } - - // Set other uniforms when the shape is dirty - if (shapeType === VoxelShapeType.ELLIPSOID) { - const radii = Matrix4.getScale( - compoundModelMatrix, - scratchEllipsoidRadii - ); - const minHeight = minBounds.z; - const maxHeight = maxBounds.z; - // The farthest distance a point can be from the center of the ellipsoid. - const maxExtent = Cartesian3.maximumComponent(radii) + maxHeight; - // The percent of space that is between the inner and outer ellipsoid - const thickness = (maxHeight - minHeight) / maxExtent; - // The percent of space that is taken up by the inner ellipsoid. - const innerScale = 1.0 - thickness; - - // The ellipsoid radii scaled to [0,1]. The max ellipsoid radius will be 1.0 and others will be less. - uniforms.ellipsoidRadiiUv = Cartesian3.fromElements( - (radii.x + maxHeight) / maxExtent, - (radii.y + maxHeight) / maxExtent, - (radii.z + maxHeight) / maxExtent, - uniforms.ellipsoidRadiiUv - ); - - // The inner ellipsoid radii scaled to [0,innerScale]. The max inner ellipsoid radius will be innerScale and others will be less. - uniforms.ellipsoidInnerRadiiUv = Cartesian3.multiplyByScalar( - uniforms.ellipsoidRadiiUv, - innerScale, - uniforms.ellipsoidInnerRadiiUv - ); - - // Used to compute geodetic surface normal. - uniforms.ellipsoidInverseRadiiSquaredUv = Cartesian3.divideComponents( - Cartesian3.ONE, - Cartesian3.multiplyComponents( - uniforms.ellipsoidRadiiUv, - uniforms.ellipsoidRadiiUv, - uniforms.ellipsoidInverseRadiiSquaredUv - ), - uniforms.ellipsoidInverseRadiiSquaredUv - ); - uniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; - uniforms.ellipsoidInverseInnerScaleUv = 1.0 / innerScale; + if (shapeDefinesChanged) { + this._shaderDirty = true; + this._shapeDefinesOld = clone(shapeDefines, true); } - // Math that's only valid if the shape is visible. - if (shape.isVisible) { - const transformPositionLocalToWorld = shape.shapeTransform; - const transformPositionWorldToLocal = Matrix4.inverse( - transformPositionLocalToWorld, - scratchTransformPositionWorldToLocal - ); - const rotation = Matrix4.getRotation( - transformPositionLocalToWorld, - scratchRotation - ); - // Note that inverse(rotation) is the same as transpose(rotation) - const inverseRotation = Matrix3.transpose( - rotation, - scratchInverseRotation - ); - const scale = Matrix4.getScale( - transformPositionLocalToWorld, - scratchScale - ); - const maximumScaleComponent = Cartesian3.maximumComponent(scale); - const localScale = Cartesian3.divideByScalar( - scale, - maximumScaleComponent, - scratchLocalScale - ); - const inverseLocalScale = Cartesian3.divideComponents( - Cartesian3.ONE, - localScale, - scratchInverseLocalScale - ); - const rotationAndLocalScale = Matrix3.multiplyByScale( - rotation, - localScale, - scratchRotationAndLocalScale - ); + const transformPositionLocalToWorld = shape.shapeTransform; + const transformPositionWorldToLocal = Matrix4.inverse( + transformPositionLocalToWorld, + scratchTransformPositionWorldToLocal + ); + const rotation = Matrix4.getRotation( + transformPositionLocalToWorld, + scratchRotation + ); + // Note that inverse(rotation) is the same as transpose(rotation) + const inverseRotation = Matrix3.transpose(rotation, scratchInverseRotation); + const scale = Matrix4.getScale(transformPositionLocalToWorld, scratchScale); + const maximumScaleComponent = Cartesian3.maximumComponent(scale); + const localScale = Cartesian3.divideByScalar( + scale, + maximumScaleComponent, + scratchLocalScale + ); + const inverseLocalScale = Cartesian3.divideComponents( + Cartesian3.ONE, + localScale, + scratchInverseLocalScale + ); + const rotationAndLocalScale = Matrix3.multiplyByScale( + rotation, + localScale, + scratchRotationAndLocalScale + ); - // Set member variables when the shape is dirty - const dimensions = provider.dimensions; - this._stepSizeUv = shape.computeApproximateStepSize(dimensions); - this._transformPositionWorldToUv = Matrix4.multiply( - transformPositionLocalToUv, - transformPositionWorldToLocal, - this._transformPositionWorldToUv - ); - this._transformPositionUvToWorld = Matrix4.multiply( - transformPositionLocalToWorld, - transformPositionUvToLocal, - this._transformPositionUvToWorld - ); - this._transformDirectionWorldToLocal = Matrix3.setScale( - inverseRotation, - inverseLocalScale, - this._transformDirectionWorldToLocal - ); - this._transformNormalLocalToWorld = Matrix3.inverseTranspose( - rotationAndLocalScale, - this._transformNormalLocalToWorld - ); - } + // Set member variables when the shape is dirty + const dimensions = provider.dimensions; + this._stepSizeUv = shape.computeApproximateStepSize(dimensions); + this._transformPositionWorldToUv = Matrix4.multiply( + transformPositionLocalToUv, + transformPositionWorldToLocal, + this._transformPositionWorldToUv + ); + this._transformPositionUvToWorld = Matrix4.multiply( + transformPositionLocalToWorld, + transformPositionUvToLocal, + this._transformPositionUvToWorld + ); + this._transformDirectionWorldToLocal = Matrix3.setScale( + inverseRotation, + inverseLocalScale, + this._transformDirectionWorldToLocal + ); + this._transformNormalLocalToWorld = Matrix3.inverseTranspose( + rotationAndLocalScale, + this._transformNormalLocalToWorld + ); } - // Initialize the voxel traversal now that the shape is ready to use. This only happens once. + // Initialize from the ready shape. This only happens once. if (!this._ready) { const dimensions = provider.dimensions; const paddingBefore = this._paddingBefore; @@ -1547,6 +1360,7 @@ VoxelPrimitive.prototype.update = function (frameState) { ); // Set uniforms that come from the traversal. + // TODO: should this be done in VoxelTraversal? const traversal = this._traversal; const useLeafNodeTexture = traversal.useLeafNodeTexture; @@ -1594,11 +1408,18 @@ VoxelPrimitive.prototype.update = function (frameState) { megatexture.regionSizeUv, uniforms.megatextureTileSizeUv ); - } else if (shape.isVisible) { - // Find the keyframe location to render at. Doesn't need to be a whole number. - let keyframeLocation = 0.0; + } + + // Update the traversal and prepare for rendering. + // This doesn't happen on the first update frame. It needs to wait until the + // primitive is made ready after the end of the first update frame. + if (this._ready && this._shapeVisible) { + const traversal = this._traversal; const clock = this._clock; const timeIntervalCollection = this._timeIntervalCollection; + + // Find the keyframe location to render at. Doesn't need to be a whole number. + let keyframeLocation = 0.0; if (defined(timeIntervalCollection) && defined(clock)) { let date = clock.currentTime; let timeInterval; @@ -1634,12 +1455,10 @@ VoxelPrimitive.prototype.update = function (frameState) { } // Update the voxel traversal - const traversal = this._traversal; - const hasLoadedData = traversal.update( frameState, keyframeLocation, - shapeIsDirty, // recomputeBoundingVolumes + shapeDirty, // recomputeBoundingVolumes this._disableUpdate // pauseUpdate ); @@ -1654,6 +1473,9 @@ VoxelPrimitive.prototype.update = function (frameState) { const minClip = this._minClippingBounds; const maxClip = this._maxClippingBounds; + const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); + const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); + let isDefaultClippingBoundsMin = minClip.x === defaultMinBounds.x && minClip.y === defaultMinBounds.y && @@ -1808,7 +1630,6 @@ VoxelPrimitive.prototype.update = function (frameState) { const cameraPositionWorld = frameState.camera.positionWC; // Update uniforms that can change every frame - const uniforms = this._uniformMapValues; uniforms.transformPositionViewToUv = Matrix4.multiply( transformPositionWorldToUv, transformPositionViewToWorld, @@ -1975,12 +1796,10 @@ function buildDrawCommands(that, context) { const useLogDepth = that._useLogDepth; const paddingBefore = that.paddingBefore; const paddingAfter = that.paddingAfter; - const minBounds = that._minBounds; - const maxBounds = that._maxBounds; + const shape = that._shape; + const shapeDefines = shape.shaderDefines; const minimumValues = provider.minimumValues; const maximumValues = provider.maximumValues; - const minClippingBounds = that._minClippingBounds; - const maxClippingBounds = that._maxClippingBounds; const keyframeCount = that._keyframeCount; const despeckle = that._despeckle; const jitter = that._jitter; @@ -2077,195 +1896,35 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); - const isDefaultMinX = minBounds.x === defaultMinBounds.x; - const isDefaultMinY = minBounds.y === defaultMinBounds.y; - const isDefaultMinZ = minBounds.z === defaultMinBounds.z; - const isDefaultMaxX = maxBounds.x === defaultMaxBounds.x; - const isDefaultMaxY = maxBounds.y === defaultMaxBounds.y; - const isDefaultMaxZ = maxBounds.z === defaultMaxBounds.z; - - let useBounds = false; - if (shapeType === VoxelShapeType.BOX) { - useBounds = - !isDefaultMinX || - !isDefaultMaxX || - !isDefaultMinY || - !isDefaultMaxY || - !isDefaultMinZ || - !isDefaultMaxZ; - } else if (shapeType === VoxelShapeType.CYLINDER) { - useBounds = - !isDefaultMinX || - !isDefaultMaxX || - !isDefaultMinY || - !isDefaultMaxY || - !isDefaultMinZ || - !isDefaultMaxZ; - } else if (shapeType === VoxelShapeType.ELLIPSOID) { - const radii = Matrix4.getScale(that._compoundModelMatrix, scratchScale); - const hasInnerEllipsoid = !( - radii.x === radii.y && - radii.y === radii.z && - minBounds.z === -radii.x - ); - useBounds = - !isDefaultMinX || - !isDefaultMaxX || - !isDefaultMinY || - !isDefaultMaxY || - hasInnerEllipsoid; - } - - if (useBounds) { - shaderBuilder.addDefine("BOUNDS", undefined, ShaderDestination.FRAGMENT); - } - if (!isDefaultMinX) { - shaderBuilder.addDefine( - "BOUNDS_0_MIN", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (!isDefaultMaxX) { - shaderBuilder.addDefine( - "BOUNDS_0_MAX", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (!isDefaultMinY) { - shaderBuilder.addDefine( - "BOUNDS_1_MIN", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (!isDefaultMaxY) { - shaderBuilder.addDefine( - "BOUNDS_1_MAX", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (!isDefaultMinZ) { - shaderBuilder.addDefine( - "BOUNDS_2_MIN", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (!isDefaultMaxZ) { - shaderBuilder.addDefine( - "BOUNDS_2_MAX", - undefined, - ShaderDestination.FRAGMENT - ); - } - let intersectionCount = 0; - if (shapeType === VoxelShapeType.BOX) { - // A bounded box is still a box, so it has the same number of shape intersections: 1 - intersectionCount = 1; - } else if (shapeType === VoxelShapeType.ELLIPSOID) { - // Intersects an outer ellipsoid for the max radius - { - shaderBuilder.addDefine( - "BOUNDS_2_MAX_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects an inner ellipsoid for the min radius - if (!isDefaultMinZ) { - shaderBuilder.addDefine( - "BOUNDS_2_MIN_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects a cone for min latitude - if (!isDefaultMinY) { - shaderBuilder.addDefine( - "BOUNDS_1_MIN_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects a cone for max latitude - if (!isDefaultMaxY) { - shaderBuilder.addDefine( - "BOUNDS_1_MAX_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects a wedge for the min and max longitude - if (!isDefaultMinX || !isDefaultMaxX) { - shaderBuilder.addDefine( - "BOUNDS_0_MIN_MAX_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - } else if (shapeType === VoxelShapeType.CYLINDER) { - // Intersects a capped cylinder for the max radius - // The min and max height are handled as part of the capped cylinder intersection - { - shaderBuilder.addDefine( - "BOUNDS_0_MAX_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects an inner infinite cylinder for the min radius - if (!isDefaultMinX) { - shaderBuilder.addDefine( - "BOUNDS_0_MIN_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; - } - // Intersects a wedge for the min and max theta - if (!isDefaultMinZ || !isDefaultMaxZ) { - shaderBuilder.addDefine( - "BOUNDS_2_MIN_MAX_IDX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount++; + // Shape specific defines + for (const key in shapeDefines) { + if (shapeDefines.hasOwnProperty(key)) { + const value = shapeDefines[key]; + if (defined(value)) { + shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); + } } } - // The intersection count is multiplied by 2 because there is an enter and exit for each intersection - shaderBuilder.addDefine( - "SHAPE_INTERSECTION_COUNT", - intersectionCount * 2, - ShaderDestination.FRAGMENT - ); - const useClippingBounds = - minClippingBounds.x !== defaultMinBounds.x || - minClippingBounds.y !== defaultMinBounds.y || - minClippingBounds.z !== defaultMinBounds.z || - maxClippingBounds.x !== defaultMaxBounds.x || - maxClippingBounds.y !== defaultMaxBounds.y || - maxClippingBounds.z !== defaultMaxBounds.z; - if (useClippingBounds) { - shaderBuilder.addDefine( - "CLIPPING_BOUNDS", - undefined, - ShaderDestination.FRAGMENT - ); - } + + // const useClippingBounds = + // minClippingBounds.x !== defaultMinBounds.x || + // minClippingBounds.y !== defaultMinBounds.y || + // minClippingBounds.z !== defaultMinBounds.z || + // maxClippingBounds.x !== defaultMaxBounds.x || + // maxClippingBounds.y !== defaultMaxBounds.y || + // maxClippingBounds.z !== defaultMaxBounds.z; + // if (useClippingBounds) { + // shaderBuilder.addDefine( + // "CLIPPING_BOUNDS", + // undefined, + // ShaderDestination.FRAGMENT + // ); + // } // Fragment shader uniforms + // The reason this uniform is added by shader builder is because some of the + // dynamically generated shader code reads from it. shaderBuilder.addUniform( "sampler2D", "u_megatextureTextures[METADATA_COUNT]", diff --git a/Source/Scene/VoxelShape.js b/Source/Scene/VoxelShape.js index 0264d5a3b8b..4291a2563d3 100644 --- a/Source/Scene/VoxelShape.js +++ b/Source/Scene/VoxelShape.js @@ -68,14 +68,18 @@ Object.defineProperties(VoxelShape.prototype, { }, /** - * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. - * The update function must be called before accessing this value. - * - * @memberof VoxelShape.prototype - * @type {Boolean} + * @type {Object.} + * @readonly + */ + shaderUniforms: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * @type {Object.} * @readonly */ - isVisible: { + shaderDefines: { get: DeveloperError.throwInstantiationError, }, }); @@ -86,6 +90,7 @@ Object.defineProperties(VoxelShape.prototype, { * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @returns {Boolean} Whether the shape is visible. */ VoxelShape.prototype.update = DeveloperError.throwInstantiationError; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index d99e412cf1a..21d2f3e5150 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -50,7 +50,7 @@ function VoxelTraversal( maximumTextureMemoryByteLength ) { /** - * TODO: maybe this shouldn't be stored? + * TODO: maybe this shouldn't be stored or passed into update function? * @type {VoxelPrimitive} * @private */ diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 1d05d5024f0..bad0f04fce0 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -9,7 +9,6 @@ Below is an example of how this code might look. Properties like "temperature" a #define SHAPE_BOX #define SHAPE_ELLIPSOID #define SHAPE_CYLINDER -#define SHAPE_INTERSECTION_COUNT ### #define MEGATEXTURE_2D #define MEGATEXTURE_3D #define DEPTH_TEST @@ -136,21 +135,26 @@ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { #define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops #define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0 -#define NO_HIT -czm_infinity -#define INF_HIT czm_infinity -#if defined(MEGATEXTURE_2D) -uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions -uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions -uniform vec2 u_megatextureVoxelSizeUv; -uniform vec2 u_megatextureSliceSizeUv; -uniform vec2 u_megatextureTileSizeUv; -#endif +#define NO_HIT (-czm_infinity) +#define INF_HIT (czm_infinity * 0.5) +#define POSITIVE_ENTRY 0.0 +#define POSITIVE_EXIT 1.0 +#define NEGATIVE_ENTRY 2.0 +#define NEGATIVE_EXIT 3.0 uniform ivec3 u_dimensions; // does not include padding #if defined(PADDING) -uniform ivec3 u_paddingBefore; -uniform ivec3 u_paddingAfter; + uniform ivec3 u_paddingBefore; + uniform ivec3 u_paddingAfter; +#endif + +#if defined(MEGATEXTURE_2D) + uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions + uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions + uniform vec2 u_megatextureVoxelSizeUv; + uniform vec2 u_megatextureSliceSizeUv; + uniform vec2 u_megatextureTileSizeUv; #endif uniform sampler2D u_octreeInternalNodeTexture; @@ -160,6 +164,19 @@ uniform sampler2D u_octreeLeafNodeTexture; uniform vec2 u_octreeLeafNodeTexelSizeUv; uniform int u_octreeLeafNodeTilesPerRow; +struct OctreeNodeData { + int data; + int flag; +}; + +struct SampleData { + int megatextureIndex; + int levelsAbove; + #if (SAMPLE_COUNT > 1) + float weight; + #endif +}; + uniform mat4 u_transformPositionViewToUv; uniform mat4 u_transformPositionUvToView; uniform mat3 u_transformDirectionViewToLocal; @@ -167,43 +184,90 @@ uniform mat3 u_transformNormalLocalToWorld; uniform vec3 u_cameraPositionUv; uniform float u_stepSize; -#if defined(BOUNDS) -uniform vec3 u_minBounds; // Bounds from the voxel primitive -uniform vec3 u_maxBounds; // Bounds from the voxel primitive -uniform vec3 u_minBoundsUv; // Similar to u_minBounds but relative to UV space [0,1] -uniform vec3 u_maxBoundsUv; // Similar to u_maxBounds but relative to UV space [0,1] -uniform vec3 u_inverseBounds; // Equal to 1.0 / (u_maxBounds - u_minBounds) -uniform vec3 u_inverseBoundsUv; // Equal to 1.0 / (u_maxBoundsUv - u_minBoundsUv) +#if defined(PICKING) + uniform vec4 u_pickColor; #endif #if defined(CLIPPING_BOUNDS) -uniform vec3 u_minClippingBounds; -uniform vec3 u_maxClippingBounds; + uniform vec3 u_minClippingBounds; + uniform vec3 u_maxClippingBounds; +#endif + +#if defined(SHAPE_BOX) + #define BOX_INTERSECTION_COUNT 1 + uniform vec2 u_boxMinBounds; + uniform vec2 u_boxMaxBounds; #endif #if defined(SHAPE_ELLIPSOID) -uniform float u_ellipsoidInverseHeightDifferenceUv; -uniform float u_ellipsoidInverseInnerScaleUv; -uniform vec3 u_ellipsoidRadiiUv; // [0,1] -uniform vec3 u_ellipsoidInnerRadiiUv; // [0,1] -uniform vec3 u_ellipsoidInverseRadiiSquaredUv; + /* Ellipsoid defines: + #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge + #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone + #define ELLIPSOID_CONE_BOTTOM_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_TOP_REGULAR ### // when there's a top cone + #define ELLIPSOID_CONE_TOP_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_INNER ### // when there's an inner ellipsoid + #define ELLIPSOID_OUTER ### // outer ellipsoid - always defined + #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections + */ + + // Ellipsoid uniforms + uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. + uniform vec3 u_ellipsoidRadiiUv; // [0,1] + uniform vec3 u_ellipsoidInverseRadiiSquaredUv; + + #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) + uniform float u_ellipsoidWestUv; + uniform float u_ellipsoidInverseLongitudeRangeUv; + #endif + #if defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + uniform float u_ellipsoidSouthUv; + uniform float u_ellipsoidInverseLatitudeRangeUv; + #endif + #if defined(ELLIPSOID_INNER) + uniform float u_ellipsoidInverseHeightDifferenceUv; + uniform float u_ellipsoidInverseInnerScaleUv; + uniform vec3 u_ellipsoidInnerRadiiUv; // [0,1] + #endif #endif -#if defined(PICKING) -uniform vec4 u_pickColor; +#if defined(SHAPE_CYLINDER) + /* Cylinder defines: + #define CYLINDER_INNER ### // when there's an inner cylinder + #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge + #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections + */ + + #if defined(CYLINDER_INNER) + uniform float u_something; + #endif + #if defined(CYLINDER_WEDGE_REGULAR) || defined(CYLINDER_WEDGE_FLIPPED) + uniform float u_cylinderMinAngle; + uniform float u_cylinderInverseAngleRange; + #endif #endif -struct OctreeNodeData { - int data; - int flag; -}; +// Determine how many intersections there are going to be +#if defined(SHAPE_BOX) + #define SHAPE_INTERSECTION_COUNT BOX_INTERSECTION_COUNT +#elif defined(SHAPE_ELLIPSOID) + #define SHAPE_INTERSECTION_COUNT ELLIPSOID_INTERSECTION_COUNT +#elif defined(SHAPE_CYLINDER) + #define SHAPE_INTERSECTION_COUNT CYLINDER_INTERSECTION_COUNT +#endif -struct SampleData { - int megatextureIndex; - int levelsAbove; - #if (SAMPLE_COUNT > 1) - float weight; - #endif +#if defined(DEPTH_TEST) + #define DEPTH_INTERSECTION_IDX (SHAPE_INTERSECTION_COUNT * 2) + #define SCENE_INTERSECTION_COUNT (SHAPE_INTERSECTION_COUNT + 1) +#else + #define SCENE_INTERSECTION_COUNT SHAPE_INTERSECTION_COUNT +#endif + +struct Intersections { + vec2 intersections[SCENE_INTERSECTION_COUNT * 2]; + int index; }; struct Ray { @@ -267,75 +331,6 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) // -------------------------------------------------------- // Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- -#if (defined(SHAPE_ELLIPSOID) || defined(SHAPE_CYLINDER)) && defined(BOUNDS) -vec2 resolveIntersections(vec2 intersections[SHAPE_INTERSECTION_COUNT]) -{ - // TODO: completely skip shape if both of its Ts are below 0.0? - vec2 entryExitT = vec2(NO_HIT, NO_HIT); - - // Sort the intersections from min T to max T with bubble sort. - // Note: If this sorting function changes, some of the intersection test may - // need to be updated. Search for "bubble sort" to find those areas. - - const int sortPasses = SHAPE_INTERSECTION_COUNT - 1; - for (int n = sortPasses; n > 0; --n) - { - for (int i = 0; i < sortPasses; ++i) - { - // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to break early instead - if (i >= n) { break; } - - vec2 intersect0 = intersections[i]; - vec2 intersect1 = intersections[i+1]; - - float idx0 = intersect0.x; - float idx1 = intersect1.x; - float t0 = intersect0.y; - float t1 = intersect1.y; - - float tmin = min(t0, t1); - float tmax = max(t0, t1); - float idxmin = tmin == t0 ? idx0 : idx1; - float idxmax = tmin == t0 ? idx1 : idx0; - - intersections[i] = vec2(idxmin, tmin); - intersections[i+1] = vec2(idxmax, tmax); - } - } - - int surroundCount = 0; - bool surroundIsPositive = false; - for (int i = 0; i < SHAPE_INTERSECTION_COUNT; i++) - { - vec2 entry = intersections[i]; - float idx = entry.x; - float t = entry.y; - - bool currShapeIsPositive = idx <= 1.0; - bool enter = mod(idx, 2.0) == 0.0; - - surroundCount += enter ? +1 : -1; - surroundIsPositive = currShapeIsPositive ? enter : surroundIsPositive; - - // entering positive or exiting negative - if (surroundCount == 1 && surroundIsPositive && enter == currShapeIsPositive) { - entryExitT.x = t; - } - - // exiting positive or entering negative after being inside positive - // TODO: Can this be simplified? - if ((!enter && currShapeIsPositive && surroundCount == 0) || (enter && !currShapeIsPositive && surroundCount == 2 && surroundIsPositive)) { - entryExitT.y = t; - - // entry and exit have been found, so the loop can stop - break; - } - } - return entryExitT; -} -#endif - #if defined(SHAPE_BOX) // Unit cube from [-1, +1] vec2 intersectUnitCube(Ray ray) @@ -353,7 +348,7 @@ vec2 intersectUnitCube(Ray ray) float tMax = min(min(m1.x, m1.y), m1.z); if (tMin >= tMax) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } return vec2(tMin, tMax); @@ -369,7 +364,7 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] float t = -o.z / d.z; vec2 planePos = o.xy + d.xy * t; if (any(greaterThan(abs(planePos), vec2(1.0)))) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } return vec2(t, t); @@ -377,9 +372,9 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] #endif #if defined(SHAPE_BOX) -vec2 intersectBoxShape(Ray ray) +vec2 intersectBoxShape(Ray ray, out Intersections ix) { - #if defined(BOUNDS) + #if defined(BOX_BOUNDED) vec3 pos = 0.5 * (u_minBounds + u_maxBounds); vec3 scale = 0.5 * (u_maxBounds - u_minBounds); @@ -408,13 +403,14 @@ vec2 intersectBoxShape(Ray ray) Ray unitRay = Ray((ray.pos - pos) / scale, ray.dir / scale); return intersectUnitCube(unitRay); } - #else - return intersectUnitCube(ray); #endif + + return intersectUnitCube(ray); + } #endif -#if ((defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX)) || defined(SHAPE_CYLINDER) && (defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX)))) +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_REGULAR)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_REGULAR)) vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) { vec2 o = ray.pos.xy; @@ -436,22 +432,33 @@ vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) float tmax = max(t1, t2); float smin = tmin == t1 ? s1 : s2; float smax = tmin == t1 ? s2 : s1; - + bool e = tmin >= 0.0; bool f = tmax >= 0.0; bool g = smin >= 0.0; bool h = smax >= 0.0; - - // if () return vec2(tmin, tmax); - // else if () return vec2(-INF_HIT, tmin); - // else if () return vec2(-INF_HIT, tmax); - // else if () return vec2(tmax, +INF_HIT); - // else return vec2(NO_HIT, NO_HIT); - + if (e != g && f == h) return vec2(tmin, tmax); else if (e == g && f == h) return vec2(-INF_HIT, tmin); else if (e != g && f != h) return vec2(tmax, +INF_HIT); - else return vec2(NO_HIT, NO_HIT); + else return vec2(NO_HIT); +} +#endif + +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) +vec2 intersectHalfSpace(Ray ray, float angle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n = vec2(sin(angle), -cos(angle)); + + float a = dot(o, n); + float b = dot(d, n); + float t = -a / b; + float s = sign(a); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); } #endif @@ -466,7 +473,7 @@ vec2 intersectUnitSphere(Ray ray) float det = b * b - c; if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } det = sqrt(det); @@ -491,7 +498,7 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } det = sqrt(det); @@ -504,51 +511,20 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(BOUNDS_1_MIN) || defined(BOUNDS_1_MAX)) -vec2 intersectUncappedCone(Ray ray, float latitude) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +vec2 intersectDoubleEndedCone(Ray ray, float latitude) { - float side = sign(latitude); - float halfAngle = czm_piOverTwo - abs(latitude); - vec3 o = ray.pos; vec3 d = ray.dir; - if (side < 0.0) { - o.z *= -1.0; - d.z *= -1.0; - } - - float h = cos(halfAngle); + float h = cos(czm_piOverTwo - abs(latitude)); float hh = h * h; - float dd = dot(d, d); - float od = dot(o, d); - float oo = dot(o, o); - - // if (abs(normalize(o).z - h) < 0.1 && abs(d.z - h) < 0.1) { - // if (angle > 0.0) { - // // if (o.z * s < 0.0) { - // // return vec2(0.0, +INF_HIT); - // // } else { - // // return vec2(-o.z / d.z, 0.0); - // // // return (o.z + x * d.z) * s = 0 - // // } - // return vec2(-INF_HIT, +INF_HIT); - // } else { - // return vec2(NO_HIT, NO_HIT); - // } - // // return vec2(-10.0, +10.0); - // } - - float a = d.z * d.z - dd * hh; - float b = d.z * o.z - od * hh; - float c = o.z * o.z - oo * hh; + float a = d.z * d.z - dot(d, d) * hh; + float b = d.z * o.z - dot(o, d) * hh; + float c = o.z * o.z - dot(o, o) * hh; float det = b * b - a * c; if (det < 0.0) { - if (side > 0.0) { - return vec2(NO_HIT, NO_HIT); - } else { - return vec2(-INF_HIT, +INF_HIT); - } + return vec2(NO_HIT); } det = sqrt(det); @@ -556,78 +532,131 @@ vec2 intersectUncappedCone(Ray ray, float latitude) float t2 = (-b + det) / a; float tmin = min(t1, t2); float tmax = max(t1, t2); + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +vec4 intersectFlippedCone(Ray ray, float latitude) { + vec3 o = ray.pos; + vec3 d = ray.dir; + vec2 ix = intersectDoubleEndedCone(ray, latitude); + + if (ix.x == NO_HIT) { + return vec4(NO_HIT); + } + float tmin = ix.x; + float tmax = ix.y; float h1 = o.z + tmin * d.z; float h2 = o.z + tmax * d.z; - if (side > 0.0) { - if (h1 < 0.0 && h2 < 0.0) return vec2(NO_HIT, NO_HIT); - else if (h1 < 0.0) return vec2(tmax, +INF_HIT); - else if (h2 < 0.0) return vec2(-INF_HIT, tmin); - else return vec2(tmin, tmax); - } else { - if (h1 < 0.0 && h2 < 0.0) return vec2(-INF_HIT, +INF_HIT); - else if (h1 < 0.0) return vec2(-INF_HIT, tmax); - else if (h2 < 0.0) return vec2(tmin, +INF_HIT); - else if (tmin < 0.0) return vec2(tmax, +INF_HIT); - else return vec2(-INF_HIT, tmin); + // One interval + if (h1 < 0.0 && h2 < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + else if (h1 < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); + else if (h2 < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); + else if (tmin < 0.0) return vec4(tmax, +INF_HIT, NO_HIT, NO_HIT); + // Two intervals + else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_TOP_REGULAR)) +vec2 intersectRegularCone(Ray ray, float latitude) { + vec3 o = ray.pos; + vec3 d = ray.dir; + vec2 ix = intersectDoubleEndedCone(ray, latitude); + + if (ix.x == NO_HIT) { + return vec2(NO_HIT); } + + float tmin = ix.x; + float tmax = ix.y; + float h1 = o.z + tmin * d.z; + float h2 = o.z + tmax * d.z; + + if (h1 < 0.0 && h2 < 0.0) return vec2(NO_HIT); + else if (h1 < 0.0) return vec2(tmax, +INF_HIT); + else if (h2 < 0.0) return vec2(-INF_HIT, tmin); + else return vec2(tmin, tmax); } #endif #if defined(SHAPE_ELLIPSOID) -vec2 intersectEllipsoidShape(Ray ray) +void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { - #if !defined(BOUNDS) - return intersectUnitSphereUnnormalizedDirection(ray); - #else - float lonMin = u_minBounds.x; // [-pi,+pi] - float lonMax = u_maxBounds.x; // [-pi,+pi] - float latMin = u_minBounds.y; // [-halfPi,+halfPi] - float latMax = u_maxBounds.y; // [-halfPi,+halfPi] - float heightMin = u_minBounds.z; // [-inf,+inf] - float heightMax = u_maxBounds.z; // [-inf,+inf] - - vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - if (outerIntersect == vec2(NO_HIT, NO_HIT)) { - return vec2(NO_HIT, NO_HIT); - } + // Outer ellipsoid + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + ix.intersections[ELLIPSOID_OUTER + 0] = vec2(outerIntersect.x, POSITIVE_ENTRY); + ix.intersections[ELLIPSOID_OUTER + 1] = vec2(outerIntersect.y, POSITIVE_EXIT); + + // Exit early if the outer ellipsoid was missed. + if (outerIntersect.x == NO_HIT) { + return; + } + + // Inner ellipsoid + #if defined(ELLIPSOID_INNER) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + ix.intersections[ELLIPSOID_INNER + 0] = vec2(innerIntersect.x, NEGATIVE_ENTRY); + ix.intersections[ELLIPSOID_INNER + 1] = vec2(innerIntersect.y, NEGATIVE_EXIT); + #endif - vec2 intersections[SHAPE_INTERSECTION_COUNT]; - intersections[0] = vec2(float(0), outerIntersect.x); - intersections[1] = vec2(float(1), outerIntersect.y); + // Bottom cone + #if defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) + // Flip the inputs because the intersection function expects a cone growing towards +Z. + float flippedSouth = -u_ellipsoidRectangle.y; + Ray flippedRay = ray; + flippedRay.dir.z *= -1.0; + flippedRay.pos.z *= -1.0; - #if defined(BOUNDS_2_MIN) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - intersections[2] = vec2(float(2), innerIntersect.x); - intersections[3] = vec2(float(3), innerIntersect.y); - #endif - - #if defined(BOUNDS_1_MIN) - // Flip the inputs because the intersection function expects a cone growing towards +Z. - Ray flippedRay = ray; - flippedRay.dir.z *= -1.0; - flippedRay.pos.z *= -1.0; - vec2 botConeIntersect = intersectUncappedCone(flippedRay, -latMin); - intersections[BOUNDS_1_MIN_IDX * 2 + 0] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 0), botConeIntersect.x); - intersections[BOUNDS_1_MIN_IDX * 2 + 1] = vec2(float(BOUNDS_1_MIN_IDX * 2 + 1), botConeIntersect.y); + #if defined(ELLIPSOID_CONE_BOT_REGULAR) + vec2 botConeIx = intersectRegularCone(flippedRay, flippedSouth); + ix.intersections[ELLIPSOID_CONE_BOT_REGULAR + 0] = vec2(botConeIx.x, -1.0); + ix.intersections[ELLIPSOID_CONE_BOT_REGULAR + 1] = vec2(botConeIx.y, -1.0); + #elif defined(ELLIPSOID_CONE_BOT_FLIPPED) + vec4 botConeIx = intersectFlippedCone(flippedRay, flippedSouth); + ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 0] = vec2(botConeIx.x, -1.0); + ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 1] = vec2(botConeIx.y, -1.0); + ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 2] = vec2(botConeIx.z, -1.0); + ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 3] = vec2(botConeIx.w, -1.0); #endif - - #if defined(BOUNDS_1_MAX) - vec2 topConeIntersect = intersectUncappedCone(ray, latMax); - intersections[BOUNDS_1_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 0), topConeIntersect.x); - intersections[BOUNDS_1_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_1_MAX_IDX * 2 + 1), topConeIntersect.y); + #endif + + // Top cone + #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + float north = u_ellipsoidRectangle.w; + #if defined(ELLIPSOID_CONE_TOP_REGULAR) + vec2 topConeIntersect = intersectRegularCone(ray, north); + ix.intersections[ELLIPSOID_CONE_TOP_REGULAR + 0] = vec2(topConeIntersect.x, -1.0); + ix.intersections[ELLIPSOID_CONE_TOP_REGULAR + 1] = vec2(topConeIntersect.y, -1.0); + #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) + vec4 topConeIntersect = intersectFlippedCone(ray, north); + ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 0] = vec2(topConeIntersect.x, -1.0); + ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 1] = vec2(topConeIntersect.y, -1.0); + ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 2] = vec2(topConeIntersect.z, -1.0); + ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 3] = vec2(topConeIntersect.w, -1.0); #endif - - #if defined(BOUNDS_0_MIN) || defined(BOUNDS_0_MAX) - vec2 wedgeIntersect = intersectWedge(ray, lonMin, lonMax); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); - intersections[BOUNDS_0_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_0_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); + #endif + + // Wedge + #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) + float west = u_ellipsoidRectangle.x; // [-pi,+pi] + float east = u_ellipsoidRectangle.z; // [-pi,+pi] + #if defined(ELLIPSOID_WEDGE_REGULAR) + vec2 wedgeIntersect = intersectWedge(ray, west, east); + ix.intersections[ELLIPSOID_WEDGE_REGULAR + 0] = vec2(wedgeIntersect.x, -1.0); + ix.intersections[ELLIPSOID_WEDGE_REGULAR + 1] = vec2(wedgeIntersect.y, -1.0); + #elif defined(ELLIPSOID_WEDGE_FLIPPED) + vec2 planeIntersectWest = intersectHalfSpace(ray, west); + vec2 planeIntersectEast = intersectHalfSpace(ray, east); + ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 0] = vec2(planeIntersectWest.x, -1.0); + ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 1] = vec2(planeIntersectWest.y, -1.0); + ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 2] = vec2(planeIntersectEast.x, -1.0); + ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 3] = vec2(planeIntersectEast.y, -1.0); #endif - - return resolveIntersections(intersections); - // return vec2(0.0); #endif } #endif @@ -644,7 +673,7 @@ vec2 intersectUnitCylinder(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } det = sqrt(det); @@ -682,7 +711,7 @@ vec2 intersectUnitCircle(Ray ray) { float distSqr = dot(zPlanePos, zPlanePos); if (distSqr > 1.0) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } return vec2(t, t); @@ -701,7 +730,7 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) float det = b * b - a * c; if (det < 0.0) { - return vec2(NO_HIT, NO_HIT); + return vec2(NO_HIT); } det = sqrt(det); @@ -715,7 +744,7 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) #endif #if defined(SHAPE_CYLINDER) -vec2 intersectCylinderShape(Ray ray) +void intersectCylinderShape(Ray ray, inout Intersections ix) { #if !defined(BOUNDS) return intersectUnitCylinder(ray); @@ -744,13 +773,12 @@ vec2 intersectCylinderShape(Ray ray) outerIntersect = intersectUnitCylinder(outerRay); } - if (outerIntersect == vec2(NO_HIT, NO_HIT)) { - return vec2(NO_HIT, NO_HIT); + if (outerIntersect.x == NO_HIT) { + return; } - vec2 intersections[SHAPE_INTERSECTION_COUNT]; - intersections[0] = vec2(float(0), outerIntersect.x); - intersections[1] = vec2(float(1), outerIntersect.y); + ix.intersections[0] = vec2(outerIntersect.x, float(0)); + ix.intersections[1] = vec2(outerIntersect.y, float(1)); #if defined(BOUNDS_0_MIN) vec3 innerScale = vec3(minRadius, minRadius, 1.0); @@ -776,7 +804,7 @@ vec2 intersectCylinderShape(Ray ray) // [outerMin, innerMin, innerMax, outerMax] will bubble sort to // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - // Note: If resolveIntersections() changes its sorting function + // Note: If sortIntersections() changes its sorting function // from bubble sort to something else, this code may need to change. intersections[0] = vec2(float(0), outerIntersect.x); @@ -790,47 +818,105 @@ vec2 intersectCylinderShape(Ray ray) vec2 wedgeIntersect = intersectWedge(ray, minAngle, maxAngle); intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); - #endif - - return resolveIntersections(intersections); + #endif #endif } #endif -vec2 intersectShape(vec3 positionUv, vec3 directionUv) { - // Do a ray-shape intersection to find the exact starting and ending points. - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); +void sortIntersections(inout Intersections ix) { + // Sort the intersections from min T to max T with bubble sort. + // Note: If this sorting function changes, some of the intersection test may + // need to be updated. Search for "bubble sort" to find those areas. + const int passes = SCENE_INTERSECTION_COUNT * 2 - 1; + for (int n = passes; n > 0; --n) { + for (int i = 0; i < passes; ++i) { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + + vec2 intersect0 = ix.intersections[i + 0]; + vec2 intersect1 = ix.intersections[i + 1]; - #if defined(SHAPE_BOX) - vec2 entryExitT = intersectBoxShape(ray); - #elif defined(SHAPE_ELLIPSOID) - vec2 entryExitT = intersectEllipsoidShape(ray); - #elif defined(SHAPE_CYLINDER) - vec2 entryExitT = intersectCylinderShape(ray); - #endif + float t0 = intersect0.x; + float t1 = intersect1.x; + float b0 = intersect0.y; + float b1 = intersect1.y; - if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { - // Intersection is invalid when start and end are behind the ray. - return vec2(NO_HIT, NO_HIT); + float tmin = min(t0, t1); + float tmax = max(t0, t1); + float bmin = tmin == t0 ? b0 : b1; + float bmax = tmin == t0 ? b1 : b0; + + ix.intersections[i + 0] = vec2(tmin, bmin); + ix.intersections[i + 1] = vec2(tmax, bmax); + } } +} + +vec2 nextIntersection(inout Intersections ix) { + vec2 entryExitT = vec2(NO_HIT); - // Set start to 0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); + #if (SCENE_INTERSECTION_COUNT == 1) + if (ix.index == 0) { + entryExitT.x = ix.intersections[0].x; + entryExitT.y = ix.intersections[1].x; + ix.index += 1; + } + #else + int surroundCount = 0; + bool surroundIsPositive = false; + const int passCount = SCENE_INTERSECTION_COUNT * 2; + for (int i = 0; i < passCount; i++) + { + vec2 intersect = ix.intersections[i]; + float t = intersect.x; + bool currShapeIsPositive = intersect.y < 2.0; + bool enter = mod(intersect.y, 2.0) == 0.0; + + surroundCount += enter ? +1 : -1; + surroundIsPositive = currShapeIsPositive ? enter : surroundIsPositive; + + // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to continue instead. + if (i < ix.index) { + continue; + } + + // entering positive or exiting negative + if (surroundCount == 1 && surroundIsPositive && enter == currShapeIsPositive) { + entryExitT.x = t; + } + + // exiting positive or entering negative after being inside positive + // TODO: Can this be simplified? + bool exitPositive = !enter && currShapeIsPositive && surroundCount == 0; + bool enterNegativeFromPositive = enter && !currShapeIsPositive && surroundCount == 2 && surroundIsPositive; + if (exitPositive || enterNegativeFromPositive) { + entryExitT.y = t; + + // entry and exit have been found, so the loop can stop + if (exitPositive) { + ix.index = SCENE_INTERSECTION_COUNT * 2; + } else { + ix.index = i + 1; + } + break; + } + } + #endif return entryExitT; } #if defined(DEPTH_TEST) -float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDirUv) { +float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv) { float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); if (logDepthOrDepth != 0.0) { // Calculate how far the ray must travel before it hits the depth buffer. vec4 eyeCoordinateDepth = czm_windowToEyeCoordinates(fragCoord, logDepthOrDepth); eyeCoordinateDepth /= eyeCoordinateDepth.w; vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - return dot(viewDirUv, depthPositionUv - viewPosUv); + return dot(directionUv, depthPositionUv - positionUv); } else { // There's no depth at this position so set it to some really far value. return czm_infinity; @@ -838,6 +924,48 @@ float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 viewPosUv, vec3 viewDir } #endif +vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv, out Intersections ix) { + // Do a ray-shape intersection to find the exact starting and ending points. + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); + + #if defined(SHAPE_BOX) + intersectBoxShape(ray, ix); + #elif defined(SHAPE_ELLIPSOID) + intersectEllipsoidShape(ray, ix); + #elif defined(SHAPE_CYLINDER) + intersectCylinderShape(ray, ix);f + #endif + + // Exit early if the shape was completely missed + if (ix.intersections[0].x == NO_HIT) { + return vec2(NO_HIT); + } + + #if defined(DEPTH_TEST) + float depthT = intersectDepth(fragCoord, screenUv, positionUv, directionUv); + ix.intersections[DEPTH_INTERSECTION_IDX + 0] = vec2(depthT, NEGATIVE_ENTRY); + ix.intersections[DEPTH_INTERSECTION_IDX + 1] = vec2(+INF_HIT, NEGATIVE_EXIT); + #endif + + sortIntersections(ix); + + // Find the first intersection interval + ix.index = 0; + vec2 entryExitT = nextIntersection(ix); + + // Intersection is invalid when start and end are behind the ray. + if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { + return vec2(NO_HIT); + } + + // Set start to 0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + + return entryExitT; +} + #if defined(SHAPE_BOX) vec3 transformFromUvToBoxSpace(in vec3 positionUv) { vec3 positionShape = positionUv; @@ -939,12 +1067,20 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; // 5 float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; // 6 - #if defined(BOUNDS) + // #if (defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED)) + // { + // longitude = (longitude - u_ellipsoidWestUv) * u_ellipsoidInverseLongitudeRangeUv; + // } + // #endif + // #if (defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) + // { + // latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; + // } + // #endif + #if (defined(ELLIPSOID_INNER)) + { height *= u_ellipsoidInverseHeightDifferenceUv; - float minLongitude = u_minBoundsUv.x; - float minLatitude = u_minBoundsUv.y; - longitude = (longitude - minLongitude) * u_inverseBoundsUv.x; - latitude = (latitude - minLatitude) * u_inverseBoundsUv.y; + } #endif return vec3(longitude, latitude, height); @@ -1281,25 +1417,18 @@ void main() vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case vec3 viewPosUv = u_cameraPositionUv; - vec2 entryExitT = intersectShape(viewPosUv, viewDirUv); - // Exit early if the shape was completely missed. - if (entryExitT == vec2(NO_HIT, NO_HIT)) { + Intersections ix; + vec2 entryExitT = intersectScene(fragCoord.xy, screenUv, viewPosUv, viewDirUv, ix); + + // Exit early if the scene was completely missed. + if (entryExitT == vec2(NO_HIT)) { discard; } float currT = entryExitT.x; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - - #if defined(DEPTH_TEST) - float depthT = intersectDepth(fragCoord.xy, screenUv, viewPosUv, viewDirUv); - - // Exit early if the depth is before the start position. - if (depthT <= currT) { - discard; - } - #endif vec4 colorAccum = vec4(0.0); @@ -1394,25 +1523,17 @@ void main() currT += stepT; positionUv += stepT * viewDirUv; - // Exit early if the ray is occluded by depth texture - #if defined(DEPTH_TEST) - if (currT >= depthT) { - break; - } - #endif - - // Do another intersection test against the shape if the ray has entered empty space + // Check if there's more intersections. if (currT > endT) { - vec2 entryExitT = intersectShape(positionUv, viewDirUv); - - // Stop raymarching if it doesn't hit anything - if (entryExitT == vec2(NO_HIT, NO_HIT)) { + vec2 entryExitT = nextIntersection(ix); + if (entryExitT == vec2(NO_HIT)) { break; + } else { + // Found another intersection. Keep raymarching. + currT += entryExitT.x; + endT += entryExitT.y; + positionUv += entryExitT.x * viewDirUv; } - - currT += entryExitT.x; - endT += entryExitT.y; - positionUv += entryExitT.x * viewDirUv; } // Traverse the tree from the current ray position. diff --git a/Source/Shaders/VoxelVS.glsl b/Source/Shaders/VoxelVS.glsl index 6c29c959b1c..c83efe4ea4e 100644 --- a/Source/Shaders/VoxelVS.glsl +++ b/Source/Shaders/VoxelVS.glsl @@ -8,4 +8,5 @@ void main() { vec2 translation = 0.5 * (aabbMax + aabbMin); vec2 scale = 0.5 * (aabbMax - aabbMin); gl_Position = vec4(position * scale + translation, 0.0, 1.0); + gl_Position = vec4(position, 0.0, 1.0); } From 944c78136052222f424fe82f3f74d2f7188f79d7 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Tue, 12 Apr 2022 18:36:49 -0400 Subject: [PATCH 019/679] better box --- Apps/Sandcastle/gallery/Voxels.html | 20 +-- Source/Scene/VoxelBoxShape.js | 197 ++++++++++++++++++++++------ Source/Scene/VoxelPrimitive.js | 6 +- Source/Shaders/VoxelFS.glsl | 93 ++++++------- 4 files changed, 212 insertions(+), 104 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 5d247673b62..c8ce699bf5e 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -396,21 +396,6 @@ }); Sandcastle.addToolbarMenu([ - { - text: "Ellipsoid - Procedural Tile", - onselect: function () { - const provider = new ProceduralSingleTileVoxelProvider( - Cesium.VoxelShapeType.ELLIPSOID - ); - const primitive = createPrimitive(provider, customShaderColor); - primitive.readyPromise.then(function () { - console.log(primitive.boundingSphere.center); - viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { - duration: 0.0, - }); - }); - }, - }, { text: "Box - Procedural Tile", onselect: function () { @@ -474,6 +459,11 @@ Cesium.VoxelShapeType.ELLIPSOID ); const primitive = createPrimitive(provider, customShaderColor); + primitive.readyPromise.then(function () { + viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { + duration: 0.0, + }); + }); }, }, { diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index 47a5cb8e161..ed1a8c60ebb 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -75,8 +75,11 @@ function VoxelBoxShape() { * @readonly */ this.shaderUniforms = { - boxMinBounds: new Cartesian3(), - boxMaxBounds: new Cartesian3(), + boxScaleUvToBoundsUv: new Cartesian3(), + boxTranslateUvToBoundsUv: new Cartesian3(), + boxScaleUvToBounds: new Cartesian3(), + boxTranslateUvToBounds: new Cartesian3(), + boxTransformUvToBounds: new Matrix4(), }; /** @@ -84,7 +87,7 @@ function VoxelBoxShape() { * @readonly */ this.shaderDefines = { - BOX_INTERSECTION_COUNT: 1, + BOX_INTERSECTION_COUNT: 1, // never changes BOX_BOUNDED: undefined, BOX_XY_PLANE: undefined, BOX_XZ_PLANE: undefined, @@ -95,6 +98,31 @@ function VoxelBoxShape() { const scratchTranslation = new Cartesian3(); const scratchScale = new Cartesian3(); const scratchRotation = new Matrix3(); +const scratchTransformLocalToBounds = new Matrix4(); +const scratchBoundsTranslation = new Cartesian3(); +const scratchBoundsScale = new Cartesian3(); + +const transformUvToLocal = Matrix4.fromRotationTranslation( + Matrix3.fromUniformScale(2.0, new Matrix3()), + new Cartesian3(-1.0, -1.0, -1.0), + new Matrix4() +); + +const transformXYZToZYX = Matrix4.fromRotation( + Matrix3.fromColumnMajorArray( + [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0], + new Matrix3() + ), + new Matrix4() +); + +const transformXYZToXZY = Matrix4.fromRotation( + Matrix3.fromColumnMajorArray( + [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0], + new Matrix3() + ), + new Matrix4() +); /** * Update the shape's state. @@ -130,10 +158,10 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { const scale = Matrix4.getScale(modelMatrix, scratchScale); - // Not visible if: + // Box is not visible if: // - any of the min bounds exceed the max bounds - // - two or more of the min bounds equal the max bounds (line and point respectively) - // - scale is 0 for any component + // - two or more of the min bounds equal the max bounds (line / point) + // - scale is 0 for any component (too annoying to reconstruct rotation matrix) if ( minBounds.x > maxBounds.x || minBounds.y > maxBounds.y || @@ -174,27 +202,113 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; - shaderUniforms.minBounds = Cartesian3.clone( - minBounds, - shaderUniforms.minBounds - ); - shaderUniforms.maxBounds = Cartesian3.clone( - maxBounds, - shaderUniforms.maxBounds - ); + // To keep things simple, clear the defines every frame + shaderDefines["BOX_BOUNDED"] = undefined; + shaderDefines["BOX_XY_PLANE"] = undefined; + shaderDefines["BOX_XZ_PLANE"] = undefined; + shaderDefines["BOX_YZ_PLANE"] = undefined; - const hasBounds = - !Cartesian3.equals(minBounds, defaultMinBounds) && - !Cartesian3.equals(maxBounds, defaultMaxBounds); - shaderDefines.BOX_BOUNDS = hasBounds ? 1 : undefined; + if ( + minBounds.x !== defaultMinBounds.x || + minBounds.y !== defaultMinBounds.y || + minBounds.z !== defaultMinBounds.z || + maxBounds.x !== defaultMaxBounds.x || + maxBounds.y !== defaultMaxBounds.y || + maxBounds.z !== defaultMaxBounds.z + ) { + shaderDefines["BOX_BOUNDED"] = true; + + // inverse(scale) + // inverse(maxBoundsUv - minBoundsUv) + // inverse((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) + // inverse(0.5 * (maxBounds - minBounds)) + // 2.0 / (maxBounds - minBounds) // with divide by zero protection + const boundsScaleLocalToBounds = Cartesian3.fromElements( + 2.0 / (minBounds.x === maxBounds.x ? 1.0 : maxBounds.x - minBounds.x), + 2.0 / (minBounds.y === maxBounds.y ? 1.0 : maxBounds.y - minBounds.y), + 2.0 / (minBounds.z === maxBounds.z ? 1.0 : maxBounds.z - minBounds.z), + scratchBoundsScale + ); + + // -inverse(scale) * translation // affine inverse + // -inverse(scale) * 0.5 * (minBounds + maxBounds) + const boundsTranslateLocalToBounds = Cartesian3.fromElements( + -boundsScaleLocalToBounds.x * 0.5 * (minBounds.x + maxBounds.x), + -boundsScaleLocalToBounds.y * 0.5 * (minBounds.y + maxBounds.y), + -boundsScaleLocalToBounds.z * 0.5 * (minBounds.z + maxBounds.z), + scratchBoundsTranslation + ); + + let transformLocalToBounds = Matrix4.fromRotationTranslation( + Matrix3.fromScale(boundsScaleLocalToBounds), + boundsTranslateLocalToBounds, + scratchTransformLocalToBounds + ); + + if ( + minBounds.x === maxBounds.x || + minBounds.y === maxBounds.y || + minBounds.z === maxBounds.z + ) { + let transformAxisConversion; + if (minBounds.x === maxBounds.x) { + shaderDefines["BOX_YZ_PLANE"] = true; + transformAxisConversion = transformXYZToZYX; + } else if (minBounds.y === maxBounds.y) { + shaderDefines["BOX_XZ_PLANE"] = true; + transformAxisConversion = transformXYZToXZY; + } else if (minBounds.z === maxBounds.z) { + shaderDefines["BOX_XY_PLANE"] = true; + transformAxisConversion = Matrix4.IDENTITY; + } + transformLocalToBounds = Matrix4.multiply( + transformAxisConversion, + transformLocalToBounds, + transformLocalToBounds + ); + } + + shaderUniforms.boxTransformUvToBounds = Matrix4.multiplyTransformation( + transformLocalToBounds, + transformUvToLocal, + shaderUniforms.boxTransformUvToBounds + ); + shaderUniforms.boxScaleUvToBounds = Matrix4.getScale( + shaderUniforms.boxTransformUvToBounds, + shaderUniforms.boxScaleUvToBounds + ); + shaderUniforms.boxTranslateUvToBounds = Matrix4.getTranslation( + shaderUniforms.boxTransformUvToBounds, + shaderUniforms.boxTranslateUvToBounds + ); + + // Go from UV space to bounded UV space: + // delerp(posUv, minBoundsUv, maxBoundsUv) + // (posUv - minBoundsUv) / (maxBoundsUv - minBoundsUv) + // posUv / (maxBoundsUv - minBoundsUv) - minBoundsUv / (maxBoundsUv - minBoundsUv) + // scale = 1.0 / (maxBoundsUv - minBoundsUv) + // scale = 1.0 / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) + // scale = 2.0 / (maxBounds - minBounds) + // translation = -minBoundsUv / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) + // translation = -2.0 * (minBounds * 0.5 + 0.5) / (maxBounds - minBounds) + // translation = -scale * (minBounds * 0.5 + 0.5) + shaderUniforms.boxScaleUvToBoundsUv = Cartesian3.clone( + boundsScaleLocalToBounds, + shaderUniforms.boxScaleUvToBoundsUv + ); + shaderUniforms.boxTranslateUvToBoundsUv = Cartesian3.fromElements( + -boundsScaleLocalToBounds.x * (minBounds.x * 0.5 + 0.5), + -boundsScaleLocalToBounds.y * (minBounds.y * 0.5 + 0.5), + -boundsScaleLocalToBounds.z * (minBounds.z * 0.5 + 0.5), + shaderUniforms.boxTranslateUvToBoundsUv + ); + } return true; }; -const scratchMinBounds = new Cartesian3(); -const scratchMaxBounds = new Cartesian3(); -const scratchMinLerp = new Cartesian3(); -const scratchMaxLerp = new Cartesian3(); +const scratchTileMinBounds = new Cartesian3(); +const scratchTileMaxBounds = new Cartesian3(); /** * Computes an oriented bounding box for a specified tile. @@ -222,33 +336,30 @@ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( Check.typeOf.object("result", result); //>>includeEnd('debug'); + const minBounds = this._minBounds; + const maxBounds = this._maxBounds; const sizeAtLevel = 1.0 / Math.pow(2, tileLevel); - const minBounds = Cartesian3.lerp( - this._minBounds, - this._maxBounds, - Cartesian3.fromElements( - sizeAtLevel * tileX, - sizeAtLevel * tileY, - sizeAtLevel * tileZ, - scratchMinLerp - ), - scratchMinBounds + const tileMinBounds = Cartesian3.fromElements( + CesiumMath.lerp(minBounds.x, maxBounds.x, sizeAtLevel * tileX), + CesiumMath.lerp(minBounds.y, maxBounds.y, sizeAtLevel * tileY), + CesiumMath.lerp(minBounds.z, maxBounds.z, sizeAtLevel * tileZ), + scratchTileMinBounds ); - const maxBounds = Cartesian3.lerp( - this._minBounds, - this._maxBounds, - Cartesian3.fromElements( - sizeAtLevel * (tileX + 1), - sizeAtLevel * (tileY + 1), - sizeAtLevel * (tileZ + 1), - scratchMaxLerp - ), - scratchMaxBounds + const tileMaxBounds = Cartesian3.fromElements( + CesiumMath.lerp(minBounds.x, maxBounds.x, sizeAtLevel * (tileX + 1)), + CesiumMath.lerp(minBounds.y, maxBounds.y, sizeAtLevel * (tileY + 1)), + CesiumMath.lerp(minBounds.z, maxBounds.z, sizeAtLevel * (tileZ + 1)), + scratchTileMaxBounds ); - return getBoxChunkObb(minBounds, maxBounds, this.shapeTransform, result); + return getBoxChunkObb( + tileMinBounds, + tileMaxBounds, + this.shapeTransform, + result + ); }; /** diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index b27bca23c64..3a3e6fbdaed 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1299,6 +1299,7 @@ VoxelPrimitive.prototype.update = function (frameState) { // Set member variables when the shape is dirty const dimensions = provider.dimensions; this._stepSizeUv = shape.computeApproximateStepSize(dimensions); + // TODO: check which of the `multiply` can be `multiplyTransformation` this._transformPositionWorldToUv = Matrix4.multiply( transformPositionLocalToUv, transformPositionWorldToLocal, @@ -1899,8 +1900,11 @@ function buildDrawCommands(that, context) { // Shape specific defines for (const key in shapeDefines) { if (shapeDefines.hasOwnProperty(key)) { - const value = shapeDefines[key]; + let value = shapeDefines[key]; + // if value is undefined, don't define it + // if value is true, define it to nothing if (defined(value)) { + value = value === true ? undefined : value; shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); } } diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index bad0f04fce0..b7f8bd9e420 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -194,9 +194,26 @@ uniform float u_stepSize; #endif #if defined(SHAPE_BOX) - #define BOX_INTERSECTION_COUNT 1 - uniform vec2 u_boxMinBounds; - uniform vec2 u_boxMaxBounds; + /* Box defines: + #define BOX_INTERSECTION_COUNT ### // always 1 + #define BOX_BOUNDED + #define BOX_XY_PLANE + #define BOX_XZ_PLANE + #define BOX_YZ_PLANE + */ + + // Box uniforms: + #if defined(BOX_BOUNDED) + uniform vec3 u_boxScaleUvToBoundsUv; + uniform vec3 u_boxTranslateUvToBoundsUv; + #if defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) + uniform mat4 u_boxTransformUvToBounds; + #else + // Similar to u_boxTransformUvToBounds but fewer instructions needed. + uniform vec3 u_boxScaleUvToBounds; + uniform vec3 u_boxTranslateUvToBounds; + #endif + #endif #endif #if defined(SHAPE_ELLIPSOID) @@ -240,6 +257,7 @@ uniform float u_stepSize; #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections */ + // Cylinder uniforms #if defined(CYLINDER_INNER) uniform float u_something; #endif @@ -372,41 +390,28 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] #endif #if defined(SHAPE_BOX) -vec2 intersectBoxShape(Ray ray, out Intersections ix) +void intersectBoxShape(Ray ray, out Intersections ix) { - #if defined(BOX_BOUNDED) - vec3 pos = 0.5 * (u_minBounds + u_maxBounds); - vec3 scale = 0.5 * (u_maxBounds - u_minBounds); - - if (any(equal(scale, vec3(0.0)))) { - // Transform the ray into unit space on Z plane - Ray flatRay; - if (scale.x == 0.0) { - flatRay = Ray( - (ray.pos.yzx - pos.yzx) / vec3(scale.yz, 1.0), - ray.dir.yzx / vec3(scale.yz, 1.0) - ); - } else if (scale.y == 0.0) { - flatRay = Ray( - (ray.pos.xzy - pos.xzy) / vec3(scale.xz, 1.0), - ray.dir.xzy / vec3(scale.xz, 1.0) - ); - } else if (scale.z == 0.0) { - flatRay = Ray( - (ray.pos.xyz - pos.xyz) / vec3(scale.xy, 1.0), - ray.dir.xyz / vec3(scale.xy, 1.0) - ); - } - return intersectUnitSquare(flatRay); - } else { - // Transform the ray into "unit space" - Ray unitRay = Ray((ray.pos - pos) / scale, ray.dir / scale); - return intersectUnitCube(unitRay); - } + #if !defined(BOX_BOUNDED) + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir = ray.dir * 2.0; + vec2 entryExit = intersectUnitCube(ray); + #elif defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) + // Transform the ray into unit square space on Z plane + ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); + vec2 entryExit = intersectUnitSquare(ray); + #else + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxTranslateUvToBounds; + ray.dir *= u_boxScaleUvToBounds; + vec2 entryExit = intersectUnitCube(ray); #endif - return intersectUnitCube(ray); - + ix.intersections[0] = vec2(entryExit.x, POSITIVE_ENTRY); + ix.intersections[1] = vec2(entryExit.y, POSITIVE_EXIT); } #endif @@ -925,11 +930,9 @@ float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 direct #endif vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv, out Intersections ix) { + Ray ray = Ray(positionUv, directionUv); + // Do a ray-shape intersection to find the exact starting and ending points. - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - Ray ray = Ray(positionUv * 2.0 - 1.0, directionUv * 2.0); - #if defined(SHAPE_BOX) intersectBoxShape(ray, ix); #elif defined(SHAPE_ELLIPSOID) @@ -968,11 +971,11 @@ vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directi #if defined(SHAPE_BOX) vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - vec3 positionShape = positionUv; - #if defined(BOUNDS) - positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] + #if defined(BOX_BOUNDED) + return positionUv * u_boxScaleUvToBoundsUv + u_boxTranslateUvToBoundsUv; + #else + return positionUv; #endif - return positionShape; } #endif @@ -1422,7 +1425,7 @@ void main() vec2 entryExitT = intersectScene(fragCoord.xy, screenUv, viewPosUv, viewDirUv, ix); // Exit early if the scene was completely missed. - if (entryExitT == vec2(NO_HIT)) { + if (entryExitT.x == NO_HIT) { discard; } @@ -1526,7 +1529,7 @@ void main() // Check if there's more intersections. if (currT > endT) { vec2 entryExitT = nextIntersection(ix); - if (entryExitT == vec2(NO_HIT)) { + if (entryExitT.x == NO_HIT) { break; } else { // Found another intersection. Keep raymarching. From c412d3655a96f873a7ad6015591632aae42f3fb3 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 10:26:31 -0400 Subject: [PATCH 020/679] made shader intersection interval code more self contained --- Source/Scene/VoxelBoxShape.js | 3 +- Source/Scene/VoxelEllipsoidShape.js | 50 ++-- Source/Shaders/VoxelFS.glsl | 351 +++++++++++++++------------- 3 files changed, 214 insertions(+), 190 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index ed1a8c60ebb..2438159a8d3 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -88,6 +88,7 @@ function VoxelBoxShape() { */ this.shaderDefines = { BOX_INTERSECTION_COUNT: 1, // never changes + BOX_INTERSECTION_INDEX: 0, // never changes BOX_BOUNDED: undefined, BOX_XY_PLANE: undefined, BOX_XZ_PLANE: undefined, @@ -202,7 +203,7 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; - // To keep things simple, clear the defines every frame + // To keep things simple, clear the defines every time shaderDefines["BOX_BOUNDED"] = undefined; shaderDefines["BOX_XY_PLANE"] = undefined; shaderDefines["BOX_XZ_PLANE"] = undefined; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index b8271a59621..c343523864e 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -153,6 +153,7 @@ VoxelEllipsoidShape.prototype.update = function ( const defaultMinBounds = VoxelEllipsoidShape.DefaultMinBounds; const defaultMaxBounds = VoxelEllipsoidShape.DefaultMaxBounds; + // Clamp the longitude / latitude to the valid range const west = CesiumMath.clamp( minBounds.x, defaultMinBounds.x, @@ -180,7 +181,7 @@ VoxelEllipsoidShape.prototype.update = function ( const minHeight = Math.max(minBounds.z, -minRadius); const maxHeight = Math.max(maxBounds.z, -minRadius); - // The closest and farthest a point can be from the center of the ellipsoid. + // Compute the closest and farthest a point can be from the center of the ellipsoid. const innerExtent = Cartesian3.add( radii, Cartesian3.fromElements(minHeight, minHeight, minHeight, scratchInner), @@ -243,6 +244,17 @@ VoxelEllipsoidShape.prototype.update = function ( const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; + // To keep things simple, clear the defines every time + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_OUTER"] = undefined; + shaderDefines["ELLIPSOID_INNER"] = undefined; + shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = undefined; + shaderUniforms.ellipsoidRectangle = Cartesian4.fromElements( west, south, @@ -272,7 +284,8 @@ VoxelEllipsoidShape.prototype.update = function ( const rectangleWidth = Rectangle.computeWidth(this._rectangle); const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); const hasWedgeRegular = - rectangleWidth >= CesiumMath.PI && rectangleWidth < CesiumMath.TWO_PI; + rectangleWidth >= CesiumMath.PI && + CesiumMath.lessThan(rectangleWidth, CesiumMath.TWO_PI, absEpsilon); const hasWedgeFlipped = rectangleWidth < CesiumMath.PI; const hasTopConeRegular = north >= 0.0 && north < +CesiumMath.PI_OVER_TWO; const hasTopConeFlipped = north < 0.0; @@ -283,12 +296,12 @@ VoxelEllipsoidShape.prototype.update = function ( let intersectionCount = 0; // Intersects an outer ellipsoid for the max height. - shaderDefines["ELLIPSOID_OUTER"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_OUTER"] = intersectionCount; intersectionCount += 1; // Intersects an inner ellipsoid for the min height. if (hasInnerEllipsoid) { - shaderDefines["ELLIPSOID_INNER"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_INNER"] = intersectionCount; intersectionCount += 1; // The percent of space that is between the inner and outer ellipsoid. @@ -305,50 +318,33 @@ VoxelEllipsoidShape.prototype.update = function ( innerScale, shaderUniforms.ellipsoidInnerRadiiUv ); - } else { - shaderDefines["ELLIPSOID_INNER"] = undefined; } // Intersects a wedge for the min and max longitude. if (hasWedgeRegular) { - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = intersectionCount * 2; - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = intersectionCount; intersectionCount += 1; } else if (hasWedgeFlipped) { - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = intersectionCount; intersectionCount += 2; - } else { - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; } // Intersects a cone for min latitude if (hasBottomConeRegular) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = intersectionCount * 2; - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = intersectionCount; intersectionCount += 1; } else if (hasBottomConeFlipped) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = intersectionCount; intersectionCount += 2; - } else { - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; } // Intersects a cone for max latitude if (hasTopConeRegular) { - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = intersectionCount * 2; - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = intersectionCount; intersectionCount += 1; } else if (hasTopConeFlipped) { - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = intersectionCount * 2; + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = intersectionCount; intersectionCount += 2; - } else { - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; } shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = intersectionCount; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index b7f8bd9e420..db72be16bb7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -138,10 +138,6 @@ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { #define NO_HIT (-czm_infinity) #define INF_HIT (czm_infinity * 0.5) -#define POSITIVE_ENTRY 0.0 -#define POSITIVE_EXIT 1.0 -#define NEGATIVE_ENTRY 2.0 -#define NEGATIVE_EXIT 3.0 uniform ivec3 u_dimensions; // does not include padding #if defined(PADDING) @@ -196,6 +192,7 @@ uniform float u_stepSize; #if defined(SHAPE_BOX) /* Box defines: #define BOX_INTERSECTION_COUNT ### // always 1 + #define BOX_INTERSECTION_INDEX ### // always 0 #define BOX_BOUNDED #define BOX_XY_PLANE #define BOX_XZ_PLANE @@ -230,10 +227,12 @@ uniform float u_stepSize; */ // Ellipsoid uniforms - uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. uniform vec3 u_ellipsoidRadiiUv; // [0,1] uniform vec3 u_ellipsoidInverseRadiiSquaredUv; + #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. + #endif #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) uniform float u_ellipsoidWestUv; uniform float u_ellipsoidInverseLongitudeRangeUv; @@ -277,26 +276,20 @@ uniform float u_stepSize; #endif #if defined(DEPTH_TEST) - #define DEPTH_INTERSECTION_IDX (SHAPE_INTERSECTION_COUNT * 2) + #define DEPTH_INTERSECTION_INDEX SHAPE_INTERSECTION_COUNT #define SCENE_INTERSECTION_COUNT (SHAPE_INTERSECTION_COUNT + 1) #else #define SCENE_INTERSECTION_COUNT SHAPE_INTERSECTION_COUNT #endif -struct Intersections { - vec2 intersections[SCENE_INTERSECTION_COUNT * 2]; - int index; -}; - +// -------------------------------------------------------- +// Misc math +// -------------------------------------------------------- struct Ray { vec3 pos; vec3 dir; }; -// -------------------------------------------------------- -// Misc math -// -------------------------------------------------------- - #if defined(JITTER) #define HASHSCALE 50.0 float hash(vec2 p) @@ -349,6 +342,131 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) // -------------------------------------------------------- // Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- +struct Intersections { + // Don't access these member variables directly - call the functions instead. + + #if (SCENE_INTERSECTION_COUNT > 1) + // Store an array of intersections. Each intersection is composed of: + // x for the T value + // y for the shape type - which encodes positive vs negative and entering vs exiting + // For example: + // y = 0: positive shape entry + // y = 1: positive shape exit + // y = 2: negative shape entry + // y = 3: negative shape exit + vec2 intersections[SCENE_INTERSECTION_COUNT * 2]; + + // Maintain state for future nextIntersection calls + int index; + int surroundCount; + bool surroundIsPositive; + #else + // When there's only one positive shape intersection none of the extra stuff is needed. + float intersections[2]; + #endif +}; + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (SCENE_INTERSECTION_COUNT > 1) + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) ix.intersections[index * 2 + 0] = vec2(entryExit.x, float(index > 0) * 2.0 + 0.0); ix.intersections[index * 2 + 1] = vec2(entryExit.y, float(index > 0) * 2.0 + 1.0) +#else + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) ix.intersections[0] = entryExit.x; ix.intersections[1] = entryExit.y +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (SCENE_INTERSECTION_COUNT > 1) + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) ix.intersections[index].x +#else + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) ix.intersections[index] +#endif + +#if (SCENE_INTERSECTION_COUNT > 1) +vec2 nextIntersection(inout Intersections ix) { + vec2 entryExitT = vec2(NO_HIT); + + const int passCount = SCENE_INTERSECTION_COUNT * 2; + for (int i = 0; i < passCount; i++) { + // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to continue instead. + if (i < ix.index) { + continue; + } + + vec2 intersect = ix.intersections[i]; + float t = intersect.x; + bool currShapeIsPositive = intersect.y < 2.0; + bool enter = mod(intersect.y, 2.0) == 0.0; + + ix.surroundCount += enter ? +1 : -1; + ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; + + // entering positive or exiting negative + if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { + entryExitT.x = t; + } + + // exiting positive or entering negative after being inside positive + // TODO: Can this be simplified? + bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; + bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; + if (exitPositive || enterNegativeFromPositive) { + entryExitT.y = t; + + // entry and exit have been found, so the loop can stop + if (exitPositive) { + // After exiting positive shape there is nothing left to intersect, so jump to the end index. + ix.index = SCENE_INTERSECTION_COUNT * 2; + } else { + // There could be more intersections against the positive shape in the future. + ix.index = i + 1; + } + break; + } + } + + return entryExitT; +} +#endif + +#if (SCENE_INTERSECTION_COUNT > 1) +vec2 initializeIntersections(inout Intersections ix) { + // Sort the intersections from min T to max T with bubble sort. + // Note: If this sorting function changes, some of the intersection test may + // need to be updated. Search for "bubble sort" to find those areas. + const int passes = SCENE_INTERSECTION_COUNT * 2 - 1; + for (int n = passes; n > 0; --n) { + for (int i = 0; i < passes; ++i) { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + + vec2 intersect0 = ix.intersections[i + 0]; + vec2 intersect1 = ix.intersections[i + 1]; + + float t0 = intersect0.x; + float t1 = intersect1.x; + float b0 = intersect0.y; + float b1 = intersect1.y; + + float tmin = min(t0, t1); + float tmax = max(t0, t1); + float bmin = tmin == t0 ? b0 : b1; + float bmax = tmin == t0 ? b1 : b0; + + ix.intersections[i + 0] = vec2(tmin, bmin); + ix.intersections[i + 1] = vec2(tmax, bmax); + } + } + + // Prepare initial state for nextIntersection + ix.index = 0; + ix.surroundCount = 0; + ix.surroundIsPositive = false; + + return nextIntersection(ix); +} +#endif + #if defined(SHAPE_BOX) // Unit cube from [-1, +1] vec2 intersectUnitCube(Ray ray) @@ -410,8 +528,7 @@ void intersectBoxShape(Ray ray, out Intersections ix) vec2 entryExit = intersectUnitCube(ray); #endif - ix.intersections[0] = vec2(entryExit.x, POSITIVE_ENTRY); - ix.intersections[1] = vec2(entryExit.y, POSITIVE_EXIT); + setIntersection(ix, BOX_INTERSECTION_INDEX, entryExit); } #endif @@ -545,14 +662,14 @@ vec2 intersectDoubleEndedCone(Ray ray, float latitude) vec4 intersectFlippedCone(Ray ray, float latitude) { vec3 o = ray.pos; vec3 d = ray.dir; - vec2 ix = intersectDoubleEndedCone(ray, latitude); + vec2 intersect = intersectDoubleEndedCone(ray, latitude); - if (ix.x == NO_HIT) { + if (intersect.x == NO_HIT) { return vec4(NO_HIT); } - float tmin = ix.x; - float tmax = ix.y; + float tmin = intersect.x; + float tmax = intersect.y; float h1 = o.z + tmin * d.z; float h2 = o.z + tmax * d.z; @@ -570,14 +687,14 @@ vec4 intersectFlippedCone(Ray ray, float latitude) { vec2 intersectRegularCone(Ray ray, float latitude) { vec3 o = ray.pos; vec3 d = ray.dir; - vec2 ix = intersectDoubleEndedCone(ray, latitude); + vec2 intersect = intersectDoubleEndedCone(ray, latitude); - if (ix.x == NO_HIT) { + if (intersect.x == NO_HIT) { return vec2(NO_HIT); } - float tmin = ix.x; - float tmax = ix.y; + float tmin = intersect.x; + float tmax = intersect.y; float h1 = o.z + tmin * d.z; float h2 = o.z + tmax * d.z; @@ -591,10 +708,14 @@ vec2 intersectRegularCone(Ray ray, float latitude) { #if defined(SHAPE_ELLIPSOID) void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + // Outer ellipsoid vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - ix.intersections[ELLIPSOID_OUTER + 0] = vec2(outerIntersect.x, POSITIVE_ENTRY); - ix.intersections[ELLIPSOID_OUTER + 1] = vec2(outerIntersect.y, POSITIVE_EXIT); + setIntersection(ix, ELLIPSOID_OUTER, outerIntersect); // Exit early if the outer ellipsoid was missed. if (outerIntersect.x == NO_HIT) { @@ -605,8 +726,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) #if defined(ELLIPSOID_INNER) Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - ix.intersections[ELLIPSOID_INNER + 0] = vec2(innerIntersect.x, NEGATIVE_ENTRY); - ix.intersections[ELLIPSOID_INNER + 1] = vec2(innerIntersect.y, NEGATIVE_EXIT); + setIntersection(ix, ELLIPSOID_INNER, innerIntersect); #endif // Bottom cone @@ -619,14 +739,11 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) #if defined(ELLIPSOID_CONE_BOT_REGULAR) vec2 botConeIx = intersectRegularCone(flippedRay, flippedSouth); - ix.intersections[ELLIPSOID_CONE_BOT_REGULAR + 0] = vec2(botConeIx.x, -1.0); - ix.intersections[ELLIPSOID_CONE_BOT_REGULAR + 1] = vec2(botConeIx.y, -1.0); + setIntersection(ix, ELLIPSOID_CONE_BOT_REGULAR, botConeIx); #elif defined(ELLIPSOID_CONE_BOT_FLIPPED) vec4 botConeIx = intersectFlippedCone(flippedRay, flippedSouth); - ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 0] = vec2(botConeIx.x, -1.0); - ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 1] = vec2(botConeIx.y, -1.0); - ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 2] = vec2(botConeIx.z, -1.0); - ix.intersections[ELLIPSOID_CONE_BOT_FLIPPED + 3] = vec2(botConeIx.w, -1.0); + setIntersection(ix, ELLIPSOID_CONE_BOT_FLIPPED + 0, botConeIx.xy); + setIntersection(ix, ELLIPSOID_CONE_BOT_FLIPPED + 1, botConeIx.zw); #endif #endif @@ -635,14 +752,11 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) float north = u_ellipsoidRectangle.w; #if defined(ELLIPSOID_CONE_TOP_REGULAR) vec2 topConeIntersect = intersectRegularCone(ray, north); - ix.intersections[ELLIPSOID_CONE_TOP_REGULAR + 0] = vec2(topConeIntersect.x, -1.0); - ix.intersections[ELLIPSOID_CONE_TOP_REGULAR + 1] = vec2(topConeIntersect.y, -1.0); + setIntersection(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersect); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) vec4 topConeIntersect = intersectFlippedCone(ray, north); - ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 0] = vec2(topConeIntersect.x, -1.0); - ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 1] = vec2(topConeIntersect.y, -1.0); - ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 2] = vec2(topConeIntersect.z, -1.0); - ix.intersections[ELLIPSOID_CONE_TOP_FLIPPED + 3] = vec2(topConeIntersect.w, -1.0); + setIntersection(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersect.xy); + setIntersection(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersect.zw); #endif #endif @@ -652,15 +766,12 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) float east = u_ellipsoidRectangle.z; // [-pi,+pi] #if defined(ELLIPSOID_WEDGE_REGULAR) vec2 wedgeIntersect = intersectWedge(ray, west, east); - ix.intersections[ELLIPSOID_WEDGE_REGULAR + 0] = vec2(wedgeIntersect.x, -1.0); - ix.intersections[ELLIPSOID_WEDGE_REGULAR + 1] = vec2(wedgeIntersect.y, -1.0); + setIntersection(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); #elif defined(ELLIPSOID_WEDGE_FLIPPED) vec2 planeIntersectWest = intersectHalfSpace(ray, west); vec2 planeIntersectEast = intersectHalfSpace(ray, east); - ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 0] = vec2(planeIntersectWest.x, -1.0); - ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 1] = vec2(planeIntersectWest.y, -1.0); - ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 2] = vec2(planeIntersectEast.x, -1.0); - ix.intersections[ELLIPSOID_WEDGE_FLIPPED + 3] = vec2(planeIntersectEast.y, -1.0); + setIntersection(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); + setIntersection(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); #endif #endif } @@ -782,8 +893,7 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) return; } - ix.intersections[0] = vec2(outerIntersect.x, float(0)); - ix.intersections[1] = vec2(outerIntersect.y, float(1)); + setIntersection(ix, BOX_INTERSECTION_INDEX, outerIntersect); #if defined(BOUNDS_0_MIN) vec3 innerScale = vec3(minRadius, minRadius, 1.0); @@ -828,91 +938,6 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) } #endif -void sortIntersections(inout Intersections ix) { - // Sort the intersections from min T to max T with bubble sort. - // Note: If this sorting function changes, some of the intersection test may - // need to be updated. Search for "bubble sort" to find those areas. - const int passes = SCENE_INTERSECTION_COUNT * 2 - 1; - for (int n = passes; n > 0; --n) { - for (int i = 0; i < passes; ++i) { - // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to break early instead - if (i >= n) { break; } - - vec2 intersect0 = ix.intersections[i + 0]; - vec2 intersect1 = ix.intersections[i + 1]; - - float t0 = intersect0.x; - float t1 = intersect1.x; - float b0 = intersect0.y; - float b1 = intersect1.y; - - float tmin = min(t0, t1); - float tmax = max(t0, t1); - float bmin = tmin == t0 ? b0 : b1; - float bmax = tmin == t0 ? b1 : b0; - - ix.intersections[i + 0] = vec2(tmin, bmin); - ix.intersections[i + 1] = vec2(tmax, bmax); - } - } -} - -vec2 nextIntersection(inout Intersections ix) { - vec2 entryExitT = vec2(NO_HIT); - - #if (SCENE_INTERSECTION_COUNT == 1) - if (ix.index == 0) { - entryExitT.x = ix.intersections[0].x; - entryExitT.y = ix.intersections[1].x; - ix.index += 1; - } - #else - int surroundCount = 0; - bool surroundIsPositive = false; - const int passCount = SCENE_INTERSECTION_COUNT * 2; - for (int i = 0; i < passCount; i++) - { - vec2 intersect = ix.intersections[i]; - float t = intersect.x; - bool currShapeIsPositive = intersect.y < 2.0; - bool enter = mod(intersect.y, 2.0) == 0.0; - - surroundCount += enter ? +1 : -1; - surroundIsPositive = currShapeIsPositive ? enter : surroundIsPositive; - - // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to continue instead. - if (i < ix.index) { - continue; - } - - // entering positive or exiting negative - if (surroundCount == 1 && surroundIsPositive && enter == currShapeIsPositive) { - entryExitT.x = t; - } - - // exiting positive or entering negative after being inside positive - // TODO: Can this be simplified? - bool exitPositive = !enter && currShapeIsPositive && surroundCount == 0; - bool enterNegativeFromPositive = enter && !currShapeIsPositive && surroundCount == 2 && surroundIsPositive; - if (exitPositive || enterNegativeFromPositive) { - entryExitT.y = t; - - // entry and exit have been found, so the loop can stop - if (exitPositive) { - ix.index = SCENE_INTERSECTION_COUNT * 2; - } else { - ix.index = i + 1; - } - break; - } - } - #endif - - return entryExitT; -} - #if defined(DEPTH_TEST) float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv) { float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); @@ -941,22 +966,24 @@ vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directi intersectCylinderShape(ray, ix);f #endif - // Exit early if the shape was completely missed - if (ix.intersections[0].x == NO_HIT) { + // Check if the positive shape was completely missed, and if so, exit early. + float entryPositiveShapeT = getIntersection(ix, 0); + if (entryPositiveShapeT == NO_HIT) { return vec2(NO_HIT); } #if defined(DEPTH_TEST) float depthT = intersectDepth(fragCoord, screenUv, positionUv, directionUv); - ix.intersections[DEPTH_INTERSECTION_IDX + 0] = vec2(depthT, NEGATIVE_ENTRY); - ix.intersections[DEPTH_INTERSECTION_IDX + 1] = vec2(+INF_HIT, NEGATIVE_EXIT); + setIntersection(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); #endif - sortIntersections(ix); - // Find the first intersection interval - ix.index = 0; - vec2 entryExitT = nextIntersection(ix); + #if (SCENE_INTERSECTION_COUNT > 1) + vec2 entryExitT = initializeIntersections(ix); + #else + float exitPositiveShapeT = getIntersection(ix, 1); + vec2 entryExitT = vec2(entryPositiveShapeT, exitPositiveShapeT); + #endif // Intersection is invalid when start and end are behind the ray. if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { @@ -1070,20 +1097,16 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; // 5 float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; // 6 - // #if (defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED)) - // { - // longitude = (longitude - u_ellipsoidWestUv) * u_ellipsoidInverseLongitudeRangeUv; - // } - // #endif - // #if (defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) - // { - // latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; - // } - // #endif + #if (defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED)) + longitude = (longitude - u_ellipsoidWestUv) * u_ellipsoidInverseLongitudeRangeUv; + #endif + + #if (defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) + latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; + #endif + #if (defined(ELLIPSOID_INNER)) - { height *= u_ellipsoidInverseHeightDifferenceUv; - } #endif return vec3(longitude, latitude, height); @@ -1528,15 +1551,19 @@ void main() // Check if there's more intersections. if (currT > endT) { - vec2 entryExitT = nextIntersection(ix); - if (entryExitT.x == NO_HIT) { + #if (SCENE_INTERSECTION_COUNT == 1) break; - } else { - // Found another intersection. Keep raymarching. - currT += entryExitT.x; - endT += entryExitT.y; - positionUv += entryExitT.x * viewDirUv; - } + #else + vec2 entryExitT = nextIntersection(ix); + if (entryExitT.x == NO_HIT) { + break; + } else { + // Found another intersection. Keep raymarching. + currT += entryExitT.x; + endT += entryExitT.y; + positionUv += entryExitT.x * viewDirUv; + } + #endif } // Traverse the tree from the current ray position. From 327dd5afac9cc88268c35c2445c52cfd6e3369dc Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 12:10:41 -0400 Subject: [PATCH 021/679] simplified options for depth intersection --- Source/Scene/VoxelCylinderShape.js | 133 ++++++++----- Source/Scene/VoxelEllipsoidShape.js | 4 +- .../Functions/windowToEyeCoordinates.glsl | 96 +++++---- Source/Shaders/VoxelFS.glsl | 185 ++++++++++-------- 4 files changed, 246 insertions(+), 172 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 520e6fc76d6..f462c1c4403 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -52,14 +52,6 @@ function VoxelCylinderShape() { */ this.shapeTransform = new Matrix4(); - /** - * Check if the shape is visible. For example, if the shape has zero scale it will be invisible. - * The update function must be called before accessing this value. - * @type {Boolean} - * @readonly - */ - this.isVisible = false; - /** * @type {Number} * @private @@ -95,6 +87,29 @@ function VoxelCylinderShape() { * @private */ this._maximumAngle = VoxelCylinderShape.DefaultMaxBounds.z; + + /** + * @type {Object.} + * @readonly + */ + this.shaderUniforms = { + cylinderInnerRadiusUv: 0.0, + cylinderMinAngleUv: 0.0, + cylinderInverseAngleUv: 0.0, + }; + + /** + * @type {Object.} + * @readonly + */ + this.shaderDefines = { + CYLINDER_INTERSECTION_COUNT: undefined, + CYLINDER_INNER: undefined, + CYLINDER_OUTER: undefined, + CYLINDER_INNER_OUTER_EQUAL: undefined, + CYLINDER_WEDGE_REGULAR: undefined, + CYLINDER_WEDGE_FLIPPED: undefined, + }; } const scratchTestAngles = new Array(6); @@ -220,51 +235,64 @@ VoxelCylinderShape.prototype.update = function ( Check.typeOf.object("maxBounds", maxBounds); //>>includeEnd('debug'); - // Don't let the scale be 0, it will screw up a bunch of math - const scaleEps = CesiumMath.EPSILON8; const scale = Matrix4.getScale(modelMatrix, scratchScale); - if (Math.abs(scale.x) < scaleEps) { - scale.x = CesiumMath.signNotZero(scale.x) * scaleEps; - } - if (Math.abs(scale.y) < scaleEps) { - scale.y = CesiumMath.signNotZero(scale.y) * scaleEps; - } - if (Math.abs(scale.z) < scaleEps) { - scale.z = CesiumMath.signNotZero(scale.z) * scaleEps; - } + const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; + const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; - // // If two or more of the scales are 0 the shape will not render. - // // If the X scale or Y scale is 0 the shape will appear as a square/rectangle. - // // If the Z scale is 0 the shape will appear as an circle/ellipse. - // const xIsZero = scale.x === 0.0; - // const yIsZero = scale.y === 0.0; - // const zIsZero = scale.z === 0.0; - // if (xIsZero + yIsZero + zIsZero >= 2) { - // this.isVisible = false; - // return; - // } - - this._minimumRadius = minBounds.x; // [0,1] - this._maximumRadius = maxBounds.x; // [0,1] - this._minimumHeight = minBounds.y; // [-1,+1] - this._maximumHeight = maxBounds.y; // [-1,+1] - this._minimumAngle = CesiumMath.negativePiToPi(minBounds.z); // [-halfPi,+halfPi] - this._maximumAngle = CesiumMath.negativePiToPi(maxBounds.z); // [-halfPi,+halfPi] + // Clamp the radii to the valid range + const minRadius = CesiumMath.clamp( + minBounds.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); + const maxRadius = CesiumMath.clamp( + maxBounds.x, + defaultMinBounds.x, + defaultMaxBounds.x + ); - const minRadius = this._minimumRadius; - const maxRadius = this._maximumRadius; - const minHeight = this._minimumHeight; - const maxHeight = this._maximumHeight; - const minAngle = this._minimumAngle; - const maxAngle = this._maximumAngle; + // Clamp the heights to the valid range + const minHeight = CesiumMath.clamp( + minBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + const maxHeight = CesiumMath.clamp( + maxBounds.y, + defaultMinBounds.y, + defaultMaxBounds.y + ); + + // Clamp the angles to the valid range + const minAngle = CesiumMath.negativePiToPi(minBounds.z); + const maxAngle = CesiumMath.negativePiToPi(maxBounds.z); - // Exit early if the bounds make the shape invisible. + const outerExtent = Cartesian3.fromElements( + scale.x * maxRadius, + scale.y * maxRadius, + scale.z * 0.5 * (maxHeight - minHeight) + ); + + // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. - if (minRadius > maxRadius || minHeight > maxHeight) { - this.isVisible = false; - return; + const absEpsilon = CesiumMath.EPSILON10; + if ( + minRadius > maxRadius || + minHeight > maxHeight || + CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, absEpsilon) + ) { + return false; } + this._minimumRadius = minRadius; // [0,1] + this._maximumRadius = maxRadius; // [0,1] + this._minimumHeight = minHeight; // [-1,+1] + this._maximumHeight = maxHeight; // [-1,+1] + this._minimumAngle = minAngle; // [-halfPi,+halfPi] + this._maximumAngle = maxAngle; // [-halfPi,+halfPi] + this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); this.orientedBoundingBox = getCylinderChunkObb( @@ -289,7 +317,18 @@ VoxelCylinderShape.prototype.update = function ( this.boundingSphere ); - this.isVisible = true; + const shaderUniforms = this.shaderUniforms; + const shaderDefines = this.shaderDefines; + + // To keep things simple, clear the defines every time + shaderDefines["CYLINDER_INTERSECTION_COUNT"] = undefined; + shaderDefines["CYLINDER_INNER"] = undefined; + shaderDefines["CYLINDER_OUTER"] = undefined; + shaderDefines["CYLINDER_INNER_OUTER_EQUAL"] = undefined; + shaderDefines["CYLINDER_WEDGE_REGULAR"] = undefined; + shaderDefines["CYLINDER_WEDGE_FLIPPED"] = undefined; + + return true; }; /** diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index c343523864e..e08d31ac555 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -114,6 +114,7 @@ function VoxelEllipsoidShape() { * @readonly */ this.shaderDefines = { + ELLIPSOID_INTERSECTION_COUNT: undefined, ELLIPSOID_WEDGE_REGULAR: undefined, ELLIPSOID_WEDGE_FLIPPED: undefined, ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, @@ -122,7 +123,6 @@ function VoxelEllipsoidShape() { ELLIPSOID_CONE_TOP_FLIPPED: undefined, ELLIPSOID_OUTER: undefined, ELLIPSOID_INNER: undefined, - ELLIPSOID_INTERSECTION_COUNT: undefined, }; } @@ -245,6 +245,7 @@ VoxelEllipsoidShape.prototype.update = function ( const shaderDefines = this.shaderDefines; // To keep things simple, clear the defines every time + shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = undefined; shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; @@ -253,7 +254,6 @@ VoxelEllipsoidShape.prototype.update = function ( shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; shaderDefines["ELLIPSOID_OUTER"] = undefined; shaderDefines["ELLIPSOID_INNER"] = undefined; - shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = undefined; shaderUniforms.ellipsoidRectangle = Cartesian4.fromElements( west, diff --git a/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl b/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl index b049c51f4ac..fb902ad40fe 100644 --- a/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +++ b/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl @@ -1,38 +1,13 @@ -/** - * Transforms a position from window to eye coordinates. - * The transform from window to normalized device coordinates is done using components - * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating - * the inverse of czm_viewportTransformation. The transformation from - * normalized device coordinates to clip coordinates is done using fragmentCoordinate.w, - * which is expected to be the scalar used in the perspective divide. The transformation - * from clip to eye coordinates is done using {@link czm_inverseProjection}. - * - * @name czm_windowToEyeCoordinates - * @glslFunction - * - * @param {vec4} fragmentCoordinate The position in window coordinates to transform. - * - * @returns {vec4} The transformed position in eye coordinates. - * - * @see czm_modelToWindowCoordinates - * @see czm_eyeToWindowCoordinates - * @see czm_inverseProjection - * @see czm_viewport - * @see czm_viewportTransformation - * - * @example - * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord); - */ -vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) +vec4 czm_screenToEyeCoordinates(vec4 screenCoordinate) { // Reconstruct NDC coordinates - float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0; - float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0; - float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; + float x = 2.0 * screenCoordinate.x - 1.0; + float y = 2.0 * screenCoordinate.y - 1.0; + float z = (screenCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; vec4 q = vec4(x, y, z, 1.0); // Reverse the perspective division to obtain clip coordinates. - q /= fragmentCoordinate.w; + q /= screenCoordinate.w; // Reverse the projection transformation to obtain eye coordinates. if (!(czm_inverseProjection == mat4(0.0))) // IE and Edge sometimes do something weird with != between mat4s @@ -59,16 +34,20 @@ vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) } /** - * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates. - * This function produces more accurate results for window positions with log depth than - * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version - * of czm_windowToEyeCoordinates. + * Transforms a position from window to eye coordinates. + * The transform from window to normalized device coordinates is done using components + * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating + * the inverse of czm_viewportTransformation. The transformation from + * normalized device coordinates to clip coordinates is done using fragmentCoordinate.w, + * which is expected to be the scalar used in the perspective divide. The transformation + * from clip to eye coordinates is done using {@link czm_inverseProjection}. * * @name czm_windowToEyeCoordinates * @glslFunction * - * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform. - * @param {float} depthOrLogDepth A depth or log depth for the fragment. + * @param {vec4} fragmentCoordinate The position in window coordinates to transform. + * + * @returns {vec4} The transformed position in eye coordinates. * * @see czm_modelToWindowCoordinates * @see czm_eyeToWindowCoordinates @@ -76,9 +55,16 @@ vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) * @see czm_viewport * @see czm_viewportTransformation * - * @returns {vec4} The transformed position in eye coordinates. + * @example + * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord); */ -vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth) +vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) +{ + vec2 screenCoordXY = (fragmentCoordinate.xy - czm_viewport.xy) / czm_viewport.zw; + return czm_screenToEyeCoordinates(vec4(screenCoordXY, fragmentCoordinate.zw)); +} + +vec4 czm_screenToEyeCoordinates(vec2 screenCoordinateXY, float depthOrLogDepth) { // See reverseLogDepth.glsl. This is separate to re-use the pow. #if defined(LOG_DEPTH) || defined(LOG_DEPTH_READ_ONLY) @@ -87,13 +73,39 @@ vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth float log2Depth = depthOrLogDepth * czm_log2FarDepthFromNearPlusOne; float depthFromNear = pow(2.0, log2Depth) - 1.0; float depthFromCamera = depthFromNear + near; - vec4 windowCoord = vec4(fragmentCoordinateXY, far * (1.0 - near / depthFromCamera) / (far - near), 1.0); - vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord); + vec4 screenCoord = vec4(screenCoordinateXY, far * (1.0 - near / depthFromCamera) / (far - near), 1.0); + vec4 eyeCoordinate = czm_screenToEyeCoordinates(screenCoord); eyeCoordinate.w = 1.0 / depthFromCamera; // Better precision return eyeCoordinate; #else - vec4 windowCoord = vec4(fragmentCoordinateXY, depthOrLogDepth, 1.0); - vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord); + vec4 screenCoord = vec4(screenCoordinateXY, depthOrLogDepth, 1.0); + vec4 eyeCoordinate = czm_screenToEyeCoordinates(screenCoord); #endif return eyeCoordinate; } + +/** + * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates. + * This function produces more accurate results for window positions with log depth than + * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version + * of czm_windowToEyeCoordinates. + * + * @name czm_windowToEyeCoordinates + * @glslFunction + * + * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform. + * @param {float} depthOrLogDepth A depth or log depth for the fragment. + * + * @see czm_modelToWindowCoordinates + * @see czm_eyeToWindowCoordinates + * @see czm_inverseProjection + * @see czm_viewport + * @see czm_viewportTransformation + * + * @returns {vec4} The transformed position in eye coordinates. + */ +vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth) +{ + vec2 screenCoordXY = (fragmentCoordinateXY.xy - czm_viewport.xy) / czm_viewport.zw; + return czm_screenToEyeCoordinates(screenCoordXY, depthOrLogDepth); +} diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index db72be16bb7..268ba6580a7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -250,7 +250,9 @@ uniform float u_stepSize; #if defined(SHAPE_CYLINDER) /* Cylinder defines: + #define CYLINDER_OUTER ### // outer cylinder #define CYLINDER_INNER ### // when there's an inner cylinder + #define CYLINDER_INNER_OUTER_EQUAL ### // when inner and outer cylinder have the same radius #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections @@ -258,7 +260,7 @@ uniform float u_stepSize; // Cylinder uniforms #if defined(CYLINDER_INNER) - uniform float u_something; + uniform float u_cylinderInnerRadiusUv; #endif #if defined(CYLINDER_WEDGE_REGULAR) || defined(CYLINDER_WEDGE_FLIPPED) uniform float u_cylinderMinAngle; @@ -368,16 +370,23 @@ struct Intersections { // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. #if (SCENE_INTERSECTION_COUNT > 1) - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) ix.intersections[index * 2 + 0] = vec2(entryExit.x, float(index > 0) * 2.0 + 0.0); ix.intersections[index * 2 + 1] = vec2(entryExit.y, float(index > 0) * 2.0 + 1.0) + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x #else - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) ix.intersections[0] = entryExit.x; ix.intersections[1] = entryExit.y + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] #endif // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. #if (SCENE_INTERSECTION_COUNT > 1) - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) ix.intersections[index].x + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) #else - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) ix.intersections[index] + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (SCENE_INTERSECTION_COUNT > 1) + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) +#else + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y #endif #if (SCENE_INTERSECTION_COUNT > 1) @@ -528,7 +537,7 @@ void intersectBoxShape(Ray ray, out Intersections ix) vec2 entryExit = intersectUnitCube(ray); #endif - setIntersection(ix, BOX_INTERSECTION_INDEX, entryExit); + setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); } #endif @@ -715,7 +724,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) // Outer ellipsoid vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersection(ix, ELLIPSOID_OUTER, outerIntersect); + setIntersectionPair(ix, ELLIPSOID_OUTER, outerIntersect); // Exit early if the outer ellipsoid was missed. if (outerIntersect.x == NO_HIT) { @@ -726,7 +735,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) #if defined(ELLIPSOID_INNER) Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersection(ix, ELLIPSOID_INNER, innerIntersect); + setIntersectionPair(ix, ELLIPSOID_INNER, innerIntersect); #endif // Bottom cone @@ -739,11 +748,11 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) #if defined(ELLIPSOID_CONE_BOT_REGULAR) vec2 botConeIx = intersectRegularCone(flippedRay, flippedSouth); - setIntersection(ix, ELLIPSOID_CONE_BOT_REGULAR, botConeIx); + setIntersectionPair(ix, ELLIPSOID_CONE_BOT_REGULAR, botConeIx); #elif defined(ELLIPSOID_CONE_BOT_FLIPPED) vec4 botConeIx = intersectFlippedCone(flippedRay, flippedSouth); - setIntersection(ix, ELLIPSOID_CONE_BOT_FLIPPED + 0, botConeIx.xy); - setIntersection(ix, ELLIPSOID_CONE_BOT_FLIPPED + 1, botConeIx.zw); + setIntersectionPair(ix, ELLIPSOID_CONE_BOT_FLIPPED + 0, botConeIx.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_BOT_FLIPPED + 1, botConeIx.zw); #endif #endif @@ -752,11 +761,11 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) float north = u_ellipsoidRectangle.w; #if defined(ELLIPSOID_CONE_TOP_REGULAR) vec2 topConeIntersect = intersectRegularCone(ray, north); - setIntersection(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersect); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersect); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) vec4 topConeIntersect = intersectFlippedCone(ray, north); - setIntersection(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersect.xy); - setIntersection(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersect.zw); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersect.zw); #endif #endif @@ -766,12 +775,12 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) float east = u_ellipsoidRectangle.z; // [-pi,+pi] #if defined(ELLIPSOID_WEDGE_REGULAR) vec2 wedgeIntersect = intersectWedge(ray, west, east); - setIntersection(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); + setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); #elif defined(ELLIPSOID_WEDGE_FLIPPED) vec2 planeIntersectWest = intersectHalfSpace(ray, west); vec2 planeIntersectEast = intersectHalfSpace(ray, east); - setIntersection(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); - setIntersection(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); #endif #endif } @@ -862,6 +871,11 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) #if defined(SHAPE_CYLINDER) void intersectCylinderShape(Ray ray, inout Intersections ix) { + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + #if !defined(BOUNDS) return intersectUnitCylinder(ray); #else @@ -893,78 +907,90 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) return; } - setIntersection(ix, BOX_INTERSECTION_INDEX, outerIntersect); + setIntersectionPair(ix, CYLINDER_OUTER, outerIntersect); - #if defined(BOUNDS_0_MIN) - vec3 innerScale = vec3(minRadius, minRadius, 1.0); - Ray innerRay = Ray((ray.pos - pos) / innerScale, ray.dir / innerScale); - vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - - // TODO: use define instead of branch - if (minRadius != maxRadius) { - intersections[2] = vec2(float(2), innerIntersect.x); - intersections[3] = vec2(float(3), innerIntersect.y); - } else { - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If sortIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - - intersections[0] = vec2(float(0), outerIntersect.x); - intersections[1] = vec2(float(2), innerIntersect.x); - intersections[2] = vec2(float(3), innerIntersect.y); - intersections[3] = vec2(float(1), outerIntersect.y); - } + #if defined(CYLINDER_INNER_OUTER_EQUAL) + + #else + #endif - #if defined(BOUNDS_2_MIN) || defined(BOUNDS_2_MAX) + vec3 innerScale = vec3(minRadius, minRadius, 1.0); + Ray innerRay = Ray((ray.pos - pos) / innerScale, ray.dir / innerScale); + vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + + // TODO: use define instead of branch + if (minRadius != maxRadius) { + intersections[2] = vec2(float(2), innerIntersect.x); + intersections[3] = vec2(float(3), innerIntersect.y); + } else { + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If sortIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + } + + #if defined(CYLINDER_WEDGE_REGULAR) vec2 wedgeIntersect = intersectWedge(ray, minAngle, maxAngle); - intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 0] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 0), wedgeIntersect.x); - intersections[BOUNDS_2_MIN_MAX_IDX * 2 + 1] = vec2(float(BOUNDS_2_MIN_MAX_IDX * 2 + 1), wedgeIntersect.y); - #endif + setIntersectionPair(ix, CYLINDER_WEDGE_REGULAR, wedgeIntersect); + #elif defined(CYLINDER_WEDGE_FLIPPED) + vec2 planeIntersectMinAngle = intersectHalfSpace(ray, minAngle); + vec2 planeIntersectMaxAngle = intersectHalfSpace(ray, maxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_FLIPPED + 0, planeIntersectMinAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_FLIPPED + 1, planeIntersectMaxAngle); + #endif #endif } #endif +void intersectShape(Ray ray, out Intersections ix) { + #if defined(SHAPE_BOX) + intersectBoxShape(ray, ix); + #elif defined(SHAPE_ELLIPSOID) + intersectEllipsoidShape(ray, ix); + #elif defined(SHAPE_CYLINDER) + intersectCylinderShape(ray, ix); + #endif +} + #if defined(DEPTH_TEST) -float intersectDepth(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv) { - float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenUv)); +float intersectDepth(vec2 screenCoord, Ray ray) { + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); if (logDepthOrDepth != 0.0) { // Calculate how far the ray must travel before it hits the depth buffer. - vec4 eyeCoordinateDepth = czm_windowToEyeCoordinates(fragCoord, logDepthOrDepth); + vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); eyeCoordinateDepth /= eyeCoordinateDepth.w; vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - return dot(directionUv, depthPositionUv - positionUv); + return dot(depthPositionUv - ray.pos, ray.dir); } else { // There's no depth at this position so set it to some really far value. - return czm_infinity; + return +INF_HIT; } } #endif -vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directionUv, out Intersections ix) { +vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { Ray ray = Ray(positionUv, directionUv); // Do a ray-shape intersection to find the exact starting and ending points. - #if defined(SHAPE_BOX) - intersectBoxShape(ray, ix); - #elif defined(SHAPE_ELLIPSOID) - intersectEllipsoidShape(ray, ix); - #elif defined(SHAPE_CYLINDER) - intersectCylinderShape(ray, ix);f - #endif + intersectShape(ray, ix); // Check if the positive shape was completely missed, and if so, exit early. float entryPositiveShapeT = getIntersection(ix, 0); @@ -972,9 +998,10 @@ vec2 intersectScene(vec2 fragCoord, vec2 screenUv, vec3 positionUv, vec3 directi return vec2(NO_HIT); } + // Intersect depth texture #if defined(DEPTH_TEST) - float depthT = intersectDepth(fragCoord, screenUv, positionUv, directionUv); - setIntersection(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); + float depthT = intersectDepth(screenCoord, ray); + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); #endif // Find the first intersection interval @@ -1119,7 +1146,6 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { float radius = length(positionLocal.xy); // [0,1] float height = positionUv.z; // [0,1] float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - vec3 positionShape = vec3(radius, height, angle); #if defined(BOUNDS) positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] @@ -1128,20 +1154,18 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { // and set the shape space position to 1 (front) or 0 (back) accordingly. #endif - return positionShape; + return vec3(radius, height, angle); } #endif vec3 transformFromUvToShapeSpace(in vec3 positionUv) { #if defined(SHAPE_BOX) - vec3 positionShape = transformFromUvToBoxSpace(positionUv); + return transformFromUvToBoxSpace(positionUv); #elif defined(SHAPE_ELLIPSOID) - vec3 positionShape = transformFromUvToEllipsoidSpace(positionUv); + return transformFromUvToEllipsoidSpace(positionUv); #elif defined(SHAPE_CYLINDER) - vec3 positionShape = transformFromUvToCylinderSpace(positionUv); + return transformFromUvToCylinderSpace(positionUv); #endif - - return positionShape; } // -------------------------------------------------------- @@ -1437,15 +1461,14 @@ void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpac void main() { vec4 fragCoord = gl_FragCoord; - vec2 screenUv = (fragCoord.xy - czm_viewport.xy) / czm_viewport.zw; - vec4 eyeCoordinate = czm_windowToEyeCoordinates(fragCoord); - vec3 eyeDirection = normalize(eyeCoordinate.xyz); + vec2 screenCoord = (fragCoord.xy - czm_viewport.xy) / czm_viewport.zw; // [0,1] + vec3 eyeDirection = normalize(czm_windowToEyeCoordinates(fragCoord).xyz); vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case vec3 viewPosUv = u_cameraPositionUv; Intersections ix; - vec2 entryExitT = intersectScene(fragCoord.xy, screenUv, viewPosUv, viewDirUv, ix); + vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); // Exit early if the scene was completely missed. if (entryExitT.x == NO_HIT) { @@ -1477,7 +1500,7 @@ void main() float stepT = u_stepSize * levelStepMult; #if defined(JITTER) - float noise = hash(screenUv); // [0,1] + float noise = hash(screenCoord); // [0,1] currT += noise * stepT; positionUv += noise * stepT * viewDirUv; #endif From ea5e344cb8cf3aeb2591cd461b333ea403824f56 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 16:32:40 -0400 Subject: [PATCH 022/679] fixed some parts of the cylinder shape --- Source/Scene/VoxelBoxShape.js | 17 +- Source/Scene/VoxelCylinderShape.js | 417 ++++++++++++++++++++-------- Source/Scene/VoxelEllipsoidShape.js | 18 +- Source/Shaders/VoxelFS.glsl | 225 +++++++-------- 4 files changed, 428 insertions(+), 249 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index 2438159a8d3..cbd62a05358 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -87,8 +87,8 @@ function VoxelBoxShape() { * @readonly */ this.shaderDefines = { - BOX_INTERSECTION_COUNT: 1, // never changes - BOX_INTERSECTION_INDEX: 0, // never changes + BOX_INTERSECTION_COUNT: undefined, + BOX_INTERSECTION_INDEX: undefined, BOX_BOUNDED: undefined, BOX_XY_PLANE: undefined, BOX_XZ_PLANE: undefined, @@ -204,10 +204,15 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { const shaderDefines = this.shaderDefines; // To keep things simple, clear the defines every time - shaderDefines["BOX_BOUNDED"] = undefined; - shaderDefines["BOX_XY_PLANE"] = undefined; - shaderDefines["BOX_XZ_PLANE"] = undefined; - shaderDefines["BOX_YZ_PLANE"] = undefined; + for (const key in shaderDefines) { + if (shaderDefines.hasOwnProperty(key)) { + shaderDefines[key] = undefined; + } + } + + // Never changes + shaderDefines["BOX_INTERSECTION_COUNT"] = 1; + shaderDefines["BOX_INTERSECTION_INDEX"] = 0; if ( minBounds.x !== defaultMinBounds.x || diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index f462c1c4403..c6d9d7833c0 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -93,9 +93,18 @@ function VoxelCylinderShape() { * @readonly */ this.shaderUniforms = { + cylinderScaleUvToBounds: new Cartesian3(), + cylinderTranslateUvToBounds: new Cartesian3(), + cylinderScaleUvToInnerBounds: new Cartesian3(), + cylinderTranslateUvToInnerBounds: new Cartesian3(), cylinderInnerRadiusUv: 0.0, + cylinderInverseRadiusRangeUv: 0.0, + cylinderMinHeightUv: 0.0, + cylinderInverseHeightRangeUv: 0.0, + cylinderMinAngle: 0.0, + cylinderMaxAngle: 0.0, cylinderMinAngleUv: 0.0, - cylinderInverseAngleUv: 0.0, + cylinderInverseAngleRangeUv: 0.0, }; /** @@ -104,118 +113,29 @@ function VoxelCylinderShape() { */ this.shaderDefines = { CYLINDER_INTERSECTION_COUNT: undefined, + CYLINDER_OUTER_INDEX: undefined, + CYLINDER_OUTER_NON_DEFAULT: undefined, CYLINDER_INNER: undefined, - CYLINDER_OUTER: undefined, CYLINDER_INNER_OUTER_EQUAL: undefined, + CYLINDER_INNER_INDEX: undefined, + CYLINDER_HEIGHT_NON_DEFAULT: undefined, + CYLINDER_HEIGHT_ZERO: undefined, + CYLINDER_WEDGE_INDEX: undefined, CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, }; } -const scratchTestAngles = new Array(6); - -// Preallocated arrays for all of the possible test angle counts -const scratchPositions = [ - new Array(), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), -]; - const scratchScale = new Cartesian3(); +const scratchBoundsTranslation = new Cartesian3(); +const scratchBoundsScale = new Cartesian3(); +const scratchTransformLocalToBounds = new Matrix4(); +const scratchTransformUvToBounds = new Matrix4(); +const transformUvToLocal = Matrix4.fromRotationTranslation( + Matrix3.fromUniformScale(2.0, new Matrix3()), + new Cartesian3(-1.0, -1.0, -1.0), + new Matrix4() +); /** * Update the shape's state. @@ -236,31 +156,35 @@ VoxelCylinderShape.prototype.update = function ( //>>includeEnd('debug'); const scale = Matrix4.getScale(modelMatrix, scratchScale); - const defaultMinBounds = VoxelCylinderShape.DefaultMinBounds; - const defaultMaxBounds = VoxelCylinderShape.DefaultMaxBounds; + const defaultMinRadius = VoxelCylinderShape.DefaultMinBounds.x; + const defaultMaxRadius = VoxelCylinderShape.DefaultMaxBounds.x; + const defaultMinHeight = VoxelCylinderShape.DefaultMinBounds.y; + const defaultMaxHeight = VoxelCylinderShape.DefaultMaxBounds.y; + const defaultMinAngle = VoxelCylinderShape.DefaultMinBounds.z; + const defaultMaxAngle = VoxelCylinderShape.DefaultMaxBounds.z; // Clamp the radii to the valid range const minRadius = CesiumMath.clamp( minBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x + defaultMinRadius, + defaultMaxRadius ); const maxRadius = CesiumMath.clamp( maxBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x + defaultMinRadius, + defaultMaxRadius ); // Clamp the heights to the valid range const minHeight = CesiumMath.clamp( minBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y + defaultMinHeight, + defaultMaxHeight ); const maxHeight = CesiumMath.clamp( maxBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y + defaultMinHeight, + defaultMaxHeight ); // Clamp the angles to the valid range @@ -277,6 +201,7 @@ VoxelCylinderShape.prototype.update = function ( // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. const absEpsilon = CesiumMath.EPSILON10; if ( + maxRadius === 0.0 || minRadius > maxRadius || minHeight > maxHeight || CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, absEpsilon) || @@ -317,16 +242,163 @@ VoxelCylinderShape.prototype.update = function ( this.boundingSphere ); + const isDefaultOuterCylinder = maxRadius === defaultMaxRadius; + const hasInnerCylinder = minRadius > defaultMinRadius; + const isDefaultHeight = + minHeight === defaultMinHeight && maxHeight === defaultMaxHeight; + + const angleWidth = + maxAngle - minAngle + (maxAngle < minAngle) * CesiumMath.TWO_PI; + const hasWedgeRegular = + angleWidth >= CesiumMath.PI && + CesiumMath.lessThan(angleWidth, CesiumMath.TWO_PI, absEpsilon); + const hasWedgeFlipped = angleWidth < CesiumMath.PI; + const hasWedge = hasWedgeRegular || hasWedgeFlipped; + const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; // To keep things simple, clear the defines every time - shaderDefines["CYLINDER_INTERSECTION_COUNT"] = undefined; - shaderDefines["CYLINDER_INNER"] = undefined; - shaderDefines["CYLINDER_OUTER"] = undefined; - shaderDefines["CYLINDER_INNER_OUTER_EQUAL"] = undefined; - shaderDefines["CYLINDER_WEDGE_REGULAR"] = undefined; - shaderDefines["CYLINDER_WEDGE_FLIPPED"] = undefined; + for (const key in shaderDefines) { + if (shaderDefines.hasOwnProperty(key)) { + shaderDefines[key] = undefined; + } + } + + // Keep track of how many intersections there are going to be. + let intersectionCount = 0; + + // Intersects an outer cylinder. + shaderDefines["CYLINDER_OUTER_INDEX"] = intersectionCount; + intersectionCount += 1; + + if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { + shaderDefines["CYLINDER_OUTER_NON_DEFAULT"] = true; + const boundsScaleLocalToBounds = Cartesian3.fromElements( + 1.0 / maxRadius, + 1.0 / maxRadius, + 1.0 / (maxHeight === minHeight ? 1.0 : 0.5 * (maxHeight - minHeight)), + scratchBoundsScale + ); + + // -inverse(scale) * translation // affine inverse + // -inverse(scale) * 0.5 * (minHeight + maxHeight) + const boundsTranslateLocalToBounds = Cartesian3.fromElements( + 0.0, + 0.0, + -boundsScaleLocalToBounds.z * 0.5 * (minHeight + maxHeight), + scratchBoundsTranslation + ); + + const transformLocalToBounds = Matrix4.fromRotationTranslation( + Matrix3.fromScale(boundsScaleLocalToBounds), + boundsTranslateLocalToBounds, + scratchTransformLocalToBounds + ); + const transformUvToBounds = Matrix4.multiplyTransformation( + transformLocalToBounds, + transformUvToLocal, + scratchTransformUvToBounds + ); + shaderUniforms.cylinderScaleUvToBounds = Matrix4.getScale( + transformUvToBounds, + shaderUniforms.cylinderScaleUvToBounds + ); + shaderUniforms.cylinderTranslateUvToBounds = Matrix4.getTranslation( + transformUvToBounds, + shaderUniforms.cylinderTranslateUvToBounds + ); + } + + // Intersects an inner cylinder for the min height. + if (hasInnerCylinder) { + shaderDefines["CYLINDER_INNER"] = true; + + if (minRadius === maxRadius) { + shaderDefines["CYLINDER_INNER_OUTER_EQUAL"] = true; + } else { + shaderDefines["CYLINDER_INNER_INDEX"] = intersectionCount; + intersectionCount += 1; + } + } + + if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { + const boundsScaleLocalToInnerBounds = Cartesian3.fromElements( + 1.0 / minRadius, + 1.0 / minRadius, + 1.0 / (maxHeight === minHeight ? 1.0 : 0.5 * (maxHeight - minHeight)), + scratchBoundsScale + ); + + // -inverse(scale) * translation // affine inverse + // -inverse(scale) * 0.5 * (minHeight + maxHeight) + const boundsTranslateLocalToInnerBounds = Cartesian3.fromElements( + 0.0, + 0.0, + -boundsScaleLocalToInnerBounds.z * 0.5 * (minHeight + maxHeight), + scratchBoundsTranslation + ); + + const transformLocalToBounds = Matrix4.fromRotationTranslation( + Matrix3.fromScale(boundsScaleLocalToInnerBounds), + boundsTranslateLocalToInnerBounds, + scratchTransformLocalToBounds + ); + const transformUvToBounds = Matrix4.multiplyTransformation( + transformLocalToBounds, + transformUvToLocal, + scratchTransformUvToBounds + ); + shaderUniforms.cylinderScaleUvToInnerBounds = Matrix4.getScale( + transformUvToBounds, + shaderUniforms.cylinderScaleUvToInnerBounds + ); + shaderUniforms.cylinderTranslateUvToInnerBounds = Matrix4.getTranslation( + transformUvToBounds, + shaderUniforms.cylinderTranslateUvToInnerBounds + ); + + shaderUniforms.cylinderInnerRadiusUv = minRadius / defaultMaxRadius; + shaderUniforms.cylinderInverseRadiusRangeUv = + 1.0 / (maxRadius / defaultMaxRadius - minRadius / defaultMaxRadius); + } + + if (!isDefaultHeight) { + shaderUniforms.cylinderMinHeightUv = minHeight * 0.5 + 0.5; + shaderUniforms.cylinderInverseHeightRangeUv = 2.0 / (maxHeight - minHeight); + shaderDefines["CYLINDER_HEIGHT_NON_DEFAULT"] = true; + + if (minHeight === maxHeight) { + shaderDefines["CYLINDER_HEIGHT_ZERO"] = true; + } + } + + if (hasWedge) { + shaderDefines["CYLINDER_WEDGE"] = true; + shaderDefines["CYLINDER_WEDGE_INDEX"] = intersectionCount; + shaderUniforms.minAngle = minAngle; + shaderUniforms.maxAngle = maxAngle; + + const minAngleUv = + (minAngle - defaultMinAngle) / (defaultMaxAngle - defaultMinAngle); + const maxAngleUv = + (maxAngle - defaultMinAngle) / (defaultMaxAngle - defaultMinAngle); + + shaderUniforms.cylinderMinAngleUv = minAngleUv; + shaderUniforms.cylinderInverseAngleRangeUv = + 1.0 / (maxAngleUv - minAngleUv); + + if (hasWedgeRegular) { + // Intersects a wedge for the min and max longitude. + shaderDefines["CYLINDER_WEDGE_REGULAR"] = true; + intersectionCount += 1; + } else if (hasWedgeFlipped) { + shaderDefines["CYLINDER_WEDGE_FLIPPED"] = true; + intersectionCount += 2; + } + } + + shaderDefines["CYLINDER_INTERSECTION_COUNT"] = intersectionCount; return true; }; @@ -494,6 +566,109 @@ VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); */ VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); +const scratchTestAngles = new Array(6); + +// Preallocated arrays for all of the possible test angle counts +const scratchPositions = [ + new Array(), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), + new Array( + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3(), + new Cartesian3() + ), +]; + /** * Computes an {@link OrientedBoundingBox} for a subregion of the shape. * diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index e08d31ac555..edd2a84d11e 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -85,7 +85,7 @@ function VoxelEllipsoidShape() { this._translation = new Cartesian3(); /** - * @type {Matrix3 + * @type {Matrix3} */ this._rotation = new Matrix3(); @@ -245,15 +245,11 @@ VoxelEllipsoidShape.prototype.update = function ( const shaderDefines = this.shaderDefines; // To keep things simple, clear the defines every time - shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = undefined; - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = undefined; - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = undefined; - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = undefined; - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = undefined; - shaderDefines["ELLIPSOID_OUTER"] = undefined; - shaderDefines["ELLIPSOID_INNER"] = undefined; + for (const key in shaderDefines) { + if (shaderDefines.hasOwnProperty(key)) { + shaderDefines[key] = undefined; + } + } shaderUniforms.ellipsoidRectangle = Cartesian4.fromElements( west, @@ -292,7 +288,7 @@ VoxelEllipsoidShape.prototype.update = function ( const hasBottomConeRegular = south <= 0.0 && south > -CesiumMath.PI_OVER_TWO; const hasBottomConeFlipped = south > 0.0; - // Determine how many intersections there are going to be. + // Keep track of how many intersections there are going to be. let intersectionCount = 0; // Intersects an outer ellipsoid for the max height. diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 268ba6580a7..7ded9eb7d57 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -215,29 +215,29 @@ uniform float u_stepSize; #if defined(SHAPE_ELLIPSOID) /* Ellipsoid defines: + #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone #define ELLIPSOID_CONE_BOTTOM_FLIPPED ### // when cone shape has two intersection intervals #define ELLIPSOID_CONE_TOP_REGULAR ### // when there's a top cone #define ELLIPSOID_CONE_TOP_FLIPPED ### // when cone shape has two intersection intervals - #define ELLIPSOID_INNER ### // when there's an inner ellipsoid #define ELLIPSOID_OUTER ### // outer ellipsoid - always defined - #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections + #define ELLIPSOID_INNER ### // when there's an inner ellipsoid */ // Ellipsoid uniforms uniform vec3 u_ellipsoidRadiiUv; // [0,1] uniform vec3 u_ellipsoidInverseRadiiSquaredUv; - #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) uniform float u_ellipsoidWestUv; uniform float u_ellipsoidInverseLongitudeRangeUv; #endif - #if defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) uniform float u_ellipsoidSouthUv; uniform float u_ellipsoidInverseLatitudeRangeUv; #endif @@ -250,25 +250,47 @@ uniform float u_stepSize; #if defined(SHAPE_CYLINDER) /* Cylinder defines: - #define CYLINDER_OUTER ### // outer cylinder - #define CYLINDER_INNER ### // when there's an inner cylinder + #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections + #define CYLINDER_OUTER_INDEX ### // outer cylinder + #define CYLINDER_OUTER_NON_DEFAULT ### // + #define CYLINDER_INNER #define CYLINDER_INNER_OUTER_EQUAL ### // when inner and outer cylinder have the same radius + #define CYLINDER_INNER_INDEX ### // when there's an inner cylinder + #define CYLINDER_HEIGHT_NON_DEFAULT ### // + #define CYLINDER_HEIGHT_ZERO // when the height is 0 + #define CYLINDER_WEDGE_INDEX // #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals - #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections */ // Cylinder uniforms + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) + uniform vec3 u_cylinderScaleUvToBounds; + uniform vec3 u_cylinderTranslateUvToBounds; + #endif + + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) + uniform float u_cylinderInnerRadiusUv; + uniform float u_cylinderInverseRadiusRangeUv; + #endif + #if defined(CYLINDER_INNER) - uniform float u_cylinderInnerRadiusUv; + uniform vec3 u_cylinderScaleUvToInnerBounds; + uniform vec3 u_cylinderTranslateUvToInnerBounds; + #endif + #if defined(CYLINDER_HEIGHT_NON_DEFAULT) + uniform float u_cylinderMinHeightUv; + uniform float u_cylinderInverseHeightRangeUv; #endif - #if defined(CYLINDER_WEDGE_REGULAR) || defined(CYLINDER_WEDGE_FLIPPED) + #if defined(CYLINDER_WEDGE) uniform float u_cylinderMinAngle; - uniform float u_cylinderInverseAngleRange; + uniform float u_cylinderMaxAngle; + uniform float u_cylinderMinAngleUv; + uniform float u_cylinderInverseAngleRangeUv; #endif #endif -// Determine how many intersections there are going to be +// Keep track of how many intersections there are going to be #if defined(SHAPE_BOX) #define SHAPE_INTERSECTION_COUNT BOX_INTERSECTION_COUNT #elif defined(SHAPE_ELLIPSOID) @@ -739,33 +761,33 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) #endif // Bottom cone - #if defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) // Flip the inputs because the intersection function expects a cone growing towards +Z. - float flippedSouth = -u_ellipsoidRectangle.y; + float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] Ray flippedRay = ray; flippedRay.dir.z *= -1.0; flippedRay.pos.z *= -1.0; - #if defined(ELLIPSOID_CONE_BOT_REGULAR) - vec2 botConeIx = intersectRegularCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOT_REGULAR, botConeIx); - #elif defined(ELLIPSOID_CONE_BOT_FLIPPED) - vec4 botConeIx = intersectFlippedCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOT_FLIPPED + 0, botConeIx.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_BOT_FLIPPED + 1, botConeIx.zw); + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_REGULAR, bottomConeIntersection); + #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) + vec4 bottomConeIntersection = intersectFlippedCone(flippedRay, flippedSouth); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 1, bottomConeIntersection.zw); #endif #endif // Top cone #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) - float north = u_ellipsoidRectangle.w; + float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] #if defined(ELLIPSOID_CONE_TOP_REGULAR) - vec2 topConeIntersect = intersectRegularCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersect); + vec2 topConeIntersection = intersectRegularCone(ray, north); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersection); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) - vec4 topConeIntersect = intersectFlippedCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersect.zw); + vec4 topConeIntersection = intersectFlippedCone(ray, north); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersection.zw); #endif #endif @@ -843,7 +865,7 @@ vec2 intersectUnitCircle(Ray ray) { } #endif -#if defined(SHAPE_CYLINDER) && defined(BOUNDS_0_MIN) +#if defined(SHAPE_CYLINDER) && defined(CYLINDER_INNER) && !defined(CYLINDER_INNER_OUTER_EQUAL) vec2 intersectInfiniteUnitCylinder(Ray ray) { vec3 o = ray.pos; @@ -871,91 +893,61 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) #if defined(SHAPE_CYLINDER) void intersectCylinderShape(Ray ray, inout Intersections ix) { - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) + Ray outerRay = Ray(ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds, ray.dir * u_cylinderScaleUvToBounds); + #else + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + Ray outerRay = Ray(ray.pos * 2.0 - 1.0, ray.dir * 2.0); + #endif - #if !defined(BOUNDS) - return intersectUnitCylinder(ray); + #if defined(CYLINDER_HEIGHT_ZERO) + vec2 outerIntersect = intersectUnitCircle(outerRay); #else - float minRadius = u_minBounds.x; // [0,1] - float maxRadius = u_maxBounds.x; // [0,1] - float minHeight = u_minBounds.y; // [-1,+1] - float maxHeight = u_maxBounds.y; // [-1,+1] - float minAngle = u_minBounds.z; // [-pi,+pi] - float maxAngle = u_maxBounds.z; // [-pi,+pi] - - float posZ = 0.5 * (minHeight + maxHeight); - vec3 pos = vec3(0.0, 0.0, posZ); - float scaleZ = 0.5 * (maxHeight - minHeight); - - vec2 outerIntersect; + vec2 outerIntersect = intersectUnitCylinder(outerRay); + #endif - // TODO: use define instead of branch - if (scaleZ == 0.0) { - vec3 outerScale = vec3(maxRadius, maxRadius, 1.0); - Ray outerRay = Ray((ray.pos - pos) / outerScale, ray.dir / outerScale); - outerIntersect = intersectUnitCircle(outerRay); - } else { - vec3 outerScale = vec3(maxRadius, maxRadius, scaleZ); - Ray outerRay = Ray((ray.pos - pos) / outerScale, ray.dir / outerScale); - outerIntersect = intersectUnitCylinder(outerRay); - } + setIntersectionPair(ix, CYLINDER_OUTER_INDEX, outerIntersect); - if (outerIntersect.x == NO_HIT) { - return; - } + if (outerIntersect.x == NO_HIT) { + return; + } - setIntersectionPair(ix, CYLINDER_OUTER, outerIntersect); + #if defined(CYLINDER_INNER_OUTER_EQUAL) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. - #if defined(CYLINDER_INNER_OUTER_EQUAL) - - #else - - #endif - - vec3 innerScale = vec3(minRadius, minRadius, 1.0); - Ray innerRay = Ray((ray.pos - pos) / innerScale, ray.dir / innerScale); + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If sortIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(CYLINDER_INNER) + Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); + #endif - // TODO: use define instead of branch - if (minRadius != maxRadius) { - intersections[2] = vec2(float(2), innerIntersect.x); - intersections[3] = vec2(float(3), innerIntersect.y); - } else { - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If sortIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - } - - #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectWedge(ray, minAngle, maxAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_REGULAR, wedgeIntersect); - #elif defined(CYLINDER_WEDGE_FLIPPED) - vec2 planeIntersectMinAngle = intersectHalfSpace(ray, minAngle); - vec2 planeIntersectMaxAngle = intersectHalfSpace(ray, maxAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_FLIPPED + 0, planeIntersectMinAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_FLIPPED + 1, planeIntersectMaxAngle); - #endif + #if defined(CYLINDER_WEDGE_REGULAR) + vec2 wedgeIntersect = intersectWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); + #elif defined(CYLINDER_WEDGE_FLIPPED) + vec2 planeIntersectMinAngle = intersectHalfSpace(outerRay, u_cylinderMinAngle); + vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, planeIntersectMinAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, planeIntersectMaxAngle); #endif } #endif @@ -1017,7 +1009,7 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int return vec2(NO_HIT); } - // Set start to 0 when ray is inside the shape. + // Set start to 0.0 when ray is inside the shape. entryExitT.x = max(entryExitT.x, 0.0); return entryExitT; @@ -1128,7 +1120,7 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { longitude = (longitude - u_ellipsoidWestUv) * u_ellipsoidInverseLongitudeRangeUv; #endif - #if (defined(ELLIPSOID_CONE_BOT_REGULAR) || defined(ELLIPSOID_CONE_BOT_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) + #if (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; #endif @@ -1147,11 +1139,22 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { float height = positionUv.z; // [0,1] float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - #if defined(BOUNDS) - positionShape = (positionShape - u_minBoundsUv) * u_inverseBoundsUv; // [0,1] - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) + radius = (radius - u_cylinderInnerRadiusUv) * u_cylinderInverseRadiusRangeUv; + #endif + + #if defined(CYLINDER_HEIGHT_NON_DEFAULT) + height = (height - u_cylinderMinHeightUv) * u_cylinderInverseHeightRangeUv; + #endif + + #if defined(CYLINDER_WEDGE_REGULAR) + angle = (angle - u_cylinderMinAngleUv) * u_cylinderInverseAngleRangeUv; + #elif defined(CYLINDER_WEDGE_FLIPPED) + angle = (angle - u_cylinderMinAngleUv) * u_cylinderInverseAngleRangeUv; #endif return vec3(radius, height, angle); From 25775af3c10cc8e371c6d292404e525de14e641d Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 17:26:54 -0400 Subject: [PATCH 023/679] change to multiply add for cylinder --- Source/Scene/VoxelCylinderShape.js | 43 +++++++++++++++++++++++------- Source/Shaders/VoxelFS.glsl | 12 ++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index c6d9d7833c0..62f72fae4d0 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -97,10 +97,10 @@ function VoxelCylinderShape() { cylinderTranslateUvToBounds: new Cartesian3(), cylinderScaleUvToInnerBounds: new Cartesian3(), cylinderTranslateUvToInnerBounds: new Cartesian3(), - cylinderInnerRadiusUv: 0.0, - cylinderInverseRadiusRangeUv: 0.0, - cylinderMinHeightUv: 0.0, - cylinderInverseHeightRangeUv: 0.0, + cylinderScaleRadiusUvToBoundsRadiusUv: 0.0, + cylinderOffsetRadiusUvToBoundsRadiusUv: 0.0, + cylinderScaleHeightUvToBoundsHeightUv: 0.0, + cylinderOffsetHeightUvToBoundsHeightUv: 0.0, cylinderMinAngle: 0.0, cylinderMaxAngle: 0.0, cylinderMinAngleUv: 0.0, @@ -358,19 +358,44 @@ VoxelCylinderShape.prototype.update = function ( shaderUniforms.cylinderTranslateUvToInnerBounds ); - shaderUniforms.cylinderInnerRadiusUv = minRadius / defaultMaxRadius; - shaderUniforms.cylinderInverseRadiusRangeUv = - 1.0 / (maxRadius / defaultMaxRadius - minRadius / defaultMaxRadius); + // delerp(radius, minRadius, maxRadius) + // (radius - minRadius) / (maxRadius - minRadius) + // radius / (maxRadius - minRadius) - minRadius / (maxRadius - minRadius) + // scale = 1.0 / (maxRadius - minRadius) + // offset = -minRadius / (maxRadius - minRadius) + // offset = minRadius / (minRadius - maxRadius) + + const scale = 1.0 / (maxRadius - minRadius); + const offset = minRadius / (minRadius - maxRadius); + + shaderUniforms.cylinderScaleRadiusUvToBoundsRadiusUv = scale; + shaderUniforms.cylinderOffsetRadiusUvToBoundsRadiusUv = offset; } if (!isDefaultHeight) { - shaderUniforms.cylinderMinHeightUv = minHeight * 0.5 + 0.5; - shaderUniforms.cylinderInverseHeightRangeUv = 2.0 / (maxHeight - minHeight); shaderDefines["CYLINDER_HEIGHT_NON_DEFAULT"] = true; if (minHeight === maxHeight) { shaderDefines["CYLINDER_HEIGHT_ZERO"] = true; } + + // delerp(heightUv, minHeightUv, maxHeightUv) + // (heightUv - minHeightUv) / (maxHeightUv - minHeightUv) + // heightUv / (maxHeightUv - minHeightUv) - minHeightUv / (maxHeightUv - minHeightUv) + // scale = 1.0 / (maxHeightUv - minHeightUv) + // scale = 1.0 / ((maxHeight * 0.5 + 0.5) - (minHeight * 0.5 + 0.5)) + // scale = 2.0 / (maxHeight - minHeight) + // offset = -minHeightUv / (maxHeightUv - minHeightUv) + // offset = -minHeightUv / ((maxHeight * 0.5 + 0.5) - (minHeight * 0.5 + 0.5)) + // offset = -2.0 * (minHeight * 0.5 + 0.5) / (maxHeight - minHeight) + // offset = -(minHeight + 1.0) / (maxHeight - minHeight) + // offset = (minHeight + 1.0) / (minHeight - maxHeight) + + const scale = 2.0 / (maxHeight - minHeight); + const offset = (minHeight + 1.0) / (minHeight - maxHeight); + + shaderUniforms.cylinderScaleHeightUvToBoundsHeightUv = scale; + shaderUniforms.cylinderOffsetHeightUvToBoundsHeightUv = offset; } if (hasWedge) { diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 7ded9eb7d57..3225d9eb2ae 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -270,8 +270,8 @@ uniform float u_stepSize; #endif #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - uniform float u_cylinderInnerRadiusUv; - uniform float u_cylinderInverseRadiusRangeUv; + uniform float u_cylinderScaleRadiusUvToBoundsRadiusUv; + uniform float u_cylinderOffsetRadiusUvToBoundsRadiusUv; #endif #if defined(CYLINDER_INNER) @@ -279,8 +279,8 @@ uniform float u_stepSize; uniform vec3 u_cylinderTranslateUvToInnerBounds; #endif #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - uniform float u_cylinderMinHeightUv; - uniform float u_cylinderInverseHeightRangeUv; + uniform float u_cylinderScaleHeightUvToBoundsHeightUv; + uniform float u_cylinderOffsetHeightUvToBoundsHeightUv; #endif #if defined(CYLINDER_WEDGE) uniform float u_cylinderMinAngle; @@ -1144,11 +1144,11 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { // and set the shape space position to 1 (front) or 0 (back) accordingly. #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - radius = (radius - u_cylinderInnerRadiusUv) * u_cylinderInverseRadiusRangeUv; + radius = radius * u_cylinderScaleRadiusUvToBoundsRadiusUv + u_cylinderOffsetRadiusUvToBoundsRadiusUv; #endif #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - height = (height - u_cylinderMinHeightUv) * u_cylinderInverseHeightRangeUv; + height = height * u_cylinderScaleHeightUvToBoundsHeightUv + u_cylinderOffsetHeightUvToBoundsHeightUv; #endif #if defined(CYLINDER_WEDGE_REGULAR) From 9f0e8e7266b53a11e17c791f12a235ca80981390 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 17:49:51 -0400 Subject: [PATCH 024/679] rearranged intersection functions by shape type --- Source/Shaders/VoxelFS.glsl | 463 ++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 232 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 3225d9eb2ae..a49b7199cfe 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -538,31 +538,6 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] } #endif -#if defined(SHAPE_BOX) -void intersectBoxShape(Ray ray, out Intersections ix) -{ - #if !defined(BOX_BOUNDED) - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir = ray.dir * 2.0; - vec2 entryExit = intersectUnitCube(ray); - #elif defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) - // Transform the ray into unit square space on Z plane - ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); - vec2 entryExit = intersectUnitSquare(ray); - #else - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxTranslateUvToBounds; - ray.dir *= u_boxScaleUvToBounds; - vec2 entryExit = intersectUnitCube(ray); - #endif - - setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); -} -#endif - #if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_REGULAR)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_REGULAR)) vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) { @@ -736,78 +711,6 @@ vec2 intersectRegularCone(Ray ray, float latitude) { } #endif -#if defined(SHAPE_ELLIPSOID) -void intersectEllipsoidShape(in Ray ray, inout Intersections ix) -{ - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; - - // Outer ellipsoid - vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersectionPair(ix, ELLIPSOID_OUTER, outerIntersect); - - // Exit early if the outer ellipsoid was missed. - if (outerIntersect.x == NO_HIT) { - return; - } - - // Inner ellipsoid - #if defined(ELLIPSOID_INNER) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INNER, innerIntersect); - #endif - - // Bottom cone - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - // Flip the inputs because the intersection function expects a cone growing towards +Z. - float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] - Ray flippedRay = ray; - flippedRay.dir.z *= -1.0; - flippedRay.pos.z *= -1.0; - - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) - vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_REGULAR, bottomConeIntersection); - #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - vec4 bottomConeIntersection = intersectFlippedCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 0, bottomConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 1, bottomConeIntersection.zw); - #endif - #endif - - // Top cone - #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) - float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] - #if defined(ELLIPSOID_CONE_TOP_REGULAR) - vec2 topConeIntersection = intersectRegularCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersection); - #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) - vec4 topConeIntersection = intersectFlippedCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersection.zw); - #endif - #endif - - // Wedge - #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) - float west = u_ellipsoidRectangle.x; // [-pi,+pi] - float east = u_ellipsoidRectangle.z; // [-pi,+pi] - #if defined(ELLIPSOID_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectWedge(ray, west, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); - #elif defined(ELLIPSOID_WEDGE_FLIPPED) - vec2 planeIntersectWest = intersectHalfSpace(ray, west); - vec2 planeIntersectEast = intersectHalfSpace(ray, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); - #endif - #endif -} -#endif - #if defined(SHAPE_CYLINDER) vec2 intersectUnitCylinder(Ray ray) { @@ -890,141 +793,6 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) } #endif -#if defined(SHAPE_CYLINDER) -void intersectCylinderShape(Ray ray, inout Intersections ix) -{ - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) - Ray outerRay = Ray(ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds, ray.dir * u_cylinderScaleUvToBounds); - #else - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - Ray outerRay = Ray(ray.pos * 2.0 - 1.0, ray.dir * 2.0); - #endif - - #if defined(CYLINDER_HEIGHT_ZERO) - vec2 outerIntersect = intersectUnitCircle(outerRay); - #else - vec2 outerIntersect = intersectUnitCylinder(outerRay); - #endif - - setIntersectionPair(ix, CYLINDER_OUTER_INDEX, outerIntersect); - - if (outerIntersect.x == NO_HIT) { - return; - } - - #if defined(CYLINDER_INNER_OUTER_EQUAL) - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If sortIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(CYLINDER_INNER) - Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); - vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); - #endif - - #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); - #elif defined(CYLINDER_WEDGE_FLIPPED) - vec2 planeIntersectMinAngle = intersectHalfSpace(outerRay, u_cylinderMinAngle); - vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, planeIntersectMinAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, planeIntersectMaxAngle); - #endif -} -#endif - -void intersectShape(Ray ray, out Intersections ix) { - #if defined(SHAPE_BOX) - intersectBoxShape(ray, ix); - #elif defined(SHAPE_ELLIPSOID) - intersectEllipsoidShape(ray, ix); - #elif defined(SHAPE_CYLINDER) - intersectCylinderShape(ray, ix); - #endif -} - -#if defined(DEPTH_TEST) -float intersectDepth(vec2 screenCoord, Ray ray) { - float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); - if (logDepthOrDepth != 0.0) { - // Calculate how far the ray must travel before it hits the depth buffer. - vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); - eyeCoordinateDepth /= eyeCoordinateDepth.w; - vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - return dot(depthPositionUv - ray.pos, ray.dir); - } else { - // There's no depth at this position so set it to some really far value. - return +INF_HIT; - } -} -#endif - -vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { - Ray ray = Ray(positionUv, directionUv); - - // Do a ray-shape intersection to find the exact starting and ending points. - intersectShape(ray, ix); - - // Check if the positive shape was completely missed, and if so, exit early. - float entryPositiveShapeT = getIntersection(ix, 0); - if (entryPositiveShapeT == NO_HIT) { - return vec2(NO_HIT); - } - - // Intersect depth texture - #if defined(DEPTH_TEST) - float depthT = intersectDepth(screenCoord, ray); - setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); - #endif - - // Find the first intersection interval - #if (SCENE_INTERSECTION_COUNT > 1) - vec2 entryExitT = initializeIntersections(ix); - #else - float exitPositiveShapeT = getIntersection(ix, 1); - vec2 entryExitT = vec2(entryPositiveShapeT, exitPositiveShapeT); - #endif - - // Intersection is invalid when start and end are behind the ray. - if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { - return vec2(NO_HIT); - } - - // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); - - return entryExitT; -} - -#if defined(SHAPE_BOX) -vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - #if defined(BOX_BOUNDED) - return positionUv * u_boxScaleUvToBoundsUv + u_boxTranslateUvToBoundsUv; - #else - return positionUv; - #endif -} -#endif - #if defined(SHAPE_ELLIPSOID) // robust iterative solution without trig functions // https://github.com/0xfaded/ellipse_demo/issues/1 @@ -1101,6 +869,112 @@ float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { } #endif +#if defined(SHAPE_BOX) +void intersectBoxShape(Ray ray, out Intersections ix) +{ + #if !defined(BOX_BOUNDED) + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir = ray.dir * 2.0; + vec2 entryExit = intersectUnitCube(ray); + #elif defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) + // Transform the ray into unit square space on Z plane + ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); + vec2 entryExit = intersectUnitSquare(ray); + #else + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxTranslateUvToBounds; + ray.dir *= u_boxScaleUvToBounds; + vec2 entryExit = intersectUnitCube(ray); + #endif + + setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); +} +#endif + +#if defined(SHAPE_BOX) +vec3 transformFromUvToBoxSpace(in vec3 positionUv) { + #if defined(BOX_BOUNDED) + return positionUv * u_boxScaleUvToBoundsUv + u_boxTranslateUvToBoundsUv; + #else + return positionUv; + #endif +} +#endif + +#if defined(SHAPE_ELLIPSOID) +void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + + // Outer ellipsoid + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + setIntersectionPair(ix, ELLIPSOID_OUTER, outerIntersect); + + // Exit early if the outer ellipsoid was missed. + if (outerIntersect.x == NO_HIT) { + return; + } + + // Inner ellipsoid + #if defined(ELLIPSOID_INNER) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + setIntersectionPair(ix, ELLIPSOID_INNER, innerIntersect); + #endif + + // Bottom cone + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) + // Flip the inputs because the intersection function expects a cone growing towards +Z. + float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] + Ray flippedRay = ray; + flippedRay.dir.z *= -1.0; + flippedRay.pos.z *= -1.0; + + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_REGULAR, bottomConeIntersection); + #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) + vec4 bottomConeIntersection = intersectFlippedCone(flippedRay, flippedSouth); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 1, bottomConeIntersection.zw); + #endif + #endif + + // Top cone + #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] + #if defined(ELLIPSOID_CONE_TOP_REGULAR) + vec2 topConeIntersection = intersectRegularCone(ray, north); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersection); + #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) + vec4 topConeIntersection = intersectFlippedCone(ray, north); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersection.zw); + #endif + #endif + + // Wedge + #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) + float west = u_ellipsoidRectangle.x; // [-pi,+pi] + float east = u_ellipsoidRectangle.z; // [-pi,+pi] + #if defined(ELLIPSOID_WEDGE_REGULAR) + vec2 wedgeIntersect = intersectWedge(ray, west, east); + setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); + #elif defined(ELLIPSOID_WEDGE_FLIPPED) + vec2 planeIntersectWest = intersectHalfSpace(ray, west); + vec2 planeIntersectEast = intersectHalfSpace(ray, east); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); + #endif + #endif +} +#endif + #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { // 1) Convert positionUv [0,1] to local space [-1,+1] to normalized cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. @@ -1132,6 +1006,68 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { } #endif +#if defined(SHAPE_CYLINDER) +void intersectCylinderShape(Ray ray, inout Intersections ix) +{ + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) + Ray outerRay = Ray(ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds, ray.dir * u_cylinderScaleUvToBounds); + #else + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + Ray outerRay = Ray(ray.pos * 2.0 - 1.0, ray.dir * 2.0); + #endif + + #if defined(CYLINDER_HEIGHT_ZERO) + vec2 outerIntersect = intersectUnitCircle(outerRay); + #else + vec2 outerIntersect = intersectUnitCylinder(outerRay); + #endif + + setIntersectionPair(ix, CYLINDER_OUTER_INDEX, outerIntersect); + + if (outerIntersect.x == NO_HIT) { + return; + } + + #if defined(CYLINDER_INNER_OUTER_EQUAL) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If sortIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(CYLINDER_INNER) + Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); + vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); + #endif + + #if defined(CYLINDER_WEDGE_REGULAR) + vec2 wedgeIntersect = intersectWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); + #elif defined(CYLINDER_WEDGE_FLIPPED) + vec2 planeIntersectMinAngle = intersectHalfSpace(outerRay, u_cylinderMinAngle); + vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, planeIntersectMinAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, planeIntersectMaxAngle); + #endif +} +#endif + #if defined(SHAPE_CYLINDER) vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] @@ -1171,6 +1107,69 @@ vec3 transformFromUvToShapeSpace(in vec3 positionUv) { #endif } +void intersectShape(Ray ray, out Intersections ix) { + #if defined(SHAPE_BOX) + intersectBoxShape(ray, ix); + #elif defined(SHAPE_ELLIPSOID) + intersectEllipsoidShape(ray, ix); + #elif defined(SHAPE_CYLINDER) + intersectCylinderShape(ray, ix); + #endif +} + +#if defined(DEPTH_TEST) +float intersectDepth(vec2 screenCoord, Ray ray) { + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); + if (logDepthOrDepth != 0.0) { + // Calculate how far the ray must travel before it hits the depth buffer. + vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); + eyeCoordinateDepth /= eyeCoordinateDepth.w; + vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); + return dot(depthPositionUv - ray.pos, ray.dir); + } else { + // There's no depth at this position so set it to some really far value. + return +INF_HIT; + } +} +#endif + +vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { + Ray ray = Ray(positionUv, directionUv); + + // Do a ray-shape intersection to find the exact starting and ending points. + intersectShape(ray, ix); + + // Check if the positive shape was completely missed, and if so, exit early. + float entryPositiveShapeT = getIntersection(ix, 0); + if (entryPositiveShapeT == NO_HIT) { + return vec2(NO_HIT); + } + + // Add depth to the list of intersections + #if defined(DEPTH_TEST) + float depthT = intersectDepth(screenCoord, ray); + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); + #endif + + // Find the first intersection interval + #if (SCENE_INTERSECTION_COUNT > 1) + vec2 entryExitT = initializeIntersections(ix); + #else + float exitPositiveShapeT = getIntersection(ix, 1); + vec2 entryExitT = vec2(entryPositiveShapeT, exitPositiveShapeT); + #endif + + // Intersection is invalid when start and end are behind the ray. + if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { + return vec2(NO_HIT); + } + + // Set start to 0.0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + + return entryExitT; +} + // -------------------------------------------------------- // Megatexture // -------------------------------------------------------- From dfecff7e48ca3381c906c2ff03142a325d5e74a3 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 18:22:48 -0400 Subject: [PATCH 025/679] fix for the flipped wedge --- Source/Scene/VoxelCylinderShape.js | 4 ++-- Source/Shaders/VoxelFS.glsl | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 62f72fae4d0..743d64748a7 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -401,8 +401,8 @@ VoxelCylinderShape.prototype.update = function ( if (hasWedge) { shaderDefines["CYLINDER_WEDGE"] = true; shaderDefines["CYLINDER_WEDGE_INDEX"] = intersectionCount; - shaderUniforms.minAngle = minAngle; - shaderUniforms.maxAngle = maxAngle; + shaderUniforms.cylinderMinAngle = minAngle; + shaderUniforms.cylinderMaxAngle = maxAngle; const minAngleUv = (minAngle - defaultMinAngle) / (defaultMaxAngle - defaultMinAngle); diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index a49b7199cfe..54305e580a7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -315,14 +315,14 @@ struct Ray { }; #if defined(JITTER) -#define HASHSCALE 50.0 float hash(vec2 p) { - vec3 p3 = fract(vec3(p.xyx) * HASHSCALE); + vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale p3 += dot(p3, p3.yzx + 19.19); return fract((p3.x + p3.y) * p3.z); } #endif + float signNoZero(float v) { return (v < 0.0) ? -1.0 : 1.0; } @@ -499,8 +499,7 @@ vec2 initializeIntersections(inout Intersections ix) { #endif #if defined(SHAPE_BOX) -// Unit cube from [-1, +1] -vec2 intersectUnitCube(Ray ray) +vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] { vec3 o = ray.pos; vec3 d = ray.dir; @@ -967,7 +966,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); #elif defined(ELLIPSOID_WEDGE_FLIPPED) vec2 planeIntersectWest = intersectHalfSpace(ray, west); - vec2 planeIntersectEast = intersectHalfSpace(ray, east); + vec2 planeIntersectEast = intersectHalfSpace(ray, east + czm_pi); setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); #endif @@ -1061,7 +1060,7 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); #elif defined(CYLINDER_WEDGE_FLIPPED) vec2 planeIntersectMinAngle = intersectHalfSpace(outerRay, u_cylinderMinAngle); - vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle); + vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle + czm_pi); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, planeIntersectMinAngle); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, planeIntersectMaxAngle); #endif From 34ddca7eb7ce582d6030812b4e4dbf05b981624a Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Wed, 13 Apr 2022 20:30:57 -0400 Subject: [PATCH 026/679] fixed flat cylinder and shell cylinder --- Source/Scene/VoxelCylinderShape.js | 20 ++++++------ Source/Scene/VoxelPrimitive.js | 15 +++++---- Source/Shaders/VoxelFS.glsl | 51 ++++++++++++++++-------------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 743d64748a7..2250ec6c53c 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -191,22 +191,21 @@ VoxelCylinderShape.prototype.update = function ( const minAngle = CesiumMath.negativePiToPi(minBounds.z); const maxAngle = CesiumMath.negativePiToPi(maxBounds.z); - const outerExtent = Cartesian3.fromElements( - scale.x * maxRadius, - scale.y * maxRadius, - scale.z * 0.5 * (maxHeight - minHeight) - ); - // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. + + // Cylinder is not visible if: + // - maxRadius is zero (line) + // - minHeight is greater than minHeight + // - scale is 0 for any component (too annoying to reconstruct rotation matrix) const absEpsilon = CesiumMath.EPSILON10; if ( maxRadius === 0.0 || minRadius > maxRadius || minHeight > maxHeight || - CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, absEpsilon) + CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, absEpsilon) || + CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, absEpsilon) ) { return false; } @@ -318,8 +317,9 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_INNER_OUTER_EQUAL"] = true; } else { shaderDefines["CYLINDER_INNER_INDEX"] = intersectionCount; - intersectionCount += 1; } + + intersectionCount += 1; } if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 3a3e6fbdaed..3144afae67c 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1229,12 +1229,7 @@ VoxelPrimitive.prototype.update = function (frameState) { const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); const shapeDirty = compoundTransformDirty || minBoundsDirty || maxBoundsDirty; - // Update the shape on the first frame or if it's dirty. - // If the shape is visible it will do some extra work. - if ( - (!this._ready || shapeDirty) && - (this._shapeVisible = shape.update(compoundTransform, minBounds, maxBounds)) - ) { + if (shapeDirty) { if (compoundTransformDirty) { this._compoundModelMatrixOld = Matrix4.clone( compoundTransform, @@ -1247,7 +1242,14 @@ VoxelPrimitive.prototype.update = function (frameState) { if (maxBoundsDirty) { this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); } + } + // Update the shape on the first frame or if it's dirty. + // If the shape is visible it will need to do some extra work. + if ( + (!this._ready || shapeDirty) && + (this._shapeVisible = shape.update(compoundTransform, minBounds, maxBounds)) + ) { // Rebuild the shader if any of the shape defines changed. const shapeDefines = shape.shaderDefines; const shapeDefinesOld = this._shapeDefinesOld; @@ -2282,6 +2284,7 @@ function buildDrawCommands(that, context) { that._drawCommandPick = drawCommandPick; // console.log(drawCommand.shaderProgram._fragmentShaderText); + console.log("recompile"); } /** diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 54305e580a7..50e20e922ab 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -767,7 +767,7 @@ vec2 intersectUnitCircle(Ray ray) { } #endif -#if defined(SHAPE_CYLINDER) && defined(CYLINDER_INNER) && !defined(CYLINDER_INNER_OUTER_EQUAL) +#if defined(SHAPE_CYLINDER) && defined(CYLINDER_INNER) vec2 intersectInfiniteUnitCylinder(Ray ray) { vec3 o = ray.pos; @@ -1028,31 +1028,34 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) return; } - #if defined(CYLINDER_INNER_OUTER_EQUAL) - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If sortIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(CYLINDER_INNER) + #if defined(CYLINDER_INNER) Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); + + #if defined(CYLINDER_INNER_OUTER_EQUAL) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If sortIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #else + setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); + #endif #endif #if defined(CYLINDER_WEDGE_REGULAR) From 9d86ee5ccac1439a719a78f0a6d018848be6d203 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 14:22:37 -0400 Subject: [PATCH 027/679] fixed some flipped angle problems for cylinder --- Apps/Sandcastle/gallery/Voxels.html | 2 + Source/Scene/VoxelCylinderShape.js | 172 ++++++++++------------------ Source/Scene/VoxelPrimitive.js | 5 +- Source/Shaders/VoxelFS.glsl | 47 +++++--- 4 files changed, 91 insertions(+), 135 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index c8ce699bf5e..b8b1321c0cb 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -84,6 +84,8 @@ break; } case Cesium.VoxelShapeType.CYLINDER: { + this.minBounds = new Cesium.Cartesian3(0.0, -1.0, +0.2); + this.maxBounds = new Cesium.Cartesian3(1.0, +1.0, -0.2); break; } } diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 2250ec6c53c..d0edaebd1f9 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -104,7 +104,8 @@ function VoxelCylinderShape() { cylinderMinAngle: 0.0, cylinderMaxAngle: 0.0, cylinderMinAngleUv: 0.0, - cylinderInverseAngleRangeUv: 0.0, + cylinderScaleAngleUvToBoundsAngleUv: 0.0, + cylinderOffsetAngleUvToBoundsAngleUv: 0.0, }; /** @@ -120,6 +121,7 @@ function VoxelCylinderShape() { CYLINDER_INNER_INDEX: undefined, CYLINDER_HEIGHT_NON_DEFAULT: undefined, CYLINDER_HEIGHT_ZERO: undefined, + CYLINDER_ANGLE_FLIPPED: undefined, CYLINDER_WEDGE_INDEX: undefined, CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, @@ -162,6 +164,7 @@ VoxelCylinderShape.prototype.update = function ( const defaultMaxHeight = VoxelCylinderShape.DefaultMaxBounds.y; const defaultMinAngle = VoxelCylinderShape.DefaultMinBounds.z; const defaultMaxAngle = VoxelCylinderShape.DefaultMaxBounds.z; + const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; // Clamp the radii to the valid range const minRadius = CesiumMath.clamp( @@ -196,7 +199,7 @@ VoxelCylinderShape.prototype.update = function ( // Cylinder is not visible if: // - maxRadius is zero (line) - // - minHeight is greater than minHeight + // - minHeight is greater than maxHeight // - scale is 0 for any component (too annoying to reconstruct rotation matrix) const absEpsilon = CesiumMath.EPSILON10; if ( @@ -246,8 +249,8 @@ VoxelCylinderShape.prototype.update = function ( const isDefaultHeight = minHeight === defaultMinHeight && maxHeight === defaultMaxHeight; - const angleWidth = - maxAngle - minAngle + (maxAngle < minAngle) * CesiumMath.TWO_PI; + const isAngleFlipped = maxAngle < minAngle; + const angleWidth = maxAngle - minAngle + isAngleFlipped * CesiumMath.TWO_PI; const hasWedgeRegular = angleWidth >= CesiumMath.PI && CesiumMath.lessThan(angleWidth, CesiumMath.TWO_PI, absEpsilon); @@ -398,20 +401,34 @@ VoxelCylinderShape.prototype.update = function ( shaderUniforms.cylinderOffsetHeightUvToBoundsHeightUv = offset; } + if (isAngleFlipped) { + shaderDefines["CYLINDER_ANGLE_FLIPPED"] = true; + } + if (hasWedge) { shaderDefines["CYLINDER_WEDGE"] = true; shaderDefines["CYLINDER_WEDGE_INDEX"] = intersectionCount; + shaderUniforms.cylinderMinAngle = minAngle; shaderUniforms.cylinderMaxAngle = maxAngle; - const minAngleUv = - (minAngle - defaultMinAngle) / (defaultMaxAngle - defaultMinAngle); - const maxAngleUv = - (maxAngle - defaultMinAngle) / (defaultMaxAngle - defaultMinAngle); + // delerp(angleUv, minAngleUv, maxAngleUv) + // (angelUv - minAngleUv) / (maxAngleUv - minAngleUv) + // angleUv / (maxAngleUv - minAngleUv) - minAngleUv / (maxAngleUv - minAngleUv) + // scale = 1.0 / (maxAngleUv - minAngleUv) + // scale = 1.0 / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) + // scale = 2.0 * pi / (maxAngle - minAngle) + // offset = -minAngleUv / (maxAngleUv - minAngleUv) + // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) + // offset = -(minAngle - pi) / (maxAngle - minAngle) + + const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; + const scale = defaultAngleWidth / angleWidth; + const offset = -(minAngle - defaultMinAngle) / angleWidth; shaderUniforms.cylinderMinAngleUv = minAngleUv; - shaderUniforms.cylinderInverseAngleRangeUv = - 1.0 / (maxAngleUv - minAngleUv); + shaderUniforms.cylinderScaleAngleUvToBoundsAngleUv = scale; + shaderUniforms.cylinderOffsetAngleUvToBoundsAngleUv = offset; if (hasWedgeRegular) { // Intersects a wedge for the min and max longitude. @@ -591,108 +608,27 @@ VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); */ VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); -const scratchTestAngles = new Array(6); +const maxTestAngles = 7; // Preallocated arrays for all of the possible test angle counts -const scratchPositions = [ - new Array(), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), - new Array( - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3(), - new Cartesian3() - ), -]; +/** + * @type {Number[]} + * @ignore + */ +const scratchTestAngles = new Array(maxTestAngles); + +/** + * @type {Cartesian3[][]} + * @ignore + */ +const scratchTestPositions = new Array(maxTestAngles + 1); +for (let i = 0; i <= maxTestAngles; i++) { + const positionsLength = i * 4; + scratchTestPositions[i] = new Array(positionsLength); + for (let j = 0; j < positionsLength; j++) { + scratchTestPositions[i][j] = new Cartesian3(); + } +} /** * Computes an {@link OrientedBoundingBox} for a subregion of the shape. @@ -744,6 +680,7 @@ function getCylinderChunkObb( return result; } + // TODO: this is not always working. See OrientedBoundingBox.fromRectangle for ideas to improve. let testAngleCount = 0; const testAngles = scratchTestAngles; const halfPi = CesiumMath.PI_OVER_TWO; @@ -752,13 +689,13 @@ function getCylinderChunkObb( testAngles[testAngleCount++] = angleEnd; if (angleStart > angleEnd) { - if (angleStart > 0.0 && angleEnd > 0.0) { + if (angleStart <= 0.0 || angleEnd >= 0.0) { testAngles[testAngleCount++] = 0.0; } - if (angleStart > +halfPi && angleEnd > +halfPi) { + if (angleStart <= +halfPi || angleEnd >= +halfPi) { testAngles[testAngleCount++] = +halfPi; } - if (angleStart > -halfPi && angleEnd > -halfPi) { + if (angleStart <= -halfPi || angleEnd >= -halfPi) { testAngles[testAngleCount++] = -halfPi; } // It will always cross the 180th meridian @@ -775,7 +712,14 @@ function getCylinderChunkObb( } } - const positions = scratchPositions[testAngleCount]; + const isAngleFlipped = angleEnd < angleStart; + const angleWidth = angleEnd - angleStart + isAngleFlipped * CesiumMath.TWO_PI; + + testAngles[testAngleCount++] = CesiumMath.negativePiToPi( + angleStart + angleWidth * 0.5 + ); + + const positions = scratchTestPositions[testAngleCount]; for (let i = 0; i < testAngleCount; i++) { const angle = testAngles[i]; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 3144afae67c..b63aa42b04e 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -2505,7 +2505,6 @@ function debugDraw(that, frameState) { const frameNumber = frameState.frameNumber; const traversal = that._traversal; const polylines = that._debugPolylines; - const shapeVisible = that._shape.isVisible; polylines.removeAll(); function makePolylineLineSegment(startPos, endPos, color, thickness) { @@ -2556,9 +2555,7 @@ function debugDraw(that, frameState) { } } - if (shapeVisible) { - drawTile(traversal.rootNode); - } + drawTile(traversal.rootNode); const axisThickness = 10.0; makePolylineLineSegment( diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 50e20e922ab..c8ea7f19be9 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -216,6 +216,8 @@ uniform float u_stepSize; #if defined(SHAPE_ELLIPSOID) /* Ellipsoid defines: #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections + #define ELLIPSOID_WEDGE + #define ELLIPSOID_WEDGE_INDEX ### #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone @@ -258,6 +260,8 @@ uniform float u_stepSize; #define CYLINDER_INNER_INDEX ### // when there's an inner cylinder #define CYLINDER_HEIGHT_NON_DEFAULT ### // #define CYLINDER_HEIGHT_ZERO // when the height is 0 + #define CYLINDER_ANGLE_FLIPPED // + #define CYLINDER_WEDGE // #define CYLINDER_WEDGE_INDEX // #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals @@ -286,7 +290,8 @@ uniform float u_stepSize; uniform float u_cylinderMinAngle; uniform float u_cylinderMaxAngle; uniform float u_cylinderMinAngleUv; - uniform float u_cylinderInverseAngleRangeUv; + uniform float u_cylinderScaleAngleUvToBoundsAngleUv; + uniform float u_cylinderOffsetAngleUvToBoundsAngleUv; #endif #endif @@ -538,7 +543,7 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] #endif #if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_REGULAR)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_REGULAR)) -vec2 intersectWedge(Ray ray, float minAngle, float maxAngle) +vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) { vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; @@ -589,6 +594,15 @@ vec2 intersectHalfSpace(Ray ray, float angle) } #endif +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) +vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); + vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); + return vec4(planeIntersectMin, planeIntersectMax); +} +#endif + #if defined(SHAPE_ELLIPSOID) vec2 intersectUnitSphere(Ray ray) { @@ -962,13 +976,12 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { float west = u_ellipsoidRectangle.x; // [-pi,+pi] float east = u_ellipsoidRectangle.z; // [-pi,+pi] #if defined(ELLIPSOID_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectWedge(ray, west, east); + vec2 wedgeIntersect = intersectRegularWedge(ray, west, east); setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); #elif defined(ELLIPSOID_WEDGE_FLIPPED) - vec2 planeIntersectWest = intersectHalfSpace(ray, west); - vec2 planeIntersectEast = intersectHalfSpace(ray, east + czm_pi); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, planeIntersectWest); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, planeIntersectEast); + vec4 wedgeIntersect = intersectFlippedWedge(ray, west, east); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, wedgeIntersect.zw); #endif #endif } @@ -1047,7 +1060,7 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) // [outerMin, innerMin, innerMax, outerMax] will bubble sort to // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - // Note: If sortIntersections() changes its sorting function + // Note: If initializeIntersections() changes its sorting function // from bubble sort to something else, this code may need to change. setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter @@ -1059,13 +1072,12 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) #endif #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + vec2 wedgeIntersect = intersectRegularWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); #elif defined(CYLINDER_WEDGE_FLIPPED) - vec2 planeIntersectMinAngle = intersectHalfSpace(outerRay, u_cylinderMinAngle); - vec2 planeIntersectMaxAngle = intersectHalfSpace(outerRay, u_cylinderMaxAngle + czm_pi); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, planeIntersectMinAngle); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, planeIntersectMaxAngle); + vec4 wedgeIntersect = intersectFlippedWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); #endif } #endif @@ -1089,10 +1101,11 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { height = height * u_cylinderScaleHeightUvToBoundsHeightUv + u_cylinderOffsetHeightUvToBoundsHeightUv; #endif - #if defined(CYLINDER_WEDGE_REGULAR) - angle = (angle - u_cylinderMinAngleUv) * u_cylinderInverseAngleRangeUv; - #elif defined(CYLINDER_WEDGE_FLIPPED) - angle = (angle - u_cylinderMinAngleUv) * u_cylinderInverseAngleRangeUv; + #if defined(CYLINDER_WEDGE) + #if defined(CYLINDER_ANGLE_FLIPPED) + angle += float(angle <= u_cylinderMinAngleUv); + #endif + angle = angle * u_cylinderScaleAngleUvToBoundsAngleUv + u_cylinderOffsetAngleUvToBoundsAngleUv; #endif return vec3(radius, height, angle); From 4c070d8e99fb9f8790714f287eb614eb46e46b4a Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 15:14:19 -0400 Subject: [PATCH 028/679] flipped longitude fix for ellipsoid --- Source/Scene/VoxelEllipsoidShape.js | 122 +++++++++++++++++++++------- Source/Shaders/VoxelFS.glsl | 59 ++++++++------ 2 files changed, 127 insertions(+), 54 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index edd2a84d11e..141aeeeef7e 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -99,7 +99,8 @@ function VoxelEllipsoidShape() { ellipsoidInverseRadiiSquaredUv: new Cartesian3(), // Wedge uniforms ellipsoidWestUv: 0.0, - ellipsoidInverseLongitudeRangeUv: 0.0, + ellipsoidScaleLongitudeUvToBoundsLongitudeUv: 0.0, + ellipsoidOffsetLongitudeUvToBoundsLongitudeUv: 0.0, // Cone uniforms ellipsoidSouthUv: 0.0, ellipsoidInverseLatitudeRangeUv: 0.0, @@ -115,14 +116,23 @@ function VoxelEllipsoidShape() { */ this.shaderDefines = { ELLIPSOID_INTERSECTION_COUNT: undefined, + ELLIPSOID_WEDGE: undefined, ELLIPSOID_WEDGE_REGULAR: undefined, ELLIPSOID_WEDGE_FLIPPED: undefined, + ELLIPSOID_WEDGE_INDEX: undefined, + ELLIPSOID_ANGLE_FLIPPED: undefined, + ELLIPSOID_CONE_BOTTOM: undefined, ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, + ELLIPSOID_CONE_BOTTOM_INDEX: undefined, + ELLIPSOID_CONE_TOP: undefined, ELLIPSOID_CONE_TOP_REGULAR: undefined, ELLIPSOID_CONE_TOP_FLIPPED: undefined, + ELLIPSOID_CONE_TOP_INDEX: undefined, ELLIPSOID_OUTER: undefined, + ELLIPSOID_OUTER_INDEX: undefined, ELLIPSOID_INNER: undefined, + ELLIPSOID_INNER_INDEX: undefined, }; } @@ -150,29 +160,33 @@ VoxelEllipsoidShape.prototype.update = function ( Check.typeOf.object("maxBounds", maxBounds); //>>includeEnd('debug'); - const defaultMinBounds = VoxelEllipsoidShape.DefaultMinBounds; - const defaultMaxBounds = VoxelEllipsoidShape.DefaultMaxBounds; + const defaultMinLongitude = VoxelEllipsoidShape.DefaultMinBounds.x; + const defaultMaxLongitude = VoxelEllipsoidShape.DefaultMaxBounds.x; + const defaultLongitudeLength = defaultMaxLongitude - defaultMinLongitude; + const defaultMinLatitude = VoxelEllipsoidShape.DefaultMinBounds.y; + const defaultMaxLatitude = VoxelEllipsoidShape.DefaultMaxBounds.y; + const defaultLatitudeLength = defaultMaxLatitude - defaultMinLatitude; // Clamp the longitude / latitude to the valid range const west = CesiumMath.clamp( minBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x + defaultMinLongitude, + defaultMaxLongitude ); const east = CesiumMath.clamp( maxBounds.x, - defaultMinBounds.x, - defaultMaxBounds.x + defaultMinLongitude, + defaultMaxLongitude ); const south = CesiumMath.clamp( minBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y + defaultMinLatitude, + defaultMaxLatitude ); const north = CesiumMath.clamp( maxBounds.y, - defaultMinBounds.y, - defaultMaxBounds.y + defaultMinLatitude, + defaultMaxLatitude ); // Don't let the height go below the center of the ellipsoid. @@ -277,27 +291,40 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidInverseRadiiSquaredUv ); + const isAngleFlipped = east < west; const rectangleWidth = Rectangle.computeWidth(this._rectangle); const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); + const hasWedgeRegular = rectangleWidth >= CesiumMath.PI && CesiumMath.lessThan(rectangleWidth, CesiumMath.TWO_PI, absEpsilon); const hasWedgeFlipped = rectangleWidth < CesiumMath.PI; + const hasWedge = hasWedgeRegular || hasWedgeFlipped; + const hasTopConeRegular = north >= 0.0 && north < +CesiumMath.PI_OVER_TWO; const hasTopConeFlipped = north < 0.0; + const hasTopCone = hasTopConeRegular || hasTopConeFlipped; + const hasBottomConeRegular = south <= 0.0 && south > -CesiumMath.PI_OVER_TWO; const hasBottomConeFlipped = south > 0.0; + const hasBottomCone = hasBottomConeRegular || hasBottomConeFlipped; + + if (isAngleFlipped) { + shaderDefines["ELLIPSOID_ANGLE_FLIPPED"] = true; + } // Keep track of how many intersections there are going to be. let intersectionCount = 0; // Intersects an outer ellipsoid for the max height. - shaderDefines["ELLIPSOID_OUTER"] = intersectionCount; + shaderDefines["ELLIPSOID_OUTER"] = true; + shaderDefines["ELLIPSOID_OUTER_INDEX"] = intersectionCount; intersectionCount += 1; // Intersects an inner ellipsoid for the min height. if (hasInnerEllipsoid) { - shaderDefines["ELLIPSOID_INNER"] = intersectionCount; + shaderDefines["ELLIPSOID_INNER"] = true; + shaderDefines["ELLIPSOID_INNER_INDEX"] = intersectionCount; intersectionCount += 1; // The percent of space that is between the inner and outer ellipsoid. @@ -317,30 +344,63 @@ VoxelEllipsoidShape.prototype.update = function ( } // Intersects a wedge for the min and max longitude. - if (hasWedgeRegular) { - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = intersectionCount; - intersectionCount += 1; - } else if (hasWedgeFlipped) { - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = intersectionCount; - intersectionCount += 2; + if (hasWedge) { + shaderDefines["ELLIPSOID_WEDGE"] = true; + shaderDefines["ELLIPSOID_WEDGE_INDEX"] = intersectionCount; + + if (hasWedgeRegular) { + shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = true; + intersectionCount += 1; + } else if (hasWedgeFlipped) { + shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = true; + intersectionCount += 2; + } + + // delerp(longitudeUv, minLongitudeUv, maxLongitudeUv) + // (longitudeUv - minLongitudeUv) / (maxLongitudeUv - minLongitudeUv) + // longitudeUv / (maxLongitudeUv - minLongitudeUv) - minLongitudeUv / (maxLongitudeUv - minLongitudeUv) + // scale = 1.0 / (maxLongitudeUv - minLongitudeUv) + // scale = 1.0 / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi))) + // scale = 2.0 * pi / (maxLongitude - minLongitude) + // offset = -minLongitudeUv / (maxLongitudeUv - minLongitudeUv) + // offset = -((minLongitude - pi) / (2.0 * pi)) / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi))) + // offset = -(minLongitude - pi) / (maxLongitude - minLongitude) + + const westUv = (west - defaultMinLongitude) / defaultLongitudeLength; + const scale = defaultLongitudeLength / rectangleWidth; + const offset = -(west - defaultMinLongitude) / rectangleWidth; + + shaderUniforms.ellipsoidWestUv = westUv; + shaderUniforms.ellipsoidScaleLongitudeUvToBoundsLongitudeUv = scale; + shaderUniforms.ellipsoidOffsetLongitudeUvToBoundsLongitudeUv = offset; } // Intersects a cone for min latitude - if (hasBottomConeRegular) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = intersectionCount; - intersectionCount += 1; - } else if (hasBottomConeFlipped) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = intersectionCount; - intersectionCount += 2; + if (hasBottomCone) { + shaderDefines["ELLIPSOID_CONE_BOTTOM"] = true; + shaderDefines["ELLIPSOID_CONE_BOTTOM_INDEX"] = intersectionCount; + + if (hasBottomConeRegular) { + shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = true; + intersectionCount += 1; + } else if (hasBottomConeFlipped) { + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = true; + intersectionCount += 2; + } } // Intersects a cone for max latitude - if (hasTopConeRegular) { - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = intersectionCount; - intersectionCount += 1; - } else if (hasTopConeFlipped) { - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = intersectionCount; - intersectionCount += 2; + if (hasTopCone) { + shaderDefines["ELLIPSOID_CONE_TOP"] = true; + shaderDefines["ELLIPSOID_CONE_TOP_INDEX"] = intersectionCount; + + if (hasTopConeRegular) { + shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = true; + intersectionCount += 1; + } else if (hasTopConeFlipped) { + shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = true; + intersectionCount += 2; + } } shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = intersectionCount; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index c8ea7f19be9..43999c11793 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -217,29 +217,37 @@ uniform float u_stepSize; /* Ellipsoid defines: #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections #define ELLIPSOID_WEDGE - #define ELLIPSOID_WEDGE_INDEX ### #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define ELLIPSOID_WEDGE_INDEX ### + #define ELLIPSOID_ANGLE_FLIPPED // + #define ELLIPSOID_CONE_BOTTOM #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone #define ELLIPSOID_CONE_BOTTOM_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_BOTTOM_INDEX ### + #define ELLIPSOID_CONE_TOP #define ELLIPSOID_CONE_TOP_REGULAR ### // when there's a top cone #define ELLIPSOID_CONE_TOP_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_TOP_INDEX ### #define ELLIPSOID_OUTER ### // outer ellipsoid - always defined + #define ELLIPSOID_OUTER_INDEX ### #define ELLIPSOID_INNER ### // when there's an inner ellipsoid + #define ELLIPSOID_INNER_INDEX ### */ // Ellipsoid uniforms uniform vec3 u_ellipsoidRadiiUv; // [0,1] uniform vec3 u_ellipsoidInverseRadiiSquaredUv; - #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_WEDGE) || defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif - #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) + #if defined(ELLIPSOID_WEDGE) uniform float u_ellipsoidWestUv; - uniform float u_ellipsoidInverseLongitudeRangeUv; + uniform float u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv; + uniform float u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; #endif - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform float u_ellipsoidSouthUv; uniform float u_ellipsoidInverseLatitudeRangeUv; #endif @@ -652,7 +660,7 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) vec2 intersectDoubleEndedCone(Ray ray, float latitude) { vec3 o = ray.pos; @@ -926,7 +934,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { // Outer ellipsoid vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersectionPair(ix, ELLIPSOID_OUTER, outerIntersect); + setIntersectionPair(ix, ELLIPSOID_OUTER_INDEX, outerIntersect); // Exit early if the outer ellipsoid was missed. if (outerIntersect.x == NO_HIT) { @@ -937,11 +945,11 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #if defined(ELLIPSOID_INNER) Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INNER, innerIntersect); + setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); #endif // Bottom cone - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) + #if defined(ELLIPSOID_CONE_BOTTOM) // Flip the inputs because the intersection function expects a cone growing towards +Z. float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] Ray flippedRay = ray; @@ -950,38 +958,38 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_REGULAR, bottomConeIntersection); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) vec4 bottomConeIntersection = intersectFlippedCone(flippedRay, flippedSouth); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 0, bottomConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_FLIPPED + 1, bottomConeIntersection.zw); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 1, bottomConeIntersection.zw); #endif #endif // Top cone - #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_CONE_TOP) float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] #if defined(ELLIPSOID_CONE_TOP_REGULAR) vec2 topConeIntersection = intersectRegularCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_REGULAR, topConeIntersection); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) vec4 topConeIntersection = intersectFlippedCone(ray, north); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 0, topConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_FLIPPED + 1, topConeIntersection.zw); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 1, topConeIntersection.zw); #endif #endif // Wedge - #if defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED) + #if defined(ELLIPSOID_WEDGE) float west = u_ellipsoidRectangle.x; // [-pi,+pi] float east = u_ellipsoidRectangle.z; // [-pi,+pi] #if defined(ELLIPSOID_WEDGE_REGULAR) vec2 wedgeIntersect = intersectRegularWedge(ray, west, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_REGULAR, wedgeIntersect); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX, wedgeIntersect); #elif defined(ELLIPSOID_WEDGE_FLIPPED) vec4 wedgeIntersect = intersectFlippedWedge(ray, west, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_WEDGE_FLIPPED + 1, wedgeIntersect.zw); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 1, wedgeIntersect.zw); #endif #endif } @@ -1002,11 +1010,14 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; // 5 float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; // 6 - #if (defined(ELLIPSOID_WEDGE_REGULAR) || defined(ELLIPSOID_WEDGE_FLIPPED)) - longitude = (longitude - u_ellipsoidWestUv) * u_ellipsoidInverseLongitudeRangeUv; + #if defined(ELLIPSOID_WEDGE) + #if defined(ELLIPSOID_ANGLE_FLIPPED) + longitude += float(longitude <= u_ellipsoidWestUv); + #endif + longitude = longitude * u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv + u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; #endif - #if (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) + #if (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; #endif @@ -1492,9 +1503,11 @@ void main() discard; } + float currT = entryExitT.x; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; + gl_FragColor = vec4(transformFromUvToShapeSpace(positionUv).xxx, 1.0); return; vec4 colorAccum = vec4(0.0); From 22f3f663ebe25985e36db21be10e4795227995c2 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 16:21:39 -0400 Subject: [PATCH 029/679] fixed some cone problems for ellipsoid shape --- Source/Scene/VoxelEllipsoidShape.js | 33 ++++++++++--- Source/Shaders/VoxelFS.glsl | 77 +++++++++++++++-------------- 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 141aeeeef7e..33a784be979 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -102,12 +102,12 @@ function VoxelEllipsoidShape() { ellipsoidScaleLongitudeUvToBoundsLongitudeUv: 0.0, ellipsoidOffsetLongitudeUvToBoundsLongitudeUv: 0.0, // Cone uniforms - ellipsoidSouthUv: 0.0, - ellipsoidInverseLatitudeRangeUv: 0.0, + ellipsoidScaleLatitudeUvToBoundsLatitudeUv: 0.0, + ellipsoidOffsetLatitudeUvToBoundsLatitudeUv: 0.0, // Inner ellipsoid uniforms ellipsoidInverseHeightDifferenceUv: 0.0, ellipsoidInverseInnerScaleUv: 0.0, - ellipsoidInnerRadiiUv: new Cartesian3(), + ellipseInnerRadiiUv: new Cartesian2(), }; /** @@ -293,6 +293,7 @@ VoxelEllipsoidShape.prototype.update = function ( const isAngleFlipped = east < west; const rectangleWidth = Rectangle.computeWidth(this._rectangle); + const rectangleHeight = Rectangle.computeHeight(this._rectangle); const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); const hasWedgeRegular = @@ -336,10 +337,10 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidInverseInnerScaleUv = 1.0 / innerScale; // The inner ellipsoid radii scaled to [0,innerScale]. The max inner ellipsoid radius will equal innerScale and others will be less. - shaderUniforms.ellipsoidInnerRadiiUv = Cartesian3.multiplyByScalar( - shaderUniforms.ellipsoidRadiiUv, - innerScale, - shaderUniforms.ellipsoidInnerRadiiUv + shaderUniforms.ellipseInnerRadiiUv = Cartesian2.fromElements( + shaderUniforms.ellipsoidRadiiUv.x * innerScale, + shaderUniforms.ellipsoidRadiiUv.z * innerScale, + shaderUniforms.ellipseInnerRadiiUv ); } @@ -375,6 +376,24 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidOffsetLongitudeUvToBoundsLongitudeUv = offset; } + if (hasBottomCone || hasTopCone) { + // delerp(latitudeUv, minLatitudeUv, maxLatitudeUv) + // (latitudeUv - minLatitudeUv) / (maxLatitudeUv - minLatitudeUv) + // latitudeUv / (maxLatitudeUv - minLatitudeUv) - minLatitudeUv / (maxLatitudeUv - minLatitudeUv) + // scale = 1.0 / (maxLatitudeUv - minLatitudeUv) + // scale = 1.0 / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) + // scale = 2.0 * pi / (maxLatitude - minLatitude) + // offset = -minLatitudeUv / (maxLatitudeUv - minLatitudeUv) + // offset = -((minLatitude - pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) + // offset = -(minLatitude - pi) / (maxLatitude - minLatitude) + + const scale = defaultLatitudeLength / rectangleHeight; + const offset = -(south - defaultMinLatitude) / rectangleHeight; + + shaderUniforms.ellipsoidScaleLatitudeUvToBoundsLatitudeUv = scale; + shaderUniforms.ellipsoidOffsetLatitudeUvToBoundsLatitudeUv = offset; + } + // Intersects a cone for min latitude if (hasBottomCone) { shaderDefines["ELLIPSOID_CONE_BOTTOM"] = true; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 43999c11793..0b93956f7bc 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -242,19 +242,21 @@ uniform float u_stepSize; #if defined(ELLIPSOID_WEDGE) || defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif - #if defined(ELLIPSOID_WEDGE) + #if defined(ELLIPSOID_WEDGE) && defined(ELLIPSOID_ANGLE_FLIPPED) uniform float u_ellipsoidWestUv; + #endif + #if defined(ELLIPSOID_WEDGE) uniform float u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv; uniform float u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; #endif #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) - uniform float u_ellipsoidSouthUv; - uniform float u_ellipsoidInverseLatitudeRangeUv; + uniform float u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv; + uniform float u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; #endif #if defined(ELLIPSOID_INNER) uniform float u_ellipsoidInverseHeightDifferenceUv; uniform float u_ellipsoidInverseInnerScaleUv; - uniform vec3 u_ellipsoidInnerRadiiUv; // [0,1] + uniform vec2 u_ellipseInnerRadiiUv; // [0,1] #endif #endif @@ -692,19 +694,18 @@ vec4 intersectFlippedCone(Ray ray, float latitude) { vec2 intersect = intersectDoubleEndedCone(ray, latitude); if (intersect.x == NO_HIT) { - return vec4(NO_HIT); + return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); } float tmin = intersect.x; float tmax = intersect.y; - float h1 = o.z + tmin * d.z; - float h2 = o.z + tmax * d.z; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; // One interval - if (h1 < 0.0 && h2 < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - else if (h1 < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); - else if (h2 < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); - else if (tmin < 0.0) return vec4(tmax, +INF_HIT, NO_HIT, NO_HIT); + if (zmin < 0.0 && zmax < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + else if (zmin < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); + else if (zmax < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); // Two intervals else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); } @@ -722,12 +723,12 @@ vec2 intersectRegularCone(Ray ray, float latitude) { float tmin = intersect.x; float tmax = intersect.y; - float h1 = o.z + tmin * d.z; - float h2 = o.z + tmax * d.z; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; - if (h1 < 0.0 && h2 < 0.0) return vec2(NO_HIT); - else if (h1 < 0.0) return vec2(tmax, +INF_HIT); - else if (h2 < 0.0) return vec2(-INF_HIT, tmin); + if (zmin < 0.0 && zmax < 0.0) return vec2(NO_HIT); + else if (zmin < 0.0) return vec2(tmax, +INF_HIT); + else if (zmax < 0.0) return vec2(-INF_HIT, tmin); else return vec2(tmin, tmax); } #endif @@ -948,19 +949,22 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); #endif - // Bottom cone - #if defined(ELLIPSOID_CONE_BOTTOM) - // Flip the inputs because the intersection function expects a cone growing towards +Z. - float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] + // Flip the ray because the intersection function expects a cone growing towards +Z. + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) Ray flippedRay = ray; flippedRay.dir.z *= -1.0; flippedRay.pos.z *= -1.0; - + #endif + + // Bottom cone + #if defined(ELLIPSOID_CONE_BOTTOM) #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) + float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - vec4 bottomConeIntersection = intersectFlippedCone(flippedRay, flippedSouth); + float south = u_ellipsoidRectangle.y; + vec4 bottomConeIntersection = intersectFlippedCone(ray, south); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 0, bottomConeIntersection.xy); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 1, bottomConeIntersection.zw); #endif @@ -968,12 +972,13 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { // Top cone #if defined(ELLIPSOID_CONE_TOP) - float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] #if defined(ELLIPSOID_CONE_TOP_REGULAR) + float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] vec2 topConeIntersection = intersectRegularCone(ray, north); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) - vec4 topConeIntersection = intersectFlippedCone(ray, north); + float flippedNorth = -u_ellipsoidRectangle.w; // [-halfPi,+halfPi] + vec4 topConeIntersection = intersectFlippedCone(flippedRay, flippedNorth); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 0, topConeIntersection.xy); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 1, topConeIntersection.zw); #endif @@ -997,18 +1002,15 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { - // 1) Convert positionUv [0,1] to local space [-1,+1] to normalized cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. - // 2) Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization so that math can be done with ellipses instead of ellipsoids. - // 3) Compute height from inner ellipse. - // 4) Compute geodetic surface normal. - // 5) Compute longitude from geodetic surface normal. - // 6) Compute latitude from geodetic surface normal. - vec3 pos3D = (positionUv * 2.0 - 1.0) * u_ellipsoidRadiiUv; // 1 - vec2 pos2D = vec2(length(pos3D.xy), pos3D.z); // 2 - float height = ellipseDistanceIterative(pos2D, u_ellipsoidInnerRadiiUv.xz); // 3 - vec3 geodeticSurfaceNormal = normalize(pos3D * u_ellipsoidInverseRadiiSquaredUv); // 4 - float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; // 5 - float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; // 6 + // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. + // Then convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization so that math can be done with ellipses instead of ellipsoids. + vec3 posEllipsoid = (positionUv * 2.0 - 1.0) * u_ellipsoidRadiiUv; + vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); + + vec3 geodeticSurfaceNormal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); + float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; + float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; + float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv); #if defined(ELLIPSOID_WEDGE) #if defined(ELLIPSOID_ANGLE_FLIPPED) @@ -1018,7 +1020,7 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { #endif #if (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) - latitude = (latitude - u_ellipsoidSouthUv) * u_ellipsoidInverseLatitudeRangeUv; + latitude = latitude * u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv + u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; #endif #if (defined(ELLIPSOID_INNER)) @@ -1507,7 +1509,6 @@ void main() float currT = entryExitT.x; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - gl_FragColor = vec4(transformFromUvToShapeSpace(positionUv).xxx, 1.0); return; vec4 colorAccum = vec4(0.0); From 1e7dad60d7078a70424a2eda90ec57a6c4a43fae Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 17:04:01 -0400 Subject: [PATCH 030/679] added fast path for when ellipsoid is sphere --- Source/Scene/VoxelEllipsoidShape.js | 7 +++ Source/Shaders/VoxelFS.glsl | 47 ++++++++++++++----- .../Widgets/VoxelInspector/VoxelInspector.js | 3 +- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 33a784be979..66f1aa260e3 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -133,6 +133,7 @@ function VoxelEllipsoidShape() { ELLIPSOID_OUTER_INDEX: undefined, ELLIPSOID_INNER: undefined, ELLIPSOID_INNER_INDEX: undefined, + ELLIPSOID_IS_SPHERE: undefined, }; } @@ -310,10 +311,16 @@ VoxelEllipsoidShape.prototype.update = function ( const hasBottomConeFlipped = south > 0.0; const hasBottomCone = hasBottomConeRegular || hasBottomConeFlipped; + const isSphere = radii.x === radii.y && radii.y === radii.z; + if (isAngleFlipped) { shaderDefines["ELLIPSOID_ANGLE_FLIPPED"] = true; } + if (isSphere) { + shaderDefines["ELLIPSOID_IS_SPHERE"] = true; + } + // Keep track of how many intersections there are going to be. let intersectionCount = 0; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 0b93956f7bc..b031eaf2ed5 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -233,6 +233,7 @@ uniform float u_stepSize; #define ELLIPSOID_OUTER_INDEX ### #define ELLIPSOID_INNER ### // when there's an inner ellipsoid #define ELLIPSOID_INNER_INDEX ### + #define ELLIPSOID_IS_SPHERE */ // Ellipsoid uniforms @@ -1002,16 +1003,19 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { - // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. - // Then convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). This is an optimization so that math can be done with ellipses instead of ellipsoids. - vec3 posEllipsoid = (positionUv * 2.0 - 1.0) * u_ellipsoidRadiiUv; - vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); - - vec3 geodeticSurfaceNormal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); - float longitude = (atan(geodeticSurfaceNormal.y, geodeticSurfaceNormal.x) + czm_pi) / czm_twoPi; - float latitude = (asin(geodeticSurfaceNormal.z) + czm_piOverTwo) / czm_pi; - float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv); - + // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). + // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. + vec3 positionLocal = positionUv * 2.0 - 1.0; + #if defined(ELLIPSOID_IS_SPHERE) + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x; + vec3 normal = normalize(posEllipsoid); + #else + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; + vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal + #endif + + // Compute longitude + float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; #if defined(ELLIPSOID_WEDGE) #if defined(ELLIPSOID_ANGLE_FLIPPED) longitude += float(longitude <= u_ellipsoidWestUv); @@ -1019,12 +1023,29 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { longitude = longitude * u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv + u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; #endif + // Compute latitude + float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; #if (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) latitude = latitude * u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv + u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; #endif - - #if (defined(ELLIPSOID_INNER)) - height *= u_ellipsoidInverseHeightDifferenceUv; + + // Compute height + #if defined(ELLIPSOID_IS_SPHERE) + #if defined(ELLIPSOID_INNER) + float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; + #else + float height = length(posEllipsoid); + #endif + #else + #if defined(ELLIPSOID_INNER) + // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). + // This is an optimization so that math can be done with ellipses instead of ellipsoids. + vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); + float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; + #else + // TODO: this is probably not correct + float height = length(posEllipsoid); + #endif #endif return vec3(longitude, latitude, height); diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index a72f841a50a..7c39a62fbec 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -4,6 +4,7 @@ import Check from "../../Core/Check.js"; import defaultValue from "../../Core/defaultValue.js"; import defined from "../../Core/defined.js"; import destroyObject from "../../Core/destroyObject.js"; +import Ellipsoid from "../../Core/Ellipsoid.js"; import knockout from "../../ThirdParty/knockout.js"; import getElement from "../getElement.js"; import InspectorShared from "../InspectorShared.js"; @@ -134,7 +135,7 @@ function VoxelInspector(container, scene) { const ellipsoidMinBounds = Cartesian3.fromElements( VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).x, VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).y, - -6356752.3142451793, // The deepest height for WGS84 + -Ellipsoid.WGS84.maximumRadius, new Cartesian3() ); const ellipsoidMaxBounds = Cartesian3.fromElements( From b7f48d5ed9373224d385a7d52259d551dbd17708 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 17:33:42 -0400 Subject: [PATCH 031/679] sort of handling thin ellipsoid --- Source/Scene/VoxelEllipsoidShape.js | 23 +++-- Source/Shaders/VoxelFS.glsl | 150 +++++++++++++++++----------- 2 files changed, 107 insertions(+), 66 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 66f1aa260e3..865bf65538c 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -120,7 +120,7 @@ function VoxelEllipsoidShape() { ELLIPSOID_WEDGE_REGULAR: undefined, ELLIPSOID_WEDGE_FLIPPED: undefined, ELLIPSOID_WEDGE_INDEX: undefined, - ELLIPSOID_ANGLE_FLIPPED: undefined, + ELLIPSOID_WEDGE_ANGLE_FLIPPED: undefined, ELLIPSOID_CONE_BOTTOM: undefined, ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, @@ -132,6 +132,7 @@ function VoxelEllipsoidShape() { ELLIPSOID_OUTER: undefined, ELLIPSOID_OUTER_INDEX: undefined, ELLIPSOID_INNER: undefined, + ELLIPSOID_INNER_OUTER_EQUAL: undefined, ELLIPSOID_INNER_INDEX: undefined, ELLIPSOID_IS_SPHERE: undefined, }; @@ -313,14 +314,6 @@ VoxelEllipsoidShape.prototype.update = function ( const isSphere = radii.x === radii.y && radii.y === radii.z; - if (isAngleFlipped) { - shaderDefines["ELLIPSOID_ANGLE_FLIPPED"] = true; - } - - if (isSphere) { - shaderDefines["ELLIPSOID_IS_SPHERE"] = true; - } - // Keep track of how many intersections there are going to be. let intersectionCount = 0; @@ -351,6 +344,14 @@ VoxelEllipsoidShape.prototype.update = function ( ); } + if (isSphere) { + shaderDefines["ELLIPSOID_IS_SPHERE"] = true; + } + + if (minHeight === maxHeight) { + shaderDefines["ELLIPSOID_INNER_OUTER_EQUAL"] = true; + } + // Intersects a wedge for the min and max longitude. if (hasWedge) { shaderDefines["ELLIPSOID_WEDGE"] = true; @@ -383,6 +384,10 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidOffsetLongitudeUvToBoundsLongitudeUv = offset; } + if (isAngleFlipped) { + shaderDefines["ELLIPSOID_WEDGE_ANGLE_FLIPPED"] = true; + } + if (hasBottomCone || hasTopCone) { // delerp(latitudeUv, minLatitudeUv, maxLatitudeUv) // (latitudeUv - minLatitudeUv) / (maxLatitudeUv - minLatitudeUv) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index b031eaf2ed5..d46cd7ae817 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -220,7 +220,7 @@ uniform float u_stepSize; #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define ELLIPSOID_WEDGE_INDEX ### - #define ELLIPSOID_ANGLE_FLIPPED // + #define ELLIPSOID_WEDGE_ANGLE_FLIPPED // #define ELLIPSOID_CONE_BOTTOM #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone #define ELLIPSOID_CONE_BOTTOM_FLIPPED ### // when cone shape has two intersection intervals @@ -233,6 +233,7 @@ uniform float u_stepSize; #define ELLIPSOID_OUTER_INDEX ### #define ELLIPSOID_INNER ### // when there's an inner ellipsoid #define ELLIPSOID_INNER_INDEX ### + #define ELLIPSOID_INNER_OUTER_EQUAL #define ELLIPSOID_IS_SPHERE */ @@ -243,7 +244,7 @@ uniform float u_stepSize; #if defined(ELLIPSOID_WEDGE) || defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif - #if defined(ELLIPSOID_WEDGE) && defined(ELLIPSOID_ANGLE_FLIPPED) + #if defined(ELLIPSOID_WEDGE) && defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) uniform float u_ellipsoidWestUv; #endif #if defined(ELLIPSOID_WEDGE) @@ -254,7 +255,7 @@ uniform float u_stepSize; uniform float u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv; uniform float u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; #endif - #if defined(ELLIPSOID_INNER) + #if defined(ELLIPSOID_INNER) && !defined(ELLIPSOID_INNER_OUTER_EQUAL) uniform float u_ellipsoidInverseHeightDifferenceUv; uniform float u_ellipsoidInverseInnerScaleUv; uniform vec2 u_ellipseInnerRadiiUv; // [0,1] @@ -289,7 +290,7 @@ uniform float u_stepSize; uniform float u_cylinderOffsetRadiusUvToBoundsRadiusUv; #endif - #if defined(CYLINDER_INNER) + #if defined(CYLINDER_INNER) && !defined(CYLINDER_INNER_OUTER_EQUAL) uniform vec3 u_cylinderScaleUvToInnerBounds; uniform vec3 u_cylinderTranslateUvToInnerBounds; #endif @@ -945,9 +946,32 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { // Inner ellipsoid #if defined(ELLIPSOID_INNER) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); + #if defined(ELLIPSOID_INNER_OUTER_EQUAL) + // When the ellipsoid is perfectly thin it's necessary to sandwich the + // inner ellipsoid intersection inside the outer ellipsoid intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the ellipsoid to be invisible because it will think the ray + // is still inside the inner (negative) ellipsoid after exiting the + // outer (positive) ellipsoid. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #else + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); + #endif #endif // Flip the ray because the intersection function expects a cone growing towards +Z. @@ -1003,6 +1027,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #if defined(SHAPE_ELLIPSOID) vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { + // Compute position and normal. // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. vec3 positionLocal = positionUv * 2.0 - 1.0; @@ -1017,7 +1042,7 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { // Compute longitude float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; #if defined(ELLIPSOID_WEDGE) - #if defined(ELLIPSOID_ANGLE_FLIPPED) + #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) longitude += float(longitude <= u_ellipsoidWestUv); #endif longitude = longitude * u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv + u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; @@ -1030,21 +1055,28 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { #endif // Compute height - #if defined(ELLIPSOID_IS_SPHERE) - #if defined(ELLIPSOID_INNER) - float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; - #else - float height = length(posEllipsoid); - #endif + #if defined(ELLIPSOID_INNER_OUTER_EQUAL) + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + float height = 1.0; #else - #if defined(ELLIPSOID_INNER) - // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). - // This is an optimization so that math can be done with ellipses instead of ellipsoids. - vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); - float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; + #if defined(ELLIPSOID_IS_SPHERE) + #if defined(ELLIPSOID_INNER) + float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; + #else + float height = length(posEllipsoid); + #endif #else - // TODO: this is probably not correct - float height = length(posEllipsoid); + #if defined(ELLIPSOID_INNER) + // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). + // This is an optimization so that math can be done with ellipses instead of ellipsoids. + vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); + float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; + #else + // TODO: this is probably not correct + float height = length(posEllipsoid); + #endif #endif #endif @@ -1075,34 +1107,32 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) return; } - #if defined(CYLINDER_INNER) + #if defined(CYLINDER_INNER_OUTER_EQUAL) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + vec2 innerIntersect = intersectInfiniteUnitCylinder(outerRay); + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(CYLINDER_INNER) Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - - #if defined(CYLINDER_INNER_OUTER_EQUAL) - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #else - setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); - #endif + setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); #endif #if defined(CYLINDER_WEDGE_REGULAR) @@ -1119,22 +1149,28 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) #if defined(SHAPE_CYLINDER) vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] - float radius = length(positionLocal.xy); // [0,1] - float height = positionUv.z; // [0,1] - float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - radius = radius * u_cylinderScaleRadiusUvToBoundsRadiusUv + u_cylinderOffsetRadiusUvToBoundsRadiusUv; + // Compute radius + #if defined(CYLINDER_INNER_OUTER_EQUAL) + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + float radius = 1.0; + #else + float radius = length(positionLocal.xy); // [0,1] + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) + radius = radius * u_cylinderScaleRadiusUvToBoundsRadiusUv + u_cylinderOffsetRadiusUvToBoundsRadiusUv; + #endif #endif - + + // Compute height + float height = positionUv.z; // [0,1] #if defined(CYLINDER_HEIGHT_NON_DEFAULT) height = height * u_cylinderScaleHeightUvToBoundsHeightUv + u_cylinderOffsetHeightUvToBoundsHeightUv; #endif + // Compute angle + float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] #if defined(CYLINDER_WEDGE) #if defined(CYLINDER_ANGLE_FLIPPED) angle += float(angle <= u_cylinderMinAngleUv); From f730221618b02d6d1928c655d808e176b72442e8 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 19:19:12 -0400 Subject: [PATCH 032/679] trying to reduce the number of shape uniforms --- Source/Scene/VoxelBoxShape.js | 33 +++--- Source/Scene/VoxelCylinderShape.js | 108 ++++++++----------- Source/Scene/VoxelEllipsoidShape.js | 24 +++-- Source/Shaders/VoxelFS.glsl | 154 +++++++++++++--------------- 4 files changed, 145 insertions(+), 174 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index cbd62a05358..301524456b1 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -75,11 +75,11 @@ function VoxelBoxShape() { * @readonly */ this.shaderUniforms = { - boxScaleUvToBoundsUv: new Cartesian3(), - boxTranslateUvToBoundsUv: new Cartesian3(), boxScaleUvToBounds: new Cartesian3(), - boxTranslateUvToBounds: new Cartesian3(), + boxOffsetUvToBounds: new Cartesian3(), boxTransformUvToBounds: new Matrix4(), + boxScaleUvToBoundsUv: new Cartesian3(), + boxOffsetUvToBoundsUv: new Cartesian3(), }; /** @@ -89,10 +89,8 @@ function VoxelBoxShape() { this.shaderDefines = { BOX_INTERSECTION_COUNT: undefined, BOX_INTERSECTION_INDEX: undefined, - BOX_BOUNDED: undefined, - BOX_XY_PLANE: undefined, - BOX_XZ_PLANE: undefined, - BOX_YZ_PLANE: undefined, + BOX_IS_BOUNDED: undefined, + BOX_IS_RECTANGLE: undefined, }; } @@ -222,7 +220,7 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { maxBounds.y !== defaultMaxBounds.y || maxBounds.z !== defaultMaxBounds.z ) { - shaderDefines["BOX_BOUNDED"] = true; + shaderDefines["BOX_IS_BOUNDED"] = true; // inverse(scale) // inverse(maxBoundsUv - minBoundsUv) @@ -256,15 +254,14 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { minBounds.y === maxBounds.y || minBounds.z === maxBounds.z ) { + shaderDefines["BOX_IS_RECTANGLE"] = true; + let transformAxisConversion; if (minBounds.x === maxBounds.x) { - shaderDefines["BOX_YZ_PLANE"] = true; transformAxisConversion = transformXYZToZYX; } else if (minBounds.y === maxBounds.y) { - shaderDefines["BOX_XZ_PLANE"] = true; transformAxisConversion = transformXYZToXZY; } else if (minBounds.z === maxBounds.z) { - shaderDefines["BOX_XY_PLANE"] = true; transformAxisConversion = Matrix4.IDENTITY; } transformLocalToBounds = Matrix4.multiply( @@ -283,9 +280,9 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { shaderUniforms.boxTransformUvToBounds, shaderUniforms.boxScaleUvToBounds ); - shaderUniforms.boxTranslateUvToBounds = Matrix4.getTranslation( + shaderUniforms.boxOffsetUvToBounds = Matrix4.getTranslation( shaderUniforms.boxTransformUvToBounds, - shaderUniforms.boxTranslateUvToBounds + shaderUniforms.boxOffsetUvToBounds ); // Go from UV space to bounded UV space: @@ -295,18 +292,18 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { // scale = 1.0 / (maxBoundsUv - minBoundsUv) // scale = 1.0 / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) // scale = 2.0 / (maxBounds - minBounds) - // translation = -minBoundsUv / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) - // translation = -2.0 * (minBounds * 0.5 + 0.5) / (maxBounds - minBounds) - // translation = -scale * (minBounds * 0.5 + 0.5) + // offset = -minBoundsUv / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) + // offset = -2.0 * (minBounds * 0.5 + 0.5) / (maxBounds - minBounds) + // offset = -scale * (minBounds * 0.5 + 0.5) shaderUniforms.boxScaleUvToBoundsUv = Cartesian3.clone( boundsScaleLocalToBounds, shaderUniforms.boxScaleUvToBoundsUv ); - shaderUniforms.boxTranslateUvToBoundsUv = Cartesian3.fromElements( + shaderUniforms.boxOffsetUvToBoundsUv = Cartesian3.fromElements( -boundsScaleLocalToBounds.x * (minBounds.x * 0.5 + 0.5), -boundsScaleLocalToBounds.y * (minBounds.y * 0.5 + 0.5), -boundsScaleLocalToBounds.z * (minBounds.z * 0.5 + 0.5), - shaderUniforms.boxTranslateUvToBoundsUv + shaderUniforms.boxOffsetUvToBoundsUv ); } diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index d0edaebd1f9..0b36456e389 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -1,4 +1,5 @@ import BoundingSphere from "../Core/BoundingSphere.js"; +import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; import CesiumMath from "../Core/Math.js"; @@ -95,17 +96,12 @@ function VoxelCylinderShape() { this.shaderUniforms = { cylinderScaleUvToBounds: new Cartesian3(), cylinderTranslateUvToBounds: new Cartesian3(), - cylinderScaleUvToInnerBounds: new Cartesian3(), - cylinderTranslateUvToInnerBounds: new Cartesian3(), - cylinderScaleRadiusUvToBoundsRadiusUv: 0.0, - cylinderOffsetRadiusUvToBoundsRadiusUv: 0.0, - cylinderScaleHeightUvToBoundsHeightUv: 0.0, - cylinderOffsetHeightUvToBoundsHeightUv: 0.0, - cylinderMinAngle: 0.0, - cylinderMaxAngle: 0.0, + cylinderInverseInnerRadiusUv: 0.0, + cylinderAngleMinMax: new Cartesian2(), + cylinderRadiusUvScaleAndOffset: new Cartesian2(), + cylinderHeightUvScaleAndOffset: new Cartesian2(), + cylinderAngleUvScaleAndOffset: new Cartesian2(), cylinderMinAngleUv: 0.0, - cylinderScaleAngleUvToBoundsAngleUv: 0.0, - cylinderOffsetAngleUvToBoundsAngleUv: 0.0, }; /** @@ -121,7 +117,7 @@ function VoxelCylinderShape() { CYLINDER_INNER_INDEX: undefined, CYLINDER_HEIGHT_NON_DEFAULT: undefined, CYLINDER_HEIGHT_ZERO: undefined, - CYLINDER_ANGLE_FLIPPED: undefined, + CYLINDER_WEDGE_ANGLE_FLIPPED: undefined, CYLINDER_WEDGE_INDEX: undefined, CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, @@ -326,40 +322,7 @@ VoxelCylinderShape.prototype.update = function ( } if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { - const boundsScaleLocalToInnerBounds = Cartesian3.fromElements( - 1.0 / minRadius, - 1.0 / minRadius, - 1.0 / (maxHeight === minHeight ? 1.0 : 0.5 * (maxHeight - minHeight)), - scratchBoundsScale - ); - - // -inverse(scale) * translation // affine inverse - // -inverse(scale) * 0.5 * (minHeight + maxHeight) - const boundsTranslateLocalToInnerBounds = Cartesian3.fromElements( - 0.0, - 0.0, - -boundsScaleLocalToInnerBounds.z * 0.5 * (minHeight + maxHeight), - scratchBoundsTranslation - ); - - const transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(boundsScaleLocalToInnerBounds), - boundsTranslateLocalToInnerBounds, - scratchTransformLocalToBounds - ); - const transformUvToBounds = Matrix4.multiplyTransformation( - transformLocalToBounds, - transformUvToLocal, - scratchTransformUvToBounds - ); - shaderUniforms.cylinderScaleUvToInnerBounds = Matrix4.getScale( - transformUvToBounds, - shaderUniforms.cylinderScaleUvToInnerBounds - ); - shaderUniforms.cylinderTranslateUvToInnerBounds = Matrix4.getTranslation( - transformUvToBounds, - shaderUniforms.cylinderTranslateUvToInnerBounds - ); + shaderUniforms.cylinderInverseInnerRadiusUv = maxRadius / minRadius; // delerp(radius, minRadius, maxRadius) // (radius - minRadius) / (maxRadius - minRadius) @@ -371,8 +334,11 @@ VoxelCylinderShape.prototype.update = function ( const scale = 1.0 / (maxRadius - minRadius); const offset = minRadius / (minRadius - maxRadius); - shaderUniforms.cylinderScaleRadiusUvToBoundsRadiusUv = scale; - shaderUniforms.cylinderOffsetRadiusUvToBoundsRadiusUv = offset; + shaderUniforms.cylinderRadiusUvScaleAndOffset = Cartesian2.fromElements( + scale, + offset, + shaderUniforms.cylinderRadiusUvScaleAndOffset + ); } if (!isDefaultHeight) { @@ -397,20 +363,40 @@ VoxelCylinderShape.prototype.update = function ( const scale = 2.0 / (maxHeight - minHeight); const offset = (minHeight + 1.0) / (minHeight - maxHeight); - shaderUniforms.cylinderScaleHeightUvToBoundsHeightUv = scale; - shaderUniforms.cylinderOffsetHeightUvToBoundsHeightUv = offset; + shaderUniforms.cylinderHeightUvScaleAndOffset = Cartesian2.fromElements( + scale, + offset, + shaderUniforms.cylinderHeightUvScaleAndOffset + ); } if (isAngleFlipped) { - shaderDefines["CYLINDER_ANGLE_FLIPPED"] = true; + shaderDefines["CYLINDER_WEDGE_ANGLE_FLIPPED"] = true; } + // Intersects a wedge for the min and max longitude. if (hasWedge) { shaderDefines["CYLINDER_WEDGE"] = true; shaderDefines["CYLINDER_WEDGE_INDEX"] = intersectionCount; - shaderUniforms.cylinderMinAngle = minAngle; - shaderUniforms.cylinderMaxAngle = maxAngle; + if (hasWedgeRegular) { + shaderDefines["CYLINDER_WEDGE_REGULAR"] = true; + intersectionCount += 1; + } else if (hasWedgeFlipped) { + shaderDefines["CYLINDER_WEDGE_FLIPPED"] = true; + intersectionCount += 2; + } + + shaderUniforms.cylinderAngleMinMax = Cartesian2.fromElements( + minAngle, + maxAngle, + shaderUniforms.cylinderAngleMinMax + ); + + if (isAngleFlipped) { + const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; + shaderUniforms.cylinderMinAngleUv = minAngleUv; + } // delerp(angleUv, minAngleUv, maxAngleUv) // (angelUv - minAngleUv) / (maxAngleUv - minAngleUv) @@ -422,22 +408,14 @@ VoxelCylinderShape.prototype.update = function ( // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // offset = -(minAngle - pi) / (maxAngle - minAngle) - const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; const scale = defaultAngleWidth / angleWidth; const offset = -(minAngle - defaultMinAngle) / angleWidth; - shaderUniforms.cylinderMinAngleUv = minAngleUv; - shaderUniforms.cylinderScaleAngleUvToBoundsAngleUv = scale; - shaderUniforms.cylinderOffsetAngleUvToBoundsAngleUv = offset; - - if (hasWedgeRegular) { - // Intersects a wedge for the min and max longitude. - shaderDefines["CYLINDER_WEDGE_REGULAR"] = true; - intersectionCount += 1; - } else if (hasWedgeFlipped) { - shaderDefines["CYLINDER_WEDGE_FLIPPED"] = true; - intersectionCount += 2; - } + shaderUniforms.cylinderAngleUvScaleAndOffset = Cartesian2.fromElements( + scale, + offset, + shaderUniforms.cylinderAngleUvScaleAndOffset + ); } shaderDefines["CYLINDER_INTERSECTION_COUNT"] = intersectionCount; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 865bf65538c..bb1f382da20 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -98,12 +98,10 @@ function VoxelEllipsoidShape() { ellipsoidRadiiUv: new Cartesian3(), ellipsoidInverseRadiiSquaredUv: new Cartesian3(), // Wedge uniforms - ellipsoidWestUv: 0.0, - ellipsoidScaleLongitudeUvToBoundsLongitudeUv: 0.0, - ellipsoidOffsetLongitudeUvToBoundsLongitudeUv: 0.0, + ellipsoidMinLongitudeUv: 0.0, + ellipsoidLongitudeUvScaleAndOffset: new Cartesian2(), // Cone uniforms - ellipsoidScaleLatitudeUvToBoundsLatitudeUv: 0.0, - ellipsoidOffsetLatitudeUvToBoundsLatitudeUv: 0.0, + ellipsoidLatitudeUvScaleAndOffset: new Cartesian2(), // Inner ellipsoid uniforms ellipsoidInverseHeightDifferenceUv: 0.0, ellipsoidInverseInnerScaleUv: 0.0, @@ -379,9 +377,12 @@ VoxelEllipsoidShape.prototype.update = function ( const scale = defaultLongitudeLength / rectangleWidth; const offset = -(west - defaultMinLongitude) / rectangleWidth; - shaderUniforms.ellipsoidWestUv = westUv; - shaderUniforms.ellipsoidScaleLongitudeUvToBoundsLongitudeUv = scale; - shaderUniforms.ellipsoidOffsetLongitudeUvToBoundsLongitudeUv = offset; + shaderUniforms.ellipsoidMinLongitudeUv = westUv; + shaderUniforms.ellipsoidLongitudeUvScaleAndOffset = Cartesian2.fromElements( + scale, + offset, + shaderUniforms.ellipsoidLongitudeUvScaleAndOffset + ); } if (isAngleFlipped) { @@ -402,8 +403,11 @@ VoxelEllipsoidShape.prototype.update = function ( const scale = defaultLatitudeLength / rectangleHeight; const offset = -(south - defaultMinLatitude) / rectangleHeight; - shaderUniforms.ellipsoidScaleLatitudeUvToBoundsLatitudeUv = scale; - shaderUniforms.ellipsoidOffsetLatitudeUvToBoundsLatitudeUv = offset; + shaderUniforms.ellipsoidLatitudeUvScaleAndOffset = Cartesian2.fromElements( + scale, + offset, + shaderUniforms.ellipsoidLatitudeUvScaleAndOffset + ); } // Intersects a cone for min latitude diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index d46cd7ae817..b5ba60e7bcd 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -193,22 +193,21 @@ uniform float u_stepSize; /* Box defines: #define BOX_INTERSECTION_COUNT ### // always 1 #define BOX_INTERSECTION_INDEX ### // always 0 - #define BOX_BOUNDED - #define BOX_XY_PLANE - #define BOX_XZ_PLANE - #define BOX_YZ_PLANE + #define BOX_IS_BOUNDED + #define BOX_IS_RECTANGLE */ // Box uniforms: - #if defined(BOX_BOUNDED) + #if defined(BOX_IS_BOUNDED) uniform vec3 u_boxScaleUvToBoundsUv; - uniform vec3 u_boxTranslateUvToBoundsUv; - #if defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) + uniform vec3 u_boxOffsetUvToBoundsUv; + #if defined(BOX_IS_RECTANGLE) + // This matrix bakes in an axis conversion so that the math works for XY plane. uniform mat4 u_boxTransformUvToBounds; #else // Similar to u_boxTransformUvToBounds but fewer instructions needed. uniform vec3 u_boxScaleUvToBounds; - uniform vec3 u_boxTranslateUvToBounds; + uniform vec3 u_boxOffsetUvToBounds; #endif #endif #endif @@ -239,21 +238,20 @@ uniform float u_stepSize; // Ellipsoid uniforms uniform vec3 u_ellipsoidRadiiUv; // [0,1] - uniform vec3 u_ellipsoidInverseRadiiSquaredUv; - + #if !defined(ELLIPSOID_IS_SPHERE) + uniform vec3 u_ellipsoidInverseRadiiSquaredUv; + #endif #if defined(ELLIPSOID_WEDGE) || defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif - #if defined(ELLIPSOID_WEDGE) && defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) - uniform float u_ellipsoidWestUv; - #endif #if defined(ELLIPSOID_WEDGE) - uniform float u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv; - uniform float u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; + uniform vec2 u_ellipsoidLongitudeUvScaleAndOffset; + #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) + uniform float u_ellipsoidMinLongitudeUv; + #endif #endif #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) - uniform float u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv; - uniform float u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; + uniform vec2 u_ellipsoidLatitudeUvScaleAndOffset; #endif #if defined(ELLIPSOID_INNER) && !defined(ELLIPSOID_INNER_OUTER_EQUAL) uniform float u_ellipsoidInverseHeightDifferenceUv; @@ -272,11 +270,11 @@ uniform float u_stepSize; #define CYLINDER_INNER_INDEX ### // when there's an inner cylinder #define CYLINDER_HEIGHT_NON_DEFAULT ### // #define CYLINDER_HEIGHT_ZERO // when the height is 0 - #define CYLINDER_ANGLE_FLIPPED // #define CYLINDER_WEDGE // #define CYLINDER_WEDGE_INDEX // #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define CYLINDER_WEDGE_ANGLE_FLIPPED // */ // Cylinder uniforms @@ -284,26 +282,21 @@ uniform float u_stepSize; uniform vec3 u_cylinderScaleUvToBounds; uniform vec3 u_cylinderTranslateUvToBounds; #endif - - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - uniform float u_cylinderScaleRadiusUvToBoundsRadiusUv; - uniform float u_cylinderOffsetRadiusUvToBoundsRadiusUv; - #endif - #if defined(CYLINDER_INNER) && !defined(CYLINDER_INNER_OUTER_EQUAL) - uniform vec3 u_cylinderScaleUvToInnerBounds; - uniform vec3 u_cylinderTranslateUvToInnerBounds; + uniform float u_cylinderInverseInnerRadiusUv; + #endif + #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) + uniform vec2 u_cylinderRadiusUvScaleAndOffset; #endif #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - uniform float u_cylinderScaleHeightUvToBoundsHeightUv; - uniform float u_cylinderOffsetHeightUvToBoundsHeightUv; + uniform vec2 u_cylinderHeightUvScaleAndOffset; #endif #if defined(CYLINDER_WEDGE) - uniform float u_cylinderMinAngle; - uniform float u_cylinderMaxAngle; - uniform float u_cylinderMinAngleUv; - uniform float u_cylinderScaleAngleUvToBoundsAngleUv; - uniform float u_cylinderOffsetAngleUvToBoundsAngleUv; + uniform vec2 u_cylinderAngleMinMax; + uniform vec2 u_cylinderAngleUvScaleAndOffset; + #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) + uniform float u_cylinderMinAngleUv; + #endif #endif #endif @@ -896,21 +889,22 @@ float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { #if defined(SHAPE_BOX) void intersectBoxShape(Ray ray, out Intersections ix) { - #if !defined(BOX_BOUNDED) - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir = ray.dir * 2.0; + #if defined(BOX_IS_BOUNDED) + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxOffsetUvToBounds; + ray.dir *= u_boxScaleUvToBounds; vec2 entryExit = intersectUnitCube(ray); - #elif defined(BOX_XY_PLANE) || defined(BOX_XZ_PLANE) || defined(BOX_YZ_PLANE) + #elif defined(BOX_IS_RECTANGLE) // Transform the ray into unit square space on Z plane + // This matrix bakes in an axis conversion so that the math works for XY plane. ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); vec2 entryExit = intersectUnitSquare(ray); #else - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxTranslateUvToBounds; - ray.dir *= u_boxScaleUvToBounds; + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir = ray.dir * 2.0; vec2 entryExit = intersectUnitCube(ray); #endif @@ -920,8 +914,8 @@ void intersectBoxShape(Ray ray, out Intersections ix) #if defined(SHAPE_BOX) vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - #if defined(BOX_BOUNDED) - return positionUv * u_boxScaleUvToBoundsUv + u_boxTranslateUvToBoundsUv; + #if defined(BOX_IS_BOUNDED) + return positionUv * u_boxScaleUvToBoundsUv + u_boxOffsetUvToBoundsUv; #else return positionUv; #endif @@ -945,33 +939,31 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { } // Inner ellipsoid - #if defined(ELLIPSOID_INNER) - #if defined(ELLIPSOID_INNER_OUTER_EQUAL) - // When the ellipsoid is perfectly thin it's necessary to sandwich the - // inner ellipsoid intersection inside the outer ellipsoid intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the ellipsoid to be invisible because it will think the ray - // is still inside the inner (negative) ellipsoid after exiting the - // outer (positive) ellipsoid. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #else - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); - #endif + #if defined(ELLIPSOID_INNER_OUTER_EQUAL) + // When the ellipsoid is perfectly thin it's necessary to sandwich the + // inner ellipsoid intersection inside the outer ellipsoid intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the ellipsoid to be invisible because it will think the ray + // is still inside the inner (negative) ellipsoid after exiting the + // outer (positive) ellipsoid. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(ELLIPSOID_INNER) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); #endif // Flip the ray because the intersection function expects a cone growing towards +Z. @@ -1043,15 +1035,15 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; #if defined(ELLIPSOID_WEDGE) #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) - longitude += float(longitude <= u_ellipsoidWestUv); + longitude += float(longitude <= u_ellipsoidMinLongitudeUv); #endif - longitude = longitude * u_ellipsoidScaleLongitudeUvToBoundsLongitudeUv + u_ellipsoidOffsetLongitudeUvToBoundsLongitudeUv; + longitude = longitude * u_ellipsoidLongitudeUvScaleAndOffset.x + u_ellipsoidLongitudeUvScaleAndOffset.y; #endif // Compute latitude float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; #if (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) - latitude = latitude * u_ellipsoidScaleLatitudeUvToBoundsLatitudeUv + u_ellipsoidOffsetLatitudeUvToBoundsLatitudeUv; + latitude = latitude * u_ellipsoidLatitudeUvScaleAndOffset.x + u_ellipsoidLatitudeUvScaleAndOffset.y; #endif // Compute height @@ -1130,16 +1122,16 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit #elif defined(CYLINDER_INNER) - Ray innerRay = Ray(ray.pos * u_cylinderScaleUvToInnerBounds + u_cylinderTranslateUvToInnerBounds, ray.dir * u_cylinderScaleUvToInnerBounds); + Ray innerRay = Ray(outerRay.pos * u_cylinderInverseInnerRadiusUv, outerRay.dir * u_cylinderInverseInnerRadiusUv); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); #endif #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectRegularWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + vec2 wedgeIntersect = intersectRegularWedge(outerRay, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); #elif defined(CYLINDER_WEDGE_FLIPPED) - vec4 wedgeIntersect = intersectFlippedWedge(outerRay, u_cylinderMinAngle, u_cylinderMaxAngle); + vec4 wedgeIntersect = intersectFlippedWedge(outerRay, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); #endif @@ -1159,23 +1151,23 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { #else float radius = length(positionLocal.xy); // [0,1] #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - radius = radius * u_cylinderScaleRadiusUvToBoundsRadiusUv + u_cylinderOffsetRadiusUvToBoundsRadiusUv; + radius = radius * u_cylinderRadiusUvScaleAndOffset.x + u_cylinderRadiusUvScaleAndOffset.y; #endif #endif // Compute height float height = positionUv.z; // [0,1] #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - height = height * u_cylinderScaleHeightUvToBoundsHeightUv + u_cylinderOffsetHeightUvToBoundsHeightUv; + height = height * u_cylinderHeightUvScaleAndOffset.x + u_cylinderHeightUvScaleAndOffset.y; #endif // Compute angle float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] #if defined(CYLINDER_WEDGE) - #if defined(CYLINDER_ANGLE_FLIPPED) + #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) angle += float(angle <= u_cylinderMinAngleUv); #endif - angle = angle * u_cylinderScaleAngleUvToBoundsAngleUv + u_cylinderOffsetAngleUvToBoundsAngleUv; + angle = angle * u_cylinderAngleUvScaleAndOffset.x + u_cylinderAngleUvScaleAndOffset.y; #endif return vec3(radius, height, angle); From a19e9b9c4e3c7c68e6c7e8c3396522cd51ddd821 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 20:05:40 -0400 Subject: [PATCH 033/679] handling multiple intersection intervals behind the ray --- Source/Shaders/VoxelFS.glsl | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index b5ba60e7bcd..791ca2573f8 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -407,6 +407,9 @@ struct Intersections { #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] #endif +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection(ix, (index) * 2 + 0), getIntersection(ix, (index) * 2 + 1)) + // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. #if (SCENE_INTERSECTION_COUNT > 1) #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) @@ -470,13 +473,13 @@ vec2 nextIntersection(inout Intersections ix) { #endif #if (SCENE_INTERSECTION_COUNT > 1) -vec2 initializeIntersections(inout Intersections ix) { +void initializeIntersections(inout Intersections ix) { // Sort the intersections from min T to max T with bubble sort. // Note: If this sorting function changes, some of the intersection test may // need to be updated. Search for "bubble sort" to find those areas. - const int passes = SCENE_INTERSECTION_COUNT * 2 - 1; - for (int n = passes; n > 0; --n) { - for (int i = 0; i < passes; ++i) { + const int sortPasses = SCENE_INTERSECTION_COUNT * 2 - 1; + for (int n = sortPasses; n > 0; --n) { + for (int i = 0; i < sortPasses; ++i) { // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot // loop with non-constant condition, so it has to break early instead if (i >= n) { break; } @@ -503,8 +506,6 @@ vec2 initializeIntersections(inout Intersections ix) { ix.index = 0; ix.surroundCount = 0; ix.surroundIsPositive = false; - - return nextIntersection(ix); } #endif @@ -1216,9 +1217,9 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int // Do a ray-shape intersection to find the exact starting and ending points. intersectShape(ray, ix); - // Check if the positive shape was completely missed, and if so, exit early. - float entryPositiveShapeT = getIntersection(ix, 0); - if (entryPositiveShapeT == NO_HIT) { + // Exit early if the positive shape was completely missed or behind the ray. + vec2 entryExitT = getIntersectionPair(ix, 0); + if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { return vec2(NO_HIT); } @@ -1228,22 +1229,22 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); #endif - // Find the first intersection interval + // Find the first intersection that's in front of the ray #if (SCENE_INTERSECTION_COUNT > 1) - vec2 entryExitT = initializeIntersections(ix); + initializeIntersections(ix); + for (int i = 0; i < SCENE_INTERSECTION_COUNT; i++) { + entryExitT = nextIntersection(ix); + if (entryExitT.y > 0.0) { + // Set start to 0.0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + break; + } + } #else - float exitPositiveShapeT = getIntersection(ix, 1); - vec2 entryExitT = vec2(entryPositiveShapeT, exitPositiveShapeT); + // Set start to 0.0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); #endif - // Intersection is invalid when start and end are behind the ray. - if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { - return vec2(NO_HIT); - } - - // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); - return entryExitT; } From f3e90f0411bb4631d6af66e9bcbd11142387b76c Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 14 Apr 2022 20:08:15 -0400 Subject: [PATCH 034/679] forgot to wrap macro param in parenthesis --- Source/Shaders/VoxelFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 791ca2573f8..4bd1872941a 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -408,7 +408,7 @@ struct Intersections { #endif // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection(ix, (index) * 2 + 0), getIntersection(ix, (index) * 2 + 1)) +#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. #if (SCENE_INTERSECTION_COUNT > 1) From 24aa97bcefe2cc710912a50191d64ca6e13ea66b Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 15 Apr 2022 09:22:31 -0400 Subject: [PATCH 035/679] square fix --- Source/Shaders/VoxelFS.glsl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 4bd1872941a..21be3c48a50 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -890,17 +890,17 @@ float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { #if defined(SHAPE_BOX) void intersectBoxShape(Ray ray, out Intersections ix) { - #if defined(BOX_IS_BOUNDED) - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxOffsetUvToBounds; - ray.dir *= u_boxScaleUvToBounds; - vec2 entryExit = intersectUnitCube(ray); - #elif defined(BOX_IS_RECTANGLE) + #if defined(BOX_IS_RECTANGLE) // Transform the ray into unit square space on Z plane // This matrix bakes in an axis conversion so that the math works for XY plane. ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); vec2 entryExit = intersectUnitSquare(ray); + #elif defined(BOX_IS_BOUNDED) + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxOffsetUvToBounds; + ray.dir *= u_boxScaleUvToBounds; + vec2 entryExit = intersectUnitCube(ray); #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. From 306002b6400de542b5ce0cb28206379b69880410 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 15 Apr 2022 10:36:37 -0400 Subject: [PATCH 036/679] handling flat cone --- Source/Scene/VoxelEllipsoidShape.js | 41 +++++++++++++--- Source/Shaders/VoxelFS.glsl | 73 +++++++++++++++++++---------- 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index bb1f382da20..2cbab24949a 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -102,6 +102,8 @@ function VoxelEllipsoidShape() { ellipsoidLongitudeUvScaleAndOffset: new Cartesian2(), // Cone uniforms ellipsoidLatitudeUvScaleAndOffset: new Cartesian2(), + ellipsoidMinLatitudeCosSqrHalfAngle: 0.0, + ellipsoidMaxLatitudeCosSqrHalfAngle: 0.0, // Inner ellipsoid uniforms ellipsoidInverseHeightDifferenceUv: 0.0, ellipsoidInverseInnerScaleUv: 0.0, @@ -122,10 +124,12 @@ function VoxelEllipsoidShape() { ELLIPSOID_CONE_BOTTOM: undefined, ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, + ELLIPSOID_CONE_BOTTOM_FLAT: undefined, ELLIPSOID_CONE_BOTTOM_INDEX: undefined, ELLIPSOID_CONE_TOP: undefined, ELLIPSOID_CONE_TOP_REGULAR: undefined, ELLIPSOID_CONE_TOP_FLIPPED: undefined, + ELLIPSOID_CONE_TOP_FLAT: undefined, ELLIPSOID_CONE_TOP_INDEX: undefined, ELLIPSOID_OUTER: undefined, ELLIPSOID_OUTER_INDEX: undefined, @@ -302,13 +306,19 @@ VoxelEllipsoidShape.prototype.update = function ( const hasWedgeFlipped = rectangleWidth < CesiumMath.PI; const hasWedge = hasWedgeRegular || hasWedgeFlipped; - const hasTopConeRegular = north >= 0.0 && north < +CesiumMath.PI_OVER_TWO; - const hasTopConeFlipped = north < 0.0; - const hasTopCone = hasTopConeRegular || hasTopConeFlipped; + const flatConeEpsilon = CesiumMath.EPSILON4; // 0.0001 radians = 0.00573 degrees + const hasTopConeRegular = + north > +flatConeEpsilon && north < defaultMaxLatitude; + const hasTopConeFlipped = north < -flatConeEpsilon; + const hasTopConeFlat = north >= -flatConeEpsilon && north <= +flatConeEpsilon; + const hasTopCone = hasTopConeRegular || hasTopConeFlipped || hasTopConeFlat; - const hasBottomConeRegular = south <= 0.0 && south > -CesiumMath.PI_OVER_TWO; - const hasBottomConeFlipped = south > 0.0; - const hasBottomCone = hasBottomConeRegular || hasBottomConeFlipped; + const hasBottomConeRegular = + south > defaultMinLatitude && south < -flatConeEpsilon; + const hasBottomConeFlipped = south > +flatConeEpsilon; + const hasBottomConeFlat = south === 0.0; + const hasBottomCone = + hasBottomConeRegular || hasBottomConeFlipped || hasBottomConeFlat; const isSphere = radii.x === radii.y && radii.y === radii.z; @@ -408,6 +418,19 @@ VoxelEllipsoidShape.prototype.update = function ( offset, shaderUniforms.ellipsoidLatitudeUvScaleAndOffset ); + + const minAngle = hasBottomConeRegular ? -south : south; + const maxAngle = hasTopConeFlipped ? -north : north; + const minCosHalfAngle = Math.cos( + CesiumMath.PI_OVER_TWO - Math.abs(minAngle) + ); + const maxCosHalfAngle = Math.cos( + CesiumMath.PI_OVER_TWO - Math.abs(maxAngle) + ); + shaderUniforms.ellipsoidMinLatitudeCosSqrHalfAngle = + minCosHalfAngle * minCosHalfAngle; + shaderUniforms.ellipsoidMaxLatitudeCosSqrHalfAngle = + maxCosHalfAngle * maxCosHalfAngle; } // Intersects a cone for min latitude @@ -421,6 +444,9 @@ VoxelEllipsoidShape.prototype.update = function ( } else if (hasBottomConeFlipped) { shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = true; intersectionCount += 2; + } else if (hasBottomConeFlat) { + shaderDefines["ELLIPSOID_CONE_BOTTOM_FLAT"] = true; + intersectionCount += 1; } } @@ -435,6 +461,9 @@ VoxelEllipsoidShape.prototype.update = function ( } else if (hasTopConeFlipped) { shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = true; intersectionCount += 2; + } else if (hasTopConeFlat) { + shaderDefines["ELLIPSOID_CONE_TOP_FLAT"] = true; + intersectionCount += 1; } } diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 21be3c48a50..a7d86882cd7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -221,12 +221,14 @@ uniform float u_stepSize; #define ELLIPSOID_WEDGE_INDEX ### #define ELLIPSOID_WEDGE_ANGLE_FLIPPED // #define ELLIPSOID_CONE_BOTTOM - #define ELLIPSOID_CONE_BOTTOM_REGULAR ### // when there's a bottom cone - #define ELLIPSOID_CONE_BOTTOM_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_BOTTOM_REGULAR // when there's a bottom cone + #define ELLIPSOID_CONE_BOTTOM_FLIPPED // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_BOTTOM_FLAT #define ELLIPSOID_CONE_BOTTOM_INDEX ### #define ELLIPSOID_CONE_TOP #define ELLIPSOID_CONE_TOP_REGULAR ### // when there's a top cone #define ELLIPSOID_CONE_TOP_FLIPPED ### // when cone shape has two intersection intervals + #define ELLIPSOID_CONE_TOP_FLAT #define ELLIPSOID_CONE_TOP_INDEX ### #define ELLIPSOID_OUTER ### // outer ellipsoid - always defined #define ELLIPSOID_OUTER_INDEX ### @@ -253,6 +255,12 @@ uniform float u_stepSize; #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec2 u_ellipsoidLatitudeUvScaleAndOffset; #endif + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) + uniform float u_ellipsoidMinLatitudeCosSqrHalfAngle; + #endif + #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + uniform float u_ellipsoidMaxLatitudeCosSqrHalfAngle; + #endif #if defined(ELLIPSOID_INNER) && !defined(ELLIPSOID_INNER_OUTER_EQUAL) uniform float u_ellipsoidInverseHeightDifferenceUv; uniform float u_ellipsoidInverseInnerScaleUv; @@ -600,6 +608,19 @@ vec2 intersectHalfSpace(Ray ray, float angle) } #endif +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLAT)) +vec2 intersectZPlane(Ray ray) +{ + float o = ray.pos.z; + float d = ray.dir.z; + float t = -o / d; + float s = sign(o); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} +#endif + #if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) { @@ -658,16 +679,14 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) -vec2 intersectDoubleEndedCone(Ray ray, float latitude) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) { vec3 o = ray.pos; vec3 d = ray.dir; - float h = cos(czm_piOverTwo - abs(latitude)); - float hh = h * h; - float a = d.z * d.z - dot(d, d) * hh; - float b = d.z * o.z - dot(o, d) * hh; - float c = o.z * o.z - dot(o, o) * hh; + float a = d.z * d.z - dot(d, d) * cosSqrHalfAngle; + float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; + float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; float det = b * b - a * c; if (det < 0.0) { @@ -684,15 +703,15 @@ vec2 intersectDoubleEndedCone(Ray ray, float latitude) #endif #if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) -vec4 intersectFlippedCone(Ray ray, float latitude) { - vec3 o = ray.pos; - vec3 d = ray.dir; - vec2 intersect = intersectDoubleEndedCone(ray, latitude); +vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); if (intersect.x == NO_HIT) { return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); } + vec3 o = ray.pos; + vec3 d = ray.dir; float tmin = intersect.x; float tmax = intersect.y; float zmin = o.z + tmin * d.z; @@ -708,15 +727,15 @@ vec4 intersectFlippedCone(Ray ray, float latitude) { #endif #if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_TOP_REGULAR)) -vec2 intersectRegularCone(Ray ray, float latitude) { - vec3 o = ray.pos; - vec3 d = ray.dir; - vec2 intersect = intersectDoubleEndedCone(ray, latitude); +vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); if (intersect.x == NO_HIT) { return vec2(NO_HIT); } + vec3 o = ray.pos; + vec3 d = ray.dir; float tmin = intersect.x; float tmax = intersect.y; float zmin = o.z + tmin * d.z; @@ -968,7 +987,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #endif // Flip the ray because the intersection function expects a cone growing towards +Z. - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLIPPED) Ray flippedRay = ray; flippedRay.dir.z *= -1.0; flippedRay.pos.z *= -1.0; @@ -977,28 +996,30 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { // Bottom cone #if defined(ELLIPSOID_CONE_BOTTOM) #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) - float flippedSouth = -u_ellipsoidRectangle.y; // [-halfPi,+halfPi] - vec2 bottomConeIntersection = intersectRegularCone(flippedRay, flippedSouth); + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidMinLatitudeCosSqrHalfAngle); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - float south = u_ellipsoidRectangle.y; - vec4 bottomConeIntersection = intersectFlippedCone(ray, south); + vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidMinLatitudeCosSqrHalfAngle); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 0, bottomConeIntersection.xy); setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 1, bottomConeIntersection.zw); + #elif defined(ELLIPSOID_CONE_BOTTOM_FLAT) + vec2 bottomConeIntersection = intersectZPlane(flippedRay); + setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); #endif #endif // Top cone #if defined(ELLIPSOID_CONE_TOP) #if defined(ELLIPSOID_CONE_TOP_REGULAR) - float north = u_ellipsoidRectangle.w; // [-halfPi,+halfPi] - vec2 topConeIntersection = intersectRegularCone(ray, north); + vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidMaxLatitudeCosSqrHalfAngle); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) - float flippedNorth = -u_ellipsoidRectangle.w; // [-halfPi,+halfPi] - vec4 topConeIntersection = intersectFlippedCone(flippedRay, flippedNorth); + vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidMaxLatitudeCosSqrHalfAngle); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 0, topConeIntersection.xy); setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 1, topConeIntersection.zw); + #elif defined(ELLIPSOID_CONE_TOP_FLAT) + vec2 topConeIntersection = intersectZPlane(ray); + setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); #endif #endif From 456680aa9c1b50786964cfe91665ffb56e190d1f Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 15 Apr 2022 14:20:17 -0400 Subject: [PATCH 037/679] fixed wedge edge artifacts --- Source/Scene/VoxelCylinderShape.js | 55 ++++++++++++++++++++++++------ Source/Shaders/VoxelFS.glsl | 24 +++++++++++-- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 0b36456e389..b1a3d577020 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -102,6 +102,8 @@ function VoxelCylinderShape() { cylinderHeightUvScaleAndOffset: new Cartesian2(), cylinderAngleUvScaleAndOffset: new Cartesian2(), cylinderMinAngleUv: 0.0, + cylinderMaxAngleUv: 0.0, + cylinderEmptyMidpointAngleUv: 0.0, }; /** @@ -121,6 +123,8 @@ function VoxelCylinderShape() { CYLINDER_WEDGE_INDEX: undefined, CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, + CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, + CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, }; } @@ -190,6 +194,10 @@ VoxelCylinderShape.prototype.update = function ( const minAngle = CesiumMath.negativePiToPi(minBounds.z); const maxAngle = CesiumMath.negativePiToPi(maxBounds.z); + const zeroScaleEpsilon = CesiumMath.EPSILON10; + const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const wedgeDetectionEpsilon = CesiumMath.EPSILON10; + // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. @@ -197,14 +205,14 @@ VoxelCylinderShape.prototype.update = function ( // - maxRadius is zero (line) // - minHeight is greater than maxHeight // - scale is 0 for any component (too annoying to reconstruct rotation matrix) - const absEpsilon = CesiumMath.EPSILON10; + if ( maxRadius === 0.0 || minRadius > maxRadius || minHeight > maxHeight || - CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, absEpsilon) + CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, zeroScaleEpsilon) || + CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, zeroScaleEpsilon) || + CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, zeroScaleEpsilon) ) { return false; } @@ -246,13 +254,26 @@ VoxelCylinderShape.prototype.update = function ( minHeight === defaultMinHeight && maxHeight === defaultMaxHeight; const isAngleFlipped = maxAngle < minAngle; - const angleWidth = maxAngle - minAngle + isAngleFlipped * CesiumMath.TWO_PI; + const angleWidth = maxAngle - minAngle + isAngleFlipped * defaultAngleWidth; const hasWedgeRegular = angleWidth >= CesiumMath.PI && - CesiumMath.lessThan(angleWidth, CesiumMath.TWO_PI, absEpsilon); + CesiumMath.lessThan(angleWidth, defaultAngleWidth, wedgeDetectionEpsilon); const hasWedgeFlipped = angleWidth < CesiumMath.PI; const hasWedge = hasWedgeRegular || hasWedgeFlipped; + const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( + minAngle, + defaultMinAngle, + undefined, + angleDiscontinuityEpsilon + ); + const isMaxAngleDiscontinuity = CesiumMath.equalsEpsilon( + maxAngle, + defaultMaxAngle, + undefined, + angleDiscontinuityEpsilon + ); + const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; @@ -393,10 +414,14 @@ VoxelCylinderShape.prototype.update = function ( shaderUniforms.cylinderAngleMinMax ); - if (isAngleFlipped) { - const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; - shaderUniforms.cylinderMinAngleUv = minAngleUv; - } + const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; + const maxAngleUv = (maxAngle - defaultMinAngle) / defaultAngleWidth; + const emptyAngleWidthUv = 1.0 - angleWidth / defaultAngleWidth; + + shaderUniforms.cylinderMinAngleUv = minAngleUv; + shaderUniforms.cylinderMaxAngleUv = maxAngleUv; + shaderUniforms.cylinderEmptyMidpointAngleUv = + (maxAngleUv + 0.5 * emptyAngleWidthUv) % 1.0; // delerp(angleUv, minAngleUv, maxAngleUv) // (angelUv - minAngleUv) / (maxAngleUv - minAngleUv) @@ -420,6 +445,13 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_INTERSECTION_COUNT"] = intersectionCount; + if (isMinAngleDiscontinuity) { + shaderDefines["CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; + } + if (isMaxAngleDiscontinuity) { + shaderDefines["CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; + } + return true; }; @@ -691,7 +723,8 @@ function getCylinderChunkObb( } const isAngleFlipped = angleEnd < angleStart; - const angleWidth = angleEnd - angleStart + isAngleFlipped * CesiumMath.TWO_PI; + const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; + const angleWidth = angleEnd - angleStart + isAngleFlipped * defaultAngleWidth; testAngles[testAngleCount++] = CesiumMath.negativePiToPi( angleStart + angleWidth * 0.5 diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index a7d86882cd7..59327ad6cc7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -283,6 +283,8 @@ uniform float u_stepSize; #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define CYLINDER_WEDGE_ANGLE_FLIPPED // + #define CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY + #define CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY */ // Cylinder uniforms @@ -302,9 +304,15 @@ uniform float u_stepSize; #if defined(CYLINDER_WEDGE) uniform vec2 u_cylinderAngleMinMax; uniform vec2 u_cylinderAngleUvScaleAndOffset; - #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) + #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) || defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) || defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + uniform float u_cylinderEmptyMidpointAngleUv; + #endif + #if defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) uniform float u_cylinderMinAngleUv; #endif + #if defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + uniform float u_cylinderMaxAngleUv; + #endif #endif #endif @@ -1187,8 +1195,17 @@ vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] #if defined(CYLINDER_WEDGE) #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) - angle += float(angle <= u_cylinderMinAngleUv); + // Comparing against u_cylinderMinAngleUv has precision problems. u_cylinderEmptyMidpointAngleUv is more conservative. + angle += float(angle < u_cylinderEmptyMidpointAngleUv); #endif + + // When the min or max angle is near the -pi/+pi discontinuity there may be flickering as both sides of the voxel data are read. + #if defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) + angle = angle > u_cylinderEmptyMidpointAngleUv ? u_cylinderMinAngleUv : angle; + #elif defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + angle = angle < u_cylinderEmptyMidpointAngleUv ? u_cylinderMaxAngleUv : angle; + #endif + angle = angle * u_cylinderAngleUvScaleAndOffset.x + u_cylinderAngleUvScaleAndOffset.y; #endif @@ -1581,6 +1598,9 @@ void main() float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; + // gl_FragColor = vec4(positionUv, 1.0); return; + // gl_FragColor = vec4(transformFromUvToShapeSpace(positionUv).zzz, 1.0); return; + vec4 colorAccum = vec4(0.0); #if defined(DESPECKLE) From 285f3a6a23ee733c59bd853b3cf802de2e1a3388 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 15 Apr 2022 15:38:38 -0400 Subject: [PATCH 038/679] wedge artifact fixes for ellipsoid --- Source/Scene/VoxelCylinderShape.js | 34 ++++++----- Source/Scene/VoxelEllipsoidShape.js | 93 +++++++++++++++++++++-------- Source/Shaders/VoxelFS.glsl | 93 ++++++++++++++++++----------- 3 files changed, 145 insertions(+), 75 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index b1a3d577020..64582b30c22 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -123,6 +123,7 @@ function VoxelCylinderShape() { CYLINDER_WEDGE_INDEX: undefined, CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, + CYLINDER_WEDGE_FLAT: undefined, CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, }; @@ -165,6 +166,7 @@ VoxelCylinderShape.prototype.update = function ( const defaultMinAngle = VoxelCylinderShape.DefaultMinBounds.z; const defaultMaxAngle = VoxelCylinderShape.DefaultMaxBounds.z; const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; + const defaultHalfAngleWidth = 0.5 * defaultAngleWidth; // Clamp the radii to the valid range const minRadius = CesiumMath.clamp( @@ -196,7 +198,7 @@ VoxelCylinderShape.prototype.update = function ( const zeroScaleEpsilon = CesiumMath.EPSILON10; const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees - const wedgeDetectionEpsilon = CesiumMath.EPSILON10; + const wedgeEpsilon = CesiumMath.EPSILON10; // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. @@ -256,10 +258,13 @@ VoxelCylinderShape.prototype.update = function ( const isAngleFlipped = maxAngle < minAngle; const angleWidth = maxAngle - minAngle + isAngleFlipped * defaultAngleWidth; const hasWedgeRegular = - angleWidth >= CesiumMath.PI && - CesiumMath.lessThan(angleWidth, defaultAngleWidth, wedgeDetectionEpsilon); - const hasWedgeFlipped = angleWidth < CesiumMath.PI; - const hasWedge = hasWedgeRegular || hasWedgeFlipped; + angleWidth > defaultHalfAngleWidth + wedgeEpsilon && + angleWidth < defaultAngleWidth - wedgeEpsilon; + const hasWedgeFlipped = angleWidth < defaultHalfAngleWidth - wedgeEpsilon; + const hasWedgeFlat = + angleWidth >= defaultHalfAngleWidth - wedgeEpsilon && + angleWidth <= defaultHalfAngleWidth + wedgeEpsilon; + const hasWedge = hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat; const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( minAngle, @@ -380,10 +385,8 @@ VoxelCylinderShape.prototype.update = function ( // offset = -2.0 * (minHeight * 0.5 + 0.5) / (maxHeight - minHeight) // offset = -(minHeight + 1.0) / (maxHeight - minHeight) // offset = (minHeight + 1.0) / (minHeight - maxHeight) - const scale = 2.0 / (maxHeight - minHeight); const offset = (minHeight + 1.0) / (minHeight - maxHeight); - shaderUniforms.cylinderHeightUvScaleAndOffset = Cartesian2.fromElements( scale, offset, @@ -406,6 +409,16 @@ VoxelCylinderShape.prototype.update = function ( } else if (hasWedgeFlipped) { shaderDefines["CYLINDER_WEDGE_FLIPPED"] = true; intersectionCount += 2; + } else if (hasWedgeFlat) { + shaderDefines["CYLINDER_WEDGE_FLAT"] = true; + intersectionCount += 1; + } + + if (isMinAngleDiscontinuity) { + shaderDefines["CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; + } + if (isMaxAngleDiscontinuity) { + shaderDefines["CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; } shaderUniforms.cylinderAngleMinMax = Cartesian2.fromElements( @@ -445,13 +458,6 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_INTERSECTION_COUNT"] = intersectionCount; - if (isMinAngleDiscontinuity) { - shaderDefines["CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; - } - if (isMaxAngleDiscontinuity) { - shaderDefines["CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; - } - return true; }; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 2cbab24949a..e3f9abd145f 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -99,6 +99,8 @@ function VoxelEllipsoidShape() { ellipsoidInverseRadiiSquaredUv: new Cartesian3(), // Wedge uniforms ellipsoidMinLongitudeUv: 0.0, + ellipsoidMaxLongitudeUv: 0.0, + ellipsoidEmptyMidpointLongitudeUv: 0.0, ellipsoidLongitudeUvScaleAndOffset: new Cartesian2(), // Cone uniforms ellipsoidLatitudeUvScaleAndOffset: new Cartesian2(), @@ -117,10 +119,13 @@ function VoxelEllipsoidShape() { this.shaderDefines = { ELLIPSOID_INTERSECTION_COUNT: undefined, ELLIPSOID_WEDGE: undefined, + ELLIPSOID_WEDGE_INDEX: undefined, ELLIPSOID_WEDGE_REGULAR: undefined, ELLIPSOID_WEDGE_FLIPPED: undefined, - ELLIPSOID_WEDGE_INDEX: undefined, + ELLIPSOID_WEDGE_FLAT: undefined, ELLIPSOID_WEDGE_ANGLE_FLIPPED: undefined, + ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, + ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, ELLIPSOID_CONE_BOTTOM: undefined, ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, @@ -167,6 +172,7 @@ VoxelEllipsoidShape.prototype.update = function ( const defaultMinLongitude = VoxelEllipsoidShape.DefaultMinBounds.x; const defaultMaxLongitude = VoxelEllipsoidShape.DefaultMaxBounds.x; const defaultLongitudeLength = defaultMaxLongitude - defaultMinLongitude; + const defaultLongitudeHalfLength = 0.5 * defaultLongitudeLength; const defaultMinLatitude = VoxelEllipsoidShape.DefaultMinBounds.y; const defaultMaxLatitude = VoxelEllipsoidShape.DefaultMaxBounds.y; const defaultLatitudeLength = defaultMaxLatitude - defaultMinLatitude; @@ -212,15 +218,20 @@ VoxelEllipsoidShape.prototype.update = function ( ); const maxExtent = Cartesian3.maximumComponent(outerExtent); + const zeroScaleEpsilon = CesiumMath.EPSILON10; + const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const wedgeEpsilon = CesiumMath.EPSILON10; + const coneEpsilon = CesiumMath.EPSILON10; + const flatConeEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + // Exit early if the shape is not visible. // Note that west may be greater than east when crossing the 180th meridian. - const absEpsilon = CesiumMath.EPSILON10; if ( south > north || minHeight > maxHeight || - CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, absEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, absEpsilon) + CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, zeroScaleEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, zeroScaleEpsilon) || + CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, zeroScaleEpsilon) ) { return false; } @@ -295,28 +306,32 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidInverseRadiiSquaredUv ); - const isAngleFlipped = east < west; - const rectangleWidth = Rectangle.computeWidth(this._rectangle); const rectangleHeight = Rectangle.computeHeight(this._rectangle); const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); + const isAngleFlipped = east < west; + const angleWidth = east - west + isAngleFlipped * defaultLongitudeLength; const hasWedgeRegular = - rectangleWidth >= CesiumMath.PI && - CesiumMath.lessThan(rectangleWidth, CesiumMath.TWO_PI, absEpsilon); - const hasWedgeFlipped = rectangleWidth < CesiumMath.PI; - const hasWedge = hasWedgeRegular || hasWedgeFlipped; + angleWidth > defaultLongitudeHalfLength + wedgeEpsilon && + angleWidth < defaultLongitudeLength - wedgeEpsilon; + const hasWedgeFlipped = + angleWidth < defaultLongitudeHalfLength - wedgeEpsilon; + const hasWedgeFlat = + angleWidth >= defaultLongitudeHalfLength - wedgeEpsilon && + angleWidth <= defaultLongitudeHalfLength + wedgeEpsilon; + const hasWedge = hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat; - const flatConeEpsilon = CesiumMath.EPSILON4; // 0.0001 radians = 0.00573 degrees const hasTopConeRegular = - north > +flatConeEpsilon && north < defaultMaxLatitude; + north > +flatConeEpsilon && north < defaultMaxLatitude - coneEpsilon; const hasTopConeFlipped = north < -flatConeEpsilon; const hasTopConeFlat = north >= -flatConeEpsilon && north <= +flatConeEpsilon; const hasTopCone = hasTopConeRegular || hasTopConeFlipped || hasTopConeFlat; const hasBottomConeRegular = - south > defaultMinLatitude && south < -flatConeEpsilon; + south > defaultMinLatitude + coneEpsilon && south < -flatConeEpsilon; const hasBottomConeFlipped = south > +flatConeEpsilon; - const hasBottomConeFlat = south === 0.0; + const hasBottomConeFlat = + south >= -flatConeEpsilon && south <= +flatConeEpsilon; const hasBottomCone = hasBottomConeRegular || hasBottomConeFlipped || hasBottomConeFlat; @@ -334,6 +349,10 @@ VoxelEllipsoidShape.prototype.update = function ( if (hasInnerEllipsoid) { shaderDefines["ELLIPSOID_INNER"] = true; shaderDefines["ELLIPSOID_INNER_INDEX"] = intersectionCount; + if (minHeight === maxHeight) { + shaderDefines["ELLIPSOID_INNER_OUTER_EQUAL"] = true; + } + intersectionCount += 1; // The percent of space that is between the inner and outer ellipsoid. @@ -356,10 +375,6 @@ VoxelEllipsoidShape.prototype.update = function ( shaderDefines["ELLIPSOID_IS_SPHERE"] = true; } - if (minHeight === maxHeight) { - shaderDefines["ELLIPSOID_INNER_OUTER_EQUAL"] = true; - } - // Intersects a wedge for the min and max longitude. if (hasWedge) { shaderDefines["ELLIPSOID_WEDGE"] = true; @@ -371,7 +386,39 @@ VoxelEllipsoidShape.prototype.update = function ( } else if (hasWedgeFlipped) { shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = true; intersectionCount += 2; + } else if (hasWedgeFlat) { + shaderDefines["ELLIPSOID_WEDGE_FLAT"] = true; + intersectionCount += 1; + } + + const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( + west, + defaultMinLongitude, + undefined, + angleDiscontinuityEpsilon + ); + const isMaxAngleDiscontinuity = CesiumMath.equalsEpsilon( + east, + defaultMaxLongitude, + undefined, + angleDiscontinuityEpsilon + ); + + if (isMinAngleDiscontinuity) { + shaderDefines["ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; } + if (isMaxAngleDiscontinuity) { + shaderDefines["ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; + } + + const westUv = (west - defaultMinLongitude) / defaultLongitudeLength; + const eastUv = (east - defaultMinLongitude) / defaultLongitudeLength; + const emptyAngleWidthUv = 1.0 - angleWidth / defaultLongitudeLength; + + shaderUniforms.ellipsoidMinLongitudeUv = westUv; + shaderUniforms.ellipsoidMaxLongitudeUv = eastUv; + shaderUniforms.ellipsoidEmptyMidpointLongitudeUv = + (eastUv + 0.5 * emptyAngleWidthUv) % 1.0; // delerp(longitudeUv, minLongitudeUv, maxLongitudeUv) // (longitudeUv - minLongitudeUv) / (maxLongitudeUv - minLongitudeUv) @@ -382,12 +429,8 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = -minLongitudeUv / (maxLongitudeUv - minLongitudeUv) // offset = -((minLongitude - pi) / (2.0 * pi)) / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi))) // offset = -(minLongitude - pi) / (maxLongitude - minLongitude) - - const westUv = (west - defaultMinLongitude) / defaultLongitudeLength; - const scale = defaultLongitudeLength / rectangleWidth; - const offset = -(west - defaultMinLongitude) / rectangleWidth; - - shaderUniforms.ellipsoidMinLongitudeUv = westUv; + const scale = defaultLongitudeLength / angleWidth; + const offset = -(west - defaultMinLongitude) / angleWidth; shaderUniforms.ellipsoidLongitudeUvScaleAndOffset = Cartesian2.fromElements( scale, offset, diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 59327ad6cc7..a35d70983bb 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -218,6 +218,7 @@ uniform float u_stepSize; #define ELLIPSOID_WEDGE #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define ELLIPSOID_WEDGE_FLAT ### #define ELLIPSOID_WEDGE_INDEX ### #define ELLIPSOID_WEDGE_ANGLE_FLIPPED // #define ELLIPSOID_CONE_BOTTOM @@ -247,11 +248,18 @@ uniform float u_stepSize; uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. #endif #if defined(ELLIPSOID_WEDGE) - uniform vec2 u_ellipsoidLongitudeUvScaleAndOffset; - #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) + #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) || defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) || defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + uniform float u_ellipsoidEmptyMidpointLongitudeUv; + #endif + #if defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) uniform float u_ellipsoidMinLongitudeUv; #endif + #if defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + uniform float u_ellipsoidMaxLongitudeUv; + #endif + uniform vec2 u_ellipsoidLongitudeUvScaleAndOffset; #endif + #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) uniform vec2 u_ellipsoidLatitudeUvScaleAndOffset; #endif @@ -282,6 +290,7 @@ uniform float u_stepSize; #define CYLINDER_WEDGE_INDEX // #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals + #define CYLINDER_WEDGE_FLAT #define CYLINDER_WEDGE_ANGLE_FLIPPED // #define CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY #define CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY @@ -564,6 +573,36 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] } #endif +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLAT)) +vec2 intersectZPlane(Ray ray) +{ + float o = ray.pos.z; + float d = ray.dir.z; + float t = -o / d; + float s = sign(o); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} +#endif + +#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_WEDGE_FLAT))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_WEDGE_FLIPPED) || defined(CYLINDER_WEDGE_FLAT))) +vec2 intersectHalfSpace(Ray ray, float angle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n = vec2(sin(angle), -cos(angle)); + + float a = dot(o, n); + float b = dot(d, n); + float t = -a / b; + float s = sign(a); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} +#endif + #if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_REGULAR)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_REGULAR)) vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) { @@ -599,36 +638,6 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) } #endif -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) -vec2 intersectHalfSpace(Ray ray, float angle) -{ - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 n = vec2(sin(angle), -cos(angle)); - - float a = dot(o, n); - float b = dot(d, n); - float t = -a / b; - float s = sign(a); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLAT)) -vec2 intersectZPlane(Ray ray) -{ - float o = ray.pos.z; - float d = ray.dir.z; - float t = -o / d; - float s = sign(o); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - #if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) { @@ -1042,6 +1051,9 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { vec4 wedgeIntersect = intersectFlippedWedge(ray, west, east); setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 0, wedgeIntersect.xy); setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 1, wedgeIntersect.zw); + #elif defined(ELLIPSOID_WEDGE_FLAT) + vec2 wedgeIntersect = intersectHalfSpace(ray, west); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX, wedgeIntersect); #endif #endif } @@ -1065,8 +1077,17 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; #if defined(ELLIPSOID_WEDGE) #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) - longitude += float(longitude <= u_ellipsoidMinLongitudeUv); + // Comparing against u_ellipsoidMinAngleUv has precision problems. u_ellipsoidEmptyMidpointAngleUv is more conservative. + longitude += float(longitude < u_ellipsoidEmptyMidpointAngleUv); #endif + + // When the min or max angle is near the -pi/+pi discontinuity there may be flickering as both sides of the voxel data are read. + #if defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) + longitude = longitude > u_ellipsoidEmptyMidpointLongitudeUv ? u_ellipsoidMinLongitudeUv : longitude; + #elif defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) + longitude = longitude < u_ellipsoidEmptyMidpointLongitudeUv ? u_ellipsoidMaxLongitudeUv : longitude; + #endif + longitude = longitude * u_ellipsoidLongitudeUvScaleAndOffset.x + u_ellipsoidLongitudeUvScaleAndOffset.y; #endif @@ -1164,6 +1185,9 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) vec4 wedgeIntersect = intersectFlippedWedge(outerRay, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); + #elif defined(CYLINDER_WEDGE_FLAT) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); #endif } #endif @@ -1598,9 +1622,6 @@ void main() float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - // gl_FragColor = vec4(positionUv, 1.0); return; - // gl_FragColor = vec4(transformFromUvToShapeSpace(positionUv).zzz, 1.0); return; - vec4 colorAccum = vec4(0.0); #if defined(DESPECKLE) From b8ae8fb27afe8d7654f0b89927bcb35f00e8f741 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Fri, 15 Apr 2022 16:45:48 -0400 Subject: [PATCH 039/679] fixed empty wedge for cylinder and ellipsoid --- Source/Scene/VoxelCylinderShape.js | 16 +++++---- Source/Scene/VoxelEllipsoidShape.js | 11 +++++-- Source/Shaders/VoxelFS.glsl | 51 +++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 64582b30c22..df561591a43 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -124,6 +124,7 @@ function VoxelCylinderShape() { CYLINDER_WEDGE_REGULAR: undefined, CYLINDER_WEDGE_FLIPPED: undefined, CYLINDER_WEDGE_FLAT: undefined, + CYLINDER_WEDGE_EMPTY: undefined, CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, }; @@ -260,11 +261,15 @@ VoxelCylinderShape.prototype.update = function ( const hasWedgeRegular = angleWidth > defaultHalfAngleWidth + wedgeEpsilon && angleWidth < defaultAngleWidth - wedgeEpsilon; - const hasWedgeFlipped = angleWidth < defaultHalfAngleWidth - wedgeEpsilon; + const hasWedgeFlipped = + angleWidth > wedgeEpsilon && + angleWidth < defaultHalfAngleWidth - wedgeEpsilon; const hasWedgeFlat = angleWidth >= defaultHalfAngleWidth - wedgeEpsilon && angleWidth <= defaultHalfAngleWidth + wedgeEpsilon; - const hasWedge = hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat; + const hasWedgeEmpty = angleWidth <= wedgeEpsilon; + const hasWedge = + hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat || hasWedgeEmpty; const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( minAngle, @@ -356,10 +361,8 @@ VoxelCylinderShape.prototype.update = function ( // scale = 1.0 / (maxRadius - minRadius) // offset = -minRadius / (maxRadius - minRadius) // offset = minRadius / (minRadius - maxRadius) - const scale = 1.0 / (maxRadius - minRadius); const offset = minRadius / (minRadius - maxRadius); - shaderUniforms.cylinderRadiusUvScaleAndOffset = Cartesian2.fromElements( scale, offset, @@ -412,6 +415,9 @@ VoxelCylinderShape.prototype.update = function ( } else if (hasWedgeFlat) { shaderDefines["CYLINDER_WEDGE_FLAT"] = true; intersectionCount += 1; + } else if (hasWedgeEmpty) { + shaderDefines["CYLINDER_WEDGE_EMPTY"] = true; + intersectionCount += 2; } if (isMinAngleDiscontinuity) { @@ -445,10 +451,8 @@ VoxelCylinderShape.prototype.update = function ( // offset = -minAngleUv / (maxAngleUv - minAngleUv) // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // offset = -(minAngle - pi) / (maxAngle - minAngle) - const scale = defaultAngleWidth / angleWidth; const offset = -(minAngle - defaultMinAngle) / angleWidth; - shaderUniforms.cylinderAngleUvScaleAndOffset = Cartesian2.fromElements( scale, offset, diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index e3f9abd145f..03d1a847c98 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -123,6 +123,7 @@ function VoxelEllipsoidShape() { ELLIPSOID_WEDGE_REGULAR: undefined, ELLIPSOID_WEDGE_FLIPPED: undefined, ELLIPSOID_WEDGE_FLAT: undefined, + ELLIPSOID_WEDGE_EMPTY: undefined, ELLIPSOID_WEDGE_ANGLE_FLIPPED: undefined, ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, @@ -315,11 +316,14 @@ VoxelEllipsoidShape.prototype.update = function ( angleWidth > defaultLongitudeHalfLength + wedgeEpsilon && angleWidth < defaultLongitudeLength - wedgeEpsilon; const hasWedgeFlipped = + angleWidth > wedgeEpsilon && angleWidth < defaultLongitudeHalfLength - wedgeEpsilon; const hasWedgeFlat = angleWidth >= defaultLongitudeHalfLength - wedgeEpsilon && angleWidth <= defaultLongitudeHalfLength + wedgeEpsilon; - const hasWedge = hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat; + const hasWedgeEmpty = angleWidth <= wedgeEpsilon; + const hasWedge = + hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat || hasWedgeEmpty; const hasTopConeRegular = north > +flatConeEpsilon && north < defaultMaxLatitude - coneEpsilon; @@ -389,6 +393,9 @@ VoxelEllipsoidShape.prototype.update = function ( } else if (hasWedgeFlat) { shaderDefines["ELLIPSOID_WEDGE_FLAT"] = true; intersectionCount += 1; + } else if (hasWedgeEmpty) { + shaderDefines["ELLIPSOID_WEDGE_EMPTY"] = true; + intersectionCount += 2; } const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( @@ -452,10 +459,8 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = -minLatitudeUv / (maxLatitudeUv - minLatitudeUv) // offset = -((minLatitude - pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) // offset = -(minLatitude - pi) / (maxLatitude - minLatitude) - const scale = defaultLatitudeLength / rectangleHeight; const offset = -(south - defaultMinLatitude) / rectangleHeight; - shaderUniforms.ellipsoidLatitudeUvScaleAndOffset = Cartesian2.fromElements( scale, offset, diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index a35d70983bb..60243c57f9b 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -216,10 +216,11 @@ uniform float u_stepSize; /* Ellipsoid defines: #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections #define ELLIPSOID_WEDGE + #define ELLIPSOID_WEDGE_INDEX ### #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define ELLIPSOID_WEDGE_FLAT ### - #define ELLIPSOID_WEDGE_INDEX ### + #define ELLIPSOID_WEDGE_EMPTY #define ELLIPSOID_WEDGE_ANGLE_FLIPPED // #define ELLIPSOID_CONE_BOTTOM #define ELLIPSOID_CONE_BOTTOM_REGULAR // when there's a bottom cone @@ -291,6 +292,7 @@ uniform float u_stepSize; #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals #define CYLINDER_WEDGE_FLAT + #define CYLINDER_WEDGE_EMPTY #define CYLINDER_WEDGE_ANGLE_FLIPPED // #define CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY #define CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY @@ -586,6 +588,25 @@ vec2 intersectZPlane(Ray ray) } #endif +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_EMPTY)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_EMPTY)) +vec4 intersectHalfPlane(Ray ray, float angle) { + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 planeDirection = vec2(cos(angle), sin(angle)); + vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); + + float a = dot(o, planeNormal); + float b = dot(d, planeNormal); + float t = -a / b; + + vec2 p = o + t * d; + bool outside = dot(p, planeDirection) < 0.0; + if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + + return vec4(-INF_HIT, t, t, +INF_HIT); +} +#endif + #if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_WEDGE_FLAT))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_WEDGE_FLIPPED) || defined(CYLINDER_WEDGE_FLAT))) vec2 intersectHalfSpace(Ray ray, float angle) { @@ -1054,6 +1075,10 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { #elif defined(ELLIPSOID_WEDGE_FLAT) vec2 wedgeIntersect = intersectHalfSpace(ray, west); setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX, wedgeIntersect); + #elif defined(ELLIPSOID_WEDGE_EMPTY) + vec4 wedgeIntersect = intersectHalfPlane(ray, west); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 1, wedgeIntersect.zw); #endif #endif } @@ -1078,7 +1103,7 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { #if defined(ELLIPSOID_WEDGE) #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) // Comparing against u_ellipsoidMinAngleUv has precision problems. u_ellipsoidEmptyMidpointAngleUv is more conservative. - longitude += float(longitude < u_ellipsoidEmptyMidpointAngleUv); + longitude += float(longitude < u_ellipsoidEmptyMidpointLongitudeUv); #endif // When the min or max angle is near the -pi/+pi discontinuity there may be flickering as both sides of the voxel data are read. @@ -1131,17 +1156,19 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { void intersectCylinderShape(Ray ray, inout Intersections ix) { #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) - Ray outerRay = Ray(ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds, ray.dir * u_cylinderScaleUvToBounds); + ray.pos = ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds; + ray.dir *= u_cylinderScaleUvToBounds; #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. - Ray outerRay = Ray(ray.pos * 2.0 - 1.0, ray.dir * 2.0); + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; #endif #if defined(CYLINDER_HEIGHT_ZERO) - vec2 outerIntersect = intersectUnitCircle(outerRay); + vec2 outerIntersect = intersectUnitCircle(ray); #else - vec2 outerIntersect = intersectUnitCylinder(outerRay); + vec2 outerIntersect = intersectUnitCylinder(ray); #endif setIntersectionPair(ix, CYLINDER_OUTER_INDEX, outerIntersect); @@ -1167,27 +1194,31 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) // Note: If initializeIntersections() changes its sorting function // from bubble sort to something else, this code may need to change. - vec2 innerIntersect = intersectInfiniteUnitCylinder(outerRay); + vec2 innerIntersect = intersectInfiniteUnitCylinder(ray); setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit #elif defined(CYLINDER_INNER) - Ray innerRay = Ray(outerRay.pos * u_cylinderInverseInnerRadiusUv, outerRay.dir * u_cylinderInverseInnerRadiusUv); + Ray innerRay = Ray(ray.pos * u_cylinderInverseInnerRadiusUv, ray.dir * u_cylinderInverseInnerRadiusUv); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); #endif #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectRegularWedge(outerRay, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); + vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); #elif defined(CYLINDER_WEDGE_FLIPPED) - vec4 wedgeIntersect = intersectFlippedWedge(outerRay, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); #elif defined(CYLINDER_WEDGE_FLAT) vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderAngleMinMax.x); setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); + #elif defined(CYLINDER_WEDGE_EMPTY) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); #endif } #endif From 7b9cfffe621ab3427d519adf1e5fff9141938d90 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 21 Apr 2022 13:40:44 -0400 Subject: [PATCH 040/679] shape space clipping --- Source/Scene/VoxelBoxShape.js | 200 +++-- Source/Scene/VoxelCylinderShape.js | 445 ++++++---- Source/Scene/VoxelEllipsoidShape.js | 794 ++++++++++++------ Source/Scene/VoxelPrimitive.js | 214 ++--- Source/Scene/VoxelShape.js | 9 + Source/Shaders/VoxelFS.glsl | 586 +++++++------ .../VoxelInspector/VoxelInspectorViewModel.js | 3 +- 7 files changed, 1310 insertions(+), 941 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index 301524456b1..782caeb50c7 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -75,11 +75,11 @@ function VoxelBoxShape() { * @readonly */ this.shaderUniforms = { - boxScaleUvToBounds: new Cartesian3(), - boxOffsetUvToBounds: new Cartesian3(), - boxTransformUvToBounds: new Matrix4(), - boxScaleUvToBoundsUv: new Cartesian3(), - boxOffsetUvToBoundsUv: new Cartesian3(), + boxTransformUvToRenderBounds: new Matrix4(), + boxScaleUvToRenderBounds: new Cartesian3(), + boxOffsetUvToRenderBounds: new Cartesian3(), + boxScaleUvToShapeBoundsUv: new Cartesian3(), + boxOffsetUvToShapeBoundsUv: new Cartesian3(), }; /** @@ -87,11 +87,18 @@ function VoxelBoxShape() { * @readonly */ this.shaderDefines = { - BOX_INTERSECTION_COUNT: undefined, BOX_INTERSECTION_INDEX: undefined, - BOX_IS_BOUNDED: undefined, - BOX_IS_RECTANGLE: undefined, + BOX_HAS_RENDER_BOUND: undefined, + BOX_HAS_SHAPE_BOUND: undefined, + BOX_IS_2D: undefined, }; + + /** + * The maximum number of intersections against the shape for any ray direction. + * @type {Number} + * @readonly + */ + this.shaderMaximumIntersectionsLength = undefined; } const scratchTranslation = new Cartesian3(); @@ -100,6 +107,10 @@ const scratchRotation = new Matrix3(); const scratchTransformLocalToBounds = new Matrix4(); const scratchBoundsTranslation = new Cartesian3(); const scratchBoundsScale = new Cartesian3(); +const scratchClipMinBounds = new Cartesian3(); +const scratchClipMaxBounds = new Cartesian3(); +const scratchRenderMinBounds = new Cartesian3(); +const scratchRenderMaxBounds = new Cartesian3(); const transformUvToLocal = Matrix4.fromRotationTranslation( Matrix3.fromUniformScale(2.0, new Matrix3()), @@ -129,13 +140,23 @@ const transformXYZToXZY = Matrix4.fromRotation( * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @param {Cartesian3} clipMinBounds The minimum clip bounds. + * @param {Cartesian3} clipMaxBounds The maximum clip bounds. * @returns {Boolean} Whether the shape is visible. */ -VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { +VoxelBoxShape.prototype.update = function ( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds +) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); + Check.typeOf.object("clipMinBounds", clipMinBounds); + Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; @@ -155,19 +176,55 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { this._maxBounds ); + clipMinBounds = Cartesian3.clamp( + clipMinBounds, + defaultMinBounds, + defaultMaxBounds, + scratchClipMinBounds + ); + + clipMaxBounds = Cartesian3.clamp( + clipMaxBounds, + defaultMinBounds, + defaultMaxBounds, + scratchClipMaxBounds + ); + + const renderMinBounds = Cartesian3.clamp( + minBounds, + clipMinBounds, + clipMaxBounds, + scratchRenderMinBounds + ); + + const renderMaxBounds = Cartesian3.clamp( + maxBounds, + clipMinBounds, + clipMaxBounds, + scratchRenderMaxBounds + ); + const scale = Matrix4.getScale(modelMatrix, scratchScale); // Box is not visible if: // - any of the min bounds exceed the max bounds // - two or more of the min bounds equal the max bounds (line / point) + // - same as above, but for clip bounds // - scale is 0 for any component (too annoying to reconstruct rotation matrix) if ( - minBounds.x > maxBounds.x || - minBounds.y > maxBounds.y || - minBounds.z > maxBounds.z || - (minBounds.x === maxBounds.x) + - (minBounds.y === maxBounds.y) + - (minBounds.z === maxBounds.z) >= + renderMinBounds.x > renderMaxBounds.x || + renderMinBounds.y > renderMaxBounds.y || + renderMinBounds.z > renderMaxBounds.z || + (renderMinBounds.x === renderMaxBounds.x) + + (renderMinBounds.y === renderMaxBounds.y) + + (renderMinBounds.z === renderMaxBounds.z) >= + 2 || + clipMinBounds.x > clipMaxBounds.x || + clipMinBounds.y > clipMaxBounds.y || + clipMinBounds.z > clipMaxBounds.z || + (clipMinBounds.x === clipMaxBounds.x) + + (clipMinBounds.y === clipMaxBounds.y) + + (clipMinBounds.z === clipMaxBounds.z) >= 2 || scale.x === 0.0 || scale.y === 0.0 || @@ -179,8 +236,8 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); this.orientedBoundingBox = getBoxChunkObb( - this._minBounds, - this._maxBounds, + renderMinBounds, + renderMaxBounds, this.shapeTransform, this.orientedBoundingBox ); @@ -208,60 +265,69 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { } } - // Never changes - shaderDefines["BOX_INTERSECTION_COUNT"] = 1; - shaderDefines["BOX_INTERSECTION_INDEX"] = 0; + const hasRenderBound = + renderMinBounds.x !== defaultMinBounds.x || + renderMaxBounds.x !== defaultMaxBounds.x || + renderMinBounds.y !== defaultMinBounds.y || + renderMaxBounds.y !== defaultMaxBounds.y || + renderMinBounds.z !== defaultMinBounds.z || + renderMaxBounds.z !== defaultMaxBounds.z; - if ( + const hasShapeBound = minBounds.x !== defaultMinBounds.x || - minBounds.y !== defaultMinBounds.y || - minBounds.z !== defaultMinBounds.z || maxBounds.x !== defaultMaxBounds.x || + minBounds.y !== defaultMinBounds.y || maxBounds.y !== defaultMaxBounds.y || - maxBounds.z !== defaultMaxBounds.z - ) { - shaderDefines["BOX_IS_BOUNDED"] = true; + minBounds.z !== defaultMinBounds.z || + maxBounds.z !== defaultMaxBounds.z; + + let intersectionCount = 0; + + shaderDefines["BOX_INTERSECTION_INDEX"] = intersectionCount; + intersectionCount += 1; + + if (hasRenderBound) { + shaderDefines["BOX_HAS_RENDER_BOUND"] = true; + + const min = renderMinBounds; + const max = renderMaxBounds; // inverse(scale) // inverse(maxBoundsUv - minBoundsUv) // inverse((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) // inverse(0.5 * (maxBounds - minBounds)) // 2.0 / (maxBounds - minBounds) // with divide by zero protection - const boundsScaleLocalToBounds = Cartesian3.fromElements( - 2.0 / (minBounds.x === maxBounds.x ? 1.0 : maxBounds.x - minBounds.x), - 2.0 / (minBounds.y === maxBounds.y ? 1.0 : maxBounds.y - minBounds.y), - 2.0 / (minBounds.z === maxBounds.z ? 1.0 : maxBounds.z - minBounds.z), + const scaleLocalToBounds = Cartesian3.fromElements( + 2.0 / (min.x === max.x ? 1.0 : max.x - min.x), + 2.0 / (min.y === max.y ? 1.0 : max.y - min.y), + 2.0 / (min.z === max.z ? 1.0 : max.z - min.z), scratchBoundsScale ); // -inverse(scale) * translation // affine inverse // -inverse(scale) * 0.5 * (minBounds + maxBounds) - const boundsTranslateLocalToBounds = Cartesian3.fromElements( - -boundsScaleLocalToBounds.x * 0.5 * (minBounds.x + maxBounds.x), - -boundsScaleLocalToBounds.y * 0.5 * (minBounds.y + maxBounds.y), - -boundsScaleLocalToBounds.z * 0.5 * (minBounds.z + maxBounds.z), + const translateLocalToBounds = Cartesian3.fromElements( + -scaleLocalToBounds.x * 0.5 * (min.x + max.x), + -scaleLocalToBounds.y * 0.5 * (min.y + max.y), + -scaleLocalToBounds.z * 0.5 * (min.z + max.z), scratchBoundsTranslation ); let transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(boundsScaleLocalToBounds), - boundsTranslateLocalToBounds, + Matrix3.fromScale(scaleLocalToBounds), + translateLocalToBounds, scratchTransformLocalToBounds ); - if ( - minBounds.x === maxBounds.x || - minBounds.y === maxBounds.y || - minBounds.z === maxBounds.z - ) { - shaderDefines["BOX_IS_RECTANGLE"] = true; + if (min.x === max.x || min.y === max.y || min.z === max.z) { + shaderDefines["BOX_IS_2D"] = true; let transformAxisConversion; - if (minBounds.x === maxBounds.x) { + if (min.x === max.x) { transformAxisConversion = transformXYZToZYX; - } else if (minBounds.y === maxBounds.y) { + } else if (min.y === max.y) { transformAxisConversion = transformXYZToXZY; - } else if (minBounds.z === maxBounds.z) { + } else if (min.z === max.z) { transformAxisConversion = Matrix4.IDENTITY; } transformLocalToBounds = Matrix4.multiply( @@ -271,19 +337,26 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { ); } - shaderUniforms.boxTransformUvToBounds = Matrix4.multiplyTransformation( + shaderUniforms.boxTransformUvToRenderBounds = Matrix4.multiplyTransformation( transformLocalToBounds, transformUvToLocal, - shaderUniforms.boxTransformUvToBounds + shaderUniforms.boxTransformUvToRenderBounds ); - shaderUniforms.boxScaleUvToBounds = Matrix4.getScale( - shaderUniforms.boxTransformUvToBounds, - shaderUniforms.boxScaleUvToBounds + shaderUniforms.boxScaleUvToRenderBounds = Matrix4.getScale( + shaderUniforms.boxTransformUvToRenderBounds, + shaderUniforms.boxScaleUvToRenderBounds ); - shaderUniforms.boxOffsetUvToBounds = Matrix4.getTranslation( - shaderUniforms.boxTransformUvToBounds, - shaderUniforms.boxOffsetUvToBounds + shaderUniforms.boxOffsetUvToRenderBounds = Matrix4.getTranslation( + shaderUniforms.boxTransformUvToRenderBounds, + shaderUniforms.boxOffsetUvToRenderBounds ); + } + + if (hasShapeBound) { + shaderDefines["BOX_HAS_SHAPE_BOUND"] = true; + + const min = minBounds; + const max = maxBounds; // Go from UV space to bounded UV space: // delerp(posUv, minBoundsUv, maxBoundsUv) @@ -295,18 +368,23 @@ VoxelBoxShape.prototype.update = function (modelMatrix, minBounds, maxBounds) { // offset = -minBoundsUv / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) // offset = -2.0 * (minBounds * 0.5 + 0.5) / (maxBounds - minBounds) // offset = -scale * (minBounds * 0.5 + 0.5) - shaderUniforms.boxScaleUvToBoundsUv = Cartesian3.clone( - boundsScaleLocalToBounds, - shaderUniforms.boxScaleUvToBoundsUv + shaderUniforms.boxScaleUvToShapeBoundsUv = Cartesian3.fromElements( + 2.0 / (min.x === max.x ? 1.0 : max.x - min.x), + 2.0 / (min.y === max.y ? 1.0 : max.y - min.y), + 2.0 / (min.z === max.z ? 1.0 : max.z - min.z), + shaderUniforms.boxScaleUvToShapeBoundsUv ); - shaderUniforms.boxOffsetUvToBoundsUv = Cartesian3.fromElements( - -boundsScaleLocalToBounds.x * (minBounds.x * 0.5 + 0.5), - -boundsScaleLocalToBounds.y * (minBounds.y * 0.5 + 0.5), - -boundsScaleLocalToBounds.z * (minBounds.z * 0.5 + 0.5), - shaderUniforms.boxOffsetUvToBoundsUv + + shaderUniforms.boxOffsetUvToShapeBoundsUv = Cartesian3.fromElements( + -shaderUniforms.boxScaleUvToShapeBoundsUv.x * (min.x * 0.5 + 0.5), + -shaderUniforms.boxScaleUvToShapeBoundsUv.y * (min.y * 0.5 + 0.5), + -shaderUniforms.boxScaleUvToShapeBoundsUv.z * (min.z * 0.5 + 0.5), + shaderUniforms.boxOffsetUvToShapeBoundsUv ); } + this.shaderMaximumIntersectionsLength = intersectionCount; + return true; }; diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index df561591a43..6cf44efe5ba 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -94,16 +94,15 @@ function VoxelCylinderShape() { * @readonly */ this.shaderUniforms = { - cylinderScaleUvToBounds: new Cartesian3(), - cylinderTranslateUvToBounds: new Cartesian3(), - cylinderInverseInnerRadiusUv: 0.0, - cylinderAngleMinMax: new Cartesian2(), - cylinderRadiusUvScaleAndOffset: new Cartesian2(), - cylinderHeightUvScaleAndOffset: new Cartesian2(), - cylinderAngleUvScaleAndOffset: new Cartesian2(), - cylinderMinAngleUv: 0.0, - cylinderMaxAngleUv: 0.0, - cylinderEmptyMidpointAngleUv: 0.0, + cylinderUvToRenderBoundsScale: new Cartesian3(), + cylinderUvToRenderBoundsTranslate: new Cartesian3(), + cylinderUvToRenderRadiusMin: 0.0, + cylinderRenderAngleMinMax: new Cartesian2(), + cylinderUvToShapeUvRadius: new Cartesian2(), + cylinderUvToShapeUvHeight: new Cartesian2(), + cylinderUvToShapeUvAngle: new Cartesian2(), + cylinderShapeUvAngleMinMax: new Cartesian2(), + cylinderShapeUvAngleEmptyMid: 0.0, }; /** @@ -111,23 +110,38 @@ function VoxelCylinderShape() { * @readonly */ this.shaderDefines = { - CYLINDER_INTERSECTION_COUNT: undefined, - CYLINDER_OUTER_INDEX: undefined, - CYLINDER_OUTER_NON_DEFAULT: undefined, - CYLINDER_INNER: undefined, - CYLINDER_INNER_OUTER_EQUAL: undefined, - CYLINDER_INNER_INDEX: undefined, - CYLINDER_HEIGHT_NON_DEFAULT: undefined, - CYLINDER_HEIGHT_ZERO: undefined, - CYLINDER_WEDGE_ANGLE_FLIPPED: undefined, - CYLINDER_WEDGE_INDEX: undefined, - CYLINDER_WEDGE_REGULAR: undefined, - CYLINDER_WEDGE_FLIPPED: undefined, - CYLINDER_WEDGE_FLAT: undefined, - CYLINDER_WEDGE_EMPTY: undefined, - CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, - CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, + CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN: undefined, + CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX: undefined, + CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT: undefined, + CYLINDER_HAS_RENDER_BOUNDS_HEIGHT: undefined, + CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO: undefined, + + CYLINDER_HAS_SHAPE_BOUNDS_RADIUS: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED: undefined, + + CYLINDER_INTERSECTION_INDEX_RADIUS_MAX: undefined, + CYLINDER_INTERSECTION_INDEX_RADIUS_MIN: undefined, + CYLINDER_INTERSECTION_INDEX_ANGLE: undefined, }; + + /** + * The maximum number of intersections against the shape for any ray direction. + * @type {Number} + * @readonly + */ + this.shaderMaximumIntersectionsLength = 0; // not known until update } const scratchScale = new Cartesian3(); @@ -147,16 +161,22 @@ const transformUvToLocal = Matrix4.fromRotationTranslation( * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @param {Cartesian3} clipMinBounds The minimum clip bounds. + * @param {Cartesian3} clipMaxBounds The maximum clip bounds. */ VoxelCylinderShape.prototype.update = function ( modelMatrix, minBounds, - maxBounds + maxBounds, + clipMinBounds, + clipMaxBounds ) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); + Check.typeOf.object("clipMinBounds", clipMinBounds); + Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); const scale = Matrix4.getScale(modelMatrix, scratchScale); @@ -169,37 +189,65 @@ VoxelCylinderShape.prototype.update = function ( const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; const defaultHalfAngleWidth = 0.5 * defaultAngleWidth; + const zeroScaleEpsilon = CesiumMath.EPSILON10; + const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const angleEpsilon = CesiumMath.EPSILON10; + // Clamp the radii to the valid range - const minRadius = CesiumMath.clamp( + const shapeMinRadius = CesiumMath.clamp( minBounds.x, defaultMinRadius, defaultMaxRadius ); - const maxRadius = CesiumMath.clamp( + const shapeMaxRadius = CesiumMath.clamp( maxBounds.x, defaultMinRadius, defaultMaxRadius ); + const clipMinRadius = CesiumMath.clamp( + clipMinBounds.x, + defaultMinRadius, + defaultMaxRadius + ); + const clipMaxRadius = CesiumMath.clamp( + clipMaxBounds.x, + defaultMinRadius, + defaultMaxRadius + ); + const renderMinRadius = Math.max(shapeMinRadius, clipMinRadius); + const renderMaxRadius = Math.min(shapeMaxRadius, clipMaxRadius); // Clamp the heights to the valid range - const minHeight = CesiumMath.clamp( + const shapeMinHeight = CesiumMath.clamp( minBounds.y, defaultMinHeight, defaultMaxHeight ); - const maxHeight = CesiumMath.clamp( + const shapeMaxHeight = CesiumMath.clamp( maxBounds.y, defaultMinHeight, defaultMaxHeight ); + const clipMinHeight = CesiumMath.clamp( + clipMinBounds.y, + defaultMinHeight, + defaultMaxHeight + ); + const clipMaxHeight = CesiumMath.clamp( + clipMaxBounds.y, + defaultMinHeight, + defaultMaxHeight + ); + const renderMinHeight = Math.max(shapeMinHeight, clipMinHeight); + const renderMaxHeight = Math.min(shapeMaxHeight, clipMaxHeight); // Clamp the angles to the valid range - const minAngle = CesiumMath.negativePiToPi(minBounds.z); - const maxAngle = CesiumMath.negativePiToPi(maxBounds.z); - - const zeroScaleEpsilon = CesiumMath.EPSILON10; - const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees - const wedgeEpsilon = CesiumMath.EPSILON10; + const shapeMinAngle = CesiumMath.negativePiToPi(minBounds.z); + const shapeMaxAngle = CesiumMath.negativePiToPi(maxBounds.z); + const clipMinAngle = CesiumMath.negativePiToPi(clipMinBounds.z); + const clipMaxAngle = CesiumMath.negativePiToPi(clipMaxBounds.z); + const renderMinAngle = Math.max(shapeMinAngle, clipMinAngle); + const renderMaxAngle = Math.min(shapeMaxAngle, clipMaxAngle); // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. @@ -210,9 +258,9 @@ VoxelCylinderShape.prototype.update = function ( // - scale is 0 for any component (too annoying to reconstruct rotation matrix) if ( - maxRadius === 0.0 || - minRadius > maxRadius || - minHeight > maxHeight || + renderMaxRadius === 0.0 || + renderMinRadius > renderMaxRadius || + renderMinHeight > renderMaxHeight || CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, zeroScaleEpsilon) || CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, zeroScaleEpsilon) || CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, zeroScaleEpsilon) @@ -220,22 +268,22 @@ VoxelCylinderShape.prototype.update = function ( return false; } - this._minimumRadius = minRadius; // [0,1] - this._maximumRadius = maxRadius; // [0,1] - this._minimumHeight = minHeight; // [-1,+1] - this._maximumHeight = maxHeight; // [-1,+1] - this._minimumAngle = minAngle; // [-halfPi,+halfPi] - this._maximumAngle = maxAngle; // [-halfPi,+halfPi] + this._minimumRadius = shapeMinRadius; // [0,1] + this._maximumRadius = shapeMaxRadius; // [0,1] + this._minimumHeight = shapeMinHeight; // [-1,+1] + this._maximumHeight = shapeMaxHeight; // [-1,+1] + this._minimumAngle = shapeMinAngle; // [-halfPi,+halfPi] + this._maximumAngle = shapeMaxAngle; // [-halfPi,+halfPi] this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); this.orientedBoundingBox = getCylinderChunkObb( - minRadius, - maxRadius, - minHeight, - maxHeight, - minAngle, - maxAngle, + renderMinRadius, + renderMaxRadius, + renderMinHeight, + renderMaxHeight, + renderMinAngle, + renderMaxAngle, this.shapeTransform, this.orientedBoundingBox ); @@ -251,39 +299,68 @@ VoxelCylinderShape.prototype.update = function ( this.boundingSphere ); - const isDefaultOuterCylinder = maxRadius === defaultMaxRadius; - const hasInnerCylinder = minRadius > defaultMinRadius; - const isDefaultHeight = - minHeight === defaultMinHeight && maxHeight === defaultMaxHeight; - - const isAngleFlipped = maxAngle < minAngle; - const angleWidth = maxAngle - minAngle + isAngleFlipped * defaultAngleWidth; - const hasWedgeRegular = - angleWidth > defaultHalfAngleWidth + wedgeEpsilon && - angleWidth < defaultAngleWidth - wedgeEpsilon; - const hasWedgeFlipped = - angleWidth > wedgeEpsilon && - angleWidth < defaultHalfAngleWidth - wedgeEpsilon; - const hasWedgeFlat = - angleWidth >= defaultHalfAngleWidth - wedgeEpsilon && - angleWidth <= defaultHalfAngleWidth + wedgeEpsilon; - const hasWedgeEmpty = angleWidth <= wedgeEpsilon; - const hasWedge = - hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat || hasWedgeEmpty; - - const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( - minAngle, + const isDefaultMaxRadiusShape = shapeMaxRadius === defaultMaxRadius; + const isDefaultMinRadiusShape = shapeMinRadius === defaultMinRadius; + const isDefaultRadiusShape = + isDefaultMinRadiusShape && isDefaultMaxRadiusShape; + const isDefaultMaxRadiusRender = renderMaxRadius === defaultMaxRadius; + const isDefaultMinRadiusRender = renderMinRadius === defaultMinRadius; + const isDefaultHeightShape = + shapeMinHeight === defaultMinHeight && shapeMaxHeight === defaultMaxHeight; + const isDefaultHeightRender = + renderMinHeight === defaultMinHeight && + renderMaxHeight === defaultMaxHeight; + + const isAngleReversedShape = shapeMaxAngle < shapeMinAngle; + const shapeAngleWidth = + shapeMaxAngle - shapeMinAngle + isAngleReversedShape * defaultAngleWidth; + const hasAngleRegularShape = + shapeAngleWidth > defaultHalfAngleWidth + angleEpsilon && + shapeAngleWidth < defaultAngleWidth - angleEpsilon; + const hasAngleFlippedShape = + shapeAngleWidth > angleEpsilon && + shapeAngleWidth < defaultHalfAngleWidth - angleEpsilon; + const hasAngleFlatShape = + shapeAngleWidth >= defaultHalfAngleWidth - angleEpsilon && + shapeAngleWidth <= defaultHalfAngleWidth + angleEpsilon; + const hasAngleEmptyShape = shapeAngleWidth <= angleEpsilon; + const hasAngleShape = + hasAngleRegularShape || + hasAngleFlippedShape || + hasAngleFlatShape || + hasAngleEmptyShape; + const hasAngleMinDiscontinuityShape = CesiumMath.equalsEpsilon( + shapeMinAngle, defaultMinAngle, undefined, angleDiscontinuityEpsilon ); - const isMaxAngleDiscontinuity = CesiumMath.equalsEpsilon( - maxAngle, + const hasAngleMaxDiscontinuityShape = CesiumMath.equalsEpsilon( + shapeMaxAngle, defaultMaxAngle, undefined, angleDiscontinuityEpsilon ); + const isAngleReversedRender = renderMaxAngle < renderMinAngle; + const renderAngleWidth = + renderMaxAngle - renderMinAngle + isAngleReversedRender * defaultAngleWidth; + const hasAngleRegularRender = + renderAngleWidth > defaultHalfAngleWidth + angleEpsilon && + renderAngleWidth < defaultAngleWidth - angleEpsilon; + const hasAngleFlippedRender = + renderAngleWidth > angleEpsilon && + renderAngleWidth < defaultHalfAngleWidth - angleEpsilon; + const hasAngleFlatRender = + renderAngleWidth >= defaultHalfAngleWidth - angleEpsilon && + renderAngleWidth <= defaultHalfAngleWidth + angleEpsilon; + const hasAngleEmptyRender = renderAngleWidth <= angleEpsilon; + const hasAngleRender = + hasAngleRegularRender || + hasAngleFlippedRender || + hasAngleFlatRender || + hasAngleEmptyRender; + const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; @@ -297,63 +374,37 @@ VoxelCylinderShape.prototype.update = function ( // Keep track of how many intersections there are going to be. let intersectionCount = 0; - // Intersects an outer cylinder. - shaderDefines["CYLINDER_OUTER_INDEX"] = intersectionCount; + shaderDefines["CYLINDER_INTERSECTION_INDEX_RADIUS_MAX"] = intersectionCount; intersectionCount += 1; - if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { - shaderDefines["CYLINDER_OUTER_NON_DEFAULT"] = true; - const boundsScaleLocalToBounds = Cartesian3.fromElements( - 1.0 / maxRadius, - 1.0 / maxRadius, - 1.0 / (maxHeight === minHeight ? 1.0 : 0.5 * (maxHeight - minHeight)), - scratchBoundsScale - ); - - // -inverse(scale) * translation // affine inverse - // -inverse(scale) * 0.5 * (minHeight + maxHeight) - const boundsTranslateLocalToBounds = Cartesian3.fromElements( - 0.0, - 0.0, - -boundsScaleLocalToBounds.z * 0.5 * (minHeight + maxHeight), - scratchBoundsTranslation - ); + if (!isDefaultMinRadiusRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN"] = true; + shaderDefines["CYLINDER_INTERSECTION_INDEX_RADIUS_MIN"] = intersectionCount; + intersectionCount += 1; - const transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(boundsScaleLocalToBounds), - boundsTranslateLocalToBounds, - scratchTransformLocalToBounds - ); - const transformUvToBounds = Matrix4.multiplyTransformation( - transformLocalToBounds, - transformUvToLocal, - scratchTransformUvToBounds - ); - shaderUniforms.cylinderScaleUvToBounds = Matrix4.getScale( - transformUvToBounds, - shaderUniforms.cylinderScaleUvToBounds - ); - shaderUniforms.cylinderTranslateUvToBounds = Matrix4.getTranslation( - transformUvToBounds, - shaderUniforms.cylinderTranslateUvToBounds - ); + shaderUniforms.cylinderInverseMinRadiusUv = + renderMaxRadius / renderMinRadius; } - - // Intersects an inner cylinder for the min height. - if (hasInnerCylinder) { - shaderDefines["CYLINDER_INNER"] = true; - - if (minRadius === maxRadius) { - shaderDefines["CYLINDER_INNER_OUTER_EQUAL"] = true; - } else { - shaderDefines["CYLINDER_INNER_INDEX"] = intersectionCount; - } - - intersectionCount += 1; + if (!isDefaultMaxRadiusRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX"] = true; } - - if (!isDefaultOuterCylinder || hasInnerCylinder || !isDefaultHeight) { - shaderUniforms.cylinderInverseInnerRadiusUv = maxRadius / minRadius; + if (renderMinRadius === renderMaxRadius) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT"] = true; + } + if (!isDefaultHeightRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_HEIGHT"] = true; + } + if (renderMinHeight === renderMaxHeight) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT"] = true; + } + if (shapeMinHeight === shapeMaxHeight) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT"] = true; + } + if (shapeMinRadius === shapeMaxRadius) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT"] = true; + } + if (!isDefaultRadiusShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_RADIUS"] = true; // delerp(radius, minRadius, maxRadius) // (radius - minRadius) / (maxRadius - minRadius) @@ -361,21 +412,17 @@ VoxelCylinderShape.prototype.update = function ( // scale = 1.0 / (maxRadius - minRadius) // offset = -minRadius / (maxRadius - minRadius) // offset = minRadius / (minRadius - maxRadius) - const scale = 1.0 / (maxRadius - minRadius); - const offset = minRadius / (minRadius - maxRadius); - shaderUniforms.cylinderRadiusUvScaleAndOffset = Cartesian2.fromElements( + const scale = 1.0 / (shapeMaxRadius - shapeMinRadius); + const offset = shapeMinRadius / (shapeMinRadius - shapeMaxRadius); + shaderUniforms.cylinderUvToShapeUvRadius = Cartesian2.fromElements( scale, offset, - shaderUniforms.cylinderRadiusUvScaleAndOffset + shaderUniforms.cylinderUvToShapeUvRadius ); } - if (!isDefaultHeight) { - shaderDefines["CYLINDER_HEIGHT_NON_DEFAULT"] = true; - - if (minHeight === maxHeight) { - shaderDefines["CYLINDER_HEIGHT_ZERO"] = true; - } + if (!isDefaultHeightShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT"] = true; // delerp(heightUv, minHeightUv, maxHeightUv) // (heightUv - minHeightUv) / (maxHeightUv - minHeightUv) @@ -388,58 +435,102 @@ VoxelCylinderShape.prototype.update = function ( // offset = -2.0 * (minHeight * 0.5 + 0.5) / (maxHeight - minHeight) // offset = -(minHeight + 1.0) / (maxHeight - minHeight) // offset = (minHeight + 1.0) / (minHeight - maxHeight) - const scale = 2.0 / (maxHeight - minHeight); - const offset = (minHeight + 1.0) / (minHeight - maxHeight); - shaderUniforms.cylinderHeightUvScaleAndOffset = Cartesian2.fromElements( + const scale = 2.0 / (shapeMaxHeight - shapeMinHeight); + const offset = (shapeMinHeight + 1.0) / (shapeMinHeight - shapeMaxHeight); + shaderUniforms.cylinderUvToShapeUvHeight = Cartesian2.fromElements( scale, offset, - shaderUniforms.cylinderHeightUvScaleAndOffset + shaderUniforms.cylinderUvToShapeUvHeight ); } - if (isAngleFlipped) { - shaderDefines["CYLINDER_WEDGE_ANGLE_FLIPPED"] = true; + if (!isDefaultMaxRadiusRender || !isDefaultHeightRender) { + const heightScale = 0.5 * (renderMaxHeight - renderMinHeight); + const scaleLocalToBounds = Cartesian3.fromElements( + 1.0 / renderMaxRadius, + 1.0 / renderMaxRadius, + 1.0 / (heightScale === 0.0 ? 1.0 : heightScale), + scratchBoundsScale + ); + // -inverse(scale) * translation // affine inverse + // -inverse(scale) * 0.5 * (minHeight + maxHeight) + const translateLocalToBounds = Cartesian3.fromElements( + 0.0, + 0.0, + -scaleLocalToBounds.z * 0.5 * (renderMinHeight + renderMaxHeight), + scratchBoundsTranslation + ); + const transformLocalToBounds = Matrix4.fromRotationTranslation( + Matrix3.fromScale(scaleLocalToBounds), + translateLocalToBounds, + scratchTransformLocalToBounds + ); + const transformUvToBounds = Matrix4.multiplyTransformation( + transformLocalToBounds, + transformUvToLocal, + scratchTransformUvToBounds + ); + shaderUniforms.cylinderUvToRenderBoundsScale = Matrix4.getScale( + transformUvToBounds, + shaderUniforms.cylinderUvToRenderBoundsScale + ); + shaderUniforms.cylinderUvToRenderBoundsTranslate = Matrix4.getTranslation( + transformUvToBounds, + shaderUniforms.cylinderUvToRenderBoundsTranslate + ); } - // Intersects a wedge for the min and max longitude. - if (hasWedge) { - shaderDefines["CYLINDER_WEDGE"] = true; - shaderDefines["CYLINDER_WEDGE_INDEX"] = intersectionCount; + if (isAngleReversedShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED"] = true; + } + + if (hasAngleRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE"] = true; + shaderDefines["CYLINDER_INTERSECTION_INDEX_ANGLE"] = intersectionCount; - if (hasWedgeRegular) { - shaderDefines["CYLINDER_WEDGE_REGULAR"] = true; + if (hasAngleRegularRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF"] = true; intersectionCount += 1; - } else if (hasWedgeFlipped) { - shaderDefines["CYLINDER_WEDGE_FLIPPED"] = true; + } else if (hasAngleFlippedRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF"] = true; intersectionCount += 2; - } else if (hasWedgeFlat) { - shaderDefines["CYLINDER_WEDGE_FLAT"] = true; + } else if (hasAngleFlatRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF"] = true; intersectionCount += 1; - } else if (hasWedgeEmpty) { - shaderDefines["CYLINDER_WEDGE_EMPTY"] = true; + } else if (hasAngleEmptyRender) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO"] = true; intersectionCount += 2; } - if (isMinAngleDiscontinuity) { - shaderDefines["CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; - } - if (isMaxAngleDiscontinuity) { - shaderDefines["CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; - } - - shaderUniforms.cylinderAngleMinMax = Cartesian2.fromElements( - minAngle, - maxAngle, + shaderUniforms.cylinderRenderAngleMinMax = Cartesian2.fromElements( + renderMinAngle, + renderMaxAngle, shaderUniforms.cylinderAngleMinMax ); + } - const minAngleUv = (minAngle - defaultMinAngle) / defaultAngleWidth; - const maxAngleUv = (maxAngle - defaultMinAngle) / defaultAngleWidth; - const emptyAngleWidthUv = 1.0 - angleWidth / defaultAngleWidth; + if (hasAngleShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE"] = true; + if (hasAngleEmptyShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO"] = true; + } + if (hasAngleMinDiscontinuityShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY"] = true; + } + if (hasAngleMaxDiscontinuityShape) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY"] = true; + } - shaderUniforms.cylinderMinAngleUv = minAngleUv; - shaderUniforms.cylinderMaxAngleUv = maxAngleUv; - shaderUniforms.cylinderEmptyMidpointAngleUv = + const minAngleUv = (shapeMinAngle - defaultMinAngle) / defaultAngleWidth; + const maxAngleUv = (shapeMaxAngle - defaultMinAngle) / defaultAngleWidth; + const emptyAngleWidthUv = 1.0 - shapeAngleWidth / defaultAngleWidth; + + shaderUniforms.cylinderShapeUvAngleMinMax = Cartesian2.fromElements( + minAngleUv, + maxAngleUv, + shaderUniforms.cylinderShapeUvAngleMinMax + ); + shaderUniforms.cylinderShapeUvAngleEmptyMid = (maxAngleUv + 0.5 * emptyAngleWidthUv) % 1.0; // delerp(angleUv, minAngleUv, maxAngleUv) @@ -451,16 +542,16 @@ VoxelCylinderShape.prototype.update = function ( // offset = -minAngleUv / (maxAngleUv - minAngleUv) // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // offset = -(minAngle - pi) / (maxAngle - minAngle) - const scale = defaultAngleWidth / angleWidth; - const offset = -(minAngle - defaultMinAngle) / angleWidth; - shaderUniforms.cylinderAngleUvScaleAndOffset = Cartesian2.fromElements( + const scale = defaultAngleWidth / shapeAngleWidth; + const offset = -(shapeMinAngle - defaultMinAngle) / shapeAngleWidth; + shaderUniforms.cylinderUvToShapeUvAngle = Cartesian2.fromElements( scale, offset, - shaderUniforms.cylinderAngleUvScaleAndOffset + shaderUniforms.cylinderUvToShapeUvAngle ); } - shaderDefines["CYLINDER_INTERSECTION_COUNT"] = intersectionCount; + this.shaderMaximumIntersectionsLength = intersectionCount; return true; }; diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 03d1a847c98..51708ae4b9f 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -1,7 +1,6 @@ import BoundingSphere from "../Core/BoundingSphere.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; -import Cartesian4 from "../Core/Cartesian4.js"; import Check from "../Core/Check.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import CesiumMath from "../Core/Math.js"; @@ -94,22 +93,16 @@ function VoxelEllipsoidShape() { * @readonly */ this.shaderUniforms = { - ellipsoidRectangle: new Cartesian4(), ellipsoidRadiiUv: new Cartesian3(), ellipsoidInverseRadiiSquaredUv: new Cartesian3(), - // Wedge uniforms - ellipsoidMinLongitudeUv: 0.0, - ellipsoidMaxLongitudeUv: 0.0, - ellipsoidEmptyMidpointLongitudeUv: 0.0, - ellipsoidLongitudeUvScaleAndOffset: new Cartesian2(), - // Cone uniforms - ellipsoidLatitudeUvScaleAndOffset: new Cartesian2(), - ellipsoidMinLatitudeCosSqrHalfAngle: 0.0, - ellipsoidMaxLatitudeCosSqrHalfAngle: 0.0, - // Inner ellipsoid uniforms + ellipsoidRenderLongitudeMinMax: new Cartesian2(), + ellipsoidShapeUvLongitudeMinMaxMid: new Cartesian3(), + ellipsoidUvToShapeUvLongitude: new Cartesian2(), + ellipsoidUvToShapeUvLatitude: new Cartesian2(), + ellipsoidRenderLatitudeCosSqrHalfMinMax: new Cartesian2(), ellipsoidInverseHeightDifferenceUv: 0.0, - ellipsoidInverseInnerScaleUv: 0.0, ellipseInnerRadiiUv: new Cartesian2(), + ellipsoidInverseInnerScaleUv: 0.0, }; /** @@ -117,39 +110,51 @@ function VoxelEllipsoidShape() { * @readonly */ this.shaderDefines = { - ELLIPSOID_INTERSECTION_COUNT: undefined, - ELLIPSOID_WEDGE: undefined, - ELLIPSOID_WEDGE_INDEX: undefined, - ELLIPSOID_WEDGE_REGULAR: undefined, - ELLIPSOID_WEDGE_FLIPPED: undefined, - ELLIPSOID_WEDGE_FLAT: undefined, - ELLIPSOID_WEDGE_EMPTY: undefined, - ELLIPSOID_WEDGE_ANGLE_FLIPPED: undefined, - ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY: undefined, - ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY: undefined, - ELLIPSOID_CONE_BOTTOM: undefined, - ELLIPSOID_CONE_BOTTOM_REGULAR: undefined, - ELLIPSOID_CONE_BOTTOM_FLIPPED: undefined, - ELLIPSOID_CONE_BOTTOM_FLAT: undefined, - ELLIPSOID_CONE_BOTTOM_INDEX: undefined, - ELLIPSOID_CONE_TOP: undefined, - ELLIPSOID_CONE_TOP_REGULAR: undefined, - ELLIPSOID_CONE_TOP_FLIPPED: undefined, - ELLIPSOID_CONE_TOP_FLAT: undefined, - ELLIPSOID_CONE_TOP_INDEX: undefined, - ELLIPSOID_OUTER: undefined, - ELLIPSOID_OUTER_INDEX: undefined, - ELLIPSOID_INNER: undefined, - ELLIPSOID_INNER_OUTER_EQUAL: undefined, - ELLIPSOID_INNER_INDEX: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO: undefined, + ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO: undefined, ELLIPSOID_IS_SPHERE: undefined, + ELLIPSOID_INTERSECTION_INDEX_LONGITUDE: undefined, + ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX: undefined, + ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN: undefined, + ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX: undefined, + ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN: undefined, }; + + /** + * The maximum number of intersections against the shape for any ray direction. + * @type {Number} + * @readonly + */ + this.shaderMaximumIntersectionsLength = 0; // not known until update } const scratchScale = new Cartesian3(); const scratchRotationScale = new Matrix3(); -const scratchOuter = new Cartesian3(); -const scratchInner = new Cartesian3(); +const scratchOuterExtentShape = new Cartesian3(); +const scratchInnerExtentShape = new Cartesian3(); +const scratchOuterExtentRender = new Cartesian3(); +const scratchInnerExtentRender = new Cartesian3(); /** * Update the shape's state. @@ -157,92 +162,208 @@ const scratchInner = new Cartesian3(); * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. + * @param {Cartesian3} clipMinBounds The minimum clip bounds. + * @param {Cartesian3} clipMaxBounds The maximum clip bounds. * @returns {Boolean} Whether the shape is visible. */ VoxelEllipsoidShape.prototype.update = function ( modelMatrix, minBounds, - maxBounds + maxBounds, + clipMinBounds, + clipMaxBounds ) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); + Check.typeOf.object("clipMinBounds", clipMinBounds); + Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); - const defaultMinLongitude = VoxelEllipsoidShape.DefaultMinBounds.x; - const defaultMaxLongitude = VoxelEllipsoidShape.DefaultMaxBounds.x; - const defaultLongitudeLength = defaultMaxLongitude - defaultMinLongitude; - const defaultLongitudeHalfLength = 0.5 * defaultLongitudeLength; - const defaultMinLatitude = VoxelEllipsoidShape.DefaultMinBounds.y; - const defaultMaxLatitude = VoxelEllipsoidShape.DefaultMaxBounds.y; - const defaultLatitudeLength = defaultMaxLatitude - defaultMinLatitude; + const zeroScaleEpsilon = CesiumMath.EPSILON10; + const longitudeDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const longitudeEpsilon = CesiumMath.EPSILON10; + const latitudeEpsilon = CesiumMath.EPSILON10; + const flatLatitudeEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + + const longitudeMinDefault = VoxelEllipsoidShape.DefaultMinBounds.x; + const longitudeMaxDefault = VoxelEllipsoidShape.DefaultMaxBounds.x; + const longitudeRangeDefault = longitudeMaxDefault - longitudeMinDefault; + const longitudeHalfRangeDefault = 0.5 * longitudeRangeDefault; + const latitudeMinDefault = VoxelEllipsoidShape.DefaultMinBounds.y; + const latitudeMaxDefault = VoxelEllipsoidShape.DefaultMaxBounds.y; + const latitudeRangeDefault = latitudeMaxDefault - latitudeMinDefault; // Clamp the longitude / latitude to the valid range - const west = CesiumMath.clamp( + const longitudeMinShape = CesiumMath.clamp( minBounds.x, - defaultMinLongitude, - defaultMaxLongitude + longitudeMinDefault, + longitudeMaxDefault ); - const east = CesiumMath.clamp( + const longitudeMaxShape = CesiumMath.clamp( maxBounds.x, - defaultMinLongitude, - defaultMaxLongitude + longitudeMinDefault, + longitudeMaxDefault + ); + const longitudeMinClip = CesiumMath.clamp( + clipMinBounds.x, + longitudeMinDefault, + longitudeMaxDefault + ); + const longitudeMaxClip = CesiumMath.clamp( + clipMaxBounds.x, + longitudeMinDefault, + longitudeMaxDefault + ); + const longitudeMinRender = CesiumMath.clamp( + longitudeMinClip, + longitudeMinShape, + longitudeMaxShape + ); + const longitudeMaxRender = CesiumMath.clamp( + longitudeMaxShape, + longitudeMinClip, + longitudeMaxClip ); - const south = CesiumMath.clamp( + + const latitudeMinShape = CesiumMath.clamp( minBounds.y, - defaultMinLatitude, - defaultMaxLatitude + latitudeMinDefault, + latitudeMaxDefault ); - const north = CesiumMath.clamp( + const latitudeMaxShape = CesiumMath.clamp( maxBounds.y, - defaultMinLatitude, - defaultMaxLatitude + latitudeMinDefault, + latitudeMaxDefault + ); + const latitudeMinClip = CesiumMath.clamp( + clipMinBounds.y, + latitudeMinDefault, + latitudeMaxDefault + ); + const latitudeMaxClip = CesiumMath.clamp( + clipMaxBounds.y, + latitudeMinDefault, + latitudeMaxDefault + ); + const latitudeMinRender = CesiumMath.clamp( + latitudeMinClip, + latitudeMinShape, + latitudeMaxShape + ); + const latitudeMaxRender = CesiumMath.clamp( + latitudeMaxShape, + latitudeMinClip, + latitudeMaxClip ); // Don't let the height go below the center of the ellipsoid. const radii = Matrix4.getScale(modelMatrix, scratchScale); + const isSphere = radii.x === radii.y && radii.y === radii.z; const minRadius = Cartesian3.minimumComponent(radii); - const minHeight = Math.max(minBounds.z, -minRadius); - const maxHeight = Math.max(maxBounds.z, -minRadius); + const minHeightShape = Math.max(minBounds.z, -minRadius); + const maxHeightShape = Math.max(maxBounds.z, -minRadius); + const minHeightClip = Math.max(clipMinBounds.z, -minRadius); + const maxHeightClip = Math.max(clipMaxBounds.z, -minRadius); + const minHeightRender = CesiumMath.clamp( + minHeightShape, + minHeightClip, + maxHeightClip + ); + const maxHeightRender = CesiumMath.clamp( + maxHeightShape, + minHeightClip, + maxHeightClip + ); // Compute the closest and farthest a point can be from the center of the ellipsoid. - const innerExtent = Cartesian3.add( + const innerExtentShape = Cartesian3.add( radii, - Cartesian3.fromElements(minHeight, minHeight, minHeight, scratchInner), - scratchInner + Cartesian3.fromElements( + minHeightShape, + minHeightShape, + minHeightShape, + scratchInnerExtentShape + ), + scratchInnerExtentShape ); - const outerExtent = Cartesian3.add( + const outerExtentShape = Cartesian3.add( radii, - Cartesian3.fromElements(maxHeight, maxHeight, maxHeight, scratchOuter), - scratchOuter + Cartesian3.fromElements( + maxHeightShape, + maxHeightShape, + maxHeightShape, + scratchOuterExtentShape + ), + scratchOuterExtentShape ); - const maxExtent = Cartesian3.maximumComponent(outerExtent); + const maxExtentShape = Cartesian3.maximumComponent(outerExtentShape); - const zeroScaleEpsilon = CesiumMath.EPSILON10; - const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees - const wedgeEpsilon = CesiumMath.EPSILON10; - const coneEpsilon = CesiumMath.EPSILON10; - const flatConeEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const innerExtentRender = Cartesian3.add( + radii, + Cartesian3.fromElements( + minHeightRender, + minHeightRender, + minHeightRender, + scratchInnerExtentRender + ), + scratchInnerExtentRender + ); + const outerExtentRender = Cartesian3.add( + radii, + Cartesian3.fromElements( + maxHeightRender, + maxHeightRender, + maxHeightRender, + scratchOuterExtentRender + ), + scratchOuterExtentRender + ); + const maxExtentRender = Cartesian3.maximumComponent(outerExtentRender); // Exit early if the shape is not visible. - // Note that west may be greater than east when crossing the 180th meridian. + // Note that minLongitude may be greater than maxLongitude when crossing the 180th meridian. if ( - south > north || - minHeight > maxHeight || - CesiumMath.equalsEpsilon(outerExtent.x, 0.0, undefined, zeroScaleEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.y, 0.0, undefined, zeroScaleEpsilon) || - CesiumMath.equalsEpsilon(outerExtent.z, 0.0, undefined, zeroScaleEpsilon) + latitudeMinRender > latitudeMaxRender || + latitudeMinRender === latitudeMaxDefault || + latitudeMaxRender === latitudeMinDefault || + minHeightRender > maxHeightRender || + maxHeightShape < minHeightClip || + minHeightShape > maxHeightClip || + CesiumMath.equalsEpsilon( + outerExtentRender.x, + 0.0, + undefined, + zeroScaleEpsilon + ) || + CesiumMath.equalsEpsilon( + outerExtentRender.y, + 0.0, + undefined, + zeroScaleEpsilon + ) || + CesiumMath.equalsEpsilon( + outerExtentRender.z, + 0.0, + undefined, + zeroScaleEpsilon + ) ) { return false; } - this._rectangle = Rectangle.fromRadians(west, south, east, north); + this._rectangle = Rectangle.fromRadians( + longitudeMinShape, + latitudeMinShape, + longitudeMaxShape, + latitudeMaxShape + ); this._translation = Matrix4.getTranslation(modelMatrix, this._translation); this._rotation = Matrix4.getRotation(modelMatrix, this._rotation); this._ellipsoid = Ellipsoid.fromCartesian3(radii, this._ellipsoid); - this._minimumHeight = minHeight; - this._maximumHeight = maxHeight; + this._minimumHeight = minHeightShape; + this._maximumHeight = maxHeightShape; this.orientedBoundingBox = getEllipsoidChunkObb( this._rectangle, @@ -255,7 +376,7 @@ VoxelEllipsoidShape.prototype.update = function ( ); this.shapeTransform = Matrix4.fromRotationTranslation( - Matrix3.setScale(this._rotation, outerExtent, scratchRotationScale), + Matrix3.setScale(this._rotation, outerExtentRender, scratchRotationScale), this._translation, this.shapeTransform ); @@ -281,18 +402,10 @@ VoxelEllipsoidShape.prototype.update = function ( } } - shaderUniforms.ellipsoidRectangle = Cartesian4.fromElements( - west, - south, - east, - north, - shaderUniforms.ellipsoidRectangle - ); - // The ellipsoid radii scaled to [0,1]. The max ellipsoid radius will be 1.0 and others will be less. shaderUniforms.ellipsoidRadiiUv = Cartesian3.divideByScalar( - outerExtent, - maxExtent, + outerExtentShape, + maxExtentShape, shaderUniforms.ellipsoidRadiiUv ); @@ -307,125 +420,221 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidInverseRadiiSquaredUv ); - const rectangleHeight = Rectangle.computeHeight(this._rectangle); - const hasInnerEllipsoid = !Cartesian3.equals(innerExtent, Cartesian3.ZERO); - - const isAngleFlipped = east < west; - const angleWidth = east - west + isAngleFlipped * defaultLongitudeLength; - const hasWedgeRegular = - angleWidth > defaultLongitudeHalfLength + wedgeEpsilon && - angleWidth < defaultLongitudeLength - wedgeEpsilon; - const hasWedgeFlipped = - angleWidth > wedgeEpsilon && - angleWidth < defaultLongitudeHalfLength - wedgeEpsilon; - const hasWedgeFlat = - angleWidth >= defaultLongitudeHalfLength - wedgeEpsilon && - angleWidth <= defaultLongitudeHalfLength + wedgeEpsilon; - const hasWedgeEmpty = angleWidth <= wedgeEpsilon; - const hasWedge = - hasWedgeRegular || hasWedgeFlipped || hasWedgeFlat || hasWedgeEmpty; - - const hasTopConeRegular = - north > +flatConeEpsilon && north < defaultMaxLatitude - coneEpsilon; - const hasTopConeFlipped = north < -flatConeEpsilon; - const hasTopConeFlat = north >= -flatConeEpsilon && north <= +flatConeEpsilon; - const hasTopCone = hasTopConeRegular || hasTopConeFlipped || hasTopConeFlat; - - const hasBottomConeRegular = - south > defaultMinLatitude + coneEpsilon && south < -flatConeEpsilon; - const hasBottomConeFlipped = south > +flatConeEpsilon; - const hasBottomConeFlat = - south >= -flatConeEpsilon && south <= +flatConeEpsilon; - const hasBottomCone = - hasBottomConeRegular || hasBottomConeFlipped || hasBottomConeFlat; - - const isSphere = radii.x === radii.y && radii.y === radii.z; + // Longitude + const isLongitudeMinMaxReversedRender = + longitudeMaxRender < longitudeMinRender; + const longitudeRangeRender = + longitudeMaxRender - + longitudeMinRender + + isLongitudeMinMaxReversedRender * longitudeRangeDefault; + const hasLongitudeRangeEqualZeroRender = + longitudeRangeRender <= longitudeEpsilon; + const hasLongitudeRangeUnderHalfRender = + longitudeRangeRender > longitudeHalfRangeDefault + longitudeEpsilon && + longitudeRangeRender < longitudeRangeDefault - longitudeEpsilon; + const hasLongitudeRangeEqualHalfRender = + longitudeRangeRender >= longitudeHalfRangeDefault - longitudeEpsilon && + longitudeRangeRender <= longitudeHalfRangeDefault + longitudeEpsilon; + const hasLongitudeRangeOverHalfRender = + longitudeRangeRender > longitudeEpsilon && + longitudeRangeRender < longitudeHalfRangeDefault - longitudeEpsilon; + const hasLongitudeRender = + hasLongitudeRangeEqualZeroRender || + hasLongitudeRangeUnderHalfRender || + hasLongitudeRangeEqualHalfRender || + hasLongitudeRangeOverHalfRender; + + const isLongitudeMinMaxReversedShape = + longitudeMaxRender < longitudeMinRender; + const longitudeRangeShape = + longitudeMaxShape - + longitudeMinShape + + isLongitudeMinMaxReversedShape * longitudeRangeDefault; + const hasLongitudeRangeEqualZeroShape = + longitudeRangeShape <= longitudeEpsilon; + const hasLongitudeRangeUnderHalfShape = + longitudeRangeShape > longitudeHalfRangeDefault + longitudeEpsilon && + longitudeRangeShape < longitudeRangeDefault - longitudeEpsilon; + const hasLongitudeRangeEqualHalfShape = + longitudeRangeShape >= longitudeHalfRangeDefault - longitudeEpsilon && + longitudeRangeShape <= longitudeHalfRangeDefault + longitudeEpsilon; + const hasLongitudeRangeOverHalfShape = + longitudeRangeShape > longitudeEpsilon && + longitudeRangeShape < longitudeHalfRangeDefault - longitudeEpsilon; + const hasLongitudeShape = + hasLongitudeRangeEqualZeroShape || + hasLongitudeRangeUnderHalfShape || + hasLongitudeRangeEqualHalfShape || + hasLongitudeRangeOverHalfShape; + + // Latitude + const latitudeRangeRender = latitudeMaxRender - latitudeMinRender; + const hasLatitudeMaxUnderHalfRender = + latitudeMaxRender < -flatLatitudeEpsilon; + const hasLatitudeMaxEqualHalfRender = + latitudeMaxRender >= -flatLatitudeEpsilon && + latitudeMaxRender <= +flatLatitudeEpsilon; + const hasLatitudeMaxOverHalfRender = + latitudeMaxRender > +flatLatitudeEpsilon && + latitudeMaxRender < latitudeMaxDefault - latitudeEpsilon; + const hasLatitudeMaxRender = + hasLatitudeMaxUnderHalfRender || + hasLatitudeMaxEqualHalfRender || + hasLatitudeMaxOverHalfRender; + const hasLatitudeMinUnderHalfRender = + latitudeMinRender > latitudeMinDefault + latitudeEpsilon && + latitudeMinRender < -flatLatitudeEpsilon; + const hasLatitudeMinEqualHalfRender = + latitudeMinRender >= -flatLatitudeEpsilon && + latitudeMinRender <= +flatLatitudeEpsilon; + const hasLatitudeMinOverHalfRender = latitudeMinRender > +flatLatitudeEpsilon; + const hasLatitudeMinRender = + hasLatitudeMinUnderHalfRender || + hasLatitudeMinEqualHalfRender || + hasLatitudeMinOverHalfRender; + const hasLatitudeRender = hasLatitudeMaxRender || hasLatitudeMinRender; + + const latitudeRangeShape = latitudeMaxShape - latitudeMinShape; + const hasLatitudeMaxUnderHalfShape = latitudeMaxShape < -flatLatitudeEpsilon; + const hasLatitudeMaxEqualHalfShape = + latitudeMaxShape >= -flatLatitudeEpsilon && + latitudeMaxShape <= +flatLatitudeEpsilon; + const hasLatitudeMaxOverHalfShape = + latitudeMaxShape > +flatLatitudeEpsilon && + latitudeMaxShape < latitudeMaxDefault - latitudeEpsilon; + const hasLatitudeMaxShape = + hasLatitudeMaxUnderHalfShape || + hasLatitudeMaxEqualHalfShape || + hasLatitudeMaxOverHalfShape; + const hasLatitudeMinUnderHalfShape = + latitudeMinShape > latitudeMinDefault + latitudeEpsilon && + latitudeMinShape < -flatLatitudeEpsilon; + const hasLatitudeMinEqualHalfShape = + latitudeMinShape >= -flatLatitudeEpsilon && + latitudeMinShape <= +flatLatitudeEpsilon; + const hasLatitudeMinOverHalfShape = latitudeMinShape > +flatLatitudeEpsilon; + const hasLatitudeMinShape = + hasLatitudeMinUnderHalfShape || + hasLatitudeMinEqualHalfShape || + hasLatitudeMinOverHalfShape; + const hasLatitudeShape = hasLatitudeMaxShape || hasLatitudeMinShape; + + // Height + const hasHeightMinRender = !Cartesian3.equals( + innerExtentRender, + Cartesian3.ZERO + ); + const hasHeightMaxRender = !Cartesian3.equals( + outerExtentRender, + Cartesian3.ZERO + ); + const hasHeightRender = hasHeightMinRender || hasHeightMaxRender; + const heightRangeRender = maxHeightRender - minHeightRender; + const hasHeightMinShape = !Cartesian3.equals( + innerExtentShape, + Cartesian3.ZERO + ); + const hasHeightMaxShape = !Cartesian3.equals( + outerExtentShape, + Cartesian3.ZERO + ); + const hasHeightShape = hasHeightMinShape || hasHeightMaxShape; // Keep track of how many intersections there are going to be. let intersectionCount = 0; // Intersects an outer ellipsoid for the max height. - shaderDefines["ELLIPSOID_OUTER"] = true; - shaderDefines["ELLIPSOID_OUTER_INDEX"] = intersectionCount; + shaderDefines["ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX"] = intersectionCount; intersectionCount += 1; - // Intersects an inner ellipsoid for the min height. - if (hasInnerEllipsoid) { - shaderDefines["ELLIPSOID_INNER"] = true; - shaderDefines["ELLIPSOID_INNER_INDEX"] = intersectionCount; - if (minHeight === maxHeight) { - shaderDefines["ELLIPSOID_INNER_OUTER_EQUAL"] = true; + if (hasHeightRender) { + if (heightRangeRender === 0.0) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO" + ] = true; } - intersectionCount += 1; - - // The percent of space that is between the inner and outer ellipsoid. - const thickness = (maxHeight - minHeight) / maxExtent; - shaderUniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; - - // The percent of space that is taken up by the inner ellipsoid. - const innerScale = 1.0 - thickness; - shaderUniforms.ellipsoidInverseInnerScaleUv = 1.0 / innerScale; + if (hasHeightMinRender) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN"] = true; + shaderDefines[ + "ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN" + ] = intersectionCount; + intersectionCount += 1; - // The inner ellipsoid radii scaled to [0,innerScale]. The max inner ellipsoid radius will equal innerScale and others will be less. - shaderUniforms.ellipseInnerRadiiUv = Cartesian2.fromElements( - shaderUniforms.ellipsoidRadiiUv.x * innerScale, - shaderUniforms.ellipsoidRadiiUv.z * innerScale, - shaderUniforms.ellipseInnerRadiiUv - ); + // The inverse of the percent of space that is taken up by the inner ellipsoid. + // 1.0 / (1.0 - thickness) // thickness = percent of space that is between the min and max height. + // 1.0 / (1.0 - (maxHeightRender - minHeightRender) / maxExtentRender) + // maxExtentRender / (maxExtentRender - (maxHeightRender - minHeightRender)) + shaderUniforms.ellipsoidInverseInnerScaleUv = + maxExtentRender / (maxExtentRender - heightRangeRender); + } } - if (isSphere) { - shaderDefines["ELLIPSOID_IS_SPHERE"] = true; + if (hasHeightShape) { + if (hasHeightMinShape) { + shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN"] = true; + + // The percent of space that is between the inner and outer ellipsoid. + const thickness = (maxHeightShape - minHeightShape) / maxExtentShape; + shaderUniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; + shaderUniforms.ellipseInnerRadiiUv = Cartesian2.fromElements( + shaderUniforms.ellipsoidRadiiUv.x * (1.0 - thickness), + shaderUniforms.ellipsoidRadiiUv.z * (1.0 - thickness), + shaderUniforms.ellipseInnerRadiiUv + ); + } + if (minHeightShape === maxHeightShape) { + shaderDefines[ + "ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO" + ] = true; + } } // Intersects a wedge for the min and max longitude. - if (hasWedge) { - shaderDefines["ELLIPSOID_WEDGE"] = true; - shaderDefines["ELLIPSOID_WEDGE_INDEX"] = intersectionCount; - - if (hasWedgeRegular) { - shaderDefines["ELLIPSOID_WEDGE_REGULAR"] = true; + if (hasLongitudeRender) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE"] = true; + shaderDefines["ELLIPSOID_INTERSECTION_INDEX_LONGITUDE"] = intersectionCount; + + if (hasLongitudeRangeUnderHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF" + ] = true; intersectionCount += 1; - } else if (hasWedgeFlipped) { - shaderDefines["ELLIPSOID_WEDGE_FLIPPED"] = true; + } else if (hasLongitudeRangeOverHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF" + ] = true; intersectionCount += 2; - } else if (hasWedgeFlat) { - shaderDefines["ELLIPSOID_WEDGE_FLAT"] = true; + } else if (hasLongitudeRangeEqualHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF" + ] = true; intersectionCount += 1; - } else if (hasWedgeEmpty) { - shaderDefines["ELLIPSOID_WEDGE_EMPTY"] = true; + } else if (hasLongitudeRangeEqualZeroRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO" + ] = true; intersectionCount += 2; } - const isMinAngleDiscontinuity = CesiumMath.equalsEpsilon( - west, - defaultMinLongitude, - undefined, - angleDiscontinuityEpsilon - ); - const isMaxAngleDiscontinuity = CesiumMath.equalsEpsilon( - east, - defaultMaxLongitude, - undefined, - angleDiscontinuityEpsilon + shaderUniforms.ellipsoidRenderLongitudeMinMax = Cartesian2.fromElements( + longitudeMinRender, + longitudeMaxRender, + shaderUniforms.ellipsoidRenderLongitudeMinMax ); + } - if (isMinAngleDiscontinuity) { - shaderDefines["ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY"] = true; - } - if (isMaxAngleDiscontinuity) { - shaderDefines["ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY"] = true; - } + if (hasLongitudeShape) { + shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE"] = true; - const westUv = (west - defaultMinLongitude) / defaultLongitudeLength; - const eastUv = (east - defaultMinLongitude) / defaultLongitudeLength; - const emptyAngleWidthUv = 1.0 - angleWidth / defaultLongitudeLength; + const isLongitudeMinMaxReversedShape = + longitudeMaxShape < longitudeMinShape; - shaderUniforms.ellipsoidMinLongitudeUv = westUv; - shaderUniforms.ellipsoidMaxLongitudeUv = eastUv; - shaderUniforms.ellipsoidEmptyMidpointLongitudeUv = - (eastUv + 0.5 * emptyAngleWidthUv) % 1.0; + if (isLongitudeMinMaxReversedShape) { + shaderDefines[ + "ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED" + ] = true; + } // delerp(longitudeUv, minLongitudeUv, maxLongitudeUv) // (longitudeUv - minLongitudeUv) / (maxLongitudeUv - minLongitudeUv) @@ -436,20 +645,141 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = -minLongitudeUv / (maxLongitudeUv - minLongitudeUv) // offset = -((minLongitude - pi) / (2.0 * pi)) / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi))) // offset = -(minLongitude - pi) / (maxLongitude - minLongitude) - const scale = defaultLongitudeLength / angleWidth; - const offset = -(west - defaultMinLongitude) / angleWidth; - shaderUniforms.ellipsoidLongitudeUvScaleAndOffset = Cartesian2.fromElements( + const scale = longitudeRangeDefault / longitudeRangeShape; + const offset = + -(longitudeMinShape - longitudeMinDefault) / longitudeRangeShape; + shaderUniforms.ellipsoidUvToShapeUvLongitude = Cartesian2.fromElements( scale, offset, - shaderUniforms.ellipsoidLongitudeUvScaleAndOffset + shaderUniforms.ellipsoidUvToShapeUvLongitude + ); + } + + if (hasLongitudeShape || hasLongitudeRender) { + const isMinLongitudeDiscontinuityRender = CesiumMath.equalsEpsilon( + longitudeMinRender, + longitudeMinDefault, + undefined, + longitudeDiscontinuityEpsilon + ); + const isMaxLongitudeDiscontinuityRender = CesiumMath.equalsEpsilon( + longitudeMaxRender, + longitudeMaxDefault, + undefined, + longitudeDiscontinuityEpsilon + ); + + if (isMinLongitudeDiscontinuityRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY" + ] = true; + } + if (isMaxLongitudeDiscontinuityRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY" + ] = true; + } + const longitudeMinShapeUv = + (longitudeMinShape - longitudeMinDefault) / longitudeRangeDefault; + const longitudeMaxShapeUv = + (longitudeMaxShape - longitudeMinDefault) / longitudeRangeDefault; + + const longitudeMaxRenderUv = + (longitudeMaxRender - longitudeMinDefault) / longitudeRangeDefault; + const longitudeRangeEmptyRender = + 1.0 - longitudeRangeRender / longitudeRangeDefault; + const emptyMidLongitudeRenderUv = + (longitudeMaxRenderUv + 0.5 * longitudeRangeEmptyRender) % 1.0; + + shaderUniforms.ellipsoidShapeUvLongitudeMinMaxMid = Cartesian3.fromElements( + longitudeMinShapeUv, + longitudeMaxShapeUv, + emptyMidLongitudeRenderUv, + shaderUniforms.ellipsoidShapeUvLongitudeMinMaxMid ); } - if (isAngleFlipped) { - shaderDefines["ELLIPSOID_WEDGE_ANGLE_FLIPPED"] = true; + if (hasLatitudeRender) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE"] = true; + + // Intersects a cone for min latitude + if (hasLatitudeMinRender) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN"] = true; + shaderDefines[ + "ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN" + ] = intersectionCount; + + if (hasLatitudeMinUnderHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF" + ] = true; + intersectionCount += 1; + } else if (hasLatitudeMinEqualHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF" + ] = true; + intersectionCount += 1; + } else if (hasLatitudeMinOverHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF" + ] = true; + intersectionCount += 2; + } + } + + // Intersects a cone for max latitude + if (hasLatitudeMaxRender) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX"] = true; + shaderDefines[ + "ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX" + ] = intersectionCount; + + if (hasLatitudeMaxUnderHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF" + ] = true; + intersectionCount += 2; + } else if (hasLatitudeMaxEqualHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF" + ] = true; + intersectionCount += 1; + } else if (hasLatitudeMaxOverHalfRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF" + ] = true; + intersectionCount += 1; + } + } + + if (latitudeMinRender === latitudeMaxRender) { + shaderDefines[ + "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO" + ] = true; + } + + const minCosHalfAngleSqr = Math.pow( + Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(latitudeMinRender)), + 2.0 + ); + const maxCosHalfAngleSqr = Math.pow( + Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(latitudeMaxRender)), + 2.0 + ); + shaderUniforms.ellipsoidRenderLatitudeCosSqrHalfMinMax = Cartesian2.fromElements( + minCosHalfAngleSqr, + maxCosHalfAngleSqr, + shaderUniforms.ellipsoidRenderLatitudeCosSqrHalfMinMax + ); } - if (hasBottomCone || hasTopCone) { + if (hasLatitudeShape) { + if (latitudeMinShape === latitudeMaxShape) { + shaderDefines[ + "ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO" + ] = true; + } + // delerp(latitudeUv, minLatitudeUv, maxLatitudeUv) // (latitudeUv - minLatitudeUv) / (maxLatitudeUv - minLatitudeUv) // latitudeUv / (maxLatitudeUv - minLatitudeUv) - minLatitudeUv / (maxLatitudeUv - minLatitudeUv) @@ -457,65 +787,23 @@ VoxelEllipsoidShape.prototype.update = function ( // scale = 1.0 / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) // scale = 2.0 * pi / (maxLatitude - minLatitude) // offset = -minLatitudeUv / (maxLatitudeUv - minLatitudeUv) - // offset = -((minLatitude - pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) - // offset = -(minLatitude - pi) / (maxLatitude - minLatitude) - const scale = defaultLatitudeLength / rectangleHeight; - const offset = -(south - defaultMinLatitude) / rectangleHeight; + // offset = -((minLatitude - -pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) + // offset = -(minLatitude - -pi) / (maxLatitude - minLatitude) + // offset = (-pi - minLatitude) / (maxLatitude - minLatitude) + const scale = latitudeRangeDefault / latitudeRangeShape; + const offset = (latitudeMinDefault - latitudeMinShape) / latitudeRangeShape; shaderUniforms.ellipsoidLatitudeUvScaleAndOffset = Cartesian2.fromElements( scale, offset, shaderUniforms.ellipsoidLatitudeUvScaleAndOffset ); - - const minAngle = hasBottomConeRegular ? -south : south; - const maxAngle = hasTopConeFlipped ? -north : north; - const minCosHalfAngle = Math.cos( - CesiumMath.PI_OVER_TWO - Math.abs(minAngle) - ); - const maxCosHalfAngle = Math.cos( - CesiumMath.PI_OVER_TWO - Math.abs(maxAngle) - ); - shaderUniforms.ellipsoidMinLatitudeCosSqrHalfAngle = - minCosHalfAngle * minCosHalfAngle; - shaderUniforms.ellipsoidMaxLatitudeCosSqrHalfAngle = - maxCosHalfAngle * maxCosHalfAngle; - } - - // Intersects a cone for min latitude - if (hasBottomCone) { - shaderDefines["ELLIPSOID_CONE_BOTTOM"] = true; - shaderDefines["ELLIPSOID_CONE_BOTTOM_INDEX"] = intersectionCount; - - if (hasBottomConeRegular) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_REGULAR"] = true; - intersectionCount += 1; - } else if (hasBottomConeFlipped) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLIPPED"] = true; - intersectionCount += 2; - } else if (hasBottomConeFlat) { - shaderDefines["ELLIPSOID_CONE_BOTTOM_FLAT"] = true; - intersectionCount += 1; - } } - // Intersects a cone for max latitude - if (hasTopCone) { - shaderDefines["ELLIPSOID_CONE_TOP"] = true; - shaderDefines["ELLIPSOID_CONE_TOP_INDEX"] = intersectionCount; - - if (hasTopConeRegular) { - shaderDefines["ELLIPSOID_CONE_TOP_REGULAR"] = true; - intersectionCount += 1; - } else if (hasTopConeFlipped) { - shaderDefines["ELLIPSOID_CONE_TOP_FLIPPED"] = true; - intersectionCount += 2; - } else if (hasTopConeFlat) { - shaderDefines["ELLIPSOID_CONE_TOP_FLAT"] = true; - intersectionCount += 1; - } + if (isSphere) { + shaderDefines["ELLIPSOID_IS_SPHERE"] = true; } - shaderDefines["ELLIPSOID_INTERSECTION_COUNT"] = intersectionCount; + this.shaderMaximumIntersectionsLength = intersectionCount; return true; }; @@ -549,19 +837,19 @@ VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( //>>includeEnd('debug'); const sizeAtLevel = 1.0 / Math.pow(2.0, tileLevel); - const westLerp = tileX * sizeAtLevel; - const eastLerp = (tileX + 1) * sizeAtLevel; - const southLerp = tileY * sizeAtLevel; - const northLerp = (tileY + 1) * sizeAtLevel; + const minLongitudeLerp = tileX * sizeAtLevel; + const maxLongitudeLerp = (tileX + 1) * sizeAtLevel; + const minLatitudeLerp = tileY * sizeAtLevel; + const maxLatitudeLerp = (tileY + 1) * sizeAtLevel; const minHeightLerp = tileZ * sizeAtLevel; const maxHeightLerp = (tileZ + 1) * sizeAtLevel; const rectangle = Rectangle.subsection( this._rectangle, - westLerp, - southLerp, - eastLerp, - northLerp, + minLongitudeLerp, + minLatitudeLerp, + maxLongitudeLerp, + maxLatitudeLerp, scratchRectangle ); diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index b63aa42b04e..5b7a32b81ae 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -420,8 +420,6 @@ function VoxelPrimitive(options) { cameraPositionUv: new Cartesian3(), ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), stepSize: 1.0, - minClippingBounds: new Cartesian3(), - maxClippingBounds: new Cartesian3(), pickColor: new Color(), }; @@ -1135,6 +1133,8 @@ VoxelPrimitive.prototype.update = function (frameState) { const maxBounds = defaultValue(provider.maxBounds, defaultMaxBounds); this._minBounds = Cartesian3.clone(minBounds, this._minBounds); this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); + this._minBoundsOld = Cartesian3.clone(this._minBounds, this._minBoundsOld); + this._maxBoundsOld = Cartesian3.clone(this._maxBounds, this._maxBoundsOld); this._minClippingBounds = Cartesian3.clone( defaultMinBounds, this._minClippingBounds @@ -1143,6 +1143,14 @@ VoxelPrimitive.prototype.update = function (frameState) { defaultMaxBounds, this._maxClippingBounds ); + this._minClippingBoundsOld = Cartesian3.clone( + this._minClippingBounds, + this._minClippingBoundsOld + ); + this._maxClippingBoundsOld = Cartesian3.clone( + this._maxClippingBounds, + this._maxClippingBoundsOld + ); // Create the shape object const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); @@ -1220,14 +1228,31 @@ VoxelPrimitive.prototype.update = function (frameState) { ); const shape = this._shape; - const shapeType = provider.shape; const minBounds = this._minBounds; const maxBounds = this._maxBounds; const minBoundsOld = this._minBoundsOld; const maxBoundsOld = this._maxBoundsOld; const minBoundsDirty = !Cartesian3.equals(minBounds, minBoundsOld); const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); - const shapeDirty = compoundTransformDirty || minBoundsDirty || maxBoundsDirty; + const clipMinBounds = this._minClippingBounds; + const clipMaxBounds = this._maxClippingBounds; + const clipMinBoundsOld = this._minClippingBoundsOld; + const clipMaxBoundsOld = this._maxClippingBoundsOld; + const clipMinBoundsDirty = !Cartesian3.equals( + clipMinBounds, + clipMinBoundsOld + ); + const clipMaxBoundsDirty = !Cartesian3.equals( + clipMaxBounds, + clipMaxBoundsOld + ); + + const shapeDirty = + compoundTransformDirty || + minBoundsDirty || + maxBoundsDirty || + clipMinBoundsDirty || + clipMaxBoundsDirty; if (shapeDirty) { if (compoundTransformDirty) { @@ -1242,13 +1267,31 @@ VoxelPrimitive.prototype.update = function (frameState) { if (maxBoundsDirty) { this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); } + if (clipMinBoundsDirty) { + this._minClippingBoundsOld = Cartesian3.clone( + clipMinBounds, + this._minClippingBoundsOld + ); + } + if (clipMaxBoundsDirty) { + this._maxClippingBoundsOld = Cartesian3.clone( + clipMaxBounds, + this._maxClippingBoundsOld + ); + } } // Update the shape on the first frame or if it's dirty. // If the shape is visible it will need to do some extra work. if ( (!this._ready || shapeDirty) && - (this._shapeVisible = shape.update(compoundTransform, minBounds, maxBounds)) + (this._shapeVisible = shape.update( + compoundTransform, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + )) ) { // Rebuild the shader if any of the shape defines changed. const shapeDefines = shape.shaderDefines; @@ -1472,125 +1515,6 @@ VoxelPrimitive.prototype.update = function (frameState) { } if (hasLoadedData && !this._disableRender) { - // Process clipping bounds. - const minClip = this._minClippingBounds; - const maxClip = this._maxClippingBounds; - - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); - - let isDefaultClippingBoundsMin = - minClip.x === defaultMinBounds.x && - minClip.y === defaultMinBounds.y && - minClip.z === defaultMinBounds.z; - - let isDefaultClippingBoundsMax = - maxClip.x === defaultMaxBounds.x && - maxClip.y === defaultMaxBounds.y && - maxClip.z === defaultMaxBounds.z; - - // Clamp the min bounds to the valid range. - if (!isDefaultClippingBoundsMin) { - minClip.x = CesiumMath.clamp( - minClip.x, - defaultMinBounds.x, - defaultMaxBounds.x - ); - minClip.y = CesiumMath.clamp( - minClip.y, - defaultMinBounds.y, - defaultMaxBounds.y - ); - if (shapeType !== VoxelShapeType.ELLIPSOID) { - minClip.z = CesiumMath.clamp( - minClip.z, - defaultMinBounds.z, - defaultMaxBounds.z - ); - } - isDefaultClippingBoundsMin = - minClip.x === defaultMinBounds.x && - minClip.y === defaultMinBounds.y && - minClip.z === defaultMinBounds.z; - } - - // Clamp the max bounds to the valid range. - if (!isDefaultClippingBoundsMax) { - maxClip.x = CesiumMath.clamp( - maxClip.x, - defaultMinBounds.x, - defaultMaxBounds.x - ); - maxClip.y = CesiumMath.clamp( - maxClip.y, - defaultMinBounds.y, - defaultMaxBounds.y - ); - if (shapeType !== VoxelShapeType.ELLIPSOID) { - maxClip.z = CesiumMath.clamp( - maxClip.z, - defaultMinBounds.z, - defaultMaxBounds.z - ); - } - isDefaultClippingBoundsMax = - maxClip.x === defaultMaxBounds.x && - maxClip.y === defaultMaxBounds.y && - maxClip.z === defaultMaxBounds.z; - } - - const minClipOld = this._minClippingBoundsOld; - const maxClipOld = this._maxClippingBoundsOld; - const minClipDirty = !Cartesian3.equals(minClip, minClipOld); - const maxClipDirty = !Cartesian3.equals(maxClip, maxClipOld); - const clippingBoundsDirty = minClipDirty || maxClipDirty; - - if (clippingBoundsDirty) { - if (minClipDirty) { - if ( - (minClip.x === defaultMinBounds.x) !== - (minClipOld.x === defaultMinBounds.x) || - (minClip.y === defaultMinBounds.y) !== - (minClipOld.y === defaultMinBounds.y) || - (minClip.z === defaultMinBounds.z) !== - (minClipOld.z === defaultMinBounds.z) - ) { - this._shaderDirty = true; - } - this._minClippingBoundsOld = Cartesian3.clone( - minClip, - this._minClippingBoundsOld - ); - } - if (maxClipDirty) { - if ( - (maxClip.x === defaultMaxBounds.x) !== - (maxClipOld.x === defaultMaxBounds.x) || - (maxClip.y === defaultMaxBounds.y) !== - (maxClipOld.y === defaultMaxBounds.y) || - (maxClip.z === defaultMaxBounds.z) !== - (maxClipOld.z === defaultMaxBounds.z) - ) { - this._shaderDirty = true; - } - this._maxClippingBoundsOld = Cartesian3.clone( - maxClip, - this._maxClippingBoundsOld - ); - } - if (!isDefaultClippingBoundsMin || !isDefaultClippingBoundsMax) { - // Set clipping uniforms - uniforms.minClippingBounds = Cartesian3.clone( - minClip, - uniforms.minClippingBounds - ); - uniforms.maxClippingBounds = Cartesian3.clone( - maxClip, - uniforms.maxClippingBounds - ); - } - } - // Check if log depth changed if (this._useLogDepth !== frameState.useLogDepth) { this._useLogDepth = frameState.useLogDepth; @@ -1834,11 +1758,6 @@ function buildDrawCommands(that, context) { attributeLength, ShaderDestination.FRAGMENT ); - shaderBuilder.addDefine( - `SHAPE_${shapeType}`, - undefined, - ShaderDestination.FRAGMENT - ); shaderBuilder.addDefine( "MEGATEXTURE_2D", @@ -1892,6 +1811,22 @@ function buildDrawCommands(that, context) { ); } + // Count how many intersections the shader will do. + let intersectionCount = shape.shaderMaximumIntersectionsLength; + if (depthTest) { + shaderBuilder.addDefine( + "DEPTH_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount += 1; + } + shaderBuilder.addDefine( + "INTERSECTION_COUNT", + intersectionCount, + ShaderDestination.FRAGMENT + ); + const sampleCount = keyframeCount > 1 ? 2 : 1; shaderBuilder.addDefine( "SAMPLE_COUNT", @@ -1900,6 +1835,12 @@ function buildDrawCommands(that, context) { ); // Shape specific defines + shaderBuilder.addDefine( + `SHAPE_${shapeType}`, + undefined, + ShaderDestination.FRAGMENT + ); + for (const key in shapeDefines) { if (shapeDefines.hasOwnProperty(key)) { let value = shapeDefines[key]; @@ -1912,21 +1853,6 @@ function buildDrawCommands(that, context) { } } - // const useClippingBounds = - // minClippingBounds.x !== defaultMinBounds.x || - // minClippingBounds.y !== defaultMinBounds.y || - // minClippingBounds.z !== defaultMinBounds.z || - // maxClippingBounds.x !== defaultMaxBounds.x || - // maxClippingBounds.y !== defaultMaxBounds.y || - // maxClippingBounds.z !== defaultMaxBounds.z; - // if (useClippingBounds) { - // shaderBuilder.addDefine( - // "CLIPPING_BOUNDS", - // undefined, - // ShaderDestination.FRAGMENT - // ); - // } - // Fragment shader uniforms // The reason this uniform is added by shader builder is because some of the diff --git a/Source/Scene/VoxelShape.js b/Source/Scene/VoxelShape.js index 4291a2563d3..f8449276f11 100644 --- a/Source/Scene/VoxelShape.js +++ b/Source/Scene/VoxelShape.js @@ -82,6 +82,15 @@ Object.defineProperties(VoxelShape.prototype, { shaderDefines: { get: DeveloperError.throwInstantiationError, }, + + /** + * The maximum number of intersections against the shape for any ray direction. + * @type {Number} + * @readonly + */ + shaderMaximumIntersectionsLength: { + get: DeveloperError.throwInstantiationError, + }, }); /** diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 60243c57f9b..4a9d86a5061 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -12,13 +12,13 @@ Below is an example of how this code might look. Properties like "temperature" a #define MEGATEXTURE_2D #define MEGATEXTURE_3D #define DEPTH_TEST +#define DEPTH_INTERSECTION_INDEX ### +#define INTERSECTION_COUNT ### #define JITTER #define NEAREST_SAMPLING #define DESPECKLE #define STATISTICS #define PADDING -#define BOUNDS -#define CLIPPING_BOUNDS #define PICKING // Uniforms @@ -184,60 +184,63 @@ uniform float u_stepSize; uniform vec4 u_pickColor; #endif -#if defined(CLIPPING_BOUNDS) - uniform vec3 u_minClippingBounds; - uniform vec3 u_maxClippingBounds; -#endif - #if defined(SHAPE_BOX) /* Box defines: - #define BOX_INTERSECTION_COUNT ### // always 1 #define BOX_INTERSECTION_INDEX ### // always 0 - #define BOX_IS_BOUNDED - #define BOX_IS_RECTANGLE + #define BOX_HAS_SHAPE_BOUND + #define BOX_HAS_RENDER_BOUND + #define BOX_IS_2D */ // Box uniforms: - #if defined(BOX_IS_BOUNDED) - uniform vec3 u_boxScaleUvToBoundsUv; - uniform vec3 u_boxOffsetUvToBoundsUv; - #if defined(BOX_IS_RECTANGLE) + #if defined(BOX_HAS_SHAPE_BOUND) + uniform vec3 u_boxScaleUvToShapeBoundsUv; + uniform vec3 u_boxOffsetUvToShapeBoundsUv; + #endif + #if defined(BOX_HAS_RENDER_BOUND) + #if defined(BOX_IS_2D) // This matrix bakes in an axis conversion so that the math works for XY plane. - uniform mat4 u_boxTransformUvToBounds; + uniform mat4 u_boxTransformUvToRenderBounds; #else // Similar to u_boxTransformUvToBounds but fewer instructions needed. - uniform vec3 u_boxScaleUvToBounds; - uniform vec3 u_boxOffsetUvToBounds; + uniform vec3 u_boxScaleUvToRenderBounds; + uniform vec3 u_boxOffsetUvToRenderBounds; #endif #endif #endif #if defined(SHAPE_ELLIPSOID) /* Ellipsoid defines: - #define ELLIPSOID_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections - #define ELLIPSOID_WEDGE - #define ELLIPSOID_WEDGE_INDEX ### - #define ELLIPSOID_WEDGE_REGULAR ### // when there's a wedge - #define ELLIPSOID_WEDGE_FLIPPED ### // when the wedge has two intersection intervals - #define ELLIPSOID_WEDGE_FLAT ### - #define ELLIPSOID_WEDGE_EMPTY - #define ELLIPSOID_WEDGE_ANGLE_FLIPPED // - #define ELLIPSOID_CONE_BOTTOM - #define ELLIPSOID_CONE_BOTTOM_REGULAR // when there's a bottom cone - #define ELLIPSOID_CONE_BOTTOM_FLIPPED // when cone shape has two intersection intervals - #define ELLIPSOID_CONE_BOTTOM_FLAT - #define ELLIPSOID_CONE_BOTTOM_INDEX ### - #define ELLIPSOID_CONE_TOP - #define ELLIPSOID_CONE_TOP_REGULAR ### // when there's a top cone - #define ELLIPSOID_CONE_TOP_FLIPPED ### // when cone shape has two intersection intervals - #define ELLIPSOID_CONE_TOP_FLAT - #define ELLIPSOID_CONE_TOP_INDEX ### - #define ELLIPSOID_OUTER ### // outer ellipsoid - always defined - #define ELLIPSOID_OUTER_INDEX ### - #define ELLIPSOID_INNER ### // when there's an inner ellipsoid - #define ELLIPSOID_INNER_INDEX ### - #define ELLIPSOID_INNER_OUTER_EQUAL + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN + #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN + #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO #define ELLIPSOID_IS_SPHERE + #define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX + #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN */ // Ellipsoid uniforms @@ -245,102 +248,85 @@ uniform float u_stepSize; #if !defined(ELLIPSOID_IS_SPHERE) uniform vec3 u_ellipsoidInverseRadiiSquaredUv; #endif - #if defined(ELLIPSOID_WEDGE) || defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) - uniform vec4 u_ellipsoidRectangle; // west [-pi,+pi], south [-halfPi,+halfPi], east [-pi,+pi], north [-halfPi,+halfPi]. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidRenderLongitudeMinMax; #endif - #if defined(ELLIPSOID_WEDGE) - #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) || defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) || defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - uniform float u_ellipsoidEmptyMidpointLongitudeUv; - #endif - #if defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) - uniform float u_ellipsoidMinLongitudeUv; - #endif - #if defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - uniform float u_ellipsoidMaxLongitudeUv; - #endif - uniform vec2 u_ellipsoidLongitudeUvScaleAndOffset; + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid; #endif - - #if defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP) - uniform vec2 u_ellipsoidLatitudeUvScaleAndOffset; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLongitude; // x = scale, y = offset #endif - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - uniform float u_ellipsoidMinLatitudeCosSqrHalfAngle; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset #endif - #if defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED) - uniform float u_ellipsoidMaxLatitudeCosSqrHalfAngle; + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + uniform vec2 u_ellipsoidRenderLatitudeCosSqrHalfMinMax; #endif - #if defined(ELLIPSOID_INNER) && !defined(ELLIPSOID_INNER_OUTER_EQUAL) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) uniform float u_ellipsoidInverseHeightDifferenceUv; - uniform float u_ellipsoidInverseInnerScaleUv; uniform vec2 u_ellipseInnerRadiiUv; // [0,1] #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) + uniform float u_ellipsoidInverseInnerScaleUv; + #endif #endif #if defined(SHAPE_CYLINDER) /* Cylinder defines: - #define CYLINDER_INTERSECTION_COUNT ### // the total number of enter and exit points for all the constituent intersections - #define CYLINDER_OUTER_INDEX ### // outer cylinder - #define CYLINDER_OUTER_NON_DEFAULT ### // - #define CYLINDER_INNER - #define CYLINDER_INNER_OUTER_EQUAL ### // when inner and outer cylinder have the same radius - #define CYLINDER_INNER_INDEX ### // when there's an inner cylinder - #define CYLINDER_HEIGHT_NON_DEFAULT ### // - #define CYLINDER_HEIGHT_ZERO // when the height is 0 - #define CYLINDER_WEDGE // - #define CYLINDER_WEDGE_INDEX // - #define CYLINDER_WEDGE_REGULAR ### // when there's a wedge - #define CYLINDER_WEDGE_FLIPPED ### // when the wedge has two intersection intervals - #define CYLINDER_WEDGE_FLAT - #define CYLINDER_WEDGE_EMPTY - #define CYLINDER_WEDGE_ANGLE_FLIPPED // - #define CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY - #define CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT + #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT + #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO + + #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS + #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT + #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT + #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED + + #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX + #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN + #define CYLINDER_INTERSECTION_INDEX_ANGLE + */ // Cylinder uniforms - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) - uniform vec3 u_cylinderScaleUvToBounds; - uniform vec3 u_cylinderTranslateUvToBounds; + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + uniform vec3 u_cylinderUvToRenderBoundsScale; + uniform vec3 u_cylinderUvToRenderBoundsTranslate; #endif - #if defined(CYLINDER_INNER) && !defined(CYLINDER_INNER_OUTER_EQUAL) - uniform float u_cylinderInverseInnerRadiusUv; + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + uniform float u_cylinderUvToRenderRadiusMin; #endif - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - uniform vec2 u_cylinderRadiusUvScaleAndOffset; + #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE) + uniform vec2 u_cylinderRenderAngleMinMax; #endif - #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - uniform vec2 u_cylinderHeightUvScaleAndOffset; + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + uniform vec2 u_cylinderUvToShapeUvRadius; // x = scale, y = offset #endif - #if defined(CYLINDER_WEDGE) - uniform vec2 u_cylinderAngleMinMax; - uniform vec2 u_cylinderAngleUvScaleAndOffset; - #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) || defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) || defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - uniform float u_cylinderEmptyMidpointAngleUv; - #endif - #if defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) - uniform float u_cylinderMinAngleUv; - #endif - #if defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - uniform float u_cylinderMaxAngleUv; - #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + uniform vec2 u_cylinderUvToShapeUvHeight; // x = scale, y = offset + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + uniform vec2 u_cylinderUvToShapeUvAngle; // x = scale, y = offset + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + uniform vec2 u_cylinderShapeUvAngleMinMax; + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + uniform float u_cylinderShapeUvAngleEmptyMid; #endif -#endif - -// Keep track of how many intersections there are going to be -#if defined(SHAPE_BOX) - #define SHAPE_INTERSECTION_COUNT BOX_INTERSECTION_COUNT -#elif defined(SHAPE_ELLIPSOID) - #define SHAPE_INTERSECTION_COUNT ELLIPSOID_INTERSECTION_COUNT -#elif defined(SHAPE_CYLINDER) - #define SHAPE_INTERSECTION_COUNT CYLINDER_INTERSECTION_COUNT -#endif - -#if defined(DEPTH_TEST) - #define DEPTH_INTERSECTION_INDEX SHAPE_INTERSECTION_COUNT - #define SCENE_INTERSECTION_COUNT (SHAPE_INTERSECTION_COUNT + 1) -#else - #define SCENE_INTERSECTION_COUNT SHAPE_INTERSECTION_COUNT #endif // -------------------------------------------------------- @@ -406,7 +392,7 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) struct Intersections { // Don't access these member variables directly - call the functions instead. - #if (SCENE_INTERSECTION_COUNT > 1) + #if (INTERSECTION_COUNT > 1) // Store an array of intersections. Each intersection is composed of: // x for the T value // y for the shape type - which encodes positive vs negative and entering vs exiting @@ -415,7 +401,7 @@ struct Intersections { // y = 1: positive shape exit // y = 2: negative shape entry // y = 3: negative shape exit - vec2 intersections[SCENE_INTERSECTION_COUNT * 2]; + vec2 intersections[INTERSECTION_COUNT * 2]; // Maintain state for future nextIntersection calls int index; @@ -428,7 +414,7 @@ struct Intersections { }; // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (SCENE_INTERSECTION_COUNT > 1) +#if (INTERSECTION_COUNT > 1) #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x #else #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] @@ -438,25 +424,25 @@ struct Intersections { #define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (SCENE_INTERSECTION_COUNT > 1) +#if (INTERSECTION_COUNT > 1) #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) #else #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) #endif // Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (SCENE_INTERSECTION_COUNT > 1) +#if (INTERSECTION_COUNT > 1) #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) #else #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y #endif -#if (SCENE_INTERSECTION_COUNT > 1) +#if (INTERSECTION_COUNT > 1) vec2 nextIntersection(inout Intersections ix) { vec2 entryExitT = vec2(NO_HIT); - const int passCount = SCENE_INTERSECTION_COUNT * 2; - for (int i = 0; i < passCount; i++) { + const int passCount = INTERSECTION_COUNT * 2; + for (int i = 0; i < passCount; ++i) { // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot // loop with non-constant condition, so it has to continue instead. if (i < ix.index) { @@ -486,7 +472,7 @@ vec2 nextIntersection(inout Intersections ix) { // entry and exit have been found, so the loop can stop if (exitPositive) { // After exiting positive shape there is nothing left to intersect, so jump to the end index. - ix.index = SCENE_INTERSECTION_COUNT * 2; + ix.index = passCount; } else { // There could be more intersections against the positive shape in the future. ix.index = i + 1; @@ -499,12 +485,12 @@ vec2 nextIntersection(inout Intersections ix) { } #endif -#if (SCENE_INTERSECTION_COUNT > 1) +#if (INTERSECTION_COUNT > 1) void initializeIntersections(inout Intersections ix) { // Sort the intersections from min T to max T with bubble sort. // Note: If this sorting function changes, some of the intersection test may // need to be updated. Search for "bubble sort" to find those areas. - const int sortPasses = SCENE_INTERSECTION_COUNT * 2 - 1; + const int sortPasses = INTERSECTION_COUNT * 2 - 1; for (int n = sortPasses; n > 0; --n) { for (int i = 0; i < sortPasses; ++i) { // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot @@ -575,7 +561,7 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLAT)) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF)) vec2 intersectZPlane(Ray ray) { float o = ray.pos.z; @@ -588,7 +574,7 @@ vec2 intersectZPlane(Ray ray) } #endif -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_EMPTY)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_EMPTY)) +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO)) vec4 intersectHalfPlane(Ray ray, float angle) { vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; @@ -607,7 +593,7 @@ vec4 intersectHalfPlane(Ray ray, float angle) { } #endif -#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_WEDGE_FLIPPED) || defined(ELLIPSOID_WEDGE_FLAT))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_WEDGE_FLIPPED) || defined(CYLINDER_WEDGE_FLAT))) +#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF))) vec2 intersectHalfSpace(Ray ray, float angle) { vec2 o = ray.pos.xy; @@ -624,7 +610,7 @@ vec2 intersectHalfSpace(Ray ray, float angle) } #endif -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_REGULAR)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_REGULAR)) +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)) vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) { vec2 o = ray.pos.xy; @@ -659,7 +645,7 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) } #endif -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_WEDGE_FLIPPED)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_WEDGE_FLIPPED)) +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)) vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) { vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); @@ -717,7 +703,7 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_REGULAR) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +#if defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE) vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) { vec3 o = ray.pos; @@ -740,7 +726,7 @@ vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) || defined(ELLIPSOID_CONE_TOP_FLIPPED)) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF)) vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); @@ -764,7 +750,7 @@ vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_TOP_REGULAR)) +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF)) vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); @@ -843,7 +829,7 @@ vec2 intersectUnitCircle(Ray ray) { } #endif -#if defined(SHAPE_CYLINDER) && defined(CYLINDER_INNER) +#if defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) vec2 intersectInfiniteUnitCylinder(Ray ray) { vec3 o = ray.pos; @@ -883,7 +869,7 @@ float ellipseDistanceIterative (vec2 pos, vec2 radii) { vec2 v = radii * t; const int iterations = 3; - for (int i = 0; i < iterations; i++) { + for (int i = 0; i < iterations; ++i) { vec2 e = a * pow(t, vec2(3.0)); vec2 q = normalize(p - e) * length(v - e); t = normalize((q + e) * invRadii); @@ -945,19 +931,21 @@ float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { #endif #if defined(SHAPE_BOX) -void intersectBoxShape(Ray ray, out Intersections ix) +void intersectShape(Ray ray, inout Intersections ix) { - #if defined(BOX_IS_RECTANGLE) - // Transform the ray into unit square space on Z plane - // This matrix bakes in an axis conversion so that the math works for XY plane. - ray.pos = vec3(u_boxTransformUvToBounds * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxTransformUvToBounds * vec4(ray.dir, 0.0)); - vec2 entryExit = intersectUnitSquare(ray); - #elif defined(BOX_IS_BOUNDED) - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToBounds + u_boxOffsetUvToBounds; - ray.dir *= u_boxScaleUvToBounds; - vec2 entryExit = intersectUnitCube(ray); + #if defined(BOX_HAS_RENDER_BOUND) + #if defined(BOX_IS_2D) + // Transform the ray into unit square space on Z plane + // This matrix bakes in an axis conversion so that the math works for XY plane. + ray.pos = vec3(u_boxTransformUvToRenderBounds * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxTransformUvToRenderBounds * vec4(ray.dir, 0.0)); + vec2 entryExit = intersectUnitSquare(ray); + #else + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToRenderBounds + u_boxOffsetUvToRenderBounds; + ray.dir *= u_boxScaleUvToRenderBounds; + vec2 entryExit = intersectUnitCube(ray); + #endif #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. @@ -971,9 +959,9 @@ void intersectBoxShape(Ray ray, out Intersections ix) #endif #if defined(SHAPE_BOX) -vec3 transformFromUvToBoxSpace(in vec3 positionUv) { - #if defined(BOX_IS_BOUNDED) - return positionUv * u_boxScaleUvToBoundsUv + u_boxOffsetUvToBoundsUv; +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + #if defined(BOX_HAS_SHAPE_BOUND) + return positionUv * u_boxScaleUvToShapeBoundsUv + u_boxOffsetUvToShapeBoundsUv; #else return positionUv; #endif @@ -981,7 +969,7 @@ vec3 transformFromUvToBoxSpace(in vec3 positionUv) { #endif #if defined(SHAPE_ELLIPSOID) -void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { +void intersectShape(in Ray ray, inout Intersections ix) { // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. ray.pos = ray.pos * 2.0 - 1.0; @@ -989,7 +977,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { // Outer ellipsoid vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersectionPair(ix, ELLIPSOID_OUTER_INDEX, outerIntersect); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); // Exit early if the outer ellipsoid was missed. if (outerIntersect.x == NO_HIT) { @@ -997,7 +985,7 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { } // Inner ellipsoid - #if defined(ELLIPSOID_INNER_OUTER_EQUAL) + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) // When the ellipsoid is perfectly thin it's necessary to sandwich the // inner ellipsoid intersection inside the outer ellipsoid intersection. @@ -1018,74 +1006,66 @@ void intersectEllipsoidShape(in Ray ray, inout Intersections ix) { setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(ELLIPSOID_INNER) + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INNER_INDEX, innerIntersect); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); #endif // Flip the ray because the intersection function expects a cone growing towards +Z. - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) || defined(ELLIPSOID_CONE_BOTTOM_FLAT) || defined(ELLIPSOID_CONE_TOP_FLIPPED) + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) Ray flippedRay = ray; flippedRay.dir.z *= -1.0; flippedRay.pos.z *= -1.0; #endif // Bottom cone - #if defined(ELLIPSOID_CONE_BOTTOM) - #if defined(ELLIPSOID_CONE_BOTTOM_REGULAR) - vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidMinLatitudeCosSqrHalfAngle); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); - #elif defined(ELLIPSOID_CONE_BOTTOM_FLIPPED) - vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidMinLatitudeCosSqrHalfAngle); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 0, bottomConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX + 1, bottomConeIntersection.zw); - #elif defined(ELLIPSOID_CONE_BOTTOM_FLAT) - vec2 bottomConeIntersection = intersectZPlane(flippedRay); - setIntersectionPair(ix, ELLIPSOID_CONE_BOTTOM_INDEX, bottomConeIntersection); - #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) + vec2 bottomConeIntersection = intersectZPlane(flippedRay); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) + vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); #endif // Top cone - #if defined(ELLIPSOID_CONE_TOP) - #if defined(ELLIPSOID_CONE_TOP_REGULAR) - vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidMaxLatitudeCosSqrHalfAngle); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); - #elif defined(ELLIPSOID_CONE_TOP_FLIPPED) - vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidMaxLatitudeCosSqrHalfAngle); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 0, topConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX + 1, topConeIntersection.zw); - #elif defined(ELLIPSOID_CONE_TOP_FLAT) - vec2 topConeIntersection = intersectZPlane(ray); - setIntersectionPair(ix, ELLIPSOID_CONE_TOP_INDEX, topConeIntersection); - #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) + vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersection.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF) + vec2 topConeIntersection = intersectZPlane(ray); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); #endif // Wedge - #if defined(ELLIPSOID_WEDGE) - float west = u_ellipsoidRectangle.x; // [-pi,+pi] - float east = u_ellipsoidRectangle.z; // [-pi,+pi] - #if defined(ELLIPSOID_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectRegularWedge(ray, west, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX, wedgeIntersect); - #elif defined(ELLIPSOID_WEDGE_FLIPPED) - vec4 wedgeIntersect = intersectFlippedWedge(ray, west, east); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 1, wedgeIntersect.zw); - #elif defined(ELLIPSOID_WEDGE_FLAT) - vec2 wedgeIntersect = intersectHalfSpace(ray, west); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX, wedgeIntersect); - #elif defined(ELLIPSOID_WEDGE_EMPTY) - vec4 wedgeIntersect = intersectHalfPlane(ray, west); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_WEDGE_INDEX + 1, wedgeIntersect.zw); - #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); #endif } #endif #if defined(SHAPE_ELLIPSOID) -vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { // Compute position and normal. // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. @@ -1099,44 +1079,55 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { #endif // Compute longitude - float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; - #if defined(ELLIPSOID_WEDGE) - #if defined(ELLIPSOID_WEDGE_ANGLE_FLIPPED) - // Comparing against u_ellipsoidMinAngleUv has precision problems. u_ellipsoidEmptyMidpointAngleUv is more conservative. - longitude += float(longitude < u_ellipsoidEmptyMidpointLongitudeUv); + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + float longitude = 1.0; + #else + float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; + + // Correct the angle when max < min + // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + longitude += float(longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z); #endif - // When the min or max angle is near the -pi/+pi discontinuity there may be flickering as both sides of the voxel data are read. - #if defined(ELLIPSOID_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) - longitude = longitude > u_ellipsoidEmptyMidpointLongitudeUv ? u_ellipsoidMinLongitudeUv : longitude; - #elif defined(ELLIPSOID_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - longitude = longitude < u_ellipsoidEmptyMidpointLongitudeUv ? u_ellipsoidMaxLongitudeUv : longitude; + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) + longitude = longitude > u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.x : longitude; + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) + longitude = longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.y : longitude; #endif - longitude = longitude * u_ellipsoidLongitudeUvScaleAndOffset.x + u_ellipsoidLongitudeUvScaleAndOffset.y; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y; + #endif #endif // Compute latitude - float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; - #if (defined(ELLIPSOID_CONE_BOTTOM) || defined(ELLIPSOID_CONE_TOP)) - latitude = latitude * u_ellipsoidLatitudeUvScaleAndOffset.x + u_ellipsoidLatitudeUvScaleAndOffset.y; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) + float latitude = 1.0; + #else + float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y; + #endif #endif // Compute height - #if defined(ELLIPSOID_INNER_OUTER_EQUAL) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) // TODO: This breaks down when minBounds == maxBounds. To fix it, this // function would have to know if ray is intersecting the front or back of the shape // and set the shape space position to 1 (front) or 0 (back) accordingly. float height = 1.0; #else #if defined(ELLIPSOID_IS_SPHERE) - #if defined(ELLIPSOID_INNER) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; #else float height = length(posEllipsoid); #endif #else - #if defined(ELLIPSOID_INNER) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). // This is an optimization so that math can be done with ellipses instead of ellipsoids. vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); @@ -1153,11 +1144,11 @@ vec3 transformFromUvToEllipsoidSpace(in vec3 positionUv) { #endif #if defined(SHAPE_CYLINDER) -void intersectCylinderShape(Ray ray, inout Intersections ix) +void intersectShape(Ray ray, inout Intersections ix) { - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) || defined(CYLINDER_HEIGHT_NON_DEFAULT) - ray.pos = ray.pos * u_cylinderScaleUvToBounds + u_cylinderTranslateUvToBounds; - ray.dir *= u_cylinderScaleUvToBounds; + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate; + ray.dir *= u_cylinderUvToRenderBoundsScale; #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. @@ -1165,19 +1156,19 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) ray.dir *= 2.0; #endif - #if defined(CYLINDER_HEIGHT_ZERO) + #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) vec2 outerIntersect = intersectUnitCircle(ray); #else vec2 outerIntersect = intersectUnitCylinder(ray); #endif - setIntersectionPair(ix, CYLINDER_OUTER_INDEX, outerIntersect); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect); if (outerIntersect.x == NO_HIT) { return; } - #if defined(CYLINDER_INNER_OUTER_EQUAL) + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) // When the cylinder is perfectly thin it's necessary to sandwich the // inner cylinder intersection inside the outer cylinder intersection. @@ -1199,107 +1190,93 @@ void intersectCylinderShape(Ray ray, inout Intersections ix) setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(CYLINDER_INNER) - Ray innerRay = Ray(ray.pos * u_cylinderInverseInnerRadiusUv, ray.dir * u_cylinderInverseInnerRadiusUv); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) + Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin); vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - setIntersectionPair(ix, CYLINDER_INNER_INDEX, innerIntersect); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect); #endif - #if defined(CYLINDER_WEDGE_REGULAR) - vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); - #elif defined(CYLINDER_WEDGE_FLIPPED) - vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderAngleMinMax.x, u_cylinderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); - #elif defined(CYLINDER_WEDGE_FLAT) - vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX, wedgeIntersect); - #elif defined(CYLINDER_WEDGE_EMPTY) - vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_WEDGE_INDEX + 1, wedgeIntersect.zw); + #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); #endif } #endif #if defined(SHAPE_CYLINDER) -vec3 transformFromUvToCylinderSpace(in vec3 positionUv) { +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] // Compute radius - #if defined(CYLINDER_INNER_OUTER_EQUAL) - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) float radius = 1.0; #else float radius = length(positionLocal.xy); // [0,1] - #if defined(CYLINDER_OUTER_NON_DEFAULT) || defined(CYLINDER_INNER) - radius = radius * u_cylinderRadiusUvScaleAndOffset.x + u_cylinderRadiusUvScaleAndOffset.y; + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset #endif #endif // Compute height - float height = positionUv.z; // [0,1] - #if defined(CYLINDER_HEIGHT_NON_DEFAULT) - height = height * u_cylinderHeightUvScaleAndOffset.x + u_cylinderHeightUvScaleAndOffset.y; + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) + float height = 1.0; + #else + float height = positionUv.z; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset + #endif #endif // Compute angle - float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - #if defined(CYLINDER_WEDGE) - #if defined(CYLINDER_WEDGE_ANGLE_FLIPPED) - // Comparing against u_cylinderMinAngleUv has precision problems. u_cylinderEmptyMidpointAngleUv is more conservative. - angle += float(angle < u_cylinderEmptyMidpointAngleUv); - #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + float angle = 1.0; + #else + float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. + angle += float(angle < u_cylinderShapeUvAngleEmptyMid); + #endif - // When the min or max angle is near the -pi/+pi discontinuity there may be flickering as both sides of the voxel data are read. - #if defined(CYLINDER_WEDGE_MIN_ANGLE_ON_DISCONTINUITY) - angle = angle > u_cylinderEmptyMidpointAngleUv ? u_cylinderMinAngleUv : angle; - #elif defined(CYLINDER_WEDGE_MAX_ANGLE_ON_DISCONTINUITY) - angle = angle < u_cylinderEmptyMidpointAngleUv ? u_cylinderMaxAngleUv : angle; - #endif + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) + angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; + #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; + #endif - angle = angle * u_cylinderAngleUvScaleAndOffset.x + u_cylinderAngleUvScaleAndOffset.y; + angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset + #endif #endif return vec3(radius, height, angle); } #endif -vec3 transformFromUvToShapeSpace(in vec3 positionUv) { - #if defined(SHAPE_BOX) - return transformFromUvToBoxSpace(positionUv); - #elif defined(SHAPE_ELLIPSOID) - return transformFromUvToEllipsoidSpace(positionUv); - #elif defined(SHAPE_CYLINDER) - return transformFromUvToCylinderSpace(positionUv); - #endif -} - -void intersectShape(Ray ray, out Intersections ix) { - #if defined(SHAPE_BOX) - intersectBoxShape(ray, ix); - #elif defined(SHAPE_ELLIPSOID) - intersectEllipsoidShape(ray, ix); - #elif defined(SHAPE_CYLINDER) - intersectCylinderShape(ray, ix); - #endif -} - #if defined(DEPTH_TEST) -float intersectDepth(vec2 screenCoord, Ray ray) { +void intersectDepth(vec2 screenCoord, Ray ray, inout Intersections ix) { float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); if (logDepthOrDepth != 0.0) { // Calculate how far the ray must travel before it hits the depth buffer. vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); eyeCoordinateDepth /= eyeCoordinateDepth.w; vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - return dot(depthPositionUv - ray.pos, ray.dir); + float t = dot(depthPositionUv - ray.pos, ray.dir); + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(t, +INF_HIT)); } else { - // There's no depth at this position so set it to some really far value. - return +INF_HIT; + // There's no depth at this location. + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(NO_HIT)); } } #endif @@ -1312,20 +1289,20 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int // Exit early if the positive shape was completely missed or behind the ray. vec2 entryExitT = getIntersectionPair(ix, 0); - if (entryExitT.x < 0.0 && entryExitT.y < 0.0) { + if (entryExitT.x == NO_HIT) { + // Positive shape was completely missed - so exit early. return vec2(NO_HIT); } - // Add depth to the list of intersections + // Depth #if defined(DEPTH_TEST) - float depthT = intersectDepth(screenCoord, ray); - setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(depthT, +INF_HIT)); + intersectDepth(screenCoord, ray, ix); #endif // Find the first intersection that's in front of the ray - #if (SCENE_INTERSECTION_COUNT > 1) + #if (INTERSECTION_COUNT > 1) initializeIntersections(ix); - for (int i = 0; i < SCENE_INTERSECTION_COUNT; i++) { + for (int i = 0; i < INTERSECTION_COUNT; ++i) { entryExitT = nextIntersection(ix); if (entryExitT.y > 0.0) { // Set start to 0.0 when ray is inside the shape. @@ -1358,7 +1335,7 @@ Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxel // Final location in the megatexture vec3 uv = tileUvOffset + voxelUvOffset; - for (int i = 0; i < PROPERTY_COUNT; i++) { + for (int i = 0; i < PROPERTY_COUNT; ++i) { vec4 sample = texture3D(u_megatextureTextures[i], uv); samples[i] = decodeTextureSample(sample); } @@ -1474,7 +1451,7 @@ Properties getPropertiesFromMegatextureAtLocalPosition(vec3 positionUvLocal, ive #else // When more than one sample is taken the accumulator needs to start at 0 Properties properties = clearProperties(); - for (int i = 0; i < SAMPLE_COUNT; i++) { + for (int i = 0; i < SAMPLE_COUNT; ++i) { vec3 actualUv = computeAncestorUv(positionUvLocal, sampleDatas[i].levelsAbove, octreeCoords); Properties tempProperties = getPropertiesFromMegatextureAtTileUv(actualUvLocal, sampleDatas[i].megatextureIndex); properties = sumProperties(properties, tempProperties) @@ -1550,7 +1527,7 @@ void traverseOctreeDownwards(in vec3 positionUv, inout ivec4 octreeCoords, inout vec3 start = vec3(octreeCoords.xyz) * sizeAtLevel; vec3 end = start + vec3(sizeAtLevel); - for (int i = 0; i < OCTREE_MAX_LEVELS; i++) { + for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { // Find out which octree child contains the position // 0 if before center, 1 if after vec3 center = 0.5 * (start + end); @@ -1580,7 +1557,7 @@ void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 parentOctreeIndex = 0; // TODO: is it possible for this to be out of bounds, and does it matter? - positionUvShapeSpace = transformFromUvToShapeSpace(positionUv); + positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); positionUvLocal = positionUvShapeSpace; OctreeNodeData rootData = getOctreeRootData(); @@ -1599,7 +1576,7 @@ void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, inout float levelStepMult, inout ivec4 octreeCoords, inout int parentOctreeIndex, inout SampleData sampleDatas[SAMPLE_COUNT]) { float dimAtLevel = pow(2.0, float(octreeCoords.w)); - positionUvShapeSpace = transformFromUvToShapeSpace(positionUv); + positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); // Note: This code assumes the position is always inside the root tile. @@ -1608,7 +1585,7 @@ void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpac if (!insideTile) { // Go up tree - for (int i = 0; i < OCTREE_MAX_LEVELS; i++) + for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { octreeCoords.xyz /= ivec3(2); octreeCoords.w -= 1; @@ -1641,14 +1618,13 @@ void main() vec3 viewPosUv = u_cameraPositionUv; Intersections ix; - vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); + vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); // Exit early if the scene was completely missed. if (entryExitT.x == NO_HIT) { discard; } - float currT = entryExitT.x; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; @@ -1684,7 +1660,7 @@ void main() setStatistics(fragmentInput.metadata.statistics); #endif - for (int stepCount = 0; stepCount < STEP_COUNT_MAX; stepCount++) { + for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state Properties properties = getPropertiesFromMegatextureAtLocalPosition(positionUvLocal, octreeCoords, sampleDatas); @@ -1748,7 +1724,7 @@ void main() // Check if there's more intersections. if (currT > endT) { - #if (SCENE_INTERSECTION_COUNT == 1) + #if (INTERSECTION_COUNT == 1) break; #else vec2 entryExitT = nextIntersection(ix); diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 8414b50a1d7..648fa10564a 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -678,7 +678,8 @@ function VoxelInspectorViewModel(scene) { ); }, getPrimitiveFunction: function () { - that.clippingBoxMinY = that._voxelPrimitive.minClippingBounds.y; + that.clippingEllipsoidMinLatitude = + that._voxelPrimitive.minClippingBounds.y; }, }); addProperty({ From cbe900490c9bced74dfb74b78c7c6d31789fca97 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 21 Apr 2022 17:14:50 -0400 Subject: [PATCH 041/679] default voxel provider and latitude fix --- Source/Scene/VoxelEllipsoidShape.js | 6 ++- Source/Scene/VoxelPrimitive.js | 62 +++++++++++++++++------------ Source/Shaders/VoxelFS.glsl | 6 ++- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 51708ae4b9f..728a846a45c 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -774,6 +774,8 @@ VoxelEllipsoidShape.prototype.update = function ( } if (hasLatitudeShape) { + shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE"] = true; + if (latitudeMinShape === latitudeMaxShape) { shaderDefines[ "ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO" @@ -792,10 +794,10 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = (-pi - minLatitude) / (maxLatitude - minLatitude) const scale = latitudeRangeDefault / latitudeRangeShape; const offset = (latitudeMinDefault - latitudeMinShape) / latitudeRangeShape; - shaderUniforms.ellipsoidLatitudeUvScaleAndOffset = Cartesian2.fromElements( + shaderUniforms.ellipsoidUvToShapeUvLatitude = Cartesian2.fromElements( scale, offset, - shaderUniforms.ellipsoidLatitudeUvScaleAndOffset + shaderUniforms.ellipsoidUvToShapeUvLatitude ); } diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 5b7a32b81ae..98290b8ecb7 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -15,42 +15,30 @@ import JulianDate from "../Core/JulianDate.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import PrimitiveType from "../Core/PrimitiveType.js"; -import RenderState from "../Renderer/RenderState.js"; -import ShaderDestination from "../Renderer/ShaderDestination.js"; import BlendingState from "./BlendingState.js"; import CullFace from "./CullFace.js"; -import CustomShader from "./ModelExperimental/CustomShader.js"; import Material from "./Material.js"; +import MetadataComponentType from "./MetadataComponentType.js"; +import MetadataType from "./MetadataType.js"; import PolylineCollection from "./PolylineCollection.js"; import VoxelShapeType from "./VoxelShapeType.js"; import VoxelTraversal from "./VoxelTraversal.js"; +import CustomShader from "./ModelExperimental/CustomShader.js"; import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; +import RenderState from "../Renderer/RenderState.js"; import ShaderBuilder from "../Renderer/ShaderBuilder.js"; +import ShaderDestination from "../Renderer/ShaderDestination.js"; import VoxelFS from "../Shaders/VoxelFS.js"; import VoxelVS from "../Shaders/VoxelVS.js"; -import MetadataType from "./MetadataType.js"; /** * A primitive that renders voxel data from a {@link VoxelProvider}. * - * TODO: make sure the following terms/definitions are consistent across all files - * world space: Cartesian WGS84 - * local space: Cartesian [-0.5, 0.5] aligned with shape. - * For box, the origin is the center of the box, and the six sides sit on the planes x = -0.5, x = 0.5 etc. - * For cylinder, the origin is the center of the cylinder with the cylinder enclosed by the [-0.5, 0.5] box on xy-plane. Positive x-axis points to theta = 0. The top and bottom caps sit at planes z = -0.5, z = 0.5. Positive y points to theta = pi/2 - * For ellipsoid, the origin is the center of the ellipsoid. The maximum height of the ellipsoid touches -0.5, 0.5 in xyz directions. - * intersection space: local space times 2 to be [-1, 1]. Used for ray intersection calculation - * UV space: local space plus 0.5 to be [0, 1]. - * shape space: In the coordinate system of the shape [0, 1] - * For box, this is the same as UV space - * For cylinder, the coordinate system is (radius, theta, z). theta = 0 is aligned with x axis - * For ellipsoid, the coordinate system is (longitude, latitude, height). where 0 is the minimum value in each dimension, and 1 is the max. - * * @alias VoxelPrimitive * @constructor * - * @param {Object} options Object with the following properties: - * @param {VoxelProvider} options.provider The voxel provider that supplies the primitive with tile data. + * @param {Object} [options] Object with the following properties: + * @param {VoxelProvider} [options.provider] The voxel provider that supplies the primitive with tile data. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix used to transform the primitive. * @param {CustomShader} [options.customShader] The custom shader used to style the primitive. * @param {Clock} [options.clock] The clock used to control time dynamic behavior. @@ -65,10 +53,6 @@ import MetadataType from "./MetadataType.js"; function VoxelPrimitive(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - Check.defined("options.provider", options.provider); - //>>includeEnd('debug'); - /** * @type {Boolean} * @private @@ -85,7 +69,10 @@ function VoxelPrimitive(options) { * @type {VoxelProvider} * @private */ - this._provider = options.provider; + this._provider = defaultValue( + options.provider, + VoxelPrimitive.DefaultProvider + ); /** * This member is not created until the provider and shape are ready. @@ -1972,7 +1959,7 @@ function buildDrawCommands(that, context) { } shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvShapeSpace"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionShapeUv"); shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); @@ -2167,7 +2154,8 @@ function buildDrawCommands(that, context) { enabled: false, }, depthMask: false, - blending: BlendingState.ALPHA_BLEND, + // internally the shader does premultiplied alpha, so it makes sense to blend that way too + blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, }); // Create the draw commands @@ -2523,4 +2511,26 @@ VoxelPrimitive.DefaultCustomShader = new CustomShader({ }`, }); +function DefaultVoxelProvider() { + this.ready = true; + this.readyPromise = Promise.resolve(this); + this.shape = VoxelShapeType.BOX; + this.dimensions = new Cartesian3(1, 1, 1); + this.names = ["data"]; + this.types = [MetadataType.SCALAR]; + this.componentTypes = [MetadataComponentType.FLOAT32]; + this.maximumTileCount = 1; +} + +DefaultVoxelProvider.prototype.requestData = function (options) { + const tileLevel = defined(options) ? defaultValue(options.tileLevel, 0) : 0; + if (tileLevel >= 1) { + return undefined; + } + + return Promise.resolve([new Float32Array(1)]); +}; + +VoxelPrimitive.DefaultProvider = new DefaultVoxelProvider(); + export default VoxelPrimitive; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 4a9d86a5061..802b629d6bb 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -59,7 +59,7 @@ struct Voxel { VoxelProperty_direction direction; vec3 positionEC; vec3 positionUv; - vec3 positionUvShapeSpace; + vec3 positionShapeUv; vec3 positionUvLocal; vec3 viewDirUv; vec3 viewDirWorld; @@ -1629,6 +1629,8 @@ void main() float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; + // gl_FragColor = vec4(convertUvToShapeUvSpace(positionUv).yyy, 1.0); return; + vec4 colorAccum = vec4(0.0); #if defined(DESPECKLE) @@ -1667,7 +1669,7 @@ void main() // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); fragmentInput.voxel.positionUv = positionUv; - fragmentInput.voxel.positionUvShapeSpace = positionUvShapeSpace; + fragmentInput.voxel.positionShapeUv = positionUvShapeSpace; fragmentInput.voxel.positionUvLocal = positionUvLocal; fragmentInput.voxel.viewDirUv = viewDirUv; fragmentInput.voxel.viewDirWorld = viewDirWorld; From 4608f9b673f4c6dbf570b1899037eabbf16fde90 Mon Sep 17 00:00:00 2001 From: IanLilleyT Date: Thu, 21 Apr 2022 17:15:39 -0400 Subject: [PATCH 042/679] sandcastle tweaks --- Apps/Sandcastle/gallery/Voxels.html | 71 ++++++++++++++++------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index b8b1321c0cb..048c6a58984 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -84,8 +84,12 @@ break; } case Cesium.VoxelShapeType.CYLINDER: { - this.minBounds = new Cesium.Cartesian3(0.0, -1.0, +0.2); - this.maxBounds = new Cesium.Cartesian3(1.0, +1.0, -0.2); + // this.minBounds = new Cesium.Cartesian3( + // 0.0, + // -1.0, + // -Cesium.Math.PI + // ); + // this.maxBounds = new Cesium.Cartesian3(1.0, +1.0, -Cesium.Math.PI + 0.5); break; } } @@ -154,6 +158,10 @@ dataColor[index * channelCount + 2] = color.blue; dataColor[index * channelCount + 3] = 0.75; // } + // dataColor[index * channelCount + 0] = lerperX; + // dataColor[index * channelCount + 1] = lerperY; + // dataColor[index * channelCount + 2] = lerperZ; + // dataColor[index * channelCount + 3] = 1.0; //0.75; } } } @@ -356,12 +364,12 @@ provider: provider, customShader: customShader, modelMatrix: Cesium.Matrix4.fromScale( - Cesium.Ellipsoid.WGS84.radii, - // Cesium.Cartesian3.fromElements( - // Cesium.Ellipsoid.WGS84.radii.x, - // Cesium.Ellipsoid.WGS84.radii.y, - // Cesium.Ellipsoid.WGS84.radii.z * 2.0 - // ), + // Cesium.Ellipsoid.WGS84.radii, + Cesium.Cartesian3.fromElements( + Cesium.Ellipsoid.WGS84.radii.x, + Cesium.Ellipsoid.WGS84.radii.x, + Cesium.Ellipsoid.WGS84.radii.x + ), new Cesium.Matrix4() ), }) @@ -398,6 +406,29 @@ }); Sandcastle.addToolbarMenu([ + { + text: "Ellipsoid - Procedural Tile", + onselect: function () { + const provider = new ProceduralSingleTileVoxelProvider( + Cesium.VoxelShapeType.ELLIPSOID + ); + const primitive = createPrimitive(provider, customShaderColor); + primitive.readyPromise.then(function () { + viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { + duration: 0.0, + }); + }); + }, + }, + { + text: "Cylinder - Procedural Tile", + onselect: function () { + const provider = new ProceduralSingleTileVoxelProvider( + Cesium.VoxelShapeType.CYLINDER + ); + const primitive = createPrimitive(provider, customShaderColor); + }, + }, { text: "Box - Procedural Tile", onselect: function () { @@ -422,6 +453,7 @@ ), duration: 0.0, }); + primitive.maxClippingBounds.x = 0.99999999; }); }, }, @@ -454,20 +486,6 @@ const primitive = createPrimitive(provider, customShaderAlpha); }, }, - { - text: "Ellipsoid - Procedural Tile", - onselect: function () { - const provider = new ProceduralSingleTileVoxelProvider( - Cesium.VoxelShapeType.ELLIPSOID - ); - const primitive = createPrimitive(provider, customShaderColor); - primitive.readyPromise.then(function () { - viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { - duration: 0.0, - }); - }); - }, - }, { text: "Ellipsoid - Procedural Tileset", onselect: function () { @@ -497,15 +515,6 @@ const primitive = createPrimitive(provider, customShaderAlpha); }, }, - { - text: "Cylinder - Procedural Tile", - onselect: function () { - const provider = new ProceduralSingleTileVoxelProvider( - Cesium.VoxelShapeType.CYLINDER - ); - const primitive = createPrimitive(provider, customShaderColor); - }, - }, { text: "Cylinder - Procedural Tileset", onselect: function () { From 485f079dae1778e3b1c00f81e7034ae8d1cc4794 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Thu, 28 Apr 2022 15:05:01 -0700 Subject: [PATCH 043/679] handling custom shader uniforms --- Source/Scene/Cesium3DTilesVoxelProvider.js | 47 +++++++++++++------ Source/Scene/VoxelPrimitive.js | 46 +++++++++++++----- .../Widgets/VoxelInspector/VoxelInspector.js | 35 +++++++------- .../VoxelInspector/VoxelInspectorViewModel.js | 34 +++++++------- 4 files changed, 104 insertions(+), 58 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 4611faf0bd0..8d441a1e72c 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -281,8 +281,8 @@ function Cesium3DTilesVoxelProvider(options) { const names = new Array(attributesLength); const types = new Array(attributesLength); const componentTypes = new Array(attributesLength); - const minimumValues = new Array(attributesLength); - const maximumValues = new Array(attributesLength); + let minimumValues = new Array(attributesLength); + let maximumValues = new Array(attributesLength); const schema = metadata.schema; const statistics = metadata.statistics; @@ -298,31 +298,48 @@ function Cesium3DTilesVoxelProvider(options) { for (let i = 0; i < propertyNamesLength; i++) { const propertyName = propertyNames[i]; const property = properties[propertyName]; - const propertyStatistics = classStatistics.properties[propertyName]; - const propertyMin = Array.isArray(propertyStatistics.min) - ? propertyStatistics.min - : [propertyStatistics.min]; - const propertyMax = Array.isArray(propertyStatistics.max) - ? propertyStatistics.max - : [propertyStatistics.max]; + const metadataType = property.type; const metadataComponentType = property.componentType; const metadataComponentCount = MetadataType.getComponentCount( metadataType ); + if (defined(classStatistics)) { + const propertyStatistics = classStatistics.properties[propertyName]; + const propertyMin = Array.isArray(propertyStatistics.min) + ? propertyStatistics.min + : [propertyStatistics.min]; + const propertyMax = Array.isArray(propertyStatistics.max) + ? propertyStatistics.max + : [propertyStatistics.max]; + + minimumValues[i] = new Array(metadataComponentCount); + maximumValues[i] = new Array(metadataComponentCount); + + for (let j = 0; j < metadataComponentCount; j++) { + minimumValues[i][j] = propertyMin[j]; + maximumValues[i][j] = propertyMax[j]; + } + } + names[i] = propertyName; types[i] = metadataType; componentTypes[i] = metadataComponentType; - minimumValues[i] = new Array(metadataComponentCount); - maximumValues[i] = new Array(metadataComponentCount); + } + } - for (let j = 0; j < metadataComponentCount; j++) { - minimumValues[i][j] = propertyMin[j]; - maximumValues[i][j] = propertyMax[j]; - } + let hasMinimumMaximumValues = false; + for (let i = 0; i < attributesLength; i++) { + if (defined(minimumValues[i]) && defined(maximumValues[i])) { + hasMinimumMaximumValues = true; + break; } } + if (!hasMinimumMaximumValues) { + minimumValues = undefined; + maximumValues = undefined; + } that.shape = VoxelShapeType.fromPrimitiveType(primitiveType); that.minBounds = Cartesian3.clone(voxel.minBounds); diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 98290b8ecb7..cc0f50b4dfe 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -5,6 +5,7 @@ import CesiumMath from "../Core/Math.js"; import Check from "../Core/Check.js"; import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; +import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; @@ -398,8 +399,6 @@ function VoxelPrimitive(options) { dimensions: new Cartesian3(), paddingBefore: new Cartesian3(), paddingAfter: new Cartesian3(), - minimumValues: [], - maximumValues: [], transformPositionViewToUv: new Matrix4(), transformPositionUvToView: new Matrix4(), transformDirectionViewToLocal: new Matrix3(), @@ -439,7 +438,7 @@ function VoxelPrimitive(options) { const provider = this._provider; const primitive = this; provider.readyPromise.catch(function (error) { - primitive._readyPromise.reject(`provider failed with error:\n${error}`); + primitive._readyPromise.reject(error); }); } @@ -1011,6 +1010,20 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, set: function (customShader) { if (this._customShader !== customShader) { + // Delete old custom shader entries from the uniform map + const uniformMap = this._uniformMap; + const oldCustomShader = this._customShader; + const oldCustomShaderUniformMap = oldCustomShader.uniformMap; + for (const uniformName in oldCustomShaderUniformMap) { + if (oldCustomShaderUniformMap.hasOwnProperty(uniformName)) { + // If the custom shader was set but the voxel shader was never + // built, the custom shader uniforms wouldn't have been added to + // the uniform map. But it doesn't matter because the delete + // operator ignores if the key doesn't exist. + delete uniformMap[uniformName]; + } + } + if (!defined(customShader)) { this._customShader = VoxelPrimitive.DefaultCustomShader; } else { @@ -1071,12 +1084,16 @@ VoxelPrimitive.prototype.update = function (frameState) { const context = frameState.context; const provider = this._provider; const uniforms = this._uniforms; + const customShader = this._customShader; // Update the provider, if applicable. if (defined(provider.update)) { provider.update(frameState); } + // Update the custom shader in case it has texture uniforms. + customShader.update(frameState); + // Exit early if it's not ready yet. if (!this._ready && !provider.ready) { return; @@ -1186,13 +1203,6 @@ VoxelPrimitive.prototype.update = function (frameState) { this._paddingAfter, uniforms.paddingAfter ); - - const minimumValues = provider.minimumValues; - const maximumValues = provider.maximumValues; - if (defined(minimumValues) && defined(maximumValues)) { - uniforms.minimumValues = minimumValues.slice(); - uniforms.maximumValues = maximumValues.slice(); - } } // Check if the shape is dirty before updating it. This needs to happen every @@ -1721,6 +1731,7 @@ function buildDrawCommands(that, context) { const customShader = that._customShader; const attributeLength = types.length; const hasStatistics = defined(minimumValues) && defined(maximumValues); + let uniformMap = that._uniformMap; // Build shader @@ -1842,6 +1853,20 @@ function buildDrawCommands(that, context) { // Fragment shader uniforms + // Custom shader uniforms + const customShaderUniforms = customShader.uniforms; + uniformMap = that._uniformMap = combine(uniformMap, customShader.uniformMap); + for (const uniformName in customShaderUniforms) { + if (customShaderUniforms.hasOwnProperty(uniformName)) { + const uniform = customShaderUniforms[uniformName]; + shaderBuilder.addUniform( + uniform.type, + uniformName, + ShaderDestination.FRAGMENT + ); + } + } + // The reason this uniform is added by shader builder is because some of the // dynamically generated shader code reads from it. shaderBuilder.addUniform( @@ -2159,7 +2184,6 @@ function buildDrawCommands(that, context) { }); // Create the draw commands - const uniformMap = that._uniformMap; const viewportQuadVertexArray = context.getViewportQuadVertexArray(); const drawCommand = new DrawCommand({ vertexArray: viewportQuadVertexArray, diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index 7c39a62fbec..49fedbd70a5 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -274,33 +274,36 @@ function VoxelInspector(container, scene) { clippingPanelContents ); - // Style - const stylePanelContents = createSection( + // Shader + const shaderPanelContents = createSection( panel, - "Style", - "styleVisible", - "styleVisibleToggle" + "Shader", + "shaderVisible", + "shaderVisibleToggle" ); - const stylePanelEditor = document.createElement("div"); - stylePanelContents.appendChild(stylePanelEditor); + const shaderPanelEditor = document.createElement("div"); + shaderPanelContents.appendChild(shaderPanelEditor); - const styleEditor = document.createElement("textarea"); - styleEditor.setAttribute( + const shaderEditor = document.createElement("textarea"); + shaderEditor.setAttribute( "data-bind", - "textInput: styleString, event: { keydown: styleEditorKeyPress }" + "textInput: shaderString, event: { keydown: shaderEditorKeyPress }" ); - stylePanelEditor.className = "cesium-cesiumInspector-styleEditor"; - stylePanelEditor.appendChild(styleEditor); - const compileStyleButton = makeButton("compileStyle", "Compile (Ctrl+Enter)"); - stylePanelEditor.appendChild(compileStyleButton); + shaderPanelEditor.className = "cesium-cesiumInspector-styleEditor"; + shaderPanelEditor.appendChild(shaderEditor); + const compileShaderButton = makeButton( + "compileShader", + "Compile (Ctrl+Enter)" + ); + shaderPanelEditor.appendChild(compileShaderButton); const compilationText = document.createElement("label"); compilationText.style.display = "block"; compilationText.setAttribute( "data-bind", - "text: styleCompilationMessage, style: {color: styleCompilationSuccess ? 'green' : 'red'}" + "text: shaderCompilationMessage, style: {color: shaderCompilationSuccess ? 'green' : 'red'}" ); - stylePanelEditor.appendChild(compilationText); + shaderPanelEditor.appendChild(compilationText); knockout.applyBindings(viewModel, element); diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 648fa10564a..15cf147fcbf 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -130,24 +130,24 @@ function VoxelInspectorViewModel(scene) { toggle: true, }); addProperty({ - name: "styleVisible", + name: "shaderVisible", initialValue: false, toggle: true, }); addProperty({ - name: "styleString", + name: "shaderString", initialValue: "", getPrimitiveFunction: function () { const shaderString = that._voxelPrimitive.customShader.fragmentShaderText; - that.styleString = formatShaderString(shaderString); + that.shaderString = formatShaderString(shaderString); }, }); addProperty({ - name: "styleCompilationMessage", + name: "shaderCompilationMessage", initialValue: "", }); addProperty({ - name: "styleCompilationSuccess", + name: "shaderCompilationSuccess", initialValue: true, }); addProperty({ @@ -1027,14 +1027,14 @@ Object.defineProperties(VoxelInspectorViewModel.prototype, { function (error) { const shaderString = that._voxelPrimitive.customShader.fragmentShaderText; - that.styleString = formatShaderString(shaderString); + that.shaderString = formatShaderString(shaderString); if (!defined(error)) { - that.styleCompilationMessage = "Shader compiled successfully!"; - that.styleCompilationSuccess = true; + that.shaderCompilationMessage = "Shader compiled successfully!"; + that.shaderCompilationSuccess = true; } else { - that.styleCompilationMessage = error.message; - that.styleCompilationSuccess = false; + that.shaderCompilationMessage = error.message; + that.shaderCompilationSuccess = false; } } ); @@ -1048,22 +1048,24 @@ Object.defineProperties(VoxelInspectorViewModel.prototype, { }); /** - * Compiles the style in the style editor. + * Compiles the shader in the shader editor. * @private */ -VoxelInspectorViewModel.prototype.compileStyle = function () { +VoxelInspectorViewModel.prototype.compileShader = function () { if (defined(this._voxelPrimitive)) { + // It's assumed that the same uniforms are going to be used regardless of edits. this._voxelPrimitive.customShader = new CustomShader({ - fragmentShaderText: this.styleString, + fragmentShaderText: this.shaderString, + uniforms: this._voxelPrimitive.customShader.uniforms, }); } }; /** - * Handles key press events on the style editor. + * Handles key press events on the shader editor. * @private */ -VoxelInspectorViewModel.prototype.styleEditorKeyPress = function ( +VoxelInspectorViewModel.prototype.shaderEditorKeyPress = function ( sender, event ) { @@ -1103,7 +1105,7 @@ VoxelInspectorViewModel.prototype.styleEditorKeyPress = function ( textArea.selectionEnd = newEnd; } else if (event.ctrlKey && (event.keyCode === 10 || event.keyCode === 13)) { //ctrl + enter - this.compileStyle(); + this.compileShader(); } return true; }; From 4cc05f124982514dac1ec1db5741342c21766533 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Thu, 28 Apr 2022 19:59:32 -0700 Subject: [PATCH 044/679] fixed disable update setting --- Source/Scene/VoxelPrimitive.js | 6 +++--- Source/Scene/VoxelTraversal.js | 27 +++++++++++++++++++-------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index cc0f50b4dfe..060a50acc5f 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1498,12 +1498,13 @@ VoxelPrimitive.prototype.update = function (frameState) { } // Update the voxel traversal - const hasLoadedData = traversal.update( + traversal.update( frameState, keyframeLocation, shapeDirty, // recomputeBoundingVolumes this._disableUpdate // pauseUpdate ); + const hasLoadedData = traversal.isRenderable(traversal.rootNode); if (hasLoadedData && this._debugDraw) { // Debug draw bounding boxes and other things. Must go after traversal update @@ -2440,7 +2441,6 @@ const polylineZAxis = new Cartesian3(0.0, 0.0, polylineAxisDistance); * @private */ function debugDraw(that, frameState) { - const frameNumber = frameState.frameNumber; const traversal = that._traversal; const polylines = that._debugPolylines; polylines.removeAll(); @@ -2474,7 +2474,7 @@ function debugDraw(that, frameState) { } function drawTile(tile) { - if (!tile.isRenderable(frameNumber)) { + if (!traversal.isRenderable(tile)) { return; } diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index 21d2f3e5150..ef0812f4057 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -93,6 +93,12 @@ function VoxelTraversal( */ this._debugPrint = false; + /** + * @type {Number} + * @private + */ + this._frameNumber = 0; + const shape = primitive._shape; const rootLevel = 0; const rootX = 0; @@ -276,7 +282,6 @@ VoxelTraversal.simultaneousRequestCountMaximum = 50; * @param {Number} keyframeLocation * @param {Boolean} recomputeBoundingVolumes * @param {Boolean} pauseUpdate - * @returns {Boolean} True if the voxel grid has any loaded data. */ VoxelTraversal.prototype.update = function ( frameState, @@ -296,10 +301,11 @@ VoxelTraversal.prototype.update = function ( } if (!pauseUpdate) { + this._frameNumber = frameState.frameNumber; const timestamp0 = getTimestamp(); loadAndUnload(this, frameState); const timestamp1 = getTimestamp(); - generateOctree(this, frameState); + generateOctree(this); const timestamp2 = getTimestamp(); const debugStatistics = this._debugPrint; @@ -315,10 +321,15 @@ VoxelTraversal.prototype.update = function ( ); } } +}; - const rootNode = this.rootNode; - const frameNumber = frameState.frameNumber; - return rootNode.isRenderable(frameNumber); +/** + * Check if a node is renderable. + * @param {SpatialNode} tile + * @returns {Boolean} + */ +VoxelTraversal.prototype.isRenderable = function (tile) { + return tile.isRenderable(this._frameNumber); }; /** @@ -508,7 +519,7 @@ function mapInfiniteRangeToZeroOne(x) { * @private */ function loadAndUnload(that, frameState) { - const frameNumber = frameState.frameNumber; + const frameNumber = that._frameNumber; const primitive = that._primitive; const shape = primitive._shape; const voxelDimensions = primitive._provider.dimensions; @@ -1402,10 +1413,10 @@ const GpuOctreeFlag = { * @param {VoxelTraversal} that * @param {FrameState} frameState */ -function generateOctree(that, frameState) { +function generateOctree(that) { const keyframeLocation = that._keyframeLocation; const useLeafNodes = that._useLeafNodeTexture; - const frameNumber = frameState.frameNumber; + const frameNumber = that._frameNumber; let internalNodeCount = 0; let leafNodeCount = 0; From 060a6e6013b1b7acefd4976cf6ec2c77ebda134f Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 2 May 2022 10:42:23 -0700 Subject: [PATCH 045/679] added gltf sample data for the shapes --- .../Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin | Bin 0 -> 32 bytes .../Voxel/VoxelBoxGltf/schema.json | 14 +++ .../Voxel/VoxelBoxGltf/voxelBox.gltf | 88 +++++++++++++++ .../Voxel/VoxelCylinderGltf/a.bin | Bin 0 -> 32 bytes .../Voxel/VoxelCylinderGltf/schema.json | 14 +++ .../VoxelCylinderGltf/voxelCylinder.gltf | 88 +++++++++++++++ .../Voxel/VoxelEllipsoidGltf/a.bin | Bin 0 -> 32 bytes .../Voxel/VoxelEllipsoidGltf/schema.json | 14 +++ .../VoxelEllipsoidGltf/voxelEllipsoid.gltf | 100 ++++++++++++++++++ Source/Scene/GltfVoxelProvider.js | 11 +- Source/Scene/VoxelEllipsoidShape.js | 1 - Source/Scene/VoxelPrimitive.js | 3 - 12 files changed, 322 insertions(+), 11 deletions(-) create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json new file mode 100644 index 00000000000..d6b1e9d87f0 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json @@ -0,0 +1,14 @@ +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf new file mode 100644 index 00000000000..0f89c2221c6 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf @@ -0,0 +1,88 @@ +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483648, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json new file mode 100644 index 00000000000..d6b1e9d87f0 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json @@ -0,0 +1,14 @@ +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf new file mode 100644 index 00000000000..6ef6eb1759c --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf @@ -0,0 +1,88 @@ +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483650, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ] + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin new file mode 100644 index 0000000000000000000000000000000000000000..6eac4f3e1f1fcfd58880ad428efeb0df90514357 GIT binary patch literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} literal 0 HcmV?d00001 diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json new file mode 100644 index 00000000000..d6b1e9d87f0 --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json @@ -0,0 +1,14 @@ +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "FLOAT32", + "required": false + } + } + }, + "tile": {} + } +} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf new file mode 100644 index 00000000000..39b31e4dd3c --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf @@ -0,0 +1,100 @@ +{ + "asset": { + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "mode": 2147483649, + "attributes": { + "_a": 0 + }, + "extensions": { + "EXT_primitive_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "bounds": { + "min": [ + -3.141592653589793, + -1.5707963267948966, + 1000000.0 + ], + "max": [ + 3.141592653589793, + 1.5707963267948966, + 2000000.0 + ] + } + } + } + } + ] + } + ], + "extensionsUsed": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensionsRequired": [ + "EXT_primitive_voxels", + "EXT_structural_metadata" + ], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "schema.json", + "propertyAttributes": [ + { + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + } + } + } + ] + } + }, + "accessors": [ + { + "bufferView": 0, + "type": "SCALAR", + "componentType": 5126, + "min": [ + 0.0 + ], + "max": [ + 1.0 + ], + "count": 8 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 32 + } + ], + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ] +} \ No newline at end of file diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index 60536d7dc03..cb8299748cc 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -324,19 +324,16 @@ GltfVoxelProvider.prototype.update = function (frameState) { */ GltfVoxelProvider.prototype.requestData = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - const tileX = defaultValue(options.tileX, 0); - const tileY = defaultValue(options.tileY, 0); - const tileZ = defaultValue(options.tileZ, 0); - const tileLevel = defaultValue(options.tileLevel, 0); - //>>includeStart('debug', pragmas.debug); if (!this.ready) { throw new DeveloperError( "requestData must not be called before the provider is ready." ); } - if (!(tileLevel === 0 && tileX === 0 && tileY === 0 && tileZ === 0)) { - throw new DeveloperError("GltfVoxelProvider can only have one tile"); + + const tileLevel = defaultValue(options.tileLevel, 0); + if (tileLevel > 0) { + return undefined; } //>>includeEnd('debug'); diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index 728a846a45c..fd75db09429 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -468,7 +468,6 @@ VoxelEllipsoidShape.prototype.update = function ( hasLongitudeRangeOverHalfShape; // Latitude - const latitudeRangeRender = latitudeMaxRender - latitudeMinRender; const hasLatitudeMaxUnderHalfRender = latitudeMaxRender < -flatLatitudeEpsilon; const hasLatitudeMaxEqualHalfRender = diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 060a50acc5f..cd9b3d33d87 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -2221,9 +2221,6 @@ function buildDrawCommands(that, context) { that._drawCommand = drawCommand; that._drawCommandPick = drawCommandPick; - - // console.log(drawCommand.shaderProgram._fragmentShaderText); - console.log("recompile"); } /** From 5bb5943adb2d10bb6cb3748052d465f875d5b2ca Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 2 May 2022 10:50:01 -0700 Subject: [PATCH 046/679] fixed cylinder min radius change --- Source/Scene/VoxelCylinderShape.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 6cf44efe5ba..9f67926f8b6 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -382,7 +382,7 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_INTERSECTION_INDEX_RADIUS_MIN"] = intersectionCount; intersectionCount += 1; - shaderUniforms.cylinderInverseMinRadiusUv = + shaderUniforms.cylinderUvToRenderRadiusMin = renderMaxRadius / renderMinRadius; } if (!isDefaultMaxRadiusRender) { From 3f5683583eb0dc4816bd272fff19df0cf4c28115 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Mon, 2 May 2022 12:26:18 -0700 Subject: [PATCH 047/679] simplified the shader step calculation --- Source/Shaders/VoxelFS.glsl | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 802b629d6bb..470966c2c8a 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1551,8 +1551,7 @@ void traverseOctreeDownwards(in vec3 positionUv, inout ivec4 octreeCoords, inout } } -void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, out float levelStepMult, out ivec4 octreeCoords, out int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { - levelStepMult = 1.0; +void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, out float stepT, out ivec4 octreeCoords, out int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { octreeCoords = ivec4(0); parentOctreeIndex = 0; @@ -1564,17 +1563,18 @@ void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data getOctreeLeafData(rootData, sampleDatas); + stepT = u_stepSize; } else { traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); - levelStepMult = 1.0 / pow(2.0, float(octreeCoords.w)); - vec3 boxStart = vec3(octreeCoords.xyz) * levelStepMult; - positionUvLocal = (positionUvShapeSpace - boxStart) / levelStepMult; + float dimAtLevel = pow(2.0, float(octreeCoords.w)); + positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords); + stepT = u_stepSize / dimAtLevel; } } -void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, inout float levelStepMult, inout ivec4 octreeCoords, inout int parentOctreeIndex, inout SampleData sampleDatas[SAMPLE_COUNT]) { +void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, inout float stepT, inout ivec4 octreeCoords, inout int parentOctreeIndex, inout SampleData sampleDatas[SAMPLE_COUNT]) { float dimAtLevel = pow(2.0, float(octreeCoords.w)); positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); @@ -1603,8 +1603,9 @@ void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpac // Go down tree traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); - levelStepMult = 1.0 / pow(2.0, float(octreeCoords.w)); - positionUvLocal = positionUvShapeSpace / levelStepMult - vec3(octreeCoords.xyz); + float dimAtLevel = pow(2.0, float(octreeCoords.w)); + positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); + stepT = u_stepSize / dimAtLevel; } } @@ -1642,14 +1643,11 @@ void main() // Traverse the tree from the start position vec3 positionUvShapeSpace; vec3 positionUvLocal; - float levelStepMult; + float stepT; ivec4 octreeCoords; int parentOctreeIndex; SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctree(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); - - // Adjust the step size based on the level in the tree - float stepT = u_stepSize * levelStepMult; + traverseOctree(positionUv, positionUvShapeSpace, positionUvLocal, stepT, octreeCoords, parentOctreeIndex, sampleDatas); #if defined(JITTER) float noise = hash(screenCoord); // [0,1] @@ -1744,10 +1742,7 @@ void main() // Traverse the tree from the current ray position. // This is similar to traverseOctree but is optimized for the common // case where the ray is in the same tile as the previous step. - traverseOctreeFromExisting(positionUv, positionUvShapeSpace, positionUvLocal, levelStepMult, octreeCoords, parentOctreeIndex, sampleDatas); - - // Adjust the step size based on the level in the tree - stepT = u_stepSize * levelStepMult; + traverseOctreeFromExisting(positionUv, positionUvShapeSpace, positionUvLocal, stepT, octreeCoords, parentOctreeIndex, sampleDatas); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From 1e21610bdb15676bce1751bba551011b962b5f41 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 09:05:15 -0700 Subject: [PATCH 048/679] moved traversal details into a struct --- Source/Shaders/VoxelFS.glsl | 92 ++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 470966c2c8a..cb688e445b7 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -165,6 +165,14 @@ struct OctreeNodeData { int flag; }; +struct TraversalData { + vec3 positionUvShapeSpace; + vec3 positionUvLocal; + float stepT; + ivec4 octreeCoords; + int parentOctreeIndex; +}; + struct SampleData { int megatextureIndex; int levelsAbove; @@ -1551,61 +1559,61 @@ void traverseOctreeDownwards(in vec3 positionUv, inout ivec4 octreeCoords, inout } } -void traverseOctree(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, out float stepT, out ivec4 octreeCoords, out int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { - octreeCoords = ivec4(0); - parentOctreeIndex = 0; +void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { + traversalData.octreeCoords = ivec4(0); + traversalData.parentOctreeIndex = 0; // TODO: is it possible for this to be out of bounds, and does it matter? - positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - positionUvLocal = positionUvShapeSpace; + traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace; OctreeNodeData rootData = getOctreeRootData(); if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data getOctreeLeafData(rootData, sampleDatas); - stepT = u_stepSize; + traversalData.stepT = u_stepSize; } else { - traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); - float dimAtLevel = pow(2.0, float(octreeCoords.w)); - positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords); - stepT = u_stepSize / dimAtLevel; + traverseOctreeDownwards(traversalData.positionUvShapeSpace, traversalData.octreeCoords, traversalData.parentOctreeIndex, sampleDatas); + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords); + traversalData.stepT = u_stepSize / dimAtLevel; } } -void traverseOctreeFromExisting(in vec3 positionUv, out vec3 positionUvShapeSpace, out vec3 positionUvLocal, inout float stepT, inout ivec4 octreeCoords, inout int parentOctreeIndex, inout SampleData sampleDatas[SAMPLE_COUNT]) { - float dimAtLevel = pow(2.0, float(octreeCoords.w)); - positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); +void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); // Note: This code assumes the position is always inside the root tile. - bool insideTile = octreeCoords.w == 0 || inRange(positionUvLocal, vec3(0.0), vec3(1.0)); + bool insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); if (!insideTile) { // Go up tree for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { - octreeCoords.xyz /= ivec3(2); - octreeCoords.w -= 1; - dimAtLevel /= 2.0; + traversalData.octreeCoords.xyz /= ivec3(2); + traversalData.octreeCoords.w -= 1; + dimAtLevel *= 0.5; - positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); - insideTile = octreeCoords.w == 0 || inRange(positionUvLocal, vec3(0.0), vec3(1.0)); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); if (!insideTile) { - parentOctreeIndex = getOctreeParentIndex(parentOctreeIndex); + traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); } else { break; } } // Go down tree - traverseOctreeDownwards(positionUvShapeSpace, octreeCoords, parentOctreeIndex, sampleDatas); - float dimAtLevel = pow(2.0, float(octreeCoords.w)); - positionUvLocal = positionUvShapeSpace * dimAtLevel - vec3(octreeCoords.xyz); - stepT = u_stepSize / dimAtLevel; + traverseOctreeDownwards(traversalData.positionUvShapeSpace, traversalData.octreeCoords, traversalData.parentOctreeIndex, sampleDatas); + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + traversalData.stepT = u_stepSize / dimAtLevel; } } @@ -1630,8 +1638,6 @@ void main() float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - // gl_FragColor = vec4(convertUvToShapeUvSpace(positionUv).yyy, 1.0); return; - vec4 colorAccum = vec4(0.0); #if defined(DESPECKLE) @@ -1641,18 +1647,20 @@ void main() #endif // Traverse the tree from the start position - vec3 positionUvShapeSpace; - vec3 positionUvLocal; - float stepT; - ivec4 octreeCoords; - int parentOctreeIndex; + TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctree(positionUv, positionUvShapeSpace, positionUvLocal, stepT, octreeCoords, parentOctreeIndex, sampleDatas); + traverseOctree(positionUv, traversalData, sampleDatas); + + // if (traversalData.octreeCoords.w == 6 && traversalData.octreeCoords.x == 33 && traversalData.octreeCoords.y == 49 && traversalData.octreeCoords.z == 63) { + // if (sampleDatas[0].levelsAbove == 1) { + // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; + // } + // } #if defined(JITTER) float noise = hash(screenCoord); // [0,1] - currT += noise * stepT; - positionUv += noise * stepT * viewDirUv; + currT += noise * traversalData.stepT; + positionUv += noise * traversalData.stepT * viewDirUv; #endif FragmentInput fragmentInput; @@ -1662,16 +1670,16 @@ void main() for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state - Properties properties = getPropertiesFromMegatextureAtLocalPosition(positionUvLocal, octreeCoords, sampleDatas); + Properties properties = getPropertiesFromMegatextureAtLocalPosition(traversalData.positionUvLocal, traversalData.octreeCoords, sampleDatas); // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); fragmentInput.voxel.positionUv = positionUv; - fragmentInput.voxel.positionShapeUv = positionUvShapeSpace; - fragmentInput.voxel.positionUvLocal = positionUvLocal; + fragmentInput.voxel.positionShapeUv = traversalData.positionUvShapeSpace; + fragmentInput.voxel.positionUvLocal = traversalData.positionUvLocal; fragmentInput.voxel.viewDirUv = viewDirUv; fragmentInput.voxel.viewDirWorld = viewDirWorld; - fragmentInput.voxel.travelDistance = stepT; + fragmentInput.voxel.travelDistance = traversalData.stepT; #if defined(STYLE_USE_POSITION_EC) styleInput.positionEC = vec3(u_transformPositionUvToView * vec4(positionUv, 1.0)); @@ -1719,8 +1727,8 @@ void main() } // Keep raymarching - currT += stepT; - positionUv += stepT * viewDirUv; + currT += traversalData.stepT; + positionUv += traversalData.stepT * viewDirUv; // Check if there's more intersections. if (currT > endT) { @@ -1742,7 +1750,7 @@ void main() // Traverse the tree from the current ray position. // This is similar to traverseOctree but is optimized for the common // case where the ray is in the same tile as the previous step. - traverseOctreeFromExisting(positionUv, positionUvShapeSpace, positionUvLocal, stepT, octreeCoords, parentOctreeIndex, sampleDatas); + traverseOctreeFromExisting(positionUv, traversalData, sampleDatas); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From 2b49355f9dd6eeaea285bec89c8395d46975e541 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 09:11:40 -0700 Subject: [PATCH 049/679] one more place for traversal struct --- Source/Shaders/VoxelFS.glsl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index cb688e445b7..80c813878cc 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1530,28 +1530,28 @@ int getOctreeParentIndex(int octreeIndex) { return parentOctreeIndex; } -void traverseOctreeDownwards(in vec3 positionUv, inout ivec4 octreeCoords, inout int parentOctreeIndex, out SampleData sampleDatas[SAMPLE_COUNT]) { - float sizeAtLevel = 1.0 / pow(2.0, float(octreeCoords.w)); - vec3 start = vec3(octreeCoords.xyz) * sizeAtLevel; +void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { + float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); + vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; vec3 end = start + vec3(sizeAtLevel); for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { // Find out which octree child contains the position // 0 if before center, 1 if after vec3 center = 0.5 * (start + end); - vec3 childCoord = step(center, positionUv); + vec3 childCoord = step(center, traversalData.positionUvShapeSpace); // Get octree coords for the next level down - octreeCoords.xyz = octreeCoords.xyz * 2 + ivec3(childCoord); - octreeCoords.w += 1; + traversalData.octreeCoords.xyz = traversalData.octreeCoords.xyz * 2 + ivec3(childCoord); + traversalData.octreeCoords.w += 1; - OctreeNodeData childData = getOctreeChildData(parentOctreeIndex, ivec3(childCoord)); + OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); if (childData.flag == OCTREE_FLAG_INTERNAL) { // keep going deeper start = mix(start, center, childCoord); end = mix(center, end, childCoord); - parentOctreeIndex = childData.data; + traversalData.parentOctreeIndex = childData.data; } else { getOctreeLeafData(childData, sampleDatas); return; @@ -1575,7 +1575,7 @@ void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out Sam } else { - traverseOctreeDownwards(traversalData.positionUvShapeSpace, traversalData.octreeCoords, traversalData.parentOctreeIndex, sampleDatas); + traverseOctreeDownwards(traversalData, sampleDatas); float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords); traversalData.stepT = u_stepSize / dimAtLevel; @@ -1610,7 +1610,7 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa } // Go down tree - traverseOctreeDownwards(traversalData.positionUvShapeSpace, traversalData.octreeCoords, traversalData.parentOctreeIndex, sampleDatas); + traverseOctreeDownwards(traversalData, sampleDatas); float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); traversalData.stepT = u_stepSize / dimAtLevel; From 0e3f1816b53f917bc7f74b2157ca7d2ddf6d3e45 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 10:59:48 -0700 Subject: [PATCH 050/679] fixed traversal bug for parent with not all children loaded --- Source/Shaders/VoxelFS.glsl | 67 ++++++++++++++----------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 80c813878cc..e6f2182228e 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -175,7 +175,8 @@ struct TraversalData { struct SampleData { int megatextureIndex; - int levelsAbove; + int levelsAbove; // TODO find a way to remove this + vec3 tileUv; #if (SAMPLE_COUNT > 1) float weight; #endif @@ -1418,7 +1419,9 @@ Properties getPropertiesFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 vox } #endif -Properties getPropertiesFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { +Properties getPropertiesFromMegatextureAtTileUv(in SampleData sampleData) { + vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? + int tileIndex = sampleData.megatextureIndex; vec3 voxelCoord = tileUv * vec3(u_dimensions); ivec3 dimensions = u_dimensions; @@ -1434,34 +1437,15 @@ Properties getPropertiesFromMegatextureAtTileUv(vec3 tileUv, int tileIndex) { #endif } -vec3 computeAncestorUv(vec3 positionUvLocal, int levelsAbove, ivec4 octreeCoords) { - if (levelsAbove > 0) { - // In some cases positionUvLocal goes outside the 0 to 1 bounds, such as when sampling neighbor voxels on the edge of a tile. - // This needs to be handled carefully, especially for mixed resolution, or else the wrong part of the tile is read. - // https://www.wolframalpha.com/input/?i=sign%28x%29+*+max%280%2C+%28abs%28x-0.5%29-0.5%29%29 - vec3 overflow = sign(positionUvLocal) * max(abs(positionUvLocal - vec3(0.5)) - vec3(0.5), vec3(0.0)); - positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0 - czm_epsilon6)); // epsilon to avoid fract(1) = 0 situation - - // Calcuate a new local uv relative to the ancestor tile. - float levelsAboveFactor = 1.0 / pow(2.0, float(levelsAbove)); - positionUvLocal = fract((vec3(octreeCoords.xyz) + positionUvLocal) * levelsAboveFactor) + overflow * levelsAboveFactor; - } else { - positionUvLocal = clamp(positionUvLocal, vec3(0.0), vec3(1.0)); - } - return positionUvLocal; -} - // Convert an array of mixed-resolution sample datas to a final weighted properties. -Properties getPropertiesFromMegatextureAtLocalPosition(vec3 positionUvLocal, ivec4 octreeCoords, SampleData sampleDatas[SAMPLE_COUNT]) { +Properties getPropertiesFromMegatextureAtLocalPosition(SampleData sampleDatas[SAMPLE_COUNT]) { #if (SAMPLE_COUNT == 1) - vec3 actualUv = computeAncestorUv(positionUvLocal, sampleDatas[0].levelsAbove, octreeCoords); - return getPropertiesFromMegatextureAtTileUv(actualUv, sampleDatas[0].megatextureIndex); + return getPropertiesFromMegatextureAtTileUv(sampleDatas[0]); #else // When more than one sample is taken the accumulator needs to start at 0 Properties properties = clearProperties(); for (int i = 0; i < SAMPLE_COUNT; ++i) { - vec3 actualUv = computeAncestorUv(positionUvLocal, sampleDatas[i].levelsAbove, octreeCoords); - Properties tempProperties = getPropertiesFromMegatextureAtTileUv(actualUvLocal, sampleDatas[i].megatextureIndex); + Properties tempProperties = getPropertiesFromMegatextureAtTileUv(sampleDatas[i]); properties = sumProperties(properties, tempProperties) } return properties; @@ -1541,19 +1525,32 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s vec3 center = 0.5 * (start + end); vec3 childCoord = step(center, traversalData.positionUvShapeSpace); - // Get octree coords for the next level down - traversalData.octreeCoords.xyz = traversalData.octreeCoords.xyz * 2 + ivec3(childCoord); - traversalData.octreeCoords.w += 1; - OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); + // Get octree coords for the next level down + ivec4 parentOctreeCoords = traversalData.octreeCoords; + traversalData.octreeCoords = ivec4(parentOctreeCoords.xyz * 2 + ivec3(childCoord), parentOctreeCoords.w + 1); + if (childData.flag == OCTREE_FLAG_INTERNAL) { // keep going deeper start = mix(start, center, childCoord); end = mix(center, end, childCoord); traversalData.parentOctreeIndex = childData.data; } else { + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + traversalData.stepT = u_stepSize / dimAtLevel; + getOctreeLeafData(childData, sampleDatas); + for (int i = 0; i < SAMPLE_COUNT; i++) { + bool usingParent = sampleDatas[i].levelsAbove == 1; + if (usingParent) { + float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); + sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); + } else { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } + } return; } } @@ -1576,9 +1573,6 @@ void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out Sam else { traverseOctreeDownwards(traversalData, sampleDatas); - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords); - traversalData.stepT = u_stepSize / dimAtLevel; } } @@ -1611,9 +1605,6 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa // Go down tree traverseOctreeDownwards(traversalData, sampleDatas); - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); - traversalData.stepT = u_stepSize / dimAtLevel; } } @@ -1651,12 +1642,6 @@ void main() SampleData sampleDatas[SAMPLE_COUNT]; traverseOctree(positionUv, traversalData, sampleDatas); - // if (traversalData.octreeCoords.w == 6 && traversalData.octreeCoords.x == 33 && traversalData.octreeCoords.y == 49 && traversalData.octreeCoords.z == 63) { - // if (sampleDatas[0].levelsAbove == 1) { - // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; - // } - // } - #if defined(JITTER) float noise = hash(screenCoord); // [0,1] currT += noise * traversalData.stepT; @@ -1670,7 +1655,7 @@ void main() for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state - Properties properties = getPropertiesFromMegatextureAtLocalPosition(traversalData.positionUvLocal, traversalData.octreeCoords, sampleDatas); + Properties properties = getPropertiesFromMegatextureAtLocalPosition(sampleDatas); // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); From c70521a3bc7313fcf3f5ae5edfe3cdb608e4d516 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 12:29:35 -0700 Subject: [PATCH 051/679] better naming for the megatexture functions --- Source/Scene/VoxelPrimitive.js | 6 ++--- Source/Scene/VoxelTraversal.js | 4 +-- Source/Shaders/VoxelFS.glsl | 49 ++++++++++++++++------------------ 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index cd9b3d33d87..58bebcfba52 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -2141,12 +2141,12 @@ function buildDrawCommands(that, context) { } } - // getPropertiesFrom2DMegatextureAtUv + // getPropertiesFromMegatextureAtUv { - const functionId = "getPropertiesFrom2DMegatextureAtUv"; + const functionId = "getPropertiesFromMegatextureAtUv"; shaderBuilder.addFunction( functionId, - `${propertiesStructName} getPropertiesFrom2DMegatextureAtUv(vec2 texcoord)`, + `${propertiesStructName} getPropertiesFromMegatextureAtUv(vec2 texcoord)`, ShaderDestination.FRAGMENT ); shaderBuilder.addFunctionLines(functionId, [ diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index ef0812f4057..945d8995043 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -244,7 +244,7 @@ function VoxelTraversal( */ this.leafNodeTexelSizeUv = undefined; - const useLeafNodeTexture = this._useLeafNodeTexture; + const useLeafNodeTexture = this.useLeafNodeTexture; if (useLeafNodeTexture) { const leafNodeTexelCount = 2; const leafNodeTextureDimensionX = 1024; @@ -1415,7 +1415,7 @@ const GpuOctreeFlag = { */ function generateOctree(that) { const keyframeLocation = that._keyframeLocation; - const useLeafNodes = that._useLeafNodeTexture; + const useLeafNodes = that.useLeafNodeTexture; const frameNumber = that._frameNumber; let internalNodeCount = 0; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index e6f2182228e..22ddf3c3407 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -104,17 +104,18 @@ void setStatistics(inout Statistics statistics) { statistics.temperature.min = 20.0; statistics.temperature.max = 50.0; } -Properties getPropertiesFrom2DMegatextureAtUv(vec2 texcoord) { - Properties properties; - properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; - properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; - return properties; -} -Properties getPropertiesFrom3DMegatextureAtUv(vec3 texcoord) { - Properties properties; - properties.temperature = texture3D(u_megatextureTextures[0], texcoord).r; - properties.direction = texture3D(u_megatextureTextures[1], texcoord).rgb; - return properties; +Properties getPropertiesFromMegatextureAtUv(vec2 texcoord) { + #if defined(MEGATEXTURE_2D) + Properties properties; + properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; + properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; + return properties; + #else + Properties properties; + properties.temperature = texture3D(u_megatextureTextures[0], texcoord).r; + properties.direction = texture3D(u_megatextureTextures[1], texcoord).rgb; + return properties; + #endif } void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { vec3 direction = fsInput.metadata.direction; @@ -1383,7 +1384,7 @@ Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxel When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice. */ -Properties getPropertiesFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) +Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) { #if defined(NEAREST_SAMPLING) // Round to the center of the nearest voxel @@ -1406,20 +1407,20 @@ Properties getPropertiesFrom2DMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 vox vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; #if defined(NEAREST_SAMPLING) - return getPropertiesFrom2DMegatextureAtUv(uv0); + return getPropertiesFromMegatextureAtUv(uv0); #else float sliceLerp = fract(slice); int sliceIndex1 = intMin(sliceIndex + 1, voxelDims.z - 1); vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; - Properties properties0 = getPropertiesFrom2DMegatextureAtUv(uv0); - Properties properties1 = getPropertiesFrom2DMegatextureAtUv(uv1); + Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); + Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); return mixProperties(properties0, properties1, sliceLerp); #endif } #endif -Properties getPropertiesFromMegatextureAtTileUv(in SampleData sampleData) { +Properties getPropertiesFromMegatexture(in SampleData sampleData) { vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? int tileIndex = sampleData.megatextureIndex; vec3 voxelCoord = tileUv * vec3(u_dimensions); @@ -1430,22 +1431,18 @@ Properties getPropertiesFromMegatextureAtTileUv(in SampleData sampleData) { voxelCoord += vec3(u_paddingBefore); #endif - #if defined(MEGATEXTURE_3D) - return getPropertiesFrom3DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); - #elif defined(MEGATEXTURE_2D) - return getPropertiesFrom2DMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); - #endif + return getPropertiesFromMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); } -// Convert an array of mixed-resolution sample datas to a final weighted properties. -Properties getPropertiesFromMegatextureAtLocalPosition(SampleData sampleDatas[SAMPLE_COUNT]) { +// Convert an array of sample datas to a final weighted properties. +Properties getPropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { #if (SAMPLE_COUNT == 1) - return getPropertiesFromMegatextureAtTileUv(sampleDatas[0]); + return getPropertiesFromMegatexture(sampleDatas[0]); #else // When more than one sample is taken the accumulator needs to start at 0 Properties properties = clearProperties(); for (int i = 0; i < SAMPLE_COUNT; ++i) { - Properties tempProperties = getPropertiesFromMegatextureAtTileUv(sampleDatas[i]); + Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); properties = sumProperties(properties, tempProperties) } return properties; @@ -1655,7 +1652,7 @@ void main() for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state - Properties properties = getPropertiesFromMegatextureAtLocalPosition(sampleDatas); + Properties properties = getPropertiesFromMegatexture(sampleDatas); // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); From 20ef9aab24561261bcdaedb793ff8c4a029fc280 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 12:42:25 -0700 Subject: [PATCH 052/679] more simplification of the megatexture reading functions --- Source/Shaders/VoxelFS.glsl | 104 +++++++++++++++++------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 22ddf3c3407..d340886b53d 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1331,26 +1331,6 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int // -------------------------------------------------------- // Megatexture // -------------------------------------------------------- - -// TODO: 3D megatexture has not been implemented yet -#if defined(MEGATEXTURE_3D) -Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) -{ - // Tile location - vec3 tileUvOffset = indexToUv3d(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - - // Voxel location - vec3 voxelUvOffset = clamp(voxelCoord, vec3(0.5), vec3(voxelDims) - vec2(0.5)) * u_megatextureVoxelSizeUv; - - // Final location in the megatexture - vec3 uv = tileUvOffset + voxelUvOffset; - - for (int i = 0; i < PROPERTY_COUNT; ++i) { - vec4 sample = texture3D(u_megatextureTextures[i], uv); - samples[i] = decodeTextureSample(sample); - } -} -#elif defined(MEGATEXTURE_2D) /* How is 3D data stored in a 2D megatexture? @@ -1384,54 +1364,66 @@ Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxel When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice. */ -Properties getPropertiesFromMegatextureAtVoxelCoord(vec3 voxelCoord, ivec3 voxelDims, int tileIndex) -{ + +Properties getPropertiesFromMegatexture(in SampleData sampleData) { + vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? + int tileIndex = sampleData.megatextureIndex; + vec3 voxelCoord = tileUv * vec3(u_dimensions); + ivec3 voxelDimensions = u_dimensions; + + #if defined(PADDING) + voxelDimensions += u_paddingBefore + u_paddingAfter; + voxelCoord += vec3(u_paddingBefore); + #endif + #if defined(NEAREST_SAMPLING) // Round to the center of the nearest voxel voxelCoord = floor(voxelCoord) + vec3(0.5); #endif - // Tile location - vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + #if defined(MEGATEXTURE_2D) + // Tile location + vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - // Slice location - float slice = voxelCoord.z - 0.5; - int sliceIndex = int(floor(slice)); - int sliceIndex0 = intClamp(sliceIndex, 0, voxelDims.z - 1); - vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + // Slice location + float slice = voxelCoord.z - 0.5; + int sliceIndex = int(floor(slice)); + int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1); + vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - // Voxel location - vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDims.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; + // Voxel location + vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; - // Final location in the megatexture - vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; + // Final location in the megatexture + vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; - #if defined(NEAREST_SAMPLING) - return getPropertiesFromMegatextureAtUv(uv0); - #else - float sliceLerp = fract(slice); - int sliceIndex1 = intMin(sliceIndex + 1, voxelDims.z - 1); - vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; - Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); - Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); - return mixProperties(properties0, properties1, sliceLerp); - #endif -} -#endif + #if defined(NEAREST_SAMPLING) + return getPropertiesFromMegatextureAtUv(uv0); + #else + float sliceLerp = fract(slice); + int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1); + vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; + Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); + Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); + return mixProperties(properties0, properties1, sliceLerp); + #endif + #elif defined(MEGATEXTURE_3D) + // TODO: 3D megatexture has not been implemented yet + // Tile location + vec3 tileUvOffset = indexToUv3d(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); -Properties getPropertiesFromMegatexture(in SampleData sampleData) { - vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? - int tileIndex = sampleData.megatextureIndex; - vec3 voxelCoord = tileUv * vec3(u_dimensions); - ivec3 dimensions = u_dimensions; + // Voxel location + vec3 voxelUvOffset = clamp(voxelCoord, vec3(0.5), vec3(voxelDimensions) - vec2(0.5)) * u_megatextureVoxelSizeUv; - #if defined(PADDING) - dimensions += u_paddingBefore + u_paddingAfter; - voxelCoord += vec3(u_paddingBefore); - #endif + // Final location in the megatexture + vec3 uv = tileUvOffset + voxelUvOffset; - return getPropertiesFromMegatextureAtVoxelCoord(voxelCoord, dimensions, tileIndex); + for (int i = 0; i < PROPERTY_COUNT; ++i) { + vec4 sample = texture3D(u_megatextureTextures[i], uv); + samples[i] = decodeTextureSample(sample); + } + #endif } // Convert an array of sample datas to a final weighted properties. From 5521fd298a2c636b197f8e0b4502c55700b7b750 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 3 May 2022 13:00:59 -0700 Subject: [PATCH 053/679] anticipating a 3d texture fix --- Source/Shaders/VoxelFS.glsl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index d340886b53d..4a2229723ca 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1419,10 +1419,7 @@ Properties getPropertiesFromMegatexture(in SampleData sampleData) { // Final location in the megatexture vec3 uv = tileUvOffset + voxelUvOffset; - for (int i = 0; i < PROPERTY_COUNT; ++i) { - vec4 sample = texture3D(u_megatextureTextures[i], uv); - samples[i] = decodeTextureSample(sample); - } + return getPropertiesFromMegatextureAtUv(uv); #endif } From 3f8085fd458acecde8f3240cb9b408f18fa8b620 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Wed, 4 May 2022 09:08:45 -0700 Subject: [PATCH 054/679] fixed root tile uvs --- Source/Shaders/VoxelFS.glsl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 4a2229723ca..59192a1b492 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1555,6 +1555,9 @@ void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out Sam // No child data, only the root tile has data getOctreeLeafData(rootData, sampleDatas); traversalData.stepT = u_stepSize; + for (int i = 0; i < SAMPLE_COUNT; i++) { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } } else { @@ -1570,8 +1573,11 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa // Note: This code assumes the position is always inside the root tile. bool insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); - if (!insideTile) - { + if (insideTile) { + for (int i = 0; i < SAMPLE_COUNT; i++) { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } + } else { // Go up tree for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { @@ -1719,8 +1725,7 @@ void main() } // Traverse the tree from the current ray position. - // This is similar to traverseOctree but is optimized for the common - // case where the ray is in the same tile as the previous step. + // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. traverseOctreeFromExisting(positionUv, traversalData, sampleDatas); } From a0883a7e292e41e7e02f328fa985b99f95dc3d81 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Wed, 4 May 2022 09:29:01 -0700 Subject: [PATCH 055/679] small shader name changes --- Source/Shaders/VoxelFS.glsl | 70 ++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 59192a1b492..1fe8306e816 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -176,7 +176,7 @@ struct TraversalData { struct SampleData { int megatextureIndex; - int levelsAbove; // TODO find a way to remove this + bool usingParentMegatextureIndex; vec3 tileUv; #if (SAMPLE_COUNT > 1) float weight; @@ -1442,33 +1442,6 @@ Properties getPropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { // Tree traversal // -------------------------------------------------------- -void getOctreeLeafData(OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { - #if (SAMPLE_COUNT == 1) - sampleDatas[0].megatextureIndex = data.data; - sampleDatas[0].levelsAbove = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT ? 1 : 0; - #else - int leafIndex = data.data; - int leafNodeTexelCount = 2; - // Adding 0.5 moves to the center of the texel - float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; - float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; - - vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); - vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); - vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); - vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); - - float lerp = normU8x2_toFloat(leafData0.xy); - - sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); - sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); - sampleDatas[0].levelsAbove = normU8_toInt(leafData0.z); - sampleDatas[1].levelsAbove = normU8_toInt(leafData0.w); - sampleDatas[0].weight = 1.0 - lerp; - sampleDatas[1].weight = lerp; - #endif -} - OctreeNodeData getOctreeRootData() { vec4 rootData = texture2D(u_octreeInternalNodeTexture, vec2(0.0)); @@ -1500,6 +1473,33 @@ int getOctreeParentIndex(int octreeIndex) { return parentOctreeIndex; } +void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { + #if (SAMPLE_COUNT == 1) + sampleDatas[0].megatextureIndex = data.data; + sampleDatas[0].usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; + #else + int leafIndex = data.data; + int leafNodeTexelCount = 2; + // Adding 0.5 moves to the center of the texel + float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; + float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; + + vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); + vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); + vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); + vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); + + float lerp = normU8x2_toFloat(leafData0.xy); + + sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); + sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); + sampleDatas[0].usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; + sampleDatas[1].usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; + sampleDatas[0].weight = 1.0 - lerp; + sampleDatas[1].weight = lerp; + #endif +} + void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; @@ -1518,19 +1518,19 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s traversalData.octreeCoords = ivec4(parentOctreeCoords.xyz * 2 + ivec3(childCoord), parentOctreeCoords.w + 1); if (childData.flag == OCTREE_FLAG_INTERNAL) { - // keep going deeper + // interior tile - keep going deeper start = mix(start, center, childCoord); end = mix(center, end, childCoord); traversalData.parentOctreeIndex = childData.data; } else { + // leaf tile - stop traversing float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); traversalData.stepT = u_stepSize / dimAtLevel; - getOctreeLeafData(childData, sampleDatas); + getOctreeLeafSampleData(childData, sampleDatas); for (int i = 0; i < SAMPLE_COUNT; i++) { - bool usingParent = sampleDatas[i].levelsAbove == 1; - if (usingParent) { + if (sampleDatas[i].usingParentMegatextureIndex) { float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); } else { @@ -1542,7 +1542,7 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s } } -void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { +void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { traversalData.octreeCoords = ivec4(0); traversalData.parentOctreeIndex = 0; @@ -1553,7 +1553,7 @@ void traverseOctree(in vec3 positionUv, out TraversalData traversalData, out Sam OctreeNodeData rootData = getOctreeRootData(); if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data - getOctreeLeafData(rootData, sampleDatas); + getOctreeLeafSampleData(rootData, sampleDatas); traversalData.stepT = u_stepSize; for (int i = 0; i < SAMPLE_COUNT; i++) { sampleDatas[i].tileUv = traversalData.positionUvLocal; @@ -1632,7 +1632,7 @@ void main() // Traverse the tree from the start position TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctree(positionUv, traversalData, sampleDatas); + traverseOctreeFromBeginning(positionUv, traversalData, sampleDatas); #if defined(JITTER) float noise = hash(screenCoord); // [0,1] From b8d627e1a04c47ed09c22b466a4cf836b5a81702 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Wed, 4 May 2022 09:39:39 -0700 Subject: [PATCH 056/679] removed despeckle option - should be replaced with temporal aa or similar --- Source/Scene/VoxelPrimitive.js | 32 ----------------- Source/Shaders/VoxelFS.glsl | 34 ++----------------- .../Widgets/VoxelInspector/VoxelInspector.js | 1 - .../VoxelInspector/VoxelInspectorViewModel.js | 6 ---- 4 files changed, 2 insertions(+), 71 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 58bebcfba52..19c22164756 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -318,12 +318,6 @@ function VoxelPrimitive(options) { */ this._stepSizeMultiplier = 1.0; - /** - * @type {Boolean} - * @private - */ - this._despeckle = false; - /** * @type {Boolean} * @private @@ -830,28 +824,6 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, }, - /** - * Gets or sets whether to reduce thin and noisy details. - * - * @memberof VoxelPrimitive.prototype - * @type {Boolean} - */ - despeckle: { - get: function () { - return this._despeckle; - }, - set: function (despeckle) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.bool("despeckle", despeckle); - //>>includeEnd('debug'); - - if (this._despeckle !== despeckle) { - this._despeckle = despeckle; - this._shaderDirty = true; - } - }, - }, - /** * Gets or sets the minimum bounds. TODO: fill in the rest later * @@ -1726,7 +1698,6 @@ function buildDrawCommands(that, context) { const minimumValues = provider.minimumValues; const maximumValues = provider.maximumValues; const keyframeCount = that._keyframeCount; - const despeckle = that._despeckle; const jitter = that._jitter; const nearestSampling = that._nearestSampling; const customShader = that._customShader; @@ -1799,9 +1770,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } - if (despeckle) { - shaderBuilder.addDefine("DESPECKLE", undefined, ShaderDestination.FRAGMENT); - } if (hasStatistics) { shaderBuilder.addDefine( "STATISTICS", diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 1fe8306e816..af6dbe70ff9 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -16,7 +16,6 @@ Below is an example of how this code might look. Properties like "temperature" a #define INTERSECTION_COUNT ### #define JITTER #define NEAREST_SAMPLING -#define DESPECKLE #define STATISTICS #define PADDING #define PICKING @@ -1623,12 +1622,6 @@ void main() vec4 colorAccum = vec4(0.0); - #if defined(DESPECKLE) - vec4 colorAccumTemp = vec4(0.0); - int nonZeroCount = 0; - int nonZeroMax = 3; - #endif - // Traverse the tree from the start position TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; @@ -1671,31 +1664,8 @@ void main() color.rgb = max(color.rgb, vec3(0.0)); color.a = clamp(color.a, 0.0, 1.0); - #if defined(DESPECKLE) - if (color.a < (1.0 - ALPHA_ACCUM_MAX)) { - float partialAlpha = float(nonZeroCount) / float(nonZeroMax); - colorAccum.a += partialAlpha * (colorAccumTemp.a - colorAccum.a); - colorAccum.rgb += partialAlpha * colorAccumTemp.rgb; - colorAccumTemp = vec4(0.0); - nonZeroCount = 0; - } else { - nonZeroCount++; - if (nonZeroCount == 1) { - colorAccumTemp.a = colorAccum.a; - } - colorAccumTemp += (1.0 - colorAccumTemp.a) * vec4(color.rgb * color.a, color.a); - - if (nonZeroCount >= nonZeroMax) { - colorAccum.a = colorAccumTemp.a; - colorAccum.rgb += colorAccumTemp.rgb; - colorAccumTemp = vec4(0.0); - nonZeroCount = 0; - } - } - #else - // Pre-multiplied alpha blend - colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a); - #endif + // Pre-multiplied alpha blend + colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a); // Stop traversing if the alpha has been fully saturated if (colorAccum.a > ALPHA_ACCUM_MAX) { diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index 49fedbd70a5..ac2d44ad46d 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -67,7 +67,6 @@ function VoxelInspector(container, scene) { displayPanelContents.appendChild( createCheckbox("Nearest Sampling", "nearestSampling") ); - displayPanelContents.appendChild(createCheckbox("Despeckle", "despeckle")); const screenSpaceErrorContainer = document.createElement("div"); screenSpaceErrorContainer.appendChild( diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 15cf147fcbf..8c51f134f5b 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -201,12 +201,6 @@ function VoxelInspectorViewModel(scene) { setPrimitiveFunction: true, getPrimitiveFunction: true, }); - addProperty({ - name: "despeckle", - initialValue: false, - setPrimitiveFunction: true, - getPrimitiveFunction: true, - }); addProperty({ name: "screenSpaceError", initialValue: 4.0, From 2b9041aee477f44a26638286f440f4fd2f7bae90 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 6 May 2022 10:53:31 -0700 Subject: [PATCH 057/679] starting smooth blending between levels of the tree --- Source/Scene/VoxelPrimitive.js | 96 +++++++++++++++++------ Source/Scene/VoxelTraversal.js | 135 ++++++++++++++++++++++----------- Source/Shaders/VoxelFS.glsl | 17 +++-- 3 files changed, 173 insertions(+), 75 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 19c22164756..4bf1c1c5aa3 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -261,12 +261,6 @@ function VoxelPrimitive(options) { // */ // this._clock = options.clock; - // /** - // * @type {Number} - // * @private - // */ - // this._keyframeCount = 1; - // Transforms and other values that are computed when the shape changes /** @@ -312,6 +306,12 @@ function VoxelPrimitive(options) { */ this._nearestSampling = false; + /** + * @type {Boolean} + * @private + */ + this._smoothLevelBlend = 0.0; + /** * @type {Number} * @private @@ -781,6 +781,28 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, }, + /** + * Gets or sets smooth blending between levels. + * + * @memberof VoxelPrimitive.prototype + * @type {Boolean} + */ + smoothLevelBlend: { + get: function () { + return this._smoothLevelBlend; + }, + set: function (smoothLevelBlend) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool("smoothLevelBlend", smoothLevelBlend); + //>>includeEnd('debug'); + + if (this._smoothLevelBlend !== smoothLevelBlend) { + this._smoothLevelBlend = smoothLevelBlend; + this._shaderDirty = true; + } + }, + }, + /** * Gets or sets the screen space error in pixels. If the screen space size * of a voxel is greater than the screen space error, the tile is subdivided. @@ -1087,12 +1109,6 @@ VoxelPrimitive.prototype.update = function (frameState) { }); uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - // const keyframeCount = defaultValue(provider.keyframeCount, 1); - // // TODO remove? - // that._keyframeCount = defaultValue( - // provider.keyframeCount, - // that._keyframeCount - // ); // // TODO remove? // that._timeIntervalCollection = defaultValue( // provider.timeIntervalCollection, @@ -1349,7 +1365,6 @@ VoxelPrimitive.prototype.update = function (frameState) { const types = provider.types; const componentTypes = provider.componentTypes; - const keyframeCount = 1; //this._keyframeCount; // Traversal setup // It's ok for memory byte length to be undefined. @@ -1364,6 +1379,8 @@ VoxelPrimitive.prototype.update = function (frameState) { ) : undefined; + const keyframeCount = defaultValue(provider.keyframeCount, 1); + this._traversal = new VoxelTraversal( this, context, @@ -1377,7 +1394,6 @@ VoxelPrimitive.prototype.update = function (frameState) { // Set uniforms that come from the traversal. // TODO: should this be done in VoxelTraversal? const traversal = this._traversal; - const useLeafNodeTexture = traversal.useLeafNodeTexture; uniforms.octreeInternalNodeTexture = traversal.internalNodeTexture; uniforms.octreeInternalNodeTexelSizeUv = Cartesian2.clone( @@ -1386,15 +1402,6 @@ VoxelPrimitive.prototype.update = function (frameState) { ); uniforms.octreeInternalNodeTilesPerRow = traversal.internalNodeTilesPerRow; - if (useLeafNodeTexture) { - uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; - uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( - traversal.leafNodeTexelSizeUv, - uniforms.octreeLeafNodeTexelSizeUv - ); - uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; - } - const megatextures = traversal.megatextures; const megatexture = megatextures[0]; const megatextureLength = megatextures.length; @@ -1491,6 +1498,16 @@ VoxelPrimitive.prototype.update = function (frameState) { this._shaderDirty = true; } + const leafNodeTexture = traversal.leafNodeTexture; + if (defined(leafNodeTexture)) { + uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; + uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( + traversal.leafNodeTexelSizeUv, + uniforms.octreeLeafNodeTexelSizeUv + ); + uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; + } + // Rebuild shaders if (this._shaderDirty) { buildDrawCommands(this, context); @@ -1697,9 +1714,9 @@ function buildDrawCommands(that, context) { const shapeDefines = shape.shaderDefines; const minimumValues = provider.minimumValues; const maximumValues = provider.maximumValues; - const keyframeCount = that._keyframeCount; const jitter = that._jitter; const nearestSampling = that._nearestSampling; + const smoothLevelBlend = that._smoothLevelBlend; const customShader = that._customShader; const attributeLength = types.length; const hasStatistics = defined(minimumValues) && defined(maximumValues); @@ -1770,6 +1787,15 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); } + + if (smoothLevelBlend) { + shaderBuilder.addDefine( + "SMOOTH_LEVEL_BLEND", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (hasStatistics) { shaderBuilder.addDefine( "STATISTICS", @@ -1794,7 +1820,7 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - const sampleCount = keyframeCount > 1 ? 2 : 1; + const sampleCount = smoothLevelBlend ? 2 : 1; shaderBuilder.addDefine( "SAMPLE_COUNT", `${sampleCount}`, @@ -2043,6 +2069,26 @@ function buildDrawCommands(that, context) { ]); } + // scaleProperties function + { + const functionId = "scaleProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} scaleProperties(${propertiesStructName} ${propertiesFieldName}, float scale)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} scaledProperties = ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `scaledProperties.${name} *= scale;`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [`return scaledProperties;`]); + } + // mixProperties { const functionId = "mixProperties"; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index 945d8995043..d05b8e3ddcf 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -221,31 +221,52 @@ function VoxelTraversal( ); /** - * @type {Boolean} - * @readonly - */ - this.useLeafNodeTexture = keyframeCount > 1; - - /** - * @type {Texture|undefined} + * Only generated when there are two or more samples. + * @type {Texture} * @readonly */ this.leafNodeTexture = undefined; /** - * @type {Number|undefined} + * Only generated when there are two or more samples. + * @type {Number} * @readonly */ this.leafNodeTilesPerRow = undefined; /** - * @type {Cartesian2|undefined} + * Only generated when there are two or more samples. + * @type {Cartesian2} * @readonly */ - this.leafNodeTexelSizeUv = undefined; + this.leafNodeTexelSizeUv = new Cartesian2(); +} + +VoxelTraversal.simultaneousRequestCountMaximum = 50; + +/** + * @param {FrameState} frameState + * @param {Number} keyframeLocation + * @param {Boolean} recomputeBoundingVolumes + * @param {Boolean} pauseUpdate + */ +VoxelTraversal.prototype.update = function ( + frameState, + keyframeLocation, + recomputeBoundingVolumes, + pauseUpdate +) { + const primitive = this._primitive; + const context = frameState.context; + const maximumTileCount = this.megatextures[0].maximumTileCount; + const keyframeCount = this._keyframeCount; - const useLeafNodeTexture = this.useLeafNodeTexture; - if (useLeafNodeTexture) { + const hasSmoothLevelBlend = primitive._smoothLevelBlend; + const hasKeyframes = keyframeCount > 1; + const sampleCount = + (hasSmoothLevelBlend ? 2 : 1) * (hasKeyframes > 1 ? 2 : 1); + const useLeafNodeTexture = sampleCount >= 2; + if (useLeafNodeTexture && !defined(this.leafNodeTexture)) { const leafNodeTexelCount = 2; const leafNodeTextureDimensionX = 1024; const leafNodeTilesPerRow = Math.floor( @@ -267,29 +288,16 @@ function VoxelTraversal( magnificationFilter: TextureMagnificationFilter.NEAREST, }), }); - this.leafNodeTexelSizeUv = new Cartesian2( + this.leafNodeTexelSizeUv = Cartesian2.fromElements( 1.0 / leafNodeTextureDimensionX, - 1.0 / leafNodeTextureDimensionY + 1.0 / leafNodeTextureDimensionY, + this.leafNodeTexelSizeUv ); this.leafNodeTilesPerRow = leafNodeTilesPerRow; + } else if (!useLeafNodeTexture && defined(this.leafNodeTexture)) { + this.leafNodeTexture = this.leafNodeTexture.destroy(); } -} - -VoxelTraversal.simultaneousRequestCountMaximum = 50; -/** - * @param {FrameState} frameState - * @param {Number} keyframeLocation - * @param {Boolean} recomputeBoundingVolumes - * @param {Boolean} pauseUpdate - */ -VoxelTraversal.prototype.update = function ( - frameState, - keyframeLocation, - recomputeBoundingVolumes, - pauseUpdate -) { - const keyframeCount = this._keyframeCount; this._keyframeLocation = CesiumMath.clamp( keyframeLocation, 0.0, @@ -305,7 +313,7 @@ VoxelTraversal.prototype.update = function ( const timestamp0 = getTimestamp(); loadAndUnload(this, frameState); const timestamp1 = getTimestamp(); - generateOctree(this); + generateOctree(this, sampleCount); const timestamp2 = getTimestamp(); const debugStatistics = this._debugPrint; @@ -1412,11 +1420,13 @@ const GpuOctreeFlag = { * * @param {VoxelTraversal} that * @param {FrameState} frameState + * @param {Number} sampleCount */ -function generateOctree(that) { +function generateOctree(that, sampleCount) { + const primitive = that._primitive; const keyframeLocation = that._keyframeLocation; - const useLeafNodes = that.useLeafNodeTexture; const frameNumber = that._frameNumber; + const useLeafNodes = sampleCount > 1; let internalNodeCount = 0; let leafNodeCount = 0; @@ -1475,18 +1485,53 @@ function generateOctree(that) { // Store the leaf node information instead // Recursion stops here because there are no renderable children if (useLeafNodes) { - const previousKeyframeNode = node.renderableKeyframeNodePrevious; - const nextKeyframeNode = node.renderableKeyframeNodeNext; - leafNodeOctreeData[leafNodeCount * 5 + 0] = - node.renderableKeyframeNodeLerp; - leafNodeOctreeData[leafNodeCount * 5 + 1] = - node.level - previousKeyframeNode.spatialNode.level; - leafNodeOctreeData[leafNodeCount * 5 + 2] = - node.level - nextKeyframeNode.spatialNode.level; - leafNodeOctreeData[leafNodeCount * 5 + 3] = - previousKeyframeNode.megatextureIndex; - leafNodeOctreeData[leafNodeCount * 5 + 4] = - nextKeyframeNode.megatextureIndex; + const baseIdx = leafNodeCount * 5; + + const useTimeDynamic = false; + if (useTimeDynamic) { + const previousKeyframeNode = node.renderableKeyframeNodePrevious; + const nextKeyframeNode = node.renderableKeyframeNodeNext; + const prevKeyframeLevel = previousKeyframeNode.spatialNode.level; + const nextKeyframeLevel = nextKeyframeNode.spatialNode.level; + const prevKeyframeLevelDifference = node.level - prevKeyframeLevel; + const nextKeyframeLevelDifference = node.level - nextKeyframeLevel; + + leafNodeOctreeData[baseIdx + 0] = node.renderableKeyframeNodeLerp; + leafNodeOctreeData[baseIdx + 1] = prevKeyframeLevelDifference; + leafNodeOctreeData[baseIdx + 2] = nextKeyframeLevelDifference; + leafNodeOctreeData[baseIdx + 3] = + previousKeyframeNode.megatextureIndex; + leafNodeOctreeData[baseIdx + 4] = nextKeyframeNode.megatextureIndex; + } else { + const keyframeNode = node.renderableKeyframeNodePrevious; + const levelDifference = node.level - keyframeNode.spatialNode.level; + + const parentNode = keyframeNode.spatialNode.parent; + const parentKeyframeNode = defined(parentNode) + ? parentNode.renderableKeyframeNodePrevious + : keyframeNode; + + let lodLerp = 0.0; + if (node.parent !== undefined) { + const sse = node.screenSpaceError; + const parentSse = node.parent.screenSpaceError; + const targetSse = primitive._screenSpaceError; + lodLerp = (targetSse - sse) / (parentSse - sse); + lodLerp = CesiumMath.clamp(lodLerp, 0.0, 1.0); + } + + const levelDifferenceChild = levelDifference; + const levelDifferenceParent = levelDifference + 1; + const megatextureIndexChild = keyframeNode.megatextureIndex; + const megatextureIndexParent = parentKeyframeNode.megatextureIndex; + + leafNodeOctreeData[baseIdx + 0] = lodLerp; + leafNodeOctreeData[baseIdx + 1] = levelDifferenceChild; + leafNodeOctreeData[baseIdx + 2] = levelDifferenceParent; + leafNodeOctreeData[baseIdx + 3] = megatextureIndexChild; + leafNodeOctreeData[baseIdx + 4] = megatextureIndexParent; + } + internalNodeOctreeData[parentEntryIndex] = (GpuOctreeFlag.LEAF << 16) | leafNodeCount; } else { diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index af6dbe70ff9..9d1a7a4faa9 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -88,6 +88,12 @@ Properties sumProperties(Properties propertiesA, Properties propertiesB) { properties.direction = propertiesA.direction + propertiesB.direction; return properties; } +Properties scaleProperties(Properties properties, float scale) { + Properties scaledProperties = properties; + scaledProperties.temperature *= scale; + scaledProperties.direction *= scale; + return scaledProperties; +} Properties mixProperties(Properties propertiesA, Properties propertiesB, float mixFactor) { Properties properties; properties.temperature = mix(propertiesA.temperature, propertiesB.temperature, mixFactor); @@ -1430,8 +1436,9 @@ Properties getPropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { // When more than one sample is taken the accumulator needs to start at 0 Properties properties = clearProperties(); for (int i = 0; i < SAMPLE_COUNT; ++i) { - Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); - properties = sumProperties(properties, tempProperties) + Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); + tempProperties = scaleProperties(tempProperties, sampleDatas[i].weight); + properties = sumProperties(properties, tempProperties); } return properties; #endif @@ -1620,8 +1627,6 @@ void main() float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - vec4 colorAccum = vec4(0.0); - // Traverse the tree from the start position TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; @@ -1638,6 +1643,8 @@ void main() setStatistics(fragmentInput.metadata.statistics); #endif + vec4 colorAccum = vec4(0.0); + for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state Properties properties = getPropertiesFromMegatexture(sampleDatas); @@ -1652,7 +1659,7 @@ void main() fragmentInput.voxel.travelDistance = traversalData.stepT; #if defined(STYLE_USE_POSITION_EC) - styleInput.positionEC = vec3(u_transformPositionUvToView * vec4(positionUv, 1.0)); + fragmentInput.voxel.positionEC = vec3(u_transformPositionUvToView * vec4(positionUv, 1.0)); #endif // Run the custom shader From f03dd023056f4d65f698f6438a92496463fb232a Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 6 May 2022 12:49:55 -0700 Subject: [PATCH 058/679] more tunable level blending --- Source/Scene/VoxelPrimitive.js | 56 +++++++------------ Source/Scene/VoxelTraversal.js | 27 ++++++--- Source/Shaders/VoxelFS.glsl | 12 ++-- .../Widgets/VoxelInspector/VoxelInspector.js | 3 + .../VoxelInspector/VoxelInspectorViewModel.js | 6 ++ 5 files changed, 57 insertions(+), 47 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 4bf1c1c5aa3..af08dc9eecf 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -307,10 +307,10 @@ function VoxelPrimitive(options) { this._nearestSampling = false; /** - * @type {Boolean} + * @type {Number} * @private */ - this._smoothLevelBlend = 0.0; + this._levelBlendFactor = 0.0; /** * @type {Number} @@ -366,24 +366,12 @@ function VoxelPrimitive(options) { * @private */ this._uniforms = { - /** - * @ignore - * @type {Texture} - */ octreeInternalNodeTexture: undefined, octreeInternalNodeTilesPerRow: 0, octreeInternalNodeTexelSizeUv: new Cartesian2(), - /** - * @ignore - * @type {Texture} - */ octreeLeafNodeTexture: undefined, octreeLeafNodeTilesPerRow: 0, octreeLeafNodeTexelSizeUv: new Cartesian2(), - /** - * @ignore - * @type {Texture[]} - */ megatextureTextures: [], megatextureSliceDimensions: new Cartesian2(), megatextureTileDimensions: new Cartesian2(), @@ -399,7 +387,7 @@ function VoxelPrimitive(options) { transformNormalLocalToWorld: new Matrix3(), cameraPositionUv: new Cartesian3(), ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), - stepSize: 1.0, + stepSize: 0, pickColor: new Color(), }; @@ -782,24 +770,23 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** - * Gets or sets smooth blending between levels. + * Controls how quickly to blend between different levels of the tree. + * 0.0 means an instantaneous pop. + * 1.0 means a full linear blend. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {Number} */ - smoothLevelBlend: { + levelBlendFactor: { get: function () { - return this._smoothLevelBlend; + return this._levelBlendFactor; }, - set: function (smoothLevelBlend) { + set: function (levelBlendFactor) { //>>includeStart('debug', pragmas.debug); - Check.typeOf.bool("smoothLevelBlend", smoothLevelBlend); + Check.typeOf.number("levelBlendFactor", levelBlendFactor); //>>includeEnd('debug'); - if (this._smoothLevelBlend !== smoothLevelBlend) { - this._smoothLevelBlend = smoothLevelBlend; - this._shaderDirty = true; - } + this._levelBlendFactor = CesiumMath.clamp(levelBlendFactor, 0.0, 1.0); }, }, @@ -1476,6 +1463,8 @@ VoxelPrimitive.prototype.update = function (frameState) { keyframeLocation = timeIntervalIndex + t; } + const sampleCountOld = traversal._sampleCount; + // Update the voxel traversal traversal.update( frameState, @@ -1483,6 +1472,11 @@ VoxelPrimitive.prototype.update = function (frameState) { shapeDirty, // recomputeBoundingVolumes this._disableUpdate // pauseUpdate ); + + if (sampleCountOld !== traversal._sampleCount) { + this._shaderDirty = true; + } + const hasLoadedData = traversal.isRenderable(traversal.rootNode); if (hasLoadedData && this._debugDraw) { @@ -1702,6 +1696,7 @@ function getGlslField(type, index) { */ function buildDrawCommands(that, context) { const provider = that._provider; + const traversal = that._traversal; const shapeType = provider.shape; const names = provider.names; const types = provider.types; @@ -1716,7 +1711,7 @@ function buildDrawCommands(that, context) { const maximumValues = provider.maximumValues; const jitter = that._jitter; const nearestSampling = that._nearestSampling; - const smoothLevelBlend = that._smoothLevelBlend; + const sampleCount = traversal._sampleCount; const customShader = that._customShader; const attributeLength = types.length; const hasStatistics = defined(minimumValues) && defined(maximumValues); @@ -1788,14 +1783,6 @@ function buildDrawCommands(that, context) { ); } - if (smoothLevelBlend) { - shaderBuilder.addDefine( - "SMOOTH_LEVEL_BLEND", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (hasStatistics) { shaderBuilder.addDefine( "STATISTICS", @@ -1820,7 +1807,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - const sampleCount = smoothLevelBlend ? 2 : 1; shaderBuilder.addDefine( "SAMPLE_COUNT", `${sampleCount}`, diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index d05b8e3ddcf..af50c7e57e1 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -147,6 +147,12 @@ function VoxelTraversal( */ this._keyframeCount = keyframeCount; + /** + * @type {Number} + * @private + */ + this._sampleCount = undefined; + /** * @type {Number} * @private @@ -261,12 +267,15 @@ VoxelTraversal.prototype.update = function ( const maximumTileCount = this.megatextures[0].maximumTileCount; const keyframeCount = this._keyframeCount; - const hasSmoothLevelBlend = primitive._smoothLevelBlend; + const levelBlendFactor = primitive._levelBlendFactor; + const haslevelBlendFactor = levelBlendFactor > 0.0; const hasKeyframes = keyframeCount > 1; const sampleCount = - (hasSmoothLevelBlend ? 2 : 1) * (hasKeyframes > 1 ? 2 : 1); - const useLeafNodeTexture = sampleCount >= 2; - if (useLeafNodeTexture && !defined(this.leafNodeTexture)) { + (haslevelBlendFactor ? 2 : 1) * (hasKeyframes > 1 ? 2 : 1); + this._sampleCount = sampleCount; + + const useLeafNodes = sampleCount >= 2; + if (useLeafNodes && !defined(this.leafNodeTexture)) { const leafNodeTexelCount = 2; const leafNodeTextureDimensionX = 1024; const leafNodeTilesPerRow = Math.floor( @@ -294,7 +303,7 @@ VoxelTraversal.prototype.update = function ( this.leafNodeTexelSizeUv ); this.leafNodeTilesPerRow = leafNodeTilesPerRow; - } else if (!useLeafNodeTexture && defined(this.leafNodeTexture)) { + } else if (!useLeafNodes && defined(this.leafNodeTexture)) { this.leafNodeTexture = this.leafNodeTexture.destroy(); } @@ -313,7 +322,7 @@ VoxelTraversal.prototype.update = function ( const timestamp0 = getTimestamp(); loadAndUnload(this, frameState); const timestamp1 = getTimestamp(); - generateOctree(this, sampleCount); + generateOctree(this, sampleCount, levelBlendFactor); const timestamp2 = getTimestamp(); const debugStatistics = this._debugPrint; @@ -1421,12 +1430,13 @@ const GpuOctreeFlag = { * @param {VoxelTraversal} that * @param {FrameState} frameState * @param {Number} sampleCount + * @param {Number} levelBlendFactor */ -function generateOctree(that, sampleCount) { +function generateOctree(that, sampleCount, levelBlendFactor) { const primitive = that._primitive; const keyframeLocation = that._keyframeLocation; const frameNumber = that._frameNumber; - const useLeafNodes = sampleCount > 1; + const useLeafNodes = sampleCount >= 2; let internalNodeCount = 0; let leafNodeCount = 0; @@ -1517,6 +1527,7 @@ function generateOctree(that, sampleCount) { const parentSse = node.parent.screenSpaceError; const targetSse = primitive._screenSpaceError; lodLerp = (targetSse - sse) / (parentSse - sse); + lodLerp = (lodLerp + levelBlendFactor - 1.0) / levelBlendFactor; lodLerp = CesiumMath.clamp(lodLerp, 0.0, 1.0); } diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 9d1a7a4faa9..9b87e8c4d59 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -313,7 +313,6 @@ uniform float u_stepSize; #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN #define CYLINDER_INTERSECTION_INDEX_ANGLE - */ // Cylinder uniforms @@ -1436,9 +1435,14 @@ Properties getPropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { // When more than one sample is taken the accumulator needs to start at 0 Properties properties = clearProperties(); for (int i = 0; i < SAMPLE_COUNT; ++i) { - Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); - tempProperties = scaleProperties(tempProperties, sampleDatas[i].weight); - properties = sumProperties(properties, tempProperties); + float weight = sampleDatas[i].weight; + + // Avoid reading the megatexture when the weight is 0 as it can be costly. + if (weight > 0.0) { + Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); + tempProperties = scaleProperties(tempProperties, weight); + properties = sumProperties(properties, tempProperties); + } } return properties; #endif diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index ac2d44ad46d..c3d229d728a 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -67,6 +67,9 @@ function VoxelInspector(container, scene) { displayPanelContents.appendChild( createCheckbox("Nearest Sampling", "nearestSampling") ); + displayPanelContents.appendChild( + makeRangeInput("Level Blend Factor", "levelBlendFactor", 0.0, 1.0) + ); const screenSpaceErrorContainer = document.createElement("div"); screenSpaceErrorContainer.appendChild( diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 8c51f134f5b..9d401ea8a67 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -201,6 +201,12 @@ function VoxelInspectorViewModel(scene) { setPrimitiveFunction: true, getPrimitiveFunction: true, }); + addProperty({ + name: "levelBlendFactor", + initialValue: 1.0, + setPrimitiveFunction: true, + getPrimitiveFunction: true, + }); addProperty({ name: "screenSpaceError", initialValue: 4.0, From dacd0819dcb5c83cccf5cbe790af69b7fce52cb7 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 6 May 2022 13:02:47 -0700 Subject: [PATCH 059/679] more accurate level difference for the blend parent --- Source/Scene/VoxelTraversal.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index af50c7e57e1..d6653a11f46 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -270,8 +270,7 @@ VoxelTraversal.prototype.update = function ( const levelBlendFactor = primitive._levelBlendFactor; const haslevelBlendFactor = levelBlendFactor > 0.0; const hasKeyframes = keyframeCount > 1; - const sampleCount = - (haslevelBlendFactor ? 2 : 1) * (hasKeyframes > 1 ? 2 : 1); + const sampleCount = (haslevelBlendFactor ? 2 : 1) * (hasKeyframes ? 2 : 1); this._sampleCount = sampleCount; const useLeafNodes = sampleCount >= 2; @@ -1532,7 +1531,7 @@ function generateOctree(that, sampleCount, levelBlendFactor) { } const levelDifferenceChild = levelDifference; - const levelDifferenceParent = levelDifference + 1; + const levelDifferenceParent = 1; const megatextureIndexChild = keyframeNode.megatextureIndex; const megatextureIndexParent = parentKeyframeNode.megatextureIndex; From dd31f9ccdc2f925a449d3b73de7508420a819f7d Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 10 May 2022 08:40:43 -0700 Subject: [PATCH 060/679] added back time dynamic --- Source/Scene/Cesium3DTilesVoxelProvider.js | 19 ++++++++++------ Source/Scene/GltfVoxelProvider.js | 12 +++++++++-- Source/Scene/VoxelPrimitive.js | 24 ++++++--------------- Source/Scene/VoxelProvider.js | 25 ++++++++++++++++++++++ Source/Scene/VoxelTraversal.js | 5 +++-- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 8d441a1e72c..7a85e8e7762 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -383,17 +383,12 @@ const scratchImplicitTileCoordinates = new ImplicitTileCoordinates({ * @param {Number} [options.tileX=0] The tile's X coordinate. * @param {Number} [options.tileY=0] The tile's Y coordinate. * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * @param {Number} [options.keyframe=0] The requested keyframe. * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. * * @exception {DeveloperError} The provider must be ready. */ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - const tileLevel = defaultValue(options.tileLevel, 0); - const tileX = defaultValue(options.tileX, 0); - const tileY = defaultValue(options.tileY, 0); - const tileZ = defaultValue(options.tileZ, 0); - //>>includeStart('debug', pragmas.debug); if (!this.ready) { throw new DeveloperError( @@ -402,6 +397,18 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { } //>>includeEnd('debug'); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const tileLevel = defaultValue(options.tileLevel, 0); + const tileX = defaultValue(options.tileX, 0); + const tileY = defaultValue(options.tileY, 0); + const tileZ = defaultValue(options.tileZ, 0); + const keyframe = defaultValue(options.keyframe, 0); + + // 3D Tiles currently doesn't support time-dynamic data. + if (keyframe !== 0) { + return undefined; + } + // 1. Load the subtree that the tile belongs to (possibly from the subtree cache) // 1a. If not in the cache, load the subtree resource // 1b. If not in the cache, load the subtree object diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index cb8299748cc..6b8a68f0112 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -317,25 +317,33 @@ GltfVoxelProvider.prototype.update = function (frameState) { * @param {Number} [options.tileX=0] The tile's X coordinate. * @param {Number} [options.tileY=0] The tile's Y coordinate. * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * @param {Number} [options.keyframe=0] The requested keyframe. * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. * * @exception {DeveloperError} The provider must be ready. * @exception {DeveloperError} Only level 0 can be requested. */ GltfVoxelProvider.prototype.requestData = function (options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); if (!this.ready) { throw new DeveloperError( "requestData must not be called before the provider is ready." ); } + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + // glTF current doesn't support level of detail. const tileLevel = defaultValue(options.tileLevel, 0); if (tileLevel > 0) { return undefined; } - //>>includeEnd('debug'); + // glTF currently doesn't support time-dynamic. + const keyframe = defaultValue(options.keyframe, 0); + if (keyframe > 0) { + return undefined; + } return Promise.resolve(this._data); }; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index af08dc9eecf..da305df1172 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -249,17 +249,11 @@ function VoxelPrimitive(options) { */ this._pickId = undefined; - // /** - // * @type {TimeIntervalCollection} - // * @private - // */ - // this._timeIntervalCollection = undefined; - - // /** - // * @type {Clock} - // * @private - // */ - // this._clock = options.clock; + /** + * @type {Clock} + * @private + */ + this._clock = options.clock; // Transforms and other values that are computed when the shape changes @@ -1096,12 +1090,6 @@ VoxelPrimitive.prototype.update = function (frameState) { }); uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - // // TODO remove? - // that._timeIntervalCollection = defaultValue( - // provider.timeIntervalCollection, - // that._timeIntervalCollection - // ); - const dimensions = provider.dimensions; const shapeType = provider.shape; @@ -1425,7 +1413,7 @@ VoxelPrimitive.prototype.update = function (frameState) { if (this._ready && this._shapeVisible) { const traversal = this._traversal; const clock = this._clock; - const timeIntervalCollection = this._timeIntervalCollection; + const timeIntervalCollection = provider.timeIntervalCollection; // Find the keyframe location to render at. Doesn't need to be a whole number. let keyframeLocation = 0.0; diff --git a/Source/Scene/VoxelProvider.js b/Source/Scene/VoxelProvider.js index d4f59eeb3c3..cb1356ddd8b 100644 --- a/Source/Scene/VoxelProvider.js +++ b/Source/Scene/VoxelProvider.js @@ -195,6 +195,30 @@ Object.defineProperties(VoxelProvider.prototype, { maximumTileCount: { get: DeveloperError.throwInstantiationError, }, + + /** + * Gets the number of keyframes in the dataset. + * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype + * @type {Number} + * @readonly + */ + keyframeCount: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * Gets the {@link TimeIntervalCollection} for the dataset, or undefined if it doesn't have timestamps. + * This should not be called before {@link VoxelProvider#ready} returns true. + * + * @memberof VoxelProvider.prototype + * @type {TimeIntervalCollection} + * @readonly + */ + timeIntervalCollection: { + get: DeveloperError.throwInstantiationError, + }, }); /** @@ -206,6 +230,7 @@ Object.defineProperties(VoxelProvider.prototype, { * @param {Number} [options.tileX=0] The tile's X coordinate. * @param {Number} [options.tileY=0] The tile's Y coordinate. * @param {Number} [options.tileZ=0] The tile's Z coordinate. + * @param {Number} [options.keyframe=0] The requested keyframe. * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. * * @exception {DeveloperError} The provider must be ready. diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index d6653a11f46..ca5e33b18dd 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -426,9 +426,10 @@ function recomputeBoundingVolumesRecursive(that, node) { function requestTiles(that, keyframeNode) { const keys = Object.keys(that.megatextures); const length = keys.length; + const keyframe = keyframeNode.keyframe; for (let i = 0; i < length; i++) { const metadataName = keys[i]; - requestData(that, keyframeNode, metadataName); + requestData(that, keyframeNode, metadataName, keyframe); } } /** @@ -1496,7 +1497,7 @@ function generateOctree(that, sampleCount, levelBlendFactor) { if (useLeafNodes) { const baseIdx = leafNodeCount * 5; - const useTimeDynamic = false; + const useTimeDynamic = true; if (useTimeDynamic) { const previousKeyframeNode = node.renderableKeyframeNodePrevious; const nextKeyframeNode = node.renderableKeyframeNodeNext; From 8c792a0b3e7c8ceaa3b7a3bd961b6f48b62f43ad Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 13 May 2022 14:38:54 -0700 Subject: [PATCH 061/679] intersection clipping planes working --- Source/Scene/VoxelPrimitive.js | 111 +++++++++++++++++++++++++++++++++ Source/Scene/VoxelTraversal.js | 2 +- Source/Shaders/VoxelFS.glsl | 48 ++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index da305df1172..55e5a0eef57 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -17,7 +17,9 @@ import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import PrimitiveType from "../Core/PrimitiveType.js"; import BlendingState from "./BlendingState.js"; +import ClippingPlaneCollection from "./ClippingPlaneCollection.js"; import CullFace from "./CullFace.js"; +import getClippingFunction from "./getClippingFunction.js"; import Material from "./Material.js"; import MetadataComponentType from "./MetadataComponentType.js"; import MetadataType from "./MetadataType.js"; @@ -181,6 +183,27 @@ function VoxelPrimitive(options) { */ this._maxClippingBoundsOld = new Cartesian3(); + /** + * Clipping planes on the primitive + * + * @type {ClippingPlaneCollection} + * @private + */ + this._clippingPlanes = undefined; + + /** + * Keeps track of when the clipping planes change + * + * @type {Number} + * @private + */ + this._clippingPlanesState = 0; + + /** + * Keeps track of when the clipping planes are enabled / disabled + */ + this._clippingPlanesEnabled = false; + /** * The primitive's model matrix. * @@ -381,6 +404,8 @@ function VoxelPrimitive(options) { transformNormalLocalToWorld: new Matrix3(), cameraPositionUv: new Cartesian3(), ndcSpaceAxisAlignedBoundingBox: new Cartesian4(), + clippingPlanesTexture: undefined, + clippingPlanesMatrix: new Matrix4(), stepSize: 0, pickColor: new Color(), }; @@ -973,6 +998,22 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, }, + /** + * The {@link ClippingPlaneCollection} used to selectively disable rendering the primitive. + * + * @memberof VoxelPrimitive.prototype + * @type {ClippingPlaneCollection} + */ + clippingPlanes: { + get: function () { + return this._clippingPlanes; + }, + set: function (clippingPlanes) { + // Don't need to check if undefined, it's handled in the setOwner function + ClippingPlaneCollection.setOwner(clippingPlanes, this, "_clippingPlanes"); + }, + }, + /** * Gets or sets the custom shader. If undefined, {@link VoxelPrimitive.DefaultCustomShader} is set. * @@ -1480,6 +1521,45 @@ VoxelPrimitive.prototype.update = function (frameState) { this._shaderDirty = true; } + // Check if clipping planes changed + const clippingPlanes = this._clippingPlanes; + if (defined(clippingPlanes)) { + clippingPlanes.update(frameState); + const clippingPlanesState = clippingPlanes.clippingPlanesState; + const clippingPlanesEnabled = clippingPlanes.enabled; + if ( + this._clippingPlanesState !== clippingPlanesState || + this._clippingPlanesEnabled !== clippingPlanesEnabled + ) { + this._clippingPlanesState = clippingPlanesState; + this._clippingPlanesEnabled = clippingPlanesEnabled; + if (clippingPlanesEnabled) { + uniforms.clippingPlanesTexture = clippingPlanes.texture; + + // Compute the clipping plane's transformation to uv space and then take the inverse + // transpose to properly transform the hessian normal form of the plane. + + // transpose(inverse(worldToUv * clippingPlaneLocalToWorld)) + // transpose(inverse(clippingPlaneLocalToWorld) * inverse(worldToUv)) + // transpose(inverse(clippingPlaneLocalToWorld) * uvToWorld) + + const transformPositionUvToWorld = this._transformPositionUvToWorld; + uniforms.clippingPlanesMatrix = Matrix4.transpose( + Matrix4.multiplyTransformation( + Matrix4.inverse( + clippingPlanes.modelMatrix, + uniforms.clippingPlanesMatrix + ), + transformPositionUvToWorld, + uniforms.clippingPlanesMatrix + ), + uniforms.clippingPlanesMatrix + ); + } + this._shaderDirty = true; + } + } + const leafNodeTexture = traversal.leafNodeTexture; if (defined(leafNodeTexture)) { uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; @@ -1703,6 +1783,12 @@ function buildDrawCommands(that, context) { const customShader = that._customShader; const attributeLength = types.length; const hasStatistics = defined(minimumValues) && defined(maximumValues); + const clippingPlanes = that._clippingPlanes; + const clippingPlanesLength = + defined(clippingPlanes) && clippingPlanes.enabled + ? clippingPlanes.length + : 0; + let uniformMap = that._uniformMap; // Build shader @@ -1779,8 +1865,31 @@ function buildDrawCommands(that, context) { ); } + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES", + undefined, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addDefine( + "CLIPPING_PLANES_COUNT", + clippingPlanesLength, + ShaderDestination.FRAGMENT + ); + } + // Count how many intersections the shader will do. let intersectionCount = shape.shaderMaximumIntersectionsLength; + + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount += clippingPlanesLength; + } + if (depthTest) { shaderBuilder.addDefine( "DEPTH_INTERSECTION_INDEX", @@ -1789,6 +1898,7 @@ function buildDrawCommands(that, context) { ); intersectionCount += 1; } + shaderBuilder.addDefine( "INTERSECTION_COUNT", intersectionCount, @@ -2254,6 +2364,7 @@ VoxelPrimitive.prototype.destroy = function () { this._pickId = this._pickId && this._pickId.destroy(); this._traversal = this._traversal && this._traversal.destroy(); + this._clippingPlanes = this._clippingPlanes && this._clippingPlanes.destroy(); return destroyObject(this); }; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index ca5e33b18dd..8282debb4a4 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -1497,7 +1497,7 @@ function generateOctree(that, sampleCount, levelBlendFactor) { if (useLeafNodes) { const baseIdx = leafNodeCount * 5; - const useTimeDynamic = true; + const useTimeDynamic = false; if (useTimeDynamic) { const previousKeyframeNode = node.renderableKeyframeNodePrevious; const nextKeyframeNode = node.renderableKeyframeNodeNext; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 9b87e8c4d59..498de40aeab 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -19,6 +19,9 @@ Below is an example of how this code might look. Properties like "temperature" a #define STATISTICS #define PADDING #define PICKING +#define CLIPPING_PLANES +#define CLIPPING_PLANES_COUNT +#define CLIPPING_PLANES_INTERSECTION_INDEX // Uniforms uniform sampler2D u_megatextureTextures[PROPERTY_COUNT]; @@ -199,6 +202,11 @@ uniform float u_stepSize; uniform vec4 u_pickColor; #endif +#if defined(CLIPPING_PLANES) + uniform sampler2D u_clippingPlanesTexture; + uniform mat4 u_clippingPlanesMatrix; +#endif + #if defined(SHAPE_BOX) /* Box defines: #define BOX_INTERSECTION_INDEX ### // always 0 @@ -607,6 +615,26 @@ vec4 intersectHalfPlane(Ray ray, float angle) { } #endif +#if defined(CLIPPING_PLANES) +// Plane is in Hessian Normal Form +vec2 intersectPlane(Ray ray, vec4 plane) { + vec3 o = ray.pos; + vec3 d = ray.dir; + vec3 n = plane.xyz; // normal + float w = plane.w; // -dot(pointOnPlane, normal) + + float a = dot(o, n); + float b = dot(d, n); + float t = -(w + a) / b; + + if (dot(d, n) > 0.0) { + return vec2(t, +INF_HIT); + } else { + return vec2(-INF_HIT, t); + } +} +#endif + #if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF))) vec2 intersectHalfSpace(Ray ray, float angle) { @@ -1278,6 +1306,21 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { } #endif +#if defined(CLIPPING_PLANES) +void intersectClippingPlanes(Ray ray, inout Intersections ix) { + for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { + int pixY = i / CLIPPING_PLANES_COUNT; + int pixX = i - (pixY * CLIPPING_PLANES_COUNT); + vec2 uv = (vec2(pixX, pixY) + 0.5) / float(CLIPPING_PLANES_COUNT); + vec4 localPlane = texture2D(u_clippingPlanesTexture, uv); + // u_clippingPlanesMatrix bakes in the transformation to UV space. + vec4 planeUv = czm_transformPlane(localPlane, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i, intersection); + } +} +#endif + #if defined(DEPTH_TEST) void intersectDepth(vec2 screenCoord, Ray ray, inout Intersections ix) { float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); @@ -1308,6 +1351,11 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Int return vec2(NO_HIT); } + // Clipping planes + #if defined(CLIPPING_PLANES) + intersectClippingPlanes(ray, ix); + #endif + // Depth #if defined(DEPTH_TEST) intersectDepth(screenCoord, ray, ix); From df50be7b3073f28e4cb501abd4c7e44d7875ad72 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 13 May 2022 16:26:25 -0700 Subject: [PATCH 062/679] added clipping union but not quite working --- Source/Scene/VoxelPrimitive.js | 7 ++++++ Source/Shaders/VoxelFS.glsl | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 55e5a0eef57..c92249fd87f 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1876,6 +1876,13 @@ function buildDrawCommands(that, context) { clippingPlanesLength, ShaderDestination.FRAGMENT ); + if (clippingPlanes.unionClippingRegions) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_UNION", + undefined, + ShaderDestination.FRAGMENT + ); + } } // Count how many intersections the shader will do. diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 498de40aeab..a9c2f170ed8 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -20,6 +20,7 @@ Below is an example of how this code might look. Properties like "temperature" a #define PADDING #define PICKING #define CLIPPING_PLANES +#define CLIPPING_PLANES_UNION #define CLIPPING_PLANES_COUNT #define CLIPPING_PLANES_INTERSECTION_INDEX @@ -1318,6 +1319,48 @@ void intersectClippingPlanes(Ray ray, inout Intersections ix) { vec2 intersection = intersectPlane(ray, planeUv); setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i, intersection); } + + #if !defined(CLIPPING_PLANES_UNION) + // Sort the clipping intersections by t and record whether the interval is + // going in the positive or negative direction. + vec2 intersections[CLIPPING_PLANES_COUNT]; + for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { + vec2 entryExitT = getIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i); + bool goingUpward = entryExitT.y == +INF_HIT; + float direction = float(goingUpward); // 0 = downward, 1 = updard + float t = goingUpward ? entryExitT.x : entryExitT.y; + intersections[i] = vec2(t, direction); + } + + // Do bubble sort on the intersections + const int sortPasses = CLIPPING_PLANES_COUNT - 1; + for (int n = sortPasses; n > 0; --n) { + for (int i = 0; i < sortPasses; ++i) { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + vec2 ix0 = intersections[i + 0]; + vec2 ix1 = intersections[i + 1]; + float tmin = min(ix0.x, ix1.x); + float tmax = max(ix0.x, ix1.x); + float dmin = tmin == ix0.x ? ix0.y : ix1.y; + float dmax = tmin == ix0.x ? ix1.y : ix0.y; + intersections[i + 0] = vec2(tmin, dmin); + intersections[i + 1] = vec2(tmax, dmax); + } + } + + // Find the intersection intervals + for (int i = 0; i < CLIPPING_PLANES_COUNT - 1; i++) { + vec2 ix0 = intersections[i + 0]; + vec2 ix1 = intersections[i + 1]; + + // positive direction followed by negative direction + bool foundIntersection = ix0.y == 1.0 && ix1.y == 0.0; + vec2 entryExitT = foundIntersection ? vec2(ix0.x, ix1.x) : vec2(NO_HIT); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i, entryExitT); + } + #endif } #endif From b0197fff1f917d3a3b5544256f8b18ebc8095c4c Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 13 May 2022 20:24:38 -0700 Subject: [PATCH 063/679] working union and intersection clipping planes --- Source/Scene/VoxelPrimitive.js | 37 ++++++++++++++++- Source/Shaders/VoxelFS.glsl | 72 ++++++++++++---------------------- 2 files changed, 61 insertions(+), 48 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index c92249fd87f..5cd9297147e 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1788,6 +1788,9 @@ function buildDrawCommands(that, context) { defined(clippingPlanes) && clippingPlanes.enabled ? clippingPlanes.length : 0; + const clippingPlanesUnion = defined(clippingPlanes) + ? clippingPlanes.unionClippingRegions + : false; let uniformMap = that._uniformMap; @@ -1876,7 +1879,7 @@ function buildDrawCommands(that, context) { clippingPlanesLength, ShaderDestination.FRAGMENT ); - if (clippingPlanes.unionClippingRegions) { + if (clippingPlanesUnion) { shaderBuilder.addDefine( "CLIPPING_PLANES_UNION", undefined, @@ -1894,7 +1897,11 @@ function buildDrawCommands(that, context) { intersectionCount, ShaderDestination.FRAGMENT ); - intersectionCount += clippingPlanesLength; + if (clippingPlanesUnion) { + intersectionCount += 2; + } else { + intersectionCount += 1; + } } if (depthTest) { @@ -2271,6 +2278,32 @@ function buildDrawCommands(that, context) { ]); } + if (clippingPlanesLength > 0) { + // Extract the getClippingPlane function from the getClippingFunction string. + // This is a bit of a hack. + const functionId = "getClippingPlane"; + const entireFunction = getClippingFunction(clippingPlanes, context); + const functionSignatureBegin = 0; + const functionSignatureEnd = entireFunction.indexOf(")") + 1; + const functionBodyBegin = + entireFunction.indexOf("{", functionSignatureEnd) + 1; + const functionBodyEnd = entireFunction.indexOf("}", functionBodyBegin); + const functionSignature = entireFunction.slice( + functionSignatureBegin, + functionSignatureEnd + ); + const functionBody = entireFunction.slice( + functionBodyBegin, + functionBodyEnd + ); + shaderBuilder.addFunction( + functionId, + functionSignature, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [functionBody]); + } + // Compile shaders const shaderBuilderPick = shaderBuilder.clone(); shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index a9c2f170ed8..f72294d0d9c 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1309,56 +1309,36 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { #if defined(CLIPPING_PLANES) void intersectClippingPlanes(Ray ray, inout Intersections ix) { - for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { - int pixY = i / CLIPPING_PLANES_COUNT; - int pixX = i - (pixY * CLIPPING_PLANES_COUNT); - vec2 uv = (vec2(pixX, pixY) + 0.5) / float(CLIPPING_PLANES_COUNT); - vec4 localPlane = texture2D(u_clippingPlanesTexture, uv); - // u_clippingPlanesMatrix bakes in the transformation to UV space. - vec4 planeUv = czm_transformPlane(localPlane, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i, intersection); - } - - #if !defined(CLIPPING_PLANES_UNION) - // Sort the clipping intersections by t and record whether the interval is - // going in the positive or negative direction. - vec2 intersections[CLIPPING_PLANES_COUNT]; + #if defined(CLIPPING_PLANES_UNION) + float minPositiveT = +INF_HIT; + float maxNegativeT = -INF_HIT; for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { - vec2 entryExitT = getIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i); - bool goingUpward = entryExitT.y == +INF_HIT; - float direction = float(goingUpward); // 0 = downward, 1 = updard - float t = goingUpward ? entryExitT.x : entryExitT.y; - intersections[i] = vec2(t, direction); + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + if (intersection.y == +INF_HIT) { + minPositiveT = min(minPositiveT, intersection.x); + } else { + maxNegativeT = max(maxNegativeT, intersection.y); + } } - - // Do bubble sort on the intersections - const int sortPasses = CLIPPING_PLANES_COUNT - 1; - for (int n = sortPasses; n > 0; --n) { - for (int i = 0; i < sortPasses; ++i) { - // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to break early instead - if (i >= n) { break; } - vec2 ix0 = intersections[i + 0]; - vec2 ix1 = intersections[i + 1]; - float tmin = min(ix0.x, ix1.x); - float tmax = max(ix0.x, ix1.x); - float dmin = tmin == ix0.x ? ix0.y : ix1.y; - float dmax = tmin == ix0.x ? ix1.y : ix0.y; - intersections[i + 0] = vec2(tmin, dmin); - intersections[i + 1] = vec2(tmax, dmax); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, vec2(minPositiveT, +INF_HIT)); + #else + float maxPositiveT = -INF_HIT; + float minNegativeT = +INF_HIT; + for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + if (intersection.y == +INF_HIT) { + maxPositiveT = max(maxPositiveT, intersection.x); + } else { + minNegativeT = min(minNegativeT, intersection.y); } } - - // Find the intersection intervals - for (int i = 0; i < CLIPPING_PLANES_COUNT - 1; i++) { - vec2 ix0 = intersections[i + 0]; - vec2 ix1 = intersections[i + 1]; - - // positive direction followed by negative direction - bool foundIntersection = ix0.y == 1.0 && ix1.y == 0.0; - vec2 entryExitT = foundIntersection ? vec2(ix0.x, ix1.x) : vec2(NO_HIT); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + i, entryExitT); + if (maxPositiveT < minNegativeT) { + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(maxPositiveT, minNegativeT)); + } else { + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(NO_HIT)); } #endif } From b7f329380b751d0b2b14ba070ccf19d502d25ea8 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 13 May 2022 20:37:18 -0700 Subject: [PATCH 064/679] fast path for one clipping plane --- Source/Scene/VoxelPrimitive.js | 4 +++- Source/Shaders/VoxelFS.glsl | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 5cd9297147e..31ad8bdeb7b 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1897,7 +1897,9 @@ function buildDrawCommands(that, context) { intersectionCount, ShaderDestination.FRAGMENT ); - if (clippingPlanesUnion) { + if (clippingPlanesLength === 1) { + intersectionCount += 1; + } else if (clippingPlanesUnion) { intersectionCount += 2; } else { intersectionCount += 1; diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index f72294d0d9c..f0280d4e68f 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1309,7 +1309,13 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { #if defined(CLIPPING_PLANES) void intersectClippingPlanes(Ray ray, inout Intersections ix) { - #if defined(CLIPPING_PLANES_UNION) + #if (CLIPPING_PLANES_COUNT == 1) + // Union and intersection are the same when there's one clipping plane, and the code + // is more simplified. + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, intersection); + #elif defined(CLIPPING_PLANES_UNION) float minPositiveT = +INF_HIT; float maxNegativeT = -INF_HIT; for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { @@ -1323,7 +1329,7 @@ void intersectClippingPlanes(Ray ray, inout Intersections ix) { } setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, vec2(minPositiveT, +INF_HIT)); - #else + #else // intersection float maxPositiveT = -INF_HIT; float minNegativeT = +INF_HIT; for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { From 9d81882099cea8209a448ed793387d068e19adc4 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Fri, 13 May 2022 20:49:18 -0700 Subject: [PATCH 065/679] small shader cleaning --- Source/Shaders/VoxelFS.glsl | 273 ++++++++++++++++++------------------ 1 file changed, 133 insertions(+), 140 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index f0280d4e68f..33ee94c9382 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -384,9 +384,6 @@ int intMax(int a, int b) { int intClamp(int v, int minVal, int maxVal) { return intMin(intMax(v, minVal), maxVal); } -float safeMod(float a, float m) { - return mod(mod(a, m) + m, m); -} bool inRange(float v, float minVal, float maxVal) { return clamp(v, minVal, maxVal) == v; } @@ -412,139 +409,6 @@ vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) // -------------------------------------------------------- // Intersection tests, shape coordinate conversions, etc // -------------------------------------------------------- -struct Intersections { - // Don't access these member variables directly - call the functions instead. - - #if (INTERSECTION_COUNT > 1) - // Store an array of intersections. Each intersection is composed of: - // x for the T value - // y for the shape type - which encodes positive vs negative and entering vs exiting - // For example: - // y = 0: positive shape entry - // y = 1: positive shape exit - // y = 2: negative shape entry - // y = 3: negative shape exit - vec2 intersections[INTERSECTION_COUNT * 2]; - - // Maintain state for future nextIntersection calls - int index; - int surroundCount; - bool surroundIsPositive; - #else - // When there's only one positive shape intersection none of the extra stuff is needed. - float intersections[2]; - #endif -}; - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x -#else - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) -#else - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) -#else - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y -#endif - -#if (INTERSECTION_COUNT > 1) -vec2 nextIntersection(inout Intersections ix) { - vec2 entryExitT = vec2(NO_HIT); - - const int passCount = INTERSECTION_COUNT * 2; - for (int i = 0; i < passCount; ++i) { - // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to continue instead. - if (i < ix.index) { - continue; - } - - vec2 intersect = ix.intersections[i]; - float t = intersect.x; - bool currShapeIsPositive = intersect.y < 2.0; - bool enter = mod(intersect.y, 2.0) == 0.0; - - ix.surroundCount += enter ? +1 : -1; - ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; - - // entering positive or exiting negative - if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { - entryExitT.x = t; - } - - // exiting positive or entering negative after being inside positive - // TODO: Can this be simplified? - bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; - bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; - if (exitPositive || enterNegativeFromPositive) { - entryExitT.y = t; - - // entry and exit have been found, so the loop can stop - if (exitPositive) { - // After exiting positive shape there is nothing left to intersect, so jump to the end index. - ix.index = passCount; - } else { - // There could be more intersections against the positive shape in the future. - ix.index = i + 1; - } - break; - } - } - - return entryExitT; -} -#endif - -#if (INTERSECTION_COUNT > 1) -void initializeIntersections(inout Intersections ix) { - // Sort the intersections from min T to max T with bubble sort. - // Note: If this sorting function changes, some of the intersection test may - // need to be updated. Search for "bubble sort" to find those areas. - const int sortPasses = INTERSECTION_COUNT * 2 - 1; - for (int n = sortPasses; n > 0; --n) { - for (int i = 0; i < sortPasses; ++i) { - // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to break early instead - if (i >= n) { break; } - - vec2 intersect0 = ix.intersections[i + 0]; - vec2 intersect1 = ix.intersections[i + 1]; - - float t0 = intersect0.x; - float t1 = intersect1.x; - float b0 = intersect0.y; - float b1 = intersect1.y; - - float tmin = min(t0, t1); - float tmax = max(t0, t1); - float bmin = tmin == t0 ? b0 : b1; - float bmax = tmin == t0 ? b1 : b0; - - ix.intersections[i + 0] = vec2(tmin, bmin); - ix.intersections[i + 1] = vec2(tmax, bmax); - } - } - - // Prepare initial state for nextIntersection - ix.index = 0; - ix.surroundCount = 0; - ix.surroundIsPositive = false; -} -#endif - #if defined(SHAPE_BOX) vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] { @@ -973,6 +837,139 @@ float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { } #endif +struct Intersections { + // Don't access these member variables directly - call the functions instead. + + #if (INTERSECTION_COUNT > 1) + // Store an array of intersections. Each intersection is composed of: + // x for the T value + // y for the shape type - which encodes positive vs negative and entering vs exiting + // For example: + // y = 0: positive shape entry + // y = 1: positive shape exit + // y = 2: negative shape entry + // y = 3: negative shape exit + vec2 intersections[INTERSECTION_COUNT * 2]; + + // Maintain state for future nextIntersection calls + int index; + int surroundCount; + bool surroundIsPositive; + #else + // When there's only one positive shape intersection none of the extra stuff is needed. + float intersections[2]; + #endif +}; + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x +#else + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) +#else + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) +#else + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y +#endif + +#if (INTERSECTION_COUNT > 1) +void initializeIntersections(inout Intersections ix) { + // Sort the intersections from min T to max T with bubble sort. + // Note: If this sorting function changes, some of the intersection test may + // need to be updated. Search for "bubble sort" to find those areas. + const int sortPasses = INTERSECTION_COUNT * 2 - 1; + for (int n = sortPasses; n > 0; --n) { + for (int i = 0; i < sortPasses; ++i) { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + + vec2 intersect0 = ix.intersections[i + 0]; + vec2 intersect1 = ix.intersections[i + 1]; + + float t0 = intersect0.x; + float t1 = intersect1.x; + float b0 = intersect0.y; + float b1 = intersect1.y; + + float tmin = min(t0, t1); + float tmax = max(t0, t1); + float bmin = tmin == t0 ? b0 : b1; + float bmax = tmin == t0 ? b1 : b0; + + ix.intersections[i + 0] = vec2(tmin, bmin); + ix.intersections[i + 1] = vec2(tmax, bmax); + } + } + + // Prepare initial state for nextIntersection + ix.index = 0; + ix.surroundCount = 0; + ix.surroundIsPositive = false; +} +#endif + +#if (INTERSECTION_COUNT > 1) +vec2 nextIntersection(inout Intersections ix) { + vec2 entryExitT = vec2(NO_HIT); + + const int passCount = INTERSECTION_COUNT * 2; + for (int i = 0; i < passCount; ++i) { + // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to continue instead. + if (i < ix.index) { + continue; + } + + vec2 intersect = ix.intersections[i]; + float t = intersect.x; + bool currShapeIsPositive = intersect.y < 2.0; + bool enter = mod(intersect.y, 2.0) == 0.0; + + ix.surroundCount += enter ? +1 : -1; + ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; + + // entering positive or exiting negative + if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { + entryExitT.x = t; + } + + // exiting positive or entering negative after being inside positive + // TODO: Can this be simplified? + bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; + bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; + if (exitPositive || enterNegativeFromPositive) { + entryExitT.y = t; + + // entry and exit have been found, so the loop can stop + if (exitPositive) { + // After exiting positive shape there is nothing left to intersect, so jump to the end index. + ix.index = passCount; + } else { + // There could be more intersections against the positive shape in the future. + ix.index = i + 1; + } + break; + } + } + + return entryExitT; +} +#endif + #if defined(SHAPE_BOX) void intersectShape(Ray ray, inout Intersections ix) { @@ -1739,10 +1736,6 @@ void main() fragmentInput.voxel.viewDirWorld = viewDirWorld; fragmentInput.voxel.travelDistance = traversalData.stepT; - #if defined(STYLE_USE_POSITION_EC) - fragmentInput.voxel.positionEC = vec3(u_transformPositionUvToView * vec4(positionUv, 1.0)); - #endif - // Run the custom shader czm_modelMaterial materialOutput; fragmentMain(fragmentInput, materialOutput); From 46c6e2f2fe93203746d8b23160b83df5af72b722 Mon Sep 17 00:00:00 2001 From: Ian Lilley Date: Tue, 17 May 2022 09:15:25 -0700 Subject: [PATCH 066/679] cant use scratch variable in promise chain --- Source/Scene/Cesium3DTilesVoxelProvider.js | 25 ++++++++-------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 7a85e8e7762..e1f868ca25b 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -365,15 +365,6 @@ function Cesium3DTilesVoxelProvider(options) { }); } -const scratchImplicitTileCoordinates = new ImplicitTileCoordinates({ - subdivisionScheme: ImplicitSubdivisionScheme.OCTREE, // not known yet - subtreeLevels: 1, // not known yet - level: 0, - x: 0, - y: 0, - z: 0, -}); - /** * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * This function should not be called before {@link VoxelProvider#ready} returns true. @@ -419,13 +410,15 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { const types = this.types; const componentTypes = this.componentTypes; - const tileCoordinates = scratchImplicitTileCoordinates; - tileCoordinates.subdivisionScheme = implicitTileset.subdivisionScheme; - tileCoordinates.subtreeLevels = implicitTileset.subtreeLevels; - tileCoordinates.level = tileLevel; - tileCoordinates.x = tileX; - tileCoordinates.y = tileY; - tileCoordinates.z = tileZ; + // Can't use a scratch variable here because the object is used inside the promise chain. + const tileCoordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: tileLevel, + x: tileX, + y: tileY, + z: tileZ, + }); // First load the subtree to check if the tile is available. // If the subtree has been requested previously it might still be in the cache. From a27d7338f5e0df14a21c97261fd565375e049d52 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 1 Jun 2022 18:23:12 -0400 Subject: [PATCH 067/679] Use newer property name --- Source/Scene/Cesium3DTilesVoxelProvider.js | 2 +- Source/Scene/GltfVoxelProvider.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index e1f868ca25b..128dbbe4213 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -563,7 +563,7 @@ function getGltfLoader(implicitTileset, tileCoord) { const gltfLoader = new GltfLoader({ gltfResource: gltfResource, releaseGltfJson: false, - loadAsTypedArray: true, + loadAttributesAsTypedArray: true, }); gltfLoader.load(); diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index 6b8a68f0112..e3a3f4f24e2 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -199,7 +199,7 @@ function GltfVoxelProvider(options) { const loader = new GltfLoader({ gltfResource: gltfResource, releaseGltfJson: true, - loadAsTypedArray: true, + loadAttributesAsTypedArray: true, }); loader.load(); promise = loader.promise; From 0d8432f841cc9e22eeddd2bb711c125873e1e03a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 25 Jul 2022 13:31:32 -0400 Subject: [PATCH 068/679] Fix variable name --- Source/Scene/VoxelPrimitive.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 31ad8bdeb7b..976638f3fcf 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -520,12 +520,12 @@ Object.defineProperties(VoxelPrimitive.prototype, { //>>includeStart('debug', pragmas.debug); if (!this._ready) { throw new DeveloperError( - "orientedBoudingBox must not be called before the primitive is ready." + "orientedBoundingBox must not be called before the primitive is ready." ); } //>>includeEnd('debug'); - return this._shape.orientedBoudingBox; + return this._shape.orientedBoundingBox; }, }, From 3d1a8ad08329f301d7242b7a003cf25bbc12a0fb Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 25 Jul 2022 17:54:52 -0400 Subject: [PATCH 069/679] Don't request tile multiple times --- Source/Scene/VoxelTraversal.js | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index 8282debb4a4..df2472a339d 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -413,35 +413,15 @@ function recomputeBoundingVolumesRecursive(that, node) { } } -/** - * Call requestData for each metadata - * - * @function - * - * @param {VoxelTraversal} that - * @param {KeyframeNode} keyframeNode - * - * @private - */ -function requestTiles(that, keyframeNode) { - const keys = Object.keys(that.megatextures); - const length = keys.length; - const keyframe = keyframeNode.keyframe; - for (let i = 0; i < length; i++) { - const metadataName = keys[i]; - requestData(that, keyframeNode, metadataName, keyframe); - } -} /** * @function * * @param {VoxelTraversal} that * @param {KeyframeNode} keyframeNode - * @param {String} metadataName * * @private */ -function requestData(that, keyframeNode, metadataName) { +function requestData(that, keyframeNode) { if ( that._simultaneousRequestCount >= VoxelTraversal.simultaneousRequestCountMaximum @@ -503,7 +483,6 @@ function requestData(that, keyframeNode, metadataName) { tileY: tileY, tileZ: tileZ, keyframe: keyframe, - metadataName: metadataName, }); if (defined(promise)) { @@ -802,7 +781,7 @@ function loadAndUnload(that, frameState) { continue; } if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.UNLOADED) { - requestTiles(that, highPriorityKeyframeNode); + requestData(that, highPriorityKeyframeNode); } if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.RECEIVED) { let addNodeIndex = 0; From f1b5f8dbd9ececb4fe5a4f8427cbfed15e831168 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 25 Jul 2022 19:44:13 -0400 Subject: [PATCH 070/679] Get availability of subtree root tile from parent subtree to avoid 404s --- Source/Scene/Cesium3DTilesVoxelProvider.js | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 128dbbe4213..1779ba02642 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -10,7 +10,6 @@ import Matrix4 from "../Core/Matrix4.js"; import Resource from "../Core/Resource.js"; import Cesium3DTilesetMetadata from "./Cesium3DTilesetMetadata.js"; import GltfLoader from "./GltfLoader.js"; -import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js"; import ImplicitSubtree from "./ImplicitSubtree.js"; import ImplicitTileCoordinates from "./ImplicitTileCoordinates.js"; import ImplicitTileset from "./ImplicitTileset.js"; @@ -422,7 +421,18 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { // First load the subtree to check if the tile is available. // If the subtree has been requested previously it might still be in the cache. - const subtreeCoord = tileCoordinates.getSubtreeCoordinates(); + let subtreeCoord; + + const isSubtreeRoot = + tileCoordinates.isSubtreeRoot() && tileCoordinates.level > 0; + + if (isSubtreeRoot) { + // Check availability from the parent subtree so that we don't try fetching a non-existent subtree + subtreeCoord = tileCoordinates.getParentSubtreeCoordinates(); + } else { + subtreeCoord = tileCoordinates.getSubtreeCoordinates(); + } + let subtree = subtreeCache.find(subtreeCoord); const that = this; @@ -467,7 +477,17 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { return subtreePromise .then(function (subtree) { const subtreeLoaderIndex = that._subtreeLoaders.indexOf(subtree); - if (!subtree.tileIsAvailableAtCoordinates(tileCoordinates)) { + + let available = false; + if (isSubtreeRoot) { + available = subtree.childSubtreeIsAvailableAtCoordinates( + tileCoordinates + ); + } else { + available = subtree.tileIsAvailableAtCoordinates(tileCoordinates); + } + + if (!available) { if (subtreeLoaderIndex !== -1) { that._subtreeLoaders.splice(subtreeLoaderIndex); } From 2718e5b2df7bdeff3b2c6708af5df6e22da97103 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 25 Jul 2022 20:48:07 -0400 Subject: [PATCH 071/679] Fix splice bug that caused non-deterministic loading --- Source/Scene/Cesium3DTilesVoxelProvider.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 1779ba02642..0dd6b3e63e5 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -270,7 +270,7 @@ function Cesium3DTilesVoxelProvider(options) { return rootGltfLoader.promise; }) .then(function (rootGltfLoader) { - that._gltfLoaders.splice(that._gltfLoaders.indexOf(rootGltfLoader)); + that._gltfLoaders.splice(that._gltfLoaders.indexOf(rootGltfLoader), 1); const gltfPrimitive = rootGltfLoader.components.nodes[0].primitives[0]; const voxel = gltfPrimitive.voxel; const primitiveType = gltfPrimitive.primitiveType; @@ -468,7 +468,8 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { that._subtreeLoaders.push(subtree); } that._subtreeResourceLoaders.splice( - that._subtreeResourceLoaders.indexOf(subtreeResource) + that._subtreeResourceLoaders.indexOf(subtreeResource), + 1 ); return subtree.readyPromise; }); @@ -489,7 +490,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { if (!available) { if (subtreeLoaderIndex !== -1) { - that._subtreeLoaders.splice(subtreeLoaderIndex); + that._subtreeLoaders.splice(subtreeLoaderIndex, 1); } return Promise.reject("Tile is not available"); } @@ -498,7 +499,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { that._gltfLoaders.push(gltfLoader); if (subtreeLoaderIndex !== -1) { - that._subtreeLoaders.splice(subtreeLoaderIndex); + that._subtreeLoaders.splice(subtreeLoaderIndex, 1); } return gltfLoader.promise; @@ -527,7 +528,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { ); } - that._gltfLoaders.splice(that._gltfLoaders.indexOf(gltfLoader)); + that._gltfLoaders.splice(that._gltfLoaders.indexOf(gltfLoader), 1); return Promise.resolve(data); }); }; From dcb828e53ff88c48dc9621b11c03fb514dcf99cc Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 28 Jul 2022 20:41:13 -0400 Subject: [PATCH 072/679] Fix non-uniform scale --- Source/Scene/VoxelBoxShape.js | 13 ++++++------- Source/Scene/VoxelPrimitive.js | 13 ++----------- Source/Shaders/VoxelVS.glsl | 1 - 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index 782caeb50c7..aa53a13d58c 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -101,7 +101,7 @@ function VoxelBoxShape() { this.shaderMaximumIntersectionsLength = undefined; } -const scratchTranslation = new Cartesian3(); +const scratchCenter = new Cartesian3(); const scratchScale = new Cartesian3(); const scratchRotation = new Matrix3(); const scratchTransformLocalToBounds = new Matrix4(); @@ -502,13 +502,12 @@ function getBoxChunkObb(minimumBounds, maximumBounds, matrix, result) { result.halfAxes = Matrix4.getMatrix3(matrix, result.halfAxes); } else { let scale = Matrix4.getScale(matrix, scratchScale); - const translation = Matrix4.getTranslation(matrix, scratchTranslation); - result.center = Cartesian3.fromElements( - translation.x + scale.x * 0.5 * (minimumBounds.x + maximumBounds.x), - translation.y + scale.y * 0.5 * (maximumBounds.y + minimumBounds.y), - translation.z + scale.z * 0.5 * (maximumBounds.z + minimumBounds.z), - result.center + const localCenter = Cartesian3.midpoint( + minimumBounds, + maximumBounds, + scratchCenter ); + result.center = Matrix4.multiplyByPoint(matrix, localCenter, result.center); scale = Cartesian3.fromElements( scale.x * 0.5 * (maximumBounds.x - minimumBounds.x), scale.y * 0.5 * (maximumBounds.y - minimumBounds.y), diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 976638f3fcf..9fa8c17fa01 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1072,9 +1072,7 @@ const scratchIntersect = new Cartesian4(); const scratchNdcAabb = new Cartesian4(); const scratchScale = new Cartesian3(); const scratchLocalScale = new Cartesian3(); -const scratchInverseLocalScale = new Cartesian3(); const scratchRotation = new Matrix3(); -const scratchInverseRotation = new Matrix3(); const scratchRotationAndLocalScale = new Matrix3(); const scratchTransformPositionWorldToLocal = new Matrix4(); const scratchTransformPositionLocalToWorld = new Matrix4(); @@ -1323,7 +1321,6 @@ VoxelPrimitive.prototype.update = function (frameState) { scratchRotation ); // Note that inverse(rotation) is the same as transpose(rotation) - const inverseRotation = Matrix3.transpose(rotation, scratchInverseRotation); const scale = Matrix4.getScale(transformPositionLocalToWorld, scratchScale); const maximumScaleComponent = Cartesian3.maximumComponent(scale); const localScale = Cartesian3.divideByScalar( @@ -1331,11 +1328,6 @@ VoxelPrimitive.prototype.update = function (frameState) { maximumScaleComponent, scratchLocalScale ); - const inverseLocalScale = Cartesian3.divideComponents( - Cartesian3.ONE, - localScale, - scratchInverseLocalScale - ); const rotationAndLocalScale = Matrix3.multiplyByScale( rotation, localScale, @@ -1356,9 +1348,8 @@ VoxelPrimitive.prototype.update = function (frameState) { transformPositionUvToLocal, this._transformPositionUvToWorld ); - this._transformDirectionWorldToLocal = Matrix3.setScale( - inverseRotation, - inverseLocalScale, + this._transformDirectionWorldToLocal = Matrix4.getMatrix3( + transformPositionWorldToLocal, this._transformDirectionWorldToLocal ); this._transformNormalLocalToWorld = Matrix3.inverseTranspose( diff --git a/Source/Shaders/VoxelVS.glsl b/Source/Shaders/VoxelVS.glsl index c83efe4ea4e..6c29c959b1c 100644 --- a/Source/Shaders/VoxelVS.glsl +++ b/Source/Shaders/VoxelVS.glsl @@ -8,5 +8,4 @@ void main() { vec2 translation = 0.5 * (aabbMax + aabbMin); vec2 scale = 0.5 * (aabbMax - aabbMin); gl_Position = vec4(position * scale + translation, 0.0, 1.0); - gl_Position = vec4(position, 0.0, 1.0); } From 3ef8e885d052dadd1c27e783587ddad62a36a1f5 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 29 Jul 2022 11:31:19 -0400 Subject: [PATCH 073/679] Sample parent tile correctly in traverseOctreeFromExisting --- Source/Shaders/VoxelFS.glsl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 33ee94c9382..39c3b2f350b 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1659,7 +1659,15 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa if (insideTile) { for (int i = 0; i < SAMPLE_COUNT; i++) { - sampleDatas[i].tileUv = traversalData.positionUvLocal; + if (sampleDatas[i].usingParentMegatextureIndex) { + ivec4 parentOctreeCoords; + parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); + parentOctreeCoords.w = traversalData.octreeCoords.w - 1; + float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); + sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); + } else { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } } } else { // Go up tree From f8b1c3907f244ae14c80b305b2643f81d9bb2f32 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 5 Aug 2022 14:59:35 -0400 Subject: [PATCH 074/679] Fix flat clipping bug --- Source/Shaders/VoxelFS.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 39c3b2f350b..fdb5bb9768b 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1260,7 +1260,7 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { // Compute radius #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - float radius = 1.0; + float radius = length(positionLocal.xy); // [0,1] #else float radius = length(positionLocal.xy); // [0,1] #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) @@ -1270,7 +1270,7 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { // Compute height #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) - float height = 1.0; + float height = positionUv.z; // [0,1] #else float height = positionUv.z; // [0,1] #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) From fe1caf6b309c7422e99a07f794e68237407b892d Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 5 Aug 2022 10:23:48 -0400 Subject: [PATCH 075/679] Fix ambiguous function call error on Windows in VoxelFS.glsl --- Source/Shaders/VoxelFS.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index fdb5bb9768b..5ea5529cd17 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1502,7 +1502,7 @@ Properties getPropertiesFromMegatexture(in SampleData sampleData) { } // Convert an array of sample datas to a final weighted properties. -Properties getPropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { +Properties accumulatePropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { #if (SAMPLE_COUNT == 1) return getPropertiesFromMegatexture(sampleDatas[0]); #else @@ -1733,7 +1733,7 @@ void main() for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state - Properties properties = getPropertiesFromMegatexture(sampleDatas); + Properties properties = accumulatePropertiesFromMegatexture(sampleDatas); // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); From f3aaa21f948f829eb6740df0bfcaa7c65e9e1577 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 8 Aug 2022 22:29:39 -0400 Subject: [PATCH 076/679] Fix broken links to ModelExperimental --- Source/Scene/GltfVoxelProvider.js | 4 ++-- Source/Scene/VoxelPrimitive.js | 2 +- Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index e3a3f4f24e2..71b4c213926 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -9,7 +9,7 @@ import Resource from "../Core/Resource.js"; import GltfLoader from "./GltfLoader.js"; import MetadataComponentType from "./MetadataComponentType.js"; import MetadataType from "./MetadataType.js"; -import ModelExperimentalUtility from "./ModelExperimental/ModelExperimentalUtility.js"; +import ModelUtility from "./Model/ModelUtility.js"; import VoxelShapeType from "./VoxelShapeType.js"; /** @@ -211,7 +211,7 @@ function GltfVoxelProvider(options) { .then(function (loader) { const gltf = loader.components; const node = gltf.nodes[0]; - const modelMatrix = ModelExperimentalUtility.getNodeTransform(node); + const modelMatrix = ModelUtility.getNodeTransform(node); const gltfPrimitive = node.primitives[0]; const voxel = gltfPrimitive.voxel; const primitiveType = gltfPrimitive.primitiveType; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 9fa8c17fa01..658415888fc 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -26,7 +26,7 @@ import MetadataType from "./MetadataType.js"; import PolylineCollection from "./PolylineCollection.js"; import VoxelShapeType from "./VoxelShapeType.js"; import VoxelTraversal from "./VoxelTraversal.js"; -import CustomShader from "./ModelExperimental/CustomShader.js"; +import CustomShader from "./Model/CustomShader.js"; import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; import RenderState from "../Renderer/RenderState.js"; diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 9d401ea8a67..60b4f2e31f2 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -6,7 +6,7 @@ import destroyObject from "../../Core/destroyObject.js"; import HeadingPitchRoll from "../../Core/HeadingPitchRoll.js"; import Matrix3 from "../../Core/Matrix3.js"; import Matrix4 from "../../Core/Matrix4.js"; -import CustomShader from "../../Scene/ModelExperimental/CustomShader.js"; +import CustomShader from "../../Scene/Model/CustomShader.js"; import VoxelShapeType from "../../Scene/VoxelShapeType.js"; import knockout from "../../ThirdParty/knockout.js"; From 23629c047099097d0279d93c9fa651a9d8709010 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 15 Aug 2022 18:58:14 -0400 Subject: [PATCH 077/679] Fix some of the spec errors --- Source/Scene/Model/ModelUtility.js | 1 + Specs/Scene/Cesium3DTilesVoxelProviderSpec.js | 9 +- Specs/Scene/GltfVoxelProviderSpec.js | 9 +- Specs/Scene/VoxelBoxShapeSpec.js | 233 ++++++++++++++---- Specs/Scene/VoxelCylinderShapeSpec.js | 8 +- Specs/Scene/VoxelEllipsoidShapeSpec.js | 28 ++- Specs/Scene/VoxelTraversalSpec.js | 11 +- 7 files changed, 220 insertions(+), 79 deletions(-) diff --git a/Source/Scene/Model/ModelUtility.js b/Source/Scene/Model/ModelUtility.js index 8c374caee8e..ee534bef9db 100644 --- a/Source/Scene/Model/ModelUtility.js +++ b/Source/Scene/Model/ModelUtility.js @@ -356,6 +356,7 @@ ModelUtility.supportedExtensions = { KHR_mesh_quantization: true, KHR_texture_basisu: true, KHR_texture_transform: true, + EXT_primitive_voxels: true, }; /** diff --git a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js index 3d62e19ad39..a1dc45defe9 100644 --- a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js +++ b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -36,7 +36,8 @@ describe( }); it("constructor works", function () { - const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const url = + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; const provider = new Cesium3DTilesVoxelProvider({ url: url, }); @@ -77,7 +78,8 @@ describe( }); it("requestData works for root tile", function () { - const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const url = + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; const provider = new Cesium3DTilesVoxelProvider({ url: url, }); @@ -110,7 +112,8 @@ describe( }); it("requestData throws if the provider is not ready", function () { - const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const url = + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; const provider = new Cesium3DTilesVoxelProvider({ url: url, }); diff --git a/Specs/Scene/GltfVoxelProviderSpec.js b/Specs/Scene/GltfVoxelProviderSpec.js index adbf9367169..28e0a15a0df 100644 --- a/Specs/Scene/GltfVoxelProviderSpec.js +++ b/Specs/Scene/GltfVoxelProviderSpec.js @@ -35,7 +35,7 @@ describe( it("constructor works", function () { const url = - "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; const provider = new GltfVoxelProvider({ gltf: url, }); @@ -74,7 +74,7 @@ describe( it("requestData works", function () { const url = - "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; const provider = new GltfVoxelProvider({ gltf: url, }); @@ -109,7 +109,7 @@ describe( it("requestData throws for non-root tiles", function () { const url = - "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf"; + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; const provider = new GltfVoxelProvider({ gltf: url, }); @@ -124,7 +124,8 @@ describe( }); it("requestData throws if the provider is not ready", function () { - const url = "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/tileset.json"; + const url = + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; const provider = new GltfVoxelProvider({ gltf: url, }); diff --git a/Specs/Scene/VoxelBoxShapeSpec.js b/Specs/Scene/VoxelBoxShapeSpec.js index c162dd4b896..a9461f403a0 100644 --- a/Specs/Scene/VoxelBoxShapeSpec.js +++ b/Specs/Scene/VoxelBoxShapeSpec.js @@ -12,7 +12,7 @@ import { describe("Scene/VoxelBoxShape", function () { it("constructs", function () { const shape = new VoxelBoxShape(); - expect(shape.isVisible).toEqual(false); + expect(shape.shapeTransform).toEqual(new Matrix4()); }); it("update works with model matrix", function () { @@ -51,7 +51,13 @@ describe("Scene/VoxelBoxShape", function () { Cartesian3.magnitude(scale) ); - shape.update(modelMatrix, minBounds, maxBounds); + const visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); expect(shape.orientedBoundingBox.center).toEqual( expectedOrientedBoundingBox.center @@ -63,7 +69,7 @@ describe("Scene/VoxelBoxShape", function () { expect(shape.boundingSphere).toEqual(expectedBoundingSphere); expect(shape.boundTransform).toEqual(modelMatrix); expect(shape.shapeTransform).toEqual(modelMatrix); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); }); it("update works with non-default minimum and maximum bounds", function () { @@ -79,7 +85,13 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = new Cartesian3(-0.75, -0.75, -0.75); const maxBounds = new Cartesian3(-0.25, -0.25, -0.25); - shape.update(modelMatrix, minBounds, maxBounds); + const visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); const expectedTranslation = new Cartesian3(0.75, 1.75, 2.75); const expectedScale = new Cartesian3(0.5, 0.75, 1.0); @@ -103,7 +115,7 @@ describe("Scene/VoxelBoxShape", function () { expect(shape.boundingSphere).toEqual(expectedBoundingSphere); expect(shape.boundTransform).toEqual(expectedModelMatrix); expect(shape.shapeTransform).toEqual(expectedModelMatrix); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); }); it("update is visible with zero scale for one component", function () { @@ -115,6 +127,7 @@ describe("Scene/VoxelBoxShape", function () { let scale; let modelMatrix; + let visible; // 0 scale for X scale = new Cartesian3(0.0, 2.0, 2.0); @@ -123,8 +136,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeTrue(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeTrue(); // 0 scale for Y scale = Cartesian3.fromElements(2.0, 0.0, 2.0, scale); @@ -133,8 +152,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeTrue(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeTrue(); // 0 scale for Z scale = Cartesian3.fromElements(2.0, 2.0, 0.0, scale); @@ -143,8 +168,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeTrue(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeTrue(); }); it("update is invisible with zero scale for two or more components", function () { @@ -156,6 +187,7 @@ describe("Scene/VoxelBoxShape", function () { let scale; let modelMatrix; + let visible; // 0 scale for X and Y scale = new Cartesian3(0.0, 0.0, 2.0); @@ -164,8 +196,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 scale for X and Z scale = Cartesian3.fromElements(0.0, 2.0, 0.0, scale); @@ -174,8 +212,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 scale for Y and Z scale = Cartesian3.fromElements(2.0, 0.0, 0.0, scale); @@ -184,8 +228,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 scale for X, Y, and Z scale = Cartesian3.fromElements(0.0, 0.0, 0.0, scale); @@ -194,8 +244,14 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); }); it("update is visible with zero bounds for one component", function () { @@ -214,19 +270,29 @@ describe("Scene/VoxelBoxShape", function () { let expectedScale; let actualScale; let actualTranslation; + let visible; + + const clipMinBounds = new Cartesian3(-1.0, -1.0, -1.0); + const clipMaxBounds = new Cartesian3(1.0, 1.0, 1.0); // 0 in X bound minBounds = new Cartesian3(0.0, -1.0, -1.0); maxBounds = new Cartesian3(0.0, +1.0, +1.0); expectedScale = new Cartesian3(0.0, 1.0, 1.0); - shape.update(modelMatrix, minBounds, maxBounds); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() ); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); expect(actualScale).toEqual(expectedScale); expect(actualTranslation).toEqual(translation); @@ -235,13 +301,19 @@ describe("Scene/VoxelBoxShape", function () { maxBounds = new Cartesian3(+1.0, 0.0, +1.0); expectedScale = new Cartesian3(1.0, 0.0, 1.0); - shape.update(modelMatrix, minBounds, maxBounds); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() ); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); expect(actualScale).toEqual(expectedScale); expect(actualTranslation).toEqual(translation); @@ -250,13 +322,19 @@ describe("Scene/VoxelBoxShape", function () { maxBounds = new Cartesian3(+1.0, +1.0, 0.0); expectedScale = new Cartesian3(1.0, 1.0, 0.0); - shape.update(modelMatrix, minBounds, maxBounds); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() ); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); expect(actualScale).toEqual(expectedScale); expect(actualTranslation).toEqual(translation); }); @@ -274,30 +352,55 @@ describe("Scene/VoxelBoxShape", function () { let minBounds; let maxBounds; + let visible; // 0 in X and Y bounds minBounds = new Cartesian3(0.0, 0.0, -1.0); maxBounds = new Cartesian3(0.0, 0.0, +1.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 in X and Z bounds minBounds = new Cartesian3(0.0, -1.0, 0.0); maxBounds = new Cartesian3(0.0, +1.0, 0.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 in Y and Z bounds minBounds = new Cartesian3(-1.0, 0.0, 0.0); maxBounds = new Cartesian3(+1.0, 0.0, 0.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); // 0 in X, Y, and Z bounds minBounds = new Cartesian3(0.0, 0.0, 0.0); maxBounds = new Cartesian3(0.0, 0.0, 0.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + minBounds, + maxBounds + ); + expect(visible).toBeFalse(); }); it("update is invisible when minimum bounds exceed maximum bounds", function () { @@ -311,26 +414,48 @@ describe("Scene/VoxelBoxShape", function () { scale ); + let visible; + let minBounds; let maxBounds; + const clipMinBounds = new Cartesian3(-1.0, -1.0, -1.0); + const clipMaxBounds = new Cartesian3(2.0, 2.0, 2.0); // Exceeds X minBounds = new Cartesian3(+2.0, -1.0, -1.0); maxBounds = new Cartesian3(+1.0, +1.0, +1.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); + expect(visible).toBeFalse(); // Exceeds Y minBounds = new Cartesian3(-1.0, +2.0, -1.0); maxBounds = new Cartesian3(+1.0, +1.0, +1.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); + expect(visible).toBeFalse(); // Exceeds Z minBounds = new Cartesian3(-1.0, -1.0, +2.0); maxBounds = new Cartesian3(+1.0, +1.0, +1.0); - shape.update(modelMatrix, minBounds, maxBounds); - expect(shape.isVisible).toBeFalse(); + visible = shape.update( + modelMatrix, + minBounds, + maxBounds, + clipMinBounds, + clipMaxBounds + ); + expect(visible).toBeFalse(); }); it("update throws with no model matrix parameter", function () { @@ -353,10 +478,17 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); + const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; expect(function () { - return shape.update(modelMatrix, undefined, maxBounds); + return shape.update( + modelMatrix, + undefined, + maxBounds, + minBounds, + maxBounds + ); }).toThrowDeveloperError(); }); @@ -371,9 +503,16 @@ describe("Scene/VoxelBoxShape", function () { scale ); const minBounds = VoxelBoxShape.DefaultMinBounds; + const maxBounds = VoxelBoxShape.DefaultMaxBounds; expect(function () { - return shape.update(modelMatrix, minBounds, undefined); + return shape.update( + modelMatrix, + minBounds, + undefined, + minBounds, + maxBounds + ); }).toThrowDeveloperError(); }); @@ -389,7 +528,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -419,7 +558,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const expectedScale = new Cartesian3(0.5, 0.5, 0.5); let expectedTranslation; @@ -577,7 +716,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -637,7 +776,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -667,7 +806,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const dimensions = new Cartesian3(32, 32, 16); const stepSize = shape.computeApproximateStepSize(dimensions); @@ -687,7 +826,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); expect(function () { return shape.computeApproximateStepSize(undefined); diff --git a/Specs/Scene/VoxelCylinderShapeSpec.js b/Specs/Scene/VoxelCylinderShapeSpec.js index 481f3a18c6c..2486f04f483 100644 --- a/Specs/Scene/VoxelCylinderShapeSpec.js +++ b/Specs/Scene/VoxelCylinderShapeSpec.js @@ -14,7 +14,7 @@ describe( function () { it("constructs", function () { const shape = new VoxelCylinderShape(); - expect(shape.isVisible).toEqual(false); + expect(shape.shapeTransform).toEqual(new Matrix4()); }); it("update works with model matrix", function () { @@ -37,7 +37,7 @@ describe( const minBounds = VoxelCylinderShape.DefaultMinBounds; const maxBounds = VoxelCylinderShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const expectedOrientedBoundingBox = new OrientedBoundingBox( translation, @@ -92,7 +92,7 @@ describe( const maxAngle = 0.0; const minBounds = new Cartesian3(minRadius, minHeight, minAngle); const maxBounds = new Cartesian3(maxRadius, maxHeight, maxAngle); - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const expectedMinX = translation.x - maxRadius * scale.x; const expectedMaxX = translation.x + maxRadius * scale.x; @@ -172,7 +172,7 @@ describe( defaultMaxBounds.y, maxAngle ); - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); const expectedScale = new Cartesian3(0.5, 1.0, 1.0); const expectedTranslation = new Cartesian3(-0.5, 0.0, 0.0); diff --git a/Specs/Scene/VoxelEllipsoidShapeSpec.js b/Specs/Scene/VoxelEllipsoidShapeSpec.js index 57c55b57f31..9d2736ca341 100644 --- a/Specs/Scene/VoxelEllipsoidShapeSpec.js +++ b/Specs/Scene/VoxelEllipsoidShapeSpec.js @@ -12,7 +12,7 @@ import { describe("Scene/VoxelEllipsoidShape", function () { it("constructs", function () { const shape = new VoxelEllipsoidShape(); - expect(shape.isVisible).toEqual(false); + expect(shape.shapeTransform).toEqual(new Matrix4()); }); it("update works with model matrix", function () { @@ -28,8 +28,16 @@ describe("Scene/VoxelEllipsoidShape", function () { scale ); - const minBounds = VoxelEllipsoidShape.DefaultMinBounds; - const maxBounds = VoxelEllipsoidShape.DefaultMaxBounds; + const minBounds = new Cartesian3( + -CesiumMath.PI, + -CesiumMath.PI_OVER_TWO, + 0.0 + ); + const maxBounds = new Cartesian3( + +CesiumMath.PI, + +CesiumMath.PI_OVER_TWO, + 100000 + ); const maxHeight = maxBounds.z; const expectedOrientedBoundingBox = new OrientedBoundingBox( @@ -52,14 +60,14 @@ describe("Scene/VoxelEllipsoidShape", function () { new BoundingSphere() ); - shape.update(modelMatrix, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); expect(shape.orientedBoundingBox.center).toEqual( expectedOrientedBoundingBox.center ); expect(shape.orientedBoundingBox.halfAxes).toEqualEpsilon( expectedOrientedBoundingBox.halfAxes, - CesiumMath.EPSILON12 + CesiumMath.EPSILON9 ); expect(shape.boundingSphere).toEqual(expectedBoundingSphere); @@ -69,10 +77,7 @@ describe("Scene/VoxelEllipsoidShape", function () { expect( Matrix4.getMatrix3(shape.boundTransform, new Matrix3()) - ).toEqualEpsilon( - expectedOrientedBoundingBox.halfAxes, - CesiumMath.EPSILON12 - ); + ).toEqualEpsilon(expectedOrientedBoundingBox.halfAxes, CesiumMath.EPSILON9); expect( Matrix4.getTranslation(shape.shapeTransform, new Cartesian3()) @@ -80,10 +85,7 @@ describe("Scene/VoxelEllipsoidShape", function () { expect( Matrix4.getMatrix3(shape.shapeTransform, new Matrix3()) - ).toEqualEpsilon( - expectedOrientedBoundingBox.halfAxes, - CesiumMath.EPSILON12 - ); + ).toEqualEpsilon(expectedOrientedBoundingBox.halfAxes, CesiumMath.EPSILON9); // expect(shape.boundTransform).toEqual(modelMatrix); // expect(shape.shapeTransform).toEqual(modelMatrix); diff --git a/Specs/Scene/VoxelTraversalSpec.js b/Specs/Scene/VoxelTraversalSpec.js index de7f2b2e48a..b7f5619da5a 100644 --- a/Specs/Scene/VoxelTraversalSpec.js +++ b/Specs/Scene/VoxelTraversalSpec.js @@ -109,9 +109,7 @@ describe( const keyframeCount = 1; const voxelDimensions = provider.voxelDimensions; const neighborEdgeCount = provider.neighborEdgeCount; - const channelCount = provider.channelCount; - const minimumValues = provider.minimumValues; - const maximumValues = provider.maximumValues; + // TODO: not available from the dummy provider (nor from the real providers) const datatypes = provider.datatypes; const textureMemory = 500; @@ -131,13 +129,10 @@ describe( return new VoxelTraversal( primitive, context, - keyframeCount, voxelDimensions, - neighborEdgeCount, - channelCount, - minimumValues, - maximumValues, datatypes, + datatypes, + keyframeCount, textureMemory ); }); From d7930089e0c82fff226d5ba8dda9941117d4250a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 15 Aug 2022 19:13:44 -0400 Subject: [PATCH 078/679] Restrict to Box shapes for debug --- Source/Shaders/VoxelFS.glsl | 928 +----------------------------------- 1 file changed, 1 insertion(+), 927 deletions(-) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 5ea5529cd17..1aaa42f62ef 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1,142 +1,3 @@ -/* -Don't delete this comment! -Some shader code is dynamically generated in VoxelPrimitive.js to support custom shaders with arbitrary metadata. -Below is an example of how this code might look. Properties like "temperature" and "direction" are just examples. - -// Defines -#define PROPERTY_COUNT ### -#define SAMPLE_COUNT ### -#define SHAPE_BOX -#define SHAPE_ELLIPSOID -#define SHAPE_CYLINDER -#define MEGATEXTURE_2D -#define MEGATEXTURE_3D -#define DEPTH_TEST -#define DEPTH_INTERSECTION_INDEX ### -#define INTERSECTION_COUNT ### -#define JITTER -#define NEAREST_SAMPLING -#define STATISTICS -#define PADDING -#define PICKING -#define CLIPPING_PLANES -#define CLIPPING_PLANES_UNION -#define CLIPPING_PLANES_COUNT -#define CLIPPING_PLANES_INTERSECTION_INDEX - -// Uniforms -uniform sampler2D u_megatextureTextures[PROPERTY_COUNT]; - -// Structs -struct PropertyStatistics_temperature { - float min; - float max; -}; -struct PropertyStatistics_direction { - vec3 min; - vec3 max; -}; -struct Statistics { - PropertyStatistics_temperature temperature; - PropertyStatistics_direction direction; -}; -struct Metadata { - Statistics statistics; - float temperature; - vec3 direction; -}; -struct VoxelProperty_temperature { - vec3 partialDerivativeLocal; - vec3 partialDerivativeWorld; - vec3 partialDerivativeView; - bool partialDerivativeValid; -}; -struct VoxelProperty_direction { - mat3 partialDerivativeLocal; - mat3 partialDerivativeWorld; - mat3 partialDerivativeView; - bool partialDerivativeValid; -}; -struct Voxel { - VoxelProperty_temperature temperature; - VoxelProperty_direction direction; - vec3 positionEC; - vec3 positionUv; - vec3 positionShapeUv; - vec3 positionUvLocal; - vec3 viewDirUv; - vec3 viewDirWorld; - float travelDistance; -}; -struct FragmentInput { - Metadata metadata; - Voxel voxel; -}; -struct Properties { - // This struct is similar to Metadata but is not part of the custom shader API and - // is intended to be used internally as a lightweight way to pass around properties. - float temperature; - vec3 direction; -}; - -// Functions -Properties clearProperties() { - Properties properties; - properties.temperature = 0.0; - properties.direction = vec3(0.0); - return properties; -} -Properties sumProperties(Properties propertiesA, Properties propertiesB) { - Properties properties; - properties.temperature = propertiesA.temperature + propertiesB.temperature; - properties.direction = propertiesA.direction + propertiesB.direction; - return properties; -} -Properties scaleProperties(Properties properties, float scale) { - Properties scaledProperties = properties; - scaledProperties.temperature *= scale; - scaledProperties.direction *= scale; - return scaledProperties; -} -Properties mixProperties(Properties propertiesA, Properties propertiesB, float mixFactor) { - Properties properties; - properties.temperature = mix(propertiesA.temperature, propertiesB.temperature, mixFactor); - properties.direction = mix(propertiesA.direction, propertiesB.direction, mixFactor); - return properties; -} -void copyPropertiesToMetadata(in Properties properties, inout Metadata metadata) { - metadata.temperature = properties.temperature; - metadata.direction = properties.direction; -} -void setStatistics(inout Statistics statistics) { - // Assume the "direction" property has no min/max - statistics.temperature.min = 20.0; - statistics.temperature.max = 50.0; -} -Properties getPropertiesFromMegatextureAtUv(vec2 texcoord) { - #if defined(MEGATEXTURE_2D) - Properties properties; - properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; - properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; - return properties; - #else - Properties properties; - properties.temperature = texture3D(u_megatextureTextures[0], texcoord).r; - properties.direction = texture3D(u_megatextureTextures[1], texcoord).rgb; - return properties; - #endif -} -void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - vec3 direction = fsInput.metadata.direction; - float temperature = fsInput.metadata.temperature; - float minTemperature = fsInput.metadata.statistics.temperature.min; - float maxTemperature = fsInput.metadata.statistics.temperature.max; - - material.diffuse = abs(direction); - material.alpha = (temperature - minTemperature) / (maxTemperature - minTemperature); -} -*/ - // These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js #define OCTREE_FLAG_INTERNAL 0 #define OCTREE_FLAG_LEAF 1 @@ -233,125 +94,6 @@ uniform float u_stepSize; #endif #endif -#if defined(SHAPE_ELLIPSOID) - /* Ellipsoid defines: - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN - #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN - #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO - #define ELLIPSOID_IS_SPHERE - #define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE - #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX - #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN - #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX - #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN - */ - - // Ellipsoid uniforms - uniform vec3 u_ellipsoidRadiiUv; // [0,1] - #if !defined(ELLIPSOID_IS_SPHERE) - uniform vec3 u_ellipsoidInverseRadiiSquaredUv; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE) - uniform vec2 u_ellipsoidRenderLongitudeMinMax; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) - uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid; - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) - uniform vec2 u_ellipsoidUvToShapeUvLongitude; // x = scale, y = offset - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) - uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) - uniform vec2 u_ellipsoidRenderLatitudeCosSqrHalfMinMax; - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - uniform float u_ellipsoidInverseHeightDifferenceUv; - uniform vec2 u_ellipseInnerRadiiUv; // [0,1] - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) - uniform float u_ellipsoidInverseInnerScaleUv; - #endif -#endif - -#if defined(SHAPE_CYLINDER) - /* Cylinder defines: - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT - #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT - #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO - - #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS - #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT - #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT - #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED - - #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX - #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN - #define CYLINDER_INTERSECTION_INDEX_ANGLE - */ - - // Cylinder uniforms - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) - uniform vec3 u_cylinderUvToRenderBoundsScale; - uniform vec3 u_cylinderUvToRenderBoundsTranslate; - #endif - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - uniform float u_cylinderUvToRenderRadiusMin; - #endif - #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE) - uniform vec2 u_cylinderRenderAngleMinMax; - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) - uniform vec2 u_cylinderUvToShapeUvRadius; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) - uniform vec2 u_cylinderUvToShapeUvHeight; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) - uniform vec2 u_cylinderUvToShapeUvAngle; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) - uniform vec2 u_cylinderShapeUvAngleMinMax; - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - uniform float u_cylinderShapeUvAngleEmptyMid; - #endif -#endif - // -------------------------------------------------------- // Misc math // -------------------------------------------------------- @@ -369,9 +111,6 @@ float hash(vec2 p) } #endif -float signNoZero(float v) { - return (v < 0.0) ? -1.0 : 1.0; -} int intMod(int a, int b) { return a - (b * (a / b)); } @@ -448,38 +187,6 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] } #endif -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF)) -vec2 intersectZPlane(Ray ray) -{ - float o = ray.pos.z; - float d = ray.dir.z; - float t = -o / d; - float s = sign(o); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO)) -vec4 intersectHalfPlane(Ray ray, float angle) { - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 planeDirection = vec2(cos(angle), sin(angle)); - vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); - - float a = dot(o, planeNormal); - float b = dot(d, planeNormal); - float t = -a / b; - - vec2 p = o + t * d; - bool outside = dot(p, planeDirection) < 0.0; - if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - - return vec4(-INF_HIT, t, t, +INF_HIT); -} -#endif - #if defined(CLIPPING_PLANES) // Plane is in Hessian Normal Form vec2 intersectPlane(Ray ray, vec4 plane) { @@ -500,343 +207,6 @@ vec2 intersectPlane(Ray ray, vec4 plane) { } #endif -#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF))) -vec2 intersectHalfSpace(Ray ray, float angle) -{ - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 n = vec2(sin(angle), -cos(angle)); - - float a = dot(o, n); - float b = dot(d, n); - float t = -a / b; - float s = sign(a); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)) -vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) -{ - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); - vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); - - float a1 = dot(o, n1); - float a2 = dot(o, n2); - float b1 = dot(d, n1); - float b2 = dot(d, n2); - - float t1 = -a1 / b1; - float t2 = -a2 / b2; - float s1 = sign(a1); - float s2 = sign(a2); - - float tmin = min(t1, t2); - float tmax = max(t1, t2); - float smin = tmin == t1 ? s1 : s2; - float smax = tmin == t1 ? s2 : s1; - - bool e = tmin >= 0.0; - bool f = tmax >= 0.0; - bool g = smin >= 0.0; - bool h = smax >= 0.0; - - if (e != g && f == h) return vec2(tmin, tmax); - else if (e == g && f == h) return vec2(-INF_HIT, tmin); - else if (e != g && f != h) return vec2(tmax, +INF_HIT); - else return vec2(NO_HIT); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)) -vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) -{ - vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); - vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); - return vec4(planeIntersectMin, planeIntersectMax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphere(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = -b - det; - float t2 = -b + det; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d, d); - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE) -vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - float a = d.z * d.z - dot(d, d) * cosSqrHalfAngle; - float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; - float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF)) -vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { - vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); - - if (intersect.x == NO_HIT) { - return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - } - - vec3 o = ray.pos; - vec3 d = ray.dir; - float tmin = intersect.x; - float tmax = intersect.y; - float zmin = o.z + tmin * d.z; - float zmax = o.z + tmax * d.z; - - // One interval - if (zmin < 0.0 && zmax < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - else if (zmin < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); - else if (zmax < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); - // Two intervals - else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF)) -vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { - vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); - - if (intersect.x == NO_HIT) { - return vec2(NO_HIT); - } - - vec3 o = ray.pos; - vec3 d = ray.dir; - float tmin = intersect.x; - float tmax = intersect.y; - float zmin = o.z + tmin * d.z; - float zmax = o.z + tmax * d.z; - - if (zmin < 0.0 && zmax < 0.0) return vec2(NO_HIT); - else if (zmin < 0.0) return vec2(tmax, +INF_HIT); - else if (zmax < 0.0) return vec2(-INF_HIT, tmin); - else return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_CYLINDER) -vec2 intersectUnitCylinder(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d.xy, d.xy); - float b = dot(o.xy, d.xy); - float c = dot(o.xy, o.xy) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float ta = (-b - det) / a; - float tb = (-b + det) / a; - float t1 = min(ta, tb); - float t2 = max(ta, tb); - - float z1 = o.z + t1 * d.z; - float z2 = o.z + t2 * d.z; - - if (abs(z1) >= 1.0) - { - float tCap = (sign(z1) - o.z) / d.z; - t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; - } - - if (abs(z2) >= 1.0) - { - float tCap = (sign(z2) - o.z) / d.z; - t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; - } - - return vec2(t1, t2); -} -#endif - -#if defined(SHAPE_CYLINDER) -vec2 intersectUnitCircle(Ray ray) { - vec3 o = ray.pos; - vec3 d = ray.dir; - - float t = -o.z / d.z; - vec2 zPlanePos = o.xy + d.xy * t; - float distSqr = dot(zPlanePos, zPlanePos); - - if (distSqr > 1.0) { - return vec2(NO_HIT); - } - - return vec2(t, t); -} -#endif - -#if defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) -vec2 intersectInfiniteUnitCylinder(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d.xy, d.xy); - float b = dot(o.xy, d.xy); - float c = dot(o.xy, o.xy) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -// robust iterative solution without trig functions -// https://github.com/0xfaded/ellipse_demo/issues/1 -// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse -// Pro: Good when radii.x ~= radii.y -// Con: Breaks at pos.x ~= 0.0, especially inside the ellipse -// Con: Inaccurate with exterior points and thin ellipses -float ellipseDistanceIterative (vec2 pos, vec2 radii) { - vec2 p = abs(pos); - vec2 invRadii = 1.0 / radii; - vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii; - vec2 t = vec2(0.70710678118); // sqrt(2) / 2 - vec2 v = radii * t; - - const int iterations = 3; - for (int i = 0; i < iterations; ++i) { - vec2 e = a * pow(t, vec2(3.0)); - vec2 q = normalize(p - e) * length(v - e); - t = normalize((q + e) * invRadii); - v = radii * t; - } - return length(v * sign(pos) - pos) * sign(p.y - v.y); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -// From: https://www.shadertoy.com/view/4sS3zz -// Pro: Accurate in most cases -// Con: Breaks if radii.x ~= radii.y -float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { - vec2 p = pos; - vec2 ab = radii; - - p = abs(p); - if (p.x > p.y) { - p = p.yx; - ab = ab.yx; - } - - float l = ab.y * ab.y - ab.x * ab.x; - float m = ab.x * p.x / l; - float n = ab.y * p.y / l; - float m2 = m * m; - float n2 = n * n; - float c = (m2 + n2 - 1.0) / 3.0; - float c3 = c * c * c; - float d = c3 + m2 * n2; - float q = d + m2 * n2; - float g = m + m * n2; - - float co; - - if (d < 0.0) { - float h = acos(q / c3) / 3.0; - float s = cos(h) + 2.0; - float t = sin(h) * sqrt(3.0); - float rx = sqrt(m2 - c * (s + t)); - float ry = sqrt(m2 - c * (s - t)); - co = ry + sign(l) * rx + abs(g) / (rx * ry); - } else { - float h = 2.0 * m * n * sqrt(d); - float s = signNoZero(q + h) * pow(abs(q + h), 1.0 / 3.0); - float t = signNoZero(q - h) * pow(abs(q - h), 1.0 / 3.0); - float rx = -(s + t) - c * 4.0 + 2.0 * m2; - float ry = (s - t) * sqrt(3.0); - float rm = sqrt(rx * rx + ry * ry); - co = ry / sqrt(rm - rx) + 2.0 * g / rm; - } - - co = (co - m) / 2.0; - float si = sqrt(max(1.0 - co * co, 0.0)); - vec2 r = ab * vec2(co, si); - return length(r - p) * signNoZero(p.y - r.y); -} -#endif - struct Intersections { // Don't access these member variables directly - call the functions instead. @@ -1008,302 +378,6 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { } #endif -#if defined(SHAPE_ELLIPSOID) -void intersectShape(in Ray ray, inout Intersections ix) { - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; - - // Outer ellipsoid - vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); - - // Exit early if the outer ellipsoid was missed. - if (outerIntersect.x == NO_HIT) { - return; - } - - // Inner ellipsoid - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - // When the ellipsoid is perfectly thin it's necessary to sandwich the - // inner ellipsoid intersection inside the outer ellipsoid intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the ellipsoid to be invisible because it will think the ray - // is still inside the inner (negative) ellipsoid after exiting the - // outer (positive) ellipsoid. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); - #endif - - // Flip the ray because the intersection function expects a cone growing towards +Z. - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) - Ray flippedRay = ray; - flippedRay.dir.z *= -1.0; - flippedRay.pos.z *= -1.0; - #endif - - // Bottom cone - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) - vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) - vec2 bottomConeIntersection = intersectZPlane(flippedRay); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) - vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); - #endif - - // Top cone - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) - vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersection.zw); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF) - vec2 topConeIntersection = intersectZPlane(ray); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) - vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); - #endif - - // Wedge - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) - vec4 wedgeIntersect = intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF) - vec2 wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF) - vec2 wedgeIntersect = intersectHalfSpace(ray, u_ellipsoidRenderLongitudeMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) - vec4 wedgeIntersect = intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); - #endif -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - // Compute position and normal. - // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). - // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. - vec3 positionLocal = positionUv * 2.0 - 1.0; - #if defined(ELLIPSOID_IS_SPHERE) - vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x; - vec3 normal = normalize(posEllipsoid); - #else - vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; - vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal - #endif - - // Compute longitude - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) - float longitude = 1.0; - #else - float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; - - // Correct the angle when max < min - // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) - longitude += float(longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z); - #endif - - // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) - longitude = longitude > u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.x : longitude; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) - longitude = longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.y : longitude; - #endif - - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) - longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y; - #endif - #endif - - // Compute latitude - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) - float latitude = 1.0; - #else - float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) - latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y; - #endif - #endif - - // Compute height - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. - float height = 1.0; - #else - #if defined(ELLIPSOID_IS_SPHERE) - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) - float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; - #else - float height = length(posEllipsoid); - #endif - #else - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) - // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). - // This is an optimization so that math can be done with ellipses instead of ellipsoids. - vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); - float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; - #else - // TODO: this is probably not correct - float height = length(posEllipsoid); - #endif - #endif - #endif - - return vec3(longitude, latitude, height); -} -#endif - -#if defined(SHAPE_CYLINDER) -void intersectShape(Ray ray, inout Intersections ix) -{ - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) - ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate; - ray.dir *= u_cylinderUvToRenderBoundsScale; - #else - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; - #endif - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) - vec2 outerIntersect = intersectUnitCircle(ray); - #else - vec2 outerIntersect = intersectUnitCylinder(ray); - #endif - - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect); - - if (outerIntersect.x == NO_HIT) { - return; - } - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - vec2 innerIntersect = intersectInfiniteUnitCylinder(ray); - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) - Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin); - vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect); - #endif - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF) - vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF) - vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) - vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) - vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); - #endif -} -#endif - -#if defined(SHAPE_CYLINDER) -vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] - - // Compute radius - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - float radius = length(positionLocal.xy); // [0,1] - #else - float radius = length(positionLocal.xy); // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) - radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset - #endif - #endif - - // Compute height - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) - float height = positionUv.z; // [0,1] - #else - float height = positionUv.z; // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) - height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset - #endif - #endif - - // Compute angle - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) - float angle = 1.0; - #else - float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. - angle += float(angle < u_cylinderShapeUvAngleEmptyMid); - #endif - - // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) - angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; - #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) - angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; - #endif - - angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset - #endif - #endif - - return vec3(radius, height, angle); -} -#endif - #if defined(CLIPPING_PLANES) void intersectClippingPlanes(Ray ray, inout Intersections ix) { #if (CLIPPING_PLANES_COUNT == 1) @@ -1800,4 +874,4 @@ void main() #else gl_FragColor = colorAccum; #endif -} \ No newline at end of file +} From ccb159359e4ddb7b3624d79592548be6f7cf4691 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 16 Aug 2022 18:32:18 -0400 Subject: [PATCH 079/679] Assume MEGATEXTURE_2D --- Source/Scene/VoxelPrimitive.js | 6 - Source/Shaders/VoxelFS.glsl | 986 +++++++++++++++++++++++++++++++-- 2 files changed, 944 insertions(+), 48 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 658415888fc..9100de0ab00 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1809,12 +1809,6 @@ function buildDrawCommands(that, context) { ShaderDestination.FRAGMENT ); - shaderBuilder.addDefine( - "MEGATEXTURE_2D", - undefined, - ShaderDestination.FRAGMENT - ); - if ( !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl index 1aaa42f62ef..2306c9cd513 100644 --- a/Source/Shaders/VoxelFS.glsl +++ b/Source/Shaders/VoxelFS.glsl @@ -1,3 +1,134 @@ +/* +Don't delete this comment! +Some shader code is dynamically generated in VoxelPrimitive.js to support custom shaders with arbitrary metadata. +Below is an example of how this code might look. Properties like "temperature" and "direction" are just examples. + +// Defines +#define PROPERTY_COUNT ### +#define SAMPLE_COUNT ### +#define SHAPE_BOX +#define SHAPE_ELLIPSOID +#define SHAPE_CYLINDER +#define MEGATEXTURE_3D +#define DEPTH_TEST +#define DEPTH_INTERSECTION_INDEX ### +#define INTERSECTION_COUNT ### +#define JITTER +#define NEAREST_SAMPLING +#define STATISTICS +#define PADDING +#define PICKING +#define CLIPPING_PLANES +#define CLIPPING_PLANES_UNION +#define CLIPPING_PLANES_COUNT +#define CLIPPING_PLANES_INTERSECTION_INDEX + +// Uniforms +uniform sampler2D u_megatextureTextures[PROPERTY_COUNT]; + +// Structs +struct PropertyStatistics_temperature { + float min; + float max; +}; +struct PropertyStatistics_direction { + vec3 min; + vec3 max; +}; +struct Statistics { + PropertyStatistics_temperature temperature; + PropertyStatistics_direction direction; +}; +struct Metadata { + Statistics statistics; + float temperature; + vec3 direction; +}; +struct VoxelProperty_temperature { + vec3 partialDerivativeLocal; + vec3 partialDerivativeWorld; + vec3 partialDerivativeView; + bool partialDerivativeValid; +}; +struct VoxelProperty_direction { + mat3 partialDerivativeLocal; + mat3 partialDerivativeWorld; + mat3 partialDerivativeView; + bool partialDerivativeValid; +}; +struct Voxel { + VoxelProperty_temperature temperature; + VoxelProperty_direction direction; + vec3 positionEC; + vec3 positionUv; + vec3 positionShapeUv; + vec3 positionUvLocal; + vec3 viewDirUv; + vec3 viewDirWorld; + float travelDistance; +}; +struct FragmentInput { + Metadata metadata; + Voxel voxel; +}; +struct Properties { + // This struct is similar to Metadata but is not part of the custom shader API and + // is intended to be used internally as a lightweight way to pass around properties. + float temperature; + vec3 direction; +}; + +// Functions +Properties clearProperties() { + Properties properties; + properties.temperature = 0.0; + properties.direction = vec3(0.0); + return properties; +} +Properties sumProperties(Properties propertiesA, Properties propertiesB) { + Properties properties; + properties.temperature = propertiesA.temperature + propertiesB.temperature; + properties.direction = propertiesA.direction + propertiesB.direction; + return properties; +} +Properties scaleProperties(Properties properties, float scale) { + Properties scaledProperties = properties; + scaledProperties.temperature *= scale; + scaledProperties.direction *= scale; + return scaledProperties; +} +Properties mixProperties(Properties propertiesA, Properties propertiesB, float mixFactor) { + Properties properties; + properties.temperature = mix(propertiesA.temperature, propertiesB.temperature, mixFactor); + properties.direction = mix(propertiesA.direction, propertiesB.direction, mixFactor); + return properties; +} +void copyPropertiesToMetadata(in Properties properties, inout Metadata metadata) { + metadata.temperature = properties.temperature; + metadata.direction = properties.direction; +} +void setStatistics(inout Statistics statistics) { + // Assume the "direction" property has no min/max + statistics.temperature.min = 20.0; + statistics.temperature.max = 50.0; +} +Properties getPropertiesFromMegatextureAtUv(vec2 texcoord) { + Properties properties; + properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; + properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; + return properties; +} +void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { + vec3 direction = fsInput.metadata.direction; + float temperature = fsInput.metadata.temperature; + float minTemperature = fsInput.metadata.statistics.temperature.min; + float maxTemperature = fsInput.metadata.statistics.temperature.max; + + material.diffuse = abs(direction); + material.alpha = (temperature - minTemperature) / (maxTemperature - minTemperature); +} +*/ + // These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js #define OCTREE_FLAG_INTERNAL 0 #define OCTREE_FLAG_LEAF 1 @@ -16,13 +147,11 @@ uniform ivec3 u_dimensions; // does not include padding uniform ivec3 u_paddingAfter; #endif -#if defined(MEGATEXTURE_2D) - uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions - uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions - uniform vec2 u_megatextureVoxelSizeUv; - uniform vec2 u_megatextureSliceSizeUv; - uniform vec2 u_megatextureTileSizeUv; -#endif +uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions +uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions +uniform vec2 u_megatextureVoxelSizeUv; +uniform vec2 u_megatextureSliceSizeUv; +uniform vec2 u_megatextureTileSizeUv; uniform sampler2D u_octreeInternalNodeTexture; uniform vec2 u_octreeInternalNodeTexelSizeUv; @@ -94,6 +223,125 @@ uniform float u_stepSize; #endif #endif +#if defined(SHAPE_ELLIPSOID) + /* Ellipsoid defines: + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY + #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF + #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE + #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN + #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO + #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN + #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO + #define ELLIPSOID_IS_SPHERE + #define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX + #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN + */ + + // Ellipsoid uniforms + uniform vec3 u_ellipsoidRadiiUv; // [0,1] + #if !defined(ELLIPSOID_IS_SPHERE) + uniform vec3 u_ellipsoidInverseRadiiSquaredUv; + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidRenderLongitudeMinMax; + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid; + #endif + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLongitude; // x = scale, y = offset + #endif + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + uniform vec2 u_ellipsoidRenderLatitudeCosSqrHalfMinMax; + #endif + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + uniform float u_ellipsoidInverseHeightDifferenceUv; + uniform vec2 u_ellipseInnerRadiiUv; // [0,1] + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) + uniform float u_ellipsoidInverseInnerScaleUv; + #endif +#endif + +#if defined(SHAPE_CYLINDER) + /* Cylinder defines: + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX + #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT + #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT + #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF + #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO + + #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS + #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT + #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT + #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY + #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED + + #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX + #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN + #define CYLINDER_INTERSECTION_INDEX_ANGLE + */ + + // Cylinder uniforms + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + uniform vec3 u_cylinderUvToRenderBoundsScale; + uniform vec3 u_cylinderUvToRenderBoundsTranslate; + #endif + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + uniform float u_cylinderUvToRenderRadiusMin; + #endif + #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE) + uniform vec2 u_cylinderRenderAngleMinMax; + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + uniform vec2 u_cylinderUvToShapeUvRadius; // x = scale, y = offset + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + uniform vec2 u_cylinderUvToShapeUvHeight; // x = scale, y = offset + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + uniform vec2 u_cylinderUvToShapeUvAngle; // x = scale, y = offset + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + uniform vec2 u_cylinderShapeUvAngleMinMax; + #endif + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + uniform float u_cylinderShapeUvAngleEmptyMid; + #endif +#endif + // -------------------------------------------------------- // Misc math // -------------------------------------------------------- @@ -111,6 +359,9 @@ float hash(vec2 p) } #endif +float signNoZero(float v) { + return (v < 0.0) ? -1.0 : 1.0; +} int intMod(int a, int b) { return a - (b * (a / b)); } @@ -187,6 +438,38 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] } #endif +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF)) +vec2 intersectZPlane(Ray ray) +{ + float o = ray.pos.z; + float d = ray.dir.z; + float t = -o / d; + float s = sign(o); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} +#endif + +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO)) +vec4 intersectHalfPlane(Ray ray, float angle) { + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 planeDirection = vec2(cos(angle), sin(angle)); + vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); + + float a = dot(o, planeNormal); + float b = dot(d, planeNormal); + float t = -a / b; + + vec2 p = o + t * d; + bool outside = dot(p, planeDirection) < 0.0; + if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + + return vec4(-INF_HIT, t, t, +INF_HIT); +} +#endif + #if defined(CLIPPING_PLANES) // Plane is in Hessian Normal Form vec2 intersectPlane(Ray ray, vec4 plane) { @@ -207,6 +490,343 @@ vec2 intersectPlane(Ray ray, vec4 plane) { } #endif +#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF))) +vec2 intersectHalfSpace(Ray ray, float angle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n = vec2(sin(angle), -cos(angle)); + + float a = dot(o, n); + float b = dot(d, n); + float t = -a / b; + float s = sign(a); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} +#endif + +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)) +vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); + vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); + + float a1 = dot(o, n1); + float a2 = dot(o, n2); + float b1 = dot(d, n1); + float b2 = dot(d, n2); + + float t1 = -a1 / b1; + float t2 = -a2 / b2; + float s1 = sign(a1); + float s2 = sign(a2); + + float tmin = min(t1, t2); + float tmax = max(t1, t2); + float smin = tmin == t1 ? s1 : s2; + float smax = tmin == t1 ? s2 : s1; + + bool e = tmin >= 0.0; + bool f = tmax >= 0.0; + bool g = smin >= 0.0; + bool h = smax >= 0.0; + + if (e != g && f == h) return vec2(tmin, tmax); + else if (e == g && f == h) return vec2(-INF_HIT, tmin); + else if (e != g && f != h) return vec2(tmax, +INF_HIT); + else return vec2(NO_HIT); +} +#endif + +#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)) +vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); + vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); + return vec4(planeIntersectMin, planeIntersectMax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec2 intersectUnitSphere(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = -b - det; + float t2 = -b + det; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d, d); + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE) +vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + float a = d.z * d.z - dot(d, d) * cosSqrHalfAngle; + float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; + float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF)) +vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); + + if (intersect.x == NO_HIT) { + return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + } + + vec3 o = ray.pos; + vec3 d = ray.dir; + float tmin = intersect.x; + float tmax = intersect.y; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; + + // One interval + if (zmin < 0.0 && zmax < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + else if (zmin < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); + else if (zmax < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); + // Two intervals + else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); +} +#endif + +#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF)) +vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); + + if (intersect.x == NO_HIT) { + return vec2(NO_HIT); + } + + vec3 o = ray.pos; + vec3 d = ray.dir; + float tmin = intersect.x; + float tmax = intersect.y; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; + + if (zmin < 0.0 && zmax < 0.0) return vec2(NO_HIT); + else if (zmin < 0.0) return vec2(tmax, +INF_HIT); + else if (zmax < 0.0) return vec2(-INF_HIT, tmin); + else return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec2 intersectUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float ta = (-b - det) / a; + float tb = (-b + det) / a; + float t1 = min(ta, tb); + float t2 = max(ta, tb); + + float z1 = o.z + t1 * d.z; + float z2 = o.z + t2 * d.z; + + if (abs(z1) >= 1.0) + { + float tCap = (sign(z1) - o.z) / d.z; + t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; + } + + if (abs(z2) >= 1.0) + { + float tCap = (sign(z2) - o.z) / d.z; + t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; + } + + return vec2(t1, t2); +} +#endif + +#if defined(SHAPE_CYLINDER) +vec2 intersectUnitCircle(Ray ray) { + vec3 o = ray.pos; + vec3 d = ray.dir; + + float t = -o.z / d.z; + vec2 zPlanePos = o.xy + d.xy * t; + float distSqr = dot(zPlanePos, zPlanePos); + + if (distSqr > 1.0) { + return vec2(NO_HIT); + } + + return vec2(t, t); +} +#endif + +#if defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) +vec2 intersectInfiniteUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +// robust iterative solution without trig functions +// https://github.com/0xfaded/ellipse_demo/issues/1 +// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse +// Pro: Good when radii.x ~= radii.y +// Con: Breaks at pos.x ~= 0.0, especially inside the ellipse +// Con: Inaccurate with exterior points and thin ellipses +float ellipseDistanceIterative (vec2 pos, vec2 radii) { + vec2 p = abs(pos); + vec2 invRadii = 1.0 / radii; + vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii; + vec2 t = vec2(0.70710678118); // sqrt(2) / 2 + vec2 v = radii * t; + + const int iterations = 3; + for (int i = 0; i < iterations; ++i) { + vec2 e = a * pow(t, vec2(3.0)); + vec2 q = normalize(p - e) * length(v - e); + t = normalize((q + e) * invRadii); + v = radii * t; + } + return length(v * sign(pos) - pos) * sign(p.y - v.y); +} +#endif + +#if defined(SHAPE_ELLIPSOID) +// From: https://www.shadertoy.com/view/4sS3zz +// Pro: Accurate in most cases +// Con: Breaks if radii.x ~= radii.y +float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { + vec2 p = pos; + vec2 ab = radii; + + p = abs(p); + if (p.x > p.y) { + p = p.yx; + ab = ab.yx; + } + + float l = ab.y * ab.y - ab.x * ab.x; + float m = ab.x * p.x / l; + float n = ab.y * p.y / l; + float m2 = m * m; + float n2 = n * n; + float c = (m2 + n2 - 1.0) / 3.0; + float c3 = c * c * c; + float d = c3 + m2 * n2; + float q = d + m2 * n2; + float g = m + m * n2; + + float co; + + if (d < 0.0) { + float h = acos(q / c3) / 3.0; + float s = cos(h) + 2.0; + float t = sin(h) * sqrt(3.0); + float rx = sqrt(m2 - c * (s + t)); + float ry = sqrt(m2 - c * (s - t)); + co = ry + sign(l) * rx + abs(g) / (rx * ry); + } else { + float h = 2.0 * m * n * sqrt(d); + float s = signNoZero(q + h) * pow(abs(q + h), 1.0 / 3.0); + float t = signNoZero(q - h) * pow(abs(q - h), 1.0 / 3.0); + float rx = -(s + t) - c * 4.0 + 2.0 * m2; + float ry = (s - t) * sqrt(3.0); + float rm = sqrt(rx * rx + ry * ry); + co = ry / sqrt(rm - rx) + 2.0 * g / rm; + } + + co = (co - m) / 2.0; + float si = sqrt(max(1.0 - co * co, 0.0)); + vec2 r = ab * vec2(co, si); + return length(r - p) * signNoZero(p.y - r.y); +} +#endif + struct Intersections { // Don't access these member variables directly - call the functions instead. @@ -378,6 +998,302 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { } #endif +#if defined(SHAPE_ELLIPSOID) +void intersectShape(in Ray ray, inout Intersections ix) { + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + + // Outer ellipsoid + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); + + // Exit early if the outer ellipsoid was missed. + if (outerIntersect.x == NO_HIT) { + return; + } + + // Inner ellipsoid + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + // When the ellipsoid is perfectly thin it's necessary to sandwich the + // inner ellipsoid intersection inside the outer ellipsoid intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the ellipsoid to be invisible because it will think the ray + // is still inside the inner (negative) ellipsoid after exiting the + // outer (positive) ellipsoid. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); + #endif + + // Flip the ray because the intersection function expects a cone growing towards +Z. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) + Ray flippedRay = ray; + flippedRay.dir.z *= -1.0; + flippedRay.pos.z *= -1.0; + #endif + + // Bottom cone + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) + vec2 bottomConeIntersection = intersectZPlane(flippedRay); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) + vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); + #endif + + // Top cone + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) + vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersection.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF) + vec2 topConeIntersection = intersectZPlane(ray); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); + #endif + + // Wedge + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); + #endif +} +#endif + +#if defined(SHAPE_ELLIPSOID) +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + // Compute position and normal. + // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). + // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. + vec3 positionLocal = positionUv * 2.0 - 1.0; + #if defined(ELLIPSOID_IS_SPHERE) + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x; + vec3 normal = normalize(posEllipsoid); + #else + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; + vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal + #endif + + // Compute longitude + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + float longitude = 1.0; + #else + float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; + + // Correct the angle when max < min + // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + longitude += float(longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z); + #endif + + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) + longitude = longitude > u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.x : longitude; + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) + longitude = longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.y : longitude; + #endif + + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y; + #endif + #endif + + // Compute latitude + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) + float latitude = 1.0; + #else + float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y; + #endif + #endif + + // Compute height + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + float height = 1.0; + #else + #if defined(ELLIPSOID_IS_SPHERE) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) + float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; + #else + float height = length(posEllipsoid); + #endif + #else + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) + // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). + // This is an optimization so that math can be done with ellipses instead of ellipsoids. + vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); + float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; + #else + // TODO: this is probably not correct + float height = length(posEllipsoid); + #endif + #endif + #endif + + return vec3(longitude, latitude, height); +} +#endif + +#if defined(SHAPE_CYLINDER) +void intersectShape(Ray ray, inout Intersections ix) +{ + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate; + ray.dir *= u_cylinderUvToRenderBoundsScale; + #else + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + #endif + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) + vec2 outerIntersect = intersectUnitCircle(ray); + #else + vec2 outerIntersect = intersectUnitCylinder(ray); + #endif + + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect); + + if (outerIntersect.x == NO_HIT) { + return; + } + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + vec2 innerIntersect = intersectInfiniteUnitCylinder(ray); + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) + Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin); + vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect); + #endif + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); + #endif +} +#endif + +#if defined(SHAPE_CYLINDER) +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] + + // Compute radius + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + float radius = length(positionLocal.xy); // [0,1] + #else + float radius = length(positionLocal.xy); // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset + #endif + #endif + + // Compute height + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) + float height = positionUv.z; // [0,1] + #else + float height = positionUv.z; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset + #endif + #endif + + // Compute angle + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + float angle = 1.0; + #else + float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. + angle += float(angle < u_cylinderShapeUvAngleEmptyMid); + #endif + + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) + angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; + #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; + #endif + + angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset + #endif + #endif + + return vec3(radius, height, angle); +} +#endif + #if defined(CLIPPING_PLANES) void intersectClippingPlanes(Ray ray, inout Intersections ix) { #if (CLIPPING_PLANES_COUNT == 1) @@ -533,45 +1449,31 @@ Properties getPropertiesFromMegatexture(in SampleData sampleData) { voxelCoord = floor(voxelCoord) + vec3(0.5); #endif - #if defined(MEGATEXTURE_2D) - // Tile location - vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - - // Slice location - float slice = voxelCoord.z - 0.5; - int sliceIndex = int(floor(slice)); - int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1); - vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - - // Voxel location - vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; - - // Final location in the megatexture - vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; + // Tile location + vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - #if defined(NEAREST_SAMPLING) - return getPropertiesFromMegatextureAtUv(uv0); - #else - float sliceLerp = fract(slice); - int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1); - vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; - Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); - Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); - return mixProperties(properties0, properties1, sliceLerp); - #endif - #elif defined(MEGATEXTURE_3D) - // TODO: 3D megatexture has not been implemented yet - // Tile location - vec3 tileUvOffset = indexToUv3d(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + // Slice location + float slice = voxelCoord.z - 0.5; + int sliceIndex = int(floor(slice)); + int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1); + vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - // Voxel location - vec3 voxelUvOffset = clamp(voxelCoord, vec3(0.5), vec3(voxelDimensions) - vec2(0.5)) * u_megatextureVoxelSizeUv; + // Voxel location + vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; - // Final location in the megatexture - vec3 uv = tileUvOffset + voxelUvOffset; + // Final location in the megatexture + vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; - return getPropertiesFromMegatextureAtUv(uv); + #if defined(NEAREST_SAMPLING) + return getPropertiesFromMegatextureAtUv(uv0); + #else + float sliceLerp = fract(slice); + int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1); + vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; + Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); + Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); + return mixProperties(properties0, properties1, sliceLerp); #endif } From 8991a4ae9aaf85f6add03c01e62b9c48d61edaca Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 18 Aug 2022 12:20:45 -0400 Subject: [PATCH 080/679] Break VoxelFS.glsl into smaller components --- Apps/Sandcastle/gallery/Voxels.html | 6 +- Apps/Sandcastle/gallery/VoxelsBox.html | 391 ++++ Source/Scene/VoxelDrawCommands.js | 763 +++++++ Source/Scene/VoxelPrimitive.js | 724 +------ Source/Shaders/VoxelFS.glsl | 1779 ----------------- Source/Shaders/Voxels/IntersectBox.glsl | 80 + .../Voxels/IntersectClippingPlanes.glsl | 71 + Source/Shaders/Voxels/IntersectCylinder.glsl | 259 +++ Source/Shaders/Voxels/IntersectDepth.glsl | 24 + Source/Shaders/Voxels/IntersectEllipsoid.glsl | 320 +++ Source/Shaders/Voxels/Intersection.glsl | 52 + Source/Shaders/Voxels/IntersectionUtils.glsl | 147 ++ Source/Shaders/Voxels/Megatexture.glsl | 138 ++ Source/Shaders/Voxels/Octree.glsl | 227 +++ Source/Shaders/Voxels/VoxelFS.glsl | 132 ++ Source/Shaders/{ => Voxels}/VoxelVS.glsl | 0 Source/Shaders/Voxels/convertUvToBox.glsl | 17 + .../Shaders/Voxels/convertUvToCylinder.glsl | 81 + .../Shaders/Voxels/convertUvToEllipsoid.glsl | 135 ++ 19 files changed, 2843 insertions(+), 2503 deletions(-) create mode 100644 Apps/Sandcastle/gallery/VoxelsBox.html create mode 100644 Source/Scene/VoxelDrawCommands.js delete mode 100644 Source/Shaders/VoxelFS.glsl create mode 100644 Source/Shaders/Voxels/IntersectBox.glsl create mode 100644 Source/Shaders/Voxels/IntersectClippingPlanes.glsl create mode 100644 Source/Shaders/Voxels/IntersectCylinder.glsl create mode 100644 Source/Shaders/Voxels/IntersectDepth.glsl create mode 100644 Source/Shaders/Voxels/IntersectEllipsoid.glsl create mode 100644 Source/Shaders/Voxels/Intersection.glsl create mode 100644 Source/Shaders/Voxels/IntersectionUtils.glsl create mode 100644 Source/Shaders/Voxels/Megatexture.glsl create mode 100644 Source/Shaders/Voxels/Octree.glsl create mode 100644 Source/Shaders/Voxels/VoxelFS.glsl rename Source/Shaders/{ => Voxels}/VoxelVS.glsl (100%) create mode 100644 Source/Shaders/Voxels/convertUvToBox.glsl create mode 100644 Source/Shaders/Voxels/convertUvToCylinder.glsl create mode 100644 Source/Shaders/Voxels/convertUvToEllipsoid.glsl diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 048c6a58984..641bbd09ed6 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -32,7 +32,7 @@

Loading...

diff --git a/Apps/Sandcastle/gallery/VoxelsBox.html b/Apps/Sandcastle/gallery/VoxelsBox.html new file mode 100644 index 00000000000..73750c27470 --- /dev/null +++ b/Apps/Sandcastle/gallery/VoxelsBox.html @@ -0,0 +1,391 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/VoxelDrawCommands.js new file mode 100644 index 00000000000..9df29b881ec --- /dev/null +++ b/Source/Scene/VoxelDrawCommands.js @@ -0,0 +1,763 @@ +import Cartesian3 from "../Core/Cartesian3"; +import combine from "../Core/combine.js"; +import defined from "../Core/defined"; +import PrimitiveType from "../Core/PrimitiveType.js"; +import BlendingState from "./BlendingState.js"; +import CullFace from "./CullFace.js"; +import getClippingFunction from "./getClippingFunction.js"; +import DrawCommand from "../Renderer/DrawCommand.js"; +import Pass from "../Renderer/Pass.js"; +import RenderState from "../Renderer/RenderState.js"; +import ShaderBuilder from "../Renderer/ShaderBuilder.js"; +import ShaderDestination from "../Renderer/ShaderDestination.js"; +import VoxelFS from "../Shaders/Voxels/VoxelFS.js"; +import VoxelVS from "../Shaders/Voxels/VoxelVS.js"; +import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js"; +import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js"; +import IntersectClippingPlanes from "../Shaders/Voxels/IntersectClippingPlanes.js"; +import IntersectBox from "../Shaders/Voxels/IntersectBox.js"; +import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js"; +import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js"; +import Intersection from "../Shaders/Voxels/Intersection.js"; +import convertUvToBox from "../Shaders/Voxels/convertUvToBox.js"; +import convertUvToCylinder from "../Shaders/Voxels/convertUvToCylinder.js"; +import convertUvToEllipsoid from "../Shaders/Voxels/convertUvToEllipsoid.js"; +import Octree from "../Shaders/Voxels/Octree.js"; +import Megatexture from "../Shaders/Voxels/Megatexture.js"; +import MetadataType from "./MetadataType.js"; + +/** + * @function + * + * @param {VoxelPrimitive} that + * @param {Context} context + * + * @private + */ +function buildVoxelDrawCommands(that, context) { + const provider = that._provider; + const traversal = that._traversal; + const shapeType = provider.shape; + const names = provider.names; + const types = provider.types; + const componentTypes = provider.componentTypes; + const depthTest = that._depthTest; + const useLogDepth = that._useLogDepth; + const paddingBefore = that.paddingBefore; + const paddingAfter = that.paddingAfter; + const shape = that._shape; + const shapeDefines = shape.shaderDefines; + const minimumValues = provider.minimumValues; + const maximumValues = provider.maximumValues; + const jitter = that._jitter; + const nearestSampling = that._nearestSampling; + const sampleCount = traversal._sampleCount; + const customShader = that._customShader; + const attributeLength = types.length; + const hasStatistics = defined(minimumValues) && defined(maximumValues); + const clippingPlanes = that._clippingPlanes; + const clippingPlanesLength = + defined(clippingPlanes) && clippingPlanes.enabled + ? clippingPlanes.length + : 0; + const clippingPlanesUnion = defined(clippingPlanes) + ? clippingPlanes.unionClippingRegions + : false; + + let uniformMap = that._uniformMap; + + // Build shader + + const shaderBuilder = new ShaderBuilder(); + + // Vertex shader + + shaderBuilder.addVertexLines([VoxelVS]); + + // Fragment shader + + shaderBuilder.addFragmentLines([ + customShader.fragmentShaderText, + "#line 0", + IntersectionUtils, + ]); + if (depthTest) { + shaderBuilder.addFragmentLines([IntersectDepth]); + } + if (clippingPlanesLength > 0) { + shaderBuilder.addFragmentLines([IntersectClippingPlanes]); + } + if (shapeType === "BOX") { + shaderBuilder.addFragmentLines([ + IntersectBox, + Intersection, + convertUvToBox, + ]); + } else if (shapeType === "CYLINDER") { + shaderBuilder.addFragmentLines([ + IntersectCylinder, + Intersection, + convertUvToCylinder, + ]); + } else if (shapeType === "ELLIPSOID") { + shaderBuilder.addFragmentLines([ + IntersectEllipsoid, + Intersection, + convertUvToEllipsoid, + ]); + } + shaderBuilder.addFragmentLines([Octree, Megatexture, VoxelFS]); + + // Fragment shader defines + + shaderBuilder.addDefine( + "METADATA_COUNT", + attributeLength, + ShaderDestination.FRAGMENT + ); + + if ( + !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || + !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) + ) { + shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); + } + if (depthTest) { + shaderBuilder.addDefine( + "DEPTH_TEST", + undefined, + ShaderDestination.FRAGMENT + ); + } + + // Allow reading from log depth texture, but don't write log depth anywhere. + // Note: This needs to be set even if depthTest is off because it affects the + // derived command system. + if (useLogDepth) { + shaderBuilder.addDefine( + "LOG_DEPTH_READ_ONLY", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (jitter) { + shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); + } + + if (nearestSampling) { + shaderBuilder.addDefine( + "NEAREST_SAMPLING", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (hasStatistics) { + shaderBuilder.addDefine( + "STATISTICS", + undefined, + ShaderDestination.FRAGMENT + ); + } + + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES", + undefined, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addDefine( + "CLIPPING_PLANES_COUNT", + clippingPlanesLength, + ShaderDestination.FRAGMENT + ); + if (clippingPlanesUnion) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_UNION", + undefined, + ShaderDestination.FRAGMENT + ); + } + } + + // Count how many intersections the shader will do. + let intersectionCount = shape.shaderMaximumIntersectionsLength; + + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + if (clippingPlanesLength === 1) { + intersectionCount += 1; + } else if (clippingPlanesUnion) { + intersectionCount += 2; + } else { + intersectionCount += 1; + } + } + + if (depthTest) { + shaderBuilder.addDefine( + "DEPTH_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount += 1; + } + + shaderBuilder.addDefine( + "INTERSECTION_COUNT", + intersectionCount, + ShaderDestination.FRAGMENT + ); + + shaderBuilder.addDefine( + "SAMPLE_COUNT", + `${sampleCount}`, + ShaderDestination.FRAGMENT + ); + + // Shape specific defines + shaderBuilder.addDefine( + `SHAPE_${shapeType}`, + undefined, + ShaderDestination.FRAGMENT + ); + + for (const key in shapeDefines) { + if (shapeDefines.hasOwnProperty(key)) { + let value = shapeDefines[key]; + // if value is undefined, don't define it + // if value is true, define it to nothing + if (defined(value)) { + value = value === true ? undefined : value; + shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); + } + } + } + + // Fragment shader uniforms + + // Custom shader uniforms + const customShaderUniforms = customShader.uniforms; + uniformMap = that._uniformMap = combine(uniformMap, customShader.uniformMap); + for (const uniformName in customShaderUniforms) { + if (customShaderUniforms.hasOwnProperty(uniformName)) { + const uniform = customShaderUniforms[uniformName]; + shaderBuilder.addUniform( + uniform.type, + uniformName, + ShaderDestination.FRAGMENT + ); + } + } + + // The reason this uniform is added by shader builder is because some of the + // dynamically generated shader code reads from it. + shaderBuilder.addUniform( + "sampler2D", + "u_megatextureTextures[METADATA_COUNT]", + ShaderDestination.FRAGMENT + ); + + // Fragment shader structs + + // PropertyStatistics structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const propertyStatisticsStructId = `PropertyStatistics_${name}`; + const propertyStatisticsStructName = `PropertyStatistics_${name}`; + shaderBuilder.addStruct( + propertyStatisticsStructId, + propertyStatisticsStructName, + ShaderDestination.FRAGMENT + ); + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "min"); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "max"); + } + + // Statistics struct + const statisticsStructId = "Statistics"; + const statisticsStructName = "Statistics"; + const statisticsFieldName = "statistics"; + shaderBuilder.addStruct( + statisticsStructId, + statisticsStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const propertyStructName = `PropertyStatistics_${name}`; + const propertyFieldName = name; + shaderBuilder.addStructField( + statisticsStructId, + propertyStructName, + propertyFieldName + ); + } + + // Metadata struct + const metadataStructId = "Metadata"; + const metadataStructName = "Metadata"; + const metadataFieldName = "metadata"; + shaderBuilder.addStruct( + metadataStructId, + metadataStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + metadataStructId, + statisticsStructName, + statisticsFieldName + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(metadataStructId, glslType, name); + } + + // VoxelProperty structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslPartialDerivativeType(type); + const voxelPropertyStructId = `VoxelProperty_${name}`; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStruct( + voxelPropertyStructId, + voxelPropertyStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeLocal" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeWorld" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeView" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeValid" + ); + } + + // Voxel struct + const voxelStructId = "Voxel"; + const voxelStructName = "Voxel"; + const voxelFieldName = "voxel"; + shaderBuilder.addStruct( + voxelStructId, + voxelStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStructField(voxelStructId, voxelPropertyStructName, name); + } + shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionShapeUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); + shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); + + // FragmentInput struct + const fragmentInputStructId = "FragmentInput"; + const fragmentInputStructName = "FragmentInput"; + shaderBuilder.addStruct( + fragmentInputStructId, + fragmentInputStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + fragmentInputStructId, + metadataStructName, + metadataFieldName + ); + shaderBuilder.addStructField( + fragmentInputStructId, + voxelStructName, + voxelFieldName + ); + + // Properties struct + const propertiesStructId = "Properties"; + const propertiesStructName = "Properties"; + const propertiesFieldName = "properties"; + shaderBuilder.addStruct( + propertiesStructId, + propertiesStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertiesStructId, glslType, name); + } + + // Fragment shader functions + + // clearProperties function + { + const functionId = "clearProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} clearProperties()`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslType = getGlslType(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = ${glslType}(0.0);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // sumProperties function + { + const functionId = "sumProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} sumProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = propertiesA.${name} + propertiesB.${name};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // scaleProperties function + { + const functionId = "scaleProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} scaleProperties(${propertiesStructName} ${propertiesFieldName}, float scale)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} scaledProperties = ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `scaledProperties.${name} *= scale;`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [`return scaledProperties;`]); + } + + // mixProperties + { + const functionId = "mixProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} mixProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB, float mixFactor)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = mix(propertiesA.${name}, propertiesB.${name}, mixFactor);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // copyPropertiesToMetadata + { + const functionId = "copyPropertiesToMetadata"; + shaderBuilder.addFunction( + functionId, + `void copyPropertiesToMetadata(in ${propertiesStructName} ${propertiesFieldName}, inout ${metadataStructName} ${metadataFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${metadataFieldName}.${name} = ${propertiesFieldName}.${name};`, + ]); + } + } + + // setStatistics function + if (hasStatistics) { + const functionId = "setStatistics"; + shaderBuilder.addFunction( + functionId, + `void setStatistics(inout ${statisticsStructName} ${statisticsFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + for (let j = 0; j < componentCount; j++) { + const glslField = getGlslField(type, j); + const minimumValue = minimumValues[i][j]; + const maximumValue = maximumValues[i][j]; + shaderBuilder.addFunctionLines(functionId, [ + `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat( + minimumValue + )};`, + `${statisticsFieldName}.${name}.max${glslField} = ${getGlslNumberAsFloat( + maximumValue + )};`, + ]); + } + } + } + + // getPropertiesFromMegatextureAtUv + { + const functionId = "getPropertiesFromMegatextureAtUv"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} getPropertiesFromMegatextureAtUv(vec2 texcoord)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `properties.${name} = texture2D(u_megatextureTextures[${i}], texcoord)${glslTextureSwizzle};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + if (clippingPlanesLength > 0) { + // Extract the getClippingPlane function from the getClippingFunction string. + // This is a bit of a hack. + const functionId = "getClippingPlane"; + const entireFunction = getClippingFunction(clippingPlanes, context); + const functionSignatureBegin = 0; + const functionSignatureEnd = entireFunction.indexOf(")") + 1; + const functionBodyBegin = + entireFunction.indexOf("{", functionSignatureEnd) + 1; + const functionBodyEnd = entireFunction.indexOf("}", functionBodyBegin); + const functionSignature = entireFunction.slice( + functionSignatureBegin, + functionSignatureEnd + ); + const functionBody = entireFunction.slice( + functionBodyBegin, + functionBodyEnd + ); + shaderBuilder.addFunction( + functionId, + functionSignature, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [functionBody]); + } + + // Compile shaders + const shaderBuilderPick = shaderBuilder.clone(); + shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); + const shaderProgram = shaderBuilder.buildShaderProgram(context); + const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context); + const renderState = RenderState.fromCache({ + cull: { + enabled: true, + face: CullFace.BACK, + }, + depthTest: { + enabled: false, + }, + depthMask: false, + // internally the shader does premultiplied alpha, so it makes sense to blend that way too + blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, + }); + + // Create the draw commands + const viewportQuadVertexArray = context.getViewportQuadVertexArray(); + const drawCommand = new DrawCommand({ + vertexArray: viewportQuadVertexArray, + primitiveType: PrimitiveType.TRIANGLES, + renderState: renderState, + shaderProgram: shaderProgram, + uniformMap: uniformMap, + pass: Pass.VOXELS, + executeInClosestFrustum: true, + owner: this, + cull: depthTest, // don't cull or occlude if depth testing is off + occlude: depthTest, // don't cull or occlude if depth testing is off + }); + + // Create the pick draw command + const drawCommandPick = DrawCommand.shallowClone( + drawCommand, + new DrawCommand() + ); + drawCommandPick.shaderProgram = shaderProgramPick; + drawCommandPick.pickOnly = true; + + // Delete the old shader programs + if (defined(that._drawCommand)) { + const command = that._drawCommand; + command.shaderProgram = + command.shaderProgram && command.shaderProgram.destroy(); + } + if (defined(that._drawCommandPick)) { + const command = that._drawCommandPick; + command.shaderProgram = + command.shaderProgram && command.shaderProgram.destroy(); + } + + that._drawCommand = drawCommand; + that._drawCommandPick = drawCommandPick; +} + +// Shader builder helpers + +/** + * Converts a {@link MetadataType} to a GLSL type. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * + * @private + */ +function getGlslType(type) { + if (type === MetadataType.SCALAR) { + return "float"; + } else if (type === MetadataType.VEC2) { + return "vec2"; + } else if (type === MetadataType.VEC3) { + return "vec3"; + } else if (type === MetadataType.VEC4) { + return "vec4"; + } +} + +/** + * Gets the GLSL swizzle when reading data from a texture. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL swizzle. + * + * @private + */ +function getGlslTextureSwizzle(type) { + if (type === MetadataType.SCALAR) { + return ".r"; + } else if (type === MetadataType.VEC2) { + return ".ra"; + } else if (type === MetadataType.VEC3) { + return ".rgb"; + } else if (type === MetadataType.VEC4) { + return ""; + } +} + +/** + * Gets the GLSL type of the partial derivative of {@link MetadataType}. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * + * @private + */ +function getGlslPartialDerivativeType(type) { + if (type === MetadataType.SCALAR) { + return "vec3"; + } else if (type === MetadataType.VEC2) { + return "mat2"; + } else if (type === MetadataType.VEC3) { + return "mat3"; + } else if (type === MetadataType.VEC4) { + return "mat4"; + } +} + +/** + * GLSL needs to have `.0` at the end of whole number floats or else it's + * treated like an integer. + * + * @function + * + * @param {Number} number The number to convert. + * @returns {String} The number as floating point in GLSL. + * + * @private + */ +function getGlslNumberAsFloat(number) { + let numberString = number.toString(); + if (numberString.indexOf(".") === -1) { + numberString = `${number}.0`; + } + return numberString; +} + +/** + * Gets the GLSL field + * + * @function + * + * @param {MetadataType} type + * @param {Number} index + * @returns {String} + * + * @private + */ +function getGlslField(type, index) { + if (type === MetadataType.SCALAR) { + return ""; + } + return `[${index}]`; +} + +export default buildVoxelDrawCommands; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 9100de0ab00..e30d45f631d 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1,3 +1,4 @@ +import buildVoxelDrawCommands from "./VoxelDrawCommands.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartesian4 from "../Core/Cartesian4.js"; @@ -5,7 +6,6 @@ import CesiumMath from "../Core/Math.js"; import Check from "../Core/Check.js"; import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; -import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; @@ -15,11 +15,7 @@ import Event from "../Core/Event.js"; import JulianDate from "../Core/JulianDate.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; -import PrimitiveType from "../Core/PrimitiveType.js"; -import BlendingState from "./BlendingState.js"; import ClippingPlaneCollection from "./ClippingPlaneCollection.js"; -import CullFace from "./CullFace.js"; -import getClippingFunction from "./getClippingFunction.js"; import Material from "./Material.js"; import MetadataComponentType from "./MetadataComponentType.js"; import MetadataType from "./MetadataType.js"; @@ -27,13 +23,7 @@ import PolylineCollection from "./PolylineCollection.js"; import VoxelShapeType from "./VoxelShapeType.js"; import VoxelTraversal from "./VoxelTraversal.js"; import CustomShader from "./Model/CustomShader.js"; -import DrawCommand from "../Renderer/DrawCommand.js"; -import Pass from "../Renderer/Pass.js"; -import RenderState from "../Renderer/RenderState.js"; -import ShaderBuilder from "../Renderer/ShaderBuilder.js"; -import ShaderDestination from "../Renderer/ShaderDestination.js"; -import VoxelFS from "../Shaders/VoxelFS.js"; -import VoxelVS from "../Shaders/VoxelVS.js"; + /** * A primitive that renders voxel data from a {@link VoxelProvider}. * @@ -1563,7 +1553,7 @@ VoxelPrimitive.prototype.update = function (frameState) { // Rebuild shaders if (this._shaderDirty) { - buildDrawCommands(this, context); + buildVoxelDrawCommands(this, context); this._shaderDirty = false; } @@ -1640,714 +1630,6 @@ VoxelPrimitive.prototype.update = function (frameState) { } }; -// Shader builder helpers - -/** - * Converts a {@link MetadataType} to a GLSL type. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. - * - * @private - */ -function getGlslType(type) { - if (type === MetadataType.SCALAR) { - return "float"; - } else if (type === MetadataType.VEC2) { - return "vec2"; - } else if (type === MetadataType.VEC3) { - return "vec3"; - } else if (type === MetadataType.VEC4) { - return "vec4"; - } -} - -/** - * Gets the GLSL swizzle when reading data from a texture. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL swizzle. - * - * @private - */ -function getGlslTextureSwizzle(type) { - if (type === MetadataType.SCALAR) { - return ".r"; - } else if (type === MetadataType.VEC2) { - return ".ra"; - } else if (type === MetadataType.VEC3) { - return ".rgb"; - } else if (type === MetadataType.VEC4) { - return ""; - } -} - -/** - * Gets the GLSL type of the partial derivative of {@link MetadataType}. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. - * - * @private - */ -function getGlslPartialDerivativeType(type) { - if (type === MetadataType.SCALAR) { - return "vec3"; - } else if (type === MetadataType.VEC2) { - return "mat2"; - } else if (type === MetadataType.VEC3) { - return "mat3"; - } else if (type === MetadataType.VEC4) { - return "mat4"; - } -} - -/** - * GLSL needs to have `.0` at the end of whole number floats or else it's - * treated like an integer. - * - * @function - * - * @param {Number} number The number to convert. - * @returns {String} The number as floating point in GLSL. - * - * @private - */ -function getGlslNumberAsFloat(number) { - let numberString = number.toString(); - if (numberString.indexOf(".") === -1) { - numberString = `${number}.0`; - } - return numberString; -} - -/** - * Gets the GLSL field - * - * @function - * - * @param {MetadataType} type - * @param {Number} index - * @returns {String} - * - * @private - */ -function getGlslField(type, index) { - if (type === MetadataType.SCALAR) { - return ""; - } - return `[${index}]`; -} - -/** - * @function - * - * @param {VoxelPrimitive} that - * @param {Context} context - * - * @private - */ -function buildDrawCommands(that, context) { - const provider = that._provider; - const traversal = that._traversal; - const shapeType = provider.shape; - const names = provider.names; - const types = provider.types; - const componentTypes = provider.componentTypes; - const depthTest = that._depthTest; - const useLogDepth = that._useLogDepth; - const paddingBefore = that.paddingBefore; - const paddingAfter = that.paddingAfter; - const shape = that._shape; - const shapeDefines = shape.shaderDefines; - const minimumValues = provider.minimumValues; - const maximumValues = provider.maximumValues; - const jitter = that._jitter; - const nearestSampling = that._nearestSampling; - const sampleCount = traversal._sampleCount; - const customShader = that._customShader; - const attributeLength = types.length; - const hasStatistics = defined(minimumValues) && defined(maximumValues); - const clippingPlanes = that._clippingPlanes; - const clippingPlanesLength = - defined(clippingPlanes) && clippingPlanes.enabled - ? clippingPlanes.length - : 0; - const clippingPlanesUnion = defined(clippingPlanes) - ? clippingPlanes.unionClippingRegions - : false; - - let uniformMap = that._uniformMap; - - // Build shader - - const shaderBuilder = new ShaderBuilder(); - - // Vertex shader - - shaderBuilder.addVertexLines([VoxelVS]); - - // Fragment shader - - shaderBuilder.addFragmentLines([ - customShader.fragmentShaderText, - "#line 0", - VoxelFS, - ]); - - // Fragment shader defines - - shaderBuilder.addDefine( - "METADATA_COUNT", - attributeLength, - ShaderDestination.FRAGMENT - ); - - if ( - !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || - !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) - ) { - shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); - } - if (depthTest) { - shaderBuilder.addDefine( - "DEPTH_TEST", - undefined, - ShaderDestination.FRAGMENT - ); - } - - // Allow reading from log depth texture, but don't write log depth anywhere. - // Note: This needs to be set even if depthTest is off because it affects the - // derived command system. - if (useLogDepth) { - shaderBuilder.addDefine( - "LOG_DEPTH_READ_ONLY", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (jitter) { - shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); - } - - if (nearestSampling) { - shaderBuilder.addDefine( - "NEAREST_SAMPLING", - undefined, - ShaderDestination.FRAGMENT - ); - } - - if (hasStatistics) { - shaderBuilder.addDefine( - "STATISTICS", - undefined, - ShaderDestination.FRAGMENT - ); - } - - if (clippingPlanesLength > 0) { - shaderBuilder.addDefine( - "CLIPPING_PLANES", - undefined, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addDefine( - "CLIPPING_PLANES_COUNT", - clippingPlanesLength, - ShaderDestination.FRAGMENT - ); - if (clippingPlanesUnion) { - shaderBuilder.addDefine( - "CLIPPING_PLANES_UNION", - undefined, - ShaderDestination.FRAGMENT - ); - } - } - - // Count how many intersections the shader will do. - let intersectionCount = shape.shaderMaximumIntersectionsLength; - - if (clippingPlanesLength > 0) { - shaderBuilder.addDefine( - "CLIPPING_PLANES_INTERSECTION_INDEX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - if (clippingPlanesLength === 1) { - intersectionCount += 1; - } else if (clippingPlanesUnion) { - intersectionCount += 2; - } else { - intersectionCount += 1; - } - } - - if (depthTest) { - shaderBuilder.addDefine( - "DEPTH_INTERSECTION_INDEX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount += 1; - } - - shaderBuilder.addDefine( - "INTERSECTION_COUNT", - intersectionCount, - ShaderDestination.FRAGMENT - ); - - shaderBuilder.addDefine( - "SAMPLE_COUNT", - `${sampleCount}`, - ShaderDestination.FRAGMENT - ); - - // Shape specific defines - shaderBuilder.addDefine( - `SHAPE_${shapeType}`, - undefined, - ShaderDestination.FRAGMENT - ); - - for (const key in shapeDefines) { - if (shapeDefines.hasOwnProperty(key)) { - let value = shapeDefines[key]; - // if value is undefined, don't define it - // if value is true, define it to nothing - if (defined(value)) { - value = value === true ? undefined : value; - shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); - } - } - } - - // Fragment shader uniforms - - // Custom shader uniforms - const customShaderUniforms = customShader.uniforms; - uniformMap = that._uniformMap = combine(uniformMap, customShader.uniformMap); - for (const uniformName in customShaderUniforms) { - if (customShaderUniforms.hasOwnProperty(uniformName)) { - const uniform = customShaderUniforms[uniformName]; - shaderBuilder.addUniform( - uniform.type, - uniformName, - ShaderDestination.FRAGMENT - ); - } - } - - // The reason this uniform is added by shader builder is because some of the - // dynamically generated shader code reads from it. - shaderBuilder.addUniform( - "sampler2D", - "u_megatextureTextures[METADATA_COUNT]", - ShaderDestination.FRAGMENT - ); - - // Fragment shader structs - - // PropertyStatistics structs - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const propertyStatisticsStructId = `PropertyStatistics_${name}`; - const propertyStatisticsStructName = `PropertyStatistics_${name}`; - shaderBuilder.addStruct( - propertyStatisticsStructId, - propertyStatisticsStructName, - ShaderDestination.FRAGMENT - ); - const glslType = getGlslType(type); - shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "min"); - shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "max"); - } - - // Statistics struct - const statisticsStructId = "Statistics"; - const statisticsStructName = "Statistics"; - const statisticsFieldName = "statistics"; - shaderBuilder.addStruct( - statisticsStructId, - statisticsStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const propertyStructName = `PropertyStatistics_${name}`; - const propertyFieldName = name; - shaderBuilder.addStructField( - statisticsStructId, - propertyStructName, - propertyFieldName - ); - } - - // Metadata struct - const metadataStructId = "Metadata"; - const metadataStructName = "Metadata"; - const metadataFieldName = "metadata"; - shaderBuilder.addStruct( - metadataStructId, - metadataStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - metadataStructId, - statisticsStructName, - statisticsFieldName - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(metadataStructId, glslType, name); - } - - // VoxelProperty structs - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslPartialDerivativeType(type); - const voxelPropertyStructId = `VoxelProperty_${name}`; - const voxelPropertyStructName = `VoxelProperty_${name}`; - shaderBuilder.addStruct( - voxelPropertyStructId, - voxelPropertyStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeLocal" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeWorld" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeView" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeValid" - ); - } - - // Voxel struct - const voxelStructId = "Voxel"; - const voxelStructName = "Voxel"; - const voxelFieldName = "voxel"; - shaderBuilder.addStruct( - voxelStructId, - voxelStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const voxelPropertyStructName = `VoxelProperty_${name}`; - shaderBuilder.addStructField(voxelStructId, voxelPropertyStructName, name); - } - shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionShapeUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); - shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); - - // FragmentInput struct - const fragmentInputStructId = "FragmentInput"; - const fragmentInputStructName = "FragmentInput"; - shaderBuilder.addStruct( - fragmentInputStructId, - fragmentInputStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - fragmentInputStructId, - metadataStructName, - metadataFieldName - ); - shaderBuilder.addStructField( - fragmentInputStructId, - voxelStructName, - voxelFieldName - ); - - // Properties struct - const propertiesStructId = "Properties"; - const propertiesStructName = "Properties"; - const propertiesFieldName = "properties"; - shaderBuilder.addStruct( - propertiesStructId, - propertiesStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(propertiesStructId, glslType, name); - } - - // Fragment shader functions - - // clearProperties function - { - const functionId = "clearProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} clearProperties()`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslType = getGlslType(type, componentType); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = ${glslType}(0.0);`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - // sumProperties function - { - const functionId = "sumProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} sumProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = propertiesA.${name} + propertiesB.${name};`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - // scaleProperties function - { - const functionId = "scaleProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} scaleProperties(${propertiesStructName} ${propertiesFieldName}, float scale)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} scaledProperties = ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `scaledProperties.${name} *= scale;`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [`return scaledProperties;`]); - } - - // mixProperties - { - const functionId = "mixProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} mixProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB, float mixFactor)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = mix(propertiesA.${name}, propertiesB.${name}, mixFactor);`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - // copyPropertiesToMetadata - { - const functionId = "copyPropertiesToMetadata"; - shaderBuilder.addFunction( - functionId, - `void copyPropertiesToMetadata(in ${propertiesStructName} ${propertiesFieldName}, inout ${metadataStructName} ${metadataFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${metadataFieldName}.${name} = ${propertiesFieldName}.${name};`, - ]); - } - } - - // setStatistics function - if (hasStatistics) { - const functionId = "setStatistics"; - shaderBuilder.addFunction( - functionId, - `void setStatistics(inout ${statisticsStructName} ${statisticsFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentCount = MetadataType.getComponentCount(type); - for (let j = 0; j < componentCount; j++) { - const glslField = getGlslField(type, j); - const minimumValue = minimumValues[i][j]; - const maximumValue = maximumValues[i][j]; - shaderBuilder.addFunctionLines(functionId, [ - `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat( - minimumValue - )};`, - `${statisticsFieldName}.${name}.max${glslField} = ${getGlslNumberAsFloat( - maximumValue - )};`, - ]); - } - } - } - - // getPropertiesFromMegatextureAtUv - { - const functionId = "getPropertiesFromMegatextureAtUv"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} getPropertiesFromMegatextureAtUv(vec2 texcoord)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); - shaderBuilder.addFunctionLines(functionId, [ - `properties.${name} = texture2D(u_megatextureTextures[${i}], texcoord)${glslTextureSwizzle};`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - if (clippingPlanesLength > 0) { - // Extract the getClippingPlane function from the getClippingFunction string. - // This is a bit of a hack. - const functionId = "getClippingPlane"; - const entireFunction = getClippingFunction(clippingPlanes, context); - const functionSignatureBegin = 0; - const functionSignatureEnd = entireFunction.indexOf(")") + 1; - const functionBodyBegin = - entireFunction.indexOf("{", functionSignatureEnd) + 1; - const functionBodyEnd = entireFunction.indexOf("}", functionBodyBegin); - const functionSignature = entireFunction.slice( - functionSignatureBegin, - functionSignatureEnd - ); - const functionBody = entireFunction.slice( - functionBodyBegin, - functionBodyEnd - ); - shaderBuilder.addFunction( - functionId, - functionSignature, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [functionBody]); - } - - // Compile shaders - const shaderBuilderPick = shaderBuilder.clone(); - shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT); - const shaderProgram = shaderBuilder.buildShaderProgram(context); - const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context); - const renderState = RenderState.fromCache({ - cull: { - enabled: true, - face: CullFace.BACK, - }, - depthTest: { - enabled: false, - }, - depthMask: false, - // internally the shader does premultiplied alpha, so it makes sense to blend that way too - blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND, - }); - - // Create the draw commands - const viewportQuadVertexArray = context.getViewportQuadVertexArray(); - const drawCommand = new DrawCommand({ - vertexArray: viewportQuadVertexArray, - primitiveType: PrimitiveType.TRIANGLES, - renderState: renderState, - shaderProgram: shaderProgram, - uniformMap: uniformMap, - pass: Pass.VOXELS, - executeInClosestFrustum: true, - owner: this, - cull: depthTest, // don't cull or occlude if depth testing is off - occlude: depthTest, // don't cull or occlude if depth testing is off - }); - - // Create the pick draw command - const drawCommandPick = DrawCommand.shallowClone( - drawCommand, - new DrawCommand() - ); - drawCommandPick.shaderProgram = shaderProgramPick; - drawCommandPick.pickOnly = true; - - // Delete the old shader programs - if (defined(that._drawCommand)) { - const command = that._drawCommand; - command.shaderProgram = - command.shaderProgram && command.shaderProgram.destroy(); - } - if (defined(that._drawCommandPick)) { - const command = that._drawCommandPick; - command.shaderProgram = - command.shaderProgram && command.shaderProgram.destroy(); - } - - that._drawCommand = drawCommand; - that._drawCommandPick = drawCommandPick; -} - /** * Returns true if this object was destroyed; otherwise, false. *

diff --git a/Source/Shaders/VoxelFS.glsl b/Source/Shaders/VoxelFS.glsl deleted file mode 100644 index 2306c9cd513..00000000000 --- a/Source/Shaders/VoxelFS.glsl +++ /dev/null @@ -1,1779 +0,0 @@ -/* -Don't delete this comment! -Some shader code is dynamically generated in VoxelPrimitive.js to support custom shaders with arbitrary metadata. -Below is an example of how this code might look. Properties like "temperature" and "direction" are just examples. - -// Defines -#define PROPERTY_COUNT ### -#define SAMPLE_COUNT ### -#define SHAPE_BOX -#define SHAPE_ELLIPSOID -#define SHAPE_CYLINDER -#define MEGATEXTURE_3D -#define DEPTH_TEST -#define DEPTH_INTERSECTION_INDEX ### -#define INTERSECTION_COUNT ### -#define JITTER -#define NEAREST_SAMPLING -#define STATISTICS -#define PADDING -#define PICKING -#define CLIPPING_PLANES -#define CLIPPING_PLANES_UNION -#define CLIPPING_PLANES_COUNT -#define CLIPPING_PLANES_INTERSECTION_INDEX - -// Uniforms -uniform sampler2D u_megatextureTextures[PROPERTY_COUNT]; - -// Structs -struct PropertyStatistics_temperature { - float min; - float max; -}; -struct PropertyStatistics_direction { - vec3 min; - vec3 max; -}; -struct Statistics { - PropertyStatistics_temperature temperature; - PropertyStatistics_direction direction; -}; -struct Metadata { - Statistics statistics; - float temperature; - vec3 direction; -}; -struct VoxelProperty_temperature { - vec3 partialDerivativeLocal; - vec3 partialDerivativeWorld; - vec3 partialDerivativeView; - bool partialDerivativeValid; -}; -struct VoxelProperty_direction { - mat3 partialDerivativeLocal; - mat3 partialDerivativeWorld; - mat3 partialDerivativeView; - bool partialDerivativeValid; -}; -struct Voxel { - VoxelProperty_temperature temperature; - VoxelProperty_direction direction; - vec3 positionEC; - vec3 positionUv; - vec3 positionShapeUv; - vec3 positionUvLocal; - vec3 viewDirUv; - vec3 viewDirWorld; - float travelDistance; -}; -struct FragmentInput { - Metadata metadata; - Voxel voxel; -}; -struct Properties { - // This struct is similar to Metadata but is not part of the custom shader API and - // is intended to be used internally as a lightweight way to pass around properties. - float temperature; - vec3 direction; -}; - -// Functions -Properties clearProperties() { - Properties properties; - properties.temperature = 0.0; - properties.direction = vec3(0.0); - return properties; -} -Properties sumProperties(Properties propertiesA, Properties propertiesB) { - Properties properties; - properties.temperature = propertiesA.temperature + propertiesB.temperature; - properties.direction = propertiesA.direction + propertiesB.direction; - return properties; -} -Properties scaleProperties(Properties properties, float scale) { - Properties scaledProperties = properties; - scaledProperties.temperature *= scale; - scaledProperties.direction *= scale; - return scaledProperties; -} -Properties mixProperties(Properties propertiesA, Properties propertiesB, float mixFactor) { - Properties properties; - properties.temperature = mix(propertiesA.temperature, propertiesB.temperature, mixFactor); - properties.direction = mix(propertiesA.direction, propertiesB.direction, mixFactor); - return properties; -} -void copyPropertiesToMetadata(in Properties properties, inout Metadata metadata) { - metadata.temperature = properties.temperature; - metadata.direction = properties.direction; -} -void setStatistics(inout Statistics statistics) { - // Assume the "direction" property has no min/max - statistics.temperature.min = 20.0; - statistics.temperature.max = 50.0; -} -Properties getPropertiesFromMegatextureAtUv(vec2 texcoord) { - Properties properties; - properties.temperature = texture2D(u_megatextureTextures[0], texcoord).r; - properties.direction = texture2D(u_megatextureTextures[1], texcoord).rgb; - return properties; -} -void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - vec3 direction = fsInput.metadata.direction; - float temperature = fsInput.metadata.temperature; - float minTemperature = fsInput.metadata.statistics.temperature.min; - float maxTemperature = fsInput.metadata.statistics.temperature.max; - - material.diffuse = abs(direction); - material.alpha = (temperature - minTemperature) / (maxTemperature - minTemperature); -} -*/ - -// These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js -#define OCTREE_FLAG_INTERNAL 0 -#define OCTREE_FLAG_LEAF 1 -#define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2 - -#define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops -#define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops -#define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0 - -#define NO_HIT (-czm_infinity) -#define INF_HIT (czm_infinity * 0.5) - -uniform ivec3 u_dimensions; // does not include padding -#if defined(PADDING) - uniform ivec3 u_paddingBefore; - uniform ivec3 u_paddingAfter; -#endif - -uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions -uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions -uniform vec2 u_megatextureVoxelSizeUv; -uniform vec2 u_megatextureSliceSizeUv; -uniform vec2 u_megatextureTileSizeUv; - -uniform sampler2D u_octreeInternalNodeTexture; -uniform vec2 u_octreeInternalNodeTexelSizeUv; -uniform int u_octreeInternalNodeTilesPerRow; -uniform sampler2D u_octreeLeafNodeTexture; -uniform vec2 u_octreeLeafNodeTexelSizeUv; -uniform int u_octreeLeafNodeTilesPerRow; - -struct OctreeNodeData { - int data; - int flag; -}; - -struct TraversalData { - vec3 positionUvShapeSpace; - vec3 positionUvLocal; - float stepT; - ivec4 octreeCoords; - int parentOctreeIndex; -}; - -struct SampleData { - int megatextureIndex; - bool usingParentMegatextureIndex; - vec3 tileUv; - #if (SAMPLE_COUNT > 1) - float weight; - #endif -}; - -uniform mat4 u_transformPositionViewToUv; -uniform mat4 u_transformPositionUvToView; -uniform mat3 u_transformDirectionViewToLocal; -uniform mat3 u_transformNormalLocalToWorld; -uniform vec3 u_cameraPositionUv; -uniform float u_stepSize; - -#if defined(PICKING) - uniform vec4 u_pickColor; -#endif - -#if defined(CLIPPING_PLANES) - uniform sampler2D u_clippingPlanesTexture; - uniform mat4 u_clippingPlanesMatrix; -#endif - -#if defined(SHAPE_BOX) - /* Box defines: - #define BOX_INTERSECTION_INDEX ### // always 0 - #define BOX_HAS_SHAPE_BOUND - #define BOX_HAS_RENDER_BOUND - #define BOX_IS_2D - */ - - // Box uniforms: - #if defined(BOX_HAS_SHAPE_BOUND) - uniform vec3 u_boxScaleUvToShapeBoundsUv; - uniform vec3 u_boxOffsetUvToShapeBoundsUv; - #endif - #if defined(BOX_HAS_RENDER_BOUND) - #if defined(BOX_IS_2D) - // This matrix bakes in an axis conversion so that the math works for XY plane. - uniform mat4 u_boxTransformUvToRenderBounds; - #else - // Similar to u_boxTransformUvToBounds but fewer instructions needed. - uniform vec3 u_boxScaleUvToRenderBounds; - uniform vec3 u_boxOffsetUvToRenderBounds; - #endif - #endif -#endif - -#if defined(SHAPE_ELLIPSOID) - /* Ellipsoid defines: - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY - #define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF - #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE - #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN - #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO - #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN - #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO - #define ELLIPSOID_IS_SPHERE - #define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE - #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX - #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN - #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX - #define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN - */ - - // Ellipsoid uniforms - uniform vec3 u_ellipsoidRadiiUv; // [0,1] - #if !defined(ELLIPSOID_IS_SPHERE) - uniform vec3 u_ellipsoidInverseRadiiSquaredUv; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE) - uniform vec2 u_ellipsoidRenderLongitudeMinMax; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) - uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid; - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) - uniform vec2 u_ellipsoidUvToShapeUvLongitude; // x = scale, y = offset - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) - uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) - uniform vec2 u_ellipsoidRenderLatitudeCosSqrHalfMinMax; - #endif - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - uniform float u_ellipsoidInverseHeightDifferenceUv; - uniform vec2 u_ellipseInnerRadiiUv; // [0,1] - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) - uniform float u_ellipsoidInverseInnerScaleUv; - #endif -#endif - -#if defined(SHAPE_CYLINDER) - /* Cylinder defines: - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX - #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT - #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT - #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF - #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO - - #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS - #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT - #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT - #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY - #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED - - #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX - #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN - #define CYLINDER_INTERSECTION_INDEX_ANGLE - */ - - // Cylinder uniforms - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) - uniform vec3 u_cylinderUvToRenderBoundsScale; - uniform vec3 u_cylinderUvToRenderBoundsTranslate; - #endif - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - uniform float u_cylinderUvToRenderRadiusMin; - #endif - #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE) - uniform vec2 u_cylinderRenderAngleMinMax; - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) - uniform vec2 u_cylinderUvToShapeUvRadius; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) - uniform vec2 u_cylinderUvToShapeUvHeight; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) - uniform vec2 u_cylinderUvToShapeUvAngle; // x = scale, y = offset - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) - uniform vec2 u_cylinderShapeUvAngleMinMax; - #endif - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - uniform float u_cylinderShapeUvAngleEmptyMid; - #endif -#endif - -// -------------------------------------------------------- -// Misc math -// -------------------------------------------------------- -struct Ray { - vec3 pos; - vec3 dir; -}; - -#if defined(JITTER) -float hash(vec2 p) -{ - vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} -#endif - -float signNoZero(float v) { - return (v < 0.0) ? -1.0 : 1.0; -} -int intMod(int a, int b) { - return a - (b * (a / b)); -} -int intMin(int a, int b) { - return a <= b ? a : b; -} -int intMax(int a, int b) { - return a >= b ? a : b; -} -int intClamp(int v, int minVal, int maxVal) { - return intMin(intMax(v, minVal), maxVal); -} -bool inRange(float v, float minVal, float maxVal) { - return clamp(v, minVal, maxVal) == v; -} -bool inRange(vec3 v, vec3 minVal, vec3 maxVal) { - return clamp(v, minVal, maxVal) == v; -} -int normU8_toInt(float value) { - return int(value * 255.0); -} -int normU8x2_toInt(vec2 value) { - return int(value.x * 255.0) + 256 * int(value.y * 255.0); -} -float normU8x2_toFloat(vec2 value) { - return float(normU8x2_toInt(value)) / 65535.0; -} -vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) -{ - int indexX = intMod(index, dimensions.x); - int indexY = index / dimensions.x; - return vec2(indexX, indexY) * uvScale; -} - -// -------------------------------------------------------- -// Intersection tests, shape coordinate conversions, etc -// -------------------------------------------------------- -#if defined(SHAPE_BOX) -vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - vec3 dInv = 1.0 / d; - vec3 od = -o * dInv; - vec3 t0 = od - dInv; - vec3 t1 = od + dInv; - vec3 m0 = min(t0, t1); - vec3 m1 = max(t0, t1); - float tMin = max(max(m0.x, m0.y), m0.z); - float tMax = min(min(m1.x, m1.y), m1.z); - - if (tMin >= tMax) { - return vec2(NO_HIT); - } - - return vec2(tMin, tMax); -} -#endif - -#if defined(SHAPE_BOX) -vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float t = -o.z / d.z; - vec2 planePos = o.xy + d.xy * t; - if (any(greaterThan(abs(planePos), vec2(1.0)))) { - return vec2(NO_HIT); - } - - return vec2(t, t); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF)) -vec2 intersectZPlane(Ray ray) -{ - float o = ray.pos.z; - float d = ray.dir.z; - float t = -o / d; - float s = sign(o); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO)) -vec4 intersectHalfPlane(Ray ray, float angle) { - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 planeDirection = vec2(cos(angle), sin(angle)); - vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); - - float a = dot(o, planeNormal); - float b = dot(d, planeNormal); - float t = -a / b; - - vec2 p = o + t * d; - bool outside = dot(p, planeDirection) < 0.0; - if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - - return vec4(-INF_HIT, t, t, +INF_HIT); -} -#endif - -#if defined(CLIPPING_PLANES) -// Plane is in Hessian Normal Form -vec2 intersectPlane(Ray ray, vec4 plane) { - vec3 o = ray.pos; - vec3 d = ray.dir; - vec3 n = plane.xyz; // normal - float w = plane.w; // -dot(pointOnPlane, normal) - - float a = dot(o, n); - float b = dot(d, n); - float t = -(w + a) / b; - - if (dot(d, n) > 0.0) { - return vec2(t, +INF_HIT); - } else { - return vec2(-INF_HIT, t); - } -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF))) || (defined(SHAPE_CYLINDER) && (defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF))) -vec2 intersectHalfSpace(Ray ray, float angle) -{ - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 n = vec2(sin(angle), -cos(angle)); - - float a = dot(o, n); - float b = dot(d, n); - float t = -a / b; - float s = sign(a); - - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)) -vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) -{ - vec2 o = ray.pos.xy; - vec2 d = ray.dir.xy; - vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); - vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); - - float a1 = dot(o, n1); - float a2 = dot(o, n2); - float b1 = dot(d, n1); - float b2 = dot(d, n2); - - float t1 = -a1 / b1; - float t2 = -a2 / b2; - float s1 = sign(a1); - float s2 = sign(a2); - - float tmin = min(t1, t2); - float tmax = max(t1, t2); - float smin = tmin == t1 ? s1 : s2; - float smax = tmin == t1 ? s2 : s1; - - bool e = tmin >= 0.0; - bool f = tmax >= 0.0; - bool g = smin >= 0.0; - bool h = smax >= 0.0; - - if (e != g && f == h) return vec2(tmin, tmax); - else if (e == g && f == h) return vec2(-INF_HIT, tmin); - else if (e != g && f != h) return vec2(tmax, +INF_HIT); - else return vec2(NO_HIT); -} -#endif - -#if (defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF)) || (defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)) -vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) -{ - vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); - vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); - return vec4(planeIntersectMin, planeIntersectMax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphere(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = -b - det; - float t2 = -b + det; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d, d); - float b = dot(d, o); - float c = dot(o, o) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE) -vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - float a = d.z * d.z - dot(d, d) * cosSqrHalfAngle; - float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; - float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF)) -vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { - vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); - - if (intersect.x == NO_HIT) { - return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - } - - vec3 o = ray.pos; - vec3 d = ray.dir; - float tmin = intersect.x; - float tmax = intersect.y; - float zmin = o.z + tmin * d.z; - float zmax = o.z + tmax * d.z; - - // One interval - if (zmin < 0.0 && zmax < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - else if (zmin < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); - else if (zmax < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); - // Two intervals - else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); -} -#endif - -#if defined(SHAPE_ELLIPSOID) && (defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF)) -vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { - vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); - - if (intersect.x == NO_HIT) { - return vec2(NO_HIT); - } - - vec3 o = ray.pos; - vec3 d = ray.dir; - float tmin = intersect.x; - float tmax = intersect.y; - float zmin = o.z + tmin * d.z; - float zmax = o.z + tmax * d.z; - - if (zmin < 0.0 && zmax < 0.0) return vec2(NO_HIT); - else if (zmin < 0.0) return vec2(tmax, +INF_HIT); - else if (zmax < 0.0) return vec2(-INF_HIT, tmin); - else return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_CYLINDER) -vec2 intersectUnitCylinder(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d.xy, d.xy); - float b = dot(o.xy, d.xy); - float c = dot(o.xy, o.xy) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float ta = (-b - det) / a; - float tb = (-b + det) / a; - float t1 = min(ta, tb); - float t2 = max(ta, tb); - - float z1 = o.z + t1 * d.z; - float z2 = o.z + t2 * d.z; - - if (abs(z1) >= 1.0) - { - float tCap = (sign(z1) - o.z) / d.z; - t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; - } - - if (abs(z2) >= 1.0) - { - float tCap = (sign(z2) - o.z) / d.z; - t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; - } - - return vec2(t1, t2); -} -#endif - -#if defined(SHAPE_CYLINDER) -vec2 intersectUnitCircle(Ray ray) { - vec3 o = ray.pos; - vec3 d = ray.dir; - - float t = -o.z / d.z; - vec2 zPlanePos = o.xy + d.xy * t; - float distSqr = dot(zPlanePos, zPlanePos); - - if (distSqr > 1.0) { - return vec2(NO_HIT); - } - - return vec2(t, t); -} -#endif - -#if defined(SHAPE_CYLINDER) && defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) -vec2 intersectInfiniteUnitCylinder(Ray ray) -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float a = dot(d.xy, d.xy); - float b = dot(o.xy, d.xy); - float c = dot(o.xy, o.xy) - 1.0; - float det = b * b - a * c; - - if (det < 0.0) { - return vec2(NO_HIT); - } - - det = sqrt(det); - float t1 = (-b - det) / a; - float t2 = (-b + det) / a; - float tmin = min(t1, t2); - float tmax = max(t1, t2); - - return vec2(tmin, tmax); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -// robust iterative solution without trig functions -// https://github.com/0xfaded/ellipse_demo/issues/1 -// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse -// Pro: Good when radii.x ~= radii.y -// Con: Breaks at pos.x ~= 0.0, especially inside the ellipse -// Con: Inaccurate with exterior points and thin ellipses -float ellipseDistanceIterative (vec2 pos, vec2 radii) { - vec2 p = abs(pos); - vec2 invRadii = 1.0 / radii; - vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii; - vec2 t = vec2(0.70710678118); // sqrt(2) / 2 - vec2 v = radii * t; - - const int iterations = 3; - for (int i = 0; i < iterations; ++i) { - vec2 e = a * pow(t, vec2(3.0)); - vec2 q = normalize(p - e) * length(v - e); - t = normalize((q + e) * invRadii); - v = radii * t; - } - return length(v * sign(pos) - pos) * sign(p.y - v.y); -} -#endif - -#if defined(SHAPE_ELLIPSOID) -// From: https://www.shadertoy.com/view/4sS3zz -// Pro: Accurate in most cases -// Con: Breaks if radii.x ~= radii.y -float ellipseDistanceAnalytical(vec2 pos, vec2 radii) { - vec2 p = pos; - vec2 ab = radii; - - p = abs(p); - if (p.x > p.y) { - p = p.yx; - ab = ab.yx; - } - - float l = ab.y * ab.y - ab.x * ab.x; - float m = ab.x * p.x / l; - float n = ab.y * p.y / l; - float m2 = m * m; - float n2 = n * n; - float c = (m2 + n2 - 1.0) / 3.0; - float c3 = c * c * c; - float d = c3 + m2 * n2; - float q = d + m2 * n2; - float g = m + m * n2; - - float co; - - if (d < 0.0) { - float h = acos(q / c3) / 3.0; - float s = cos(h) + 2.0; - float t = sin(h) * sqrt(3.0); - float rx = sqrt(m2 - c * (s + t)); - float ry = sqrt(m2 - c * (s - t)); - co = ry + sign(l) * rx + abs(g) / (rx * ry); - } else { - float h = 2.0 * m * n * sqrt(d); - float s = signNoZero(q + h) * pow(abs(q + h), 1.0 / 3.0); - float t = signNoZero(q - h) * pow(abs(q - h), 1.0 / 3.0); - float rx = -(s + t) - c * 4.0 + 2.0 * m2; - float ry = (s - t) * sqrt(3.0); - float rm = sqrt(rx * rx + ry * ry); - co = ry / sqrt(rm - rx) + 2.0 * g / rm; - } - - co = (co - m) / 2.0; - float si = sqrt(max(1.0 - co * co, 0.0)); - vec2 r = ab * vec2(co, si); - return length(r - p) * signNoZero(p.y - r.y); -} -#endif - -struct Intersections { - // Don't access these member variables directly - call the functions instead. - - #if (INTERSECTION_COUNT > 1) - // Store an array of intersections. Each intersection is composed of: - // x for the T value - // y for the shape type - which encodes positive vs negative and entering vs exiting - // For example: - // y = 0: positive shape entry - // y = 1: positive shape exit - // y = 2: negative shape entry - // y = 3: negative shape exit - vec2 intersections[INTERSECTION_COUNT * 2]; - - // Maintain state for future nextIntersection calls - int index; - int surroundCount; - bool surroundIsPositive; - #else - // When there's only one positive shape intersection none of the extra stuff is needed. - float intersections[2]; - #endif -}; - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x -#else - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) -#else - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) -#else - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y -#endif - -#if (INTERSECTION_COUNT > 1) -void initializeIntersections(inout Intersections ix) { - // Sort the intersections from min T to max T with bubble sort. - // Note: If this sorting function changes, some of the intersection test may - // need to be updated. Search for "bubble sort" to find those areas. - const int sortPasses = INTERSECTION_COUNT * 2 - 1; - for (int n = sortPasses; n > 0; --n) { - for (int i = 0; i < sortPasses; ++i) { - // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to break early instead - if (i >= n) { break; } - - vec2 intersect0 = ix.intersections[i + 0]; - vec2 intersect1 = ix.intersections[i + 1]; - - float t0 = intersect0.x; - float t1 = intersect1.x; - float b0 = intersect0.y; - float b1 = intersect1.y; - - float tmin = min(t0, t1); - float tmax = max(t0, t1); - float bmin = tmin == t0 ? b0 : b1; - float bmax = tmin == t0 ? b1 : b0; - - ix.intersections[i + 0] = vec2(tmin, bmin); - ix.intersections[i + 1] = vec2(tmax, bmax); - } - } - - // Prepare initial state for nextIntersection - ix.index = 0; - ix.surroundCount = 0; - ix.surroundIsPositive = false; -} -#endif - -#if (INTERSECTION_COUNT > 1) -vec2 nextIntersection(inout Intersections ix) { - vec2 entryExitT = vec2(NO_HIT); - - const int passCount = INTERSECTION_COUNT * 2; - for (int i = 0; i < passCount; ++i) { - // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot - // loop with non-constant condition, so it has to continue instead. - if (i < ix.index) { - continue; - } - - vec2 intersect = ix.intersections[i]; - float t = intersect.x; - bool currShapeIsPositive = intersect.y < 2.0; - bool enter = mod(intersect.y, 2.0) == 0.0; - - ix.surroundCount += enter ? +1 : -1; - ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; - - // entering positive or exiting negative - if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { - entryExitT.x = t; - } - - // exiting positive or entering negative after being inside positive - // TODO: Can this be simplified? - bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; - bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; - if (exitPositive || enterNegativeFromPositive) { - entryExitT.y = t; - - // entry and exit have been found, so the loop can stop - if (exitPositive) { - // After exiting positive shape there is nothing left to intersect, so jump to the end index. - ix.index = passCount; - } else { - // There could be more intersections against the positive shape in the future. - ix.index = i + 1; - } - break; - } - } - - return entryExitT; -} -#endif - -#if defined(SHAPE_BOX) -void intersectShape(Ray ray, inout Intersections ix) -{ - #if defined(BOX_HAS_RENDER_BOUND) - #if defined(BOX_IS_2D) - // Transform the ray into unit square space on Z plane - // This matrix bakes in an axis conversion so that the math works for XY plane. - ray.pos = vec3(u_boxTransformUvToRenderBounds * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxTransformUvToRenderBounds * vec4(ray.dir, 0.0)); - vec2 entryExit = intersectUnitSquare(ray); - #else - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToRenderBounds + u_boxOffsetUvToRenderBounds; - ray.dir *= u_boxScaleUvToRenderBounds; - vec2 entryExit = intersectUnitCube(ray); - #endif - #else - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir = ray.dir * 2.0; - vec2 entryExit = intersectUnitCube(ray); - #endif - - setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); -} -#endif - -#if defined(SHAPE_BOX) -vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - #if defined(BOX_HAS_SHAPE_BOUND) - return positionUv * u_boxScaleUvToShapeBoundsUv + u_boxOffsetUvToShapeBoundsUv; - #else - return positionUv; - #endif -} -#endif - -#if defined(SHAPE_ELLIPSOID) -void intersectShape(in Ray ray, inout Intersections ix) { - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; - - // Outer ellipsoid - vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); - - // Exit early if the outer ellipsoid was missed. - if (outerIntersect.x == NO_HIT) { - return; - } - - // Inner ellipsoid - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - // When the ellipsoid is perfectly thin it's necessary to sandwich the - // inner ellipsoid intersection inside the outer ellipsoid intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the ellipsoid to be invisible because it will think the ray - // is still inside the inner (negative) ellipsoid after exiting the - // outer (positive) ellipsoid. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) - Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); - vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); - #endif - - // Flip the ray because the intersection function expects a cone growing towards +Z. - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) - Ray flippedRay = ray; - flippedRay.dir.z *= -1.0; - flippedRay.pos.z *= -1.0; - #endif - - // Bottom cone - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) - vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) - vec2 bottomConeIntersection = intersectZPlane(flippedRay); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) - vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); - #endif - - // Top cone - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) - vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersection.zw); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF) - vec2 topConeIntersection = intersectZPlane(ray); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) - vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); - #endif - - // Wedge - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) - vec4 wedgeIntersect = intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF) - vec2 wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF) - vec2 wedgeIntersect = intersectHalfSpace(ray, u_ellipsoidRenderLongitudeMinMax.x); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); - #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) - vec4 wedgeIntersect = intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); - #endif -} -#endif - -#if defined(SHAPE_ELLIPSOID) -vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - // Compute position and normal. - // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). - // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. - vec3 positionLocal = positionUv * 2.0 - 1.0; - #if defined(ELLIPSOID_IS_SPHERE) - vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x; - vec3 normal = normalize(posEllipsoid); - #else - vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; - vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal - #endif - - // Compute longitude - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) - float longitude = 1.0; - #else - float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; - - // Correct the angle when max < min - // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) - longitude += float(longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z); - #endif - - // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) - longitude = longitude > u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.x : longitude; - #endif - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) - longitude = longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.y : longitude; - #endif - - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) - longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y; - #endif - #endif - - // Compute latitude - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) - float latitude = 1.0; - #else - float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) - latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y; - #endif - #endif - - // Compute height - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) - // TODO: This breaks down when minBounds == maxBounds. To fix it, this - // function would have to know if ray is intersecting the front or back of the shape - // and set the shape space position to 1 (front) or 0 (back) accordingly. - float height = 1.0; - #else - #if defined(ELLIPSOID_IS_SPHERE) - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) - float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; - #else - float height = length(posEllipsoid); - #endif - #else - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) - // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). - // This is an optimization so that math can be done with ellipses instead of ellipsoids. - vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); - float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; - #else - // TODO: this is probably not correct - float height = length(posEllipsoid); - #endif - #endif - #endif - - return vec3(longitude, latitude, height); -} -#endif - -#if defined(SHAPE_CYLINDER) -void intersectShape(Ray ray, inout Intersections ix) -{ - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) - ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate; - ray.dir *= u_cylinderUvToRenderBoundsScale; - #else - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir *= 2.0; - #endif - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) - vec2 outerIntersect = intersectUnitCircle(ray); - #else - vec2 outerIntersect = intersectUnitCylinder(ray); - #endif - - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect); - - if (outerIntersect.x == NO_HIT) { - return; - } - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - // When the cylinder is perfectly thin it's necessary to sandwich the - // inner cylinder intersection inside the outer cylinder intersection. - - // Without this special case, - // [outerMin, outerMax, innerMin, innerMax] will bubble sort to - // [outerMin, innerMin, outerMax, innerMax] which will cause the back - // side of the cylinder to be invisible because it will think the ray - // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. - - // With this special case, - // [outerMin, innerMin, innerMax, outerMax] will bubble sort to - // [outerMin, innerMin, innerMax, outerMax] which will work correctly. - - // Note: If initializeIntersections() changes its sorting function - // from bubble sort to something else, this code may need to change. - vec2 innerIntersect = intersectInfiniteUnitCylinder(ray); - setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter - setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter - setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit - setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) - Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin); - vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect); - #endif - - #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF) - vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF) - vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) - vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) - vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); - setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); - #endif -} -#endif - -#if defined(SHAPE_CYLINDER) -vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] - - // Compute radius - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) - float radius = length(positionLocal.xy); // [0,1] - #else - float radius = length(positionLocal.xy); // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) - radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset - #endif - #endif - - // Compute height - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) - float height = positionUv.z; // [0,1] - #else - float height = positionUv.z; // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) - height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset - #endif - #endif - - // Compute angle - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) - float angle = 1.0; - #else - float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. - angle += float(angle < u_cylinderShapeUvAngleEmptyMid); - #endif - - // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) - angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; - #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) - angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; - #endif - - angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset - #endif - #endif - - return vec3(radius, height, angle); -} -#endif - -#if defined(CLIPPING_PLANES) -void intersectClippingPlanes(Ray ray, inout Intersections ix) { - #if (CLIPPING_PLANES_COUNT == 1) - // Union and intersection are the same when there's one clipping plane, and the code - // is more simplified. - vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, intersection); - #elif defined(CLIPPING_PLANES_UNION) - float minPositiveT = +INF_HIT; - float maxNegativeT = -INF_HIT; - for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { - vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - if (intersection.y == +INF_HIT) { - minPositiveT = min(minPositiveT, intersection.x); - } else { - maxNegativeT = max(maxNegativeT, intersection.y); - } - } - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, vec2(minPositiveT, +INF_HIT)); - #else // intersection - float maxPositiveT = -INF_HIT; - float minNegativeT = +INF_HIT; - for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { - vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - if (intersection.y == +INF_HIT) { - maxPositiveT = max(maxPositiveT, intersection.x); - } else { - minNegativeT = min(minNegativeT, intersection.y); - } - } - if (maxPositiveT < minNegativeT) { - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(maxPositiveT, minNegativeT)); - } else { - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(NO_HIT)); - } - #endif -} -#endif - -#if defined(DEPTH_TEST) -void intersectDepth(vec2 screenCoord, Ray ray, inout Intersections ix) { - float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); - if (logDepthOrDepth != 0.0) { - // Calculate how far the ray must travel before it hits the depth buffer. - vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); - eyeCoordinateDepth /= eyeCoordinateDepth.w; - vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); - float t = dot(depthPositionUv - ray.pos, ray.dir); - setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(t, +INF_HIT)); - } else { - // There's no depth at this location. - setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(NO_HIT)); - } -} -#endif - -vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { - Ray ray = Ray(positionUv, directionUv); - - // Do a ray-shape intersection to find the exact starting and ending points. - intersectShape(ray, ix); - - // Exit early if the positive shape was completely missed or behind the ray. - vec2 entryExitT = getIntersectionPair(ix, 0); - if (entryExitT.x == NO_HIT) { - // Positive shape was completely missed - so exit early. - return vec2(NO_HIT); - } - - // Clipping planes - #if defined(CLIPPING_PLANES) - intersectClippingPlanes(ray, ix); - #endif - - // Depth - #if defined(DEPTH_TEST) - intersectDepth(screenCoord, ray, ix); - #endif - - // Find the first intersection that's in front of the ray - #if (INTERSECTION_COUNT > 1) - initializeIntersections(ix); - for (int i = 0; i < INTERSECTION_COUNT; ++i) { - entryExitT = nextIntersection(ix); - if (entryExitT.y > 0.0) { - // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); - break; - } - } - #else - // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); - #endif - - return entryExitT; -} - -// -------------------------------------------------------- -// Megatexture -// -------------------------------------------------------- -/* - How is 3D data stored in a 2D megatexture? - - In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total). - The data is sliced by Z. The data at Z = 0 is placed in texels (0,0), (0,1), (1,0), (1,1) and - the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1). - Note that there could be empty space in the megatexture because it's a power of two. - - 0 1 2 3 - +---+---+---+---+ - | | | | | 3 - +---+---+---+---+ - | | | | | 2 - +-------+-------+ - |010|110|011|111| 1 - |--- ---|--- ---| - |000|100|001|101| 0 - +-------+-------+ - - When doing linear interpolation the megatexture needs to be sampled twice: once for - the Z slice above the voxel coordinate and once for the slice below. The two slices - are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is - halfway between two Z slices so the interpolation factor is 0.5. Below is a side view - of the 3D voxel grid with voxel coordinates on the left side. - - 2 +---+ - |001| - 1 +-z-+ - |000| - 0 +---+ - - When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice. -*/ - -Properties getPropertiesFromMegatexture(in SampleData sampleData) { - vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? - int tileIndex = sampleData.megatextureIndex; - vec3 voxelCoord = tileUv * vec3(u_dimensions); - ivec3 voxelDimensions = u_dimensions; - - #if defined(PADDING) - voxelDimensions += u_paddingBefore + u_paddingAfter; - voxelCoord += vec3(u_paddingBefore); - #endif - - #if defined(NEAREST_SAMPLING) - // Round to the center of the nearest voxel - voxelCoord = floor(voxelCoord) + vec3(0.5); - #endif - - // Tile location - vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); - - // Slice location - float slice = voxelCoord.z - 0.5; - int sliceIndex = int(floor(slice)); - int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1); - vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - - // Voxel location - vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; - - // Final location in the megatexture - vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; - - #if defined(NEAREST_SAMPLING) - return getPropertiesFromMegatextureAtUv(uv0); - #else - float sliceLerp = fract(slice); - int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1); - vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); - vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; - Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); - Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); - return mixProperties(properties0, properties1, sliceLerp); - #endif -} - -// Convert an array of sample datas to a final weighted properties. -Properties accumulatePropertiesFromMegatexture(SampleData sampleDatas[SAMPLE_COUNT]) { - #if (SAMPLE_COUNT == 1) - return getPropertiesFromMegatexture(sampleDatas[0]); - #else - // When more than one sample is taken the accumulator needs to start at 0 - Properties properties = clearProperties(); - for (int i = 0; i < SAMPLE_COUNT; ++i) { - float weight = sampleDatas[i].weight; - - // Avoid reading the megatexture when the weight is 0 as it can be costly. - if (weight > 0.0) { - Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); - tempProperties = scaleProperties(tempProperties, weight); - properties = sumProperties(properties, tempProperties); - } - } - return properties; - #endif -} - -// -------------------------------------------------------- -// Tree traversal -// -------------------------------------------------------- - -OctreeNodeData getOctreeRootData() { - vec4 rootData = texture2D(u_octreeInternalNodeTexture, vec2(0.0)); - - OctreeNodeData data; - data.data = normU8x2_toInt(rootData.xy); - data.flag = normU8x2_toInt(rootData.zw); - return data; -} - -OctreeNodeData getOctreeChildData(int parentOctreeIndex, ivec3 childCoord) { - int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x; - int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex; - int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow; - vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); - vec4 childData = texture2D(u_octreeInternalNodeTexture, octreeUv); - - OctreeNodeData data; - data.data = normU8x2_toInt(childData.xy); - data.flag = normU8x2_toInt(childData.zw); - return data; -} - -int getOctreeParentIndex(int octreeIndex) { - int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9; - int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow; - vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); - vec4 parentData = texture2D(u_octreeInternalNodeTexture, octreeUv); - int parentOctreeIndex = normU8x2_toInt(parentData.xy); - return parentOctreeIndex; -} - -void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { - #if (SAMPLE_COUNT == 1) - sampleDatas[0].megatextureIndex = data.data; - sampleDatas[0].usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; - #else - int leafIndex = data.data; - int leafNodeTexelCount = 2; - // Adding 0.5 moves to the center of the texel - float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; - float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; - - vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); - vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); - vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); - vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); - - float lerp = normU8x2_toFloat(leafData0.xy); - - sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); - sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); - sampleDatas[0].usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; - sampleDatas[1].usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; - sampleDatas[0].weight = 1.0 - lerp; - sampleDatas[1].weight = lerp; - #endif -} - -void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { - float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); - vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; - vec3 end = start + vec3(sizeAtLevel); - - for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { - // Find out which octree child contains the position - // 0 if before center, 1 if after - vec3 center = 0.5 * (start + end); - vec3 childCoord = step(center, traversalData.positionUvShapeSpace); - - OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); - - // Get octree coords for the next level down - ivec4 parentOctreeCoords = traversalData.octreeCoords; - traversalData.octreeCoords = ivec4(parentOctreeCoords.xyz * 2 + ivec3(childCoord), parentOctreeCoords.w + 1); - - if (childData.flag == OCTREE_FLAG_INTERNAL) { - // interior tile - keep going deeper - start = mix(start, center, childCoord); - end = mix(center, end, childCoord); - traversalData.parentOctreeIndex = childData.data; - } else { - // leaf tile - stop traversing - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); - traversalData.stepT = u_stepSize / dimAtLevel; - - getOctreeLeafSampleData(childData, sampleDatas); - for (int i = 0; i < SAMPLE_COUNT; i++) { - if (sampleDatas[i].usingParentMegatextureIndex) { - float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); - sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); - } else { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } - } - return; - } - } -} - -void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { - traversalData.octreeCoords = ivec4(0); - traversalData.parentOctreeIndex = 0; - - // TODO: is it possible for this to be out of bounds, and does it matter? - traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace; - - OctreeNodeData rootData = getOctreeRootData(); - if (rootData.flag == OCTREE_FLAG_LEAF) { - // No child data, only the root tile has data - getOctreeLeafSampleData(rootData, sampleDatas); - traversalData.stepT = u_stepSize; - for (int i = 0; i < SAMPLE_COUNT; i++) { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } - } - else - { - traverseOctreeDownwards(traversalData, sampleDatas); - } -} - -void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); - - // Note: This code assumes the position is always inside the root tile. - bool insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); - - if (insideTile) { - for (int i = 0; i < SAMPLE_COUNT; i++) { - if (sampleDatas[i].usingParentMegatextureIndex) { - ivec4 parentOctreeCoords; - parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); - parentOctreeCoords.w = traversalData.octreeCoords.w - 1; - float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); - sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); - } else { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } - } - } else { - // Go up tree - for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) - { - traversalData.octreeCoords.xyz /= ivec3(2); - traversalData.octreeCoords.w -= 1; - dimAtLevel *= 0.5; - - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); - insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); - - if (!insideTile) { - traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); - } else { - break; - } - } - - // Go down tree - traverseOctreeDownwards(traversalData, sampleDatas); - } -} - -void main() -{ - vec4 fragCoord = gl_FragCoord; - vec2 screenCoord = (fragCoord.xy - czm_viewport.xy) / czm_viewport.zw; // [0,1] - vec3 eyeDirection = normalize(czm_windowToEyeCoordinates(fragCoord).xyz); - vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case - vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case - vec3 viewPosUv = u_cameraPositionUv; - - Intersections ix; - vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); - - // Exit early if the scene was completely missed. - if (entryExitT.x == NO_HIT) { - discard; - } - - float currT = entryExitT.x; - float endT = entryExitT.y; - vec3 positionUv = viewPosUv + currT * viewDirUv; - - // Traverse the tree from the start position - TraversalData traversalData; - SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctreeFromBeginning(positionUv, traversalData, sampleDatas); - - #if defined(JITTER) - float noise = hash(screenCoord); // [0,1] - currT += noise * traversalData.stepT; - positionUv += noise * traversalData.stepT * viewDirUv; - #endif - - FragmentInput fragmentInput; - #if defined(STATISTICS) - setStatistics(fragmentInput.metadata.statistics); - #endif - - vec4 colorAccum = vec4(0.0); - - for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { - // Read properties from the megatexture based on the traversal state - Properties properties = accumulatePropertiesFromMegatexture(sampleDatas); - - // Prepare the custom shader inputs - copyPropertiesToMetadata(properties, fragmentInput.metadata); - fragmentInput.voxel.positionUv = positionUv; - fragmentInput.voxel.positionShapeUv = traversalData.positionUvShapeSpace; - fragmentInput.voxel.positionUvLocal = traversalData.positionUvLocal; - fragmentInput.voxel.viewDirUv = viewDirUv; - fragmentInput.voxel.viewDirWorld = viewDirWorld; - fragmentInput.voxel.travelDistance = traversalData.stepT; - - // Run the custom shader - czm_modelMaterial materialOutput; - fragmentMain(fragmentInput, materialOutput); - - // Sanitize the custom shader output - vec4 color = vec4(materialOutput.diffuse, materialOutput.alpha); - color.rgb = max(color.rgb, vec3(0.0)); - color.a = clamp(color.a, 0.0, 1.0); - - // Pre-multiplied alpha blend - colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a); - - // Stop traversing if the alpha has been fully saturated - if (colorAccum.a > ALPHA_ACCUM_MAX) { - colorAccum.a = ALPHA_ACCUM_MAX; - break; - } - - // Keep raymarching - currT += traversalData.stepT; - positionUv += traversalData.stepT * viewDirUv; - - // Check if there's more intersections. - if (currT > endT) { - #if (INTERSECTION_COUNT == 1) - break; - #else - vec2 entryExitT = nextIntersection(ix); - if (entryExitT.x == NO_HIT) { - break; - } else { - // Found another intersection. Keep raymarching. - currT += entryExitT.x; - endT += entryExitT.y; - positionUv += entryExitT.x * viewDirUv; - } - #endif - } - - // Traverse the tree from the current ray position. - // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. - traverseOctreeFromExisting(positionUv, traversalData, sampleDatas); - } - - // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] - colorAccum.a /= ALPHA_ACCUM_MAX; - - #if defined(PICKING) - // If alpha is 0.0 there is nothing to pick - if (colorAccum.a == 0.0) { - discard; - } - gl_FragColor = u_pickColor; - #else - gl_FragColor = colorAccum; - #endif -} diff --git a/Source/Shaders/Voxels/IntersectBox.glsl b/Source/Shaders/Voxels/IntersectBox.glsl new file mode 100644 index 00000000000..4ad129993c9 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectBox.glsl @@ -0,0 +1,80 @@ +// import { Ray, NO_HIT } from "./IntersectionUtils.glsl"; + +/* Box defines: +#define BOX_INTERSECTION_INDEX ### // always 0 +#define BOX_HAS_RENDER_BOUND +#define BOX_IS_2D +*/ + +// Box uniforms: +#if defined(BOX_HAS_RENDER_BOUND) + #if defined(BOX_IS_2D) + // This matrix bakes in an axis conversion so that the math works for XY plane. + uniform mat4 u_boxTransformUvToRenderBounds; + #else + // Similar to u_boxTransformUvToBounds but fewer instructions needed. + uniform vec3 u_boxScaleUvToRenderBounds; + uniform vec3 u_boxOffsetUvToRenderBounds; + #endif +#endif + +vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + vec3 dInv = 1.0 / d; + vec3 od = -o * dInv; + vec3 t0 = od - dInv; + vec3 t1 = od + dInv; + vec3 m0 = min(t0, t1); + vec3 m1 = max(t0, t1); + float tMin = max(max(m0.x, m0.y), m0.z); + float tMax = min(min(m1.x, m1.y), m1.z); + + if (tMin >= tMax) { + return vec2(NO_HIT); + } + + return vec2(tMin, tMax); +} + +vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float t = -o.z / d.z; + vec2 planePos = o.xy + d.xy * t; + if (any(greaterThan(abs(planePos), vec2(1.0)))) { + return vec2(NO_HIT); + } + + return vec2(t, t); +} + +void intersectShape(Ray ray, inout Intersections ix) +{ + #if defined(BOX_HAS_RENDER_BOUND) + #if defined(BOX_IS_2D) + // Transform the ray into unit square space on Z plane + // This matrix bakes in an axis conversion so that the math works for XY plane. + ray.pos = vec3(u_boxTransformUvToRenderBounds * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxTransformUvToRenderBounds * vec4(ray.dir, 0.0)); + vec2 entryExit = intersectUnitSquare(ray); + #else + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxScaleUvToRenderBounds + u_boxOffsetUvToRenderBounds; + ray.dir *= u_boxScaleUvToRenderBounds; + vec2 entryExit = intersectUnitCube(ray); + #endif + #else + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir = ray.dir * 2.0; + vec2 entryExit = intersectUnitCube(ray); + #endif + + setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); +} diff --git a/Source/Shaders/Voxels/IntersectClippingPlanes.glsl b/Source/Shaders/Voxels/IntersectClippingPlanes.glsl new file mode 100644 index 00000000000..2e7d06ecd13 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectClippingPlanes.glsl @@ -0,0 +1,71 @@ +// import { Ray, Intersections, INF_HIT, NO_HIT, setIntersectionPair } from "./IntersectionUtils.glsl"; + +/* Clipping plane defines +#define CLIPPING_PLANES_UNION +#define CLIPPING_PLANES_COUNT +#define CLIPPING_PLANES_INTERSECTION_INDEX +*/ + +uniform sampler2D u_clippingPlanesTexture; +uniform mat4 u_clippingPlanesMatrix; + +// Plane is in Hessian Normal Form +vec2 intersectPlane(Ray ray, vec4 plane) { + vec3 o = ray.pos; + vec3 d = ray.dir; + vec3 n = plane.xyz; // normal + float w = plane.w; // -dot(pointOnPlane, normal) + + float a = dot(o, n); + float b = dot(d, n); + float t = -(w + a) / b; + + if (dot(d, n) > 0.0) { + return vec2(t, +INF_HIT); + } else { + return vec2(-INF_HIT, t); + } +} + +void intersectClippingPlanes(Ray ray, inout Intersections ix) { + #if (CLIPPING_PLANES_COUNT == 1) + // Union and intersection are the same when there's one clipping plane, and the code + // is more simplified. + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, intersection); + #elif defined(CLIPPING_PLANES_UNION) + float minPositiveT = +INF_HIT; + float maxNegativeT = -INF_HIT; + for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + if (intersection.y == +INF_HIT) { + minPositiveT = min(minPositiveT, intersection.x); + } else { + maxNegativeT = max(maxNegativeT, intersection.y); + } + } + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, vec2(minPositiveT, +INF_HIT)); + #else // intersection + float maxPositiveT = -INF_HIT; + float minNegativeT = +INF_HIT; + for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { + vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); + vec2 intersection = intersectPlane(ray, planeUv); + if (intersection.y == +INF_HIT) { + maxPositiveT = max(maxPositiveT, intersection.x); + } else { + minNegativeT = min(minNegativeT, intersection.y); + } + } + if (maxPositiveT < minNegativeT) { + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(maxPositiveT, minNegativeT)); + } else { + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(NO_HIT)); + } + #endif +} + +// export { intersectClippingPlanes }; \ No newline at end of file diff --git a/Source/Shaders/Voxels/IntersectCylinder.glsl b/Source/Shaders/Voxels/IntersectCylinder.glsl new file mode 100644 index 00000000000..bcb70498ef1 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectCylinder.glsl @@ -0,0 +1,259 @@ +// import { Ray, setIntersection, setIntersectionPair } from "./IntersectionUtils.glsl"; + +/* Cylinder defines: +#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN +#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX +#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT +#define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT +#define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO + +#define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS +#define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT +#define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT +#define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED + +#define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX +#define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN +#define CYLINDER_INTERSECTION_INDEX_ANGLE +*/ + +// Cylinder uniforms +#if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + uniform vec3 u_cylinderUvToRenderBoundsScale; + uniform vec3 u_cylinderUvToRenderBoundsTranslate; +#endif +#if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + uniform float u_cylinderUvToRenderRadiusMin; +#endif +#if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE) + uniform vec2 u_cylinderRenderAngleMinMax; +#endif + +vec4 intersectHalfPlane(Ray ray, float angle) { + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 planeDirection = vec2(cos(angle), sin(angle)); + vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); + + float a = dot(o, planeNormal); + float b = dot(d, planeNormal); + float t = -a / b; + + vec2 p = o + t * d; + bool outside = dot(p, planeDirection) < 0.0; + if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + + return vec4(-INF_HIT, t, t, +INF_HIT); +} + +vec2 intersectHalfSpace(Ray ray, float angle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n = vec2(sin(angle), -cos(angle)); + + float a = dot(o, n); + float b = dot(d, n); + float t = -a / b; + float s = sign(a); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} + +vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); + vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); + + float a1 = dot(o, n1); + float a2 = dot(o, n2); + float b1 = dot(d, n1); + float b2 = dot(d, n2); + + float t1 = -a1 / b1; + float t2 = -a2 / b2; + float s1 = sign(a1); + float s2 = sign(a2); + + float tmin = min(t1, t2); + float tmax = max(t1, t2); + float smin = tmin == t1 ? s1 : s2; + float smax = tmin == t1 ? s2 : s1; + + bool e = tmin >= 0.0; + bool f = tmax >= 0.0; + bool g = smin >= 0.0; + bool h = smax >= 0.0; + + if (e != g && f == h) return vec2(tmin, tmax); + else if (e == g && f == h) return vec2(-INF_HIT, tmin); + else if (e != g && f != h) return vec2(tmax, +INF_HIT); + else return vec2(NO_HIT); +} + +vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); + vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); + return vec4(planeIntersectMin, planeIntersectMax); +} + +vec2 intersectUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float ta = (-b - det) / a; + float tb = (-b + det) / a; + float t1 = min(ta, tb); + float t2 = max(ta, tb); + + float z1 = o.z + t1 * d.z; + float z2 = o.z + t2 * d.z; + + if (abs(z1) >= 1.0) + { + float tCap = (sign(z1) - o.z) / d.z; + t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; + } + + if (abs(z2) >= 1.0) + { + float tCap = (sign(z2) - o.z) / d.z; + t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; + } + + return vec2(t1, t2); +} + +vec2 intersectUnitCircle(Ray ray) { + vec3 o = ray.pos; + vec3 d = ray.dir; + + float t = -o.z / d.z; + vec2 zPlanePos = o.xy + d.xy * t; + float distSqr = dot(zPlanePos, zPlanePos); + + if (distSqr > 1.0) { + return vec2(NO_HIT); + } + + return vec2(t, t); +} + +vec2 intersectInfiniteUnitCylinder(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d.xy, d.xy); + float b = dot(o.xy, d.xy); + float c = dot(o.xy, o.xy) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} + +void intersectShape(Ray ray, inout Intersections ix) +{ + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT) + ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate; + ray.dir *= u_cylinderUvToRenderBoundsScale; + #else + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + #endif + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) + vec2 outerIntersect = intersectUnitCircle(ray); + #else + vec2 outerIntersect = intersectUnitCylinder(ray); + #endif + + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect); + + if (outerIntersect.x == NO_HIT) { + return; + } + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + // When the cylinder is perfectly thin it's necessary to sandwich the + // inner cylinder intersection inside the outer cylinder intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the cylinder to be invisible because it will think the ray + // is still inside the inner (negative) cylinder after exiting the + // outer (positive) cylinder. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + vec2 innerIntersect = intersectInfiniteUnitCylinder(ray); + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) + Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin); + vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect); + #endif + + #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); + #endif +} + +// export { intersectShape }; \ No newline at end of file diff --git a/Source/Shaders/Voxels/IntersectDepth.glsl b/Source/Shaders/Voxels/IntersectDepth.glsl new file mode 100644 index 00000000000..29160abdaf9 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectDepth.glsl @@ -0,0 +1,24 @@ +// import { Ray, Intersections, setIntersectionPair, INF_HIT, NO_HIT } from "./IntersectionUtils.glsl"; + +/* intersectDepth defines +#define DEPTH_INTERSECTION_INDEX ### +*/ + +uniform mat4 u_transformPositionViewToUv; + +void intersectDepth(vec2 screenCoord, Ray ray, inout Intersections ix) { + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, screenCoord)); + if (logDepthOrDepth != 0.0) { + // Calculate how far the ray must travel before it hits the depth buffer. + vec4 eyeCoordinateDepth = czm_screenToEyeCoordinates(screenCoord, logDepthOrDepth); + eyeCoordinateDepth /= eyeCoordinateDepth.w; + vec3 depthPositionUv = vec3(u_transformPositionViewToUv * eyeCoordinateDepth); + float t = dot(depthPositionUv - ray.pos, ray.dir); + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(t, +INF_HIT)); + } else { + // There's no depth at this location. + setIntersectionPair(ix, DEPTH_INTERSECTION_INDEX, vec2(NO_HIT)); + } +} + +// export { intersectDepth }; diff --git a/Source/Shaders/Voxels/IntersectEllipsoid.glsl b/Source/Shaders/Voxels/IntersectEllipsoid.glsl new file mode 100644 index 00000000000..efadd1d3871 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectEllipsoid.glsl @@ -0,0 +1,320 @@ +// import { Ray, Intersections, setIntersection, setIntersectionPair, INF_HIT, NO_HIT } from "./IntersectionUtils.glsl"; + +/* Ellipsoid defines: +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF +#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN +#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE +#define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX +#define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN +#define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX +#define ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN +*/ + +#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidRenderLongitudeMinMax; +#endif +#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + uniform vec2 u_ellipsoidRenderLatitudeCosSqrHalfMinMax; +#endif +#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) + uniform float u_ellipsoidInverseInnerScaleUv; +#endif + +vec2 intersectZPlane(Ray ray) +{ + float o = ray.pos.z; + float d = ray.dir.z; + float t = -o / d; + float s = sign(o); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} + +vec4 intersectHalfPlane(Ray ray, float angle) { + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 planeDirection = vec2(cos(angle), sin(angle)); + vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x); + + float a = dot(o, planeNormal); + float b = dot(d, planeNormal); + float t = -a / b; + + vec2 p = o + t * d; + bool outside = dot(p, planeDirection) < 0.0; + if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + + return vec4(-INF_HIT, t, t, +INF_HIT); +} + +vec2 intersectHalfSpace(Ray ray, float angle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n = vec2(sin(angle), -cos(angle)); + + float a = dot(o, n); + float b = dot(d, n); + float t = -a / b; + float s = sign(a); + + if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); + else return vec2(-INF_HIT, t); +} + +vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 o = ray.pos.xy; + vec2 d = ray.dir.xy; + vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); + vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); + + float a1 = dot(o, n1); + float a2 = dot(o, n2); + float b1 = dot(d, n1); + float b2 = dot(d, n2); + + float t1 = -a1 / b1; + float t2 = -a2 / b2; + float s1 = sign(a1); + float s2 = sign(a2); + + float tmin = min(t1, t2); + float tmax = max(t1, t2); + float smin = tmin == t1 ? s1 : s2; + float smax = tmin == t1 ? s2 : s1; + + bool e = tmin >= 0.0; + bool f = tmax >= 0.0; + bool g = smin >= 0.0; + bool h = smax >= 0.0; + + if (e != g && f == h) return vec2(tmin, tmax); + else if (e == g && f == h) return vec2(-INF_HIT, tmin); + else if (e != g && f != h) return vec2(tmax, +INF_HIT); + else return vec2(NO_HIT); +} + +vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) +{ + vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); + vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); + return vec4(planeIntersectMin, planeIntersectMax); +} + +vec2 intersectUnitSphere(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = -b - det; + float t2 = -b + det; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} + +vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + + float a = dot(d, d); + float b = dot(d, o); + float c = dot(o, o) - 1.0; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + + return vec2(tmin, tmax); +} + +vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) +{ + vec3 o = ray.pos; + vec3 d = ray.dir; + float a = d.z * d.z - dot(d, d) * cosSqrHalfAngle; + float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; + float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; + float det = b * b - a * c; + + if (det < 0.0) { + return vec2(NO_HIT); + } + + det = sqrt(det); + float t1 = (-b - det) / a; + float t2 = (-b + det) / a; + float tmin = min(t1, t2); + float tmax = max(t1, t2); + return vec2(tmin, tmax); +} + +vec4 intersectFlippedCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); + + if (intersect.x == NO_HIT) { + return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + } + + vec3 o = ray.pos; + vec3 d = ray.dir; + float tmin = intersect.x; + float tmax = intersect.y; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; + + // One interval + if (zmin < 0.0 && zmax < 0.0) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); + else if (zmin < 0.0) return vec4(-INF_HIT, tmax, NO_HIT, NO_HIT); + else if (zmax < 0.0) return vec4(tmin, +INF_HIT, NO_HIT, NO_HIT); + // Two intervals + else return vec4(-INF_HIT, tmin, tmax, +INF_HIT); +} + +vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { + vec2 intersect = intersectDoubleEndedCone(ray, cosSqrHalfAngle); + + if (intersect.x == NO_HIT) { + return vec2(NO_HIT); + } + + vec3 o = ray.pos; + vec3 d = ray.dir; + float tmin = intersect.x; + float tmax = intersect.y; + float zmin = o.z + tmin * d.z; + float zmax = o.z + tmax * d.z; + + if (zmin < 0.0 && zmax < 0.0) return vec2(NO_HIT); + else if (zmin < 0.0) return vec2(tmax, +INF_HIT); + else if (zmax < 0.0) return vec2(-INF_HIT, tmin); + else return vec2(tmin, tmax); +} + +void intersectShape(in Ray ray, inout Intersections ix) { + // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. + // Direction is scaled as well to be in sync with position. + ray.pos = ray.pos * 2.0 - 1.0; + ray.dir *= 2.0; + + // Outer ellipsoid + vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); + + // Exit early if the outer ellipsoid was missed. + if (outerIntersect.x == NO_HIT) { + return; + } + + // Inner ellipsoid + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + // When the ellipsoid is perfectly thin it's necessary to sandwich the + // inner ellipsoid intersection inside the outer ellipsoid intersection. + + // Without this special case, + // [outerMin, outerMax, innerMin, innerMax] will bubble sort to + // [outerMin, innerMin, outerMax, innerMax] which will cause the back + // side of the ellipsoid to be invisible because it will think the ray + // is still inside the inner (negative) ellipsoid after exiting the + // outer (positive) ellipsoid. + + // With this special case, + // [outerMin, innerMin, innerMax, outerMax] will bubble sort to + // [outerMin, innerMin, innerMax, outerMax] which will work correctly. + + // Note: If initializeIntersections() changes its sorting function + // from bubble sort to something else, this code may need to change. + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, outerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, outerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) + Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); + vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); + #endif + + // Flip the ray because the intersection function expects a cone growing towards +Z. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) + Ray flippedRay = ray; + flippedRay.dir.z *= -1.0; + flippedRay.pos.z *= -1.0; + #endif + + // Bottom cone + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) + vec2 bottomConeIntersection = intersectRegularCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) + vec2 bottomConeIntersection = intersectZPlane(flippedRay); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN, bottomConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF) + vec4 bottomConeIntersection = intersectFlippedCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 0, bottomConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); + #endif + + // Top cone + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) + vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 1, topConeIntersection.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF) + vec2 topConeIntersection = intersectZPlane(ray); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF) + vec2 topConeIntersection = intersectRegularCone(ray, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX, topConeIntersection); + #endif + + // Wedge + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + vec4 wedgeIntersect = intersectHalfPlane(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF) + vec2 wedgeIntersect = intersectRegularWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF) + vec2 wedgeIntersect = intersectHalfSpace(ray, u_ellipsoidRenderLongitudeMinMax.x); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE, wedgeIntersect); + #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF) + vec4 wedgeIntersect = intersectFlippedWedge(ray, u_ellipsoidRenderLongitudeMinMax.x, u_ellipsoidRenderLongitudeMinMax.y); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 0, wedgeIntersect.xy); + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE + 1, wedgeIntersect.zw); + #endif +} + +// export { intersectShape }; diff --git a/Source/Shaders/Voxels/Intersection.glsl b/Source/Shaders/Voxels/Intersection.glsl new file mode 100644 index 00000000000..4b6d482c17b --- /dev/null +++ b/Source/Shaders/Voxels/Intersection.glsl @@ -0,0 +1,52 @@ +// import { Ray, NO_HIT, getIntersectionPair, initializeIntersections, nextIntersection } from "./IntersectionUtils.glsl"; +// import { intersectShape } from ("./IntersectBox.glsl", "./IntersectCylinder.glsl", "IntersectEllipsoid.glsl"); +// import { intersectClippingPlanes } from "./IntersectClippingPlane.glsl"; +// import { intersectDepth } from "./IntersectDepth.glsl"; + +/* Intersection defines +#define INTERSECTION_COUNT ### +*/ + +vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { + Ray ray = Ray(positionUv, directionUv); + + // Do a ray-shape intersection to find the exact starting and ending points. + intersectShape(ray, ix); + + // Exit early if the positive shape was completely missed or behind the ray. + vec2 entryExitT = getIntersectionPair(ix, 0); + if (entryExitT.x == NO_HIT) { + // Positive shape was completely missed - so exit early. + return vec2(NO_HIT); + } + + // Clipping planes + #if defined(CLIPPING_PLANES) + intersectClippingPlanes(ray, ix); + #endif + + // Depth + #if defined(DEPTH_TEST) + intersectDepth(screenCoord, ray, ix); + #endif + + // Find the first intersection that's in front of the ray + #if (INTERSECTION_COUNT > 1) + initializeIntersections(ix); + for (int i = 0; i < INTERSECTION_COUNT; ++i) { + entryExitT = nextIntersection(ix); + if (entryExitT.y > 0.0) { + // Set start to 0.0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + break; + } + } + #else + // Set start to 0.0 when ray is inside the shape. + entryExitT.x = max(entryExitT.x, 0.0); + #endif + + return entryExitT; +} + +// export { intersectScene }; diff --git a/Source/Shaders/Voxels/IntersectionUtils.glsl b/Source/Shaders/Voxels/IntersectionUtils.glsl new file mode 100644 index 00000000000..d7ab5cde8c9 --- /dev/null +++ b/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -0,0 +1,147 @@ +/* Intersection defines +#define INTERSECTION_COUNT ### +*/ + +#define NO_HIT (-czm_infinity) +#define INF_HIT (czm_infinity * 0.5) + +struct Ray { + vec3 pos; + vec3 dir; +}; + +struct Intersections { + // Don't access these member variables directly - call the functions instead. + + #if (INTERSECTION_COUNT > 1) + // Store an array of intersections. Each intersection is composed of: + // x for the T value + // y for the shape type - which encodes positive vs negative and entering vs exiting + // For example: + // y = 0: positive shape entry + // y = 1: positive shape exit + // y = 2: negative shape entry + // y = 3: negative shape exit + vec2 intersections[INTERSECTION_COUNT * 2]; + + // Maintain state for future nextIntersection calls + int index; + int surroundCount; + bool surroundIsPositive; + #else + // When there's only one positive shape intersection none of the extra stuff is needed. + float intersections[2]; + #endif +}; + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x +#else + #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) +#else + #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) +#endif + +// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +#if (INTERSECTION_COUNT > 1) + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) +#else + #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y +#endif + +#if (INTERSECTION_COUNT > 1) +void initializeIntersections(inout Intersections ix) { + // Sort the intersections from min T to max T with bubble sort. + // Note: If this sorting function changes, some of the intersection test may + // need to be updated. Search for "bubble sort" to find those areas. + const int sortPasses = INTERSECTION_COUNT * 2 - 1; + for (int n = sortPasses; n > 0; --n) { + for (int i = 0; i < sortPasses; ++i) { + // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= n) { break; } + + vec2 intersect0 = ix.intersections[i + 0]; + vec2 intersect1 = ix.intersections[i + 1]; + + float t0 = intersect0.x; + float t1 = intersect1.x; + float b0 = intersect0.y; + float b1 = intersect1.y; + + float tmin = min(t0, t1); + float tmax = max(t0, t1); + float bmin = tmin == t0 ? b0 : b1; + float bmax = tmin == t0 ? b1 : b0; + + ix.intersections[i + 0] = vec2(tmin, bmin); + ix.intersections[i + 1] = vec2(tmax, bmax); + } + } + + // Prepare initial state for nextIntersection + ix.index = 0; + ix.surroundCount = 0; + ix.surroundIsPositive = false; +} +#endif + +#if (INTERSECTION_COUNT > 1) +vec2 nextIntersection(inout Intersections ix) { + vec2 entryExitT = vec2(NO_HIT); + + const int passCount = INTERSECTION_COUNT * 2; + for (int i = 0; i < passCount; ++i) { + // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to continue instead. + if (i < ix.index) { + continue; + } + + vec2 intersect = ix.intersections[i]; + float t = intersect.x; + bool currShapeIsPositive = intersect.y < 2.0; + bool enter = mod(intersect.y, 2.0) == 0.0; + + ix.surroundCount += enter ? +1 : -1; + ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; + + // entering positive or exiting negative + if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { + entryExitT.x = t; + } + + // exiting positive or entering negative after being inside positive + // TODO: Can this be simplified? + bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; + bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; + if (exitPositive || enterNegativeFromPositive) { + entryExitT.y = t; + + // entry and exit have been found, so the loop can stop + if (exitPositive) { + // After exiting positive shape there is nothing left to intersect, so jump to the end index. + ix.index = passCount; + } else { + // There could be more intersections against the positive shape in the future. + ix.index = i + 1; + } + break; + } + } + + return entryExitT; +} +#endif + +// NOTE: initializeIntersections, nextIntersection aren't even declared unless INTERSECTION_COUNT > 1 +// export { NO_HIT, INF_HIT, Ray, Intersections, getIntersectionPair, setIntersectionPair, initializeIntersections, nextIntersection }; diff --git a/Source/Shaders/Voxels/Megatexture.glsl b/Source/Shaders/Voxels/Megatexture.glsl new file mode 100644 index 00000000000..b7ba38b12c1 --- /dev/null +++ b/Source/Shaders/Voxels/Megatexture.glsl @@ -0,0 +1,138 @@ +// import { SampleData, intMod } from "./Octree.glsl"; + +/* Megatexture defines: +#define SAMPLE_COUNT ### +#define NEAREST_SAMPLING +#define PADDING +*/ + +uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions +uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions +uniform vec2 u_megatextureVoxelSizeUv; +uniform vec2 u_megatextureSliceSizeUv; +uniform vec2 u_megatextureTileSizeUv; + +uniform ivec3 u_dimensions; // does not include padding +#if defined(PADDING) + uniform ivec3 u_paddingBefore; + uniform ivec3 u_paddingAfter; +#endif + +// Integer min, max, clamp: For WebGL1 only +int intMin(int a, int b) { + return a <= b ? a : b; +} +int intMax(int a, int b) { + return a >= b ? a : b; +} +int intClamp(int v, int minVal, int maxVal) { + return intMin(intMax(v, minVal), maxVal); +} + +vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale) +{ + int indexX = intMod(index, dimensions.x); + int indexY = index / dimensions.x; + return vec2(indexX, indexY) * uvScale; +} + +/* + How is 3D data stored in a 2D megatexture? + + In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total). + The data is sliced by Z. The data at Z = 0 is placed in texels (0,0), (0,1), (1,0), (1,1) and + the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1). + Note that there could be empty space in the megatexture because it's a power of two. + + 0 1 2 3 + +---+---+---+---+ + | | | | | 3 + +---+---+---+---+ + | | | | | 2 + +-------+-------+ + |010|110|011|111| 1 + |--- ---|--- ---| + |000|100|001|101| 0 + +-------+-------+ + + When doing linear interpolation the megatexture needs to be sampled twice: once for + the Z slice above the voxel coordinate and once for the slice below. The two slices + are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is + halfway between two Z slices so the interpolation factor is 0.5. Below is a side view + of the 3D voxel grid with voxel coordinates on the left side. + + 2 +---+ + |001| + 1 +-z-+ + |000| + 0 +---+ + + When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice. +*/ + +Properties getPropertiesFromMegatexture(in SampleData sampleData) { + vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary? + int tileIndex = sampleData.megatextureIndex; + vec3 voxelCoord = tileUv * vec3(u_dimensions); + ivec3 voxelDimensions = u_dimensions; + + #if defined(PADDING) + voxelDimensions += u_paddingBefore + u_paddingAfter; + voxelCoord += vec3(u_paddingBefore); + #endif + + #if defined(NEAREST_SAMPLING) + // Round to the center of the nearest voxel + voxelCoord = floor(voxelCoord) + vec3(0.5); + #endif + + // Tile location + vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv); + + // Slice location + float slice = voxelCoord.z - 0.5; + int sliceIndex = int(floor(slice)); + int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1); + vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + + // Voxel location + vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv; + + // Final location in the megatexture + vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset; + + #if defined(NEAREST_SAMPLING) + return getPropertiesFromMegatextureAtUv(uv0); + #else + float sliceLerp = fract(slice); + int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1); + vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv); + vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset; + Properties properties0 = getPropertiesFromMegatextureAtUv(uv0); + Properties properties1 = getPropertiesFromMegatextureAtUv(uv1); + return mixProperties(properties0, properties1, sliceLerp); + #endif +} + +// Convert an array of sample datas to a final weighted properties. +Properties accumulatePropertiesFromMegatexture(in SampleData sampleDatas[SAMPLE_COUNT]) { + #if (SAMPLE_COUNT == 1) + return getPropertiesFromMegatexture(sampleDatas[0]); + #else + // When more than one sample is taken the accumulator needs to start at 0 + Properties properties = clearProperties(); + for (int i = 0; i < SAMPLE_COUNT; ++i) { + float weight = sampleDatas[i].weight; + + // Avoid reading the megatexture when the weight is 0 as it can be costly. + if (weight > 0.0) { + Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]); + tempProperties = scaleProperties(tempProperties, weight); + properties = sumProperties(properties, tempProperties); + } + } + return properties; + #endif +} + +// export { accumulatePropertiesFromMegatexture }; \ No newline at end of file diff --git a/Source/Shaders/Voxels/Octree.glsl b/Source/Shaders/Voxels/Octree.glsl new file mode 100644 index 00000000000..2bd215a4103 --- /dev/null +++ b/Source/Shaders/Voxels/Octree.glsl @@ -0,0 +1,227 @@ +// import { convertUvToShapeUvSpace } from ("./convertUvToBox.glsl", "./convertUvToCylinder.glsl", "convertUvToEllipsoid.glsl"); + +// These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js +#define OCTREE_FLAG_INTERNAL 0 +#define OCTREE_FLAG_LEAF 1 +#define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2 + +#define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops + +uniform sampler2D u_octreeInternalNodeTexture; +uniform vec2 u_octreeInternalNodeTexelSizeUv; +uniform int u_octreeInternalNodeTilesPerRow; +uniform sampler2D u_octreeLeafNodeTexture; +uniform vec2 u_octreeLeafNodeTexelSizeUv; +uniform int u_octreeLeafNodeTilesPerRow; + +uniform float u_stepSize; + +struct OctreeNodeData { + int data; + int flag; +}; + +struct TraversalData { + vec3 positionUvShapeSpace; + vec3 positionUvLocal; + float stepT; + ivec4 octreeCoords; + int parentOctreeIndex; +}; + +struct SampleData { + int megatextureIndex; + bool usingParentMegatextureIndex; + vec3 tileUv; + #if (SAMPLE_COUNT > 1) + float weight; + #endif +}; + +// Integer mod: For WebGL1 only +int intMod(int a, int b) { + return a - (b * (a / b)); +} +bool inRange(float v, float minVal, float maxVal) { + return clamp(v, minVal, maxVal) == v; +} +bool inRange(vec3 v, vec3 minVal, vec3 maxVal) { + return clamp(v, minVal, maxVal) == v; +} +int normU8_toInt(float value) { + return int(value * 255.0); +} +int normU8x2_toInt(vec2 value) { + return int(value.x * 255.0) + 256 * int(value.y * 255.0); +} +float normU8x2_toFloat(vec2 value) { + return float(normU8x2_toInt(value)) / 65535.0; +} + +OctreeNodeData getOctreeRootData() { + vec4 rootData = texture2D(u_octreeInternalNodeTexture, vec2(0.0)); + + OctreeNodeData data; + data.data = normU8x2_toInt(rootData.xy); + data.flag = normU8x2_toInt(rootData.zw); + return data; +} + +OctreeNodeData getOctreeChildData(int parentOctreeIndex, ivec3 childCoord) { + int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x; + int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex; + int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow; + vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); + vec4 childData = texture2D(u_octreeInternalNodeTexture, octreeUv); + + OctreeNodeData data; + data.data = normU8x2_toInt(childData.xy); + data.flag = normU8x2_toInt(childData.zw); + return data; +} + +int getOctreeParentIndex(int octreeIndex) { + int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9; + int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow; + vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); + vec4 parentData = texture2D(u_octreeInternalNodeTexture, octreeUv); + int parentOctreeIndex = normU8x2_toInt(parentData.xy); + return parentOctreeIndex; +} + +void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { + #if (SAMPLE_COUNT == 1) + sampleDatas[0].megatextureIndex = data.data; + sampleDatas[0].usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; + #else + int leafIndex = data.data; + int leafNodeTexelCount = 2; + // Adding 0.5 moves to the center of the texel + float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; + float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; + + vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); + vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); + vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); + vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); + + float lerp = normU8x2_toFloat(leafData0.xy); + + sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); + sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); + sampleDatas[0].usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; + sampleDatas[1].usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; + sampleDatas[0].weight = 1.0 - lerp; + sampleDatas[1].weight = lerp; + #endif +} + +void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { + float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); + vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; + vec3 end = start + vec3(sizeAtLevel); + + for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { + // Find out which octree child contains the position + // 0 if before center, 1 if after + vec3 center = 0.5 * (start + end); + vec3 childCoord = step(center, traversalData.positionUvShapeSpace); + + OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); + + // Get octree coords for the next level down + ivec4 parentOctreeCoords = traversalData.octreeCoords; + traversalData.octreeCoords = ivec4(parentOctreeCoords.xyz * 2 + ivec3(childCoord), parentOctreeCoords.w + 1); + + if (childData.flag == OCTREE_FLAG_INTERNAL) { + // interior tile - keep going deeper + start = mix(start, center, childCoord); + end = mix(center, end, childCoord); + traversalData.parentOctreeIndex = childData.data; + } else { + // leaf tile - stop traversing + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + traversalData.stepT = u_stepSize / dimAtLevel; + + getOctreeLeafSampleData(childData, sampleDatas); + for (int i = 0; i < SAMPLE_COUNT; i++) { + if (sampleDatas[i].usingParentMegatextureIndex) { + float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); + sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); + } else { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } + } + return; + } + } +} + +void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { + traversalData.octreeCoords = ivec4(0); + traversalData.parentOctreeIndex = 0; + + // TODO: is it possible for this to be out of bounds, and does it matter? + traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace; + + OctreeNodeData rootData = getOctreeRootData(); + if (rootData.flag == OCTREE_FLAG_LEAF) { + // No child data, only the root tile has data + getOctreeLeafSampleData(rootData, sampleDatas); + traversalData.stepT = u_stepSize; + for (int i = 0; i < SAMPLE_COUNT; i++) { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } + } + else + { + traverseOctreeDownwards(traversalData, sampleDatas); + } +} + +void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + + // Note: This code assumes the position is always inside the root tile. + bool insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); + + if (insideTile) { + for (int i = 0; i < SAMPLE_COUNT; i++) { + if (sampleDatas[i].usingParentMegatextureIndex) { + ivec4 parentOctreeCoords; + parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); + parentOctreeCoords.w = traversalData.octreeCoords.w - 1; + float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); + sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); + } else { + sampleDatas[i].tileUv = traversalData.positionUvLocal; + } + } + } else { + // Go up tree + for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) + { + traversalData.octreeCoords.xyz /= ivec3(2); + traversalData.octreeCoords.w -= 1; + dimAtLevel *= 0.5; + + traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); + + if (!insideTile) { + traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); + } else { + break; + } + } + + // Go down tree + traverseOctreeDownwards(traversalData, sampleDatas); + } +} + +// export { SampleData, traverseOctreeFromBeginning, traverseOctreeFromExisting }; diff --git a/Source/Shaders/Voxels/VoxelFS.glsl b/Source/Shaders/Voxels/VoxelFS.glsl new file mode 100644 index 00000000000..5399843201b --- /dev/null +++ b/Source/Shaders/Voxels/VoxelFS.glsl @@ -0,0 +1,132 @@ +// import { intersectScene } from "./Intersection.glsl"; +// import { TraversalData, SampleData, traverseOctreeFromBeginning, traverseOctreeFromExisting } from "./Octree.glsl"; +// import { accumulatePropertiesFromMegatexture } from "./Megatexture.glsl"; + +#define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops +#define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0 + +uniform mat3 u_transformDirectionViewToLocal; +uniform vec3 u_cameraPositionUv; + +#if defined(PICKING) + uniform vec4 u_pickColor; +#endif + +#if defined(JITTER) +float hash(vec2 p) +{ + vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); +} +#endif + +void main() +{ + vec4 fragCoord = gl_FragCoord; + vec2 screenCoord = (fragCoord.xy - czm_viewport.xy) / czm_viewport.zw; // [0,1] + vec3 eyeDirection = normalize(czm_windowToEyeCoordinates(fragCoord).xyz); + vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case + vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case + vec3 viewPosUv = u_cameraPositionUv; + + Intersections ix; + vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); + + // Exit early if the scene was completely missed. + if (entryExitT.x == NO_HIT) { + discard; + } + + float currT = entryExitT.x; + float endT = entryExitT.y; + vec3 positionUv = viewPosUv + currT * viewDirUv; + + // Traverse the tree from the start position + TraversalData traversalData; + SampleData sampleDatas[SAMPLE_COUNT]; + traverseOctreeFromBeginning(positionUv, traversalData, sampleDatas); + + #if defined(JITTER) + float noise = hash(screenCoord); // [0,1] + currT += noise * traversalData.stepT; + positionUv += noise * traversalData.stepT * viewDirUv; + #endif + + FragmentInput fragmentInput; + #if defined(STATISTICS) + setStatistics(fragmentInput.metadata.statistics); + #endif + + vec4 colorAccum =vec4(0.0); + + for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { + // Read properties from the megatexture based on the traversal state + Properties properties = accumulatePropertiesFromMegatexture(sampleDatas); + + // Prepare the custom shader inputs + copyPropertiesToMetadata(properties, fragmentInput.metadata); + fragmentInput.voxel.positionUv = positionUv; + fragmentInput.voxel.positionShapeUv = traversalData.positionUvShapeSpace; + fragmentInput.voxel.positionUvLocal = traversalData.positionUvLocal; + fragmentInput.voxel.viewDirUv = viewDirUv; + fragmentInput.voxel.viewDirWorld = viewDirWorld; + fragmentInput.voxel.travelDistance = traversalData.stepT; + + // Run the custom shader + czm_modelMaterial materialOutput; + fragmentMain(fragmentInput, materialOutput); + + // Sanitize the custom shader output + vec4 color = vec4(materialOutput.diffuse, materialOutput.alpha); + color.rgb = max(color.rgb, vec3(0.0)); + color.a = clamp(color.a, 0.0, 1.0); + + // Pre-multiplied alpha blend + colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a); + + // Stop traversing if the alpha has been fully saturated + if (colorAccum.a > ALPHA_ACCUM_MAX) { + colorAccum.a = ALPHA_ACCUM_MAX; + break; + } + + // Keep raymarching + currT += traversalData.stepT; + positionUv += traversalData.stepT * viewDirUv; + + // Check if there's more intersections. + if (currT > endT) { + #if (INTERSECTION_COUNT == 1) + break; + #else + vec2 entryExitT = nextIntersection(ix); + if (entryExitT.x == NO_HIT) { + break; + } else { + // Found another intersection. Keep raymarching. + currT += entryExitT.x; + endT += entryExitT.y; + positionUv += entryExitT.x * viewDirUv; + } + #endif + } + + // Traverse the tree from the current ray position. + // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. + traverseOctreeFromExisting(positionUv, traversalData, sampleDatas); + } + + // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] + colorAccum.a /= ALPHA_ACCUM_MAX; + + #if defined(PICKING) + // If alpha is 0.0 there is nothing to pick + if (colorAccum.a == 0.0) { + discard; + } + gl_FragColor = u_pickColor; + #else + gl_FragColor = colorAccum; + #endif +} diff --git a/Source/Shaders/VoxelVS.glsl b/Source/Shaders/Voxels/VoxelVS.glsl similarity index 100% rename from Source/Shaders/VoxelVS.glsl rename to Source/Shaders/Voxels/VoxelVS.glsl diff --git a/Source/Shaders/Voxels/convertUvToBox.glsl b/Source/Shaders/Voxels/convertUvToBox.glsl new file mode 100644 index 00000000000..09ce687cf1f --- /dev/null +++ b/Source/Shaders/Voxels/convertUvToBox.glsl @@ -0,0 +1,17 @@ +/* Box defines: +#define BOX_HAS_SHAPE_BOUND +*/ + +// Box uniforms: +#if defined(BOX_HAS_SHAPE_BOUND) + uniform vec3 u_boxScaleUvToShapeBoundsUv; + uniform vec3 u_boxOffsetUvToShapeBoundsUv; +#endif + +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + #if defined(BOX_HAS_SHAPE_BOUND) + return positionUv * u_boxScaleUvToShapeBoundsUv + u_boxOffsetUvToShapeBoundsUv; + #else + return positionUv; + #endif +} diff --git a/Source/Shaders/Voxels/convertUvToCylinder.glsl b/Source/Shaders/Voxels/convertUvToCylinder.glsl new file mode 100644 index 00000000000..40af7c87593 --- /dev/null +++ b/Source/Shaders/Voxels/convertUvToCylinder.glsl @@ -0,0 +1,81 @@ +/* Cylinder defines: +#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT +#define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO + +#define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS +#define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT +#define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT +#define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED +*/ + +#if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + uniform vec2 u_cylinderUvToShapeUvRadius; // x = scale, y = offset +#endif +#if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + uniform vec2 u_cylinderUvToShapeUvHeight; // x = scale, y = offset +#endif +#if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + uniform vec2 u_cylinderUvToShapeUvAngle; // x = scale, y = offset +#endif +#if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + uniform vec2 u_cylinderShapeUvAngleMinMax; +#endif +#if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + uniform float u_cylinderShapeUvAngleEmptyMid; +#endif + +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] + + // Compute radius + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) + float radius = length(positionLocal.xy); // [0,1] + #else + float radius = length(positionLocal.xy); // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS) + radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset + #endif + #endif + + // Compute height + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) + float height = positionUv.z; // [0,1] + #else + float height = positionUv.z; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT) + height = height * u_cylinderUvToShapeUvHeight.x + u_cylinderUvToShapeUvHeight.y; // x = scale, y = offset + #endif + #endif + + // Compute angle + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + float angle = 1.0; + #else + float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) + // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. + angle += float(angle < u_cylinderShapeUvAngleEmptyMid); + #endif + + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) + angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; + #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) + angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; + #endif + + angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset + #endif + #endif + + return vec3(radius, height, angle); +} + +// export { convertUvToShapeUvSpace }; \ No newline at end of file diff --git a/Source/Shaders/Voxels/convertUvToEllipsoid.glsl b/Source/Shaders/Voxels/convertUvToEllipsoid.glsl new file mode 100644 index 00000000000..d02e3abe66a --- /dev/null +++ b/Source/Shaders/Voxels/convertUvToEllipsoid.glsl @@ -0,0 +1,135 @@ +/* Ellipsoid defines: +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY +#define ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY +#define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE +#define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED +#define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE +#define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN +#define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_IS_SPHERE +*/ + +uniform vec3 u_ellipsoidRadiiUv; // [0,1] +#if !defined(ELLIPSOID_IS_SPHERE) + uniform vec3 u_ellipsoidInverseRadiiSquaredUv; +#endif +#if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) || defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + uniform vec3 u_ellipsoidShapeUvLongitudeMinMaxMid; +#endif +#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLongitude; // x = scale, y = offset +#endif +#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset +#endif +#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + uniform float u_ellipsoidInverseHeightDifferenceUv; + uniform vec2 u_ellipseInnerRadiiUv; // [0,1] +#endif + +// robust iterative solution without trig functions +// https://github.com/0xfaded/ellipse_demo/issues/1 +// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse +// Pro: Good when radii.x ~= radii.y +// Con: Breaks at pos.x ~= 0.0, especially inside the ellipse +// Con: Inaccurate with exterior points and thin ellipses +float ellipseDistanceIterative (vec2 pos, vec2 radii) { + vec2 p = abs(pos); + vec2 invRadii = 1.0 / radii; + vec2 a = vec2(1.0, -1.0) * (radii.x * radii.x - radii.y * radii.y) * invRadii; + vec2 t = vec2(0.70710678118); // sqrt(2) / 2 + vec2 v = radii * t; + + const int iterations = 3; + for (int i = 0; i < iterations; ++i) { + vec2 e = a * pow(t, vec2(3.0)); + vec2 q = normalize(p - e) * length(v - e); + t = normalize((q + e) * invRadii); + v = radii * t; + } + return length(v * sign(pos) - pos) * sign(p.y - v.y); +} + +vec3 convertUvToShapeUvSpace(in vec3 positionUv) { + // Compute position and normal. + // Convert positionUv [0,1] to local space [-1,+1] to "normalized" cartesian space [-a,+a] where a = (radii + height) / (max(radii) + height). + // A point on the largest ellipsoid axis would be [-1,+1] and everything else would be smaller. + vec3 positionLocal = positionUv * 2.0 - 1.0; + #if defined(ELLIPSOID_IS_SPHERE) + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv.x; + vec3 normal = normalize(posEllipsoid); + #else + vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; + vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal + #endif + + // Compute longitude + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) + float longitude = 1.0; + #else + float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; + + // Correct the angle when max < min + // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) + longitude += float(longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z); + #endif + + // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY) + longitude = longitude > u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.x : longitude; + #endif + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY) + longitude = longitude < u_ellipsoidShapeUvLongitudeMinMaxMid.z ? u_ellipsoidShapeUvLongitudeMinMaxMid.y : longitude; + #endif + + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE) + longitude = longitude * u_ellipsoidUvToShapeUvLongitude.x + u_ellipsoidUvToShapeUvLongitude.y; + #endif + #endif + + // Compute latitude + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO) + float latitude = 1.0; + #else + float latitude = (asin(normal.z) + czm_piOverTwo) / czm_pi; + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) + latitude = latitude * u_ellipsoidUvToShapeUvLatitude.x + u_ellipsoidUvToShapeUvLatitude.y; + #endif + #endif + + // Compute height + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + // TODO: This breaks down when minBounds == maxBounds. To fix it, this + // function would have to know if ray is intersecting the front or back of the shape + // and set the shape space position to 1 (front) or 0 (back) accordingly. + float height = 1.0; + #else + #if defined(ELLIPSOID_IS_SPHERE) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) + float height = (length(posEllipsoid) - u_ellipseInnerRadiiUv.x) * u_ellipsoidInverseHeightDifferenceUv; + #else + float height = length(posEllipsoid); + #endif + #else + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) + // Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z) (assuming radii.x == radii.y which is true for WGS84). + // This is an optimization so that math can be done with ellipses instead of ellipsoids. + vec2 posEllipse = vec2(length(posEllipsoid.xy), posEllipsoid.z); + float height = ellipseDistanceIterative(posEllipse, u_ellipseInnerRadiiUv) * u_ellipsoidInverseHeightDifferenceUv; + #else + // TODO: this is probably not correct + float height = length(posEllipsoid); + #endif + #endif + #endif + + return vec3(longitude, latitude, height); +} + +// export { convertUvToShapeUvSpace }; From a245360e6a1d9ed438f9463ec12db64956184fe6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 18 Aug 2022 18:13:54 -0400 Subject: [PATCH 081/679] Fix Windows linking error in getOctreeLeafSampleData --- Source/Shaders/Voxels/Octree.glsl | 64 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/Source/Shaders/Voxels/Octree.glsl b/Source/Shaders/Voxels/Octree.glsl index 2bd215a4103..327b43d8765 100644 --- a/Source/Shaders/Voxels/Octree.glsl +++ b/Source/Shaders/Voxels/Octree.glsl @@ -89,32 +89,34 @@ int getOctreeParentIndex(int octreeIndex) { return parentOctreeIndex; } -void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleDatas[SAMPLE_COUNT]) { - #if (SAMPLE_COUNT == 1) - sampleDatas[0].megatextureIndex = data.data; - sampleDatas[0].usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; - #else - int leafIndex = data.data; - int leafNodeTexelCount = 2; - // Adding 0.5 moves to the center of the texel - float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; - float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; - - vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); - vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); - vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); - vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); - - float lerp = normU8x2_toFloat(leafData0.xy); - - sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); - sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); - sampleDatas[0].usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; - sampleDatas[1].usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; - sampleDatas[0].weight = 1.0 - lerp; - sampleDatas[1].weight = lerp; - #endif +void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleData) { + sampleData.megatextureIndex = data.data; + sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; +} + +#if (SAMPLE_COUNT > 1) +void getOctreeLeafSampleDatas(in OctreeNodeData data, inout SampleData sampleData0, inout SampleData sampleData1) { + int leafIndex = data.data; + int leafNodeTexelCount = 2; + // Adding 0.5 moves to the center of the texel + float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; + float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; + + vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); + vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); + vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0); + vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1); + + float lerp = normU8x2_toFloat(leafData0.xy); + + sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy); + sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw); + sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; + sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; + sampleData0.weight = 1.0 - lerp; + sampleData1.weight = lerp; } +#endif void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); @@ -144,7 +146,11 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); traversalData.stepT = u_stepSize / dimAtLevel; - getOctreeLeafSampleData(childData, sampleDatas); + #if (SAMPLE_COUNT == 1) + getOctreeLeafSampleData(childData, sampleDatas[0]); + #else + getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]); + #endif for (int i = 0; i < SAMPLE_COUNT; i++) { if (sampleDatas[i].usingParentMegatextureIndex) { float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); @@ -169,7 +175,11 @@ void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversal OctreeNodeData rootData = getOctreeRootData(); if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data - getOctreeLeafSampleData(rootData, sampleDatas); + #if (SAMPLE_COUNT == 1) + getOctreeLeafSampleData(rootData, sampleDatas[0]); + #else + getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]); + #endif traversalData.stepT = u_stepSize; for (int i = 0; i < SAMPLE_COUNT; i++) { sampleDatas[i].tileUv = traversalData.positionUvLocal; From b5ab598eaa3346e315557c96bcae9211f5c23f15 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 19 Aug 2022 13:53:44 -0400 Subject: [PATCH 082/679] Fix docs and failing test in OrientedBoundingBox --- Apps/Sandcastle/gallery/VoxelsBox.html | 391 ------------------------- Source/Core/OrientedBoundingBox.js | 27 +- 2 files changed, 4 insertions(+), 414 deletions(-) delete mode 100644 Apps/Sandcastle/gallery/VoxelsBox.html diff --git a/Apps/Sandcastle/gallery/VoxelsBox.html b/Apps/Sandcastle/gallery/VoxelsBox.html deleted file mode 100644 index 73750c27470..00000000000 --- a/Apps/Sandcastle/gallery/VoxelsBox.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - - - - - Cesium Demo - - - - - - -
-

Loading...

-
- - - diff --git a/Source/Core/OrientedBoundingBox.js b/Source/Core/OrientedBoundingBox.js index 849402b023a..f18ebabd3d9 100644 --- a/Source/Core/OrientedBoundingBox.js +++ b/Source/Core/OrientedBoundingBox.js @@ -18,13 +18,13 @@ import Rectangle from "./Rectangle.js"; /** * Creates an instance of an OrientedBoundingBox. - * An OrientedBoundingBox of some object is a closed and convex cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. + * An OrientedBoundingBox of some object is a closed and convex rectangular cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. * @alias OrientedBoundingBox * @constructor * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 + * Equivalently, the transformation matrix, to rotate and scale a 1x1x1 * cube centered at the origin. * * @@ -334,7 +334,7 @@ const scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. * - * @exception {DeveloperError} rectangle.width must be between 0 and pi. + * @exception {DeveloperError} rectangle.width must be between 0 and 2 * pi. * @exception {DeveloperError} rectangle.height must be between 0 and pi. * @exception {DeveloperError} ellipsoid must be an ellipsoid of revolution (radii.x == radii.y) */ @@ -350,7 +350,7 @@ OrientedBoundingBox.fromRectangle = function ( throw new DeveloperError("rectangle is required"); } if (rectangle.width < 0.0 || rectangle.width > CesiumMath.TWO_PI) { - throw new DeveloperError("Rectangle width must be between 0 and 2*pi"); + throw new DeveloperError("Rectangle width must be between 0 and 2 * pi"); } if (rectangle.height < 0.0 || rectangle.height > CesiumMath.PI) { throw new DeveloperError("Rectangle height must be between 0 and pi"); @@ -373,25 +373,6 @@ OrientedBoundingBox.fromRectangle = function ( maximumHeight = defaultValue(maximumHeight, 0.0); ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - if (rectangle.equals(Rectangle.MAX_VALUE)) { - if (!defined(result)) { - result = new OrientedBoundingBox(); - } - result.halfAxes = Matrix3.fromScale( - Cartesian3.add( - ellipsoid.radii, - Cartesian3.fromElements( - maximumHeight, - maximumHeight, - maximumHeight, - scratchScale - ), - scratchScale - ) - ); - return result; - } - let minX, maxX, minY, maxY, minZ, maxZ, plane; if (rectangle.width <= CesiumMath.PI) { From 791525d2d335a15beedf27ea9f46d81a7196ad3e Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 19 Aug 2022 23:49:41 -0400 Subject: [PATCH 083/679] Fix failing tests for Voxel shapes --- Source/Scene/VoxelBoxShape.js | 24 +++-- Source/Scene/VoxelCylinderShape.js | 13 ++- Source/Scene/VoxelEllipsoidShape.js | 16 ++- Specs/Scene/VoxelBoxShapeSpec.js | 143 ++++++------------------- Specs/Scene/VoxelCylinderShapeSpec.js | 71 ++++++------ Specs/Scene/VoxelEllipsoidShapeSpec.js | 46 +++++--- 6 files changed, 131 insertions(+), 182 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index aa53a13d58c..df569d7f0fd 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -5,6 +5,7 @@ import Check from "../Core/Check.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; +import defaultValue from "../Core/defaultValue.js"; /** * A box {@link VoxelShape}. @@ -140,8 +141,8 @@ const transformXYZToXZY = Matrix4.fromRotation( * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * @param {Cartesian3} clipMinBounds The minimum clip bounds. - * @param {Cartesian3} clipMaxBounds The maximum clip bounds. + * @param {Cartesian3} [clipMinBounds=VoxelBoxShape.DefaultMinBounds] The minimum clip bounds. + * @param {Cartesian3} [clipMaxBounds=VoxelBoxShape.DefaultMaxBounds] The maximum clip bounds. * @returns {Boolean} Whether the shape is visible. */ VoxelBoxShape.prototype.update = function ( @@ -151,6 +152,14 @@ VoxelBoxShape.prototype.update = function ( clipMinBounds, clipMaxBounds ) { + clipMinBounds = defaultValue( + clipMinBounds, + VoxelBoxShape.DefaultMinBounds.clone() + ); + clipMaxBounds = defaultValue( + clipMaxBounds, + VoxelBoxShape.DefaultMaxBounds.clone() + ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); @@ -219,13 +228,6 @@ VoxelBoxShape.prototype.update = function ( (renderMinBounds.y === renderMaxBounds.y) + (renderMinBounds.z === renderMaxBounds.z) >= 2 || - clipMinBounds.x > clipMaxBounds.x || - clipMinBounds.y > clipMaxBounds.y || - clipMinBounds.z > clipMaxBounds.z || - (clipMinBounds.x === clipMaxBounds.x) + - (clipMinBounds.y === clipMaxBounds.y) + - (clipMinBounds.z === clipMaxBounds.z) >= - 2 || scale.x === 0.0 || scale.y === 0.0 || scale.z === 0.0 @@ -481,8 +483,8 @@ VoxelBoxShape.DefaultMaxBounds = new Cartesian3(+1.0, +1.0, +1.0); * * @function * - * @param {Number} minimumBounds The minimum bounds. - * @param {Number} maximumBounds The maximum bounds. + * @param {Cartesian3} minimumBounds The minimum bounds, in the local coordinates of the shape. + * @param {Cartesian3} maximumBounds The maximum bounds, in the local coordinates of the shape. * @param {Matrix4} matrix The matrix to transform the points. * @param {OrientedBoundingBox} result The object onto which to store the result. * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. diff --git a/Source/Scene/VoxelCylinderShape.js b/Source/Scene/VoxelCylinderShape.js index 9f67926f8b6..d32467ff387 100644 --- a/Source/Scene/VoxelCylinderShape.js +++ b/Source/Scene/VoxelCylinderShape.js @@ -1,3 +1,4 @@ +import defaultValue from "../Core/defaultValue.js"; import BoundingSphere from "../Core/BoundingSphere.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; @@ -161,8 +162,8 @@ const transformUvToLocal = Matrix4.fromRotationTranslation( * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * @param {Cartesian3} clipMinBounds The minimum clip bounds. - * @param {Cartesian3} clipMaxBounds The maximum clip bounds. + * @param {Cartesian3} [clipMinBounds=VoxelCylinderShape.DefaultMinBounds] The minimum clip bounds. + * @param {Cartesian3} [clipMaxBounds=VoxelCylinderShape.DefaultMaxBounds] The maximum clip bounds. */ VoxelCylinderShape.prototype.update = function ( modelMatrix, @@ -171,6 +172,14 @@ VoxelCylinderShape.prototype.update = function ( clipMinBounds, clipMaxBounds ) { + clipMinBounds = defaultValue( + clipMinBounds, + VoxelCylinderShape.DefaultMinBounds.clone() + ); + clipMaxBounds = defaultValue( + clipMaxBounds, + VoxelCylinderShape.DefaultMaxBounds.clone() + ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); diff --git a/Source/Scene/VoxelEllipsoidShape.js b/Source/Scene/VoxelEllipsoidShape.js index fd75db09429..5cdc0f87ee3 100644 --- a/Source/Scene/VoxelEllipsoidShape.js +++ b/Source/Scene/VoxelEllipsoidShape.js @@ -8,6 +8,7 @@ import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; import Rectangle from "../Core/Rectangle.js"; +import defaultValue from "../Core/defaultValue.js"; /** * An ellipsoid {@link VoxelShape}. @@ -162,8 +163,8 @@ const scratchInnerExtentRender = new Cartesian3(); * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * @param {Cartesian3} clipMinBounds The minimum clip bounds. - * @param {Cartesian3} clipMaxBounds The maximum clip bounds. + * @param {Cartesian3} [clipMinBounds=VoxelEllipsoidShape.DefaultMinBounds] The minimum clip bounds. + * @param {Cartesian3} [clipMaxBounds=VoxelEllipsoidShape.DefaultMaxBounds] The maximum clip bounds. * @returns {Boolean} Whether the shape is visible. */ VoxelEllipsoidShape.prototype.update = function ( @@ -173,6 +174,14 @@ VoxelEllipsoidShape.prototype.update = function ( clipMinBounds, clipMaxBounds ) { + clipMinBounds = defaultValue( + clipMinBounds, + VoxelEllipsoidShape.DefaultMinBounds.clone() + ); + clipMaxBounds = defaultValue( + clipMaxBounds, + VoxelEllipsoidShape.DefaultMaxBounds.clone() + ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); @@ -911,7 +920,8 @@ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( * @param {Number} minHeight The minimumZ. * @param {Number} maxHeight The maximumZ. * @param {Ellipsoid} ellipsoid The ellipsoid. - * @param {Matrix4} matrix The matrix to transform the points. + * @param {Cartesian3} translation The translation applied to the shape + * @param {Matrix3} rotation The rotation applied to the shape * @param {OrientedBoundingBox} result The object onto which to store the result. * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. * diff --git a/Specs/Scene/VoxelBoxShapeSpec.js b/Specs/Scene/VoxelBoxShapeSpec.js index a9461f403a0..09f02aeab47 100644 --- a/Specs/Scene/VoxelBoxShapeSpec.js +++ b/Specs/Scene/VoxelBoxShapeSpec.js @@ -51,13 +51,7 @@ describe("Scene/VoxelBoxShape", function () { Cartesian3.magnitude(scale) ); - const visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + const visible = shape.update(modelMatrix, minBounds, maxBounds); expect(shape.orientedBoundingBox.center).toEqual( expectedOrientedBoundingBox.center @@ -93,7 +87,7 @@ describe("Scene/VoxelBoxShape", function () { maxBounds ); - const expectedTranslation = new Cartesian3(0.75, 1.75, 2.75); + const expectedTranslation = new Cartesian3(0.0, 0.5, 1); const expectedScale = new Cartesian3(0.5, 0.75, 1.0); const expectedRotation = rotation; const expectedModelMatrix = Matrix4.fromTranslationQuaternionRotationScale( @@ -114,11 +108,12 @@ describe("Scene/VoxelBoxShape", function () { expect(shape.orientedBoundingBox).toEqual(expectedOrientedBoundingBox); expect(shape.boundingSphere).toEqual(expectedBoundingSphere); expect(shape.boundTransform).toEqual(expectedModelMatrix); - expect(shape.shapeTransform).toEqual(expectedModelMatrix); + expect(shape.shapeTransform).toEqual(modelMatrix); expect(visible).toBeTrue(); }); - it("update is visible with zero scale for one component", function () { + xit("update is visible with zero scale for one component", function () { + // Not implemented. See the comment in VoxelBoxShape.prototype.update const shape = new VoxelBoxShape(); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; @@ -136,13 +131,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeTrue(); // 0 scale for Y @@ -152,13 +141,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeTrue(); // 0 scale for Z @@ -168,13 +151,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeTrue(); }); @@ -196,13 +173,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); // 0 scale for X and Z @@ -212,13 +183,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); // 0 scale for Y and Z @@ -228,13 +193,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); // 0 scale for X, Y, and Z @@ -244,13 +203,7 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); }); @@ -287,7 +240,7 @@ describe("Scene/VoxelBoxShape", function () { clipMinBounds, clipMaxBounds ); - actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualScale = Matrix4.getScale(shape.boundTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() @@ -308,7 +261,7 @@ describe("Scene/VoxelBoxShape", function () { clipMinBounds, clipMaxBounds ); - actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualScale = Matrix4.getScale(shape.boundTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() @@ -329,7 +282,7 @@ describe("Scene/VoxelBoxShape", function () { clipMinBounds, clipMaxBounds ); - actualScale = Matrix4.getScale(shape.shapeTransform, new Cartesian3()); + actualScale = Matrix4.getScale(shape.boundTransform, new Cartesian3()); actualTranslation = Matrix4.getTranslation( shape.shapeTransform, new Cartesian3() @@ -357,13 +310,7 @@ describe("Scene/VoxelBoxShape", function () { // 0 in X and Y bounds minBounds = new Cartesian3(0.0, 0.0, -1.0); maxBounds = new Cartesian3(0.0, 0.0, +1.0); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); // 0 in X and Z bounds @@ -381,25 +328,13 @@ describe("Scene/VoxelBoxShape", function () { // 0 in Y and Z bounds minBounds = new Cartesian3(-1.0, 0.0, 0.0); maxBounds = new Cartesian3(+1.0, 0.0, 0.0); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); // 0 in X, Y, and Z bounds minBounds = new Cartesian3(0.0, 0.0, 0.0); maxBounds = new Cartesian3(0.0, 0.0, 0.0); - visible = shape.update( - modelMatrix, - minBounds, - maxBounds, - minBounds, - maxBounds - ); + visible = shape.update(modelMatrix, minBounds, maxBounds); expect(visible).toBeFalse(); }); @@ -422,8 +357,8 @@ describe("Scene/VoxelBoxShape", function () { const clipMaxBounds = new Cartesian3(2.0, 2.0, 2.0); // Exceeds X - minBounds = new Cartesian3(+2.0, -1.0, -1.0); - maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + minBounds = new Cartesian3(+1.0, -1.0, -1.0); + maxBounds = new Cartesian3(+0.9, +1.0, +1.0); visible = shape.update( modelMatrix, minBounds, @@ -434,8 +369,8 @@ describe("Scene/VoxelBoxShape", function () { expect(visible).toBeFalse(); // Exceeds Y - minBounds = new Cartesian3(-1.0, +2.0, -1.0); - maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + minBounds = new Cartesian3(-1.0, +1.0, -1.0); + maxBounds = new Cartesian3(+1.0, +0.9, +1.0); visible = shape.update( modelMatrix, minBounds, @@ -446,8 +381,8 @@ describe("Scene/VoxelBoxShape", function () { expect(visible).toBeFalse(); // Exceeds Z - minBounds = new Cartesian3(-1.0, -1.0, +2.0); - maxBounds = new Cartesian3(+1.0, +1.0, +1.0); + minBounds = new Cartesian3(-1.0, -1.0, +1.0); + maxBounds = new Cartesian3(+1.0, +1.0, +0.9); visible = shape.update( modelMatrix, minBounds, @@ -478,17 +413,10 @@ describe("Scene/VoxelBoxShape", function () { rotation, scale ); - const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; expect(function () { - return shape.update( - modelMatrix, - undefined, - maxBounds, - minBounds, - maxBounds - ); + return shape.update(modelMatrix, undefined, maxBounds); }).toThrowDeveloperError(); }); @@ -503,16 +431,9 @@ describe("Scene/VoxelBoxShape", function () { scale ); const minBounds = VoxelBoxShape.DefaultMinBounds; - const maxBounds = VoxelBoxShape.DefaultMaxBounds; expect(function () { - return shape.update( - modelMatrix, - minBounds, - undefined, - minBounds, - maxBounds - ); + return shape.update(modelMatrix, minBounds, undefined); }).toThrowDeveloperError(); }); @@ -528,7 +449,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -558,7 +479,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); const expectedScale = new Cartesian3(0.5, 0.5, 0.5); let expectedTranslation; @@ -716,7 +637,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -776,7 +697,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); const tileLevel = 0; const tileX = 0; @@ -806,7 +727,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); const dimensions = new Cartesian3(32, 32, 16); const stepSize = shape.computeApproximateStepSize(dimensions); @@ -826,7 +747,7 @@ describe("Scene/VoxelBoxShape", function () { ); const minBounds = VoxelBoxShape.DefaultMinBounds; const maxBounds = VoxelBoxShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + shape.update(modelMatrix, minBounds, maxBounds); expect(function () { return shape.computeApproximateStepSize(undefined); diff --git a/Specs/Scene/VoxelCylinderShapeSpec.js b/Specs/Scene/VoxelCylinderShapeSpec.js index 2486f04f483..59fa85e519b 100644 --- a/Specs/Scene/VoxelCylinderShapeSpec.js +++ b/Specs/Scene/VoxelCylinderShapeSpec.js @@ -22,11 +22,6 @@ describe( const translation = new Cartesian3(1.0, 2.0, 3.0); const scale = new Cartesian3(2.0, 3.0, 4.0); - const halfScale = Cartesian3.multiplyByScalar( - scale, - 0.5, - new Cartesian3() - ); const angle = CesiumMath.PI_OVER_FOUR; const rotation = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, angle); const modelMatrix = Matrix4.fromTranslationQuaternionRotationScale( @@ -37,25 +32,25 @@ describe( const minBounds = VoxelCylinderShape.DefaultMinBounds; const maxBounds = VoxelCylinderShape.DefaultMaxBounds; - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + const visible = shape.update(modelMatrix, minBounds, maxBounds); const expectedOrientedBoundingBox = new OrientedBoundingBox( translation, Matrix3.fromColumnMajorArray([ - halfScale.x * Math.cos(angle), - halfScale.x * Math.sin(angle), + scale.x * Math.cos(angle), + scale.x * Math.sin(angle), 0.0, - halfScale.y * Math.cos(angle + CesiumMath.PI_OVER_TWO), - halfScale.y * Math.sin(angle + CesiumMath.PI_OVER_TWO), + scale.y * Math.cos(angle + CesiumMath.PI_OVER_TWO), + scale.y * Math.sin(angle + CesiumMath.PI_OVER_TWO), 0.0, 0.0, 0.0, - halfScale.z, + scale.z, ]) ); const expectedBoundingSphere = new BoundingSphere( translation, - Cartesian3.magnitude(halfScale) + Cartesian3.magnitude(scale) ); expect(shape.orientedBoundingBox.center).toEqual( @@ -68,7 +63,7 @@ describe( expect(shape.boundingSphere).toEqual(expectedBoundingSphere); expect(shape.boundTransform).toEqual(modelMatrix); expect(shape.shapeTransform).toEqual(modelMatrix); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); }); it("update works with non-default minimum and maximum bounds", function () { @@ -92,19 +87,19 @@ describe( const maxAngle = 0.0; const minBounds = new Cartesian3(minRadius, minHeight, minAngle); const maxBounds = new Cartesian3(maxRadius, maxHeight, maxAngle); - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + const visible = shape.update(modelMatrix, minBounds, maxBounds); const expectedMinX = translation.x - maxRadius * scale.x; const expectedMaxX = translation.x + maxRadius * scale.x; - const expectedMinY = translation.y + minHeight * scale.y; - const expectedMaxY = translation.y + maxHeight * scale.y; - const expectedMinZ = translation.z - maxRadius * scale.z; - const expectedMaxZ = translation.z; + const expectedMinY = translation.y - maxRadius * scale.y; + const expectedMaxY = translation.y; + const expectedMinZ = translation.z + minHeight * scale.z; + const expectedMaxZ = translation.z + maxHeight * scale.z; const expectedScale = new Cartesian3( - expectedMaxX - expectedMinX, - expectedMaxY - expectedMinY, - expectedMaxZ - expectedMinZ + 0.5 * (expectedMaxX - expectedMinX), + 0.5 * (expectedMaxY - expectedMinY), + 0.5 * (expectedMaxZ - expectedMinZ) ); const expectedTranslation = new Cartesian3( 0.5 * (expectedMaxX + expectedMinX), @@ -112,18 +107,13 @@ describe( 0.5 * (expectedMaxZ + expectedMinZ) ); - const expectedHalfScale = Cartesian3.multiplyByScalar( - expectedScale, - 0.5, - new Cartesian3() - ); const expectedOrientedBoundingBox = new OrientedBoundingBox( expectedTranslation, - Matrix3.fromScale(expectedHalfScale) + Matrix3.fromScale(expectedScale) ); const expectedBoundingSphere = new BoundingSphere( expectedTranslation, - Cartesian3.magnitude(expectedHalfScale) + Cartesian3.magnitude(expectedScale) ); const expectedBoundTransform = Matrix4.setTranslation( Matrix4.fromScale(expectedScale, new Matrix4()), @@ -142,7 +132,7 @@ describe( expect(shape.boundingSphere).toEqual(expectedBoundingSphere); expect(shape.boundTransform).toEqual(expectedBoundTransform); expect(shape.shapeTransform).toEqual(modelMatrix); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); }); it("update works with minimum and maximum bounds that cross the 180th meridian", function () { @@ -172,23 +162,18 @@ describe( defaultMaxBounds.y, maxAngle ); - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + const visible = shape.update(modelMatrix, minBounds, maxBounds); const expectedScale = new Cartesian3(0.5, 1.0, 1.0); const expectedTranslation = new Cartesian3(-0.5, 0.0, 0.0); - const expectedHalfScale = Cartesian3.multiplyByScalar( - expectedScale, - 0.5, - new Cartesian3() - ); const expectedOrientedBoundingBox = new OrientedBoundingBox( expectedTranslation, - Matrix3.fromScale(expectedHalfScale) + Matrix3.fromScale(expectedScale) ); const expectedBoundingSphere = new BoundingSphere( expectedTranslation, - Cartesian3.magnitude(expectedHalfScale) + Cartesian3.magnitude(expectedScale) ); const expectedBoundTransform = Matrix4.setTranslation( Matrix4.fromScale(expectedScale, new Matrix4()), @@ -204,10 +189,16 @@ describe( expectedOrientedBoundingBox.halfAxes, CesiumMath.EPSILON12 ); - expect(shape.boundingSphere).toEqual(expectedBoundingSphere); - expect(shape.boundTransform).toEqual(expectedBoundTransform); + expect(shape.boundingSphere).toEqualEpsilon( + expectedBoundingSphere, + CesiumMath.EPSILON12 + ); + expect(shape.boundTransform).toEqualEpsilon( + expectedBoundTransform, + CesiumMath.EPSILON12 + ); expect(shape.shapeTransform).toEqual(modelMatrix); - expect(shape.isVisible).toBeTrue(); + expect(visible).toBeTrue(); }); }, "WebGL" diff --git a/Specs/Scene/VoxelEllipsoidShapeSpec.js b/Specs/Scene/VoxelEllipsoidShapeSpec.js index 9d2736ca341..05a105d6b37 100644 --- a/Specs/Scene/VoxelEllipsoidShapeSpec.js +++ b/Specs/Scene/VoxelEllipsoidShapeSpec.js @@ -18,7 +18,7 @@ describe("Scene/VoxelEllipsoidShape", function () { it("update works with model matrix", function () { const shape = new VoxelEllipsoidShape(); const translation = new Cartesian3(1.0, 2.0, 3.0); - const scale = new Cartesian3(2.0, 2.0, 4.0); + const scale = new Cartesian3(2.0, 2.0, 2.0); const angle = CesiumMath.PI_OVER_FOUR; const rotation = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, angle); @@ -42,16 +42,16 @@ describe("Scene/VoxelEllipsoidShape", function () { const expectedOrientedBoundingBox = new OrientedBoundingBox( translation, - Matrix3.fromColumnMajorArray([ - (scale.x + maxHeight) * Math.cos(angle), - (scale.x + maxHeight) * Math.sin(angle), + Matrix3.fromRowMajorArray([ 0.0, - (scale.y + maxHeight) * Math.cos(angle + CesiumMath.PI_OVER_TWO), - (scale.y + maxHeight) * Math.sin(angle + CesiumMath.PI_OVER_TWO), 0.0, + scale.z + maxHeight, + (scale.x + maxHeight) * Math.cos(angle), + -(scale.y + maxHeight) * Math.sin(angle), 0.0, + (scale.x + maxHeight) * Math.sin(angle), + (scale.y + maxHeight) * Math.cos(angle), 0.0, - scale.z + maxHeight, ]) ); @@ -60,7 +60,7 @@ describe("Scene/VoxelEllipsoidShape", function () { new BoundingSphere() ); - shape.update(modelMatrix, minBounds, maxBounds, minBounds, maxBounds); + const visible = shape.update(modelMatrix, minBounds, maxBounds); expect(shape.orientedBoundingBox.center).toEqual( expectedOrientedBoundingBox.center @@ -83,13 +83,29 @@ describe("Scene/VoxelEllipsoidShape", function () { Matrix4.getTranslation(shape.shapeTransform, new Cartesian3()) ).toEqualEpsilon(expectedOrientedBoundingBox.center, CesiumMath.EPSILON12); - expect( - Matrix4.getMatrix3(shape.shapeTransform, new Matrix3()) - ).toEqualEpsilon(expectedOrientedBoundingBox.halfAxes, CesiumMath.EPSILON9); - - // expect(shape.boundTransform).toEqual(modelMatrix); - // expect(shape.shapeTransform).toEqual(modelMatrix); - // expect(shape.isVisible).toBeTrue(); + const expectedShapeTransform = Matrix4.fromRowMajorArray([ + (scale.x + maxHeight) * Math.cos(angle), + -(scale.x + maxHeight) * Math.sin(angle), + 0.0, + expectedOrientedBoundingBox.center.x, + (scale.y + maxHeight) * Math.sin(angle), + (scale.y + maxHeight) * Math.cos(angle), + 0.0, + expectedOrientedBoundingBox.center.y, + 0.0, + 0.0, + scale.z + maxHeight, + expectedOrientedBoundingBox.center.z, + 0.0, + 0.0, + 0.0, + 1.0, + ]); + expect(shape.shapeTransform).toEqualEpsilon( + expectedShapeTransform, + CesiumMath.EPSILON9 + ); + expect(visible).toBeTrue(); }); // const PI_OVER_TWO = CesiumMath.PI_OVER_TWO; From e4e4a02576c289f5688ac75df771ac72e77b37e0 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 22 Aug 2022 19:39:05 -0400 Subject: [PATCH 084/679] Fix failing tests for Viewer and VoxelPrimitive --- Specs/Scene/VoxelPrimitiveSpec.js | 203 +++++------------------------ Specs/Widgets/Viewer/ViewerSpec.js | 4 +- 2 files changed, 38 insertions(+), 169 deletions(-) diff --git a/Specs/Scene/VoxelPrimitiveSpec.js b/Specs/Scene/VoxelPrimitiveSpec.js index e45fb36ecf4..f066ac230fd 100644 --- a/Specs/Scene/VoxelPrimitiveSpec.js +++ b/Specs/Scene/VoxelPrimitiveSpec.js @@ -1,108 +1,50 @@ import { - AttributeType, Cartesian3, - ComponentDatatype, + Cesium3DTilesVoxelProvider, defined, - Matrix3, Matrix4, - Pass, - VoxelBoxShape, VoxelPrimitive, } from "../../Source/Cesium.js"; import createScene from "../createScene.js"; - -const metadataName = "dummyMetadataName"; -function DummyVoxelProvider() { - this.shape = new VoxelBoxShape(); - this.voxelDimensions = new Cartesian3(2, 2, 2); - this.voxelsPerTile = 2 * 2 * 2; - this.ready = true; - this.readyPromise = Promise.resolve(this); - this._tileCount = 4096; - this.neighborEdgeCount = 0; - this.metadataNames = [metadataName]; - this.numberOfLevels = 16; - - this.properties = {}; - - this.properties[metadataName] = { - type: AttributeType.VEC4, - componentType: ComponentDatatype.FLOAT, - componentCount: 4, - min: 0, - max: 1, - count: this.voxelsPerTile * this._tileCount, - }; -} -DummyVoxelProvider.prototype.requestData = function (options) { - const maxIndex = Math.pow(2, options.level) - 1; - const requestOutsideOfShape = - options.x < 0 || - options.x > maxIndex || - options.y < 0 || - options.y > maxIndex || - options.z < 0 || - options.z > maxIndex; - if (options.level >= this.numberOfLevels || requestOutsideOfShape) { - return Promise.resolve(undefined); - } - const returnArray = new Uint32Array(this.voxelsPerTile); - return Promise.resolve(returnArray); -}; +import pollToPromise from "../pollToPromise.js"; describe( "Scene/VoxelPrimitive", function () { const scene = createScene(); - const provider = new DummyVoxelProvider(); - let primitive; + let provider; + beforeEach(function () { - scene.primitives.removeAll(); - primitive = new VoxelPrimitive({ - provider: provider, + provider = new Cesium3DTilesVoxelProvider({ + url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(() => { + scene.primitives.removeAll(); }); - scene._primitives.add(primitive); - scene.renderForSpecs(); }); it("constructs a primitive", function () { - const command = scene.frameState.commandList[0]; - expect(command).toBeDefined(); - expect(command.pass).toBe(Pass.VOXELS); + const primitive = new VoxelPrimitive(); + expect(primitive.geometryInstances).not.toBeDefined(); + expect(primitive.appearance).not.toBeDefined(); + expect(primitive.depthFailAppearance).not.toBeDefined(); + expect(primitive.modelMatrix).toEqual(Matrix4.IDENTITY); + expect(primitive.show).toEqual(true); }); it("constructs with options", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); + expect(primitive.provider).toBe(provider); return primitive.readyPromise.then(function () { - const property = provider.properties[metadataName]; expect(primitive.shape._type).toBe(provider.shape._type); - expect( - primitive._voxelDimensions.equals(provider.voxelDimensions) - ).toBe(true); - expect(primitive._voxelNeighborEdgeCount).toBe( - provider.neighborEdgeCount - ); - // Object.values workaround is Object.keys.map - const minimumValues = primitive.minimumValues[0]; - expect( - Object.keys(minimumValues) - .map(function (key) { - return minimumValues[key]; - }) - .every(function (value) { - return value === property.min; - }) - ).toBe(true); - const maximumValues = primitive.maximumValues[0]; - expect( - Object.keys(maximumValues) - .map(function (key) { - return maximumValues[key]; - }) - .every(function (value) { - return value === property.max; - }) - ).toBe(true); + expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); expect(primitive._tileCount).toBe(provider._tileCount); expect(defined(primitive._traversal)).toBe(true); // TODO should we test writing glsl functions? i.e. sample functions, setting style input values for each metadata @@ -110,6 +52,10 @@ describe( }); it("sets clipping range extrema when given valid range between 0 and 1", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); + const setValue = Cartesian3.fromElements(0.1, 0.5, 0.3); expect(primitive.minClippingBounds.equals(setValue)).toBe(false); primitive.minClippingBounds = setValue; @@ -119,102 +65,25 @@ describe( expect(primitive.maxClippingBounds.equals(setValue)).toBe(true); }); - it("clamps clipping range extrema when given values outside [0, 1]", function () { - const setValue = Cartesian3.fromElements(-1.0, 0.5, 2.0); - const clampedValue = Cartesian3.fromElements(0.0, 0.5, 1.0); - primitive.minClippingBounds = setValue; - expect(primitive.minClippingBounds.equals(clampedValue)).toBe(true); - primitive.maxClippingBounds = setValue; - expect(primitive.maxClippingBounds.equals(clampedValue)).toBe(true); - }); - it("uses default style", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); primitive.style = undefined; expect(primitive.style).toBe(VoxelPrimitive.DefaultStyle); }); - it("creates style", function () { - const options = { - type: "VoxelPrimitiveStyle", - source: - "vec4 style(StyleInput styleInput) {\n" + - " return vec4(1.0);\n" + - "}", - uniforms: { dummyUniform: 0 }, - }; - const material = VoxelPrimitive.CreateStyle(options); - expect(material._template.type).toBe(options.type); - expect(material._template.source).toBe(options.source); - expect(material._template.uniforms.dummyUniform).toBe( - options.uniforms.dummyUniform - ); - }); + it("updates step size", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); - it("updates transform matrices", function () { const shape = primitive._shape; shape.translation = new Cartesian3(2.382, -3.643, 1.084); return primitive.readyPromise.then(function () { primitive.update(scene.frameState); - const worldToBoundTransform = Matrix4.inverse( - shape._boundTransform, - new Matrix4() - ); - expect( - primitive._worldToBoundTransform.equals(worldToBoundTransform) - ).toBe(true); - - const shapeTransform = shape._shapeTransform; - const worldToShapeTransform = Matrix4.inverse( - shape._shapeTransform, - new Matrix4() - ); - expect( - primitive._worldToShapeTransform.equals(worldToShapeTransform) - ).toBe(true); - - const shapeScale = Matrix4.getScale(shapeTransform, new Matrix4()); - const shapeRotation = Matrix4.getRotation( - shapeTransform, - new Matrix4() - ); - const shapeScaleMaximum = Cartesian3.maximumComponent(shapeScale); - const shapeNormalizedScale = Cartesian3.divideByScalar( - shapeScale, - shapeScaleMaximum, - new Matrix4() - ); - const scaleAndRotation = Matrix3.multiplyByScale( - shapeRotation, - shapeNormalizedScale, - new Matrix4() - ); - const worldToUvTransformDirection = Matrix3.inverse( - scaleAndRotation, - new Matrix3() - ); - expect( - primitive._worldToUvTransformDirection.equals( - worldToUvTransformDirection - ) - ).toBe(true); - - const shapeToWorldNormal = Matrix4.getRotation( - shapeTransform, - new Matrix4() - ); - Matrix3.multiplyByScale( - shapeToWorldNormal, - shapeNormalizedScale, - shapeToWorldNormal - ); - Matrix3.transpose(shapeToWorldNormal, shapeToWorldNormal); - Matrix3.inverse(shapeToWorldNormal, shapeToWorldNormal); - expect(primitive._shapeToWorldNormal.equals(shapeToWorldNormal)).toBe( - true - ); - const stepSizeUv = shape.computeApproximateStepSize( - primitive._voxelDimensions + primitive.dimensions ); expect(primitive._stepSizeUv).toBe(stepSizeUv); }); diff --git a/Specs/Widgets/Viewer/ViewerSpec.js b/Specs/Widgets/Viewer/ViewerSpec.js index 02b07a73c7e..e043dc175c7 100644 --- a/Specs/Widgets/Viewer/ViewerSpec.js +++ b/Specs/Widgets/Viewer/ViewerSpec.js @@ -1401,8 +1401,8 @@ describe( function loadVoxelPrimitive(viewer) { const voxelPrimitive = new VoxelPrimitive({ provider: new GltfVoxelProvider({ - url: - "./Data/Cesium3DTiles/Voxel/SimpleWithMetadata/0/0/0/0/tile.gltf", + gltf: + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf", }), }); viewer.scene.primitives.add(voxelPrimitive); From 7d8d1a0f9e54bcd4151f8c3621e249ed7b43b422 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 22 Aug 2022 22:34:32 -0400 Subject: [PATCH 085/679] Drop obsolete tests and use real VoxelProvider in VoxelTraversalSpec --- Specs/Scene/VoxelTraversalSpec.js | 498 +++++++++++------------------- 1 file changed, 173 insertions(+), 325 deletions(-) diff --git a/Specs/Scene/VoxelTraversalSpec.js b/Specs/Scene/VoxelTraversalSpec.js index b7f5619da5a..c69915bfc63 100644 --- a/Specs/Scene/VoxelTraversalSpec.js +++ b/Specs/Scene/VoxelTraversalSpec.js @@ -1,95 +1,17 @@ import { - AttributeType, - ComponentDatatype, - defer, + Matrix4, + VoxelEllipsoidShape, VoxelTraversal, VoxelPrimitive, - VoxelBoxShape, Cartesian3, OrientedBoundingBox, Math as CesiumMath, CullingVolume, + Cesium3DTilesVoxelProvider, } from "../../Source/Cesium.js"; import MetadataType from "../../Source/Scene/MetadataType.js"; import createScene from "../createScene.js"; - -const randomNumber = CesiumMath.nextRandomNumber; -const testQueryCoords = Cartesian3.fromElements( - randomNumber() - 0.5, // get in the same interval as the shape [-0.5, 0.5] - randomNumber() - 0.5, - randomNumber() - 0.5 -); -const numberOfLevels = 15; -const numberOfBins = Math.pow(2, numberOfLevels - 1); -const maxIndex = numberOfBins - 1; -const testQueryTileCoords = Cartesian3.fromElements( - Math.floor((testQueryCoords.x + 0.5) * numberOfBins), - Math.floor((testQueryCoords.y + 0.5) * numberOfBins), - Math.floor((testQueryCoords.z + 0.5) * numberOfBins) -); -if (testQueryCoords.x > maxIndex) { - testQueryCoords.x = maxIndex; -} -if (testQueryCoords.y > maxIndex) { - testQueryCoords.y = maxIndex; -} -if (testQueryCoords.z > maxIndex) { - testQueryCoords.z = maxIndex; -} -const metadataName = "dummyMetadataName"; -function DummyVoxelProvider() { - this.shape = new VoxelBoxShape(); - const voxelDimension = 64; - this.voxelDimensions = new Cartesian3( - voxelDimension, - voxelDimension, - voxelDimension - ); - const channelCount = 4; - this.voxelsPerTile = voxelDimension * voxelDimension * voxelDimension; - this.floatsPerTile = channelCount * this.voxelsPerTile; - this.ready = true; - this.readyPromise = Promise.resolve(this); - this._tileCount = 4096; - this.neighborEdgeCount = 0; - this.numberOfLevels = numberOfLevels; - - this.properties = {}; - this.properties[metadataName] = { - type: AttributeType.VEC4, - componentType: ComponentDatatype.FLOAT, - componentCount: 4, - min: 0, - max: 1, - count: this.voxelsPerTile * this._tileCount, - }; -} -DummyVoxelProvider.prototype.requestData = function (options) { - const maxIndex = Math.pow(2, options.level) - 1; - const requestOutsideOfShape = - options.x < 0 || - options.x > maxIndex || - options.y < 0 || - options.y > maxIndex || - options.z < 0 || - options.z > maxIndex; - if (options.level >= this.numberOfLevels || requestOutsideOfShape) { - return Promise.resolve(undefined); - } - const returnArray = new Uint32Array(this.floatsPerTile); - if ( - (options.x === testQueryTileCoords.x && - options.y === testQueryTileCoords.y && - options.z === testQueryTileCoords.z && - options.level === this.numberOfLevels - 1) || - this.numberOfLevels === 1 // voxel index test - ) { - for (let i = 0; i < this.floatsPerTile; i++) { - returnArray[i] = i; - } - } - return Promise.resolve(returnArray); -}; +import pollToPromise from "../pollToPromise.js"; const towardPrimitive = Cartesian3.fromElements(1.0, 1.0, 1.0); @@ -101,20 +23,30 @@ function turnCameraAround(scene) { describe( "Scene/VoxelTraversal", function () { - const provider = new DummyVoxelProvider(); const scene = createScene(); + + let provider; + beforeAll(function () { + provider = new Cesium3DTilesVoxelProvider({ + url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }).then(() => { + scene.primitives.removeAll(); + }); + }); + const frameState = scene.frameState; - const camera = frameState.camera; + const camera = scene.camera; const context = scene.context; const keyframeCount = 1; - const voxelDimensions = provider.voxelDimensions; - const neighborEdgeCount = provider.neighborEdgeCount; - // TODO: not available from the dummy provider (nor from the real providers) - const datatypes = provider.datatypes; const textureMemory = 500; - let traversalPromise = defer(); let primitive; + let traversal; beforeEach(function () { camera.position = Cartesian3.fromElements(-10, -10, -10); camera.direction = Cartesian3.fromElements(1, 1, 1); @@ -125,13 +57,13 @@ describe( }); scene.primitives.add(primitive); scene.renderForSpecs(); - traversalPromise = primitive.readyPromise.then(function () { - return new VoxelTraversal( + return primitive.readyPromise.then(function () { + traversal = new VoxelTraversal( primitive, context, - voxelDimensions, - datatypes, - datatypes, + provider.dimensions, + provider.types, + provider.componentTypes, keyframeCount, textureMemory ); @@ -139,252 +71,168 @@ describe( }); it("constructs with arguments", function () { - return traversalPromise.then(function (traversal) { - expect(traversal.primitive).toBe(primitive); - const megatextureKeys = Object.keys(traversal.megatextures); - expect(megatextureKeys.length).toBe(1); - expect(megatextureKeys).toEqual( - jasmine.arrayContaining([metadataName]) - ); - const megatexture = traversal.megatexture; - expect(megatexture.channelCount).toBe( - provider.properties[metadataName].componentCount - ); - expect(megatexture.datatype).toBe(MetadataType.FLOAT); - const twiceNeighborEdgeCount = 2 * neighborEdgeCount; - expect( - megatexture.voxelCountPerTile.equals( - Cartesian3.add( - voxelDimensions, - Cartesian3.fromElements( - twiceNeighborEdgeCount, - twiceNeighborEdgeCount, - twiceNeighborEdgeCount - ), - new Cartesian3() - ) - ) - ).toBe(true); - expect(megatexture.metadataName).toBe(metadataName); - }); + expect(traversal._primitive).toBe(primitive); + expect(traversal.megatextures.length).toBe(1); + const megatexture = traversal.megatextures[0]; + expect(megatexture.datatype).toBe(MetadataType.FLOAT); }); it("recomputes bounding volume when shape moves", function () { - return traversalPromise.then(function (traversal) { - const rootNode = traversal.rootNode; - const oldOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); - const shape = traversal.primitive._shape; - const translation = Cartesian3.fromElements(1, 1, 1); - shape.translation = translation; - shape.update(); - const keyFrameLocation = 0; - const recomputeBoundingVolumes = true; - const pauseUpdate = false; - traversal.update( - frameState, - keyFrameLocation, - recomputeBoundingVolumes, - pauseUpdate - ); - const newOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); - expect( - OrientedBoundingBox.equals( - oldOrientedBoundingBox, - newOrientedBoundingBox - ) - ).toBe(false); - expect(newOrientedBoundingBox.center.equals(translation)).toBe(true); - }); + const rootNode = traversal.rootNode; + const oldOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); + const shape = traversal._primitive._shape; + const translation = Cartesian3.fromElements(1, 1, 1); + shape.translation = translation; + const modelMatrix = Matrix4.fromTranslation(translation); + shape.update( + modelMatrix, + VoxelEllipsoidShape.DefaultMinBounds, + VoxelEllipsoidShape.DefaultMaxBounds + ); + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + const newOrientedBoundingBox = rootNode.orientedBoundingBox.clone(); + expect( + OrientedBoundingBox.equals( + oldOrientedBoundingBox, + newOrientedBoundingBox + ) + ).toBe(false); + expect(newOrientedBoundingBox.center.equals(translation)).toBe(true); }); it("computes screen space error for root tile", function () { - return traversalPromise.then(function (traversal) { - const rootNode = traversal.rootNode; - const cameraPosition = frameState.camera.positionWC; - const screenSpaceErrorDenominator = - frameState.camera.frustum.sseDenominator; - const screenHeight = - frameState.context.drawingBufferHeight / frameState.pixelRatio; - const screenSpaceErrorMultiplier = - screenHeight / screenSpaceErrorDenominator; - rootNode.computeScreenSpaceError( - cameraPosition, - screenSpaceErrorMultiplier - ); - - let distanceToCamera = Math.sqrt( - rootNode.orientedBoundingBox.distanceSquaredTo(cameraPosition) - ); - distanceToCamera = Math.max(distanceToCamera, CesiumMath.EPSILON7); - const error = - screenSpaceErrorMultiplier * - (rootNode.approximateVoxelSize / distanceToCamera); - expect(rootNode.screenSpaceError).toBe(error); - }); + const rootNode = traversal.rootNode; + const cameraPosition = frameState.camera.positionWC; + const screenSpaceErrorDenominator = + frameState.camera.frustum.sseDenominator; + const screenHeight = + frameState.context.drawingBufferHeight / frameState.pixelRatio; + const screenSpaceErrorMultiplier = + screenHeight / screenSpaceErrorDenominator; + rootNode.computeScreenSpaceError( + cameraPosition, + screenSpaceErrorMultiplier + ); + + let distanceToCamera = Math.sqrt( + rootNode.orientedBoundingBox.distanceSquaredTo(cameraPosition) + ); + distanceToCamera = Math.max(distanceToCamera, CesiumMath.EPSILON7); + const error = + screenSpaceErrorMultiplier * + (rootNode.approximateVoxelSize / distanceToCamera); + expect(rootNode.screenSpaceError).toBe(error); }); it("computes visibility for root tile", function () { - return traversalPromise.then(function (traversal) { - const rootNode = traversal.rootNode; - const visibilityPlaneMask = CullingVolume.MASK_INDETERMINATE; - - const visibilityWhenLookingAtRoot = rootNode.visibility( - frameState, - visibilityPlaneMask - ); - expect(visibilityWhenLookingAtRoot).toBe(CullingVolume.MASK_INSIDE); - - turnCameraAround(scene); - const visibilityWhenLookingAway = rootNode.visibility( - frameState, - visibilityPlaneMask - ); - expect(visibilityWhenLookingAway).toBe(CullingVolume.MASK_OUTSIDE); - }); - }); - - it("loads tiles into megatexture", function () { - return traversalPromise.then(function (traversal) { - const keyFrameLocation = 0; - const recomputeBoundingVolumes = true; - const pauseUpdate = false; - traversal.update( - frameState, - keyFrameLocation, - recomputeBoundingVolumes, - pauseUpdate - ); - - const megatexture = traversal.megatextures[metadataName]; - let tilesInMegatextureCount = megatexture.occupiedCount; - const tileInQueueWhenLookingAtRoot = tilesInMegatextureCount === 1; - expect(tileInQueueWhenLookingAtRoot).toBe(true); - - traversal.megatexture.remove(0); - turnCameraAround(scene); - traversal.update( - frameState, - keyFrameLocation, - recomputeBoundingVolumes, - pauseUpdate - ); - tilesInMegatextureCount = traversal.megatexture.occupiedCount; - const tileNotInQueueWhenLookingAway = tilesInMegatextureCount === 0; - expect(tileNotInQueueWhenLookingAway).toBe(true); - }); - }); - - it("unloads tiles in megatexture", function () { - return traversalPromise.then(function (traversal) { - const keyFrameLocation = 0; - const recomputeBoundingVolumes = true; - const pauseUpdate = false; - function updateTraversalTenTimes() { - // to fully fetch data and copy to texture - function updateTraversal() { - traversal.update( - frameState, - keyFrameLocation, - recomputeBoundingVolumes, - pauseUpdate - ); - } - for (let i = 0; i < 10; i++) { - updateTraversal(); - } - } - - const eps = CesiumMath.EPSILON7; - const bottomLeftNearCorner = Cartesian3.fromElements( - -0.5 - eps, - -0.5 - eps, - -0.5 - eps - ); - const topRightFarCorner = Cartesian3.fromElements( - 0.5 + eps, - 0.5 + eps, - 0.5 + eps - ); - scene.camera.position = bottomLeftNearCorner; - updateTraversalTenTimes(); - const numberOfNodesOnGPU = traversal.keyframeNodesInMegatexture.length; - const deepestNode = - traversal.keyframeNodesInMegatexture[numberOfNodesOnGPU - 1]; - const deepestSpatialNode = deepestNode.spatialNode; - const nodeIsInMegatexture = - deepestNode.state === VoxelTraversal.LoadState.LOADED; - expect(nodeIsInMegatexture).toBe(true); - - scene.camera.position = topRightFarCorner; - turnCameraAround(scene); - updateTraversalTenTimes(); - const nodeNoLongerInMegatexture = - traversal.keyframeNodesInMegatexture.filter(function (keyFrameNode) { - const spatialNode = keyFrameNode.spatialNode; - return ( - spatialNode.level === deepestSpatialNode.level && - spatialNode.x === deepestSpatialNode.x && - spatialNode.y === deepestSpatialNode.y && - spatialNode.x === deepestSpatialNode.z - ); - }).length === 0; - expect(nodeNoLongerInMegatexture).toBe(true); - }); + const rootNode = traversal.rootNode; + const visibilityPlaneMask = CullingVolume.MASK_INDETERMINATE; + + const visibilityWhenLookingAtRoot = rootNode.visibility( + frameState, + visibilityPlaneMask + ); + expect(visibilityWhenLookingAtRoot).toBe(CullingVolume.MASK_INSIDE); + + turnCameraAround(scene); + const visibilityWhenLookingAway = rootNode.visibility( + frameState, + visibilityPlaneMask + ); + expect(visibilityWhenLookingAway).toBe(CullingVolume.MASK_OUTSIDE); }); - it("gets tile metadata at a world cartesian coordiate", function () { - return traversalPromise - .then(function (traversal) { - return traversal.getMetadataAtWorldCartesian( - testQueryCoords, - metadataName - ); - }) - .then(function (queryValue) { - expect(queryValue[1]).not.toBe(0); - }); + xit("loads tiles into megatexture", function () { + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + + const megatexture = traversal.megatextures[0]; + let tilesInMegatextureCount = megatexture.occupiedCount; + const tileInQueueWhenLookingAtRoot = tilesInMegatextureCount === 1; + expect(tileInQueueWhenLookingAtRoot).toBe(true); + + traversal.megatexture.remove(0); + turnCameraAround(scene); + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate + ); + tilesInMegatextureCount = traversal.megatextures[0].occupiedCount; + const tileNotInQueueWhenLookingAway = tilesInMegatextureCount === 0; + expect(tileNotInQueueWhenLookingAway).toBe(true); }); - it("gives undefined when querying metadata outside of bounds", function () { - return traversalPromise - .then(function (traversal) { - return traversal.getMetadataAtWorldCartesian( - Cartesian3.fromElements(1, 1, 1), - metadataName + xit("unloads tiles in megatexture", function () { + const keyFrameLocation = 0; + const recomputeBoundingVolumes = true; + const pauseUpdate = false; + function updateTraversalTenTimes() { + // to fully fetch data and copy to texture + function updateTraversal() { + traversal.update( + frameState, + keyFrameLocation, + recomputeBoundingVolumes, + pauseUpdate ); - }) - .then(function (queryValue) { - expect(queryValue).toBe(undefined); - }); - }); - - it("returns right voxel within tile when querying", function () { - return traversalPromise.then(function (traversal) { - traversal.primitive.provider.numberOfLevels = 1; - const voxelsPerTile = provider.voxelsPerTile; - const queryPromises = new Array(voxelsPerTile); - const queryPointCoords = [ - [-0.5, -0.5, -0.5], - [0, -0.5, -0.5], - [-0.5, 0, -0.5], - [0, 0, -0.5], - [-0.5, -0.5, 0], - [0, -0.5, 0], - [-0.5, 0, 0], - [0, 0, 0], - ]; - queryPointCoords.forEach(function (coord, index) { - queryPromises[index] = traversal.getMetadataAtWorldCartesian( - Cartesian3.fromArray(coord), - metadataName + } + for (let i = 0; i < 10; i++) { + updateTraversal(); + } + } + + const eps = CesiumMath.EPSILON7; + const bottomLeftNearCorner = Cartesian3.fromElements( + -0.5 - eps, + -0.5 - eps, + -0.5 - eps + ); + const topRightFarCorner = Cartesian3.fromElements( + 0.5 + eps, + 0.5 + eps, + 0.5 + eps + ); + scene.camera.position = bottomLeftNearCorner; + updateTraversalTenTimes(); + const numberOfNodesOnGPU = traversal._keyframeNodesInMegatexture.length; + const deepestNode = + traversal._keyframeNodesInMegatexture[numberOfNodesOnGPU - 1]; + const deepestSpatialNode = deepestNode.spatialNode; + const nodeIsInMegatexture = + deepestNode.state === VoxelTraversal.LoadState.LOADED; + expect(nodeIsInMegatexture).toBe(true); + + scene.camera.position = topRightFarCorner; + turnCameraAround(scene); + updateTraversalTenTimes(); + const nodeNoLongerInMegatexture = + traversal._keyframeNodesInMegatexture.filter(function (keyFrameNode) { + const spatialNode = keyFrameNode.spatialNode; + return ( + spatialNode.level === deepestSpatialNode.level && + spatialNode.x === deepestSpatialNode.x && + spatialNode.y === deepestSpatialNode.y && + spatialNode.x === deepestSpatialNode.z ); - }); - return Promise.all(queryPromises).then(function (queryValues) { - queryValues.forEach(function (value, index) { - expect(value[0]).toBe(index); - }); - }); - }); + }).length === 0; + expect(nodeNoLongerInMegatexture).toBe(true); }); }, "WebGL" From 5daf6729053ff0fce263a2511b06f52f514c7660 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 23 Aug 2022 19:38:52 -0400 Subject: [PATCH 086/679] Refactor VoxelTraversal, extend WebGLStub for specs --- Source/Scene/KeyframeNode.js | 47 ++ Source/Scene/Megatexture.js | 507 +++++++++++++++ Source/Scene/SpatialNode.js | 434 +++++++++++++ Source/Scene/VoxelTraversal.js | 1019 +------------------------------ Specs/Scene/KeyframeNodeSpec.js | 44 ++ Specs/getWebGLStub.js | 5 + 6 files changed, 1064 insertions(+), 992 deletions(-) create mode 100644 Source/Scene/KeyframeNode.js create mode 100644 Source/Scene/Megatexture.js create mode 100644 Source/Scene/SpatialNode.js create mode 100644 Specs/Scene/KeyframeNodeSpec.js diff --git a/Source/Scene/KeyframeNode.js b/Source/Scene/KeyframeNode.js new file mode 100644 index 00000000000..2ce89690525 --- /dev/null +++ b/Source/Scene/KeyframeNode.js @@ -0,0 +1,47 @@ +const LoadState = Object.freeze({ + UNLOADED: 0, // Has no data and is in dormant state + RECEIVING: 1, // Is waiting on data from the provider + RECEIVED: 2, // Received data from the provider + LOADED: 3, // Processed data from provider + FAILED: 4, // Failed to receive data from the provider + UNAVAILABLE: 5, // No data available for this tile +}); + +/** + * @alias KeyframeNode + * @constructor + * + * @param {SpatialNode} spatialNode + * @param {Number} keyframe + * + * @private + */ +function KeyframeNode(spatialNode, keyframe) { + this.spatialNode = spatialNode; + this.keyframe = keyframe; + this.state = LoadState.UNLOADED; + this.metadatas = []; + this.megatextureIndex = -1; + this.priority = -Number.MAX_VALUE; + this.highPriorityFrameNumber = -1; +} + +/** + * @param {KeyframeNode} a + * @param {KeyframeNode} b + */ +KeyframeNode.priorityComparator = function (a, b) { + return a.priority - b.priority; +}; + +/** + * @param {KeyframeNode} a + * @param {KeyframeNode} b + */ +KeyframeNode.searchComparator = function (a, b) { + return a.keyframe - b.keyframe; +}; + +KeyframeNode.LoadState = LoadState; + +export default KeyframeNode; diff --git a/Source/Scene/Megatexture.js b/Source/Scene/Megatexture.js new file mode 100644 index 00000000000..e453644c3f0 --- /dev/null +++ b/Source/Scene/Megatexture.js @@ -0,0 +1,507 @@ +import Cartesian2 from "../Core/Cartesian2.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import ContextLimits from "../Renderer/ContextLimits.js"; +import defaultValue from "../Core/defaultValue.js"; +import defined from "../Core/defined.js"; +import destroyObject from "../Core/destroyObject.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import CesiumMath from "../Core/Math.js"; +import MetadataComponentType from "./MetadataComponentType.js"; +import PixelDatatype from "../Renderer/PixelDatatype.js"; +import PixelFormat from "../Core/PixelFormat.js"; +import RuntimeError from "../Core/RuntimeError.js"; +import Sampler from "../Renderer/Sampler.js"; +import Texture from "../Renderer/Texture.js"; +import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js"; +import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; +import TextureWrap from "../Renderer/TextureWrap.js"; + +/** + * @alias Megatexture + * @constructor + * + * @param {Context} context + * @param {Cartesian3} dimensions + * @param {Number} channelCount + * @param {MetadataComponentType} componentType + * @param {Number} [textureMemoryByteLength] + * + * @private + */ +function Megatexture( + context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength +) { + // TODO there are a lot of texture packing rules, see https://github.com/CesiumGS/cesium/issues/9572 + // Unsigned short textures not allowed in webgl 1, so treat as float + if (componentType === MetadataComponentType.UNSIGNED_SHORT) { + componentType = MetadataComponentType.FLOAT32; + } + + const supportsFloatingPointTexture = context.floatingPointTexture; + if ( + componentType === MetadataComponentType.FLOAT32 && + !supportsFloatingPointTexture + ) { + throw new RuntimeError("Floating point texture not supported"); + } + + // TODO support more + let pixelType; + if ( + componentType === MetadataComponentType.FLOAT32 || + componentType === MetadataComponentType.FLOAT64 + ) { + pixelType = PixelDatatype.FLOAT; + } else if (componentType === MetadataComponentType.UINT8) { + pixelType = PixelDatatype.UNSIGNED_BYTE; + } + + let pixelFormat; + if (channelCount === 1) { + pixelFormat = PixelFormat.LUMINANCE; + } else if (channelCount === 2) { + pixelFormat = PixelFormat.LUMINANCE_ALPHA; + } else if (channelCount === 3) { + pixelFormat = PixelFormat.RGB; + } else if (channelCount === 4) { + pixelFormat = PixelFormat.RGBA; + } + + const maximumTextureMemoryByteLength = 512 * 1024 * 1024; + const defaultTextureMemoryByteLength = 128 * 1024 * 1024; + textureMemoryByteLength = Math.min( + defaultValue(textureMemoryByteLength, defaultTextureMemoryByteLength), + maximumTextureMemoryByteLength + ); + const maximumTextureDimensionContext = ContextLimits.maximumTextureSize; + const componentTypeByteLength = MetadataComponentType.getSizeInBytes( + componentType + ); + const texelCount = Math.floor( + textureMemoryByteLength / (channelCount * componentTypeByteLength) + ); + const textureDimension = Math.min( + maximumTextureDimensionContext, + CesiumMath.previousPowerOfTwo(Math.floor(Math.sqrt(texelCount))) + ); + + const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.x)); + const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); + const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; + const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; + const regionCountPerMegatextureX = Math.floor( + textureDimension / voxelCountPerRegionX + ); + const regionCountPerMegatextureY = Math.floor( + textureDimension / voxelCountPerRegionY + ); + + // TODO can this happen? + if (regionCountPerMegatextureX === 0 || regionCountPerMegatextureY === 0) { + throw new RuntimeError("Tileset is too large to fit into megatexture"); + } + + /** + * @type {Number} + * @readonly + */ + this.channelCount = channelCount; + + /** + * @type {MetadataComponentType} + * @readonly + */ + this.componentType = componentType; + + /** + * @type {Cartesian3} + * @readonly + */ + this.voxelCountPerTile = Cartesian3.clone(dimensions, new Cartesian3()); + + /** + * @type {Number} + * @readonly + */ + this.maximumTileCount = + regionCountPerMegatextureX * regionCountPerMegatextureY; + + /** + * @type {Cartesian2} + * @readonly + */ + this.regionCountPerMegatexture = new Cartesian2( + regionCountPerMegatextureX, + regionCountPerMegatextureY + ); + + /** + * @type {Cartesian2} + * @readonly + */ + this.voxelCountPerRegion = new Cartesian2( + voxelCountPerRegionX, + voxelCountPerRegionY + ); + + /** + * @type {Cartesian2} + * @readonly + */ + this.sliceCountPerRegion = new Cartesian2( + sliceCountPerRegionX, + sliceCountPerRegionY + ); + + /** + * @type {Cartesian2} + * @readonly + */ + this.voxelSizeUv = new Cartesian2( + 1.0 / textureDimension, + 1.0 / textureDimension + ); + + /** + * @type {Cartesian2} + * @readonly + */ + this.sliceSizeUv = new Cartesian2( + dimensions.x / textureDimension, + dimensions.y / textureDimension + ); + + /** + * @type {Cartesian2} + * @readonly + */ + this.regionSizeUv = new Cartesian2( + voxelCountPerRegionX / textureDimension, + voxelCountPerRegionY / textureDimension + ); + + /** + * @type {Texture} + * @readonly + */ + this.texture = new Texture({ + context: context, + pixelFormat: pixelFormat, + pixelDatatype: pixelType, + flipY: false, + width: textureDimension, + height: textureDimension, + sampler: new Sampler({ + wrapS: TextureWrap.CLAMP_TO_EDGE, + wrapT: TextureWrap.CLAMP_TO_EDGE, + minificationFilter: TextureMinificationFilter.LINEAR, + magnificationFilter: TextureMagnificationFilter.LINEAR, + }), + }); + + const ArrayType = MetadataComponentType.toTypedArrayType(componentType); + + /** + * @type {Array} + */ + this.tileVoxelDataTemp = new ArrayType( + voxelCountPerRegionX * voxelCountPerRegionY * channelCount + ); + + /** + * @type {MegatextureNode[]} + * @readonly + */ + this.nodes = new Array(this.maximumTileCount); + for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { + this.nodes[tileIndex] = new MegatextureNode(tileIndex); + } + for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { + const node = this.nodes[tileIndex]; + node.previousNode = tileIndex > 0 ? this.nodes[tileIndex - 1] : undefined; + node.nextNode = + tileIndex < this.maximumTileCount - 1 + ? this.nodes[tileIndex + 1] + : undefined; + } + + /** + * @type {MegatextureNode} + * @readonly + */ + this.occupiedList = undefined; + + /** + * @type {MegatextureNode} + * @readonly + */ + this.emptyList = this.nodes[0]; + + /** + * @type {Number} + * @readonly + */ + this.occupiedCount = 0; +} + +/** + * @alias MegatextureNode + * @constructor + * + * @param {Number} index + * + * @private + */ +function MegatextureNode(index) { + /** + * @type {Number} + */ + this.index = index; + + /** + * @type {MegatextureNode} + */ + this.nextNode = undefined; + + /** + * @type {MegatextureNode} + */ + this.previousNode = undefined; +} + +/** + * @param {Array} data + * @returns {Number} + */ +Megatexture.prototype.add = function (data) { + if (this.isFull()) { + throw new DeveloperError("Trying to add when there are no empty spots"); + } + + // remove head of empty list + const node = this.emptyList; + this.emptyList = this.emptyList.nextNode; + if (defined(this.emptyList)) { + this.emptyList.previousNode = undefined; + } + + // make head of occupied list + node.nextNode = this.occupiedList; + if (defined(node.nextNode)) { + node.nextNode.previousNode = node; + } + this.occupiedList = node; + + const index = node.index; + this.writeDataToTexture(index, data); + + this.occupiedCount++; + return index; +}; + +/** + * @param {Number} index + */ +Megatexture.prototype.remove = function (index) { + if (index < 0 || index >= this.maximumTileCount) { + throw new DeveloperError("Megatexture index out of bounds"); + } + + // remove from list + const node = this.nodes[index]; + if (defined(node.previousNode)) { + node.previousNode.nextNode = node.nextNode; + } + if (defined(node.nextNode)) { + node.nextNode.previousNode = node.previousNode; + } + + // make head of empty list + node.nextNode = this.emptyList; + if (defined(node.nextNode)) { + node.nextNode.previousNode = node; + } + node.previousNode = undefined; + this.emptyList = node; + this.occupiedCount--; +}; + +/** + * @returns {Boolean} + */ +Megatexture.prototype.isFull = function () { + return this.emptyList === undefined; +}; + +/** + * @param {Number} tileCount + * @param {Cartesian3} dimensions + * @param {Number} channelCount number of channels in the metadata. Must be 1 to 4. + * @param {MetadataComponentType} componentType + * @returns {Number} + */ +Megatexture.getApproximateTextureMemoryByteLength = function ( + tileCount, + dimensions, + channelCount, + componentType +) { + // TODO there's a lot of code duplicate with Megatexture constructor + + // Unsigned short textures not allowed in webgl 1, so treat as float + if (componentType === MetadataComponentType.UNSIGNED_SHORT) { + componentType = MetadataComponentType.FLOAT32; + } + + const datatypeSizeInBytes = MetadataComponentType.getSizeInBytes( + componentType + ); + const voxelCountTotal = + tileCount * dimensions.x * dimensions.y * dimensions.z; + + const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.z)); + const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); + const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; + const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; + + // Find the power of two that can fit all tile data, accounting for slices. + // There's probably a non-iterative solution for this, but this is good enough for now. + let textureDimension = CesiumMath.previousPowerOfTwo( + Math.floor(Math.sqrt(voxelCountTotal)) + ); + for (;;) { + const regionCountX = Math.floor(textureDimension / voxelCountPerRegionX); + const regionCountY = Math.floor(textureDimension / voxelCountPerRegionY); + const regionCount = regionCountX * regionCountY; + if (regionCount >= tileCount) { + break; + } else { + textureDimension *= 2; + } + } + + const textureMemoryByteLength = + textureDimension * textureDimension * channelCount * datatypeSizeInBytes; + return textureMemoryByteLength; +}; + +/** + * @param {Number} index + * @param {Float32Array|Uint16Array|Uint8Array} data + */ +Megatexture.prototype.writeDataToTexture = function (index, data) { + const texture = this.texture; + const channelCount = this.channelCount; + const regionDimensionsPerMegatexture = this.regionCountPerMegatexture; + const voxelDimensionsPerRegion = this.voxelCountPerRegion; + const voxelDimensionsPerTile = this.voxelCountPerTile; + const sliceDimensionsPerRegion = this.sliceCountPerRegion; + + let tileData = data; + + // Unsigned short textures not allowed in webgl 1, so treat as float + if (data.constructor === Uint16Array) { + const elementCount = data.length; + tileData = new Float32Array(elementCount); + for (let i = 0; i < elementCount / channelCount; i++) { + for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) { + const dataIndex = i * channelCount + channelIndex; + const minimumValue = this.minimumValues[channelIndex]; + const maximumValue = this.maximumValues[channelIndex]; + // TODO extrema are unnormalized, but we are normalizing to [0, 1] here. what do we want to do? will the user expect to get normalized samples and extrema in the style function? + tileData[dataIndex] = + (data[dataIndex] - minimumValue) / (maximumValue - minimumValue); + // tileData[dataIndex] = CesiumMath.lerp( + // minimumValue, + // maximumValue, + // data[dataIndex] / 65535 + // ); + } + } + } + + const tileVoxelData = this.tileVoxelDataTemp; + for (let z = 0; z < voxelDimensionsPerTile.z; z++) { + const sliceVoxelOffsetX = + (z % sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.x; + const sliceVoxelOffsetY = + Math.floor(z / sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.y; + for (let y = 0; y < voxelDimensionsPerTile.y; y++) { + for (let x = 0; x < voxelDimensionsPerTile.x; x++) { + const readIndex = + z * voxelDimensionsPerTile.y * voxelDimensionsPerTile.x + + y * voxelDimensionsPerTile.x + + x; + const writeIndex = + (sliceVoxelOffsetY + y) * voxelDimensionsPerRegion.x + + (sliceVoxelOffsetX + x); + for (let c = 0; c < channelCount; c++) { + tileVoxelData[writeIndex * channelCount + c] = + tileData[readIndex * channelCount + c]; + } + } + } + } + + const voxelWidth = voxelDimensionsPerRegion.x; + const voxelHeight = voxelDimensionsPerRegion.y; + const voxelOffsetX = + (index % regionDimensionsPerMegatexture.x) * voxelDimensionsPerRegion.x; + const voxelOffsetY = + Math.floor(index / regionDimensionsPerMegatexture.x) * + voxelDimensionsPerRegion.y; + + const source = { + arrayBufferView: tileVoxelData, + width: voxelWidth, + height: voxelHeight, + }; + + const copyOptions = { + source: source, + xOffset: voxelOffsetX, + yOffset: voxelOffsetY, + }; + + texture.copyFrom(copyOptions); +}; + +/** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see Megatexture#destroy + */ +Megatexture.prototype.isDestroyed = function () { + return false; +}; + +/** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see Megatexture#isDestroyed + * + * @example + * megatexture = megatexture && megatexture.destroy(); + */ +Megatexture.prototype.destroy = function () { + this.texture = this.texture && this.texture.destroy(); + return destroyObject(this); +}; + +export default Megatexture; diff --git a/Source/Scene/SpatialNode.js b/Source/Scene/SpatialNode.js new file mode 100644 index 00000000000..3b4a417fb15 --- /dev/null +++ b/Source/Scene/SpatialNode.js @@ -0,0 +1,434 @@ +import binarySearch from "../Core/binarySearch.js"; +import Cartesian3 from "../Core/Cartesian3.js"; +import CesiumMath from "../Core/Math.js"; +import defined from "../Core/defined.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import KeyframeNode from "./KeyframeNode"; +import Matrix3 from "../Core/Matrix3.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; + +/** + * @alias SpatialNode + * @constructor + * + * @param {Number} level + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {SpatialNode} parent + * @param {VoxelShapeType} shape + * + * @private + */ +function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { + /** + * @ignore + * @type {SpatialNode[]} + */ + this.children = undefined; + this.parent = parent; + + this.level = level; + this.x = x; + this.y = y; + this.z = z; + + /** + * @ignore + * @type {KeyframeNode[]} + */ + this.keyframeNodes = []; + /** + * @ignore + * @type {KeyframeNode[]} + */ + this.renderableKeyframeNodes = []; + + this.renderableKeyframeNodeLerp = 0.0; + /** + * @ignore + * @type {KeyframeNode} + */ + this.renderableKeyframeNodePrevious = undefined; + /** + * @ignore + * @type {KeyframeNode} + */ + this.renderableKeyframeNodeNext = undefined; + + this.orientedBoundingBox = new OrientedBoundingBox(); + this.approximateVoxelSize = 0.0; + this.screenSpaceError = 0.0; + this.visitedFrameNumber = -1; + + this.computeBoundingVolumes(shape, voxelDimensions); +} + +/** + * @param {SpatialNode} a + * @param {SpatialNode} b + * @returns {Boolean} + */ +SpatialNode.spatialComparator = function (a, b) { + // The higher of the two screen space errors is prioritized + return b.screenSpaceError - a.screenSpaceError; +}; + +const scratchObbHalfScale = new Cartesian3(); + +/** + * @param {VoxelShape} shape + * @param {Cartesian3} voxelDimensions + */ +SpatialNode.prototype.computeBoundingVolumes = function ( + shape, + voxelDimensions +) { + this.orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( + this.level, + this.x, + this.y, + this.z, + this.orientedBoundingBox + ); + + const halfScale = Matrix3.getScale( + this.orientedBoundingBox.halfAxes, + scratchObbHalfScale + ); + const maximumScale = 2.0 * Cartesian3.maximumComponent(halfScale); + this.approximateVoxelSize = + maximumScale / Cartesian3.minimumComponent(voxelDimensions); +}; + +/** + * @param {FrameState} frameState + * @param {Number} visibilityPlaneMask + * @returns {Number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. + */ +SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { + const obb = this.orientedBoundingBox; + const cullingVolume = frameState.cullingVolume; + return cullingVolume.computeVisibilityWithPlaneMask(obb, visibilityPlaneMask); +}; + +/** + * @param {Cartesian3} cameraPosition + * @param {Number} screenSpaceErrorMultiplier + */ +SpatialNode.prototype.computeScreenSpaceError = function ( + cameraPosition, + screenSpaceErrorMultiplier +) { + const obb = this.orientedBoundingBox; + + let distance = Math.sqrt(obb.distanceSquaredTo(cameraPosition)); + // Avoid divide-by-zero when viewer is inside the tile. + distance = Math.max(distance, CesiumMath.EPSILON7); + const approximateVoxelSize = this.approximateVoxelSize; + const error = screenSpaceErrorMultiplier * (approximateVoxelSize / distance); + this.screenSpaceError = error; +}; + +// This object imitates a KeyframeNode. Only used for binary search function. +const scratchBinarySearchKeyframeNode = { + keyframe: 0, +}; + +/** + * Finds the index of the keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. + * + * @param {Number} keyframe + * @returns {Number} + */ +SpatialNode.prototype.findKeyframeIndex = function (keyframe) { + const keyframeNodes = this.keyframeNodes; + scratchBinarySearchKeyframeNode.keyframe = keyframe; + const index = binarySearch( + keyframeNodes, + scratchBinarySearchKeyframeNode, + KeyframeNode.searchComparator + ); + return index; +}; + +/** + * Finds the index of the renderable keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. + * + * @param {Number} keyframe + * @returns {Number} + */ +SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { + const renderableKeyframeNodes = this.renderableKeyframeNodes; + scratchBinarySearchKeyframeNode.keyframe = keyframe; + const index = binarySearch( + renderableKeyframeNodes, + scratchBinarySearchKeyframeNode, + KeyframeNode.searchComparator + ); + return index; +}; + +/** + * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. + * + * @param {Number} keyframeLocation + */ +SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( + keyframeLocation +) { + let spatialNode = this; + const startLevel = spatialNode.level; + + const targetKeyframePrev = Math.floor(keyframeLocation); + const targetKeyframeNext = Math.ceil(keyframeLocation); + + let bestKeyframeNodePrev; + let bestKeyframeNodeNext; + let minimumDistancePrev = +Number.MAX_VALUE; + let minimumDistanceNext = +Number.MAX_VALUE; + + while (defined(spatialNode)) { + const renderableKeyframeNodes = spatialNode.renderableKeyframeNodes; + + if (renderableKeyframeNodes.length >= 1) { + let keyframeNodeIndexPrev = spatialNode.findRenderableKeyframeIndex( + targetKeyframePrev + ); + if (keyframeNodeIndexPrev < 0) { + keyframeNodeIndexPrev = CesiumMath.clamp( + ~keyframeNodeIndexPrev - 1, + 0, + renderableKeyframeNodes.length - 1 + ); + } + const keyframeNodePrev = renderableKeyframeNodes[keyframeNodeIndexPrev]; + const keyframePrev = keyframeNodePrev.keyframe; + + let keyframeNodeNext; + if ( + targetKeyframeNext === targetKeyframePrev || + targetKeyframePrev < keyframePrev + ) { + keyframeNodeNext = keyframeNodePrev; + } else { + const keyframeNodeIndexNext = Math.min( + keyframeNodeIndexPrev + 1, + renderableKeyframeNodes.length - 1 + ); + keyframeNodeNext = renderableKeyframeNodes[keyframeNodeIndexNext]; + } + const keyframeNext = keyframeNodeNext.keyframe; + + const keyframeDistancePrev = targetKeyframePrev - keyframePrev; + const keyframeDistanceNext = keyframeNext - targetKeyframeNext; + const levelDistance = startLevel - spatialNode.level; + + // Balance temporal and visual quality + const levelWeight = Math.exp(levelDistance * 4.0); + const normalKeyframeWeight = 1.0; + const reverseKeyframeWeight = 200.0; // Keyframes on the opposite of the desired direction are deprioritized. + const distancePrev = + levelDistance * levelWeight + + (keyframeDistancePrev >= 0 + ? keyframeDistancePrev * normalKeyframeWeight + : -keyframeDistancePrev * reverseKeyframeWeight); + const distanceNext = + levelDistance * levelWeight + + (keyframeDistanceNext >= 0 + ? keyframeDistanceNext * normalKeyframeWeight + : -keyframeDistanceNext * reverseKeyframeWeight); + + // // Prioritize visual quality + // const distancePrev = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; + // const distanceNext = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; + + // // Prioritize temporal quality + // const distancePrev = keyframeDistancePrev >= 0 ? keyframeDistancePrev : Number.MAX_VALUE + keyframeDistancePrev; + // const distanceNext = keyframeDistanceNext >= 0 ? keyframeDistanceNext : Number.MAX_VALUE + keyframeDistanceNext; + + if (distancePrev < minimumDistancePrev) { + minimumDistancePrev = distancePrev; + bestKeyframeNodePrev = keyframeNodePrev; + } + if (distanceNext < minimumDistanceNext) { + minimumDistanceNext = distanceNext; + bestKeyframeNodeNext = keyframeNodeNext; + } + if (keyframeDistancePrev === 0 && keyframeDistanceNext === 0) { + // Nothing higher up will be better, so break early. + break; + } + } + + spatialNode = spatialNode.parent; + } + + this.renderableKeyframeNodePrevious = bestKeyframeNodePrev; + this.renderableKeyframeNodeNext = bestKeyframeNodeNext; + if (defined(bestKeyframeNodePrev) && defined(bestKeyframeNodeNext)) { + const bestKeyframePrev = bestKeyframeNodePrev.keyframe; + const bestKeyframeNext = bestKeyframeNodeNext.keyframe; + this.renderableKeyframeNodeLerp = + bestKeyframePrev === bestKeyframeNext + ? 0.0 + : CesiumMath.clamp( + (keyframeLocation - bestKeyframePrev) / + (bestKeyframeNext - bestKeyframePrev), + 0.0, + 1.0 + ); + } +}; + +/** + * @param {Number} frameNumber + * @returns {Boolean} + */ +SpatialNode.prototype.isVisited = function (frameNumber) { + return this.visitedFrameNumber === frameNumber; +}; + +/** + * @param {Number} keyframe + */ +SpatialNode.prototype.createKeyframeNode = function (keyframe) { + let index = this.findKeyframeIndex(keyframe); + if (index < 0) { + index = ~index; // convert to insertion index + const keyframeNode = new KeyframeNode(this, keyframe); + this.keyframeNodes.splice(index, 0, keyframeNode); + } +}; +/** + * @param {KeyframeNode} keyframeNode + * @param {Megatexture} megatexture + */ +SpatialNode.prototype.destroyKeyframeNode = function ( + keyframeNode, + megatextures +) { + const keyframe = keyframeNode.keyframe; + const keyframeIndex = this.findKeyframeIndex(keyframe); + if (keyframeIndex < 0) { + throw new DeveloperError("Keyframe node does not exist."); + } + + const keyframeNodes = this.keyframeNodes; + keyframeNodes.splice(keyframeIndex, 1); + + if (keyframeNode.megatextureIndex !== -1) { + const megatextureArray = Object.keys(megatextures).map(function (key) { + return megatextures[key]; + }); // Object.values workaround + const numberOfMegatextures = megatextureArray.length; + for (let i = 0; i < numberOfMegatextures; i++) { + megatextureArray[i].remove(keyframeNode.megatextureIndex); + } + + const renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( + keyframe + ); + if (renderableKeyframeNodeIndex < 0) { + throw new DeveloperError("Renderable keyframe node does not exist."); + } + + const renderableKeyframeNodes = this.renderableKeyframeNodes; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); + } + + keyframeNode.spatialNode = undefined; + keyframeNode.state = KeyframeNode.LoadState.UNLOADED; + keyframeNode.metadatas = {}; + keyframeNode.megatextureIndex = -1; + keyframeNode.priority = -Number.MAX_VALUE; + keyframeNode.highPriorityFrameNumber = -1; +}; + +/** + * @param {KeyframeNode} keyframeNode + * @param {Megatexture[]} megatextures + */ +SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( + keyframeNode, + megatextures +) { + if ( + keyframeNode.state !== KeyframeNode.LoadState.RECEIVED || + keyframeNode.megatextureIndex !== -1 || + keyframeNode.metadatas.length !== megatextures.length + ) { + throw new DeveloperError("Keyframe node cannot be added to megatexture"); + } + + const length = megatextures.length; + for (let i = 0; i < length; i++) { + const megatexture = megatextures[i]; + keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadatas[i]); + keyframeNode.metadatas[i] = undefined; // data is in megatexture so no need to hold onto it + } + + keyframeNode.state = KeyframeNode.LoadState.LOADED; + + const renderableKeyframeNodes = this.renderableKeyframeNodes; + let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( + keyframeNode.keyframe + ); + if (renderableKeyframeNodeIndex >= 0) { + throw new DeveloperError("Keyframe already renderable"); + } + renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); +}; + +/** + * @param {KeyframeNode} keyframeNode + * @param {Megatexture} megatexture + */ +SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( + keyframeNode, + megatexture +) { + if ( + keyframeNode.state !== KeyframeNode.LoadState.RECEIVED || + keyframeNode.megatextureIndex !== -1 || + !defined(keyframeNode.metadatas[megatexture.metadataName]) + ) { + throw new DeveloperError("Keyframe node cannot be added to megatexture"); + } + + keyframeNode.megatextureIndex = megatexture.add( + keyframeNode.metadatas[megatexture.metadataName] + ); + keyframeNode.metadatas[megatexture.metadataName] = undefined; // data is in megatexture so no need to hold onto it + keyframeNode.state = KeyframeNode.LoadState.LOADED; + + const renderableKeyframeNodes = this.renderableKeyframeNodes; + let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( + keyframeNode.keyframe + ); + if (renderableKeyframeNodeIndex >= 0) { + throw new DeveloperError("Keyframe already renderable"); + } + renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; + renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); +}; + +/** + * @param {Number} frameNumber + */ +SpatialNode.prototype.isRenderable = function (frameNumber) { + const previousNode = this.renderableKeyframeNodePrevious; + const nextNode = this.renderableKeyframeNodeNext; + const level = this.level; + + return ( + defined(previousNode) && + defined(nextNode) && + (previousNode.spatialNode.level === level || + nextNode.spatialNode.level === level) && + this.visitedFrameNumber === frameNumber + ); +}; + +export default SpatialNode; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index df2472a339d..c817568380a 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -1,27 +1,20 @@ -import binarySearch from "../Core/binarySearch.js"; import Cartesian2 from "../Core/Cartesian2.js"; -import Cartesian3 from "../Core/Cartesian3.js"; import CesiumMath from "../Core/Math.js"; import CullingVolume from "../Core/CullingVolume.js"; -import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; -import DeveloperError from "../Core/DeveloperError.js"; import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; import getTimestamp from "../Core/getTimestamp.js"; -import Matrix3 from "../Core/Matrix3.js"; -import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; +import KeyframeNode from "./KeyframeNode.js"; +import MetadataType from "./MetadataType.js"; +import Megatexture from "./Megatexture.js"; import PixelFormat from "../Core/PixelFormat.js"; -import RuntimeError from "../Core/RuntimeError.js"; -import ContextLimits from "../Renderer/ContextLimits.js"; import PixelDatatype from "../Renderer/PixelDatatype.js"; import Sampler from "../Renderer/Sampler.js"; +import SpatialNode from "./SpatialNode.js"; import Texture from "../Renderer/Texture.js"; -import TextureWrap from "../Renderer/TextureWrap.js"; import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js"; import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; -import MetadataType from "./MetadataType.js"; -import MetadataComponentType from "./MetadataComponentType.js"; /** * Handles tileset traversal, tile requests, and GPU resources. Intended to be @@ -443,12 +436,12 @@ function requestData(that, keyframeNode) { const length = primitive._provider.types.length; if (!defined(result)) { - keyframeNode.state = VoxelTraversal.LoadState.UNAVAILABLE; - } else if (result === VoxelTraversal.LoadState.FAILED) { - keyframeNode.state = VoxelTraversal.LoadState.FAILED; + keyframeNode.state = KeyframeNode.LoadState.UNAVAILABLE; + } else if (result === KeyframeNode.LoadState.FAILED) { + keyframeNode.state = KeyframeNode.LoadState.FAILED; } else if (!Array.isArray(result) || result.length !== length) { // TODO should this throw runtime error? - keyframeNode.state = VoxelTraversal.LoadState.FAILED; + keyframeNode.state = KeyframeNode.LoadState.FAILED; } else { const megatextures = that.megatextures; for (let i = 0; i < length; i++) { @@ -463,9 +456,9 @@ function requestData(that, keyframeNode) { if (data.length === expectedLength) { keyframeNode.metadatas[i] = data; // State is received only when all metadata requests have been received - keyframeNode.state = VoxelTraversal.LoadState.RECEIVED; + keyframeNode.state = KeyframeNode.LoadState.RECEIVED; } else { - keyframeNode.state = VoxelTraversal.LoadState.FAILED; + keyframeNode.state = KeyframeNode.LoadState.FAILED; break; } } @@ -474,7 +467,7 @@ function requestData(that, keyframeNode) { const postRequestFailure = function () { that._simultaneousRequestCount--; - keyframeNode.state = VoxelTraversal.LoadState.FAILED; + keyframeNode.state = KeyframeNode.LoadState.FAILED; }; const promise = provider.requestData({ @@ -487,10 +480,10 @@ function requestData(that, keyframeNode) { if (defined(promise)) { that._simultaneousRequestCount++; - keyframeNode.state = VoxelTraversal.LoadState.RECEIVING; + keyframeNode.state = KeyframeNode.LoadState.RECEIVING; promise.then(postRequestSuccess).catch(postRequestFailure); } else { - keyframeNode.state = VoxelTraversal.LoadState.FAILED; + keyframeNode.state = KeyframeNode.LoadState.FAILED; } } @@ -626,13 +619,13 @@ function loadAndUnload(that, frameState) { ); if ( - keyframeNode.state !== VoxelTraversal.LoadState.UNAVAILABLE && - keyframeNode.state !== VoxelTraversal.LoadState.FAILED && + keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE && + keyframeNode.state !== KeyframeNode.LoadState.FAILED && keyframeNode.priority !== -Number.MAX_VALUE ) { priorityQueue.insert(keyframeNode); } - if (keyframeNode.state === VoxelTraversal.LoadState.LOADED) { + if (keyframeNode.state === KeyframeNode.LoadState.LOADED) { hasLoadedKeyframe = true; } } @@ -773,17 +766,17 @@ function loadAndUnload(that, frameState) { highPriorityKeyframeNodes[highPriorityKeyframeNodeIndex]; if ( - highPriorityKeyframeNode.state === VoxelTraversal.LoadState.LOADED || + highPriorityKeyframeNode.state === KeyframeNode.LoadState.LOADED || highPriorityKeyframeNode.spatialNode === undefined ) { // Already loaded, so nothing to do. // Or destroyed when adding a higher priority node continue; } - if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.UNLOADED) { + if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.UNLOADED) { requestData(that, highPriorityKeyframeNode); } - if (highPriorityKeyframeNode.state === VoxelTraversal.LoadState.RECEIVED) { + if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.RECEIVED) { let addNodeIndex = 0; if (megatexture.isFull()) { // If the megatexture is full, try removing a discardable node with the lowest priority. @@ -824,7 +817,7 @@ function printDebugInformation( const keyframeCount = that._keyframeCount; const rootNode = that.rootNode; - const loadStateCount = Object.keys(VoxelTraversal.LoadState).length; + const loadStateCount = Object.keys(KeyframeNode.LoadState).length; const loadStatesByKeyframe = new Array(loadStateCount); const loadStateByCount = new Array(loadStateCount); let nodeCountTotal = 0; @@ -871,17 +864,15 @@ function printDebugInformation( traverseRecursive(rootNode); const loadedKeyframeStatistics = `KEYFRAMES: ${ - loadStatesByKeyframe[VoxelTraversal.LoadState.LOADED] + loadStatesByKeyframe[KeyframeNode.LoadState.LOADED] }`; const loadStateStatistics = - `UNLOADED: ${loadStateByCount[VoxelTraversal.LoadState.UNLOADED]} | ` + - `RECEIVING: ${loadStateByCount[VoxelTraversal.LoadState.RECEIVING]} | ` + - `RECEIVED: ${loadStateByCount[VoxelTraversal.LoadState.RECEIVED]} | ` + - `LOADED: ${loadStateByCount[VoxelTraversal.LoadState.LOADED]} | ` + - `FAILED: ${loadStateByCount[VoxelTraversal.LoadState.FAILED]} | ` + - `UNAVAILABLE: ${ - loadStateByCount[VoxelTraversal.LoadState.UNAVAILABLE] - } | ` + + `UNLOADED: ${loadStateByCount[KeyframeNode.LoadState.UNLOADED]} | ` + + `RECEIVING: ${loadStateByCount[KeyframeNode.LoadState.RECEIVING]} | ` + + `RECEIVED: ${loadStateByCount[KeyframeNode.LoadState.RECEIVED]} | ` + + `LOADED: ${loadStateByCount[KeyframeNode.LoadState.LOADED]} | ` + + `FAILED: ${loadStateByCount[KeyframeNode.LoadState.FAILED]} | ` + + `UNAVAILABLE: ${loadStateByCount[KeyframeNode.LoadState.UNAVAILABLE]} | ` + `TOTAL: ${nodeCountTotal}`; const loadAndUnloadTimeMsRounded = @@ -900,474 +891,6 @@ function printDebugInformation( ); } -VoxelTraversal.LoadState = { - UNLOADED: 0, // Has no data and is in dormant state - RECEIVING: 1, // Is waiting on data from the provider - RECEIVED: 2, // Received data from the provider - LOADED: 3, // Processed data from provider - FAILED: 4, // Failed to receive data from the provider - UNAVAILABLE: 5, // No data available for this tile -}; - -/** - * @alias SpatialNode - * @constructor - * - * @param {Number} level - * @param {Number} x - * @param {Number} y - * @param {Number} z - * @param {SpatialNode} parent - * @param {VoxelShapeType} shape - * - * @private - */ -function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { - /** - * @ignore - * @type {SpatialNode[]} - */ - this.children = undefined; - this.parent = parent; - - this.level = level; - this.x = x; - this.y = y; - this.z = z; - - /** - * @ignore - * @type {KeyframeNode[]} - */ - this.keyframeNodes = []; - /** - * @ignore - * @type {KeyframeNode[]} - */ - this.renderableKeyframeNodes = []; - - this.renderableKeyframeNodeLerp = 0.0; - /** - * @ignore - * @type {KeyframeNode} - */ - this.renderableKeyframeNodePrevious = undefined; - /** - * @ignore - * @type {KeyframeNode} - */ - this.renderableKeyframeNodeNext = undefined; - - this.orientedBoundingBox = new OrientedBoundingBox(); - this.approximateVoxelSize = 0.0; - this.screenSpaceError = 0.0; - this.visitedFrameNumber = -1; - - this.computeBoundingVolumes(shape, voxelDimensions); -} - -/** - * @param {SpatialNode} a - * @param {SpatialNode} b - * @returns {Boolean} - */ -SpatialNode.spatialComparator = function (a, b) { - // The higher of the two screen space errors is prioritized - return b.screenSpaceError - a.screenSpaceError; -}; - -const scratchObbHalfScale = new Cartesian3(); - -/** - * @param {VoxelShape} shape - * @param {Cartesian3} voxelDimensions - */ -SpatialNode.prototype.computeBoundingVolumes = function ( - shape, - voxelDimensions -) { - this.orientedBoundingBox = shape.computeOrientedBoundingBoxForTile( - this.level, - this.x, - this.y, - this.z, - this.orientedBoundingBox - ); - - const halfScale = Matrix3.getScale( - this.orientedBoundingBox.halfAxes, - scratchObbHalfScale - ); - const maximumScale = 2.0 * Cartesian3.maximumComponent(halfScale); - this.approximateVoxelSize = - maximumScale / Cartesian3.minimumComponent(voxelDimensions); -}; - -/** - * @param {FrameState} frameState - * @param {Number} visibilityPlaneMask - * @returns {Number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. - */ -SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { - const obb = this.orientedBoundingBox; - const cullingVolume = frameState.cullingVolume; - return cullingVolume.computeVisibilityWithPlaneMask(obb, visibilityPlaneMask); -}; - -/** - * @param {Cartesian3} cameraPosition - * @param {Number} screenSpaceErrorMultiplier - */ -SpatialNode.prototype.computeScreenSpaceError = function ( - cameraPosition, - screenSpaceErrorMultiplier -) { - const obb = this.orientedBoundingBox; - - let distance = Math.sqrt(obb.distanceSquaredTo(cameraPosition)); - // Avoid divide-by-zero when viewer is inside the tile. - distance = Math.max(distance, CesiumMath.EPSILON7); - const approximateVoxelSize = this.approximateVoxelSize; - const error = screenSpaceErrorMultiplier * (approximateVoxelSize / distance); - this.screenSpaceError = error; -}; - -// This object imitates a KeyframeNode. Only used for binary search function. -const scratchBinarySearchKeyframeNode = { - keyframe: 0, -}; - -/** - * Finds the index of the keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * - * @param {Number} keyframe - * @returns {Number} - */ -SpatialNode.prototype.findKeyframeIndex = function (keyframe) { - const keyframeNodes = this.keyframeNodes; - scratchBinarySearchKeyframeNode.keyframe = keyframe; - const index = binarySearch( - keyframeNodes, - scratchBinarySearchKeyframeNode, - KeyframeNode.searchComparator - ); - return index; -}; - -/** - * Finds the index of the renderable keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * - * @param {Number} keyframe - * @returns {Number} - */ -SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { - const renderableKeyframeNodes = this.renderableKeyframeNodes; - scratchBinarySearchKeyframeNode.keyframe = keyframe; - const index = binarySearch( - renderableKeyframeNodes, - scratchBinarySearchKeyframeNode, - KeyframeNode.searchComparator - ); - return index; -}; - -/** - * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. - * - * @param {Number} keyframeLocation - */ -SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( - keyframeLocation -) { - let spatialNode = this; - const startLevel = spatialNode.level; - - const targetKeyframePrev = Math.floor(keyframeLocation); - const targetKeyframeNext = Math.ceil(keyframeLocation); - - let bestKeyframeNodePrev; - let bestKeyframeNodeNext; - let minimumDistancePrev = +Number.MAX_VALUE; - let minimumDistanceNext = +Number.MAX_VALUE; - - while (defined(spatialNode)) { - const renderableKeyframeNodes = spatialNode.renderableKeyframeNodes; - - if (renderableKeyframeNodes.length >= 1) { - let keyframeNodeIndexPrev = spatialNode.findRenderableKeyframeIndex( - targetKeyframePrev - ); - if (keyframeNodeIndexPrev < 0) { - keyframeNodeIndexPrev = CesiumMath.clamp( - ~keyframeNodeIndexPrev - 1, - 0, - renderableKeyframeNodes.length - 1 - ); - } - const keyframeNodePrev = renderableKeyframeNodes[keyframeNodeIndexPrev]; - const keyframePrev = keyframeNodePrev.keyframe; - - let keyframeNodeNext; - if ( - targetKeyframeNext === targetKeyframePrev || - targetKeyframePrev < keyframePrev - ) { - keyframeNodeNext = keyframeNodePrev; - } else { - const keyframeNodeIndexNext = Math.min( - keyframeNodeIndexPrev + 1, - renderableKeyframeNodes.length - 1 - ); - keyframeNodeNext = renderableKeyframeNodes[keyframeNodeIndexNext]; - } - const keyframeNext = keyframeNodeNext.keyframe; - - const keyframeDistancePrev = targetKeyframePrev - keyframePrev; - const keyframeDistanceNext = keyframeNext - targetKeyframeNext; - const levelDistance = startLevel - spatialNode.level; - - // Balance temporal and visual quality - const levelWeight = Math.exp(levelDistance * 4.0); - const normalKeyframeWeight = 1.0; - const reverseKeyframeWeight = 200.0; // Keyframes on the opposite of the desired direction are deprioritized. - const distancePrev = - levelDistance * levelWeight + - (keyframeDistancePrev >= 0 - ? keyframeDistancePrev * normalKeyframeWeight - : -keyframeDistancePrev * reverseKeyframeWeight); - const distanceNext = - levelDistance * levelWeight + - (keyframeDistanceNext >= 0 - ? keyframeDistanceNext * normalKeyframeWeight - : -keyframeDistanceNext * reverseKeyframeWeight); - - // // Prioritize visual quality - // const distancePrev = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; - // const distanceNext = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; - - // // Prioritize temporal quality - // const distancePrev = keyframeDistancePrev >= 0 ? keyframeDistancePrev : Number.MAX_VALUE + keyframeDistancePrev; - // const distanceNext = keyframeDistanceNext >= 0 ? keyframeDistanceNext : Number.MAX_VALUE + keyframeDistanceNext; - - if (distancePrev < minimumDistancePrev) { - minimumDistancePrev = distancePrev; - bestKeyframeNodePrev = keyframeNodePrev; - } - if (distanceNext < minimumDistanceNext) { - minimumDistanceNext = distanceNext; - bestKeyframeNodeNext = keyframeNodeNext; - } - if (keyframeDistancePrev === 0 && keyframeDistanceNext === 0) { - // Nothing higher up will be better, so break early. - break; - } - } - - spatialNode = spatialNode.parent; - } - - this.renderableKeyframeNodePrevious = bestKeyframeNodePrev; - this.renderableKeyframeNodeNext = bestKeyframeNodeNext; - if (defined(bestKeyframeNodePrev) && defined(bestKeyframeNodeNext)) { - const bestKeyframePrev = bestKeyframeNodePrev.keyframe; - const bestKeyframeNext = bestKeyframeNodeNext.keyframe; - this.renderableKeyframeNodeLerp = - bestKeyframePrev === bestKeyframeNext - ? 0.0 - : CesiumMath.clamp( - (keyframeLocation - bestKeyframePrev) / - (bestKeyframeNext - bestKeyframePrev), - 0.0, - 1.0 - ); - } -}; - -/** - * @param {Number} frameNumber - * @returns {Boolean} - */ -SpatialNode.prototype.isVisited = function (frameNumber) { - return this.visitedFrameNumber === frameNumber; -}; - -/** - * @param {Number} keyframe - */ -SpatialNode.prototype.createKeyframeNode = function (keyframe) { - let index = this.findKeyframeIndex(keyframe); - if (index < 0) { - index = ~index; // convert to insertion index - const keyframeNode = new KeyframeNode(this, keyframe); - this.keyframeNodes.splice(index, 0, keyframeNode); - } -}; -/** - * @param {KeyframeNode} keyframeNode - * @param {Megatexture} megatexture - */ -SpatialNode.prototype.destroyKeyframeNode = function ( - keyframeNode, - megatextures -) { - const keyframe = keyframeNode.keyframe; - const keyframeIndex = this.findKeyframeIndex(keyframe); - if (keyframeIndex < 0) { - throw new DeveloperError("Keyframe node does not exist."); - } - - const keyframeNodes = this.keyframeNodes; - keyframeNodes.splice(keyframeIndex, 1); - - if (keyframeNode.megatextureIndex !== -1) { - const megatextureArray = Object.keys(megatextures).map(function (key) { - return megatextures[key]; - }); // Object.values workaround - const numberOfMegatextures = megatextureArray.length; - for (let i = 0; i < numberOfMegatextures; i++) { - megatextureArray[i].remove(keyframeNode.megatextureIndex); - } - - const renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframe - ); - if (renderableKeyframeNodeIndex < 0) { - throw new DeveloperError("Renderable keyframe node does not exist."); - } - - const renderableKeyframeNodes = this.renderableKeyframeNodes; - renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); - } - - keyframeNode.spatialNode = undefined; - keyframeNode.state = VoxelTraversal.LoadState.UNLOADED; - keyframeNode.metadatas = {}; - keyframeNode.megatextureIndex = -1; - keyframeNode.priority = -Number.MAX_VALUE; - keyframeNode.highPriorityFrameNumber = -1; -}; - -/** - * @param {KeyframeNode} keyframeNode - * @param {Megatexture[]} megatextures - */ -SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( - keyframeNode, - megatextures -) { - if ( - keyframeNode.state !== VoxelTraversal.LoadState.RECEIVED || - keyframeNode.megatextureIndex !== -1 || - keyframeNode.metadatas.length !== megatextures.length - ) { - throw new DeveloperError("Keyframe node cannot be added to megatexture"); - } - - const length = megatextures.length; - for (let i = 0; i < length; i++) { - const megatexture = megatextures[i]; - keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadatas[i]); - keyframeNode.metadatas[i] = undefined; // data is in megatexture so no need to hold onto it - } - - keyframeNode.state = VoxelTraversal.LoadState.LOADED; - - const renderableKeyframeNodes = this.renderableKeyframeNodes; - let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframeNode.keyframe - ); - if (renderableKeyframeNodeIndex >= 0) { - throw new DeveloperError("Keyframe already renderable"); - } - renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; - renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); -}; - -/** - * @param {KeyframeNode} keyframeNode - * @param {Megatexture} megatexture - */ -SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( - keyframeNode, - megatexture -) { - if ( - keyframeNode.state !== VoxelTraversal.LoadState.RECEIVED || - keyframeNode.megatextureIndex !== -1 || - !defined(keyframeNode.metadatas[megatexture.metadataName]) - ) { - throw new DeveloperError("Keyframe node cannot be added to megatexture"); - } - - keyframeNode.megatextureIndex = megatexture.add( - keyframeNode.metadatas[megatexture.metadataName] - ); - keyframeNode.metadatas[megatexture.metadataName] = undefined; // data is in megatexture so no need to hold onto it - keyframeNode.state = VoxelTraversal.LoadState.LOADED; - - const renderableKeyframeNodes = this.renderableKeyframeNodes; - let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframeNode.keyframe - ); - if (renderableKeyframeNodeIndex >= 0) { - throw new DeveloperError("Keyframe already renderable"); - } - renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; - renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); -}; - -/** - * @param {Number} frameNumber - */ -SpatialNode.prototype.isRenderable = function (frameNumber) { - const previousNode = this.renderableKeyframeNodePrevious; - const nextNode = this.renderableKeyframeNodeNext; - const level = this.level; - - return ( - defined(previousNode) && - defined(nextNode) && - (previousNode.spatialNode.level === level || - nextNode.spatialNode.level === level) && - this.visitedFrameNumber === frameNumber - ); -}; - -/** - * @alias KeyframeNode - * @constructor - * - * @param {SpatialNode} spatialNode - * @param {Number} keyframe - * - * @private - */ -function KeyframeNode(spatialNode, keyframe) { - this.spatialNode = spatialNode; - this.keyframe = keyframe; - this.state = VoxelTraversal.LoadState.UNLOADED; - this.metadatas = []; - this.megatextureIndex = -1; - this.priority = -Number.MAX_VALUE; - this.highPriorityFrameNumber = -1; -} - -/** - * @param {KeyframeNode} a - * @param {KeyframeNode} b - */ -KeyframeNode.priorityComparator = function (a, b) { - return a.priority - b.priority; -}; - -/** - * @param {KeyframeNode} a - * @param {KeyframeNode} b - */ -KeyframeNode.searchComparator = function (a, b) { - return a.keyframe - b.keyframe; -}; - // GPU Octree Layout // (shown as binary tree instead of octree for demonstration purposes) // @@ -1696,492 +1219,4 @@ VoxelTraversal.getApproximateTextureMemoryByteLength = function ( return textureMemoryByteLength; }; -/** - * @alias Megatexture - * @constructor - * - * @param {Context} context - * @param {Cartesian3} dimensions - * @param {Number} channelCount - * @param {MetadataComponentType} componentType - * @param {Number} [textureMemoryByteLength] - * - * @private - */ -function Megatexture( - context, - dimensions, - channelCount, - componentType, - textureMemoryByteLength -) { - // TODO there are a lot of texture packing rules, see https://github.com/CesiumGS/cesium/issues/9572 - // Unsigned short textures not allowed in webgl 1, so treat as float - if (componentType === MetadataComponentType.UNSIGNED_SHORT) { - componentType = MetadataComponentType.FLOAT32; - } - - const supportsFloatingPointTexture = context.floatingPointTexture; - if ( - componentType === MetadataComponentType.FLOAT32 && - !supportsFloatingPointTexture - ) { - throw new RuntimeError("Floating point texture not supported"); - } - - // TODO support more - let pixelType; - if ( - componentType === MetadataComponentType.FLOAT32 || - componentType === MetadataComponentType.FLOAT64 - ) { - pixelType = PixelDatatype.FLOAT; - } else if (componentType === MetadataComponentType.UINT8) { - pixelType = PixelDatatype.UNSIGNED_BYTE; - } - - let pixelFormat; - if (channelCount === 1) { - pixelFormat = PixelFormat.LUMINANCE; - } else if (channelCount === 2) { - pixelFormat = PixelFormat.LUMINANCE_ALPHA; - } else if (channelCount === 3) { - pixelFormat = PixelFormat.RGB; - } else if (channelCount === 4) { - pixelFormat = PixelFormat.RGBA; - } - - const maximumTextureMemoryByteLength = 512 * 1024 * 1024; - const defaultTextureMemoryByteLength = 128 * 1024 * 1024; - textureMemoryByteLength = Math.min( - defaultValue(textureMemoryByteLength, defaultTextureMemoryByteLength), - maximumTextureMemoryByteLength - ); - const maximumTextureDimensionContext = ContextLimits.maximumTextureSize; - const componentTypeByteLength = MetadataComponentType.getSizeInBytes( - componentType - ); - const texelCount = Math.floor( - textureMemoryByteLength / (channelCount * componentTypeByteLength) - ); - const textureDimension = Math.min( - maximumTextureDimensionContext, - CesiumMath.previousPowerOfTwo(Math.floor(Math.sqrt(texelCount))) - ); - - const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.x)); - const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); - const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; - const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; - const regionCountPerMegatextureX = Math.floor( - textureDimension / voxelCountPerRegionX - ); - const regionCountPerMegatextureY = Math.floor( - textureDimension / voxelCountPerRegionY - ); - - // TODO can this happen? - if (regionCountPerMegatextureX === 0 || regionCountPerMegatextureY === 0) { - throw new RuntimeError("Tileset is too large to fit into megatexture"); - } - - /** - * @type {Number} - * @readonly - */ - this.channelCount = channelCount; - - /** - * @type {MetadataComponentType} - * @readonly - */ - this.componentType = componentType; - - /** - * @type {Cartesian3} - * @readonly - */ - this.voxelCountPerTile = Cartesian3.clone(dimensions, new Cartesian3()); - - /** - * @type {Number} - * @readonly - */ - this.maximumTileCount = - regionCountPerMegatextureX * regionCountPerMegatextureY; - - /** - * @type {Cartesian2} - * @readonly - */ - this.regionCountPerMegatexture = new Cartesian2( - regionCountPerMegatextureX, - regionCountPerMegatextureY - ); - - /** - * @type {Cartesian2} - * @readonly - */ - this.voxelCountPerRegion = new Cartesian2( - voxelCountPerRegionX, - voxelCountPerRegionY - ); - - /** - * @type {Cartesian2} - * @readonly - */ - this.sliceCountPerRegion = new Cartesian2( - sliceCountPerRegionX, - sliceCountPerRegionY - ); - - /** - * @type {Cartesian2} - * @readonly - */ - this.voxelSizeUv = new Cartesian2( - 1.0 / textureDimension, - 1.0 / textureDimension - ); - - /** - * @type {Cartesian2} - * @readonly - */ - this.sliceSizeUv = new Cartesian2( - dimensions.x / textureDimension, - dimensions.y / textureDimension - ); - - /** - * @type {Cartesian2} - * @readonly - */ - this.regionSizeUv = new Cartesian2( - voxelCountPerRegionX / textureDimension, - voxelCountPerRegionY / textureDimension - ); - - /** - * @type {Texture} - * @readonly - */ - this.texture = new Texture({ - context: context, - pixelFormat: pixelFormat, - pixelDatatype: pixelType, - flipY: false, - width: textureDimension, - height: textureDimension, - sampler: new Sampler({ - wrapS: TextureWrap.CLAMP_TO_EDGE, - wrapT: TextureWrap.CLAMP_TO_EDGE, - minificationFilter: TextureMinificationFilter.LINEAR, - magnificationFilter: TextureMagnificationFilter.LINEAR, - }), - }); - - const ArrayType = MetadataComponentType.toTypedArrayType(componentType); - - /** - * @type {Array} - */ - this.tileVoxelDataTemp = new ArrayType( - voxelCountPerRegionX * voxelCountPerRegionY * channelCount - ); - - /** - * @type {MegatextureNode[]} - * @readonly - */ - this.nodes = new Array(this.maximumTileCount); - for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { - this.nodes[tileIndex] = new MegatextureNode(tileIndex); - } - for (let tileIndex = 0; tileIndex < this.maximumTileCount; tileIndex++) { - const node = this.nodes[tileIndex]; - node.previousNode = tileIndex > 0 ? this.nodes[tileIndex - 1] : undefined; - node.nextNode = - tileIndex < this.maximumTileCount - 1 - ? this.nodes[tileIndex + 1] - : undefined; - } - - /** - * @type {MegatextureNode} - * @readonly - */ - this.occupiedList = undefined; - - /** - * @type {MegatextureNode} - * @readonly - */ - this.emptyList = this.nodes[0]; - - /** - * @type {Number} - * @readonly - */ - this.occupiedCount = 0; -} - -/** - * @alias MegatextureNode - * @constructor - * - * @param {Number} index - * - * @private - */ -function MegatextureNode(index) { - /** - * @type {Number} - */ - this.index = index; - - /** - * @type {MegatextureNode} - */ - this.nextNode = undefined; - - /** - * @type {MegatextureNode} - */ - this.previousNode = undefined; -} - -/** - * @param {Array} data - * @returns {Number} - */ -Megatexture.prototype.add = function (data) { - if (this.isFull()) { - throw new DeveloperError("Trying to add when there are no empty spots"); - } - - // remove head of empty list - const node = this.emptyList; - this.emptyList = this.emptyList.nextNode; - if (defined(this.emptyList)) { - this.emptyList.previousNode = undefined; - } - - // make head of occupied list - node.nextNode = this.occupiedList; - if (defined(node.nextNode)) { - node.nextNode.previousNode = node; - } - this.occupiedList = node; - - const index = node.index; - this.writeDataToTexture(index, data); - - this.occupiedCount++; - return index; -}; - -/** - * @param {Number} index - */ -Megatexture.prototype.remove = function (index) { - if (index < 0 || index >= this.maximumTileCount) { - throw new DeveloperError("Megatexture index out of bounds"); - } - - // remove from list - const node = this.nodes[index]; - if (defined(node.previousNode)) { - node.previousNode.nextNode = node.nextNode; - } - if (defined(node.nextNode)) { - node.nextNode.previousNode = node.previousNode; - } - - // make head of empty list - node.nextNode = this.emptyList; - if (defined(node.nextNode)) { - node.nextNode.previousNode = node; - } - node.previousNode = undefined; - this.emptyList = node; - this.occupiedCount--; -}; - -/** - * @returns {Boolean} - */ -Megatexture.prototype.isFull = function () { - return this.emptyList === undefined; -}; - -/** - * @param {Number} tileCount - * @param {Cartesian3} dimensions - * @param {Number} channelCount number of channels in the metadata. Must be 1 to 4. - * @param {MetadataComponentType} componentType - * @returns {Number} - */ -Megatexture.getApproximateTextureMemoryByteLength = function ( - tileCount, - dimensions, - channelCount, - componentType -) { - // TODO there's a lot of code duplicate with Megatexture constructor - - // Unsigned short textures not allowed in webgl 1, so treat as float - if (componentType === MetadataComponentType.UNSIGNED_SHORT) { - componentType = MetadataComponentType.FLOAT32; - } - - const datatypeSizeInBytes = MetadataComponentType.getSizeInBytes( - componentType - ); - const voxelCountTotal = - tileCount * dimensions.x * dimensions.y * dimensions.z; - - const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.z)); - const sliceCountPerRegionY = Math.ceil(dimensions.z / sliceCountPerRegionX); - const voxelCountPerRegionX = sliceCountPerRegionX * dimensions.x; - const voxelCountPerRegionY = sliceCountPerRegionY * dimensions.y; - - // Find the power of two that can fit all tile data, accounting for slices. - // There's probably a non-iterative solution for this, but this is good enough for now. - let textureDimension = CesiumMath.previousPowerOfTwo( - Math.floor(Math.sqrt(voxelCountTotal)) - ); - for (;;) { - const regionCountX = Math.floor(textureDimension / voxelCountPerRegionX); - const regionCountY = Math.floor(textureDimension / voxelCountPerRegionY); - const regionCount = regionCountX * regionCountY; - if (regionCount >= tileCount) { - break; - } else { - textureDimension *= 2; - } - } - - const textureMemoryByteLength = - textureDimension * textureDimension * channelCount * datatypeSizeInBytes; - return textureMemoryByteLength; -}; - -/** - * @param {Number} index - * @param {Float32Array|Uint16Array|Uint8Array} data - */ -Megatexture.prototype.writeDataToTexture = function (index, data) { - const texture = this.texture; - const channelCount = this.channelCount; - const regionDimensionsPerMegatexture = this.regionCountPerMegatexture; - const voxelDimensionsPerRegion = this.voxelCountPerRegion; - const voxelDimensionsPerTile = this.voxelCountPerTile; - const sliceDimensionsPerRegion = this.sliceCountPerRegion; - - let tileData = data; - - // Unsigned short textures not allowed in webgl 1, so treat as float - if (data.constructor === Uint16Array) { - const elementCount = data.length; - tileData = new Float32Array(elementCount); - for (let i = 0; i < elementCount / channelCount; i++) { - for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) { - const dataIndex = i * channelCount + channelIndex; - const minimumValue = this.minimumValues[channelIndex]; - const maximumValue = this.maximumValues[channelIndex]; - // TODO extrema are unnormalized, but we are normalizing to [0, 1] here. what do we want to do? will the user expect to get normalized samples and extrema in the style function? - tileData[dataIndex] = - (data[dataIndex] - minimumValue) / (maximumValue - minimumValue); - // tileData[dataIndex] = CesiumMath.lerp( - // minimumValue, - // maximumValue, - // data[dataIndex] / 65535 - // ); - } - } - } - - const tileVoxelData = this.tileVoxelDataTemp; - for (let z = 0; z < voxelDimensionsPerTile.z; z++) { - const sliceVoxelOffsetX = - (z % sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.x; - const sliceVoxelOffsetY = - Math.floor(z / sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.y; - for (let y = 0; y < voxelDimensionsPerTile.y; y++) { - for (let x = 0; x < voxelDimensionsPerTile.x; x++) { - const readIndex = - z * voxelDimensionsPerTile.y * voxelDimensionsPerTile.x + - y * voxelDimensionsPerTile.x + - x; - const writeIndex = - (sliceVoxelOffsetY + y) * voxelDimensionsPerRegion.x + - (sliceVoxelOffsetX + x); - for (let c = 0; c < channelCount; c++) { - tileVoxelData[writeIndex * channelCount + c] = - tileData[readIndex * channelCount + c]; - } - } - } - } - - const voxelWidth = voxelDimensionsPerRegion.x; - const voxelHeight = voxelDimensionsPerRegion.y; - const voxelOffsetX = - (index % regionDimensionsPerMegatexture.x) * voxelDimensionsPerRegion.x; - const voxelOffsetY = - Math.floor(index / regionDimensionsPerMegatexture.x) * - voxelDimensionsPerRegion.y; - - const source = { - arrayBufferView: tileVoxelData, - width: voxelWidth, - height: voxelHeight, - }; - - const copyOptions = { - source: source, - xOffset: voxelOffsetX, - yOffset: voxelOffsetY, - }; - - texture.copyFrom(copyOptions); -}; - -/** - * Returns true if this object was destroyed; otherwise, false. - *

- * If this object was destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. - * - * @returns {Boolean} true if this object was destroyed; otherwise, false. - * - * @see Megatexture#destroy - */ -Megatexture.prototype.isDestroyed = function () { - return false; -}; - -/** - * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic - * release of WebGL resources, instead of relying on the garbage collector to destroy this object. - *

- * Once an object is destroyed, it should not be used; calling any function other than - * isDestroyed will result in a {@link DeveloperError} exception. Therefore, - * assign the return value (undefined) to the object as done in the example. - * - * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. - * - * @see Megatexture#isDestroyed - * - * @example - * megatexture = megatexture && megatexture.destroy(); - */ -Megatexture.prototype.destroy = function () { - this.texture = this.texture && this.texture.destroy(); - return destroyObject(this); -}; - export default VoxelTraversal; diff --git a/Specs/Scene/KeyframeNodeSpec.js b/Specs/Scene/KeyframeNodeSpec.js new file mode 100644 index 00000000000..4fcef07dd6f --- /dev/null +++ b/Specs/Scene/KeyframeNodeSpec.js @@ -0,0 +1,44 @@ +import { KeyframeNode } from "../../Source/Cesium.js"; + +const dummySpatialNode = {}; + +describe("Scene/KeyframeNode", function () { + it("constructs", function () { + const keyframe = 13; + const keyframeNode = new KeyframeNode(dummySpatialNode, keyframe); + + expect(keyframeNode.spatialNode).toBe(dummySpatialNode); + expect(keyframeNode.keyframe).toBe(keyframe); + expect(keyframeNode.state).toBe(KeyframeNode.LoadState.UNLOADED); + expect(keyframeNode.metadatas).toEqual([]); + expect(keyframeNode.megatextureIndex).toBe(-1); + expect(keyframeNode.priority).toBe(-Number.MAX_VALUE); + expect(keyframeNode.highPriorityFrameNumber).toBe(-1); + }); + + it("priorityComparator compares priorities", function () { + const keyframe1 = 13; + const keyframe2 = 7; + const keyframeNode1 = new KeyframeNode(dummySpatialNode, keyframe1); + const keyframeNode2 = new KeyframeNode(dummySpatialNode, keyframe2); + keyframeNode1.priority = 1; + keyframeNode2.priority = 2; + const comparison = KeyframeNode.priorityComparator( + keyframeNode1, + keyframeNode2 + ); + expect(comparison).toBe(-1); + }); + + it("searchComparator compares keyframe indices", function () { + const keyframe1 = 13; + const keyframe2 = 7; + const keyframeNode1 = new KeyframeNode(dummySpatialNode, keyframe1); + const keyframeNode2 = new KeyframeNode(dummySpatialNode, keyframe2); + const comparison = KeyframeNode.searchComparator( + keyframeNode1, + keyframeNode2 + ); + expect(comparison).toBe(6); + }); +}); diff --git a/Specs/getWebGLStub.js b/Specs/getWebGLStub.js index 1e905036fed..0fa07f22900 100644 --- a/Specs/getWebGLStub.js +++ b/Specs/getWebGLStub.js @@ -212,6 +212,11 @@ function getExtensionStub(name) { return instancedArraysStub; } + // Voxel tests rely on floating point textures + if (name === "OES_texture_float") { + return {}; + } + // No other extensions are stubbed. return null; } From 63c30d2fc79307ee19ff18af67c77cd88fda6194 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 24 Aug 2022 14:58:05 -0400 Subject: [PATCH 087/679] Update JSDoc to fix typescript definitions --- Source/Scene/Cesium3DTilesVoxelProvider.js | 12 +++++++----- Source/Scene/GltfVoxelProvider.js | 16 +++++++++------- Source/Scene/VoxelPrimitive.js | 4 ++++ Source/Scene/VoxelProvider.js | 5 +++++ Source/Scene/VoxelTraversal.js | 1 + 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 0dd6b3e63e5..e93605b9876 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -130,7 +130,7 @@ function Cesium3DTilesVoxelProvider(options) { // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use /** - * Gets stuff + * Gets the metadata names. * * @type {String[]} * @readonly @@ -138,23 +138,24 @@ function Cesium3DTilesVoxelProvider(options) { this.names = new Array(); /** - * Gets stuff + * Gets the metadata types * * @type {MetadataType[]} * @readonly + * @private */ this.types = new Array(); /** - * Gets stuff + * Gets the metadata component types * * @type {MetadataComponentType[]} * @readonly + * @private */ this.componentTypes = new Array(); /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the minimum value * * @type {Number[][]|undefined} @@ -163,7 +164,6 @@ function Cesium3DTilesVoxelProvider(options) { this.minimumValues = undefined; /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the maximum value * * @type {Number[][]|undefined} @@ -535,8 +535,10 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { /** * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. + * @function * * @param {FrameState} frameState + * @private */ Cesium3DTilesVoxelProvider.prototype.update = function (frameState) { const loaders = this._gltfLoaders; diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index 71b4c213926..ec50bf91194 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -19,7 +19,8 @@ import VoxelShapeType from "./VoxelShapeType.js"; * @constructor * * @param {Object} options Object with the following properties: - * @param {String|Resource|Uint8Array|Object|GltfLoader} options.gltf A Resource/URL to a glTF/glb file, a binary glTF buffer, or a JSON object containing the glTF contents + * @param {String|Resource|Uint8Array|Object} options.gltf A Resource/URL to a glTF/glb file, a binary glTF buffer, or a JSON object containing the glTF contents + * options.gltf could also have type GltfLoader, but that is a private type * * @see Cesium3DTilesVoxelProvider * @see VoxelProvider @@ -125,7 +126,7 @@ function GltfVoxelProvider(options) { // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use /** - * Gets stuff + * Gets the metadata names. * * @type {String[]} * @readonly @@ -133,23 +134,24 @@ function GltfVoxelProvider(options) { this.names = new Array(); /** - * Gets stuff + * Gets the metadata types * * @type {MetadataType[]} * @readonly + * @private */ this.types = new Array(); /** - * Gets stuff + * Gets the metadata component types * * @type {MetadataComponentType[]} * @readonly + * @private */ this.componentTypes = new Array(); /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the minimum value * * @type {Number[][]|undefined} @@ -158,7 +160,6 @@ function GltfVoxelProvider(options) { this.minimumValues = undefined; /** - * TODO is [][] valid JSDOC? https://stackoverflow.com/questions/25602978/jsdoc-two-dimensional-array * Gets the maximum value * * @type {Number[][]|undefined} @@ -296,9 +297,10 @@ function GltfVoxelProvider(options) { /** * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. - * If the provider doesn't need this functionality it should leave this function undefined. + * @function * * @param {FrameState} frameState + * @private */ GltfVoxelProvider.prototype.update = function (frameState) { const loader = this._loader; diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index e30d45f631d..4437b04074f 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -191,6 +191,8 @@ function VoxelPrimitive(options) { /** * Keeps track of when the clipping planes are enabled / disabled + * @type {Boolean} + * @private */ this._clippingPlanesEnabled = false; @@ -1081,8 +1083,10 @@ const transformPositionUvToLocal = Matrix4.fromRotationTranslation( /** * Updates the voxel primitive. + * @function * * @param {FrameState} frameState + * @private */ VoxelPrimitive.prototype.update = function (frameState) { const context = frameState.context; diff --git a/Source/Scene/VoxelProvider.js b/Source/Scene/VoxelProvider.js index cb1356ddd8b..5b61cdd3b31 100644 --- a/Source/Scene/VoxelProvider.js +++ b/Source/Scene/VoxelProvider.js @@ -145,6 +145,7 @@ Object.defineProperties(VoxelProvider.prototype, { * @memberof VoxelProvider.prototype * @type {MetadataType[]} * @readonly + * @private */ types: { get: DeveloperError.throwInstantiationError, @@ -157,6 +158,7 @@ Object.defineProperties(VoxelProvider.prototype, { * @memberof VoxelProvider.prototype * @type {MetadataComponentType[]} * @readonly + * @private */ componentTypes: { get: DeveloperError.throwInstantiationError, @@ -224,6 +226,7 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * This function should not be called before {@link VoxelProvider#ready} returns true. + * @function * * @param {Object} [options] Object with the following properties: * @param {Number} [options.tileLevel=0] The tile's level. @@ -240,8 +243,10 @@ VoxelProvider.prototype.requestData = DeveloperError.throwInstantiationError; /** * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. * If the provider doesn't need this functionality it should leave this function undefined. + * @function * * @param {FrameState} frameState + * @private */ VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index c817568380a..d4740f40ada 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -933,6 +933,7 @@ const GpuOctreeFlag = { * @param {FrameState} frameState * @param {Number} sampleCount * @param {Number} levelBlendFactor + * @private */ function generateOctree(that, sampleCount, levelBlendFactor) { const primitive = that._primitive; From 4f4520a05d57b189cbeb87de2deb057c137209a8 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 26 Aug 2022 15:32:17 -0400 Subject: [PATCH 088/679] Add specs for Megatexture and SpatialNode --- Source/Scene/Megatexture.js | 37 ++---- Source/Scene/SpatialNode.js | 9 +- Source/Scene/VoxelDrawCommands.js | 72 +++++------ Specs/Scene/MegatextureSpec.js | 199 ++++++++++++++++++++++++++++++ Specs/Scene/SpatialNodeSpec.js | 28 +++++ 5 files changed, 266 insertions(+), 79 deletions(-) create mode 100644 Specs/Scene/MegatextureSpec.js create mode 100644 Specs/Scene/SpatialNodeSpec.js diff --git a/Source/Scene/Megatexture.js b/Source/Scene/Megatexture.js index e453644c3f0..6bf0390dfd8 100644 --- a/Source/Scene/Megatexture.js +++ b/Source/Scene/Megatexture.js @@ -100,7 +100,6 @@ function Megatexture( textureDimension / voxelCountPerRegionY ); - // TODO can this happen? if (regionCountPerMegatextureX === 0 || regionCountPerMegatextureY === 0) { throw new RuntimeError("Tileset is too large to fit into megatexture"); } @@ -394,35 +393,14 @@ Megatexture.getApproximateTextureMemoryByteLength = function ( * @param {Float32Array|Uint16Array|Uint8Array} data */ Megatexture.prototype.writeDataToTexture = function (index, data) { - const texture = this.texture; - const channelCount = this.channelCount; - const regionDimensionsPerMegatexture = this.regionCountPerMegatexture; - const voxelDimensionsPerRegion = this.voxelCountPerRegion; + // Unsigned short textures not allowed in webgl 1, so treat as float + const tileData = + data.constructor === Uint16Array ? new Float32Array(data) : data; + const voxelDimensionsPerTile = this.voxelCountPerTile; const sliceDimensionsPerRegion = this.sliceCountPerRegion; - - let tileData = data; - - // Unsigned short textures not allowed in webgl 1, so treat as float - if (data.constructor === Uint16Array) { - const elementCount = data.length; - tileData = new Float32Array(elementCount); - for (let i = 0; i < elementCount / channelCount; i++) { - for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) { - const dataIndex = i * channelCount + channelIndex; - const minimumValue = this.minimumValues[channelIndex]; - const maximumValue = this.maximumValues[channelIndex]; - // TODO extrema are unnormalized, but we are normalizing to [0, 1] here. what do we want to do? will the user expect to get normalized samples and extrema in the style function? - tileData[dataIndex] = - (data[dataIndex] - minimumValue) / (maximumValue - minimumValue); - // tileData[dataIndex] = CesiumMath.lerp( - // minimumValue, - // maximumValue, - // data[dataIndex] / 65535 - // ); - } - } - } + const voxelDimensionsPerRegion = this.voxelCountPerRegion; + const channelCount = this.channelCount; const tileVoxelData = this.tileVoxelDataTemp; for (let z = 0; z < voxelDimensionsPerTile.z; z++) { @@ -447,6 +425,7 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { } } + const regionDimensionsPerMegatexture = this.regionCountPerMegatexture; const voxelWidth = voxelDimensionsPerRegion.x; const voxelHeight = voxelDimensionsPerRegion.y; const voxelOffsetX = @@ -467,7 +446,7 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { yOffset: voxelOffsetY, }; - texture.copyFrom(copyOptions); + this.texture.copyFrom(copyOptions); }; /** diff --git a/Source/Scene/SpatialNode.js b/Source/Scene/SpatialNode.js index 3b4a417fb15..28825c82bab 100644 --- a/Source/Scene/SpatialNode.js +++ b/Source/Scene/SpatialNode.js @@ -17,6 +17,7 @@ import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; * @param {Number} z * @param {SpatialNode} parent * @param {VoxelShapeType} shape + * @param {Cartesian3} voxelDimensions * * @private */ @@ -239,14 +240,6 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( ? keyframeDistanceNext * normalKeyframeWeight : -keyframeDistanceNext * reverseKeyframeWeight); - // // Prioritize visual quality - // const distancePrev = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; - // const distanceNext = levelDistance === 0.0 ? 0.0 : Number.MAX_VALUE; - - // // Prioritize temporal quality - // const distancePrev = keyframeDistancePrev >= 0 ? keyframeDistancePrev : Number.MAX_VALUE + keyframeDistancePrev; - // const distanceNext = keyframeDistanceNext >= 0 ? keyframeDistanceNext : Number.MAX_VALUE + keyframeDistanceNext; - if (distancePrev < minimumDistancePrev) { minimumDistancePrev = distancePrev; bestKeyframeNodePrev = keyframeNodePrev; diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/VoxelDrawCommands.js index 9df29b881ec..e62a9acf321 100644 --- a/Source/Scene/VoxelDrawCommands.js +++ b/Source/Scene/VoxelDrawCommands.js @@ -29,33 +29,24 @@ import MetadataType from "./MetadataType.js"; /** * @function * - * @param {VoxelPrimitive} that + * @param {VoxelPrimitive} primitive * @param {Context} context * * @private */ -function buildVoxelDrawCommands(that, context) { - const provider = that._provider; - const traversal = that._traversal; - const shapeType = provider.shape; - const names = provider.names; +function buildVoxelDrawCommands(primitive, context) { + const provider = primitive._provider; + const traversal = primitive._traversal; const types = provider.types; const componentTypes = provider.componentTypes; - const depthTest = that._depthTest; - const useLogDepth = that._useLogDepth; - const paddingBefore = that.paddingBefore; - const paddingAfter = that.paddingAfter; - const shape = that._shape; - const shapeDefines = shape.shaderDefines; + const depthTest = primitive._depthTest; + const shape = primitive._shape; const minimumValues = provider.minimumValues; const maximumValues = provider.maximumValues; - const jitter = that._jitter; - const nearestSampling = that._nearestSampling; - const sampleCount = traversal._sampleCount; - const customShader = that._customShader; + const customShader = primitive._customShader; const attributeLength = types.length; const hasStatistics = defined(minimumValues) && defined(maximumValues); - const clippingPlanes = that._clippingPlanes; + const clippingPlanes = primitive._clippingPlanes; const clippingPlanesLength = defined(clippingPlanes) && clippingPlanes.enabled ? clippingPlanes.length @@ -64,8 +55,6 @@ function buildVoxelDrawCommands(that, context) { ? clippingPlanes.unionClippingRegions : false; - let uniformMap = that._uniformMap; - // Build shader const shaderBuilder = new ShaderBuilder(); @@ -87,6 +76,8 @@ function buildVoxelDrawCommands(that, context) { if (clippingPlanesLength > 0) { shaderBuilder.addFragmentLines([IntersectClippingPlanes]); } + + const shapeType = provider.shape; if (shapeType === "BOX") { shaderBuilder.addFragmentLines([ IntersectBox, @@ -106,6 +97,7 @@ function buildVoxelDrawCommands(that, context) { convertUvToEllipsoid, ]); } + shaderBuilder.addFragmentLines([Octree, Megatexture, VoxelFS]); // Fragment shader defines @@ -117,8 +109,8 @@ function buildVoxelDrawCommands(that, context) { ); if ( - !Cartesian3.equals(paddingBefore, Cartesian3.ZERO) || - !Cartesian3.equals(paddingAfter, Cartesian3.ZERO) + !Cartesian3.equals(primitive.paddingBefore, Cartesian3.ZERO) || + !Cartesian3.equals(primitive.paddingAfter, Cartesian3.ZERO) ) { shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); } @@ -133,25 +125,23 @@ function buildVoxelDrawCommands(that, context) { // Allow reading from log depth texture, but don't write log depth anywhere. // Note: This needs to be set even if depthTest is off because it affects the // derived command system. - if (useLogDepth) { + if (primitive._useLogDepth) { shaderBuilder.addDefine( "LOG_DEPTH_READ_ONLY", undefined, ShaderDestination.FRAGMENT ); } - if (jitter) { + if (primitive._jitter) { shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); } - - if (nearestSampling) { + if (primitive._nearestSampling) { shaderBuilder.addDefine( "NEAREST_SAMPLING", undefined, ShaderDestination.FRAGMENT ); } - if (hasStatistics) { shaderBuilder.addDefine( "STATISTICS", @@ -212,20 +202,13 @@ function buildVoxelDrawCommands(that, context) { intersectionCount, ShaderDestination.FRAGMENT ); - shaderBuilder.addDefine( "SAMPLE_COUNT", - `${sampleCount}`, - ShaderDestination.FRAGMENT - ); - - // Shape specific defines - shaderBuilder.addDefine( - `SHAPE_${shapeType}`, - undefined, + `${traversal._sampleCount}`, ShaderDestination.FRAGMENT ); + const shapeDefines = shape.shaderDefines; for (const key in shapeDefines) { if (shapeDefines.hasOwnProperty(key)) { let value = shapeDefines[key]; @@ -242,7 +225,11 @@ function buildVoxelDrawCommands(that, context) { // Custom shader uniforms const customShaderUniforms = customShader.uniforms; - uniformMap = that._uniformMap = combine(uniformMap, customShader.uniformMap); + let uniformMap = primitive._uniformMap; + uniformMap = primitive._uniformMap = combine( + uniformMap, + customShader.uniformMap + ); for (const uniformName in customShaderUniforms) { if (customShaderUniforms.hasOwnProperty(uniformName)) { const uniform = customShaderUniforms[uniformName]; @@ -263,6 +250,7 @@ function buildVoxelDrawCommands(that, context) { ); // Fragment shader structs + const names = provider.names; // PropertyStatistics structs for (let i = 0; i < attributeLength; i++) { @@ -640,19 +628,19 @@ function buildVoxelDrawCommands(that, context) { drawCommandPick.pickOnly = true; // Delete the old shader programs - if (defined(that._drawCommand)) { - const command = that._drawCommand; + if (defined(primitive._drawCommand)) { + const command = primitive._drawCommand; command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); } - if (defined(that._drawCommandPick)) { - const command = that._drawCommandPick; + if (defined(primitive._drawCommandPick)) { + const command = primitive._drawCommandPick; command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy(); } - that._drawCommand = drawCommand; - that._drawCommandPick = drawCommandPick; + primitive._drawCommand = drawCommand; + primitive._drawCommandPick = drawCommandPick; } // Shader builder helpers diff --git a/Specs/Scene/MegatextureSpec.js b/Specs/Scene/MegatextureSpec.js new file mode 100644 index 00000000000..5eaa23b0ead --- /dev/null +++ b/Specs/Scene/MegatextureSpec.js @@ -0,0 +1,199 @@ +import { + Cartesian3, + Megatexture, + MetadataComponentType, + RuntimeError, +} from "../Source/Cesium.js"; +import createScene from "../createScene.js"; + +describe("Scene/Megatexture", function () { + const scene = createScene(); + + it("constructs", function () { + const dimensions = new Cartesian3(16, 16, 16); + const channelCount = 4; + const componentType = MetadataComponentType.FLOAT32; + const textureMemoryByteLength = 16 * 16 * 16 * 4 * 4; + + // Constructor should throw if memory is too small + expect(function () { + return new Megatexture( + scene.context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength / 2 + ); + }).toThrowError(RuntimeError); + + const megatexture = new Megatexture( + scene.context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength + ); + expect(megatexture.channelCount).toBe(channelCount); + expect(megatexture.componentType).toBe(componentType); + expect(megatexture.voxelCountPerTile).toEqual(dimensions); + }); + + it("adds data to an existing megatexture", function () { + const dimension = 16; + const dimensions = new Cartesian3(dimension, dimension, dimension); + const channelCount = 4; + const componentType = MetadataComponentType.UINT16; + const tileSize = + dimension ** 3 * + channelCount * + MetadataComponentType.getSizeInBytes(componentType); + + const megatexture = new Megatexture( + scene.context, + dimensions, + channelCount, + componentType + ); + + const data = new Uint16Array(tileSize); + const index = megatexture.add(data); + expect(index).toBe(0); + }); + + it("throws if trying to add to a full megatexture", function () { + const dimension = 16; + const dimensions = new Cartesian3(dimension, dimension, dimension); + const channelCount = 1; + const componentType = MetadataComponentType.FLOAT32; + const tileSize = + dimension ** 3 * + channelCount * + MetadataComponentType.getSizeInBytes(componentType); + + // Allocate enough memory for only one tile + const tileCount = 1; + const textureMemoryByteLength = tileCount * tileSize; + const megatexture = new Megatexture( + scene.context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength + ); + + const data = new Float32Array(tileSize); + megatexture.add(data); + + // megatexture should be full now + expect(function () { + return megatexture.add(data); + }).toThrowDeveloperError(); + }); + + it("removes tile from a texture", function () { + const dimension = 16; + const dimensions = new Cartesian3(dimension, dimension, dimension); + const channelCount = 1; + const componentType = MetadataComponentType.FLOAT32; + const tileSize = + dimension ** 3 * + channelCount * + MetadataComponentType.getSizeInBytes(componentType); + + // Make room for 4 tiles + const tileCount = 4; + const textureMemoryByteLength = tileCount * tileSize; + const megatexture = new Megatexture( + scene.context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength + ); + + expect(megatexture.occupiedCount).toBe(0); + + // Fill up the megatexture + const data = new Float32Array(tileSize); + megatexture.add(data); + megatexture.add(data); + const index2 = megatexture.add(data); + megatexture.add(data); + + // megatexture should be full now + expect(megatexture.occupiedCount).toBe(4); + expect(function () { + return megatexture.add(data); + }).toThrowDeveloperError(); + + // Remove one tile + megatexture.remove(index2); + + // We should have room for another tile now + expect(megatexture.occupiedCount).toBe(3); + megatexture.add(data); + expect(megatexture.occupiedCount).toBe(4); + + // Out-of-bounds index should throw an error + expect(function () { + megatexture.remove(-1); + }).toThrowDeveloperError(); + expect(function () { + megatexture.remove(4); + }).toThrowDeveloperError(); + }); + + it("reports approximate memory size", function () { + const tileCount = 4; + const dimension = 16; + const dimensions = new Cartesian3(dimension, dimension, dimension); + const channelCount = 4; + const componentType = MetadataComponentType.FLOAT32; + const textureMemoryByteLength = + tileCount * + dimension ** 3 * + channelCount * + MetadataComponentType.getSizeInBytes(componentType); + + expect( + Megatexture.getApproximateTextureMemoryByteLength( + tileCount, + dimensions, + channelCount, + componentType + ) + ).toBe(textureMemoryByteLength); + }); + + it("destroys", function () { + const tileCount = 4; + const dimension = 16; + const dimensions = new Cartesian3(dimension, dimension, dimension); + const channelCount = 4; + const componentType = MetadataComponentType.FLOAT32; + const textureMemoryByteLength = + tileCount * + dimension ** 3 * + channelCount * + MetadataComponentType.getSizeInBytes(componentType); + + const megatexture = new Megatexture( + scene.context, + dimensions, + channelCount, + componentType, + textureMemoryByteLength + ); + + expect(megatexture.maximumTileCount).toBe(4); + megatexture.remove(0); + expect(megatexture.isDestroyed()).toBe(false); + + megatexture.destroy(); + + expect(megatexture.isDestroyed()).toBe(true); + expect(function () { + return megatexture.remove(0); + }).toThrowDeveloperError(); + }); +}); diff --git a/Specs/Scene/SpatialNodeSpec.js b/Specs/Scene/SpatialNodeSpec.js new file mode 100644 index 00000000000..f7d02c6f3c7 --- /dev/null +++ b/Specs/Scene/SpatialNodeSpec.js @@ -0,0 +1,28 @@ +import { + Cartesian3, + Matrix4, + SpatialNode, + VoxelBoxShape, +} from "../Source/Cesium.js"; + +describe("Scene/SpatialNode", function () { + it("constructs", function () { + const shape = new VoxelBoxShape(); + const modelMatrix = Matrix4.IDENTITY.clone(); + const minBounds = VoxelBoxShape.DefaultMinBounds.clone(); + const maxBounds = VoxelBoxShape.DefaultMaxBounds.clone(); + shape.update(modelMatrix, minBounds, maxBounds); + + const level = 0; + const x = 1; + const y = 2; + const z = 3; + const parent = undefined; + const dimensions = new Cartesian3(2, 3, 4); + + const node = new SpatialNode(level, x, y, z, parent, shape, dimensions); + + expect(node.level).toEqual(0); + expect(node.screenSpaceError).toEqual(0.0); + }); +}); From 021da45d8c604c7eb51dc52b613db17eba6f89fd Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 26 Aug 2022 15:59:32 -0400 Subject: [PATCH 089/679] PR feedback --- Source/Scene/VoxelBoxShape.js | 7 +++++-- Source/Shaders/Voxels/VoxelFS.glsl | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Source/Scene/VoxelBoxShape.js b/Source/Scene/VoxelBoxShape.js index df569d7f0fd..4eaa2e0c34d 100644 --- a/Source/Scene/VoxelBoxShape.js +++ b/Source/Scene/VoxelBoxShape.js @@ -216,9 +216,9 @@ VoxelBoxShape.prototype.update = function ( const scale = Matrix4.getScale(modelMatrix, scratchScale); // Box is not visible if: - // - any of the min bounds exceed the max bounds + // - any of the min render bounds exceed the max render bounds // - two or more of the min bounds equal the max bounds (line / point) - // - same as above, but for clip bounds + // - any of the min clip bounds exceed the max clip bounds // - scale is 0 for any component (too annoying to reconstruct rotation matrix) if ( renderMinBounds.x > renderMaxBounds.x || @@ -228,6 +228,9 @@ VoxelBoxShape.prototype.update = function ( (renderMinBounds.y === renderMaxBounds.y) + (renderMinBounds.z === renderMaxBounds.z) >= 2 || + clipMinBounds.x > clipMaxBounds.x || + clipMinBounds.y > clipMaxBounds.y || + clipMinBounds.z > clipMaxBounds.z || scale.x === 0.0 || scale.y === 0.0 || scale.z === 0.0 diff --git a/Source/Shaders/Voxels/VoxelFS.glsl b/Source/Shaders/Voxels/VoxelFS.glsl index 5399843201b..7f941e42be6 100644 --- a/Source/Shaders/Voxels/VoxelFS.glsl +++ b/Source/Shaders/Voxels/VoxelFS.glsl @@ -15,9 +15,9 @@ uniform vec3 u_cameraPositionUv; #if defined(JITTER) float hash(vec2 p) { - vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); + vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); } #endif From cc2f931b99d26ad560e3386cc8c22e74d05b42ec Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 31 Aug 2022 00:15:49 -0400 Subject: [PATCH 090/679] Refactor VoxelDrawCommands for testability --- Apps/Sandcastle/gallery/Voxels.html | 53 +- Source/Scene/VoxelDrawCommands.js | 657 +------------------------ Source/Scene/VoxelRenderResources.js | 224 +++++++++ Source/Scene/processVoxelProperties.js | 455 +++++++++++++++++ 4 files changed, 691 insertions(+), 698 deletions(-) create mode 100644 Source/Scene/VoxelRenderResources.js create mode 100644 Source/Scene/processVoxelProperties.js diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 641bbd09ed6..dc2501d937d 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -44,7 +44,6 @@ }); viewer.extend(Cesium.viewerVoxelInspectorMixin); viewer.scene.debugShowFramesPerSecond = true; - let voxelPrimitive; function ProceduralSingleTileVoxelProvider(shape) { switch (shape) { @@ -60,10 +59,6 @@ ); const west = minBounds.x; const east = maxBounds.x; - //const west = -Cesium.Math.PI + 0.4; - //const east = -Cesium.Math.PI + 0.7; - // const south = -Cesium.Math.PI_OVER_TWO + 0.1; - // const north = Cesium.Math.PI_OVER_TWO - 0.1; const south = minBounds.y; const north = maxBounds.y; const minimumHeight = 1000000.0; @@ -84,24 +79,12 @@ break; } case Cesium.VoxelShapeType.CYLINDER: { - // this.minBounds = new Cesium.Cartesian3( - // 0.0, - // -1.0, - // -Cesium.Math.PI - // ); - // this.maxBounds = new Cesium.Cartesian3(1.0, +1.0, -Cesium.Math.PI + 0.5); break; } } this.shape = shape; this.dimensions = new Cesium.Cartesian3(8, 8, 8); - // this.names = ["color", "shininess"]; - // this.types = [Cesium.MetadataType.VEC4, Cesium.MetadataType.SCALAR]; - // this.componentTypes = [ - // Cesium.MetadataComponentType.FLOAT32, - // Cesium.MetadataComponentType.FLOAT32, - // ]; this.names = ["color"]; this.types = [Cesium.MetadataType.VEC4]; this.componentTypes = [Cesium.MetadataComponentType.FLOAT32]; @@ -147,28 +130,15 @@ const index = z * dimensions.y * dimensions.x + y * dimensions.x + x; - // if (tileLevel === 0) { - // dataColor[index * channelCount + 0] = Math.random(); - // dataColor[index * channelCount + 1] = Math.random(); - // dataColor[index * channelCount + 2] = Math.random(); - // dataColor[index * channelCount + 3] = 1.0; - // } else { dataColor[index * channelCount + 0] = color.red; dataColor[index * channelCount + 1] = color.green; dataColor[index * channelCount + 2] = color.blue; dataColor[index * channelCount + 3] = 0.75; - // } - // dataColor[index * channelCount + 0] = lerperX; - // dataColor[index * channelCount + 1] = lerperY; - // dataColor[index * channelCount + 2] = lerperZ; - // dataColor[index * channelCount + 3] = 1.0; //0.75; } } } - // return Promise.resolve([dataColor, dataShininess]); return Promise.resolve([dataColor]); - // return Promise.resolve(dataColor); }; function ProceduralMultiTileVoxelProvider(shape) { @@ -359,7 +329,7 @@ function createPrimitive(provider, customShader) { viewer.scene.primitives.removeAll(); - voxelPrimitive = viewer.scene.primitives.add( + const voxelPrimitive = viewer.scene.primitives.add( new Cesium.VoxelPrimitive({ provider: provider, customShader: customShader, @@ -413,11 +383,6 @@ Cesium.VoxelShapeType.ELLIPSOID ); const primitive = createPrimitive(provider, customShaderColor); - primitive.readyPromise.then(function () { - viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { - duration: 0.0, - }); - }); }, }, { @@ -437,22 +402,6 @@ ); const primitive = createPrimitive(provider, customShaderColor); primitive.readyPromise.then(function () { - viewer.camera.flyToBoundingSphere(primitive.boundingSphere, { - duration: 0.0, - }); - // viewer.camera.position = new Cesium.Cartesian3( - // 20210315.04663869, - // 22200569.010404103, - // 16940652.047713447 - // ); - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 22489095.52149246, - 15457085.667961657, - 20334893.228182133 - ), - duration: 0.0, - }); primitive.maxClippingBounds.x = 0.99999999; }); }, diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/VoxelDrawCommands.js index e62a9acf321..e6f7ebf4833 100644 --- a/Source/Scene/VoxelDrawCommands.js +++ b/Source/Scene/VoxelDrawCommands.js @@ -1,5 +1,3 @@ -import Cartesian3 from "../Core/Cartesian3"; -import combine from "../Core/combine.js"; import defined from "../Core/defined"; import PrimitiveType from "../Core/PrimitiveType.js"; import BlendingState from "./BlendingState.js"; @@ -8,23 +6,9 @@ import getClippingFunction from "./getClippingFunction.js"; import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; import RenderState from "../Renderer/RenderState.js"; -import ShaderBuilder from "../Renderer/ShaderBuilder.js"; import ShaderDestination from "../Renderer/ShaderDestination.js"; -import VoxelFS from "../Shaders/Voxels/VoxelFS.js"; -import VoxelVS from "../Shaders/Voxels/VoxelVS.js"; -import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js"; -import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js"; -import IntersectClippingPlanes from "../Shaders/Voxels/IntersectClippingPlanes.js"; -import IntersectBox from "../Shaders/Voxels/IntersectBox.js"; -import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js"; -import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js"; -import Intersection from "../Shaders/Voxels/Intersection.js"; -import convertUvToBox from "../Shaders/Voxels/convertUvToBox.js"; -import convertUvToCylinder from "../Shaders/Voxels/convertUvToCylinder.js"; -import convertUvToEllipsoid from "../Shaders/Voxels/convertUvToEllipsoid.js"; -import Octree from "../Shaders/Voxels/Octree.js"; -import Megatexture from "../Shaders/Voxels/Megatexture.js"; -import MetadataType from "./MetadataType.js"; +import VoxelRenderResources from "./VoxelRenderResources"; +import processVoxelProperties from "./processVoxelProperties"; /** * @function @@ -35,530 +19,15 @@ import MetadataType from "./MetadataType.js"; * @private */ function buildVoxelDrawCommands(primitive, context) { - const provider = primitive._provider; - const traversal = primitive._traversal; - const types = provider.types; - const componentTypes = provider.componentTypes; - const depthTest = primitive._depthTest; - const shape = primitive._shape; - const minimumValues = provider.minimumValues; - const maximumValues = provider.maximumValues; - const customShader = primitive._customShader; - const attributeLength = types.length; - const hasStatistics = defined(minimumValues) && defined(maximumValues); - const clippingPlanes = primitive._clippingPlanes; - const clippingPlanesLength = - defined(clippingPlanes) && clippingPlanes.enabled - ? clippingPlanes.length - : 0; - const clippingPlanesUnion = defined(clippingPlanes) - ? clippingPlanes.unionClippingRegions - : false; - - // Build shader - - const shaderBuilder = new ShaderBuilder(); - - // Vertex shader - - shaderBuilder.addVertexLines([VoxelVS]); - - // Fragment shader - - shaderBuilder.addFragmentLines([ - customShader.fragmentShaderText, - "#line 0", - IntersectionUtils, - ]); - if (depthTest) { - shaderBuilder.addFragmentLines([IntersectDepth]); - } - if (clippingPlanesLength > 0) { - shaderBuilder.addFragmentLines([IntersectClippingPlanes]); - } - - const shapeType = provider.shape; - if (shapeType === "BOX") { - shaderBuilder.addFragmentLines([ - IntersectBox, - Intersection, - convertUvToBox, - ]); - } else if (shapeType === "CYLINDER") { - shaderBuilder.addFragmentLines([ - IntersectCylinder, - Intersection, - convertUvToCylinder, - ]); - } else if (shapeType === "ELLIPSOID") { - shaderBuilder.addFragmentLines([ - IntersectEllipsoid, - Intersection, - convertUvToEllipsoid, - ]); - } - - shaderBuilder.addFragmentLines([Octree, Megatexture, VoxelFS]); - - // Fragment shader defines - - shaderBuilder.addDefine( - "METADATA_COUNT", - attributeLength, - ShaderDestination.FRAGMENT - ); - - if ( - !Cartesian3.equals(primitive.paddingBefore, Cartesian3.ZERO) || - !Cartesian3.equals(primitive.paddingAfter, Cartesian3.ZERO) - ) { - shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); - } - if (depthTest) { - shaderBuilder.addDefine( - "DEPTH_TEST", - undefined, - ShaderDestination.FRAGMENT - ); - } - - // Allow reading from log depth texture, but don't write log depth anywhere. - // Note: This needs to be set even if depthTest is off because it affects the - // derived command system. - if (primitive._useLogDepth) { - shaderBuilder.addDefine( - "LOG_DEPTH_READ_ONLY", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (primitive._jitter) { - shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); - } - if (primitive._nearestSampling) { - shaderBuilder.addDefine( - "NEAREST_SAMPLING", - undefined, - ShaderDestination.FRAGMENT - ); - } - if (hasStatistics) { - shaderBuilder.addDefine( - "STATISTICS", - undefined, - ShaderDestination.FRAGMENT - ); - } - - if (clippingPlanesLength > 0) { - shaderBuilder.addDefine( - "CLIPPING_PLANES", - undefined, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addDefine( - "CLIPPING_PLANES_COUNT", - clippingPlanesLength, - ShaderDestination.FRAGMENT - ); - if (clippingPlanesUnion) { - shaderBuilder.addDefine( - "CLIPPING_PLANES_UNION", - undefined, - ShaderDestination.FRAGMENT - ); - } - } - - // Count how many intersections the shader will do. - let intersectionCount = shape.shaderMaximumIntersectionsLength; - - if (clippingPlanesLength > 0) { - shaderBuilder.addDefine( - "CLIPPING_PLANES_INTERSECTION_INDEX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - if (clippingPlanesLength === 1) { - intersectionCount += 1; - } else if (clippingPlanesUnion) { - intersectionCount += 2; - } else { - intersectionCount += 1; - } - } - - if (depthTest) { - shaderBuilder.addDefine( - "DEPTH_INTERSECTION_INDEX", - intersectionCount, - ShaderDestination.FRAGMENT - ); - intersectionCount += 1; - } - - shaderBuilder.addDefine( - "INTERSECTION_COUNT", - intersectionCount, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addDefine( - "SAMPLE_COUNT", - `${traversal._sampleCount}`, - ShaderDestination.FRAGMENT - ); - - const shapeDefines = shape.shaderDefines; - for (const key in shapeDefines) { - if (shapeDefines.hasOwnProperty(key)) { - let value = shapeDefines[key]; - // if value is undefined, don't define it - // if value is true, define it to nothing - if (defined(value)) { - value = value === true ? undefined : value; - shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); - } - } - } - - // Fragment shader uniforms - - // Custom shader uniforms - const customShaderUniforms = customShader.uniforms; - let uniformMap = primitive._uniformMap; - uniformMap = primitive._uniformMap = combine( - uniformMap, - customShader.uniformMap - ); - for (const uniformName in customShaderUniforms) { - if (customShaderUniforms.hasOwnProperty(uniformName)) { - const uniform = customShaderUniforms[uniformName]; - shaderBuilder.addUniform( - uniform.type, - uniformName, - ShaderDestination.FRAGMENT - ); - } - } - - // The reason this uniform is added by shader builder is because some of the - // dynamically generated shader code reads from it. - shaderBuilder.addUniform( - "sampler2D", - "u_megatextureTextures[METADATA_COUNT]", - ShaderDestination.FRAGMENT - ); - - // Fragment shader structs - const names = provider.names; - - // PropertyStatistics structs - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const propertyStatisticsStructId = `PropertyStatistics_${name}`; - const propertyStatisticsStructName = `PropertyStatistics_${name}`; - shaderBuilder.addStruct( - propertyStatisticsStructId, - propertyStatisticsStructName, - ShaderDestination.FRAGMENT - ); - const glslType = getGlslType(type); - shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "min"); - shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "max"); - } - - // Statistics struct - const statisticsStructId = "Statistics"; - const statisticsStructName = "Statistics"; - const statisticsFieldName = "statistics"; - shaderBuilder.addStruct( - statisticsStructId, - statisticsStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const propertyStructName = `PropertyStatistics_${name}`; - const propertyFieldName = name; - shaderBuilder.addStructField( - statisticsStructId, - propertyStructName, - propertyFieldName - ); - } - - // Metadata struct - const metadataStructId = "Metadata"; - const metadataStructName = "Metadata"; - const metadataFieldName = "metadata"; - shaderBuilder.addStruct( - metadataStructId, - metadataStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - metadataStructId, - statisticsStructName, - statisticsFieldName - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(metadataStructId, glslType, name); - } - - // VoxelProperty structs - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslPartialDerivativeType(type); - const voxelPropertyStructId = `VoxelProperty_${name}`; - const voxelPropertyStructName = `VoxelProperty_${name}`; - shaderBuilder.addStruct( - voxelPropertyStructId, - voxelPropertyStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeLocal" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeWorld" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeView" - ); - shaderBuilder.addStructField( - voxelPropertyStructId, - glslType, - "partialDerivativeValid" - ); - } - - // Voxel struct - const voxelStructId = "Voxel"; - const voxelStructName = "Voxel"; - const voxelFieldName = "voxel"; - shaderBuilder.addStruct( - voxelStructId, - voxelStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const voxelPropertyStructName = `VoxelProperty_${name}`; - shaderBuilder.addStructField(voxelStructId, voxelPropertyStructName, name); - } - shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionShapeUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); - shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); - shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); - - // FragmentInput struct - const fragmentInputStructId = "FragmentInput"; - const fragmentInputStructName = "FragmentInput"; - shaderBuilder.addStruct( - fragmentInputStructId, - fragmentInputStructName, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addStructField( - fragmentInputStructId, - metadataStructName, - metadataFieldName - ); - shaderBuilder.addStructField( - fragmentInputStructId, - voxelStructName, - voxelFieldName - ); - - // Properties struct - const propertiesStructId = "Properties"; - const propertiesStructName = "Properties"; - const propertiesFieldName = "properties"; - shaderBuilder.addStruct( - propertiesStructId, - propertiesStructName, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const glslType = getGlslType(type); - shaderBuilder.addStructField(propertiesStructId, glslType, name); - } - - // Fragment shader functions + const renderResources = new VoxelRenderResources(primitive); - // clearProperties function - { - const functionId = "clearProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} clearProperties()`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslType = getGlslType(type, componentType); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = ${glslType}(0.0);`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - // sumProperties function - { - const functionId = "sumProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} sumProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = propertiesA.${name} + propertiesB.${name};`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } - - // scaleProperties function - { - const functionId = "scaleProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} scaleProperties(${propertiesStructName} ${propertiesFieldName}, float scale)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} scaledProperties = ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `scaledProperties.${name} *= scale;`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [`return scaledProperties;`]); - } - - // mixProperties - { - const functionId = "mixProperties"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} mixProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB, float mixFactor)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesFieldName}.${name} = mix(propertiesA.${name}, propertiesB.${name}, mixFactor);`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } + processVoxelProperties(renderResources, primitive); - // copyPropertiesToMetadata - { - const functionId = "copyPropertiesToMetadata"; - shaderBuilder.addFunction( - functionId, - `void copyPropertiesToMetadata(in ${propertiesStructName} ${propertiesFieldName}, inout ${metadataStructName} ${metadataFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - shaderBuilder.addFunctionLines(functionId, [ - `${metadataFieldName}.${name} = ${propertiesFieldName}.${name};`, - ]); - } - } - - // setStatistics function - if (hasStatistics) { - const functionId = "setStatistics"; - shaderBuilder.addFunction( - functionId, - `void setStatistics(inout ${statisticsStructName} ${statisticsFieldName})`, - ShaderDestination.FRAGMENT - ); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentCount = MetadataType.getComponentCount(type); - for (let j = 0; j < componentCount; j++) { - const glslField = getGlslField(type, j); - const minimumValue = minimumValues[i][j]; - const maximumValue = maximumValues[i][j]; - shaderBuilder.addFunctionLines(functionId, [ - `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat( - minimumValue - )};`, - `${statisticsFieldName}.${name}.max${glslField} = ${getGlslNumberAsFloat( - maximumValue - )};`, - ]); - } - } - } - - // getPropertiesFromMegatextureAtUv - { - const functionId = "getPropertiesFromMegatextureAtUv"; - shaderBuilder.addFunction( - functionId, - `${propertiesStructName} getPropertiesFromMegatextureAtUv(vec2 texcoord)`, - ShaderDestination.FRAGMENT - ); - shaderBuilder.addFunctionLines(functionId, [ - `${propertiesStructName} ${propertiesFieldName};`, - ]); - for (let i = 0; i < attributeLength; i++) { - const name = names[i]; - const type = types[i]; - const componentType = componentTypes[i]; - const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); - shaderBuilder.addFunctionLines(functionId, [ - `properties.${name} = texture2D(u_megatextureTextures[${i}], texcoord)${glslTextureSwizzle};`, - ]); - } - shaderBuilder.addFunctionLines(functionId, [ - `return ${propertiesFieldName};`, - ]); - } + const { + shaderBuilder, + clippingPlanes, + clippingPlanesLength, + } = renderResources; if (clippingPlanesLength > 0) { // Extract the getClippingPlane function from the getClippingFunction string. @@ -606,12 +75,13 @@ function buildVoxelDrawCommands(primitive, context) { // Create the draw commands const viewportQuadVertexArray = context.getViewportQuadVertexArray(); + const depthTest = primitive._depthTest; const drawCommand = new DrawCommand({ vertexArray: viewportQuadVertexArray, primitiveType: PrimitiveType.TRIANGLES, renderState: renderState, shaderProgram: shaderProgram, - uniformMap: uniformMap, + uniformMap: renderResources.uniformMap, pass: Pass.VOXELS, executeInClosestFrustum: true, owner: this, @@ -643,109 +113,4 @@ function buildVoxelDrawCommands(primitive, context) { primitive._drawCommandPick = drawCommandPick; } -// Shader builder helpers - -/** - * Converts a {@link MetadataType} to a GLSL type. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. - * - * @private - */ -function getGlslType(type) { - if (type === MetadataType.SCALAR) { - return "float"; - } else if (type === MetadataType.VEC2) { - return "vec2"; - } else if (type === MetadataType.VEC3) { - return "vec3"; - } else if (type === MetadataType.VEC4) { - return "vec4"; - } -} - -/** - * Gets the GLSL swizzle when reading data from a texture. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL swizzle. - * - * @private - */ -function getGlslTextureSwizzle(type) { - if (type === MetadataType.SCALAR) { - return ".r"; - } else if (type === MetadataType.VEC2) { - return ".ra"; - } else if (type === MetadataType.VEC3) { - return ".rgb"; - } else if (type === MetadataType.VEC4) { - return ""; - } -} - -/** - * Gets the GLSL type of the partial derivative of {@link MetadataType}. - * - * @function - * - * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. - * - * @private - */ -function getGlslPartialDerivativeType(type) { - if (type === MetadataType.SCALAR) { - return "vec3"; - } else if (type === MetadataType.VEC2) { - return "mat2"; - } else if (type === MetadataType.VEC3) { - return "mat3"; - } else if (type === MetadataType.VEC4) { - return "mat4"; - } -} - -/** - * GLSL needs to have `.0` at the end of whole number floats or else it's - * treated like an integer. - * - * @function - * - * @param {Number} number The number to convert. - * @returns {String} The number as floating point in GLSL. - * - * @private - */ -function getGlslNumberAsFloat(number) { - let numberString = number.toString(); - if (numberString.indexOf(".") === -1) { - numberString = `${number}.0`; - } - return numberString; -} - -/** - * Gets the GLSL field - * - * @function - * - * @param {MetadataType} type - * @param {Number} index - * @returns {String} - * - * @private - */ -function getGlslField(type, index) { - if (type === MetadataType.SCALAR) { - return ""; - } - return `[${index}]`; -} - export default buildVoxelDrawCommands; diff --git a/Source/Scene/VoxelRenderResources.js b/Source/Scene/VoxelRenderResources.js new file mode 100644 index 00000000000..6aa295e5753 --- /dev/null +++ b/Source/Scene/VoxelRenderResources.js @@ -0,0 +1,224 @@ +import Cartesian3 from "../Core/Cartesian3"; +import combine from "../Core/combine.js"; +import defined from "../Core/defined"; +import ShaderBuilder from "../Renderer/ShaderBuilder.js"; +import ShaderDestination from "../Renderer/ShaderDestination.js"; +import VoxelFS from "../Shaders/Voxels/VoxelFS.js"; +import VoxelVS from "../Shaders/Voxels/VoxelVS.js"; +import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js"; +import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js"; +import IntersectClippingPlanes from "../Shaders/Voxels/IntersectClippingPlanes.js"; +import IntersectBox from "../Shaders/Voxels/IntersectBox.js"; +import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js"; +import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js"; +import Intersection from "../Shaders/Voxels/Intersection.js"; +import convertUvToBox from "../Shaders/Voxels/convertUvToBox.js"; +import convertUvToCylinder from "../Shaders/Voxels/convertUvToCylinder.js"; +import convertUvToEllipsoid from "../Shaders/Voxels/convertUvToEllipsoid.js"; +import Octree from "../Shaders/Voxels/Octree.js"; +import Megatexture from "../Shaders/Voxels/Megatexture.js"; + +/** + * Set up render resources, including basic shader code, for rendering + * a Voxel primitive. + * The shader code generated by this function may be modified in later stages. + * @constructor + * @param {VoxelPrimitive} primitive + * + * @private + */ +function VoxelRenderResources(primitive) { + const shaderBuilder = new ShaderBuilder(); + /** + * An object used to build a shader incrementally. Each pipeline stage + * may add lines of shader code to this object. + * + * @type {ShaderBuilder} + * @readonly + * + * @private + */ + this.shaderBuilder = shaderBuilder; + + // Custom shader uniforms + const customShader = primitive._customShader; + const uniformMap = combine(primitive._uniformMap, customShader.uniformMap); + primitive._uniformMap = uniformMap; + + const customShaderUniforms = customShader.uniforms; + for (const uniformName in customShaderUniforms) { + if (customShaderUniforms.hasOwnProperty(uniformName)) { + const uniform = customShaderUniforms[uniformName]; + shaderBuilder.addUniform( + uniform.type, + uniformName, + ShaderDestination.FRAGMENT + ); + } + } + // The reason this uniform is added by shader builder is because some of the + // dynamically generated shader code reads from it. + shaderBuilder.addUniform( + "sampler2D", + "u_megatextureTextures[METADATA_COUNT]", + ShaderDestination.FRAGMENT + ); + + /** + * A dictionary mapping uniform name to functions that return the uniform + * values. + * + * @type {Object.} + */ + this.uniformMap = uniformMap; + + const clippingPlanes = primitive._clippingPlanes; + const clippingPlanesLength = + defined(clippingPlanes) && clippingPlanes.enabled + ? clippingPlanes.length + : 0; + + this.clippingPlanes = clippingPlanes; + this.clippingPlanesLength = clippingPlanesLength; + + // Build shader + shaderBuilder.addVertexLines([VoxelVS]); + + shaderBuilder.addFragmentLines([ + customShader.fragmentShaderText, + "#line 0", + IntersectionUtils, + ]); + + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES", + undefined, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addDefine( + "CLIPPING_PLANES_COUNT", + clippingPlanesLength, + ShaderDestination.FRAGMENT + ); + if (clippingPlanes.unionClippingRegions) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_UNION", + undefined, + ShaderDestination.FRAGMENT + ); + } + shaderBuilder.addFragmentLines([IntersectClippingPlanes]); + } + if (primitive._depthTest) { + shaderBuilder.addDefine( + "DEPTH_TEST", + undefined, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFragmentLines([IntersectDepth]); + } + + const shapeType = primitive._provider.shape; + if (shapeType === "BOX") { + shaderBuilder.addFragmentLines([ + IntersectBox, + Intersection, + convertUvToBox, + ]); + } else if (shapeType === "CYLINDER") { + shaderBuilder.addFragmentLines([ + IntersectCylinder, + Intersection, + convertUvToCylinder, + ]); + } else if (shapeType === "ELLIPSOID") { + shaderBuilder.addFragmentLines([ + IntersectEllipsoid, + Intersection, + convertUvToEllipsoid, + ]); + } + + shaderBuilder.addFragmentLines([Octree, Megatexture, VoxelFS]); + + const shape = primitive._shape; + const shapeDefines = shape.shaderDefines; + for (const key in shapeDefines) { + if (shapeDefines.hasOwnProperty(key)) { + let value = shapeDefines[key]; + // if value is undefined, don't define it + // if value is true, define it to nothing + if (defined(value)) { + value = value === true ? undefined : value; + shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT); + } + } + } + + // Count how many intersections the shader will do. + let intersectionCount = shape.shaderMaximumIntersectionsLength; + if (clippingPlanesLength > 0) { + shaderBuilder.addDefine( + "CLIPPING_PLANES_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + if (clippingPlanesLength === 1) { + intersectionCount += 1; + } else if (clippingPlanes.unionClippingRegions) { + intersectionCount += 2; + } else { + intersectionCount += 1; + } + } + if (primitive._depthTest) { + shaderBuilder.addDefine( + "DEPTH_INTERSECTION_INDEX", + intersectionCount, + ShaderDestination.FRAGMENT + ); + intersectionCount += 1; + } + shaderBuilder.addDefine( + "INTERSECTION_COUNT", + intersectionCount, + ShaderDestination.FRAGMENT + ); + + // Additional fragment shader defines + if ( + !Cartesian3.equals(primitive.paddingBefore, Cartesian3.ZERO) || + !Cartesian3.equals(primitive.paddingAfter, Cartesian3.ZERO) + ) { + shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT); + } + // Allow reading from log depth texture, but don't write log depth anywhere. + // Note: This needs to be set even if depthTest is off because it affects the + // derived command system. + if (primitive._useLogDepth) { + shaderBuilder.addDefine( + "LOG_DEPTH_READ_ONLY", + undefined, + ShaderDestination.FRAGMENT + ); + } + if (primitive._jitter) { + shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT); + } + if (primitive._nearestSampling) { + shaderBuilder.addDefine( + "NEAREST_SAMPLING", + undefined, + ShaderDestination.FRAGMENT + ); + } + const traversal = primitive._traversal; + shaderBuilder.addDefine( + "SAMPLE_COUNT", + `${traversal._sampleCount}`, + ShaderDestination.FRAGMENT + ); +} + +export default VoxelRenderResources; diff --git a/Source/Scene/processVoxelProperties.js b/Source/Scene/processVoxelProperties.js new file mode 100644 index 00000000000..574ad35859a --- /dev/null +++ b/Source/Scene/processVoxelProperties.js @@ -0,0 +1,455 @@ +import defined from "../Core/defined"; +import MetadataType from "./MetadataType.js"; +import ShaderDestination from "../Renderer/ShaderDestination.js"; + +/** + * Update the shader with defines, structs, and functions to handle + * voxel properties and statistics + * @function + * + * @param {VoxelRenderResources} renderResources + * @param {VoxelPrimitive} primitive + * + * @private + */ +function processVoxelProperties(renderResources, primitive) { + const { shaderBuilder } = renderResources; + + const { + names, + types, + componentTypes, + minimumValues, + maximumValues, + } = primitive._provider; + + const attributeLength = types.length; + const hasStatistics = defined(minimumValues) && defined(maximumValues); + + shaderBuilder.addDefine( + "METADATA_COUNT", + attributeLength, + ShaderDestination.FRAGMENT + ); + + if (hasStatistics) { + shaderBuilder.addDefine( + "STATISTICS", + undefined, + ShaderDestination.FRAGMENT + ); + } + + // PropertyStatistics structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const propertyStatisticsStructId = `PropertyStatistics_${name}`; + const propertyStatisticsStructName = `PropertyStatistics_${name}`; + shaderBuilder.addStruct( + propertyStatisticsStructId, + propertyStatisticsStructName, + ShaderDestination.FRAGMENT + ); + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "min"); + shaderBuilder.addStructField(propertyStatisticsStructId, glslType, "max"); + } + + // Statistics struct + const statisticsStructId = "Statistics"; + const statisticsStructName = "Statistics"; + const statisticsFieldName = "statistics"; + shaderBuilder.addStruct( + statisticsStructId, + statisticsStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const propertyStructName = `PropertyStatistics_${name}`; + const propertyFieldName = name; + shaderBuilder.addStructField( + statisticsStructId, + propertyStructName, + propertyFieldName + ); + } + + // Metadata struct + const metadataStructId = "Metadata"; + const metadataStructName = "Metadata"; + const metadataFieldName = "metadata"; + shaderBuilder.addStruct( + metadataStructId, + metadataStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + metadataStructId, + statisticsStructName, + statisticsFieldName + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(metadataStructId, glslType, name); + } + + // VoxelProperty structs + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslPartialDerivativeType(type); + const voxelPropertyStructId = `VoxelProperty_${name}`; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStruct( + voxelPropertyStructId, + voxelPropertyStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeLocal" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeWorld" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeView" + ); + shaderBuilder.addStructField( + voxelPropertyStructId, + glslType, + "partialDerivativeValid" + ); + } + + // Voxel struct + const voxelStructId = "Voxel"; + const voxelStructName = "Voxel"; + const voxelFieldName = "voxel"; + shaderBuilder.addStruct( + voxelStructId, + voxelStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const voxelPropertyStructName = `VoxelProperty_${name}`; + shaderBuilder.addStructField(voxelStructId, voxelPropertyStructName, name); + } + shaderBuilder.addStructField(voxelStructId, "vec3", "positionEC"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionShapeUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); + shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); + shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); + + // FragmentInput struct + const fragmentInputStructId = "FragmentInput"; + const fragmentInputStructName = "FragmentInput"; + shaderBuilder.addStruct( + fragmentInputStructId, + fragmentInputStructName, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addStructField( + fragmentInputStructId, + metadataStructName, + metadataFieldName + ); + shaderBuilder.addStructField( + fragmentInputStructId, + voxelStructName, + voxelFieldName + ); + + // Properties struct + const propertiesStructId = "Properties"; + const propertiesStructName = "Properties"; + const propertiesFieldName = "properties"; + shaderBuilder.addStruct( + propertiesStructId, + propertiesStructName, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const glslType = getGlslType(type); + shaderBuilder.addStructField(propertiesStructId, glslType, name); + } + + // Fragment shader functions + + // clearProperties function + { + const functionId = "clearProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} clearProperties()`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslType = getGlslType(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = ${glslType}(0.0);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // sumProperties function + { + const functionId = "sumProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} sumProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = propertiesA.${name} + propertiesB.${name};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // scaleProperties function + { + const functionId = "scaleProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} scaleProperties(${propertiesStructName} ${propertiesFieldName}, float scale)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} scaledProperties = ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `scaledProperties.${name} *= scale;`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [`return scaledProperties;`]); + } + + // mixProperties + { + const functionId = "mixProperties"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} mixProperties(${propertiesStructName} propertiesA, ${propertiesStructName} propertiesB, float mixFactor)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesFieldName}.${name} = mix(propertiesA.${name}, propertiesB.${name}, mixFactor);`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } + + // copyPropertiesToMetadata + { + const functionId = "copyPropertiesToMetadata"; + shaderBuilder.addFunction( + functionId, + `void copyPropertiesToMetadata(in ${propertiesStructName} ${propertiesFieldName}, inout ${metadataStructName} ${metadataFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + shaderBuilder.addFunctionLines(functionId, [ + `${metadataFieldName}.${name} = ${propertiesFieldName}.${name};`, + ]); + } + } + + // setStatistics function + if (hasStatistics) { + const functionId = "setStatistics"; + shaderBuilder.addFunction( + functionId, + `void setStatistics(inout ${statisticsStructName} ${statisticsFieldName})`, + ShaderDestination.FRAGMENT + ); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentCount = MetadataType.getComponentCount(type); + for (let j = 0; j < componentCount; j++) { + const glslField = getGlslField(type, j); + const minimumValue = minimumValues[i][j]; + const maximumValue = maximumValues[i][j]; + shaderBuilder.addFunctionLines(functionId, [ + `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat( + minimumValue + )};`, + `${statisticsFieldName}.${name}.max${glslField} = ${getGlslNumberAsFloat( + maximumValue + )};`, + ]); + } + } + } + + // getPropertiesFromMegatextureAtUv + { + const functionId = "getPropertiesFromMegatextureAtUv"; + shaderBuilder.addFunction( + functionId, + `${propertiesStructName} getPropertiesFromMegatextureAtUv(vec2 texcoord)`, + ShaderDestination.FRAGMENT + ); + shaderBuilder.addFunctionLines(functionId, [ + `${propertiesStructName} ${propertiesFieldName};`, + ]); + for (let i = 0; i < attributeLength; i++) { + const name = names[i]; + const type = types[i]; + const componentType = componentTypes[i]; + const glslTextureSwizzle = getGlslTextureSwizzle(type, componentType); + shaderBuilder.addFunctionLines(functionId, [ + `properties.${name} = texture2D(u_megatextureTextures[${i}], texcoord)${glslTextureSwizzle};`, + ]); + } + shaderBuilder.addFunctionLines(functionId, [ + `return ${propertiesFieldName};`, + ]); + } +} + +/** + * Converts a {@link MetadataType} to a GLSL type. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * + * @private + */ +function getGlslType(type) { + if (type === MetadataType.SCALAR) { + return "float"; + } else if (type === MetadataType.VEC2) { + return "vec2"; + } else if (type === MetadataType.VEC3) { + return "vec3"; + } else if (type === MetadataType.VEC4) { + return "vec4"; + } +} + +/** + * Gets the GLSL swizzle when reading data from a texture. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL swizzle. + * + * @private + */ +function getGlslTextureSwizzle(type) { + if (type === MetadataType.SCALAR) { + return ".r"; + } else if (type === MetadataType.VEC2) { + return ".ra"; + } else if (type === MetadataType.VEC3) { + return ".rgb"; + } else if (type === MetadataType.VEC4) { + return ""; + } +} + +/** + * Gets the GLSL type of the partial derivative of {@link MetadataType}. + * + * @function + * + * @param {MetadataType} type The {@link MetadataType}. + * @returns {String} The GLSL type. + * + * @private + */ +function getGlslPartialDerivativeType(type) { + if (type === MetadataType.SCALAR) { + return "vec3"; + } else if (type === MetadataType.VEC2) { + return "mat2"; + } else if (type === MetadataType.VEC3) { + return "mat3"; + } else if (type === MetadataType.VEC4) { + return "mat4"; + } +} + +/** + * GLSL needs to have `.0` at the end of whole number floats or else it's + * treated like an integer. + * + * @function + * + * @param {Number} number The number to convert. + * @returns {String} The number as floating point in GLSL. + * + * @private + */ +function getGlslNumberAsFloat(number) { + let numberString = number.toString(); + if (numberString.indexOf(".") === -1) { + numberString = `${number}.0`; + } + return numberString; +} + +/** + * Gets the GLSL field + * + * @function + * + * @param {MetadataType} type + * @param {Number} index + * @returns {String} + * + * @private + */ +function getGlslField(type, index) { + if (type === MetadataType.SCALAR) { + return ""; + } + return `[${index}]`; +} + +export default processVoxelProperties; From 87ea92184f4cc171f97c9d477b5c410f589f6282 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 31 Aug 2022 17:19:12 -0400 Subject: [PATCH 091/679] Add VoxelRenderResourcesSpec --- Source/Scene/Cesium3DTilesVoxelProvider.js | 4 ++-- Source/Scene/GltfVoxelProvider.js | 4 ++-- Specs/Scene/VoxelPrimitiveSpec.js | 3 +-- Specs/Scene/VoxelRenderResourcesSpec.js | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 Specs/Scene/VoxelRenderResourcesSpec.js diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index e93605b9876..7a291d4cf80 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -112,7 +112,7 @@ function Cesium3DTilesVoxelProvider(options) { * TODO: mark this optional * This should not be called before {@link VoxelProvider#ready} returns true. * - * @type {Number|undefined} + * @type {Cartesian3|undefined} * @readonly */ this.paddingBefore = undefined; @@ -122,7 +122,7 @@ function Cesium3DTilesVoxelProvider(options) { * This should not be called before {@link VoxelProvider#ready} returns true. * TODO: mark this optional * - * @type {Number|undefined} + * @type {Cartesian3|undefined} * @readonly */ this.paddingAfter = undefined; diff --git a/Source/Scene/GltfVoxelProvider.js b/Source/Scene/GltfVoxelProvider.js index ec50bf91194..a7b9b055dde 100644 --- a/Source/Scene/GltfVoxelProvider.js +++ b/Source/Scene/GltfVoxelProvider.js @@ -108,7 +108,7 @@ function GltfVoxelProvider(options) { * TODO: mark this optional * This should not be called before {@link VoxelProvider#ready} returns true. * - * @type {Number|undefined} + * @type {Cartesian3|undefined} * @readonly */ this.paddingBefore = undefined; @@ -118,7 +118,7 @@ function GltfVoxelProvider(options) { * This should not be called before {@link VoxelProvider#ready} returns true. * TODO: mark this optional * - * @type {Number|undefined} + * @type {Cartesian3|undefined} * @readonly */ this.paddingAfter = undefined; diff --git a/Specs/Scene/VoxelPrimitiveSpec.js b/Specs/Scene/VoxelPrimitiveSpec.js index f066ac230fd..20f00a6cd12 100644 --- a/Specs/Scene/VoxelPrimitiveSpec.js +++ b/Specs/Scene/VoxelPrimitiveSpec.js @@ -1,7 +1,6 @@ import { Cartesian3, Cesium3DTilesVoxelProvider, - defined, Matrix4, VoxelPrimitive, } from "../../Source/Cesium.js"; @@ -46,7 +45,7 @@ describe( expect(primitive.shape._type).toBe(provider.shape._type); expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); expect(primitive._tileCount).toBe(provider._tileCount); - expect(defined(primitive._traversal)).toBe(true); + expect(primitive._traversal).toBeDefined(); // TODO should we test writing glsl functions? i.e. sample functions, setting style input values for each metadata }); }); diff --git a/Specs/Scene/VoxelRenderResourcesSpec.js b/Specs/Scene/VoxelRenderResourcesSpec.js new file mode 100644 index 00000000000..66dfb3c30ec --- /dev/null +++ b/Specs/Scene/VoxelRenderResourcesSpec.js @@ -0,0 +1,15 @@ +import { VoxelPrimitive, VoxelRenderResources } from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; + +describe("Scene/VoxelRenderResources", function () { + const scene = createScene(); + + it("constructs", function () { + const primitive = new VoxelPrimitive(); + primitive.show = false; + primitive.update(scene.frameState); + const renderResources = new VoxelRenderResources(primitive); + expect(renderResources.shaderBuilder).toBeDefined(); + expect(renderResources.uniformMap).toBeDefined(); + }); +}); From 0bce78024813ab566103994e10673e9a6c551ab3 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 31 Aug 2022 14:15:05 -0400 Subject: [PATCH 092/679] Fix import in SpatialNode --- Source/Scene/SpatialNode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/SpatialNode.js b/Source/Scene/SpatialNode.js index 28825c82bab..14c2525fc05 100644 --- a/Source/Scene/SpatialNode.js +++ b/Source/Scene/SpatialNode.js @@ -3,7 +3,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import CesiumMath from "../Core/Math.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; -import KeyframeNode from "./KeyframeNode"; +import KeyframeNode from "./KeyframeNode.js"; import Matrix3 from "../Core/Matrix3.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; From c5326bee9c310ee181f9d6d4216a26abc871cda0 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 31 Aug 2022 14:45:12 -0400 Subject: [PATCH 093/679] Fix more import syntax --- Source/Scene/VoxelDrawCommands.js | 6 +++--- Source/Scene/VoxelRenderResources.js | 4 ++-- Source/Scene/processVoxelProperties.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/VoxelDrawCommands.js index e6f7ebf4833..e2d5e872e77 100644 --- a/Source/Scene/VoxelDrawCommands.js +++ b/Source/Scene/VoxelDrawCommands.js @@ -1,4 +1,4 @@ -import defined from "../Core/defined"; +import defined from "../Core/defined.js"; import PrimitiveType from "../Core/PrimitiveType.js"; import BlendingState from "./BlendingState.js"; import CullFace from "./CullFace.js"; @@ -7,8 +7,8 @@ import DrawCommand from "../Renderer/DrawCommand.js"; import Pass from "../Renderer/Pass.js"; import RenderState from "../Renderer/RenderState.js"; import ShaderDestination from "../Renderer/ShaderDestination.js"; -import VoxelRenderResources from "./VoxelRenderResources"; -import processVoxelProperties from "./processVoxelProperties"; +import VoxelRenderResources from "./VoxelRenderResources.js"; +import processVoxelProperties from "./processVoxelProperties.js"; /** * @function diff --git a/Source/Scene/VoxelRenderResources.js b/Source/Scene/VoxelRenderResources.js index 6aa295e5753..922435690dc 100644 --- a/Source/Scene/VoxelRenderResources.js +++ b/Source/Scene/VoxelRenderResources.js @@ -1,6 +1,6 @@ -import Cartesian3 from "../Core/Cartesian3"; +import Cartesian3 from "../Core/Cartesian3.js"; import combine from "../Core/combine.js"; -import defined from "../Core/defined"; +import defined from "../Core/defined.js"; import ShaderBuilder from "../Renderer/ShaderBuilder.js"; import ShaderDestination from "../Renderer/ShaderDestination.js"; import VoxelFS from "../Shaders/Voxels/VoxelFS.js"; diff --git a/Source/Scene/processVoxelProperties.js b/Source/Scene/processVoxelProperties.js index 574ad35859a..61702148ca1 100644 --- a/Source/Scene/processVoxelProperties.js +++ b/Source/Scene/processVoxelProperties.js @@ -1,4 +1,4 @@ -import defined from "../Core/defined"; +import defined from "../Core/defined.js"; import MetadataType from "./MetadataType.js"; import ShaderDestination from "../Renderer/ShaderDestination.js"; From be35e4540be0fe62dd81fa5747df777bb4320ee6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 1 Sep 2022 15:43:27 -0400 Subject: [PATCH 094/679] Clean up VoxelPrimitive.update with early returns, smaller functions --- Source/Scene/VoxelPrimitive.js | 505 +++++++++++++++++---------------- 1 file changed, 256 insertions(+), 249 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 4437b04074f..a18dbec5c0c 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1123,7 +1123,6 @@ VoxelPrimitive.prototype.update = function (frameState) { }); uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - const dimensions = provider.dimensions; const shapeType = provider.shape; // Set the bounds @@ -1157,8 +1156,7 @@ VoxelPrimitive.prototype.update = function (frameState) { this._shape = new ShapeConstructor(); const shape = this._shape; - const shapeDefines = shape.shaderDefines; - this._shapeDefinesOld = clone(shapeDefines, true); + this._shapeDefinesOld = clone(shape.shaderDefines, true); // Add shape uniforms to the uniform map const shapeUniforms = shape.shaderUniforms; @@ -1190,6 +1188,7 @@ VoxelPrimitive.prototype.update = function (frameState) { // Set uniforms that come from the provider. // Note that minBounds and maxBounds can be set dynamically, so their uniforms aren't set here. + const dimensions = provider.dimensions; uniforms.dimensions = Cartesian3.clone(dimensions, uniforms.dimensions); uniforms.paddingBefore = Cartesian3.clone( this._paddingBefore, @@ -1204,40 +1203,28 @@ VoxelPrimitive.prototype.update = function (frameState) { // Check if the shape is dirty before updating it. This needs to happen every // frame because the member variables can be modified externally via the // getters. - const primitiveTransform = this._modelMatrix; const providerTransform = defaultValue( provider.modelMatrix, Matrix4.IDENTITY ); const compoundTransform = Matrix4.multiplyTransformation( providerTransform, - primitiveTransform, + this._modelMatrix, this._compoundModelMatrix ); - const compoundTransformOld = this._compoundModelMatrixOld; - const compoundTransformDirty = !Matrix4.equals( - compoundTransform, - compoundTransformOld + const compoundTransformDirty = this.updateBound( + "_compoundModelMatrix", + "_compoundModelMatrixOld" ); - - const shape = this._shape; - const minBounds = this._minBounds; - const maxBounds = this._maxBounds; - const minBoundsOld = this._minBoundsOld; - const maxBoundsOld = this._maxBoundsOld; - const minBoundsDirty = !Cartesian3.equals(minBounds, minBoundsOld); - const maxBoundsDirty = !Cartesian3.equals(maxBounds, maxBoundsOld); - const clipMinBounds = this._minClippingBounds; - const clipMaxBounds = this._maxClippingBounds; - const clipMinBoundsOld = this._minClippingBoundsOld; - const clipMaxBoundsOld = this._maxClippingBoundsOld; - const clipMinBoundsDirty = !Cartesian3.equals( - clipMinBounds, - clipMinBoundsOld + const minBoundsDirty = this.updateBound("_minBounds", "_minBoundsOld"); + const maxBoundsDirty = this.updateBound("_maxBounds", "_maxBoundsOld"); + const clipMinBoundsDirty = this.updateBound( + "_minClippingBounds", + "_minClippingBoundsOld" ); - const clipMaxBoundsDirty = !Cartesian3.equals( - clipMaxBounds, - clipMaxBoundsOld + const clipMaxBoundsDirty = this.updateBound( + "_maxClippingBounds", + "_maxClippingBoundsOld" ); const shapeDirty = @@ -1247,54 +1234,26 @@ VoxelPrimitive.prototype.update = function (frameState) { clipMinBoundsDirty || clipMaxBoundsDirty; - if (shapeDirty) { - if (compoundTransformDirty) { - this._compoundModelMatrixOld = Matrix4.clone( - compoundTransform, - this._compoundModelMatrixOld - ); - } - if (minBoundsDirty) { - this._minBoundsOld = Cartesian3.clone(minBounds, this._minBoundsOld); - } - if (maxBoundsDirty) { - this._maxBoundsOld = Cartesian3.clone(maxBounds, this._maxBoundsOld); - } - if (clipMinBoundsDirty) { - this._minClippingBoundsOld = Cartesian3.clone( - clipMinBounds, - this._minClippingBoundsOld - ); - } - if (clipMaxBoundsDirty) { - this._maxClippingBoundsOld = Cartesian3.clone( - clipMaxBounds, - this._maxClippingBoundsOld - ); - } - } - // Update the shape on the first frame or if it's dirty. - // If the shape is visible it will need to do some extra work. - if ( - (!this._ready || shapeDirty) && - (this._shapeVisible = shape.update( + const shape = this._shape; + if (!this._ready || shapeDirty) { + this._shapeVisible = shape.update( compoundTransform, - minBounds, - maxBounds, - clipMinBounds, - clipMaxBounds - )) - ) { + this._minBounds, + this._maxBounds, + this._clipMinBounds, + this._clipMaxBounds + ); + } + // If the shape is visible it will need to do some extra work. + if ((!this._ready || shapeDirty) && this._shapeVisible) { // Rebuild the shader if any of the shape defines changed. const shapeDefines = shape.shaderDefines; const shapeDefinesOld = this._shapeDefinesOld; let shapeDefinesChanged = false; for (const property in shapeDefines) { if (shapeDefines.hasOwnProperty(property)) { - const value = shapeDefines[property]; - const valueOld = shapeDefinesOld[property]; - if (value !== valueOld) { + if (shapeDefines[property] !== shapeDefinesOld[property]) { shapeDefinesChanged = true; break; } @@ -1436,203 +1395,251 @@ VoxelPrimitive.prototype.update = function (frameState) { // Update the traversal and prepare for rendering. // This doesn't happen on the first update frame. It needs to wait until the // primitive is made ready after the end of the first update frame. - if (this._ready && this._shapeVisible) { - const traversal = this._traversal; - const clock = this._clock; - const timeIntervalCollection = provider.timeIntervalCollection; - - // Find the keyframe location to render at. Doesn't need to be a whole number. - let keyframeLocation = 0.0; - if (defined(timeIntervalCollection) && defined(clock)) { - let date = clock.currentTime; - let timeInterval; - let timeIntervalIndex = timeIntervalCollection.indexOf(date); - if (timeIntervalIndex >= 0) { - timeInterval = timeIntervalCollection.get(timeIntervalIndex); - } else { - // Date fell outside the range - timeIntervalIndex = ~timeIntervalIndex; - if (timeIntervalIndex === timeIntervalCollection.length) { - // Date past range - timeIntervalIndex = timeIntervalCollection.length - 1; - timeInterval = timeIntervalCollection.get(timeIntervalIndex); - date = timeInterval.stop; - } else { - // Date before range - timeInterval = timeIntervalCollection.get(timeIntervalIndex); - date = timeInterval.start; - } - } - - // De-lerp between the start and end of the interval - const totalSeconds = JulianDate.secondsDifference( - timeInterval.stop, - timeInterval.start - ); - const secondsDifferenceStart = JulianDate.secondsDifference( - date, - timeInterval.start - ); - const t = secondsDifferenceStart / totalSeconds; - keyframeLocation = timeIntervalIndex + t; - } + if (!this._ready || !this._shapeVisible) { + return; + } + const clock = this._clock; + const timeIntervalCollection = provider.timeIntervalCollection; + const keyframeLocation = getKeyframeLocation(timeIntervalCollection, clock); + + const traversal = this._traversal; + const sampleCountOld = traversal._sampleCount; + + // Update the voxel traversal + traversal.update( + frameState, + keyframeLocation, + shapeDirty, // recomputeBoundingVolumes + this._disableUpdate // pauseUpdate + ); - const sampleCountOld = traversal._sampleCount; + if (sampleCountOld !== traversal._sampleCount) { + this._shaderDirty = true; + } - // Update the voxel traversal - traversal.update( - frameState, - keyframeLocation, - shapeDirty, // recomputeBoundingVolumes - this._disableUpdate // pauseUpdate - ); + const hasLoadedData = traversal.isRenderable(traversal.rootNode); + if (!hasLoadedData) { + return; + } - if (sampleCountOld !== traversal._sampleCount) { - this._shaderDirty = true; - } + if (this._debugDraw) { + // Debug draw bounding boxes and other things. Must go after traversal update + // because that's what updates the tile bounding boxes. + debugDraw(this, frameState); + } - const hasLoadedData = traversal.isRenderable(traversal.rootNode); + if (this._disableRender) { + return; + } - if (hasLoadedData && this._debugDraw) { - // Debug draw bounding boxes and other things. Must go after traversal update - // because that's what updates the tile bounding boxes. - debugDraw(this, frameState); - } + // Check if log depth changed + if (this._useLogDepth !== frameState.useLogDepth) { + this._useLogDepth = frameState.useLogDepth; + this._shaderDirty = true; + } - if (hasLoadedData && !this._disableRender) { - // Check if log depth changed - if (this._useLogDepth !== frameState.useLogDepth) { - this._useLogDepth = frameState.useLogDepth; - this._shaderDirty = true; - } + // Check if clipping planes changed + const clippingPlanesChanged = updateClippingPlanes(this, frameState); + if (clippingPlanesChanged) { + this._shaderDirty = true; + } - // Check if clipping planes changed - const clippingPlanes = this._clippingPlanes; - if (defined(clippingPlanes)) { - clippingPlanes.update(frameState); - const clippingPlanesState = clippingPlanes.clippingPlanesState; - const clippingPlanesEnabled = clippingPlanes.enabled; - if ( - this._clippingPlanesState !== clippingPlanesState || - this._clippingPlanesEnabled !== clippingPlanesEnabled - ) { - this._clippingPlanesState = clippingPlanesState; - this._clippingPlanesEnabled = clippingPlanesEnabled; - if (clippingPlanesEnabled) { - uniforms.clippingPlanesTexture = clippingPlanes.texture; - - // Compute the clipping plane's transformation to uv space and then take the inverse - // transpose to properly transform the hessian normal form of the plane. - - // transpose(inverse(worldToUv * clippingPlaneLocalToWorld)) - // transpose(inverse(clippingPlaneLocalToWorld) * inverse(worldToUv)) - // transpose(inverse(clippingPlaneLocalToWorld) * uvToWorld) - - const transformPositionUvToWorld = this._transformPositionUvToWorld; - uniforms.clippingPlanesMatrix = Matrix4.transpose( - Matrix4.multiplyTransformation( - Matrix4.inverse( - clippingPlanes.modelMatrix, - uniforms.clippingPlanesMatrix - ), - transformPositionUvToWorld, - uniforms.clippingPlanesMatrix - ), - uniforms.clippingPlanesMatrix - ); - } - this._shaderDirty = true; - } - } + const leafNodeTexture = traversal.leafNodeTexture; + if (defined(leafNodeTexture)) { + uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; + uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( + traversal.leafNodeTexelSizeUv, + uniforms.octreeLeafNodeTexelSizeUv + ); + uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; + } - const leafNodeTexture = traversal.leafNodeTexture; - if (defined(leafNodeTexture)) { - uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; - uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( - traversal.leafNodeTexelSizeUv, - uniforms.octreeLeafNodeTexelSizeUv - ); - uniforms.octreeLeafNodeTilesPerRow = traversal.leafNodeTilesPerRow; - } + // Rebuild shaders + if (this._shaderDirty) { + buildVoxelDrawCommands(this, context); + this._shaderDirty = false; + } - // Rebuild shaders - if (this._shaderDirty) { - buildVoxelDrawCommands(this, context); - this._shaderDirty = false; - } + // Calculate the NDC-space AABB to "scissor" the fullscreen quad + const transformPositionWorldToProjection = + context.uniformState.viewProjection; + const orientedBoundingBox = shape.orientedBoundingBox; + const ndcAabb = orientedBoundingBoxToNdcAabb( + orientedBoundingBox, + transformPositionWorldToProjection, + scratchNdcAabb + ); - // Calculate the NDC-space AABB to "scissor" the fullscreen quad - const transformPositionWorldToProjection = - context.uniformState.viewProjection; - const orientedBoundingBox = shape.orientedBoundingBox; - const ndcAabb = orientedBoundingBoxToNdcAabb( - orientedBoundingBox, - transformPositionWorldToProjection, - scratchNdcAabb - ); + // If the object is offscreen, don't render it. + const offscreen = + ndcAabb.x === +1.0 || + ndcAabb.y === +1.0 || + ndcAabb.z === -1.0 || + ndcAabb.w === -1.0; + if (offscreen) { + return; + } - // If the object is offscreen, don't render it. - const offscreen = - ndcAabb.x === +1.0 || - ndcAabb.y === +1.0 || - ndcAabb.z === -1.0 || - ndcAabb.w === -1.0; - - if (!offscreen) { - const transformPositionWorldToView = context.uniformState.view; - const transformPositionViewToWorld = context.uniformState.inverseView; - const transformDirectionViewToWorld = - context.uniformState.inverseViewRotation; - const transformDirectionWorldToLocal = this - ._transformDirectionWorldToLocal; - const transformPositionUvToWorld = this._transformPositionUvToWorld; - const transformPositionWorldToUv = this._transformPositionWorldToUv; - const transformNormalLocalToWorld = this._transformNormalLocalToWorld; - const cameraPositionWorld = frameState.camera.positionWC; - - // Update uniforms that can change every frame - uniforms.transformPositionViewToUv = Matrix4.multiply( - transformPositionWorldToUv, - transformPositionViewToWorld, - uniforms.transformPositionViewToUv - ); - uniforms.transformPositionUvToView = Matrix4.multiply( - transformPositionWorldToView, - transformPositionUvToWorld, - uniforms.transformPositionUvToView - ); - uniforms.transformDirectionViewToLocal = Matrix3.multiply( - transformDirectionWorldToLocal, - transformDirectionViewToWorld, - uniforms.transformDirectionViewToLocal - ); - uniforms.transformNormalLocalToWorld = Matrix3.clone( - transformNormalLocalToWorld, - uniforms.transformNormalLocalToWorld - ); - uniforms.cameraPositionUv = Matrix4.multiplyByPoint( - transformPositionWorldToUv, - cameraPositionWorld, - uniforms.cameraPositionUv - ); - uniforms.stepSize = this._stepSizeUv * this._stepSizeMultiplier; + // Prepare to render: update uniforms that can change every frame + // Using a uniform instead of going through RenderState's scissor because the viewport is not accessible here, and the scissor command needs pixel coordinates. + uniforms.ndcSpaceAxisAlignedBoundingBox = Cartesian4.clone( + ndcAabb, + uniforms.ndcSpaceAxisAlignedBoundingBox + ); + const transformPositionViewToWorld = context.uniformState.inverseView; + uniforms.transformPositionViewToUv = Matrix4.multiply( + this._transformPositionWorldToUv, + transformPositionViewToWorld, + uniforms.transformPositionViewToUv + ); + const transformPositionWorldToView = context.uniformState.view; + uniforms.transformPositionUvToView = Matrix4.multiply( + transformPositionWorldToView, + this._transformPositionUvToWorld, + uniforms.transformPositionUvToView + ); + const transformDirectionViewToWorld = + context.uniformState.inverseViewRotation; + uniforms.transformDirectionViewToLocal = Matrix3.multiply( + this._transformDirectionWorldToLocal, + transformDirectionViewToWorld, + uniforms.transformDirectionViewToLocal + ); + uniforms.transformNormalLocalToWorld = Matrix3.clone( + this._transformNormalLocalToWorld, + uniforms.transformNormalLocalToWorld + ); + const cameraPositionWorld = frameState.camera.positionWC; + uniforms.cameraPositionUv = Matrix4.multiplyByPoint( + this._transformPositionWorldToUv, + cameraPositionWorld, + uniforms.cameraPositionUv + ); + uniforms.stepSize = this._stepSizeUv * this._stepSizeMultiplier; + + // Render the primitive + const command = frameState.passes.pick + ? this._drawCommandPick + : this._drawCommand; + command.boundingVolume = shape.boundingSphere; + frameState.commandList.push(command); +}; - // Using a uniform instead of going through RenderState's scissor because the viewport is not accessible here, and the scissor command needs pixel coordinates. - uniforms.ndcSpaceAxisAlignedBoundingBox = Cartesian4.clone( - ndcAabb, - uniforms.ndcSpaceAxisAlignedBoundingBox - ); +/** + * Compare old and new values of a bound and update the old if it is different. + * @param {String} oldBoundKey A key pointing to a bounds object of type Cartesian3 or Matrix4 + * @param {String} newBoundKey A key pointing to a bounds object of the same type as the object at oldBoundKey + * @returns {Boolean} Whether the bound value changed + * + * @private + */ +VoxelPrimitive.prototype.updateBound = function (newBoundKey, oldBoundKey) { + const newBound = this[newBoundKey]; + const BoundClass = newBound.constructor; + const dirty = !BoundClass.equals(newBound, this[oldBoundKey]); + if (dirty) { + this[oldBoundKey] = BoundClass.clone(newBound, this[oldBoundKey]); + } + return dirty; +}; - // Render the primitive - const command = frameState.passes.pick - ? this._drawCommandPick - : this._drawCommand; - command.boundingVolume = shape.boundingSphere; - frameState.commandList.push(command); - } +/** + * Find the keyframe location to render at. Doesn't need to be a whole number. + * @param {TimeIntervalCollection} timeIntervalCollection + * @param {Clock} clock + * @returns {Number} + * + * @private + */ +function getKeyframeLocation(timeIntervalCollection, clock) { + if (!defined(timeIntervalCollection) || !defined(clock)) { + return 0.0; + } + let date = clock.currentTime; + let timeInterval; + let timeIntervalIndex = timeIntervalCollection.indexOf(date); + if (timeIntervalIndex >= 0) { + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + } else { + // Date fell outside the range + timeIntervalIndex = ~timeIntervalIndex; + if (timeIntervalIndex === timeIntervalCollection.length) { + // Date past range + timeIntervalIndex = timeIntervalCollection.length - 1; + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.stop; + } else { + // Date before range + timeInterval = timeIntervalCollection.get(timeIntervalIndex); + date = timeInterval.start; } } -}; + // De-lerp between the start and end of the interval + const totalSeconds = JulianDate.secondsDifference( + timeInterval.stop, + timeInterval.start + ); + const secondsDifferenceStart = JulianDate.secondsDifference( + date, + timeInterval.start + ); + const t = secondsDifferenceStart / totalSeconds; + + return timeIntervalIndex + t; +} + +/** + * Update the clipping planes state and associated uniforms + * + * @param {VoxelPrimitive} primitive + * @param {FrameState} frameState + * @returns {Boolean} Whether the clipping planes changed + * @private + */ +function updateClippingPlanes(primitive, frameState) { + const clippingPlanes = primitive._clippingPlanes; + if (!defined(clippingPlanes)) { + return false; + } + + clippingPlanes.update(frameState); + + const { clippingPlanesState, enabled } = clippingPlanes; + if ( + primitive._clippingPlanesState === clippingPlanesState && + primitive._clippingPlanesEnabled === enabled + ) { + return false; + } + primitive._clippingPlanesState = clippingPlanesState; + primitive._clippingPlanesEnabled = enabled; + + if (enabled) { + const uniforms = primitive._uniforms; + uniforms.clippingPlanesTexture = clippingPlanes.texture; + + // Compute the clipping plane's transformation to uv space and then take the inverse + // transpose to properly transform the hessian normal form of the plane. + + // transpose(inverse(worldToUv * clippingPlaneLocalToWorld)) + // transpose(inverse(clippingPlaneLocalToWorld) * inverse(worldToUv)) + // transpose(inverse(clippingPlaneLocalToWorld) * uvToWorld) + + uniforms.clippingPlanesMatrix = Matrix4.transpose( + Matrix4.multiplyTransformation( + Matrix4.inverse( + clippingPlanes.modelMatrix, + uniforms.clippingPlanesMatrix + ), + primitive._transformPositionUvToWorld, + uniforms.clippingPlanesMatrix + ), + uniforms.clippingPlanesMatrix + ); + } + + return true; +} /** * Returns true if this object was destroyed; otherwise, false. From 295e89e50b70772f2eb88579a180d84c79ebac0d Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 1 Sep 2022 19:23:22 -0400 Subject: [PATCH 095/679] Continue cleaning up VoxelPrimitive --- Source/Scene/VoxelPrimitive.js | 389 +++++++++++++++++---------------- 1 file changed, 200 insertions(+), 189 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index a18dbec5c0c..62cfa6e8d73 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1089,18 +1089,14 @@ const transformPositionUvToLocal = Matrix4.fromRotationTranslation( * @private */ VoxelPrimitive.prototype.update = function (frameState) { - const context = frameState.context; - const provider = this._provider; - const uniforms = this._uniforms; - const customShader = this._customShader; - // Update the provider, if applicable. + const provider = this._provider; if (defined(provider.update)) { provider.update(frameState); } // Update the custom shader in case it has texture uniforms. - customShader.update(frameState); + this._customShader.update(frameState); // Exit early if it's not ready yet. if (!this._ready && !provider.ready) { @@ -1108,6 +1104,8 @@ VoxelPrimitive.prototype.update = function (frameState) { } // Initialize from the ready provider. This only happens once. + const context = frameState.context; + const uniforms = this._uniforms; if (!this._ready) { // Don't make the primitive ready until after its first update because // external code may want to change some of its properties before it's rendered. @@ -1123,196 +1121,24 @@ VoxelPrimitive.prototype.update = function (frameState) { }); uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - const shapeType = provider.shape; - - // Set the bounds - const defaultMinBounds = VoxelShapeType.getMinBounds(shapeType); - const defaultMaxBounds = VoxelShapeType.getMaxBounds(shapeType); - const minBounds = defaultValue(provider.minBounds, defaultMinBounds); - const maxBounds = defaultValue(provider.maxBounds, defaultMaxBounds); - this._minBounds = Cartesian3.clone(minBounds, this._minBounds); - this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); - this._minBoundsOld = Cartesian3.clone(this._minBounds, this._minBoundsOld); - this._maxBoundsOld = Cartesian3.clone(this._maxBounds, this._maxBoundsOld); - this._minClippingBounds = Cartesian3.clone( - defaultMinBounds, - this._minClippingBounds - ); - this._maxClippingBounds = Cartesian3.clone( - defaultMaxBounds, - this._maxClippingBounds - ); - this._minClippingBoundsOld = Cartesian3.clone( - this._minClippingBounds, - this._minClippingBoundsOld - ); - this._maxClippingBoundsOld = Cartesian3.clone( - this._maxClippingBounds, - this._maxClippingBoundsOld - ); - - // Create the shape object - const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); - this._shape = new ShapeConstructor(); - - const shape = this._shape; - this._shapeDefinesOld = clone(shape.shaderDefines, true); - - // Add shape uniforms to the uniform map - const shapeUniforms = shape.shaderUniforms; - const uniformMap = this._uniformMap; - for (const key in shapeUniforms) { - if (shapeUniforms.hasOwnProperty(key)) { - const name = `u_${key}`; - - //>>includeStart('debug', pragmas.debug); - if (defined(uniformMap[name])) { - throw new DeveloperError(`Uniform name "${name}" is already defined`); - } - //>>includeEnd('debug'); - - uniformMap[name] = function () { - return shapeUniforms[key]; - }; - } - } - - this._paddingBefore = Cartesian3.clone( - defaultValue(provider.paddingBefore, Cartesian3.ZERO), - this._paddingBefore - ); - this._paddingAfter = Cartesian3.clone( - defaultValue(provider.paddingAfter, Cartesian3.ZERO), - this._paddingBefore - ); - - // Set uniforms that come from the provider. - // Note that minBounds and maxBounds can be set dynamically, so their uniforms aren't set here. - const dimensions = provider.dimensions; - uniforms.dimensions = Cartesian3.clone(dimensions, uniforms.dimensions); - uniforms.paddingBefore = Cartesian3.clone( - this._paddingBefore, - uniforms.paddingBefore - ); - uniforms.paddingAfter = Cartesian3.clone( - this._paddingAfter, - uniforms.paddingAfter - ); + initFromProvider(this, provider); } // Check if the shape is dirty before updating it. This needs to happen every // frame because the member variables can be modified externally via the // getters. - const providerTransform = defaultValue( - provider.modelMatrix, - Matrix4.IDENTITY - ); - const compoundTransform = Matrix4.multiplyTransformation( - providerTransform, - this._modelMatrix, - this._compoundModelMatrix - ); - const compoundTransformDirty = this.updateBound( - "_compoundModelMatrix", - "_compoundModelMatrixOld" - ); - const minBoundsDirty = this.updateBound("_minBounds", "_minBoundsOld"); - const maxBoundsDirty = this.updateBound("_maxBounds", "_maxBoundsOld"); - const clipMinBoundsDirty = this.updateBound( - "_minClippingBounds", - "_minClippingBoundsOld" - ); - const clipMaxBoundsDirty = this.updateBound( - "_maxClippingBounds", - "_maxClippingBoundsOld" - ); - - const shapeDirty = - compoundTransformDirty || - minBoundsDirty || - maxBoundsDirty || - clipMinBoundsDirty || - clipMaxBoundsDirty; - - // Update the shape on the first frame or if it's dirty. + const shapeDirty = checkTransformAndBounds(this, provider); const shape = this._shape; if (!this._ready || shapeDirty) { - this._shapeVisible = shape.update( - compoundTransform, - this._minBounds, - this._maxBounds, - this._clipMinBounds, - this._clipMaxBounds - ); - } - // If the shape is visible it will need to do some extra work. - if ((!this._ready || shapeDirty) && this._shapeVisible) { - // Rebuild the shader if any of the shape defines changed. - const shapeDefines = shape.shaderDefines; - const shapeDefinesOld = this._shapeDefinesOld; - let shapeDefinesChanged = false; - for (const property in shapeDefines) { - if (shapeDefines.hasOwnProperty(property)) { - if (shapeDefines[property] !== shapeDefinesOld[property]) { - shapeDefinesChanged = true; - break; - } - } - } + const shapeDefinesChanged = updateShapeAndTransforms(this, shape, provider); if (shapeDefinesChanged) { this._shaderDirty = true; - this._shapeDefinesOld = clone(shapeDefines, true); } - - const transformPositionLocalToWorld = shape.shapeTransform; - const transformPositionWorldToLocal = Matrix4.inverse( - transformPositionLocalToWorld, - scratchTransformPositionWorldToLocal - ); - const rotation = Matrix4.getRotation( - transformPositionLocalToWorld, - scratchRotation - ); - // Note that inverse(rotation) is the same as transpose(rotation) - const scale = Matrix4.getScale(transformPositionLocalToWorld, scratchScale); - const maximumScaleComponent = Cartesian3.maximumComponent(scale); - const localScale = Cartesian3.divideByScalar( - scale, - maximumScaleComponent, - scratchLocalScale - ); - const rotationAndLocalScale = Matrix3.multiplyByScale( - rotation, - localScale, - scratchRotationAndLocalScale - ); - - // Set member variables when the shape is dirty - const dimensions = provider.dimensions; - this._stepSizeUv = shape.computeApproximateStepSize(dimensions); - // TODO: check which of the `multiply` can be `multiplyTransformation` - this._transformPositionWorldToUv = Matrix4.multiply( - transformPositionLocalToUv, - transformPositionWorldToLocal, - this._transformPositionWorldToUv - ); - this._transformPositionUvToWorld = Matrix4.multiply( - transformPositionLocalToWorld, - transformPositionUvToLocal, - this._transformPositionUvToWorld - ); - this._transformDirectionWorldToLocal = Matrix4.getMatrix3( - transformPositionWorldToLocal, - this._transformDirectionWorldToLocal - ); - this._transformNormalLocalToWorld = Matrix3.inverseTranspose( - rotationAndLocalScale, - this._transformNormalLocalToWorld - ); } // Initialize from the ready shape. This only happens once. if (!this._ready) { + //initFromShape(this, context); const dimensions = provider.dimensions; const paddingBefore = this._paddingBefore; const paddingAfter = this._paddingAfter; @@ -1525,23 +1351,208 @@ VoxelPrimitive.prototype.update = function (frameState) { frameState.commandList.push(command); }; +/** + * Initialize primitive properties that are derived from the voxel provider + * @param {VoxelPrimitive} primitive + * @param {VoxelProvider} provider + * @private + */ +function initFromProvider(primitive, provider) { + const { + shape: shapeType, + minBounds = VoxelShapeType.getMinBounds(shapeType), + maxBounds = VoxelShapeType.getMaxBounds(shapeType), + } = provider; + + // Set the bounds + primitive._minBounds = Cartesian3.clone(minBounds, primitive._minBounds); + primitive._maxBounds = Cartesian3.clone(maxBounds, primitive._maxBounds); + primitive._minClippingBounds = Cartesian3.clone( + VoxelShapeType.getMinBounds(shapeType), + primitive._minClippingBounds + ); + primitive._maxClippingBounds = Cartesian3.clone( + VoxelShapeType.getMinBounds(shapeType), + primitive._maxClippingBounds + ); + + // Create the shape object + const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); + primitive._shape = new ShapeConstructor(); + + const { shaderDefines, shaderUniforms: shapeUniforms } = primitive._shape; + primitive._shapeDefinesOld = clone(shaderDefines, true); + + // Add shape uniforms to the uniform map + const uniformMap = primitive._uniformMap; + for (const key in shapeUniforms) { + if (shapeUniforms.hasOwnProperty(key)) { + const name = `u_${key}`; + + //>>includeStart('debug', pragmas.debug); + if (defined(uniformMap[name])) { + throw new DeveloperError(`Uniform name "${name}" is already defined`); + } + //>>includeEnd('debug'); + + uniformMap[name] = function () { + return shapeUniforms[key]; + }; + } + } + + // Set uniforms that come from the provider. + // Note that minBounds and maxBounds can be set dynamically, so their uniforms aren't set here. + const uniforms = primitive._uniforms; + uniforms.dimensions = Cartesian3.clone( + provider.dimensions, + uniforms.dimensions + ); + primitive._paddingBefore = Cartesian3.clone( + defaultValue(provider.paddingBefore, Cartesian3.ZERO), + primitive._paddingBefore + ); + uniforms.paddingBefore = Cartesian3.clone( + primitive._paddingBefore, + uniforms.paddingBefore + ); + primitive._paddingAfter = Cartesian3.clone( + defaultValue(provider.paddingAfter, Cartesian3.ZERO), + primitive._paddingBefore + ); + uniforms.paddingAfter = Cartesian3.clone( + primitive._paddingAfter, + uniforms.paddingAfter + ); +} + +/** + * Track changes in provider transform and primitive bounds + * @param {VoxelPrimitive} primitive + * @param {VoxelProvider} provider + * @returns {Boolean} Whether any of the transform or bounds changed + */ +function checkTransformAndBounds(primitive, provider) { + const providerTransform = defaultValue( + provider.modelMatrix, + Matrix4.IDENTITY + ); + primitive._compoundModelMatrix = Matrix4.multiplyTransformation( + providerTransform, + primitive._modelMatrix, + primitive._compoundModelMatrix + ); + return ( + updateBound(primitive, "_compoundModelMatrix", "_compoundModelMatrixOld") && + updateBound(primitive, "_minBounds", "_minBoundsOld") && + updateBound(primitive, "_maxBounds", "_maxBoundsOld") && + updateBound(primitive, "_minClippingBounds", "_minClippingBoundsOld") && + updateBound(primitive, "_maxClippingBounds", "_maxClippingBoundsOld") + ); +} + /** * Compare old and new values of a bound and update the old if it is different. - * @param {String} oldBoundKey A key pointing to a bounds object of type Cartesian3 or Matrix4 - * @param {String} newBoundKey A key pointing to a bounds object of the same type as the object at oldBoundKey + * @param {VoxelPrimitive} The primitive with bounds properties + * @param {String} oldBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 + * @param {String} newBoundKey A key pointing to a bounds property of the same type as the property at oldBoundKey * @returns {Boolean} Whether the bound value changed * * @private */ -VoxelPrimitive.prototype.updateBound = function (newBoundKey, oldBoundKey) { - const newBound = this[newBoundKey]; +function updateBound(primitive, newBoundKey, oldBoundKey) { + const newBound = primitive[newBoundKey]; const BoundClass = newBound.constructor; - const dirty = !BoundClass.equals(newBound, this[oldBoundKey]); + const dirty = !BoundClass.equals(newBound, primitive[oldBoundKey]); if (dirty) { - this[oldBoundKey] = BoundClass.clone(newBound, this[oldBoundKey]); + primitive[oldBoundKey] = BoundClass.clone(newBound, primitive[oldBoundKey]); } return dirty; -}; +} + +/** + * Update the shape and related transforms + * @param {VoxelPrimitive} primitive + * @param {VoxelShape} shape + * @param {VoxelProvider} provider + * @returns {Boolean} Whether any of the shape defines changed, requiring the shader to be rebuilt + */ +function updateShapeAndTransforms(primitive, shape, provider) { + primitive._shapeVisible = shape.update( + primitive._compoundModelMatrix, + primitive._minBounds, + primitive._maxBounds, + primitive._clipMinBounds, + primitive._clipMaxBounds + ); + if (!primitive._shapeVisible) { + return false; + } + + // Check if any of the shape defines changed. + const shapeDefines = shape.shaderDefines; + const shapeDefinesOld = primitive._shapeDefinesOld; + let shapeDefinesChanged = false; + for (const property in shapeDefines) { + if (shapeDefines.hasOwnProperty(property)) { + if (shapeDefines[property] !== shapeDefinesOld[property]) { + shapeDefinesChanged = true; + break; + } + } + } + if (shapeDefinesChanged) { + primitive._shapeDefinesOld = clone(shapeDefines, true); + } + + const transformPositionLocalToWorld = shape.shapeTransform; + const transformPositionWorldToLocal = Matrix4.inverse( + transformPositionLocalToWorld, + scratchTransformPositionWorldToLocal + ); + const rotation = Matrix4.getRotation( + transformPositionLocalToWorld, + scratchRotation + ); + // Note that inverse(rotation) is the same as transpose(rotation) + const scale = Matrix4.getScale(transformPositionLocalToWorld, scratchScale); + const maximumScaleComponent = Cartesian3.maximumComponent(scale); + const localScale = Cartesian3.divideByScalar( + scale, + maximumScaleComponent, + scratchLocalScale + ); + const rotationAndLocalScale = Matrix3.multiplyByScale( + rotation, + localScale, + scratchRotationAndLocalScale + ); + + // Set member variables when the shape is dirty + const dimensions = provider.dimensions; + primitive._stepSizeUv = shape.computeApproximateStepSize(dimensions); + // TODO: check which of the `multiply` can be `multiplyTransformation` + primitive._transformPositionWorldToUv = Matrix4.multiply( + transformPositionLocalToUv, + transformPositionWorldToLocal, + primitive._transformPositionWorldToUv + ); + primitive._transformPositionUvToWorld = Matrix4.multiply( + transformPositionLocalToWorld, + transformPositionUvToLocal, + primitive._transformPositionUvToWorld + ); + primitive._transformDirectionWorldToLocal = Matrix4.getMatrix3( + transformPositionWorldToLocal, + primitive._transformDirectionWorldToLocal + ); + primitive._transformNormalLocalToWorld = Matrix3.inverseTranspose( + rotationAndLocalScale, + primitive._transformNormalLocalToWorld + ); + + return shapeDefinesChanged; +} /** * Find the keyframe location to render at. Doesn't need to be a whole number. From e1314de44fe5000c4c1390019332786aff050731 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 6 Sep 2022 18:48:53 -0400 Subject: [PATCH 096/679] Pull one-time actions out of VoxelPrimitive.update --- Source/Scene/VoxelPrimitive.js | 193 +++++++++++++++++---------------- 1 file changed, 99 insertions(+), 94 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 62cfa6e8d73..071e70c1787 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1059,7 +1059,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { // TODO 3-channel + 1-channel metadata is a problem right now // Individually, they both work, but together the 1-channel is messed up -const scratchTotalDimensions = new Cartesian3(); +const scratchDimensions = new Cartesian3(); const scratchIntersect = new Cartesian4(); const scratchNdcAabb = new Cartesian4(); const scratchScale = new Cartesian3(); @@ -1136,86 +1136,10 @@ VoxelPrimitive.prototype.update = function (frameState) { } } - // Initialize from the ready shape. This only happens once. + // Set up traversal using the updated shape. This only happens once. if (!this._ready) { - //initFromShape(this, context); - const dimensions = provider.dimensions; - const paddingBefore = this._paddingBefore; - const paddingAfter = this._paddingAfter; - const totalDimensions = Cartesian3.clone( - dimensions, - scratchTotalDimensions - ); - Cartesian3.add(totalDimensions, paddingBefore, totalDimensions); - Cartesian3.add(totalDimensions, paddingAfter, totalDimensions); - - const types = provider.types; - const componentTypes = provider.componentTypes; - - // Traversal setup - // It's ok for memory byte length to be undefined. - // The system will choose a default memory size. - const maximumTileCount = provider.maximumTileCount; - const maximumTextureMemoryByteLength = defined(maximumTileCount) - ? VoxelTraversal.getApproximateTextureMemoryByteLength( - maximumTileCount, - totalDimensions, - types, - componentTypes - ) - : undefined; - - const keyframeCount = defaultValue(provider.keyframeCount, 1); - - this._traversal = new VoxelTraversal( - this, - context, - totalDimensions, - types, - componentTypes, - keyframeCount, - maximumTextureMemoryByteLength - ); - - // Set uniforms that come from the traversal. - // TODO: should this be done in VoxelTraversal? - const traversal = this._traversal; - - uniforms.octreeInternalNodeTexture = traversal.internalNodeTexture; - uniforms.octreeInternalNodeTexelSizeUv = Cartesian2.clone( - traversal.internalNodeTexelSizeUv, - uniforms.octreeInternalNodeTexelSizeUv - ); - uniforms.octreeInternalNodeTilesPerRow = traversal.internalNodeTilesPerRow; - - const megatextures = traversal.megatextures; - const megatexture = megatextures[0]; - const megatextureLength = megatextures.length; - uniforms.megatextureTextures = new Array(megatextureLength); - for (let i = 0; i < megatextureLength; i++) { - uniforms.megatextureTextures[i] = megatextures[i].texture; - } - - uniforms.megatextureSliceDimensions = Cartesian2.clone( - megatexture.sliceCountPerRegion, - uniforms.megatextureSliceDimensions - ); - uniforms.megatextureTileDimensions = Cartesian2.clone( - megatexture.regionCountPerMegatexture, - uniforms.megatextureTileDimensions - ); - uniforms.megatextureVoxelSizeUv = Cartesian2.clone( - megatexture.voxelSizeUv, - uniforms.megatextureVoxelSizeUv - ); - uniforms.megatextureSliceSizeUv = Cartesian2.clone( - megatexture.sliceSizeUv, - uniforms.megatextureSliceSizeUv - ); - uniforms.megatextureTileSizeUv = Cartesian2.clone( - megatexture.regionSizeUv, - uniforms.megatextureTileSizeUv - ); + this._traversal = setupTraversal(this, provider, context); + setTraversalUniforms(this._traversal, uniforms); } // Update the traversal and prepare for rendering. @@ -1231,7 +1155,6 @@ VoxelPrimitive.prototype.update = function (frameState) { const traversal = this._traversal; const sampleCountOld = traversal._sampleCount; - // Update the voxel traversal traversal.update( frameState, keyframeLocation, @@ -1243,8 +1166,7 @@ VoxelPrimitive.prototype.update = function (frameState) { this._shaderDirty = true; } - const hasLoadedData = traversal.isRenderable(traversal.rootNode); - if (!hasLoadedData) { + if (!traversal.isRenderable(traversal.rootNode)) { return; } @@ -1442,13 +1364,13 @@ function checkTransformAndBounds(primitive, provider) { primitive._modelMatrix, primitive._compoundModelMatrix ); - return ( - updateBound(primitive, "_compoundModelMatrix", "_compoundModelMatrixOld") && - updateBound(primitive, "_minBounds", "_minBoundsOld") && - updateBound(primitive, "_maxBounds", "_maxBoundsOld") && - updateBound(primitive, "_minClippingBounds", "_minClippingBoundsOld") && - updateBound(primitive, "_maxClippingBounds", "_maxClippingBoundsOld") - ); + const numChanges = + updateBound(primitive, "_compoundModelMatrix", "_compoundModelMatrixOld") + + updateBound(primitive, "_minBounds", "_minBoundsOld") + + updateBound(primitive, "_maxBounds", "_maxBoundsOld") + + updateBound(primitive, "_minClippingBounds", "_minClippingBoundsOld") + + updateBound(primitive, "_maxClippingBounds", "_maxClippingBoundsOld"); + return numChanges > 0; } /** @@ -1456,18 +1378,18 @@ function checkTransformAndBounds(primitive, provider) { * @param {VoxelPrimitive} The primitive with bounds properties * @param {String} oldBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 * @param {String} newBoundKey A key pointing to a bounds property of the same type as the property at oldBoundKey - * @returns {Boolean} Whether the bound value changed + * @returns {Number} 1 if the bound value changed, 0 otherwise * * @private */ function updateBound(primitive, newBoundKey, oldBoundKey) { const newBound = primitive[newBoundKey]; const BoundClass = newBound.constructor; - const dirty = !BoundClass.equals(newBound, primitive[oldBoundKey]); - if (dirty) { + const changed = !BoundClass.equals(newBound, primitive[oldBoundKey]); + if (changed) { primitive[oldBoundKey] = BoundClass.clone(newBound, primitive[oldBoundKey]); } - return dirty; + return changed ? 1 : 0; } /** @@ -1554,6 +1476,89 @@ function updateShapeAndTransforms(primitive, shape, provider) { return shapeDefinesChanged; } +/** + * Set up a VoxelTraversal based on dimensions and types from the primitive and provider + * @param {VoxelPrimitive} primitive + * @param {VoxelProvider} provider + * @param {Context} context + * @returns {VoxelTraversal} + * @private + */ +function setupTraversal(primitive, provider, context) { + const dimensions = Cartesian3.clone(provider.dimensions, scratchDimensions); + Cartesian3.add(dimensions, primitive._paddingBefore, dimensions); + Cartesian3.add(dimensions, primitive._paddingAfter, dimensions); + + // It's ok for memory byte length to be undefined. + // The system will choose a default memory size. + const maximumTileCount = provider.maximumTileCount; + const maximumTextureMemoryByteLength = defined(maximumTileCount) + ? VoxelTraversal.getApproximateTextureMemoryByteLength( + maximumTileCount, + dimensions, + provider.types, + provider.componentTypes + ) + : undefined; + + const keyframeCount = defaultValue(provider.keyframeCount, 1); + + return new VoxelTraversal( + primitive, + context, + dimensions, + provider.types, + provider.componentTypes, + keyframeCount, + maximumTextureMemoryByteLength + ); +} + +/** + * Set uniforms that come from the traversal. + * TODO: should this be done in VoxelTraversal? + * @param {VoxelTraversal} traversal + * @param {Object} uniforms + * @private + */ +function setTraversalUniforms(traversal, uniforms) { + uniforms.octreeInternalNodeTexture = traversal.internalNodeTexture; + uniforms.octreeInternalNodeTexelSizeUv = Cartesian2.clone( + traversal.internalNodeTexelSizeUv, + uniforms.octreeInternalNodeTexelSizeUv + ); + uniforms.octreeInternalNodeTilesPerRow = traversal.internalNodeTilesPerRow; + + const megatextures = traversal.megatextures; + const megatexture = megatextures[0]; + const megatextureLength = megatextures.length; + uniforms.megatextureTextures = new Array(megatextureLength); + for (let i = 0; i < megatextureLength; i++) { + uniforms.megatextureTextures[i] = megatextures[i].texture; + } + + uniforms.megatextureSliceDimensions = Cartesian2.clone( + megatexture.sliceCountPerRegion, + uniforms.megatextureSliceDimensions + ); + uniforms.megatextureTileDimensions = Cartesian2.clone( + megatexture.regionCountPerMegatexture, + uniforms.megatextureTileDimensions + ); + uniforms.megatextureVoxelSizeUv = Cartesian2.clone( + megatexture.voxelSizeUv, + uniforms.megatextureVoxelSizeUv + ); + uniforms.megatextureSliceSizeUv = Cartesian2.clone( + megatexture.sliceSizeUv, + uniforms.megatextureSliceSizeUv + ); + uniforms.megatextureTileSizeUv = Cartesian2.clone( + megatexture.regionSizeUv, + uniforms.megatextureTileSizeUv + ); +} + /** * Find the keyframe location to render at. Doesn't need to be a whole number. * @param {TimeIntervalCollection} timeIntervalCollection From d106eddc976cb806d6ab6ebace9551585c144411 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 7 Sep 2022 13:57:23 -0400 Subject: [PATCH 097/679] Move all one-time code in VoxelPrimitive.update to initFromProvider --- Source/Scene/VoxelPrimitive.js | 105 ++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 071e70c1787..0502f29776b 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1105,7 +1105,6 @@ VoxelPrimitive.prototype.update = function (frameState) { // Initialize from the ready provider. This only happens once. const context = frameState.context; - const uniforms = this._uniforms; if (!this._ready) { // Don't make the primitive ready until after its first update because // external code may want to change some of its properties before it's rendered. @@ -1115,13 +1114,8 @@ VoxelPrimitive.prototype.update = function (frameState) { primitive._readyPromise.resolve(primitive); }); - // Create pickId here instead of the constructor because it needs the context object. - this._pickId = context.createPickId({ - primitive: this, - }); - uniforms.pickColor = Color.clone(this._pickId.color, uniforms.pickColor); - - initFromProvider(this, provider); + initFromProvider(this, provider, context); + return; } // Check if the shape is dirty before updating it. This needs to happen every @@ -1129,28 +1123,21 @@ VoxelPrimitive.prototype.update = function (frameState) { // getters. const shapeDirty = checkTransformAndBounds(this, provider); const shape = this._shape; - if (!this._ready || shapeDirty) { - const shapeDefinesChanged = updateShapeAndTransforms(this, shape, provider); - if (shapeDefinesChanged) { + if (shapeDirty) { + this._shapeVisible = updateShapeAndTransforms(this, shape, provider); + if (checkShapeDefines(this, shape)) { this._shaderDirty = true; } } - - // Set up traversal using the updated shape. This only happens once. - if (!this._ready) { - this._traversal = setupTraversal(this, provider, context); - setTraversalUniforms(this._traversal, uniforms); + if (!this._shapeVisible) { + return; } // Update the traversal and prepare for rendering. - // This doesn't happen on the first update frame. It needs to wait until the - // primitive is made ready after the end of the first update frame. - if (!this._ready || !this._shapeVisible) { - return; - } - const clock = this._clock; - const timeIntervalCollection = provider.timeIntervalCollection; - const keyframeLocation = getKeyframeLocation(timeIntervalCollection, clock); + const keyframeLocation = getKeyframeLocation( + provider.timeIntervalCollection, + this._clock + ); const traversal = this._traversal; const sampleCountOld = traversal._sampleCount; @@ -1193,6 +1180,7 @@ VoxelPrimitive.prototype.update = function (frameState) { } const leafNodeTexture = traversal.leafNodeTexture; + const uniforms = this._uniforms; if (defined(leafNodeTexture)) { uniforms.octreeLeafNodeTexture = traversal.leafNodeTexture; uniforms.octreeLeafNodeTexelSizeUv = Cartesian2.clone( @@ -1277,16 +1265,22 @@ VoxelPrimitive.prototype.update = function (frameState) { * Initialize primitive properties that are derived from the voxel provider * @param {VoxelPrimitive} primitive * @param {VoxelProvider} provider + * @param {Context} context * @private */ -function initFromProvider(primitive, provider) { +function initFromProvider(primitive, provider, context) { + const uniforms = primitive._uniforms; + + primitive._pickId = context.createPickId({ primitive }); + uniforms.pickColor = Color.clone(primitive._pickId.color, uniforms.pickColor); + + // Set the bounds const { shape: shapeType, minBounds = VoxelShapeType.getMinBounds(shapeType), maxBounds = VoxelShapeType.getMaxBounds(shapeType), } = provider; - // Set the bounds primitive._minBounds = Cartesian3.clone(minBounds, primitive._minBounds); primitive._maxBounds = Cartesian3.clone(maxBounds, primitive._maxBounds); primitive._minClippingBounds = Cartesian3.clone( @@ -1298,9 +1292,16 @@ function initFromProvider(primitive, provider) { primitive._maxClippingBounds ); - // Create the shape object + checkTransformAndBounds(primitive, provider); + + // Create the shape object, and update it so it is valid for VoxelTraversal const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); primitive._shape = new ShapeConstructor(); + primitive._shapeVisible = updateShapeAndTransforms( + primitive, + primitive._shape, + provider + ); const { shaderDefines, shaderUniforms: shapeUniforms } = primitive._shape; primitive._shapeDefinesOld = clone(shaderDefines, true); @@ -1325,7 +1326,6 @@ function initFromProvider(primitive, provider) { // Set uniforms that come from the provider. // Note that minBounds and maxBounds can be set dynamically, so their uniforms aren't set here. - const uniforms = primitive._uniforms; uniforms.dimensions = Cartesian3.clone( provider.dimensions, uniforms.dimensions @@ -1346,6 +1346,10 @@ function initFromProvider(primitive, provider) { primitive._paddingAfter, uniforms.paddingAfter ); + + // Create the VoxelTraversal, and set related uniforms + primitive._traversal = setupTraversal(primitive, provider, context); + setTraversalUniforms(primitive._traversal, uniforms); } /** @@ -1397,36 +1401,21 @@ function updateBound(primitive, newBoundKey, oldBoundKey) { * @param {VoxelPrimitive} primitive * @param {VoxelShape} shape * @param {VoxelProvider} provider - * @returns {Boolean} Whether any of the shape defines changed, requiring the shader to be rebuilt + * @returns {Boolean} True if the shape is visible + * @private */ function updateShapeAndTransforms(primitive, shape, provider) { - primitive._shapeVisible = shape.update( + const visible = shape.update( primitive._compoundModelMatrix, primitive._minBounds, primitive._maxBounds, primitive._clipMinBounds, primitive._clipMaxBounds ); - if (!primitive._shapeVisible) { + if (!visible) { return false; } - // Check if any of the shape defines changed. - const shapeDefines = shape.shaderDefines; - const shapeDefinesOld = primitive._shapeDefinesOld; - let shapeDefinesChanged = false; - for (const property in shapeDefines) { - if (shapeDefines.hasOwnProperty(property)) { - if (shapeDefines[property] !== shapeDefinesOld[property]) { - shapeDefinesChanged = true; - break; - } - } - } - if (shapeDefinesChanged) { - primitive._shapeDefinesOld = clone(shapeDefines, true); - } - const transformPositionLocalToWorld = shape.shapeTransform; const transformPositionWorldToLocal = Matrix4.inverse( transformPositionLocalToWorld, @@ -1473,7 +1462,7 @@ function updateShapeAndTransforms(primitive, shape, provider) { primitive._transformNormalLocalToWorld ); - return shapeDefinesChanged; + return true; } /** @@ -1559,6 +1548,24 @@ function setTraversalUniforms(traversal, uniforms) { ); } +/** + * Track changes in shape-related shader defines + * @param {VoxelPrimitive} primitive + * @param {VoxelShape} shape + * @returns {Boolean} True if any of the shape defines changed, requiring a shader rebuild + * @private + */ +function checkShapeDefines(primitive, shape) { + const shapeDefines = shape.shaderDefines; + const shapeDefinesChanged = Object.keys(shapeDefines).some( + (key) => shapeDefines[key] !== primitive._shapeDefinesOld[key] + ); + if (shapeDefinesChanged) { + primitive._shapeDefinesOld = clone(shapeDefines, true); + } + return shapeDefinesChanged; +} + /** * Find the keyframe location to render at. Doesn't need to be a whole number. * @param {TimeIntervalCollection} timeIntervalCollection @@ -1609,7 +1616,7 @@ function getKeyframeLocation(timeIntervalCollection, clock) { * * @param {VoxelPrimitive} primitive * @param {FrameState} frameState - * @returns {Boolean} Whether the clipping planes changed + * @returns {Boolean} Whether the clipping planes changed, requiring a shader rebuild * @private */ function updateClippingPlanes(primitive, frameState) { From f9f58a987b57eb0e40d5ae77ad582fb439b5c71a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 7 Sep 2022 19:00:23 -0400 Subject: [PATCH 098/679] Fix voxel clipping planes, add spec for VoxelPrimitive.destroy --- Source/Scene/VoxelPrimitive.js | 97 ++++--------------------------- Specs/Scene/VoxelPrimitiveSpec.js | 19 ++++++ 2 files changed, 30 insertions(+), 86 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 0502f29776b..a0aefca060c 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -547,19 +547,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {Matrix4} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ compoundModelMatrix: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "compoundModelMatrix must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._compoundModelMatrix; }, }, @@ -849,29 +839,14 @@ Object.defineProperties(VoxelPrimitive.prototype, { * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * - * @exception {DeveloperError} If the primitive is not ready. */ minBounds: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minBounds must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._minBounds; }, set: function (minBounds) { //>>includeStart('debug', pragmas.debug); Check.defined("minBounds", minBounds); - if (!this._ready) { - throw new DeveloperError( - "minBounds must not be called before the primitive is ready." - ); - } //>>includeEnd('debug'); this._minBounds = Cartesian3.clone(minBounds, this._minBounds); @@ -883,29 +858,14 @@ Object.defineProperties(VoxelPrimitive.prototype, { * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * - * @exception {DeveloperError} If the primitive is not ready. */ maxBounds: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maxBounds must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._maxBounds; }, set: function (maxBounds) { //>>includeStart('debug', pragmas.debug); Check.defined("maxBounds", maxBounds); - if (!this._ready) { - throw new DeveloperError( - "maxBounds must not be called before the primitive is ready." - ); - } //>>includeEnd('debug'); this._maxBounds = Cartesian3.clone(maxBounds, this._maxBounds); @@ -919,29 +879,14 @@ Object.defineProperties(VoxelPrimitive.prototype, { * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * - * @exception {DeveloperError} If the primitive is not ready. */ minClippingBounds: { get: function () { - //>>includeStart('debug', pragmas.debug) - if (!this._ready) { - throw new DeveloperError( - "minClippingBounds must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._minClippingBounds; }, set: function (minClippingBounds) { //>>includeStart('debug', pragmas.debug); Check.defined("minClippingBounds", minClippingBounds); - if (!this._ready) { - throw new DeveloperError( - "minClippingBounds must not be called before the primitive is ready." - ); - } //>>includeEnd('debug'); this._minClippingBounds = Cartesian3.clone( @@ -958,29 +903,14 @@ Object.defineProperties(VoxelPrimitive.prototype, { * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} - * - * @exception {DeveloperError} If the primitive is not ready. */ maxClippingBounds: { get: function () { - //>>includeStart('debug', pragmas.debug) - if (!this._ready) { - throw new DeveloperError( - "maxClippingBounds must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._maxClippingBounds; }, set: function (maxClippingBounds) { //>>includeStart('debug', pragmas.debug); Check.defined("maxClippingBounds", maxClippingBounds); - if (!this._ready) { - throw new DeveloperError( - "maxClippingBounds must not be called before the primitive is ready." - ); - } //>>includeEnd('debug'); this._maxClippingBounds = Cartesian3.clone( @@ -1281,16 +1211,10 @@ function initFromProvider(primitive, provider, context) { maxBounds = VoxelShapeType.getMaxBounds(shapeType), } = provider; - primitive._minBounds = Cartesian3.clone(minBounds, primitive._minBounds); - primitive._maxBounds = Cartesian3.clone(maxBounds, primitive._maxBounds); - primitive._minClippingBounds = Cartesian3.clone( - VoxelShapeType.getMinBounds(shapeType), - primitive._minClippingBounds - ); - primitive._maxClippingBounds = Cartesian3.clone( - VoxelShapeType.getMinBounds(shapeType), - primitive._maxClippingBounds - ); + primitive.minBounds = minBounds; + primitive.maxBounds = maxBounds; + primitive.minClippingBounds = VoxelShapeType.getMinBounds(shapeType); + primitive.maxClippingBounds = VoxelShapeType.getMaxBounds(shapeType); checkTransformAndBounds(primitive, provider); @@ -1357,6 +1281,7 @@ function initFromProvider(primitive, provider, context) { * @param {VoxelPrimitive} primitive * @param {VoxelProvider} provider * @returns {Boolean} Whether any of the transform or bounds changed + * @private */ function checkTransformAndBounds(primitive, provider) { const providerTransform = defaultValue( @@ -1406,11 +1331,11 @@ function updateBound(primitive, newBoundKey, oldBoundKey) { */ function updateShapeAndTransforms(primitive, shape, provider) { const visible = shape.update( - primitive._compoundModelMatrix, - primitive._minBounds, - primitive._maxBounds, - primitive._clipMinBounds, - primitive._clipMaxBounds + primitive.compoundModelMatrix, + primitive.minBounds, + primitive.maxBounds, + primitive.minClippingBounds, + primitive.maxClippingBounds ); if (!visible) { return false; @@ -1620,7 +1545,7 @@ function getKeyframeLocation(timeIntervalCollection, clock) { * @private */ function updateClippingPlanes(primitive, frameState) { - const clippingPlanes = primitive._clippingPlanes; + const clippingPlanes = primitive.clippingPlanes; if (!defined(clippingPlanes)) { return false; } diff --git a/Specs/Scene/VoxelPrimitiveSpec.js b/Specs/Scene/VoxelPrimitiveSpec.js index 20f00a6cd12..b30092adf89 100644 --- a/Specs/Scene/VoxelPrimitiveSpec.js +++ b/Specs/Scene/VoxelPrimitiveSpec.js @@ -87,6 +87,25 @@ describe( expect(primitive._stepSizeUv).toBe(stepSizeUv); }); }); + + it("destroys", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); + expect(primitive.isDestroyed()).toBe(false); + + return primitive.readyPromise.then(function () { + primitive.update(scene.frameState); + expect(primitive.isDestroyed()).toBe(false); + expect(primitive._pickId).toBeDefined(); + expect(primitive._traversal).toBeDefined(); + + primitive.destroy(); + expect(primitive.isDestroyed()).toBe(true); + expect(primitive._pickId).toBeUndefined(); + expect(primitive._traversal).toBeUndefined(); + }); + }); }, "WebGL" ); From 873317eeb8a3f39836fe378609b206868976d2ae Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 8 Sep 2022 19:20:39 -0400 Subject: [PATCH 099/679] Add specs for VoxelTraversal and VoxelPrimitive --- Source/Scene/SpatialNode.js | 104 +++++------------ Source/Scene/VoxelTraversal.js | 179 +++++++++++------------------- Specs/Scene/VoxelPrimitiveSpec.js | 27 +++++ Specs/Scene/VoxelTraversalSpec.js | 38 ++++--- 4 files changed, 136 insertions(+), 212 deletions(-) diff --git a/Source/Scene/SpatialNode.js b/Source/Scene/SpatialNode.js index 14c2525fc05..cb284a4def6 100644 --- a/Source/Scene/SpatialNode.js +++ b/Source/Scene/SpatialNode.js @@ -137,38 +137,21 @@ const scratchBinarySearchKeyframeNode = { }; /** - * Finds the index of the keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * + * Find the index of a given key frame position within an array of KeyframeNodes, + * or the complement (~) of the index where it would be in the sorted array. * @param {Number} keyframe + * @param {KeyframeNode[]} keyframeNodes * @returns {Number} + * @private */ -SpatialNode.prototype.findKeyframeIndex = function (keyframe) { - const keyframeNodes = this.keyframeNodes; +function findKeyframeIndex(keyframe, keyframeNodes) { scratchBinarySearchKeyframeNode.keyframe = keyframe; - const index = binarySearch( + return binarySearch( keyframeNodes, scratchBinarySearchKeyframeNode, KeyframeNode.searchComparator ); - return index; -}; - -/** - * Finds the index of the renderable keyframe if it exists, or the complement (~) of the index where it would be in the sorted array. - * - * @param {Number} keyframe - * @returns {Number} - */ -SpatialNode.prototype.findRenderableKeyframeIndex = function (keyframe) { - const renderableKeyframeNodes = this.renderableKeyframeNodes; - scratchBinarySearchKeyframeNode.keyframe = keyframe; - const index = binarySearch( - renderableKeyframeNodes, - scratchBinarySearchKeyframeNode, - KeyframeNode.searchComparator - ); - return index; -}; +} /** * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. @@ -193,8 +176,9 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( const renderableKeyframeNodes = spatialNode.renderableKeyframeNodes; if (renderableKeyframeNodes.length >= 1) { - let keyframeNodeIndexPrev = spatialNode.findRenderableKeyframeIndex( - targetKeyframePrev + let keyframeNodeIndexPrev = findKeyframeIndex( + targetKeyframePrev, + renderableKeyframeNodes ); if (keyframeNodeIndexPrev < 0) { keyframeNodeIndexPrev = CesiumMath.clamp( @@ -286,48 +270,44 @@ SpatialNode.prototype.isVisited = function (frameNumber) { * @param {Number} keyframe */ SpatialNode.prototype.createKeyframeNode = function (keyframe) { - let index = this.findKeyframeIndex(keyframe); + let index = findKeyframeIndex(keyframe, this.keyframeNodes); if (index < 0) { index = ~index; // convert to insertion index const keyframeNode = new KeyframeNode(this, keyframe); this.keyframeNodes.splice(index, 0, keyframeNode); } }; + /** * @param {KeyframeNode} keyframeNode - * @param {Megatexture} megatexture + * @param {Megatexture[]} megatextures */ SpatialNode.prototype.destroyKeyframeNode = function ( keyframeNode, megatextures ) { const keyframe = keyframeNode.keyframe; - const keyframeIndex = this.findKeyframeIndex(keyframe); + const keyframeIndex = findKeyframeIndex(keyframe, this.keyframeNodes); if (keyframeIndex < 0) { throw new DeveloperError("Keyframe node does not exist."); } - const keyframeNodes = this.keyframeNodes; - keyframeNodes.splice(keyframeIndex, 1); + this.keyframeNodes.splice(keyframeIndex, 1); if (keyframeNode.megatextureIndex !== -1) { - const megatextureArray = Object.keys(megatextures).map(function (key) { - return megatextures[key]; - }); // Object.values workaround - const numberOfMegatextures = megatextureArray.length; - for (let i = 0; i < numberOfMegatextures; i++) { - megatextureArray[i].remove(keyframeNode.megatextureIndex); + for (let i = 0; i < megatextures.length; i++) { + megatextures[i].remove(keyframeNode.megatextureIndex); } - const renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframe + const renderableKeyframeNodeIndex = findKeyframeIndex( + keyframe, + this.renderableKeyframeNodes ); if (renderableKeyframeNodeIndex < 0) { throw new DeveloperError("Renderable keyframe node does not exist."); } - const renderableKeyframeNodes = this.renderableKeyframeNodes; - renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); + this.renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1); } keyframeNode.spatialNode = undefined; @@ -354,8 +334,7 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( throw new DeveloperError("Keyframe node cannot be added to megatexture"); } - const length = megatextures.length; - for (let i = 0; i < length; i++) { + for (let i = 0; i < megatextures.length; i++) { const megatexture = megatextures[i]; keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadatas[i]); keyframeNode.metadatas[i] = undefined; // data is in megatexture so no need to hold onto it @@ -364,41 +343,9 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( keyframeNode.state = KeyframeNode.LoadState.LOADED; const renderableKeyframeNodes = this.renderableKeyframeNodes; - let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframeNode.keyframe - ); - if (renderableKeyframeNodeIndex >= 0) { - throw new DeveloperError("Keyframe already renderable"); - } - renderableKeyframeNodeIndex = ~renderableKeyframeNodeIndex; - renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 0, keyframeNode); -}; - -/** - * @param {KeyframeNode} keyframeNode - * @param {Megatexture} megatexture - */ -SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( - keyframeNode, - megatexture -) { - if ( - keyframeNode.state !== KeyframeNode.LoadState.RECEIVED || - keyframeNode.megatextureIndex !== -1 || - !defined(keyframeNode.metadatas[megatexture.metadataName]) - ) { - throw new DeveloperError("Keyframe node cannot be added to megatexture"); - } - - keyframeNode.megatextureIndex = megatexture.add( - keyframeNode.metadatas[megatexture.metadataName] - ); - keyframeNode.metadatas[megatexture.metadataName] = undefined; // data is in megatexture so no need to hold onto it - keyframeNode.state = KeyframeNode.LoadState.LOADED; - - const renderableKeyframeNodes = this.renderableKeyframeNodes; - let renderableKeyframeNodeIndex = this.findRenderableKeyframeIndex( - keyframeNode.keyframe + let renderableKeyframeNodeIndex = findKeyframeIndex( + keyframeNode.keyframe, + renderableKeyframeNodes ); if (renderableKeyframeNodeIndex >= 0) { throw new DeveloperError("Keyframe already renderable"); @@ -409,6 +356,7 @@ SpatialNode.prototype.addKeyframeNodeToMegatexture = function ( /** * @param {Number} frameNumber + * @returns Boolean */ SpatialNode.prototype.isRenderable = function (frameNumber) { const previousNode = this.renderableKeyframeNodePrevious; diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index d4740f40ada..8dbaad85e12 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -309,26 +309,27 @@ VoxelTraversal.prototype.update = function ( recomputeBoundingVolumesRecursive(this, this.rootNode); } - if (!pauseUpdate) { - this._frameNumber = frameState.frameNumber; - const timestamp0 = getTimestamp(); - loadAndUnload(this, frameState); - const timestamp1 = getTimestamp(); - generateOctree(this, sampleCount, levelBlendFactor); - const timestamp2 = getTimestamp(); - - const debugStatistics = this._debugPrint; - if (debugStatistics) { - const loadAndUnloadTimeMs = timestamp1 - timestamp0; - const generateOctreeTimeMs = timestamp2 - timestamp1; - const totalTimeMs = timestamp2 - timestamp0; - printDebugInformation( - this, - loadAndUnloadTimeMs, - generateOctreeTimeMs, - totalTimeMs - ); - } + if (pauseUpdate) { + return; + } + + this._frameNumber = frameState.frameNumber; + const timestamp0 = getTimestamp(); + loadAndUnload(this, frameState); + const timestamp1 = getTimestamp(); + generateOctree(this, sampleCount, levelBlendFactor); + const timestamp2 = getTimestamp(); + + if (this._debugPrint) { + const loadAndUnloadTimeMs = timestamp1 - timestamp0; + const generateOctreeTimeMs = timestamp2 - timestamp1; + const totalTimeMs = timestamp2 - timestamp0; + printDebugInformation( + this, + loadAndUnloadTimeMs, + generateOctreeTimeMs, + totalTimeMs + ); } }; @@ -445,14 +446,12 @@ function requestData(that, keyframeNode) { } else { const megatextures = that.megatextures; for (let i = 0; i < length; i++) { - const megatexture = megatextures[i]; - const tileVoxelCount = - megatexture.voxelCountPerTile.x * - megatexture.voxelCountPerTile.y * - megatexture.voxelCountPerTile.z; + const { voxelCountPerTile, channelCount } = megatextures[i]; + const { x, y, z } = voxelCountPerTile; + const tileVoxelCount = x * y * z; const data = result[i]; - const expectedLength = tileVoxelCount * megatexture.channelCount; + const expectedLength = tileVoxelCount * channelCount; if (data.length === expectedLength) { keyframeNode.metadatas[i] = data; // State is received only when all metadata requests have been received @@ -632,98 +631,46 @@ function loadAndUnload(that, frameState) { const meetsScreenSpaceError = spatialNode.screenSpaceError < targetScreenSpaceError; - if (!meetsScreenSpaceError && hasLoadedKeyframe) { - if (!defined(spatialNode.children)) { - const childLevel = spatialNode.level + 1; - const childXMin = spatialNode.x * 2 + 0; - const childXMax = spatialNode.x * 2 + 1; - const childYMin = spatialNode.y * 2 + 0; - const childYMax = spatialNode.y * 2 + 1; - const childZMin = spatialNode.z * 2 + 0; - const childZMax = spatialNode.z * 2 + 1; - - spatialNode.children = new Array( - new SpatialNode( - childLevel, - childXMin, - childYMin, - childZMin, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMax, - childYMin, - childZMin, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMin, - childYMax, - childZMin, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMax, - childYMax, - childZMin, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMin, - childYMin, - childZMax, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMax, - childYMin, - childZMax, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMin, - childYMax, - childZMax, - spatialNode, - shape, - voxelDimensions - ), - new SpatialNode( - childLevel, - childXMax, - childYMax, - childZMax, - spatialNode, - shape, - voxelDimensions - ) - ); - } - for (let childIndex = 0; childIndex < 8; childIndex++) { - const child = spatialNode.children[childIndex]; - addToQueueRecursive(child, visibilityPlaneMask); - } - } else { + if (meetsScreenSpaceError || !hasLoadedKeyframe) { // Free up memory spatialNode.children = undefined; + return; + } + + if (!defined(spatialNode.children)) { + const childLevel = spatialNode.level + 1; + const childXMin = spatialNode.x * 2 + 0; + const childXMax = spatialNode.x * 2 + 1; + const childYMin = spatialNode.y * 2 + 0; + const childYMax = spatialNode.y * 2 + 1; + const childZMin = spatialNode.z * 2 + 0; + const childZMax = spatialNode.z * 2 + 1; + + const childCoords = [ + [childXMin, childYMin, childZMin], + [childXMax, childYMin, childZMin], + [childXMin, childYMax, childZMin], + [childXMax, childYMax, childZMin], + [childXMin, childYMin, childZMax], + [childXMax, childYMin, childZMax], + [childXMin, childYMax, childZMax], + [childXMax, childYMax, childZMax], + ]; + spatialNode.children = childCoords.map(([x, y, z]) => { + return new SpatialNode( + childLevel, + x, + y, + z, + spatialNode, + shape, + voxelDimensions + ); + }); + } + for (let childIndex = 0; childIndex < 8; childIndex++) { + const child = spatialNode.children[childIndex]; + addToQueueRecursive(child, visibilityPlaneMask); } } diff --git a/Specs/Scene/VoxelPrimitiveSpec.js b/Specs/Scene/VoxelPrimitiveSpec.js index b30092adf89..8e78b907125 100644 --- a/Specs/Scene/VoxelPrimitiveSpec.js +++ b/Specs/Scene/VoxelPrimitiveSpec.js @@ -1,6 +1,7 @@ import { Cartesian3, Cesium3DTilesVoxelProvider, + CustomShader, Matrix4, VoxelPrimitive, } from "../../Source/Cesium.js"; @@ -88,6 +89,32 @@ describe( }); }); + it("accepts a new Custom Shader", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + scene.renderForSpecs(); + + return primitive.readyPromise.then(function () { + expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); + + // If new shader is undefined, we should get DefaultCustomShader again + primitive.customShader = undefined; + scene.renderForSpecs(); + expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); + + const modifiedShader = new CustomShader({ + fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) +{ + material.diffuse = vec3(1.0, 1.0, 0.0); + material.alpha = 0.8; +}`, + }); + primitive.customShader = modifiedShader; + scene.renderForSpecs(); + expect(primitive.customShader).toBe(modifiedShader); + }); + }); + it("destroys", function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); diff --git a/Specs/Scene/VoxelTraversalSpec.js b/Specs/Scene/VoxelTraversalSpec.js index c69915bfc63..64cb9c921f8 100644 --- a/Specs/Scene/VoxelTraversalSpec.js +++ b/Specs/Scene/VoxelTraversalSpec.js @@ -39,9 +39,7 @@ describe( }); }); - const frameState = scene.frameState; const camera = scene.camera; - const context = scene.context; const keyframeCount = 1; const textureMemory = 500; @@ -60,7 +58,7 @@ describe( return primitive.readyPromise.then(function () { traversal = new VoxelTraversal( primitive, - context, + scene.context, provider.dimensions, provider.types, provider.componentTypes, @@ -93,7 +91,7 @@ describe( const recomputeBoundingVolumes = true; const pauseUpdate = false; traversal.update( - frameState, + scene.frameState, keyFrameLocation, recomputeBoundingVolumes, pauseUpdate @@ -109,21 +107,18 @@ describe( }); it("computes screen space error for root tile", function () { - const rootNode = traversal.rootNode; - const cameraPosition = frameState.camera.positionWC; - const screenSpaceErrorDenominator = - frameState.camera.frustum.sseDenominator; - const screenHeight = - frameState.context.drawingBufferHeight / frameState.pixelRatio; + const { context, pixelRatio } = scene.frameState; + const screenHeight = context.drawingBufferHeight / pixelRatio; const screenSpaceErrorMultiplier = - screenHeight / screenSpaceErrorDenominator; + screenHeight / camera.frustum.sseDenominator; + const rootNode = traversal.rootNode; rootNode.computeScreenSpaceError( - cameraPosition, + camera.positionWC, screenSpaceErrorMultiplier ); let distanceToCamera = Math.sqrt( - rootNode.orientedBoundingBox.distanceSquaredTo(cameraPosition) + rootNode.orientedBoundingBox.distanceSquaredTo(camera.positionWC) ); distanceToCamera = Math.max(distanceToCamera, CesiumMath.EPSILON7); const error = @@ -137,25 +132,32 @@ describe( const visibilityPlaneMask = CullingVolume.MASK_INDETERMINATE; const visibilityWhenLookingAtRoot = rootNode.visibility( - frameState, + scene.frameState, visibilityPlaneMask ); expect(visibilityWhenLookingAtRoot).toBe(CullingVolume.MASK_INSIDE); + // expect(traversal.isRenderable(rootNode)).toBe(true); turnCameraAround(scene); const visibilityWhenLookingAway = rootNode.visibility( - frameState, + scene.frameState, visibilityPlaneMask ); expect(visibilityWhenLookingAway).toBe(CullingVolume.MASK_OUTSIDE); }); + it("destroys", function () { + expect(traversal.isDestroyed()).toBe(false); + traversal.destroy(); + expect(traversal.isDestroyed()).toBe(true); + }); + xit("loads tiles into megatexture", function () { const keyFrameLocation = 0; const recomputeBoundingVolumes = true; const pauseUpdate = false; traversal.update( - frameState, + scene.frameState, keyFrameLocation, recomputeBoundingVolumes, pauseUpdate @@ -169,7 +171,7 @@ describe( traversal.megatexture.remove(0); turnCameraAround(scene); traversal.update( - frameState, + scene.frameState, keyFrameLocation, recomputeBoundingVolumes, pauseUpdate @@ -187,7 +189,7 @@ describe( // to fully fetch data and copy to texture function updateTraversal() { traversal.update( - frameState, + scene.frameState, keyFrameLocation, recomputeBoundingVolumes, pauseUpdate From b0d8e09448bcb46faf7922e6f4d79307c4d255f0 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 9 Sep 2022 10:33:54 -0400 Subject: [PATCH 100/679] Reduce function nesting in VoxelTraversal --- Source/Scene/VoxelTraversal.js | 206 ++++++++++++++++----------------- 1 file changed, 101 insertions(+), 105 deletions(-) diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index 8dbaad85e12..a3562fbbe9e 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -1015,111 +1015,6 @@ function generateOctree(that, sampleCount, levelBlendFactor) { buildOctree(rootNode, 0, 0, 0, 0); } - /** - * @ignore - * @param {Number[]} data - * @param {Number} texelsPerTile - * @param {Number} tilesPerRow - * @param {Texture} texture - */ - function copyToInternalNodeTexture( - data, - texelsPerTile, - tilesPerRow, - texture - ) { - const channelCount = PixelFormat.componentsLength(texture.pixelFormat); - const tileCount = Math.ceil(data.length / texelsPerTile); - const copyWidth = Math.max( - 1, - texelsPerTile * Math.min(tileCount, tilesPerRow) - ); - const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); - - const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); - for (let i = 0; i < data.length; i++) { - const val = data[i]; - const startIndex = i * channelCount; - for (let j = 0; j < channelCount; j++) { - textureData[startIndex + j] = (val >>> (j * 8)) & 0xff; - } - } - - const source = { - arrayBufferView: textureData, - width: copyWidth, - height: copyHeight, - }; - - const copyOptions = { - source: source, - xOffset: 0, - yOffset: 0, - }; - - texture.copyFrom(copyOptions); - } - - /** - * @ignore - * @param {Number[]} data - * @param {Number} texelsPerTile - * @param {Number} tilesPerRow - * @param {Texture} texture - */ - function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) { - const channelCount = PixelFormat.componentsLength(texture.pixelFormat); - const datasPerTile = 5; - const tileCount = Math.ceil(data.length / datasPerTile); - const copyWidth = Math.max( - 1, - texelsPerTile * Math.min(tileCount, tilesPerRow) - ); - const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); - - const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); - for (let tileIndex = 0; tileIndex < tileCount; tileIndex++) { - const timeLerp = data[tileIndex * datasPerTile + 0]; - const previousKeyframeLevelsAbove = data[tileIndex * datasPerTile + 1]; - const nextKeyframeLevelsAbove = data[tileIndex * datasPerTile + 2]; - const previousKeyframeMegatextureIndex = - data[tileIndex * datasPerTile + 3]; - const nextKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 4]; - - const timeLerpCompressed = CesiumMath.clamp( - Math.floor(65536 * timeLerp), - 0, - 65535 - ); - textureData[tileIndex * 8 + 0] = (timeLerpCompressed >>> 0) & 0xff; - textureData[tileIndex * 8 + 1] = (timeLerpCompressed >>> 8) & 0xff; - textureData[tileIndex * 8 + 2] = previousKeyframeLevelsAbove & 0xff; - textureData[tileIndex * 8 + 3] = nextKeyframeLevelsAbove & 0xff; - textureData[tileIndex * 8 + 4] = - (previousKeyframeMegatextureIndex >>> 0) & 0xff; - textureData[tileIndex * 8 + 5] = - (previousKeyframeMegatextureIndex >>> 8) & 0xff; - textureData[tileIndex * 8 + 6] = - (nextKeyframeMegatextureIndex >>> 0) & 0xff; - textureData[tileIndex * 8 + 7] = - (nextKeyframeMegatextureIndex >>> 8) & 0xff; - } - - const source = { - arrayBufferView: textureData, - width: copyWidth, - height: copyHeight, - }; - - const copyOptions = { - source: source, - xOffset: 0, - yOffset: 0, - }; - - texture.copyFrom(copyOptions); - } - copyToInternalNodeTexture( internalNodeOctreeData, 9, @@ -1136,6 +1031,107 @@ function generateOctree(that, sampleCount, levelBlendFactor) { } } +/** + * + * @param {Number[]} data + * @param {Number} texelsPerTile + * @param {Number} tilesPerRow + * @param {Texture} texture + * @private + */ +function copyToInternalNodeTexture(data, texelsPerTile, tilesPerRow, texture) { + const channelCount = PixelFormat.componentsLength(texture.pixelFormat); + const tileCount = Math.ceil(data.length / texelsPerTile); + const copyWidth = Math.max( + 1, + texelsPerTile * Math.min(tileCount, tilesPerRow) + ); + const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); + + const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); + for (let i = 0; i < data.length; i++) { + const val = data[i]; + const startIndex = i * channelCount; + for (let j = 0; j < channelCount; j++) { + textureData[startIndex + j] = (val >>> (j * 8)) & 0xff; + } + } + + const source = { + arrayBufferView: textureData, + width: copyWidth, + height: copyHeight, + }; + + const copyOptions = { + source: source, + xOffset: 0, + yOffset: 0, + }; + + texture.copyFrom(copyOptions); +} + +/** + * + * @param {Number[]} data + * @param {Number} texelsPerTile + * @param {Number} tilesPerRow + * @param {Texture} texture + * @private + */ +function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) { + const channelCount = PixelFormat.componentsLength(texture.pixelFormat); + const datasPerTile = 5; + const tileCount = Math.ceil(data.length / datasPerTile); + const copyWidth = Math.max( + 1, + texelsPerTile * Math.min(tileCount, tilesPerRow) + ); + const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow)); + + const textureData = new Uint8Array(copyWidth * copyHeight * channelCount); + for (let tileIndex = 0; tileIndex < tileCount; tileIndex++) { + const timeLerp = data[tileIndex * datasPerTile + 0]; + const previousKeyframeLevelsAbove = data[tileIndex * datasPerTile + 1]; + const nextKeyframeLevelsAbove = data[tileIndex * datasPerTile + 2]; + const previousKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 3]; + const nextKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 4]; + + const timeLerpCompressed = CesiumMath.clamp( + Math.floor(65536 * timeLerp), + 0, + 65535 + ); + textureData[tileIndex * 8 + 0] = (timeLerpCompressed >>> 0) & 0xff; + textureData[tileIndex * 8 + 1] = (timeLerpCompressed >>> 8) & 0xff; + textureData[tileIndex * 8 + 2] = previousKeyframeLevelsAbove & 0xff; + textureData[tileIndex * 8 + 3] = nextKeyframeLevelsAbove & 0xff; + textureData[tileIndex * 8 + 4] = + (previousKeyframeMegatextureIndex >>> 0) & 0xff; + textureData[tileIndex * 8 + 5] = + (previousKeyframeMegatextureIndex >>> 8) & 0xff; + textureData[tileIndex * 8 + 6] = + (nextKeyframeMegatextureIndex >>> 0) & 0xff; + textureData[tileIndex * 8 + 7] = + (nextKeyframeMegatextureIndex >>> 8) & 0xff; + } + + const source = { + arrayBufferView: textureData, + width: copyWidth, + height: copyHeight, + }; + + const copyOptions = { + source: source, + xOffset: 0, + yOffset: 0, + }; + + texture.copyFrom(copyOptions); +} + /** * @param {Number} tileCount * @param {Cartesian3} dimensions From bcdfad661359045069668454151ff792db8ff3d1 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Sat, 17 Sep 2022 17:20:49 -0400 Subject: [PATCH 101/679] Remove dead code in VoxelTraversal, reduce nesting --- Source/Scene/VoxelTraversal.js | 174 ++++++++++++++------------------- 1 file changed, 76 insertions(+), 98 deletions(-) diff --git a/Source/Scene/VoxelTraversal.js b/Source/Scene/VoxelTraversal.js index a3562fbbe9e..ed22615b759 100644 --- a/Source/Scene/VoxelTraversal.js +++ b/Source/Scene/VoxelTraversal.js @@ -432,7 +432,7 @@ function requestData(that, keyframeNode) { const tileY = spatialNode.y; const tileZ = spatialNode.z; - const postRequestSuccess = function (result) { + function postRequestSuccess(result) { that._simultaneousRequestCount--; const length = primitive._provider.types.length; @@ -462,12 +462,12 @@ function requestData(that, keyframeNode) { } } } - }; + } - const postRequestFailure = function () { + function postRequestFailure() { that._simultaneousRequestCount--; keyframeNode.state = KeyframeNode.LoadState.FAILED; - }; + } const promise = provider.requestData({ tileLevel: tileLevel, @@ -554,45 +554,19 @@ function loadAndUnload(that, frameState) { // If they already exist, nothing will be created. if (keyframeCount === 1) { spatialNode.createKeyframeNode(0); - } else { - // // Always keep two keyframes loaded even if the playhead is directly on a keyframe. - // spatialNode.createKeyframeNode(previousKeyframe); - // spatialNode.createKeyframeNode(nextKeyframe); - - // Create all keyframes - // eslint-disable-next-line no-lonely-if - if (spatialNode.keyframeNodes.length !== keyframeCount) { - for (let k = 0; k < keyframeCount; k++) { - spatialNode.createKeyframeNode(k); - } + } else if (spatialNode.keyframeNodes.length !== keyframeCount) { + for (let k = 0; k < keyframeCount; k++) { + spatialNode.createKeyframeNode(k); } } const ssePriority = mapInfiniteRangeToZeroOne(spatialNode.screenSpaceError); let hasLoadedKeyframe = false; const keyframeNodes = spatialNode.keyframeNodes; - for ( - let keyframeIndex = 0; - keyframeIndex < keyframeNodes.length; - keyframeIndex++ - ) { - const keyframeNode = keyframeNodes[keyframeIndex]; + for (let i = 0; i < keyframeNodes.length; i++) { + const keyframeNode = keyframeNodes[i]; const keyframe = keyframeNode.keyframe; - // // Prioritize all keyframes equally - // keyframeNode.priority = ssePriority; - - // // Prioritize ONLY keyframes adjacent to the playhead - // keyframeNode.priority = ssePriority; - // if (keyframe !== previousKeyframe && keyframe !== nextKeyframe) { - // keyframeNode.priority = -Number.MAX_VALUE; - // } - - // // Prioritize keyframes closest to the playhead - // keyframeNode.priority = ssePriority; - // const keyframeDifference = Math.min(Math.abs(keyframe - previousKeyframe), Math.abs(keyframe - nextKeyframe)); - // keyframeNode.priority -= keyframeDifference; - // Balanced prioritization const keyframeDifference = Math.min( Math.abs(keyframe - previousKeyframe), @@ -638,24 +612,8 @@ function loadAndUnload(that, frameState) { } if (!defined(spatialNode.children)) { + const childCoords = getChildCoords(spatialNode); const childLevel = spatialNode.level + 1; - const childXMin = spatialNode.x * 2 + 0; - const childXMax = spatialNode.x * 2 + 1; - const childYMin = spatialNode.y * 2 + 0; - const childYMax = spatialNode.y * 2 + 1; - const childZMin = spatialNode.z * 2 + 0; - const childZMax = spatialNode.z * 2 + 1; - - const childCoords = [ - [childXMin, childYMin, childZMin], - [childXMax, childYMin, childZMin], - [childXMin, childYMax, childZMin], - [childXMax, childYMax, childZMin], - [childXMin, childYMin, childZMax], - [childXMax, childYMin, childZMax], - [childXMin, childYMax, childZMax], - [childXMax, childYMax, childZMax], - ]; spatialNode.children = childCoords.map(([x, y, z]) => { return new SpatialNode( childLevel, @@ -748,6 +706,33 @@ function loadAndUnload(that, frameState) { } } +/** + * Compute the X, Y, Z coordinates of the children of a node + * @param {SpatialNode} spatialNode The parent node + * @returns {Array[]} Child coordinate arrays + * @private + */ +function getChildCoords(spatialNode) { + const { x, y, z } = spatialNode; + const xMin = x * 2; + const yMin = y * 2; + const zMin = z * 2; + const yMax = yMin + 1; + const xMax = xMin + 1; + const zMax = zMin + 1; + + return [ + [xMin, yMin, zMin], + [xMax, yMin, zMin], + [xMin, yMax, zMin], + [xMax, yMax, zMin], + [xMin, yMin, zMax], + [xMax, yMin, zMax], + [xMin, yMax, zMax], + [xMax, yMax, zMax], + ]; +} + /** * @function * @@ -883,7 +868,7 @@ const GpuOctreeFlag = { * @private */ function generateOctree(that, sampleCount, levelBlendFactor) { - const primitive = that._primitive; + const targetSse = that._primitive._screenSpaceError; const keyframeLocation = that._keyframeLocation; const frameNumber = that._frameNumber; const useLeafNodes = sampleCount >= 2; @@ -946,52 +931,25 @@ function generateOctree(that, sampleCount, levelBlendFactor) { // Recursion stops here because there are no renderable children if (useLeafNodes) { const baseIdx = leafNodeCount * 5; + const keyframeNode = node.renderableKeyframeNodePrevious; + const levelDifference = node.level - keyframeNode.spatialNode.level; - const useTimeDynamic = false; - if (useTimeDynamic) { - const previousKeyframeNode = node.renderableKeyframeNodePrevious; - const nextKeyframeNode = node.renderableKeyframeNodeNext; - const prevKeyframeLevel = previousKeyframeNode.spatialNode.level; - const nextKeyframeLevel = nextKeyframeNode.spatialNode.level; - const prevKeyframeLevelDifference = node.level - prevKeyframeLevel; - const nextKeyframeLevelDifference = node.level - nextKeyframeLevel; - - leafNodeOctreeData[baseIdx + 0] = node.renderableKeyframeNodeLerp; - leafNodeOctreeData[baseIdx + 1] = prevKeyframeLevelDifference; - leafNodeOctreeData[baseIdx + 2] = nextKeyframeLevelDifference; - leafNodeOctreeData[baseIdx + 3] = - previousKeyframeNode.megatextureIndex; - leafNodeOctreeData[baseIdx + 4] = nextKeyframeNode.megatextureIndex; - } else { - const keyframeNode = node.renderableKeyframeNodePrevious; - const levelDifference = node.level - keyframeNode.spatialNode.level; - - const parentNode = keyframeNode.spatialNode.parent; - const parentKeyframeNode = defined(parentNode) - ? parentNode.renderableKeyframeNodePrevious - : keyframeNode; - - let lodLerp = 0.0; - if (node.parent !== undefined) { - const sse = node.screenSpaceError; - const parentSse = node.parent.screenSpaceError; - const targetSse = primitive._screenSpaceError; - lodLerp = (targetSse - sse) / (parentSse - sse); - lodLerp = (lodLerp + levelBlendFactor - 1.0) / levelBlendFactor; - lodLerp = CesiumMath.clamp(lodLerp, 0.0, 1.0); - } - - const levelDifferenceChild = levelDifference; - const levelDifferenceParent = 1; - const megatextureIndexChild = keyframeNode.megatextureIndex; - const megatextureIndexParent = parentKeyframeNode.megatextureIndex; - - leafNodeOctreeData[baseIdx + 0] = lodLerp; - leafNodeOctreeData[baseIdx + 1] = levelDifferenceChild; - leafNodeOctreeData[baseIdx + 2] = levelDifferenceParent; - leafNodeOctreeData[baseIdx + 3] = megatextureIndexChild; - leafNodeOctreeData[baseIdx + 4] = megatextureIndexParent; - } + const parentNode = keyframeNode.spatialNode.parent; + const parentKeyframeNode = defined(parentNode) + ? parentNode.renderableKeyframeNodePrevious + : keyframeNode; + + const lodLerp = getLodLerp(node, targetSse, levelBlendFactor); + const levelDifferenceChild = levelDifference; + const levelDifferenceParent = 1; + const megatextureIndexChild = keyframeNode.megatextureIndex; + const megatextureIndexParent = parentKeyframeNode.megatextureIndex; + + leafNodeOctreeData[baseIdx + 0] = lodLerp; + leafNodeOctreeData[baseIdx + 1] = levelDifferenceChild; + leafNodeOctreeData[baseIdx + 2] = levelDifferenceParent; + leafNodeOctreeData[baseIdx + 3] = megatextureIndexChild; + leafNodeOctreeData[baseIdx + 4] = megatextureIndexParent; internalNodeOctreeData[parentEntryIndex] = (GpuOctreeFlag.LEAF << 16) | leafNodeCount; @@ -1031,6 +989,26 @@ function generateOctree(that, sampleCount, levelBlendFactor) { } } +/** + * Compute an interpolation factor between a node and its parent + * @param {SpatialNode} node + * @param {Number} targetSse + * @param {Number} levelBlendFactor + * @returns {Number} + * @private + */ +function getLodLerp(node, targetSse, levelBlendFactor) { + if (node.parent === undefined) { + return 0.0; + } + const sse = node.screenSpaceError; + const parentSse = node.parent.screenSpaceError; + const lodLerp = (targetSse - sse) / (parentSse - sse); + const blended = (lodLerp + levelBlendFactor - 1.0) / levelBlendFactor; + + return CesiumMath.clamp(blended, 0.0, 1.0); +} + /** * * @param {Number[]} data From 23468f3352454e391405a6cfe84bc1ec474dc872 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Sat, 17 Sep 2022 18:26:42 -0400 Subject: [PATCH 102/679] Fix import syntax --- Source/Scene/SpatialNode.js | 2 +- Source/Scene/VoxelDrawCommands.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/SpatialNode.js b/Source/Scene/SpatialNode.js index 3b4a417fb15..53ebe168edf 100644 --- a/Source/Scene/SpatialNode.js +++ b/Source/Scene/SpatialNode.js @@ -3,7 +3,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import CesiumMath from "../Core/Math.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; -import KeyframeNode from "./KeyframeNode"; +import KeyframeNode from "./KeyframeNode.js"; import Matrix3 from "../Core/Matrix3.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/VoxelDrawCommands.js index 9df29b881ec..008f960306a 100644 --- a/Source/Scene/VoxelDrawCommands.js +++ b/Source/Scene/VoxelDrawCommands.js @@ -1,6 +1,6 @@ -import Cartesian3 from "../Core/Cartesian3"; +import Cartesian3 from "../Core/Cartesian3.js"; import combine from "../Core/combine.js"; -import defined from "../Core/defined"; +import defined from "../Core/defined.js"; import PrimitiveType from "../Core/PrimitiveType.js"; import BlendingState from "./BlendingState.js"; import CullFace from "./CullFace.js"; From 944fed980b6521c89535282a1934b8478b65541c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Sat, 17 Sep 2022 21:38:46 -0400 Subject: [PATCH 103/679] Warn if uniform is already defined --- Source/Scene/VoxelPrimitive.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index a0aefca060c..4e28fbf9264 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -15,6 +15,7 @@ import Event from "../Core/Event.js"; import JulianDate from "../Core/JulianDate.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; +import oneTimeWarning from "../Core/oneTimeWarning.js"; import ClippingPlaneCollection from "./ClippingPlaneCollection.js"; import Material from "./Material.js"; import MetadataComponentType from "./MetadataComponentType.js"; @@ -1238,7 +1239,9 @@ function initFromProvider(primitive, provider, context) { //>>includeStart('debug', pragmas.debug); if (defined(uniformMap[name])) { - throw new DeveloperError(`Uniform name "${name}" is already defined`); + oneTimeWarning( + `VoxelPrimitive: Uniform name "${name}" is already defined` + ); } //>>includeEnd('debug'); From 984856bd9248a2e2792732700429aaaecfa50066 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 23 Sep 2022 11:11:33 -0400 Subject: [PATCH 104/679] Reduce nesting, add docs in Cesium3DTilesVoxelProvider --- Source/Scene/Cesium3DTilesVoxelProvider.js | 347 ++++++++++----------- 1 file changed, 169 insertions(+), 178 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 7a291d4cf80..bff71497da9 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -227,26 +227,12 @@ function Cesium3DTilesVoxelProvider(options) { // 2. Load schema.json // 3. Load root glTF to get provider properties const resource = Resource.createIfNeeded(options.url); - const tilesetPromise = resource.fetchJson(); - tilesetPromise + resource + .fetchJson() .then(function (tileset) { tilesetJson = tileset; tileJson = tilesetJson.root; - - let metadataSchemaLoader; - if (defined(tilesetJson.schemaUri)) { - metadataSchemaLoader = ResourceCache.loadSchema({ - resource: resource.getDerivedResource({ - url: tilesetJson.schemaUri, - preserveQueryParameters: true, - }), - }); - } else { - metadataSchemaLoader = ResourceCache.loadSchema({ - schema: tilesetJson.schema, - }); - } - return metadataSchemaLoader.promise; + return getMetadataSchemaLoader(tilesetJson, resource).promise; }) .then(function (schemaLoader) { const metadataSchema = schemaLoader.schema; @@ -271,90 +257,23 @@ function Cesium3DTilesVoxelProvider(options) { }) .then(function (rootGltfLoader) { that._gltfLoaders.splice(that._gltfLoaders.indexOf(rootGltfLoader), 1); - const gltfPrimitive = rootGltfLoader.components.nodes[0].primitives[0]; - const voxel = gltfPrimitive.voxel; - const primitiveType = gltfPrimitive.primitiveType; - const attributes = gltfPrimitive.attributes; - const attributesLength = attributes.length; - const names = new Array(attributesLength); - const types = new Array(attributesLength); - const componentTypes = new Array(attributesLength); - let minimumValues = new Array(attributesLength); - let maximumValues = new Array(attributesLength); - - const schema = metadata.schema; - const statistics = metadata.statistics; - const classNames = Object.keys(schema.classes); - const classNamesLength = classNames.length; - for (let i = 0; i < classNamesLength; i++) { - const className = classNames[i]; - const classStatistics = statistics.classes[className]; - const classInfo = schema.classes[className]; - const properties = classInfo.properties; - const propertyNames = Object.keys(properties); - const propertyNamesLength = propertyNames.length; - for (let i = 0; i < propertyNamesLength; i++) { - const propertyName = propertyNames[i]; - const property = properties[propertyName]; - - const metadataType = property.type; - const metadataComponentType = property.componentType; - const metadataComponentCount = MetadataType.getComponentCount( - metadataType - ); - - if (defined(classStatistics)) { - const propertyStatistics = classStatistics.properties[propertyName]; - const propertyMin = Array.isArray(propertyStatistics.min) - ? propertyStatistics.min - : [propertyStatistics.min]; - const propertyMax = Array.isArray(propertyStatistics.max) - ? propertyStatistics.max - : [propertyStatistics.max]; - - minimumValues[i] = new Array(metadataComponentCount); - maximumValues[i] = new Array(metadataComponentCount); - - for (let j = 0; j < metadataComponentCount; j++) { - minimumValues[i][j] = propertyMin[j]; - maximumValues[i][j] = propertyMax[j]; - } - } - - names[i] = propertyName; - types[i] = metadataType; - componentTypes[i] = metadataComponentType; - } - } + addAttributeInfo(metadata, that); - let hasMinimumMaximumValues = false; - for (let i = 0; i < attributesLength; i++) { - if (defined(minimumValues[i]) && defined(maximumValues[i])) { - hasMinimumMaximumValues = true; - break; - } - } - if (!hasMinimumMaximumValues) { - minimumValues = undefined; - maximumValues = undefined; - } + const gltfPrimitive = rootGltfLoader.components.nodes[0].primitives[0]; + const { primitiveType, voxel } = gltfPrimitive; that.shape = VoxelShapeType.fromPrimitiveType(primitiveType); + that.minBounds = Cartesian3.clone(voxel.minBounds); that.maxBounds = Cartesian3.clone(voxel.maxBounds); that.dimensions = Cartesian3.clone(voxel.dimensions); that.paddingBefore = Cartesian3.clone(voxel.paddingBefore); that.paddingAfter = Cartesian3.clone(voxel.paddingAfter); - that.maximumTileCount = defined(statistics.classes.tile) - ? statistics.classes.tile.count - : undefined; + + that.maximumTileCount = metadata.statistics.classes.tile?.count; + that.modelMatrix = Matrix4.clone(tileJson.transform); - that.names = names; - that.types = types; - that.componentTypes = componentTypes; - that.minimumValues = minimumValues; - that.maximumValues = maximumValues; that.ready = true; that._readyPromise.resolve(that); that._implicitTileset = implicitTileset; @@ -364,6 +283,86 @@ function Cesium3DTilesVoxelProvider(options) { }); } +/** + * Get a schema loader to load the metadata schema referenced in a tileset JSON file + * @param {Object} tilesetJson A tileset JSON object describing a 3DTiles tileset + * @param {Resource} resource + * @returns {MetadataSchemaLoader} + * @private + */ +function getMetadataSchemaLoader(tilesetJson, resource) { + const { schemaUri, schema } = tilesetJson; + if (!defined(schemaUri)) { + return ResourceCache.loadSchema({ schema }); + } + return ResourceCache.loadSchema({ + resource: resource.getDerivedResource({ + url: schemaUri, + preserveQueryParameters: true, + }), + }); +} + +/** + * Add info about metadata attributes to a VoxelPrimitive: + * names, types, componentTypes, minimumValues, maximumValues + * @param {Cesium3DTilesetMetadata} metadata + * @param {VoxelPrimitive} primitive + * @private + */ +function addAttributeInfo(metadata, primitive) { + const { schema, statistics } = metadata; + + // Collect a flattened array of info from all properties in all classes. + const propertyInfo = Object.entries(schema.classes).flatMap(getPropertyInfo); + + function getPropertyInfo([className, classInfo]) { + const classStatistics = statistics.classes[className]; + const { properties } = classInfo; + return Object.entries(properties).map(([name, property]) => { + const { type, componentType } = property; + + const min = classStatistics?.properties[name].min; + const max = classStatistics?.properties[name].max; + const componentCount = MetadataType.getComponentCount(type); + const minValue = copyArray(min, componentCount); + const maxValue = copyArray(max, componentCount); + + return { name, type, componentType, minValue, maxValue }; + }); + } + + primitive.names = propertyInfo.map((info) => info.name); + primitive.types = propertyInfo.map((info) => info.type); + primitive.componentTypes = propertyInfo.map((info) => info.componentType); + + const minimumValues = propertyInfo.map((info) => info.minValue); + const maximumValues = propertyInfo.map((info) => info.maxValue); + const hasMinimumValues = minimumValues.some(defined); + + primitive.minimumValues = hasMinimumValues ? minimumValues : undefined; + primitive.maximumValues = hasMinimumValues ? maximumValues : undefined; +} + +/** + * Copy input values into a new array of a specified length. + * If the input is not an array, its value will be copied into the first element + * of the returned array. If the input is an array shorter than the returned + * array, the extra elements in the returned array will be undefined. If the + * input is undefined, the return will be undefined. + * @param {*} values The values to copy + * @param {Number} length The length of the returned array + * @returns {Array} A new array filled with the supplied values + * @private + */ +function copyArray(values, length) { + if (!defined(values)) { + return; + } + const valuesArray = Array.isArray(values) ? values : [values]; + return Array.from({ length }, (v, i) => valuesArray[i]); +} + /** * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. * This function should not be called before {@link VoxelProvider#ready} returns true. @@ -400,12 +399,9 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { } // 1. Load the subtree that the tile belongs to (possibly from the subtree cache) - // 1a. If not in the cache, load the subtree resource - // 1b. If not in the cache, load the subtree object // 2. Load the glTF if available const implicitTileset = this._implicitTileset; - const subtreeCache = this._subtreeCache; const types = this.types; const componentTypes = this.componentTypes; @@ -419,95 +415,39 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { z: tileZ, }); - // First load the subtree to check if the tile is available. - // If the subtree has been requested previously it might still be in the cache. - let subtreeCoord; - + // TODO: is the first condition flipped? if isSubtreeRoot, level == 0 const isSubtreeRoot = tileCoordinates.isSubtreeRoot() && tileCoordinates.level > 0; - if (isSubtreeRoot) { - // Check availability from the parent subtree so that we don't try fetching a non-existent subtree - subtreeCoord = tileCoordinates.getParentSubtreeCoordinates(); - } else { - subtreeCoord = tileCoordinates.getSubtreeCoordinates(); - } - - let subtree = subtreeCache.find(subtreeCoord); + // TODO: are these switched? Root has no parent + const subtreeCoord = isSubtreeRoot + ? tileCoordinates.getParentSubtreeCoordinates() + : tileCoordinates.getSubtreeCoordinates(); const that = this; - let subtreePromise; - if (defined(subtree)) { - subtreePromise = subtree.readyPromise; - } else { - const subtreeRelative = implicitTileset.subtreeUriTemplate.getDerivedResource( - { - templateValues: subtreeCoord.getTemplateValues(), - } - ); - const subtreeResource = implicitTileset.baseResource.getDerivedResource({ - url: subtreeRelative.url, - }); - this._subtreeResourceLoaders.push(subtreeResource); - subtreePromise = subtreeResource - .fetchArrayBuffer() - .then(function (arrayBuffer) { - // Check one more time if the subtree is in the cache. - // This could happen if there are two in-flight tile requests from the same subtree and one finishes before the other. - subtree = subtreeCache.find(subtreeCoord); - if (!defined(subtree)) { - const bufferU8 = new Uint8Array(arrayBuffer); - subtree = new ImplicitSubtree( - subtreeResource, - undefined, - bufferU8, - implicitTileset, - subtreeCoord - ); - subtreeCache.addSubtree(subtree); - that._subtreeLoaders.push(subtree); - } - that._subtreeResourceLoaders.splice( - that._subtreeResourceLoaders.indexOf(subtreeResource), - 1 - ); - return subtree.readyPromise; - }); - } - return subtreePromise + return getSubtreePromise(that, subtreeCoord) .then(function (subtree) { - const subtreeLoaderIndex = that._subtreeLoaders.indexOf(subtree); + const available = isSubtreeRoot + ? subtree.childSubtreeIsAvailableAtCoordinates(tileCoordinates) + : subtree.tileIsAvailableAtCoordinates(tileCoordinates); - let available = false; - if (isSubtreeRoot) { - available = subtree.childSubtreeIsAvailableAtCoordinates( - tileCoordinates - ); - } else { - available = subtree.tileIsAvailableAtCoordinates(tileCoordinates); + const subtreeLoaderIndex = that._subtreeLoaders.indexOf(subtree); + if (subtreeLoaderIndex !== -1) { + that._subtreeLoaders.splice(subtreeLoaderIndex, 1); } - if (!available) { - if (subtreeLoaderIndex !== -1) { - that._subtreeLoaders.splice(subtreeLoaderIndex, 1); - } return Promise.reject("Tile is not available"); } const gltfLoader = getGltfLoader(implicitTileset, tileCoordinates); that._gltfLoaders.push(gltfLoader); - if (subtreeLoaderIndex !== -1) { - that._subtreeLoaders.splice(subtreeLoaderIndex, 1); - } - return gltfLoader.promise; }) .then(function (gltfLoader) { const node = gltfLoader.components.scene.nodes[0]; - const primitive = node.primitives[0]; - const attributes = primitive.attributes; + const attributes = node.primitives[0].attributes; const attributesLength = attributes.length; const data = new Array(attributesLength); @@ -529,10 +469,65 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { } that._gltfLoaders.splice(that._gltfLoaders.indexOf(gltfLoader), 1); - return Promise.resolve(data); + return data; }); }; +/** + * + * @param {VoxelPrimitive} primitive + * @param {ImplicitTileCoordinates} subtreeCoord + * @returns {Promise.} + * @private + */ +function getSubtreePromise(primitive, subtreeCoord) { + const implicitTileset = primitive._implicitTileset; + const subtreeCache = primitive._subtreeCache; + + // First load the subtree to check if the tile is available. + // If the subtree has been requested previously it might still be in the cache + const subtree = subtreeCache.find(subtreeCoord); + if (defined(subtree)) { + return subtree.readyPromise; + } + + const { subtreeUriTemplate, baseResource } = implicitTileset; + const subtreeRelative = subtreeUriTemplate.getDerivedResource({ + templateValues: subtreeCoord.getTemplateValues(), + }); + const subtreeResource = baseResource.getDerivedResource({ + url: subtreeRelative.url, + }); + primitive._subtreeResourceLoaders.push(subtreeResource); + + return subtreeResource.fetchArrayBuffer().then(addSubtree); + + function addSubtree(arrayBuffer) { + // Check one more time if the subtree is in the cache. + // This could happen if there are two in-flight tile requests from the same + // subtree and one finishes before the other. + let subtree = subtreeCache.find(subtreeCoord); + if (defined(subtree)) { + return subtree.readyPromise; + } + const bufferU8 = new Uint8Array(arrayBuffer); + subtree = new ImplicitSubtree( + subtreeResource, + undefined, + bufferU8, + implicitTileset, + subtreeCoord + ); + subtreeCache.addSubtree(subtree); + primitive._subtreeLoaders.push(subtree); + const subtreeResourceIndex = primitive._subtreeResourceLoaders.indexOf( + subtreeResource + ); + primitive._subtreeResourceLoaders.splice(subtreeResourceIndex, 1); + return subtree.readyPromise; + } +} + /** * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. * @function @@ -542,8 +537,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { */ Cesium3DTilesVoxelProvider.prototype.update = function (frameState) { const loaders = this._gltfLoaders; - const loaderLength = loaders.length; - for (let i = 0; i < loaderLength; i++) { + for (let i = 0; i < loaders.length; i++) { loaders[i].process(frameState); } }; @@ -565,21 +559,18 @@ Cesium3DTilesVoxelProvider.prototype.doneLoading = function () { }; /** - * @function - * - * @param {ArrayBuffer} gltfBuffer The buffer that comes when the promise from gltfResource.fetchArrayBuffer() resolves. - * @param {Resource} gltfResource Resource derived from base that points to gltf. - * @returns {GltfLoader} - * + * Get a loader for a glTF tile from a tileset + * @param {ImplicitTileset} implicitTileset The tileset from which the loader will retrieve a glTF tile + * @param {ImplicitTileCoordinates} tileCoord The coordinates of the desired tile + * @returns {GltfLoader} A loader for the requested tile * @private */ function getGltfLoader(implicitTileset, tileCoord) { - const gltfRelative = implicitTileset.contentUriTemplates[0].getDerivedResource( - { - templateValues: tileCoord.getTemplateValues(), - } - ); - const gltfResource = implicitTileset.baseResource.getDerivedResource({ + const { contentUriTemplates, baseResource } = implicitTileset; + const gltfRelative = contentUriTemplates[0].getDerivedResource({ + templateValues: tileCoord.getTemplateValues(), + }); + const gltfResource = baseResource.getDerivedResource({ url: gltfRelative.url, }); From d274e76d7d863a6771a5878eaf6667ca7beb9bf3 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 26 Sep 2022 16:21:10 -0400 Subject: [PATCH 105/679] Fix attribute name mismatch in Cesium3DTilesVoxelProvider --- Source/Scene/Cesium3DTilesVoxelProvider.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index bff71497da9..8cc730d7431 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -404,6 +404,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { const implicitTileset = this._implicitTileset; const types = this.types; const componentTypes = this.componentTypes; + const names = this.names; // Can't use a scratch variable here because the object is used inside the promise chain. const tileCoordinates = new ImplicitTileCoordinates({ @@ -452,7 +453,15 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { const data = new Array(attributesLength); for (let i = 0; i < attributesLength; i++) { - const attribute = attributes[i]; + // The attributes array from GltfLoader is not in the same order as + // names, types, etc. from the provider. + // A temporary fix: Look up the attribute based on its name + const name = `_${names[i]}`; + const attribute = attributes.find((a) => a.name === name); + if (!defined(attribute)) { + continue; + } + const type = types[i]; const componentType = componentTypes[i]; const componentDatatype = MetadataComponentType.toComponentDatatype( From 652a4e933b9452d03c7e4b8508e98b7d0d9a3888 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 27 Sep 2022 10:19:11 -0400 Subject: [PATCH 106/679] Add processVoxelPropertiesSpec --- Specs/Scene/processVoxelPropertiesSpec.js | 130 ++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Specs/Scene/processVoxelPropertiesSpec.js diff --git a/Specs/Scene/processVoxelPropertiesSpec.js b/Specs/Scene/processVoxelPropertiesSpec.js new file mode 100644 index 00000000000..c5b6adcb0a0 --- /dev/null +++ b/Specs/Scene/processVoxelPropertiesSpec.js @@ -0,0 +1,130 @@ +import { + Cesium3DTilesVoxelProvider, + VoxelPrimitive, + VoxelRenderResources, + processVoxelProperties, +} from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; +import ShaderBuilderTester from "../ShaderBuilderTester.js"; +import pollToPromise from "../pollToPromise.js"; + +describe("Scene/processVoxelProperties", function () { + let scene; + let provider; + + beforeAll(function () { + scene = createScene(); + + provider = new Cesium3DTilesVoxelProvider({ + url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }); + }); + + it("adds shader defines and structs", function () { + const primitive = new VoxelPrimitive({ provider }); + primitive.update(scene.frameState); + + const renderResources = new VoxelRenderResources(primitive); + processVoxelProperties(renderResources, primitive); + + const { shaderBuilder } = renderResources; + + // Check fragment shader defines + // ShaderBuilderTest.expectHasFragmentDefines would check defines from + // previous stages, so just check the relevant lines directly + ShaderBuilderTester.expectFragmentLinesContains(shaderBuilder, [ + "#define METADATA_COUNT 1", + "#define STATISTICS", + ]); + + // Check for PropertyStatistics structs + const propertyStatisticsFields = [" float min;", " float max;"]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "PropertyStatistics_a", + "PropertyStatistics_a", + propertyStatisticsFields + ); + + // Check for Statistics struct + const statisticsFields = [" PropertyStatistics_a a;"]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "Statistics", + "Statistics", + statisticsFields + ); + + // Check for Metadata struct + const metadataFields = [" Statistics statistics;", " float a;"]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "Metadata", + "Metadata", + metadataFields + ); + + // Check for VoxelProperty structs + const voxelPropertyFields = [ + " vec3 partialDerivativeLocal;", + " vec3 partialDerivativeWorld;", + " vec3 partialDerivativeView;", + " vec3 partialDerivativeValid;", + ]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "VoxelProperty_a", + "VoxelProperty_a", + voxelPropertyFields + ); + + // Check for Voxel struct + const voxelFields = [ + " VoxelProperty_a a;", + " vec3 positionEC;", + " vec3 positionUv;", + " vec3 positionShapeUv;", + " vec3 positionUvLocal;", + " vec3 viewDirUv;", + " vec3 viewDirWorld;", + " float travelDistance;", + ]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "Voxel", + "Voxel", + voxelFields + ); + + // Check for FragmentInput struct + const fragmentInputFields = [" Metadata metadata;", " Voxel voxel;"]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "FragmentInput", + "FragmentInput", + fragmentInputFields + ); + + // Check for Properties struct + const propertiesFields = [" float a;"]; + ShaderBuilderTester.expectHasFragmentStruct( + shaderBuilder, + "Properties", + "Properties", + propertiesFields + ); + + // Check clearProperties function + // Check sumProperties function + // Check scaleProperties function + // Check mixProperties function + // Check copyPropertiesToMetadata function + // Check setStatistics function + // Check getPropertiesFromMegatextureAtUv function + }); +}); From e80ad3be7e8357c39e3eec78ace05527aa89973f Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 27 Sep 2022 14:19:20 -0400 Subject: [PATCH 107/679] Add buildVoxelDrawCommandsSpec --- Source/Scene/VoxelPrimitive.js | 2 +- ...wCommands.js => buildVoxelDrawCommands.js} | 0 Specs/Scene/buildVoxelDrawCommandsSpec.js | 61 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) rename Source/Scene/{VoxelDrawCommands.js => buildVoxelDrawCommands.js} (100%) create mode 100644 Specs/Scene/buildVoxelDrawCommandsSpec.js diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index a0aefca060c..913e429cc7a 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1,4 +1,4 @@ -import buildVoxelDrawCommands from "./VoxelDrawCommands.js"; +import buildVoxelDrawCommands from "./buildVoxelDrawCommands.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartesian4 from "../Core/Cartesian4.js"; diff --git a/Source/Scene/VoxelDrawCommands.js b/Source/Scene/buildVoxelDrawCommands.js similarity index 100% rename from Source/Scene/VoxelDrawCommands.js rename to Source/Scene/buildVoxelDrawCommands.js diff --git a/Specs/Scene/buildVoxelDrawCommandsSpec.js b/Specs/Scene/buildVoxelDrawCommandsSpec.js new file mode 100644 index 00000000000..8362314c0f1 --- /dev/null +++ b/Specs/Scene/buildVoxelDrawCommandsSpec.js @@ -0,0 +1,61 @@ +import { + Cartesian3, + Cesium3DTilesVoxelProvider, + ClippingPlane, + ClippingPlaneCollection, + VoxelPrimitive, + buildVoxelDrawCommands, +} from "../../Source/Cesium.js"; +import createScene from "../createScene.js"; +import pollToPromise from "../pollToPromise.js"; + +describe("Scene/VoxelDrawCommands", function () { + let scene; + let provider; + + beforeAll(function () { + scene = createScene(); + + provider = new Cesium3DTilesVoxelProvider({ + url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", + }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }); + }); + + it("sets up basic voxel draw commands", function () { + const primitive = new VoxelPrimitive({ provider }); + primitive.update(scene.frameState); + + buildVoxelDrawCommands(primitive, scene.context); + expect(primitive._drawCommand).toBeDefined(); + expect(primitive._drawCommandPick).toBeDefined(); + }); + + it("adds clipping function for primitive with clipping planes", function () { + const primitive = new VoxelPrimitive({ provider }); + + const planes = [ + new ClippingPlane(Cartesian3.UNIT_X, 1.0), + new ClippingPlane(Cartesian3.UNIT_Y, 2.0), + ]; + + primitive.clippingPlanes = new ClippingPlaneCollection({ + planes: planes, + }); + + primitive.update(scene.frameState); + + buildVoxelDrawCommands(primitive, scene.context); + + const { shaderProgram } = primitive._drawCommand; + const fragmentShaderText = shaderProgram._fragmentShaderText; + const clippingFunctionSignature = + "vec4 getClippingPlane(highp sampler2D packedClippingPlanes, int clippingPlaneNumber, mat4 transform)"; + + expect(fragmentShaderText.includes(clippingFunctionSignature)).toBe(true); + }); +}); From 0382995fa221881fb6b8ed814b251a244162d06a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 4 Oct 2022 14:40:21 -0400 Subject: [PATCH 108/679] Reduce knockout usage in VoxelInspector --- .../Widgets/VoxelInspector/VoxelInspector.js | 129 +++++++----------- .../VoxelInspector/VoxelInspectorViewModel.js | 46 +------ 2 files changed, 55 insertions(+), 120 deletions(-) diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index c3d229d728a..ef37f80512d 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -2,7 +2,6 @@ import Cartesian3 from "../../Core/Cartesian3.js"; import CesiumMath from "../../Core/Math.js"; import Check from "../../Core/Check.js"; import defaultValue from "../../Core/defaultValue.js"; -import defined from "../../Core/defined.js"; import destroyObject from "../../Core/destroyObject.js"; import Ellipsoid from "../../Core/Ellipsoid.js"; import knockout from "../../ThirdParty/knockout.js"; @@ -33,29 +32,25 @@ function VoxelInspector(container, scene) { const text = document.createElement("div"); text.textContent = "Voxel Inspector"; text.className = "cesium-cesiumInspector-button"; - text.setAttribute("data-bind", "click: inspectorVisibleToggle"); element.appendChild(text); - element.className = "cesium-cesiumInspector cesium-VoxelInspector"; - element.setAttribute( - "data-bind", - 'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}' - ); + + element.className = + "cesium-cesiumInspector cesium-VoxelInspector cesium-cesiumInspector-hidden"; + text.addEventListener("click", function () { + element.classList.toggle("cesium-cesiumInspector-visible"); + element.classList.toggle("cesium-cesiumInspector-hidden"); + }); + container.appendChild(element); const panel = document.createElement("div"); panel.className = "cesium-cesiumInspector-dropDown"; element.appendChild(panel); - const createSection = InspectorShared.createSection; - const createCheckbox = InspectorShared.createCheckbox; + const { createCheckbox } = InspectorShared; // Display - const displayPanelContents = createSection( - panel, - "Display", - "displayVisible", - "displayVisibleToggle" - ); + const displayPanelContents = createSection(panel, "Display"); displayPanelContents.appendChild(createCheckbox("Depth Test", "depthTest")); displayPanelContents.appendChild(createCheckbox("Show", "show")); @@ -71,25 +66,16 @@ function VoxelInspector(container, scene) { makeRangeInput("Level Blend Factor", "levelBlendFactor", 0.0, 1.0) ); - const screenSpaceErrorContainer = document.createElement("div"); - screenSpaceErrorContainer.appendChild( + displayPanelContents.appendChild( makeRangeInput("Screen Space Error", "screenSpaceError", 0, 128) ); - displayPanelContents.appendChild(screenSpaceErrorContainer); - const stepSizeContainer = document.createElement("div"); - stepSizeContainer.appendChild( + displayPanelContents.appendChild( makeRangeInput("Step Size", "stepSize", 0.0, 2.0) ); - displayPanelContents.appendChild(stepSizeContainer); // Transform - const transformPanelContents = createSection( - panel, - "Transform", - "transformVisible", - "transformVisibleToggle" - ); + const transformPanelContents = createSection(panel, "Transform"); const maxTrans = 20000000.0; const maxScale = 20000000.0; @@ -124,12 +110,7 @@ function VoxelInspector(container, scene) { ); // Bounds - const boundsPanelContents = createSection( - panel, - "Bounds", - "boundsVisible", - "boundsVisibleToggle" - ); + const boundsPanelContents = createSection(panel, "Bounds"); const boxMinBounds = VoxelShapeType.getMinBounds(VoxelShapeType.BOX); const boxMaxBounds = VoxelShapeType.getMaxBounds(VoxelShapeType.BOX); @@ -212,12 +193,7 @@ function VoxelInspector(container, scene) { ); // Clipping - const clippingPanelContents = createSection( - panel, - "Clipping", - "clippingVisible", - "clippingVisibleToggle" - ); + const clippingPanelContents = createSection(panel, "Clipping"); makeCoordinateRange( "Max X", @@ -277,12 +253,7 @@ function VoxelInspector(container, scene) { ); // Shader - const shaderPanelContents = createSection( - panel, - "Shader", - "shaderVisible", - "shaderVisibleToggle" - ); + const shaderPanelContents = createSection(panel, "Shader"); const shaderPanelEditor = document.createElement("div"); shaderPanelContents.appendChild(shaderPanelEditor); @@ -348,6 +319,39 @@ VoxelInspector.prototype.destroy = function () { return destroyObject(this); }; +/** + * Creates a hide-able section element in an Inspector panel + * Similar to InspectorShared.createSection, but without the knockout dependency + * @param {HTMLElement} panel The parent element + * @param {String} headerText The text to display at the top of the section + * @returns {HTMLElement} An element containing the section content + * @private + */ +function createSection(panel, headerText) { + //>>includeStart('debug', pragmas.debug); + Check.defined("panel", panel); + Check.typeOf.string("headerText", headerText); + //>>includeEnd('debug'); + + const section = document.createElement("div"); + section.className = + "cesium-cesiumInspector-section cesium-cesiumInspector-section-collapsed"; + panel.appendChild(section); + + const sectionHeader = document.createElement("h3"); + sectionHeader.className = "cesium-cesiumInspector-sectionHeader"; + sectionHeader.appendChild(document.createTextNode(headerText)); + sectionHeader.addEventListener("click", function () { + section.classList.toggle("cesium-cesiumInspector-section-collapsed"); + }); + section.appendChild(sectionHeader); + + const sectionContent = document.createElement("div"); + sectionContent.className = "cesium-cesiumInspector-sectionContent"; + section.appendChild(sectionContent); + return sectionContent; +} + function makeRangeInput(text, property, min, max, step, displayProperty) { displayProperty = defaultValue(displayProperty, property); const input = document.createElement("input"); @@ -373,44 +377,13 @@ function makeRangeInput(text, property, min, max, step, displayProperty) { return container; } -// function makeTestSlider(text, property, min, max, step, displayProperty) { -// displayProperty = defaultValue(displayProperty, property); -// const input = document.createElement('input'); -// // input.setAttribute('data-bind', 'value: ' + displayProperty); -// input.setAttribute('data-bind', 'attr: {min: 1, max: MaxPage}, value: ' + displayProperty); - -// input.type = 'number'; - -// const slider = document.createElement('input'); -// slider.type = 'range'; -// slider.min = min; -// slider.max = max; -// slider.step = step; -// slider.setAttribute('data-bind', 'valueUpdate: "input", value: ' + property); - -// const wrapper = document.createElement('div'); -// wrapper.appendChild(slider); - -// const container = document.createElement('div'); -// container.className = 'cesium-cesiumInspector-slider'; -// container.appendChild(document.createTextNode(text)); -// container.appendChild(input); -// container.appendChild(wrapper); - -// return container; -// } - -function makeButton(action, text, active) { +function makeButton(action, text) { const button = document.createElement("button"); button.type = "button"; button.textContent = text; button.className = "cesium-cesiumInspector-pickButton"; - let binding = `click: ${action}`; - if (defined(active)) { - binding += `, css: {"cesium-cesiumInspector-pickButtonHighlight" : ${active}}`; - } + const binding = `click: ${action}`; button.setAttribute("data-bind", binding); - return button; } diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index 60b4f2e31f2..d1713c9fe6d 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -1,6 +1,5 @@ import Cartesian3 from "../../Core/Cartesian3.js"; import Check from "../../Core/Check.js"; -import defaultValue from "../../Core/defaultValue.js"; import defined from "../../Core/defined.js"; import destroyObject from "../../Core/destroyObject.js"; import HeadingPitchRoll from "../../Core/HeadingPitchRoll.js"; @@ -64,20 +63,19 @@ function VoxelInspectorViewModel(scene) { const that = this; function addProperty(options) { - const name = options.name; - const initialValue = options.initialValue; - const toggle = defaultValue(options.toggle, false); - let setPrimitiveFunction = options.setPrimitiveFunction; - let getPrimitiveFunction = options.getPrimitiveFunction; + const { name, initialValue } = options; that[name] = initialValue; that._definedProperties.push(name); + let setPrimitiveFunction = options.setPrimitiveFunction; if (setPrimitiveFunction === true) { setPrimitiveFunction = function (value) { that._voxelPrimitive[name] = value; }; } + + let getPrimitiveFunction = options.getPrimitiveFunction; if (getPrimitiveFunction === true) { getPrimitiveFunction = function () { that[name] = that._voxelPrimitive[name]; @@ -87,12 +85,6 @@ function VoxelInspectorViewModel(scene) { that._getPrimitiveFunctions.push(getPrimitiveFunction); } - if (toggle) { - that.constructor.prototype[`${name}Toggle`] = function () { - that[name] = !that[name]; - }; - } - const knock = knockout.observable(); knockout.defineProperty(that, name, { get: function () { @@ -119,21 +111,6 @@ function VoxelInspectorViewModel(scene) { return knock; } - addProperty({ - name: "inspectorVisible", - initialValue: false, - toggle: true, - }); - addProperty({ - name: "displayVisible", - initialValue: false, - toggle: true, - }); - addProperty({ - name: "shaderVisible", - initialValue: false, - toggle: true, - }); addProperty({ name: "shaderString", initialValue: "", @@ -150,21 +127,6 @@ function VoxelInspectorViewModel(scene) { name: "shaderCompilationSuccess", initialValue: true, }); - addProperty({ - name: "transformVisible", - initialValue: false, - toggle: true, - }); - addProperty({ - name: "boundsVisible", - initialValue: false, - toggle: true, - }); - addProperty({ - name: "clippingVisible", - initialValue: false, - toggle: true, - }); addProperty({ name: "depthTest", initialValue: false, From 567def92b5de60ec8a89641ccf1f79a4811fa858 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 4 Oct 2022 15:15:54 -0400 Subject: [PATCH 109/679] Reduce code duplication in VoxelInspectorViewModel --- .../VoxelInspector/VoxelInspectorViewModel.js | 386 +++--------------- 1 file changed, 62 insertions(+), 324 deletions(-) diff --git a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js index d1713c9fe6d..f5638cf32b9 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js +++ b/Source/Widgets/VoxelInspector/VoxelInspectorViewModel.js @@ -111,6 +111,14 @@ function VoxelInspectorViewModel(scene) { return knock; } + function getBoundSetter(boundKey, component) { + return function (value) { + const bound = that._voxelPrimitive[boundKey].clone(); + bound[component] = value; + that._voxelPrimitive[boundKey] = bound; + }; + } + addProperty({ name: "shaderString", initialValue: "", @@ -205,302 +213,151 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "boundsBoxMaxX", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - value, - maxBounds.y, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "x"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsBoxMaxX = maxBounds.x; + that.boundsBoxMaxX = that._voxelPrimitive.maxBounds.x; }, }); addProperty({ name: "boundsBoxMinX", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - value, - minBounds.y, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "x"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsBoxMinX = minBounds.x; + that.boundsBoxMinX = that._voxelPrimitive.minBounds.x; }, }); addProperty({ name: "boundsBoxMaxY", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - value, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "y"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsBoxMaxY = maxBounds.y; + that.boundsBoxMaxY = that._voxelPrimitive.maxBounds.y; }, }); addProperty({ name: "boundsBoxMinY", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - value, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "y"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsBoxMinY = minBounds.y; + that.boundsBoxMinY = that._voxelPrimitive.minBounds.y; }, }); addProperty({ name: "boundsBoxMaxZ", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - maxBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "z"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsBoxMaxZ = maxBounds.z; + that.boundsBoxMaxZ = that._voxelPrimitive.maxBounds.z; }, }); addProperty({ name: "boundsBoxMinZ", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - minBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "z"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsBoxMinZ = minBounds.z; + that.boundsBoxMinZ = that._voxelPrimitive.minBounds.z; }, }); addProperty({ name: "boundsEllipsoidMaxLongitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - value, - maxBounds.y, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "x"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsEllipsoidMaxLongitude = maxBounds.x; + that.boundsEllipsoidMaxLongitude = that._voxelPrimitive.maxBounds.x; }, }); addProperty({ name: "boundsEllipsoidMinLongitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - value, - minBounds.y, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "x"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsEllipsoidMinLongitude = minBounds.x; + that.boundsEllipsoidMinLongitude = that._voxelPrimitive.minBounds.x; }, }); addProperty({ name: "boundsEllipsoidMaxLatitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - value, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "y"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsEllipsoidMaxLatitude = maxBounds.y; + that.boundsEllipsoidMaxLatitude = that._voxelPrimitive.maxBounds.y; }, }); addProperty({ name: "boundsEllipsoidMinLatitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - value, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "y"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsEllipsoidMinLatitude = minBounds.y; + that.boundsEllipsoidMinLatitude = that._voxelPrimitive.minBounds.y; }, }); addProperty({ name: "boundsEllipsoidMaxHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - maxBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "z"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsEllipsoidMaxHeight = maxBounds.z; + that.boundsEllipsoidMaxHeight = that._voxelPrimitive.maxBounds.z; }, }); addProperty({ name: "boundsEllipsoidMinHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - minBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "z"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsEllipsoidMinHeight = minBounds.z; + that.boundsEllipsoidMinHeight = that._voxelPrimitive.minBounds.z; }, }); addProperty({ name: "boundsCylinderMaxRadius", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - value, - maxBounds.y, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "x"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsCylinderMaxRadius = maxBounds.x; + that.boundsCylinderMaxRadius = that._voxelPrimitive.maxBounds.x; }, }); addProperty({ name: "boundsCylinderMinRadius", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - value, - minBounds.y, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "x"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsCylinderMinRadius = minBounds.x; + that.boundsCylinderMinRadius = that._voxelPrimitive.minBounds.x; }, }); addProperty({ name: "boundsCylinderMaxHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - value, - maxBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "y"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsCylinderMaxHeight = maxBounds.y; + that.boundsCylinderMaxHeight = that._voxelPrimitive.maxBounds.y; }, }); addProperty({ name: "boundsCylinderMinHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - value, - minBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "y"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsCylinderMinHeight = minBounds.y; + that.boundsCylinderMinHeight = that._voxelPrimitive.minBounds.y; }, }); addProperty({ name: "boundsCylinderMaxAngle", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxBounds = that._voxelPrimitive.maxBounds; - that._voxelPrimitive.maxBounds = new Cartesian3( - maxBounds.x, - maxBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxBounds", "z"), getPrimitiveFunction: function () { - const maxBounds = that._voxelPrimitive.maxBounds; - that.boundsCylinderMaxAngle = maxBounds.z; + that.boundsCylinderMaxAngle = that._voxelPrimitive.maxBounds.z; }, }); addProperty({ name: "boundsCylinderMinAngle", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minBounds = that._voxelPrimitive.minBounds; - that._voxelPrimitive.minBounds = new Cartesian3( - minBounds.x, - minBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minBounds", "z"), getPrimitiveFunction: function () { - const minBounds = that._voxelPrimitive.minBounds; - that.boundsCylinderMinAngle = minBounds.z; + that.boundsCylinderMinAngle = that._voxelPrimitive.minBounds.z; }, }); addProperty({ name: "clippingBoxMaxX", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - value, - maxClippingBounds.y, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingBoxMaxX = that._voxelPrimitive.maxClippingBounds.x; }, @@ -508,14 +365,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingBoxMinX", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - value, - minClippingBounds.y, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingBoxMinX = that._voxelPrimitive.minClippingBounds.x; }, @@ -523,14 +373,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingBoxMaxY", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - value, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingBoxMaxY = that._voxelPrimitive.maxClippingBounds.y; }, @@ -538,14 +381,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingBoxMinY", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - value, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingBoxMinY = that._voxelPrimitive.minClippingBounds.y; }, @@ -553,14 +389,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingBoxMaxZ", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - maxClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingBoxMaxZ = that._voxelPrimitive.maxClippingBounds.z; }, @@ -568,14 +397,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingBoxMinZ", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - minClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingBoxMinZ = that._voxelPrimitive.minClippingBounds.z; }, @@ -583,14 +405,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMaxLongitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - value, - maxClippingBounds.y, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingEllipsoidMaxLongitude = that._voxelPrimitive.maxClippingBounds.x; @@ -599,14 +414,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMinLongitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - value, - minClippingBounds.y, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingEllipsoidMinLongitude = that._voxelPrimitive.minClippingBounds.x; @@ -615,14 +423,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMaxLatitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - value, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingEllipsoidMaxLatitude = that._voxelPrimitive.maxClippingBounds.y; @@ -631,14 +432,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMinLatitude", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - value, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingEllipsoidMinLatitude = that._voxelPrimitive.minClippingBounds.y; @@ -647,14 +441,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMaxHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - maxClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingEllipsoidMaxHeight = that._voxelPrimitive.maxClippingBounds.z; @@ -663,14 +450,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingEllipsoidMinHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - minClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingEllipsoidMinHeight = that._voxelPrimitive.minClippingBounds.z; @@ -679,14 +459,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMaxRadius", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - value, - maxClippingBounds.y, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingCylinderMaxRadius = that._voxelPrimitive.maxClippingBounds.x; }, @@ -694,14 +467,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMinRadius", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - value, - minClippingBounds.y, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "x"), getPrimitiveFunction: function () { that.clippingCylinderMinRadius = that._voxelPrimitive.minClippingBounds.x; }, @@ -709,14 +475,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMaxHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - value, - maxClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingCylinderMaxHeight = that._voxelPrimitive.maxClippingBounds.y; }, @@ -724,14 +483,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMinHeight", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - value, - minClippingBounds.z - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "y"), getPrimitiveFunction: function () { that.clippingCylinderMinHeight = that._voxelPrimitive.minClippingBounds.y; }, @@ -739,14 +491,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMaxAngle", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const maxClippingBounds = that._voxelPrimitive.maxClippingBounds; - that._voxelPrimitive.maxClippingBounds = new Cartesian3( - maxClippingBounds.x, - maxClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("maxClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingCylinderMaxAngle = that._voxelPrimitive.maxClippingBounds.z; }, @@ -754,14 +499,7 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "clippingCylinderMinAngle", initialValue: 0.0, - setPrimitiveFunction: function (value) { - const minClippingBounds = that._voxelPrimitive.minClippingBounds; - that._voxelPrimitive.minClippingBounds = new Cartesian3( - minClippingBounds.x, - minClippingBounds.y, - value - ); - }, + setPrimitiveFunction: getBoundSetter("minClippingBounds", "z"), getPrimitiveFunction: function () { that.clippingCylinderMinAngle = that._voxelPrimitive.minClippingBounds.z; }, From 067b259e7daaf46ea4c0042d5fee667cc9488e4e Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 4 Oct 2022 18:59:35 -0400 Subject: [PATCH 110/679] Add VoxelInspectorSpec --- .../Widgets/VoxelInspector/VoxelInspector.js | 36 ++++++++----- .../VoxelInspector/VoxelInspectorSpec.js | 54 +++++++++++++++++++ 2 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 Specs/Widgets/VoxelInspector/VoxelInspectorSpec.js diff --git a/Source/Widgets/VoxelInspector/VoxelInspector.js b/Source/Widgets/VoxelInspector/VoxelInspector.js index ef37f80512d..dbfe08d34d2 100644 --- a/Source/Widgets/VoxelInspector/VoxelInspector.js +++ b/Source/Widgets/VoxelInspector/VoxelInspector.js @@ -47,21 +47,21 @@ function VoxelInspector(container, scene) { panel.className = "cesium-cesiumInspector-dropDown"; element.appendChild(panel); - const { createCheckbox } = InspectorShared; - // Display const displayPanelContents = createSection(panel, "Display"); - displayPanelContents.appendChild(createCheckbox("Depth Test", "depthTest")); - displayPanelContents.appendChild(createCheckbox("Show", "show")); - displayPanelContents.appendChild( - createCheckbox("Disable Update", "disableUpdate") - ); - displayPanelContents.appendChild(createCheckbox("Debug Draw", "debugDraw")); - displayPanelContents.appendChild(createCheckbox("Jitter", "jitter")); - displayPanelContents.appendChild( - createCheckbox("Nearest Sampling", "nearestSampling") - ); + const { createCheckbox } = InspectorShared; + [ + ["Depth Test", "depthTest"], + ["Show", "show"], + ["Disable Update", "disableUpdate"], + ["Debug Draw", "debugDraw"], + ["Jitter", "jitter"], + ["Nearest Sampling", "nearestSampling"], + ].forEach(([title, variable]) => { + displayPanelContents.appendChild(createCheckbox(title, variable)); + }); + displayPanelContents.appendChild( makeRangeInput("Level Blend Factor", "levelBlendFactor", 0.0, 1.0) ); @@ -287,6 +287,18 @@ function VoxelInspector(container, scene) { } Object.defineProperties(VoxelInspector.prototype, { + /** + * Gets the parent container. + * @memberof VoxelInspector.prototype + * + * @type {Element} + */ + container: { + get: function () { + return this._container; + }, + }, + /** * Gets the view model. * @memberof VoxelInspector.prototype diff --git a/Specs/Widgets/VoxelInspector/VoxelInspectorSpec.js b/Specs/Widgets/VoxelInspector/VoxelInspectorSpec.js new file mode 100644 index 00000000000..b4b9cd3a769 --- /dev/null +++ b/Specs/Widgets/VoxelInspector/VoxelInspectorSpec.js @@ -0,0 +1,54 @@ +import { Ellipsoid, Globe, VoxelInspector } from "../../../../Source/Cesium.js"; + +import createScene from "../../createScene.js"; + +describe( + "Widgets/VoxelInspector/VoxelInspector", + function () { + let scene; + beforeAll(function () { + scene = createScene(); + const ellipsoid = Ellipsoid.UNIT_SPHERE; + const globe = new Globe(ellipsoid); + scene.globe = globe; + }); + + afterAll(function () { + scene.destroyForSpecs(); + }); + + it("can create and destroy", function () { + const container = document.createElement("div"); + container.id = "testContainer"; + document.body.appendChild(container); + + const widget = new VoxelInspector("testContainer", scene); + expect(widget.container).toBe(container); + expect(widget.viewModel.scene).toBe(scene); + expect(widget.isDestroyed()).toEqual(false); + widget.destroy(); + expect(widget.isDestroyed()).toEqual(true); + + document.body.removeChild(container); + }); + + it("constructor throws with no element", function () { + expect(function () { + return new VoxelInspector(); + }).toThrowDeveloperError(); + }); + + it("constructor throws with string element that does not exist", function () { + expect(function () { + return new VoxelInspector("does not exist", scene); + }).toThrowDeveloperError(); + }); + + it("constructor throws with no scene", function () { + expect(function () { + return new VoxelInspector(document.body); + }).toThrowDeveloperError(); + }); + }, + "WebGL" +); From 851e0f391143117a76f424a39c820cfe34f368a4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 6 Oct 2022 17:19:06 -0400 Subject: [PATCH 111/679] Always update clippingPlanesMatrix when voxel clipping is enabled --- Source/Scene/VoxelPrimitive.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Source/Scene/VoxelPrimitive.js b/Source/Scene/VoxelPrimitive.js index 16062b5d77c..0b959ae67c8 100644 --- a/Source/Scene/VoxelPrimitive.js +++ b/Source/Scene/VoxelPrimitive.js @@ -1556,14 +1556,6 @@ function updateClippingPlanes(primitive, frameState) { clippingPlanes.update(frameState); const { clippingPlanesState, enabled } = clippingPlanes; - if ( - primitive._clippingPlanesState === clippingPlanesState && - primitive._clippingPlanesEnabled === enabled - ) { - return false; - } - primitive._clippingPlanesState = clippingPlanesState; - primitive._clippingPlanesEnabled = enabled; if (enabled) { const uniforms = primitive._uniforms; @@ -1589,6 +1581,15 @@ function updateClippingPlanes(primitive, frameState) { ); } + if ( + primitive._clippingPlanesState === clippingPlanesState && + primitive._clippingPlanesEnabled === enabled + ) { + return false; + } + primitive._clippingPlanesState = clippingPlanesState; + primitive._clippingPlanesEnabled = enabled; + return true; } From 777efc1a6426ce126acd61545cd5cb5069a714c7 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 16:38:15 +0200 Subject: [PATCH 112/679] Rename content "url" to "uri" in all Geometry tileset JSON files --- .../Geometry/GeometryTileAll/tileset.json | 10 +++++----- .../GeometryTileAllBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../Geometry/GeometryTileAllWithBatchIds/tileset.json | 4 ++-- .../GeometryTileAllWithBatchTable/tileset.json | 10 +++++----- .../Geometry/GeometryTileBoxes/tileset.json | 10 +++++----- .../GeometryTileBoxesBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../GeometryTileBoxesWithBatchIds/tileset.json | 4 ++-- .../GeometryTileBoxesWithBatchTable/tileset.json | 10 +++++----- .../Geometry/GeometryTileCylinders/tileset.json | 10 +++++----- .../GeometryTileCylindersBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../GeometryTileCylindersWithBatchIds/tileset.json | 4 ++-- .../GeometryTileCylindersWithBatchTable/tileset.json | 10 +++++----- .../Geometry/GeometryTileEllipsoids/tileset.json | 10 +++++----- .../GeometryTileEllipsoidsBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../GeometryTileEllipsoidsWithBatchIds/tileset.json | 4 ++-- .../GeometryTileEllipsoidsWithBatchTable/tileset.json | 10 +++++----- .../Geometry/GeometryTileSpheres/tileset.json | 10 +++++----- .../GeometryTileSpheresBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../GeometryTileSpheresWithBatchIds/tileset.json | 4 ++-- .../GeometryTileSpheresWithBatchTable/tileset.json | 10 +++++----- 25 files changed, 80 insertions(+), 80 deletions(-) diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAll/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAll/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAll/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAll/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildren/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildren/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildrenWithBatchTable/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllBatchedChildrenWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchIds/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchIds/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchTable/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileAllWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxes/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxes/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxes/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxes/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildren/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildren/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildrenWithBatchTable/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesBatchedChildrenWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchIds/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchIds/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchTable/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileBoxesWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylinders/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylinders/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylinders/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylinders/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildren/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildren/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildrenWithBatchTable/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersBatchedChildrenWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchIds/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchIds/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchTable/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileCylindersWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoids/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoids/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoids/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoids/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildren/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildren/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildrenWithBatchTable/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsBatchedChildrenWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchIds/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchIds/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchTable/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileEllipsoidsWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheres/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheres/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheres/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheres/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildren/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildren/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildrenWithBatchTable/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresBatchedChildrenWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchIds/tileset.json index d673ef8ee99..647031b7afc 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchIds/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "children.geom" + "uri": "children.geom" } } ] diff --git a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchTable/tileset.json index 4aed1065eb0..001cfafb234 100644 --- a/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Geometry/GeometryTileSpheresWithBatchTable/tileset.json @@ -35,7 +35,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.geom" + "uri": "parent.geom" }, "children": [ { @@ -51,7 +51,7 @@ }, "geometricError": 0, "content": { - "url": "ul.geom" + "uri": "ul.geom" } }, { @@ -67,7 +67,7 @@ }, "geometricError": 0, "content": { - "url": "ur.geom" + "uri": "ur.geom" } }, { @@ -83,7 +83,7 @@ }, "geometricError": 0, "content": { - "url": "ll.geom" + "uri": "ll.geom" } }, { @@ -99,7 +99,7 @@ }, "geometricError": 0, "content": { - "url": "lr.geom" + "uri": "lr.geom" } } ] From d842a597cb8ab24339a4c374ea46dc052a046bb1 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 19:09:12 +0200 Subject: [PATCH 113/679] Make contentAvailabilities an array in binary subtree file --- .../ImplicitTileset/subtrees/0.0.0.subtree | Bin 184 -> 144 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Specs/Data/Cesium3DTiles/Implicit/ImplicitTileset/subtrees/0.0.0.subtree b/Specs/Data/Cesium3DTiles/Implicit/ImplicitTileset/subtrees/0.0.0.subtree index d95e4c5d98e56847be42f62e448975546bbc39dd..1cdc0b74bcf56359c79f309f0db41b682abc9bde 100644 GIT binary patch literal 144 zcmXReO)6nzU|^^KVq{RQRFavK>R6VTnUk25nUh&ksbp2Hl$@VeT#}eqqGV-Qs{`Vd hq~?{NDvCx`6$@0Bk(rYc478^x6_0@iwY3UB006NBErb97 literal 184 zcmXReO)6nzU|?7P#K@qUOF==YBr_+~u`Dq&Cow5AC$pqd$w~nv4wOmG&nqrT%qszk p7y?CVbwJ92f+eYWC8X%c$jnIz20EcAm9RwyAd9$aLG~*s007`6F<1Zq From 05009f7c6297651822e71b853f23e0d71c9b6aea Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 19:20:16 +0200 Subject: [PATCH 114/679] Make contentAvailabilities arrays in JSON subtree files --- .../subtrees/0.0.0.json | 10 ++++++---- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 10 ++++++---- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 16 ++++++++-------- .../subtrees/1.1/0.0.0.json | 10 ++++++---- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../ImplicitSubtreeMetadata/subtrees/0.0.0.json | 8 +++++--- .../subtrees/1.0/0.0.0.json | 8 +++++--- .../subtrees/1.1/0.0.0.json | 8 +++++--- .../ImplicitTileMetadata/subtrees/1.0/0.0.0.json | 8 +++++--- .../ImplicitTileMetadata/subtrees/1.1/0.0.0.json | 8 +++++--- 22 files changed, 116 insertions(+), 74 deletions(-) diff --git a/Specs/Data/Cesium3DTiles/Implicit/ImplicitTilesetWithJsonSubtree/subtrees/0.0.0.json b/Specs/Data/Cesium3DTiles/Implicit/ImplicitTilesetWithJsonSubtree/subtrees/0.0.0.json index c68b8917346..ee1e5e5f52c 100644 --- a/Specs/Data/Cesium3DTiles/Implicit/ImplicitTilesetWithJsonSubtree/subtrees/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Implicit/ImplicitTilesetWithJsonSubtree/subtrees/0.0.0.json @@ -2,10 +2,12 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 } -} \ No newline at end of file +} diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.0/0.0.0.json index 2f7f083a87c..adb230826aa 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.0/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.1/0.0.0.json index cde7648fe9b..8c6b6ce7e94 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/subtrees/1.1/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, @@ -32,4 +34,4 @@ } ], "tileMetadata": 0 -} \ No newline at end of file +} diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.0/0.0.0.json index 20f6568e521..87d05ad21c6 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.0/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.1/0.0.0.json index 2fdca3ee39a..da117c9a6ed 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/subtrees/1.1/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.0/0.0.0.json index 5036b4119d6..cdefc91c0f4 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.0/0.0.0.json @@ -20,9 +20,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.1/0.0.0.json index 3617c3e61f9..7bd30eec63b 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/subtrees/1.1/0.0.0.json @@ -20,9 +20,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.0/0.0.0.json index 29390a599a3..c6be6b70c1d 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.0/0.0.0.json @@ -40,14 +40,16 @@ "bitstream": 0, "availableCount": 4 }, - "contentAvailability": { - "bitstream": 0, - "availableCount": 4 - }, + "contentAvailability": [ + { + "bitstream": 0, + "availableCount": 4 + } + ], "childSubtreeAvailability": { "constant": 0 }, - "propertyTables" : [ + "propertyTables": [ { "class": "building", "properties": { @@ -60,9 +62,7 @@ } } ], - "contentMetadata": [ - 0 - ], + "contentMetadata": [0], "extensions": { "3DTILES_metadata": { "class": "tile", diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.1/0.0.0.json index e39e009a965..70f5d5d6e95 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/subtrees/1.1/0.0.0.json @@ -40,10 +40,12 @@ "bitstream": 0, "availableCount": 4 }, - "contentAvailability": { - "bitstream": 0, - "availableCount": 4 - }, + "contentAvailability": [ + { + "bitstream": 0, + "availableCount": 4 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.0/0.0.0.json index 49abd9cfbc5..fd3062ebbb6 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.0/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.1/0.0.0.json index 38a0530e28c..1eced6cb436 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/subtrees/1.1/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.0/0.0.0.json index 3d242aa3c28..2bfde5f155a 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.0/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.1/0.0.0.json index bf2d44bf265..dfb29670c29 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/subtrees/1.1/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.0/0.0.0.json index d3af491120f..bef32c3b61f 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.0/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.1/0.0.0.json index c3f3c38e6cc..a796a1415cb 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/subtrees/1.1/0.0.0.json @@ -25,9 +25,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.0/0.0.0.json index c869e252f3e..d8c8d68b3ba 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.0/0.0.0.json @@ -20,9 +20,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.1/0.0.0.json index 51854a68292..92bd8293e79 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/subtrees/1.1/0.0.0.json @@ -20,9 +20,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/subtrees/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/subtrees/0.0.0.json index a6ee1496461..9f391906532 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/subtrees/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/subtrees/0.0.0.json @@ -2,9 +2,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.0/0.0.0.json index 496fd3f590c..bc2ec12ece7 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.0/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.1/0.0.0.json index f660da26882..991faecd8ba 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/subtrees/1.1/0.0.0.json @@ -15,9 +15,11 @@ "tileAvailability": { "constant": 1 }, - "contentAvailability": { - "constant": 0 - }, + "contentAvailability": [ + { + "constant": 0 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.0/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.0/0.0.0.json index 22510a21f6f..6eb40ca98f8 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.0/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.0/0.0.0.json @@ -26,9 +26,11 @@ "bitstream": 0, "availableCount": 4 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.1/0.0.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.1/0.0.0.json index 806f031105a..1fc58b6cd32 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.1/0.0.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/subtrees/1.1/0.0.0.json @@ -26,9 +26,11 @@ "bitstream": 0, "availableCount": 4 }, - "contentAvailability": { - "constant": 1 - }, + "contentAvailability": [ + { + "constant": 1 + } + ], "childSubtreeAvailability": { "constant": 0 }, From 83306253e36bbc3fb53801fdae8dee62f1a47be5 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 19:38:59 +0200 Subject: [PATCH 115/679] Add IDs to metadata schemas --- .../Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.0.json | 1 + .../Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.1.json | 1 + .../Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.0.json | 1 + .../Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.1.json | 1 + Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/schema.json | 1 + Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.0.json | 1 + Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.1.json | 1 + .../ImplicitContentBoundingVolumeSemantics/tileset_1.0.json | 1 + .../ImplicitContentBoundingVolumeSemantics/tileset_1.1.json | 1 + .../ImplicitContentHeightAndRegionSemantics/tileset_1.0.json | 1 + .../ImplicitContentHeightAndRegionSemantics/tileset_1.1.json | 1 + .../Metadata/ImplicitContentHeightSemantics/tileset_1.0.json | 1 + .../Metadata/ImplicitContentHeightSemantics/tileset_1.1.json | 1 + .../Metadata/ImplicitContentMetadata/tileset_1.0.json | 1 + .../Metadata/ImplicitContentMetadata/tileset_1.1.json | 1 + .../Metadata/ImplicitGeometricErrorSemantics/tileset_1.0.json | 1 + .../Metadata/ImplicitGeometricErrorSemantics/tileset_1.1.json | 1 + .../Metadata/ImplicitGroupMetadata/tileset_1.0.json | 1 + .../Metadata/ImplicitGroupMetadata/tileset_1.1.json | 1 + .../Metadata/ImplicitHeightAndRegionSemantics/tileset_1.0.json | 1 + .../Metadata/ImplicitHeightAndRegionSemantics/tileset_1.1.json | 1 + .../Metadata/ImplicitHeightAndSphereSemantics/tileset_1.0.json | 1 + .../Metadata/ImplicitHeightAndSphereSemantics/tileset_1.1.json | 1 + .../Metadata/ImplicitHeightSemantics/s2-tileset_1.0.json | 1 + .../Metadata/ImplicitHeightSemantics/s2-tileset_1.1.json | 1 + .../Metadata/ImplicitHeightSemantics/tileset_1.0.json | 1 + .../Metadata/ImplicitHeightSemantics/tileset_1.1.json | 1 + .../ImplicitMultipleContentsWithMetadata/tileset_1.0.json | 1 + .../ImplicitMultipleContentsWithMetadata/tileset_1.1.json | 1 + .../Metadata/ImplicitSubtreeMetadata/tileset_1.0.json | 1 + .../Metadata/ImplicitSubtreeMetadata/tileset_1.1.json | 1 + .../ImplicitTileBoundingVolumeSemantics/tileset_1.0.json | 1 + .../ImplicitTileBoundingVolumeSemantics/tileset_1.1.json | 1 + .../Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.0.json | 1 + .../Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.1.json | 1 + .../Metadata/MultipleContentsWithMetadata/tileset_1.0.json | 1 + .../Metadata/MultipleContentsWithMetadata/tileset_1.1.json | 1 + .../Metadata/PropertyAttributesPointCloud/MetadataSchema.json | 1 + Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.0.json | 1 + Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.1.json | 1 + .../Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.0.json | 1 + .../Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.1.json | 1 + .../MultipleContents/GroupMetadata/tileset_1.0.json | 1 + .../MultipleContents/GroupMetadata/tileset_1.1.json | 1 + 44 files changed, 44 insertions(+) diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.0.json index fbb40d4b923..59780f7ae03 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.0.json @@ -9,6 +9,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "AllMetadataTypesSchemaId", "classes": { "tileset": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.1.json index 2a119367343..8fbcbb5f9b4 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/tileset_1.1.json @@ -4,6 +4,7 @@ "tilesetVersion": "1.2.3" }, "schema": { + "id": "AllMetadataTypesSchemaId", "classes": { "tileset": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.0.json index d5cdd294104..dd615a7ed48 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.0.json @@ -9,6 +9,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ContentMetadataSchemaId", "classes": { "content": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.1.json index 8fae9e37a46..d4a19f8a50d 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/tileset_1.1.json @@ -4,6 +4,7 @@ "tilesetVersion": "1.2.3" }, "schema": { + "id": "ContentMetadataSchemaId", "classes": { "content": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/schema.json b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/schema.json index 1f239c50d33..2bba3ee9b61 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/schema.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/schema.json @@ -1,4 +1,5 @@ { + "id": "ExternalSchemaId", "classes": { "tileset": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.0.json index 445b229f1a1..34a67f8ce40 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.0.json @@ -9,6 +9,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "GroupMetadataSchemaId", "classes": { "residential": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.1.json index 4be9539ee63..f1f8f2b537b 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/tileset_1.1.json @@ -4,6 +4,7 @@ "tilesetVersion": "1.2.3" }, "schema": { + "id": "GroupMetadataSchemaId", "classes": { "residential": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.0.json index c56337be790..59166afd42c 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitContentBoundingVolumeSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.1.json index f4ecbb0440a..2d763b98f05 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentBoundingVolumeSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitContentBoundingVolumeSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.0.json index 20d5c7c3b46..29a69bb69f4 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitContentHeightAndRegionSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.1.json index 43e880255bb..b53214c8f1a 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightAndRegionSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitContentHeightAndRegionSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.0.json index e1cf9a12557..b5987c2323d 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitContentHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.1.json index c84d6ac3aaf..2cdf5a8c176 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentHeightSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitContentHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.0.json index 941a8a00c4a..a5850ebff7f 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitContentMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.1.json index 3c04f2bb09c..a0d52566369 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitContentMetadata/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitContentMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.0.json index 0ebbcbd8698..6d03374a79d 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitGeometricErrorMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.1.json index d131121f217..66085956dc7 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGeometricErrorSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitGeometricErrorMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.0.json index cf41e70e1ad..88a9df1ead3 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.0.json @@ -15,6 +15,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitGroupMetadataSchemaId", "classes": { "layer": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.1.json index 15b2928472d..e51feccb994 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitGroupMetadata/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitGroupMetadataSchemaId", "classes": { "layer": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.0.json index 6659d665e9d..36dbd9dabb3 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitHeightAndRegionSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.1.json index d4ff1bc9719..e92c544827b 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndRegionSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitHeightAndRegionSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.0.json index 05869e18eea..b8271ca2797 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitHeightAndSphereSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.1.json index c33ca1af255..b89da2a8c86 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightAndSphereSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitHeightAndSphereSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.0.json index 66b97f354dc..31983927267 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.1.json index 492c9657a18..d1393ce4101 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/s2-tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.0.json index 2e58b3fb8e1..133363dad94 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.1.json index 04aa57a68fe..c5fa85aaf04 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitHeightSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitHeightSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.0.json index f0429e6f365..07060c554f0 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.0.json @@ -16,6 +16,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitMultipleContentsWithMetadataSchemaId", "classes": { "building": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.1.json index 101de6a11ff..d04befc39d8 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitMultipleContentsWithMetadata/tileset_1.1.json @@ -6,6 +6,7 @@ "name": "Sample Implicit Tileset" }, "schema": { + "id": "ImplicitMultipleContentsWithMetadataSchemaId", "classes": { "building": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.0.json index 287535700cf..a228e7a99a4 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitSubtreeMetadataSchemaId", "classes": { "subtree": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.1.json index 91475d3d766..be1fa380184 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitSubtreeMetadata/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitSubtreeMetadataSchemaId", "classes": { "subtree": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.0.json index 8c5ed4ed7a0..41f9374a1cf 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitTileBoundingVolumeSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.1.json index d8146f14460..95b173224e5 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileBoundingVolumeSemantics/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitTileBoundingVolumeSemanticsMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.0.json index 44593d30b62..bec94e4513a 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.0.json @@ -11,6 +11,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "ImplicitTileMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.1.json index c5681dc317c..95094b1622c 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/ImplicitTileMetadata/tileset_1.1.json @@ -3,6 +3,7 @@ "version": "1.1" }, "schema": { + "id": "ImplicitTileMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.0.json index e0a2184dbb9..8023ca365cd 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.0.json @@ -30,6 +30,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "MultipleContentsWithMetadataSchemaId", "classes": { "batched": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.1.json index 59a27ff08f0..be0d377bbee 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/MultipleContentsWithMetadata/tileset_1.1.json @@ -21,6 +21,7 @@ } }, "schema": { + "id": "MultipleContentsWithMetadataSchemaId", "classes": { "batched": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/PropertyAttributesPointCloud/MetadataSchema.json b/Specs/Data/Cesium3DTiles/Metadata/PropertyAttributesPointCloud/MetadataSchema.json index bfad454ffa1..85e79a11ae5 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/PropertyAttributesPointCloud/MetadataSchema.json +++ b/Specs/Data/Cesium3DTiles/Metadata/PropertyAttributesPointCloud/MetadataSchema.json @@ -1,4 +1,5 @@ { + "id": "PropertyAttributesPointCloudMetadataSchemaId", "classes" : { "exampleMetadataClass" : { "name" : "Example metadata class", diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.0.json index af4b64b2d3b..4bf5925b90f 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.0.json @@ -9,6 +9,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "TileMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.1.json index e7af40b0423..a2a01359d6f 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/tileset_1.1.json @@ -4,6 +4,7 @@ "tilesetVersion": "1.2.3" }, "schema": { + "id": "TileMetadataSchemaId", "classes": { "tile": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.0.json index 00e8c2a19a0..fc64905dfb9 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.0.json @@ -12,6 +12,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "TilesetMetadataSchemaId", "classes": { "tileset": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.1.json index 33272b18950..42fa698f830 100644 --- a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/tileset_1.1.json @@ -4,6 +4,7 @@ "tilesetVersion": "1.2.3" }, "schema": { + "id": "TilesetMetadataSchemaId", "classes": { "tileset": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.0.json b/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.0.json index 9ed9a81ce49..9c494fcbcf8 100644 --- a/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.0.json +++ b/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.0.json @@ -25,6 +25,7 @@ "extensions": { "3DTILES_metadata": { "schema": { + "id": "GroupMetadataSchemaId", "classes": { "layer": { "properties": { diff --git a/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.1.json b/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.1.json index ed20265d24e..054862205aa 100644 --- a/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.1.json +++ b/Specs/Data/Cesium3DTiles/MultipleContents/GroupMetadata/tileset_1.1.json @@ -21,6 +21,7 @@ } }, "schema": { + "id": "GroupMetadataSchemaId", "classes": { "layer": { "properties": { From 4b3b4186b4afa2307d7d1666569826d864b984ca Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 20:09:48 +0200 Subject: [PATCH 116/679] Update binary tile content with proper alignment --- .../BatchedAnimated/batchedAnimated.b3dm | Bin 10208 -> 10216 bytes .../Batched/BatchedColors/batchedColors.b3dm | Bin 13316 -> 13320 bytes .../BatchedColorsMix/batchedColorsMix.b3dm | Bin 13372 -> 13368 bytes .../batchedColorsTranslucent.b3dm | Bin 13372 -> 13368 bytes .../batchedDeprecated1.b3dm | Bin 9440 -> 9436 bytes .../batchedDeprecated2.b3dm | Bin 9444 -> 9440 bytes .../BatchedExpiration/batchedExpiration.b3dm | Bin 9672 -> 9672 bytes .../BatchedNoBatchIds/batchedNoBatchIds.b3dm | Bin 7896 -> 7896 bytes .../BatchedTextured/batchedTextured.b3dm | Bin 27560 -> 27560 bytes .../batchedTranslucent.b3dm | Bin 9672 -> 9672 bytes .../batchedTranslucentOpaqueMix.b3dm | Bin 10024 -> 10024 bytes .../Batched/BatchedWGS84/batchedWGS84.b3dm | Bin 9600 -> 9600 bytes .../batchedWithBatchTable.b3dm | Bin 10304 -> 10304 bytes .../batchedWithBatchTableBinary.b3dm | Bin 10072 -> 10072 bytes .../batchedWithBoundingSphere.b3dm | Bin 9672 -> 9672 bytes .../BatchedWithContentDataUri/tileset.json | 2 +- .../batchedWithRtcCenter.b3dm | Bin 9500 -> 9496 bytes .../batchedWithTransformBox.b3dm | Bin 9468 -> 9464 bytes .../batchedWithTransformRegion.b3dm | Bin 9468 -> 9464 bytes .../batchedWithTransformSphere.b3dm | Bin 9468 -> 9464 bytes .../batchedWithVertexColors.b3dm | Bin 10860 -> 10856 bytes .../batchedWithoutBatchTable.b3dm | Bin 9048 -> 9048 bytes .../Composite/Composite/composite.cmpt | Bin 13472 -> 13472 bytes .../compositeOfComposite.cmpt | Bin 13488 -> 13488 bytes .../Hierarchy/BatchTableHierarchy/tile.b3dm | Bin 78260 -> 78264 bytes .../BatchTableHierarchyBinary/tile.b3dm | Bin 79364 -> 79368 bytes .../BatchTableHierarchyLegacy/tile.b3dm | Bin 78228 -> 78232 bytes .../tile.b3dm | Bin 78596 -> 78600 bytes .../BatchTableHierarchyNoParents/tile.b3dm | Bin 77924 -> 77928 bytes .../instancedGltfExternal.i3dm | Bin 503 -> 504 bytes .../instancedOct32POrientation.i3dm | Bin 4044 -> 4048 bytes .../instancedOrientation.i3dm | Bin 4428 -> 4432 bytes .../instancedQuantized.i3dm | Bin 3764 -> 3768 bytes .../instancedQuantizedOct32POrientation.i3dm | Bin 4020 -> 4024 bytes .../Instanced/InstancedRTC/instancedRTC.i3dm | Bin 3852 -> 3856 bytes .../instancedRedMaterial.i3dm | Bin 3780 -> 3784 bytes .../InstancedScale/instancedScale.i3dm | Bin 3908 -> 3912 bytes .../instancedScaleNonUniform.i3dm | Bin 4116 -> 4120 bytes .../InstancedTextured/instancedTextured.i3dm | Bin 8096 -> 22864 bytes .../instancedWithBatchIds.i3dm | Bin 3868 -> 3872 bytes .../instancedWithBatchTable.i3dm | Bin 3780 -> 3784 bytes .../instancedWithBatchTableBinary.i3dm | Bin 3868 -> 3872 bytes .../instancedWithoutBatchTable.i3dm | Bin 3692 -> 3696 bytes .../Metadata/AllMetadataTypes/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/AllMetadataTypes/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/AllMetadataTypes/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/AllMetadataTypes/ur.b3dm | Bin 9688 -> 9672 bytes .../Metadata/ContentMetadata/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/ContentMetadata/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/ContentMetadata/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/ContentMetadata/ur.b3dm | Bin 9688 -> 9672 bytes .../Metadata/ExternalSchema/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/ExternalSchema/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/ExternalSchema/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/ExternalSchema/ur.b3dm | Bin 9688 -> 9672 bytes .../Metadata/GroupMetadata/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/GroupMetadata/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/GroupMetadata/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/GroupMetadata/ur.b3dm | Bin 9688 -> 9672 bytes .../Metadata/TileMetadata/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/TileMetadata/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/TileMetadata/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/TileMetadata/ur.b3dm | Bin 9688 -> 9672 bytes .../Metadata/TilesetMetadata/ll.b3dm | Bin 9700 -> 9688 bytes .../Metadata/TilesetMetadata/lr.b3dm | Bin 9704 -> 9688 bytes .../Metadata/TilesetMetadata/ul.b3dm | Bin 9684 -> 9664 bytes .../Metadata/TilesetMetadata/ur.b3dm | Bin 9688 -> 9672 bytes .../PointCloudBatched/pointCloudBatched.pnts | Bin 25628 -> 25632 bytes .../pointCloudConstantColor.pnts | Bin 12180 -> 12192 bytes .../PointCloudDraco/pointCloudDraco.pnts | Bin 15964 -> 15968 bytes .../pointCloudDracoBatched.pnts | Bin 11684 -> 11688 bytes .../pointCloudDracoPartial.pnts | Bin 25812 -> 25808 bytes .../PointCloudNoColor/pointCloudNoColor.pnts | Bin 12148 -> 12160 bytes .../PointCloudNormals/pointCloudNormals.pnts | Bin 27212 -> 27216 bytes .../pointCloudNormalsOctEncoded.pnts | Bin 17212 -> 17224 bytes .../pointCloudQuantized.pnts | Bin 9236 -> 9248 bytes .../pointCloudQuantizedOctEncoded.pnts | Bin 11276 -> 11280 bytes .../PointCloudRGB/pointCloudRGB.pnts | Bin 15180 -> 15184 bytes .../PointCloudRGB565/pointCloudRGB565.pnts | Bin 14180 -> 14192 bytes .../PointCloudRGBA/pointCloudRGBA.pnts | Bin 16180 -> 16184 bytes .../PointCloud/PointCloudTimeDynamic/0.pnts | Bin 33404 -> 33400 bytes .../PointCloud/PointCloudTimeDynamic/1.pnts | Bin 33404 -> 33400 bytes .../PointCloud/PointCloudTimeDynamic/2.pnts | Bin 33404 -> 33400 bytes .../PointCloud/PointCloudTimeDynamic/3.pnts | Bin 33404 -> 33400 bytes .../PointCloud/PointCloudTimeDynamic/4.pnts | Bin 33404 -> 33400 bytes .../PointCloudTimeDynamicDraco/0.pnts | Bin 16684 -> 16688 bytes .../PointCloudTimeDynamicDraco/1.pnts | Bin 16676 -> 16680 bytes .../PointCloudTimeDynamicDraco/2.pnts | Bin 16676 -> 16680 bytes .../PointCloudTimeDynamicDraco/3.pnts | Bin 16668 -> 16672 bytes .../PointCloudTimeDynamicDraco/4.pnts | Bin 16676 -> 16680 bytes .../PointCloudTimeDynamicWithTransform/0.pnts | Bin 33332 -> 33336 bytes .../PointCloudTimeDynamicWithTransform/1.pnts | Bin 33332 -> 33336 bytes .../PointCloudTimeDynamicWithTransform/2.pnts | Bin 33332 -> 33336 bytes .../PointCloudTimeDynamicWithTransform/3.pnts | Bin 33332 -> 33336 bytes .../PointCloudTimeDynamicWithTransform/4.pnts | Bin 33332 -> 33336 bytes .../PointCloudWGS84/pointCloudWGS84.pnts | Bin 15108 -> 15120 bytes .../pointCloudWithPerPointProperties.pnts | Bin 33332 -> 33336 bytes .../pointCloudWithTransform.pnts | Bin 15108 -> 15120 bytes .../Cesium3DTiles/Tilesets/Tileset/ll.b3dm | Bin 9700 -> 9688 bytes .../Cesium3DTiles/Tilesets/Tileset/lr.b3dm | Bin 9704 -> 9688 bytes .../Tilesets/Tileset/parent.b3dm | Bin 9680 -> 9664 bytes .../Cesium3DTiles/Tilesets/Tileset/ul.b3dm | Bin 9684 -> 9664 bytes .../Cesium3DTiles/Tilesets/Tileset/ur.b3dm | Bin 9688 -> 9672 bytes .../Tilesets/TilesetEmptyRoot/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetEmptyRoot/lr.b3dm | Bin 9688 -> 9688 bytes .../Tilesets/TilesetEmptyRoot/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetEmptyRoot/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetOfTilesets/lr.b3dm | Bin 9688 -> 9688 bytes .../Tilesets/TilesetOfTilesets/parent.b3dm | Bin 9664 -> 9664 bytes .../TilesetOfTilesets/tileset3/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetOfTilesets/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetOfTilesets/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetPoints/0.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/1.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/2.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/3.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/4.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/5.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/6.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/7.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetPoints/parent.pnts | Bin 15108 -> 15120 bytes .../Tilesets/TilesetRefinementMix/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetRefinementMix/lr.b3dm | Bin 9688 -> 9688 bytes .../Tilesets/TilesetRefinementMix/parent.b3dm | Bin 9664 -> 9664 bytes .../Tilesets/TilesetRefinementMix/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetRefinementMix/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetReplacement1/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetReplacement1/lr.b3dm | Bin 9688 -> 9688 bytes .../Tilesets/TilesetReplacement1/parent.b3dm | Bin 9664 -> 9664 bytes .../Tilesets/TilesetReplacement1/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetReplacement1/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetReplacement2/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetReplacement2/parent.b3dm | Bin 9664 -> 9664 bytes .../Tilesets/TilesetReplacement2/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetReplacement3/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetReplacement3/lr.b3dm | Bin 9688 -> 9688 bytes .../Tilesets/TilesetReplacement3/parent.b3dm | Bin 9664 -> 9664 bytes .../Tilesets/TilesetReplacement3/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetReplacement3/ur.b3dm | Bin 9672 -> 9672 bytes .../ll.b3dm | Bin 9684 -> 9688 bytes .../lr.b3dm | Bin 9688 -> 9688 bytes .../parent.b3dm | Bin 9664 -> 9664 bytes .../ul.b3dm | Bin 9668 -> 9664 bytes .../ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetSubtreeExpiration/ll.b3dm | Bin 9684 -> 9688 bytes .../Tilesets/TilesetSubtreeExpiration/lr.b3dm | Bin 9688 -> 9688 bytes .../TilesetSubtreeExpiration/parent.b3dm | Bin 9664 -> 9664 bytes .../Tilesets/TilesetSubtreeExpiration/ul.b3dm | Bin 9668 -> 9664 bytes .../Tilesets/TilesetSubtreeExpiration/ur.b3dm | Bin 9672 -> 9672 bytes .../Tilesets/TilesetUniform/0_0_0.b3dm | Bin 8688 -> 8672 bytes .../Tilesets/TilesetUniform/1_0_0.b3dm | Bin 8708 -> 8688 bytes .../Tilesets/TilesetUniform/1_0_1.b3dm | Bin 8708 -> 8688 bytes .../Tilesets/TilesetUniform/1_0_2.b3dm | Bin 8712 -> 8696 bytes .../Tilesets/TilesetUniform/1_1_0.b3dm | Bin 8700 -> 8680 bytes .../Tilesets/TilesetUniform/1_1_1.b3dm | Bin 8708 -> 8688 bytes .../Tilesets/TilesetUniform/1_1_2.b3dm | Bin 8712 -> 8696 bytes .../Tilesets/TilesetUniform/1_2_0.b3dm | Bin 8696 -> 8680 bytes .../Tilesets/TilesetUniform/1_2_1.b3dm | Bin 8712 -> 8696 bytes .../Tilesets/TilesetUniform/1_2_2.b3dm | Bin 8704 -> 8688 bytes .../Tilesets/TilesetUniform/2_3_3.b3dm | Bin 8720 -> 8704 bytes .../Tilesets/TilesetUniform/2_3_4.b3dm | Bin 8716 -> 8704 bytes .../Tilesets/TilesetUniform/2_3_5.b3dm | Bin 8716 -> 8704 bytes .../Tilesets/TilesetUniform/2_4_3.b3dm | Bin 8716 -> 8704 bytes .../Tilesets/TilesetUniform/2_4_4.b3dm | Bin 8720 -> 8704 bytes .../Tilesets/TilesetUniform/2_4_5.b3dm | Bin 8716 -> 8696 bytes .../Tilesets/TilesetUniform/2_5_3.b3dm | Bin 8716 -> 8704 bytes .../Tilesets/TilesetUniform/2_5_4.b3dm | Bin 8724 -> 8704 bytes .../Tilesets/TilesetUniform/2_5_5.b3dm | Bin 8716 -> 8696 bytes .../TilesetWithExternalResources/embed.i3dm | Bin 7744 -> 22472 bytes .../external.b3dm | Bin 7688 -> 22416 bytes .../external.i3dm | Bin 142 -> 144 bytes .../textured_box_separate/textured_box.glb | Bin 2160 -> 2200 bytes .../tileset2/embed.i3dm | Bin 7744 -> 22472 bytes .../tileset2/external.b3dm | Bin 7688 -> 22416 bytes .../tileset2/external.i3dm | Bin 145 -> 152 bytes .../TilesetWithTransforms/buildings.b3dm | Bin 9468 -> 9464 bytes .../TilesetWithTransforms/instances.i3dm | Bin 3764 -> 3768 bytes .../TilesetWithViewerRequestVolume/ll.b3dm | Bin 9684 -> 9688 bytes .../TilesetWithViewerRequestVolume/lr.b3dm | Bin 9688 -> 9688 bytes .../points.pnts | Bin 15132 -> 15136 bytes .../TilesetWithViewerRequestVolume/ul.b3dm | Bin 9668 -> 9664 bytes .../TilesetWithViewerRequestVolume/ur.b3dm | Bin 9672 -> 9672 bytes 182 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedAnimated/batchedAnimated.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedAnimated/batchedAnimated.b3dm index 10878c25abf44ca4d62cf574f50ade6e55a0eeb7..537ab702f653d81b4017557c094dddb84433ffe1 100644 GIT binary patch delta 63 zcmaFh|H7X$$v7pKk%58X#YWEOOiT=_n?Es`u`pShZPsF+#>ix0u=x^2 SWG5RavT)inFf;%$0|NkX LnF>N3liw!=>>3fB diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedColors/batchedColors.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedColors/batchedColors.b3dm index 28cf4bd01d3a30847da1d50eb0f504dc6a304fa7..913ce3c92ca9c8b3240306005622c8035ed6f4c1 100644 GIT binary patch delta 65 zcmZq4=*ZwqGET{5WME+6*vR>uiB-Xnf#J*MuT0Hs{CSDFsY+H#Nu_CNsYOaUo69+E ScqbnfQ)g8Gfz7YQBxM14N)rnJ delta 62 zcmeCkXvyGAGET{5WME)m*~s~viB-msf#JjEuT0Hsn>#qId4+V8@)C1Xm8_JC^7Bjl S@>5ckCLb14-~2&LLKXl+0ux~X diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedColorsMix/batchedColorsMix.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedColorsMix/batchedColorsMix.b3dm index 50badeebe96071de390243e99a433bd41225819c..3344051e3880e5e98ee2219611bef0dcbe4887cf 100644 GIT binary patch delta 59 zcmdm!u_J>s$v7pKk%581Vk75sCe{E$1_qVQUzwWO`12BTQ#09 V<)@@7P5vdO#-yOISwUPv766UW6Hx#F diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedColorsTranslucent/batchedColorsTranslucent.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedColorsTranslucent/batchedColorsTranslucent.b3dm index aec0e8b11168d758f12c8576cc12b2f696a44d58..6b2a88312dc958b1f44099f73c67eba5616708fb 100644 GIT binary patch delta 59 zcmdm!u_J>s$v7pKk%581Vk75sCe{E$1_qVQUzwWO`12BTQ#09 V<)@@7P5vdO#-yOISwUPv766UW6Hx#F diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedDeprecated1/batchedDeprecated1.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedDeprecated1/batchedDeprecated1.b3dm index ec87d5cdc4dd16aa94c9942e9b763c4867ed995e..8c25e02d8288124ba45cdddd346d0ec419582705 100644 GIT binary patch delta 59 zcmaFhdB>A8$v7pKk%58X&PL8=Ce{cg1_qtY6PW^-`12BTQ=Lp79rhA% delta 64 zcmccP`M{Gi$v7pKk%58X!A8zzCe|1w1_p!86PW^-Hh*MU!z84ml$V&Bs$`{9l%HSX Um!FcVG0EPY&oB#j- diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedDeprecated2/batchedDeprecated2.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedDeprecated2/batchedDeprecated2.b3dm index 6aab4df9793919ddbd2fa85b4010dcde1e4692aa..a59e7f236c311ca9ab71252c9ffd25127d6c839f 100644 GIT binary patch delta 59 zcmaFj`M{Gi$v7pKk%58X!A8z@Ce{cg1_qtYQ<(yo`12BTQ=Lp7A{G*m delta 64 zcmaFh`NWem$v7pKk%58X$wtn0Ce|1w1_p!8Q<(yoHh*PV!z84ml$V&Bs$`{9l%HSX Um!FcVGffB*ox<`-lD delta 71 zcmV-N0J#6C*8!;40kHG}0g$ux0y+Z`VtI6BOl59obZ8RPH$voB9re4nFAmo6tjs68)36L7slru9i_a)+*BnirK0@&62JVERHexd9BP|0I3#2NAioU_ diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedWithBatchTable/batchedWithBatchTable.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedWithBatchTable/batchedWithBatchTable.b3dm index b867b67f266fae303ad7824193230f880d006eef..992d27970f5801af0d1b9479c639d826f18fb252 100644 GIT binary patch delta 37 tcmX>Qa3ElV0|$RzVs5IEl~Ph^T3Tw6lFnv(j&)3v|8r?>R^yhE1por$44D7` delta 40 wcmX>Qa3ElV1IOk7j(^b diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedWithBoundingSphere/batchedWithBoundingSphere.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedWithBoundingSphere/batchedWithBoundingSphere.b3dm index 9f8cf594c0b4c3879259dc573f0acfb63fa2f90b..a65800983d20be956a0322416207b448299acccd 100644 GIT binary patch delta 37 tcmX@%eZqUg30D5R#N1RRE2X5;w6xSBC7sR3S=TX5Zs*Y4ypBUk762J_4YU9N delta 40 wcmX@%eZqUg3D(UwSl2QM=_utT=B6rHDHY}Cm-ywUq$*8r<05{SRp#T5? diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedWithTransformBox/batchedWithTransformBox.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedWithTransformBox/batchedWithTransformBox.b3dm index cb44445561968854e524bd91f0ad3b93e79fb74a..6ad506e212cd3fc7544b7c2919369ba8df0c23d1 100644 GIT binary patch delta 59 zcmez4`NNYl$v7pKk%58X$41WiOso+~3=BG(*D?h#@#iJxrYcz}C6%V7r4}jaZ2rTt Pj%o59cD2n<*d=5EI^z>j delta 65 zcmez2`Nxwp$v7pKk%58X&qmJqOsp|V3=9UF*D?h#ZRTZN%Os?ul$V&Bs$`{9l%HSX Vm!FcVGj delta 65 zcmez2`Nxwp$v7pKk%58X&qmJqOsp|V3=9UF*D?h#ZRTZN%Os?ul$V&Bs$`{9l%HSX Vm!FcVGj delta 65 zcmez2`Nxwp$v7pKk%58X&qmJqOsp|V3=9UF*D?h#ZRTZN%Os?ul$V&Bs$`{9l%HSX Vm!FcVG?DR1puJ&6cPXc diff --git a/Specs/Data/Cesium3DTiles/Batched/BatchedWithoutBatchTable/batchedWithoutBatchTable.b3dm b/Specs/Data/Cesium3DTiles/Batched/BatchedWithoutBatchTable/batchedWithoutBatchTable.b3dm index ac3daaaa028c42d4e81160607421a2e71ec66874..aca28366696baa4908766bafa731934e5c36fad7 100644 GIT binary patch delta 37 tcmccNcEfE$1T%kLVs5IEl~Ph^T3Tw6lFsIE=50ssR&3<3ZE delta 40 wcmccNcEfE$1oP$$=Cw>hI!bwoxv5H4N=5nkC4TuSsY;VY*)%shut~@Q04!Dw1poj5 diff --git a/Specs/Data/Cesium3DTiles/Composite/Composite/composite.cmpt b/Specs/Data/Cesium3DTiles/Composite/Composite/composite.cmpt index 4564fa268abfa05df9a0fa909ea81040678b362f..70d6d1a5b3d26ff4b42cda257a71701cd7c836f4 100644 GIT binary patch delta 37 tcmZ3Gxgc}H4OafV#N1RRE2X5;w6xSBC7sRJS=TX5eypvzc^}6kZ2%tZ4ltXj#1&#;W0Du<| Aq5uE@ diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm index c9eda60d78cf14d4e58b6cdffb7327864796e626..6d5989aa9096a3aad08f86f5bc1fa60e4d1f3bc1 100644 GIT binary patch delta 95 zcmdn;m}SRf7S1H&lw3vz28JCQIr-TbS8SGKt7B5kOUzAGvQkPaO-oBHQqoaMsw_$M zNzF?y$xyN~H#Ige*}Q^7o{`aH^9jyY#>w&An#>9c8qJ;D+dH`#wbfXF#xVc@g(Vu- delta 91 zcmdn-m}Sdj7S1H&lw3vz28JygIr-Tbmu!|~t78&Osw_$MNzF?y$xyN~H#Ige*t~;7 vo{`aD^9{~cMj;)gyu{p8B`c+({QMHX{FGFs$+6s;j4I8Y+}k_38MV~_6?PkK diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyBinary/tile.b3dm index 992d1a7190e9f01b0bc08cd2bdef907303d0836c..d6ea5a9e347b5b67236d1941462bb89d56bb31de 100644 GIT binary patch delta 95 zcmZp9!_x7Fg)_-GC6|$bfq`QqXFM0rp5*)n}6`gGcuZNmf&k;oV=c2lUYGQqxmNP_M7~S+G;F7;}`&HLmMUl delta 91 zcmeBp!_xAGg)_-GC6|$bfq`WsXFM0rp5*an>l#p v85s>WYw)!)3h5~2CFZ6oSt%9e=a=~9r=%)PUdyk^sM36sfBQ{-Mr}0!#bFw~ diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyLegacy/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyLegacy/tile.b3dm index 17e76151f1cc428a6095a4d1a48700ca0ec6805e..387930219ff5ba5970d603880792ad43a93940bd 100644 GIT binary patch delta 95 zcmbR8m}SOe7S1H&lw3vz28J0MIp4D~uGsvOwT?+KFEKY&$x11yG%YQ)NJ&R2sj?*1 zCp9mWOE0HJR_sY<`tZ+jFauTHJKF@G@3KHw`X!QYOApTjbi`+*s>dy delta 91 zcmV-h0Hptz;{=rB1PNj@WNiTe005M+3GW2~q_g=2egY9rp5*)n}2Z1GcuZNmf&t>oV=b#lUYGQqxmM!_M1G6+G;F7;}`&A4jTmk delta 91 zcmeBp#?tbPg)_-GC6|$bfq`WsXFNOOlFgaybxeXul_jY@sd?!o8A?{>rp5*an>o1T v85s>WYjC$R3h5~2CFZ6oSt%9e=a=~9r=%)PUdyA&sM36sXZuYaMr}0!zF!)g diff --git a/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyNoParents/tile.b3dm b/Specs/Data/Cesium3DTiles/Hierarchy/BatchTableHierarchyNoParents/tile.b3dm index c63977a14720a8e16abc7a369b291a48086614d2..099dd6d1f7734c38c019d682f2549b288a08c66a 100644 GIT binary patch delta 95 zcmaFzfaS#l7S1H&lw3vz28N7{ocmcAS8P7XQpcp2mzbNXWTli;nwFMYq@<&iR9TYh ylbV-alA&Z}Zfa~`vN?iXo{`aHa|K5$<79p=O=blJjb=-(?Ur1O+G;F7;}`(Z!WyUm delta 91 zcmaFyfaS>p7S1H&lw3vz28NW4ocmcAmux=CQpY5iR9TYhlbV-alA&Z}Zfa~`usMTW vo{`aDa|cH&qmYhLUSe*ll9f_XetwBxeoCs+WL_>!MwMnuuI-jwjM{1dT0|Q@ diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedGltfExternal/instancedGltfExternal.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedGltfExternal/instancedGltfExternal.i3dm index afcfc8739afadd19bd9970dc8eaa5f452756d06d..aa0df91f95bc9d01fc40a07a1732bb7b0f40fe4e 100644 GIT binary patch delta 20 bcmey){DYY@(>NuUk%58X$41U~jEoEbN6-cj delta 18 Zcmeyt{GFLI(>NuUk%58X`$o=pi~u{Y1`PlJ diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedOct32POrientation/instancedOct32POrientation.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedOct32POrientation/instancedOct32POrientation.i3dm index 643cd02ef3cedfc9f352ed805802eaec1429f7e8..8f32383fb78329f8d982ab4443ee60c75acc246d 100644 GIT binary patch delta 23 dcmX>je?guz(>NuUk%58X!bZ-+{478Q0{~SP1+oAD delta 18 Zcmca0e@31&(>NuUk%58X%tp?``~WzR1*!l5 diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedOrientation/instancedOrientation.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedOrientation/instancedOrientation.i3dm index 90f8694f975ecce833de710e3000bc7c9119fb19..b06894dee449bda665393772cc9e593f319de751 100644 GIT binary patch delta 23 dcmX@3bU}$T(>NuUk%56BU?ZoqAPbPe002!O1iAnK delta 18 ZcmcbhbVi9Y(>NuUk%581XCtSxAOJOT1hN1C diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedQuantized/instancedQuantized.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedQuantized/instancedQuantized.i3dm index 9f82ed1e12f7cdb429da6f3ee48d3dea9f821e0c..4a543a14b85eba6b208594d4c26131782db09d43 100644 GIT binary patch delta 23 dcmdlYyF->U(>NuUk%56>$41W8d@Mi)0{~A11x)|| delta 18 ZcmdlXyG52W(>NuUk%56>%SO)Cd;m0e1w{Y= diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedQuantizedOct32POrientation/instancedQuantizedOct32POrientation.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedQuantizedOct32POrientation/instancedQuantizedOct32POrientation.i3dm index f91a947a4d60e367f45a61e258b46997e5707662..487d1cc5c2a2e8e16204d3747200d51e442228ab 100644 GIT binary patch delta 23 dcmdlYzeAog(>NuUk%56>$41W8{478Q0{~B61yTS2 delta 18 ZcmdlXzeS!i(>NuUk%56>%SO)C`~Wn#1xf$_ diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedRTC/instancedRTC.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedRTC/instancedRTC.i3dm index 78add2f4497501d0dc98285602e87afffe061cf9..5ea45dfdddc11cd8c71bb9e1b85b6e0ba35246a5 100644 GIT binary patch delta 23 dcmeB?n;^%TX`GVF$iToLu#uCQp9RQZ002EK1F!%9 delta 18 ZcmbOr*CWT7X`GVF$iTqBvyqdT9{?(_1E>H1 diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedRedMaterial/instancedRedMaterial.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedRedMaterial/instancedRedMaterial.i3dm index cdda54315c00f4754fbdd442ea0b127e122fec00..b0cff3c5a6d45857ffd18804742a1a7cc69b4390 100644 GIT binary patch delta 23 dcmX>idqS2o(>NuUk%58X#755Dd@Mi)0{~Lg1&sgz delta 18 ZcmX>hdqkEq(>NuUk%58X$VSfHd;m8G1%&_r diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedScale/instancedScale.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedScale/instancedScale.i3dm index c6d19ff19b490ee811dd323cd3c12ed3315c4479..e6284fe442cebb78d1f13dea64ea87f75cd42c04 100644 GIT binary patch delta 23 dcmX>icS4Rc(>NuUk%581VhcSMde(>NuUk%581Wh19GKL9hR1c(3t diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedScaleNonUniform/instancedScaleNonUniform.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedScaleNonUniform/instancedScaleNonUniform.i3dm index d81cf99bfcbf0027ebb75eec52654ae34d1ff48d..5fdaa851136f188075b43f634e3678a563e3f815 100644 GIT binary patch delta 23 dcmbQDFhhYe(>NuUk%56hVk0NF01J@8002L31JwWk delta 18 ZcmbQCFhzkg(>NuUk%56hWFsfH001mG1I+*c diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedTextured/instancedTextured.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedTextured/instancedTextured.i3dm index cce7e37198f7b5cdbc58cefe42d468eedd98e269..2589b46b027405193862935100dda3e8d1237459 100644 GIT binary patch delta 20433 zcmbTe1yoe;_cuC-h#-m}NQ1O=cgzqzHQqm0FA>E8hcXuh>T?50+ zd+_`F-S_|AweDK?-s2kPOr7UE&$IVu@BP_(n+_eSz`}rJXBUtQh&zzYz7 z&qm;bA3P@kpTUbje8C5J*}vcW@3W$ks>Tz3Zh()MTM)v}%g-y$DwRQCkzgpYcJ370%dqzgb z#wRAHrf2>v0n00^YwH`ETZc!-C#PrU7s$(-ncd9vzsJ9G`@hYM2%Ooi+qbcAz4P;)QN86(DU6PmeItuaDBwU|L!h{Y*a@1Pdr8etpid^w_*IpOoD%y4{zr7cWU6w zfd3a$d;kAyZcG22+5eu{41@q13*0|!A_x@HS5IE&(h4B;K7C!~EE~LbN8469TQ9!u z53{2VB+bfJ8!}j|xL#geJ{DS+yMX)bOpFp9DLfa-@#quuBk(?kp0GP^i@33jpaO6& zv|X5^{hl*>bxSn*4U@#}T;eE-i5_z|_t+{yn=f^*O-RRC==Ly>4Tj2KR??i3@8WG3 z$N}B;Z9u06Ns$v>MCApf&kIdE%i!W}?l=@QB%A_6x+R>phXG<}g#vu;v4?K*<8k9B z<^}mNtY=2eZDy}2mc162&I;l76|4-MbZ66rKQWN66c`A!-SDlhvbwsQxX!YV@45ZZ z_^<2g?|i!#_|6e{<1gvw>mpAd|(3sbS&$_EW?&+<9pWdeHqWHOZz+pBN#i zb(tgVlB6Tc>yG3i$^!^8LMZJ;FIXK5>~;V4_)+}R=H*jfwnI()(c-RnX`L zo6}tLY~EWe@Ka{L-55*_81=rGh)DRs*;?NLH5xEV^ncm_w8eJ~H_#ojRX|TiF%a28 z$e+UNZmz89<;;ByWT;4jiF!2tpKRbHzDV#?!Vs<<-y6x%Ax8WDv(xGa^+tZ~Aun&- zW~g3EovEzBgnF!1c-D{(FW!#+wrQ*IXyF?v<_*}HNk zT6Q+>=a}*;Y>cIuP7Z^On-n27=YkcWo2;lap%f0iUk287ZNdxMK#OttX>pvSPPft1 z1~=#8WWCu_!EWeOIsk7rOe}f69>K+R`#ZAGz2h3ut|2u3r9%(}%-R-4>lvM}5W{*E zPLD7U{%dqPJ>Ri+C6YayE(#>FswiSzvlBtPBhx6BZ+r$=5>sB!Xz$LiD|a%}6I8HK64h14XlN+N@YuJi(VjSmW)hlUe#2K5*8Mo$G_ zar>|H#{Pl>1;rYU>PkNmx>j$e(F#RhINwr)x?&(cL99OVrg2o-1x)cSV@>gZ?TC{x zV7rg#a7F2wY~?h_M_!O&AVzsD_Qnd;yq)ENfh!ou!_(rgY(1)m+-)Oy6vs-X#fTyv zl&T#D^7du};dzBZ)l=^8j@&PjRISjmpr-u*PKe~eMR?W-eg_bDyog*Q#z4HyLQfcu zc0h^nY555pov)ZxfN*D48Ly=qsWv(${9AIsHDW2~PE4IzvCY%`mRxV&#-hlJ zWOeu%04|n}%v#wtt9aA;_2Ttyo$F8b7)U6c;^m!a(lQ+hC$n{m9atpJ`-6C6#BMUa z7rZSS14%o5_5gNl#35@!UD#`EkI+`wl--PawI=-<_^k_%;81=ASjgO9x^C)B%B3&< z`-ym+O_=0 zMk+UvnfdYRotI&tFwEpl+#+|P6q*SRyyHHn_nfr680h>2zuD`A42kv+KqS}mEes@E z`}@+7z$scGTD{30+}Oyv&PgOC3;EYE#D_H_v`FtM7tH(+4F@G40moq@OZPQsENlklf zn9bgT#kagjMy~~GNnDK+jQ0v1bMjcx826$*lyVz90Z_}zRNH&lGA%@Zxv8F^g8Rya zf|9zWe~BD^PdoYMYRuI`+R(io$$6>Gvy4Ym=sX~D9GN5M039JaMC;7Q){s1krBX*Y zuLQpUl5DwB2wPDOHWiLe+*j__a2{%)+OV?V5pU5qD@qW=t}8)vS*RT;p|__KdmZhx znWru%Lao<#Ht3qQ`4hTX1}->hMqvHO3HU`*;DlcLo&(HOq}Le($)Xf2kf9SXw?GRf zH9C*)5vqfjkRFl?_qVMUQn{CSYPbMAJ!hN!P)GQO_GI^sw2tbWL!OvNpy}tT?*yID z^%9K|m3tD&K8CB24iN}m>FT(oFGcd^eIqHcg-Uq=2yHC@32DVZZrxaP-UALpC)>v1 zKL+~l{&UuZOXr0pSq@lkP8i7HDX5Mknob%d7fi_-9wG8G+(XKkw;A?pD zRQkoowCa-V+2n9Woqt{fo{?7@6V{8{#?AHy)bZvQwH;vjglvliYOT6ow9Wm>|hS>E>clDYQvF)a&%au+n0nOX7)fxRq(2IU<%x>TXev(Qc=4hDW2O{yu|M6 z+-Ssj=}D-k_InX8(B~+U{?-);0}dC_%_@Gkzg@~__B5L8FN>ksd+zn?6qk6&OT*kn zdsQmX`Em~0bS413{C9AX{ssQ}LIWk1ERGKTJleGP=@B!}xwu8VXHlC+Eq*b(3>!HC z9&Ap_C4gZ)`S)@Rqy|1v6!E@z9s}tNe|vHaO|`ADdxm~`i4KbxBl1XV0`(_NRd{#B z_W6;NH{oIaZhXKDBmjuhxBQU?D{|X<5!;-(x?^H&m_AyX^lUaYVTJZo1x9K+uQbY| zo)?eWB4f1A)T{WejgYKIl;D+-J+85v1dj88->Q{Q2Yk=YipWp~Q?%=#J{QdrE|x8$ z3Yxp~4xsQgx!3J^Rwrm(=c#4o7Vt)aOHvuX4_+7Kn;ii`N-ildHJjPxGt7%}!6BYbn*T%|}%$ z9>5(YG|h&75yQU^bASfUm_mSVQABLh=rJxOcL8XK5hskgRO$_O%$8jk$QvNs{L{$N z*>ax*)B0;b0LYjfY+YMI-PBF07B6E&`2C8ReI)4Uh0YFu*B*nZ02q$ zb$bEVsuJ&w6{?s#76(!Il|>5c;j}{l0`%SVJVC=jLwe|2u~*1fs0IZ^b4Z>mdTn7D zjg8uzsRwO-bN4>zM{Y1A+la)F?C8Hnz8PSjJS2c0kY%#l-71-bpGa_GAfxK*&+XoF z*U}Y9*08Txu zCeX$AbIvXm!flmh<7xG5Ei&#?hJE2J*wyp>^+(t2PHHYtpJSN>;eQaI$zbc^k?MLliF&HV#>IwG$ zgE$LYuvbC{;BJ3DBPNX4wdJX8#vzt6Gr{Fs;Wk>K);Icw0K7Sw>keZ%FrL7 zt!5GaU=fXTv!QmrBeBjyzh7O?&jlD&3iRJN1_0<8*baUHR_I4jzjaj!(Q>@N55&nM zJ%5F1#J%gq1JXOe9hJ_&!i{=3@+?uGU?B787oXP9tGO142+Y4%&Wrz>r3R>guuK|!_m3b)t<99d2qm7 z0N$qSQZqw{e2sy0brf&AaZJP7A6cT$!`AEaHI;d^mHHdLHq@f{%+-H1hh2jbvZr{d z4SJ~Ik{C!%=LHxiDDm_QXkF3qBUaCE9Hp#tBnBdNUxU<7ZOIDlN12hNb)l(&W@<4n z2waUkbIRX62A$zd%4(cG4Pf(Inl-K6;<682yKev7gCF-y5obe5^~|}=1h4^>q~Vt0 zc>R}`)vXc1&d~iR&DrH0Z&3BEki&(3!f^nt1od@PeT_pzD9hJ954JwphxX*1PSU%`*uLbCbxec^<>i}B zmu871+pIx*2a^;n47*c*jGl6P;wf!+9+Ak;5NHFDLb@BEUAPWAP-Zr8YARl4?c>_s zHkdAvqE3g^){HNw*iB@K2joIQdjVHx!a%}})if1cqw}b&?KO>0lP$;Hu%KOkim>ii>D(&I`v@ui*+1}5ErF$KNzN0dsg7|P#CTQ+uUX^mn z|8lBqbstPxh?80L2%Fjt3HT&EaT5aw7|$Rh8}==hBRP|Nd+7LeGxSRrT=K7(I86N) zJv>q2vMd#JNBi&#D&1}J-9I5P%Z6k8-Q`}!F}hmGgPU6w9mNbQuW8m40X+elo z)_P~3`XPS5=CNM*4-jUB;CX`}Wa!?eaDBFr@1YypY*@9Yc72avUkbX;YaE)EZNNug6fI^u~8j(d`xwZ+VTYXW7y?g%xVE3$a zs*~GM*V=MYWEXgXk;Art|G}? zx`ZbbuQ8A{cJhH~eHw@M{;JAZLm!n!X}i}F!w(YQRI&l~-^JEJ6R!sduoPgTs{~TmWjnxJ136@A% zn)bEW0zRFGI=#&3&;E1 zz*W-V2Ak@_(?X@fXw^k4O^XmyhQ$GRk0#KV8iWX)DH2NkOvjzoh@Sdhuws4@WgLZ` z0QL*}Z>6j{!iJJG+}0*$S{7H#CKOSsw(E?mH@<*~0``?9K}x_L@S6o*0-}VL=4Rye zZEX+v`Qm?|e+`Bex z(F%#s%QF--j^hf>2Vfw*`|(=_mAE_cqBjdQ&OIL38ERa1fqN_jPh&#_-G+YQiOO>8 zyrS&#qPn44GU5Ju!PB-4BfHPo>QJbgKr3HgsbwAw2G?}vhncR<6Q*}_wD{IkPc66l z8}(8^ulUBHjZs%U(|-$;qxx?sKqIfyS@2yTBwkIl64dv%fPfC-^9#_r#%Bs#PQ*?e zspM{6kuf1tueZfZO(jag-{R73LsMTk*|{r!SrFd8j-d-bCfU zTO8DeABTAEIM-Hii;?f|Jgs;=r0-DHJc|kyCaRhc$^XFVWpyk>?Q1%ka`)z!09vpn zq}ReHO`sAvPR!Q$v?xS!z-=`E!J~!Fj5cnEJ-VOmvixCF(-V?4OF7cKtT3urmJ9+A{y=i| z_5JPaxksS244E4+j=#n+91}ziWIYYxEF(t-r=J%(w&D+uyOciCOw@bvw3A9Py--!u zudRnm*Q}olzM+&iJtq(I8ezfhp7TxW0@s~iiK}|pYe3lRTqvdi_%a)3;8EY4jjSD- z^q5Wmv3yZ$ci_-Zn!cZkKL<45_)Twwgv5PG<#v55(6tx{y^4$k53aK5$#B zD(*ySUzTG4NGbG^<|#^j%~btQS^QdIA2cb>h>tfx{Q%$KA5{rO zg%|Ns@&gS(lmlK)T~!0W@RBfK^;Tk>z*WCkjk65;o33x1`cT<7TU?1viDz5(^rF24 zyf*+DQk=d|zEtc$E$_5>Y;}_Fq_+K$&V2P*3$%_6Ixn(~te}ElApNfZ_WGB}RlR5E zeGr>7DD&R@)8Ow1un!N<<9y0kBPiQDMkX<$)SGna_Q-lq_$!Ub0FceJfqkgm2aUgm zPtD82JHT(-Vuu&uHhBr7mVw9jQkJ8%$)}}!$;6J8+4~(Y`QKjsDsgBG zGRSEB!LBkGqRVFOK()=0zRh%Np_I?cTXAMZ=g)ZsBGxj{BdT?eF_4Ix`~z1!%GVV5 z0Zl9P8?~gkPz4x2i?%jrzVzY?a1owJNgoytKFl%+C zBMyS@mr(aKc$bbZ#dOh+#T$yXR6D+^x-UbS5FqTEsIk?AO2Lez1-UeQk>;1AFIwoo z@#@G&p${++eE;*Ze0%+fonA08H8v?OtMhMq`QS9-z5|SK<;yBZ zqw|75q*3IR!lUl0?$cw!3+=cR?N=I2tju@M9&dgb;jH`ZawDa0sY8axN^dtf<&I5J z0ThF-hDBqVQbQXHBM2}1?O-pUTnxmB8$-U!<1$^^Tl(k7HN{(qw(Qs;hVC5PVD-@h z&N9L)c;9H`q4W_edZ+o}MC0g1M`Gla^VqfQvu`~=GlP577c9J;_c%mI1J}_qNx(Ho z_zxAZ%-HncDf0|A?)2m%noTIn3m`lz*t1Cd_l#Go1*ekt6*Nx(v~2VRKF|)rI#UHj z+yQeu+F{%V|Iphc;W77nWD)K+Jnun-?&aWwScwnGB60s zs4|-?ceCYHGBAOG;7M%@kOra%zi)yPmJ9FG(>Xz8G<$lJu3z%K<8(jjuDf)y&~&(; zDr??~#JA>1RA66O>QE`5R5~l~q#{4dJCrMj0yw%}3z380X9-Wqs6A#;{hB4uA5R(1 z`4Brpxo_y_2@N3uy%3=sZdmsvr3eMO^WR*`hAup0xQ_9PcF67u1Gyx%`zi&~+1wzJ zo-7jd9PoUMf_}~2Kpc?Fl4IC-Scvy>=z4a~0eO_IBD z=&SM3P-z+}=%1S*7KEq_H+PSPvudRjzjovq&_~L*@T#w~9UUK$cJ}Yh;r*Ah3{X~cIDYz_`!ATGD>OB4pMte5DCsq!Pgo5BRtVdmokzZ4ecb}Q_+q2Ty zi8j_=obd1Bk+DSrt6E#EfcVF3KY(6ah9DYpRUdYexwe(yTmpJ5XjJV8y_(Hct>4;gZSZ|=gTFJfe1rPvQOfZjTJ5~O#1*k0; zv?AU4!VFJ*(qY_hk%sFKAy%?7T8c_`VWr~t|24h7kQ9mVORPt{j7#h4Yd33Tyy8$l zyU9Ieq;aV3F2^XB+a+5_+flirba^M%#^F31U^J~@*CrF^sIKvTc;DKqc}7k2=*td! z!;CS&6e7Q%e(f%Fe_ez-5Z)8K*QRtlrso7hoA!QHB=L3HkAo(rCL-^43MH|hrh`xh z8r?F`=>q*gHWh=6(GfS}T_oB5MaB0U5*H+$*3Y*=d1OyJM@tHVJcB7TA>ZlKb`Whn zT1S1!oPGpNg+#ydKl9d_6KJQ^0hXyFmA^?yBnLV!{Q=_yhmm$iqOuydWd1ZKT~T zgkNnz;51(?@(nzY3vuuSC=u^gpK`goTZx>oy>AwQzh;JkRKq!T92bq7Yv3+ar&Nf9 z;tEGi%P&>N?wl>=3+pgwyY9!whHIcg&{MK2>>7X9fU`&Y&7atQ%d(;ATd*>DCDqY) zM*29_j>NlbY2DQX)d<|(amcNB=Sc=xaYY45$eL`GKUfDH@fKBkWI%2Qo~nkEii-3n z81+Q;2hyQxS^+c|hsz2*hn>F&G^o5`@R#+qC`vq3PUF139UXRwwd%+SvF5ouREDKT z2k5U^V;LENnc8RnYAv7Pa*25h-NxDC0nZwnqOGnv5CNT3&@VSXX#=^(A`y+5>bd07 zGmzx^W_^}_(mtQxCXMJC6Cmj6q>aS)WJQk-yjNTwDGZzO(L(X6R8hTL5fqz zWT1B(WM>2oMh7o(jxLcv-^6R7tURDIXT7W&)vsmj^ZXB>sWa-TClD50AOYG1w@r$w zD*^%xq!{gao9{V`cI{-d0fJx7(Yk&{F)`}r9(!|B#N=Iyy7k&>ZIwh5;Io*UaETMZ z&k@t`Cvp_2n=JCCYP*|J)S?pJQK*9cK3?R4#927J9=yhn4HP+McRXkFeb~I)d%fun zW^GBimaA&?wD@}I1XvFXttURrt2*UPB_zY7ZQtNFzo7DN+|adu>Q=|>hYl-prm(pm z5l012Su4pc@Hz@VTJc5#iWjSpJYeErOOHL|5GR4jmXR ztbKCX<*3}AZ*zOV+F*~K`Yu~F-stD znCBey2J}f6Olh}SS-}E?p~CkkB@!@N8sfv{S0de@Gp6CxovUjvFC$vw9Ja`=zK5>% zMLE^h;Fk5H+Mfxj^sNtoStP{^?NbUf`;ry+ZxR&%J88Y?yW``|q{R_3kP7=6W)8AQ z*eNku04(@gng=WZ2n}`VR4awp* zqwbWmkQn3a-{eMk=%;BnFjc?2qt((7_$iS6^bd%}YDv&-FaxWjR8*TMZkDIm(X+kk~hyb52#91Vt?QD(dw`3^tfIVFQ@zZ>e7CIuD*u zf${K{fay*!qo7w*-Y+x&_inCrnvQ_%>(u8kTL*(lAoI(i=D^t!&R{UJzQ)eMdwk^U+A&$(5QIIeWIg$^iy&3S4Syy6o-4O6GYAI%L8IU@-t8Dr{Uj zhe65WWmhr@63*=&q3GLxtIQ1O5>UUfI+vt2cp`vYW{zNr(f&L#7A&zV2`Dm?58!m| z4l=P?rTs8d5np21EQUyk2zEKjP|9z7@H(uJnK^(C*iegipEDX@cDk4ar)ro;nqjRY zFAP!^N9(8gs9u8g?k=!&rm*E{?lk_`7Fc67PwS4-Q^W@h zP-s^`M5Uk5jKaukcNE7)KoPe^4WMVP9Ir|~#?Xm45|T^`Y9rGsc6rxnv3ZiaC@8f) z7DubRu(WykDFH9SO*|YiQ7L<9G_*Kp!W7E5Lf}Q3z;5HLYq>c;pnt?Y9|kjebCY?x zB-PaXcB_g<2Hp4lR9V`FdekpNd&aC7Q8?Gv@G-yaD9rWU2D^kkklj#Iry(NJ z8}Xr8u>gL86xc-taaCIOY($C3@z`wpgmZMcXXCnpB_&ap~I>j^XHnnDPmUFFF>Rd>pGrV zA4O_S!%wnNKpelzDNrIm8`0d^O+G$stUgw6Au(&Ps6;W-+WWJ^FX`=;elS!2r^JWGMk$Eb1&ej((%VUx|eaML+wSA!D#0H#5aX+h4T2Bl59T1gb5db2S7-9 zZW$n#+Z4U(QlECWtB4G7cm<*_n3%P!#zjNx!L3oqYF;|}#}_ni!bzVp!^R4W052ee zt75OV4*MFuuJg}Q6(_Jfu@ZR(Bo-fz1RrE{UQ{3{RU~U>tnWW^V)Yiqy(lEyRT=R~ z#z1K3{%CbUmo)#%wrt_8km%@YxUBu?$NH4GQ=9&mkNgc%)=@Ytq3??SQR@85hpH5V z$PA`4(|%ShUJqaFDq z;%nzeFS>SR^@ID|;)={BM^7nWk=$CouDTpbOf`-wA4sU~&JG;;O<3H-MeMO)TUFtT*e8#Z$(npMrd$0l(nvfGAP`Iqoj)_4&+IN2jDT zNYjW|=@#tlmc4(U54;0RtYzqxB9=Q^(KCSf0Hw)7MPtbEHHF}#X^KgwZ=-|KFsZ^= z__nH&eb(-CLTvb|me1po=*eWN(H@qfH&HhDK&scVRmpSoV9QNu!$6_#*mJAzAod+g zuOARC4*_48$7=rx5P2kMmZBbcJfxXdPF9YFc8$h&o)Z!NMu1@N z9g+S6E6vGZ~K#>+KPDM zMO%FbZs+b8Ks`t+yk2+0P*b@s7Q4J-)Y6c+!#h=^j5o3-1+edE5E#H zj$c}RT^9r4q3Z*AsvDm@ld{CbZbw+L78r~iNMS0+O@0NctU^wU{mjB>k7~j3ANLeD zHfHNnZZ~I5y&6Oog+qOV%qdzI8=@p6m3V9SraXdM+C4<&H!>UpAzQutRy+ayZib93 z2fPRH_BD~hh-1)^{Ms)q#Q5TGdO^HkreHSCl!&UnXYjJzT?@fVl z&_VH^W{&^;5!fCCwyI!&|MWyW#C{0&r~FyDd}OIhs_FVQE?U*jtJFU$^I6Z-ZjUdE zl2Y0@t{3mGL7+YDXqHeneRBJr`57t!CdxBZ`;bQFB;xu?W3?!K-43&t{oUtq8< zLoMzmK-M@3C^-M)%L;SydH^R4v2;eoSl z+{u)yw8cw)Q3!k$%@VAc^=R=AmLMrFe2g_p=`@`3Gon%`Mr1LMPV)5C+^q^JRuKsr zcA1Y}b;(?DKRYNA*wVs|(h5FnSv!Tyz5-KUq6ca5ui{^EMeFq22!PAYeAD=I3+JXe z=szotb&H6YADf;}Ko0VVghBQhqabDmau*8=09%M|wJtm)aYBhPmW{+tZyAgOw@Za4;NcV=`1MFbUWn-L`}yYf7m{lIAYn*B8#xPe|r6#{#^?6(`?&V z*(pV+&imFVSOM4M{R%}rDPN?hU+7Mh8U=AAc4l6KU{6fO99c<|t;CynO8@LTIkONi zV5W02d3|N$pAv7#$SBI+ZtR6~YrPa+a^_0^_0W(eBs#BKWt6G^ z>t)uQ(%#Q|2OjjHK{l>9POW}M;@8SH@4u@FSI2!>H!ly&2Lv_AuVxgo2OupNHv1YnV2&l!j;~Wy{YclC|LA%vPA-?S-#L1zK->)UJV&PiUSg z#(q8oF4fz_a>wcHi;}xX&v=N~OcV;AUy-rMO&1+Vs2cO=d~X}G-Z6|=)*7xKJ8=>! zi1KEAW*s*bvm56{Lt20j{mH7C| z%2AoMfoA(Bb@w!(-7!^d*fYh8Yf%algEB5nrYM^P@K&_vGR z4ojt4YtiV#n0aD-L6$5Q8P-?osLr;e9zKfDQx-W}!A4kwQdL0IN;^}g7#E4!sGeII z1%c96eIJ1AvqP4b7%Q{lR6Rex@=hRwahCWIhtn_)lKID$FJ%Gxxmli_`c%`iy68q7 zj>#DD)Q84X`!(uA$DEnuuOe@m@oUw54@i2HT$$&v5oR^hKow_07)`0>^O$M#;dEr1 zkSd+!N>|5{C|bKBFhbzT-iysE#wBK^0#T&(iM%@@-YyO(khr8;_{G6O7Yh^sV3quZDr-9kE15 z;QGeFhsI)4qnd^tWtkhOe7p9#4w#wKW3@7}SBlLO#T8Yi3(n4%+tQ3)ln9`rn$@~? zdN2TlFVCSz`3;G7Oa*tk829v;r!1_?B=K(he8!t@MP);(disV$GB;~ev-=#f*2fAX zjE#)T%*(6}#XixwoJ!LpXAY(n{+is+P1<5&=qsTK3z}!#FCxQ0VWq!m()&Lf6tVa~ zX_b-XCuXpCsCgr(0M@M=Ni_?yioT$t%P?93PF7xjvf9Z0Xz#+{vXLDtNHWB{h9lGoFC_0pBHYcUFuX*CpA(N287D(AcCOzhMcNB%vI)wPOq@T!z9Q;Ihh! ziOI{UY^X4NaucPPL}n@AY^W_Cxdmrj3NzolHT2~feHYMt&+`4G+>dMgXUg=XG>?B~ z{Njq@8CKho?fOG1kclMz*`1N$OOz!S<;yl*96_Wxl&#@r*~)i9Z$S_kw4tn~QWd3t z;&e@3pUFn6(Y}ou&S;A7R(e`sK}tCFO+FUN_)*ySgyG?DH_N5z?of_6MmkwT5^At> zX*iTpFqi>2;q3Z7!Y)pdP~L4j)c<*?lfgWL|ALwH+cm!Y?a`7mqq>WDk$Ckz^$8)hM|>|^zePuNJP!++b!3fc!of@{wHFY;sG{!A^)pf6+1932jcz?<6;s;tc&6f@`ujmYkJK6nJvdmn zB3(m%#{5``*fH;6_Dr+djF4YWvxHe&q+hxD#LRYGS|w6`$*-M>R4LN~a!!C}V~p-C zJj7CLYfQ_&40>bV+D{*M{y?(UM(rt-gd{PNZ4Eg`;-09xFwb)HPIXDh< z!#Ed?Gqx`urIx3bG2$7(!!s<^^v$E5w!q{Mcz5LXQeAVs^k+cM7p|s6j;P07=l5rE z6M2-y7&thIxK|U|?M+$TByh_*%%2PsMwX;hZYxQ0t61@5 zN>Ia@^3$-lB7CAUAGh0YYVIiis^(S*z8lX}iXf^{WCi7q2&*7*)hY$ZFdst9<1z-mt7-#!gFXX+`t~}O@6p^Emqf*qkZ=v}?ZRHrsn$aso^93k&{oO}^ zbdy`y=)pBug&Wh*wAhS@TVB{Yj%H`?=k)6KW5ib3{R=-JkRWj3a{wK|ux$ew-q&1?U92vn*T;8$32nz-^57*q z6Q6};d~GiDD~-zBg=Ry3y!K&Uo=;on%rvSFw!mQ)EKCcd$F8m)VRo?So`%aGONl7` zM#hm9Bep1s-sPOAbVx6g7d{A*VgR|0IgcRw$$Ea_;bF}Xj*4?zFHbapchW?0nnvWB zB*atfEMCiyzg*=N(tmi_bLE>=8BUqPyg~WrJ~MNzt=+CABgMcZ?{_S9Rxp(E`({Ks zMopY96Q|erWNORB?vbV~dHICqYlGL`VY&*H0nEPc95a)JCzdTl1;3o&xya9Vg(K+e zC(k)XJiHXD7B<2wf0j%G;Wg6->KRLY{6y zRIAI-}oe_BoVY+?Sl)uilpZxZnL7K>rZ=@St`)?kkz@ zYn8r^uEybnk_Y5|tcu%m3Y`y9*Bds;%$xeslXSc+)eQ)KFNg|Dnz0W1_oQESw>^)S zxVP~uYulQi3>#S4+(swn%>D?y+uleio8aZc68z>%eV(!l7s>5EQp~?n@71v0oh;Sf zNV5oMIX?>}=WssyO%2coJer*T^wBKuuH#OS0}qb?iSzc4P?pm_g71;eFN{mQSr>fl zYBujkpT@u9I11v-4Og=PJDZMpQU%s-rC^r}rnr<+Y#bztc@ftMq7$^R>KK9WA(#V%1Y_`JxjKBMGWx!lp@j}*0i7LV?UxDv%?sKE zW*c?0<%7@4^!MhiWJkc>g_`+$f@MxkGCD1F!*v{lOu%SG(^hRw6$o8SL?CoQaBqO? z@2H^V{0m*07Ue%(Gv0y7b?_IsZd~h!KT)*L#`Gk5@P+*oel!tU(KU}2Bp#mO^Xk#0 z{PMYjvVrs1sYyyFz6mLo45y5b4C9G7)9@0HFC>e6#dSx}2S4~t_K5!iKQQuL>a&oV zBv3ADF!}&{-5RF!=Hf@s1l4g{#)rI$J|SE6)~@B58@@s+A!RFHPr0`nV{)`~y``MaDyJNOX` zt-+&IWvyM|t5zL-=AD&AV~qD6Z}+`aQLS5hqA0bm_~xhO%k`5~Iy=A-cl8XC<=k}! z3#}Pd@2m*4n&N!iJ|h-LEBA7Lnes<1VME7D3}or0-NJMf>L?IS@mbjKiG;6n-&p@R zeQYPI0;moW%pV5Bp4!E8XJ-bDhW{zc!uekTM+&(0z%^hP-aawu?CA9x3TF1kke7#& z!pgm?N0^{(JnBG&Zz!qQ#oPRye+;ZkPRLq^7p7O|+0~UqX3W2YE(ZQGz`2vzF&xvK zKES=_k8A}{+sFkj{xJf9gXH8`PR4aJC;8bqwmnby?LNa!(>Y;AHo;w`QK!ygMH~3R zS*7<<0A?9=9w+Z?cpsih4UBwdkB?*)@ah5tt9AbXrYg~N%F=@kc_(+Ke+vcS?71+o zmu%gcUk@Ol-*;v?K0T3E4dv9iZP&R)!B*WvNq$Ggq{3g(@J3WZc7DkE~oB$W&-N4@)b9)jOg^5*kz{@ftuYI z156a*P~bY9ll8qZ6oXiMe*`w85gW4+_<1uio}U?`7uQ zRfn@~op`rCTp6#}6Q{uZ#erN3u1)j;3e#wm609qY!21 zy6Eo>h2Z%RYz#7r#mfr@#~dax^z4AinDq>cPi2dPDf<|Tp^Y9!f8kR6W>Bm>i6Zjq z3KZ+7*;HA0K(XKbf@^28bmgcVS%I8B#6^-uf#MQ zvCHuCGIW^u$EUC@e=TLU#9*!8+5f}9w(+`*W5&H8ZhR5skg+dIn1Ir9hZ30 zEsdq(I-X*yex`PMcy_R#-MQxeZ^}Zf9szA00T#ye}X(f3p@V+as4Od@C$KyfM%Z1W84E-+HUS*FVy{FpcB_M`_cOGMWW2YdZ)Hf zWwhPo_c1THhLy1}w~K*gJi}ZU2Qq-H)_9t|!BL0qIx{F3;u%WjVSXos%%iew@K4ep zpD|cLUA_esjiIT0!*}97T+D>i>KS{5uL%C8USzo|j$>^xgr_r7U3Q8JAxb`>tGTID z-Xhfje@ptBoyOYRLKyQC`KI3=7N}lflB4>R6)Ay~-L7J>@c?t?8VZ^{MJ*Y#>Ii8x z6@w>k+H$i@DSnu+5iXv0RRC%5E5_( zVRED(CU9o$>ML?^7WkU&9c%~!#8*Ela}j2a2xSOi1ip&?W+5hJnw{Sb%1NvkqE$_#3UGNKNd;3w-7Tj=)x3EsBXBO?6-ygt0jPk5 zOTxF|meW{@c#BX{%4@`EowxwIIR4O4sIa=Y0VqTpO7T!29q3!=?96Je+#J0Ke_joW z_&BMZajOm(OZ+8FTa{VC;f-^V1#jYj0OD&F?GE5n)!6?4jzf8yt#&WULIzd^UK~Op zlAt>r{{TobcE3>}svc=%#ck+pA>rv}0Fj8F($#DxOrtA3azaR4#YUAu@0NYIWRNsrs1 zP(35Typ_OneMVO8fuWhUoAC7p3xgC(b1@Xc!mk)NkGnpg4Fw;(e}WZp{s^?6iS&jc z2yC+ZAfO#_>}GxF0~)j#9MQwu=2#gOt2X8iOY?Zjy+~?M!g6&D!Fz6@!{#%q!%}U@ zIeM`CqFf?ny3O8QR_N7z!eCTw56=T^z#G*MZ!rplUj^6AGpm@%Hm!pzaZfoMPh#`(0{-j~pQkFo;2y($%+@=jfI43Mt+>h9%f5>W4&fWBu1nJhp+fwW0M_}~8DlM1k(Fhi4yH?))PXHZ<@lO&E9YY9B zG$*N!kq7vXP&A7cg!d5H;Qr=kMOZhq*U8y_Dvq+KjEs6gQ~)VZ%(y~~FQ~ZKLa0t) z5YHL#$~LDcUS6dbh9tZluzO{eAGB?hR>rDELd^1j9=h#Hwfw{fllX`=gxj_JOh(CK O;PpTM*#H0l0002=^aOzb delta 5541 zcmV;W6+?0Rj+Wd30q=Wo~D5Xd*f` zGBPx?B?J-y5;Ze8GkskwB57@5XJvCDI$L{_S_L5jaBh=+1xT~g1*-uFP#6FJLP<^l zlfVZnle-5HlfMTDv&#ns1AmE7PDc$28VUda01Zh#by4mp1%-PP57&#%rozjNx;z3AAnW6&c}P9Lk&kdI;?0UrUC00X8H000pKLLduB z!eA7@C{Uxo>;_0O;Y1^K7^sMWFd(cQ0DlV{06YY_RVZ|!V>MD?wT2O3#4rMM;eC3A z14RG;lmRgCQ04)sxi}dEpo~$5C=)u_#B1%et5u7Wz$h>jO@H=*qJf5D1R8}smC`Tg zsYe5q0=vx5=pywKN*H7T2Be7n<9!ApDr}-P0T3~`Rdl!-AFIZvT#QjBvz|L^XPq0l)xiRrKR|d0!b3fFaa67ta7x3Vo8r5e~&BGjufoAYwRCi?^P^ zRX#=-pw{;Rz<&TR0=tazI-zWVGW3MYT+d%Jf5{(9w!>9VEw2HP*HO zaI3JUNG@>^0YQ`tW#F)g)3a2INZSGc0)n+g;)!aeMTf%)&?$)+W!YhBrp6-7StAI5 zh@rrVH=h>V3dOOa`zuXB67iI4Xg8atQ50hUPzLKyOMgcysStyzzk;(e$VrfH%e$U|`J z03af^{Fv<3D1xh37-JtD5yRO%3K0MS!KxEdwSR}eRWBZetUNA-%uPc903+B^ES+#N zjN0`N2*H_Jvhj>LG;IV800KBtjrNvNpGuyb*YWt`qwG< z$GgjPF>FHF%T{i5NDW7GhZY0Ctnur1k+|aHeHmu0t2cDqyssCkSyeQ)AOO1NwF}r`u#*jKJyDzJEF;>j{95z@duRu5>1vMVryj#m?xTK=eQW zBPgh%b%B*A{0|Z_Y&s(=Fd>DWf z0Lejsuuee^0TkD0g)T8%00aa(OJkV%TvCTi@!tyV@@a~G9dQDJo#(LVuSSIZ=6}71 ztJ*@QT2)6he-Nxc>=bk@Z=I+n=M+O&0Bk;ur8aSltWKr*`zm=$txnr^qE_GXqJ&{% zp`X;4r(KVR&ecKNDEnXpTaVZLSmbJ&=4tf(?dKv<+^zINorXgJKtOPyT2N`*+3gZB zTDH4<(T;NsUjOx+=eZ4MN@~@%BEEv9`9|NEu)Ro#PF5lb~p< zq(&)oYjPxW9F4*g0~m&;iF~s>=~#_GXdB#eslTG4Dj!@V7jlF%OpM^DQ|NA|LAW4{ z;Aj=JZ+PhiK!FoAr_5#nD6GXT<`Y!H6pi^bst~3U);8h}VeHa%{aQh2Gk+(a#3s|0 z<4){WX+#Mq0}v1xMcg^T&?n8DW|Pbkb}O``Mm<TZ)}3Af;?d?}SlVaes006;-8lJ1B~9>XfT-Q)v?bC=^OvBtqL>gtDvz!yN+> zGvf_>%9w1C<_&X9$o8$=TTxV{M0r3`2^*RjcYFVYID^pi6^WuC2$WL)0C+SMp-w{v zFf=o6_R!?OKXOfi;puT5m+mb4x!4`e5d3bqV^AjxFBD_kBmlT^0Dq|PvPhiarwnHF zO9)E)m*k$@&0L&_-8=^f|D)@MZoh+>~0_3)fVy$m3>b{M0Fq-vDS z8l21zW|xb_V(|}vkAFb9-W{LuCgI-U4qc{t^!^y08$b< z|8~MN{kr5ylH~Dtu2`TAs-e5i3qPFI=Y%O^FeuY9X9#bZ94h+pFKeHys3{SJ3ywu2 zO1w4Yv0L8D?lh3|!H;&8?L6fYTO&JA2)lnoO8;~-XUvy7K3KW+4MK^41pr`-5vpCA z-hckY*L`(_=YN8nUfu5AV>bzW?Vmb-c;~aM?dzY;c+bH}KbbHD3uBJ;^oF zYFF9+e0)2`P3MhfgYD%{W)Z?`@OyA%iqhhlf!!$FHGeRXGhpAzZJ&Mjra>|_O~;wq zpc>K80#rRt94Um|Jt!&O%ya#(u9&N8Ufv|C_sK;!Xr$SVs(7>b=;*YT)ILV=^!SdP z0hP6-e_na7C^T!D9@T|7EC?Y`!tMZK3`Tdg4$9zVhKtufck29M{?RIgaCyzyRo}hE z8PhYx)PFzSOj;y0Ae8-fP?Fs!@K)8QbNPFSUZs}jf&hSoeZwxB5#Kd1iEE_a|6|W5 z7zu&Qws!mb|J=KhGhlA6BP+qs0sxHbW*?HtWBu=~dAzv1z)$W*{JEeoeX4-ag7N8m zBYkbfTtNslnGywQ*_M}T>v+vcbB8%-BvS*%Ab-Uw-P$*SGiK-EjoS~dLkRl?z)vDZ zXjn!%b5NqykCEOJ?4eFY^Zw_e>nSD8=S1QYW6~mrfI&h}k4@u{!*i8IZ>@f?IYMzI z0E!IZp^eo5Tk^DKY?qcRYiYZb#EX>+U!@zmX9_)@A6c0 z#{6zrvW}TC1Bf?^)BEs>xcg3gxBbvM0e=U2)J_y7{Vl+w(m6wuWo`@gtDoKzvXNe1 zU3qfRL{4VV!6ZI8HchX1Y?AOZ6L_q@xct~_EAI{Jx+KBSfT!XH7H7aTSR=iuXMC?z zu91H6SZP&J_!>b7xxLP%8~?x=lNoQw>uS@&4hAY=cMnc7aT`P4%zrR=S7Gtvf`5#d z1!bgmlfXC9{U?9e5sZ=gm2dWZy5;Bp;|#dHe?r%=gTb^u@qN>H1)ogwSh&M4>u*A1vX$q80KjfQ0e_mWO4wb4lFVEqeS7soC<47z8dabE>tvNE%?+>` zgeS*_SSB*dcmdb-pD8PN=ktd{xNRH*W;G@GaY0GuKmnN6JAOdAA0s_maUv3#5du`_ zty!}ESt^5a2gzqUKiSnwgZmRV>Iks=oH9tW$=B!DIb*gTTzjx^ zd&nV;FfGOA4*<&8wFx4ZjDNE^Lz4Nr{nLthMmY{5FO-tsFS(hsn{Scve~s%H2rIQ3 z{J8$(CHoeB@pw2koe-C5l9rp(mI1zxwIiGUpj+DbY0LtVs9-|Nde{bpx74u1Ld&&xSuCUx(S+c~Z|Udk9eG%B@AB5zaSg}>ifQBx9TWg{nT z7@__E005KJ#BmPFpu5BPICl&1_}P8$eEtY(@!JU*Wb?8uFY}Y_*+Y|irJ5T1qWX-t zZ$}=h*|vZ6(c(Sf6o0Y+Koq1zODERouG&o>(!;jYEyvxv&$tO;6d<#MJR#dYGRw;U zjz`}cQ(0RItt1ws?d=D*Hn$sIFF&7gZ#n8LDDwgUMrcrmWm5MJnen{tih|-j&wV&u z7Q;=gjgsZ5smlc{1q6WIZcj=|0)T1{iIcGy0Fik9<2#QQ?|%-t+N_K8?K0}A+ZP9t z>sEV6yxIRxrIbAOzvHTE!)*eijAo|~o;B)a%7}j#1OQH_v;L0`CLs{*Z{3%F?ChS_ z)jk01IreS-wuJ$N4G2X00Pu$oZ>bE^_17~6qKxT1vq`pwn^_~w>-7dWdqMG@_trcC zQE;3~z~buf-+w7AJ*dlU>vt_JD*IKJT+(hy>XJB+HT75p+#I!VyWIih?warQRrm2d zZ%YbB!gC)^uk+T1InUnX-!9$o-+C3YdUP7zT;-}+cwH`+Utj7`T#x@{9DkRp6$GIL zOKuKlf|I3(-u&!AlR=+cl2EO8MqYE-VzU4!io*9oC4ZHL&n%f*Q&)ka>^7DNP({tz z``;dRE~H(cpN?!^uw+W(Xc;>HkxkjDxy_nvvu|KrR#w*By9WxlKmEat<<7GZm4Xm< zd8!|NH*fdREdd@os1KDNZu;ZvtL96BZf(De(aD4EYkW5E-}wRO!>XzhLImLo!f@pD zzy7xQg@3|xhgve-4KYEJOmE~r(AkkQd*bu_W_JMidiV0RI~G;emPn$WeRf9K(j)CU zjy;K7^jLLub)3yq=dCSs7N0CVu=SVxg0p*!k~#Xde=#QG(`5wDQ&sLPK2W%Q%g@Ve>MCW?sDCe$ri^xW^fJkDoQ6?9cg_{D{KwBG zshWxaq1b;$3}cJ|yKwL8`p2Xrgd#?u70vVfo$DpU%c8Nr2(C`(GY6rzp#6G!jS?udQ+>XxUnc2QAXy>@XMzBr+Knqnla*OPH$|x zG=J&+$Ml(z6qo5gN(C?%>5(=nJ}$Lgt$~Z#U>)0IPUGr-C;-&E&O1ge;Ix6X%N6vU zD5HDbA>x3Ni9jn&ojUXy*<*UUas!c^^g-9<%w&N*(KJv1DAUIFoP`i;*RP-Dulc47 zd{_(ETLe*SHOsd9C%xPDZe*!%?43URk$+_CH9@3`L6tQeab5anjirpX>$*wFNX!|0 z&CP+t-cSIjm)nLdNbS(MUDu7pBwPMt%qzieOa%=9A==$}FNS~GqV377(J#qD&>K^s z?6=uW$q!6?mqEKD`Zw>KG3u#~@i`%UHWUCDV+odw$pi0GR8PD1RifneytPlq@qa9& z&=~TLGaK1$#*`uVwFA&UYs}O^PlUXK7W$UIMwOA-cZ}%qo2xcMrj%qly5E+&z^B%Q zJV{tR7mTr+`aL|P+a&Gk!+=tfmD*?i_;(Ss(i62WdO+Wdq0f%$b<5QTKvr7s`QsO= znlH?Gbm%%#iTB3758NM-$$zTm>)mbfP&M5;P3CHhWEgeVr}fvW0?H?0D(mscmh;9Z^QJQh)l)%6m~j z`roH9A^_A&X>Gy#n;r!g+wBx8@y)#MncnH+BIVU02LM92PH}GDw|G~PDiq9(XmDiqH{nP8kWk)4ZZWS0*q9ofpP96M6MnW%HG=H~B?$SB{TxJc% zlIkP-Pi-qG-F2dLpD0L?c1?t8D)D6`fBzC zzx(*tKGp40J&e`gNFV9oV;CTWB+(#?rU6~X4$r=|gE3VlN(;o;m;vCDYpOr{=kit+ zRs3?Y?3Y8Qc6fX)jDJOpFh)3#)S3aKlu$+~C88i@rw`0YAKoQtfZ1R(%XWltRFz4h z3xEc!Nx-5YNVVRwQs;?k_xY;YQm3cfqtvLHmoSY`O(P0rR1_qP1W7O$M6)cKECzeB zJtM)ImSoN7U`k_*YDA+z@FED_#u%0000NuUk%56hVI!w7KMRn-002Pz1MmO< delta 18 ZcmZ1=H%E>$(>NuUk%56hW+SICKL9O21Lyz% diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedWithBatchTable/instancedWithBatchTable.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedWithBatchTable/instancedWithBatchTable.i3dm index b0f0bef88d10d9b810de4d93c07b5a33c8ca5b53..82f7fc972b123deba0ac362dbc7842554e33509f 100644 GIT binary patch delta 23 dcmX>idqS2o(>NuUk%58X#755Dd@Mi)0{~Lg1&sgz delta 18 ZcmX>hdqkEq(>NuUk%58X$VSfHd;m8G1%&_r diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedWithBatchTableBinary/instancedWithBatchTableBinary.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedWithBatchTableBinary/instancedWithBatchTableBinary.i3dm index 10183f57b9caf33939287b9ba3ed6bec14670c4c..0eb97c4ea1d91f5c6a93a6a61e6cfc478e6c32b5 100644 GIT binary patch delta 23 dcmbOuw?K|F(>NuUk%56hVI!w7KMRn-002Pz1MmO< delta 18 ZcmZ1=H%E>$(>NuUk%56hW+SICKL9O21Lyz% diff --git a/Specs/Data/Cesium3DTiles/Instanced/InstancedWithoutBatchTable/instancedWithoutBatchTable.i3dm b/Specs/Data/Cesium3DTiles/Instanced/InstancedWithoutBatchTable/instancedWithoutBatchTable.i3dm index fc9543d39752caddbbac973414be0c80cd22122b..4ae31f88e9b5b3e312e49c7a1f7581e3a9fc98b5 100644 GIT binary patch delta 23 dcmaDO^Ff9)(>NuUk%57sU?XQT9}AGd002|61uFmm delta 18 Zcmew$^G1d<(>NuUk%56BXCr4a9{@Se1tS0e diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/AllMetadataTypes/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ContentMetadata/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/ExternalSchema/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/GroupMetadata/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TileMetadata/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ll.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/lr.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ul.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ul.b3dm index b7a4c162220cd75ae50d09bca77d7f6b06cbd390..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 38 ucmccOeZZSD$v7pKk%58Xz(&sJOsqGQ7#P-U{>s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ur.b3dm b/Specs/Data/Cesium3DTiles/Metadata/TilesetMetadata/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudBatched/pointCloudBatched.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudBatched/pointCloudBatched.pnts index 9f37709b1616e6f9d81f917aa954788109f150a9..650fe08aee46c315341b785eda329e1fe8a5df8a 100644 GIT binary patch delta 1084 zcmW-gJ8o1_42J#qZLcCyG&L(=D+q}IDG(wcB@K$AOG}xaf|5Qh4P6#P!4mj9S9dgL z<{aDq>->23pU-~r<>v0z&Fu2M*-Crfhjh7ctLTVR#o!;{Q| z$^z3^AfO}7q>ryX1u@W!9fK$y$gu*H90YQIeR3#fD1)ba!8c841$Ou|b3uaz zUq-bWfNiJPTA0n)+=*bvJ9%1_qfF28I_vdPO1w!v`SU0L0Z3r)M+jOq8u;tliAccrdn} z9R!#`fLInQ2rz;Gu`E0$*W<95Sfdf@@K}P!j(V#31dk*d? zVgmstCZ>8OCK!_tivfj$Gn93cHbkAZ;$NP|GNQhUwKpa1}iKNczg delta 48 wcmZ1wKP6taAg`pDk%56>iarCw3?ThL4@f{k^+d}`MxBYW(u}nmw?EVa0310B=l}o! diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudDraco/pointCloudDraco.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudDraco/pointCloudDraco.pnts index 8de2b0de2f61577ae926718024887cd72d1982cf..d12ab7de59e0e46e5b2acc7405713e940be86670 100644 GIT binary patch delta 29 kcmcap^Pq;eAg`pDk%56B!H$8!WFxOVBcsA*Pex%|0FW^U#sB~S delta 27 icmaD*bEk&4Ag`pDk%56B#*Tr(U?Zg)Rd_&qm(qjLZrO3Y!-*GU@;Tm-PsA delta 26 icmZ1xy(F5qAg`pDk%56>i7o>}$41`ijEh$=>Hq+8p9lQ_ diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudDracoPartial/pointCloudDracoPartial.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudDracoPartial/pointCloudDracoPartial.pnts index 5a679c57d9764c13762a4ef305717dc387cd56eb..237b7d7c2084f6dbe38c40f6569d3ed461fd43b9 100644 GIT binary patch delta 29 lcmca|lJUYxM&5$Fl43>%28IhM3=Aq8d5sx2yD&~j1^}Fj2|)k= delta 32 ocmca`lJUw(M&5$Fl43>%28Jss3=A3@d5syF6cjewF-}Sb0JM||hX4Qo diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudNoColor/pointCloudNoColor.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudNoColor/pointCloudNoColor.pnts index 53a38bcc62913c6163822b7afe03130afb0e904f..ba2744077711da63c86b295a591e9ad7b437fe91 100644 GIT binary patch delta 84 zcmewo*AQ=6kXKU7$iTqRpwGZi1Ee45F)(ldX%MJZ3h)p14Ds~$Q?ja7N~$bL^-oJH dPAyTgGN{#=C>zCEs{jNWr##T(s0K3?6ab3>73u&0 delta 48 vcmZpO{}Lx#kXKU7$iTo*qR+rk0i+-30SPFmo@g1xs54Pknz44{j0buE9XSiA diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudNormals/pointCloudNormals.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudNormals/pointCloudNormals.pnts index af2e25ae9c71e37ef446fe86d24044ef79b8d532..82e39bd1acd8e687b83fb120467f917e757d85be 100644 GIT binary patch delta 59 zcmX?eh4I1_M%jYAl43>%28Mtv28Jy_x+0T-fdfc`K=s6m5JsJevQdn+8!uL8a#YtU GfB^vFRu3`& delta 54 zcmca`h4IW4M%jYAl43>%1_qxj28JC#x*`)uKtc7yq9{h4iLxQAwF*G6@oaS_0F99i Afng7j&TwL2-~iGfP(86Cno(z>Y!qv)0uXGxlHtTr J4Q47R007#i4s-wj delta 50 xcmX@n#<-`AQMMqjq?nO`fx*U^fnf)b&Ts+}P*6RwGKx`WqHHu{?Zz7!P5>|)3>^Rf diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudQuantized/pointCloudQuantized.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudQuantized/pointCloudQuantized.pnts index a0494c1b9717eb744ca083b5416a24dc0e7a6eef..32807dfae165269f36e64b51543c33adc7f3ac56 100644 GIT binary patch delta 61 zcmbQ@vA{#NAg`pDk%56hL4|?g3Xs-NW?;K1*!WUgnWGxa HR8Rl_l6DOj delta 48 vcmZ4BF~vi+Ag`pDk%56hM1_Ij0+7~F1`<$EJu$YMQD>s8J!9?0x7x}8_5})a diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudQuantizedOctEncoded/pointCloudQuantizedOctEncoded.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudQuantizedOctEncoded/pointCloudQuantizedOctEncoded.pnts index 01566ef5c56585914363a04cf92d9187151aa38c..ee9427a4624867a04e2b60997c012ad5dcf38ef0 100644 GIT binary patch delta 58 zcmeB)m=GabkXKU7$iToLpu@oM1xWwUVqo9^(jZVhab+^2&P3U6#@fw-jK8%ws%sU% F005UQ4X^+J delta 53 zcmbOb(GwwCkXKU7$iTqBqr<@P14#eS0uoSAJ+ZNyQD>rTGHa~@5NzgU{H+B5N|p>j diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGB/pointCloudRGB.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGB/pointCloudRGB.pnts index 455d3b84065b30703e32280b73a8d550ae13c4cd..dc9f6347680bd738cb6d44f3bdd52eca2da92a04 100644 GIT binary patch delta 57 zcmX?8cA-qRAg`pDk%56Bz?y+!3Xq;*#lXM;q(Pv1Vucx_&P3TL#@daWXIgPo*D8Pk E0HI+G$p8QV delta 52 ycmcamcBV|WAg`pDk%581$C`m*29Ta%1tg%LdSXZvqs~NGGuB!KAlSHmrWF8E`3zkE diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGB565/pointCloudRGB565.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGB565/pointCloudRGB565.pnts index 64e59eed46c26fe5a23d11ad674ea3f1545114d0..74cd18d946912b187617538df79fcec948f30984 100644 GIT binary patch delta 61 zcmaEo_aRTVAg`pDk%57sz?^|$4v^kp#=yV;K1*tltv8Ammk Hsh|J= diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGBA/pointCloudRGBA.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudRGBA/pointCloudRGBA.pnts index ac30c6af8c757e019b8014a4b1d51658a4aabb00..1d19bd6a5fcfe4a5bdda234bd1c909b2bff84739 100644 GIT binary patch delta 57 zcmdl|x1&zBAg`pDk%581!k&R)3XpEFV_@I_(jZVhvBI2DXQFHrW9`N*4R##WwF+PW E0FyrrZU6uP delta 52 ycmdl{x1~s8Icu!~5NzDgU;M1& delta 29 kcmZ3`#5kvkk+&ePq?nO`fkDQRfq`QquQ=mo4aOh#0Cj8!WB>pF diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudTimeDynamicDraco/4.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudTimeDynamicDraco/4.pnts index c2f3f4e8eca2e7791220ed99a128ed7d57abdc92..a3fb6083f64873247fb95083a887d6051affd333 100644 GIT binary patch delta 33 ncmZ3|#JHk~k+&ePq?nO`fkDHOfq`cuuQ(%%0uU@#VRQfhjrj)s delta 28 jcmZ3{#JHr1k+&ePq?nO`fkDNQfq`QquQ=mk4Mqn5Zy*MB diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudTimeDynamicWithTransform/0.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudTimeDynamicWithTransform/0.pnts index 9750c4bdb33daaa9debf874188d6b4a44d1c362a..fa6a6b1ec536a64f528f9c5b3298c72236db62ea 100644 GIT binary patch delta 29 kcmdne!nC7>iMJrHq?nO`fx)7QfgxlfZ#<*I#>~@=0E90H-T(jq delta 27 icmdnd!nCD@iMJrHq?nO`fx)DSfgxZbZ~VrB6O90NrUiMJrHq?nO`fx)7QfgxlfZ#<*I#>~@=0E90H-T(jq delta 27 icmdnd!nCD@iMJrHq?nO`fx)DSfgxZbZ~VrB6O90NrUiMJrHq?nO`fx)7QfgxlfZ#<*I#>~@=0E90H-T(jq delta 27 icmdnd!nCD@iMJrHq?nO`fx)DSfgxZbZ~VrB6O90NrUiMJrHq?nO`fx)7QfgxlfZ#<*I#>~@=0E90H-T(jq delta 27 icmdnd!nCD@iMJrHq?nO`fx)DSfgxZbZ~VrB6O90NrUiMJrHq?nO`fx)7QfgxlfZ#<*I#>~@=0E90H-T(jq delta 27 icmdnd!nCD@iMJrHq?nO`fx)DSfgxZbZ~VrB6O90NrU7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithPerPointProperties/pointCloudWithPerPointProperties.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithPerPointProperties/pointCloudWithPerPointProperties.pnts index 3b30ca4525034ecdf9eed38bf65daf9ff942641d..710ae22f397580e5204dc5a45d33242ed56dcaec 100644 GIT binary patch delta 4107 zcmX|^c~lMB`^Jx=QZ&fiL_(#~oX*+rvxOoX-Xn>$m@T|9RHC)_y+EyNA3GslpH`4KGih?E?e?!L%TOU}=Ai z6$%86{dJL@K(Hsu)N-tW_M(OM4oe+f=i55WUOGoxXku(^yl-6py1Z$RNc=}qG*q*$ zAzLc}A*)QGU{FavB*HBk=kc_XTHtkd7X!8$iHt8ef zdBM0LxrJV-I-D9%f@SXe(Dl5Jwv}6v!&p5GHEd_EA0DKqGG>sQ9f{=BWT=S4krgUJ z?T|K#^va~Ld1ko7b?E0cB{IKzlg#g_!Cw4yD(c%+pl{epn`cSGE@aq$Ru@(7MqJn` zeAbe~ZJSG!v}zE-uWm)bmsH#=%0z&XKeVGIB>GJYCa#)zW&1DLE7XxxyF9LDnPHj? zu)3IZ|Eh!-fjh`g%Y6z>41dCf*KP>lH5uawz4^t znOycF^CvP$*s>a<9HKDWEDG+<3qh?Zbhkv2w(E&VVz7y+*i0rAex~fmr6{jC0=f1R zm=mx8Iz{)%;pP;YrV~l0mrBv~^~p@O`Xude9fGM-=OgmrI;;${K!zkkOgD1Bv+y8m zDw)v7?Do_OLlSPVz>D)J#WRQ2%hr*1&=vYwrbvN3-$i3uGTD?KAzK{m%_QHW+4I5K zY((cEw*Sw2BK2lRk!OrQ`%!v`ou71!T>2KWx$UDM(qojuQ2kQQPP)`m$UdOMhxY5HtY)dSubX6^WF4dX2Wfiz5r+ciL># zObc^P&@h)UT3_*wCaD_Z@01zXm_H0J?uU|xVI5P+-%H1Jj!??Eb2P?NfcG9keAZYD z3mt8IwcS8B5A0^%CTm&E9BEOBShtF8pHV|5aa+-5dKoLKi}7T|K}2O_)A8#v^kIQ7 zZ7Z;$LQ^H7ugWky(YbFB z1Z|)x;l_~HOQ)~)a-uJ_15s6X8cMMrv0P4?*Lyre+U_+tJ)Tip^DC0}TSxAjUb3gw zGij!@5ys>ng-%}zF5MBMcU33(c-65kwv38f&(R508B~q!p@|2VP-VP@nAR9QAKmIu>irWY>HbzRYl9n$cw}uJMuR>SGDrziW%0 z=p8WIE4G20zdA{DDri)57&*-?AcLS{nm*aq`rA`8sCwkVGx^$hIy4Fp>$gnvY(wNg$Z zI#M;b^Ko15eryWA`SU!|#SVTfHs?8#{9^D=3($XZ3$mgUfz=v(#%|mGZBOOO+e-0d zqza|Xcm_(}4=a;#SbCyEcz$3o?s!RagZv4+s#}@MO-qIRpyl+YAsK4^GZA-H1tWg= z(R+t3>U@?8yU)+C{A&?DyDo%E;~LVhcY?UL)&{zR_G0F<0Q7YYLz_kh3t6IwhO&`3 zwJ?`jHpbGCT)@2MBpU9%L5xJ2OI>I|&I@nh|n3taYh69V!<^p!xqguYS&1kxx--9t`h2ztal&8N9=3BG=O!#fN(i z4==&tD0NJavSY=EYbkT82$pWMa7Ozh^X!qva$_+OwvNTnS#GR!wF4#O zUS!#yzS7<1f#h6fiBaK)Q6!8)Vb(0{+v!6p-vtzXEsyoY9iuyQ6DZ}zGPw5^!N0K{ zOB{=_Kz0tg?#*Ih-C5L9-oSzlWTE)%9M1H2e~zJIoR0R9S)Z10@w9T)BtF$joyWf)&&xA){>wvQaxjuFD~g$V ztSNRFPls7&I5qC+!^4IrII^)CF-MzFv-uj*51OM~=>dDSQ5Sc6mSWdXT`U-yh={@4 z5Mva9YUK+kv5&!~S7RV~aGXhPRz+XQVgwkhg}p0bR`@b(7@rRN_^0qxseq|Z07Sos z(ctnta#j#qFYZ&BoEQo}bJ6u82RfttuyJDz6^Ok>RS}^yGjBMK z$Gs7`G<>Ji=^pU2h=5U(2L#Fk(fLr09AYQX{w=4;b;55V=P84*BP|-|msQ}(+Z)){ z8G>am8>sf}JE7~NKx!Ed>e%prwq|!n^2O> z)}!P@IoPMz48N^f+$k3PTCpKdifTsCQES}sX%bq$-%6=>wAh-fFVGy&4b9APyxUd8 z>yq_(mCI`s4lskqjD1YGJ)Pe54WxCMk1^c28sf67KAaJZ;MQGoTs$Wa6E^nJ+aX)& zOtC69rKQ+v^YW0%@akP#wa^fOIswe zxUFdqwJ19{#Jr(d9S2yFwF+`Vw?in1hMw9QI;^iseSbZs8&j>snEybCWoMp{;8g^h z^GSfZd}rv#9YVgAE@Vn4lY2U&g4b&JurmO`=OU5)Xe}C)UeL;FQ|hZU$I)xOR99ET zz80<~iG~zh)|lc>gf3>ks-dW{i$$fbBk*?K3D_srFxe&Hbl|V)kiJ?N*XOZ3N=@^rH6?{=Qic^1pI~Bq!!y1cEW{P69rsAOF3|>5( zh=y;65uNrAE?SM_vLiM5NAC?R5LheV&o@Z%+Ff^X;I%WdEv4BNLnmm(-NEkYda~WR8jFUB%aNNR#f{3P zx&F%vyqxQV-i}ceCuyP(OE)NnouUS3Rcxu=kAF3bF=}Qh>fRhem9G@eSj-g}4?a!H zT@~O}iXy<*!mmcPjJm_(GX;N1^lbE3&sfN^WJ* S`mc`i1duTE=xp2Lg%Dps^(k(h*ag%I5 zSwL&L09*5S!Q;6&LjFFAIKK-i>+8}lRZ_(D0_TK~jkvpWzEia_9R6PZ@$ zKO`63Kqq4y`7eA06431n!R_H3oH43JXGj@(GQzND#EX7!>!$^6EhLe0j?Gz?N80Xs z_*xc(D;ZI+co>Rzl4@9(beXY-3FLL=1g&f?XS)}v&@UVEDc}AdI^HP-zv5Pk+DnV5GHx-!B!|Dq<9!OnEz_m_k`~mi9!)GMo~*a? zslHE+6(yvxPm!XS{56XPA~w_4%QDpCEk&&=bE$io6#e(zmKAwcGYiRHa{0vG~JW*gC3&kzd=cm$oX&+pTzX-QMP1tI#MzX8}+I<_SL39fJ zWc4SRyi6jGrWBs_Emd-iJjv>w1mjaw0tQF+p=04=`mT74(zY5vW|bzK_S~RuhbTHR zua~?Z_+z`^I5Gq)JP_pafQiZ5A}QkvZVgnRq2?51wIiV=la3B&adZtW!j9IrRNr`o zHq6e$B1>`ZU634SdjBiBbq8VlP>jn+6lISyYU$D~S=w8vf#GGX2zoc2t1i~zc%9QY zOP&npuznWTx#kQFb%~Pwj5ywDH(dxk^6uc?xhb4on>y#$CCd$(j>3MIELW-5N`bQ# z_;os-{C~A3VzX-|wkW@c=Y(T1zv4Lg4A#8FxL?31KDdbiFo#NwT(YQP6;JsYx9uaExtz=6AH=uwE`~xk&N299=Kheh^MhKkS=bgfn`&e^vk(8 zZ5{*fpp$rByBd+l-jefe9SVz`iWOlT>OA$4dvYyVq_GHVH5e^^ zNKH0xXrGQJGR>A^;*b-0?A61?zsj(@tOxy$&B%Ap!!iF;=xQ%xKN~GZ(3~Z>)On8C zzdwxshQ@K0r!=_JA*$RjQ{=hZrIK7mTmdx}D`2>V2c@Dfyq8zfuqH!=yD@JGH!^6& zUD;;DX$nU4IE6Arln>q`@BO+MOKp)S$!Wkk6;3+VhI={6IQ~E0G=y8qK<#>GqLo2bUIOyX6*0)EUTgO z^%>q*RHOH0EIbb+!>KTy1lejFwOl_!OM@kG&u9%q_eDc4I2=v2Uhvl24CS&6OsR|@ zvCXgP(=$D|%C7={S0M5)u7bI;4t#z!Mbw=Xq--CA#&RjR=Vj9Qm@iC8CW)+%ug9F6 zLX1Y=f{jTAzOjXvddh`1G*(j3B{8sA1p(}bW66C&DcOEJgx6L%*u|YhjF&k+@B>J? zs+>XB2A>+k;dFxsezq+$DBXpT;#wF_xdl;PI-YAfVMyvKO&%WrnUqpA-;03Moe1;r z+i3`}66Yij$aB%MT;FvdZWViRvU2Y!Rnm5 zt2`%!hcK;#?hvj+xEA5u$to4j(MXq5Ix&+A)t2Ql$JmkkcOQAay?`#$aLms4;jO4k z`*9C8v!%F(p?F>ZTi^sJ{+Zs#5timYSPnws1uVMf##qpX!#W&Vrih@2g`-< z5T=#T9zvOga$m1WL-me66x`^6)s^BOEEmE<7*;}e{Qum|!Zi4ZJjadK9r$~9#SfGV z*)dD@J^Bug<4*pThQmEo<|Sipnf##)8)sa?j_t=Wz=EN;RB({^=E*Ren}ta;tPr2; z%KA50!ZGU?*p|3s|BwMh7t3JW85L^wm`&2slPKM|kZJF&pjUO0NF9_$f%{J=57veE zvbI}gV~eKCCR2qOQ8#DW1|G$tyex2JI|CFPJ85sKO66R_a^L`n;(<@*ad&ar1c zr6f{e@WWbu{LFe%vl#cos(00tVC!E&C9eMb zS4*~$Nxuc0Br0*)_6b^2b1}L{0YdNBihm#%qb7QMI*@flti)ck-Ej7n<7OPx;GWMC z=LF`_;pkd=me;H~6+uZ_us>Er(qq+X-||3w&DP=8Ok2Y3d8NV$uUfd4%%=;m!gCd5 z56%2ht%NLpe}9Y}(KcLtr3zOxwvIbn=kxM^;$xM~ddNL7|Iw_3C>OFr7*@i2kggBM z?~=s=ewwuoHkI0AcYy)=$EuYp&z!D($U<($LpXi8f^dIBaM`NN{^mG{4b8=6c~!Ip z$e~N@ceXI)IvJ}=;$y^9YWT*{$n{LtWtB-;rV=Rf)5SWOGlb55((av%x;`z;=g-8W zIj>2x;RuO+bEcuig2!}dzx7xF@glcw0gK#c$TVW)nM+s`Uwg6+)h~=9we%x&be<#a z5tXAi{TrEwm<0L1YA3bwnMfH+u_M3Q(e&0frX;(O`u47;dvg>>?^PUSDh^Xp*GcHk zxQU$J5?H7E;@FWC8mx+AI+r}CXa8J+pw|Ue(MH(O|6#0V&EP6l%5mr1suAZj4QGao z`KtpW$jyH%iGR;U^Lkyp?wZVr#e=J;(&x^d=*N*bODL|%;q91yl01B)>HGRS(3|m! zGAd*^`Kf&F>G^q_vCnfjC7IxMtrru|yGjWT#U!?;3{{v;wqmm}W%8{`YeW2TU$t^YAr70%b~^ZHS!mzagtMKaevPoMC`+D2w%O9US@OjS|OXd7sSFq zrHX1qJ2Bcfo%`}aiF>BljmxLKaYxW*MvA`6=-Q?ndeaq-e0~kvE}Mef%okYd`2wN4 zGjX|LCYEU2=8yaHCRwyjMQ*A#%Cc_piEwtx~4>d{J(PG1e5Uf9yfP*VEXx5h$s;bDOH!F|Q z1t%AZez}pdekLk@@Q#@TPKEf-W8Gf$KJ8mqNOj_C=)Xyy*`^yN%;WYdmX-IEDc#%6 z|L3|6jZStUy)S;$H9VG<55ifshApqN>@$CzoD{RqG2_Rko003Ma$0>Thw7c>1Z-r7 z26eosC9^A&&^>!5oHxIv&wnkaoSGRFbF7OVg*~D~*`<656$x0}IE-?~BCPzU6q-h{ zhwmGQ>E8x^bNItNJl7uYkFuD;4c`pt-gMl>NDkthDQBn%6Ptdtb-J z8Q1aKxmd&{%46=lz3j@-OB6Ln7V+&;lwOuk_Eijx2eu$)s|V!vO~L+KiDZOEcK5I} zf7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/Tileset/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/Tileset/ll.b3dm index df79fe32f39e95cb641763ba5c6153c75f085b34..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 45 ycmaFjeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@YYYoxF@gjZFazHlN{;kOcryfek?b delta 57 zcmccN{luFy$v7pKk%58X$wtoaOssE|7#I$0W@YYY71B}4OUzAGvQjF_&oA-IPf1mp NJcUDT^8pSCSpXqt5^Mkf diff --git a/Specs/Data/Cesium3DTiles/Tilesets/Tileset/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/Tileset/lr.b3dm index e273cb03a764ef7af934058e48d3feb44a809cd8..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 38 ucmaFieZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@VnpI(Y?$#^!SzQnCO5b_|IC delta 57 zcmccN{lc3w$v7pKk%58X#YWEWOspT27#NOhW@VnpDx{;7mzbNXWTjM;pI_papOUIH Nc^Zet<^voOvH&D&5`q8# diff --git a/Specs/Data/Cesium3DTiles/Tilesets/Tileset/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/Tileset/parent.b3dm index 8cb958955234e1ecaac3837ecbf0162b8fd47bf8..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 41 xcmccMeZZSD$v7pKk%58Xz(&sdOso%-7#Ox}e#s$LI(Z6*+U7kR60!gQRt)9< delta 60 zcmX@$eZ`wI$v7pKk%58X%0|xTOssE|7#I$0{>s$LDx{;7mzbNXWTjM;pI_papOUIH QxrsxKNkL)r3JwWb0A-;QDF6Tf diff --git a/Specs/Data/Cesium3DTiles/Tilesets/Tileset/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/Tileset/ur.b3dm index 9ae74c7b0534d9e965355d8307a483d7127d5b63..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 41 xcmccNeZreF$v7pKk%58X#755dOsqGQ7#P-U{>#+OI(Zg{8k2&;<^voOvH&OU4O9RC delta 57 zcmX@%eZ!kG$v7pKk%58X#zxNfOsp@I7#Q|!{>#+ODx{;7mzbNXWTjM;pI_papOUIH Nxr0M(^9BwHSpYPY6AJ(U diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ul.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ul.b3dm index ecd600aba82546a7f878e6e0f82b2e7f46b950e6..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 59 zcmV-B0L1^qOTbGBVl!lI0RR91z_AJE0tMJ2006AB^#afW4{l*?Wgs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetEmptyRoot/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/0.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/0.pnts index 3622fbf0fb4da7c8fb0cd2f4a34f444ca6833781..a527ac20d22f8521e715b7e7b6dc620e30ca1ecb 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/1.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/1.pnts index c9f9698361ffe5640c25255efc27ef49d5f67a06..52e49ee7e671261896196aeaba4fd778708d110d 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/2.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/2.pnts index 30a52479f5755516622c76966bfc72ef9f75a9fc..9d8dc8ccbf90c455680ee5614fd5a488bb9917e0 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/3.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/3.pnts index b913eeab18934919383bb0ffd60e0177d4e0e4c2..c9164c14ef51bd11b860c4ca42eced5aa8924317 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/4.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/4.pnts index 1da4e463dbc459ceea0a2bbd090a0c8212002a3b..6f70991a931847c4b19f95a19b7dcd8812de957b 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/5.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/5.pnts index d99fa39f8c7786c90a548a47de37ae9a79dfbde3..3b54e05271f062325d4585541fc64fc5b0e6152f 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/6.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/6.pnts index f7cc21a997507ec9e0db08ac9e35100968ec7b93..9de69eeb50146b7c029894622e012772901e11c7 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/7.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/7.pnts index b8e4f9ea9a1c553754c9472d586254711b345576..8a5aef4d75f391f4e1b5bab85702f67e6695d465 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/parent.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetPoints/parent.pnts index da80bf879a8827a034504f7554700b7947aba18f..3e4708be28245aae66e84e13e04f07cd3b78eb9c 100644 GIT binary patch delta 77 zcmZoEn@}cOkXKU7$iToLV9me~0;FeHF)(ldX%MKMXk;d(qZHup=@$|l@8jy{9^#>7 WWoTevP^$n08#8BHaa4nu3JL&)))4>z delta 64 zcmbPG)>39vkXKU7$iTqBV$Hx10HkMF0SPFmRtoU<^a}}&_i^=e5Ajg4GBhwS(3vP} L##p;CceWJ(yfhAz diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetRefinementMix/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement1/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement2/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement2/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement2/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement2/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement3/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacement3/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/parent.b3dm index 8f6c2012861e5552393b79400807bd505c9521fa..dfd93033e14462b866dab8b17e62210bab4d0b0a 100644 GIT binary patch delta 40 wcmX@$eZYIeVOIXU#N1RRE2X5;w6xSBC7sQOSl2O4ZsJg5Qc&2ufs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetSubtreeExpiration/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/0_0_0.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/0_0_0.b3dm index 00277d8462cb556f94dadde82c14dcbb2392cff8..d11d0d0823133a202f9f488063002ab2b206c140 100644 GIT binary patch delta 40 wcmez1{J@zr$v7pKk%58X!A8z_Ce{Xd1_qnWxlB^5lV`H4Gb(J}&u%CM0Qi^-A^-pY delta 57 zcmaFh{K1(s$v7pKk%58X!$!_{Ce{h^3=BS-bD5-Ag>;ni5_40PtdxrK^Gp2lQ&N>C Nx3jBn-oS1k1pw_S5c&WB diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_0.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_0.b3dm index 3514e4cd2a2af276357fa40ba20af57fa7095b34..3bc47c69098db2b7943a925ad781ab1a57e11c97 100644 GIT binary patch delta 39 vcmZp1`QXfzWSo-A$iTqxL2)Bj9usSWJOhKx=2|8h*2$~c)i+;ZH;@7ViLjV8( diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_1.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_1.b3dm index 99b4ac8569fa8995368ddef7c241d3b6ed966a7a..579fd55c7238a2f0473d00c85774dcf34867808a 100644 GIT binary patch delta 39 vcmZp1`QXfzWSo-A$iTqxL2)Bj9usSWJOhKx=2|8h*2$~c)i+;ZH;@7ViLjV8( diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_2.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_0_2.b3dm index ec337a97d138bd2083a3ccf134606109b697230a..21d4e9dcc939614796a24d74f4f95f7c2a58e2c1 100644 GIT binary patch delta 41 xcmeBh`Qgl!WSo-A$iTqxLvbTl853)RJOhKx=2j*t*2x>$)fp8wUuQRz0s#A<3vB=Z delta 58 zcmez2+~LBNWSo-A$iTqBp|p{!jEQxEJOhKz=2j*tRv{gwyu{p8B`c+({QMHX{FGFs O$@AIOH=kfPkOBb41`tL7 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_1_0.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_1_0.b3dm index 205dbd0eee18dc670e39493332786d3ba8dfa2d1..769ee6eb192e28bd10cad6bd86a6734a38b5dc64 100644 GIT binary patch delta 38 ucmez4{KA;ni5_40PtdxrK^Gp2lQ&N>C PPh?kTRM@iLjV8( diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_1_2.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_1_2.b3dm index e32032e27e1d1e868126f9bcb9ed5b10bb89cdc2..0d3de7e6a0a61ebaa4be83c64e7faee7c5710dba 100644 GIT binary patch delta 41 xcmeBh`Qgl!WSo-A$iTqxLvbTl853)RJOhKx=2j*t*2x>$)fp8wUuQRz0s#A<3vB=Z delta 58 zcmez2+~LBNWSo-A$iTqBp|p{!jEQxEJOhKz=2j*tRv{gwyu{p8B`c+({QMHX{FGFs O$@AIOH=kfPkOBb41`tL7 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_0.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_0.b3dm index 8779e2254cfbdb00af7017e89371eb1c18da0cde..82695e097497b3a59dac08eea69cf8135343d581 100644 GIT binary patch delta 40 wcmez2{KA;ni5_40PtdxrK^Gp2lQ&N>C N_p_^S-ob7l1pxH15i$S( diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_1.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_1.b3dm index fc503c3b3a9f6c611c7b347a3a281a98605aa7e8..05f91911e0f3e6e7e37b691a698b215e5c6ebac0 100644 GIT binary patch delta 41 xcmeBh`Qgl!WSo-A$iTqxLvbTl853)RJOhKx=2j*t*2x>$)fp8wUuQRz0s#A<3vB=Z delta 58 zcmez2+~LBNWSo-A$iTqBp|p{!jEQxEJOhKz=2j*tRv{gwyu{p8B`c+({QMHX{FGFs O$@AIOH=kfPkOBb41`tL7 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_2.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/1_2_2.b3dm index 1775fc0f1d4b2a60c5d890c62988dc1f644d7c31..eaa15e77e615decb4faac7485af64f01830d28ee 100644 GIT binary patch delta 39 vcmZp0`QXfzWSo-A$iTqxL2)Bj9usSWJOhKx=2|8R*2&A+H8-DQH(%{0GWSo-A$N&TzIm?+?JLDM{TsF5dDY8!9!LG6S9=nkg0JHq)$ delta 57 zcmZp0nc%{iWSo-A$iToLu#vNziFJlN14GE>RwhMOAswZ>#N1RRE2X0R{1U(XlvJh3 N%h)wGUtl+o0syFg590s; diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_3_4.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_3_4.b3dm index 2d5bc41455a0c8f9bdebf48ac1d4a019c0f3eada..4a9667877a9ca530dcd9878315149881486c0ee2 100644 GIT binary patch delta 44 vcmeBiX>j38GET{5WB`JVoaIcc9r6qeE}L7K2cvqGET{5WME+6*~nSW#5zTufgxaXE0Y|nkd9JbVs5IEl~PfDeu-axN~+T2 N#q8>vFR&X(0RW|256l1n diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_3_5.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_3_5.b3dm index 2e32e9129cc8815348238e6290d5b3217b0e9fef..b0c9e23c044523ae9d22e81e522eeeace2efb1c5 100644 GIT binary patch delta 45 vcmeBiX>j38GET{5WB`JVoaIcc9r6qeE}L7K2cvqGET{5WME+6*~nSW#5zTufgxaXE0a8{kd9JbVs5IEl~PfDeu-axN~+T2 NCG2XOFR&X(0RW|Y56u7o diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_3.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_3.b3dm index 31e75dfb7b040388cb924753ef8c65c5055993f2..4597378a3395e66e1c2d2e0c756e0a2e5a20619d 100644 GIT binary patch delta 44 vcmeBiX>j38GET{5WB`JVoaIcc9r6qeE}L7K2cvqGET{5WME+6*~nSW#5zTufgxaXE0Y|nkd9JbVs5IEl~PfDeu-axN~+T2 N#q8>vFR&X(0RW|256l1n diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_4.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_4.b3dm index 89cb54de483ae202542aee70705a7bcbe5ef4a46..fed87e786e60783e9617702a23ae06e23b5480e8 100644 GIT binary patch delta 41 vcmbQ>(%{0GWSo-A$N&TzIqR8N8{`=nY&Q2YNwZGg#jeJrps@J?yMYt{)1C?@ delta 57 zcmZp0nc%{iWSo-A$iToLu#vN#iFJZJ1B1`zUM6W)AswZ>#N1RRE2X0R{1U(XlvJh3 NE7;XGUtl+o0syDi58VI& diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_5.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_4_5.b3dm index b5f7696a731c206fc0f6e89a38caf35d5c3b5c64..926ef07b957fbfa0f5460378ae2ea0f1779a5a3d 100644 GIT binary patch delta 39 vcmeBi`Qgl!WSo-A$iTqxLvbTl853)RJOhKx=2j*d*2$aM)i>W^H;@7V=*j38GET{5WB`JVoaIcc9r6qeE}L7K2cvqGET{5WME+6*~nSW#5zTufgxaXE0a8{kd9JbVs5IEl~PfDeu-axN~+T2 NCG2XOFR&X(0RW|Y56u7o diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_5_4.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetUniform/2_5_4.b3dm index 66984df1e913ecd464562f4b2d44f20c137c44f3..ca19e656e1920201020cd404c9d940be0a1cf951 100644 GIT binary patch delta 38 scmbQ@(%{0GWSo-A$N&TzIqR8N8{`=nY&Q2Y$*@k|&91)r3A=$50J^UU?*IS* delta 59 zcmZp0nc~8kWSo-A$iToLvXQf%iFJxR14F>(UM3k#N1RRE2X0R{1U(XlvJh3 PE7{c<6*iw|HqzHQqm0FA>E9Mba#hzcMS|P z@4@fyci;be*Sc%ndk<@vGr@Vz^E`Wh_THbpH$Nmh%dqfa0@hAg5D27GKMLO#_oY4r z;$QBGh0W@0;bg-g&fsD5#>3Oi#@gJ{Nmb(sKR3X~%Pk1u=jG=W z=M@s?6?wwXFU}_@&L?y;EY_{Re{%B+>wlbMgG1g7w+KFP{xke-@cj1wI4Audw}plM z?{(I|?_mGu9Lf*A01x0UIM7|l|FH@;Hwq4knSsbb?%uwA=Qi%$J9qBj;oZe2Ah}O) z?;ZgK@gqVK8cI4^8cJ&FCrsR|PZ&5Esi~ieuyOM82?`3*v5HBF@=J0H2=d=t1Pc!j zkKi5w`ThIk{PfiH{QvU+{^yJT$8*dN2+`e}o5I0jfM640;SgbAenaTM8^y)?d;B{Y z@HIBhE!^98?&9I!1HVxH5CX0h4)!e^T-;l?z)u6f&mp&naEa;pWNtsww7A0nxRUU{ zi^{mmC|mxMRBPyfNx;(WJs$pJGI9z^W){|`Z0v$U!Xlz#;&RXA6%?NggL8 z8d+J}*xK2{9NaxTy}aM}_@OioSzSpt?3@%Z=k|Y_ z84)-$>|3{RZr!<=85Xwp&D4o*;nMTnCYI5>W8wOUf&blI64|JX@}GE&0$K;8mTp7% zkC_DjFdyE`?eEmUnF0SVruP2-*W8x=JG1{iv1tea4i>n7I7ARAq_>{D&ZQMV>V5jU z%2_sW?T)ssbhci2-4|v@9Y~s$tu|<|P;tGyx_m6OE_VU<*%==pJW_Zrl;hDW=ttmv z3_W3Y+!k?T8Ab)%xzKiDj`n-b?A0aF=r=?Xw{wZBC?loy{GGf`)`sU{JS&)Alex z46RUr&prCkO@1tH?8LkvKZfyBg{8AXxP1jHLkHd2RN+qy%(Q)ULL`2mwTGm4s$upecxj8CBJ-!^T0ZxZ5YTzabjv%c%S_w@icc{ z+PofgKTA!r>Cz`g2x?vC2)iU{&+@u0xq$Kjf{YMKd(rb&#{zp@iyl9Ue;QqWJd(*X z@No)5CN9tFw5#R;Zd)=6ny;15ukXGpu_Lqh@)&U4aH#%CXYc<&6s;>1xB9d3AM53` z*1=Jce@c2j?4k-9-C(ntYo5(}3k814?6(?&sR5&&7vm8LKR8?K+o4ANMv4AU8-U;O zokIjmYMZ15avzQ{5M>pKnY?;= z*c&l4(WdGs6U?H@OEMJ$8BTopPm`>#J1YE9%=!>;M#}DbrdnN^?n%d@ph=i_2%Hx7 zHLp(#&J3;YUcuYaPGg{#YbbVfifiry1~LO(gULFLe%~5?pV9lRfg$=~< z^V&d*artR+oTN^d(bEPu=i+3&nNz_o=wvzoZ#GOUdA=UO#dYgDve3Q#8qua9H1?%k z5CzQG7DnqCov;wYdK6BNFcAK0bUHoI9A`u`)p5A|{VaDgKF}+NxY$o1%{{F>V?tM7 z>vgjzS~fY0@FGd>!!`zzo>Z@Nr9$2wOY^|d(N;q;+EEr%H5}EIej;?O-cF$vioS5Zr3iJ!KzxE&edJB! zsI&{1;$23Y;sM)XCu6{NAJOiL(ly!2X^@Y+Aj3e6@>=YT6{>kV$^!#eFp!6*#b4RF zRSmg+59d)FE0q=_ig-|}b{NRpn+=5L6$({Py1zSezerNGLd$}h_5(N}k_Q*zStIxz zK-}>na*Y@R@iq%RVK~|WA<7&c@F{l`J0PuBvD^OwfPO9{FN&u-{9}cII6+gNnT`w& zyH;iH2LK9`-l)KiNMOa`Ho1^6yln@FJQBK8)bi=(n21kei4HVln;epoK|5V?=TQ?r^L2l*EB@;w-q9oz50!Wh5~dK zm+BozO6EhJuW}bI>&S|dcHCApU3VF5S={MxK%FP@_ZU@FXz)PoQPHIyW%nuG4;LQz z@8RG>?Aj|tSKudGhuukV%WdAB-k1c%?;(7B6Vhph7zky&mTsil$f)q5WWQ^~Qqb*~ zI<;b(r}-_p-oA}Rkr&D8@G}5hEFGD(vTauJruFNE>svb4pX@P^P&&oS+tH+DIucH1 z>l8b%NZj`a@y3YVWPC69?`#Yt?ey6L*s&3ZtO<2tkFh;MTVYdnGwRiv^lM;I7aqZ( z{0gv;xxsYZ)ajHx2x6whurg*Yhn5BwPFY(viR^S|M7!$sXL;$hwXRBqa;^*HOfWH6yf0&nXwo{16QX zB_ILUVIxcYePr2@Q0xPF)`QF}l%X%r=vZCH8EL`*6p9Wq{8d#dHpJPHi-BC@SKb#p zIbn&MKDD_v2^!1$kK9Ig8L2qNX?D#3sI9dEn%Jb+0p|X83AaY_<#+QL2D|!d4ZJOD zR1!oB^HrgbSEu0dE9@Mgg&Sq@ zT#mPKxOM1A6vjzSd2E=?V8h~DUL>Q}0<|Qr#t6oGgpN6RtZ0mT&>l*;4W0m~Wo4>u z-E5f_qQBf!&rrd=LzXIT94$s)aF^nqbYRm7dej1k#m3! zlO3XU=3;9|9>r3rBb--)UjRwATq%UDCS@4Lr=$jQK2x8Zj zpt&s6j+D^b(}}%~cG}ESmlL7Z>pdHA&D#74-7EtaoHQe_e)t6ZqA74fuYJz}W-8L- zjDciP3Kq!FiI`iU1(O<`$My)-K}<*w$%XsdRtu@zOFT842cDj@&3vdM{6l-P`$k$v zb=DzI%p=hBbJcf(4(NJ`Mv2NjiDVzc)kud31g~^;T+){!dGp@kl-NS0ya0r@7J!7b zVj$Qz7M=Hi!_djLap;eMzPtadHQ~~EVM&$)mYWj>a(D`=}5wdsnp zjGWoI*?1txn`e~ZwUnxa@-WYnG5V;iA5@6XfXCICst*MZ#Nxx|1%BkSW&OA7bbg?X z7g8;QIa0K#4mS82o;;O)@iDEsBzq<~oKfeW*MMi_)yBB>!nSdXB zz6k2?{%y#k-4C)Q;M4B%vG`(&+LfA&8kd5KryJ(L}1v+2OL7UD5pqKv+F4DiiUtegT#FE9)&Ywq{_C7sg`Z*W3 zi1!R?^QgryW|v_jC%}WvX}JV2tSA3oj)By``->vp7tdiJ9pP_Jj-jcxHFnR?PcPA7 z5u-#NX-%O1q^Sz;uGl_5lJX`z%-@X)^(m-R&D`r6u2an@%!L)LB81@5TxW1 zlWP`v4g!A=O7WNr18FRa-_R^svjjt4(L9aVVS1$N=i34!-C>f1&qb2H#$cTj&v&a+X;iFv^^<1b?&$?)d(~}B{ zY_p=;%Q36sg|tdwxd=_NlR~=S#>1>2ocmTDG~UYQ+P%!?>o|;4fnM_aP3@z!_5r&@G6FZ5lnkL&;qL8e+r=qb`+t zgB`PFCkFBc2si&UyfpD_)W~|Ov3sUd4B1>rVlLpdXR=Ob8y$cUv_3Qv2TB#-c@Yau zXv<1>qohV0yO(@nKJZ?h)<3p!fug?XAP%hL&YznDM}l3Sx~2m7P=!vC&Mjd9KvYpY zWl67y7K1QZ1h15IoD%DOzbIB_L${*M%kZJ(R|8MB>d*?6O;Zot7IGYowzOxVvFr2= zCzqFcqB$(Fx(S=PTS{GCz_qHxdt-$vCXa;y6n~`2C zv+xrMP7Gv3ef_!JTW;JM!mLO#Z&0lCpJZsB9q*W@#dp;ag# zD&M%EfQ#;$i*N#|qeYjnl(*yGje*1?ct*>yz#*OXuPf1>rU|6j#m4S=H=>uS%gGm} z3k`Zix1_R)eC*P7MGE>lrQjMq?$@(nTtMo5tW~-HE$xNzz&3STsb( zIdPN#FRa*(sQwxUYon#Mk8HfHB$KRb^(?*k4PC6l;DQlj zl3FstF##(xNCR-{VKsp+zMpe;sSs|fEE`X&XKImgpEB$Vv0+!w_tzg?vpcD|K$XkC zvi!X2C0M89El$zvsc!OBOXFrZ#yS?ARXhazH1Wh(5_Mti54c$CBl4JZclB{};s2_D z;5jxtS8m{Z6HFNOVOLd+T!DTS z;c4--`l31iGRn{&p{-^S{$K%(d$XZ-zQeK3gNv`O=Vk+pDh2v(90LIK3~UF!04ww( zs6|~>LbMz&@B?x3NY7tk3UTjx;ehmZaC@aQFn^;Sjyy}$Cm6^a`o*U;^lGjJB0}^> zk)Bo;cWA->tL5%p^iZKlC-K=c^9H^T7x>M&%1?%cMC{Mst-7WFL>VFjc5B380U+}3Vj;GA^!^dar26Ik2^0=; z1QgTvzz@*TXZ-q7cas+P`$+GQPr}VM0}kmvMIy?$LBWVb)RtAIZJh3`_WmWmqa#ox z^SY7KE3KoCm0Fke)$`U(^=cDS7SK13Q^P>4iNCwXT#U>!NywJQ`}&4gJJpbVELH4k z57=R+cQ!bhSS#+i5Y2ZkFflQok52_-dQTL#&N6Xod6v7)BrH$nfI`_xwdsUe zYQEERk$GJ64+c^@u*BYE(p#mn#14FmT^Kl~@IY)5F612*HTZtWHOF>Emm!m~r2WqZ zkV~bYbKl8-KGTD?&87Pd@QtFek%6CHmT(+ED?xo7QD5T_5z6v)&x5T`^rAg^r;_w8 zGPW=IV;vJALV5Y7Q>9rV$u?`yo`EDq3&XC|A0wySo_I>z9Y-Yc(*)W;q>%0gXcw-- z4wRVL|$*XTSgC8W1a zY!Z3Z^IL<+!kHG+Huq!SkbLKpCEf;G!m??~Vuy!qx8v;@ll$%f63SpCSDeH$U2#PE zwB3Jr!h0-B-~8ot48Tj?FFNo&zslLu;Lg>;C0@~V)#KajeU4?RAn4SLr|&-@>&;pS>ZQI7>kXUBkfjsbQtae)2&H6w z;S~~kNmO9|2$?i+;kb&-;tiQ?ik=f}7Rvk3H;^2eQY!7@0Q_dC7P7sc3rqJp27O0m zLIv@mrcBV>%e*S(l>g;a+3G%!G#@9k;1M>t9TMt^Ve&b#DaGjW*uFL-#O!ev=1=#KW`7gW024 zVJ&G2CC9+CY14ubsjT&mUiCx#KFwpj@E;(|3c>RRK*-R&MdA8vKHoz(w%M?#(Bz+_ zlE?c08` zt1Ra$t>J$4G6hqJTn~O&XC!U%9pk zrCWVbhqHVC0$}&7bgGlvgs&>OxxZcrJ}Lkeec>?Byg;gAUG=X+(qFh%G7WMIAV&Rw zrfT;QUua|;_N*ewTsnov6|XUnHFom;DSaA;w!W&$8ABhHMrpg(5z_TROX;AG9U2pSb z2Zj05l-KMjULt%gM$&h#WMd4bJz;0p3-O?oknng>rUzc@c5z3ZaJSms^72+C9Y_vO z@v-q67bDHd$rq0Ixq+*sfekj*`KN_Sh0&@DR+<(erVI=H@NP|@F*OJgI$b1``k9V9 zs}Vi2I>H8%G~Cw4r&|_Q%*GW_sa4(H0W=n&hiHXF=;av-8pm-3=L0a1p8fbOgUUNQ@uD{iHO4&_*b!=6c5&xe z2%g4<2)YIR!V{I{)^SDI=|y!zwPeEm^@68t8-{nEvDKkaH-T2ZzEaB^8Vs)K%nvhN zoySe@=4kP)sh(PH^)>3HfL`&9LmQ*6dZzytC`a|(P=H2Wr!(NYKuElrXeFrcZvg=v z#OD{Fb&byyxEzliKT^rvydq;lre1H0mzqkHgulH*w+&5w;biBo{AFHv|B~-zMcpGF zkf%8OqhWIRdU+F-|88MG8-5((x#L`0!7WC^`O2(S@R4kRG6r0TqOSkrbxhe)0 zboDhlW>$W7f>e9GRexkY=*#e2-yIG;U+C3Vnaphh5OVxgYtbqJw0+B>JctxuAzRAf z=4FKu#j<1&fbjd1tFP~GXU{$Yt!2n;zj6FEuHmR4vOnu-2xl2NGC2Lb(6JSNXw0Sb zk!GUai>Dn_is^-_qJF=-xpd9?xZoQ~c~i6UFt1^jJ6*HBNuA)j^DA*x4|(+qdz}l# zGyq>_;tV|Mo3oL%gA*Pz=|7e)YV8gj`bg9FQ}Jhk<{Q81jgXMIFR9$FZw0y*1EE(^ z<4XZRr#Fj_vgsCWpv(2G;qB~jrGZlD*Ze9lZ2Xc9J>a>%H6D5K>EVs=^B3pwKhiI8 z6Qoh6I{_Iw*}?~IYgNS^DDBH~3;-#GUeY{8sjr!;|0#=K3$x_#z3gAxegPW&S*Xt} zf&Z`XeNGM{#ELnScj5T{y@%+*!ti?2uA;sHT2l;Uk;njct}(ALEdN#jB{z6ACiX>u zuRstslqr-$kgo`$-Q?Qy@zLK&2A77noUM z&^^>9W`;L&?a*Lul0IGW5@>ij5@$jNt%~Prpd`EPXi7Y3W#x}L075FFm-JrVL%*+b zS@ZD-g$jI=0Nt&3_&wAQ9kNgLSYn-XJWHmk{W8s!{1`hPXe{4xyCn2AD9$S%*(c}; zpOJ_(cPY`GkU>w}c)0+m7*1coMQQxYmcq(ltQhp`eD6jg4;7YMNT1uchXq1d9f9toyD>iB~u z#U1wXCaCY{8~CFtp{Vd8UP`{d0f=(I%c-ks;1^yJ2CUvnj1jo%7prlWK^N(I$EXjL zeY3@t*pzs-Wlt~KO2B&qkRiqC`{YZ-4%G5ao5xls`A%xvAL-0jpS3{i*r0PF+sFzk z_yyAc3Sh5)nOxO#hTaFUIfF9q%|8wPegON>&>Zfkj5UI?y<=n&BTBtVmu`=&=Y+q~ zhztPPOdHsT+I`UYYxvZ>JiHAo+7>&!2)D^g7_kgIzL&BbrAQ{+FE1D$+xM7-gWspHeV-I$f!4O?GYX_=rj`VG&TMMOpR^Ey`BRY4^D-f}kfgV<^ zdyIiZ+~gm);!(b)zz=9*A$j4tEAYNNDF<&XCO)bp;B~FIeC5ux+8z>3Z*W?A)O9=D zey9a+VdlCpcRF?1GZ}h7geKV%+?m;6$Jf--G%^LP+gsR{cz9pjN$9;rYP)wEQi{zY zYUAANEfFIAAHb~Dm5w+Fx?e)w)8L&tz7$hMKNfB%)>7^Gs_NbhWkP_kcf7_{6DkEW zk{0CB@I{(mlD=r6|Hi8$AB8@^K=A#~%ku5@BbIMV!Ha;?d}R?Y3$}qMHiaIw7TYJA zNfV=o*Kv773w@wS1X&dz9gQ^uru9;Xpke~p08Lzzh($$y|KszUtJxiK($kaao;z z)5`~^5%(QngezZGIU1ek1tN_iuM{42Rdt;n6JBV?rD(s>Xkul)d-izq%P?o%qRWkx zzNHQs8ZEum;FLQ$Nd-_0xEdCXYDx`m%nu{H?6-rxfO0VqBW?`&E|1GpX;0~&Bi9sf zA=`J4QWCG|4Sm5{DCq#WNpgBye_7g=2-gBV~#vJ7^C! zzdqwS<(mO%!#-XpqM?cD&USQs zMB34}uTNgh(pez%^y&6U)}FrI2=o&j%BSG6Tn0Bi$gAUc5sdb17ROf(jf8^W)2v6G z3z1(_j(4A#^V_r1*@-sRUYzjn;*qgM0;^hEtbq8(Y(IcrTZSgR&YazJchZSbQip6^ zWSB1Rh$Op&Fi|63$f+SPCspWu+iR+fnQKQ07t*XecRNsKAz;P8u{KW-8R3%33M}^R zrkA?wxdK{jeeEnibh9wf;M{M|Ld64d$XxDnxp`wrojH`0#|OJp#Oka4Kw8PY@C6V6 zT1+sHW;9l^n4ay^X+BsTM z5abz5p$Yj;pSFW&>(M&uOXl>$XeuQ7mH(Ny)~rAqtq!nE9jW|HLLxap`Y=~DeW&Be z`B`BtnLu%G#s&F~6uXM8&nxb8>Sep*LX)PQw&N>iKV#X1qS}vCG?F+YV8E^230f$^ zZM}Vx4jap2-i4-4l;cxYyA6*q$0RV8VyrglM?@awv$nqY?WY^6e!7kJ(;+6Dr;I=F z?}77%GjN=#e9Ap25r;*_}Fj_R0w)Xc7|d?rGh8k)Z=u^bTR7lZV^g%%RRHOkpf<3`*lcrXMCl)BEpk`1e_;&dHCxhZ1eE=ApX zZMC*aq6zR>%uTq&3E=05Y4{U4g49hGc~iCB#VBe~32!e{L4O}BazWzGA6^e!GbO*Dxq+H8YHF{cnJ#+%BhlSSTALdk@@+K3KVbZp5?lixk@^0MF zwSVeX$Lxm=D{`i=xgQZn1y5Nk$u00Y3O`!$Mgoc#x@>M0Uwuc_x+%Q{b62+fdNQ)C zz!Hw_{VO|EpY2%*m*lc)%K*TGOzNd!tKNI|1OxGd#;?Fs`@cA1AYiUyun0<;xdK@J zkU%YfmLNn|-1jye7%i-Qhc4N${y_ynWo0j`3?#vP@CHkA$;&NnMK$Qx0!e9L$rT`M z*#~0<#L+=3+F~I~AaIE19P|eCN#{*zw^>=i0))ZB_a`M1Fj^Yo!{t{ZU7$0j;nbC@ zYcDS&TH+kGz^=ZBuJ%Pa)z;i8>qE6Y6H@72?+3F;iWl0a6lV4%EAHPUDgbuUdee8u z#~n!v!(<>8_BG5LWRY-EVzdBQ@U=7#SO5?j<_3d)SkwBOYc?o#0;76p?|6U%OjGdJ zo53RxrH#U?zQo!j(}C(l>0i=jU^e`)fZJ};I6qC5Lv@lL@LRYpEUwX)w3SBe;v)jf z?D7m5x}qg}Xx&p1 zFmJ*JFx6wLUg3yHNCIUqIoiA4=Z)g$Sh30g#^3XqE`m8&;cK^QF z$Y)`ZDH8FDLY<-mj4B!;F)Yf#_+lG|P z^AvQ*gbl!A076vQm~;+SuPkm;tA1m`Ivots^fCQWi(+r}?NJg7vOWuym%dRgqQavm@9dzeo zT7C8=$?mxs@4QYsyQHqSMa1$8tIa+o*m<(9^)&o!JB|dMh+QJYk|QDN9w^m9&gjc& zs!XP;W8?Z`{4x$UxxOySuvt;wzuJ9e%Vo& z>$?qh340*Bp{7nlM5HI;L$hK5`~)emiwfeZwCvu9JcFhRf@#G4HMx*8ywaW%>IU6y zg3lo8VVfW3%~rQn2_IBCSKItvmk;VU@5HBF-MB0wfz(MkGTM z^Nn9LrS>R3{QxO z_?ePyKEs3w=Ya=6NO^7yR8>FnG za9Kj%75}5u@s|%(DF%@lOlPM3${GTh)J2e6cn3zqRRBc_@b1Vu^H*C!OhD~Sm({g> zUC6xvX-xvO^N!sLM;M)NH;2*Vq2FhZd@7Ji?GJ|MHp1$Y2X)!%n2^c(3U7o8N?gSs zGy`Ar@0X-W8-o$=%p*OaUoHL?#;+;X$#>Y8Mh#Yl*uU1oSM)}pD~x2zsBn1!9Em7k zfv!7yL=165i{?f<@=3(k&W&7j?#k*1_qxRunN5tGQotg)wR~N5Ih2@c992G$P~DyB zKk^&5xQUC{W6Q++!|#n?AjCz4S732phMt#CiJl{{GeamPLOAcuh^XcjPK>&Om-UXR zIu$%jt&dCFsmiU`9cGJ!I^$h zqyTcvUE1sOnX8UYNokO#5wQ|B>)5K~IeMVw zrnI5IPY?H5=mP+=5Y0u)Oq~SEy7^Ux^RrLYaR4XWTce0_W ztF5cZ{Bq0AYP{NoGlNXaC*GJULbAe7SAA!uFC8ffG(p?pMW{>A*S#sN)`-j83uf)p zeA<(BeUFHV$hemg-plF&POBnVxjC=Ef}KY@64=)LHtePO83WN&-6pku!G#~K6%ZP2 zb;Upny&*q!vGmu&mxeQm35e35i@K>vAw{|yuutAvwO%kspDX3{1th+65a{qHKo`xy z?3s8;c-!wk8LF*_CtkGGx8Zi~jsesIw8HCkCk!=}>teCXJ4P)Hi95WLMap=?Yf?aq z`89rFy+pt7SXB>9J7|4x9er86dw zypXZ}$SK$64jUpEgz$^yNDb-eW=P_@ zdk&Vx{<@(ZqC4};n`Zf?)z@_~5FWZ-kf*xw*)u6iOzd`q6>EWk$o>?j@;k||K$TU< zX|bQ4AL&*tIR4|F;>N~oeah|Ttf^On$f9tlZ;&}f>*7F^grpL&cW=rgxTW1gR2Grp z7zo+w<+tK-=yx+@WI5p7kGHRh6h<6_j^x)qX(7fJf71)%1=9sHai&C6_1y!PzJc zI^gl&W)$!l8*Jpb1vYe0{HK}Ye}4qF2Z60B7~nrW5f5=5g8eCfRxTe|>XK@@evOM( zweu?V&&qt(J-OTM%c7)|Hb(2S>GeWJ$;388m;1M{j0%zXXv&M|@7de_&raG4zINYJ zVi|Ma*8T-!nZ_?LSeJ4Z9wW%ppF{$S(YGza}>#j&u7i1~5o`2^%3k4P9~pD_wzrXhE+umG@y2)lLuA&C=8 zjInGuc05<3!>QOWTxx7Yo>x!Z(_p;blX|fu_qTKOkx<_V~m0!T1r&h89_b z)&0}!=k)JVpr2-bkCvTMgzCI+je-?$P28_g)RXc>iu#4_M5$2_N8)7WH3)XcWXzJ4 zG}%hLiKq0>zMV4z@dBnhCX&}zHvTE`CJp8OJZ|Z*u%qRdd7F%){O!hGIJeeI;U#CT z^j{ARX+om&x>QD(`o3Of%_{Bvym#P19~xxiitE(sXC!{DZ1euRns9a8mvvKV0xfSc zPeCHNHlB$sm4l^}M%yG;!rJ^cRTk0`r{8lFtQ3}yi17-Vg7C!w6)eWPSBwjnIK)l1 z!$7)pk5l&)$M&VBa>W&=0+m7EZD`@9gK+R`ZH=l)%V1(_AM%&)Yh1q?y7H`_<}FTJ zRyR@HrY{Llyo@n765V8`#gX%VJVZkCV5@+DAf1WrjIfxHUR(}O$f8Q?JVvx$hAD%I zZGe>Ioa}j!qe0XJuz8C%llRk%HHCG&)#rMGDPuJgsj(2t*jKGvGDrHl-*;p1kqAy- zRH_)_W@ABZ16#WO?fUw6Yr&nRC+6eFc_bhs%OJ<-`tI+>g6&gKEcoZRhRR)%lqvG! zs6*nhET$|~jWV<6N7e!G(rMO>c|+N1fc1HpUbKd3BTH$BW>U8NY$90;F78Z)3Ep1# zdQ_nG#z*ZMDEYYNnPTkcL*P>Vw^;5NoqbVq*T@+U5u1rZ;qxmp7P+aS0|`}Q9-Z&M zN3C}ZBbK#>>PJtUgbJd(S)WXvTn`qEuP70{6Bs+s$7&vLEPk8zpO zh*!kT0Q@M*MHHIIIn-{cRBJ67eHb%GtS`ut#UjJ{N*&elJE@zGBJ`9+&Q`Dy7NJxX z5Vg|AlqtqVqBf%EmPSFK^i|&nAp7i)f@ zYzU(%)qEZ^Z9bfe{4JzPXSveZz9fp)t_X|}c(V6m^NMkanQ8giw{IW!tN|Z>zD6F@ z8Ec5x^9ZKSL#wg$m~Juw@i`hXEiW$9<}Se{6_0=~`CT*gJAr&#)pnCfTGqzHD(?j2 zv>1IWxWTJoAbCeD(GhoiNy$@qyARBg;?BVDV7%Mo>Ein3$lv7prXq#S^`d1UVpOM$o^>W z!r-!z9V<#cb4e2W^^2UBI0+>+eP=VCfcyd9C2?0)j2zb`*}+Gnjj7Psq#uj0giDf8 zj$7I>1{5xX;ScVx%8H4}%c*RrFnn?orIvfzk>N{}B^Tw(HdP!!q&b+a;bz&& zcS3JL5E!(ftfo>GrGMgdOPLSNO3)l9CNp|cP-ki|wU0XDw)qKzM#qL($SeC;J>wHL66)|pJ6S>dz({b-+5bg; zoLm34$lgH24M6b8Xu7^5X86hfKC1kog&U6L;lJH;lEgr-*YL-Sl%J#udsKY4G*6bOr;odOtTtm#d$N0?)QKt!i}ZDXW;$p2ss4 z2i4yX`gx?*KpEO3`X8SI$9&U#a@jhi2zz#*DM#P4FSJS(gK#2Cx1kEmQd>bYYNj->O~6R9*z3#Mof zb8tWWfNMF-t33~idc$B6U7DuipisoP7|(P@XX;8X3+AMozT?WHoI>a zOc-90Qn{rh$*p3=lPN(BXUb2**^2Oq%6!~rzp1&S{HvN?vg2Xj=&)=*7U99ZRGQ>2k}Lz=8tA( z?&tLA_GCX#9@86qS~w@A_FS7Xm4JonLFta5l>G}oAdnz%{&N5w!H{hO8Q#}ij$N!y zqu0l`e+g~JUh?22I}@LUWqfTe^ec_Z+=XUCe!TW!UY<)^=gc&!4z|E$7A#B)qsOVP zA7*y2=$eAdA4`cSEh6K{iV<6sMDKD=RNAGN$qOF@Nil$2$E-(?{X{*#@X(NE2uH=a zt(PYnz&mN8I87sRO%mcMb{4N?$X~AV3h6t%?7s5Nstl)0VcwwpbDx>H*4A#Zi?=W43$^d3xcaG_a!V}9D zqJm#e@Lc5QyTTFl^%LhD!yaA=Rr4F+l|M_Sfbg2B1NDrhUhd&JWT;M|=RSwW z3ByF`F;t(e-XY0L5m%$8cuQB@J0UwSgiR-Devg@I8Uy)QYi0+F<|?@2&ny0i>EzI2 z&_r-2jqnp;dTTBJ?^Lq8sTS|c5^bFB(2Q)NnBT>#!*oWz)$DU9ySOhoyI;L6`*FW( z5kUVC`S752Ebc3r?rW9a_Rhwkgpvp3eyobyata*}Qr88m$5ap6=q|f;JiimN@jayJMPmPc2%U6+l_sWaD=EGzOvyzowg(f zg0^IWbMc}`re449GHOZ>rPXl4$yojHm9kR$e)p2CT@eHPKBb8Chc)eI`Z$kh2l!7o zY$qiet8U*DwV9~;Ik^ne8yS7WfY*v{ds(_1{Sr1n^cMPOHKEuOtiK@sS>F@=mW%_$_R+h(b<@^g>nil0hT{GT+$aU}+xNcnQhd)uY&qnnmy77hm6Mi%i zTG2I+6eJ#=;q&Uzr2O)^jk1CB*r`cMC%y?OmJFwij|}69IMeVFk1r&Pe8qKJ&<8*G zP4=+=JU=k}UFx%tnj}yzYB2HuXWbg6^ycD6_c+z@?~D(56}>{X>aCs2)62_}e&RIh zV^gV$U#lI_9S8oQ>0tzj?;1RMo?v~OS{JN(Am8%@{`t&{uNWx^2~TG;GiwhaFo*>rNWjVfw~bPXC+gT}7{QnLIorn- zqVrY>k2krn+9T<~qWX6Hi|sRaNAX0s*<`IZt@_9^2VqBrDS_K^Amb}l!>AzbvU%n= zDyKqpsiIo9_C!%?U-8XP%a`jX zsdRRL6Vja|xBdxo`CkDh3fc82so2Ha{GERctV>SFT89^=SLfN)l|*LD zzl1IZ{xZP1li4vG)15xRz2}c?1yI|_1up(E0)d0%x+uFtC?w-I-qxAfVrOW;s4RkyZ`m)VXcfxkba5%^|eiW8*RvTpo2c zmLHR`oe!`UEi`u}ir4o^mYRDya}c*SEd{bRag+^ zH?NH7^qSaZrxJmh-53K*6yZ?dI-QgCy)hJnSbKj2Hlq<6vk~}tGclf@8KdLbEH`eY zl2v2d1{3FzR9AmAV^~#(vHpEd^wsf(5M7c2d z9!7uRQv7C6tUZY$^6Cl{>!;aNS$IIP-~EDXXR>tVs2o{=oIb=wlFs1M=SOKm)#2>Q zHI%_D;>yTlN03-^<0#k5mssujI*S+gwj2IWC8o-={{UwdZ6|IeOty$h?)eKsmrPik zoy>H*^#WsW4`r{!G#s(Z@bWTrnE1!1uq}TrWwyj%t>4-I!~i4_0RRF41Ofv90|5X4 z000000RRypF+ov*alsH_v7yoMk^kBN2mt~C0Y4D;z%HGls_IxZ_ZuE3rexRLL~R-{ z=6 zp8o&?N2%|E72N$FS*~V>$Fdc#nMzd9>Kgl+UlG;jP}uVZK;mR#U9Ns0 z4qU_ro@U<=fGN-V=e%@8v7R6Xk1>COJU|OO{{V6QC*|-9ae07dp3r0516kT`?qV<0 z{bHaK*ERc^d?KgjD0_{e^#p2n9SqNGa7B~E6-SsMT=)12LtI1>oXQ{@LoGLs=#*AA zkM0&la}ZWb{!!5xq&Awp%2RTO9%DeVJbH<@an-({i~CC8`Y`y zO6FmHCxpzSvTX2A(jcEPSV3LB1r?2`jizZft1~@VzKc6 zbLJWfnmt7=8MEpLX*3msCy7k1YIhnWi>TgI6*V0}Z+~$V#jbqC0+=rM#0Cx7^%Q5% z_Z>aKRXaujIDn4eUubASb)BV@d6?gcZ*0UTqCecS>xdMr;y5USCy9S;lUuohxWCFE zDmzGP?g|{k_Zp>>(Levh03{Fs00II60s;a90RaF20000101+WEK~Z6GfuWJH!O`## z;s4qI2mt{A0Y4BDa0X#=q#!16X6@=La&Q*-n(ZBI2m-`cKPht&W{wDD2w?=iivDIH zCS{tO`-!$O-aQh^IR1ZeQXk~X!uxRns1G2Fh5S*`LZlr7A8|mn@=T}=T@o%+P#_)X zTj=b}YOdTIy$F9^4T|_Ushx4F4j4=PB}`kDS;66rbCCsa;(!3+YZmPe;8fMv{{W6d zd7G_vFUmp&Rs~)hLLri%I~@N2NLETIQRJ0#))*)V5H_F4fqxfWnBwQW{{RvTrBS}2 zSZ<(x;v;syQ5QDcx~7s@0TmU;P^zF<`_C0)aJc!X3f2WVem)f-VQCxqzi==?Cbzp2nCpWCY`6GRFrP0w7 zy-;0ycM!s&EpUW>f~s9`{?QRqxvPkhQOtPwVp5T{Z7K2B4xVG-d$Gc)qTQXRBaE>18l$>)emnm3WQ$;*UdAl zn8`M+gDY`T!a=bl4{QBP^e8}8yfJTBf+2rS(p#8?yx!{Io>_$DN-Hxr%5!uJ06hUu^+*UhOd)b}&pDZsL}HyVuz#9^*np*Ysa^uQ`Dm+8?67HPXy z-u+Ji9f$Ex5)d6j2u(C6sg98c_>WLDix!0U5ZU1V=4VA%H?-Hu*?uaHvZ#!VdO=hG zDNxL~LX0n{xY$CdPGAtv8Su(Brzl=tr5J`JydAK6WtJbbZIo8VszyT0@_-(??Mk)$ c#0Qi3h&6=Uwfsy*$ztI3KmXYP000000GglmivR!s delta 5541 zcmV;W6GNv-$;21AmE7PDc$28VUda01Zh#by4mp1%-PP57&#%rozjNx;z3AAnW6&c}P9Lk&kdI;?0UrUC00X8H000pKLLduB z!eA7@C{Uxo>;_0O;Y1^K7^sMWFd(cQ0DlV{06YY_RVZ|!V>MD?wT2O3#4rMM;eC3A z14RG;lmRgCQ04)sxi}dEpo~$5C=)u_#B1%et5u7Wz$h>jO@H=*qJf5D1R8}smC`Tg zsYe5q0=vx5=pywKN*H7T2Be7n<9!ApDr}-P0T3~`Rdl!-AFIZvT#QjBvz|L^XPq0l)xiRrKR|d0!b3fFaa67ta7x3Vo8r5e~&BGjufoAYwRCi?^P^ zRX#=-pw{;Rz<&TR0=tazI-zWVGW3MYT+d%Jf5{(9w!>9VEw2HP*HO zaI3JUNG@>^0YQ`tW#F)g)3a2INZSGc0)n+g;)!aeMTf%)&?$)+W!YhBrp6-7StAI5 zh@rrVH=h>V3dOOa`zuXB67iI4Xg8atQ50hUPzLKyOMgcysStyzzk;(e$VrfH%e$U|`J z03af^{Fv<3D1xh37-JtD5yRO%3K0MS!KxEdwSR}eRWBZetUNA-%uPc903+B^ES+#N zjN0`N2*H_Jvhj>LG;IV800KBtjrNvNpGuyb*YWt`qwG< z$GgjPF>FHF%T{i5NDW7GhZY0Ctnur1k+|aHeHmu0t2cDqyssCkSyeQ)AOO1NwF}r`u#*jKJyDzJEF;>j{95z@duRu5>1vMVryj#m?xTK=eQW zBPgh%b%B*A{0|Z_Y&s(=Fd>DWf z0Lejsuuee^0TkD0g)T8%00aa(OJkV%TvCTi@!tyV@@a~G9dQDJo#(LVuSSIZ=6}71 ztJ*@QT2)6he-Nxc>=bk@Z=I+n=M+O&0Bk;ur8aSltWKr*`zm=$txnr^qE_GXqJ&{% zp`X;4r(KVR&ecKNDEnXpTaVZLSmbJ&=4tf(?dKv<+^zINorXgJKtOPyT2N`*+3gZB zTDH4<(T;NsUjOx+=eZ4MN@~@%BEEv9`9|NEu)Ro#PF5lb~p< zq(&)oYjPxW9F4*g0~m&;iF~s>=~#_GXdB#eslTG4Dj!@V7jlF%OpM^DQ|NA|LAW4{ z;Aj=JZ+PhiK!FoAr_5#nD6GXT<`Y!H6pi^bst~3U);8h}VeHa%{aQh2Gk+(a#3s|0 z<4){WX+#Mq0}v1xMcg^T&?n8DW|Pbkb}O``Mm<TZ)}3Af;?d?}SlVaes006;-8lJ1B~9>XfT-Q)v?bC=^OvBtqL>gtDvz!yN+> zGvf_>%9w1C<_&X9$o8$=TTxV{M0r3`2^*RjcYFVYID^pi6^WuC2$WL)0C+SMp-w{v zFf=o6_R!?OKXOfi;puT5m+mb4x!4`e5d3bqV^AjxFBD_kBmlT^0Dq|PvPhiarwnHF zO9)E)m*k$@&0L&_-8=^f|D)@MZoh+>~0_3)fVy$m3>b{M0Fq-vDS z8l21zW|xb_V(|}vkAFb9-W{LuCgI-U4qc{t^!^y08$b< z|8~MN{kr5ylH~Dtu2`TAs-e5i3qPFI=Y%O^FeuY9X9#bZ94h+pFKeHys3{SJ3ywu2 zO1w4Yv0L8D?lh3|!H;&8?L6fYTO&JA2)lnoO8;~-XUvy7K3KW+4MK^41pr`-5vpCA z-hckY*L`(_=YN8nUfu5AV>bzW?Vmb-c;~aM?dzY;c+bH}KbbHD3uBJ;^oF zYFF9+e0)2`P3MhfgYD%{W)Z?`@OyA%iqhhlf!!$FHGeRXGhpAzZJ&Mjra>|_O~;wq zpc>K80#rRt94Um|Jt!&O%ya#(u9&N8Ufv|C_sK;!Xr$SVs(7>b=;*YT)ILV=^!SdP z0hP6-e_na7C^T!D9@T|7EC?Y`!tMZK3`Tdg4$9zVhKtufck29M{?RIgaCyzyRo}hE z8PhYx)PFzSOj;y0Ae8-fP?Fs!@K)8QbNPFSUZs}jf&hSoeZwxB5#Kd1iEE_a|6|W5 z7zu&Qws!mb|J=KhGhlA6BP+qs0sxHbW*?HtWBu=~dAzv1z)$W*{JEeoeX4-ag7N8m zBYkbfTtNslnGywQ*_M}T>v+vcbB8%-BvS*%Ab-Uw-P$*SGiK-EjoS~dLkRl?z)vDZ zXjn!%b5NqykCEOJ?4eFY^Zw_e>nSD8=S1QYW6~mrfI&h}k4@u{!*i8IZ>@f?IYMzI z0E!IZp^eo5Tk^DKY?qcRYiYZb#EX>+U!@zmX9_)@A6c0 z#{6zrvW}TC1Bf?^)BEs>xcg3gxBbvM0e=U2)J_y7{Vl+w(m6wuWo`@gtDoKzvXNe1 zU3qfRL{4VV!6ZI8HchX1Y?AOZ6L_q@xct~_EAI{Jx+KBSfT!XH7H7aTSR=iuXMC?z zu91H6SZP&J_!>b7xxLP%8~?x=lNoQw>uS@&4hAY=cMnc7aT`P4%zrR=S7Gtvf`5#d z1!bgmlfXC9{U?9e5sZ=gm2dWZy5;Bp;|#dHe?r%=gTb^u@qN>H1)ogwSh&M4>u*A1vX$q80KjfQ0e_mWO4wb4lFVEqeS7soC<47z8dabE>tvNE%?+>` zgeS*_SSB*dcmdb-pD8PN=ktd{xNRH*W;G@GaY0GuKmnN6JAOdAA0s_maUv3#5du`_ zty!}ESt^5a2gzqUKiSnwgZmRV>Iks=oH9tW$=B!DIb*gTTzjx^ zd&nV;FfGOA4*<&8wFx4ZjDNE^Lz4Nr{nLthMmY{5FO-tsFS(hsn{Scve~s%H2rIQ3 z{J8$(CHoeB@pw2koe-C5l9rp(mI1zxwIiGUpj+DbY0LtVs9-|Nde{bpx74u1Ld&&xSuCUx(S+c~Z|Udk9eG%B@AB5zaSg}>ifQBx9TWg{nT z7@__E005KJ#BmPFpu5BPICl&1_}P8$eEtY(@!JU*Wb?8uFY}Y_*+Y|irJ5T1qWX-t zZ$}=h*|vZ6(c(Sf6o0Y+Koq1zODERouG&o>(!;jYEyvxv&$tO;6d<#MJR#dYGRw;U zjz`}cQ(0RItt1ws?d=D*Hn$sIFF&7gZ#n8LDDwgUMrcrmWm5MJnen{tih|-j&wV&u z7Q;=gjgsZ5smlc{1q6WIZcj=|0)T1{iIcGy0Fik9<2#QQ?|%-t+N_K8?K0}A+ZP9t z>sEV6yxIRxrIbAOzvHTE!)*eijAo|~o;B)a%7}j#1OQH_v;L0`CLs{*Z{3%F?ChS_ z)jk01IreS-wuJ$N4G2X00Pu$oZ>bE^_17~6qKxT1vq`pwn^_~w>-7dWdqMG@_trcC zQE;3~z~buf-+w7AJ*dlU>vt_JD*IKJT+(hy>XJB+HT75p+#I!VyWIih?warQRrm2d zZ%YbB!gC)^uk+T1InUnX-!9$o-+C3YdUP7zT;-}+cwH`+Utj7`T#x@{9DkRp6$GIL zOKuKlf|I3(-u&!AlR=+cl2EO8MqYE-VzU4!io*9oC4ZHL&n%f*Q&)ka>^7DNP({tz z``;dRE~H(cpN?!^uw+W(Xc;>HkxkjDxy_nvvu|KrR#w*By9WxlKmEat<<7GZm4Xm< zd8!|NH*fdREdd@os1KDNZu;ZvtL96BZf(De(aD4EYkW5E-}wRO!>XzhLImLo!f@pD zzy7xQg@3|xhgve-4KYEJOmE~r(AkkQd*bu_W_JMidiV0RI~G;emPn$WeRf9K(j)CU zjy;K7^jLLub)3yq=dCSs7N0CVu=SVxg0p*!k~#Xde=#QG(`5wDQ&sLPK2W%Q%g@Ve>MCW?sDCe$ri^xW^fJkDoQ6?9cg_{D{KwBG zshWxaq1b;$3}cJ|yKwL8`p2Xrgd#?u70vVfo$DpU%c8Nr2(C`(GY6rzp#6G!jS?udQ+>XxUnc2QAXy>@XMzBr+Knqnla*OPH$|x zG=J&+$Ml(z6qo5gN(C?%>5(=nJ}$Lgt$~Z#U>)0IPUGr-C;-&E&O1ge;Ix6X%N6vU zD5HDbA>x3Ni9jn&ojUXy*<*UUas!c^^g-9<%w&N*(KJv1DAUIFoP`i;*RP-Dulc47 zd{_(ETLe*SHOsd9C%xPDZe*!%?43URk$+_CH9@3`L6tQeab5anjirpX>$*wFNX!|0 z&CP+t-cSIjm)nLdNbS(MUDu7pBwPMt%qzieOa%=9A==$}FNS~GqV377(J#qD&>K^s z?6=uW$q!6?mqEKD`Zw>KG3u#~@i`%UHWUCDV+odw$pi0GR8PD1RifneytPlq@qa9& z&=~TLGaK1$#*`uVwFA&UYs}O^PlUXK7W$UIMwOA-cZ}%qo2xcMrj%qly5E+&z^B%Q zJV{tR7mTr+`aL|P+a&Gk!+=tfmD*?i_;(Ss(i62WdO+Wdq0f%$b<5QTKvr7s`QsO= znlH?Gbm%%#iTB3758NM-$$zTm>)mbfP&M5;P3CHhWEgeVr}fvW0?H?0D(mscmh;9Z^QJQh)l)%6m~j z`roH9A^_A&X>Gy#n;r!g+wBx8@y)#MncnH+BIVU02LM92PH}GDw|G~PDiq9(XmDiqH{nP8kWk)4ZZWS0*q9ofpP96M6MnW%HG=H~B?$SB{TxJc% zlIkP-Pi-qG-F2dLpD0L?c1?t8D)D6`fBzC zzx(*tKGp40J&e`gNFV9oV;CTWB+(#?rU6~X4$r=|gE3VlN(;o;m;vCDYpOr{=kit+ zRs3?Y?3Y8Qc6fX)jDJOpFh)3#)S3aKlu$+~C88i@rw`0YAKoQtfZ1R(%XWltRFz4h z3xEc!Nx-5YNVVRwQs;?k_xY;YQm3cfqtvLHmoSY`O(P0rR1_qP1W7O$M6)cKECzeB zJtM)ImSoN7U`k_*YDA+z@FED_#u%0000qzHQqm0FA>E9Mba#hzcMS|P z@4@fyci;be*Sc%ndk<@vGr@Vz^E`Wh_THbpH=iZHmSN#r3RpW~K_HN?`ce4YxG(h~ z5dU&1ENoV13nv=}aRv{YHy)mDHrD2rE^in(87zG~Y+l$n+j-bCi1YJ`2?$rJVH0D~ z^YikG@dlW3GQgZH>}=c_#EtzJ{&N9KH<*>9drSxpBaXvso60gAENr|dothActdbfe z<^Y!?W*hfm%s%ej$}3!48~`(kS%f@PR!~xaU}0fHsKFly=8pik{2Q1p1frzG4!H~7 zEG~o+3m0;8+sfdB>ObdN;Q3Q5oWJkmfaiSR1qi@rBk;iwo|Ayj;6)(5-~+tu-|zkR zSy4$<;|V`Ez{kri2;t}D=N0D_66Y0p!p|?xCn(M*bTcg0t-pVA^9$>LoMVGS-VC=0 zK5+gs{B7|3_Ww91{U5i5h5he!*1+#z|K}Xa5552o;4V1OUC95j3O6?j4vCq8$U*Mj zzJ2F5?%g|g?%?6w#U~)SPjK%Z0R{0RLJ}HEI$9b^YU(FU+^kO+I2oy_pNg4-b#v9s&9N`{exe)b#xS^8o(mi~q-S%nu0B-J6@j!D4`5 z6Jg;HVPSql=)fDr#rk{vI~njbHqI^F+js8b;ok$lQ2h`Bt`!dUEgW3jTerYZ1HjKA zw}^0w>G@=CKhm_g!vMIF@V|@7xXUP8{*zQ|=zvMU((OGS{$nz73QA@c)~9Ujf*(s~8yFf{S=-p!*~1*%Jv_a<-}v}`_!#sl`16;L=$P2JZ}AC< zNts#MIk|cH1%(xrRn;}Mb@dIuT7S2-cXW1j508wFjZaKYP5)T}mRDBS);Bh{4v&sc zPS4ISke4?zyP4^KkALU(f14Q*I5X^9w{ULVxtSRjw)f4{iEiQ2^W7$v(Y#~f`iO!5 z-CYvdsEqQTc#HyC2c(v6L->!G1phD}-puXq)WDem|1YNY{{Pq9mi{}l|2?s32muZj zxPLfA5GbU#p1jVb6+r5J`nt+lHgN5ZwykuwUU=OXW=9=Jnw70KXs}Rmy}Y`7EVM3n z0r%M%A0a$acrKLV(JSaj;C&1|VRzgXabp=q1>CvNc43b8d(Q0DCDG_NL=v}iiK{3k zdd%J2ZL0)rzSO-oAsu6(+rvOM7%GEVNpniRi~q(z4(P6L0Xj8Eik#>oDlZ^?PH4(m z=FXkX9fyL3gi~Npw}jL7FhC5gP=L=p`p`{&EN<+?ydXb@^~|XGx7lloWv_*$vqHFi z1uH`b-Pu&(PYmQM1qK3bGkmM7tgbF6uCwgpdu~5C_UpR(JKydFzHnAW!YXH!ETp(n%53CEb^zkyKPK57e@zCWwK3ZVCgDDet%zM0;u^jYe;YzIyfH=bBaTdZ5Jk>#5`k zC($W$^P$)s3}kszU>{X*WZJX#u*BGd3ChjjUHWpa$a&5DPsB6dQR(V*L`Q|m# z25r!+jPTS7yRM#LAP$x1u0}@gKE450L@7T0fhL?S;qRLA$6$2SgeECn4tgkyN{87yM5O7Ay z?s}$LU7GGm$D*J~n0E-A7WOr-PYccrt?pjI+tN;BpqFbXc65qs?g9of16_m3I*oqc z8h)SA`>lZ@<4p<`HU{(+Omy4b}>gLEjt_caZGv@HpbFSC5OSrOo|Yj zv%w0`O;*&IPzs0MF9Ykk-@^0SK#OttX>pvSPM6Ws1~=#8WWAYF!7k`zIsk7rOe}f6 z9>K+R>pQa0z5N=|rXe);rCksO%-9x2>lvM}5W{*DPLD7U{%dqPJ*>9FI9u$Rvd{M}XytDz|(NSEw>MI2Bc+~qSs`Cor7x6F*?dzP2;Gv3z*_vMw{XR+hHeTz;++e?uybi*~)2Y{@#o;!&kTAS$2Z%fpx|PC5(()5H zI$trX0O8Iy0|R-5ft;|X2N@uC-V0g zRa9v3KwrX@(dG zWxSSdq}s@+@SxJuE zI@h1GxOusJ1)aOVVKSv$0m28 z6q*hWyzM@#_nfr680h!}zuD`A42iZ6KqS}mEes@E`}@+7z$scGTD{30+}OyvjtL|s z3;EYk#D_H_v`Eh>7tH(+4F@G40oP$8OZbyawE~*hq}T!G z{&oqsM)Ku%^BD%a`f3flEo)Q~L<{p(tLJ;}4e)v;){zXlGt(cYZEr3k4|7@~yQ?d- zXL`|=`R}%k2w_5P;qkG_h;eV6<`=IYZCF|Gh_~pQ6(tB_*Oj2TEYyya(A(3Ay^eO;%u|;Wq1Nj?8*t6q{0ZGG0~ee$ zBd~t>1pJ~Ya6+$r&jDsC(&LPQWKjwh$k2(HTc8D#8lA`X2-QJMNDs+{``cCvsoYCE zHJk^Yp0mw-s3ZJCd$RjRT1R!(Ay3RB(DZZFcY+S+dWlAf$~}o>AH&s1hX@3(bah

Ze_LUinENI*}2(xAjq3%l;E|Ls)X_|&yz9wsH`7Uh|hq>)tIUe z1rNmH!{!BkY)skSwC&(KdV(P0szL>_5Pp#G$(3h%DiK0lK3COpjFjSrZH1ORdRmOs*9 zMQ&R!Vw*EpcT9{8(??2^p3S5ttk9mSz({T9lty^e^WsrkWQ_KidKKTb5t8+Y61+09 z$2E2nz;QmXs9O27-}mgShzw;gNxKf}bI}apLfJB^pt&pW0197|d)=02b%NG)o?KRL z0dEwzB$e^|;B`U1*&Yz27I_W=e-KLXmyVmj72B3}uRBH{d%( zgf0T0G-OgiWefM|Kxc3n12JG92eOT?6r4e?J4jb9_;!f{aP%k{jdPWj#Tg%-2O z6XxNgT^99Rs8P?lXo=I43W{vAqT0(btKx;UN?^GNO|p|hy5PpctY=bG&h$H+77Gr7 zI0*bT)%OaVPeNhLui(kw(FetWCpt#ijf4;8vKPD@9LuBJ(h1F10Ct*(bh~c^M%F+T zQZ=98advVkzt!kIv3lqGX?|6>+3D$XEu~tvxu|Nz1GvMurrF>xV)*wV4$#0EQwY#4 zh=^?(J-$Q9T>u(l#0jG=m3o66vt=g+@&*Vu|1`Wb@odz{daAK|rc(^rTu5Rr;I(J6 zPG=h(fDp7kG!h3&72tUh3r%RtN_V5AMjX4Bd|^KDUY*uIwsC=?zUUwhtmMw0n*&FJ zU7xz90{BpcPLj?oVF5r?Q9NZyuZR|dFj)kzlysaD>wUi{R%S!DqRq?jq2yNsPqymN z3YAS$58M`V9F4ZLXQ8p{^bIGMmwKW(EU~%?o4H#`U0%Sos>FL^g(@bGg#i?PWs$;q zIPD;S0DU(-Ptb7CkRJM0>=p7AszE`~9F*sZUYlP=p`2}+_ew-ksA!jHX<=3 zJNmDYZ~ECM4hi4~WSQ)C*d?>@6A4ZXWJG=ax!qfC+#15N1lajN!+6{K-8;QM`u##a z#-#zd(J^k}W7XH>GmN2CC?G1|xS)WG?wX5m0;!`#m#~z#V2$Lx&JNg zh4H{XG?ZpDOP70*Ndj0jM8`RClmIWR*p8~Q#!io)&evXA!-J1VT~z8+{ETa(rM8c3 zysadYtZVfwz4#4Xtis@e5o3~CGQu$dD>Fy~aOz<-fiAwEb9Si^ZmTRCPpfBYk#V0g z>IMskuOv%fGVxyy_)br{gV7(d(&h@>NUYW;n(=7M)c*1pGAd#8?t_ zVeJpNSnDJ5m~?mbadhGTs(|9RAGLeMV5BgkC)oE7;w)_5ZXW55#82e-r>?7^aBCVm zSe{pI;CvHI81-RSRgGMMeih+q@wED)IsY=s&>x|#W)c2i0gZdJp?1E*vCe~wude52 z1B@yK`feNp0Q3xO2fhF+^dqQ6T~$J~953(#aq>vdUttPy?|R{Y^mcH2r86*pqaKbt zOVlSA$Q=5`r#19yt_31O^hc4NRu^|@!Tzh|?p^dyp-3n3*)#J7z7H4p&AG}?hJ{4z z&)==OrT|14A_I17#9;v;FfY_lbZ&LE=ZsAr955Gv|JHS>nI=TO#y~pTi?`i4reJN4 zEYas->vj2>$~@XieGOk5YEgXV>OY#pu0aXeQ@qp$J=AbX3?!%H0*n)sc=`miuITs? ztLHb4Qr0;V1ChF~LF%WrWQF#l%t+F@(9}RPwU`$Ku120Y` zn$~V%*@v!8w{P~rk9($wv%#c#=G#hi)`(zd=zf&u%<_&msQOmO zp+aIIwtDpb5y_}n6#aLm8EG(mSZIGR{1?zs@ncP=n7F`ti51!HPX zacX&%yUiplPv(F^*-5qOgjs67({qt|T=NeGQaiB3-el5SrLx2he2ZNeIHvGGY!WWy z9TheBe#kY)c14#Vld`1!&jyf7rJ!@)$$vi6gSO43`wj4oqOp;IpI(-596&2UeH~F> z;}8+b@^#OHtxxo#J$a{+^e!^CFZp8~6Cpx*`KD8)St7|cYtWv7Bt;9uuGAkRr`(=+ zO4}VrB=XY)+CZd`?gnTVuEP$LnGKwpikDe?xwf|rrb?u!(_ytWW6LRa<5}VXxlqtv zz}1;BkZ@x)O$FEJJS`=pw@qvkdDZh+sD&>^_GC>{~2Hawhq9)A8$O=$FpBvlGp9qezN161-U^;ZFknyzptZx0dXq>^$2~OEq0X^-YLM4eoJy- zja|n`ZLOk!LYYk(kwss*wh5(MeNl(Ad;bDp_pEfPliP%^D!IA8UI;!a02O`VFwnd} zs$yOBuS3#bxK=U^atk0v{eY%w_Yq%cWE}RaBFS7jg~t`IF_1NO^8P7(8i%&Ns>&Hd zAC*RFyVnv!4-(&0vH|wr#nwUOq0D={dQR~xn}pH@v1Zrbwr&;KdQf!fmMA!LYKCZB zJ`{{MQr(FsIBbo5^>PmkTGY!2tny4lgC_eb?K{QR)8IxVM#)azB!%)rnyTiqbUUFt zcAd-DH;#9_M#S@1uZU&dOZE%waY!VM)&=bemPlEe_O{ppJ{^ZTvVDT_az?Y=nr;pg zAb-jKo-W~~UfgL=?F?OS^JE8w`O}ow>?vL%d@V-Ocdle(45mF{XV(kypp=mCcu}SY zUh8&oN1kxE+THT=*W7r>r`{29q@0*2bq>7FNv0 z6;Z0T>x`>6zJQ1V&XpxWO28hl$O10`Q9?^|GxGYDwuk&&@juYN216Uo#s_jANWNWI zb^-nV0Xj`(WXNemZWOl(bdtyRB%T8ueH}*KDS^mv7_6pZc2hj$nTXg?-6B9#sMVBI z>&E=RfK5yqo+QAbsBsH6P74P;r7WjMnwl|p(9(!yJ)w_pUI}ijklP%)L5Z|7M@{=! zMY~-!y)lqaHl`A2XcnFMiUUVjVlwKiz+(Y47NLh|g+%D(844Q5aRuiCFp!@8_$`CV zJ3H~BHw!h!Jr>vzYFu`4=U51y#)b&G1^vPkmF3oPMcL^^bwjme!u|Dvr)(RBcb~D< zp-?x0R=&Pc%N!aEuIbDVGhLm>P4DJt@vW(zT5k0<>ZO2Q@r^?pqpo_U{}w1m_1#c_ zMqZ~g;JZLbyqahwsPAt90UgBW7oc^G&lI>Ej~zc!$=$pnV?w50Z;O|jN|c1Zy+gMR zO?}~H=dS!^UU>hK?`1{ZBOZ{aIQ*kwa`<|A6P5pNVL%&x9OAj-TwB2{M!vuEwBq%k zzC&5_3@TKZsA^m!{{yF&)v*w@ujxq2-J8Dz(1JA~Jr+J`0+q-yVz$PoMIn;?ZmR(Z z9xZfcv~e5k(fw?fuCsQ896dI{k+hz6@O^VrSy?zqTY+A9aM_xg{q={zq`3~&HA|D8%lXov+^*nVU{~x zv%X24;JWiGaa9j_^$UBQ3&k`5UuNPAJnEaXk+p*p9y94bmM?1U4jlSO)Av*HXMyG$ zzv+#Tkhm|Y+^%m0x)uYWS5o6k0YIlWi;uGD7Hy!*^{wIU>~N)lQs~$GDllyPk_|oJ zxxO_XdGYDtjqvjq=kY(%FL4v3QKvfr89Ld*2X1Rs#T_W^%W@0=DTQ9rJVmLmnX3OO zi(d<~`buhA{9Znsx%X$_J`KRY2WKwCCT4K zsJZ(|4^2}bO94Qo61f+cSz^#V)Fx(zH*@XKU~ZB=UGWlVcsdeiLI$mh=W3uNyX|O7 zJZWX+k2(NCDx#P4Ufx5$uX0)Q@d$+qe3Jm(t#|l6)DIo9PxV-0opU@(rmFoi&6WHZ zJ055(-*LMn^ff5XD<9b>=n0>Zh%|R8(VdV%PuzI90H_#FU%^Fb{L7ZY%3$RwvDfb# zhkNo+#Oa&*rR^SbQi$!mr^afa9`J{;5*HLzZp9Y} zu=fQmhi9SKqP89hra$WVgC@lt_VFgD@8=u%qbi}O@FHGHzP|y8a=^=}t7_mEUJ?eZ z-b#!Sxat?Hah5?B>3YYg50!nh#g*8Uc(!FvFWO4LdjpUm#p(OxOT`Y<@=lw_RwwyR zYTF;_%vYbaKpT{de6s%?(+ZKhib zrF>T2iaR4Zcg`yiv6g`zR;_!CfkfQoAGqRCzNWwrXksCG;kqmEzC0-hZ!9K0swCib zt+;&U&a~Pd5>0P#T6)xVJKTP#1#e;Ix-fS-b=fl+dO(CG*%I8D*Xrcect0NzUKEOcm{m;wt?e!y;Z%e_8 zfYW?s5ibk2fhabG9<>(RC!0wVqledVc|;3+phyH+6(AjrH3O#gQttdE8%W}R^)aKK zqc9ML($seW6dfRED%GClgWK9c-Kb*~o_=--=sae1nzh?Tg-d9VBjTQ~SV6yL2xsKE zDzodBFoVA8)VztQu}N`RoqyBI2d5GD9bkkjUsgF9o#zE2jUulU9(7f9ogNcjXvd{! zztU)8Wxjj%c=O9JXWgR9jg-En4jCFPz1859J32`PPz<;l7L9634Q|X2BfRXlgS~)q zF%Tne4EZjP%T#Gk>7OIl6mKEgvSWuBx^r-Y)kh9E%LuRFy(5u_(nqZ5o#uz*jUyNB ziIG>%qt~*}zIFf14DME+xA1n};}9VYTt~|!0oNemKUlyrZPSgX%rnrq)18lKHlZvp zfbgu~%pmdKGhVG0oJ!tT&^!Uqve6g#KpP0_OcfNBf3;9RheJ-yMn$6CW;V-?qQhO| z%PwEvH(<9Q7fo6~rF(<2vQk0@mKkz#uH6%51LO&6Zcmz&HkiC$%j=8i*qN zz6nZLF1%My=LC__?CDLqe#!Ta)BUKc?$XIZ)8T%qta&RE-8!ki ziu^3^P_7&b;OctKM-F_SAv`6c_LxESX_h>HJZU)VL+lLYzM-GTHG~B8LWFX-VO^J$ zA{6M3e{(4ty6}*pI>sy7LAxsqBqDauQ-}5mF`Zae0aYPzC@t0WQ zuJCqv;OhaZ=x~IP=<5LB?3e{P1D7osxU+&vb~ zs+Cgw+MZ`XA1U9$tG>>5bbLhG(YLQpUd_^3AoTR<_DI&AzTF7)6CKK@;Ido>H$BL! z<9HE__G}i%R}PJYg5cAvN1Y3iUsH~EpPBR9v(nj#Hr8I8@bBW0u|)!_T3f7u_{VHN zfL>dMCcVy_-E?=-iBVFAY+YoSF7JpWyM!=NBVNd)cE=$?tYl@R z6qW44O2zO0YifNyDH7qASdVxam)6- z@{X^K!Ff2qXj;MUw@jR)y2ksVeQU4gX*JQKFFWiF)5ZW(i2S_zwY$*$brJ4Bcz5vL zZ>8f=Jtr92wCAfLiLcXs95gXC5qY;mD2e?v9fUH_=$3&_7w8AFsTgF847(ZcBFXkI zD!$*4xFG4Ye!dOLBYWC8T2c_?8BC!G`A(mB>I*AnYY%gKpU+N zuuL7P{7ph4IY9a_S2ca7KWrk%FqD`r1q z*@U9nk5n|0I3r-dt=$P)D8g;MeUc6v%VOSzrcRXOQ&zhTk1@w2FqUGhHt9!19_6#P zzWD8@8>)V~jrP+aCY+~?Kk)B~JPZWP3o^2P54X96@T<)WoaU=VzJUjFAr77ZCE{J` zlP-66E0N>2_st^k*UT`GYB4cvw5lnRkhT;Zr``K8L(owLP!ejNsF)BX6^ za1B%ldP;VMUE}W>aQ0}wxf9!OSvEAi^HwIWq}qGWNFS%#k$875t-G3_8iBhz4!ITY zJjoy{uBadhS(B~u2kW3C-lA%c49IQAQ`K-%QIY-xqaLsRKss1WD}V;$a9N?}u=5vz z29-Aq{<6LnMTv*XX`I)$qr*rUZE-`PR z+c;Y|;8|l+wAEDyBA^or`sL;)zd`P?NJL}0dN#TA3?#X}S)b*fw9V!JmPT}r3J`R6 z(8lRkNn2OVInh*ItDGJF`lfHD+mWC)u*leKb7(~AA80LdSG0d&4F)Y=-%f)P9%ke{ zEuv>@PgP=*{vB_JX8IpG5clEEr&S}4jXaM3 z&=|b}z=@@YaK^U4eM9&=?2fa?Fpw2ikwEz6-MmRu4Oz)%B{C@oB_{@8`SJ`}3{`{7 zC^rUj0cP34l>ma8GhyEDMpOUZun!S3g{qR_V+a|2?w?Kq>Td3E0p#eWon_8IAFXZe zHH8-Ngdj^u>foN&B8UPSzxmilCy-axiPVRvAjL^!GSD*yvNM7PBLkPXN0&&Tcl@eDjzdHx5`)ERNr69|hgkO1w1+a^WT6#)STQjGSz#rK>=yLO`40KqTk zXk9<8m>BhQkG;7mV&X1E-Fj`cwo0N2@L9}FxWozI=ZIQ=|>hYl-prm(pm5l012Su4pc@Hz@VTJc5#iWjSpJYeEr6CFL|5GRHXRr(tbKCX<*3}AZ*zOV+F*~K`Yu~Axj`|i02&i2J}hiO=-7TS-}E?!NT_^ zB@!@N8sfv{S0Y`YGp6Cxm8)wnFC$vw9Jau&zK5>%MLE^h+$rlrwLKG3>0R#!vq*{; z+NTs|_9ZLs-y|vkcG7y&cgM#aNejbdAQkpC%p7Eqa8hEl09f#~G!Iw+5E|wNgML`k z`kQMuD0Kp(dT8%>fCEfZ@YkEcBM_yH!mGZ-+9cC~>O|>Z(q>>b{IG!AZqhhEO_f7+ zk{|F}xGpTN(U-K9M(pAv0?X|33>mtjC3|UFmQjwPrv1HGU`bc^G>eUDSMGB4l$Ac? zmEJ4B0|`1gDz7F-T!3Bpao#-aJjU$#_G3lr8zt}M0g71iRn+T?7#uKf!UizaW2;{2IuD#sf${K{fT<2Jqo7w*-Y3)#_inCr znu>tz>(u8kTL*(lAoI(?=D?W}&R{UJzQ)eMdw-dm6u8vZblKa6l+5!KbjXAaz+wPGRM?nw4ug`#%g$sHB%IqlLeaMmyUYye z6i~mhI+vt2cp`vYW{zNr(f%AV7A&zV2`Dm?58!m|3No=;rTs8n5np21EQUyk2zEKj zP|9z7@H(uJnK^(C*iegipEc@dcDk4Wr)ro;nqjRYFAP!^N9(8gs2+m#u1>IYrm*E{ z?iBv$7Fc67=?79hEIb`_=VMxZ_9n^hxf$=gPCL7#uD3cGb6Zx%g&6aKoJ3)D{5(nYrK1ijLVRXPcXn z)v78D)bJM4QjYgeiv^6P_vhaMjg6Pu9~`(c*>l+1pwP~Mh)O@9X@%j}?kJ9pfFf>- z8bHrnIbM}~l%WH0BqW&>^qWkp*yUY^#pX%wf}qs;XdJEb{L<#-rv$tRH}P=9c%|&2 z(cr?Y2~#NJ3V|1C0=tc~uI1)jzy1;TTo}yg%}wU%l2lXk8+H|s47&IG$@Tg%sj{>U z^@v}F_Ow|sqHwmi;bVT;QJCwy4R#58AiJTaPD4bbC*ni1VgdXFDX@zQ;;OXl-iSPd zrV4^-#Qin7kTbl}o)hW@-ED%;AnIY8ALh+gw^a!rR61GDwPS7fY4*^b+Pcj^Jkm7C}LLEFF>Rd>pY%ZA3r^JWGLxG6b1&ej((%VU zx|eaMgKb3 zNGv`a4nD}}xTruk&A<@y* za9R72kM${Wr#5{rANd=ktfO#QLf;ktqtx-24^=4!kr_;9rv1tq0-4lBkXv{MM#EJA zMGEll$U5^^TS81g?M#=|wS8U4y#Q%V0<`mv-3mt-oo_dX(c_`tXODa;kV@?jhUYfI z>XQd`+3J{($@&U!gbGSr#UC^SU-R#mq)8it5%0_+J)vJM{uaisDb~q%*qBBQR)yHV z*1}ixMxZNx@WC}4rEJ9|V7aYKvdMmzFJ#MjP^Ty*Zr>Ie6_#TA)NjGR)y zBDuAEU3EE>m}(qVK9Eq|o#{XF8@ITLi`Zk!#QekWjbI?eMTA#iabJd>mrseFBd{|= zC?!HT@6Cv)<`qtix`LPWj;T5oJWQ>ROWUc<-;%wrpkv@3<_EUmgq*SDvV zSZ~%Fji-!FKLz?Va?D-Y>+_kbj!sEwkfsr_5;p7%+upy|2i^`Q)-v=; z5zFnZ=xIQ_pVDN$qA}$7nnLi=6vc$ow~+y9m{egbd|Oq?K5O?mAr5?1%ja=P^h7e% zNH&WQ*Y5g^#R$E>9}$|)K$)i&PcR~S&&HarGO zUX4e@)EUo{Qh-tXaOm}-uK5lI!lX?ZFi3F(AP)bag?VfCtubP%h_JV28;-;kG zG}aiU@1Rxn0oPP3D0O$Tp{c8_tH}Iv%g$=N+J!TNOv@+Um?}cD!cSLyXQnS5DG4+| z+u=p1OVHQ7DXrFs%iIfQ?bCePlXZQMh>6I!ml58}>H`VO*8Mi@ zrTG~H(Nx_gwSK{cAFUM-8f|sOKnuMgKXtM6*Ta{FGl>a^(x8jFsYxM4x*M=h-deR@ zFh`#&<@E(5zH<=h@FzeQ&B5%Mcu9EM?>`x;t%xUHwAHuacJ7V=)C07_>vbm#HI?gP zvCBI~Ee(k~ypu)Bc*AQ_K#Tb`eqp^tzwcO84@^5~eQzCoS-gA*O>8!Q&(lZZ+UKy) zMiQMK4R8`HudohR3Pba@^*yy-bn~I#_o@tG0nv7f45< z`s|)|Wpw2i-Flg$rGF%N%BJT?bz5f=>eCJu@41~8O+2F!{^9Eb?=OV#i{(fS>F8!o zBy(>0Z)xAe%QchYpx-o!_LzGPmc{MB!+3MxD;&JGAGh}2r;N6e6uZa{!9D|PJ*FI?>#utCn z3*rUS1v7D`L{#>YPx=ni&nMsD)rCGeAYd=+wIGuq?9&B>$B)h5?f*@HFveNA3ujP<&2hw75i@W9zNZfD9>+Tta@CxL0^o8p-!%SUv@5uTa#J@sO1z1u^v}MXGXwDgraLB**H9DY) z<(GMzjH3MQ#$GtL)=S|fXRh>L4-IKTqVu{`Mwt4(US`cI?ftxW;6Wc6WaEnK)aqv> zeywct{=1rRb=;SAQ)vP%Z!%9oBDpr6i7l0brIbe7Bv-=P{5Dk<(h{fNa}=x;mXC<> z3YvoO#Q_y8#=BRH3zs;=O}4{8x^$0I_Y}wWrKWPl6{iA~LEmj?;iiLd@M~?2s!7XW zVrw7rm+xy_zZ$yote@sBPFq$tQQW342~fO@F*g$3WTwTD^L{);Li1p&fPf&KiS3NA zn2=sv4o}FUO6xpEv|ffOgNbc`l;oW3d61())C913i#C(@(~LERb-dN*dV(oqH4~|^ z5X;zCty?lj`nunDWAKp(PG3~27~*DQL2UzDy8i9@`gd!=ouwz{9 zX^3W0w)|`&Sqm=iOoa*FUif-cp!LQ_?HVZgxaOH+?B_$^QvJ7B?iihYQF7PF84nSg zi9+G?D>4?jsiFf3Rbw8V@4rW_cMKzzwT9|PPn?7bqP$t3S;tMr>_#stFOBD#6`&1L zm1Y>7HgBxhJeo_Io)^Ff_kLKuXb>?WK5+7e#IV!U@&}{#t?wTUBJErQEZtMEe zT|*Vnkm;(K`*F{5t<#TjnbL??#LWQwD9S|?n#eiSZmCpjEgF3oGe@j1$dbh(!}>}c z)$u#2n~x&<s=~un`uaR22}l(#Di2#zmqwqUV-IL7?%WXSztfCfln9`rn$HWB{h9#GoFC_0pBHYS5}N1 z*CpA(N286Y(AcCOi?D=Cl2DFY+A#(cE`#9@?y$;=iOI{UY^X4NaucPPKxQf6Zm2CE zxdmrj3NzolHTdNjeJ9X-&+`3*+>dMgXUg=XG>?B~{Njq@8B*Jk?fgS3kclMz*_Dyu zOOz!S<;ylz96_Wxn62Sv*~)i9Z$S_kw4tn~QWd3t;&e@3pUFn6(YB2m%4mx3QhHio zK}tCJO+FUN_)*ySgyG?$o8{6}S13muBb}@v2{qWcG!#lH7|Z~iaCR;Zvx}1?ly}(< z_I)1gU@*_%zhEZ)c8xE8Yb5GNe-KL09496-dQwnlYB05rI^wqZ34=z*hFQof`&d2W z6E+g+@I^aWLHoc+aLw8OMSh%H|F+29K*S9|@X2Vpz9VM%$^Sm8{Go*#j^*LM@DBlQ zL$Q&}!!tD>=I%z2+xrD8k4Hj>xN|p*wXmm%a~$3Db0WqS${1c1GIWSH%6DM zpNRs`wl=M5bn7Xrn9`odGZhEb-w*nEq}D*_!NI~6=^FAg=Eq9Jj(In;XPVV!g#2=v zCCu6){mRWJW~TGfDv|O_e(iLmN|_#za{@dYWpr=hA(moWV_NoQ&>Q{McKW#E2a>fm zYEPjgB#Du1YtT9J&WXAU^BlKAm@$KKg+5BrYAjdIL4{wb`qPJI=V!)@v*JzgA?Yo! z+%=kEuZwu)Tf6d7E6$=nINoLfwe-i5_njrpMv->lWf)p%J}+`bF}FM`tN_Fq%dL;7 zTs`W!V-Jp`^VbupG)xPoXb*F6Km34eIn1j)4~criU=m%LrsAMb#JCvGbVg_DN-qoT zmTEI%j+6&w!jSTuq4_QI9*%@6X&xJFjA^U4XnT_lLQB<&1x23$MOSpH`pomz_D38# z`Z>cZH9Q4GnoWeShu`Zle=uPn^ zXQHx-b1S_B;Fhm}UO)LpHC^UQ898l)(m$m~D;FPyBdC&+KV&5q?Z##r-41;I@`vt{ zDRz#)AurbSt|YwPLi2;#$}yBRqeqJ73sCI3*h_$Plbhe@zGJWoH>RO!u^AS(ys&k~ zzyH93N9Ok_4FlnOq)05KImc`w1$m!`x8>j?yTy>V!P@06nYq^1Zr75LqJM(-JC-^t7)tqlGa?50M<%NC-7Urz8`5%l#F=N!WxUJ6z78{w5dOQwMEnyCZz zjHO=knKKn`PC;a-PNC;MhsO!SMCmb9pRL{@$x9Jeqo#OESKK=xJ1>MyCux3TxobJ$!Y@(Ro#jC?~ zM!wbTb11vGFFCtky)FB3ziSad{}B1`pmr?oE1B+VmEQKw#-W6g2jqUNiraDu9S>61 z8#c+zn|jlebi6Fp4G0$JMTI5JScm+()33UIKaZEVxA7}$+nS#Y2UywMMknUX{0P0< z)<`Lv;N`;-{N_u2p0W!U$*n(9%)e6a)v(^3DAnFbvj}H7KMN)2a6Ve32IvDGO-z0I zXqI=^aVN-uhev?KdHY8w%jqA%_ekd##--k@^FDSpo42J;<6m(c1##wvtJ#2^O-DSb z0&CbQIOT#VE~OM32Z>@{#C3w`#H_&lc;c#^&Ecn};aC-BW1rx>MfXZ(du2QB(;IeG zq?Ox^eU5O1s2#qt;Xj?WBnE=EWP)??qDZD*zwR<>N)M&gaKg!0{qU8tQu==PlC514 z1N=Uvi1ddw?PvNpk7x(@PdIERB^s-4-xIZ&sQNj%4AUDKeZzp)if(&Zx*YuyHbC?i z`e!wv*b}V3ApTk36aAP9zjK>&H~!YIUaQ-DK@D&l-i9gO-+}~5&syz)-QH1OO{wMt zZRYUCsFAslFFf2ks-GA^i1^zp|Mwp~JiMKLCLNjdSoVpr?91)47Y{YTgd8`;o8@Sq zvUP#gm9U-ap5JjPd{jAN>;XaTm-;r@^&!^g1#JQ|jk?+L!DnUqdvjK@!(i`1&D=e~ zGN&dPotCJgf1o`5V|0DZh-6WsG#Ni3tgHPd~b9^0|$&f%Dj@NlGWa2`QEgr;Lvb zU+iF#KKWvyhr3P%dgP@&ISu8m9E-;z##5)$#9) z4|x^6LbmFyoy*h9%aVTLH0onhsfu5#9nl>J{-Nn%1c>h%JbIpBeVbYrta>2d^926+ z%!{uat8-Wozicg%KSemMiO<**|4YG)_m_X_ct=+51x>UY_1y_iXEQTv4A|A6@duycR7D{@FV71gGZ>!T06s6t=fCdJ1UDt8Sg#b z?tQ7ETDSH@QEFfD%}>jh>nEvnc7WrZ)iX$zbLSZ>v}Q!Tqax61lJjxfv{)dm+{^uC z${)3a4ec*6kfoP)^HWi%qd+*tXJNl5628v8qkUuau^p@mpgKq}e;5dRY8TI)of$L| z{--Pp_lM9+@_A{#&7F-?N_^Y1{}nh2$MwdLmxq$V%Dt;cn4oPu>Oh5WD5==R+x(q> z46I8|$XbUNrdQ|L)s;kM%)f*#2L3X@xs%y39MhdXz`f^>Yz0u;$OSI`F#>^uH-9-b^idSD$#Vx(t{0oCwHcQ3kBiqxiGMoY~7h(4I&%=WHZ29RHshFto%~?a zN?`VGO9gK(r|x@Z0_w2x6*sSp==7S{Wv3E>n%x)!Ocdcz;5wa?^}R6^gIIfi1U91) z8?zDkc{4GdpBba$*(^71rIJ-++XfTokyKZIG-Fs*hq3;BPW09Bh7ety%#>@>4xY;L ztfOM3TQ4ie45M}4O=+PBJ%1A6ziwiR9SdHvETiIYiF`_<)|E4 zft)_XMUu|o)8|KNLe=5y$~Bb1EaJ+@V@Hr!bK@x2%a>T~`8tai_qH4UPbH?xv;P2R z6>TSOB}}%6O78g!LYGWfoSn>cyY&KNZx3a!#55eS%kc6tbeQjn@R9%800;pB0RcY{_rNZl zqN?gxHTN4HC#GcA+(c~}Fy?-#x5TSC%%V3Pmw3`Gjiur`o?@$hrLSxNbIbx6+F>WY z3^x}=-ZmD-pm7a-#cLmb>z@Ar14pUvf)(O#>R@rq+vDM)*UTGOkLo&mn|w`1Q4mUU zo5cb~fsP>BS2CHtC0nE@FYX`^+Aa#1f83%1CWCmEDJWH&OIfaFhsUxNubE0z(CQld znqLvs=1|!420-FuVqLC&AP!u_2A*c$5P&Jq`sciKM6sSA29Gg+f;>PAJO2Q2{U_z{ z3vqdXW}eVv+yhzKZth|))cszyCWVtJjV{I{nr!!Jrc8UriN&-WcY!Bsm(0XTq;;9qEHL3N#_lzEuniEnJgC!#;xvg?Qx ztl~H*gC~i9ZIfHMg1EoRASydZYwijh!}l7clhHr_!~i7_0RRF50s;a80|5a500000 z0RRypF+ovbae<+cvBA;s5aIvY00;pA00BP`5^x4#a-<+8aAxi5D{^oa_?qn5JZ?ppO8eAfKhLuB0w!14S7YAxRtOR zfqxXhnhG+IJ0VCGSp5$$$0s1ehh)KEHHqgC1!mSCxsT%g5Qo6z`rsGd86*)$LHtuT zf}kOPe70+*65JN_ag9u_+xio>U2XhPbD5Qnq|@#CAkW|Ej6chaV5wRKis23Z$7iad zRZXM{aCsm}1ye)aEvG`&ym=}ka4z2!OB-eZsDOn_!nfg;(^!gli%?R^Ys6@sxB$C2 z{?JjVu)4SbC`21d@lYTg=v(OQ%xbRO9K8sCUJZ))IH{d+s}2}T{3T3Vm07{zjdPI& zZ{mOe;%gS|4&YSP*#7{ILwTF6b}!08237@L96}+IpgSD@07zC!DN*E=bJiFr2oN@( z$bo+sU6|tMy#D|a3#C!Mp;&I9e&Qo`zfl)9+`6WcSpgLl$K)ze>$5<2(g+v!w0i=7 zci?|r_)PKF@ggckdcdz>Lc?6&q9FeOPNFf)+YCHZxgFU4A;K;JXQ`K%pwQ^( zfxPAc;!;_Hk)cwhmE&bfq)^7Xv983(^vuG~Sd2xfo*R^95P~sF@Vokr3dB={l>m={ zns6onGNCB4kooE={1{BrAIG zHsGK@%4E)iEL5iVC|+I5k&Sh<=?LHg@S8J0MV{q=$H2LM$ye`why(mtO1@xKFeP2X zcX)(UEeB{{VbvR79;JlB{{Y1?hz5cabVA9hn(j$hh|+AwFX0u~U3P@3c~M+{x{IWM zuytT;L?<__!TBS7bfwYJ6TMJfdv_4RqAhTQeuAo9aQ@K|Qn{;$l2Ocf_+nC#wQrQC z2Ep`R63TE2!h!{{TG!PxVL$I!qyQbI&=MlSE>jFtC4`gV=zkwueCm zh^aP4MP>(*VOL1HXj!Iz%@32gQe9XnS0iDyok3nGh0a$7;m8ZWKob7z3#O_Fa=}{M zrVT?nvBbcY4(El{N;@d~M*2evOSkb53<54-@{lt@l^33^mkn^rk#+SchhT=l;++SG ztjMa@SS8VUqzNbvXKjIS_CQx*w=lKKPTH3(G*iLpfVaQgkJzSv$ZAo}-Sn0O>DI&B zQtRbMVD!K$Etl!h2o`C(R^I(j03C<%PZAIvLkLYYC#jB+2l$UrG>aC5_Ym3O{^n;z zSU0rS$=QA?jQ| z1JEw5Ct?i!Rs?|1g+DI60s!pdzx97GcEyYB0EB-c0s;X6VNmYFWnNt2VNM^b(~ys1 z9|0c$l>h^#5&!@Z141ARNWx$gz$j3o!0ZM{GT}rcbr`6KfiNJf9RPm|8~{87xm751 zp<^{tVYP-4V8k#2bm4t^g#$$Z0F(hR@KELfsJS>91E7pihA0y{*~Dw@w5wH%lfWo2 z6it8jfueziVgwq6J(bcg=cz{nl>)oW&*&oc6G|9l0S2Uq{o{QGAu4R5H31MYxK(tx z8Xv31r(BFtCbS4AAQTv&OdGn^PP@l5n?yBwl>xv2YE|^(d3j$M5r84oIv39XR0@5P z#Ssq0CNp$303c#GQH!^p!Bsv+7@*eo0lGRR4gZp`pT=tA_*gb{*s9{lA=RO5?z?bo}|f=ad2El%#tI#~$S+aF=w zwSTAzFFS&36+p4C{Yw|+QrIU)(ZMQF_lv^%E|$%wrHw@h$4o6UsH&M8)#U{;($9Your5E#N6-g{<i{4kw)~jv)hL3iR~Ta-9TCIXJqi&30l}&hQni1Fz*R3E zg{(X-h0IMu0RSV|QY@WtGK|{w4+z1TTC(wsIW%nq4FCc-QjPYOQK4P?m#xSH<;oGK zgjxWAN+15Js9pI@tjl$UtU?td3jk&C#R+tw^(lrUCkPnH0+MuHNQkl3#~|2hT@Z+g z2sRW;)v=#&%^8~1CCMmZL>Yh7`pCLNReOu;L_GppjgM_CHcrj-2A&rMu^(`@4u5h4 z2{?uqevZTV@O7z;-}=`n_s6@-bTMo~+05>^qe;`*1&J6oofcwP`v7*6*rfIWU~r~o zUamtI$0}g7p(qGN1v>ESGh(GDhU*O&!BbE>`D=}Vei!%t=A9=`1GzdBo42`n2 zMUsg10N`vLE~q3iO?()D6adLVfUr(M4gnO`XoW5@TmS?FJ4<7j`CL+mOYz?d?eb}g zejRZFf}Q8E=&weE{pNqYhpXB`rdm};G=C7RKkO8AEpMHuCg&7GSO9E3jiokmjI2(j z`THt)ORY}ZcA{3_@}h)cW1*kan5SKjhR)SN+bH{B1Y3{S{8;2_n&xTr{q5%>QQWQc zLY;;~0YE@-pjuFA+u7|BFXG&_+NPK^(M%kV!UMCB$6!G>x zk+HV6-AEZ=1fAmzc9WoJtfWRMb8B)Wa~zGr69X8AripyBJn2}CKxiA>a;d+fqADL; zBo}goGfa%&s8i@}r$M+NjNoV$v~PIn1werlHK)vG0Vu4+E#?zc!W519G^!A$64o~2 z4q@!lb^TgFXfuB&pTs89mg7$BR%t{DC<71>7)9JU!O$nooMw~E5_T)Jq((hhT31x1 zcvM1I>~S#0KoXEe#yJjSj}%jaSu%*o=_RVyDQWJ&06?(2LKIO1J05%*9h_mgwQr)` zBsACw>6UEF>uS{~tMX`T_E-Juv|EauDj=n7O7DbGS#f`H@)cF3bUP@DaO#w+aZ_m% z04NknT_i%=UWBr&1j8Kz5;Nlse9D+?k>(9^Ovv`F+*?spr9^o^QVAQH8FzdCggArH z^c9JsAPAIF{{VP26roN-1~4=;ZuZdRz&~dfhk=HGR4EAS zcL+@-Y~C=B)#rpMV=ySwGG_>H znH(zm@h@witf(mwg$s^FBTBqA<*{4d%kDIg^TCgHmF+y`5?doXPzbw!L`wg3GiS_~ zJ3d&s^$kLafCT_xj1j6`o8Eu^#Mgawgy(;PoL=4T-eWfjeC?k)f8?d*cRStXm$VN6 zq9E7SRV`RDeE>iRiGoyEdT`l4 zUTkoh12^#3dNp4O7(K}~(rQ=P|9pHq#!csqW`phJPi7IqYw&w;WQx+_nStFX+%Z`~Td#k~3g#t|KeK&;kIA>t-L4$z%QRt$Dn- zyueTHM*O*;Fny|k(1P*ld?S5r#auxMG?@|wY1x*SYU_B-NppueXe3hu#vp&iD&5*Q zfiq_3;f>o5u0sg>1;9@tMrc?@I&)B>)sK;*a7Zgr&qHCft zH#060!N9B1dASam+h_aAr?Y=WA;bbn6V=erj5OII-P)JO&vqaEX8VCJ19bh3W&N(D z-|fri47hu6QdXi-cjq&?XMB$o6KBlA&mTQseL7%vE;YCZ9d69DLJ*^be?Nh1q*XbJ@4{VbH@B`Sh9|pF$0JbfMs z(154n1{P<)G*~0Osb_qzRIZVJ@mOh9QTQ4`2)Vt^r5pdi8Iu`r$m?p;!VU&1VRsKs zGI1M2-pqe6cvoTZ1u+1N9E1-tiTK&;)A>gF>WX`G)II>nqH)=lm!0l% z&Y1ZlLeC5sgH)?Dse1>`nC}m)Ias*EFY9kYW3rX!f&jp7KmmW6uS(cmgObc#BYk`I zLns2hRT@>F{_A9wD9sJ98iXguhFB&t%Xk6T^`9v#c<1wnL%3}m17=0E|M z);oScx*sDwTX7;1nGph1=dD??{#nkLtOR3T7i+MwKp|{SZZiKk-=9{_Gf3tTem12f z+1AMq3rdvzXET5GsrkenJR|+#;M&lPG;sO$m;7}*7jp*8=%3glCAeU4Ti=8p4ikS> zl{C8kdC;n|E>H7P=xO(A&K&;t#6iA7IMbS8R`hI z``@qdl$7ziu18vMBa<0bnRe(`uXHk}ZcYLx8$ig65evo(8GlL6e)FQF%w z^}qV*+%o4GXerS&<*n5Za|Sr9(rGyMUN1kNac?>5EGY8=07hs~ zhGkOs4w>=1?uvrqJ;ql{*!51uvZWy*+u7X$!K zr?dW#4kjTG?Qh+ef9&j@*3~`$>^b&r{799aJ$_B5S4-uc6q8Fem8IT(JcWUJE#wpA8z{N>#OEVf^KcUjM2%1?rVHD z@89_W=fkS15<&#w3c_&Y^uPYL`GtSNbB9_o-3>88lT2^qKhW8cGkfCm{APCm_BpPEIv@Ueap|wYw9Xx(WrkflctPz zcJwmIah!%xKX=X*vHZu+CaIc=0HN4_Mhs(&0lRST>-xu}BZMMGpcT#Y{GID1#LJ?w zzX+~Q=raeQwxIobdW{jrSio4oNI(dqNTx3%x=%A;Kj(-20Kk9^>3UPEr?{~w8c{~( z%<#*m{HJ-cV45-FX-;o!yEK34{m1l~krbEdKS~8K7wM5UDn2f?U9EwO*fT>oq~7ib0h% z9C2OxXN{$dw(Gh{$wRjL8G< zQ&dm8_En{ZS z@tdnQL#C8uI=bJMyTGT`g*-`EJr|6zoBBOGq}wFz>cfCil9k$L{`hwhw9*r`FM2@V zjG@nt>UGQ220&I?@A=~ws+up%d35MHQi=D*z7O0mV2f!fdahOm%wf%X^rpqh_6*kM>O~fl{eg)Kb5cg=sC}I+;If5+R_u7` z;HhnG!yQpZvr>Qh%*uOFK>FXOF(LreOKEMv`)Ch&|P7zP?#`H}=0j-jqg|7JC5Hi-5(#ieFZ3f3@0uK33XWC?i&5 z{0#%{8Q6I;i7=svH~^R8^Zqm6drKy|lo9j_!5mi0tWBV=|#y%Y1Lk0dOf-kVM0}J@4*4`HkCK zjSy;egJ6uB4A!0*Bc=^`f>CH;0^QO8T#C;s@s-z}TK&`O#brk&QEn9&RH7u?J5C+^ zNJc_0Su}sQO77A+093ix#tzTEwSzHL zB}xm#*q8y}l546z`{(jj6;=Flvh0^br*?RJE{uOgj4(zxkkpz1qm)oaDJ7yHWv36! zNgv)NX@J>aGs|{_a8#8^q6>fqtVzJ4AV{^|vQp=XYWMl7+ES;d+@sW}nwKz*P)#EW zWmFU-j08zA7(}xynk)u;vOOcgnwDhE=wM1?jA}%qOpDITj9vgZg{FGHbY)7x*ac?; z(cm&zg7CdDS0P}G)vLH|v`Dt)&69Qj+NB+UsF(i-*Xy4Ef-7DP00000NkvXXu0mjf E0G#H0S^xk5 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/external.i3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/external.i3dm index 5da1db5fe54dfa52786291cb1d40b22b2a660413..03fb3dcaddb87bec22a3eb4f3fb7c25db0f9c91a 100644 GIT binary patch delta 20 bcmeBUoWRJLX`GVF$iTobVIpTM69WSPGRXu< delta 17 YcmbQh*vH73X`GVF$iTqRH<7ay043@KMF0Q* diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/textured_box.glb b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/textured_box.glb index a0c016ef93fc1d55f9921a3696030283ee30b157..dbaa65f3ba3355e09c66f667f4c89b97499252ab 100644 GIT binary patch delta 106 zcmew$Fhh_xJtxGCiGhJ(1_uL!$wppACegga+*BnirIOT&lG38ol=!6l3MHM*yiBZ& x@=&RyqRiy%VkI4=(xObDN(fgkt6;J=vj>+BNT+jteo@Ni0_OFMn-y3Cm;pikA4~uM delta 67 zcmbOs_(6a-JtxGCiGhKkfP;a7XCp5o(`FSW7Dma^qD&<#CFj)Q%+lO=pZxUvc(qzHQqm0FA>E9Mba#hzcMS|P z@4@fyci;be*Sc%ndk<@vGr@Vz^E`Wh_THbpH$Nmh%dqfa0@hAg5D27GKMLO#_oY4r z;$QBGh0W@0;bg-g&fsD5#>3Oi#@gJ{Nmb(sKR3X~%Pk1u=jG=W z=M@s?6?wwXFU}_@&L?y;EY_{Re{%B+>wlbMgG1g7w+KFP{xke-@cj1wI4Audw}plM z?{(I|?_mGu9Lf*A01x0UIM7|l|FH@;Hwq4knSsbb?%uwA=Qi%$J9qBj;oZe2Ah}O) z?;ZgK@gqVK8cI4^8cJ&FCrsR|PZ&5Esi~ieuyOM82?`3*v5HBF@=J0H2=d=t1Pc!j zkKi5w`ThIk{PfiH{QvU+{^yJT$8*dN2+`e}o5I0jfM640;SgbAenaTM8^y)?d;B{Y z@HIBhE!^98?&9I!1HVxH5CX0h4)!e^T-;l?z)u6f&mp&naEa;pWNtsww7A0nxRUU{ zi^{mmC|mxMRBPyfNx;(WJs$pJGI9z^W){|`Z0v$U!Xlz#;&RXA6%?NggL8 z8d+J}*xK2{9NaxTy}aM}_@OioSzSpt?3@%Z=k|Y_ z84)-$>|3{RZr!<=85Xwp&D4o*;nMTnCYI5>W8wOUf&blI64|JX@}GE&0$K;8mTp7% zkC_DjFdyE`?eEmUnF0SVruP2-*W8x=JG1{iv1tea4i>n7I7ARAq_>{D&ZQMV>V5jU z%2_sW?T)ssbhci2-4|v@9Y~s$tu|<|P;tGyx_m6OE_VU<*%==pJW_Zrl;hDW=ttmv z3_W3Y+!k?T8Ab)%xzKiDj`n-b?A0aF=r=?Xw{wZBC?loy{GGf`)`sU{JS&)Alex z46RUr&prCkO@1tH?8LkvKZfyBg{8AXxP1jHLkHd2RN+qy%(Q)ULL`2mwTGm4s$upecxj8CBJ-!^T0ZxZ5YTzabjv%c%S_w@icc{ z+PofgKTA!r>Cz`g2x?vC2)iU{&+@u0xq$Kjf{YMKd(rb&#{zp@iyl9Ue;QqWJd(*X z@No)5CN9tFw5#R;Zd)=6ny;15ukXGpu_Lqh@)&U4aH#%CXYc<&6s;>1xB9d3AM53` z*1=Jce@c2j?4k-9-C(ntYo5(}3k814?6(?&sR5&&7vm8LKR8?K+o4ANMv4AU8-U;O zokIjmYMZ15avzQ{5M>pKnY?;= z*c&l4(WdGs6U?H@OEMJ$8BTopPm`>#J1YE9%=!>;M#}DbrdnN^?n%d@ph=i_2%Hx7 zHLp(#&J3;YUcuYaPGg{#YbbVfifiry1~LO(gULFLe%~5?pV9lRfg$=~< z^V&d*artR+oTN^d(bEPu=i+3&nNz_o=wvzoZ#GOUdA=UO#dYgDve3Q#8qua9H1?%k z5CzQG7DnqCov;wYdK6BNFcAK0bUHoI9A`u`)p5A|{VaDgKF}+NxY$o1%{{F>V?tM7 z>vgjzS~fY0@FGd>!!`zzo>Z@Nr9$2wOY^|d(N;q;+EEr%H5}EIej;?O-cF$vioS5Zr3iJ!KzxE&edJB! zsI&{1;$23Y;sM)XCu6{NAJOiL(ly!2X^@Y+Aj3e6@>=YT6{>kV$^!#eFp!6*#b4RF zRSmg+59d)FE0q=_ig-|}b{NRpn+=5L6$({Py1zSezerNGLd$}h_5(N}k_Q*zStIxz zK-}>na*Y@R@iq%RVK~|WA<7&c@F{l`J0PuBvD^OwfPO9{FN&u-{9}cII6+gNnT`w& zyH;iH2LK9`-l)KiNMOa`Ho1^6yln@FJQBK8)bi=(n21kei4HVln;epoK|5V?=TQ?r^L2l*EB@;w-q9oz50!Wh5~dK zm+BozO6EhJuW}bI>&S|dcHCApU3VF5S={MxK%FP@_ZU@FXz)PoQPHIyW%nuG4;LQz z@8RG>?Aj|tSKudGhuukV%WdAB-k1c%?;(7B6Vhph7zky&mTsil$f)q5WWQ^~Qqb*~ zI<;b(r}-_p-oA}Rkr&D8@G}5hEFGD(vTauJruFNE>svb4pX@P^P&&oS+tH+DIucH1 z>l8b%NZj`a@y3YVWPC69?`#Yt?ey6L*s&3ZtO<2tkFh;MTVYdnGwRiv^lM;I7aqZ( z{0gv;xxsYZ)ajHx2x6whurg*Yhn5BwPFY(viR^S|M7!$sXL;$hwXRBqa;^*HOfWH6yf0&nXwo{16QX zB_ILUVIxcYePr2@Q0xPF)`QF}l%X%r=vZCH8EL`*6p9Wq{8d#dHpJPHi-BC@SKb#p zIbn&MKDD_v2^!1$kK9Ig8L2qNX?D#3sI9dEn%Jb+0p|X83AaY_<#+QL2D|!d4ZJOD zR1!oB^HrgbSEu0dE9@Mgg&Sq@ zT#mPKxOM1A6vjzSd2E=?V8h~DUL>Q}0<|Qr#t6oGgpN6RtZ0mT&>l*;4W0m~Wo4>u z-E5f_qQBf!&rrd=LzXIT94$s)aF^nqbYRm7dej1k#m3! zlO3XU=3;9|9>r3rBb--)UjRwATq%UDCS@4Lr=$jQK2x8Zj zpt&s6j+D^b(}}%~cG}ESmlL7Z>pdHA&D#74-7EtaoHQe_e)t6ZqA74fuYJz}W-8L- zjDciP3Kq!FiI`iU1(O<`$My)-K}<*w$%XsdRtu@zOFT842cDj@&3vdM{6l-P`$k$v zb=DzI%p=hBbJcf(4(NJ`Mv2NjiDVzc)kud31g~^;T+){!dGp@kl-NS0ya0r@7J!7b zVj$Qz7M=Hi!_djLap;eMzPtadHQ~~EVM&$)mYWj>a(D`=}5wdsnp zjGWoI*?1txn`e~ZwUnxa@-WYnG5V;iA5@6XfXCICst*MZ#Nxx|1%BkSW&OA7bbg?X z7g8;QIa0K#4mS82o;;O)@iDEsBzq<~oKfeW*MMi_)yBB>!nSdXB zz6k2?{%y#k-4C)Q;M4B%vG`(&+LfA&8kd5KryJ(L}1v+2OL7UD5pqKv+F4DiiUtegT#FE9)&Ywq{_C7sg`Z*W3 zi1!R?^QgryW|v_jC%}WvX}JV2tSA3oj)By``->vp7tdiJ9pP_Jj-jcxHFnR?PcPA7 z5u-#NX-%O1q^Sz;uGl_5lJX`z%-@X)^(m-R&D`r6u2an@%!L)LB81@5TxW1 zlWP`v4g!A=O7WNr18FRa-_R^svjjt4(L9aVVS1$N=i34!-C>f1&qb2H#$cTj&v&a+X;iFv^^<1b?&$?)d(~}B{ zY_p=;%Q36sg|tdwxd=_NlR~=S#>1>2ocmTDG~UYQ+P%!?>o|;4fnM_aP3@z!_5r&@G6FZ5lnkL&;qL8e+r=qb`+t zgB`PFCkFBc2si&UyfpD_)W~|Ov3sUd4B1>rVlLpdXR=Ob8y$cUv_3Qv2TB#-c@Yau zXv<1>qohV0yO(@nKJZ?h)<3p!fug?XAP%hL&YznDM}l3Sx~2m7P=!vC&Mjd9KvYpY zWl67y7K1QZ1h15IoD%DOzbIB_L${*M%kZJ(R|8MB>d*?6O;Zot7IGYowzOxVvFr2= zCzqFcqB$(Fx(S=PTS{GCz_qHxdt-$vCXa;y6n~`2C zv+xrMP7Gv3ef_!JTW;JM!mLO#Z&0lCpJZsB9q*W@#dp;ag# zD&M%EfQ#;$i*N#|qeYjnl(*yGje*1?ct*>yz#*OXuPf1>rU|6j#m4S=H=>uS%gGm} z3k`Zix1_R)eC*P7MGE>lrQjMq?$@(nTtMo5tW~-HE$xNzz&3STsb( zIdPN#FRa*(sQwxUYon#Mk8HfHB$KRb^(?*k4PC6l;DQlj zl3FstF##(xNCR-{VKsp+zMpe;sSs|fEE`X&XKImgpEB$Vv0+!w_tzg?vpcD|K$XkC zvi!X2C0M89El$zvsc!OBOXFrZ#yS?ARXhazH1Wh(5_Mti54c$CBl4JZclB{};s2_D z;5jxtS8m{Z6HFNOVOLd+T!DTS z;c4--`l31iGRn{&p{-^S{$K%(d$XZ-zQeK3gNv`O=Vk+pDh2v(90LIK3~UF!04ww( zs6|~>LbMz&@B?x3NY7tk3UTjx;ehmZaC@aQFn^;Sjyy}$Cm6^a`o*U;^lGjJB0}^> zk)Bo;cWA->tL5%p^iZKlC-K=c^9H^T7x>M&%1?%cMC{Mst-7WFL>VFjc5B380U+}3Vj;GA^!^dar26Ik2^0=; z1QgTvzz@*TXZ-q7cas+P`$+GQPr}VM0}kmvMIy?$LBWVb)RtAIZJh3`_WmWmqa#ox z^SY7KE3KoCm0Fke)$`U(^=cDS7SK13Q^P>4iNCwXT#U>!NywJQ`}&4gJJpbVELH4k z57=R+cQ!bhSS#+i5Y2ZkFflQok52_-dQTL#&N6Xod6v7)BrH$nfI`_xwdsUe zYQEERk$GJ64+c^@u*BYE(p#mn#14FmT^Kl~@IY)5F612*HTZtWHOF>Emm!m~r2WqZ zkV~bYbKl8-KGTD?&87Pd@QtFek%6CHmT(+ED?xo7QD5T_5z6v)&x5T`^rAg^r;_w8 zGPW=IV;vJALV5Y7Q>9rV$u?`yo`EDq3&XC|A0wySo_I>z9Y-Yc(*)W;q>%0gXcw-- z4wRVL|$*XTSgC8W1a zY!Z3Z^IL<+!kHG+Huq!SkbLKpCEf;G!m??~Vuy!qx8v;@ll$%f63SpCSDeH$U2#PE zwB3Jr!h0-B-~8ot48Tj?FFNo&zslLu;Lg>;C0@~V)#KajeU4?RAn4SLr|&-@>&;pS>ZQI7>kXUBkfjsbQtae)2&H6w z;S~~kNmO9|2$?i+;kb&-;tiQ?ik=f}7Rvk3H;^2eQY!7@0Q_dC7P7sc3rqJp27O0m zLIv@mrcBV>%e*S(l>g;a+3G%!G#@9k;1M>t9TMt^Ve&b#DaGjW*uFL-#O!ev=1=#KW`7gW024 zVJ&G2CC9+CY14ubsjT&mUiCx#KFwpj@E;(|3c>RRK*-R&MdA8vKHoz(w%M?#(Bz+_ zlE?c08` zt1Ra$t>J$4G6hqJTn~O&XC!U%9pk zrCWVbhqHVC0$}&7bgGlvgs&>OxxZcrJ}Lkeec>?Byg;gAUG=X+(qFh%G7WMIAV&Rw zrfT;QUua|;_N*ewTsnov6|XUnHFom;DSaA;w!W&$8ABhHMrpg(5z_TROX;AG9U2pSb z2Zj05l-KMjULt%gM$&h#WMd4bJz;0p3-O?oknng>rUzc@c5z3ZaJSms^72+C9Y_vO z@v-q67bDHd$rq0Ixq+*sfekj*`KN_Sh0&@DR+<(erVI=H@NP|@F*OJgI$b1``k9V9 zs}Vi2I>H8%G~Cw4r&|_Q%*GW_sa4(H0W=n&hiHXF=;av-8pm-3=L0a1p8fbOgUUNQ@uD{iHO4&_*b!=6c5&xe z2%g4<2)YIR!V{I{)^SDI=|y!zwPeEm^@68t8-{nEvDKkaH-T2ZzEaB^8Vs)K%nvhN zoySe@=4kP)sh(PH^)>3HfL`&9LmQ*6dZzytC`a|(P=H2Wr!(NYKuElrXeFrcZvg=v z#OD{Fb&byyxEzliKT^rvydq;lre1H0mzqkHgulH*w+&5w;biBo{AFHv|B~-zMcpGF zkf%8OqhWIRdU+F-|88MG8-5((x#L`0!7WC^`O2(S@R4kRG6r0TqOSkrbxhe)0 zboDhlW>$W7f>e9GRexkY=*#e2-yIG;U+C3Vnaphh5OVxgYtbqJw0+B>JctxuAzRAf z=4FKu#j<1&fbjd1tFP~GXU{$Yt!2n;zj6FEuHmR4vOnu-2xl2NGC2Lb(6JSNXw0Sb zk!GUai>Dn_is^-_qJF=-xpd9?xZoQ~c~i6UFt1^jJ6*HBNuA)j^DA*x4|(+qdz}l# zGyq>_;tV|Mo3oL%gA*Pz=|7e)YV8gj`bg9FQ}Jhk<{Q81jgXMIFR9$FZw0y*1EE(^ z<4XZRr#Fj_vgsCWpv(2G;qB~jrGZlD*Ze9lZ2Xc9J>a>%H6D5K>EVs=^B3pwKhiI8 z6Qoh6I{_Iw*}?~IYgNS^DDBH~3;-#GUeY{8sjr!;|0#=K3$x_#z3gAxegPW&S*Xt} zf&Z`XeNGM{#ELnScj5T{y@%+*!ti?2uA;sHT2l;Uk;njct}(ALEdN#jB{z6ACiX>u zuRstslqr-$kgo`$-Q?Qy@zLK&2A77noUM z&^^>9W`;L&?a*Lul0IGW5@>ij5@$jNt%~Prpd`EPXi7Y3W#x}L075FFm-JrVL%*+b zS@ZD-g$jI=0Nt&3_&wAQ9kNgLSYn-XJWHmk{W8s!{1`hPXe{4xyCn2AD9$S%*(c}; zpOJ_(cPY`GkU>w}c)0+m7*1coMQQxYmcq(ltQhp`eD6jg4;7YMNT1uchXq1d9f9toyD>iB~u z#U1wXCaCY{8~CFtp{Vd8UP`{d0f=(I%c-ks;1^yJ2CUvnj1jo%7prlWK^N(I$EXjL zeY3@t*pzs-Wlt~KO2B&qkRiqC`{YZ-4%G5ao5xls`A%xvAL-0jpS3{i*r0PF+sFzk z_yyAc3Sh5)nOxO#hTaFUIfF9q%|8wPegON>&>Zfkj5UI?y<=n&BTBtVmu`=&=Y+q~ zhztPPOdHsT+I`UYYxvZ>JiHAo+7>&!2)D^g7_kgIzL&BbrAQ{+FE1D$+xM7-gWspHeV-I$f!4O?GYX_=rj`VG&TMMOpR^Ey`BRY4^D-f}kfgV<^ zdyIiZ+~gm);!(b)zz=9*A$j4tEAYNNDF<&XCO)bp;B~FIeC5ux+8z>3Z*W?A)O9=D zey9a+VdlCpcRF?1GZ}h7geKV%+?m;6$Jf--G%^LP+gsR{cz9pjN$9;rYP)wEQi{zY zYUAANEfFIAAHb~Dm5w+Fx?e)w)8L&tz7$hMKNfB%)>7^Gs_NbhWkP_kcf7_{6DkEW zk{0CB@I{(mlD=r6|Hi8$AB8@^K=A#~%ku5@BbIMV!Ha;?d}R?Y3$}qMHiaIw7TYJA zNfV=o*Kv773w@wS1X&dz9gQ^uru9;Xpke~p08Lzzh($$y|KszUtJxiK($kaao;z z)5`~^5%(QngezZGIU1ek1tN_iuM{42Rdt;n6JBV?rD(s>Xkul)d-izq%P?o%qRWkx zzNHQs8ZEum;FLQ$Nd-_0xEdCXYDx`m%nu{H?6-rxfO0VqBW?`&E|1GpX;0~&Bi9sf zA=`J4QWCG|4Sm5{DCq#WNpgBye_7g=2-gBV~#vJ7^C! zzdqwS<(mO%!#-XpqM?cD&USQs zMB34}uTNgh(pez%^y&6U)}FrI2=o&j%BSG6Tn0Bi$gAUc5sdb17ROf(jf8^W)2v6G z3z1(_j(4A#^V_r1*@-sRUYzjn;*qgM0;^hEtbq8(Y(IcrTZSgR&YazJchZSbQip6^ zWSB1Rh$Op&Fi|63$f+SPCspWu+iR+fnQKQ07t*XecRNsKAz;P8u{KW-8R3%33M}^R zrkA?wxdK{jeeEnibh9wf;M{M|Ld64d$XxDnxp`wrojH`0#|OJp#Oka4Kw8PY@C6V6 zT1+sHW;9l^n4ay^X+BsTM z5abz5p$Yj;pSFW&>(M&uOXl>$XeuQ7mH(Ny)~rAqtq!nE9jW|HLLxap`Y=~DeW&Be z`B`BtnLu%G#s&F~6uXM8&nxb8>Sep*LX)PQw&N>iKV#X1qS}vCG?F+YV8E^230f$^ zZM}Vx4jap2-i4-4l;cxYyA6*q$0RV8VyrglM?@awv$nqY?WY^6e!7kJ(;+6Dr;I=F z?}77%GjN=#e9Ap25r;*_}Fj_R0w)Xc7|d?rGh8k)Z=u^bTR7lZV^g%%RRHOkpf<3`*lcrXMCl)BEpk`1e_;&dHCxhZ1eE=ApX zZMC*aq6zR>%uTq&3E=05Y4{U4g49hGc~iCB#VBe~32!e{L4O}BazWzGA6^e!GbO*Dxq+H8YHF{cnJ#+%BhlSSTALdk@@+K3KVbZp5?lixk@^0MF zwSVeX$Lxm=D{`i=xgQZn1y5Nk$u00Y3O`!$Mgoc#x@>M0Uwuc_x+%Q{b62+fdNQ)C zz!Hw_{VO|EpY2%*m*lc)%K*TGOzNd!tKNI|1OxGd#;?Fs`@cA1AYiUyun0<;xdK@J zkU%YfmLNn|-1jye7%i-Qhc4N${y_ynWo0j`3?#vP@CHkA$;&NnMK$Qx0!e9L$rT`M z*#~0<#L+=3+F~I~AaIE19P|eCN#{*zw^>=i0))ZB_a`M1Fj^Yo!{t{ZU7$0j;nbC@ zYcDS&TH+kGz^=ZBuJ%Pa)z;i8>qE6Y6H@72?+3F;iWl0a6lV4%EAHPUDgbuUdee8u z#~n!v!(<>8_BG5LWRY-EVzdBQ@U=7#SO5?j<_3d)SkwBOYc?o#0;76p?|6U%OjGdJ zo53RxrH#U?zQo!j(}C(l>0i=jU^e`)fZJ};I6qC5Lv@lL@LRYpEUwX)w3SBe;v)jf z?D7m5x}qg}Xx&p1 zFmJ*JFx6wLUg3yHNCIUqIoiA4=Z)g$Sh30g#^3XqE`m8&;cK^QF z$Y)`ZDH8FDLY<-mj4B!;F)Yf#_+lG|P z^AvQ*gbl!A076vQm~;+SuPkm;tA1m`Ivots^fCQWi(+r}?NJg7vOWuym%dRgqQavm@9dzeo zT7C8=$?mxs@4QYsyQHqSMa1$8tIa+o*m<(9^)&o!JB|dMh+QJYk|QDN9w^m9&gjc& zs!XP;W8?Z`{4x$UxxOySuvt;wzuJ9e%Vo& z>$?qh340*Bp{7nlM5HI;L$hK5`~)emiwfeZwCvu9JcFhRf@#G4HMx*8ywaW%>IU6y zg3lo8VVfW3%~rQn2_IBCSKItvmk;VU@5HBF-MB0wfz(MkGTM z^Nn9LrS>R3{QxO z_?ePyKEs3w=Ya=6NO^7yR8>FnG za9Kj%75}5u@s|%(DF%@lOlPM3${GTh)J2e6cn3zqRRBc_@b1Vu^H*C!OhD~Sm({g> zUC6xvX-xvO^N!sLM;M)NH;2*Vq2FhZd@7Ji?GJ|MHp1$Y2X)!%n2^c(3U7o8N?gSs zGy`Ar@0X-W8-o$=%p*OaUoHL?#;+;X$#>Y8Mh#Yl*uU1oSM)}pD~x2zsBn1!9Em7k zfv!7yL=165i{?f<@=3(k&W&7j?#k*1_qxRunN5tGQotg)wR~N5Ih2@c992G$P~DyB zKk^&5xQUC{W6Q++!|#n?AjCz4S732phMt#CiJl{{GeamPLOAcuh^XcjPK>&Om-UXR zIu$%jt&dCFsmiU`9cGJ!I^$h zqyTcvUE1sOnX8UYNokO#5wQ|B>)5K~IeMVw zrnI5IPY?H5=mP+=5Y0u)Oq~SEy7^Ux^RrLYaR4XWTce0_W ztF5cZ{Bq0AYP{NoGlNXaC*GJULbAe7SAA!uFC8ffG(p?pMW{>A*S#sN)`-j83uf)p zeA<(BeUFHV$hemg-plF&POBnVxjC=Ef}KY@64=)LHtePO83WN&-6pku!G#~K6%ZP2 zb;Upny&*q!vGmu&mxeQm35e35i@K>vAw{|yuutAvwO%kspDX3{1th+65a{qHKo`xy z?3s8;c-!wk8LF*_CtkGGx8Zi~jsesIw8HCkCk!=}>teCXJ4P)Hi95WLMap=?Yf?aq z`89rFy+pt7SXB>9J7|4x9er86dw zypXZ}$SK$64jUpEgz$^yNDb-eW=P_@ zdk&Vx{<@(ZqC4};n`Zf?)z@_~5FWZ-kf*xw*)u6iOzd`q6>EWk$o>?j@;k||K$TU< zX|bQ4AL&*tIR4|F;>N~oeah|Ttf^On$f9tlZ;&}f>*7F^grpL&cW=rgxTW1gR2Grp z7zo+w<+tK-=yx+@WI5p7kGHRh6h<6_j^x)qX(7fJf71)%1=9sHai&C6_1y!PzJc zI^gl&W)$!l8*Jpb1vYe0{HK}Ye}4qF2Z60B7~nrW5f5=5g8eCfRxTe|>XK@@evOM( zweu?V&&qt(J-OTM%c7)|Hb(2S>GeWJ$;388m;1M{j0%zXXv&M|@7de_&raG4zINYJ zVi|Ma*8T-!nZ_?LSeJ4Z9wW%ppF{$S(YGza}>#j&u7i1~5o`2^%3k4P9~pD_wzrXhE+umG@y2)lLuA&C=8 zjInGuc05<3!>QOWTxx7Yo>x!Z(_p;blX|fu_qTKOkx<_V~m0!T1r&h89_b z)&0}!=k)JVpr2-bkCvTMgzCI+je-?$P28_g)RXc>iu#4_M5$2_N8)7WH3)XcWXzJ4 zG}%hLiKq0>zMV4z@dBnhCX&}zHvTE`CJp8OJZ|Z*u%qRdd7F%){O!hGIJeeI;U#CT z^j{ARX+om&x>QD(`o3Of%_{Bvym#P19~xxiitE(sXC!{DZ1euRns9a8mvvKV0xfSc zPeCHNHlB$sm4l^}M%yG;!rJ^cRTk0`r{8lFtQ3}yi17-Vg7C!w6)eWPSBwjnIK)l1 z!$7)pk5l&)$M&VBa>W&=0+m7EZD`@9gK+R`ZH=l)%V1(_AM%&)Yh1q?y7H`_<}FTJ zRyR@HrY{Llyo@n765V8`#gX%VJVZkCV5@+DAf1WrjIfxHUR(}O$f8Q?JVvx$hAD%I zZGe>Ioa}j!qe0XJuz8C%llRk%HHCG&)#rMGDPuJgsj(2t*jKGvGDrHl-*;p1kqAy- zRH_)_W@ABZ16#WO?fUw6Yr&nRC+6eFc_bhs%OJ<-`tI+>g6&gKEcoZRhRR)%lqvG! zs6*nhET$|~jWV<6N7e!G(rMO>c|+N1fc1HpUbKd3BTH$BW>U8NY$90;F78Z)3Ep1# zdQ_nG#z*ZMDEYYNnPTkcL*P>Vw^;5NoqbVq*T@+U5u1rZ;qxmp7P+aS0|`}Q9-Z&M zN3C}ZBbK#>>PJtUgbJd(S)WXvTn`qEuP70{6Bs+s$7&vLEPk8zpO zh*!kT0Q@M*MHHIIIn-{cRBJ67eHb%GtS`ut#UjJ{N*&elJE@zGBJ`9+&Q`Dy7NJxX z5Vg|AlqtqVqBf%EmPSFK^i|&nAp7i)f@ zYzU(%)qEZ^Z9bfe{4JzPXSveZz9fp)t_X|}c(V6m^NMkanQ8giw{IW!tN|Z>zD6F@ z8Ec5x^9ZKSL#wg$m~Juw@i`hXEiW$9<}Se{6_0=~`CT*gJAr&#)pnCfTGqzHD(?j2 zv>1IWxWTJoAbCeD(GhoiNy$@qyARBg;?BVDV7%Mo>Ein3$lv7prXq#S^`d1UVpOM$o^>W z!r-!z9V<#cb4e2W^^2UBI0+>+eP=VCfcyd9C2?0)j2zb`*}+Gnjj7Psq#uj0giDf8 zj$7I>1{5xX;ScVx%8H4}%c*RrFnn?orIvfzk>N{}B^Tw(HdP!!q&b+a;bz&& zcS3JL5E!(ftfo>GrGMgdOPLSNO3)l9CNp|cP-ki|wU0XDw)qKzM#qL($SeC;J>wHL66)|pJ6S>dz({b-+5bg; zoLm34$lgH24M6b8Xu7^5X86hfKC1kog&U6L;lJH;lEgr-*YL-Sl%J#udsKY4G*6bOr;odOtTtm#d$N0?)QKt!i}ZDXW;$p2ss4 z2i4yX`gx?*KpEO3`X8SI$9&U#a@jhi2zz#*DM#P4FSJS(gK#2Cx1kEmQd>bYYNj->O~6R9*z3#Mof zb8tWWfNMF-t33~idc$B6U7DuipisoP7|(P@XX;8X3+AMozT?WHoI>a zOc-90Qn{rh$*p3=lPN(BXUb2**^2Oq%6!~rzp1&S{HvN?vg2Xj=&)=*7U99ZRGQ>2k}Lz=8tA( z?&tLA_GCX#9@86qS~w@A_FS7Xm4JonLFta5l>G}oAdnz%{&N5w!H{hO8Q#}ij$N!y zqu0l`e+g~JUh?22I}@LUWqfTe^ec_Z+=XUCe!TW!UY<)^=gc&!4z|E$7A#B)qsOVP zA7*y2=$eAdA4`cSEh6K{iV<6sMDKD=RNAGN$qOF@Nil$2$E-(?{X{*#@X(NE2uH=a zt(PYnz&mN8I87sRO%mcMb{4N?$X~AV3h6t%?7s5Nstl)0VcwwpbDx>H*4A#Zi?=W43$^d3xcaG_a!V}9D zqJm#e@Lc5QyTTFl^%LhD!yaA=Rr4F+l|M_Sfbg2B1NDrhUhd&JWT;M|=RSwW z3ByF`F;t(e-XY0L5m%$8cuQB@J0UwSgiR-Devg@I8Uy)QYi0+F<|?@2&ny0i>EzI2 z&_r-2jqnp;dTTBJ?^Lq8sTS|c5^bFB(2Q)NnBT>#!*oWz)$DU9ySOhoyI;L6`*FW( z5kUVC`S752Ebc3r?rW9a_Rhwkgpvp3eyobyata*}Qr88m$5ap6=q|f;JiimN@jayJMPmPc2%U6+l_sWaD=EGzOvyzowg(f zg0^IWbMc}`re449GHOZ>rPXl4$yojHm9kR$e)p2CT@eHPKBb8Chc)eI`Z$kh2l!7o zY$qiet8U*DwV9~;Ik^ne8yS7WfY*v{ds(_1{Sr1n^cMPOHKEuOtiK@sS>F@=mW%_$_R+h(b<@^g>nil0hT{GT+$aU}+xNcnQhd)uY&qnnmy77hm6Mi%i zTG2I+6eJ#=;q&Uzr2O)^jk1CB*r`cMC%y?OmJFwij|}69IMeVFk1r&Pe8qKJ&<8*G zP4=+=JU=k}UFx%tnj}yzYB2HuXWbg6^ycD6_c+z@?~D(56}>{X>aCs2)62_}e&RIh zV^gV$U#lI_9S8oQ>0tzj?;1RMo?v~OS{JN(Am8%@{`t&{uNWx^2~TG;GiwhaFo*>rNWjVfw~bPXC+gT}7{QnLIorn- zqVrY>k2krn+9T<~qWX6Hi|sRaNAX0s*<`IZt@_9^2VqBrDS_K^Amb}l!>AzbvU%n= zDyKqpsiIo9_C!%?U-8XP%a`jX zsdRRL6Vja|xBdxo`CkDh3fc82so2Ha{GERctV>SFT89^=SLfN)l|*LD zzl1IZ{xZP1li4vG)15xRz2}c?1yI|_1up(E0)d0%x+uFtC?w-I-qxAfVrOW;s4RkyZ`m)VXcfxkba5%^|eiW8*RvTpo2c zmLHR`oe!`UEi`u}ir4o^mYRDya}c*SEd{bRag+^ zH?NH7^qSaZrxJmh-53K*6yZ?dI-QgCy)hJnSbKj2Hlq<6vk~}tGclf@8KdLbEH`eY zl2v2d1{3FzR9AmAV^~#(vHpEd^wsf(5M7c2d z9!7uRQv7C6tUZY$^6Cl{>!;aNS$IIP-~EDXXR>tVs2o{=oIb=wlFs1M=SOKm)#2>Q zHI%_D;>yTlN03-^<0#k5mssujI*S+gwj2IWC8o-={{UwdZ6|IeOty$h?)eKsmrPik zoy>H*^#WsW4`r{!G#s(Z@bWTrnE1!1uq}TrWwyj%t>4-I!~i4_0RRF41Ofv90|5X4 z000000RRypF+ov*alsH_v7yoMk^kBN2mt~C0Y4D;z%HGls_IxZ_ZuE3rexRLL~R-{ z=6 zp8o&?N2%|E72N$FS*~V>$Fdc#nMzd9>Kgl+UlG;jP}uVZK;mR#U9Ns0 z4qU_ro@U<=fGN-V=e%@8v7R6Xk1>COJU|OO{{V6QC*|-9ae07dp3r0516kT`?qV<0 z{bHaK*ERc^d?KgjD0_{e^#p2n9SqNGa7B~E6-SsMT=)12LtI1>oXQ{@LoGLs=#*AA zkM0&la}ZWb{!!5xq&Awp%2RTO9%DeVJbH<@an-({i~CC8`Y`y zO6FmHCxpzSvTX2A(jcEPSV3LB1r?2`jizZft1~@VzKc6 zbLJWfnmt7=8MEpLX*3msCy7k1YIhnWi>TgI6*V0}Z+~$V#jbqC0+=rM#0Cx7^%Q5% z_Z>aKRXaujIDn4eUubASb)BV@d6?gcZ*0UTqCecS>xdMr;y5USCy9S;lUuohxWCFE zDmzGP?g|{k_Zp>>(Levh03{Fs00II60s;a90RaF20000101+WEK~Z6GfuWJH!O`## z;s4qI2mt{A0Y4BDa0X#=q#!16X6@=La&Q*-n(ZBI2m-`cKPht&W{wDD2w?=iivDIH zCS{tO`-!$O-aQh^IR1ZeQXk~X!uxRns1G2Fh5S*`LZlr7A8|mn@=T}=T@o%+P#_)X zTj=b}YOdTIy$F9^4T|_Ushx4F4j4=PB}`kDS;66rbCCsa;(!3+YZmPe;8fMv{{W6d zd7G_vFUmp&Rs~)hLLri%I~@N2NLETIQRJ0#))*)V5H_F4fqxfWnBwQW{{RvTrBS}2 zSZ<(x;v;syQ5QDcx~7s@0TmU;P^zF<`_C0)aJc!X3f2WVem)f-VQCxqzi==?Cbzp2nCpWCY`6GRFrP0w7 zy-;0ycM!s&EpUW>f~s9`{?QRqxvPkhQOtPwVp5T{Z7K2B4xVG-d$Gc)qTQXRBaE>18l$>)emnm3WQ$;*UdAl zn8`M+gDY`T!a=bl4{QBP^e8}8yfJTBf+2rS(p#8?yx!{Io>_$DN-Hxr%5!uJ06hUu^+*UhOd)b}&pDZsL}HyVuz#9^*np*Ysa^uQ`Dm+8?67HPXy z-u+Ji9f$Ex5)d6j2u(C6sg98c_>WLDix!0U5ZU1V=4VA%H?-Hu*?uaHvZ#!VdO=hG zDNxL~LX0n{xY$CdPGAtv8Su(Brzl=tr5J`JydAK6WtJbbZIo8VszyT0@_-(??Mk)$ c#0Qi3h&6=Uwfsy*$ztI3KmXYP000000GglmivR!s delta 5541 zcmV;W6GNv-$;21AmE7PDc$28VUda01Zh#by4mp1%-PP57&#%rozjNx;z3AAnW6&c}P9Lk&kdI;?0UrUC00X8H000pKLLduB z!eA7@C{Uxo>;_0O;Y1^K7^sMWFd(cQ0DlV{06YY_RVZ|!V>MD?wT2O3#4rMM;eC3A z14RG;lmRgCQ04)sxi}dEpo~$5C=)u_#B1%et5u7Wz$h>jO@H=*qJf5D1R8}smC`Tg zsYe5q0=vx5=pywKN*H7T2Be7n<9!ApDr}-P0T3~`Rdl!-AFIZvT#QjBvz|L^XPq0l)xiRrKR|d0!b3fFaa67ta7x3Vo8r5e~&BGjufoAYwRCi?^P^ zRX#=-pw{;Rz<&TR0=tazI-zWVGW3MYT+d%Jf5{(9w!>9VEw2HP*HO zaI3JUNG@>^0YQ`tW#F)g)3a2INZSGc0)n+g;)!aeMTf%)&?$)+W!YhBrp6-7StAI5 zh@rrVH=h>V3dOOa`zuXB67iI4Xg8atQ50hUPzLKyOMgcysStyzzk;(e$VrfH%e$U|`J z03af^{Fv<3D1xh37-JtD5yRO%3K0MS!KxEdwSR}eRWBZetUNA-%uPc903+B^ES+#N zjN0`N2*H_Jvhj>LG;IV800KBtjrNvNpGuyb*YWt`qwG< z$GgjPF>FHF%T{i5NDW7GhZY0Ctnur1k+|aHeHmu0t2cDqyssCkSyeQ)AOO1NwF}r`u#*jKJyDzJEF;>j{95z@duRu5>1vMVryj#m?xTK=eQW zBPgh%b%B*A{0|Z_Y&s(=Fd>DWf z0Lejsuuee^0TkD0g)T8%00aa(OJkV%TvCTi@!tyV@@a~G9dQDJo#(LVuSSIZ=6}71 ztJ*@QT2)6he-Nxc>=bk@Z=I+n=M+O&0Bk;ur8aSltWKr*`zm=$txnr^qE_GXqJ&{% zp`X;4r(KVR&ecKNDEnXpTaVZLSmbJ&=4tf(?dKv<+^zINorXgJKtOPyT2N`*+3gZB zTDH4<(T;NsUjOx+=eZ4MN@~@%BEEv9`9|NEu)Ro#PF5lb~p< zq(&)oYjPxW9F4*g0~m&;iF~s>=~#_GXdB#eslTG4Dj!@V7jlF%OpM^DQ|NA|LAW4{ z;Aj=JZ+PhiK!FoAr_5#nD6GXT<`Y!H6pi^bst~3U);8h}VeHa%{aQh2Gk+(a#3s|0 z<4){WX+#Mq0}v1xMcg^T&?n8DW|Pbkb}O``Mm<TZ)}3Af;?d?}SlVaes006;-8lJ1B~9>XfT-Q)v?bC=^OvBtqL>gtDvz!yN+> zGvf_>%9w1C<_&X9$o8$=TTxV{M0r3`2^*RjcYFVYID^pi6^WuC2$WL)0C+SMp-w{v zFf=o6_R!?OKXOfi;puT5m+mb4x!4`e5d3bqV^AjxFBD_kBmlT^0Dq|PvPhiarwnHF zO9)E)m*k$@&0L&_-8=^f|D)@MZoh+>~0_3)fVy$m3>b{M0Fq-vDS z8l21zW|xb_V(|}vkAFb9-W{LuCgI-U4qc{t^!^y08$b< z|8~MN{kr5ylH~Dtu2`TAs-e5i3qPFI=Y%O^FeuY9X9#bZ94h+pFKeHys3{SJ3ywu2 zO1w4Yv0L8D?lh3|!H;&8?L6fYTO&JA2)lnoO8;~-XUvy7K3KW+4MK^41pr`-5vpCA z-hckY*L`(_=YN8nUfu5AV>bzW?Vmb-c;~aM?dzY;c+bH}KbbHD3uBJ;^oF zYFF9+e0)2`P3MhfgYD%{W)Z?`@OyA%iqhhlf!!$FHGeRXGhpAzZJ&Mjra>|_O~;wq zpc>K80#rRt94Um|Jt!&O%ya#(u9&N8Ufv|C_sK;!Xr$SVs(7>b=;*YT)ILV=^!SdP z0hP6-e_na7C^T!D9@T|7EC?Y`!tMZK3`Tdg4$9zVhKtufck29M{?RIgaCyzyRo}hE z8PhYx)PFzSOj;y0Ae8-fP?Fs!@K)8QbNPFSUZs}jf&hSoeZwxB5#Kd1iEE_a|6|W5 z7zu&Qws!mb|J=KhGhlA6BP+qs0sxHbW*?HtWBu=~dAzv1z)$W*{JEeoeX4-ag7N8m zBYkbfTtNslnGywQ*_M}T>v+vcbB8%-BvS*%Ab-Uw-P$*SGiK-EjoS~dLkRl?z)vDZ zXjn!%b5NqykCEOJ?4eFY^Zw_e>nSD8=S1QYW6~mrfI&h}k4@u{!*i8IZ>@f?IYMzI z0E!IZp^eo5Tk^DKY?qcRYiYZb#EX>+U!@zmX9_)@A6c0 z#{6zrvW}TC1Bf?^)BEs>xcg3gxBbvM0e=U2)J_y7{Vl+w(m6wuWo`@gtDoKzvXNe1 zU3qfRL{4VV!6ZI8HchX1Y?AOZ6L_q@xct~_EAI{Jx+KBSfT!XH7H7aTSR=iuXMC?z zu91H6SZP&J_!>b7xxLP%8~?x=lNoQw>uS@&4hAY=cMnc7aT`P4%zrR=S7Gtvf`5#d z1!bgmlfXC9{U?9e5sZ=gm2dWZy5;Bp;|#dHe?r%=gTb^u@qN>H1)ogwSh&M4>u*A1vX$q80KjfQ0e_mWO4wb4lFVEqeS7soC<47z8dabE>tvNE%?+>` zgeS*_SSB*dcmdb-pD8PN=ktd{xNRH*W;G@GaY0GuKmnN6JAOdAA0s_maUv3#5du`_ zty!}ESt^5a2gzqUKiSnwgZmRV>Iks=oH9tW$=B!DIb*gTTzjx^ zd&nV;FfGOA4*<&8wFx4ZjDNE^Lz4Nr{nLthMmY{5FO-tsFS(hsn{Scve~s%H2rIQ3 z{J8$(CHoeB@pw2koe-C5l9rp(mI1zxwIiGUpj+DbY0LtVs9-|Nde{bpx74u1Ld&&xSuCUx(S+c~Z|Udk9eG%B@AB5zaSg}>ifQBx9TWg{nT z7@__E005KJ#BmPFpu5BPICl&1_}P8$eEtY(@!JU*Wb?8uFY}Y_*+Y|irJ5T1qWX-t zZ$}=h*|vZ6(c(Sf6o0Y+Koq1zODERouG&o>(!;jYEyvxv&$tO;6d<#MJR#dYGRw;U zjz`}cQ(0RItt1ws?d=D*Hn$sIFF&7gZ#n8LDDwgUMrcrmWm5MJnen{tih|-j&wV&u z7Q;=gjgsZ5smlc{1q6WIZcj=|0)T1{iIcGy0Fik9<2#QQ?|%-t+N_K8?K0}A+ZP9t z>sEV6yxIRxrIbAOzvHTE!)*eijAo|~o;B)a%7}j#1OQH_v;L0`CLs{*Z{3%F?ChS_ z)jk01IreS-wuJ$N4G2X00Pu$oZ>bE^_17~6qKxT1vq`pwn^_~w>-7dWdqMG@_trcC zQE;3~z~buf-+w7AJ*dlU>vt_JD*IKJT+(hy>XJB+HT75p+#I!VyWIih?warQRrm2d zZ%YbB!gC)^uk+T1InUnX-!9$o-+C3YdUP7zT;-}+cwH`+Utj7`T#x@{9DkRp6$GIL zOKuKlf|I3(-u&!AlR=+cl2EO8MqYE-VzU4!io*9oC4ZHL&n%f*Q&)ka>^7DNP({tz z``;dRE~H(cpN?!^uw+W(Xc;>HkxkjDxy_nvvu|KrR#w*By9WxlKmEat<<7GZm4Xm< zd8!|NH*fdREdd@os1KDNZu;ZvtL96BZf(De(aD4EYkW5E-}wRO!>XzhLImLo!f@pD zzy7xQg@3|xhgve-4KYEJOmE~r(AkkQd*bu_W_JMidiV0RI~G;emPn$WeRf9K(j)CU zjy;K7^jLLub)3yq=dCSs7N0CVu=SVxg0p*!k~#Xde=#QG(`5wDQ&sLPK2W%Q%g@Ve>MCW?sDCe$ri^xW^fJkDoQ6?9cg_{D{KwBG zshWxaq1b;$3}cJ|yKwL8`p2Xrgd#?u70vVfo$DpU%c8Nr2(C`(GY6rzp#6G!jS?udQ+>XxUnc2QAXy>@XMzBr+Knqnla*OPH$|x zG=J&+$Ml(z6qo5gN(C?%>5(=nJ}$Lgt$~Z#U>)0IPUGr-C;-&E&O1ge;Ix6X%N6vU zD5HDbA>x3Ni9jn&ojUXy*<*UUas!c^^g-9<%w&N*(KJv1DAUIFoP`i;*RP-Dulc47 zd{_(ETLe*SHOsd9C%xPDZe*!%?43URk$+_CH9@3`L6tQeab5anjirpX>$*wFNX!|0 z&CP+t-cSIjm)nLdNbS(MUDu7pBwPMt%qzieOa%=9A==$}FNS~GqV377(J#qD&>K^s z?6=uW$q!6?mqEKD`Zw>KG3u#~@i`%UHWUCDV+odw$pi0GR8PD1RifneytPlq@qa9& z&=~TLGaK1$#*`uVwFA&UYs}O^PlUXK7W$UIMwOA-cZ}%qo2xcMrj%qly5E+&z^B%Q zJV{tR7mTr+`aL|P+a&Gk!+=tfmD*?i_;(Ss(i62WdO+Wdq0f%$b<5QTKvr7s`QsO= znlH?Gbm%%#iTB3758NM-$$zTm>)mbfP&M5;P3CHhWEgeVr}fvW0?H?0D(mscmh;9Z^QJQh)l)%6m~j z`roH9A^_A&X>Gy#n;r!g+wBx8@y)#MncnH+BIVU02LM92PH}GDw|G~PDiq9(XmDiqH{nP8kWk)4ZZWS0*q9ofpP96M6MnW%HG=H~B?$SB{TxJc% zlIkP-Pi-qG-F2dLpD0L?c1?t8D)D6`fBzC zzx(*tKGp40J&e`gNFV9oV;CTWB+(#?rU6~X4$r=|gE3VlN(;o;m;vCDYpOr{=kit+ zRs3?Y?3Y8Qc6fX)jDJOpFh)3#)S3aKlu$+~C88i@rw`0YAKoQtfZ1R(%XWltRFz4h z3xEc!Nx-5YNVVRwQs;?k_xY;YQm3cfqtvLHmoSY`O(P0rR1_qP1W7O$M6)cKECzeB zJtM)ImSoN7U`k_*YDA+z@FED_#u%0000qzHQqm0FA>E9Mba#hzcMS|P z@4@fyci;be*Sc%ndk<@vGr@Vz^E`Wh_THbpH=iZHmSN#r3RpW~K_HN?`ce4YxG(h~ z5dU&1ENoV13nv=}aRv{YHy)mDHrD2rE^in(87zG~Y+l$n+j-bCi1YJ`2?$rJVH0D~ z^YikG@dlW3GQgZH>}=c_#EtzJ{&N9KH<*>9drSxpBaXvso60gAENr|dothActdbfe z<^Y!?W*hfm%s%ej$}3!48~`(kS%f@PR!~xaU}0fHsKFly=8pik{2Q1p1frzG4!H~7 zEG~o+3m0;8+sfdB>ObdN;Q3Q5oWJkmfaiSR1qi@rBk;iwo|Ayj;6)(5-~+tu-|zkR zSy4$<;|V`Ez{kri2;t}D=N0D_66Y0p!p|?xCn(M*bTcg0t-pVA^9$>LoMVGS-VC=0 zK5+gs{B7|3_Ww91{U5i5h5he!*1+#z|K}Xa5552o;4V1OUC95j3O6?j4vCq8$U*Mj zzJ2F5?%g|g?%?6w#U~)SPjK%Z0R{0RLJ}HEI$9b^YU(FU+^kO+I2oy_pNg4-b#v9s&9N`{exe)b#xS^8o(mi~q-S%nu0B-J6@j!D4`5 z6Jg;HVPSql=)fDr#rk{vI~njbHqI^F+js8b;ok$lQ2h`Bt`!dUEgW3jTerYZ1HjKA zw}^0w>G@=CKhm_g!vMIF@V|@7xXUP8{*zQ|=zvMU((OGS{$nz73QA@c)~9Ujf*(s~8yFf{S=-p!*~1*%Jv_a<-}v}`_!#sl`16;L=$P2JZ}AC< zNts#MIk|cH1%(xrRn;}Mb@dIuT7S2-cXW1j508wFjZaKYP5)T}mRDBS);Bh{4v&sc zPS4ISke4?zyP4^KkALU(f14Q*I5X^9w{ULVxtSRjw)f4{iEiQ2^W7$v(Y#~f`iO!5 z-CYvdsEqQTc#HyC2c(v6L->!G1phD}-puXq)WDem|1YNY{{Pq9mi{}l|2?s32muZj zxPLfA5GbU#p1jVb6+r5J`nt+lHgN5ZwykuwUU=OXW=9=Jnw70KXs}Rmy}Y`7EVM3n z0r%M%A0a$acrKLV(JSaj;C&1|VRzgXabp=q1>CvNc43b8d(Q0DCDG_NL=v}iiK{3k zdd%J2ZL0)rzSO-oAsu6(+rvOM7%GEVNpniRi~q(z4(P6L0Xj8Eik#>oDlZ^?PH4(m z=FXkX9fyL3gi~Npw}jL7FhC5gP=L=p`p`{&EN<+?ydXb@^~|XGx7lloWv_*$vqHFi z1uH`b-Pu&(PYmQM1qK3bGkmM7tgbF6uCwgpdu~5C_UpR(JKydFzHnAW!YXH!ETp(n%53CEb^zkyKPK57e@zCWwK3ZVCgDDet%zM0;u^jYe;YzIyfH=bBaTdZ5Jk>#5`k zC($W$^P$)s3}kszU>{X*WZJX#u*BGd3ChjjUHWpa$a&5DPsB6dQR(V*L`Q|m# z25r!+jPTS7yRM#LAP$x1u0}@gKE450L@7T0fhL?S;qRLA$6$2SgeECn4tgkyN{87yM5O7Ay z?s}$LU7GGm$D*J~n0E-A7WOr-PYccrt?pjI+tN;BpqFbXc65qs?g9of16_m3I*oqc z8h)SA`>lZ@<4p<`HU{(+Omy4b}>gLEjt_caZGv@HpbFSC5OSrOo|Yj zv%w0`O;*&IPzs0MF9Ykk-@^0SK#OttX>pvSPM6Ws1~=#8WWAYF!7k`zIsk7rOe}f6 z9>K+R>pQa0z5N=|rXe);rCksO%-9x2>lvM}5W{*DPLD7U{%dqPJ*>9FI9u$Rvd{M}XytDz|(NSEw>MI2Bc+~qSs`Cor7x6F*?dzP2;Gv3z*_vMw{XR+hHeTz;++e?uybi*~)2Y{@#o;!&kTAS$2Z%fpx|PC5(()5H zI$trX0O8Iy0|R-5ft;|X2N@uC-V0g zRa9v3KwrX@(dG zWxSSdq}s@+@SxJuE zI@h1GxOusJ1)aOVVKSv$0m28 z6q*hWyzM@#_nfr680h!}zuD`A42iZ6KqS}mEes@E`}@+7z$scGTD{30+}OyvjtL|s z3;EYk#D_H_v`Eh>7tH(+4F@G40oP$8OZbyawE~*hq}T!G z{&oqsM)Ku%^BD%a`f3flEo)Q~L<{p(tLJ;}4e)v;){zXlGt(cYZEr3k4|7@~yQ?d- zXL`|=`R}%k2w_5P;qkG_h;eV6<`=IYZCF|Gh_~pQ6(tB_*Oj2TEYyya(A(3Ay^eO;%u|;Wq1Nj?8*t6q{0ZGG0~ee$ zBd~t>1pJ~Ya6+$r&jDsC(&LPQWKjwh$k2(HTc8D#8lA`X2-QJMNDs+{``cCvsoYCE zHJk^Yp0mw-s3ZJCd$RjRT1R!(Ay3RB(DZZFcY+S+dWlAf$~}o>AH&s1hX@3(bah

Ze_LUinENI*}2(xAjq3%l;E|Ls)X_|&yz9wsH`7Uh|hq>)tIUe z1rNmH!{!BkY)skSwC&(KdV(P0szL>_5Pp#G$(3h%DiK0lK3COpjFjSrZH1ORdRmOs*9 zMQ&R!Vw*EpcT9{8(??2^p3S5ttk9mSz({T9lty^e^WsrkWQ_KidKKTb5t8+Y61+09 z$2E2nz;QmXs9O27-}mgShzw;gNxKf}bI}apLfJB^pt&pW0197|d)=02b%NG)o?KRL z0dEwzB$e^|;B`U1*&Yz27I_W=e-KLXmyVmj72B3}uRBH{d%( zgf0T0G-OgiWefM|Kxc3n12JG92eOT?6r4e?J4jb9_;!f{aP%k{jdPWj#Tg%-2O z6XxNgT^99Rs8P?lXo=I43W{vAqT0(btKx;UN?^GNO|p|hy5PpctY=bG&h$H+77Gr7 zI0*bT)%OaVPeNhLui(kw(FetWCpt#ijf4;8vKPD@9LuBJ(h1F10Ct*(bh~c^M%F+T zQZ=98advVkzt!kIv3lqGX?|6>+3D$XEu~tvxu|Nz1GvMurrF>xV)*wV4$#0EQwY#4 zh=^?(J-$Q9T>u(l#0jG=m3o66vt=g+@&*Vu|1`Wb@odz{daAK|rc(^rTu5Rr;I(J6 zPG=h(fDp7kG!h3&72tUh3r%RtN_V5AMjX4Bd|^KDUY*uIwsC=?zUUwhtmMw0n*&FJ zU7xz90{BpcPLj?oVF5r?Q9NZyuZR|dFj)kzlysaD>wUi{R%S!DqRq?jq2yNsPqymN z3YAS$58M`V9F4ZLXQ8p{^bIGMmwKW(EU~%?o4H#`U0%Sos>FL^g(@bGg#i?PWs$;q zIPD;S0DU(-Ptb7CkRJM0>=p7AszE`~9F*sZUYlP=p`2}+_ew-ksA!jHX<=3 zJNmDYZ~ECM4hi4~WSQ)C*d?>@6A4ZXWJG=ax!qfC+#15N1lajN!+6{K-8;QM`u##a z#-#zd(J^k}W7XH>GmN2CC?G1|xS)WG?wX5m0;!`#m#~z#V2$Lx&JNg zh4H{XG?ZpDOP70*Ndj0jM8`RClmIWR*p8~Q#!io)&evXA!-J1VT~z8+{ETa(rM8c3 zysadYtZVfwz4#4Xtis@e5o3~CGQu$dD>Fy~aOz<-fiAwEb9Si^ZmTRCPpfBYk#V0g z>IMskuOv%fGVxyy_)br{gV7(d(&h@>NUYW;n(=7M)c*1pGAd#8?t_ zVeJpNSnDJ5m~?mbadhGTs(|9RAGLeMV5BgkC)oE7;w)_5ZXW55#82e-r>?7^aBCVm zSe{pI;CvHI81-RSRgGMMeih+q@wED)IsY=s&>x|#W)c2i0gZdJp?1E*vCe~wude52 z1B@yK`feNp0Q3xO2fhF+^dqQ6T~$J~953(#aq>vdUttPy?|R{Y^mcH2r86*pqaKbt zOVlSA$Q=5`r#19yt_31O^hc4NRu^|@!Tzh|?p^dyp-3n3*)#J7z7H4p&AG}?hJ{4z z&)==OrT|14A_I17#9;v;FfY_lbZ&LE=ZsAr955Gv|JHS>nI=TO#y~pTi?`i4reJN4 zEYas->vj2>$~@XieGOk5YEgXV>OY#pu0aXeQ@qp$J=AbX3?!%H0*n)sc=`miuITs? ztLHb4Qr0;V1ChF~LF%WrWQF#l%t+F@(9}RPwU`$Ku120Y` zn$~V%*@v!8w{P~rk9($wv%#c#=G#hi)`(zd=zf&u%<_&msQOmO zp+aIIwtDpb5y_}n6#aLm8EG(mSZIGR{1?zs@ncP=n7F`ti51!HPX zacX&%yUiplPv(F^*-5qOgjs67({qt|T=NeGQaiB3-el5SrLx2he2ZNeIHvGGY!WWy z9TheBe#kY)c14#Vld`1!&jyf7rJ!@)$$vi6gSO43`wj4oqOp;IpI(-596&2UeH~F> z;}8+b@^#OHtxxo#J$a{+^e!^CFZp8~6Cpx*`KD8)St7|cYtWv7Bt;9uuGAkRr`(=+ zO4}VrB=XY)+CZd`?gnTVuEP$LnGKwpikDe?xwf|rrb?u!(_ytWW6LRa<5}VXxlqtv zz}1;BkZ@x)O$FEJJS`=pw@qvkdDZh+sD&>^_GC>{~2Hawhq9)A8$O=$FpBvlGp9qezN161-U^;ZFknyzptZx0dXq>^$2~OEq0X^-YLM4eoJy- zja|n`ZLOk!LYYk(kwss*wh5(MeNl(Ad;bDp_pEfPliP%^D!IA8UI;!a02O`VFwnd} zs$yOBuS3#bxK=U^atk0v{eY%w_Yq%cWE}RaBFS7jg~t`IF_1NO^8P7(8i%&Ns>&Hd zAC*RFyVnv!4-(&0vH|wr#nwUOq0D={dQR~xn}pH@v1Zrbwr&;KdQf!fmMA!LYKCZB zJ`{{MQr(FsIBbo5^>PmkTGY!2tny4lgC_eb?K{QR)8IxVM#)azB!%)rnyTiqbUUFt zcAd-DH;#9_M#S@1uZU&dOZE%waY!VM)&=bemPlEe_O{ppJ{^ZTvVDT_az?Y=nr;pg zAb-jKo-W~~UfgL=?F?OS^JE8w`O}ow>?vL%d@V-Ocdle(45mF{XV(kypp=mCcu}SY zUh8&oN1kxE+THT=*W7r>r`{29q@0*2bq>7FNv0 z6;Z0T>x`>6zJQ1V&XpxWO28hl$O10`Q9?^|GxGYDwuk&&@juYN216Uo#s_jANWNWI zb^-nV0Xj`(WXNemZWOl(bdtyRB%T8ueH}*KDS^mv7_6pZc2hj$nTXg?-6B9#sMVBI z>&E=RfK5yqo+QAbsBsH6P74P;r7WjMnwl|p(9(!yJ)w_pUI}ijklP%)L5Z|7M@{=! zMY~-!y)lqaHl`A2XcnFMiUUVjVlwKiz+(Y47NLh|g+%D(844Q5aRuiCFp!@8_$`CV zJ3H~BHw!h!Jr>vzYFu`4=U51y#)b&G1^vPkmF3oPMcL^^bwjme!u|Dvr)(RBcb~D< zp-?x0R=&Pc%N!aEuIbDVGhLm>P4DJt@vW(zT5k0<>ZO2Q@r^?pqpo_U{}w1m_1#c_ zMqZ~g;JZLbyqahwsPAt90UgBW7oc^G&lI>Ej~zc!$=$pnV?w50Z;O|jN|c1Zy+gMR zO?}~H=dS!^UU>hK?`1{ZBOZ{aIQ*kwa`<|A6P5pNVL%&x9OAj-TwB2{M!vuEwBq%k zzC&5_3@TKZsA^m!{{yF&)v*w@ujxq2-J8Dz(1JA~Jr+J`0+q-yVz$PoMIn;?ZmR(Z z9xZfcv~e5k(fw?fuCsQ896dI{k+hz6@O^VrSy?zqTY+A9aM_xg{q={zq`3~&HA|D8%lXov+^*nVU{~x zv%X24;JWiGaa9j_^$UBQ3&k`5UuNPAJnEaXk+p*p9y94bmM?1U4jlSO)Av*HXMyG$ zzv+#Tkhm|Y+^%m0x)uYWS5o6k0YIlWi;uGD7Hy!*^{wIU>~N)lQs~$GDllyPk_|oJ zxxO_XdGYDtjqvjq=kY(%FL4v3QKvfr89Ld*2X1Rs#T_W^%W@0=DTQ9rJVmLmnX3OO zi(d<~`buhA{9Znsx%X$_J`KRY2WKwCCT4K zsJZ(|4^2}bO94Qo61f+cSz^#V)Fx(zH*@XKU~ZB=UGWlVcsdeiLI$mh=W3uNyX|O7 zJZWX+k2(NCDx#P4Ufx5$uX0)Q@d$+qe3Jm(t#|l6)DIo9PxV-0opU@(rmFoi&6WHZ zJ055(-*LMn^ff5XD<9b>=n0>Zh%|R8(VdV%PuzI90H_#FU%^Fb{L7ZY%3$RwvDfb# zhkNo+#Oa&*rR^SbQi$!mr^afa9`J{;5*HLzZp9Y} zu=fQmhi9SKqP89hra$WVgC@lt_VFgD@8=u%qbi}O@FHGHzP|y8a=^=}t7_mEUJ?eZ z-b#!Sxat?Hah5?B>3YYg50!nh#g*8Uc(!FvFWO4LdjpUm#p(OxOT`Y<@=lw_RwwyR zYTF;_%vYbaKpT{de6s%?(+ZKhib zrF>T2iaR4Zcg`yiv6g`zR;_!CfkfQoAGqRCzNWwrXksCG;kqmEzC0-hZ!9K0swCib zt+;&U&a~Pd5>0P#T6)xVJKTP#1#e;Ix-fS-b=fl+dO(CG*%I8D*Xrcect0NzUKEOcm{m;wt?e!y;Z%e_8 zfYW?s5ibk2fhabG9<>(RC!0wVqledVc|;3+phyH+6(AjrH3O#gQttdE8%W}R^)aKK zqc9ML($seW6dfRED%GClgWK9c-Kb*~o_=--=sae1nzh?Tg-d9VBjTQ~SV6yL2xsKE zDzodBFoVA8)VztQu}N`RoqyBI2d5GD9bkkjUsgF9o#zE2jUulU9(7f9ogNcjXvd{! zztU)8Wxjj%c=O9JXWgR9jg-En4jCFPz1859J32`PPz<;l7L9634Q|X2BfRXlgS~)q zF%Tne4EZjP%T#Gk>7OIl6mKEgvSWuBx^r-Y)kh9E%LuRFy(5u_(nqZ5o#uz*jUyNB ziIG>%qt~*}zIFf14DME+xA1n};}9VYTt~|!0oNemKUlyrZPSgX%rnrq)18lKHlZvp zfbgu~%pmdKGhVG0oJ!tT&^!Uqve6g#KpP0_OcfNBf3;9RheJ-yMn$6CW;V-?qQhO| z%PwEvH(<9Q7fo6~rF(<2vQk0@mKkz#uH6%51LO&6Zcmz&HkiC$%j=8i*qN zz6nZLF1%My=LC__?CDLqe#!Ta)BUKc?$XIZ)8T%qta&RE-8!ki ziu^3^P_7&b;OctKM-F_SAv`6c_LxESX_h>HJZU)VL+lLYzM-GTHG~B8LWFX-VO^J$ zA{6M3e{(4ty6}*pI>sy7LAxsqBqDauQ-}5mF`Zae0aYPzC@t0WQ zuJCqv;OhaZ=x~IP=<5LB?3e{P1D7osxU+&vb~ zs+Cgw+MZ`XA1U9$tG>>5bbLhG(YLQpUd_^3AoTR<_DI&AzTF7)6CKK@;Ido>H$BL! z<9HE__G}i%R}PJYg5cAvN1Y3iUsH~EpPBR9v(nj#Hr8I8@bBW0u|)!_T3f7u_{VHN zfL>dMCcVy_-E?=-iBVFAY+YoSF7JpWyM!=NBVNd)cE=$?tYl@R z6qW44O2zO0YifNyDH7qASdVxam)6- z@{X^K!Ff2qXj;MUw@jR)y2ksVeQU4gX*JQKFFWiF)5ZW(i2S_zwY$*$brJ4Bcz5vL zZ>8f=Jtr92wCAfLiLcXs95gXC5qY;mD2e?v9fUH_=$3&_7w8AFsTgF847(ZcBFXkI zD!$*4xFG4Ye!dOLBYWC8T2c_?8BC!G`A(mB>I*AnYY%gKpU+N zuuL7P{7ph4IY9a_S2ca7KWrk%FqD`r1q z*@U9nk5n|0I3r-dt=$P)D8g;MeUc6v%VOSzrcRXOQ&zhTk1@w2FqUGhHt9!19_6#P zzWD8@8>)V~jrP+aCY+~?Kk)B~JPZWP3o^2P54X96@T<)WoaU=VzJUjFAr77ZCE{J` zlP-66E0N>2_st^k*UT`GYB4cvw5lnRkhT;Zr``K8L(owLP!ejNsF)BX6^ za1B%ldP;VMUE}W>aQ0}wxf9!OSvEAi^HwIWq}qGWNFS%#k$875t-G3_8iBhz4!ITY zJjoy{uBadhS(B~u2kW3C-lA%c49IQAQ`K-%QIY-xqaLsRKss1WD}V;$a9N?}u=5vz z29-Aq{<6LnMTv*XX`I)$qr*rUZE-`PR z+c;Y|;8|l+wAEDyBA^or`sL;)zd`P?NJL}0dN#TA3?#X}S)b*fw9V!JmPT}r3J`R6 z(8lRkNn2OVInh*ItDGJF`lfHD+mWC)u*leKb7(~AA80LdSG0d&4F)Y=-%f)P9%ke{ zEuv>@PgP=*{vB_JX8IpG5clEEr&S}4jXaM3 z&=|b}z=@@YaK^U4eM9&=?2fa?Fpw2ikwEz6-MmRu4Oz)%B{C@oB_{@8`SJ`}3{`{7 zC^rUj0cP34l>ma8GhyEDMpOUZun!S3g{qR_V+a|2?w?Kq>Td3E0p#eWon_8IAFXZe zHH8-Ngdj^u>foN&B8UPSzxmilCy-axiPVRvAjL^!GSD*yvNM7PBLkPXN0&&Tcl@eDjzdHx5`)ERNr69|hgkO1w1+a^WT6#)STQjGSz#rK>=yLO`40KqTk zXk9<8m>BhQkG;7mV&X1E-Fj`cwo0N2@L9}FxWozI=ZIQ=|>hYl-prm(pm5l012Su4pc@Hz@VTJc5#iWjSpJYeEr6CFL|5GRHXRr(tbKCX<*3}AZ*zOV+F*~K`Yu~Axj`|i02&i2J}hiO=-7TS-}E?!NT_^ zB@!@N8sfv{S0Y`YGp6Cxm8)wnFC$vw9Jau&zK5>%MLE^h+$rlrwLKG3>0R#!vq*{; z+NTs|_9ZLs-y|vkcG7y&cgM#aNejbdAQkpC%p7Eqa8hEl09f#~G!Iw+5E|wNgML`k z`kQMuD0Kp(dT8%>fCEfZ@YkEcBM_yH!mGZ-+9cC~>O|>Z(q>>b{IG!AZqhhEO_f7+ zk{|F}xGpTN(U-K9M(pAv0?X|33>mtjC3|UFmQjwPrv1HGU`bc^G>eUDSMGB4l$Ac? zmEJ4B0|`1gDz7F-T!3Bpao#-aJjU$#_G3lr8zt}M0g71iRn+T?7#uKf!UizaW2;{2IuD#sf${K{fT<2Jqo7w*-Y3)#_inCr znu>tz>(u8kTL*(lAoI(?=D?W}&R{UJzQ)eMdw-dm6u8vZblKa6l+5!KbjXAaz+wPGRM?nw4ug`#%g$sHB%IqlLeaMmyUYye z6i~mhI+vt2cp`vYW{zNr(f%AV7A&zV2`Dm?58!m|3No=;rTs8n5np21EQUyk2zEKj zP|9z7@H(uJnK^(C*iegipEc@dcDk4Wr)ro;nqjRYFAP!^N9(8gs2+m#u1>IYrm*E{ z?iBv$7Fc67=?79hEIb`_=VMxZ_9n^hxf$=gPCL7#uD3cGb6Zx%g&6aKoJ3)D{5(nYrK1ijLVRXPcXn z)v78D)bJM4QjYgeiv^6P_vhaMjg6Pu9~`(c*>l+1pwP~Mh)O@9X@%j}?kJ9pfFf>- z8bHrnIbM}~l%WH0BqW&>^qWkp*yUY^#pX%wf}qs;XdJEb{L<#-rv$tRH}P=9c%|&2 z(cr?Y2~#NJ3V|1C0=tc~uI1)jzy1;TTo}yg%}wU%l2lXk8+H|s47&IG$@Tg%sj{>U z^@v}F_Ow|sqHwmi;bVT;QJCwy4R#58AiJTaPD4bbC*ni1VgdXFDX@zQ;;OXl-iSPd zrV4^-#Qin7kTbl}o)hW@-ED%;AnIY8ALh+gw^a!rR61GDwPS7fY4*^b+Pcj^Jkm7C}LLEFF>Rd>pY%ZA3r^JWGLxG6b1&ej((%VU zx|eaMgKb3 zNGv`a4nD}}xTruk&A<@y* za9R72kM${Wr#5{rANd=ktfO#QLf;ktqtx-24^=4!kr_;9rv1tq0-4lBkXv{MM#EJA zMGEll$U5^^TS81g?M#=|wS8U4y#Q%V0<`mv-3mt-oo_dX(c_`tXODa;kV@?jhUYfI z>XQd`+3J{($@&U!gbGSr#UC^SU-R#mq)8it5%0_+J)vJM{uaisDb~q%*qBBQR)yHV z*1}ixMxZNx@WC}4rEJ9|V7aYKvdMmzFJ#MjP^Ty*Zr>Ie6_#TA)NjGR)y zBDuAEU3EE>m}(qVK9Eq|o#{XF8@ITLi`Zk!#QekWjbI?eMTA#iabJd>mrseFBd{|= zC?!HT@6Cv)<`qtix`LPWj;T5oJWQ>ROWUc<-;%wrpkv@3<_EUmgq*SDvV zSZ~%Fji-!FKLz?Va?D-Y>+_kbj!sEwkfsr_5;p7%+upy|2i^`Q)-v=; z5zFnZ=xIQ_pVDN$qA}$7nnLi=6vc$ow~+y9m{egbd|Oq?K5O?mAr5?1%ja=P^h7e% zNH&WQ*Y5g^#R$E>9}$|)K$)i&PcR~S&&HarGO zUX4e@)EUo{Qh-tXaOm}-uK5lI!lX?ZFi3F(AP)bag?VfCtubP%h_JV28;-;kG zG}aiU@1Rxn0oPP3D0O$Tp{c8_tH}Iv%g$=N+J!TNOv@+Um?}cD!cSLyXQnS5DG4+| z+u=p1OVHQ7DXrFs%iIfQ?bCePlXZQMh>6I!ml58}>H`VO*8Mi@ zrTG~H(Nx_gwSK{cAFUM-8f|sOKnuMgKXtM6*Ta{FGl>a^(x8jFsYxM4x*M=h-deR@ zFh`#&<@E(5zH<=h@FzeQ&B5%Mcu9EM?>`x;t%xUHwAHuacJ7V=)C07_>vbm#HI?gP zvCBI~Ee(k~ypu)Bc*AQ_K#Tb`eqp^tzwcO84@^5~eQzCoS-gA*O>8!Q&(lZZ+UKy) zMiQMK4R8`HudohR3Pba@^*yy-bn~I#_o@tG0nv7f45< z`s|)|Wpw2i-Flg$rGF%N%BJT?bz5f=>eCJu@41~8O+2F!{^9Eb?=OV#i{(fS>F8!o zBy(>0Z)xAe%QchYpx-o!_LzGPmc{MB!+3MxD;&JGAGh}2r;N6e6uZa{!9D|PJ*FI?>#utCn z3*rUS1v7D`L{#>YPx=ni&nMsD)rCGeAYd=+wIGuq?9&B>$B)h5?f*@HFveNA3ujP<&2hw75i@W9zNZfD9>+Tta@CxL0^o8p-!%SUv@5uTa#J@sO1z1u^v}MXGXwDgraLB**H9DY) z<(GMzjH3MQ#$GtL)=S|fXRh>L4-IKTqVu{`Mwt4(US`cI?ftxW;6Wc6WaEnK)aqv> zeywct{=1rRb=;SAQ)vP%Z!%9oBDpr6i7l0brIbe7Bv-=P{5Dk<(h{fNa}=x;mXC<> z3YvoO#Q_y8#=BRH3zs;=O}4{8x^$0I_Y}wWrKWPl6{iA~LEmj?;iiLd@M~?2s!7XW zVrw7rm+xy_zZ$yote@sBPFq$tQQW342~fO@F*g$3WTwTD^L{);Li1p&fPf&KiS3NA zn2=sv4o}FUO6xpEv|ffOgNbc`l;oW3d61())C913i#C(@(~LERb-dN*dV(oqH4~|^ z5X;zCty?lj`nunDWAKp(PG3~27~*DQL2UzDy8i9@`gd!=ouwz{9 zX^3W0w)|`&Sqm=iOoa*FUif-cp!LQ_?HVZgxaOH+?B_$^QvJ7B?iihYQF7PF84nSg zi9+G?D>4?jsiFf3Rbw8V@4rW_cMKzzwT9|PPn?7bqP$t3S;tMr>_#stFOBD#6`&1L zm1Y>7HgBxhJeo_Io)^Ff_kLKuXb>?WK5+7e#IV!U@&}{#t?wTUBJErQEZtMEe zT|*Vnkm;(K`*F{5t<#TjnbL??#LWQwD9S|?n#eiSZmCpjEgF3oGe@j1$dbh(!}>}c z)$u#2n~x&<s=~un`uaR22}l(#Di2#zmqwqUV-IL7?%WXSztfCfln9`rn$HWB{h9#GoFC_0pBHYS5}N1 z*CpA(N286Y(AcCOi?D=Cl2DFY+A#(cE`#9@?y$;=iOI{UY^X4NaucPPKxQf6Zm2CE zxdmrj3NzolHTdNjeJ9X-&+`3*+>dMgXUg=XG>?B~{Njq@8B*Jk?fgS3kclMz*_Dyu zOOz!S<;ylz96_Wxn62Sv*~)i9Z$S_kw4tn~QWd3t;&e@3pUFn6(YB2m%4mx3QhHio zK}tCJO+FUN_)*ySgyG?$o8{6}S13muBb}@v2{qWcG!#lH7|Z~iaCR;Zvx}1?ly}(< z_I)1gU@*_%zhEZ)c8xE8Yb5GNe-KL09496-dQwnlYB05rI^wqZ34=z*hFQof`&d2W z6E+g+@I^aWLHoc+aLw8OMSh%H|F+29K*S9|@X2Vpz9VM%$^Sm8{Go*#j^*LM@DBlQ zL$Q&}!!tD>=I%z2+xrD8k4Hj>xN|p*wXmm%a~$3Db0WqS${1c1GIWSH%6DM zpNRs`wl=M5bn7Xrn9`odGZhEb-w*nEq}D*_!NI~6=^FAg=Eq9Jj(In;XPVV!g#2=v zCCu6){mRWJW~TGfDv|O_e(iLmN|_#za{@dYWpr=hA(moWV_NoQ&>Q{McKW#E2a>fm zYEPjgB#Du1YtT9J&WXAU^BlKAm@$KKg+5BrYAjdIL4{wb`qPJI=V!)@v*JzgA?Yo! z+%=kEuZwu)Tf6d7E6$=nINoLfwe-i5_njrpMv->lWf)p%J}+`bF}FM`tN_Fq%dL;7 zTs`W!V-Jp`^VbupG)xPoXb*F6Km34eIn1j)4~criU=m%LrsAMb#JCvGbVg_DN-qoT zmTEI%j+6&w!jSTuq4_QI9*%@6X&xJFjA^U4XnT_lLQB<&1x23$MOSpH`pomz_D38# z`Z>cZH9Q4GnoWeShu`Zle=uPn^ zXQHx-b1S_B;Fhm}UO)LpHC^UQ898l)(m$m~D;FPyBdC&+KV&5q?Z##r-41;I@`vt{ zDRz#)AurbSt|YwPLi2;#$}yBRqeqJ73sCI3*h_$Plbhe@zGJWoH>RO!u^AS(ys&k~ zzyH93N9Ok_4FlnOq)05KImc`w1$m!`x8>j?yTy>V!P@06nYq^1Zr75LqJM(-JC-^t7)tqlGa?50M<%NC-7Urz8`5%l#F=N!WxUJ6z78{w5dOQwMEnyCZz zjHO=knKKn`PC;a-PNC;MhsO!SMCmb9pRL{@$x9Jeqo#OESKK=xJ1>MyCux3TxobJ$!Y@(Ro#jC?~ zM!wbTb11vGFFCtky)FB3ziSad{}B1`pmr?oE1B+VmEQKw#-W6g2jqUNiraDu9S>61 z8#c+zn|jlebi6Fp4G0$JMTI5JScm+()33UIKaZEVxA7}$+nS#Y2UywMMknUX{0P0< z)<`Lv;N`;-{N_u2p0W!U$*n(9%)e6a)v(^3DAnFbvj}H7KMN)2a6Ve32IvDGO-z0I zXqI=^aVN-uhev?KdHY8w%jqA%_ekd##--k@^FDSpo42J;<6m(c1##wvtJ#2^O-DSb z0&CbQIOT#VE~OM32Z>@{#C3w`#H_&lc;c#^&Ecn};aC-BW1rx>MfXZ(du2QB(;IeG zq?Ox^eU5O1s2#qt;Xj?WBnE=EWP)??qDZD*zwR<>N)M&gaKg!0{qU8tQu==PlC514 z1N=Uvi1ddw?PvNpk7x(@PdIERB^s-4-xIZ&sQNj%4AUDKeZzp)if(&Zx*YuyHbC?i z`e!wv*b}V3ApTk36aAP9zjK>&H~!YIUaQ-DK@D&l-i9gO-+}~5&syz)-QH1OO{wMt zZRYUCsFAslFFf2ks-GA^i1^zp|Mwp~JiMKLCLNjdSoVpr?91)47Y{YTgd8`;o8@Sq zvUP#gm9U-ap5JjPd{jAN>;XaTm-;r@^&!^g1#JQ|jk?+L!DnUqdvjK@!(i`1&D=e~ zGN&dPotCJgf1o`5V|0DZh-6WsG#Ni3tgHPd~b9^0|$&f%Dj@NlGWa2`QEgr;Lvb zU+iF#KKWvyhr3P%dgP@&ISu8m9E-;z##5)$#9) z4|x^6LbmFyoy*h9%aVTLH0onhsfu5#9nl>J{-Nn%1c>h%JbIpBeVbYrta>2d^926+ z%!{uat8-Wozicg%KSemMiO<**|4YG)_m_X_ct=+51x>UY_1y_iXEQTv4A|A6@duycR7D{@FV71gGZ>!T06s6t=fCdJ1UDt8Sg#b z?tQ7ETDSH@QEFfD%}>jh>nEvnc7WrZ)iX$zbLSZ>v}Q!Tqax61lJjxfv{)dm+{^uC z${)3a4ec*6kfoP)^HWi%qd+*tXJNl5628v8qkUuau^p@mpgKq}e;5dRY8TI)of$L| z{--Pp_lM9+@_A{#&7F-?N_^Y1{}nh2$MwdLmxq$V%Dt;cn4oPu>Oh5WD5==R+x(q> z46I8|$XbUNrdQ|L)s;kM%)f*#2L3X@xs%y39MhdXz`f^>Yz0u;$OSI`F#>^uH-9-b^idSD$#Vx(t{0oCwHcQ3kBiqxiGMoY~7h(4I&%=WHZ29RHshFto%~?a zN?`VGO9gK(r|x@Z0_w2x6*sSp==7S{Wv3E>n%x)!Ocdcz;5wa?^}R6^gIIfi1U91) z8?zDkc{4GdpBba$*(^71rIJ-++XfTokyKZIG-Fs*hq3;BPW09Bh7ety%#>@>4xY;L ztfOM3TQ4ie45M}4O=+PBJ%1A6ziwiR9SdHvETiIYiF`_<)|E4 zft)_XMUu|o)8|KNLe=5y$~Bb1EaJ+@V@Hr!bK@x2%a>T~`8tai_qH4UPbH?xv;P2R z6>TSOB}}%6O78g!LYGWfoSn>cyY&KNZx3a!#55eS%kc6tbeQjn@R9%800;pB0RcY{_rNZl zqN?gxHTN4HC#GcA+(c~}Fy?-#x5TSC%%V3Pmw3`Gjiur`o?@$hrLSxNbIbx6+F>WY z3^x}=-ZmD-pm7a-#cLmb>z@Ar14pUvf)(O#>R@rq+vDM)*UTGOkLo&mn|w`1Q4mUU zo5cb~fsP>BS2CHtC0nE@FYX`^+Aa#1f83%1CWCmEDJWH&OIfaFhsUxNubE0z(CQld znqLvs=1|!420-FuVqLC&AP!u_2A*c$5P&Jq`sciKM6sSA29Gg+f;>PAJO2Q2{U_z{ z3vqdXW}eVv+yhzKZth|))cszyCWVtJjV{I{nr!!Jrc8UriN&-WcY!Bsm(0XTq;;9qEHL3N#_lzEuniEnJgC!#;xvg?Qx ztl~H*gC~i9ZIfHMg1EoRASydZYwijh!}l7clhHr_!~i7_0RRF50s;a80|5a500000 z0RRypF+ovbae<+cvBA;s5aIvY00;pA00BP`5^x4#a-<+8aAxi5D{^oa_?qn5JZ?ppO8eAfKhLuB0w!14S7YAxRtOR zfqxXhnhG+IJ0VCGSp5$$$0s1ehh)KEHHqgC1!mSCxsT%g5Qo6z`rsGd86*)$LHtuT zf}kOPe70+*65JN_ag9u_+xio>U2XhPbD5Qnq|@#CAkW|Ej6chaV5wRKis23Z$7iad zRZXM{aCsm}1ye)aEvG`&ym=}ka4z2!OB-eZsDOn_!nfg;(^!gli%?R^Ys6@sxB$C2 z{?JjVu)4SbC`21d@lYTg=v(OQ%xbRO9K8sCUJZ))IH{d+s}2}T{3T3Vm07{zjdPI& zZ{mOe;%gS|4&YSP*#7{ILwTF6b}!08237@L96}+IpgSD@07zC!DN*E=bJiFr2oN@( z$bo+sU6|tMy#D|a3#C!Mp;&I9e&Qo`zfl)9+`6WcSpgLl$K)ze>$5<2(g+v!w0i=7 zci?|r_)PKF@ggckdcdz>Lc?6&q9FeOPNFf)+YCHZxgFU4A;K;JXQ`K%pwQ^( zfxPAc;!;_Hk)cwhmE&bfq)^7Xv983(^vuG~Sd2xfo*R^95P~sF@Vokr3dB={l>m={ zns6onGNCB4kooE={1{BrAIG zHsGK@%4E)iEL5iVC|+I5k&Sh<=?LHg@S8J0MV{q=$H2LM$ye`why(mtO1@xKFeP2X zcX)(UEeB{{VbvR79;JlB{{Y1?hz5cabVA9hn(j$hh|+AwFX0u~U3P@3c~M+{x{IWM zuytT;L?<__!TBS7bfwYJ6TMJfdv_4RqAhTQeuAo9aQ@K|Qn{;$l2Ocf_+nC#wQrQC z2Ep`R63TE2!h!{{TG!PxVL$I!qyQbI&=MlSE>jFtC4`gV=zkwueCm zh^aP4MP>(*VOL1HXj!Iz%@32gQe9XnS0iDyok3nGh0a$7;m8ZWKob7z3#O_Fa=}{M zrVT?nvBbcY4(El{N;@d~M*2evOSkb53<54-@{lt@l^33^mkn^rk#+SchhT=l;++SG ztjMa@SS8VUqzNbvXKjIS_CQx*w=lKKPTH3(G*iLpfVaQgkJzSv$ZAo}-Sn0O>DI&B zQtRbMVD!K$Etl!h2o`C(R^I(j03C<%PZAIvLkLYYC#jB+2l$UrG>aC5_Ym3O{^n;z zSU0rS$=QA?jQ| z1JEw5Ct?i!Rs?|1g+DI60s!pdzx97GcEyYB0EB-c0s;X6VNmYFWnNt2VNM^b(~ys1 z9|0c$l>h^#5&!@Z141ARNWx$gz$j3o!0ZM{GT}rcbr`6KfiNJf9RPm|8~{87xm751 zp<^{tVYP-4V8k#2bm4t^g#$$Z0F(hR@KELfsJS>91E7pihA0y{*~Dw@w5wH%lfWo2 z6it8jfueziVgwq6J(bcg=cz{nl>)oW&*&oc6G|9l0S2Uq{o{QGAu4R5H31MYxK(tx z8Xv31r(BFtCbS4AAQTv&OdGn^PP@l5n?yBwl>xv2YE|^(d3j$M5r84oIv39XR0@5P z#Ssq0CNp$303c#GQH!^p!Bsv+7@*eo0lGRR4gZp`pT=tA_*gb{*s9{lA=RO5?z?bo}|f=ad2El%#tI#~$S+aF=w zwSTAzFFS&36+p4C{Yw|+QrIU)(ZMQF_lv^%E|$%wrHw@h$4o6UsH&M8)#U{;($9Your5E#N6-g{<i{4kw)~jv)hL3iR~Ta-9TCIXJqi&30l}&hQni1Fz*R3E zg{(X-h0IMu0RSV|QY@WtGK|{w4+z1TTC(wsIW%nq4FCc-QjPYOQK4P?m#xSH<;oGK zgjxWAN+15Js9pI@tjl$UtU?td3jk&C#R+tw^(lrUCkPnH0+MuHNQkl3#~|2hT@Z+g z2sRW;)v=#&%^8~1CCMmZL>Yh7`pCLNReOu;L_GppjgM_CHcrj-2A&rMu^(`@4u5h4 z2{?uqevZTV@O7z;-}=`n_s6@-bTMo~+05>^qe;`*1&J6oofcwP`v7*6*rfIWU~r~o zUamtI$0}g7p(qGN1v>ESGh(GDhU*O&!BbE>`D=}Vei!%t=A9=`1GzdBo42`n2 zMUsg10N`vLE~q3iO?()D6adLVfUr(M4gnO`XoW5@TmS?FJ4<7j`CL+mOYz?d?eb}g zejRZFf}Q8E=&weE{pNqYhpXB`rdm};G=C7RKkO8AEpMHuCg&7GSO9E3jiokmjI2(j z`THt)ORY}ZcA{3_@}h)cW1*kan5SKjhR)SN+bH{B1Y3{S{8;2_n&xTr{q5%>QQWQc zLY;;~0YE@-pjuFA+u7|BFXG&_+NPK^(M%kV!UMCB$6!G>x zk+HV6-AEZ=1fAmzc9WoJtfWRMb8B)Wa~zGr69X8AripyBJn2}CKxiA>a;d+fqADL; zBo}goGfa%&s8i@}r$M+NjNoV$v~PIn1werlHK)vG0Vu4+E#?zc!W519G^!A$64o~2 z4q@!lb^TgFXfuB&pTs89mg7$BR%t{DC<71>7)9JU!O$nooMw~E5_T)Jq((hhT31x1 zcvM1I>~S#0KoXEe#yJjSj}%jaSu%*o=_RVyDQWJ&06?(2LKIO1J05%*9h_mgwQr)` zBsACw>6UEF>uS{~tMX`T_E-Juv|EauDj=n7O7DbGS#f`H@)cF3bUP@DaO#w+aZ_m% z04NknT_i%=UWBr&1j8Kz5;Nlse9D+?k>(9^Ovv`F+*?spr9^o^QVAQH8FzdCggArH z^c9JsAPAIF{{VP26roN-1~4=;ZuZdRz&~dfhk=HGR4EAS zcL+@-Y~C=B)#rpMV=ySwGG_>H znH(zm@h@witf(mwg$s^FBTBqA<*{4d%kDIg^TCgHmF+y`5?doXPzbw!L`wg3GiS_~ zJ3d&s^$kLafCT_xj1j6`o8Eu^#Mgawgy(;PoL=4T-eWfjeC?k)f8?d*cRStXm$VN6 zq9E7SRV`RDeE>iRiGoyEdT`l4 zUTkoh12^#3dNp4O7(K}~(rQ=P|9pHq#!csqW`phJPi7IqYw&w;WQx+_nStFX+%Z`~Td#k~3g#t|KeK&;kIA>t-L4$z%QRt$Dn- zyueTHM*O*;Fny|k(1P*ld?S5r#auxMG?@|wY1x*SYU_B-NppueXe3hu#vp&iD&5*Q zfiq_3;f>o5u0sg>1;9@tMrc?@I&)B>)sK;*a7Zgr&qHCft zH#060!N9B1dASam+h_aAr?Y=WA;bbn6V=erj5OII-P)JO&vqaEX8VCJ19bh3W&N(D z-|fri47hu6QdXi-cjq&?XMB$o6KBlA&mTQseL7%vE;YCZ9d69DLJ*^be?Nh1q*XbJ@4{VbH@B`Sh9|pF$0JbfMs z(154n1{P<)G*~0Osb_qzRIZVJ@mOh9QTQ4`2)Vt^r5pdi8Iu`r$m?p;!VU&1VRsKs zGI1M2-pqe6cvoTZ1u+1N9E1-tiTK&;)A>gF>WX`G)II>nqH)=lm!0l% z&Y1ZlLeC5sgH)?Dse1>`nC}m)Ias*EFY9kYW3rX!f&jp7KmmW6uS(cmgObc#BYk`I zLns2hRT@>F{_A9wD9sJ98iXguhFB&t%Xk6T^`9v#c<1wnL%3}m17=0E|M z);oScx*sDwTX7;1nGph1=dD??{#nkLtOR3T7i+MwKp|{SZZiKk-=9{_Gf3tTem12f z+1AMq3rdvzXET5GsrkenJR|+#;M&lPG;sO$m;7}*7jp*8=%3glCAeU4Ti=8p4ikS> zl{C8kdC;n|E>H7P=xO(A&K&;t#6iA7IMbS8R`hI z``@qdl$7ziu18vMBa<0bnRe(`uXHk}ZcYLx8$ig65evo(8GlL6e)FQF%w z^}qV*+%o4GXerS&<*n5Za|Sr9(rGyMUN1kNac?>5EGY8=07hs~ zhGkOs4w>=1?uvrqJ;ql{*!51uvZWy*+u7X$!K zr?dW#4kjTG?Qh+ef9&j@*3~`$>^b&r{799aJ$_B5S4-uc6q8Fem8IT(JcWUJE#wpA8z{N>#OEVf^KcUjM2%1?rVHD z@89_W=fkS15<&#w3c_&Y^uPYL`GtSNbB9_o-3>88lT2^qKhW8cGkfCm{APCm_BpPEIv@Ueap|wYw9Xx(WrkflctPz zcJwmIah!%xKX=X*vHZu+CaIc=0HN4_Mhs(&0lRST>-xu}BZMMGpcT#Y{GID1#LJ?w zzX+~Q=raeQwxIobdW{jrSio4oNI(dqNTx3%x=%A;Kj(-20Kk9^>3UPEr?{~w8c{~( z%<#*m{HJ-cV45-FX-;o!yEK34{m1l~krbEdKS~8K7wM5UDn2f?U9EwO*fT>oq~7ib0h% z9C2OxXN{$dw(Gh{$wRjL8G< zQ&dm8_En{ZS z@tdnQL#C8uI=bJMyTGT`g*-`EJr|6zoBBOGq}wFz>cfCil9k$L{`hwhw9*r`FM2@V zjG@nt>UGQ220&I?@A=~ws+up%d35MHQi=D*z7O0mV2f!fdahOm%wf%X^rpqh_6*kM>O~fl{eg)Kb5cg=sC}I+;If5+R_u7` z;HhnG!yQpZvr>Qh%*uOFK>FXOF(LreOKEMv`)Ch&|P7zP?#`H}=0j-jqg|7JC5Hi-5(#ieFZ3f3@0uK33XWC?i&5 z{0#%{8Q6I;i7=svH~^R8^Zqm6drKy|lo9j_!5mi0tWBV=|#y%Y1Lk0dOf-kVM0}J@4*4`HkCK zjSy;egJ6uB4A!0*Bc=^`f>CH;0^QO8T#C;s@s-z}TK&`O#brk&QEn9&RH7u?J5C+^ zNJc_0Su}sQO77A+093ix#tzTEwSzHL zB}xm#*q8y}l546z`{(jj6;=Flvh0^br*?RJE{uOgj4(zxkkpz1qm)oaDJ7yHWv36! zNgv)NX@J>aGs|{_a8#8^q6>fqtVzJ4AV{^|vQp=XYWMl7+ES;d+@sW}nwKz*P)#EW zWmFU-j08zA7(}xynk)u;vOOcgnwDhE=wM1?jA}%qOpDITj9vgZg{FGHbY)7x*ac?; z(cm&zg7CdDS0P}G)vLH|v`Dt)&69Qj+NB+UsF(i-*Xy4Ef-7DP00000NkvXXu0mjf E0G#H0S^xk5 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/tileset2/external.i3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/tileset2/external.i3dm index 169a87d21900fbec3c316b23c769468513f9d9eb..1295a1b23a85fa1775ce056615fe177b5487c30b 100644 GIT binary patch delta 25 ccmbQpID?Th(>NuUk%56>#zf8zb|4J`07={gWB>pF delta 17 YcmbQiIFXSv(>NuUk%56>;zZ6404A;kRsaA1 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithTransforms/buildings.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithTransforms/buildings.b3dm index cb44445561968854e524bd91f0ad3b93e79fb74a..6ad506e212cd3fc7544b7c2919369ba8df0c23d1 100644 GIT binary patch delta 59 zcmez4`NNYl$v7pKk%58X$41WiOso+~3=BG(*D?h#@#iJxrYcz}C6%V7r4}jaZ2rTt Pj%o59cD2n<*d=5EI^z>j delta 65 zcmez2`Nxwp$v7pKk%58X&qmJqOsp|V3=9UF*D?h#ZRTZN%Os?ul$V&Bs$`{9l%HSX Vm!FcVGU(>NuUk%56>$41W8d@Mi)0{~A11x)|| delta 18 ZcmdlXyG52W(>NuUk%56>%SO)Cd;m0e1w{Y= diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ll.b3dm index 98b2b469bda19cfb816fbe84d325a3b27a7daa19..6a60aa28bd716229298304fb046ce512246ad1e6 100644 GIT binary patch delta 66 zcmccOeZ!kG$v7pKk%58X#zxNXOso%-7#Ox}W@Wy_#GjX#o2q1`lvJ9QmRh8wv-uk9 TI;P3fIMmn_z+m$p4hdNR*liSr delta 62 zcmV-E0Kxy*OVmpVVl!lI0RR91)UgTo0tMV6006MF1q0Fov*!h^0un4DZeeX@B03^+ UZ*O!?Z)9a6lavT1v%m-#9hS5dx&QzG diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/lr.b3dm index ebb24758d31f22e191700241a078cc47d500dd9e..1830dd5d58f5986aad3fe13464151903ff9809ef 100644 GIT binary patch delta 37 tcmccNeZzahO;-NA#N1RRE2X5;w6xSBC7sPTSl2O4p24B9c^`+AEC3<24i*3a delta 40 wcmccNeZzahP1emXS=TZN=_utT=B6rHDHY}Cm-ywUq$*9G#-XwK0EdJu09Gvz82|tP diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/points.pnts b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/points.pnts index ddb3915a0146ff6993ac6f5a66585bf75c1cb21b..307c2ed00898bae839685d41a51122503d2530d4 100644 GIT binary patch delta 57 zcmbPJwxCS5Ag`pDk%56h!J2^~1xU}ZVqo9^(jZVh(cO$uXQHeoW9`PKSymj?wF+PW E0CO4)cK`qY delta 52 ycmZ2bHm6LsAg`pDk%56h#+rd414z%X0uoSAJuyU+QD>s88EdTq5NxcQWd#5(SPMJ= diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ul.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ul.b3dm index ecd600aba82546a7f878e6e0f82b2e7f46b950e6..0708ad9272d119abc7d6186b95a9f60e923f22fa 100644 GIT binary patch delta 59 zcmV-B0L1^qOTbGBVl!lI0RR91z_AJE0tMJ2006AB^#afW4{l*?Wgs0bJx;+qv^ diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/ur.b3dm index 7dd42a0fdf4bef6e9779f53b49c8550efffc1186..3eab09842e7a22fc35c1a82e60e35e5d39cba2fe 100644 GIT binary patch delta 40 wcmX@%eZqUgX;%Kc#N1RRE2X5;w6xSBC7sQuSl2O4?&45mQc&2ufkQ$T06+u{`~Uy| delta 40 wcmX@%eZqUgY1YlRS=TZN=_utT=B6rHDHY}Cm-ywUq$*AB;85GVfkQ$T08Hl&y#N3J From f208942a052c1c9327730943955f191b745dd60b Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 12 Oct 2022 20:27:48 +0200 Subject: [PATCH 117/679] Rename content "url" to "uri" in all Vector tileset JSON files --- .../Vector/VectorTileCombined/tileset.json | 2 +- .../Vector/VectorTileCombinedWithBatchIds/tileset.json | 2 +- .../Cesium3DTiles/Vector/VectorTilePoints/tileset.json | 10 +++++----- .../VectorTilePointsBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../Vector/VectorTilePointsWithBatchIds/tileset.json | 4 ++-- .../Vector/VectorTilePointsWithBatchTable/tileset.json | 10 +++++----- .../Vector/VectorTilePolygons/tileset.json | 10 +++++----- .../VectorTilePolygonsBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../Vector/VectorTilePolygonsWithBatchIds/tileset.json | 4 ++-- .../VectorTilePolygonsWithBatchTable/tileset.json | 10 +++++----- .../Vector/VectorTilePolylines/tileset.json | 10 +++++----- .../VectorTilePolylinesBatchedChildren/tileset.json | 4 ++-- .../tileset.json | 4 ++-- .../VectorTilePolylinesWithBatchIds/tileset.json | 4 ++-- .../VectorTilePolylinesWithBatchTable/tileset.json | 10 +++++----- 17 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTileCombined/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTileCombined/tileset.json index 1de81a00ee2..40fa60b8bf4 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTileCombined/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTileCombined/tileset.json @@ -48,7 +48,7 @@ }, "geometricError": 0, "content": { - "url": "tile.vctr" + "uri": "tile.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTileCombinedWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTileCombinedWithBatchIds/tileset.json index 1de81a00ee2..40fa60b8bf4 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTileCombinedWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTileCombinedWithBatchIds/tileset.json @@ -48,7 +48,7 @@ }, "geometricError": 0, "content": { - "url": "tile.vctr" + "uri": "tile.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePoints/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePoints/tileset.json index a9fce7164ed..3ff2f12288a 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePoints/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePoints/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildren/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildren/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildrenWithBatchTable/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsBatchedChildrenWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchIds/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchIds/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchTable/tileset.json index a9fce7164ed..3ff2f12288a 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePointsWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json index de1f196c90c..7423c9b4b8d 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json @@ -17,7 +17,7 @@ "geometricError": 500, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildren/tileset.json index 23d139c4660..2a149c33444 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildren/tileset.json @@ -17,7 +17,7 @@ "geometricError": 500, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildrenWithBatchTable/tileset.json index 23d139c4660..2a149c33444 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsBatchedChildrenWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 500, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchIds/tileset.json index 23d139c4660..2a149c33444 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchIds/tileset.json @@ -17,7 +17,7 @@ "geometricError": 500, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchTable/tileset.json index de1f196c90c..7423c9b4b8d 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolygonsWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 500, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json index a9fce7164ed..3ff2f12288a 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildren/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildren/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildren/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildren/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildrenWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildrenWithBatchTable/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildrenWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesBatchedChildrenWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchIds/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchIds/tileset.json index 8b8dee7fdd6..a1fd8547d1c 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchIds/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchIds/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "children.vctr" + "uri": "children.vctr" } } ] diff --git a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchTable/tileset.json b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchTable/tileset.json index a9fce7164ed..3ff2f12288a 100644 --- a/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchTable/tileset.json +++ b/Specs/Data/Cesium3DTiles/Vector/VectorTilePolylinesWithBatchTable/tileset.json @@ -17,7 +17,7 @@ "geometricError": 100, "refine": "REPLACE", "content": { - "url": "parent.vctr" + "uri": "parent.vctr" }, "children": [ { @@ -33,7 +33,7 @@ }, "geometricError": 0, "content": { - "url": "ul.vctr" + "uri": "ul.vctr" } }, { @@ -49,7 +49,7 @@ }, "geometricError": 0, "content": { - "url": "ur.vctr" + "uri": "ur.vctr" } }, { @@ -65,7 +65,7 @@ }, "geometricError": 0, "content": { - "url": "ll.vctr" + "uri": "ll.vctr" } }, { @@ -81,7 +81,7 @@ }, "geometricError": 0, "content": { - "url": "lr.vctr" + "uri": "lr.vctr" } } ] From bf6fbfa1b474d763a0255ffc42a8163caece4316 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Thu, 13 Oct 2022 14:28:57 +0200 Subject: [PATCH 118/679] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index b9f44a0ad8c..38de346aa31 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -337,3 +337,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Ilya Shevelev](https://github.com/ilyaly) - [Gabriel Aldous](https://github.com/Sn00pyW00dst0ck) - [金俊](https://github.com/jinjun1994) +- [Marco Hutter](https://github.com/javagl) From 8d05096cd505d496cd86a82a1ce3c1950374f87a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Thu, 13 Oct 2022 19:39:16 -0400 Subject: [PATCH 119/679] Refactor Octree.glsl for clarity --- Source/Shaders/Voxels/Octree.glsl | 108 ++++++++++++++--------------- Source/Shaders/Voxels/VoxelFS.glsl | 1 + 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/Source/Shaders/Voxels/Octree.glsl b/Source/Shaders/Voxels/Octree.glsl index 327b43d8765..97c324dc41c 100644 --- a/Source/Shaders/Voxels/Octree.glsl +++ b/Source/Shaders/Voxels/Octree.glsl @@ -42,12 +42,6 @@ struct SampleData { int intMod(int a, int b) { return a - (b * (a / b)); } -bool inRange(float v, float minVal, float maxVal) { - return clamp(v, minVal, maxVal) == v; -} -bool inRange(vec3 v, vec3 minVal, vec3 maxVal) { - return clamp(v, minVal, maxVal) == v; -} int normU8_toInt(float value) { return int(value * 255.0); } @@ -89,13 +83,31 @@ int getOctreeParentIndex(int octreeIndex) { return parentOctreeIndex; } -void getOctreeLeafSampleData(in OctreeNodeData data, inout SampleData sampleData) { +vec3 getPositionUvLocal(in TraversalData traversalData) { + // TODO: use bit-shifting (only in WebGL2) + float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); + return traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); +} + +vec3 getParentTileUv(in TraversalData traversalData) { + ivec4 parentOctreeCoords; + parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); + parentOctreeCoords.w = traversalData.octreeCoords.w - 1; + // TODO: use getPositionUvLocal? Need to change it to 2 args? + float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); + return traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); +} + +void getOctreeLeafSampleData(in OctreeNodeData data, in TraversalData traversalData, out SampleData sampleData) { sampleData.megatextureIndex = data.data; sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; + sampleData.tileUv = sampleData.usingParentMegatextureIndex + ? getParentTileUv(traversalData) + : traversalData.positionUvLocal; } #if (SAMPLE_COUNT > 1) -void getOctreeLeafSampleDatas(in OctreeNodeData data, inout SampleData sampleData0, inout SampleData sampleData1) { +void getOctreeLeafSampleDatas(in OctreeNodeData data, in TraversalData traversalData, out SampleData sampleData0, out SampleData sampleData1) { int leafIndex = data.data; int leafNodeTexelCount = 2; // Adding 0.5 moves to the center of the texel @@ -112,7 +124,13 @@ void getOctreeLeafSampleDatas(in OctreeNodeData data, inout SampleData sampleDat sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy); sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw); sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; + sampleData0.tileUv = sampleData0.usingParentMegatextureIndex + ? getParentTileUv(traversalData) + : traversalData.positionUvLocal; sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; + sampleData1.tileUv = sampleData1.usingParentMegatextureIndex + ? getParentTileUv(traversalData) + : traversalData.positionUvLocal; sampleData0.weight = 1.0 - lerp; sampleData1.weight = lerp; } @@ -132,8 +150,8 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); // Get octree coords for the next level down - ivec4 parentOctreeCoords = traversalData.octreeCoords; - traversalData.octreeCoords = ivec4(parentOctreeCoords.xyz * 2 + ivec3(childCoord), parentOctreeCoords.w + 1); + ivec4 octreeCoords = traversalData.octreeCoords; + traversalData.octreeCoords = ivec4(octreeCoords.xyz * 2 + ivec3(childCoord), octreeCoords.w + 1); if (childData.flag == OCTREE_FLAG_INTERNAL) { // interior tile - keep going deeper @@ -142,23 +160,14 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s traversalData.parentOctreeIndex = childData.data; } else { // leaf tile - stop traversing + traversalData.positionUvLocal = getPositionUvLocal(traversalData); float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); traversalData.stepT = u_stepSize / dimAtLevel; - #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(childData, sampleDatas[0]); + getOctreeLeafSampleData(childData, traversalData, sampleDatas[0]); #else - getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]); + getOctreeLeafSampleDatas(childData, traversalData, sampleDatas[0], sampleDatas[1]); #endif - for (int i = 0; i < SAMPLE_COUNT; i++) { - if (sampleDatas[i].usingParentMegatextureIndex) { - float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); - sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); - } else { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } - } return; } } @@ -167,49 +176,43 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { traversalData.octreeCoords = ivec4(0); traversalData.parentOctreeIndex = 0; - // TODO: is it possible for this to be out of bounds, and does it matter? traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace; OctreeNodeData rootData = getOctreeRootData(); if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data + traversalData.positionUvLocal = getPositionUvLocal(traversalData); + traversalData.stepT = u_stepSize; #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(rootData, sampleDatas[0]); + getOctreeLeafSampleData(rootData, traversalData, sampleDatas[0]); #else - getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]); + getOctreeLeafSampleDatas(rootData, traversalData, sampleDatas[0], sampleDatas[1]); #endif - traversalData.stepT = u_stepSize; - for (int i = 0; i < SAMPLE_COUNT; i++) { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } - } - else - { + } else { traverseOctreeDownwards(traversalData, sampleDatas); } } +bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) { + return clamp(v, minVal, maxVal) == v; +} + +bool insideTile(in TraversalData traversalData) { + bool inside = inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); + // Assume (!) the position is always inside the root tile. + return inside || traversalData.octreeCoords.w == 0; +} + void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traversalData.positionUvLocal = getPositionUvLocal(traversalData); - // Note: This code assumes the position is always inside the root tile. - bool insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); - - if (insideTile) { + if (insideTile(traversalData)) { for (int i = 0; i < SAMPLE_COUNT; i++) { - if (sampleDatas[i].usingParentMegatextureIndex) { - ivec4 parentOctreeCoords; - parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); - parentOctreeCoords.w = traversalData.octreeCoords.w - 1; - float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); - sampleDatas[i].tileUv = traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); - } else { - sampleDatas[i].tileUv = traversalData.positionUvLocal; - } + sampleDatas[i].tileUv = sampleDatas[i].usingParentMegatextureIndex + ? getParentTileUv(traversalData) + : traversalData.positionUvLocal; } } else { // Go up tree @@ -217,12 +220,9 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa { traversalData.octreeCoords.xyz /= ivec3(2); traversalData.octreeCoords.w -= 1; - dimAtLevel *= 0.5; - - traversalData.positionUvLocal = traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); - insideTile = traversalData.octreeCoords.w == 0 || inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); + traversalData.positionUvLocal = getPositionUvLocal(traversalData); - if (!insideTile) { + if (!insideTile(traversalData)) { traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); } else { break; diff --git a/Source/Shaders/Voxels/VoxelFS.glsl b/Source/Shaders/Voxels/VoxelFS.glsl index 7f941e42be6..583acdff1c5 100644 --- a/Source/Shaders/Voxels/VoxelFS.glsl +++ b/Source/Shaders/Voxels/VoxelFS.glsl @@ -1,4 +1,5 @@ // import { intersectScene } from "./Intersection.glsl"; +// import { nextIntersection } from "./IntersectionUtils.glsl"; // import { TraversalData, SampleData, traverseOctreeFromBeginning, traverseOctreeFromExisting } from "./Octree.glsl"; // import { accumulatePropertiesFromMegatexture } from "./Megatexture.glsl"; From 285f7ad4409a3bbba479ffd05da20392ecddb088 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 14 Oct 2022 18:55:48 -0400 Subject: [PATCH 120/679] Clean up structs and functions in Octree.glsl --- Source/Shaders/Voxels/Octree.glsl | 124 +++++++++++++---------------- Source/Shaders/Voxels/VoxelFS.glsl | 17 +++- 2 files changed, 68 insertions(+), 73 deletions(-) diff --git a/Source/Shaders/Voxels/Octree.glsl b/Source/Shaders/Voxels/Octree.glsl index 97c324dc41c..ab2749d389e 100644 --- a/Source/Shaders/Voxels/Octree.glsl +++ b/Source/Shaders/Voxels/Octree.glsl @@ -1,5 +1,3 @@ -// import { convertUvToShapeUvSpace } from ("./convertUvToBox.glsl", "./convertUvToCylinder.glsl", "convertUvToEllipsoid.glsl"); - // These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js #define OCTREE_FLAG_INTERNAL 0 #define OCTREE_FLAG_LEAF 1 @@ -22,8 +20,6 @@ struct OctreeNodeData { }; struct TraversalData { - vec3 positionUvShapeSpace; - vec3 positionUvLocal; float stepT; ivec4 octreeCoords; int parentOctreeIndex; @@ -39,42 +35,37 @@ struct SampleData { }; // Integer mod: For WebGL1 only -int intMod(int a, int b) { +int intMod(in int a, in int b) { return a - (b * (a / b)); } -int normU8_toInt(float value) { +int normU8_toInt(in float value) { return int(value * 255.0); } -int normU8x2_toInt(vec2 value) { +int normU8x2_toInt(in vec2 value) { return int(value.x * 255.0) + 256 * int(value.y * 255.0); } -float normU8x2_toFloat(vec2 value) { +float normU8x2_toFloat(in vec2 value) { return float(normU8x2_toInt(value)) / 65535.0; } -OctreeNodeData getOctreeRootData() { - vec4 rootData = texture2D(u_octreeInternalNodeTexture, vec2(0.0)); +OctreeNodeData getOctreeNodeData(in vec2 octreeUv) { + vec4 texData = texture2D(u_octreeInternalNodeTexture, octreeUv); OctreeNodeData data; - data.data = normU8x2_toInt(rootData.xy); - data.flag = normU8x2_toInt(rootData.zw); + data.data = normU8x2_toInt(texData.xy); + data.flag = normU8x2_toInt(texData.zw); return data; } -OctreeNodeData getOctreeChildData(int parentOctreeIndex, ivec3 childCoord) { +OctreeNodeData getOctreeChildData(in int parentOctreeIndex, in ivec3 childCoord) { int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x; int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex; int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow; vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); - vec4 childData = texture2D(u_octreeInternalNodeTexture, octreeUv); - - OctreeNodeData data; - data.data = normU8x2_toInt(childData.xy); - data.flag = normU8x2_toInt(childData.zw); - return data; + return getOctreeNodeData(octreeUv); } -int getOctreeParentIndex(int octreeIndex) { +int getOctreeParentIndex(in int octreeIndex) { int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9; int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow; vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5); @@ -83,31 +74,30 @@ int getOctreeParentIndex(int octreeIndex) { return parentOctreeIndex; } -vec3 getPositionUvLocal(in TraversalData traversalData) { +/** +* Convert a position in the uv-space of the tileset bounding shape +* into the uv-space of a tile within the tileset +*/ +vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) { // TODO: use bit-shifting (only in WebGL2) - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - return traversalData.positionUvShapeSpace * dimAtLevel - vec3(traversalData.octreeCoords.xyz); + float dimAtLevel = pow(2.0, float(octreeCoords.w)); + return shapePosition * dimAtLevel - vec3(octreeCoords.xyz); } -vec3 getParentTileUv(in TraversalData traversalData) { - ivec4 parentOctreeCoords; - parentOctreeCoords.xyz = traversalData.octreeCoords.xyz / ivec3(2); - parentOctreeCoords.w = traversalData.octreeCoords.w - 1; - // TODO: use getPositionUvLocal? Need to change it to 2 args? - float parentDimAtLevel = pow(2.0, float(parentOctreeCoords.w)); - return traversalData.positionUvShapeSpace * parentDimAtLevel - vec3(parentOctreeCoords.xyz); +void setSampleUv(in vec3 shapePosition, in ivec4 octreeCoords, inout SampleData sampleData) { + ivec4 sampleCoords = sampleData.usingParentMegatextureIndex + ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1) + : octreeCoords; + sampleData.tileUv = getTileUv(shapePosition, sampleCoords); } -void getOctreeLeafSampleData(in OctreeNodeData data, in TraversalData traversalData, out SampleData sampleData) { +void getOctreeLeafSampleData(in OctreeNodeData data, out SampleData sampleData) { sampleData.megatextureIndex = data.data; sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; - sampleData.tileUv = sampleData.usingParentMegatextureIndex - ? getParentTileUv(traversalData) - : traversalData.positionUvLocal; } #if (SAMPLE_COUNT > 1) -void getOctreeLeafSampleDatas(in OctreeNodeData data, in TraversalData traversalData, out SampleData sampleData0, out SampleData sampleData1) { +void getOctreeLeafSampleDatas(in OctreeNodeData data, out SampleData sampleData0, out SampleData sampleData1) { int leafIndex = data.data; int leafNodeTexelCount = 2; // Adding 0.5 moves to the center of the texel @@ -123,20 +113,15 @@ void getOctreeLeafSampleDatas(in OctreeNodeData data, in TraversalData traversal sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy); sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw); + // TODO: this looks wrong? Should be comparing to OCTREE_FLAG_PACKED_LEAF_FROM_PARENT sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; - sampleData0.tileUv = sampleData0.usingParentMegatextureIndex - ? getParentTileUv(traversalData) - : traversalData.positionUvLocal; sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; - sampleData1.tileUv = sampleData1.usingParentMegatextureIndex - ? getParentTileUv(traversalData) - : traversalData.positionUvLocal; sampleData0.weight = 1.0 - lerp; sampleData1.weight = lerp; } #endif -void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { +void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; vec3 end = start + vec3(sizeAtLevel); @@ -145,7 +130,7 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s // Find out which octree child contains the position // 0 if before center, 1 if after vec3 center = 0.5 * (start + end); - vec3 childCoord = step(center, traversalData.positionUvShapeSpace); + vec3 childCoord = step(center, shapePosition); OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); @@ -160,37 +145,43 @@ void traverseOctreeDownwards(inout TraversalData traversalData, out SampleData s traversalData.parentOctreeIndex = childData.data; } else { // leaf tile - stop traversing - traversalData.positionUvLocal = getPositionUvLocal(traversalData); float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); traversalData.stepT = u_stepSize / dimAtLevel; #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(childData, traversalData, sampleDatas[0]); + getOctreeLeafSampleData(childData, sampleDatas[0]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); #else - getOctreeLeafSampleDatas(childData, traversalData, sampleDatas[0], sampleDatas[1]); + getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]); #endif return; } } } -void traverseOctreeFromBeginning(in vec3 positionUv, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { +/** +* Transform a given position to an octree tile coordinate and a position within that tile, +* and find the corresponding megatexture index and texture coordinates +*/ +void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { traversalData.octreeCoords = ivec4(0); traversalData.parentOctreeIndex = 0; - // TODO: is it possible for this to be out of bounds, and does it matter? - traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - OctreeNodeData rootData = getOctreeRootData(); + OctreeNodeData rootData = getOctreeNodeData(vec2(0.0)); if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data - traversalData.positionUvLocal = getPositionUvLocal(traversalData); traversalData.stepT = u_stepSize; #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(rootData, traversalData, sampleDatas[0]); + getOctreeLeafSampleData(rootData, sampleDatas[0]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); #else - getOctreeLeafSampleDatas(rootData, traversalData, sampleDatas[0], sampleDatas[1]); + getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]); #endif } else { - traverseOctreeDownwards(traversalData, sampleDatas); + traverseOctreeDownwards(shapePosition, traversalData, sampleDatas); } } @@ -198,31 +189,26 @@ bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) { return clamp(v, minVal, maxVal) == v; } -bool insideTile(in TraversalData traversalData) { - bool inside = inRange(traversalData.positionUvLocal, vec3(0.0), vec3(1.0)); +bool insideTile(in vec3 shapePosition, in ivec4 octreeCoords) { + vec3 tileUv = getTileUv(shapePosition, octreeCoords); + bool inside = inRange(tileUv, vec3(0.0), vec3(1.0)); // Assume (!) the position is always inside the root tile. - return inside || traversalData.octreeCoords.w == 0; + return inside || octreeCoords.w == 0; } -void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { - traversalData.positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traversalData.positionUvLocal = getPositionUvLocal(traversalData); - - if (insideTile(traversalData)) { +void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { + if (insideTile(shapePosition, traversalData.octreeCoords)) { for (int i = 0; i < SAMPLE_COUNT; i++) { - sampleDatas[i].tileUv = sampleDatas[i].usingParentMegatextureIndex - ? getParentTileUv(traversalData) - : traversalData.positionUvLocal; + setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[i]); } } else { // Go up tree for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { - traversalData.octreeCoords.xyz /= ivec3(2); + traversalData.octreeCoords.xyz /= 2; traversalData.octreeCoords.w -= 1; - traversalData.positionUvLocal = getPositionUvLocal(traversalData); - if (!insideTile(traversalData)) { + if (!insideTile(shapePosition, traversalData.octreeCoords)) { traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); } else { break; @@ -230,7 +216,7 @@ void traverseOctreeFromExisting(in vec3 positionUv, inout TraversalData traversa } // Go down tree - traverseOctreeDownwards(traversalData, sampleDatas); + traverseOctreeDownwards(shapePosition, traversalData, sampleDatas); } } diff --git a/Source/Shaders/Voxels/VoxelFS.glsl b/Source/Shaders/Voxels/VoxelFS.glsl index 583acdff1c5..568952f188e 100644 --- a/Source/Shaders/Voxels/VoxelFS.glsl +++ b/Source/Shaders/Voxels/VoxelFS.glsl @@ -1,5 +1,6 @@ // import { intersectScene } from "./Intersection.glsl"; // import { nextIntersection } from "./IntersectionUtils.glsl"; +// import { convertUvToShapeUvSpace } from ("./convertUvToBox.glsl", "./convertUvToCylinder.glsl", "./convertUvToEllipsoid.glsl"); // import { TraversalData, SampleData, traverseOctreeFromBeginning, traverseOctreeFromExisting } from "./Octree.glsl"; // import { accumulatePropertiesFromMegatexture } from "./Megatexture.glsl"; @@ -42,12 +43,18 @@ void main() float currT = entryExitT.x; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; + // TODO: is it possible for this to be out of bounds, and does it matter? + vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); // Traverse the tree from the start position TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; - traverseOctreeFromBeginning(positionUv, traversalData, sampleDatas); + traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); + // TODO: + // - jitter doesn't affect the first traversal? + // - jitter is always > 0? + // - jitter is only applied at one step? #if defined(JITTER) float noise = hash(screenCoord); // [0,1] currT += noise * traversalData.stepT; @@ -68,8 +75,8 @@ void main() // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); fragmentInput.voxel.positionUv = positionUv; - fragmentInput.voxel.positionShapeUv = traversalData.positionUvShapeSpace; - fragmentInput.voxel.positionUvLocal = traversalData.positionUvLocal; + fragmentInput.voxel.positionShapeUv = positionUvShapeSpace; + fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv; fragmentInput.voxel.viewDirUv = viewDirUv; fragmentInput.voxel.viewDirWorld = viewDirWorld; fragmentInput.voxel.travelDistance = traversalData.stepT; @@ -106,6 +113,7 @@ void main() break; } else { // Found another intersection. Keep raymarching. + // TODO: Why are we adding?? Shouldn't we jump to currT = entryExitT.x ? currT += entryExitT.x; endT += entryExitT.y; positionUv += entryExitT.x * viewDirUv; @@ -115,7 +123,8 @@ void main() // Traverse the tree from the current ray position. // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. - traverseOctreeFromExisting(positionUv, traversalData, sampleDatas); + positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); + traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From 3485b2f20ab2ddaf499d97b6c63db898d0d52f03 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 14 Oct 2022 19:20:29 -0400 Subject: [PATCH 121/679] Fix handling of multiple intersections in VoxelFS.glsl --- Source/Shaders/Voxels/VoxelFS.glsl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Shaders/Voxels/VoxelFS.glsl b/Source/Shaders/Voxels/VoxelFS.glsl index 568952f188e..824cdbb559d 100644 --- a/Source/Shaders/Voxels/VoxelFS.glsl +++ b/Source/Shaders/Voxels/VoxelFS.glsl @@ -112,11 +112,10 @@ void main() if (entryExitT.x == NO_HIT) { break; } else { - // Found another intersection. Keep raymarching. - // TODO: Why are we adding?? Shouldn't we jump to currT = entryExitT.x ? - currT += entryExitT.x; - endT += entryExitT.y; - positionUv += entryExitT.x * viewDirUv; + // Found another intersection. Resume raymarching there + currT = entryExitT.x; + endT = entryExitT.y; + positionUv = viewPosUv + currT * viewDirUv; } #endif } From 078d47545566ec58ccd91fac98d186d0f6130fef Mon Sep 17 00:00:00 2001 From: "BimAngle Co. Ltd" Date: Sun, 23 Oct 2022 12:39:27 +0800 Subject: [PATCH 122/679] fix KTX2 image load fail. --- Source/Scene/GltfImageLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/GltfImageLoader.js b/Source/Scene/GltfImageLoader.js index 60c33efb891..e190c2bb206 100644 --- a/Source/Scene/GltfImageLoader.js +++ b/Source/Scene/GltfImageLoader.js @@ -293,7 +293,7 @@ function loadImageFromBufferTypedArray(typedArray) { const ktx2Regex = /(^data:image\/ktx2)|(\.ktx2$)/i; function loadImageFromUri(resource) { - const uri = resource.url; + const uri = resource._url; if (ktx2Regex.test(uri)) { // Resolves to a CompressedTextureBuffer return loadKTX2(resource); From 77ff9643e0cafad185d52cd6c508af430927f23f Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 25 Oct 2022 12:47:10 -0400 Subject: [PATCH 123/679] Add spec for ImplicitSubtreeCache --- Source/Scene/Cesium3DTilesVoxelProvider.js | 125 +----------------- Source/Scene/ImplicitSubtreeCache.js | 127 +++++++++++++++++++ Specs/Scene/ImplicitSubtreeCacheSpec.js | 139 +++++++++++++++++++++ 3 files changed, 268 insertions(+), 123 deletions(-) create mode 100644 Source/Scene/ImplicitSubtreeCache.js create mode 100644 Specs/Scene/ImplicitSubtreeCacheSpec.js diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 8cc730d7431..d095f8e6161 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -5,12 +5,12 @@ import defaultValue from "../Core/defaultValue.js"; import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; -import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; import Matrix4 from "../Core/Matrix4.js"; import Resource from "../Core/Resource.js"; import Cesium3DTilesetMetadata from "./Cesium3DTilesetMetadata.js"; import GltfLoader from "./GltfLoader.js"; import ImplicitSubtree from "./ImplicitSubtree.js"; +import ImplicitSubtreeCache from "./ImplicitSubtreeCache.js"; import ImplicitTileCoordinates from "./ImplicitTileCoordinates.js"; import ImplicitTileset from "./ImplicitTileset.js"; import MetadataComponentType from "./MetadataComponentType.js"; @@ -189,6 +189,7 @@ function Cesium3DTilesVoxelProvider(options) { * @type {ImplicitSubtreeCache} * @private */ + // TODO: set a default maximumSubtreeCount to limit memory usage this._subtreeCache = new ImplicitSubtreeCache(); /** @@ -593,126 +594,4 @@ function getGltfLoader(implicitTileset, tileCoord) { return gltfLoader; } -/** - * @alias ImplicitSubtreeCacheNode - * @constructor - * - * @param {ImplicitSubtree} subtree - * @param {Number} stamp - * - * @private - */ -function ImplicitSubtreeCacheNode(subtree, stamp) { - this.subtree = subtree; - this.stamp = stamp; -} - -/** - * @alias ImplicitSubtreeCache - * @constructor - * - * @param {Object} [options] Object with the following properties - * @param {Number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. - * - * @private - */ -function ImplicitSubtreeCache(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * @type {Number} - * @private - */ - this._maximumSubtreeCount = defaultValue(options.maximumSubtreeCount, 0); - - /** - * A counter that goes up whenever a subtree is added. Used to sort subtrees by recency. - * @type {Number} - * @private - */ - this._subtreeRequestCounter = 0; - - /** - * @type {DoubleEndedPriorityQueue} - * @private - */ - this._queue = new DoubleEndedPriorityQueue({ - comparator: ImplicitSubtreeCache.comparator, - }); -} - -/** - * @param {ImplicitSubtree} subtree - */ -ImplicitSubtreeCache.prototype.addSubtree = function (subtree) { - const cacheNode = new ImplicitSubtreeCacheNode( - subtree, - this._subtreeRequestCounter - ); - this._subtreeRequestCounter++; - this._queue.insert(cacheNode); - - // Make sure the parent subtree exists in the cache - const subtreeCoord = subtree.implicitCoordinates; - if (subtreeCoord.level > 0) { - const parentCoord = subtreeCoord.deriveParentSubtreeCoordinates(); - const parentNode = this.find(parentCoord); - - //>>includeStart('debug', pragmas.debug) - if (parentNode === undefined) { - throw new DeveloperError("parent node needs to exist"); - } - //>>includeEnd('debug'); - } - - if (this._maximumSubtreeCount > 0) { - while (this._queue.length > this._maximumSubtreeCount) { - const lowestPriorityNode = this._queue.getMinimum(); - if (lowestPriorityNode === cacheNode) { - // Don't remove itself - break; - } - - this._queue.removeMinimum(); - } - } -}; - -/** - * @param {ImplicitTileCoordinates} subtreeCoord - * @returns {ImplicitSubtree|undefined} - */ -ImplicitSubtreeCache.prototype.find = function (subtreeCoord) { - const queue = this._queue; - const array = queue.internalArray; - const arrayLength = queue.length; - - for (let i = 0; i < arrayLength; i++) { - const other = array[i]; - const otherSubtree = other.subtree; - const otherCoord = otherSubtree.implicitCoordinates; - if (subtreeCoord.isEqual(otherCoord)) { - return other.subtree; - } - } - return undefined; -}; - -/** - * @param {ImplicitSubtreeCacheNode} a - * @param {ImplicitSubtreeCacheNode} b - * @returns {Number} - */ -ImplicitSubtreeCache.comparator = function (a, b) { - const aCoord = a.subtree.implicitCoordinates; - const bCoord = b.subtree.implicitCoordinates; - if (aCoord.isAncestorOf(bCoord)) { - // Technically this shouldn't happen because the ancestor subtree was supposed to be added to the cache first. - return +1.0; - } else if (bCoord.isAncestorOf(aCoord)) { - return -1.0; - } - return a.stamp - b.stamp; -}; - export default Cesium3DTilesVoxelProvider; diff --git a/Source/Scene/ImplicitSubtreeCache.js b/Source/Scene/ImplicitSubtreeCache.js new file mode 100644 index 00000000000..b9bc554a764 --- /dev/null +++ b/Source/Scene/ImplicitSubtreeCache.js @@ -0,0 +1,127 @@ +import defaultValue from "../Core/defaultValue.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; + +/** + * @alias ImplicitSubtreeCache + * @constructor + * + * @param {Object} [options] Object with the following properties + * @param {Number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. + * + * @private + */ +function ImplicitSubtreeCache(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + /** + * @type {Number} + * @private + */ + this._maximumSubtreeCount = defaultValue(options.maximumSubtreeCount, 0); + + /** + * A counter that goes up whenever a subtree is added. Used to sort subtrees by recency. + * @type {Number} + * @private + */ + this._subtreeRequestCounter = 0; + + /** + * @type {DoubleEndedPriorityQueue} + * @private + */ + this._queue = new DoubleEndedPriorityQueue({ + comparator: ImplicitSubtreeCache.comparator, + }); +} + +/** + * @param {ImplicitSubtree} subtree + */ +ImplicitSubtreeCache.prototype.addSubtree = function (subtree) { + const cacheNode = new ImplicitSubtreeCacheNode( + subtree, + this._subtreeRequestCounter + ); + this._subtreeRequestCounter++; + this._queue.insert(cacheNode); + + // Make sure the parent subtree exists in the cache + const subtreeCoord = subtree.implicitCoordinates; + if (subtreeCoord.level > 0) { + const parentCoord = subtreeCoord.getParentSubtreeCoordinates(); + const parentNode = this.find(parentCoord); + + //>>includeStart('debug', pragmas.debug) + if (parentNode === undefined) { + throw new DeveloperError("parent node needs to exist"); + } + //>>includeEnd('debug'); + } + + if (this._maximumSubtreeCount > 0) { + while (this._queue.length > this._maximumSubtreeCount) { + const lowestPriorityNode = this._queue.getMinimum(); + if (lowestPriorityNode === cacheNode) { + // Don't remove itself + break; + } + + this._queue.removeMinimum(); + } + } +}; + +/** + * @param {ImplicitTileCoordinates} subtreeCoord + * @returns {ImplicitSubtree|undefined} + */ +ImplicitSubtreeCache.prototype.find = function (subtreeCoord) { + const queue = this._queue; + const array = queue.internalArray; + const arrayLength = queue.length; + + for (let i = 0; i < arrayLength; i++) { + const other = array[i]; + const otherSubtree = other.subtree; + const otherCoord = otherSubtree.implicitCoordinates; + if (subtreeCoord.isEqual(otherCoord)) { + return other.subtree; + } + } + return undefined; +}; + +/** + * @param {ImplicitSubtreeCacheNode} a + * @param {ImplicitSubtreeCacheNode} b + * @returns {Number} + */ +ImplicitSubtreeCache.comparator = function (a, b) { + const aCoord = a.subtree.implicitCoordinates; + const bCoord = b.subtree.implicitCoordinates; + if (aCoord.isAncestor(bCoord)) { + // Technically this shouldn't happen because the ancestor subtree was supposed to be added to the cache first. + return +1.0; + } else if (bCoord.isAncestor(aCoord)) { + return -1.0; + } + return a.stamp - b.stamp; +}; + +/** + * @alias ImplicitSubtreeCacheNode + * @constructor + * + * @param {ImplicitSubtree} subtree + * @param {Number} stamp + * + * @private + */ +function ImplicitSubtreeCacheNode(subtree, stamp) { + this.subtree = subtree; + this.stamp = stamp; +} + +export default ImplicitSubtreeCache; diff --git a/Specs/Scene/ImplicitSubtreeCacheSpec.js b/Specs/Scene/ImplicitSubtreeCacheSpec.js new file mode 100644 index 00000000000..253b9d50b11 --- /dev/null +++ b/Specs/Scene/ImplicitSubtreeCacheSpec.js @@ -0,0 +1,139 @@ +import { + ImplicitSubtree, + ImplicitSubtreeCache, + ImplicitTileset, + ImplicitTileCoordinates, + Resource, +} from "../../Source/Cesium.js"; + +describe("Scene/ImplicitSubtreeCache", function () { + const implicitOctreeJson = { + geometricError: 500, + refine: "REPLACE", + boundingVolume: { + region: [0, 0, Math.PI / 24, Math.PI / 24, 0, 1000.0], + }, + content: { + uri: "https://example.com/{level}/{x}_{y}_{z}.b3dm", + }, + implicitTiling: { + subdivisionScheme: "OCTREE", + subtreeLevels: 2, + availableLevels: 4, + subtrees: { + uri: "https://example.com/{level}/{x}_{y}_{z}.subtree", + }, + }, + }; + + const subtreeConstantJson = { + tileAvailability: { + constant: 1, + }, + contentAvailability: { + constant: 1, + }, + childSubtreeAvailability: { + constant: 0, + }, + }; + + let tilesetResource; + let subtreeResource; + let implicitOctree; + let metadataSchema; // intentionally left undefined + + beforeEach(function () { + tilesetResource = new Resource({ + url: "https://example.com/tileset.json", + }); + + subtreeResource = new Resource({ + url: "https://example.com/test.subtree", + }); + + implicitOctree = new ImplicitTileset( + tilesetResource, + implicitOctreeJson, + metadataSchema + ); + }); + + it("constructs", function () { + const cache = new ImplicitSubtreeCache(); + expect(cache._maximumSubtreeCount).toBe(0); + expect(cache._subtreeRequestCounter).toBe(0); + }); + + it("can add a subtree", function () { + const cache = new ImplicitSubtreeCache(); + const octreeCoordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitOctree.subdivisionScheme, + subtreeLevels: implicitOctree.subtreeLevels, + level: 0, + x: 0, + y: 0, + z: 0, + }); + const subtree = new ImplicitSubtree( + subtreeResource, + subtreeConstantJson, + undefined, + implicitOctree, + octreeCoordinates + ); + cache.addSubtree(subtree); + expect(cache._subtreeRequestCounter).toBe(1); + }); + + it("addSubtree throws if parent does not exist", function () { + const cache = new ImplicitSubtreeCache(); + const octreeCoordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitOctree.subdivisionScheme, + subtreeLevels: implicitOctree.subtreeLevels, + level: 2, + x: 0, + y: 1, + z: 0, + }); + const subtree = new ImplicitSubtree( + subtreeResource, + subtreeConstantJson, + undefined, + implicitOctree, + octreeCoordinates + ); + expect(() => cache.addSubtree(subtree)).toThrowDeveloperError(); + }); + + it("addSubtree trims cache as needed", function () { + const cache = new ImplicitSubtreeCache({ + maximumSubtreeCount: 3, + }); + const octreeCoordArray = [ + { level: 0, x: 0, y: 0, z: 0 }, + { level: 2, x: 1, y: 0, z: 0 }, + { level: 2, x: 0, y: 1, z: 0 }, + { level: 2, x: 0, y: 0, z: 1 }, + ]; + const octreeCoordParams = { + subdivisionScheme: implicitOctree.subdivisionScheme, + subtreeLevels: implicitOctree.subtreeLevels, + }; + octreeCoordArray.forEach((octreeCoord) => { + const octreeCoordinates = new ImplicitTileCoordinates( + Object.assign({}, octreeCoordParams, octreeCoord) + ); + const subtree = new ImplicitSubtree( + subtreeResource, + subtreeConstantJson, + undefined, + implicitOctree, + octreeCoordinates + ); + cache.addSubtree(subtree); + }); + expect(cache._subtreeRequestCounter).toBe(4); + expect(cache._queue.length).toBe(3); + }); +}); From 9cac5d42867a9dcc3bd603e4faadb14980281ce4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 26 Oct 2022 11:34:33 -0400 Subject: [PATCH 124/679] Test attribute ordering in Cesium3DTilesVoxelProviderSpec --- Source/Scene/Cesium3DTilesVoxelProvider.js | 16 ++- .../VoxelMultiAttribute3DTiles/README.md | 11 +++ .../VoxelMultiAttribute3DTiles/schema.json | 27 ++++++ .../subtrees/0/0/0/0.subtree | Bin 0 -> 200 bytes .../tiles/0/0/0/0.gltf | 91 ++++++++++++++++++ .../VoxelMultiAttribute3DTiles/tileset.json | 53 ++++++++++ .../VoxelMultiAttribute3DTiles/voxel2x2.csv | 9 ++ .../VoxelMultiAttribute3DTiles/voxel2x2.json | 40 ++++++++ Specs/Scene/Cesium3DTilesVoxelProviderSpec.js | 67 +++++++++---- 9 files changed, 289 insertions(+), 25 deletions(-) create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/subtrees/0/0/0/0.subtree create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.csv create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index d095f8e6161..780ef1cc503 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -417,11 +417,12 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { z: tileZ, }); - // TODO: is the first condition flipped? if isSubtreeRoot, level == 0 + // Find the coordinates of the parent subtree containing tileCoordinates + // If tileCoordinates is a subtree child, use that subtree + // If tileCoords is a subtree root, use its parent subtree const isSubtreeRoot = tileCoordinates.isSubtreeRoot() && tileCoordinates.level > 0; - // TODO: are these switched? Root has no parent const subtreeCoord = isSubtreeRoot ? tileCoordinates.getParentSubtreeCoordinates() : tileCoordinates.getSubtreeCoordinates(); @@ -456,9 +457,14 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { for (let i = 0; i < attributesLength; i++) { // The attributes array from GltfLoader is not in the same order as // names, types, etc. from the provider. - // A temporary fix: Look up the attribute based on its name - const name = `_${names[i]}`; - const attribute = attributes.find((a) => a.name === name); + // Find the appropriate glTF attribute based on its name + const name = names[i]; + const attribute = attributes.find((attribute) => { + // glTF custom attribute names should be prefixed with "_". Remove the "_" + const attributeName = attribute.name.substring(1); + // Also check raw name to handle non-conformant glTFs with no "_" + return attributeName === name || attribute.name === name; + }); if (!defined(attribute)) { continue; } diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md new file mode 100644 index 00000000000..468b82060cc --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md @@ -0,0 +1,11 @@ +# VoxelMultiAttribute3DTiles + +The data was generated as follows: + +1. Generate 8-sample (2x2 cube) CSV file, voxel2x2.csv +2. Run tiler with the config file voxel2x2.json +3. Modify ./tiles/0/0/0/0.gltf to re-order the meshes.primitives.attributes dictionary. + +Note: in step 3, the (key: index) pairs are left intact. We simply +re-ordered the entries to simulate a bug in Cesium3DTilesVoxelProvider. +The bug has since been fixed. diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json new file mode 100644 index 00000000000..4c989331219 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json @@ -0,0 +1,27 @@ +{ + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true, + "noData": -99999.0 + }, + "b": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true, + "noData": -99999.0 + }, + "c": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true, + "noData": -99999.0 + } + } + } + } +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/subtrees/0/0/0/0.subtree b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/subtrees/0/0/0/0.subtree new file mode 100644 index 0000000000000000000000000000000000000000..8d5bf10089741b25252f6fb776daa999b781b54c GIT binary patch literal 200 zcmXReO)6nzU|`q)#K@ppsU$Ne)v+uwGbb@AGbgj8Qpu`XDG|cYNp;RI%_~u|GSpE@ v&d)0@Nd$9h!Mu{xyb@G>(F8Td0(E9&=A;AzT~m}w&{_jzYYl2^6%-Tz=^sHV literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf new file mode 100644 index 00000000000..0a987473e24 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf @@ -0,0 +1,91 @@ +{ + "extensionsUsed": ["EXT_structural_metadata", "EXT_primitive_voxels"], + "extensionsRequired": ["EXT_primitive_voxels"], + "accessors": [{ + "bufferView": 0, + "componentType": 5126, + "count": 8, + "type": "SCALAR" + }, { + "bufferView": 1, + "componentType": 5126, + "count": 8, + "type": "SCALAR" + }, { + "bufferView": 2, + "componentType": 5126, + "count": 8, + "type": "SCALAR" + }], + "asset": { + "version": "2.0" + }, + "buffers": [{ + "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "byteLength": 96 + }], + "bufferViews": [{ + "buffer": 0, + "byteLength": 32, + "target": 34962 + }, { + "buffer": 0, + "byteOffset": 32, + "byteLength": 32, + "target": 34962 + }, { + "buffer": 0, + "byteOffset": 64, + "byteLength": 32, + "target": 34962 + }], + "meshes": [{ + "primitives": [{ + "attributes": { + "_c": 0, + "_b": 1, + "_a": 2 + }, + "mode": 2147483648, + "extensions": { + "EXT_structural_metadata": { + "propertyAttributes": [0] + }, + "EXT_primitive_voxels": { + "dimensions": [2, 2, 2], + "bounds": { + "min": [-1.0, -1.0, -1.0], + "max": [1.0, 1.0, 1.0] + } + } + } + }] + }], + "nodes": [{ + "matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], + "mesh": 0 + }], + "scene": 0, + "scenes": [{ + "nodes": [0] + }], + "extensions": { + "EXT_structural_metadata": { + "schemaUri": "../../../../schema.json", + "propertyAttributes": [{ + "class": "voxel", + "properties": { + "a": { + "attribute": "_a" + }, + "b": { + "attribute": "_b" + }, + "c": { + "attribute": "_c" + } + } + }] + } + } +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json new file mode 100644 index 00000000000..12d0ff74f87 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json @@ -0,0 +1,53 @@ +{ + "asset": { + "version": "1.1", + "extras": { + "ion": { + "georeferenced": true, + "movable": true + } + } + }, + "schemaUri": "schema.json", + "statistics": { + "classes": { + "voxel": { + "count": 8, + "properties": { + "a": { + "min": 0.0, + "max": 0.0 + }, + "b": { + "min": 0.5, + "max": 0.5 + }, + "c": { + "min": 1.0, + "max": 1.0 + } + } + } + } + }, + "geometricError": 1.7320508075688772, + "root": { + "boundingVolume": { + "box": [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] + }, + "geometricError": 0.8660254037844386, + "refine": "REPLACE", + "transform": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0], + "content": { + "uri": "tiles/{level}/{x}/{y}/{z}.gltf" + }, + "implicitTiling": { + "subdivisionScheme": "OCTREE", + "subtreeLevels": 1, + "availableLevels": 1, + "subtrees": { + "uri": "subtrees/{level}/{x}/{y}/{z}.subtree" + } + } + } +} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.csv b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.csv new file mode 100644 index 00000000000..826ffa6122b --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.csv @@ -0,0 +1,9 @@ +X,Y,Z,a,b,c +0,0,0,0,0.5,1 +0,0,1,0,0.5,1 +0,1,0,0,0.5,1 +0,1,1,0,0.5,1 +1,0,0,0,0.5,1 +1,0,1,0,0.5,1 +1,1,0,0,0.5,1 +1,1,1,0,0.5,1 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json new file mode 100644 index 00000000000..db8f5fd0f01 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json @@ -0,0 +1,40 @@ +{ + "input": { + "path": "./voxel2x2.csv" + }, + "output": { + "path": "./" + }, + "gltf": { + "binary": false + }, + "csv": { + "properties": { + "a": { + "noData": -99999.0, + "type": "FLOAT32" + }, + "b": { + "noData": -99999.0, + "type": "FLOAT32" + }, + "c": { + "noData": -99999.0, + "type": "FLOAT32" + } + } + }, + "pipeline": { + "voxelTiler": { + "properties": ["a", "b", "c"], + "tileDimensions": 2, + "grid": { + "xSpacing": 1, + "ySpacing": 1, + "zSpacing": 1, + "rotation": 0 + } + } + }, + "force": true +} diff --git a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js index a1dc45defe9..eae93b43ab1 100644 --- a/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js +++ b/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -87,28 +87,28 @@ describe( return pollToPromise(function () { provider.update(scene.frameState); return provider.ready; - }).then(function () { - const requestTilePromise = provider.requestData(); - // need to call update until the promise is ready - return pollToPromise(function () { - provider.update(scene.frameState); - return provider.doneLoading(); - }) - .then(function () { + }) + .then(function () { + const requestTilePromise = provider.requestData(); + // need to call update until the promise is ready + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.doneLoading(); + }).then(function () { return requestTilePromise; - }) - .then(function (data) { - expect(data.length).toEqual(1); - - const dimensions = provider.dimensions; - const voxelCount = dimensions.x * dimensions.y * dimensions.z; - const componentCount = MetadataType.getComponentCount( - provider.types[0] - ); - const expectedLength = voxelCount * componentCount; - expect(data[0].length).toEqual(expectedLength); }); - }); + }) + .then(function (data) { + expect(data.length).toEqual(1); + + const dimensions = provider.dimensions; + const voxelCount = dimensions.x * dimensions.y * dimensions.z; + const componentCount = MetadataType.getComponentCount( + provider.types[0] + ); + const expectedLength = voxelCount * componentCount; + expect(data[0].length).toEqual(expectedLength); + }); }); it("requestData throws if the provider is not ready", function () { @@ -121,6 +121,33 @@ describe( return provider.requestData(); }).toThrowDeveloperError(); }); + + it("requestData loads multiple attributes correctly", function () { + const url = + "./Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json"; + const provider = new Cesium3DTilesVoxelProvider({ url }); + + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.ready; + }) + .then(function () { + const requestTilePromise = provider.requestData(); + // need to call update until the promise is ready + return pollToPromise(function () { + provider.update(scene.frameState); + return provider.doneLoading(); + }).then(function () { + return requestTilePromise; + }); + }) + .then(function (data) { + expect(data.length).toBe(3); + expect(data[0][0]).toBe(0.0); + expect(data[1][0]).toBe(0.5); + expect(data[2][0]).toBe(1.0); + }); + }); }, "WebGL" ); From 812ef9829aa8d7453b03970e04c62bf93fc37ae7 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 26 Oct 2022 14:47:47 -0400 Subject: [PATCH 125/679] Fix ResourceCache.clearForSpecs to handle glTF embedded buffers --- Source/Scene/ResourceCache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/ResourceCache.js b/Source/Scene/ResourceCache.js index 5b10fdcd6fe..351abd0dbff 100644 --- a/Source/Scene/ResourceCache.js +++ b/Source/Scene/ResourceCache.js @@ -760,9 +760,9 @@ ResourceCache.clearForSpecs = function () { GltfTextureLoader, GltfImageLoader, GltfBufferViewLoader, - BufferLoader, MetadataSchemaLoader, GltfJsonLoader, + BufferLoader, ]; let cacheKey; From 60984fc18f33f57c1d1755d9ddb7cae498f14d47 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 31 Oct 2022 13:12:54 -0400 Subject: [PATCH 126/679] Remove hack in Cesium3DTilesVoxelProvider for non-compliant glTFs --- Source/Scene/Cesium3DTilesVoxelProvider.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Cesium3DTilesVoxelProvider.js b/Source/Scene/Cesium3DTilesVoxelProvider.js index 780ef1cc503..5e02dbc9b2e 100644 --- a/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -457,14 +457,10 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { for (let i = 0; i < attributesLength; i++) { // The attributes array from GltfLoader is not in the same order as // names, types, etc. from the provider. - // Find the appropriate glTF attribute based on its name - const name = names[i]; - const attribute = attributes.find((attribute) => { - // glTF custom attribute names should be prefixed with "_". Remove the "_" - const attributeName = attribute.name.substring(1); - // Also check raw name to handle non-conformant glTFs with no "_" - return attributeName === name || attribute.name === name; - }); + // Find the appropriate glTF attribute based on its name. + // Note: glTF custom attribute names are prefixed with "_" + const name = `_${names[i]}`; + const attribute = attributes.find((a) => a.name === name); if (!defined(attribute)) { continue; } From aaf6bd8a5ca26dba0ce4ac113b9ffd58708fad13 Mon Sep 17 00:00:00 2001 From: Sanjeet Suhag Date: Tue, 1 Nov 2022 15:39:57 -0400 Subject: [PATCH 127/679] Adds engine and widgets workspaces --- .eslintignore | 21 +- .gitignore | 18 +- .npmignore | 3 + .prettierignore | 25 +- .travis.yml | 24 +- .vscode/launch.json | 121 +++ Apps/.eslintrc.json | 2 +- Apps/HelloWorld.html | 2 +- .../Contributors/ReleaseGuide/README.md | 52 +- Specs/.eslintrc.json | 2 +- Specs/BadGeometry.js | 2 +- Specs/Cesium3DTilesTester.js | 2 +- Specs/DomEventSimulator.js | 2 +- Specs/ImplicitTilingTester.js | 2 +- Specs/MetadataTester.js | 2 +- Specs/MockDataSource.js | 2 +- Specs/MockImageryProvider.js | 2 +- Specs/MockTerrainProvider.js | 2 +- Specs/SpecRunner.html | 18 +- Specs/TerrainTileProcessor.js | 2 +- Specs/TestWorkers/.eslintrc.json | 18 +- Specs/ViewportPrimitive.js | 7 +- Specs/addDefaultMatchers.js | 5 +- Specs/createCamera.js | 2 +- Specs/createCanvas.js | 2 +- Specs/createContext.js | 2 +- Specs/createDynamicGeometryUpdaterSpecs.js | 5 +- Specs/createDynamicProperty.js | 2 +- Specs/createFrameState.js | 2 +- ...reateGeometryUpdaterGroundGeometrySpecs.js | 2 +- Specs/createGeometryUpdaterSpecs.js | 2 +- Specs/createGlobe.js | 2 +- Specs/createPackableArraySpecs.js | 2 +- Specs/createPackableSpecs.js | 4 +- Specs/createScene.js | 2 +- Specs/createTileKey.js | 2 +- Specs/createViewer.js | 3 +- Specs/equals.js | 2 +- Specs/equalsMethodEqualityTester.js | 2 +- Specs/generateJsonBuffer.js | 2 +- Specs/getWebGLStub.js | 2 +- Specs/karma.conf.cjs | 7 +- Specs/pick.js | 2 +- Specs/pollToPromise.js | 2 +- Specs/render.js | 2 +- Specs/runLater.js | 2 +- Specs/spec-main.js | 3 +- Specs/testDefinitionChanged.js | 2 +- Specs/testMaterialDefinitionChanged.js | 2 +- Tools/jsdoc/conf.json | 10 +- Tools/jsdoc/ts-conf.json | 8 +- build.js | 750 ++++++++++++-- gulpfile.js | 718 ++++++++++---- index.html | 1 + package.json | 32 +- {Source => packages}/.eslintrc.json | 0 packages/engine/.gitignore | 16 + packages/engine/LICENSE.md | 933 ++++++++++++++++++ packages/engine/README.md | 58 ++ .../Assets/IAU2006_XYS/IAU2006_XYS_0.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_1.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_10.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_11.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_12.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_13.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_14.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_15.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_16.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_17.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_18.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_19.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_2.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_20.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_21.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_22.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_23.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_24.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_25.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_26.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_27.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_3.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_4.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_5.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_6.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_7.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_8.json | 0 .../Assets/IAU2006_XYS/IAU2006_XYS_9.json | 0 .../Assets/Images/bing_maps_credit.png | Bin .../Source}/Assets/Images/cesium_credit.png | Bin .../Assets/Images/google_earth_credit.png | Bin .../Source}/Assets/Images/ion-credit.png | Bin .../Assets/Textures/LensFlare/DirtMask.jpg | Bin .../Assets/Textures/LensFlare/StarBurst.jpg | Bin .../Assets/Textures/NaturalEarthII/0/0/0.jpg | Bin .../Assets/Textures/NaturalEarthII/0/1/0.jpg | Bin .../Assets/Textures/NaturalEarthII/1/0/0.jpg | Bin .../Assets/Textures/NaturalEarthII/1/0/1.jpg | Bin .../Assets/Textures/NaturalEarthII/1/1/0.jpg | Bin .../Assets/Textures/NaturalEarthII/1/1/1.jpg | Bin .../Assets/Textures/NaturalEarthII/1/2/0.jpg | Bin .../Assets/Textures/NaturalEarthII/1/2/1.jpg | Bin .../Assets/Textures/NaturalEarthII/1/3/0.jpg | Bin .../Assets/Textures/NaturalEarthII/1/3/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/0/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/0/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/0/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/0/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/1/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/1/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/1/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/1/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/2/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/2/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/2/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/2/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/3/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/3/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/3/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/3/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/4/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/4/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/4/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/4/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/5/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/5/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/5/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/5/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/6/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/6/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/6/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/6/3.jpg | Bin .../Assets/Textures/NaturalEarthII/2/7/0.jpg | Bin .../Assets/Textures/NaturalEarthII/2/7/1.jpg | Bin .../Assets/Textures/NaturalEarthII/2/7/2.jpg | Bin .../Assets/Textures/NaturalEarthII/2/7/3.jpg | Bin .../NaturalEarthII/tilemapresource.xml | 0 .../Assets/Textures/SkyBox/tycho2t3_80_mx.jpg | Bin .../Assets/Textures/SkyBox/tycho2t3_80_my.jpg | Bin .../Assets/Textures/SkyBox/tycho2t3_80_mz.jpg | Bin .../Assets/Textures/SkyBox/tycho2t3_80_px.jpg | Bin .../Assets/Textures/SkyBox/tycho2t3_80_py.jpg | Bin .../Assets/Textures/SkyBox/tycho2t3_80_pz.jpg | Bin .../Source}/Assets/Textures/maki/airfield.png | Bin .../Source}/Assets/Textures/maki/airport.png | Bin .../Assets/Textures/maki/alcohol-shop.png | Bin .../Assets/Textures/maki/america-football.png | Bin .../Assets/Textures/maki/art-gallery.png | Bin .../Source}/Assets/Textures/maki/bakery.png | Bin .../Source}/Assets/Textures/maki/bank.png | Bin .../Source}/Assets/Textures/maki/bar.png | Bin .../Source}/Assets/Textures/maki/baseball.png | Bin .../Assets/Textures/maki/basketball.png | Bin .../Source}/Assets/Textures/maki/beer.png | Bin .../Source}/Assets/Textures/maki/bicycle.png | Bin .../Source}/Assets/Textures/maki/building.png | Bin .../Source}/Assets/Textures/maki/bus.png | Bin .../Source}/Assets/Textures/maki/cafe.png | Bin .../Source}/Assets/Textures/maki/camera.png | Bin .../Source}/Assets/Textures/maki/campsite.png | Bin .../Source}/Assets/Textures/maki/car.png | Bin .../Source}/Assets/Textures/maki/cemetery.png | Bin .../Source}/Assets/Textures/maki/cesium.png | Bin .../Source}/Assets/Textures/maki/chemist.png | Bin .../Source}/Assets/Textures/maki/cinema.png | Bin .../Assets/Textures/maki/circle-stroked.png | Bin .../Source}/Assets/Textures/maki/circle.png | Bin .../Source}/Assets/Textures/maki/city.png | Bin .../Assets/Textures/maki/clothing-store.png | Bin .../Source}/Assets/Textures/maki/college.png | Bin .../Assets/Textures/maki/commercial.png | Bin .../Source}/Assets/Textures/maki/cricket.png | Bin .../Source}/Assets/Textures/maki/cross.png | Bin .../Source}/Assets/Textures/maki/dam.png | Bin .../Source}/Assets/Textures/maki/danger.png | Bin .../Assets/Textures/maki/disability.png | Bin .../Source}/Assets/Textures/maki/dog-park.png | Bin .../Source}/Assets/Textures/maki/embassy.png | Bin .../Textures/maki/emergency-telephone.png | Bin .../Source}/Assets/Textures/maki/entrance.png | Bin .../Source}/Assets/Textures/maki/farm.png | Bin .../Assets/Textures/maki/fast-food.png | Bin .../Source}/Assets/Textures/maki/ferry.png | Bin .../Assets/Textures/maki/fire-station.png | Bin .../Source}/Assets/Textures/maki/fuel.png | Bin .../Source}/Assets/Textures/maki/garden.png | Bin .../Source}/Assets/Textures/maki/gift.png | Bin .../Source}/Assets/Textures/maki/golf.png | Bin .../Source}/Assets/Textures/maki/grocery.png | Bin .../Assets/Textures/maki/hairdresser.png | Bin .../Source}/Assets/Textures/maki/harbor.png | Bin .../Source}/Assets/Textures/maki/heart.png | Bin .../Source}/Assets/Textures/maki/heliport.png | Bin .../Source}/Assets/Textures/maki/hospital.png | Bin .../Assets/Textures/maki/ice-cream.png | Bin .../Assets/Textures/maki/industrial.png | Bin .../Source}/Assets/Textures/maki/land-use.png | Bin .../Source}/Assets/Textures/maki/laundry.png | Bin .../Source}/Assets/Textures/maki/library.png | Bin .../Assets/Textures/maki/lighthouse.png | Bin .../Source}/Assets/Textures/maki/lodging.png | Bin .../Source}/Assets/Textures/maki/logging.png | Bin .../Textures/maki/london-underground.png | Bin .../Assets/Textures/maki/marker-stroked.png | Bin .../Source}/Assets/Textures/maki/marker.png | Bin .../Assets/Textures/maki/minefield.png | Bin .../Assets/Textures/maki/mobilephone.png | Bin .../Source}/Assets/Textures/maki/monument.png | Bin .../Source}/Assets/Textures/maki/museum.png | Bin .../Source}/Assets/Textures/maki/music.png | Bin .../Source}/Assets/Textures/maki/oil-well.png | Bin .../Source}/Assets/Textures/maki/park.png | Bin .../Source}/Assets/Textures/maki/park2.png | Bin .../Assets/Textures/maki/parking-garage.png | Bin .../Source}/Assets/Textures/maki/parking.png | Bin .../Source}/Assets/Textures/maki/pharmacy.png | Bin .../Source}/Assets/Textures/maki/pitch.png | Bin .../Assets/Textures/maki/place-of-worship.png | Bin .../Assets/Textures/maki/playground.png | Bin .../Source}/Assets/Textures/maki/police.png | Bin .../Assets/Textures/maki/polling-place.png | Bin .../Source}/Assets/Textures/maki/post.png | Bin .../Source}/Assets/Textures/maki/prison.png | Bin .../Assets/Textures/maki/rail-above.png | Bin .../Assets/Textures/maki/rail-light.png | Bin .../Assets/Textures/maki/rail-metro.png | Bin .../Assets/Textures/maki/rail-underground.png | Bin .../Source}/Assets/Textures/maki/rail.png | Bin .../Textures/maki/religious-christian.png | Bin .../Assets/Textures/maki/religious-jewish.png | Bin .../Assets/Textures/maki/religious-muslim.png | Bin .../Assets/Textures/maki/restaurant.png | Bin .../Assets/Textures/maki/roadblock.png | Bin .../Source}/Assets/Textures/maki/rocket.png | Bin .../Source}/Assets/Textures/maki/school.png | Bin .../Source}/Assets/Textures/maki/scooter.png | Bin .../Source}/Assets/Textures/maki/shop.png | Bin .../Source}/Assets/Textures/maki/skiing.png | Bin .../Assets/Textures/maki/slaughterhouse.png | Bin .../Source}/Assets/Textures/maki/soccer.png | Bin .../Assets/Textures/maki/square-stroked.png | Bin .../Source}/Assets/Textures/maki/square.png | Bin .../Assets/Textures/maki/star-stroked.png | Bin .../Source}/Assets/Textures/maki/star.png | Bin .../Source}/Assets/Textures/maki/suitcase.png | Bin .../Source}/Assets/Textures/maki/swimming.png | Bin .../Assets/Textures/maki/telephone.png | Bin .../Source}/Assets/Textures/maki/tennis.png | Bin .../Source}/Assets/Textures/maki/theatre.png | Bin .../Source}/Assets/Textures/maki/toilets.png | Bin .../Assets/Textures/maki/town-hall.png | Bin .../Source}/Assets/Textures/maki/town.png | Bin .../Assets/Textures/maki/triangle-stroked.png | Bin .../Source}/Assets/Textures/maki/triangle.png | Bin .../Source}/Assets/Textures/maki/village.png | Bin .../Assets/Textures/maki/warehouse.png | Bin .../Assets/Textures/maki/waste-basket.png | Bin .../Source}/Assets/Textures/maki/water.png | Bin .../Source}/Assets/Textures/maki/wetland.png | Bin .../Source}/Assets/Textures/maki/zoo.png | Bin .../Source}/Assets/Textures/moonSmall.jpg | Bin .../engine/Source}/Assets/Textures/pin.svg | 0 .../Source}/Assets/Textures/waterNormals.jpg | Bin .../Assets/Textures/waterNormalsSmall.jpg | Bin .../Assets/approximateTerrainHeights.json | 0 .../Source}/Core/ApproximateTerrainHeights.js | 1 - .../ArcGISTiledElevationTerrainProvider.js | 0 .../engine/Source}/Core/ArcType.js | 0 .../Source}/Core/ArticulationStageType.js | 0 .../engine/Source}/Core/AssociativeArray.js | 0 .../Source}/Core/AttributeCompression.js | 0 .../Source}/Core/AxisAlignedBoundingBox.js | 0 .../Source}/Core/BingMapsGeocoderService.js | 0 .../engine/Source}/Core/BoundingRectangle.js | 0 .../engine/Source}/Core/BoundingSphere.js | 0 .../engine/Source}/Core/BoxGeometry.js | 0 .../engine/Source}/Core/BoxOutlineGeometry.js | 0 .../engine/Source}/Core/Cartesian2.js | 0 .../engine/Source}/Core/Cartesian3.js | 0 .../engine/Source}/Core/Cartesian4.js | 0 .../engine/Source}/Core/Cartographic.js | 0 .../Core/CartographicGeocoderService.js | 0 .../engine/Source}/Core/CatmullRomSpline.js | 0 .../Source}/Core/CesiumTerrainProvider.js | 0 .../engine/Source}/Core/Check.js | 0 .../engine/Source}/Core/CircleGeometry.js | 0 .../Source}/Core/CircleOutlineGeometry.js | 0 .../engine/Source}/Core/Clock.js | 0 .../engine/Source}/Core/ClockRange.js | 0 .../engine/Source}/Core/ClockStep.js | 0 .../engine/Source}/Core/Color.js | 0 .../Core/ColorGeometryInstanceAttribute.js | 0 .../engine/Source}/Core/ComponentDatatype.js | 0 .../Source}/Core/CompressedTextureBuffer.js | 0 .../engine/Source}/Core/ConstantSpline.js | 0 .../Source}/Core/CoplanarPolygonGeometry.js | 0 .../Core/CoplanarPolygonGeometryLibrary.js | 0 .../Core/CoplanarPolygonOutlineGeometry.js | 0 .../engine/Source}/Core/CornerType.js | 0 .../engine/Source}/Core/CorridorGeometry.js | 0 .../Source}/Core/CorridorGeometryLibrary.js | 0 .../Source}/Core/CorridorOutlineGeometry.js | 0 .../engine/Source}/Core/Credit.js | 0 .../Source}/Core/CubicRealPolynomial.js | 0 .../engine/Source}/Core/CullingVolume.js | 0 .../Core/CustomHeightmapTerrainProvider.js | 0 .../engine/Source}/Core/CylinderGeometry.js | 0 .../Source}/Core/CylinderGeometryLibrary.js | 0 .../Source}/Core/CylinderOutlineGeometry.js | 0 .../engine/Source}/Core/DefaultProxy.js | 0 .../engine/Source}/Core/DeveloperError.js | 0 .../Source}/Core/DistanceDisplayCondition.js | 0 ...splayConditionGeometryInstanceAttribute.js | 0 .../Source}/Core/DoubleEndedPriorityQueue.js | 0 .../engine/Source}/Core/DoublyLinkedList.js | 0 .../Core/EarthOrientationParameters.js | 0 .../Core/EarthOrientationParametersSample.js | 0 .../engine/Source}/Core/EasingFunction.js | 0 .../engine/Source}/Core/EllipseGeometry.js | 0 .../Source}/Core/EllipseGeometryLibrary.js | 0 .../Source}/Core/EllipseOutlineGeometry.js | 0 .../engine/Source}/Core/Ellipsoid.js | 0 .../engine/Source}/Core/EllipsoidGeodesic.js | 0 .../engine/Source}/Core/EllipsoidGeometry.js | 0 .../Source}/Core/EllipsoidOutlineGeometry.js | 0 .../engine/Source}/Core/EllipsoidRhumbLine.js | 0 .../Source}/Core/EllipsoidTangentPlane.js | 0 .../Source}/Core/EllipsoidTerrainProvider.js | 0 .../Source}/Core/EllipsoidalOccluder.js | 0 .../engine/Source}/Core/EncodedCartesian3.js | 0 .../engine/Source}/Core/Event.js | 0 .../engine/Source}/Core/EventHelper.js | 0 .../engine/Source}/Core/ExtrapolationType.js | 0 .../engine/Source}/Core/FeatureDetection.js | 0 .../engine/Source}/Core/FrustumGeometry.js | 0 .../Source}/Core/FrustumOutlineGeometry.js | 0 .../engine/Source}/Core/Fullscreen.js | 0 .../engine/Source}/Core/GeocodeType.js | 0 .../engine/Source}/Core/GeocoderService.js | 0 .../Source}/Core/GeographicProjection.js | 0 .../Source}/Core/GeographicTilingScheme.js | 0 .../engine/Source}/Core/Geometry.js | 0 .../engine/Source}/Core/GeometryAttribute.js | 0 .../engine/Source}/Core/GeometryAttributes.js | 0 .../engine/Source}/Core/GeometryFactory.js | 0 .../engine/Source}/Core/GeometryInstance.js | 0 .../Source}/Core/GeometryInstanceAttribute.js | 0 .../Source}/Core/GeometryOffsetAttribute.js | 0 .../engine/Source}/Core/GeometryPipeline.js | 0 .../engine/Source}/Core/GeometryType.js | 0 .../Core/GoogleEarthEnterpriseMetadata.js | 0 .../Core/GoogleEarthEnterpriseTerrainData.js | 0 .../GoogleEarthEnterpriseTerrainProvider.js | 0 .../GoogleEarthEnterpriseTileInformation.js | 0 .../engine/Source}/Core/GregorianDate.js | 0 .../Source}/Core/GroundPolylineGeometry.js | 0 .../engine/Source}/Core/HeadingPitchRange.js | 0 .../engine/Source}/Core/HeadingPitchRoll.js | 0 .../engine/Source}/Core/Heap.js | 0 .../engine/Source}/Core/HeightmapEncoding.js | 0 .../Source}/Core/HeightmapTerrainData.js | 0 .../Source}/Core/HeightmapTessellator.js | 0 .../Core/HermitePolynomialApproximation.js | 0 .../engine/Source}/Core/HermiteSpline.js | 0 .../engine/Source}/Core/HilbertOrder.js | 0 .../engine/Source}/Core/Iau2000Orientation.js | 0 .../engine/Source}/Core/Iau2006XysData.js | 0 .../engine/Source}/Core/Iau2006XysSample.js | 0 .../engine/Source}/Core/IauOrientationAxes.js | 0 .../Source}/Core/IauOrientationParameters.js | 0 .../engine/Source}/Core/IndexDatatype.js | 0 .../Source}/Core/InterpolationAlgorithm.js | 0 .../engine/Source}/Core/InterpolationType.js | 0 .../engine/Source}/Core/Intersect.js | 0 .../engine/Source}/Core/IntersectionTests.js | 0 .../engine/Source}/Core/Intersections2D.js | 0 .../engine/Source}/Core/Interval.js | 0 .../engine/Source}/Core/Ion.js | 0 .../engine/Source}/Core/IonGeocoderService.js | 0 .../engine/Source}/Core/IonResource.js | 0 .../engine/Source}/Core/Iso8601.js | 0 .../engine/Source}/Core/JulianDate.js | 0 .../engine/Source}/Core/KTX2Transcoder.js | 0 .../Source}/Core/KeyboardEventModifier.js | 0 .../Core/LagrangePolynomialApproximation.js | 0 .../engine/Source}/Core/LeapSecond.js | 0 .../Source}/Core/LinearApproximation.js | 0 .../engine/Source}/Core/LinearSpline.js | 0 .../engine/Source}/Core/ManagedArray.js | 0 .../engine/Source}/Core/MapProjection.js | 0 .../engine/Source}/Core/Math.js | 0 .../engine/Source}/Core/Matrix2.js | 0 .../engine/Source}/Core/Matrix3.js | 0 .../engine/Source}/Core/Matrix4.js | 0 .../engine/Source}/Core/MorphWeightSpline.js | 0 .../engine/Source}/Core/MortonOrder.js | 0 .../engine/Source}/Core/NearFarScalar.js | 0 .../engine/Source}/Core/Occluder.js | 0 .../Core/OffsetGeometryInstanceAttribute.js | 0 .../Source}/Core/OpenCageGeocoderService.js | 0 .../Source}/Core/OrientedBoundingBox.js | 0 .../Source}/Core/OrthographicFrustum.js | 0 .../Core/OrthographicOffCenterFrustum.js | 0 .../engine/Source}/Core/Packable.js | 0 .../Source}/Core/PackableForInterpolation.js | 0 .../Source}/Core/PeliasGeocoderService.js | 0 .../engine/Source}/Core/PerspectiveFrustum.js | 0 .../Core/PerspectiveOffCenterFrustum.js | 0 .../engine/Source}/Core/PinBuilder.js | 0 .../engine/Source}/Core/PixelFormat.js | 0 .../engine/Source}/Core/Plane.js | 0 .../engine/Source}/Core/PlaneGeometry.js | 0 .../Source}/Core/PlaneOutlineGeometry.js | 0 .../engine/Source}/Core/PolygonGeometry.js | 0 .../Source}/Core/PolygonGeometryLibrary.js | 0 .../engine/Source}/Core/PolygonHierarchy.js | 0 .../Source}/Core/PolygonOutlineGeometry.js | 0 .../engine/Source}/Core/PolygonPipeline.js | 0 .../engine/Source}/Core/PolylineGeometry.js | 0 .../engine/Source}/Core/PolylinePipeline.js | 0 .../Source}/Core/PolylineVolumeGeometry.js | 0 .../Core/PolylineVolumeGeometryLibrary.js | 0 .../Core/PolylineVolumeOutlineGeometry.js | 0 .../engine/Source}/Core/PrimitiveType.js | 0 .../engine/Source}/Core/Proxy.js | 0 .../Source}/Core/QuadraticRealPolynomial.js | 0 .../Source}/Core/QuantizedMeshTerrainData.js | 0 .../Source}/Core/QuarticRealPolynomial.js | 0 .../engine/Source}/Core/Quaternion.js | 0 .../engine/Source}/Core/QuaternionSpline.js | 0 .../engine/Source}/Core/Queue.js | 0 .../engine/Source}/Core/Ray.js | 0 .../engine/Source}/Core/Rectangle.js | 0 .../Source}/Core/RectangleCollisionChecker.js | 0 .../engine/Source}/Core/RectangleGeometry.js | 0 .../Source}/Core/RectangleGeometryLibrary.js | 0 .../Source}/Core/RectangleOutlineGeometry.js | 0 .../engine/Source}/Core/ReferenceFrame.js | 0 .../engine/Source}/Core/Request.js | 0 .../engine/Source}/Core/RequestErrorEvent.js | 0 .../engine/Source}/Core/RequestScheduler.js | 0 .../engine/Source}/Core/RequestState.js | 0 .../engine/Source}/Core/RequestType.js | 0 .../engine/Source}/Core/Resource.js | 0 .../engine/Source}/Core/RuntimeError.js | 0 .../engine/Source}/Core/S2Cell.js | 0 .../Source}/Core/ScreenSpaceEventHandler.js | 0 .../Source}/Core/ScreenSpaceEventType.js | 0 .../Core/ShowGeometryInstanceAttribute.js | 0 .../Core/Simon1994PlanetaryPositions.js | 0 .../Source}/Core/SimplePolylineGeometry.js | 0 .../engine/Source}/Core/SphereGeometry.js | 0 .../Source}/Core/SphereOutlineGeometry.js | 0 .../engine/Source}/Core/Spherical.js | 0 .../engine/Source}/Core/Spline.js | 0 .../engine/Source}/Core/SteppedSpline.js | 0 .../engine/Source}/Core/TaskProcessor.js | 0 .../engine/Source}/Core/TerrainData.js | 0 .../engine/Source}/Core/TerrainEncoding.js | 0 .../Source}/Core/TerrainExaggeration.js | 0 .../engine/Source}/Core/TerrainMesh.js | 0 .../engine/Source}/Core/TerrainProvider.js | 0 .../Source}/Core/TerrainQuantization.js | 0 .../engine/Source}/Core/TileAvailability.js | 0 .../engine/Source}/Core/TileEdge.js | 0 .../engine/Source}/Core/TileProviderError.js | 0 .../engine/Source}/Core/TilingScheme.js | 0 .../engine/Source}/Core/TimeConstants.js | 0 .../engine/Source}/Core/TimeInterval.js | 0 .../Source}/Core/TimeIntervalCollection.js | 0 .../engine/Source}/Core/TimeStandard.js | 0 .../engine/Source}/Core/Tipsify.js | 0 .../engine/Source}/Core/Transforms.js | 0 .../Source}/Core/TranslationRotationScale.js | 0 .../Source}/Core/TridiagonalSystemSolver.js | 0 .../engine/Source}/Core/TrustedServers.js | 0 .../Source}/Core/VRTheWorldTerrainProvider.js | 0 .../engine/Source}/Core/VertexFormat.js | 0 .../engine/Source}/Core/VideoSynchronizer.js | 0 .../engine/Source}/Core/Visibility.js | 0 .../engine/Source}/Core/VulkanConstants.js | 0 .../engine/Source}/Core/WallGeometry.js | 0 .../Source}/Core/WallGeometryLibrary.js | 0 .../Source}/Core/WallOutlineGeometry.js | 0 .../engine/Source}/Core/WebGLConstants.js | 0 .../Source}/Core/WebMercatorProjection.js | 0 .../Source}/Core/WebMercatorTilingScheme.js | 0 .../engine/Source}/Core/WindingOrder.js | 0 .../Source}/Core/WireframeIndexGenerator.js | 0 .../engine/Source}/Core/appendForwardSlash.js | 0 .../Source}/Core/arrayRemoveDuplicates.js | 0 .../Source}/Core/barycentricCoordinates.js | 0 .../engine/Source}/Core/binarySearch.js | 0 .../engine/Source}/Core/buildModuleUrl.js | 0 .../Source/Core/cancelAnimationFrame.js | 53 + .../engine/Source}/Core/clone.js | 0 .../engine/Source}/Core/combine.js | 0 .../engine/Source}/Core/createGuid.js | 0 .../engine/Source}/Core/createWorldTerrain.js | 0 .../Core/decodeGoogleEarthEnterpriseData.js | 0 .../Core/decodeVectorPolylinePositions.js | 0 .../engine/Source}/Core/defaultValue.js | 0 .../engine/Source}/Core/defer.js | 0 .../engine/Source}/Core/defined.js | 0 .../engine/Source}/Core/deprecationWarning.js | 0 .../engine/Source}/Core/destroyObject.js | 0 .../engine/Source}/Core/formatError.js | 0 .../engine/Source}/Core/getAbsoluteUri.js | 0 .../engine/Source}/Core/getBaseUri.js | 0 .../Source}/Core/getExtensionFromUri.js | 0 .../engine/Source}/Core/getFilenameFromUri.js | 0 .../Source}/Core/getImageFromTypedArray.js | 0 .../engine/Source}/Core/getImagePixels.js | 0 .../Source}/Core/getJsonFromTypedArray.js | 0 .../engine/Source}/Core/getMagic.js | 0 .../Source}/Core/getStringFromTypedArray.js | 0 .../engine/Source}/Core/getTimestamp.js | 0 .../engine/Source}/Core/isBitSet.js | 0 .../engine/Source}/Core/isBlobUri.js | 0 .../engine/Source}/Core/isCrossOriginUrl.js | 0 .../engine/Source}/Core/isDataUri.js | 0 .../engine/Source}/Core/isLeapYear.js | 0 .../Source}/Core/loadAndExecuteScript.js | 0 .../Source}/Core/loadImageFromTypedArray.js | 0 .../engine/Source}/Core/loadKTX2.js | 0 .../engine/Source}/Core/mergeSort.js | 0 .../engine/Source}/Core/objectToQuery.js | 0 .../engine/Source}/Core/oneTimeWarning.js | 0 .../Source}/Core/parseResponseHeaders.js | 0 .../Source}/Core/pointInsideTriangle.js | 0 .../engine/Source}/Core/queryToObject.js | 0 .../Source/Core/requestAnimationFrame.js | 83 ++ .../Core/resizeImageToNextPowerOfTwo.js | 0 .../engine/Source}/Core/sampleTerrain.js | 0 .../Source}/Core/sampleTerrainMostDetailed.js | 0 .../Source}/Core/scaleToGeodeticSurface.js | 0 .../engine/Source}/Core/subdivideArray.js | 0 .../Source}/Core/webGLConstantToGlslType.js | 0 .../engine/Source}/Core/wrapFunction.js | 0 .../engine/Source}/Core/writeTextToCanvas.js | 0 .../Source}/DataSources/BillboardGraphics.js | 0 .../DataSources/BillboardVisualizer.js | 0 .../DataSources/BoundingSphereState.js | 0 .../Source}/DataSources/BoxGeometryUpdater.js | 0 .../engine/Source}/DataSources/BoxGraphics.js | 0 .../Source}/DataSources/CallbackProperty.js | 0 .../DataSources/Cesium3DTilesetGraphics.js | 0 .../DataSources/Cesium3DTilesetVisualizer.js | 0 .../CheckerboardMaterialProperty.js | 0 .../DataSources/ColorMaterialProperty.js | 0 .../DataSources/CompositeEntityCollection.js | 0 .../DataSources/CompositeMaterialProperty.js | 0 .../DataSources/CompositePositionProperty.js | 0 .../Source}/DataSources/CompositeProperty.js | 0 .../DataSources/ConstantPositionProperty.js | 0 .../Source}/DataSources/ConstantProperty.js | 0 .../DataSources/CorridorGeometryUpdater.js | 0 .../Source}/DataSources/CorridorGraphics.js | 0 .../Source}/DataSources/CustomDataSource.js | 0 .../DataSources/CylinderGeometryUpdater.js | 0 .../Source}/DataSources/CylinderGraphics.js | 0 .../Source}/DataSources/CzmlDataSource.js | 0 .../engine/Source}/DataSources/DataSource.js | 0 .../Source}/DataSources/DataSourceClock.js | 0 .../DataSources/DataSourceCollection.js | 0 .../Source}/DataSources/DataSourceDisplay.js | 0 .../DataSources/DynamicGeometryBatch.js | 0 .../DataSources/DynamicGeometryUpdater.js | 0 .../DataSources/EllipseGeometryUpdater.js | 0 .../Source}/DataSources/EllipseGraphics.js | 0 .../DataSources/EllipsoidGeometryUpdater.js | 0 .../Source}/DataSources/EllipsoidGraphics.js | 0 .../engine/Source}/DataSources/Entity.js | 0 .../Source}/DataSources/EntityCluster.js | 0 .../Source}/DataSources/EntityCollection.js | 0 .../engine/Source}/DataSources/EntityView.js | 0 .../Source}/DataSources/GeoJsonDataSource.js | 0 .../Source}/DataSources/GeometryUpdater.js | 0 .../Source}/DataSources/GeometryVisualizer.js | 0 .../Source}/DataSources/GpxDataSource.js | 0 .../DataSources/GridMaterialProperty.js | 0 .../DataSources/GroundGeometryUpdater.js | 0 .../DataSources/ImageMaterialProperty.js | 0 .../engine/Source}/DataSources/KmlCamera.js | 0 .../Source}/DataSources/KmlDataSource.js | 2 +- .../engine/Source}/DataSources/KmlLookAt.js | 0 .../engine/Source}/DataSources/KmlTour.js | 0 .../Source}/DataSources/KmlTourFlyTo.js | 0 .../engine/Source}/DataSources/KmlTourWait.js | 0 .../Source}/DataSources/LabelGraphics.js | 0 .../Source}/DataSources/LabelVisualizer.js | 0 .../Source}/DataSources/MaterialProperty.js | 0 .../Source}/DataSources/ModelGraphics.js | 0 .../Source}/DataSources/ModelVisualizer.js | 0 .../DataSources/NodeTransformationProperty.js | 0 .../Source}/DataSources/PathGraphics.js | 0 .../Source}/DataSources/PathVisualizer.js | 0 .../DataSources/PlaneGeometryUpdater.js | 0 .../Source}/DataSources/PlaneGraphics.js | 0 .../Source}/DataSources/PointGraphics.js | 0 .../Source}/DataSources/PointVisualizer.js | 0 .../DataSources/PolygonGeometryUpdater.js | 0 .../Source}/DataSources/PolygonGraphics.js | 0 .../PolylineArrowMaterialProperty.js | 0 .../PolylineDashMaterialProperty.js | 0 .../DataSources/PolylineGeometryUpdater.js | 0 .../PolylineGlowMaterialProperty.js | 0 .../Source}/DataSources/PolylineGraphics.js | 0 .../PolylineOutlineMaterialProperty.js | 0 .../Source}/DataSources/PolylineVisualizer.js | 0 .../PolylineVolumeGeometryUpdater.js | 0 .../DataSources/PolylineVolumeGraphics.js | 0 .../Source}/DataSources/PositionProperty.js | 0 .../DataSources/PositionPropertyArray.js | 0 .../engine/Source}/DataSources/Property.js | 0 .../Source}/DataSources/PropertyArray.js | 0 .../engine/Source}/DataSources/PropertyBag.js | 0 .../DataSources/RectangleGeometryUpdater.js | 0 .../Source}/DataSources/RectangleGraphics.js | 0 .../Source}/DataSources/ReferenceProperty.js | 0 .../engine/Source}/DataSources/Rotation.js | 0 .../DataSources/SampledPositionProperty.js | 0 .../Source}/DataSources/SampledProperty.js | 0 .../DataSources/ScaledPositionProperty.js | 0 .../DataSources/StaticGeometryColorBatch.js | 0 .../StaticGeometryPerMaterialBatch.js | 0 .../StaticGroundGeometryColorBatch.js | 0 .../StaticGroundGeometryPerMaterialBatch.js | 0 .../StaticGroundPolylinePerMaterialBatch.js | 0 .../DataSources/StaticOutlineGeometryBatch.js | 0 .../DataSources/StripeMaterialProperty.js | 0 .../Source}/DataSources/StripeOrientation.js | 0 .../DataSources/TerrainOffsetProperty.js | 0 .../TimeIntervalCollectionPositionProperty.js | 0 .../TimeIntervalCollectionProperty.js | 0 .../VelocityOrientationProperty.js | 0 .../DataSources/VelocityVectorProperty.js | 0 .../engine/Source}/DataSources/Visualizer.js | 0 .../DataSources/WallGeometryUpdater.js | 0 .../Source}/DataSources/WallGraphics.js | 0 .../createMaterialPropertyDescriptor.js | 0 .../DataSources/createPropertyDescriptor.js | 0 .../createRawPropertyDescriptor.js | 0 .../engine/Source}/DataSources/exportKml.js | 0 .../engine/Source/DataSources}/getElement.js | 0 .../heightReferenceOnEntityPropertyChanged.js | 0 .../Source}/Renderer/AutomaticUniforms.js | 0 .../engine/Source}/Renderer/Buffer.js | 0 .../engine/Source}/Renderer/BufferUsage.js | 0 .../engine/Source}/Renderer/ClearCommand.js | 0 .../engine/Source}/Renderer/ComputeCommand.js | 0 .../engine/Source}/Renderer/ComputeEngine.js | 0 .../engine/Source}/Renderer/Context.js | 0 .../engine/Source}/Renderer/ContextLimits.js | 0 .../engine/Source}/Renderer/CubeMap.js | 0 .../engine/Source}/Renderer/CubeMapFace.js | 0 .../engine/Source}/Renderer/DrawCommand.js | 0 .../engine/Source}/Renderer/Framebuffer.js | 0 .../Source}/Renderer/FramebufferManager.js | 0 .../engine/Source}/Renderer/MipmapHint.js | 0 .../Renderer/MultisampleFramebuffer.js | 0 .../engine/Source}/Renderer/Pass.js | 0 .../engine/Source}/Renderer/PassState.js | 0 .../engine/Source}/Renderer/PixelDatatype.js | 0 .../engine/Source}/Renderer/RenderState.js | 0 .../engine/Source}/Renderer/Renderbuffer.js | 0 .../Source}/Renderer/RenderbufferFormat.js | 0 .../engine/Source}/Renderer/Sampler.js | 0 .../engine/Source}/Renderer/ShaderBuilder.js | 0 .../engine/Source}/Renderer/ShaderCache.js | 0 .../Source}/Renderer/ShaderDestination.js | 0 .../engine/Source}/Renderer/ShaderFunction.js | 0 .../engine/Source}/Renderer/ShaderProgram.js | 0 .../engine/Source}/Renderer/ShaderSource.js | 0 .../engine/Source}/Renderer/ShaderStruct.js | 0 .../engine/Source}/Renderer/Texture.js | 0 .../engine/Source}/Renderer/TextureCache.js | 0 .../Renderer/TextureMagnificationFilter.js | 0 .../Renderer/TextureMinificationFilter.js | 0 .../engine/Source}/Renderer/TextureWrap.js | 0 .../engine/Source}/Renderer/UniformState.js | 0 .../engine/Source}/Renderer/VertexArray.js | 0 .../Source}/Renderer/VertexArrayFacade.js | 0 .../engine/Source}/Renderer/createUniform.js | 0 .../Source}/Renderer/createUniformArray.js | 0 .../Source}/Renderer/freezeRenderState.js | 0 .../engine/Source}/Renderer/loadCubeMap.js | 0 .../Source}/Renderer/modernizeShader.js | 0 .../engine/Source}/Scene/AlphaMode.js | 0 .../engine/Source}/Scene/Appearance.js | 0 .../Scene/ArcGisMapServerImageryProvider.js | 0 .../engine/Source}/Scene/AttributeType.js | 0 .../engine/Source}/Scene/AutoExposure.js | 0 .../engine/Source}/Scene/Axis.js | 0 .../engine/Source}/Scene/B3dmParser.js | 0 .../engine/Source}/Scene/BatchTable.js | 0 .../Source}/Scene/BatchTableHierarchy.js | 0 .../engine/Source}/Scene/BatchTexture.js | 0 .../engine/Source}/Scene/Billboard.js | 0 .../Source}/Scene/BillboardCollection.js | 0 .../Source}/Scene/BingMapsImageryProvider.js | 0 .../engine/Source}/Scene/BingMapsStyle.js | 0 .../engine/Source}/Scene/BlendEquation.js | 0 .../engine/Source}/Scene/BlendFunction.js | 0 .../engine/Source}/Scene/BlendOption.js | 0 .../engine/Source}/Scene/BlendingState.js | 0 .../engine/Source}/Scene/BoxEmitter.js | 0 .../engine/Source}/Scene/BrdfLutGenerator.js | 0 .../engine/Source}/Scene/BufferLoader.js | 0 .../engine/Source}/Scene/Camera.js | 0 .../Source}/Scene/CameraEventAggregator.js | 0 .../engine/Source}/Scene/CameraEventType.js | 0 .../engine/Source}/Scene/CameraFlightPath.js | 0 .../Source}/Scene/Cesium3DContentGroup.js | 0 .../engine/Source}/Scene/Cesium3DTile.js | 0 .../Source}/Scene/Cesium3DTileBatchTable.js | 0 .../Scene/Cesium3DTileColorBlendMode.js | 0 .../Source}/Scene/Cesium3DTileContent.js | 0 .../Scene/Cesium3DTileContentFactory.js | 0 .../Source}/Scene/Cesium3DTileContentState.js | 0 .../Source}/Scene/Cesium3DTileContentType.js | 0 .../Source}/Scene/Cesium3DTileFeature.js | 0 .../Source}/Scene/Cesium3DTileFeatureTable.js | 0 .../Scene/Cesium3DTileOptimizationHint.js | 0 .../Scene/Cesium3DTileOptimizations.js | 0 .../engine/Source}/Scene/Cesium3DTilePass.js | 0 .../Source}/Scene/Cesium3DTilePassState.js | 0 .../Source}/Scene/Cesium3DTilePointFeature.js | 0 .../Source}/Scene/Cesium3DTileRefine.js | 0 .../engine/Source}/Scene/Cesium3DTileStyle.js | 0 .../Source}/Scene/Cesium3DTileStyleEngine.js | 0 .../engine/Source}/Scene/Cesium3DTileset.js | 0 .../Source}/Scene/Cesium3DTilesetCache.js | 0 .../Source}/Scene/Cesium3DTilesetHeatmap.js | 0 .../Source}/Scene/Cesium3DTilesetMetadata.js | 0 .../Cesium3DTilesetMostDetailedTraversal.js | 0 .../Scene/Cesium3DTilesetStatistics.js | 0 .../Source}/Scene/Cesium3DTilesetTraversal.js | 0 .../engine/Source}/Scene/CircleEmitter.js | 0 .../Source}/Scene/ClassificationPrimitive.js | 0 .../Source}/Scene/ClassificationType.js | 0 .../engine/Source}/Scene/ClippingPlane.js | 0 .../Source}/Scene/ClippingPlaneCollection.js | 0 .../engine/Source}/Scene/CloudCollection.js | 0 .../engine/Source}/Scene/CloudType.js | 0 .../engine/Source}/Scene/ColorBlendMode.js | 0 .../Source}/Scene/Composite3DTileContent.js | 0 .../Source}/Scene/ConditionsExpression.js | 0 .../engine/Source}/Scene/ConeEmitter.js | 0 .../engine/Source}/Scene/ContentMetadata.js | 0 .../engine/Source}/Scene/CreditDisplay.js | 0 .../engine/Source}/Scene/CullFace.js | 0 .../engine/Source}/Scene/CumulusCloud.js | 0 .../engine/Source}/Scene/DebugAppearance.js | 0 .../Source}/Scene/DebugCameraPrimitive.js | 0 .../engine/Source}/Scene/DebugInspector.js | 0 .../Scene/DebugModelMatrixPrimitive.js | 0 .../engine/Source}/Scene/DepthFunction.js | 0 .../engine/Source}/Scene/DepthPlane.js | 0 .../engine/Source}/Scene/DerivedCommand.js | 0 .../DeviceOrientationCameraController.js | 0 .../engine/Source}/Scene/DirectionalLight.js | 0 .../Scene/DiscardEmptyTileImagePolicy.js | 0 .../Scene/DiscardMissingTileImagePolicy.js | 0 .../engine/Source}/Scene/DracoLoader.js | 0 .../Source}/Scene/EllipsoidPrimitive.js | 0 .../Scene/EllipsoidSurfaceAppearance.js | 0 .../Source}/Scene/Empty3DTileContent.js | 0 .../engine/Source}/Scene/Expression.js | 0 .../Source}/Scene/ExpressionNodeType.js | 0 .../engine/Source}/Scene/Fog.js | 0 .../engine/Source}/Scene/FrameRateMonitor.js | 0 .../engine/Source}/Scene/FrameState.js | 0 .../engine/Source}/Scene/FrustumCommands.js | 0 .../Source}/Scene/Geometry3DTileContent.js | 0 .../Source}/Scene/GetFeatureInfoFormat.js | 0 .../engine/Source}/Scene/Globe.js | 0 .../engine/Source}/Scene/GlobeDepth.js | 0 .../Source}/Scene/GlobeSurfaceShaderSet.js | 0 .../engine/Source}/Scene/GlobeSurfaceTile.js | 0 .../Source}/Scene/GlobeSurfaceTileProvider.js | 0 .../engine/Source}/Scene/GlobeTranslucency.js | 0 .../Scene/GlobeTranslucencyFramebuffer.js | 0 .../Source}/Scene/GlobeTranslucencyState.js | 0 .../Source}/Scene/GltfBufferViewLoader.js | 0 .../engine/Source}/Scene/GltfDracoLoader.js | 0 .../engine/Source}/Scene/GltfImageLoader.js | 0 .../Source}/Scene/GltfIndexBufferLoader.js | 0 .../engine/Source}/Scene/GltfJsonLoader.js | 0 .../engine/Source}/Scene/GltfLoader.js | 0 .../engine/Source}/Scene/GltfLoaderUtil.js | 0 .../Source}/Scene/GltfPipeline/ForEach.js | 0 .../Source}/Scene/GltfPipeline/addBuffer.js | 0 .../Source}/Scene/GltfPipeline/addDefaults.js | 0 .../GltfPipeline/addExtensionsRequired.js | 0 .../Scene/GltfPipeline/addExtensionsUsed.js | 0 .../Scene/GltfPipeline/addPipelineExtras.js | 0 .../Source}/Scene/GltfPipeline/addToArray.js | 0 .../Scene/GltfPipeline/findAccessorMinMax.js | 0 .../GltfPipeline/forEachTextureInMaterial.js | 0 .../GltfPipeline/getAccessorByteStride.js | 0 .../Scene/GltfPipeline/getComponentReader.js | 0 .../GltfPipeline/moveTechniqueRenderStates.js | 0 .../GltfPipeline/moveTechniquesToExtension.js | 0 .../GltfPipeline/numberOfComponentsForType.js | 0 .../Source}/Scene/GltfPipeline/parseGlb.js | 0 .../Scene/GltfPipeline/readAccessorPacked.js | 0 .../Scene/GltfPipeline/removeExtension.js | 0 .../GltfPipeline/removeExtensionsRequired.js | 0 .../GltfPipeline/removeExtensionsUsed.js | 0 .../GltfPipeline/removePipelineExtras.js | 0 .../GltfPipeline/removeUnusedElements.js | 0 .../updateAccessorComponentTypes.js | 0 .../Scene/GltfPipeline/updateVersion.js | 0 .../Scene/GltfPipeline/usesExtension.js | 0 .../Scene/GltfStructuralMetadataLoader.js | 0 .../engine/Source}/Scene/GltfTextureLoader.js | 0 .../Source}/Scene/GltfVertexBufferLoader.js | 0 .../GoogleEarthEnterpriseImageryProvider.js | 0 .../GoogleEarthEnterpriseMapsProvider.js | 0 .../Source}/Scene/GridImageryProvider.js | 0 .../Source}/Scene/GroundPolylinePrimitive.js | 0 .../engine/Source}/Scene/GroundPrimitive.js | 0 .../engine/Source}/Scene/GroupMetadata.js | 0 .../engine/Source}/Scene/HeightReference.js | 0 .../engine/Source}/Scene/HorizontalOrigin.js | 0 .../engine/Source}/Scene/I3SDataProvider.js | 0 .../engine/Source}/Scene/I3SFeature.js | 0 .../engine/Source}/Scene/I3SField.js | 0 .../engine/Source}/Scene/I3SGeometry.js | 0 .../engine/Source}/Scene/I3SLayer.js | 0 .../engine/Source}/Scene/I3SNode.js | 0 .../engine/Source}/Scene/I3dmParser.js | 0 .../Source}/Scene/ImageBasedLighting.js | 0 .../engine/Source}/Scene/Imagery.js | 0 .../engine/Source}/Scene/ImageryLayer.js | 0 .../Source}/Scene/ImageryLayerCollection.js | 0 .../Source}/Scene/ImageryLayerFeatureInfo.js | 0 .../engine/Source}/Scene/ImageryProvider.js | 0 .../engine/Source}/Scene/ImageryState.js | 0 .../Source}/Scene/Implicit3DTileContent.js | 0 .../Scene/ImplicitAvailabilityBitstream.js | 0 .../Source}/Scene/ImplicitMetadataView.js | 0 .../Scene/ImplicitSubdivisionScheme.js | 0 .../engine/Source}/Scene/ImplicitSubtree.js | 0 .../Source}/Scene/ImplicitSubtreeMetadata.js | 0 .../Source}/Scene/ImplicitTileCoordinates.js | 0 .../engine/Source}/Scene/ImplicitTileset.js | 0 .../Scene/InstanceAttributeSemantic.js | 0 .../Source}/Scene/InvertClassification.js | 0 .../Source}/Scene/IonImageryProvider.js | 0 .../Source}/Scene/IonWorldImageryStyle.js | 0 .../engine/Source}/Scene/JobScheduler.js | 0 .../engine/Source}/Scene/JobType.js | 0 .../engine/Source}/Scene/JsonMetadataTable.js | 0 .../engine/Source}/Scene/Label.js | 0 .../engine/Source}/Scene/LabelCollection.js | 0 .../engine/Source}/Scene/LabelStyle.js | 0 .../engine/Source}/Scene/Light.js | 0 .../engine/Source}/Scene/MapMode2D.js | 0 .../Source}/Scene/MapboxImageryProvider.js | 0 .../Scene/MapboxStyleImageryProvider.js | 0 .../engine/Source}/Scene/Material.js | 0 .../Source}/Scene/MaterialAppearance.js | 0 .../engine/Source}/Scene/MetadataClass.js | 0 .../Source}/Scene/MetadataClassProperty.js | 0 .../Source}/Scene/MetadataComponentType.js | 0 .../engine/Source}/Scene/MetadataEntity.js | 0 .../engine/Source}/Scene/MetadataEnum.js | 0 .../engine/Source}/Scene/MetadataEnumValue.js | 0 .../engine/Source}/Scene/MetadataSchema.js | 0 .../Source}/Scene/MetadataSchemaLoader.js | 0 .../engine/Source}/Scene/MetadataSemantic.js | 0 .../engine/Source}/Scene/MetadataTable.js | 0 .../Source}/Scene/MetadataTableProperty.js | 0 .../engine/Source}/Scene/MetadataType.js | 0 .../Source}/Scene/Model/AlphaPipelineStage.js | 0 .../engine/Source}/Scene/Model/B3dmLoader.js | 0 .../Scene/Model/BatchTexturePipelineStage.js | 0 .../Scene/Model/CPUStylingPipelineStage.js | 0 .../Model/ClassificationModelDrawCommand.js | 0 .../Model/ClassificationPipelineStage.js | 0 .../Source}/Scene/Model/CustomShader.js | 0 .../Source}/Scene/Model/CustomShaderMode.js | 0 .../Scene/Model/CustomShaderPipelineStage.js | 0 .../Model/CustomShaderTranslucencyMode.js | 0 .../Model/DequantizationPipelineStage.js | 0 .../Scene/Model/FeatureIdPipelineStage.js | 0 .../Source}/Scene/Model/GeoJsonLoader.js | 0 .../Scene/Model/GeometryPipelineStage.js | 0 .../engine/Source}/Scene/Model/I3dmLoader.js | 0 .../Model/ImageBasedLightingPipelineStage.js | 0 .../Scene/Model/InstancingPipelineStage.js | 0 .../Source}/Scene/Model/LightingModel.js | 0 .../Scene/Model/LightingPipelineStage.js | 0 .../Scene/Model/MaterialPipelineStage.js | 0 .../Scene/Model/MetadataPipelineStage.js | 0 .../engine/Source}/Scene/Model/Model.js | 0 .../Source}/Scene/Model/Model3DTileContent.js | 0 .../Source}/Scene/Model/ModelAlphaOptions.js | 0 .../Source}/Scene/Model/ModelAnimation.js | 0 .../Scene/Model/ModelAnimationChannel.js | 0 .../Scene/Model/ModelAnimationCollection.js | 0 .../Source}/Scene/Model/ModelArticulation.js | 0 .../Scene/Model/ModelArticulationStage.js | 0 .../Model/ModelClippingPlanesPipelineStage.js | 0 .../Scene/Model/ModelColorPipelineStage.js | 0 .../Source}/Scene/Model/ModelDrawCommand.js | 0 .../Source}/Scene/Model/ModelFeature.js | 0 .../Source}/Scene/Model/ModelFeatureTable.js | 0 .../Scene/Model/ModelLightingOptions.js | 0 .../Scene/Model/ModelMatrixUpdateStage.js | 0 .../engine/Source}/Scene/Model/ModelNode.js | 0 .../Scene/Model/ModelRenderResources.js | 0 .../Source}/Scene/Model/ModelRuntimeNode.js | 0 .../Scene/Model/ModelRuntimePrimitive.js | 0 .../Source}/Scene/Model/ModelSceneGraph.js | 0 .../Model/ModelSilhouettePipelineStage.js | 0 .../engine/Source}/Scene/Model/ModelSkin.js | 0 .../Scene/Model/ModelSplitterPipelineStage.js | 0 .../Source}/Scene/Model/ModelStatistics.js | 0 .../engine/Source}/Scene/Model/ModelType.js | 0 .../Source}/Scene/Model/ModelUtility.js | 0 .../Scene/Model/MorphTargetsPipelineStage.js | 0 .../Scene/Model/NodeRenderResources.js | 0 .../Model/NodeStatisticsPipelineStage.js | 0 .../Scene/Model/PickingPipelineStage.js | 0 .../engine/Source}/Scene/Model/PntsLoader.js | 0 .../Model/PointCloudStylingPipelineStage.js | 0 .../Scene/Model/PrimitiveOutlineGenerator.js | 0 .../Model/PrimitiveOutlinePipelineStage.js | 0 .../Scene/Model/PrimitiveRenderResources.js | 0 .../Model/PrimitiveStatisticsPipelineStage.js | 0 .../Scene/Model/SceneMode2DPipelineStage.js | 0 .../Model/SelectedFeatureIdPipelineStage.js | 0 .../Scene/Model/SkinningPipelineStage.js | 0 .../Scene/Model/StyleCommandsNeeded.js | 0 .../Source}/Scene/Model/TextureManager.js | 0 .../Source}/Scene/Model/TextureUniform.js | 0 .../Scene/Model/TilesetPipelineStage.js | 0 .../engine/Source}/Scene/Model/UniformType.js | 0 .../engine/Source}/Scene/Model/VaryingType.js | 0 .../Scene/Model/WireframePipelineStage.js | 0 .../Source}/Scene/Model/buildDrawCommand.js | 0 .../Source}/Scene/ModelAnimationLoop.js | 0 .../Source}/Scene/ModelAnimationState.js | 0 .../engine/Source}/Scene/ModelComponents.js | 0 .../engine/Source}/Scene/Moon.js | 0 .../Source}/Scene/Multiple3DTileContent.js | 0 .../Source}/Scene/NeverTileDiscardPolicy.js | 0 .../engine/Source}/Scene/OIT.js | 0 .../Scene/OctahedralProjectedCubeMap.js | 0 .../Scene/OpenStreetMapImageryProvider.js | 0 .../Scene/OrderedGroundPrimitiveCollection.js | 0 .../engine/Source}/Scene/Particle.js | 0 .../engine/Source}/Scene/ParticleBurst.js | 0 .../engine/Source}/Scene/ParticleEmitter.js | 0 .../engine/Source}/Scene/ParticleSystem.js | 0 .../Scene/PerInstanceColorAppearance.js | 0 .../Source}/Scene/PerformanceDisplay.js | 2 +- .../engine/Source}/Scene/PickDepth.js | 0 .../Source}/Scene/PickDepthFramebuffer.js | 0 .../engine/Source}/Scene/PickFramebuffer.js | 0 .../engine/Source}/Scene/Picking.js | 0 .../engine/Source}/Scene/PntsParser.js | 0 .../engine/Source}/Scene/PointCloud.js | 0 .../Scene/PointCloudEyeDomeLighting.js | 0 .../engine/Source}/Scene/PointCloudShading.js | 0 .../engine/Source}/Scene/PointPrimitive.js | 0 .../Source}/Scene/PointPrimitiveCollection.js | 0 .../engine/Source}/Scene/Polyline.js | 0 .../Source}/Scene/PolylineCollection.js | 0 .../Source}/Scene/PolylineColorAppearance.js | 0 .../Scene/PolylineMaterialAppearance.js | 0 .../engine/Source}/Scene/PostProcessStage.js | 0 .../Scene/PostProcessStageCollection.js | 0 .../Scene/PostProcessStageComposite.js | 0 .../Source}/Scene/PostProcessStageLibrary.js | 0 .../Scene/PostProcessStageSampleMode.js | 0 .../Scene/PostProcessStageTextureCache.js | 0 .../engine/Source}/Scene/Primitive.js | 0 .../Source}/Scene/PrimitiveCollection.js | 0 .../engine/Source}/Scene/PrimitiveLoadPlan.js | 0 .../engine/Source}/Scene/PrimitivePipeline.js | 0 .../engine/Source}/Scene/PrimitiveState.js | 0 .../engine/Source}/Scene/PropertyAttribute.js | 0 .../Scene/PropertyAttributeProperty.js | 0 .../engine/Source}/Scene/PropertyTable.js | 0 .../engine/Source}/Scene/PropertyTexture.js | 0 .../Source}/Scene/PropertyTextureProperty.js | 0 .../engine/Source}/Scene/QuadtreeOccluders.js | 0 .../engine/Source}/Scene/QuadtreePrimitive.js | 0 .../engine/Source}/Scene/QuadtreeTile.js | 0 .../Source}/Scene/QuadtreeTileLoadState.js | 0 .../Source}/Scene/QuadtreeTileProvider.js | 0 .../engine/Source}/Scene/ResourceCache.js | 0 .../engine/Source}/Scene/ResourceCacheKey.js | 0 .../Source}/Scene/ResourceCacheStatistics.js | 0 .../engine/Source}/Scene/ResourceLoader.js | 0 .../Source}/Scene/ResourceLoaderState.js | 0 .../engine/Source}/Scene/SDFSettings.js | 0 .../engine/Source}/Scene/Scene.js | 2 +- .../engine/Source}/Scene/SceneFramebuffer.js | 0 .../engine/Source}/Scene/SceneMode.js | 0 .../engine/Source}/Scene/SceneTransforms.js | 0 .../engine/Source}/Scene/SceneTransitioner.js | 0 .../Scene/ScreenSpaceCameraController.js | 0 .../engine/Source}/Scene/ShadowMap.js | 0 .../engine/Source}/Scene/ShadowMapShader.js | 0 .../engine/Source}/Scene/ShadowMode.js | 0 .../Source}/Scene/ShadowVolumeAppearance.js | 0 .../Scene/SingleTileImageryProvider.js | 0 .../engine/Source}/Scene/SkyAtmosphere.js | 0 .../engine/Source}/Scene/SkyBox.js | 0 .../engine/Source}/Scene/SphereEmitter.js | 0 .../engine/Source}/Scene/SplitDirection.js | 0 .../engine/Source}/Scene/Splitter.js | 0 .../engine/Source}/Scene/StencilConstants.js | 0 .../engine/Source}/Scene/StencilFunction.js | 0 .../engine/Source}/Scene/StencilOperation.js | 0 .../Source}/Scene/StructuralMetadata.js | 0 .../engine/Source}/Scene/StyleExpression.js | 0 .../engine/Source}/Scene/Sun.js | 0 .../engine/Source}/Scene/SunLight.js | 0 .../engine/Source}/Scene/SunPostProcess.js | 0 .../Source}/Scene/SupportedImageFormats.js | 0 .../engine/Source}/Scene/TerrainFillMesh.js | 0 .../engine/Source}/Scene/TerrainState.js | 0 .../engine/Source}/Scene/TextureAtlas.js | 0 .../Source}/Scene/TileBoundingRegion.js | 0 .../Source}/Scene/TileBoundingS2Cell.js | 0 .../Source}/Scene/TileBoundingSphere.js | 0 .../Source}/Scene/TileBoundingVolume.js | 0 .../Scene/TileCoordinatesImageryProvider.js | 0 .../engine/Source}/Scene/TileDiscardPolicy.js | 0 .../engine/Source}/Scene/TileImagery.js | 0 .../Scene/TileMapServiceImageryProvider.js | 0 .../engine/Source}/Scene/TileMetadata.js | 0 .../Source}/Scene/TileOrientedBoundingBox.js | 0 .../Source}/Scene/TileReplacementQueue.js | 0 .../Source}/Scene/TileSelectionResult.js | 0 .../engine/Source}/Scene/TileState.js | 0 .../Source}/Scene/Tileset3DTileContent.js | 0 .../engine/Source}/Scene/TilesetMetadata.js | 0 .../Source}/Scene/TimeDynamicImagery.js | 0 .../Source}/Scene/TimeDynamicPointCloud.js | 0 .../engine/Source}/Scene/Tonemapper.js | 0 .../Scene/TranslucentTileClassification.js | 0 .../engine/Source}/Scene/TweenCollection.js | 0 .../Scene/UrlTemplateImageryProvider.js | 0 .../engine/Source}/Scene/Vector3DTileBatch.js | 0 .../Scene/Vector3DTileClampedPolylines.js | 0 .../Source}/Scene/Vector3DTileContent.js | 0 .../Source}/Scene/Vector3DTileGeometry.js | 0 .../Source}/Scene/Vector3DTilePoints.js | 0 .../Source}/Scene/Vector3DTilePolygons.js | 0 .../Source}/Scene/Vector3DTilePolylines.js | 0 .../Source}/Scene/Vector3DTilePrimitive.js | 0 .../Source}/Scene/VertexAttributeSemantic.js | 0 .../engine/Source}/Scene/VerticalOrigin.js | 0 .../engine/Source}/Scene/View.js | 0 .../engine/Source}/Scene/ViewportQuad.js | 0 .../Scene/WebMapServiceImageryProvider.js | 0 .../Scene/WebMapTileServiceImageryProvider.js | 0 .../Scene/computeFlyToLocationForRectangle.js | 0 .../Scene/createBillboardPointCallback.js | 0 .../Scene/createElevationBandMaterial.js | 0 .../Source}/Scene/createOsmBuildings.js | 0 .../Scene/createTangentSpaceDebugPrimitive.js | 0 .../Source}/Scene/createWorldImagery.js | 0 .../Source}/Scene/findContentMetadata.js | 0 .../engine/Source}/Scene/findGroupMetadata.js | 0 .../engine/Source}/Scene/findTileMetadata.js | 0 .../engine/Source}/Scene/getBinaryAccessor.js | 0 .../Source}/Scene/getClipAndStyleCode.js | 0 .../Source}/Scene/getClippingFunction.js | 0 .../engine/Source}/Scene/hasExtension.js | 0 .../engine/Source}/Scene/parseBatchTable.js | 0 .../Scene/parseBoundingVolumeSemantics.js | 0 .../Scene/parseFeatureMetadataLegacy.js | 0 .../Source}/Scene/parseStructuralMetadata.js | 0 .../Source}/Scene/preprocess3DTileContent.js | 0 .../Source}/Shaders/AdjustTranslucentFS.glsl | 0 .../Appearances/AllMaterialAppearanceFS.glsl | 0 .../Appearances/AllMaterialAppearanceVS.glsl | 0 .../BasicMaterialAppearanceFS.glsl | 0 .../BasicMaterialAppearanceVS.glsl | 0 .../EllipsoidSurfaceAppearanceFS.glsl | 0 .../EllipsoidSurfaceAppearanceVS.glsl | 0 .../PerInstanceColorAppearanceFS.glsl | 0 .../PerInstanceColorAppearanceVS.glsl | 0 .../PerInstanceFlatColorAppearanceFS.glsl | 0 .../PerInstanceFlatColorAppearanceVS.glsl | 0 .../PolylineColorAppearanceVS.glsl | 0 .../PolylineMaterialAppearanceVS.glsl | 0 .../TexturedMaterialAppearanceFS.glsl | 0 .../TexturedMaterialAppearanceVS.glsl | 0 .../Source}/Shaders/AtmosphereCommon.glsl | 0 .../Shaders/BillboardCollectionFS.glsl | 0 .../Shaders/BillboardCollectionVS.glsl | 0 .../Source}/Shaders/BrdfLutGeneratorFS.glsl | 0 .../Builtin/Constants/degreesPerRadian.glsl | 0 .../Shaders/Builtin/Constants/depthRange.glsl | 0 .../Shaders/Builtin/Constants/epsilon1.glsl | 0 .../Shaders/Builtin/Constants/epsilon2.glsl | 0 .../Shaders/Builtin/Constants/epsilon3.glsl | 0 .../Shaders/Builtin/Constants/epsilon4.glsl | 0 .../Shaders/Builtin/Constants/epsilon5.glsl | 0 .../Shaders/Builtin/Constants/epsilon6.glsl | 0 .../Shaders/Builtin/Constants/epsilon7.glsl | 0 .../Shaders/Builtin/Constants/infinity.glsl | 0 .../Shaders/Builtin/Constants/oneOverPi.glsl | 0 .../Builtin/Constants/oneOverTwoPi.glsl | 0 .../Builtin/Constants/passCesium3DTile.glsl | 0 .../passCesium3DTileClassification.glsl | 0 ...sCesium3DTileClassificationIgnoreShow.glsl | 0 .../Builtin/Constants/passClassification.glsl | 0 .../Builtin/Constants/passCompute.glsl | 0 .../Builtin/Constants/passEnvironment.glsl | 0 .../Shaders/Builtin/Constants/passGlobe.glsl | 0 .../Shaders/Builtin/Constants/passOpaque.glsl | 0 .../Builtin/Constants/passOverlay.glsl | 0 .../Constants/passTerrainClassification.glsl | 0 .../Builtin/Constants/passTranslucent.glsl | 0 .../Source}/Shaders/Builtin/Constants/pi.glsl | 0 .../Shaders/Builtin/Constants/piOverFour.glsl | 0 .../Shaders/Builtin/Constants/piOverSix.glsl | 0 .../Builtin/Constants/piOverThree.glsl | 0 .../Shaders/Builtin/Constants/piOverTwo.glsl | 0 .../Builtin/Constants/radiansPerDegree.glsl | 0 .../Builtin/Constants/sceneMode2D.glsl | 0 .../Builtin/Constants/sceneMode3D.glsl | 0 .../Constants/sceneModeColumbusView.glsl | 0 .../Builtin/Constants/sceneModeMorphing.glsl | 0 .../Builtin/Constants/solarRadius.glsl | 0 .../Builtin/Constants/threePiOver2.glsl | 0 .../Shaders/Builtin/Constants/twoPi.glsl | 0 .../Constants/webMercatorMaxLatitude.glsl | 0 .../Shaders/Builtin/Functions/HSBToRGB.glsl | 0 .../Shaders/Builtin/Functions/HSLToRGB.glsl | 0 .../Shaders/Builtin/Functions/RGBToHSB.glsl | 0 .../Shaders/Builtin/Functions/RGBToHSL.glsl | 0 .../Shaders/Builtin/Functions/RGBToXYZ.glsl | 0 .../Shaders/Builtin/Functions/XYZToRGB.glsl | 0 .../Builtin/Functions/acesTonemapping.glsl | 0 .../Builtin/Functions/alphaWeight.glsl | 0 .../Shaders/Builtin/Functions/antialias.glsl | 0 .../approximateSphericalCoordinates.glsl | 0 .../Shaders/Builtin/Functions/backFacing.glsl | 0 .../Builtin/Functions/branchFreeTernary.glsl | 0 .../Builtin/Functions/cascadeColor.glsl | 0 .../Builtin/Functions/cascadeDistance.glsl | 0 .../Builtin/Functions/cascadeMatrix.glsl | 0 .../Builtin/Functions/cascadeWeights.glsl | 0 .../Builtin/Functions/columbusViewMorph.glsl | 0 .../Builtin/Functions/computePosition.glsl | 0 .../Builtin/Functions/cosineAndSine.glsl | 0 .../decompressTextureCoordinates.glsl | 0 .../Builtin/Functions/defaultPbrMaterial.glsl | 0 .../Shaders/Builtin/Functions/depthClamp.glsl | 0 .../eastNorthUpToEyeCoordinates.glsl | 0 .../Functions/ellipsoidContainsPoint.glsl | 0 .../ellipsoidWgs84TextureCoordinates.glsl | 0 .../Builtin/Functions/equalsEpsilon.glsl | 0 .../Shaders/Builtin/Functions/eyeOffset.glsl | 0 .../Functions/eyeToWindowCoordinates.glsl | 0 .../Functions/fastApproximateAtan.glsl | 0 .../Shaders/Builtin/Functions/fog.glsl | 0 .../Builtin/Functions/gammaCorrect.glsl | 0 .../Functions/geodeticSurfaceNormal.glsl | 0 .../Builtin/Functions/getDefaultMaterial.glsl | 0 .../Builtin/Functions/getLambertDiffuse.glsl | 0 .../Builtin/Functions/getSpecular.glsl | 0 .../Builtin/Functions/getWaterNoise.glsl | 0 .../Shaders/Builtin/Functions/hue.glsl | 0 .../Builtin/Functions/inverseGamma.glsl | 0 .../Shaders/Builtin/Functions/isEmpty.glsl | 0 .../Shaders/Builtin/Functions/isFull.glsl | 0 .../latitudeToWebMercatorFraction.glsl | 0 .../Builtin/Functions/lineDistance.glsl | 0 .../Builtin/Functions/linearToSrgb.glsl | 0 .../Shaders/Builtin/Functions/luminance.glsl | 0 .../Builtin/Functions/metersPerPixel.glsl | 0 .../Functions/modelToWindowCoordinates.glsl | 0 .../Functions/multiplyWithColorBalance.glsl | 0 .../Builtin/Functions/nearFarScalar.glsl | 0 .../Shaders/Builtin/Functions/octDecode.glsl | 0 .../Shaders/Builtin/Functions/packDepth.glsl | 0 .../Builtin/Functions/pbrLighting.glsl | 0 .../pbrMetallicRoughnessMaterial.glsl | 0 .../pbrSpecularGlossinessMaterial.glsl | 0 .../Shaders/Builtin/Functions/phong.glsl | 0 .../Builtin/Functions/planeDistance.glsl | 0 .../Builtin/Functions/pointAlongRay.glsl | 0 .../rayEllipsoidIntersectionInterval.glsl | 0 .../raySphereIntersectionInterval.glsl | 0 .../Shaders/Builtin/Functions/readDepth.glsl | 0 .../Builtin/Functions/readNonPerspective.glsl | 0 .../Builtin/Functions/reverseLogDepth.glsl | 0 .../Shaders/Builtin/Functions/round.glsl | 0 .../Functions/sampleOctahedralProjection.glsl | 0 .../Shaders/Builtin/Functions/saturation.glsl | 0 .../Builtin/Functions/shadowDepthCompare.glsl | 0 .../Builtin/Functions/shadowVisibility.glsl | 0 .../Builtin/Functions/signNotZero.glsl | 0 .../Builtin/Functions/sphericalHarmonics.glsl | 0 .../Builtin/Functions/srgbToLinear.glsl | 0 .../Functions/tangentToEyeSpaceMatrix.glsl | 0 .../Builtin/Functions/transformPlane.glsl | 0 .../Functions/translateRelativeToEye.glsl | 0 .../Builtin/Functions/translucentPhong.glsl | 0 .../Shaders/Builtin/Functions/transpose.glsl | 0 .../Builtin/Functions/unpackDepth.glsl | 0 .../Builtin/Functions/unpackFloat.glsl | 0 .../Shaders/Builtin/Functions/unpackUint.glsl | 0 .../Builtin/Functions/valueTransform.glsl | 0 .../Builtin/Functions/vertexLogDepth.glsl | 0 .../Functions/windowToEyeCoordinates.glsl | 0 .../Builtin/Functions/writeDepthClamp.glsl | 0 .../Builtin/Functions/writeLogDepth.glsl | 0 .../Functions/writeNonPerspective.glsl | 0 .../Builtin/Structs/depthRangeStruct.glsl | 0 .../Shaders/Builtin/Structs/material.glsl | 0 .../Builtin/Structs/materialInput.glsl | 0 .../Builtin/Structs/modelMaterial.glsl | 0 .../Builtin/Structs/modelVertexOutput.glsl | 0 .../Builtin/Structs/pbrParameters.glsl | 0 .../Source}/Shaders/Builtin/Structs/ray.glsl | 0 .../Shaders/Builtin/Structs/raySegment.glsl | 0 .../Builtin/Structs/shadowParameters.glsl | 0 .../Source}/Shaders/CloudCollectionFS.glsl | 0 .../Source}/Shaders/CloudCollectionVS.glsl | 0 .../engine/Source}/Shaders/CloudNoiseFS.glsl | 0 .../engine/Source}/Shaders/CloudNoiseVS.glsl | 0 .../CompareAndPackTranslucentDepth.glsl | 0 .../Source}/Shaders/CompositeOITFS.glsl | 0 .../engine/Source}/Shaders/DepthPlaneFS.glsl | 0 .../engine/Source}/Shaders/DepthPlaneVS.glsl | 0 .../engine/Source}/Shaders/EllipsoidFS.glsl | 0 .../engine/Source}/Shaders/EllipsoidVS.glsl | 0 .../engine/Source}/Shaders/FXAA3_11.glsl | 0 .../engine/Source}/Shaders/GlobeFS.glsl | 0 .../engine/Source}/Shaders/GlobeVS.glsl | 0 .../Source}/Shaders/GroundAtmosphere.glsl | 0 .../Shaders/Materials/AspectRampMaterial.glsl | 0 .../Shaders/Materials/BumpMapMaterial.glsl | 0 .../Materials/CheckerboardMaterial.glsl | 0 .../Shaders/Materials/DotMaterial.glsl | 0 .../Materials/ElevationBandMaterial.glsl | 0 .../Materials/ElevationContourMaterial.glsl | 0 .../Materials/ElevationRampMaterial.glsl | 0 .../Shaders/Materials/FadeMaterial.glsl | 0 .../Shaders/Materials/GridMaterial.glsl | 0 .../Shaders/Materials/NormalMapMaterial.glsl | 0 .../Materials/PolylineArrowMaterial.glsl | 0 .../Materials/PolylineDashMaterial.glsl | 0 .../Materials/PolylineGlowMaterial.glsl | 0 .../Materials/PolylineOutlineMaterial.glsl | 0 .../Materials/RimLightingMaterial.glsl | 0 .../Shaders/Materials/SlopeRampMaterial.glsl | 0 .../Shaders/Materials/StripeMaterial.glsl | 0 .../Source}/Shaders/Materials/Water.glsl | 0 .../Shaders/Model/CPUStylingStageFS.glsl | 0 .../Shaders/Model/CPUStylingStageVS.glsl | 0 .../Shaders/Model/CustomShaderStageFS.glsl | 0 .../Shaders/Model/CustomShaderStageVS.glsl | 0 .../Shaders/Model/FeatureIdStageFS.glsl | 0 .../Shaders/Model/FeatureIdStageVS.glsl | 0 .../Shaders/Model/GeometryStageFS.glsl | 0 .../Shaders/Model/GeometryStageVS.glsl | 0 .../Model/ImageBasedLightingStageFS.glsl | 0 .../Shaders/Model/InstancingStageCommon.glsl | 0 .../Shaders/Model/InstancingStageVS.glsl | 0 .../Model/LegacyInstancingStageVS.glsl | 0 .../Shaders/Model/LightingStageFS.glsl | 0 .../Shaders/Model/MaterialStageFS.glsl | 0 .../Shaders/Model/MetadataStageFS.glsl | 0 .../Shaders/Model/MetadataStageVS.glsl | 0 .../Model/ModelClippingPlanesStageFS.glsl | 0 .../Shaders/Model/ModelColorStageFS.glsl | 0 .../engine/Source}/Shaders/Model/ModelFS.glsl | 0 .../Shaders/Model/ModelSilhouetteStageFS.glsl | 0 .../Shaders/Model/ModelSilhouetteStageVS.glsl | 0 .../Shaders/Model/ModelSplitterStageFS.glsl | 0 .../engine/Source}/Shaders/Model/ModelVS.glsl | 0 .../Shaders/Model/MorphTargetsStageVS.glsl | 0 .../Model/PointCloudStylingStageVS.glsl | 0 .../Model/PrimitiveOutlineStageFS.glsl | 0 .../Model/PrimitiveOutlineStageVS.glsl | 0 .../Model/SelectedFeatureIdStageCommon.glsl | 0 .../Shaders/Model/SkinningStageVS.glsl | 0 .../Shaders/OctahedralProjectionAtlasFS.glsl | 0 .../Shaders/OctahedralProjectionFS.glsl | 0 .../Shaders/OctahedralProjectionVS.glsl | 0 .../Shaders/PointPrimitiveCollectionFS.glsl | 0 .../Shaders/PointPrimitiveCollectionVS.glsl | 0 .../Source}/Shaders/PolylineCommon.glsl | 0 .../engine/Source}/Shaders/PolylineFS.glsl | 0 .../Shaders/PolylineShadowVolumeFS.glsl | 0 .../Shaders/PolylineShadowVolumeMorphFS.glsl | 0 .../Shaders/PolylineShadowVolumeMorphVS.glsl | 0 .../Shaders/PolylineShadowVolumeVS.glsl | 0 .../engine/Source}/Shaders/PolylineVS.glsl | 0 .../AcesTonemappingStage.glsl | 0 .../PostProcessStages/AdditiveBlend.glsl | 0 .../AmbientOcclusionGenerate.glsl | 0 .../AmbientOcclusionModulate.glsl | 0 .../PostProcessStages/BlackAndWhite.glsl | 0 .../PostProcessStages/BloomComposite.glsl | 0 .../Shaders/PostProcessStages/BrightPass.glsl | 0 .../Shaders/PostProcessStages/Brightness.glsl | 0 .../CompositeTranslucentClassification.glsl | 0 .../PostProcessStages/ContrastBias.glsl | 0 .../PostProcessStages/DepthOfField.glsl | 0 .../Shaders/PostProcessStages/DepthView.glsl | 0 .../PostProcessStages/DepthViewPacked.glsl | 0 .../PostProcessStages/EdgeDetection.glsl | 0 .../Shaders/PostProcessStages/FXAA.glsl | 0 .../PostProcessStages/FilmicTonemapping.glsl | 0 .../PostProcessStages/GaussianBlur1D.glsl | 0 .../Shaders/PostProcessStages/LensFlare.glsl | 0 .../ModifiedReinhardTonemapping.glsl | 0 .../PostProcessStages/NightVision.glsl | 0 .../PostProcessStages/PassThrough.glsl | 0 .../PostProcessStages/PassThroughDepth.glsl | 0 .../PointCloudEyeDomeLighting.glsl | 0 .../ReinhardTonemapping.glsl | 0 .../Shaders/PostProcessStages/Silhouette.glsl | 0 .../Shaders/ReprojectWebMercatorFS.glsl | 0 .../Shaders/ReprojectWebMercatorVS.glsl | 0 .../Shaders/ShadowVolumeAppearanceFS.glsl | 0 .../Shaders/ShadowVolumeAppearanceVS.glsl | 0 .../Source}/Shaders/ShadowVolumeFS.glsl | 0 .../Source}/Shaders/SkyAtmosphereCommon.glsl | 0 .../Source}/Shaders/SkyAtmosphereFS.glsl | 0 .../Source}/Shaders/SkyAtmosphereVS.glsl | 0 .../engine/Source}/Shaders/SkyBoxFS.glsl | 0 .../engine/Source}/Shaders/SkyBoxVS.glsl | 0 .../engine/Source}/Shaders/SunFS.glsl | 0 .../engine/Source}/Shaders/SunTextureFS.glsl | 0 .../engine/Source}/Shaders/SunVS.glsl | 0 .../Vector3DTileClampedPolylinesFS.glsl | 0 .../Vector3DTileClampedPolylinesVS.glsl | 0 .../Shaders/Vector3DTilePolylinesVS.glsl | 0 .../engine/Source}/Shaders/VectorTileVS.glsl | 0 .../Source}/Shaders/ViewportQuadFS.glsl | 0 .../Source}/Shaders/ViewportQuadVS.glsl | 0 .../ThirdParty/Workers/basis_transcoder.js | 0 .../Source}/ThirdParty/Workers/package.json | 0 .../Source}/ThirdParty/basis_transcoder.wasm | Bin .../ThirdParty/google-earth-dbroot-parser.js | 0 .../engine/Source/Widget}/CesiumWidget.css | 8 + .../engine/Source/Widget}/CesiumWidget.js | 42 +- .../engine/Source/Widget}/lighter.css | 0 .../Workers/cesiumWorkerBootstrapper.js | 0 .../engine/Source}/Workers/package.json | 0 .../Source}/Workers/transferTypedArrayTest.js | 0 .../Source}/WorkersES6/combineGeometry.js | 0 .../Source}/WorkersES6/createBoxGeometry.js | 0 .../WorkersES6/createBoxOutlineGeometry.js | 0 .../WorkersES6/createCircleGeometry.js | 0 .../WorkersES6/createCircleOutlineGeometry.js | 0 .../createCoplanarPolygonGeometry.js | 0 .../createCoplanarPolygonOutlineGeometry.js | 0 .../WorkersES6/createCorridorGeometry.js | 0 .../createCorridorOutlineGeometry.js | 0 .../WorkersES6/createCylinderGeometry.js | 0 .../createCylinderOutlineGeometry.js | 0 .../WorkersES6/createEllipseGeometry.js | 0 .../createEllipseOutlineGeometry.js | 0 .../WorkersES6/createEllipsoidGeometry.js | 0 .../createEllipsoidOutlineGeometry.js | 0 .../WorkersES6/createFrustumGeometry.js | 0 .../createFrustumOutlineGeometry.js | 0 .../Source}/WorkersES6/createGeometry.js | 0 .../createGroundPolylineGeometry.js | 0 .../Source}/WorkersES6/createPlaneGeometry.js | 0 .../WorkersES6/createPlaneOutlineGeometry.js | 0 .../WorkersES6/createPolygonGeometry.js | 0 .../createPolygonOutlineGeometry.js | 0 .../WorkersES6/createPolylineGeometry.js | 0 .../createPolylineVolumeGeometry.js | 0 .../createPolylineVolumeOutlineGeometry.js | 0 .../WorkersES6/createRectangleGeometry.js | 0 .../createRectangleOutlineGeometry.js | 0 .../createSimplePolylineGeometry.js | 0 .../WorkersES6/createSphereGeometry.js | 0 .../WorkersES6/createSphereOutlineGeometry.js | 0 .../WorkersES6/createTaskProcessorWorker.js | 0 .../createVectorTileClampedPolylines.js | 0 .../WorkersES6/createVectorTileGeometries.js | 0 .../WorkersES6/createVectorTilePoints.js | 0 .../WorkersES6/createVectorTilePolygons.js | 0 .../WorkersES6/createVectorTilePolylines.js | 0 ...VerticesFromGoogleEarthEnterpriseBuffer.js | 0 .../WorkersES6/createVerticesFromHeightmap.js | 0 .../createVerticesFromQuantizedTerrainMesh.js | 0 .../Source}/WorkersES6/createWallGeometry.js | 0 .../WorkersES6/createWallOutlineGeometry.js | 0 .../engine/Source}/WorkersES6/decodeDraco.js | 0 .../decodeGoogleEarthEnterprisePacket.js | 0 .../engine/Source}/WorkersES6/decodeI3S.js | 0 .../Source}/WorkersES6/transcodeKTX2.js | 0 .../upsampleQuantizedTerrainMesh.js | 0 packages/engine/Specs/.eslintrc.json | 10 + .../Core/ApproximateTerrainHeightsSpec.js | 5 +- ...ArcGISTiledElevationTerrainProviderSpec.js | 7 +- .../Specs}/Core/AssociativeArraySpec.js | 2 +- .../Specs}/Core/AttributeCompressionSpec.js | 2 +- .../Specs}/Core/AxisAlignedBoundingBoxSpec.js | 2 +- .../Core/BingMapsGeocoderServiceSpec.js | 6 +- .../Specs}/Core/BoundingRectangleSpec.js | 4 +- .../engine/Specs}/Core/BoundingSphereSpec.js | 7 +- .../engine/Specs}/Core/BoxGeometrySpec.js | 4 +- .../Specs}/Core/BoxOutlineGeometrySpec.js | 4 +- .../engine/Specs}/Core/Cartesian2Spec.js | 7 +- .../engine/Specs}/Core/Cartesian3Spec.js | 8 +- .../engine/Specs}/Core/Cartesian4Spec.js | 8 +- .../Core/CartographicGeocoderServiceSpec.js | 5 +- .../engine/Specs}/Core/CartographicSpec.js | 4 +- .../Specs}/Core/CatmullRomSplineSpec.js | 8 +- .../Specs}/Core/CesiumTerrainProviderSpec.js | 6 +- .../engine/Specs}/Core/CheckSpec.js | 2 +- .../engine/Specs}/Core/CircleGeometrySpec.js | 6 +- .../Specs}/Core/CircleOutlineGeometrySpec.js | 8 +- .../engine/Specs}/Core/ClockSpec.js | 2 +- .../ColorGeometryInstanceAttributeSpec.js | 2 +- .../engine/Specs}/Core/ColorSpec.js | 6 +- .../Specs}/Core/ComponentDatatypeSpec.js | 2 +- .../engine/Specs}/Core/ConstantSplineSpec.js | 6 +- .../Core/CoplanarPolygonGeometrySpec.js | 6 +- .../CoplanarPolygonOutlineGeometrySpec.js | 7 +- .../Specs}/Core/CorridorGeometrySpec.js | 6 +- .../Core/CorridorOutlineGeometrySpec.js | 4 +- .../Specs}/Core/CubicRealPolynomialSpec.js | 4 +- .../engine/Specs}/Core/CullingVolumeSpec.js | 2 +- .../CustomHeightmapTerrainProviderSpec.js | 2 +- .../Specs}/Core/CylinderGeometrySpec.js | 4 +- .../Core/CylinderOutlineGeometrySpec.js | 4 +- .../engine/Specs}/Core/DeveloperErrorSpec.js | 2 +- ...yConditionGeometryInstanceAttributeSpec.js | 2 +- .../Core/DistanceDisplayConditionSpec.js | 4 +- .../Core/DoubleEndedPriorityQueueSpec.js | 2 +- .../Specs}/Core/DoublyLinkedListSpec.js | 2 +- .../Core/EarthOrientationParametersSpec.js | 2 +- .../engine/Specs}/Core/EllipseGeometrySpec.js | 6 +- .../Specs}/Core/EllipseOutlineGeometrySpec.js | 4 +- .../Specs}/Core/EllipsoidGeodesicSpec.js | 8 +- .../Specs}/Core/EllipsoidGeometrySpec.js | 6 +- .../Core/EllipsoidOutlineGeometrySpec.js | 6 +- .../Specs}/Core/EllipsoidRhumbLineSpec.js | 4 +- .../engine/Specs}/Core/EllipsoidSpec.js | 11 +- .../Specs}/Core/EllipsoidTangentPlaneSpec.js | 2 +- .../Core/EllipsoidTerrainProviderSpec.js | 7 +- .../Specs}/Core/EllipsoidalOccluderSpec.js | 4 +- .../Specs}/Core/EncodedCartesian3Spec.js | 2 +- .../engine/Specs}/Core/EventSpec.js | 2 +- .../Specs}/Core/FeatureDetectionSpec.js | 2 +- .../engine/Specs}/Core/FrustumGeometrySpec.js | 6 +- .../Specs}/Core/FrustumOutlineGeometrySpec.js | 6 +- .../engine/Specs}/Core/FullscreenSpec.js | 2 +- .../Specs}/Core/GeographicProjectionSpec.js | 4 +- .../Specs}/Core/GeographicTilingSchemeSpec.js | 4 +- .../Specs}/Core/GeometryAttributeSpec.js | 5 +- .../Core/GeometryInstanceAttributeSpec.js | 5 +- .../Specs}/Core/GeometryInstanceSpec.js | 2 +- .../Specs}/Core/GeometryPipelineSpec.js | 4 +- .../engine/Specs}/Core/GeometrySpec.js | 4 +- .../Core/GoogleEarthEnterpriseMetadataSpec.js | 4 +- .../GoogleEarthEnterpriseTerrainDataSpec.js | 4 +- ...oogleEarthEnterpriseTerrainProviderSpec.js | 6 +- .../Specs}/Core/GroundPolylineGeometrySpec.js | 6 +- .../Specs}/Core/HeadingPitchRangeSpec.js | 2 +- .../Specs}/Core/HeadingPitchRollSpec.js | 4 +- .../engine/Specs}/Core/HeapSpec.js | 2 +- .../Specs}/Core/HeightmapTerrainDataSpec.js | 2 +- .../HermitePolynomialApproximationSpec.js | 2 +- .../engine/Specs}/Core/HermiteSplineSpec.js | 8 +- .../engine/Specs}/Core/HilbertOrderSpec.js | 2 +- .../Specs}/Core/Iau2000OrientationSpec.js | 6 +- .../engine/Specs}/Core/Iau2006XysDataSpec.js | 4 +- .../Specs}/Core/IauOrientationAxesSpec.js | 4 +- .../engine/Specs}/Core/IndexDatatypeSpec.js | 4 +- .../Specs}/Core/IntersectionTestsSpec.js | 4 +- .../engine/Specs}/Core/Intersections2DSpec.js | 2 +- .../engine/Specs}/Core/IntervalSpec.js | 2 +- .../Specs}/Core/IonGeocoderServiceSpec.js | 8 +- .../engine/Specs}/Core/IonResourceSpec.js | 2 +- .../engine/Specs}/Core/JulianDateSpec.js | 4 +- .../LagrangePolynomialApproximationSpec.js | 2 +- .../engine/Specs}/Core/LeapSecondSpec.js | 2 +- .../Specs}/Core/LinearApproximationSpec.js | 2 +- .../engine/Specs}/Core/LinearSplineSpec.js | 2 +- .../engine/Specs}/Core/ManagedArraySpec.js | 2 +- .../engine/Specs}/Core/MathSpec.js | 2 +- .../engine/Specs}/Core/Matrix2Spec.js | 8 +- .../engine/Specs}/Core/Matrix3Spec.js | 8 +- .../engine/Specs}/Core/Matrix4Spec.js | 8 +- .../engine/Specs}/Core/MortonOrderSpec.js | 2 +- .../engine/Specs}/Core/NearFarScalarSpec.js | 4 +- .../engine/Specs}/Core/OccluderSpec.js | 4 +- .../Core/OpenCageGeocoderServiceSpec.js | 2 +- .../Specs}/Core/OrientedBoundingBoxSpec.js | 6 +- .../Specs}/Core/OrthographicFrustumSpec.js | 6 +- .../Core/OrthographicOffCenterFrustumSpec.js | 4 +- .../Specs}/Core/PeliasGeocoderServiceSpec.js | 2 +- .../Specs}/Core/PerspectiveFrustumSpec.js | 6 +- .../Core/PerspectiveOffCenterFrustumSpec.js | 4 +- .../engine/Specs}/Core/PinBuilderSpec.js | 2 +- .../engine/Specs}/Core/PixelFormatSpec.js | 2 +- .../engine/Specs}/Core/PlaneGeometrySpec.js | 8 +- .../Specs}/Core/PlaneOutlineGeometrySpec.js | 4 +- .../engine/Specs}/Core/PlaneSpec.js | 4 +- .../engine/Specs}/Core/PolygonGeometrySpec.js | 6 +- .../Specs}/Core/PolygonOutlineGeometrySpec.js | 6 +- .../engine/Specs}/Core/PolygonPipelineSpec.js | 4 +- .../Specs}/Core/PolylineGeometrySpec.js | 6 +- .../Specs}/Core/PolylinePipelineSpec.js | 4 +- .../Specs}/Core/PolylineVolumeGeometrySpec.js | 4 +- .../Core/PolylineVolumeOutlineGeometrySpec.js | 4 +- .../engine/Specs}/Core/PrimitiveTypeSpec.js | 2 +- .../Core/QuadraticRealPolynomialSpec.js | 4 +- .../Core/QuantizedMeshTerrainDataSpec.js | 4 +- .../Specs}/Core/QuarticRealPolynomialSpec.js | 4 +- .../engine/Specs}/Core/QuaternionSpec.js | 6 +- .../Specs}/Core/QuaternionSplineSpec.js | 8 +- .../engine/Specs}/Core/QueueSpec.js | 2 +- .../engine/Specs}/Core/RaySpec.js | 2 +- .../Core/RectangleCollisionCheckerSpec.js | 5 +- .../Specs}/Core/RectangleGeometrySpec.js | 6 +- .../Core/RectangleOutlineGeometrySpec.js | 6 +- .../engine/Specs}/Core/RectangleSpec.js | 11 +- .../Specs}/Core/RequestErrorEventSpec.js | 2 +- .../Specs}/Core/RequestSchedulerSpec.js | 7 +- .../engine/Specs}/Core/ResourceSpec.js | 8 +- .../engine/Specs}/Core/RuntimeErrorSpec.js | 2 +- .../engine/Specs}/Core/S2CellSpec.js | 8 +- .../Core/ScreenSpaceEventHandlerSpec.js | 4 +- .../Core/ShowGeometryInstanceAttributeSpec.js | 2 +- .../Core/Simon1994PlanetaryPositionsSpec.js | 2 +- .../Specs}/Core/SimplePolylineGeometrySpec.js | 6 +- .../engine/Specs}/Core/SphereGeometrySpec.js | 10 +- .../Specs}/Core/SphereOutlineGeometrySpec.js | 6 +- .../engine/Specs}/Core/SphericalSpec.js | 4 +- .../engine/Specs}/Core/SplineSpec.js | 7 +- .../engine/Specs}/Core/SteppedSplineSpec.js | 6 +- .../engine/Specs}/Core/TaskProcessorSpec.js | 8 +- .../engine/Specs}/Core/TerrainEncodingSpec.js | 4 +- .../Specs}/Core/TileAvailabilitySpec.js | 2 +- .../Specs}/Core/TimeIntervalCollectionSpec.js | 2 +- .../engine/Specs}/Core/TimeIntervalSpec.js | 2 +- .../engine/Specs}/Core/TipsifySpec.js | 2 +- .../engine/Specs}/Core/TransformsSpec.js | 4 +- .../Core/TranslationRotationScaleSpec.js | 2 +- .../Core/TridiagonalSystemSolverSpec.js | 4 +- .../engine/Specs}/Core/TrustedServersSpec.js | 2 +- .../Core/VRTheWorldTerrainProviderSpec.js | 4 +- .../engine/Specs}/Core/VertexFormatSpec.js | 4 +- .../Specs}/Core/VideoSynchronizerSpec.js | 6 +- .../engine/Specs}/Core/WallGeometrySpec.js | 6 +- .../Specs}/Core/WallOutlineGeometrySpec.js | 10 +- .../Specs}/Core/WebMercatorProjectionSpec.js | 4 +- .../Core/WebMercatorTilingSchemeSpec.js | 4 +- .../Core/WireframeIndexGeneratorSpec.js | 2 +- .../Specs}/Core/appendForwardSlashSpec.js | 2 +- .../Specs}/Core/arrayRemoveDuplicatesSpec.js | 8 +- .../Specs}/Core/barycentricCoordinatesSpec.js | 4 +- .../engine/Specs}/Core/binarySearchSpec.js | 2 +- .../engine/Specs}/Core/buildModuleUrlSpec.js | 2 +- .../engine/Specs}/Core/cloneSpec.js | 2 +- .../engine/Specs}/Core/combineSpec.js | 2 +- .../engine/Specs}/Core/createGuidSpec.js | 2 +- .../engine/Specs}/Core/defaultValueSpec.js | 2 +- .../engine/Specs}/Core/definedSpec.js | 2 +- .../Specs}/Core/deprecationWarningSpec.js | 2 +- .../engine/Specs}/Core/getAbsoluteUriSpec.js | 2 +- .../engine/Specs}/Core/getBaseUriSpec.js | 2 +- .../Specs}/Core/getExtensionFromUriSpec.js | 2 +- .../Specs}/Core/getFilenameFromUriSpec.js | 2 +- .../Specs}/Core/getImageFromTypedArraySpec.js | 2 +- .../Specs}/Core/getJsonFromTypedArraySpec.js | 2 +- .../Core/getStringFromTypedArraySpec.js | 2 +- .../engine/Specs}/Core/isBlobUriSpec.js | 2 +- .../Specs}/Core/isCrossOriginUrlSpec.js | 2 +- .../engine/Specs}/Core/isDataUriSpec.js | 2 +- .../engine/Specs}/Core/isLeapYearSpec.js | 2 +- .../Core/loadImageFromTypedArraySpec.js | 2 +- .../engine/Specs}/Core/loadKTX2Spec.js | 2 +- .../engine/Specs}/Core/mergeSortSpec.js | 6 +- .../engine/Specs}/Core/objectToQuerySpec.js | 2 +- .../engine/Specs}/Core/oneTimeWarningSpec.js | 2 +- .../Specs}/Core/parseResponseHeadersSpec.js | 2 +- .../Specs}/Core/pointInsideTriangleSpec.js | 2 +- .../engine/Specs}/Core/queryToObjectSpec.js | 2 +- .../Specs/Core/requestAnimationFrameSpec.js | 50 + .../Core/resizeImageToNextPowerOfTwoSpec.js | 2 +- .../Core/sampleTerrainMostDetailedSpec.js | 2 +- .../engine/Specs}/Core/sampleTerrainSpec.js | 2 +- .../engine/Specs}/Core/subdivideArraySpec.js | 2 +- .../Specs}/Core/writeTextToCanvasSpec.js | 2 +- .../DataSources/BillboardGraphicsSpec.js | 2 +- .../DataSources/BillboardVisualizerSpec.js | 8 +- .../DataSources/BoxGeometryUpdaterSpec.js | 10 +- .../Specs}/DataSources/BoxGraphicsSpec.js | 6 +- .../DataSources/CallbackPropertySpec.js | 2 +- .../Cesium3DTilesetGraphicsSpec.js | 5 +- .../Cesium3DTilesetVisualizerSpec.js | 6 +- .../CheckerboardMaterialPropertySpec.js | 4 +- .../DataSources/ColorMaterialPropertySpec.js | 2 +- .../CompositeEntityCollectionSpec.js | 2 +- .../CompositeMaterialPropertySpec.js | 2 +- .../CompositePositionPropertySpec.js | 2 +- .../DataSources/CompositePropertySpec.js | 2 +- .../ConstantPositionPropertySpec.js | 2 +- .../DataSources/ConstantPropertySpec.js | 6 +- .../CorridorGeometryUpdaterSpec.js | 14 +- .../DataSources/CorridorGraphicsSpec.js | 6 +- .../DataSources/CustomDataSourceSpec.js | 2 +- .../CylinderGeometryUpdaterSpec.js | 10 +- .../DataSources/CylinderGraphicsSpec.js | 6 +- .../Specs}/DataSources/CzmlDataSourceSpec.js | 2 +- .../Specs}/DataSources/DataSourceClockSpec.js | 2 +- .../DataSources/DataSourceCollectionSpec.js | 4 +- .../DataSources/DataSourceDisplaySpec.js | 6 +- .../DataSources/DynamicGeometryUpdaterSpec.js | 4 +- .../DataSources/EllipseGeometryUpdaterSpec.js | 12 +- .../Specs}/DataSources/EllipseGraphicsSpec.js | 6 +- .../EllipsoidGeometryUpdaterSpec.js | 12 +- .../DataSources/EllipsoidGraphicsSpec.js | 6 +- .../Specs}/DataSources/EntityClusterSpec.js | 8 +- .../DataSources/EntityCollectionSpec.js | 2 +- .../engine/Specs}/DataSources/EntitySpec.js | 2 +- .../Specs}/DataSources/EntityViewSpec.js | 4 +- .../DataSources/GeoJsonDataSourceSpec.js | 2 +- .../Specs}/DataSources/GeometryUpdaterSpec.js | 8 +- .../DataSources/GeometryVisualizerSpec.js | 8 +- .../Specs}/DataSources/GpxDataSourceSpec.js | 2 +- .../DataSources/GridMaterialPropertySpec.js | 2 +- .../DataSources/GroundGeometryUpdaterSpec.js | 2 +- .../DataSources/ImageMaterialPropertySpec.js | 2 +- .../Specs}/DataSources/KmlDataSourceSpec.js | 8 +- .../Specs}/DataSources/KmlTourFlyToSpec.js | 6 +- .../engine/Specs}/DataSources/KmlTourSpec.js | 7 +- .../Specs}/DataSources/LabelGraphicsSpec.js | 2 +- .../Specs}/DataSources/LabelVisualizerSpec.js | 6 +- .../Specs}/DataSources/ModelGraphicsSpec.js | 2 +- .../Specs}/DataSources/ModelVisualizerSpec.js | 6 +- .../NodeTransformationPropertySpec.js | 4 +- .../Specs}/DataSources/PathGraphicsSpec.js | 2 +- .../Specs}/DataSources/PathVisualizerSpec.js | 4 +- .../DataSources/PlaneGeometryUpdaterSpec.js | 10 +- .../Specs}/DataSources/PlaneGraphicsSpec.js | 6 +- .../Specs}/DataSources/PointGraphicsSpec.js | 2 +- .../Specs}/DataSources/PointVisualizerSpec.js | 4 +- .../DataSources/PolygonGeometryUpdaterSpec.js | 14 +- .../Specs}/DataSources/PolygonGraphicsSpec.js | 6 +- .../PolylineArrowMaterialPropertySpec.js | 2 +- .../PolylineDashMaterialPropertySpec.js | 2 +- .../PolylineGeometryUpdaterSpec.js | 8 +- .../PolylineGlowMaterialPropertySpec.js | 4 +- .../DataSources/PolylineGraphicsSpec.js | 6 +- .../PolylineOutlineMaterialPropertySpec.js | 2 +- .../DataSources/PolylineVisualizerSpec.js | 8 +- .../PolylineVolumeGeometryUpdaterSpec.js | 10 +- .../DataSources/PolylineVolumeGraphicsSpec.js | 6 +- .../DataSources/PositionPropertyArraySpec.js | 2 +- .../Specs}/DataSources/PropertyArraySpec.js | 2 +- .../Specs}/DataSources/PropertyBagSpec.js | 2 +- .../RectangleGeometryUpdaterSpec.js | 14 +- .../DataSources/RectangleGraphicsSpec.js | 6 +- .../DataSources/ReferencePropertySpec.js | 2 +- .../engine/Specs}/DataSources/RotationSpec.js | 10 +- .../SampledPositionPropertySpec.js | 2 +- .../Specs}/DataSources/SampledPropertySpec.js | 4 +- .../StaticGeometryColorBatchSpec.js | 8 +- .../StaticGeometryPerMaterialBatchSpec.js | 8 +- .../StaticGroundGeometryColorBatchSpec.js | 8 +- ...taticGroundGeometryPerMaterialBatchSpec.js | 8 +- ...taticGroundPolylinePerMaterialBatchSpec.js | 8 +- .../StaticOutlineGeometryBatchSpec.js | 8 +- .../DataSources/StripeMaterialPropertySpec.js | 4 +- .../DataSources/TerrainOffsetPropertySpec.js | 6 +- ...eIntervalCollectionPositionPropertySpec.js | 2 +- .../TimeIntervalCollectionPropertySpec.js | 2 +- .../VelocityOrientationPropertySpec.js | 2 +- .../DataSources/VelocityVectorPropertySpec.js | 4 +- .../DataSources/WallGeometryUpdaterSpec.js | 10 +- .../Specs}/DataSources/WallGraphicsSpec.js | 6 +- .../createMaterialPropertyDescriptorSpec.js | 2 +- .../Specs}/DataSources/exportKmlSpec.js | 4 +- .../Specs}/Renderer/AutomaticUniformSpec.js | 8 +- .../engine/Specs}/Renderer/BufferSpec.js | 4 +- .../Specs}/Renderer/BuiltinFunctionsSpec.js | 8 +- .../Specs}/Renderer/ClearCommandSpec.js | 2 +- .../engine/Specs}/Renderer/ClearSpec.js | 4 +- .../Specs}/Renderer/ComputeCommandSpec.js | 4 +- .../engine/Specs}/Renderer/ContextSpec.js | 4 +- .../engine/Specs}/Renderer/CubeMapSpec.js | 4 +- .../engine/Specs}/Renderer/DrawCommandSpec.js | 2 +- .../engine/Specs}/Renderer/DrawSpec.js | 4 +- .../Specs}/Renderer/FramebufferManagerSpec.js | 4 +- .../engine/Specs}/Renderer/FramebufferSpec.js | 4 +- .../Renderer/MultisampleFramebufferSpec.js | 4 +- .../engine/Specs}/Renderer/PassStateSpec.js | 2 +- .../engine/Specs}/Renderer/RenderStateSpec.js | 4 +- .../Specs}/Renderer/RenderbufferSpec.js | 4 +- .../engine/Specs}/Renderer/SamplerSpec.js | 4 +- .../Specs}/Renderer/ShaderBuilderSpec.js | 8 +- .../engine/Specs}/Renderer/ShaderCacheSpec.js | 4 +- .../Specs}/Renderer/ShaderDestinationSpec.js | 2 +- .../Specs}/Renderer/ShaderFunctionSpec.js | 2 +- .../Specs}/Renderer/ShaderProgramSpec.js | 4 +- .../Specs}/Renderer/ShaderSourceSpec.js | 2 +- .../Specs}/Renderer/ShaderStructSpec.js | 2 +- .../Specs}/Renderer/TextureCacheSpec.js | 4 +- .../engine/Specs}/Renderer/TextureSpec.js | 4 +- .../engine/Specs}/Renderer/UniformSpec.js | 4 +- .../Specs}/Renderer/VertexArrayFacadeSpec.js | 4 +- .../Specs}/Renderer/VertexArrayFactorySpec.js | 4 +- .../engine/Specs}/Renderer/VertexArraySpec.js | 4 +- .../Specs}/Renderer/freezeRenderStateSpec.js | 2 +- .../engine/Specs}/Renderer/loadCubeMapSpec.js | 4 +- .../Specs}/Renderer/modernizeShaderSpec.js | 2 +- .../engine/Specs}/Scene/AppearanceSpec.js | 2 +- .../ArcGisMapServerImageryProviderSpec.js | 4 +- .../engine/Specs}/Scene/AttributeTypeSpec.js | 2 +- .../engine/Specs}/Scene/AxisSpec.js | 4 +- .../engine/Specs}/Scene/B3dmParserSpec.js | 6 +- .../Specs}/Scene/BatchTableHierarchySpec.js | 2 +- .../engine/Specs}/Scene/BatchTableSpec.js | 6 +- .../engine/Specs}/Scene/BatchTextureSpec.js | 4 +- .../Specs}/Scene/BillboardCollectionSpec.js | 10 +- .../Scene/BingMapsImageryProviderSpec.js | 4 +- .../engine/Specs}/Scene/BoxEmitterSpec.js | 2 +- .../engine/Specs}/Scene/BufferLoaderSpec.js | 2 +- .../Specs}/Scene/CameraEventAggregatorSpec.js | 6 +- .../Specs}/Scene/CameraFlightPathSpec.js | 6 +- .../engine/Specs}/Scene/CameraSpec.js | 4 +- .../Specs}/Scene/Cesium3DContentGroupSpec.js | 2 +- .../Scene/Cesium3DTileBatchTableSpec.js | 11 +- .../Specs}/Scene/Cesium3DTileContentSpec.js | 2 +- .../Scene/Cesium3DTileContentTypeSpec.js | 2 +- .../Specs}/Scene/Cesium3DTileFeatureSpec.js | 6 +- .../Scene/Cesium3DTileFeatureTableSpec.js | 5 +- .../Specs}/Scene/Cesium3DTilePassStateSpec.js | 5 +- .../engine/Specs}/Scene/Cesium3DTileSpec.js | 4 +- .../Specs}/Scene/Cesium3DTileStyleSpec.js | 2 +- .../Scene/Cesium3DTilesetHeatmapSpec.js | 4 +- .../Scene/Cesium3DTilesetMetadataSpec.js | 5 +- .../Specs}/Scene/Cesium3DTilesetSpec.js | 10 +- .../engine/Specs}/Scene/CircleEmitterSpec.js | 2 +- .../Scene/ClassificationPrimitiveSpec.js | 6 +- .../Scene/ClippingPlaneCollectionSpec.js | 6 +- .../engine/Specs}/Scene/ClippingPlaneSpec.js | 4 +- .../Specs}/Scene/CloudCollectionSpec.js | 8 +- .../Scene/Composite3DTileContentSpec.js | 6 +- .../Specs}/Scene/ConditionsExpressionSpec.js | 6 +- .../engine/Specs}/Scene/ConeEmitterSpec.js | 4 +- .../Specs}/Scene/ContentMetadataSpec.js | 2 +- .../engine/Specs}/Scene/CreditDisplaySpec.js | 4 +- .../Specs}/Scene/DebugAppearanceSpec.js | 4 +- .../Specs}/Scene/DebugCameraPrimitiveSpec.js | 4 +- .../Scene/DebugModelMatrixPrimitiveSpec.js | 8 +- .../engine/Specs}/Scene/DepthPlaneSpec.js | 8 +- .../DeviceOrientationCameraControllerSpec.js | 13 +- .../Specs}/Scene/DirectionalLightSpec.js | 2 +- .../Scene/DiscardEmptyTileImagePolicySpec.js | 7 +- .../DiscardMissingTileImagePolicySpec.js | 4 +- .../Specs}/Scene/EllipsoidPrimitiveSpec.js | 4 +- .../Scene/EllipsoidSurfaceAppearanceSpec.js | 4 +- .../Specs}/Scene/Empty3DTileContentSpec.js | 2 +- .../engine/Specs}/Scene/ExpressionSpec.js | 4 +- .../Specs}/Scene/FrameRateMonitorSpec.js | 8 +- .../Specs}/Scene/FrustumCommandsSpec.js | 2 +- .../Specs}/Scene/Geometry3DTileContentSpec.js | 6 +- .../Specs}/Scene/GeometryRenderingSpec.js | 8 +- .../engine/Specs}/Scene/GlobeSpec.js | 6 +- .../Scene/GlobeSurfaceTileProviderSpec.js | 6 +- .../Specs}/Scene/GlobeSurfaceTileSpec.js | 10 +- .../Scene/GlobeTranslucencyFramebufferSpec.js | 4 +- .../Scene/GlobeTranslucencyStateSpec.js | 4 +- .../Specs}/Scene/GltfBufferViewLoaderSpec.js | 2 +- .../engine/Specs}/Scene/GltfBuilder.js | 2 +- .../Specs}/Scene/GltfDracoLoaderSpec.js | 10 +- .../Specs}/Scene/GltfImageLoaderSpec.js | 8 +- .../Specs}/Scene/GltfIndexBufferLoaderSpec.js | 10 +- .../engine/Specs}/Scene/GltfJsonLoaderSpec.js | 4 +- .../engine/Specs}/Scene/GltfLoaderSpec.js | 12 +- .../engine/Specs}/Scene/GltfLoaderUtilSpec.js | 4 +- .../Scene/GltfStructuralMetadataLoaderSpec.js | 10 +- .../Specs}/Scene/GltfTextureLoaderSpec.js | 8 +- .../Scene/GltfVertexBufferLoaderSpec.js | 10 +- ...oogleEarthEnterpriseImageryProviderSpec.js | 4 +- .../GoogleEarthEnterpriseMapsProviderSpec.js | 4 +- .../Specs}/Scene/GridImageryProviderSpec.js | 4 +- .../Scene/GroundPolylinePrimitiveSpec.js | 10 +- .../Specs}/Scene/GroundPrimitiveSpec.js | 10 +- .../engine/Specs}/Scene/GroupMetadataSpec.js | 6 +- .../Specs}/Scene/HeightmapTessellatorSpec.js | 4 +- .../Specs}/Scene/I3SDataProviderSpec.js | 2 +- .../engine/Specs}/Scene/I3SLayerSpec.js | 6 +- .../engine/Specs}/Scene/I3SNodeSpec.js | 4 +- .../engine/Specs}/Scene/I3dmParserSpec.js | 4 +- .../Specs}/Scene/ImageBasedLightingSpec.js | 6 +- .../Scene/ImageryLayerCollectionSpec.js | 6 +- .../engine/Specs}/Scene/ImageryLayerSpec.js | 6 +- .../Specs}/Scene/Implicit3DTileContentSpec.js | 8 +- .../ImplicitAvailabilityBitstreamSpec.js | 5 +- .../Specs}/Scene/ImplicitMetadataViewSpec.js | 4 +- .../Scene/ImplicitSubdivisionSchemeSpec.js | 2 +- .../Scene/ImplicitSubtreeMetadataSpec.js | 2 +- .../Specs}/Scene/ImplicitSubtreeSpec.js | 6 +- .../Scene/ImplicitTileCoordinatesSpec.js | 2 +- .../Specs}/Scene/ImplicitTilesetSpec.js | 2 +- .../Scene/InstanceAttributeSemanticSpec.js | 2 +- .../Specs}/Scene/IonImageryProviderSpec.js | 2 +- .../engine/Specs}/Scene/JobSchedulerSpec.js | 2 +- .../Specs}/Scene/JsonMetadataTableSpec.js | 2 +- .../Specs}/Scene/LabelCollectionSpec.js | 10 +- .../engine/Specs}/Scene/LightSpec.js | 2 +- .../Specs}/Scene/MapboxImageryProviderSpec.js | 6 +- .../Scene/MapboxStyleImageryProviderSpec.js | 6 +- .../Specs}/Scene/MaterialAppearanceSpec.js | 4 +- .../engine/Specs}/Scene/MaterialSpec.js | 6 +- .../Specs}/Scene/MetadataClassPropertySpec.js | 2 +- .../engine/Specs}/Scene/MetadataClassSpec.js | 2 +- .../Specs}/Scene/MetadataComponentTypeSpec.js | 5 +- .../engine/Specs}/Scene/MetadataEntitySpec.js | 2 +- .../engine/Specs}/Scene/MetadataEnumSpec.js | 2 +- .../Specs}/Scene/MetadataEnumValueSpec.js | 2 +- .../Specs}/Scene/MetadataSchemaLoaderSpec.js | 2 +- .../engine/Specs}/Scene/MetadataSchemaSpec.js | 2 +- .../Specs}/Scene/MetadataTablePropertySpec.js | 4 +- .../engine/Specs}/Scene/MetadataTableSpec.js | 4 +- .../engine/Specs}/Scene/MetadataTypeSpec.js | 2 +- .../Scene/Model/AlphaPipelineStageSpec.js | 4 +- .../Specs}/Scene/Model/B3dmLoaderSpec.js | 8 +- .../Model/BatchTexturePipelineStageSpec.js | 7 +- .../Model/CPUStylingPipelineStageSpec.js | 4 +- .../ClassificationModelDrawCommandSpec.js | 2 +- .../Model/ClassificationPipelineStageSpec.js | 4 +- .../Model/CustomShaderPipelineStageSpec.js | 4 +- .../Specs}/Scene/Model/CustomShaderSpec.js | 6 +- .../Model/DequantizationPipelineStageSpec.js | 8 +- .../Scene/Model/FeatureIdPipelineStageSpec.js | 8 +- .../Specs}/Scene/Model/GeoJsonLoaderSpec.js | 6 +- .../Scene/Model/GeometryPipelineStageSpec.js | 8 +- .../Specs}/Scene/Model/I3dmLoaderSpec.js | 8 +- .../ImageBasedLightingPipelineStageSpec.js | 4 +- .../Model/InstancingPipelineStageSpec.js | 8 +- .../Scene/Model/LightingPipelineStageSpec.js | 4 +- .../Scene/Model/MaterialPipelineStageSpec.js | 8 +- .../Scene/Model/MetadataPipelineStageSpec.js | 10 +- .../Scene/Model/Model3DTileContentSpec.js | 8 +- .../Scene/Model/ModelAnimationChannelSpec.js | 2 +- .../Model/ModelAnimationCollectionSpec.js | 6 +- .../Specs}/Scene/Model/ModelAnimationSpec.js | 2 +- .../Scene/Model/ModelArticulationSpec.js | 2 +- .../Scene/Model/ModelArticulationStageSpec.js | 2 +- .../ModelClippingPlanesPipelineStageSpec.js | 4 +- .../Model/ModelColorPipelineStageSpec.js | 4 +- .../Scene/Model/ModelDrawCommandSpec.js | 2 +- .../Specs}/Scene/Model/ModelFeatureSpec.js | 4 +- .../Scene/Model/ModelFeatureTableSpec.js | 4 +- .../Scene/Model/ModelMatrixUpdateStageSpec.js | 4 +- .../Specs}/Scene/Model/ModelNodeSpec.js | 2 +- .../Scene/Model/ModelRenderResourcesSpec.js | 4 +- .../Scene/Model/ModelRuntimeNodeSpec.js | 2 +- .../Scene/Model/ModelRuntimePrimitiveSpec.js | 2 +- .../Specs}/Scene/Model/ModelSceneGraphSpec.js | 4 +- .../Model/ModelSilhouettePipelineStageSpec.js | 4 +- .../Specs}/Scene/Model/ModelSkinSpec.js | 2 +- .../engine/Specs}/Scene/Model/ModelSpec.js | 8 +- .../Model/ModelSplitterPipelineStageSpec.js | 4 +- .../Specs}/Scene/Model/ModelStatisticsSpec.js | 2 +- .../Specs}/Scene/Model/ModelTypeSpec.js | 2 +- .../Specs}/Scene/Model/ModelUtilitySpec.js | 2 +- .../Model/MorphTargetsPipelineStageSpec.js | 8 +- .../Scene/Model/NodeRenderResourcesSpec.js | 4 +- .../Model/NodeStatisticsPipelineStageSpec.js | 6 +- .../Scene/Model/PickingPipelineStageSpec.js | 8 +- .../Specs}/Scene/Model/PntsLoaderSpec.js | 10 +- .../PointCloudStylingPipelineStageSpec.js | 6 +- .../Scene/Model/PrimitiveLoadPlanSpec.js | 4 +- .../Model/PrimitiveOutlineGeneratorSpec.js | 4 +- .../PrimitiveOutlinePipelineStageSpec.js | 8 +- .../Model/PrimitiveRenderResourcesSpec.js | 4 +- .../PrimitiveStatisticsPipelineStageSpec.js | 6 +- .../Model/SceneMode2DPipelineStageSpec.js | 8 +- .../SelectedFeatureIdPipelineStageSpec.js | 8 +- .../Scene/Model/SkinningPipelineStageSpec.js | 8 +- .../Specs}/Scene/Model/TextureManagerSpec.js | 10 +- .../Specs}/Scene/Model/TextureUniformSpec.js | 2 +- .../Scene/Model/TilesetPipelineStageSpec.js | 4 +- .../Scene/Model/WireframePipelineStageSpec.js | 8 +- .../Specs}/Scene/Model/loadAndZoomToModel.js | 4 +- .../engine/Specs}/Scene/MoonSpec.js | 4 +- .../engine/Specs}/Scene/MultifrustumSpec.js | 8 +- .../Specs}/Scene/Multiple3DTileContentSpec.js | 8 +- .../Scene/OctahedralProjectedCubeMapSpec.js | 10 +- .../Scene/OpenStreetMapImageryProviderSpec.js | 6 +- .../OrderedGroundPrimitiveCollectionSpec.js | 2 +- .../engine/Specs}/Scene/ParticleSpec.js | 7 +- .../engine/Specs}/Scene/ParticleSystemSpec.js | 6 +- .../Scene/PerInstanceColorAppearanceSpec.js | 4 +- .../engine/Specs}/Scene/PickingSpec.js | 12 +- .../engine/Specs}/Scene/PntsParserSpec.js | 4 +- .../Scene/PointCloudEyeDomeLightingSpec.js | 8 +- .../Specs}/Scene/PointCloudShadingSpec.js | 4 +- .../Scene/PointPrimitiveCollectionSpec.js | 6 +- .../Specs}/Scene/PolylineCollectionSpec.js | 6 +- .../Scene/PolylineColorAppearanceSpec.js | 4 +- .../Scene/PolylineMaterialAppearanceSpec.js | 4 +- .../Scene/PostProcessStageCollectionSpec.js | 6 +- .../Scene/PostProcessStageCompositeSpec.js | 6 +- .../Scene/PostProcessStageLibrarySpec.js | 10 +- .../Specs}/Scene/PostProcessStageSpec.js | 6 +- .../Specs}/Scene/PrimitiveCollectionSpec.js | 6 +- .../Specs}/Scene/PrimitiveCullingSpec.js | 8 +- .../Specs}/Scene/PrimitivePipelineSpec.js | 2 +- .../engine/Specs}/Scene/PrimitiveSpec.js | 14 +- .../Scene/PropertyAttributePropertySpec.js | 2 +- .../Specs}/Scene/PropertyAttributeSpec.js | 2 +- .../engine/Specs}/Scene/PropertyTableSpec.js | 4 +- .../Scene/PropertyTexturePropertySpec.js | 4 +- .../Specs}/Scene/PropertyTextureSpec.js | 4 +- .../Specs}/Scene/QuadtreePrimitiveSpec.js | 10 +- .../engine/Specs}/Scene/QuadtreeTileSpec.js | 4 +- .../Specs}/Scene/ResourceCacheKeySpec.js | 2 +- .../engine/Specs}/Scene/ResourceCacheSpec.js | 10 +- .../Scene/ResourceCacheStatisticsSpec.js | 2 +- .../engine/Specs}/Scene/ResourceLoaderSpec.js | 2 +- .../engine/Specs}/Scene/SceneSpec.js | 12 +- .../Specs}/Scene/SceneTransformsSpec.js | 6 +- .../Scene/ScreenSpaceCameraControllerSpec.js | 10 +- .../engine/Specs}/Scene/ShadowMapSpec.js | 8 +- .../Scene/ShadowVolumeAppearanceSpec.js | 4 +- .../Scene/SingleTileImageryProviderSpec.js | 4 +- .../engine/Specs}/Scene/SkyAtmosphereSpec.js | 6 +- .../engine/Specs}/Scene/SkyBoxSpec.js | 4 +- .../engine/Specs}/Scene/SphereEmitterSpec.js | 2 +- .../Specs}/Scene/StructuralMetadataSpec.js | 2 +- .../Specs}/Scene/StyleExpressionSpec.js | 2 +- .../engine/Specs}/Scene/SunLightSpec.js | 2 +- .../engine/Specs}/Scene/SunSpec.js | 11 +- .../Specs}/Scene/SupportedImageFormatsSpec.js | 2 +- .../Specs}/Scene/TerrainFillMeshSpec.js | 8 +- .../engine/Specs}/Scene/TextureAtlasSpec.js | 6 +- .../Specs}/Scene/TileBoundingRegionSpec.js | 6 +- .../Specs}/Scene/TileBoundingS2CellSpec.js | 6 +- .../Specs}/Scene/TileBoundingSphereSpec.js | 6 +- .../Specs}/Scene/TileBoundingVolumeSpec.js | 2 +- .../TileCoordinatesImageryProviderSpec.js | 4 +- .../engine/Specs}/Scene/TileImagerySpec.js | 2 +- .../TileMapServiceImageryProviderSpec.js | 6 +- .../engine/Specs}/Scene/TileMetadataSpec.js | 2 +- .../Scene/TileOrientedBoundingBoxSpec.js | 6 +- .../Specs}/Scene/TileReplacementQueueSpec.js | 2 +- .../Specs}/Scene/Tileset3DTileContentSpec.js | 6 +- .../Specs}/Scene/TilesetMetadataSpec.js | 6 +- .../Specs}/Scene/TimeDynamicImagerySpec.js | 2 +- .../Specs}/Scene/TimeDynamicPointCloudSpec.js | 8 +- .../TranslucentTileClassificationSpec.js | 4 +- .../Specs}/Scene/TweenCollectionSpec.js | 6 +- .../Scene/UrlTemplateImageryProviderSpec.js | 6 +- .../Scene/Vector3DTileClampedPolylinesSpec.js | 6 +- .../Specs}/Scene/Vector3DTileContentSpec.js | 6 +- .../Specs}/Scene/Vector3DTileGeometrySpec.js | 8 +- .../Specs}/Scene/Vector3DTilePointsSpec.js | 8 +- .../Specs}/Scene/Vector3DTilePolygonsSpec.js | 10 +- .../Specs}/Scene/Vector3DTilePolylinesSpec.js | 8 +- .../Scene/VertexAttributeSemanticSpec.js | 2 +- .../engine/Specs}/Scene/ViewportQuadSpec.js | 4 +- .../Scene/WebMapServiceImageryProviderSpec.js | 6 +- .../WebMapTileServiceImageryProviderSpec.js | 4 +- .../computeFlyToLocationForRectangleSpec.js | 6 +- .../Scene/createElevationBandMaterialSpec.js | 6 +- .../createTangentSpaceDebugPrimitiveSpec.js | 2 +- .../Specs}/Scene/findContentMetadataSpec.js | 6 +- .../Specs}/Scene/findGroupMetadataSpec.js | 2 +- .../Specs}/Scene/findTileMetadataSpec.js | 6 +- .../engine/Specs}/Scene/hasExtensionSpec.js | 2 +- .../Specs}/Scene/parseBatchTableSpec.js | 2 +- .../Scene/parseBoundingVolumeSemanticsSpec.js | 2 +- .../Scene/parseFeatureMetadataLegacySpec.js | 6 +- .../Scene/parseStructuralMetadataSpec.js | 6 +- .../Scene/preprocess3DTileContentSpec.js | 2 +- .../engine/Specs/Widget}/CesiumWidgetSpec.js | 12 +- packages/engine/Specs/test.mjs | 17 + packages/engine/package.json | 73 ++ packages/engine/tsd-conf.json | 33 + packages/widgets/.gitignore | 4 + packages/widgets/LICENSE.md | 261 +++++ packages/widgets/README.md | 58 ++ .../widgets/Source}/Animation/Animation.css | 0 .../widgets/Source}/Animation/Animation.js | 12 +- .../Source}/Animation/AnimationViewModel.js | 17 +- .../widgets/Source}/Animation/lighter.css | 0 .../BaseLayerPicker/BaseLayerPicker.css | 0 .../BaseLayerPicker/BaseLayerPicker.js | 14 +- .../BaseLayerPickerViewModel.js | 12 +- .../BaseLayerPicker/ProviderViewModel.js | 6 +- .../createDefaultImageryProviderViewModels.js | 18 +- .../createDefaultTerrainProviderViewModels.js | 10 +- .../Source}/BaseLayerPicker/lighter.css | 0 .../Cesium3DTilesInspector.css | 0 .../Cesium3DTilesInspector.js | 14 +- .../Cesium3DTilesInspectorViewModel.js | 30 +- .../CesiumInspector/CesiumInspector.css | 0 .../CesiumInspector/CesiumInspector.js | 12 +- .../CesiumInspectorViewModel.js | 26 +- .../widgets/Source}/ClockViewModel.js | 14 +- .../widgets/Source}/Command.js | 2 +- .../FullscreenButton/FullscreenButton.css | 0 .../FullscreenButton/FullscreenButton.js | 12 +- .../FullscreenButtonViewModel.js | 16 +- .../widgets/Source}/Geocoder/Geocoder.css | 0 .../widgets/Source}/Geocoder/Geocoder.js | 14 +- .../Source}/Geocoder/GeocoderViewModel.js | 30 +- .../widgets/Source}/Geocoder/lighter.css | 0 .../widgets/Source}/HomeButton/HomeButton.js | 12 +- .../Source}/HomeButton/HomeButtonViewModel.js | 5 +- .../Images/ImageryProviders/bingAerial.png | Bin .../ImageryProviders/bingAerialLabels.png | Bin .../Images/ImageryProviders/bingRoads.png | Bin .../Images/ImageryProviders/blueMarble.png | Bin .../Images/ImageryProviders/earthAtNight.png | Bin .../esriNationalGeographic.png | Bin .../ImageryProviders/esriWorldImagery.png | Bin .../ImageryProviders/esriWorldStreetMap.png | Bin .../mapQuestOpenStreetMap.png | Bin .../ImageryProviders/mapboxSatellite.png | Bin .../Images/ImageryProviders/mapboxStreets.png | Bin .../Images/ImageryProviders/mapboxTerrain.png | Bin .../ImageryProviders/naturalEarthII.png | Bin .../Images/ImageryProviders/openStreetMap.png | Bin .../Images/ImageryProviders/sentinel-2.png | Bin .../Images/ImageryProviders/stamenToner.png | Bin .../ImageryProviders/stamenWatercolor.png | Bin .../Source}/Images/NavigationHelp/Mouse.svg | 0 .../Images/NavigationHelp/MouseLeft.svg | 0 .../Images/NavigationHelp/MouseMiddle.svg | 0 .../Images/NavigationHelp/MouseRight.svg | 0 .../Source}/Images/NavigationHelp/Touch.svg | 0 .../Images/NavigationHelp/TouchDrag.svg | 0 .../Images/NavigationHelp/TouchRotate.svg | 0 .../Images/NavigationHelp/TouchTilt.svg | 0 .../Images/NavigationHelp/TouchZoom.svg | 0 .../TerrainProviders/CesiumWorldTerrain.png | Bin .../Images/TerrainProviders/Ellipsoid.png | Bin .../widgets/Source}/Images/TimelineIcons.png | Bin .../widgets/Source}/Images/info-loading.gif | Bin .../widgets/Source}/InfoBox/InfoBox.css | 0 .../widgets/Source}/InfoBox/InfoBox.js | 16 +- .../Source}/InfoBox/InfoBoxDescription.css | 0 .../Source}/InfoBox/InfoBoxViewModel.js | 5 +- .../widgets/Source}/InspectorShared.js | 3 +- .../NavigationHelpButton.css | 0 .../NavigationHelpButton.js | 18 +- .../NavigationHelpButtonViewModel.js | 2 +- .../Source}/NavigationHelpButton/lighter.css | 0 .../PerformanceWatchdog.css | 0 .../PerformanceWatchdog.js | 12 +- .../PerformanceWatchdogViewModel.js | 14 +- .../ProjectionPicker/ProjectionPicker.css | 0 .../ProjectionPicker/ProjectionPicker.js | 14 +- .../ProjectionPickerViewModel.js | 16 +- .../SceneModePicker/SceneModePicker.css | 0 .../SceneModePicker/SceneModePicker.js | 14 +- .../SceneModePickerViewModel.js | 16 +- .../SelectionIndicator/SelectionIndicator.css | 0 .../SelectionIndicator/SelectionIndicator.js | 12 +- .../SelectionIndicatorViewModel.js | 16 +- .../widgets/Source}/SvgPathBindingHandler.js | 0 .../Source}/ThirdParty/knockout-3.5.1.js | 0 .../Source}/ThirdParty/knockout-es5.js | 0 .../widgets/Source}/ThirdParty/knockout.js | 2 +- .../widgets/Source}/Timeline/Timeline.css | 0 .../widgets/Source}/Timeline/Timeline.js | 14 +- .../Timeline/TimelineHighlightRange.js | 3 +- .../widgets/Source}/Timeline/TimelineTrack.js | 4 +- .../widgets/Source}/Timeline/lighter.css | 0 .../widgets/Source}/ToggleButtonViewModel.js | 6 +- .../widgets/Source}/VRButton/VRButton.css | 0 .../widgets/Source}/VRButton/VRButton.js | 12 +- .../Source}/VRButton/VRButtonViewModel.js | 20 +- .../widgets/Source}/Viewer/Viewer.css | 0 .../widgets/Source}/Viewer/Viewer.js | 64 +- .../viewerCesium3DTilesInspectorMixin.js | 2 +- .../Viewer/viewerCesiumInspectorMixin.js | 3 +- .../Source}/Viewer/viewerDragDropMixin.js | 23 +- .../Viewer/viewerPerformanceWatchdogMixin.js | 4 +- .../widgets/Source}/createCommand.js | 7 +- .../widgets/Source}/lighter.css | 2 +- .../widgets/Source}/lighterShared.css | 0 .../widgets/Source}/shared.css | 0 .../widgets/Source}/subscribeAndEvaluate.js | 2 +- .../widgets/Source}/widgets.css | 2 +- packages/widgets/Specs/.eslintrc.json | 10 + .../widgets/Specs}/Animation/AnimationSpec.js | 13 +- .../Animation/AnimationViewModelSpec.js | 10 +- .../BaseLayerPicker/BaseLayerPickerSpec.js | 7 +- .../BaseLayerPickerViewModelSpec.js | 6 +- .../BaseLayerPicker/ProviderViewModelSpec.js | 6 +- .../Cesium3DTilesInspectorSpec.js | 10 +- .../Cesium3DTilesInspectorViewModelSpec.js | 10 +- .../CesiumInspector/CesiumInspectorSpec.js | 9 +- .../CesiumInspectorViewModelSpec.js | 8 +- .../widgets/Specs}/ClockViewModelSpec.js | 9 +- .../FullscreenButton/FullscreenButtonSpec.js | 2 +- .../FullscreenButtonViewModelSpec.js | 7 +- .../widgets/Specs}/Geocoder/GeocoderSpec.js | 4 +- .../Specs}/Geocoder/GeocoderViewModelSpec.js | 11 +- .../Specs}/HomeButton/HomeButtonSpec.js | 4 +- .../HomeButton/HomeButtonViewModelSpec.js | 9 +- .../widgets/Specs}/InfoBox/InfoBoxSpec.js | 5 +- .../Specs}/InfoBox/InfoBoxViewModelSpec.js | 2 +- .../NavigationHelpButtonSpec.js | 9 +- .../NavigationHelpButtonViewModelSpec.js | 2 +- .../PerformanceWatchdogSpec.js | 4 +- .../PerformanceWatchdogViewModelSpec.js | 13 +- .../ProjectionPicker/ProjectionPickerSpec.js | 11 +- .../ProjectionPickerViewModelSpec.js | 7 +- .../SceneModePicker/SceneModePickerSpec.js | 11 +- .../SceneModePickerViewModelSpec.js | 13 +- .../SelectionIndicatorSpec.js | 4 +- .../SelectionIndicatorViewModelSpec.js | 10 +- .../Specs}/SvgPathBindingHandlerSpec.js | 2 +- .../widgets/Specs}/ThirdParty/knockoutSpec.js | 2 +- .../widgets/Specs}/Timeline/TimelineSpec.js | 4 +- .../widgets/Specs}/VRButton/VRButtonSpec.js | 4 +- .../Specs}/VRButton/VRButtonViewModelSpec.js | 5 +- .../widgets/Specs}/Viewer/ViewerSpec.js | 15 +- .../Specs}/Viewer/viewerDragDropMixinSpec.js | 16 +- .../viewerPerformanceWatchdogMixinSpec.js | 4 +- .../widgets/Specs}/createCommandSpec.js | 4 +- packages/widgets/Specs/test.mjs | 9 + packages/widgets/package.json | 52 + packages/widgets/tsd-conf.json | 32 + server.js | 84 +- travis/test-release.sh | 6 + travis/verify.sh | 5 +- 2141 files changed, 5018 insertions(+), 2412 deletions(-) rename {Source => packages}/.eslintrc.json (100%) create mode 100644 packages/engine/.gitignore create mode 100644 packages/engine/LICENSE.md create mode 100644 packages/engine/README.md rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_0.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_1.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_10.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_11.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_12.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_13.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_14.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_15.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_16.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_17.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_18.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_19.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_2.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_20.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_21.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_22.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_23.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_24.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_25.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_26.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_27.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_3.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_4.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_5.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_6.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_7.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_8.json (100%) rename {Source => packages/engine/Source}/Assets/IAU2006_XYS/IAU2006_XYS_9.json (100%) rename {Source => packages/engine/Source}/Assets/Images/bing_maps_credit.png (100%) rename {Source => packages/engine/Source}/Assets/Images/cesium_credit.png (100%) rename {Source => packages/engine/Source}/Assets/Images/google_earth_credit.png (100%) rename {Source => packages/engine/Source}/Assets/Images/ion-credit.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/LensFlare/DirtMask.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/LensFlare/StarBurst.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/0/0/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/0/1/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/0/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/0/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/1/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/1/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/2/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/2/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/3/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/1/3/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/0/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/0/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/0/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/0/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/1/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/1/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/1/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/1/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/2/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/2/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/2/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/2/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/3/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/3/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/3/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/3/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/4/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/4/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/4/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/4/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/5/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/5/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/5/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/5/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/6/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/6/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/6/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/6/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/7/0.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/7/1.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/7/2.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/2/7/3.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/NaturalEarthII/tilemapresource.xml (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_my.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_px.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_py.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/airfield.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/airport.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/alcohol-shop.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/america-football.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/art-gallery.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/bakery.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/bank.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/bar.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/baseball.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/basketball.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/beer.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/bicycle.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/building.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/bus.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cafe.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/camera.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/campsite.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/car.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cemetery.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cesium.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/chemist.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cinema.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/circle-stroked.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/circle.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/city.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/clothing-store.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/college.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/commercial.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cricket.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/cross.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/dam.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/danger.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/disability.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/dog-park.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/embassy.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/emergency-telephone.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/entrance.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/farm.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/fast-food.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/ferry.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/fire-station.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/fuel.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/garden.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/gift.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/golf.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/grocery.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/hairdresser.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/harbor.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/heart.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/heliport.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/hospital.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/ice-cream.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/industrial.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/land-use.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/laundry.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/library.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/lighthouse.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/lodging.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/logging.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/london-underground.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/marker-stroked.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/marker.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/minefield.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/mobilephone.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/monument.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/museum.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/music.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/oil-well.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/park.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/park2.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/parking-garage.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/parking.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/pharmacy.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/pitch.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/place-of-worship.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/playground.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/police.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/polling-place.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/post.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/prison.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rail-above.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rail-light.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rail-metro.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rail-underground.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rail.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/religious-christian.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/religious-jewish.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/religious-muslim.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/restaurant.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/roadblock.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/rocket.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/school.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/scooter.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/shop.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/skiing.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/slaughterhouse.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/soccer.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/square-stroked.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/square.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/star-stroked.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/star.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/suitcase.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/swimming.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/telephone.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/tennis.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/theatre.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/toilets.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/town-hall.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/town.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/triangle-stroked.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/triangle.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/village.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/warehouse.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/waste-basket.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/water.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/wetland.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/maki/zoo.png (100%) rename {Source => packages/engine/Source}/Assets/Textures/moonSmall.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/pin.svg (100%) rename {Source => packages/engine/Source}/Assets/Textures/waterNormals.jpg (100%) rename {Source => packages/engine/Source}/Assets/Textures/waterNormalsSmall.jpg (100%) rename {Source => packages/engine/Source}/Assets/approximateTerrainHeights.json (100%) rename {Source => packages/engine/Source}/Core/ApproximateTerrainHeights.js (99%) rename {Source => packages/engine/Source}/Core/ArcGISTiledElevationTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/ArcType.js (100%) rename {Source => packages/engine/Source}/Core/ArticulationStageType.js (100%) rename {Source => packages/engine/Source}/Core/AssociativeArray.js (100%) rename {Source => packages/engine/Source}/Core/AttributeCompression.js (100%) rename {Source => packages/engine/Source}/Core/AxisAlignedBoundingBox.js (100%) rename {Source => packages/engine/Source}/Core/BingMapsGeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/BoundingRectangle.js (100%) rename {Source => packages/engine/Source}/Core/BoundingSphere.js (100%) rename {Source => packages/engine/Source}/Core/BoxGeometry.js (100%) rename {Source => packages/engine/Source}/Core/BoxOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Cartesian2.js (100%) rename {Source => packages/engine/Source}/Core/Cartesian3.js (100%) rename {Source => packages/engine/Source}/Core/Cartesian4.js (100%) rename {Source => packages/engine/Source}/Core/Cartographic.js (100%) rename {Source => packages/engine/Source}/Core/CartographicGeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/CatmullRomSpline.js (100%) rename {Source => packages/engine/Source}/Core/CesiumTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/Check.js (100%) rename {Source => packages/engine/Source}/Core/CircleGeometry.js (100%) rename {Source => packages/engine/Source}/Core/CircleOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Clock.js (100%) rename {Source => packages/engine/Source}/Core/ClockRange.js (100%) rename {Source => packages/engine/Source}/Core/ClockStep.js (100%) rename {Source => packages/engine/Source}/Core/Color.js (100%) rename {Source => packages/engine/Source}/Core/ColorGeometryInstanceAttribute.js (100%) rename {Source => packages/engine/Source}/Core/ComponentDatatype.js (100%) rename {Source => packages/engine/Source}/Core/CompressedTextureBuffer.js (100%) rename {Source => packages/engine/Source}/Core/ConstantSpline.js (100%) rename {Source => packages/engine/Source}/Core/CoplanarPolygonGeometry.js (100%) rename {Source => packages/engine/Source}/Core/CoplanarPolygonGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/CoplanarPolygonOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/CornerType.js (100%) rename {Source => packages/engine/Source}/Core/CorridorGeometry.js (100%) rename {Source => packages/engine/Source}/Core/CorridorGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/CorridorOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Credit.js (100%) rename {Source => packages/engine/Source}/Core/CubicRealPolynomial.js (100%) rename {Source => packages/engine/Source}/Core/CullingVolume.js (100%) rename {Source => packages/engine/Source}/Core/CustomHeightmapTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/CylinderGeometry.js (100%) rename {Source => packages/engine/Source}/Core/CylinderGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/CylinderOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/DefaultProxy.js (100%) rename {Source => packages/engine/Source}/Core/DeveloperError.js (100%) rename {Source => packages/engine/Source}/Core/DistanceDisplayCondition.js (100%) rename {Source => packages/engine/Source}/Core/DistanceDisplayConditionGeometryInstanceAttribute.js (100%) rename {Source => packages/engine/Source}/Core/DoubleEndedPriorityQueue.js (100%) rename {Source => packages/engine/Source}/Core/DoublyLinkedList.js (100%) rename {Source => packages/engine/Source}/Core/EarthOrientationParameters.js (100%) rename {Source => packages/engine/Source}/Core/EarthOrientationParametersSample.js (100%) rename {Source => packages/engine/Source}/Core/EasingFunction.js (100%) rename {Source => packages/engine/Source}/Core/EllipseGeometry.js (100%) rename {Source => packages/engine/Source}/Core/EllipseGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/EllipseOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Ellipsoid.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidGeodesic.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidGeometry.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidRhumbLine.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidTangentPlane.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/EllipsoidalOccluder.js (100%) rename {Source => packages/engine/Source}/Core/EncodedCartesian3.js (100%) rename {Source => packages/engine/Source}/Core/Event.js (100%) rename {Source => packages/engine/Source}/Core/EventHelper.js (100%) rename {Source => packages/engine/Source}/Core/ExtrapolationType.js (100%) rename {Source => packages/engine/Source}/Core/FeatureDetection.js (100%) rename {Source => packages/engine/Source}/Core/FrustumGeometry.js (100%) rename {Source => packages/engine/Source}/Core/FrustumOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Fullscreen.js (100%) rename {Source => packages/engine/Source}/Core/GeocodeType.js (100%) rename {Source => packages/engine/Source}/Core/GeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/GeographicProjection.js (100%) rename {Source => packages/engine/Source}/Core/GeographicTilingScheme.js (100%) rename {Source => packages/engine/Source}/Core/Geometry.js (100%) rename {Source => packages/engine/Source}/Core/GeometryAttribute.js (100%) rename {Source => packages/engine/Source}/Core/GeometryAttributes.js (100%) rename {Source => packages/engine/Source}/Core/GeometryFactory.js (100%) rename {Source => packages/engine/Source}/Core/GeometryInstance.js (100%) rename {Source => packages/engine/Source}/Core/GeometryInstanceAttribute.js (100%) rename {Source => packages/engine/Source}/Core/GeometryOffsetAttribute.js (100%) rename {Source => packages/engine/Source}/Core/GeometryPipeline.js (100%) rename {Source => packages/engine/Source}/Core/GeometryType.js (100%) rename {Source => packages/engine/Source}/Core/GoogleEarthEnterpriseMetadata.js (100%) rename {Source => packages/engine/Source}/Core/GoogleEarthEnterpriseTerrainData.js (100%) rename {Source => packages/engine/Source}/Core/GoogleEarthEnterpriseTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/GoogleEarthEnterpriseTileInformation.js (100%) rename {Source => packages/engine/Source}/Core/GregorianDate.js (100%) rename {Source => packages/engine/Source}/Core/GroundPolylineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/HeadingPitchRange.js (100%) rename {Source => packages/engine/Source}/Core/HeadingPitchRoll.js (100%) rename {Source => packages/engine/Source}/Core/Heap.js (100%) rename {Source => packages/engine/Source}/Core/HeightmapEncoding.js (100%) rename {Source => packages/engine/Source}/Core/HeightmapTerrainData.js (100%) rename {Source => packages/engine/Source}/Core/HeightmapTessellator.js (100%) rename {Source => packages/engine/Source}/Core/HermitePolynomialApproximation.js (100%) rename {Source => packages/engine/Source}/Core/HermiteSpline.js (100%) rename {Source => packages/engine/Source}/Core/HilbertOrder.js (100%) rename {Source => packages/engine/Source}/Core/Iau2000Orientation.js (100%) rename {Source => packages/engine/Source}/Core/Iau2006XysData.js (100%) rename {Source => packages/engine/Source}/Core/Iau2006XysSample.js (100%) rename {Source => packages/engine/Source}/Core/IauOrientationAxes.js (100%) rename {Source => packages/engine/Source}/Core/IauOrientationParameters.js (100%) rename {Source => packages/engine/Source}/Core/IndexDatatype.js (100%) rename {Source => packages/engine/Source}/Core/InterpolationAlgorithm.js (100%) rename {Source => packages/engine/Source}/Core/InterpolationType.js (100%) rename {Source => packages/engine/Source}/Core/Intersect.js (100%) rename {Source => packages/engine/Source}/Core/IntersectionTests.js (100%) rename {Source => packages/engine/Source}/Core/Intersections2D.js (100%) rename {Source => packages/engine/Source}/Core/Interval.js (100%) rename {Source => packages/engine/Source}/Core/Ion.js (100%) rename {Source => packages/engine/Source}/Core/IonGeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/IonResource.js (100%) rename {Source => packages/engine/Source}/Core/Iso8601.js (100%) rename {Source => packages/engine/Source}/Core/JulianDate.js (100%) rename {Source => packages/engine/Source}/Core/KTX2Transcoder.js (100%) rename {Source => packages/engine/Source}/Core/KeyboardEventModifier.js (100%) rename {Source => packages/engine/Source}/Core/LagrangePolynomialApproximation.js (100%) rename {Source => packages/engine/Source}/Core/LeapSecond.js (100%) rename {Source => packages/engine/Source}/Core/LinearApproximation.js (100%) rename {Source => packages/engine/Source}/Core/LinearSpline.js (100%) rename {Source => packages/engine/Source}/Core/ManagedArray.js (100%) rename {Source => packages/engine/Source}/Core/MapProjection.js (100%) rename {Source => packages/engine/Source}/Core/Math.js (100%) rename {Source => packages/engine/Source}/Core/Matrix2.js (100%) rename {Source => packages/engine/Source}/Core/Matrix3.js (100%) rename {Source => packages/engine/Source}/Core/Matrix4.js (100%) rename {Source => packages/engine/Source}/Core/MorphWeightSpline.js (100%) rename {Source => packages/engine/Source}/Core/MortonOrder.js (100%) rename {Source => packages/engine/Source}/Core/NearFarScalar.js (100%) rename {Source => packages/engine/Source}/Core/Occluder.js (100%) rename {Source => packages/engine/Source}/Core/OffsetGeometryInstanceAttribute.js (100%) rename {Source => packages/engine/Source}/Core/OpenCageGeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/OrientedBoundingBox.js (100%) rename {Source => packages/engine/Source}/Core/OrthographicFrustum.js (100%) rename {Source => packages/engine/Source}/Core/OrthographicOffCenterFrustum.js (100%) rename {Source => packages/engine/Source}/Core/Packable.js (100%) rename {Source => packages/engine/Source}/Core/PackableForInterpolation.js (100%) rename {Source => packages/engine/Source}/Core/PeliasGeocoderService.js (100%) rename {Source => packages/engine/Source}/Core/PerspectiveFrustum.js (100%) rename {Source => packages/engine/Source}/Core/PerspectiveOffCenterFrustum.js (100%) rename {Source => packages/engine/Source}/Core/PinBuilder.js (100%) rename {Source => packages/engine/Source}/Core/PixelFormat.js (100%) rename {Source => packages/engine/Source}/Core/Plane.js (100%) rename {Source => packages/engine/Source}/Core/PlaneGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PlaneOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PolygonGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PolygonGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/PolygonHierarchy.js (100%) rename {Source => packages/engine/Source}/Core/PolygonOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PolygonPipeline.js (100%) rename {Source => packages/engine/Source}/Core/PolylineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PolylinePipeline.js (100%) rename {Source => packages/engine/Source}/Core/PolylineVolumeGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PolylineVolumeGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/PolylineVolumeOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/PrimitiveType.js (100%) rename {Source => packages/engine/Source}/Core/Proxy.js (100%) rename {Source => packages/engine/Source}/Core/QuadraticRealPolynomial.js (100%) rename {Source => packages/engine/Source}/Core/QuantizedMeshTerrainData.js (100%) rename {Source => packages/engine/Source}/Core/QuarticRealPolynomial.js (100%) rename {Source => packages/engine/Source}/Core/Quaternion.js (100%) rename {Source => packages/engine/Source}/Core/QuaternionSpline.js (100%) rename {Source => packages/engine/Source}/Core/Queue.js (100%) rename {Source => packages/engine/Source}/Core/Ray.js (100%) rename {Source => packages/engine/Source}/Core/Rectangle.js (100%) rename {Source => packages/engine/Source}/Core/RectangleCollisionChecker.js (100%) rename {Source => packages/engine/Source}/Core/RectangleGeometry.js (100%) rename {Source => packages/engine/Source}/Core/RectangleGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/RectangleOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/ReferenceFrame.js (100%) rename {Source => packages/engine/Source}/Core/Request.js (100%) rename {Source => packages/engine/Source}/Core/RequestErrorEvent.js (100%) rename {Source => packages/engine/Source}/Core/RequestScheduler.js (100%) rename {Source => packages/engine/Source}/Core/RequestState.js (100%) rename {Source => packages/engine/Source}/Core/RequestType.js (100%) rename {Source => packages/engine/Source}/Core/Resource.js (100%) rename {Source => packages/engine/Source}/Core/RuntimeError.js (100%) rename {Source => packages/engine/Source}/Core/S2Cell.js (100%) rename {Source => packages/engine/Source}/Core/ScreenSpaceEventHandler.js (100%) rename {Source => packages/engine/Source}/Core/ScreenSpaceEventType.js (100%) rename {Source => packages/engine/Source}/Core/ShowGeometryInstanceAttribute.js (100%) rename {Source => packages/engine/Source}/Core/Simon1994PlanetaryPositions.js (100%) rename {Source => packages/engine/Source}/Core/SimplePolylineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/SphereGeometry.js (100%) rename {Source => packages/engine/Source}/Core/SphereOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/Spherical.js (100%) rename {Source => packages/engine/Source}/Core/Spline.js (100%) rename {Source => packages/engine/Source}/Core/SteppedSpline.js (100%) rename {Source => packages/engine/Source}/Core/TaskProcessor.js (100%) rename {Source => packages/engine/Source}/Core/TerrainData.js (100%) rename {Source => packages/engine/Source}/Core/TerrainEncoding.js (100%) rename {Source => packages/engine/Source}/Core/TerrainExaggeration.js (100%) rename {Source => packages/engine/Source}/Core/TerrainMesh.js (100%) rename {Source => packages/engine/Source}/Core/TerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/TerrainQuantization.js (100%) rename {Source => packages/engine/Source}/Core/TileAvailability.js (100%) rename {Source => packages/engine/Source}/Core/TileEdge.js (100%) rename {Source => packages/engine/Source}/Core/TileProviderError.js (100%) rename {Source => packages/engine/Source}/Core/TilingScheme.js (100%) rename {Source => packages/engine/Source}/Core/TimeConstants.js (100%) rename {Source => packages/engine/Source}/Core/TimeInterval.js (100%) rename {Source => packages/engine/Source}/Core/TimeIntervalCollection.js (100%) rename {Source => packages/engine/Source}/Core/TimeStandard.js (100%) rename {Source => packages/engine/Source}/Core/Tipsify.js (100%) rename {Source => packages/engine/Source}/Core/Transforms.js (100%) rename {Source => packages/engine/Source}/Core/TranslationRotationScale.js (100%) rename {Source => packages/engine/Source}/Core/TridiagonalSystemSolver.js (100%) rename {Source => packages/engine/Source}/Core/TrustedServers.js (100%) rename {Source => packages/engine/Source}/Core/VRTheWorldTerrainProvider.js (100%) rename {Source => packages/engine/Source}/Core/VertexFormat.js (100%) rename {Source => packages/engine/Source}/Core/VideoSynchronizer.js (100%) rename {Source => packages/engine/Source}/Core/Visibility.js (100%) rename {Source => packages/engine/Source}/Core/VulkanConstants.js (100%) rename {Source => packages/engine/Source}/Core/WallGeometry.js (100%) rename {Source => packages/engine/Source}/Core/WallGeometryLibrary.js (100%) rename {Source => packages/engine/Source}/Core/WallOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/Core/WebGLConstants.js (100%) rename {Source => packages/engine/Source}/Core/WebMercatorProjection.js (100%) rename {Source => packages/engine/Source}/Core/WebMercatorTilingScheme.js (100%) rename {Source => packages/engine/Source}/Core/WindingOrder.js (100%) rename {Source => packages/engine/Source}/Core/WireframeIndexGenerator.js (100%) rename {Source => packages/engine/Source}/Core/appendForwardSlash.js (100%) rename {Source => packages/engine/Source}/Core/arrayRemoveDuplicates.js (100%) rename {Source => packages/engine/Source}/Core/barycentricCoordinates.js (100%) rename {Source => packages/engine/Source}/Core/binarySearch.js (100%) rename {Source => packages/engine/Source}/Core/buildModuleUrl.js (100%) create mode 100644 packages/engine/Source/Core/cancelAnimationFrame.js rename {Source => packages/engine/Source}/Core/clone.js (100%) rename {Source => packages/engine/Source}/Core/combine.js (100%) rename {Source => packages/engine/Source}/Core/createGuid.js (100%) rename {Source => packages/engine/Source}/Core/createWorldTerrain.js (100%) rename {Source => packages/engine/Source}/Core/decodeGoogleEarthEnterpriseData.js (100%) rename {Source => packages/engine/Source}/Core/decodeVectorPolylinePositions.js (100%) rename {Source => packages/engine/Source}/Core/defaultValue.js (100%) rename {Source => packages/engine/Source}/Core/defer.js (100%) rename {Source => packages/engine/Source}/Core/defined.js (100%) rename {Source => packages/engine/Source}/Core/deprecationWarning.js (100%) rename {Source => packages/engine/Source}/Core/destroyObject.js (100%) rename {Source => packages/engine/Source}/Core/formatError.js (100%) rename {Source => packages/engine/Source}/Core/getAbsoluteUri.js (100%) rename {Source => packages/engine/Source}/Core/getBaseUri.js (100%) rename {Source => packages/engine/Source}/Core/getExtensionFromUri.js (100%) rename {Source => packages/engine/Source}/Core/getFilenameFromUri.js (100%) rename {Source => packages/engine/Source}/Core/getImageFromTypedArray.js (100%) rename {Source => packages/engine/Source}/Core/getImagePixels.js (100%) rename {Source => packages/engine/Source}/Core/getJsonFromTypedArray.js (100%) rename {Source => packages/engine/Source}/Core/getMagic.js (100%) rename {Source => packages/engine/Source}/Core/getStringFromTypedArray.js (100%) rename {Source => packages/engine/Source}/Core/getTimestamp.js (100%) rename {Source => packages/engine/Source}/Core/isBitSet.js (100%) rename {Source => packages/engine/Source}/Core/isBlobUri.js (100%) rename {Source => packages/engine/Source}/Core/isCrossOriginUrl.js (100%) rename {Source => packages/engine/Source}/Core/isDataUri.js (100%) rename {Source => packages/engine/Source}/Core/isLeapYear.js (100%) rename {Source => packages/engine/Source}/Core/loadAndExecuteScript.js (100%) rename {Source => packages/engine/Source}/Core/loadImageFromTypedArray.js (100%) rename {Source => packages/engine/Source}/Core/loadKTX2.js (100%) rename {Source => packages/engine/Source}/Core/mergeSort.js (100%) rename {Source => packages/engine/Source}/Core/objectToQuery.js (100%) rename {Source => packages/engine/Source}/Core/oneTimeWarning.js (100%) rename {Source => packages/engine/Source}/Core/parseResponseHeaders.js (100%) rename {Source => packages/engine/Source}/Core/pointInsideTriangle.js (100%) rename {Source => packages/engine/Source}/Core/queryToObject.js (100%) create mode 100644 packages/engine/Source/Core/requestAnimationFrame.js rename {Source => packages/engine/Source}/Core/resizeImageToNextPowerOfTwo.js (100%) rename {Source => packages/engine/Source}/Core/sampleTerrain.js (100%) rename {Source => packages/engine/Source}/Core/sampleTerrainMostDetailed.js (100%) rename {Source => packages/engine/Source}/Core/scaleToGeodeticSurface.js (100%) rename {Source => packages/engine/Source}/Core/subdivideArray.js (100%) rename {Source => packages/engine/Source}/Core/webGLConstantToGlslType.js (100%) rename {Source => packages/engine/Source}/Core/wrapFunction.js (100%) rename {Source => packages/engine/Source}/Core/writeTextToCanvas.js (100%) rename {Source => packages/engine/Source}/DataSources/BillboardGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/BillboardVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/BoundingSphereState.js (100%) rename {Source => packages/engine/Source}/DataSources/BoxGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/BoxGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/CallbackProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/Cesium3DTilesetGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/Cesium3DTilesetVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/CheckerboardMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/ColorMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/CompositeEntityCollection.js (100%) rename {Source => packages/engine/Source}/DataSources/CompositeMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/CompositePositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/CompositeProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/ConstantPositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/ConstantProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/CorridorGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/CorridorGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/CustomDataSource.js (100%) rename {Source => packages/engine/Source}/DataSources/CylinderGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/CylinderGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/CzmlDataSource.js (100%) rename {Source => packages/engine/Source}/DataSources/DataSource.js (100%) rename {Source => packages/engine/Source}/DataSources/DataSourceClock.js (100%) rename {Source => packages/engine/Source}/DataSources/DataSourceCollection.js (100%) rename {Source => packages/engine/Source}/DataSources/DataSourceDisplay.js (100%) rename {Source => packages/engine/Source}/DataSources/DynamicGeometryBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/DynamicGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/EllipseGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/EllipseGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/EllipsoidGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/EllipsoidGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/Entity.js (100%) rename {Source => packages/engine/Source}/DataSources/EntityCluster.js (100%) rename {Source => packages/engine/Source}/DataSources/EntityCollection.js (100%) rename {Source => packages/engine/Source}/DataSources/EntityView.js (100%) rename {Source => packages/engine/Source}/DataSources/GeoJsonDataSource.js (100%) rename {Source => packages/engine/Source}/DataSources/GeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/GeometryVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/GpxDataSource.js (100%) mode change 100755 => 100644 rename {Source => packages/engine/Source}/DataSources/GridMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/GroundGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/ImageMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/KmlCamera.js (100%) rename {Source => packages/engine/Source}/DataSources/KmlDataSource.js (99%) rename {Source => packages/engine/Source}/DataSources/KmlLookAt.js (100%) rename {Source => packages/engine/Source}/DataSources/KmlTour.js (100%) rename {Source => packages/engine/Source}/DataSources/KmlTourFlyTo.js (100%) rename {Source => packages/engine/Source}/DataSources/KmlTourWait.js (100%) rename {Source => packages/engine/Source}/DataSources/LabelGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/LabelVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/MaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/ModelGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/ModelVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/NodeTransformationProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PathGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PathVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/PlaneGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/PlaneGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PointGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PointVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/PolygonGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/PolygonGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineArrowMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineDashMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineGlowMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineOutlineMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineVisualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineVolumeGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/PolylineVolumeGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/PositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/PositionPropertyArray.js (100%) rename {Source => packages/engine/Source}/DataSources/Property.js (100%) rename {Source => packages/engine/Source}/DataSources/PropertyArray.js (100%) rename {Source => packages/engine/Source}/DataSources/PropertyBag.js (100%) rename {Source => packages/engine/Source}/DataSources/RectangleGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/RectangleGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/ReferenceProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/Rotation.js (100%) mode change 100755 => 100644 rename {Source => packages/engine/Source}/DataSources/SampledPositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/SampledProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/ScaledPositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticGeometryColorBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticGeometryPerMaterialBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticGroundGeometryColorBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticGroundGeometryPerMaterialBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticGroundPolylinePerMaterialBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StaticOutlineGeometryBatch.js (100%) rename {Source => packages/engine/Source}/DataSources/StripeMaterialProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/StripeOrientation.js (100%) rename {Source => packages/engine/Source}/DataSources/TerrainOffsetProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/TimeIntervalCollectionPositionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/TimeIntervalCollectionProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/VelocityOrientationProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/VelocityVectorProperty.js (100%) rename {Source => packages/engine/Source}/DataSources/Visualizer.js (100%) rename {Source => packages/engine/Source}/DataSources/WallGeometryUpdater.js (100%) rename {Source => packages/engine/Source}/DataSources/WallGraphics.js (100%) rename {Source => packages/engine/Source}/DataSources/createMaterialPropertyDescriptor.js (100%) rename {Source => packages/engine/Source}/DataSources/createPropertyDescriptor.js (100%) rename {Source => packages/engine/Source}/DataSources/createRawPropertyDescriptor.js (100%) rename {Source => packages/engine/Source}/DataSources/exportKml.js (100%) rename {Source/Widgets => packages/engine/Source/DataSources}/getElement.js (100%) rename {Source => packages/engine/Source}/DataSources/heightReferenceOnEntityPropertyChanged.js (100%) rename {Source => packages/engine/Source}/Renderer/AutomaticUniforms.js (100%) rename {Source => packages/engine/Source}/Renderer/Buffer.js (100%) rename {Source => packages/engine/Source}/Renderer/BufferUsage.js (100%) rename {Source => packages/engine/Source}/Renderer/ClearCommand.js (100%) rename {Source => packages/engine/Source}/Renderer/ComputeCommand.js (100%) rename {Source => packages/engine/Source}/Renderer/ComputeEngine.js (100%) rename {Source => packages/engine/Source}/Renderer/Context.js (100%) rename {Source => packages/engine/Source}/Renderer/ContextLimits.js (100%) rename {Source => packages/engine/Source}/Renderer/CubeMap.js (100%) rename {Source => packages/engine/Source}/Renderer/CubeMapFace.js (100%) rename {Source => packages/engine/Source}/Renderer/DrawCommand.js (100%) rename {Source => packages/engine/Source}/Renderer/Framebuffer.js (100%) rename {Source => packages/engine/Source}/Renderer/FramebufferManager.js (100%) rename {Source => packages/engine/Source}/Renderer/MipmapHint.js (100%) rename {Source => packages/engine/Source}/Renderer/MultisampleFramebuffer.js (100%) rename {Source => packages/engine/Source}/Renderer/Pass.js (100%) rename {Source => packages/engine/Source}/Renderer/PassState.js (100%) rename {Source => packages/engine/Source}/Renderer/PixelDatatype.js (100%) rename {Source => packages/engine/Source}/Renderer/RenderState.js (100%) rename {Source => packages/engine/Source}/Renderer/Renderbuffer.js (100%) rename {Source => packages/engine/Source}/Renderer/RenderbufferFormat.js (100%) rename {Source => packages/engine/Source}/Renderer/Sampler.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderBuilder.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderCache.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderDestination.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderFunction.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderProgram.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderSource.js (100%) rename {Source => packages/engine/Source}/Renderer/ShaderStruct.js (100%) rename {Source => packages/engine/Source}/Renderer/Texture.js (100%) rename {Source => packages/engine/Source}/Renderer/TextureCache.js (100%) rename {Source => packages/engine/Source}/Renderer/TextureMagnificationFilter.js (100%) rename {Source => packages/engine/Source}/Renderer/TextureMinificationFilter.js (100%) rename {Source => packages/engine/Source}/Renderer/TextureWrap.js (100%) rename {Source => packages/engine/Source}/Renderer/UniformState.js (100%) rename {Source => packages/engine/Source}/Renderer/VertexArray.js (100%) rename {Source => packages/engine/Source}/Renderer/VertexArrayFacade.js (100%) rename {Source => packages/engine/Source}/Renderer/createUniform.js (100%) rename {Source => packages/engine/Source}/Renderer/createUniformArray.js (100%) rename {Source => packages/engine/Source}/Renderer/freezeRenderState.js (100%) rename {Source => packages/engine/Source}/Renderer/loadCubeMap.js (100%) rename {Source => packages/engine/Source}/Renderer/modernizeShader.js (100%) rename {Source => packages/engine/Source}/Scene/AlphaMode.js (100%) rename {Source => packages/engine/Source}/Scene/Appearance.js (100%) rename {Source => packages/engine/Source}/Scene/ArcGisMapServerImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/AttributeType.js (100%) rename {Source => packages/engine/Source}/Scene/AutoExposure.js (100%) rename {Source => packages/engine/Source}/Scene/Axis.js (100%) rename {Source => packages/engine/Source}/Scene/B3dmParser.js (100%) rename {Source => packages/engine/Source}/Scene/BatchTable.js (100%) rename {Source => packages/engine/Source}/Scene/BatchTableHierarchy.js (100%) rename {Source => packages/engine/Source}/Scene/BatchTexture.js (100%) rename {Source => packages/engine/Source}/Scene/Billboard.js (100%) rename {Source => packages/engine/Source}/Scene/BillboardCollection.js (100%) rename {Source => packages/engine/Source}/Scene/BingMapsImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/BingMapsStyle.js (100%) rename {Source => packages/engine/Source}/Scene/BlendEquation.js (100%) rename {Source => packages/engine/Source}/Scene/BlendFunction.js (100%) rename {Source => packages/engine/Source}/Scene/BlendOption.js (100%) rename {Source => packages/engine/Source}/Scene/BlendingState.js (100%) rename {Source => packages/engine/Source}/Scene/BoxEmitter.js (100%) rename {Source => packages/engine/Source}/Scene/BrdfLutGenerator.js (100%) rename {Source => packages/engine/Source}/Scene/BufferLoader.js (100%) rename {Source => packages/engine/Source}/Scene/Camera.js (100%) rename {Source => packages/engine/Source}/Scene/CameraEventAggregator.js (100%) rename {Source => packages/engine/Source}/Scene/CameraEventType.js (100%) rename {Source => packages/engine/Source}/Scene/CameraFlightPath.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DContentGroup.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTile.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileBatchTable.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileColorBlendMode.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileContentFactory.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileContentState.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileContentType.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileFeature.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileFeatureTable.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileOptimizationHint.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileOptimizations.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilePass.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilePassState.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilePointFeature.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileRefine.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileStyle.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileStyleEngine.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTileset.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetCache.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetHeatmap.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetMostDetailedTraversal.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetStatistics.js (100%) rename {Source => packages/engine/Source}/Scene/Cesium3DTilesetTraversal.js (100%) rename {Source => packages/engine/Source}/Scene/CircleEmitter.js (100%) rename {Source => packages/engine/Source}/Scene/ClassificationPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/ClassificationType.js (100%) rename {Source => packages/engine/Source}/Scene/ClippingPlane.js (100%) rename {Source => packages/engine/Source}/Scene/ClippingPlaneCollection.js (100%) rename {Source => packages/engine/Source}/Scene/CloudCollection.js (100%) rename {Source => packages/engine/Source}/Scene/CloudType.js (100%) rename {Source => packages/engine/Source}/Scene/ColorBlendMode.js (100%) rename {Source => packages/engine/Source}/Scene/Composite3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/ConditionsExpression.js (100%) rename {Source => packages/engine/Source}/Scene/ConeEmitter.js (100%) rename {Source => packages/engine/Source}/Scene/ContentMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/CreditDisplay.js (100%) rename {Source => packages/engine/Source}/Scene/CullFace.js (100%) rename {Source => packages/engine/Source}/Scene/CumulusCloud.js (100%) rename {Source => packages/engine/Source}/Scene/DebugAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/DebugCameraPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/DebugInspector.js (100%) rename {Source => packages/engine/Source}/Scene/DebugModelMatrixPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/DepthFunction.js (100%) rename {Source => packages/engine/Source}/Scene/DepthPlane.js (100%) rename {Source => packages/engine/Source}/Scene/DerivedCommand.js (100%) rename {Source => packages/engine/Source}/Scene/DeviceOrientationCameraController.js (100%) rename {Source => packages/engine/Source}/Scene/DirectionalLight.js (100%) rename {Source => packages/engine/Source}/Scene/DiscardEmptyTileImagePolicy.js (100%) rename {Source => packages/engine/Source}/Scene/DiscardMissingTileImagePolicy.js (100%) rename {Source => packages/engine/Source}/Scene/DracoLoader.js (100%) rename {Source => packages/engine/Source}/Scene/EllipsoidPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/EllipsoidSurfaceAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/Empty3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/Expression.js (100%) rename {Source => packages/engine/Source}/Scene/ExpressionNodeType.js (100%) rename {Source => packages/engine/Source}/Scene/Fog.js (100%) rename {Source => packages/engine/Source}/Scene/FrameRateMonitor.js (100%) rename {Source => packages/engine/Source}/Scene/FrameState.js (100%) rename {Source => packages/engine/Source}/Scene/FrustumCommands.js (100%) rename {Source => packages/engine/Source}/Scene/Geometry3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/GetFeatureInfoFormat.js (100%) rename {Source => packages/engine/Source}/Scene/Globe.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeDepth.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeSurfaceShaderSet.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeSurfaceTile.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeSurfaceTileProvider.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeTranslucency.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeTranslucencyFramebuffer.js (100%) rename {Source => packages/engine/Source}/Scene/GlobeTranslucencyState.js (100%) rename {Source => packages/engine/Source}/Scene/GltfBufferViewLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfDracoLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfImageLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfIndexBufferLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfJsonLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfLoaderUtil.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/ForEach.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addBuffer.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addDefaults.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addExtensionsRequired.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addExtensionsUsed.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addPipelineExtras.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/addToArray.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/findAccessorMinMax.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/forEachTextureInMaterial.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/getAccessorByteStride.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/getComponentReader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/moveTechniqueRenderStates.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/moveTechniquesToExtension.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/numberOfComponentsForType.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/parseGlb.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/readAccessorPacked.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/removeExtension.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/removeExtensionsRequired.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/removeExtensionsUsed.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/removePipelineExtras.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/removeUnusedElements.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/updateAccessorComponentTypes.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/updateVersion.js (100%) rename {Source => packages/engine/Source}/Scene/GltfPipeline/usesExtension.js (100%) rename {Source => packages/engine/Source}/Scene/GltfStructuralMetadataLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfTextureLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GltfVertexBufferLoader.js (100%) rename {Source => packages/engine/Source}/Scene/GoogleEarthEnterpriseImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/GoogleEarthEnterpriseMapsProvider.js (100%) rename {Source => packages/engine/Source}/Scene/GridImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/GroundPolylinePrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/GroundPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/GroupMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/HeightReference.js (100%) rename {Source => packages/engine/Source}/Scene/HorizontalOrigin.js (100%) rename {Source => packages/engine/Source}/Scene/I3SDataProvider.js (100%) rename {Source => packages/engine/Source}/Scene/I3SFeature.js (100%) rename {Source => packages/engine/Source}/Scene/I3SField.js (100%) rename {Source => packages/engine/Source}/Scene/I3SGeometry.js (100%) rename {Source => packages/engine/Source}/Scene/I3SLayer.js (100%) rename {Source => packages/engine/Source}/Scene/I3SNode.js (100%) rename {Source => packages/engine/Source}/Scene/I3dmParser.js (100%) rename {Source => packages/engine/Source}/Scene/ImageBasedLighting.js (100%) rename {Source => packages/engine/Source}/Scene/Imagery.js (100%) rename {Source => packages/engine/Source}/Scene/ImageryLayer.js (100%) rename {Source => packages/engine/Source}/Scene/ImageryLayerCollection.js (100%) rename {Source => packages/engine/Source}/Scene/ImageryLayerFeatureInfo.js (100%) rename {Source => packages/engine/Source}/Scene/ImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/ImageryState.js (100%) rename {Source => packages/engine/Source}/Scene/Implicit3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitAvailabilityBitstream.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitMetadataView.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitSubdivisionScheme.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitSubtree.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitSubtreeMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitTileCoordinates.js (100%) rename {Source => packages/engine/Source}/Scene/ImplicitTileset.js (100%) rename {Source => packages/engine/Source}/Scene/InstanceAttributeSemantic.js (100%) rename {Source => packages/engine/Source}/Scene/InvertClassification.js (100%) rename {Source => packages/engine/Source}/Scene/IonImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/IonWorldImageryStyle.js (100%) rename {Source => packages/engine/Source}/Scene/JobScheduler.js (100%) rename {Source => packages/engine/Source}/Scene/JobType.js (100%) rename {Source => packages/engine/Source}/Scene/JsonMetadataTable.js (100%) rename {Source => packages/engine/Source}/Scene/Label.js (100%) rename {Source => packages/engine/Source}/Scene/LabelCollection.js (100%) rename {Source => packages/engine/Source}/Scene/LabelStyle.js (100%) rename {Source => packages/engine/Source}/Scene/Light.js (100%) rename {Source => packages/engine/Source}/Scene/MapMode2D.js (100%) rename {Source => packages/engine/Source}/Scene/MapboxImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/MapboxStyleImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/Material.js (100%) rename {Source => packages/engine/Source}/Scene/MaterialAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataClass.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataClassProperty.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataComponentType.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataEntity.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataEnum.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataEnumValue.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataSchema.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataSchemaLoader.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataSemantic.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataTable.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataTableProperty.js (100%) rename {Source => packages/engine/Source}/Scene/MetadataType.js (100%) rename {Source => packages/engine/Source}/Scene/Model/AlphaPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/B3dmLoader.js (100%) rename {Source => packages/engine/Source}/Scene/Model/BatchTexturePipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/CPUStylingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ClassificationModelDrawCommand.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ClassificationPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/CustomShader.js (100%) rename {Source => packages/engine/Source}/Scene/Model/CustomShaderMode.js (100%) rename {Source => packages/engine/Source}/Scene/Model/CustomShaderPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/CustomShaderTranslucencyMode.js (100%) rename {Source => packages/engine/Source}/Scene/Model/DequantizationPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/FeatureIdPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/GeoJsonLoader.js (100%) rename {Source => packages/engine/Source}/Scene/Model/GeometryPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/I3dmLoader.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ImageBasedLightingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/InstancingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/LightingModel.js (100%) rename {Source => packages/engine/Source}/Scene/Model/LightingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/MaterialPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/MetadataPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/Model.js (100%) rename {Source => packages/engine/Source}/Scene/Model/Model3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelAlphaOptions.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelAnimation.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelAnimationChannel.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelAnimationCollection.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelArticulation.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelArticulationStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelClippingPlanesPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelColorPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelDrawCommand.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelFeature.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelFeatureTable.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelLightingOptions.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelMatrixUpdateStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelNode.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelRenderResources.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelRuntimeNode.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelRuntimePrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelSceneGraph.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelSilhouettePipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelSkin.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelSplitterPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelStatistics.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelType.js (100%) rename {Source => packages/engine/Source}/Scene/Model/ModelUtility.js (100%) rename {Source => packages/engine/Source}/Scene/Model/MorphTargetsPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/NodeRenderResources.js (100%) rename {Source => packages/engine/Source}/Scene/Model/NodeStatisticsPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PickingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PntsLoader.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PointCloudStylingPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PrimitiveOutlineGenerator.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PrimitiveOutlinePipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PrimitiveRenderResources.js (100%) rename {Source => packages/engine/Source}/Scene/Model/PrimitiveStatisticsPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/SceneMode2DPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/SelectedFeatureIdPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/SkinningPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/StyleCommandsNeeded.js (100%) rename {Source => packages/engine/Source}/Scene/Model/TextureManager.js (100%) rename {Source => packages/engine/Source}/Scene/Model/TextureUniform.js (100%) rename {Source => packages/engine/Source}/Scene/Model/TilesetPipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/UniformType.js (100%) rename {Source => packages/engine/Source}/Scene/Model/VaryingType.js (100%) rename {Source => packages/engine/Source}/Scene/Model/WireframePipelineStage.js (100%) rename {Source => packages/engine/Source}/Scene/Model/buildDrawCommand.js (100%) rename {Source => packages/engine/Source}/Scene/ModelAnimationLoop.js (100%) rename {Source => packages/engine/Source}/Scene/ModelAnimationState.js (100%) rename {Source => packages/engine/Source}/Scene/ModelComponents.js (100%) rename {Source => packages/engine/Source}/Scene/Moon.js (100%) rename {Source => packages/engine/Source}/Scene/Multiple3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/NeverTileDiscardPolicy.js (100%) rename {Source => packages/engine/Source}/Scene/OIT.js (100%) rename {Source => packages/engine/Source}/Scene/OctahedralProjectedCubeMap.js (100%) rename {Source => packages/engine/Source}/Scene/OpenStreetMapImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/OrderedGroundPrimitiveCollection.js (100%) rename {Source => packages/engine/Source}/Scene/Particle.js (100%) rename {Source => packages/engine/Source}/Scene/ParticleBurst.js (100%) rename {Source => packages/engine/Source}/Scene/ParticleEmitter.js (100%) rename {Source => packages/engine/Source}/Scene/ParticleSystem.js (100%) rename {Source => packages/engine/Source}/Scene/PerInstanceColorAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/PerformanceDisplay.js (98%) rename {Source => packages/engine/Source}/Scene/PickDepth.js (100%) rename {Source => packages/engine/Source}/Scene/PickDepthFramebuffer.js (100%) rename {Source => packages/engine/Source}/Scene/PickFramebuffer.js (100%) rename {Source => packages/engine/Source}/Scene/Picking.js (100%) rename {Source => packages/engine/Source}/Scene/PntsParser.js (100%) rename {Source => packages/engine/Source}/Scene/PointCloud.js (100%) rename {Source => packages/engine/Source}/Scene/PointCloudEyeDomeLighting.js (100%) rename {Source => packages/engine/Source}/Scene/PointCloudShading.js (100%) rename {Source => packages/engine/Source}/Scene/PointPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/PointPrimitiveCollection.js (100%) rename {Source => packages/engine/Source}/Scene/Polyline.js (100%) rename {Source => packages/engine/Source}/Scene/PolylineCollection.js (100%) rename {Source => packages/engine/Source}/Scene/PolylineColorAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/PolylineMaterialAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStage.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStageCollection.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStageComposite.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStageLibrary.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStageSampleMode.js (100%) rename {Source => packages/engine/Source}/Scene/PostProcessStageTextureCache.js (100%) rename {Source => packages/engine/Source}/Scene/Primitive.js (100%) rename {Source => packages/engine/Source}/Scene/PrimitiveCollection.js (100%) rename {Source => packages/engine/Source}/Scene/PrimitiveLoadPlan.js (100%) rename {Source => packages/engine/Source}/Scene/PrimitivePipeline.js (100%) rename {Source => packages/engine/Source}/Scene/PrimitiveState.js (100%) rename {Source => packages/engine/Source}/Scene/PropertyAttribute.js (100%) rename {Source => packages/engine/Source}/Scene/PropertyAttributeProperty.js (100%) rename {Source => packages/engine/Source}/Scene/PropertyTable.js (100%) rename {Source => packages/engine/Source}/Scene/PropertyTexture.js (100%) rename {Source => packages/engine/Source}/Scene/PropertyTextureProperty.js (100%) rename {Source => packages/engine/Source}/Scene/QuadtreeOccluders.js (100%) rename {Source => packages/engine/Source}/Scene/QuadtreePrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/QuadtreeTile.js (100%) rename {Source => packages/engine/Source}/Scene/QuadtreeTileLoadState.js (100%) rename {Source => packages/engine/Source}/Scene/QuadtreeTileProvider.js (100%) rename {Source => packages/engine/Source}/Scene/ResourceCache.js (100%) rename {Source => packages/engine/Source}/Scene/ResourceCacheKey.js (100%) rename {Source => packages/engine/Source}/Scene/ResourceCacheStatistics.js (100%) rename {Source => packages/engine/Source}/Scene/ResourceLoader.js (100%) rename {Source => packages/engine/Source}/Scene/ResourceLoaderState.js (100%) rename {Source => packages/engine/Source}/Scene/SDFSettings.js (100%) rename {Source => packages/engine/Source}/Scene/Scene.js (99%) rename {Source => packages/engine/Source}/Scene/SceneFramebuffer.js (100%) rename {Source => packages/engine/Source}/Scene/SceneMode.js (100%) rename {Source => packages/engine/Source}/Scene/SceneTransforms.js (100%) rename {Source => packages/engine/Source}/Scene/SceneTransitioner.js (100%) rename {Source => packages/engine/Source}/Scene/ScreenSpaceCameraController.js (100%) rename {Source => packages/engine/Source}/Scene/ShadowMap.js (100%) rename {Source => packages/engine/Source}/Scene/ShadowMapShader.js (100%) rename {Source => packages/engine/Source}/Scene/ShadowMode.js (100%) rename {Source => packages/engine/Source}/Scene/ShadowVolumeAppearance.js (100%) rename {Source => packages/engine/Source}/Scene/SingleTileImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/SkyAtmosphere.js (100%) rename {Source => packages/engine/Source}/Scene/SkyBox.js (100%) rename {Source => packages/engine/Source}/Scene/SphereEmitter.js (100%) rename {Source => packages/engine/Source}/Scene/SplitDirection.js (100%) rename {Source => packages/engine/Source}/Scene/Splitter.js (100%) rename {Source => packages/engine/Source}/Scene/StencilConstants.js (100%) rename {Source => packages/engine/Source}/Scene/StencilFunction.js (100%) rename {Source => packages/engine/Source}/Scene/StencilOperation.js (100%) rename {Source => packages/engine/Source}/Scene/StructuralMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/StyleExpression.js (100%) rename {Source => packages/engine/Source}/Scene/Sun.js (100%) rename {Source => packages/engine/Source}/Scene/SunLight.js (100%) rename {Source => packages/engine/Source}/Scene/SunPostProcess.js (100%) rename {Source => packages/engine/Source}/Scene/SupportedImageFormats.js (100%) rename {Source => packages/engine/Source}/Scene/TerrainFillMesh.js (100%) rename {Source => packages/engine/Source}/Scene/TerrainState.js (100%) rename {Source => packages/engine/Source}/Scene/TextureAtlas.js (100%) rename {Source => packages/engine/Source}/Scene/TileBoundingRegion.js (100%) rename {Source => packages/engine/Source}/Scene/TileBoundingS2Cell.js (100%) rename {Source => packages/engine/Source}/Scene/TileBoundingSphere.js (100%) rename {Source => packages/engine/Source}/Scene/TileBoundingVolume.js (100%) rename {Source => packages/engine/Source}/Scene/TileCoordinatesImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/TileDiscardPolicy.js (100%) rename {Source => packages/engine/Source}/Scene/TileImagery.js (100%) rename {Source => packages/engine/Source}/Scene/TileMapServiceImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/TileMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/TileOrientedBoundingBox.js (100%) rename {Source => packages/engine/Source}/Scene/TileReplacementQueue.js (100%) rename {Source => packages/engine/Source}/Scene/TileSelectionResult.js (100%) rename {Source => packages/engine/Source}/Scene/TileState.js (100%) rename {Source => packages/engine/Source}/Scene/Tileset3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/TilesetMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/TimeDynamicImagery.js (100%) rename {Source => packages/engine/Source}/Scene/TimeDynamicPointCloud.js (100%) rename {Source => packages/engine/Source}/Scene/Tonemapper.js (100%) rename {Source => packages/engine/Source}/Scene/TranslucentTileClassification.js (100%) rename {Source => packages/engine/Source}/Scene/TweenCollection.js (100%) rename {Source => packages/engine/Source}/Scene/UrlTemplateImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTileBatch.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTileClampedPolylines.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTileContent.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTileGeometry.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTilePoints.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTilePolygons.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTilePolylines.js (100%) rename {Source => packages/engine/Source}/Scene/Vector3DTilePrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/VertexAttributeSemantic.js (100%) rename {Source => packages/engine/Source}/Scene/VerticalOrigin.js (100%) rename {Source => packages/engine/Source}/Scene/View.js (100%) rename {Source => packages/engine/Source}/Scene/ViewportQuad.js (100%) rename {Source => packages/engine/Source}/Scene/WebMapServiceImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/WebMapTileServiceImageryProvider.js (100%) rename {Source => packages/engine/Source}/Scene/computeFlyToLocationForRectangle.js (100%) rename {Source => packages/engine/Source}/Scene/createBillboardPointCallback.js (100%) rename {Source => packages/engine/Source}/Scene/createElevationBandMaterial.js (100%) rename {Source => packages/engine/Source}/Scene/createOsmBuildings.js (100%) rename {Source => packages/engine/Source}/Scene/createTangentSpaceDebugPrimitive.js (100%) rename {Source => packages/engine/Source}/Scene/createWorldImagery.js (100%) rename {Source => packages/engine/Source}/Scene/findContentMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/findGroupMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/findTileMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/getBinaryAccessor.js (100%) rename {Source => packages/engine/Source}/Scene/getClipAndStyleCode.js (100%) rename {Source => packages/engine/Source}/Scene/getClippingFunction.js (100%) rename {Source => packages/engine/Source}/Scene/hasExtension.js (100%) rename {Source => packages/engine/Source}/Scene/parseBatchTable.js (100%) rename {Source => packages/engine/Source}/Scene/parseBoundingVolumeSemantics.js (100%) rename {Source => packages/engine/Source}/Scene/parseFeatureMetadataLegacy.js (100%) rename {Source => packages/engine/Source}/Scene/parseStructuralMetadata.js (100%) rename {Source => packages/engine/Source}/Scene/preprocess3DTileContent.js (100%) rename {Source => packages/engine/Source}/Shaders/AdjustTranslucentFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/AllMaterialAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/AllMaterialAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/BasicMaterialAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/BasicMaterialAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/EllipsoidSurfaceAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/EllipsoidSurfaceAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PerInstanceColorAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PerInstanceFlatColorAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PerInstanceFlatColorAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PolylineColorAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/PolylineMaterialAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/TexturedMaterialAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Appearances/TexturedMaterialAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/AtmosphereCommon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/BillboardCollectionFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/BillboardCollectionVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/BrdfLutGeneratorFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/degreesPerRadian.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/depthRange.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon1.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon2.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon3.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon4.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon5.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon6.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/epsilon7.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/infinity.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/oneOverPi.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/oneOverTwoPi.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passCesium3DTile.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passClassification.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passCompute.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passEnvironment.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passGlobe.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passOpaque.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passOverlay.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passTerrainClassification.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/passTranslucent.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/pi.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/piOverFour.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/piOverSix.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/piOverThree.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/piOverTwo.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/radiansPerDegree.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/sceneMode2D.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/sceneMode3D.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/sceneModeColumbusView.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/sceneModeMorphing.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/solarRadius.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/threePiOver2.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/twoPi.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Constants/webMercatorMaxLatitude.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/HSBToRGB.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/HSLToRGB.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/RGBToHSB.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/RGBToHSL.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/RGBToXYZ.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/XYZToRGB.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/acesTonemapping.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/alphaWeight.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/antialias.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/approximateSphericalCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/backFacing.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/branchFreeTernary.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/cascadeColor.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/cascadeDistance.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/cascadeMatrix.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/cascadeWeights.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/columbusViewMorph.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/computePosition.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/cosineAndSine.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/decompressTextureCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/defaultPbrMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/depthClamp.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/eastNorthUpToEyeCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/ellipsoidContainsPoint.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/ellipsoidWgs84TextureCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/equalsEpsilon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/eyeOffset.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/eyeToWindowCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/fastApproximateAtan.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/fog.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/gammaCorrect.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/geodeticSurfaceNormal.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/getDefaultMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/getLambertDiffuse.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/getSpecular.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/getWaterNoise.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/hue.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/inverseGamma.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/isEmpty.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/isFull.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/latitudeToWebMercatorFraction.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/lineDistance.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/linearToSrgb.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/luminance.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/metersPerPixel.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/modelToWindowCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/multiplyWithColorBalance.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/nearFarScalar.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/octDecode.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/packDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/pbrLighting.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/pbrMetallicRoughnessMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/pbrSpecularGlossinessMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/phong.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/planeDistance.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/pointAlongRay.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/rayEllipsoidIntersectionInterval.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/raySphereIntersectionInterval.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/readDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/readNonPerspective.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/reverseLogDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/round.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/sampleOctahedralProjection.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/saturation.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/shadowDepthCompare.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/shadowVisibility.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/signNotZero.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/sphericalHarmonics.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/srgbToLinear.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/tangentToEyeSpaceMatrix.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/transformPlane.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/translateRelativeToEye.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/translucentPhong.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/transpose.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/unpackDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/unpackFloat.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/unpackUint.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/valueTransform.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/vertexLogDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/writeDepthClamp.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/writeLogDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Functions/writeNonPerspective.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/depthRangeStruct.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/material.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/materialInput.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/modelMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/modelVertexOutput.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/pbrParameters.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/ray.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/raySegment.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Builtin/Structs/shadowParameters.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CloudCollectionFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CloudCollectionVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CloudNoiseFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CloudNoiseVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CompareAndPackTranslucentDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/CompositeOITFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/DepthPlaneFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/DepthPlaneVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/EllipsoidFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/EllipsoidVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/FXAA3_11.glsl (100%) rename {Source => packages/engine/Source}/Shaders/GlobeFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/GlobeVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/GroundAtmosphere.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/AspectRampMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/BumpMapMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/CheckerboardMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/DotMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/ElevationBandMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/ElevationContourMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/ElevationRampMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/FadeMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/GridMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/NormalMapMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/PolylineArrowMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/PolylineDashMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/PolylineGlowMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/PolylineOutlineMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/RimLightingMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/SlopeRampMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/StripeMaterial.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Materials/Water.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/CPUStylingStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/CPUStylingStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/CustomShaderStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/CustomShaderStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/FeatureIdStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/FeatureIdStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/GeometryStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/GeometryStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ImageBasedLightingStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/InstancingStageCommon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/InstancingStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/LegacyInstancingStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/LightingStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/MaterialStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/MetadataStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/MetadataStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelClippingPlanesStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelColorStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelSilhouetteStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelSilhouetteStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelSplitterStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/ModelVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/MorphTargetsStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/PointCloudStylingStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/PrimitiveOutlineStageFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/PrimitiveOutlineStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/SelectedFeatureIdStageCommon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Model/SkinningStageVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/OctahedralProjectionAtlasFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/OctahedralProjectionFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/OctahedralProjectionVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PointPrimitiveCollectionFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PointPrimitiveCollectionVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineCommon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineShadowVolumeFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineShadowVolumeMorphFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineShadowVolumeMorphVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineShadowVolumeVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PolylineVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/AcesTonemappingStage.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/AdditiveBlend.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/AmbientOcclusionModulate.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/BlackAndWhite.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/BloomComposite.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/BrightPass.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/Brightness.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/CompositeTranslucentClassification.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/ContrastBias.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/DepthOfField.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/DepthView.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/DepthViewPacked.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/EdgeDetection.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/FXAA.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/FilmicTonemapping.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/GaussianBlur1D.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/LensFlare.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/NightVision.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/PassThrough.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/PassThroughDepth.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/PointCloudEyeDomeLighting.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/ReinhardTonemapping.glsl (100%) rename {Source => packages/engine/Source}/Shaders/PostProcessStages/Silhouette.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ReprojectWebMercatorFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ReprojectWebMercatorVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ShadowVolumeAppearanceFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ShadowVolumeAppearanceVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ShadowVolumeFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SkyAtmosphereCommon.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SkyAtmosphereFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SkyAtmosphereVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SkyBoxFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SkyBoxVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SunFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SunTextureFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/SunVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Vector3DTileClampedPolylinesFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Vector3DTileClampedPolylinesVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/Vector3DTilePolylinesVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/VectorTileVS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ViewportQuadFS.glsl (100%) rename {Source => packages/engine/Source}/Shaders/ViewportQuadVS.glsl (100%) rename {Source => packages/engine/Source}/ThirdParty/Workers/basis_transcoder.js (100%) rename {Source => packages/engine/Source}/ThirdParty/Workers/package.json (100%) rename {Source => packages/engine/Source}/ThirdParty/basis_transcoder.wasm (100%) mode change 100755 => 100644 rename {Source => packages/engine/Source}/ThirdParty/google-earth-dbroot-parser.js (100%) rename {Source/Widgets/CesiumWidget => packages/engine/Source/Widget}/CesiumWidget.css (94%) rename {Source/Widgets/CesiumWidget => packages/engine/Source/Widget}/CesiumWidget.js (96%) rename {Source/Widgets/CesiumWidget => packages/engine/Source/Widget}/lighter.css (100%) rename {Source => packages/engine/Source}/Workers/cesiumWorkerBootstrapper.js (100%) rename {Source => packages/engine/Source}/Workers/package.json (100%) rename {Source => packages/engine/Source}/Workers/transferTypedArrayTest.js (100%) rename {Source => packages/engine/Source}/WorkersES6/combineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createBoxGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createBoxOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCircleGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCircleOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCoplanarPolygonGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCoplanarPolygonOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCorridorGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCorridorOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCylinderGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createCylinderOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createEllipseGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createEllipseOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createEllipsoidGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createEllipsoidOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createFrustumGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createFrustumOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createGroundPolylineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPlaneGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPlaneOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPolygonGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPolygonOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPolylineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPolylineVolumeGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createPolylineVolumeOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createRectangleGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createRectangleOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createSimplePolylineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createSphereGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createSphereOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createTaskProcessorWorker.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVectorTileClampedPolylines.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVectorTileGeometries.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVectorTilePoints.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVectorTilePolygons.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVectorTilePolylines.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVerticesFromGoogleEarthEnterpriseBuffer.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVerticesFromHeightmap.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createVerticesFromQuantizedTerrainMesh.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createWallGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/createWallOutlineGeometry.js (100%) rename {Source => packages/engine/Source}/WorkersES6/decodeDraco.js (100%) rename {Source => packages/engine/Source}/WorkersES6/decodeGoogleEarthEnterprisePacket.js (100%) rename {Source => packages/engine/Source}/WorkersES6/decodeI3S.js (100%) rename {Source => packages/engine/Source}/WorkersES6/transcodeKTX2.js (100%) rename {Source => packages/engine/Source}/WorkersES6/upsampleQuantizedTerrainMesh.js (100%) create mode 100644 packages/engine/Specs/.eslintrc.json rename {Specs => packages/engine/Specs}/Core/ApproximateTerrainHeightsSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/ArcGISTiledElevationTerrainProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/AssociativeArraySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/AttributeCompressionSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/AxisAlignedBoundingBoxSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/BingMapsGeocoderServiceSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/BoundingRectangleSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/BoundingSphereSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/BoxGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/BoxOutlineGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/Cartesian2Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/Cartesian3Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/Cartesian4Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/CartographicGeocoderServiceSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/CartographicSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/CatmullRomSplineSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/CesiumTerrainProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/CheckSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/CircleGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/CircleOutlineGeometrySpec.js (96%) rename {Specs => packages/engine/Specs}/Core/ClockSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/ColorGeometryInstanceAttributeSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/ColorSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/ComponentDatatypeSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/ConstantSplineSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/CoplanarPolygonGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/CoplanarPolygonOutlineGeometrySpec.js (96%) rename {Specs => packages/engine/Specs}/Core/CorridorGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/CorridorOutlineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/CubicRealPolynomialSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/CullingVolumeSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/CustomHeightmapTerrainProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/CylinderGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/CylinderOutlineGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/DeveloperErrorSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/DistanceDisplayConditionGeometryInstanceAttributeSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/DistanceDisplayConditionSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/DoubleEndedPriorityQueueSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/DoublyLinkedListSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EarthOrientationParametersSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EllipseGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/EllipseOutlineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/EllipsoidGeodesicSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/EllipsoidGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/EllipsoidOutlineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/EllipsoidRhumbLineSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EllipsoidSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EllipsoidTangentPlaneSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EllipsoidTerrainProviderSpec.js (90%) rename {Specs => packages/engine/Specs}/Core/EllipsoidalOccluderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/EncodedCartesian3Spec.js (97%) rename {Specs => packages/engine/Specs}/Core/EventSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/FeatureDetectionSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/FrustumGeometrySpec.js (94%) rename {Specs => packages/engine/Specs}/Core/FrustumOutlineGeometrySpec.js (93%) rename {Specs => packages/engine/Specs}/Core/FullscreenSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/GeographicProjectionSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/GeographicTilingSchemeSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/GeometryAttributeSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/GeometryInstanceAttributeSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/GeometryInstanceSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/GeometryPipelineSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/GeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/GoogleEarthEnterpriseMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/GoogleEarthEnterpriseTerrainDataSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/GoogleEarthEnterpriseTerrainProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/GroundPolylineGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/HeadingPitchRangeSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/HeadingPitchRollSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/HeapSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/HeightmapTerrainDataSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/HermitePolynomialApproximationSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/HermiteSplineSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/HilbertOrderSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/Iau2000OrientationSpec.js (89%) rename {Specs => packages/engine/Specs}/Core/Iau2006XysDataSpec.js (95%) rename {Specs => packages/engine/Specs}/Core/IauOrientationAxesSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/IndexDatatypeSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/IntersectionTestsSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/Intersections2DSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/IntervalSpec.js (89%) rename {Specs => packages/engine/Specs}/Core/IonGeocoderServiceSpec.js (90%) rename {Specs => packages/engine/Specs}/Core/IonResourceSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/JulianDateSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/LagrangePolynomialApproximationSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/LeapSecondSpec.js (88%) rename {Specs => packages/engine/Specs}/Core/LinearApproximationSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/LinearSplineSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/ManagedArraySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/MathSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/Matrix2Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/Matrix3Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/Matrix4Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/MortonOrderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/NearFarScalarSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/OccluderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/OpenCageGeocoderServiceSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/OrientedBoundingBoxSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/OrthographicFrustumSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/OrthographicOffCenterFrustumSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PeliasGeocoderServiceSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PerspectiveFrustumSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PerspectiveOffCenterFrustumSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PinBuilderSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PixelFormatSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/PlaneGeometrySpec.js (90%) rename {Specs => packages/engine/Specs}/Core/PlaneOutlineGeometrySpec.js (74%) rename {Specs => packages/engine/Specs}/Core/PlaneSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PolygonGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/PolygonOutlineGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/PolygonPipelineSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/PolylineGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/PolylinePipelineSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PolylineVolumeGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/PolylineVolumeOutlineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/PrimitiveTypeSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/QuadraticRealPolynomialSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/QuantizedMeshTerrainDataSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/QuarticRealPolynomialSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/QuaternionSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/QuaternionSplineSpec.js (95%) rename {Specs => packages/engine/Specs}/Core/QueueSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/RaySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/RectangleCollisionCheckerSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/RectangleGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/RectangleOutlineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/RectangleSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/RequestErrorEventSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/RequestSchedulerSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/ResourceSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/RuntimeErrorSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/S2CellSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/ScreenSpaceEventHandlerSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/ShowGeometryInstanceAttributeSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/Simon1994PlanetaryPositionsSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/SimplePolylineGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/SphereGeometrySpec.js (94%) rename {Specs => packages/engine/Specs}/Core/SphereOutlineGeometrySpec.js (90%) rename {Specs => packages/engine/Specs}/Core/SphericalSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/SplineSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/SteppedSplineSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/TaskProcessorSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/TerrainEncodingSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TileAvailabilitySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TimeIntervalCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TimeIntervalSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TipsifySpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TransformsSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/TranslationRotationScaleSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/TridiagonalSystemSolverSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/TrustedServersSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/VRTheWorldTerrainProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/VertexFormatSpec.js (86%) rename {Specs => packages/engine/Specs}/Core/VideoSynchronizerSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/WallGeometrySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/WallOutlineGeometrySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/WebMercatorProjectionSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/WebMercatorTilingSchemeSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/WireframeIndexGeneratorSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/appendForwardSlashSpec.js (88%) rename {Specs => packages/engine/Specs}/Core/arrayRemoveDuplicatesSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/barycentricCoordinatesSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/binarySearchSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/buildModuleUrlSpec.js (97%) rename {Specs => packages/engine/Specs}/Core/cloneSpec.js (95%) rename {Specs => packages/engine/Specs}/Core/combineSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/createGuidSpec.js (93%) rename {Specs => packages/engine/Specs}/Core/defaultValueSpec.js (87%) rename {Specs => packages/engine/Specs}/Core/definedSpec.js (86%) rename {Specs => packages/engine/Specs}/Core/deprecationWarningSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/getAbsoluteUriSpec.js (93%) rename {Specs => packages/engine/Specs}/Core/getBaseUriSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/getExtensionFromUriSpec.js (90%) rename {Specs => packages/engine/Specs}/Core/getFilenameFromUriSpec.js (89%) rename {Specs => packages/engine/Specs}/Core/getImageFromTypedArraySpec.js (91%) rename {Specs => packages/engine/Specs}/Core/getJsonFromTypedArraySpec.js (93%) rename {Specs => packages/engine/Specs}/Core/getStringFromTypedArraySpec.js (97%) rename {Specs => packages/engine/Specs}/Core/isBlobUriSpec.js (92%) rename {Specs => packages/engine/Specs}/Core/isCrossOriginUrlSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/isDataUriSpec.js (90%) rename {Specs => packages/engine/Specs}/Core/isLeapYearSpec.js (93%) rename {Specs => packages/engine/Specs}/Core/loadImageFromTypedArraySpec.js (98%) rename {Specs => packages/engine/Specs}/Core/loadKTX2Spec.js (99%) rename {Specs => packages/engine/Specs}/Core/mergeSortSpec.js (94%) rename {Specs => packages/engine/Specs}/Core/objectToQuerySpec.js (93%) rename {Specs => packages/engine/Specs}/Core/oneTimeWarningSpec.js (91%) rename {Specs => packages/engine/Specs}/Core/parseResponseHeadersSpec.js (93%) rename {Specs => packages/engine/Specs}/Core/pointInsideTriangleSpec.js (96%) rename {Specs => packages/engine/Specs}/Core/queryToObjectSpec.js (95%) create mode 100644 packages/engine/Specs/Core/requestAnimationFrameSpec.js rename {Specs => packages/engine/Specs}/Core/resizeImageToNextPowerOfTwoSpec.js (93%) rename {Specs => packages/engine/Specs}/Core/sampleTerrainMostDetailedSpec.js (98%) rename {Specs => packages/engine/Specs}/Core/sampleTerrainSpec.js (99%) rename {Specs => packages/engine/Specs}/Core/subdivideArraySpec.js (95%) rename {Specs => packages/engine/Specs}/Core/writeTextToCanvasSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/BillboardGraphicsSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/BillboardVisualizerSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/BoxGeometryUpdaterSpec.js (94%) rename {Specs => packages/engine/Specs}/DataSources/BoxGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/CallbackPropertySpec.js (96%) rename {Specs => packages/engine/Specs}/DataSources/Cesium3DTilesetGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/Cesium3DTilesetVisualizerSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/CheckerboardMaterialPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/ColorMaterialPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/CompositeEntityCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/CompositeMaterialPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/CompositePositionPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/CompositePropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/ConstantPositionPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/ConstantPropertySpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/CorridorGeometryUpdaterSpec.js (95%) rename {Specs => packages/engine/Specs}/DataSources/CorridorGraphicsSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/CustomDataSourceSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/CylinderGeometryUpdaterSpec.js (96%) rename {Specs => packages/engine/Specs}/DataSources/CylinderGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/CzmlDataSourceSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/DataSourceClockSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/DataSourceCollectionSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/DataSourceDisplaySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/DynamicGeometryUpdaterSpec.js (95%) rename {Specs => packages/engine/Specs}/DataSources/EllipseGeometryUpdaterSpec.js (96%) rename {Specs => packages/engine/Specs}/DataSources/EllipseGraphicsSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/EllipsoidGeometryUpdaterSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/EllipsoidGraphicsSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/EntityClusterSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/EntityCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/EntitySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/EntityViewSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/GeoJsonDataSourceSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/GeometryUpdaterSpec.js (95%) rename {Specs => packages/engine/Specs}/DataSources/GeometryVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/GpxDataSourceSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/GridMaterialPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/GroundGeometryUpdaterSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/ImageMaterialPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/KmlDataSourceSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/KmlTourFlyToSpec.js (96%) rename {Specs => packages/engine/Specs}/DataSources/KmlTourSpec.js (96%) rename {Specs => packages/engine/Specs}/DataSources/LabelGraphicsSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/LabelVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/ModelGraphicsSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/ModelVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/NodeTransformationPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/PathGraphicsSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PathVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PlaneGeometryUpdaterSpec.js (91%) rename {Specs => packages/engine/Specs}/DataSources/PlaneGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/PointGraphicsSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PointVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PolygonGeometryUpdaterSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/PolygonGraphicsSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/PolylineArrowMaterialPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/PolylineDashMaterialPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PolylineGeometryUpdaterSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PolylineGlowMaterialPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/PolylineGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/PolylineOutlineMaterialPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PolylineVisualizerSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PolylineVolumeGeometryUpdaterSpec.js (95%) rename {Specs => packages/engine/Specs}/DataSources/PolylineVolumeGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/PositionPropertyArraySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/PropertyArraySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/PropertyBagSpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/RectangleGeometryUpdaterSpec.js (94%) rename {Specs => packages/engine/Specs}/DataSources/RectangleGraphicsSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/ReferencePropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/RotationSpec.js (79%) rename {Specs => packages/engine/Specs}/DataSources/SampledPositionPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/SampledPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/StaticGeometryColorBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StaticGeometryPerMaterialBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StaticGroundGeometryColorBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StaticGroundGeometryPerMaterialBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StaticGroundPolylinePerMaterialBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StaticOutlineGeometryBatchSpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/StripeMaterialPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/TerrainOffsetPropertySpec.js (91%) rename {Specs => packages/engine/Specs}/DataSources/TimeIntervalCollectionPositionPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/TimeIntervalCollectionPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/VelocityOrientationPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/DataSources/VelocityVectorPropertySpec.js (98%) rename {Specs => packages/engine/Specs}/DataSources/WallGeometryUpdaterSpec.js (95%) rename {Specs => packages/engine/Specs}/DataSources/WallGraphicsSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/createMaterialPropertyDescriptorSpec.js (97%) rename {Specs => packages/engine/Specs}/DataSources/exportKmlSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/AutomaticUniformSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/BufferSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/BuiltinFunctionsSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/ClearCommandSpec.js (94%) rename {Specs => packages/engine/Specs}/Renderer/ClearSpec.js (97%) rename {Specs => packages/engine/Specs}/Renderer/ComputeCommandSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/ContextSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/CubeMapSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/DrawCommandSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/DrawSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/FramebufferManagerSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/FramebufferSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/MultisampleFramebufferSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/PassStateSpec.js (87%) rename {Specs => packages/engine/Specs}/Renderer/RenderStateSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/RenderbufferSpec.js (97%) rename {Specs => packages/engine/Specs}/Renderer/SamplerSpec.js (95%) rename {Specs => packages/engine/Specs}/Renderer/ShaderBuilderSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/ShaderCacheSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/ShaderDestinationSpec.js (95%) rename {Specs => packages/engine/Specs}/Renderer/ShaderFunctionSpec.js (96%) rename {Specs => packages/engine/Specs}/Renderer/ShaderProgramSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/ShaderSourceSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/ShaderStructSpec.js (96%) rename {Specs => packages/engine/Specs}/Renderer/TextureCacheSpec.js (96%) rename {Specs => packages/engine/Specs}/Renderer/TextureSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/UniformSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/VertexArrayFacadeSpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/VertexArrayFactorySpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/VertexArraySpec.js (99%) rename {Specs => packages/engine/Specs}/Renderer/freezeRenderStateSpec.js (89%) rename {Specs => packages/engine/Specs}/Renderer/loadCubeMapSpec.js (98%) rename {Specs => packages/engine/Specs}/Renderer/modernizeShaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/AppearanceSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ArcGisMapServerImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/AttributeTypeSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/AxisSpec.js (89%) rename {Specs => packages/engine/Specs}/Scene/B3dmParserSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/BatchTableHierarchySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/BatchTableSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/BatchTextureSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/BillboardCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/BingMapsImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/BoxEmitterSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/BufferLoaderSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/CameraEventAggregatorSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/CameraFlightPathSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/CameraSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DContentGroupSpec.js (87%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileBatchTableSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileContentSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileContentTypeSpec.js (91%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileFeatureSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileFeatureTableSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTilePassStateSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTileStyleSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTilesetHeatmapSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTilesetMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Cesium3DTilesetSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/CircleEmitterSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/ClassificationPrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ClippingPlaneCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ClippingPlaneSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/CloudCollectionSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Composite3DTileContentSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/ConditionsExpressionSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/ConeEmitterSpec.js (89%) rename {Specs => packages/engine/Specs}/Scene/ContentMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/CreditDisplaySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/DebugAppearanceSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/DebugCameraPrimitiveSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/DebugModelMatrixPrimitiveSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/DepthPlaneSpec.js (76%) rename {Specs => packages/engine/Specs}/Scene/DeviceOrientationCameraControllerSpec.js (89%) rename {Specs => packages/engine/Specs}/Scene/DirectionalLightSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/DiscardEmptyTileImagePolicySpec.js (90%) rename {Specs => packages/engine/Specs}/Scene/DiscardMissingTileImagePolicySpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/EllipsoidPrimitiveSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/EllipsoidSurfaceAppearanceSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Empty3DTileContentSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/ExpressionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/FrameRateMonitorSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/FrustumCommandsSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/Geometry3DTileContentSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GeometryRenderingSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GlobeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GlobeSurfaceTileProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GlobeSurfaceTileSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GlobeTranslucencyFramebufferSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GlobeTranslucencyStateSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfBufferViewLoaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfBuilder.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfDracoLoaderSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/GltfImageLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GltfIndexBufferLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GltfJsonLoaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfLoaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfLoaderUtilSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GltfStructuralMetadataLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GltfTextureLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GltfVertexBufferLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/GoogleEarthEnterpriseImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GoogleEarthEnterpriseMapsProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GridImageryProviderSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/GroundPolylinePrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GroundPrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/GroupMetadataSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/HeightmapTessellatorSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/I3SDataProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/I3SLayerSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/I3SNodeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/I3dmParserSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/ImageBasedLightingSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/ImageryLayerCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImageryLayerSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Implicit3DTileContentSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImplicitAvailabilityBitstreamSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/ImplicitMetadataViewSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImplicitSubdivisionSchemeSpec.js (90%) rename {Specs => packages/engine/Specs}/Scene/ImplicitSubtreeMetadataSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImplicitSubtreeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImplicitTileCoordinatesSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ImplicitTilesetSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/InstanceAttributeSemanticSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/IonImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/JobSchedulerSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/JsonMetadataTableSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/LabelCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/LightSpec.js (85%) rename {Specs => packages/engine/Specs}/Scene/MapboxImageryProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/MapboxStyleImageryProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/MaterialAppearanceSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/MaterialSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataClassPropertySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataClassSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataComponentTypeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataEntitySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataEnumSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/MetadataEnumValueSpec.js (92%) rename {Specs => packages/engine/Specs}/Scene/MetadataSchemaLoaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataSchemaSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/MetadataTablePropertySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataTableSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/MetadataTypeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/AlphaPipelineStageSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/Model/B3dmLoaderSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/BatchTexturePipelineStageSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/Model/CPUStylingPipelineStageSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/ClassificationModelDrawCommandSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ClassificationPipelineStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/CustomShaderPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/CustomShaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/DequantizationPipelineStageSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/FeatureIdPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/GeoJsonLoaderSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/GeometryPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/I3dmLoaderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/ImageBasedLightingPipelineStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/InstancingPipelineStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/LightingPipelineStageSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/MaterialPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/MetadataPipelineStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/Model3DTileContentSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelAnimationChannelSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelAnimationCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelAnimationSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelArticulationSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelArticulationStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelClippingPlanesPipelineStageSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelColorPipelineStageSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelDrawCommandSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelFeatureSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelFeatureTableSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelMatrixUpdateStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelNodeSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelRenderResourcesSpec.js (91%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelRuntimeNodeSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelRuntimePrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelSceneGraphSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelSilhouettePipelineStageSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelSkinSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelSplitterPipelineStageSpec.js (92%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelStatisticsSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelTypeSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/Model/ModelUtilitySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/MorphTargetsPipelineStageSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/NodeRenderResourcesSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/NodeStatisticsPipelineStageSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/PickingPipelineStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/PntsLoaderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/PointCloudStylingPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/PrimitiveLoadPlanSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/PrimitiveOutlineGeneratorSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/PrimitiveOutlinePipelineStageSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/Model/PrimitiveRenderResourcesSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Model/PrimitiveStatisticsPipelineStageSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/SceneMode2DPipelineStageSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Model/SelectedFeatureIdPipelineStageSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/SkinningPipelineStageSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/Model/TextureManagerSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/Model/TextureUniformSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Model/TilesetPipelineStageSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/Model/WireframePipelineStageSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/Model/loadAndZoomToModel.js (96%) rename {Specs => packages/engine/Specs}/Scene/MoonSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/MultifrustumSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Multiple3DTileContentSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/OctahedralProjectedCubeMapSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/OpenStreetMapImageryProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/OrderedGroundPrimitiveCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ParticleSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/ParticleSystemSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/PerInstanceColorAppearanceSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/PickingSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PntsParserSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/PointCloudEyeDomeLightingSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/PointCloudShadingSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/PointPrimitiveCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PolylineCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PolylineColorAppearanceSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/PolylineMaterialAppearanceSpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/PostProcessStageCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PostProcessStageCompositeSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/PostProcessStageLibrarySpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/PostProcessStageSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/PrimitiveCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PrimitiveCullingSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/PrimitivePipelineSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/PrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PropertyAttributePropertySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PropertyAttributeSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/PropertyTableSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PropertyTexturePropertySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/PropertyTextureSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/QuadtreePrimitiveSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/QuadtreeTileSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ResourceCacheKeySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ResourceCacheSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ResourceCacheStatisticsSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ResourceLoaderSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/SceneSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/SceneTransformsSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/ScreenSpaceCameraControllerSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ShadowMapSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/ShadowVolumeAppearanceSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/SingleTileImageryProviderSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/SkyAtmosphereSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/SkyBoxSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/SphereEmitterSpec.js (94%) rename {Specs => packages/engine/Specs}/Scene/StructuralMetadataSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/StyleExpressionSpec.js (92%) rename {Specs => packages/engine/Specs}/Scene/SunLightSpec.js (89%) rename {Specs => packages/engine/Specs}/Scene/SunSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/SupportedImageFormatsSpec.js (89%) rename {Specs => packages/engine/Specs}/Scene/TerrainFillMeshSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TextureAtlasSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TileBoundingRegionSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/TileBoundingS2CellSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/TileBoundingSphereSpec.js (93%) rename {Specs => packages/engine/Specs}/Scene/TileBoundingVolumeSpec.js (87%) rename {Specs => packages/engine/Specs}/Scene/TileCoordinatesImageryProviderSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/TileImagerySpec.js (95%) rename {Specs => packages/engine/Specs}/Scene/TileMapServiceImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TileMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/TileOrientedBoundingBoxSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/TileReplacementQueueSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Tileset3DTileContentSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/TilesetMetadataSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TimeDynamicImagerySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TimeDynamicPointCloudSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TranslucentTileClassificationSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/TweenCollectionSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/UrlTemplateImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTileClampedPolylinesSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTileContentSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTileGeometrySpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTilePointsSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTilePolygonsSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/Vector3DTilePolylinesSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/VertexAttributeSemanticSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/ViewportQuadSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/WebMapServiceImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/WebMapTileServiceImageryProviderSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/computeFlyToLocationForRectangleSpec.js (97%) rename {Specs => packages/engine/Specs}/Scene/createElevationBandMaterialSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/createTangentSpaceDebugPrimitiveSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/findContentMetadataSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/findGroupMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/findTileMetadataSpec.js (96%) rename {Specs => packages/engine/Specs}/Scene/hasExtensionSpec.js (92%) rename {Specs => packages/engine/Specs}/Scene/parseBatchTableSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/parseBoundingVolumeSemanticsSpec.js (99%) rename {Specs => packages/engine/Specs}/Scene/parseFeatureMetadataLegacySpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/parseStructuralMetadataSpec.js (98%) rename {Specs => packages/engine/Specs}/Scene/preprocess3DTileContentSpec.js (98%) rename {Specs/Widgets/CesiumWidget => packages/engine/Specs/Widget}/CesiumWidgetSpec.js (98%) create mode 100644 packages/engine/Specs/test.mjs create mode 100644 packages/engine/package.json create mode 100644 packages/engine/tsd-conf.json create mode 100644 packages/widgets/.gitignore create mode 100644 packages/widgets/LICENSE.md create mode 100644 packages/widgets/README.md rename {Source/Widgets => packages/widgets/Source}/Animation/Animation.css (100%) rename {Source/Widgets => packages/widgets/Source}/Animation/Animation.js (99%) rename {Source/Widgets => packages/widgets/Source}/Animation/AnimationViewModel.js (98%) rename {Source/Widgets => packages/widgets/Source}/Animation/lighter.css (100%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/BaseLayerPicker.css (100%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/BaseLayerPicker.js (97%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/BaseLayerPickerViewModel.js (96%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/ProviderViewModel.js (93%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/createDefaultImageryProviderViewModels.js (93%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/createDefaultTerrainProviderViewModels.js (79%) rename {Source/Widgets => packages/widgets/Source}/BaseLayerPicker/lighter.css (100%) rename {Source/Widgets => packages/widgets/Source}/Cesium3DTilesInspector/Cesium3DTilesInspector.css (100%) rename {Source/Widgets => packages/widgets/Source}/Cesium3DTilesInspector/Cesium3DTilesInspector.js (97%) rename {Source/Widgets => packages/widgets/Source}/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js (98%) rename {Source/Widgets => packages/widgets/Source}/CesiumInspector/CesiumInspector.css (100%) rename {Source/Widgets => packages/widgets/Source}/CesiumInspector/CesiumInspector.js (97%) rename {Source/Widgets => packages/widgets/Source}/CesiumInspector/CesiumInspectorViewModel.js (97%) rename {Source/Widgets => packages/widgets/Source}/ClockViewModel.js (94%) rename {Source/Widgets => packages/widgets/Source}/Command.js (96%) rename {Source/Widgets => packages/widgets/Source}/FullscreenButton/FullscreenButton.css (100%) rename {Source/Widgets => packages/widgets/Source}/FullscreenButton/FullscreenButton.js (93%) rename {Source/Widgets => packages/widgets/Source}/FullscreenButton/FullscreenButtonViewModel.js (91%) rename {Source/Widgets => packages/widgets/Source}/Geocoder/Geocoder.css (100%) rename {Source/Widgets => packages/widgets/Source}/Geocoder/Geocoder.js (96%) rename {Source/Widgets => packages/widgets/Source}/Geocoder/GeocoderViewModel.js (94%) rename {Source/Widgets => packages/widgets/Source}/Geocoder/lighter.css (100%) rename {Source/Widgets => packages/widgets/Source}/HomeButton/HomeButton.js (90%) rename {Source/Widgets => packages/widgets/Source}/HomeButton/HomeButtonViewModel.js (92%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/bingAerial.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/bingAerialLabels.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/bingRoads.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/blueMarble.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/earthAtNight.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/esriNationalGeographic.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/esriWorldImagery.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/esriWorldStreetMap.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/mapQuestOpenStreetMap.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/mapboxSatellite.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/mapboxStreets.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/mapboxTerrain.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/naturalEarthII.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/openStreetMap.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/sentinel-2.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/stamenToner.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/ImageryProviders/stamenWatercolor.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/Mouse.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/MouseLeft.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/MouseMiddle.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/MouseRight.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/Touch.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/TouchDrag.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/TouchRotate.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/TouchTilt.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/NavigationHelp/TouchZoom.svg (100%) rename {Source/Widgets => packages/widgets/Source}/Images/TerrainProviders/CesiumWorldTerrain.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/TerrainProviders/Ellipsoid.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/TimelineIcons.png (100%) rename {Source/Widgets => packages/widgets/Source}/Images/info-loading.gif (100%) rename {Source/Widgets => packages/widgets/Source}/InfoBox/InfoBox.css (100%) rename {Source/Widgets => packages/widgets/Source}/InfoBox/InfoBox.js (94%) rename {Source/Widgets => packages/widgets/Source}/InfoBox/InfoBoxDescription.css (100%) rename {Source/Widgets => packages/widgets/Source}/InfoBox/InfoBoxViewModel.js (96%) rename {Source/Widgets => packages/widgets/Source}/InspectorShared.js (97%) rename {Source/Widgets => packages/widgets/Source}/NavigationHelpButton/NavigationHelpButton.css (100%) rename {Source/Widgets => packages/widgets/Source}/NavigationHelpButton/NavigationHelpButton.js (95%) rename {Source/Widgets => packages/widgets/Source}/NavigationHelpButton/NavigationHelpButtonViewModel.js (97%) rename {Source/Widgets => packages/widgets/Source}/NavigationHelpButton/lighter.css (100%) rename {Source/Widgets => packages/widgets/Source}/PerformanceWatchdog/PerformanceWatchdog.css (100%) rename {Source/Widgets => packages/widgets/Source}/PerformanceWatchdog/PerformanceWatchdog.js (92%) rename {Source/Widgets => packages/widgets/Source}/PerformanceWatchdog/PerformanceWatchdogViewModel.js (91%) rename {Source/Widgets => packages/widgets/Source}/ProjectionPicker/ProjectionPicker.css (100%) rename {Source/Widgets => packages/widgets/Source}/ProjectionPicker/ProjectionPicker.js (95%) rename {Source/Widgets => packages/widgets/Source}/ProjectionPicker/ProjectionPickerViewModel.js (92%) rename {Source/Widgets => packages/widgets/Source}/SceneModePicker/SceneModePicker.css (100%) rename {Source/Widgets => packages/widgets/Source}/SceneModePicker/SceneModePicker.js (97%) rename {Source/Widgets => packages/widgets/Source}/SceneModePicker/SceneModePickerViewModel.js (92%) rename {Source/Widgets => packages/widgets/Source}/SelectionIndicator/SelectionIndicator.css (100%) rename {Source/Widgets => packages/widgets/Source}/SelectionIndicator/SelectionIndicator.js (92%) rename {Source/Widgets => packages/widgets/Source}/SelectionIndicator/SelectionIndicatorViewModel.js (93%) rename {Source/Widgets => packages/widgets/Source}/SvgPathBindingHandler.js (100%) rename {Source => packages/widgets/Source}/ThirdParty/knockout-3.5.1.js (100%) rename {Source => packages/widgets/Source}/ThirdParty/knockout-es5.js (100%) rename {Source => packages/widgets/Source}/ThirdParty/knockout.js (78%) rename {Source/Widgets => packages/widgets/Source}/Timeline/Timeline.css (100%) rename {Source/Widgets => packages/widgets/Source}/Timeline/Timeline.js (98%) rename {Source/Widgets => packages/widgets/Source}/Timeline/TimelineHighlightRange.js (94%) rename {Source/Widgets => packages/widgets/Source}/Timeline/TimelineTrack.js (94%) rename {Source/Widgets => packages/widgets/Source}/Timeline/lighter.css (100%) rename {Source/Widgets => packages/widgets/Source}/ToggleButtonViewModel.js (88%) rename {Source/Widgets => packages/widgets/Source}/VRButton/VRButton.css (100%) rename {Source/Widgets => packages/widgets/Source}/VRButton/VRButton.js (94%) rename {Source/Widgets => packages/widgets/Source}/VRButton/VRButtonViewModel.js (91%) rename {Source/Widgets => packages/widgets/Source}/Viewer/Viewer.css (100%) rename {Source/Widgets => packages/widgets/Source}/Viewer/Viewer.js (97%) rename {Source/Widgets => packages/widgets/Source}/Viewer/viewerCesium3DTilesInspectorMixin.js (96%) rename {Source/Widgets => packages/widgets/Source}/Viewer/viewerCesiumInspectorMixin.js (92%) rename {Source/Widgets => packages/widgets/Source}/Viewer/viewerDragDropMixin.js (94%) rename {Source/Widgets => packages/widgets/Source}/Viewer/viewerPerformanceWatchdogMixin.js (91%) rename {Source/Widgets => packages/widgets/Source}/createCommand.js (87%) rename {Source/Widgets => packages/widgets/Source}/lighter.css (81%) rename {Source/Widgets => packages/widgets/Source}/lighterShared.css (100%) rename {Source/Widgets => packages/widgets/Source}/shared.css (100%) rename {Source/Widgets => packages/widgets/Source}/subscribeAndEvaluate.js (95%) rename {Source/Widgets => packages/widgets/Source}/widgets.css (92%) create mode 100644 packages/widgets/Specs/.eslintrc.json rename {Specs/Widgets => packages/widgets/Specs}/Animation/AnimationSpec.js (89%) rename {Specs/Widgets => packages/widgets/Specs}/Animation/AnimationViewModelSpec.js (99%) rename {Specs/Widgets => packages/widgets/Specs}/BaseLayerPicker/BaseLayerPickerSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/BaseLayerPicker/BaseLayerPickerViewModelSpec.js (98%) rename {Specs/Widgets => packages/widgets/Specs}/BaseLayerPicker/ProviderViewModelSpec.js (97%) rename {Specs/Widgets => packages/widgets/Specs}/Cesium3DTilesInspector/Cesium3DTilesInspectorSpec.js (89%) rename {Specs/Widgets => packages/widgets/Specs}/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js (98%) rename {Specs/Widgets => packages/widgets/Specs}/CesiumInspector/CesiumInspectorSpec.js (89%) rename {Specs/Widgets => packages/widgets/Specs}/CesiumInspector/CesiumInspectorViewModelSpec.js (97%) rename {Specs/Widgets => packages/widgets/Specs}/ClockViewModelSpec.js (96%) rename {Specs/Widgets => packages/widgets/Specs}/FullscreenButton/FullscreenButtonSpec.js (96%) rename {Specs/Widgets => packages/widgets/Specs}/FullscreenButton/FullscreenButtonViewModelSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/Geocoder/GeocoderSpec.js (95%) rename {Specs/Widgets => packages/widgets/Specs}/Geocoder/GeocoderViewModelSpec.js (97%) rename {Specs/Widgets => packages/widgets/Specs}/HomeButton/HomeButtonSpec.js (93%) rename {Specs/Widgets => packages/widgets/Specs}/HomeButton/HomeButtonViewModelSpec.js (90%) rename {Specs/Widgets => packages/widgets/Specs}/InfoBox/InfoBoxSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/InfoBox/InfoBoxViewModelSpec.js (96%) rename {Specs/Widgets => packages/widgets/Specs}/NavigationHelpButton/NavigationHelpButtonSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/NavigationHelpButton/NavigationHelpButtonViewModelSpec.js (88%) rename {Specs/Widgets => packages/widgets/Specs}/PerformanceWatchdog/PerformanceWatchdogSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/PerformanceWatchdog/PerformanceWatchdogViewModelSpec.js (96%) rename {Specs/Widgets => packages/widgets/Specs}/ProjectionPicker/ProjectionPickerSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/ProjectionPicker/ProjectionPickerViewModelSpec.js (95%) rename {Specs/Widgets => packages/widgets/Specs}/SceneModePicker/SceneModePickerSpec.js (90%) rename {Specs/Widgets => packages/widgets/Specs}/SceneModePicker/SceneModePickerViewModelSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/SelectionIndicator/SelectionIndicatorSpec.js (92%) rename {Specs/Widgets => packages/widgets/Specs}/SelectionIndicator/SelectionIndicatorViewModelSpec.js (95%) rename {Specs/Widgets => packages/widgets/Specs}/SvgPathBindingHandlerSpec.js (98%) rename {Specs => packages/widgets/Specs}/ThirdParty/knockoutSpec.js (92%) rename {Specs/Widgets => packages/widgets/Specs}/Timeline/TimelineSpec.js (88%) rename {Specs/Widgets => packages/widgets/Specs}/VRButton/VRButtonSpec.js (94%) rename {Specs/Widgets => packages/widgets/Specs}/VRButton/VRButtonViewModelSpec.js (93%) rename {Specs/Widgets => packages/widgets/Specs}/Viewer/ViewerSpec.js (99%) rename {Specs/Widgets => packages/widgets/Specs}/Viewer/viewerDragDropMixinSpec.js (97%) rename {Specs/Widgets => packages/widgets/Specs}/Viewer/viewerPerformanceWatchdogMixinSpec.js (93%) rename {Specs/Widgets => packages/widgets/Specs}/createCommandSpec.js (96%) create mode 100644 packages/widgets/Specs/test.mjs create mode 100644 packages/widgets/package.json create mode 100644 packages/widgets/tsd-conf.json create mode 100755 travis/test-release.sh diff --git a/.eslintignore b/.eslintignore index 2560a5e4588..e2233333666 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,15 +2,24 @@ Apps/HelloWorld.html Apps/Sandcastle/ThirdParty/** Build/** Documentation/** -Source/Scene/GltfPipeline/** -Source/Shaders/** -Source/ThirdParty/** -Source/Workers/** -!Source/Workers/transferTypedArrayTest.js +Source/** Specs/jasmine/** ThirdParty/** Tools/** Apps/Sandcastle/jsHintOptions.js Apps/Sandcastle/gallery/gallery-index.js index.html -index.release.html \ No newline at end of file +index.release.html + + +# packages/engine +packages/engine/Build/** +packages/engine/Source/Scene/GltfPipeline/** +packages/engine/Source/Shaders/** +packages/engine/Source/ThirdParty/** +packages/engine/Source/Workers/** +!packages/engine/Source/Workers/transferTypedArrayTest.js + +# packages/widgets +packages/widgets/Build/** +packages/widgets/Source/ThirdParty/** \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3184a481591..4e6a62ceb3a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,24 +13,14 @@ Thumbs.db /Apps/Sandcastle/gallery/gallery-index.js /Apps/Sandcastle/templates/bucket.css -/Source/Cesium.js +/Source/Assets/ +/Source/ThirdParty/ +/Source/Widgets/ /Source/Cesium.d.ts +/Source/Cesium.js /Specs/SpecList.js /Specs/jasmine/** -/Source/Shaders/**/*.js -/Source/ThirdParty/Shaders/**/*.js -/Source/Workers/** -!/Source/Workers/cesiumWorkerBootstrapper.js -!/Source/Workers/transferTypedArrayTest.js -!/Source/Workers/package.json - -Source/ThirdParty/_commonjsHelpers* -Source/ThirdParty/draco_decoder.wasm -Source/ThirdParty/Workers/draco_decoder_nodejs.js -Source/ThirdParty/Workers/pako_inflate.min.js -Source/ThirdParty/Workers/pako_deflate.min.js -Source/ThirdParty/Workers/z-worker-pako.js /Tools/jsdoc/cesium_template/static/javascript/prism.js /Tools/jsdoc/cesium_template/static/styles/prism.css diff --git a/.npmignore b/.npmignore index 79a9b497108..1d8511544a5 100644 --- a/.npmignore +++ b/.npmignore @@ -19,6 +19,8 @@ /Build/Sandcastle /Build/Specs /Cesium-*.zip +/cesium-engine-*.tgz +/cesium-widgets-*.tgz /Documentation /build.js /favicon.ico @@ -26,6 +28,7 @@ /index.html /index.release.html /launches +/packages/ /server.js /Source/copyrightHeader.js /Specs diff --git a/.prettierignore b/.prettierignore index 94968c0bdc6..6237c3b02b1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,7 +8,7 @@ !.vscode/**/ !Apps/**/ !Documentation/**/ -!Source/**/ +!packages/**/ !Specs/**/ !Tools/**/ @@ -20,16 +20,25 @@ !**/*.ts # Re-ignore a few things caught above + **/*.min.js -Source/Cesium.js -Source/Scene/GltfPipeline/** -Source/Shaders/**/*.js -Source/ThirdParty/** -Source/Workers/**/* + +packages/engine/Build/** +packages/engine/index.js +packages/engine/Source/Scene/GltfPipeline/** +packages/engine/Source/Shaders/**/*.js +packages/engine/Source/ThirdParty/** +packages/engine/Source/Workers/**/* +!packages/engine/Source/Workers/cesiumWorkerBootstrapper.js +!packages/engine/Source/Workers/transferTypedArrayTest.js + +packages/widgets/Build/** +packages/widgets/index.js +packages/widgets/Source/ThirdParty/** + Specs/jasmine/** + Apps/Sandcastle/ThirdParty Tools/jsdoc/cesium_template/static/javascript/prism.js Tools/jsdoc/cesium_template/static/styles/prism.css -!Source/Workers/cesiumWorkerBootstrapper.js -!Source/Workers/transferTypedArrayTest.js diff --git a/.travis.yml b/.travis.yml index 46c5d22491f..bf63302cd13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,14 +9,18 @@ notifications: secure: JKzk2sJSbZ9h2PUVWj6KtOAdFbEEnOtv/VZy05pJ2H41xRgUHiGdtMW/vMSeq6XX3IJN8eW2zd0cJTgkFn0ioAlYvID8zRhcvkFHg60QXquoqtp5y65dxjtVz79hefxSo7FO1NhMZBQWE9Tg6R7XkoyTMth62+T9vqOgu2Hms6M= if: (branch = main) AND (type = push) on_success: change # default: always -script: - - ./travis/prepare.sh - - npm --silent run deploy-status -- --status pending --message 'Waiting for build' +jobs: + include: + - stage: + name: "Linting, Coverage, Deployment" + script: + - ./travis/prepare.sh + - npm --silent run deploy-status -- --status pending --message 'Waiting for build' + - npm --silent run eslint + - npm --silent run markdownlint + - npm --silent run prettier-check + - ./travis/release.sh + - ./travis/deploy.sh + - name: "Release Tests" + script: ./travis/test-release.sh - - npm --silent run eslint - - npm --silent run markdownlint - - npm --silent run prettier-check - - - ./travis/release.sh - - ./travis/deploy.sh - - ./travis/verify.sh diff --git a/.vscode/launch.json b/.vscode/launch.json index eadf6f3fe77..d10ffdef066 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,116 @@ { "version": "0.2.0", "configurations": [ + { + "name": "start via NPM", + "request": "launch", + "runtimeArgs": [ + "run-script", + "test" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Launch build widgets via NPM", + "request": "launch", + "runtimeArgs": [ + "run-script", + "build", + "-w", + "@cesium/widgets" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Launch via NPM", + "request": "launch", + "runtimeArgs": [ + "run-script", + "test", + "-w", + "@cesium/engine" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "name": "Launch build engine via NPM", + "request": "launch", + "runtimeArgs": [ + "run-script", + "build", + "-w", + "@cesium/engine" + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "args": [ + "buildEngine" + ], + "name": "Gulp task - buildEngine", + "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", + "request": "launch", + "cwd": "${workspaceFolder}/packages/engine", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "args": [ + "build", + "--workspaces" + ], + "name": "Gulp task - build - workspaces", + "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "args": [ + "build" + ], + "name": "Gulp task - build", + "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "node" + }, + { + "args": [ + "build-ts", + "-w", + "@cesium/widgets" + ], + "name": "Gulp task - build-ts", + "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "node" + }, { "type": "node", "request": "launch", @@ -21,6 +131,17 @@ "type": "pwa-chrome", "url": "http://localhost:8080", "webRoot": "${workspaceFolder}" + }, + { + "type": "chrome", + "request": "attach", + "name": "Attach Karma Chrome", + "address": "localhost", + "port": 9333, + "pathMapping": { + "/": "${workspaceRoot}/", + "/base/": "${workspaceRoot}/" + } } ] } diff --git a/Apps/.eslintrc.json b/Apps/.eslintrc.json index ae9a392652a..e646ee82716 100644 --- a/Apps/.eslintrc.json +++ b/Apps/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "../Source/.eslintrc.json" + "extends": "../packages/.eslintrc.json" } diff --git a/Apps/HelloWorld.html b/Apps/HelloWorld.html index 277d7479d7b..e74dfe33d00 100644 --- a/Apps/HelloWorld.html +++ b/Apps/HelloWorld.html @@ -11,7 +11,7 @@ content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> Hello World! - + + + + + + + + + + + + + + diff --git a/Documentation/Images/Cesium_light_color.svg b/Documentation/Images/Cesium_light_color.svg new file mode 100755 index 00000000000..a4fe9e61df9 --- /dev/null +++ b/Documentation/Images/Cesium_light_color.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + diff --git a/Documentation/OfflineGuide/README.md b/Documentation/OfflineGuide/README.md index eb3a194f54d..661697ba963 100644 --- a/Documentation/OfflineGuide/README.md +++ b/Documentation/OfflineGuide/README.md @@ -30,7 +30,7 @@ const viewer = new Cesium.Viewer("cesiumContainer", { ## 3D Tiles, glTF, and other static files -Most other files loaded in CesiumJS, such as 3D Tiles or glTF, are static assets that do not require any server-side operations to load. However, since browsers commonly treat requests to load resources using the `file://` schema as cross-origin requests, it's reccomended that you set up a local server. +Most other files loaded in CesiumJS, such as 3D Tiles or glTF, are static assets that do not require any server-side operations to load. However, since browsers commonly treat requests to load resources using the `file://` schema as cross-origin requests, it's recommended that you set up a local server. 1. Download and install [Node.js](https://nodejs.org/en/download/) diff --git a/README.md b/README.md index 8bc451fca6f..cfd294b6224 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,18 @@ # CesiumJS -![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) - [![Build Status](https://travis-ci.com/CesiumGS/cesium.svg?branch=main)](https://travis-ci.com/CesiumGS/cesium) [![npm](https://img.shields.io/npm/v/cesium)](https://www.npmjs.com/package/cesium) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) + + + + + + Cesium + + + CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. Built on open formats, CesiumJS is designed for robust interoperability and scaling for massive datasets. @@ -34,7 +41,7 @@ import "cesium/Build/Cesium/Widgets/widgets.css"; const viewer = new CesiumWidgets.Viewer("cesiumContainer"); ``` -Or, import individual modules to benefit from tree shaking optmtimizations through most build tools: +Or, import individual modules to benefit from tree shaking optimizations through most build tools: ```js import { Viewer } from "cesium"; @@ -45,7 +52,7 @@ const viewer = new Viewer("cesiumContainer"); #### Packages -In addition to the `cesium` package, CesiumJS is also distrubuted as scoped npm packages for more specific dependency management: +In addition to the `cesium` package, CesiumJS is also distributed as scoped npm packages for more specific dependency management: - [`@cesium/engine`](./packages/engine/README.md) - CesiumJS's core, rendering, and data APIs - [`@cesium/widgets`](./packages/widgets/README.md) - A widgets library for use with CesiumJS @@ -75,7 +82,7 @@ Our mission is to create the leading 3D globe and map for static and time-dynami The Cesium platform follows an [open-core business model](https://cesium.com/why-cesium/open-ecosystem/cesium-business-model/) with open source runtime engines such as CesiumJS and optional commercial subscription to Cesium ion. -CesiumJS can stream [3D content such as terrain, imagery, and 3D Tiles from the commercial Cesium ion platform](https://cesium.com/platform/cesium-ion/content/) alongside open standards from other offline or online servives. We provide Cesium ion as the quickest option for all users to get up and running, but you are free to use any combination of content sources with CesiumJS that you please. +CesiumJS can stream [3D content such as terrain, imagery, and 3D Tiles from the commercial Cesium ion platform](https://cesium.com/platform/cesium-ion/content/) alongside open standards from other offline or online services. We provide Cesium ion as the quickest option for all users to get up and running, but you are free to use any combination of content sources with CesiumJS that you please. [Using Cesium ion](https://cesium.com/ion/signup/) helps support CesiumJS development. :heart: diff --git a/package.json b/package.json index 4162cc81e62..c81a574681c 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "build-docs-watch": "gulp buildDocsWatch", "eslint": "eslint \"./**/*.js\" \"./**/*.cjs\" \"./**/*.html\" --cache --quiet", "make-zip": "gulp makeZip", - "markdownlint": "markdownlint \"*.md\" \"Documentation/**/*.md\" --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", + "markdownlint": "markdownlint \"*.md\" \"Documentation/**/*.md\" \"packages/**/*.md\" --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", "release": "gulp release", "website-release": "gulp websiteRelease", "test": "gulp test", @@ -158,7 +158,7 @@ "prettier --write" ], "*.md": [ - "markdownlint --ignore CHANGES.md --ignore LICENSE.md --ignore \"./**/LICENSE.md\"", + "markdownlint --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", "prettier --write" ] }, diff --git a/packages/engine/README.md b/packages/engine/README.md index 441a753632c..a18a148d7c2 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -1,11 +1,18 @@ # @cesium/engine -![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) - [![Build Status](https://travis-ci.com/CesiumGS/cesium.svg?branch=main)](https://travis-ci.com/CesiumGS/cesium) [![npm](https://img.shields.io/npm/v/@cesium/engine)](https://www.npmjs.com/package/@cesium/engine) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) + + + + + + Cesium + + + [CesiumJS](../../README.md) is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. `@cesium/engine` includes cesiumJS's core, rendering, and data APIs. Here you'll find terrain and imagery engines, support for 3D Tiles and 3D models, geometries, and vector data. @@ -38,7 +45,7 @@ import "@cesium/engine/Source/Widget/CesiumWidget.css"; const cesiumWidget = new Cesium.CesiumWidget("cesiumContainer"); ``` -Or, import individual modules to benefit from tree shaking optmtimizations through most build tools: +Or, import individual modules to benefit from tree shaking optimizations through most build tools: ```js import { CesiumWidget } from "@cesium/engine"; diff --git a/packages/widgets/README.md b/packages/widgets/README.md index c2e0188c9a1..c2d658dad26 100644 --- a/packages/widgets/README.md +++ b/packages/widgets/README.md @@ -1,11 +1,18 @@ # @cesium/widgets -![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) - [![Build Status](https://travis-ci.com/CesiumGS/cesium.svg?branch=main)](https://travis-ci.com/CesiumGS/cesium) [![npm](https://img.shields.io/npm/v/@cesium/widgets)](https://www.npmjs.com/package/@cesium/widgets) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) + + + + + + Cesium + + + [CesiumJS](../../README.md) is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. `@cesium/widgets` is a widgets library for use with CesiumJS— including the `CesiumViewer` widget plus widgets for common tasks such as animation, base layer selection and geocoding. @@ -38,7 +45,7 @@ import "@cesium/widgets/Source/widgets.css"; const viewer = new CesiumWidgets.Viewer("cesiumContainer"); ``` -Or, import individual modules to benefit from tree shaking optmtimizations through most build tools: +Or, import individual modules to benefit from tree shaking optimizations through most build tools: ```js import { Viewer } from "@cesium/widgets"; From 10544f51c8a1f050674713bb92fc89b405489552 Mon Sep 17 00:00:00 2001 From: Sungho Lim Date: Thu, 15 Dec 2022 10:53:45 +0900 Subject: [PATCH 244/679] Add Fixed to CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c628cf3358b..5be69c125a6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - Fixed a bug where the entity collection of a `GpxDataSource` did not have the `owner` property set. [#10921](https://github.com/CesiumGS/cesium/issues/10921) - Fixed a bug where \*.ktx2 images loading fail. [#10869](https://github.com/CesiumGS/cesium/pull/10869) - Fixed a bug where a `Model` would sometimes disappear when loaded in Columbus View. [#10945](https://github.com/CesiumGS/cesium/pull/10945) +- Fixed a bug where `result` parameters were omitted from the TypeScript definitions. [#10864](https://github.com/CesiumGS/cesium/issues/10864) ### 1.100 - 2022-12-01 From df8e826f637fbf6427559d29765008c028c66a3c Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 15 Dec 2022 10:02:38 -0500 Subject: [PATCH 245/679] Rollback header image --- README.md | 9 +-------- packages/engine/README.md | 9 +-------- packages/widgets/README.md | 9 +-------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index cfd294b6224..3296d63e78a 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,7 @@ [![npm](https://img.shields.io/npm/v/cesium)](https://www.npmjs.com/package/cesium) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) - - - - - - Cesium - - +![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. diff --git a/packages/engine/README.md b/packages/engine/README.md index a18a148d7c2..a937dd8fc38 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -4,14 +4,7 @@ [![npm](https://img.shields.io/npm/v/@cesium/engine)](https://www.npmjs.com/package/@cesium/engine) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) - - - - - - Cesium - - +![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) [CesiumJS](../../README.md) is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. diff --git a/packages/widgets/README.md b/packages/widgets/README.md index c2d658dad26..460f350619d 100644 --- a/packages/widgets/README.md +++ b/packages/widgets/README.md @@ -4,14 +4,7 @@ [![npm](https://img.shields.io/npm/v/@cesium/widgets)](https://www.npmjs.com/package/@cesium/widgets) [![Docs](https://img.shields.io/badge/docs-online-orange.svg)](https://cesium.com/learn/) - - - - - - Cesium - - +![Cesium](https://github.com/CesiumGS/cesium/wiki/logos/Cesium_Logo_Color.jpg) [CesiumJS](../../README.md) is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. From d826ed62739f6bf731d970dedf08722cdc605938 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 15 Dec 2022 13:54:24 -0500 Subject: [PATCH 246/679] Update autolinker and jsep --- packages/engine/Source/DataSources/GpxDataSource.js | 8 +++----- packages/engine/Source/DataSources/KmlDataSource.js | 8 +++----- packages/engine/Source/Scene/Expression.js | 2 +- packages/engine/package.json | 5 ++--- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/engine/Source/DataSources/GpxDataSource.js b/packages/engine/Source/DataSources/GpxDataSource.js index 00e59d756a2..cd3b78cab7e 100644 --- a/packages/engine/Source/DataSources/GpxDataSource.js +++ b/packages/engine/Source/DataSources/GpxDataSource.js @@ -41,11 +41,9 @@ const autolinker = new Autolinker({ stripPrefix: false, email: false, replaceFn: function (linker, match) { - if (!match.protocolUrlMatch) { - // Prevent matching of non-explicit urls. - // i.e. foo.id won't match but http://foo.id will - return false; - } + //Prevent matching of non-explicit urls. + //i.e. foo.id won't match but http://foo.id will + return match.urlMatchType === "scheme" || match.urlMatchType === "www"; }, }); diff --git a/packages/engine/Source/DataSources/KmlDataSource.js b/packages/engine/Source/DataSources/KmlDataSource.js index ecde87be568..a1ba044f608 100644 --- a/packages/engine/Source/DataSources/KmlDataSource.js +++ b/packages/engine/Source/DataSources/KmlDataSource.js @@ -143,11 +143,9 @@ const autolinker = new Autolinker({ stripPrefix: false, email: false, replaceFn: function (match) { - if (!match.protocolUrlMatch) { - //Prevent matching of non-explicit urls. - //i.e. foo.id won't match but http://foo.id will - return false; - } + //Prevent matching of non-explicit urls. + //i.e. foo.id won't match but http://foo.id will + return match.urlMatchType === "scheme" || match.urlMatchType === "www"; }, }); diff --git a/packages/engine/Source/Scene/Expression.js b/packages/engine/Source/Scene/Expression.js index 825859c3bfc..1ccd59e4504 100644 --- a/packages/engine/Source/Scene/Expression.js +++ b/packages/engine/Source/Scene/Expression.js @@ -659,7 +659,7 @@ function parseCall(expression, ast) { const object = ast.callee.object; if (call === "test" || call === "exec") { // Make sure this is called on a valid type - if (object.callee.name !== "regExp") { + if (!defined(object.callee) || object.callee.name !== "regExp") { throw new RuntimeError(`${call} is not a function.`); } if (argsLength === 0) { diff --git a/packages/engine/package.json b/packages/engine/package.json index cbc04b75ea7..d6d84dadf0b 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -34,12 +34,12 @@ "dependencies": { "@tweenjs/tween.js": "^18.6.4", "@zip.js/zip.js": "2.4.x", - "autolinker": "^3.14.3", + "autolinker": "^4.0.0", "bitmap-sdf": "^1.0.3", "dompurify": "^2.2.2", "earcut": "^2.2.4", "grapheme-splitter": "^1.0.4", - "jsep": "^0.3.1", + "jsep": "^1.3.8", "kdbush": "^3.0.0", "ktx-parse": "^0.4.5", "lerc": "^2.0.0", @@ -52,7 +52,6 @@ "urijs": "^1.19.7" }, "type": "module", - "devDependencies": {}, "scripts": { "build": "gulp build --workspace @cesium/engine", "build-ts": "gulp buildTs --workspace @cesium/engine", From 6e106581309d9a666e57cb31c6fd73e0f0f35284 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 15 Dec 2022 13:57:26 -0500 Subject: [PATCH 247/679] Fix file watcher for workers --- server.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/server.js b/server.js index 1614b04f81c..7da1be06afd 100644 --- a/server.js +++ b/server.js @@ -232,14 +232,20 @@ const serveResult = (result, fileName, res, next) => { ignoreInitial: true, }); workerWatcher.on("all", async () => { - const start = performance.now(); - await bundleWorkers({ - path: outputDirectory, - sourcemap: true, - }); - console.log( - `Rebuilt Workers/* in ${formatTimeSinceInSeconds(start)} seconds.` - ); + try { + const start = performance.now(); + await bundleWorkers({ + input: ["packages/engine/Source/Workers/**"], + inputES6: workerSourceFiles, + path: outputDirectory, + sourcemap: true, + }); + console.log( + `Rebuilt Workers/* in ${formatTimeSinceInSeconds(start)} seconds.` + ); + } catch (e) { + console.error(e); + } }); app.get("/Build/CesiumUnminified/Cesium.js", async function ( From 4a7a9b653b5d0867c8eab2712ef632628d51050e Mon Sep 17 00:00:00 2001 From: Sanjeet Suhag Date: Thu, 15 Dec 2022 18:11:07 -0500 Subject: [PATCH 248/679] Feedback pass --- .../gallery/development/Custom Primitive.html | 6 +- CHANGES.md | 6 ++ .../Contributors/CodingGuide/README.md | 1 + .../Contributors/TestingGuide/README.md | 6 +- Documentation/CustomShaderGuide/README.md | 4 +- Documentation/FabricGuide/README.md | 4 +- .../Fabric/Examples/MaterialHierarchy2.json | 4 +- .../Fabric/Examples/TextureUniforms.json | 6 +- packages/engine/Source/Renderer/Context.js | 9 +-- .../engine/Source/Renderer/ShaderBuilder.js | 8 +-- .../engine/Source/Renderer/ShaderSource.js | 18 +++--- .../Source/Renderer/demodernizeShader.js | 13 ++-- .../Source/Scene/Cesium3DTileBatchTable.js | 4 +- .../Scene/Model/FeatureIdPipelineStage.js | 4 +- .../Source/Scene/Model/LightingModel.js | 2 +- packages/engine/Source/Scene/PointCloud.js | 2 +- .../Source/Scene/PointCloudEyeDomeLighting.js | 3 +- .../engine/Source/Scene/PolylineCollection.js | 3 +- .../Scene/PolylineMaterialAppearance.js | 5 +- .../engine/Source/Scene/PostProcessStage.js | 8 +-- packages/engine/Source/Scene/Primitive.js | 2 +- .../Source/Scene/ShadowVolumeAppearance.js | 2 +- .../Shaders/Builtin/Functions/depthClamp.glsl | 6 +- .../Builtin/Functions/textureCube.glsl | 17 +++++ .../engine/Source/Shaders/EllipsoidFS.glsl | 3 - packages/engine/Specs/Renderer/DrawSpec.js | 62 +++++++++++++++++++ .../engine/Specs/Renderer/ShaderSourceSpec.js | 12 ++-- packages/engine/Specs/Renderer/TextureSpec.js | 38 ++++++++++++ .../Specs/Renderer/demodernizeShaderSpec.js | 19 +----- 29 files changed, 190 insertions(+), 87 deletions(-) create mode 100644 packages/engine/Source/Shaders/Builtin/Functions/textureCube.glsl diff --git a/Apps/Sandcastle/gallery/development/Custom Primitive.html b/Apps/Sandcastle/gallery/development/Custom Primitive.html index 753ab7833ba..a64a480d383 100644 --- a/Apps/Sandcastle/gallery/development/Custom Primitive.html +++ b/Apps/Sandcastle/gallery/development/Custom Primitive.html @@ -184,8 +184,8 @@ // Inteference patterns made by two plane waves crossing each // other at an angle. The color is based on the height. const vertexShader = ` - attribute vec3 a_position; - varying vec3 v_position; + in vec3 a_position; + out vec3 v_position; uniform float u_time; void main() { @@ -200,7 +200,7 @@ `; const fragmentShader = ` - varying vec3 v_position; + in vec3 v_position; uniform float u_time; uniform sampler2D u_texture; void main() diff --git a/CHANGES.md b/CHANGES.md index 341f5a3193f..9f16917035a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log +#### Major Announcements :loudspeaker: + +- Starting with version 1.102, CesiumJS will default to using a WebGL2 context for rendering. + - Any custom materials, custom primitive or custom shaders will need to be upgraded to use GLSL 300. + - WebGL1 will still be supported. + ### 1.101 - 2023-01-01 ### engine diff --git a/Documentation/Contributors/CodingGuide/README.md b/Documentation/Contributors/CodingGuide/README.md index 1303f108b25..3b6218e9597 100644 --- a/Documentation/Contributors/CodingGuide/README.md +++ b/Documentation/Contributors/CodingGuide/README.md @@ -994,6 +994,7 @@ fullscreenSubscription.dispose(); - Files for vertex shaders have a `VS` suffix; fragment shaders have an `FS` suffix. For example: `BillboardCollectionVS.glsl` and `BillboardCollectionFS.glsl`. - Generally, identifiers, such as functions and variables, use `camelCase`. - Cesium built-in identifiers start with `czm_`, for example, [`czm_material`](https://github.com/CesiumGS/cesium/blob/main/Source/Shaders/Builtin/Structs/material.glsl). Files have the same name without the `czm_` prefix, e.g., `material.glsl`. +- Use `czm_textureCube` when sampling a cube map instead of `texture`. This is to preserve backwards compatibility with WebGL 1. - Varyings start with `v_`, e.g., ```javascript diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index 3773886c2a5..2488dae152c 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -494,7 +494,7 @@ Uniforms, the model matrix, and various depth options can be provided. In additi it("can declare automatic uniforms", function () { const fs = "void main() { " + - " gl_FragColor = vec4((czm_viewport.x == 0.0) && (czm_viewport.y == 0.0) && (czm_viewport.z == 1.0) && (czm_viewport.w == 1.0)); " + + " out_FragColor = vec4((czm_viewport.x == 0.0) && (czm_viewport.y == 0.0) && (czm_viewport.z == 1.0) && (czm_viewport.w == 1.0)); " + "}"; expect({ context: context, @@ -573,7 +573,7 @@ it("has czm_transpose (2x2)", function () { "void main() { " + " mat2 m = mat2(1.0, 2.0, 3.0, 4.0); " + " mat2 mt = mat2(1.0, 3.0, 2.0, 4.0); " + - " gl_FragColor = vec4(czm_transpose(m) == mt); " + + " out_FragColor = vec4(czm_transpose(m) == mt); " + "}"; context.verifyDrawForSpecs(fs); @@ -586,7 +586,7 @@ it("has czm_transpose (2x2)", function () { expect(context.readPixels()).toEqual([255, 255, 255, 255]); ``` -In the test above, the expectation is implicit in the GLSL string for the fragment shader, `fs`, which assigns white to `gl_FragColor` if `czm_transpose` correctly transposes the matrix. +In the test above, the expectation is implicit in the GLSL string for the fragment shader, `fs`, which assigns white to `out_FragColor` if `czm_transpose` correctly transposes the matrix. ### Spies diff --git a/Documentation/CustomShaderGuide/README.md b/Documentation/CustomShaderGuide/README.md index 6fa06742800..7a95e34cac7 100644 --- a/Documentation/CustomShaderGuide/README.md +++ b/Documentation/CustomShaderGuide/README.md @@ -133,8 +133,8 @@ const textureWithSampler = new Cesium.TextureUniform({ ## Varyings Varyings are declared in the `CustomShader` constructor. This automatically -adds a line such as `varying float v_userDefinedVarying;` to the top of the -GLSL shader. +adds lines such as `out float v_userDefinedVarying;` and `in float v_userDefinedVarying;` to the top of the +GLSL vertex and fragment shaders respectively. The user is responsible for assigning a value to this varying in `vertexShaderText` and using it in `fragmentShaderText`. For example: diff --git a/Documentation/FabricGuide/README.md b/Documentation/FabricGuide/README.md index 302115d549e..2996c0b3c46 100644 --- a/Documentation/FabricGuide/README.md +++ b/Documentation/FabricGuide/README.md @@ -235,7 +235,7 @@ A slightly more complicated example adds a specular component so that the materi } ``` -The `components` property contains sub-properties that define the appearance of the material. The value of each sub-property is a GLSL code snippet, hence the `vec3(0.5)` above, which creates a 3D vector with each component set to `0.5`. These have access to all GLSL functions like `mix`, `cos`, `texture2D`, etc. There are five sub-properties. +The `components` property contains sub-properties that define the appearance of the material. The value of each sub-property is a GLSL code snippet, hence the `vec3(0.5)` above, which creates a 3D vector with each component set to `0.5`. These have access to all GLSL functions like `mix`, `cos`, `texture`, etc. There are five sub-properties. | Name | Default | Description | | :---------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -358,7 +358,7 @@ We can implement our own `DiffuseMap` material by using an image uniform: image : 'czm_defaultImage' }, components : { - diffuse : 'texture2D(image, materialInput.st).rgb' + diffuse : 'texture(image, materialInput.st).rgb' } } ``` diff --git a/Documentation/Schemas/Fabric/Examples/MaterialHierarchy2.json b/Documentation/Schemas/Fabric/Examples/MaterialHierarchy2.json index 8462f1b1277..a61ad11b54a 100644 --- a/Documentation/Schemas/Fabric/Examples/MaterialHierarchy2.json +++ b/Documentation/Schemas/Fabric/Examples/MaterialHierarchy2.json @@ -5,7 +5,7 @@ "hot": "hot.jpg" }, "components" : { - "diffuse" : "texture2D(hot, materialInput.st).rgb" + "diffuse" : "texture(hot, materialInput.st).rgb" } }, "cold" : { @@ -13,7 +13,7 @@ "cold": "cold.jpg" }, "components" : { - "diffuse" : "texture2D(cold, materialInput.st).rgb" + "diffuse" : "texture(cold, materialInput.st).rgb" } } }, diff --git a/Documentation/Schemas/Fabric/Examples/TextureUniforms.json b/Documentation/Schemas/Fabric/Examples/TextureUniforms.json index 037c900d529..38e639ef125 100644 --- a/Documentation/Schemas/Fabric/Examples/TextureUniforms.json +++ b/Documentation/Schemas/Fabric/Examples/TextureUniforms.json @@ -12,8 +12,8 @@ } }, "components": { - "diffuse" : "textureCube(mycubemap, normalize(vec3(1.0))).rgb /* not an interesting reflection */", - "specular" : "texture2D(myothertexture2D, materialInput.st).r", - "emission" : "texture2D(mytexture2D, materialInput.st).rgb" + "diffuse" : "czm_textureCube(mycubemap, normalize(vec3(1.0))).rgb /* not an interesting reflection */", + "specular" : "texture(myothertexture2D, materialInput.st).r", + "emission" : "texture(mytexture2D, materialInput.st).rgb" } } \ No newline at end of file diff --git a/packages/engine/Source/Renderer/Context.js b/packages/engine/Source/Renderer/Context.js index 95abe2d6f44..d4c45887625 100644 --- a/packages/engine/Source/Renderer/Context.js +++ b/packages/engine/Source/Renderer/Context.js @@ -42,9 +42,12 @@ function Context(canvas, options) { Check.defined("canvas", canvas); //>>includeEnd('debug'); + const webgl2Supported = typeof WebGL2RenderingContext !== "undefined"; + const { getWebGLStub, - requestWebgl1 = false, + // Automatically fall back to WebGL1 if WebGL2 is not supported. + requestWebgl1 = !webgl2Supported, webgl: webglOptions = {}, allowTextureFilterAnisotropic = true, } = defaultValue(options, {}); @@ -62,9 +65,7 @@ function Context(canvas, options) { : getWebGLContext(canvas, webglOptions, requestWebgl1); // Get context type. instanceof will throw if WebGL2 is not supported - const webgl2 = - typeof WebGL2RenderingContext !== "undefined" && - glContext instanceof WebGL2RenderingContext; + const webgl2 = webgl2Supported && glContext instanceof WebGL2RenderingContext; this._canvas = canvas; this._originalGLContext = glContext; diff --git a/packages/engine/Source/Renderer/ShaderBuilder.js b/packages/engine/Source/Renderer/ShaderBuilder.js index ccc946be2bb..ddf650988a7 100644 --- a/packages/engine/Source/Renderer/ShaderBuilder.js +++ b/packages/engine/Source/Renderer/ShaderBuilder.js @@ -43,9 +43,9 @@ import ShaderFunction from "./ShaderFunction.js"; * "void main()", * "{", * " #ifdef SOLID_COLOR", - * " gl_FragColor = vec4(u_color, 1.0);", + * " out_FragColor = vec4(u_color, 1.0);", * " #else", - * " gl_FragColor = vec4(v_color, 1.0);", + * " out_FragColor = vec4(v_color, 1.0);", * " #endif", * "}" * ]); @@ -428,9 +428,9 @@ ShaderBuilder.prototype.addVertexLines = function (lines) { * "void main()", * "{", * " #ifdef SOLID_COLOR", - * " gl_FragColor = vec4(u_color, 1.0);", + * " out_FragColor = vec4(u_color, 1.0);", * " #else", - * " gl_FragColor = vec4(v_color, 1.0);", + * " out_FragColor = vec4(v_color, 1.0);", * " #endif", * "}" * ]); diff --git a/packages/engine/Source/Renderer/ShaderSource.js b/packages/engine/Source/Renderer/ShaderSource.js index 89e7c787d25..493aa622920 100644 --- a/packages/engine/Source/Renderer/ShaderSource.js +++ b/packages/engine/Source/Renderer/ShaderSource.js @@ -295,8 +295,6 @@ function combineShader(shaderSource, isFragmentShader, context) { if (!context.webgl2) { result = demodernizeShader(result, isFragmentShader); } else { - // Replace all czm_textureCube calls with texture - result = result.replaceAll(/czm_textureCube/g, `texture`); result = `#version 300 es\n${result}`; } @@ -309,21 +307,21 @@ function combineShader(shaderSource, isFragmentShader, context) { * @param {Object} [options] Object with the following properties: * @param {String[]} [options.sources] An array of strings to combine containing GLSL code for the shader. * @param {String[]} [options.defines] An array of strings containing GLSL identifiers to #define. - * @param {String} [options.pickColorQualifier] The GLSL qualifier, uniform or varying, for the input czm_pickColor. When defined, a pick fragment shader is generated. + * @param {String} [options.pickColorQualifier] The GLSL qualifier, uniform or in, for the input czm_pickColor. When defined, a pick fragment shader is generated. * @param {Boolean} [options.includeBuiltIns=true] If true, referenced built-in functions will be included with the combined shader. Set to false if this shader will become a source in another shader, to avoid duplicating functions. * - * @exception {DeveloperError} options.pickColorQualifier must be 'uniform' or 'varying'. + * @exception {DeveloperError} options.pickColorQualifier must be 'uniform' or 'in'. * * @example * // 1. Prepend #defines to a shader * const source = new Cesium.ShaderSource({ * defines : ['WHITE'], - * sources : ['void main() { \n#ifdef WHITE\n gl_FragColor = vec4(1.0); \n#else\n gl_FragColor = vec4(0.0); \n#endif\n }'] + * sources : ['void main() { \n#ifdef WHITE\n out_FragColor = vec4(1.0); \n#else\n out_FragColor = vec4(0.0); \n#endif\n }'] * }); * * // 2. Modify a fragment shader for picking * const source2 = new Cesium.ShaderSource({ - * sources : ['void main() { gl_FragColor = vec4(1.0); }'], + * sources : ['void main() { out_FragColor = vec4(1.0); }'], * pickColorQualifier : 'uniform' * }); * @@ -337,10 +335,10 @@ function ShaderSource(options) { if ( defined(pickColorQualifier) && pickColorQualifier !== "uniform" && - pickColorQualifier !== "varying" + pickColorQualifier !== "in" ) { throw new DeveloperError( - "options.pickColorQualifier must be 'uniform' or 'varying'." + "options.pickColorQualifier must be 'uniform' or 'in'." ); } //>>includeEnd('debug'); @@ -457,9 +455,7 @@ ShaderSource.createPickFragmentShaderSource = function ( "czm_old_main" ); const pickMain = - `${ - pickColorQualifier === "varying" ? "in" : "uniform" - } vec4 czm_pickColor; \n` + + `${pickColorQualifier} vec4 czm_pickColor; \n` + `void main() \n` + `{ \n` + ` czm_old_main(); \n` + diff --git a/packages/engine/Source/Renderer/demodernizeShader.js b/packages/engine/Source/Renderer/demodernizeShader.js index ec6d1de03f4..357ed8de644 100644 --- a/packages/engine/Source/Renderer/demodernizeShader.js +++ b/packages/engine/Source/Renderer/demodernizeShader.js @@ -5,6 +5,8 @@ * This function does not aim to provide a comprehensive transpilation from GLSL 3.00 to GLSL 1.00; only the functionality * used within the CesiumJS shaders is supported. * + * @private + * * @param {string} input The GLSL 3.00 shader. * @param {boolean} isFragmentShader True if the shader is a fragment shader. * @@ -16,9 +18,6 @@ function demodernizeShader(input, isFragmentShader) { // Remove version string got GLSL 3.00. output = output.replaceAll(`version 300 es`, ``); - // Replace all czm_textureCube calls with textureCube - output = output.replaceAll(/czm_textureCube/g, `textureCube`); - // Replace all texture calls with texture2D output = output.replaceAll( /(texture\()/g, @@ -30,7 +29,7 @@ function demodernizeShader(input, isFragmentShader) { output = output.replaceAll(/(in)\s+(vec\d|mat\d|float)/g, `varying $2`); if (/out_FragData_(\d+)/.test(output)) { - output = `#extension GL_EXT_draw_buffers : enable\n ${output}`; + output = `#extension GL_EXT_draw_buffers : enable\n${output}`; // Remove all layout declarations for out_FragData. output = output.replaceAll( @@ -42,7 +41,7 @@ function demodernizeShader(input, isFragmentShader) { output = output.replaceAll(/out_FragData_(\d+)/g, `gl_FragData[$1]`); } - // Replace out_FragColor with out_FragColor. + // Replace out_FragColor with gl_FragColor. output = output.replaceAll(/out_FragColor/g, `gl_FragColor`); output = output.replaceAll(/out_FragColor\[(\d+)\]/g, `gl_FragColor[$1]`); @@ -53,7 +52,7 @@ function demodernizeShader(input, isFragmentShader) { ); if (/gl_FragDepth/.test(output)) { - output = `#extension GL_EXT_frag_depth : enable\n ${output}`; + output = `#extension GL_EXT_frag_depth : enable\n${output}`; // Replace gl_FragDepth with gl_FragDepthEXT. output = output.replaceAll(/gl_FragDepth/g, `gl_FragDepthEXT`); } @@ -63,7 +62,7 @@ function demodernizeShader(input, isFragmentShader) { // Replace the out with varying. output = output.replaceAll( - /(out)\s+(vec\d|mat\d|float)\s+([A-z_0-9]+);/g, + /(out)\s+(vec\d|mat\d|float)\s+([\w]+);/g, `varying $2 $3;` ); } diff --git a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js index e77b66588f5..4430c4c0c35 100644 --- a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js +++ b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js @@ -578,7 +578,7 @@ function getDefaultShader(source, applyHighlight) { } // The color blend mode is intended for the RGB channels so alpha is always just multiplied. - // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) + // out_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) return ( `${source}uniform float tile_colorBlend; \n` + `void tile_color(vec4 tile_featureColor) \n` + @@ -668,7 +668,7 @@ function modifyDiffuse(source, diffuseAttributeOrUniformName, applyHighlight) { "} \n"; // The color blend mode is intended for the RGB channels so alpha is always just multiplied. - // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) + // out_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) const highlight = " tile_featureColor = czm_gammaCorrect(tile_featureColor); \n" + " out_FragColor.a *= tile_featureColor.a; \n" + diff --git a/packages/engine/Source/Scene/Model/FeatureIdPipelineStage.js b/packages/engine/Source/Scene/Model/FeatureIdPipelineStage.js index 75a4f26773b..6448b598426 100644 --- a/packages/engine/Source/Scene/Model/FeatureIdPipelineStage.js +++ b/packages/engine/Source/Scene/Model/FeatureIdPipelineStage.js @@ -295,13 +295,13 @@ function processImplicitRange( ); // Declare the vertex attribute in the shader - // Example: attribute float a_implicit_feature_id_n; + // Example: in float a_implicit_feature_id_n; const shaderBuilder = renderResources.shaderBuilder; const implicitAttributeName = `a_implicit_${variableName}`; shaderBuilder.addAttribute("float", implicitAttributeName); // Also declare the corresponding varyings - // Example: varying float v_implicit_feature_id_n; + // Example: in float v_implicit_feature_id_n; const implicitVaryingName = `v_implicit_${variableName}`; shaderBuilder.addVarying("float", implicitVaryingName); diff --git a/packages/engine/Source/Scene/Model/LightingModel.js b/packages/engine/Source/Scene/Model/LightingModel.js index 675ee3c5f9d..f36715f3271 100644 --- a/packages/engine/Source/Scene/Model/LightingModel.js +++ b/packages/engine/Source/Scene/Model/LightingModel.js @@ -9,7 +9,7 @@ const LightingModel = { /** * Use unlit shading, i.e. skip lighting calculations. The model's * diffuse color (assumed to be linear RGB, not sRGB) is used directly - * when computing gl_FragColor. The alpha mode is still + * when computing out_FragColor. The alpha mode is still * applied. * * @type {Number} diff --git a/packages/engine/Source/Scene/PointCloud.js b/packages/engine/Source/Scene/PointCloud.js index 2458cebf1f8..e78704c262b 100644 --- a/packages/engine/Source/Scene/PointCloud.js +++ b/packages/engine/Source/Scene/PointCloud.js @@ -947,7 +947,7 @@ function createShaders(pointCloud, frameState, style) { attributeType = `vec${componentCount}`; } - attributeDeclarations += `attribute ${attributeType} ${attributeName}; \n`; + attributeDeclarations += `in ${attributeType} ${attributeName}; \n`; attributeLocations[attributeName] = attribute.location; } diff --git a/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js b/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js index d4490212470..e247beac473 100644 --- a/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js +++ b/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js @@ -129,8 +129,7 @@ function getECShaderProgram(context, shaderProgram) { fs.sources.splice( 0, 0, - `layout (location = 0) out vec4 out_FragData_0; - layout (location = 1) out vec4 out_FragData_1;` + `layout (location = 0) out vec4 out_FragData_0;\nlayout (location = 1) out vec4 out_FragData_1;` ); fs.sources = fs.sources.map(function (source) { diff --git a/packages/engine/Source/Scene/PolylineCollection.js b/packages/engine/Source/Scene/PolylineCollection.js index c0f681cdc12..3f9150479a0 100644 --- a/packages/engine/Source/Scene/PolylineCollection.js +++ b/packages/engine/Source/Scene/PolylineCollection.js @@ -1294,8 +1294,7 @@ PolylineBucket.prototype.updateShader = function ( // Check for use of v_polylineAngle in material shader if ( - this.material.shaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== - -1 + this.material.shaderSource.search(/in\s+float\s+v_polylineAngle;/g) !== -1 ) { defines.push("POLYLINE_DASH"); } diff --git a/packages/engine/Source/Scene/PolylineMaterialAppearance.js b/packages/engine/Source/Scene/PolylineMaterialAppearance.js index 91a5c1d72cc..01f96114991 100644 --- a/packages/engine/Source/Scene/PolylineMaterialAppearance.js +++ b/packages/engine/Source/Scene/PolylineMaterialAppearance.js @@ -111,9 +111,8 @@ Object.defineProperties(PolylineMaterialAppearance.prototype, { get: function () { let vs = this._vertexShaderSource; if ( - this.material.shaderSource.search( - /varying\s+float\s+v_polylineAngle;/g - ) !== -1 + this.material.shaderSource.search(/in\s+float\s+v_polylineAngle;/g) !== + -1 ) { vs = `#define POLYLINE_DASH\n${vs}`; } diff --git a/packages/engine/Source/Scene/PostProcessStage.js b/packages/engine/Source/Scene/PostProcessStage.js index 0e976aa150f..245ab8edfa8 100644 --- a/packages/engine/Source/Scene/PostProcessStage.js +++ b/packages/engine/Source/Scene/PostProcessStage.js @@ -53,7 +53,7 @@ import PostProcessStageSampleMode from "./PostProcessStageSampleMode.js"; * uniform vec3 offset; * void main() { * vec4 color = texture(colorTexture, v_textureCoordinates); - * gl_FragColor = vec4(color.rgb * scale + offset, 1.0); + * out_FragColor = vec4(color.rgb * scale + offset, 1.0); * }`; * scene.postProcessStages.add(new Cesium.PostProcessStage({ * fragmentShader : fs, @@ -76,9 +76,9 @@ import PostProcessStageSampleMode from "./PostProcessStageSampleMode.js"; * vec4 color = texture(colorTexture, v_textureCoordinates); * if (czm_selected()) { * vec3 highlighted = highlight.a * highlight.rgb + (1.0 - highlight.a) * color.rgb; - * gl_FragColor = vec4(highlighted, 1.0); + * out_FragColor = vec4(highlighted, 1.0); * } else { - * gl_FragColor = color; + * out_FragColor = color; * } * }`; * const stage = scene.postProcessStages.add(new Cesium.PostProcessStage({ @@ -364,7 +364,7 @@ Object.defineProperties(PostProcessStage.prototype, { * if (czm_selected(v_textureCoordinates)) { * // apply post-process stage * } else { - * gl_FragColor = texture(colorTexture, v_textureCoordinates); + * out_FragColor = texture(colorTexture, v_textureCoordinates); * } * *

diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index feb6c04dcee..2ac5e23c073 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -771,7 +771,7 @@ Primitive._modifyShaderPosition = function ( if (!defined(primitive.rtcCenter)) { // Use GPU RTE if (!scene3DOnly) { - attributes += `in vec3 ${name}2DHigh;\n` + `in vec3 ${name}2DLow;\n`; + attributes += `in vec3 ${name}2DHigh;\nin vec3 ${name}2DLow;\n`; computeFunctions += `${functionName}\n` + diff --git a/packages/engine/Source/Scene/ShadowVolumeAppearance.js b/packages/engine/Source/Scene/ShadowVolumeAppearance.js index 169bf41b2c9..8a3186d24bf 100644 --- a/packages/engine/Source/Scene/ShadowVolumeAppearance.js +++ b/packages/engine/Source/Scene/ShadowVolumeAppearance.js @@ -168,7 +168,7 @@ ShadowVolumeAppearance.prototype.createPickFragmentShader = function ( return new ShaderSource({ defines: defines, sources: [ShadowVolumeAppearanceFS], - pickColorQualifier: "varying", + pickColorQualifier: "in", }); }; diff --git a/packages/engine/Source/Shaders/Builtin/Functions/depthClamp.glsl b/packages/engine/Source/Shaders/Builtin/Functions/depthClamp.glsl index 468ce8954df..e3f4de325aa 100644 --- a/packages/engine/Source/Shaders/Builtin/Functions/depthClamp.glsl +++ b/packages/engine/Source/Shaders/Builtin/Functions/depthClamp.glsl @@ -1,5 +1,5 @@ // emulated noperspective -#if !defined(LOG_DEPTH) +#if (__VERSION__ == 300 || defined(GL_EXT_frag_depth)) && !defined(LOG_DEPTH) out float v_WindowZ; #endif @@ -36,8 +36,12 @@ out float v_WindowZ; vec4 czm_depthClamp(vec4 coords) { #ifndef LOG_DEPTH +#if __VERSION__ == 300 || defined(GL_EXT_frag_depth) v_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w; coords.z = 0.0; +#else + coords.z = min(coords.z, coords.w); +#endif #endif return coords; } diff --git a/packages/engine/Source/Shaders/Builtin/Functions/textureCube.glsl b/packages/engine/Source/Shaders/Builtin/Functions/textureCube.glsl new file mode 100644 index 00000000000..123f1598ff1 --- /dev/null +++ b/packages/engine/Source/Shaders/Builtin/Functions/textureCube.glsl @@ -0,0 +1,17 @@ +/** + * A wrapper around the texture (WebGL2) / textureCube (WebGL1) + * function to allow for WebGL 1 support. + * + * @name czm_textureCube + * @glslFunction + * + * @param {samplerCube} sampler The sampler. + * @param {vec3} p The coordinates to sample the texture at. + */ +vec4 czm_textureCube(samplerCube sampler, vec3 p) { +#if __VERSION__ == 300 + return texture(sampler, p); +#else + return textureCube(sampler, p); +#endif +} \ No newline at end of file diff --git a/packages/engine/Source/Shaders/EllipsoidFS.glsl b/packages/engine/Source/Shaders/EllipsoidFS.glsl index fcb153b166e..b8b3671feac 100644 --- a/packages/engine/Source/Shaders/EllipsoidFS.glsl +++ b/packages/engine/Source/Shaders/EllipsoidFS.glsl @@ -1,6 +1,3 @@ -#ifdef WRITE_DEPTH -#endif - uniform vec3 u_radii; uniform vec3 u_oneOverEllipsoidRadiiSquared; diff --git a/packages/engine/Specs/Renderer/DrawSpec.js b/packages/engine/Specs/Renderer/DrawSpec.js index 02ea731cb12..ea4a508eddc 100644 --- a/packages/engine/Specs/Renderer/DrawSpec.js +++ b/packages/engine/Specs/Renderer/DrawSpec.js @@ -1476,6 +1476,68 @@ describe( command.execute(context); }).toThrowDeveloperError(); }); + + describe("WebGL1", function () { + let webgl1Context; + + beforeAll(() => { + webgl1Context = createContext({ + requestWebgl1: true, + }); + }); + + afterAll(() => { + webgl1Context.destroyForSpecs(); + }); + + it("throws when instanceCount is greater than one and instancing is disabled", function () { + const webgl1Context = createContext({ + requestWebgl1: true, + }); + // disable extension + const instancedArrays = webgl1Context._instancedArrays; + webgl1Context._instancedArrays = undefined; + + const vs = + "in vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }"; + const fs = "void main() { out_FragColor = vec4(1.0); }"; + sp = ShaderProgram.fromCache({ + context: webgl1Context, + vertexShaderSource: vs, + fragmentShaderSource: fs, + attributeLocations: { + position: 0, + }, + }); + + va = new VertexArray({ + context: webgl1Context, + attributes: [ + { + index: 0, + vertexBuffer: Buffer.createVertexBuffer({ + context: webgl1Context, + typedArray: new Float32Array([0, 0, 0, 1]), + usage: BufferUsage.STATIC_DRAW, + }), + componentsPerAttribute: 4, + }, + ], + }); + + const command = new DrawCommand({ + primitiveType: PrimitiveType.POINTS, + shaderProgram: sp, + vertexArray: va, + instanceCount: 2, + }); + + expect(function () { + command.execute(webgl1Context); + }).toThrowDeveloperError(); + context._instancedArrays = instancedArrays; + }); + }); }, "WebGL" ); diff --git a/packages/engine/Specs/Renderer/ShaderSourceSpec.js b/packages/engine/Specs/Renderer/ShaderSourceSpec.js index 44cc8ca0e16..8a63340b072 100644 --- a/packages/engine/Specs/Renderer/ShaderSourceSpec.js +++ b/packages/engine/Specs/Renderer/ShaderSourceSpec.js @@ -53,7 +53,7 @@ describe("Renderer/ShaderSource", function () { it("creates a pick shader with a varying", function () { const source = new ShaderSource({ sources: ["void main() { out_FragColor = vec4(1.0); }"], - pickColorQualifier: "varying", + pickColorQualifier: "in", }); const shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain("in vec4 czm_pickColor;"); @@ -80,7 +80,7 @@ describe("Renderer/ShaderSource", function () { const source = new ShaderSource({ defines: ["A"], sources: ["void main() { out_FragColor = vec4(1.0); }"], - pickColorQualifier: "varying", + pickColorQualifier: "in", includeBuiltIns: false, }); const clone = source.clone(); @@ -103,12 +103,12 @@ describe("Renderer/ShaderSource", function () { const source = new ShaderSource({ defines: ["A", "B", "C"], sources: ["void main() { out_FragColor = vec4(1.0); }"], - pickColorQualifier: "varying", + pickColorQualifier: "in", includeBuiltIns: false, }); expect(source.getCacheKey()).toBe( - "A,B,C:varying:false:void main() { out_FragColor = vec4(1.0); }" + "A,B,C:in:false:void main() { out_FragColor = vec4(1.0); }" ); }); @@ -140,7 +140,7 @@ describe("Renderer/ShaderSource", function () { const source = new ShaderSource({ defines: ["A"], sources: ["void main() { out_FragColor = vec4(1.0); }"], - pickColorQualifier: "varying", + pickColorQualifier: "in", includeBuiltIns: false, }); const shaderText = source.createCombinedFragmentShader(mockContext); @@ -155,7 +155,7 @@ describe("Renderer/ShaderSource", function () { sources: [ "layout (location = 0) out vec4 out_FragColor; void main() { out_FragColor = vec4(1.0); }", ], - pickColorQualifier: "varying", + pickColorQualifier: "in", includeBuiltIns: false, }); const shaderText = source.createCombinedFragmentShader(mockContext); diff --git a/packages/engine/Specs/Renderer/TextureSpec.js b/packages/engine/Specs/Renderer/TextureSpec.js index c88404f5b9a..1399d971fef 100644 --- a/packages/engine/Specs/Renderer/TextureSpec.js +++ b/packages/engine/Specs/Renderer/TextureSpec.js @@ -1468,6 +1468,44 @@ describe( } }); + describe("WebGL1", function () { + let webgl1Context; + + beforeAll(() => { + webgl1Context = createContext({ + requestWebgl1: true, + }); + }); + + afterAll(() => { + webgl1Context.destroyForSpecs(); + }); + + it("throws when generating mipmaps with a non-power of two width", function () { + texture = new Texture({ + context: webgl1Context, + width: 3, + height: 2, + }); + + expect(function () { + texture.generateMipmap(); + }).toThrowDeveloperError(); + }); + + it("throws when generating mipmaps with a non-power of two height", function () { + texture = new Texture({ + context: webgl1Context, + width: 2, + height: 3, + }); + + expect(function () { + texture.generateMipmap(); + }).toThrowDeveloperError(); + }); + }); + it("throws when generating mipmaps with an invalid hint", function () { texture = new Texture({ context: context, diff --git a/packages/engine/Specs/Renderer/demodernizeShaderSpec.js b/packages/engine/Specs/Renderer/demodernizeShaderSpec.js index 167863a5363..3eca6c16b14 100644 --- a/packages/engine/Specs/Renderer/demodernizeShaderSpec.js +++ b/packages/engine/Specs/Renderer/demodernizeShaderSpec.js @@ -41,7 +41,7 @@ describe("Renderer/demodernizeShader", () => { expect(output).toContain("gl_FragData[11] = vec4(1.0, 2.0, 3.0, 4.0);"); }); - it("replaces out_FragColor with gl_FragData", () => { + it("replaces out_FragColor with gl_FragColor", () => { const input = `#version 300 es layout (location = 0) vec4 out_FragColor; @@ -77,21 +77,6 @@ describe("Renderer/demodernizeShader", () => { expect(output).toContain("vec4 tex = texture2D(u_texture, vec2(0.0));"); }); - it("replaces czm_textureCube with textureCube", () => { - const input = `#version 300 es - uniform samplerCube u_texture; - void main() { - vec4 tex = czm_textureCube(u_texture, vec3(0.0)); // textureCube - } - `; - const output = demodernizeShader(input, false); - - const expectedVersion = "#version 100"; - expect(output.startsWith(expectedVersion)).toEqual(true); - - expect(output).toContain("vec4 tex = textureCube(u_texture, vec3(0.0));"); - }); - it("replaces in with attribute in vertex shader", () => { const input = `#version 300 es in float a_float; @@ -154,7 +139,7 @@ describe("Renderer/demodernizeShader", () => { const expectedVersion = "#version 100"; expect(output.startsWith(expectedVersion)).toEqual(true); - + expect(output).toContain("#extension GL_EXT_frag_depth : enable"); expect(output).toContain("gl_FragDepthEXT = vec4(1.0);"); expect(output).toContain("gl_FragDepthEXT += vec4(2.0);"); }); From eeb73c310b7fbdab93237bf492ec9afe7580642c Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 09:22:25 -0500 Subject: [PATCH 249/679] Update rollup --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e33ccf384cf..e758c19d0ed 100644 --- a/package.json +++ b/package.json @@ -55,8 +55,8 @@ "@cesium/widgets": "1.0.0" }, "devDependencies": { - "@rollup/plugin-commonjs": "^22.0.2", - "@rollup/plugin-node-resolve": "^14.0.0", + "@rollup/plugin-commonjs": "^23.0.5", + "@rollup/plugin-node-resolve": "^15.0.1", "aws-sdk": "^2.1210.0", "chokidar": "^3.5.3", "cloc": "^2.8.0", @@ -108,7 +108,7 @@ "prismjs": "^1.28.0", "request": "^2.79.0", "rimraf": "^3.0.2", - "rollup": "^2.52.2", + "rollup": "^3.7.4", "rollup-plugin-strip-pragma": "^1.0.0", "rollup-plugin-terser": "^7.0.2", "stream-to-promise": "^3.0.0", @@ -166,4 +166,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} From 7ba0a9968e690a69f4cda8acacc9ba631236cd45 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 09:23:13 -0500 Subject: [PATCH 250/679] Remove images --- Documentation/Images/Cesium_dark_color.svg | 61 --------------------- Documentation/Images/Cesium_light_color.svg | 59 -------------------- 2 files changed, 120 deletions(-) delete mode 100755 Documentation/Images/Cesium_dark_color.svg delete mode 100755 Documentation/Images/Cesium_light_color.svg diff --git a/Documentation/Images/Cesium_dark_color.svg b/Documentation/Images/Cesium_dark_color.svg deleted file mode 100755 index 0de3ade30e6..00000000000 --- a/Documentation/Images/Cesium_dark_color.svg +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Documentation/Images/Cesium_light_color.svg b/Documentation/Images/Cesium_light_color.svg deleted file mode 100755 index a4fe9e61df9..00000000000 --- a/Documentation/Images/Cesium_light_color.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - From 570ac8692fcac897caf7ff68ba1383509cb71943 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 09:44:47 -0500 Subject: [PATCH 251/679] Update markdowncli --- Documentation/Contributors/CodeReviewGuide/README.md | 2 +- Documentation/Contributors/PresentersGuide/README.md | 2 +- Documentation/FabricGuide/README.md | 6 +++--- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/Contributors/CodeReviewGuide/README.md b/Documentation/Contributors/CodeReviewGuide/README.md index 3bb5cbd4d8e..d041b813536 100644 --- a/Documentation/Contributors/CodeReviewGuide/README.md +++ b/Documentation/Contributors/CodeReviewGuide/README.md @@ -6,7 +6,7 @@ This guide describes best practices for code reviewers. - [General](#general) - [Reviewing](#reviewing) -- [Changes to the Public CesiumJS API](#changes-to-the-public-cesium-api) +- [Changes to the Public CesiumJS API](#changes-to-the-public-cesiumjs-api) - [Testing](#testing) - [Merging](#merging) - [Useful Git Commit Management](#useful-git-commit-management) diff --git a/Documentation/Contributors/PresentersGuide/README.md b/Documentation/Contributors/PresentersGuide/README.md index 99cc1d8edda..b46691672e3 100644 --- a/Documentation/Contributors/PresentersGuide/README.md +++ b/Documentation/Contributors/PresentersGuide/README.md @@ -8,7 +8,7 @@ The Cesium team gives a lot of [talks](https://cesium.com/learn/presentations/). - [Tell a Story](#tell-a-story) - [You're Not Too Short on Time](#youre-not-too-short-on-time) - [Use "Short" Slides](#use-short-slides) -- [Inspire. Don't Teach](#inspire--dont-teach) +- [Inspire. Don't Teach](#inspire-dont-teach) - [Finish with a Call to Action](#finish-with-a-call-to-action) - [Practice](#practice) - [Test the Projector](#test-the-projector) diff --git a/Documentation/FabricGuide/README.md b/Documentation/FabricGuide/README.md index 302115d549e..8288a4b0f90 100644 --- a/Documentation/FabricGuide/README.md +++ b/Documentation/FabricGuide/README.md @@ -107,7 +107,7 @@ Procedural texture materials procedurally compute patterns on the GPU so they do ### Base Materials -Base materials represent fine-grain fundamental material characteristics, such as how much incoming light is reflected in a single direction, i.e., the _specular intensity_, or how much light is emitted, i.e., the _emission_. These materials can be used as is, but are more commonly [combined](#CombiningMaterials) using Fabric to create a more complex material. +Base materials represent fine-grain fundamental material characteristics, such as how much incoming light is reflected in a single direction, i.e., the _specular intensity_, or how much light is emitted, i.e., the _emission_. These materials can be used as is, but are more commonly [combined](#combining-materials) using Fabric to create a more complex material. | Name | Screenshot | Description | | :------------ | :---------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -370,11 +370,11 @@ polygon.material = Cesium.Material.fromType("OurDiffuseMap"); polygon.material.uniforms.image = "diffuse.png"; ``` -There is also a cube-map placeholder, `czm_defaultCubeMap`. The standard GLSL uniform types, `float`, `vec3`, `mat4`, etc. are supported. Uniform arrays are not supported yet, but are on the [roadmap](#Roadmap). +There is also a cube-map placeholder, `czm_defaultCubeMap`. The standard GLSL uniform types, `float`, `vec3`, `mat4`, etc. are supported. Uniform arrays are not supported yet, but are on the roadmap. ### Combining Materials -So far, we can use the [built-in](#BuiltInMaterials) materials, or create our own by using Fabric to specify the material's [components](#Components) or full GLSL [source](#Source). We can also build materials from existing materials (recursively) forming a hierarchy of materials. +So far, we can use the [built-in](#built-in-materials) materials, or create our own by using Fabric to specify the material's [components](#components) or full GLSL [source](#source). We can also build materials from existing materials (recursively) forming a hierarchy of materials. Fabric has a `materials` property where the value of each sub-property is Fabric, i.e., a material. These materials can be referenced in the `components` and `source` properties so they can be built upon. For example, a material representing plastic can be implemented with a `DiffuseMap` and `SpecularMap`. diff --git a/package.json b/package.json index e758c19d0ed..5f253ded7e6 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "karma-safari-launcher": "^1.0.0", "karma-sourcemap-loader": "^0.3.8", "karma-spec-reporter": "^0.0.32", - "markdownlint-cli": "^0.31.1", + "markdownlint-cli": "^0.32.2", "merge-stream": "^2.0.0", "mime": "^3.0.0", "mkdirp": "^1.0.4", From 65fed36e18bc83602d62878f9e44812587abacfc Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:11:22 -0500 Subject: [PATCH 252/679] Update karma runners --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5f253ded7e6..e5b2c615742 100644 --- a/package.json +++ b/package.json @@ -92,11 +92,11 @@ "karma-edge-launcher": "^0.4.2", "karma-firefox-launcher": "^2.1.1", "karma-ie-launcher": "^1.0.0", - "karma-jasmine": "^4.0.1", + "karma-jasmine": "^5.1.0", "karma-longest-reporter": "^1.1.0", "karma-safari-launcher": "^1.0.0", "karma-sourcemap-loader": "^0.3.8", - "karma-spec-reporter": "^0.0.32", + "karma-spec-reporter": "^0.0.36", "markdownlint-cli": "^0.32.2", "merge-stream": "^2.0.0", "mime": "^3.0.0", From 6219c4e344c1f746532cfc13559f7f44f1de6045 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:14:19 -0500 Subject: [PATCH 253/679] Update typescript --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5b2c615742..299b20d7e98 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "rollup-plugin-terser": "^7.0.2", "stream-to-promise": "^3.0.0", "tsd-jsdoc": "^2.5.0", - "typescript": "^4.3.4", + "typescript": "^4.9.4", "yargs": "^17.0.1" }, "scripts": { From c13b728a1d0c702b34d67c631d7aeaa9d59432cf Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:16:39 -0500 Subject: [PATCH 254/679] Update eslint --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 299b20d7e98..c28650badb9 100644 --- a/package.json +++ b/package.json @@ -65,11 +65,11 @@ "download": "^8.0.0", "draco3d": "^1.5.1", "esbuild": "^0.15.7", - "eslint": "^8.19.0", + "eslint": "^8.29.0", "eslint-config-cesium": "^9.0.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-es": "^4.1.0", - "eslint-plugin-html": "^6.1.2", + "eslint-plugin-html": "^7.1.0", "eslint-plugin-node": "^11.1.0", "express": "^4.17.1", "globby": "^13.1.2", From bb4eb6f5acdd46a3e27138e5272437ca5ffe5f92 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:18:43 -0500 Subject: [PATCH 255/679] Update husky --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c28650badb9..5e14c063454 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "gulp-replace": "^1.1.3", "gulp-tap": "^2.0.0", "gulp-zip": "^5.1.0", - "husky": "^7.0.2", + "husky": "^8.0.2", "istanbul-lib-instrument": "^5.2.0", "jasmine-core": "^4.0.1", "jsdoc": "^3.6.7", From 148e213cfbf05a5bed9b0b6eb01bbcbee0abe0f8 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:31:41 -0500 Subject: [PATCH 256/679] update globby --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e14c063454..9497810e7b9 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "eslint-plugin-html": "^7.1.0", "eslint-plugin-node": "^11.1.0", "express": "^4.17.1", - "globby": "^13.1.2", + "globby": "^13.1.3", "glsl-strip-comments": "^1.0.0", "gulp": "^4.0.2", "gulp-clean-css": "^4.3.0", From 37c81d44a9d2c854d3ba768b961c066423f320ef Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:39:46 -0500 Subject: [PATCH 257/679] Update esbuild --- build.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.js b/build.js index 7f1424721af..1915c734bfb 100644 --- a/build.js +++ b/build.js @@ -349,7 +349,7 @@ export async function bundleCombinedWorkers(options) { const workerConfig = defaultESBuildOptions(); workerConfig.bundle = false; workerConfig.banner = { - js: options.copyrightHeader, + js: combinedCopyrightHeader, }; workerConfig.entryPoints = workers; workerConfig.outdir = options.path; @@ -421,7 +421,7 @@ export async function bundleWorkers(options) { const workerConfig = defaultESBuildOptions(); workerConfig.bundle = false; workerConfig.banner = { - js: options.copyrightHeader, + js: combinedCopyrightHeader, }; workerConfig.entryPoints = workers; workerConfig.outdir = options.path; diff --git a/package.json b/package.json index 9497810e7b9..d49660bd68f 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "decompress": "^4.2.1", "download": "^8.0.0", "draco3d": "^1.5.1", - "esbuild": "^0.15.7", + "esbuild": "^0.16.7", "eslint": "^8.29.0", "eslint-config-cesium": "^9.0.0", "eslint-config-prettier": "^8.3.0", From e481f61488abd63d7722f0e97ca302f8b60003a6 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 10:40:55 -0500 Subject: [PATCH 258/679] Update aws sdk --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d49660bd68f..9b8e281c5a2 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^23.0.5", "@rollup/plugin-node-resolve": "^15.0.1", - "aws-sdk": "^2.1210.0", + "aws-sdk": "^2.1276.0", "chokidar": "^3.5.3", "cloc": "^2.8.0", "compression": "^1.7.4", From 9f7c5b1160c9f119759283464da01a5d7e52f53f Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 16 Dec 2022 11:17:12 -0500 Subject: [PATCH 259/679] Rollback rollup for compatability with plugins --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b8e281c5a2..213ec325f63 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "prismjs": "^1.28.0", "request": "^2.79.0", "rimraf": "^3.0.2", - "rollup": "^3.7.4", + "rollup": "^2.79.1", "rollup-plugin-strip-pragma": "^1.0.0", "rollup-plugin-terser": "^7.0.2", "stream-to-promise": "^3.0.0", From 3ac1532752421fa0c0329772548113f9b54e0521 Mon Sep 17 00:00:00 2001 From: Sanjeet Suhag Date: Fri, 16 Dec 2022 14:47:53 -0500 Subject: [PATCH 260/679] Adds WebGL2 announcement --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 5be69c125a6..a877903d2d6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,13 @@ ### 1.101 - 2023-01-02 +#### Major Announcements :loudspeaker: + +- Starting with version 1.102, CesiumJS will default to using a WebGL2 context for rendering. + - Any custom materials, custom primitive or custom shaders will need to be upgraded to use GLSL 300. + - WebGL1 will still be supported. If WebGL2 is not available, CesiumJS will automatically fall back to WebGL1. + - To request a WebGL 1 context, set `requestWebgl1` to `true` when providing `ContextOptions`. + #### engine ##### Additions :tada: From 99d39c2b275c5f298548741d67e23cf6e0d0118a Mon Sep 17 00:00:00 2001 From: Sanjeet Suhag Date: Fri, 16 Dec 2022 15:11:29 -0500 Subject: [PATCH 261/679] Feedback pass --- CHANGES.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a877903d2d6..94a328db99e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,17 @@ #### Major Announcements :loudspeaker: -- Starting with version 1.102, CesiumJS will default to using a WebGL2 context for rendering. - - Any custom materials, custom primitive or custom shaders will need to be upgraded to use GLSL 300. +- Starting with version 1.102, CesiumJS will default to using a WebGL2 context for rendering. WebGL2 is widely supported on all platforms and this change will result in better feature support across devices, especially mobile. - WebGL1 will still be supported. If WebGL2 is not available, CesiumJS will automatically fall back to WebGL1. - - To request a WebGL 1 context, set `requestWebgl1` to `true` when providing `ContextOptions`. + - In order to work in a WebGL2 context, any custom materials, custom primitive or custom shaders will need to be upgraded to use GLSL 300. + - Otherwise to request a WebGL 1 context, set `requestWebgl1` to `true` when providing `ContextOptions` as shown below: + ```js + const viewer = new Viewer("cesiumContainer", { + contextOptions: { + requestWebgl1: true, + }, + }); + ``` #### engine From 8efd4f8975b0205c50ff5ac861e2ad4133667ee9 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 10:17:35 -0500 Subject: [PATCH 262/679] Revert ResourceCache change --- packages/engine/Source/Scene/ResourceCache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ResourceCache.js b/packages/engine/Source/Scene/ResourceCache.js index 0efdf79a817..862b39aeeaa 100644 --- a/packages/engine/Source/Scene/ResourceCache.js +++ b/packages/engine/Source/Scene/ResourceCache.js @@ -781,9 +781,9 @@ ResourceCache.clearForSpecs = function () { GltfTextureLoader, GltfImageLoader, GltfBufferViewLoader, + BufferLoader, MetadataSchemaLoader, GltfJsonLoader, - BufferLoader, ]; let cacheKey; From ae2a13299f23cd34c63d327f858a622e9b2bcb83 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 10:25:14 -0500 Subject: [PATCH 263/679] Revert CesiumInspector.css change --- packages/widgets/Source/CesiumInspector/CesiumInspector.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/Source/CesiumInspector/CesiumInspector.css b/packages/widgets/Source/CesiumInspector/CesiumInspector.css index c69e46ba06b..63efebda669 100644 --- a/packages/widgets/Source/CesiumInspector/CesiumInspector.css +++ b/packages/widgets/Source/CesiumInspector/CesiumInspector.css @@ -54,7 +54,7 @@ margin: 5px 0; font-family: sans-serif; font-size: 10pt; - width: 100%; + width: 185px; } .cesium-cesiumInspector-frustumStatistics { From 47ede9f06f055af412d1c750f9fce6a01e21c333 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 10:34:51 -0500 Subject: [PATCH 264/679] Remove toTypedArrayType --- packages/engine/Source/Scene/Megatexture.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Scene/Megatexture.js b/packages/engine/Source/Scene/Megatexture.js index 6bf0390dfd8..d9951235d38 100644 --- a/packages/engine/Source/Scene/Megatexture.js +++ b/packages/engine/Source/Scene/Megatexture.js @@ -1,5 +1,6 @@ import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; +import ComponentDatatype from "../Core/ComponentDatatype.js"; import ContextLimits from "../Renderer/ContextLimits.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; @@ -202,12 +203,15 @@ function Megatexture( }), }); - const ArrayType = MetadataComponentType.toTypedArrayType(componentType); + const componentDatatype = MetadataComponentType.toComponentDatatype( + componentType + ); /** * @type {Array} */ - this.tileVoxelDataTemp = new ArrayType( + this.tileVoxelDataTemp = ComponentDatatype.createTypedArray( + componentDatatype, voxelCountPerRegionX * voxelCountPerRegionY * channelCount ); From f37293aac57c7d546923461372ef6c4df5c6af3e Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Mon, 19 Dec 2022 10:53:40 -0500 Subject: [PATCH 265/679] Fix billboard alignedAxis in 2D --- CHANGES.md | 1 + packages/engine/Source/Shaders/BillboardCollectionVS.glsl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5be69c125a6..b2eed74530b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ - Fixed a bug where the scale of a `PointPrimitive` was incorrect when `scaleByDistance` was set to a `NearFarScalar` [#10912](https://github.com/CesiumGS/cesium/pull/10912) - Fixed glTF models with a mix of Draco and non-Draco attributes. [#10936](https://github.com/CesiumGS/cesium/pull/10936) +- Fixed a bug where billboards with `alignedAxis`properties were not properly aligned in 2D and Columbus View. [#10965](https://github.com/CesiumGS/cesium/issues/10965) - Fixed the JSDoc and TypeScript definitions of arguments in `Matrix2.multiplyByScalar`, `Matrix3.multiplyByScalar`, and several functions in the `S2Cell` class. [#10899](https://github.com/CesiumGS/cesium/pull/10899) - Fixed a bug where the entity collection of a `GpxDataSource` did not have the `owner` property set. [#10921](https://github.com/CesiumGS/cesium/issues/10921) - Fixed a bug where \*.ktx2 images loading fail. [#10869](https://github.com/CesiumGS/cesium/pull/10869) diff --git a/packages/engine/Source/Shaders/BillboardCollectionVS.glsl b/packages/engine/Source/Shaders/BillboardCollectionVS.glsl index 5408b2606fb..56d291f34fc 100644 --- a/packages/engine/Source/Shaders/BillboardCollectionVS.glsl +++ b/packages/engine/Source/Shaders/BillboardCollectionVS.glsl @@ -67,7 +67,7 @@ vec4 addScreenSpaceOffset(vec4 positionEC, vec2 imageSize, float scale, vec2 dir float angle = rotation; if (validAlignedAxis) { - vec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0); + vec4 projectedAlignedAxis = czm_modelView3D * vec4(alignedAxis, 0.0); angle += sign(-projectedAlignedAxis.x) * acos(sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) / (projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y)); } From 4f7fbd6c6581a5773ea11a29d34a21b208706e24 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 10:53:53 -0500 Subject: [PATCH 266/679] Added tests for MetadataComponentType changes --- .../Source/Scene/MetadataClassProperty.js | 9 +- .../Source/Scene/MetadataComponentType.js | 88 +++--------- .../Specs/Scene/MetadataComponentTypeSpec.js | 129 ++++++++++++------ 3 files changed, 111 insertions(+), 115 deletions(-) diff --git a/packages/engine/Source/Scene/MetadataClassProperty.js b/packages/engine/Source/Scene/MetadataClassProperty.js index 22afbe9a558..516f3731839 100644 --- a/packages/engine/Source/Scene/MetadataClassProperty.js +++ b/packages/engine/Source/Scene/MetadataClassProperty.js @@ -450,7 +450,7 @@ function isLegacy(property) { // EXT_feature_metadata allowed numeric types as a type. Now they are // represented as {type: SINGLE, componentType: type} - if (MetadataComponentType.isNumericType(type)) { + if (defined(MetadataComponentType[type])) { return true; } @@ -585,10 +585,7 @@ function parseType(property, enums) { // Both EXT_feature_metadata and EXT_structural_metadata allow numeric types like // INT32 or FLOAT64 as a componentType. - if ( - defined(componentType) && - MetadataComponentType.isNumericType(componentType) - ) { + if (defined(componentType) && defined(MetadataComponentType[componentType])) { return { type: MetadataType.SCALAR, componentType: componentType, @@ -602,7 +599,7 @@ function parseType(property, enums) { // EXT_feature_metadata: integer and float types were allowed as types, // but now these are expressed as {type: SCALAR, componentType: type} - if (MetadataComponentType.isNumericType(type)) { + if (defined(MetadataComponentType[type])) { return { type: MetadataType.SCALAR, componentType: type, diff --git a/packages/engine/Source/Scene/MetadataComponentType.js b/packages/engine/Source/Scene/MetadataComponentType.js index cd0d2fc35b5..e94a48d84e7 100644 --- a/packages/engine/Source/Scene/MetadataComponentType.js +++ b/packages/engine/Source/Scene/MetadataComponentType.js @@ -114,9 +114,7 @@ const MetadataComponentType = { */ MetadataComponentType.getMinimum = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); switch (type) { @@ -166,9 +164,7 @@ MetadataComponentType.getMinimum = function (type) { */ MetadataComponentType.getMaximum = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); switch (type) { @@ -204,36 +200,6 @@ MetadataComponentType.getMaximum = function (type) { } }; -/** - * Returns whether the type is a numeric type. - * - * @param {MetadataComponentType} type The type. - * @returns {Boolean} Whether the type is a numeric type. - * - * @private - */ -MetadataComponentType.isNumericType = function (type) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.string("type", type); - //>>includeEnd('debug'); - - switch (type) { - case MetadataComponentType.INT8: - case MetadataComponentType.UINT8: - case MetadataComponentType.INT16: - case MetadataComponentType.UINT16: - case MetadataComponentType.INT32: - case MetadataComponentType.UINT32: - case MetadataComponentType.INT64: - case MetadataComponentType.UINT64: - case MetadataComponentType.FLOAT32: - case MetadataComponentType.FLOAT64: - return true; - default: - return false; - } -}; - /** * Returns whether the type is an integer type. * @@ -422,10 +388,9 @@ MetadataComponentType.unapplyValueTransform = function (value, offset, scale) { */ MetadataComponentType.getSizeInBytes = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); + switch (type) { case MetadataComponentType.INT8: case MetadataComponentType.UINT8: @@ -447,7 +412,7 @@ MetadataComponentType.getSizeInBytes = function (type) { }; /** - * Gets the type from a {@link ComponentDatatype}. + * Gets the {@link MetadataComponentType} from a {@link ComponentDatatype}. * * @param {ComponentDatatype} componentDatatype The component datatype. * @returns {MetadataComponentType} The metadata component type. @@ -455,6 +420,10 @@ MetadataComponentType.getSizeInBytes = function (type) { * @private */ MetadataComponentType.fromComponentDatatype = function (componentDatatype) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("componentDatatype", componentDatatype); + //>>includeEnd('debug'); + switch (componentDatatype) { case ComponentDatatype.BYTE: return MetadataComponentType.INT8; @@ -475,12 +444,19 @@ MetadataComponentType.fromComponentDatatype = function (componentDatatype) { } }; +/** + * Gets the {@link ComponentDatatype} from a {@link MetadataComponentType}. + * + * @param {MetadataComponentType} type The metadata component datatype. + * @returns {ComponentDatatype} The component datatype. + * + * @private + */ MetadataComponentType.toComponentDatatype = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); + switch (type) { case MetadataComponentType.INT8: return ComponentDatatype.BYTE; @@ -501,30 +477,4 @@ MetadataComponentType.toComponentDatatype = function (type) { } }; -MetadataComponentType.toTypedArrayType = function (type) { - //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } - //>>includeEnd('debug'); - switch (type) { - case MetadataComponentType.INT8: - return Int8Array; - case MetadataComponentType.UINT8: - return Uint8Array; - case MetadataComponentType.INT16: - return Int16Array; - case MetadataComponentType.UINT16: - return Uint16Array; - case MetadataComponentType.INT32: - return Int32Array; - case MetadataComponentType.UINT32: - return Uint32Array; - case MetadataComponentType.FLOAT32: - return Float32Array; - case MetadataComponentType.FLOAT64: - return Float64Array; - } -}; - export default Object.freeze(MetadataComponentType); diff --git a/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js b/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js index 9c4749e30fd..3bb720dff7e 100644 --- a/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js +++ b/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js @@ -1,4 +1,8 @@ -import { FeatureDetection, MetadataComponentType } from "../../index.js"; +import { + ComponentDatatype, + FeatureDetection, + MetadataComponentType, +} from "../../index.js"; describe("Scene/MetadataComponentType", function () { it("getMinimum", function () { @@ -133,45 +137,6 @@ describe("Scene/MetadataComponentType", function () { }).toThrowDeveloperError(); }); - it("isNumericType", function () { - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT8) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT8) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT16) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT16) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT64) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT64) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.FLOAT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.FLOAT64) - ).toBe(true); - }); - - it("isNumericType throws without type", function () { - expect(function () { - MetadataComponentType.isNumericType(); - }).toThrowDeveloperError(); - }); - it("isIntegerType", function () { expect( MetadataComponentType.isIntegerType(MetadataComponentType.INT8) @@ -524,4 +489,88 @@ describe("Scene/MetadataComponentType", function () { MetadataComponentType.getSizeInBytes(MetadataComponentType.STRING); }).toThrowDeveloperError(); }); + + it("fromComponentDatatype", function () { + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.BYTE) + ).toBe(MetadataComponentType.INT8); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_BYTE + ) + ).toBe(MetadataComponentType.UINT8); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.SHORT) + ).toBe(MetadataComponentType.INT16); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_SHORT + ) + ).toBe(MetadataComponentType.UINT16); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.INT) + ).toBe(MetadataComponentType.INT32); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_INT + ) + ).toBe(MetadataComponentType.UINT32); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.FLOAT) + ).toBe(MetadataComponentType.FLOAT32); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.DOUBLE) + ).toBe(MetadataComponentType.FLOAT64); + }); + + it("fromComponentDatatype throws without componentDatatype", function () { + expect(function () { + MetadataComponentType.fromComponentDatatype(); + }).toThrowDeveloperError(); + }); + + it("toComponentDatatype", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT8) + ).toBe(ComponentDatatype.BYTE); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT8) + ).toBe(ComponentDatatype.UNSIGNED_BYTE); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT16) + ).toBe(ComponentDatatype.SHORT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT16) + ).toBe(ComponentDatatype.UNSIGNED_SHORT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT32) + ).toBe(ComponentDatatype.INT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT32) + ).toBe(ComponentDatatype.UNSIGNED_INT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.FLOAT32) + ).toBe(ComponentDatatype.FLOAT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.FLOAT64) + ).toBe(ComponentDatatype.DOUBLE); + }); + + it("toComponentDatatype returns undefined for INT64", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT64) + ).toBeUndefined(); + }); + + it("toComponentDatatype returns undefined for UINT64", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT64) + ).toBeUndefined(); + }); + + it("toComponentDatatype throws without type", function () { + expect(function () { + MetadataComponentType.toComponentDatatype(); + }).toThrowDeveloperError(); + }); }); From 26048daa32c7864c42c9188c02ec183f989749fe Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 10:56:41 -0500 Subject: [PATCH 267/679] Miscellaneous changes from voxels branch --- Specs/getWebGLStub.js | 5 + .../engine/Source/Core/OrientedBoundingBox.js | 8 +- .../engine/Source/Scene/DerivedCommand.js | 7 + .../Source/Scene/MetadataClassProperty.js | 9 +- .../Source/Scene/MetadataComponentType.js | 110 +++++++++------ .../Functions/windowToEyeCoordinates.glsl | 98 +++++++------ .../Specs/Scene/MetadataComponentTypeSpec.js | 129 ++++++++++++------ 7 files changed, 234 insertions(+), 132 deletions(-) diff --git a/Specs/getWebGLStub.js b/Specs/getWebGLStub.js index 68e797ba176..6d355a5c229 100644 --- a/Specs/getWebGLStub.js +++ b/Specs/getWebGLStub.js @@ -212,6 +212,11 @@ function getExtensionStub(name) { return instancedArraysStub; } + // Voxel tests rely on floating point textures + if (name === "OES_texture_float") { + return {}; + } + // No other extensions are stubbed. return null; } diff --git a/packages/engine/Source/Core/OrientedBoundingBox.js b/packages/engine/Source/Core/OrientedBoundingBox.js index 50d5d679e4d..f18ebabd3d9 100644 --- a/packages/engine/Source/Core/OrientedBoundingBox.js +++ b/packages/engine/Source/Core/OrientedBoundingBox.js @@ -18,13 +18,13 @@ import Rectangle from "./Rectangle.js"; /** * Creates an instance of an OrientedBoundingBox. - * An OrientedBoundingBox of some object is a closed and convex cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. + * An OrientedBoundingBox of some object is a closed and convex rectangular cuboid. It can provide a tighter bounding volume than {@link BoundingSphere} or {@link AxisAlignedBoundingBox} in many cases. * @alias OrientedBoundingBox * @constructor * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 0x0x0 + * Equivalently, the transformation matrix, to rotate and scale a 1x1x1 * cube centered at the origin. * * @@ -334,7 +334,7 @@ const scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. * - * @exception {DeveloperError} rectangle.width must be between 0 and pi. + * @exception {DeveloperError} rectangle.width must be between 0 and 2 * pi. * @exception {DeveloperError} rectangle.height must be between 0 and pi. * @exception {DeveloperError} ellipsoid must be an ellipsoid of revolution (radii.x == radii.y) */ @@ -350,7 +350,7 @@ OrientedBoundingBox.fromRectangle = function ( throw new DeveloperError("rectangle is required"); } if (rectangle.width < 0.0 || rectangle.width > CesiumMath.TWO_PI) { - throw new DeveloperError("Rectangle width must be between 0 and 2*pi"); + throw new DeveloperError("Rectangle width must be between 0 and 2 * pi"); } if (rectangle.height < 0.0 || rectangle.height > CesiumMath.PI) { throw new DeveloperError("Rectangle height must be between 0 and pi"); diff --git a/packages/engine/Source/Scene/DerivedCommand.js b/packages/engine/Source/Scene/DerivedCommand.js index 8d0e058ff89..d5a30d837e8 100644 --- a/packages/engine/Source/Scene/DerivedCommand.js +++ b/packages/engine/Source/Scene/DerivedCommand.js @@ -148,6 +148,13 @@ const vertexlogDepthRegex = /\s+czm_vertexLogDepth\(/; const extensionRegex = /\s*#extension\s+GL_EXT_frag_depth\s*:\s*enable/; function getLogDepthShaderProgram(context, shaderProgram) { + const disableLogDepthWrite = + shaderProgram.fragmentShaderSource.defines.indexOf("LOG_DEPTH_READ_ONLY") >= + 0; + if (disableLogDepthWrite) { + return shaderProgram; + } + let shader = context.shaderCache.getDerivedShaderProgram( shaderProgram, "logDepth" diff --git a/packages/engine/Source/Scene/MetadataClassProperty.js b/packages/engine/Source/Scene/MetadataClassProperty.js index 22afbe9a558..516f3731839 100644 --- a/packages/engine/Source/Scene/MetadataClassProperty.js +++ b/packages/engine/Source/Scene/MetadataClassProperty.js @@ -450,7 +450,7 @@ function isLegacy(property) { // EXT_feature_metadata allowed numeric types as a type. Now they are // represented as {type: SINGLE, componentType: type} - if (MetadataComponentType.isNumericType(type)) { + if (defined(MetadataComponentType[type])) { return true; } @@ -585,10 +585,7 @@ function parseType(property, enums) { // Both EXT_feature_metadata and EXT_structural_metadata allow numeric types like // INT32 or FLOAT64 as a componentType. - if ( - defined(componentType) && - MetadataComponentType.isNumericType(componentType) - ) { + if (defined(componentType) && defined(MetadataComponentType[componentType])) { return { type: MetadataType.SCALAR, componentType: componentType, @@ -602,7 +599,7 @@ function parseType(property, enums) { // EXT_feature_metadata: integer and float types were allowed as types, // but now these are expressed as {type: SCALAR, componentType: type} - if (MetadataComponentType.isNumericType(type)) { + if (defined(MetadataComponentType[type])) { return { type: MetadataType.SCALAR, componentType: type, diff --git a/packages/engine/Source/Scene/MetadataComponentType.js b/packages/engine/Source/Scene/MetadataComponentType.js index f14f1ca69a0..e94a48d84e7 100644 --- a/packages/engine/Source/Scene/MetadataComponentType.js +++ b/packages/engine/Source/Scene/MetadataComponentType.js @@ -1,5 +1,6 @@ import CesiumMath from "../Core/Math.js"; import Check from "../Core/Check.js"; +import ComponentDatatype from "../Core/ComponentDatatype.js"; import DeveloperError from "../Core/DeveloperError.js"; import FeatureDetection from "../Core/FeatureDetection.js"; @@ -113,9 +114,7 @@ const MetadataComponentType = { */ MetadataComponentType.getMinimum = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); switch (type) { @@ -165,9 +164,7 @@ MetadataComponentType.getMinimum = function (type) { */ MetadataComponentType.getMaximum = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); switch (type) { @@ -203,36 +200,6 @@ MetadataComponentType.getMaximum = function (type) { } }; -/** - * Returns whether the type is a numeric type. - * - * @param {MetadataComponentType} type The type. - * @returns {Boolean} Whether the type is a numeric type. - * - * @private - */ -MetadataComponentType.isNumericType = function (type) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.string("type", type); - //>>includeEnd('debug'); - - switch (type) { - case MetadataComponentType.INT8: - case MetadataComponentType.UINT8: - case MetadataComponentType.INT16: - case MetadataComponentType.UINT16: - case MetadataComponentType.INT32: - case MetadataComponentType.UINT32: - case MetadataComponentType.INT64: - case MetadataComponentType.UINT64: - case MetadataComponentType.FLOAT32: - case MetadataComponentType.FLOAT64: - return true; - default: - return false; - } -}; - /** * Returns whether the type is an integer type. * @@ -421,10 +388,9 @@ MetadataComponentType.unapplyValueTransform = function (value, offset, scale) { */ MetadataComponentType.getSizeInBytes = function (type) { //>>includeStart('debug', pragmas.debug); - if (!MetadataComponentType.isNumericType(type)) { - throw new DeveloperError("type must be a numeric type"); - } + Check.typeOf.string("type", type); //>>includeEnd('debug'); + switch (type) { case MetadataComponentType.INT8: case MetadataComponentType.UINT8: @@ -445,4 +411,70 @@ MetadataComponentType.getSizeInBytes = function (type) { } }; +/** + * Gets the {@link MetadataComponentType} from a {@link ComponentDatatype}. + * + * @param {ComponentDatatype} componentDatatype The component datatype. + * @returns {MetadataComponentType} The metadata component type. + * + * @private + */ +MetadataComponentType.fromComponentDatatype = function (componentDatatype) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("componentDatatype", componentDatatype); + //>>includeEnd('debug'); + + switch (componentDatatype) { + case ComponentDatatype.BYTE: + return MetadataComponentType.INT8; + case ComponentDatatype.UNSIGNED_BYTE: + return MetadataComponentType.UINT8; + case ComponentDatatype.SHORT: + return MetadataComponentType.INT16; + case ComponentDatatype.UNSIGNED_SHORT: + return MetadataComponentType.UINT16; + case ComponentDatatype.INT: + return MetadataComponentType.INT32; + case ComponentDatatype.UNSIGNED_INT: + return MetadataComponentType.UINT32; + case ComponentDatatype.FLOAT: + return MetadataComponentType.FLOAT32; + case ComponentDatatype.DOUBLE: + return MetadataComponentType.FLOAT64; + } +}; + +/** + * Gets the {@link ComponentDatatype} from a {@link MetadataComponentType}. + * + * @param {MetadataComponentType} type The metadata component datatype. + * @returns {ComponentDatatype} The component datatype. + * + * @private + */ +MetadataComponentType.toComponentDatatype = function (type) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.string("type", type); + //>>includeEnd('debug'); + + switch (type) { + case MetadataComponentType.INT8: + return ComponentDatatype.BYTE; + case MetadataComponentType.UINT8: + return ComponentDatatype.UNSIGNED_BYTE; + case MetadataComponentType.INT16: + return ComponentDatatype.SHORT; + case MetadataComponentType.UINT16: + return ComponentDatatype.UNSIGNED_SHORT; + case MetadataComponentType.INT32: + return ComponentDatatype.INT; + case MetadataComponentType.UINT32: + return ComponentDatatype.UNSIGNED_INT; + case MetadataComponentType.FLOAT32: + return ComponentDatatype.FLOAT; + case MetadataComponentType.FLOAT64: + return ComponentDatatype.DOUBLE; + } +}; + export default Object.freeze(MetadataComponentType); diff --git a/packages/engine/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl b/packages/engine/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl index 00bdd392994..fb902ad40fe 100644 --- a/packages/engine/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +++ b/packages/engine/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl @@ -1,38 +1,13 @@ -/** - * Transforms a position from window to eye coordinates. - * The transform from window to normalized device coordinates is done using components - * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating - * the inverse of czm_viewportTransformation. The transformation from - * normalized device coordinates to clip coordinates is done using fragmentCoordinate.w, - * which is expected to be the scalar used in the perspective divide. The transformation - * from clip to eye coordinates is done using {@link czm_inverseProjection}. - * - * @name czm_windowToEyeCoordinates - * @glslFunction - * - * @param {vec4} fragmentCoordinate The position in window coordinates to transform. - * - * @returns {vec4} The transformed position in eye coordinates. - * - * @see czm_modelToWindowCoordinates - * @see czm_eyeToWindowCoordinates - * @see czm_inverseProjection - * @see czm_viewport - * @see czm_viewportTransformation - * - * @example - * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord); - */ -vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) +vec4 czm_screenToEyeCoordinates(vec4 screenCoordinate) { // Reconstruct NDC coordinates - float x = 2.0 * (fragmentCoordinate.x - czm_viewport.x) / czm_viewport.z - 1.0; - float y = 2.0 * (fragmentCoordinate.y - czm_viewport.y) / czm_viewport.w - 1.0; - float z = (fragmentCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; + float x = 2.0 * screenCoordinate.x - 1.0; + float y = 2.0 * screenCoordinate.y - 1.0; + float z = (screenCoordinate.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; vec4 q = vec4(x, y, z, 1.0); // Reverse the perspective division to obtain clip coordinates. - q /= fragmentCoordinate.w; + q /= screenCoordinate.w; // Reverse the projection transformation to obtain eye coordinates. if (!(czm_inverseProjection == mat4(0.0))) // IE and Edge sometimes do something weird with != between mat4s @@ -59,16 +34,20 @@ vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) } /** - * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates. - * This function produces more accurate results for window positions with log depth than - * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version - * of czm_windowToEyeCoordinates. + * Transforms a position from window to eye coordinates. + * The transform from window to normalized device coordinates is done using components + * of (@link czm_viewport} and {@link czm_viewportTransformation} instead of calculating + * the inverse of czm_viewportTransformation. The transformation from + * normalized device coordinates to clip coordinates is done using fragmentCoordinate.w, + * which is expected to be the scalar used in the perspective divide. The transformation + * from clip to eye coordinates is done using {@link czm_inverseProjection}. * * @name czm_windowToEyeCoordinates * @glslFunction * - * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform. - * @param {float} depthOrLogDepth A depth or log depth for the fragment. + * @param {vec4} fragmentCoordinate The position in window coordinates to transform. + * + * @returns {vec4} The transformed position in eye coordinates. * * @see czm_modelToWindowCoordinates * @see czm_eyeToWindowCoordinates @@ -76,24 +55,57 @@ vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) * @see czm_viewport * @see czm_viewportTransformation * - * @returns {vec4} The transformed position in eye coordinates. + * @example + * vec4 positionEC = czm_windowToEyeCoordinates(gl_FragCoord); */ -vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth) +vec4 czm_windowToEyeCoordinates(vec4 fragmentCoordinate) +{ + vec2 screenCoordXY = (fragmentCoordinate.xy - czm_viewport.xy) / czm_viewport.zw; + return czm_screenToEyeCoordinates(vec4(screenCoordXY, fragmentCoordinate.zw)); +} + +vec4 czm_screenToEyeCoordinates(vec2 screenCoordinateXY, float depthOrLogDepth) { // See reverseLogDepth.glsl. This is separate to re-use the pow. -#ifdef LOG_DEPTH +#if defined(LOG_DEPTH) || defined(LOG_DEPTH_READ_ONLY) float near = czm_currentFrustum.x; float far = czm_currentFrustum.y; float log2Depth = depthOrLogDepth * czm_log2FarDepthFromNearPlusOne; float depthFromNear = pow(2.0, log2Depth) - 1.0; float depthFromCamera = depthFromNear + near; - vec4 windowCoord = vec4(fragmentCoordinateXY, far * (1.0 - near / depthFromCamera) / (far - near), 1.0); - vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord); + vec4 screenCoord = vec4(screenCoordinateXY, far * (1.0 - near / depthFromCamera) / (far - near), 1.0); + vec4 eyeCoordinate = czm_screenToEyeCoordinates(screenCoord); eyeCoordinate.w = 1.0 / depthFromCamera; // Better precision return eyeCoordinate; #else - vec4 windowCoord = vec4(fragmentCoordinateXY, depthOrLogDepth, 1.0); - vec4 eyeCoordinate = czm_windowToEyeCoordinates(windowCoord); + vec4 screenCoord = vec4(screenCoordinateXY, depthOrLogDepth, 1.0); + vec4 eyeCoordinate = czm_screenToEyeCoordinates(screenCoord); #endif return eyeCoordinate; } + +/** + * Transforms a position given as window x/y and a depth or a log depth from window to eye coordinates. + * This function produces more accurate results for window positions with log depth than + * conventionally unpacking the log depth using czm_reverseLogDepth and using the standard version + * of czm_windowToEyeCoordinates. + * + * @name czm_windowToEyeCoordinates + * @glslFunction + * + * @param {vec2} fragmentCoordinateXY The XY position in window coordinates to transform. + * @param {float} depthOrLogDepth A depth or log depth for the fragment. + * + * @see czm_modelToWindowCoordinates + * @see czm_eyeToWindowCoordinates + * @see czm_inverseProjection + * @see czm_viewport + * @see czm_viewportTransformation + * + * @returns {vec4} The transformed position in eye coordinates. + */ +vec4 czm_windowToEyeCoordinates(vec2 fragmentCoordinateXY, float depthOrLogDepth) +{ + vec2 screenCoordXY = (fragmentCoordinateXY.xy - czm_viewport.xy) / czm_viewport.zw; + return czm_screenToEyeCoordinates(screenCoordXY, depthOrLogDepth); +} diff --git a/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js b/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js index 9c4749e30fd..3bb720dff7e 100644 --- a/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js +++ b/packages/engine/Specs/Scene/MetadataComponentTypeSpec.js @@ -1,4 +1,8 @@ -import { FeatureDetection, MetadataComponentType } from "../../index.js"; +import { + ComponentDatatype, + FeatureDetection, + MetadataComponentType, +} from "../../index.js"; describe("Scene/MetadataComponentType", function () { it("getMinimum", function () { @@ -133,45 +137,6 @@ describe("Scene/MetadataComponentType", function () { }).toThrowDeveloperError(); }); - it("isNumericType", function () { - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT8) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT8) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT16) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT16) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.INT64) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.UINT64) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.FLOAT32) - ).toBe(true); - expect( - MetadataComponentType.isNumericType(MetadataComponentType.FLOAT64) - ).toBe(true); - }); - - it("isNumericType throws without type", function () { - expect(function () { - MetadataComponentType.isNumericType(); - }).toThrowDeveloperError(); - }); - it("isIntegerType", function () { expect( MetadataComponentType.isIntegerType(MetadataComponentType.INT8) @@ -524,4 +489,88 @@ describe("Scene/MetadataComponentType", function () { MetadataComponentType.getSizeInBytes(MetadataComponentType.STRING); }).toThrowDeveloperError(); }); + + it("fromComponentDatatype", function () { + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.BYTE) + ).toBe(MetadataComponentType.INT8); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_BYTE + ) + ).toBe(MetadataComponentType.UINT8); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.SHORT) + ).toBe(MetadataComponentType.INT16); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_SHORT + ) + ).toBe(MetadataComponentType.UINT16); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.INT) + ).toBe(MetadataComponentType.INT32); + expect( + MetadataComponentType.fromComponentDatatype( + ComponentDatatype.UNSIGNED_INT + ) + ).toBe(MetadataComponentType.UINT32); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.FLOAT) + ).toBe(MetadataComponentType.FLOAT32); + expect( + MetadataComponentType.fromComponentDatatype(ComponentDatatype.DOUBLE) + ).toBe(MetadataComponentType.FLOAT64); + }); + + it("fromComponentDatatype throws without componentDatatype", function () { + expect(function () { + MetadataComponentType.fromComponentDatatype(); + }).toThrowDeveloperError(); + }); + + it("toComponentDatatype", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT8) + ).toBe(ComponentDatatype.BYTE); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT8) + ).toBe(ComponentDatatype.UNSIGNED_BYTE); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT16) + ).toBe(ComponentDatatype.SHORT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT16) + ).toBe(ComponentDatatype.UNSIGNED_SHORT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT32) + ).toBe(ComponentDatatype.INT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT32) + ).toBe(ComponentDatatype.UNSIGNED_INT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.FLOAT32) + ).toBe(ComponentDatatype.FLOAT); + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.FLOAT64) + ).toBe(ComponentDatatype.DOUBLE); + }); + + it("toComponentDatatype returns undefined for INT64", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.INT64) + ).toBeUndefined(); + }); + + it("toComponentDatatype returns undefined for UINT64", function () { + expect( + MetadataComponentType.toComponentDatatype(MetadataComponentType.UINT64) + ).toBeUndefined(); + }); + + it("toComponentDatatype throws without type", function () { + expect(function () { + MetadataComponentType.toComponentDatatype(); + }).toThrowDeveloperError(); + }); }); From af66631facdb033a4b6630b263a703da66f820bc Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 11:26:10 -0500 Subject: [PATCH 268/679] Remove @exception tags --- packages/engine/Source/Scene/MetadataComponentType.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/engine/Source/Scene/MetadataComponentType.js b/packages/engine/Source/Scene/MetadataComponentType.js index e94a48d84e7..a5540b09ee8 100644 --- a/packages/engine/Source/Scene/MetadataComponentType.js +++ b/packages/engine/Source/Scene/MetadataComponentType.js @@ -108,8 +108,6 @@ const MetadataComponentType = { * @param {MetadataComponentType} type The type. * @returns {Number|BigInt} The minimum value. * - * @exception {DeveloperError} type must be a numeric type - * * @private */ MetadataComponentType.getMinimum = function (type) { @@ -158,8 +156,6 @@ MetadataComponentType.getMinimum = function (type) { * @param {MetadataComponentType} type The type. * @returns {Number|BigInt} The maximum value. * - * @exception {DeveloperError} type must be a numeric type - * * @private */ MetadataComponentType.getMaximum = function (type) { @@ -382,8 +378,6 @@ MetadataComponentType.unapplyValueTransform = function (value, offset, scale) { * @param {MetadataComponentType} type The type. * @returns {Number} The size in bytes. * - * @exception {DeveloperError} type must be a numeric type - * * @private */ MetadataComponentType.getSizeInBytes = function (type) { From 78a85134c95f98be97b5f0ff008c7bbaa5eee4e1 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 13:14:05 -0500 Subject: [PATCH 269/679] Remove whitespace --- packages/widgets/Source/Viewer/Viewer.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 8d68c62af28..554f484ea04 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2247,6 +2247,7 @@ function updateZoomTarget(viewer) { boundingSphere.radius ); } + options = { offset: zoomOptions.offset, duration: zoomOptions.duration, @@ -2258,14 +2259,17 @@ function updateZoomTarget(viewer) { viewer._completeZoom(false); }, }; + if (viewer._zoomIsFlight) { camera.flyToBoundingSphere(boundingSphere, options); } else { camera.viewBoundingSphere(boundingSphere, zoomOptions.offset); camera.lookAtTransform(Matrix4.IDENTITY); + // Finish the promise viewer._completeZoom(true); } + clearZoom(viewer); }); } From 5eea7a04c00dbc46e016f9f8354ec43f38dc6b05 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 13:28:02 -0500 Subject: [PATCH 270/679] Update VoxelInspector.css [temp] --- .../Source/VoxelInspector/VoxelInspector.css | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspector.css b/packages/widgets/Source/VoxelInspector/VoxelInspector.css index 60cae4fd30d..cdbb905623c 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspector.css +++ b/packages/widgets/Source/VoxelInspector/VoxelInspector.css @@ -12,11 +12,6 @@ ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { margin-top: 5px; } -.cesium-cesiumInspector-visible { - width: 400px; - height: auto; -} - .cesium-cesiumInspector-slider input[type="number"] { text-align: left; background-color: #222; @@ -58,23 +53,23 @@ ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { background: transparent; color: #edffff; border: none; - padding: 1px; + padding: 0; white-space: pre; overflow-wrap: normal; overflow-x: auto; } -.cesium-3DTilesInspector { +.cesium-VoxelInspector { width: 300px; pointer-events: all; } -.cesium-3DTilesInspector-statistics { +.cesium-VoxelInspector-statistics { font-size: 11px; } -.cesium-3DTilesInspector div, -.cesium-3DTilesInspector input[type="range"] { +.cesium-VoxelInspector div, +.cesium-VoxelInspector input[type="range"] { width: 100%; box-sizing: border-box; } @@ -84,11 +79,11 @@ ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { overflow: auto; } -.cesium-3DTilesInspector .cesium-cesiumInspector-section { +.cesium-VoxelInspector .cesium-cesiumInspector-section { margin-top: 3px; } -.cesium-3DTilesInspector +.cesium-VoxelInspector .cesium-cesiumInspector-sectionHeader + .cesium-cesiumInspector-show { border-top: 1px solid white; From 0d968d1d86dd01f922a7fee5ebe7fbc0f2a015a0 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 13:29:09 -0500 Subject: [PATCH 271/679] Only import VoxelInspector.css once --- packages/widgets/Source/widgets.css | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/widgets/Source/widgets.css b/packages/widgets/Source/widgets.css index 54bdaae5bb1..773ddb8e984 100644 --- a/packages/widgets/Source/widgets.css +++ b/packages/widgets/Source/widgets.css @@ -16,4 +16,3 @@ @import url(./SelectionIndicator/SelectionIndicator.css); @import url(./Timeline/Timeline.css); @import url(./Viewer/Viewer.css); -@import url(./VoxelInspector/VoxelInspector.css); From 47a79e354e5737e0a660873a33c0128cb9eb6e3f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 15:18:36 -0500 Subject: [PATCH 272/679] Move more inspector functions to InspectorShared.js --- .../Cesium3DTilesInspector.js | 97 ++++++------------- .../Source/CesiumInspector/CesiumInspector.js | 1 - packages/widgets/Source/InspectorShared.js | 82 +++++++++++++++- 3 files changed, 107 insertions(+), 73 deletions(-) diff --git a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js index a113c5e8908..41733257ff7 100644 --- a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js +++ b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js @@ -1,10 +1,4 @@ -import { - Check, - defaultValue, - defined, - destroyObject, - getElement, -} from "@cesium/engine"; +import { Check, destroyObject, getElement } from "@cesium/engine"; import knockout from "../ThirdParty/knockout.js"; import InspectorShared from "../InspectorShared.js"; import Cesium3DTilesInspectorViewModel from "./Cesium3DTilesInspectorViewModel.js"; @@ -50,12 +44,13 @@ function Cesium3DTilesInspector(container, scene) { container.appendChild(element); const panel = document.createElement("div"); - this._panel = panel; panel.className = "cesium-cesiumInspector-dropDown"; element.appendChild(panel); const createSection = InspectorShared.createSection; const createCheckbox = InspectorShared.createCheckbox; + const createRangeInput = InspectorShared.createRangeInput; + const createButton = InspectorShared.createButton; const tilesetPanelContents = createSection( panel, @@ -111,15 +106,15 @@ function Cesium3DTilesInspector(container, scene) { properties.appendChild(propertiesField); tilesetPanelContents.appendChild(properties); tilesetPanelContents.appendChild( - makeButton("togglePickTileset", "Pick Tileset", "pickActive") + createButton("Pick Tileset", "togglePickTileset", "pickActive") ); tilesetPanelContents.appendChild( - makeButton("trimTilesCache", "Trim Tiles Cache") + createButton("Trim Tiles Cache", "trimTilesCache") ); tilesetPanelContents.appendChild(createCheckbox("Enable Picking", "picking")); displayPanelContents.appendChild(createCheckbox("Colorize", "colorize")); - displayPanelContents.appendChild( + const wireframeCheckbox = displayPanelContents.appendChild( createCheckbox( "Wireframe", "wireframe", @@ -127,7 +122,7 @@ function Cesium3DTilesInspector(container, scene) { ) ); - //Create warning text when the Wireframe checkbox is disabled + // Create warning text when the Wireframe checkbox is disabled const warningText = document.createElement("p"); warningText.setAttribute( "data-bind", @@ -139,7 +134,7 @@ function Cesium3DTilesInspector(container, scene) { ); warningText.innerText = "Set enableDebugWireframe to true in the tileset constructor to enable this option."; - displayPanelContents.lastChild.appendChild(warningText); + wireframeCheckbox.appendChild(warningText); displayPanelContents.appendChild( createCheckbox("Bounding Volumes", "showBoundingVolumes") @@ -160,13 +155,13 @@ function Cesium3DTilesInspector(container, scene) { "visible: pointCloudShading" ); pointCloudShadingContainer.appendChild( - makeRangeInput("geometricErrorScale", 0, 2, 0.01, "Geometric Error Scale") + createRangeInput("Geometric Error Scale", "geometricErrorScale", 0, 2, 0.01) ); pointCloudShadingContainer.appendChild( - makeRangeInput("maximumAttenuation", 0, 32, 1, "Maximum Attenuation") + createRangeInput("Maximum Attenuation", "maximumAttenuation", 0, 32, 1) ); pointCloudShadingContainer.appendChild( - makeRangeInput("baseResolution", 0, 1, 0.01, "Base Resolution") + createRangeInput("Base Resolution", "baseResolution", 0, 1, 0.01) ); pointCloudShadingContainer.appendChild( createCheckbox("Eye Dome Lighting (EDL)", "eyeDomeLighting") @@ -176,10 +171,10 @@ function Cesium3DTilesInspector(container, scene) { const edlContainer = document.createElement("div"); edlContainer.setAttribute("data-bind", "visible: eyeDomeLighting"); edlContainer.appendChild( - makeRangeInput("eyeDomeLightingStrength", 0, 2.0, 0.1, "EDL Strength") + createRangeInput("EDL Strength", "eyeDomeLightingStrength", 0, 2.0, 0.1) ); edlContainer.appendChild( - makeRangeInput("eyeDomeLightingRadius", 0, 4.0, 0.1, "EDL Radius") + createRangeInput("EDL Radius", "eyeDomeLightingRadius", 0, 4.0, 0.1) ); pointCloudShadingContainer.appendChild(edlContainer); @@ -191,12 +186,12 @@ function Cesium3DTilesInspector(container, scene) { ); const sseContainer = document.createElement("div"); sseContainer.appendChild( - makeRangeInput( + createRangeInput( + "Maximum Screen Space Error", "maximumScreenSpaceError", 0, 128, - 1, - "Maximum Screen Space Error" + 1 ) ); updatePanelContents.appendChild(sseContainer); @@ -206,22 +201,22 @@ function Cesium3DTilesInspector(container, scene) { "visible: dynamicScreenSpaceError" ); dynamicScreenSpaceErrorContainer.appendChild( - makeRangeInput( + createRangeInput( + "Screen Space Error Density", "dynamicScreenSpaceErrorDensitySliderValue", 0, 1, 0.005, - "Screen Space Error Density", "dynamicScreenSpaceErrorDensity" ) ); dynamicScreenSpaceErrorContainer.appendChild( - makeRangeInput( + createRangeInput( + "Screen Space Error Factor", "dynamicScreenSpaceErrorFactor", 1, 10, - 0.1, - "Screen Space Error Factor" + 0.1 ) ); updatePanelContents.appendChild(dynamicScreenSpaceErrorContainer); @@ -280,7 +275,7 @@ function Cesium3DTilesInspector(container, scene) { ); stylePanelEditor.className = "cesium-cesiumInspector-styleEditor"; stylePanelEditor.appendChild(styleEditor); - const closeStylesBtn = makeButton("compileStyle", "Compile (Ctrl+Enter)"); + const closeStylesBtn = createButton("Compile (Ctrl+Enter)", "compileStyle"); stylePanelEditor.appendChild(closeStylesBtn); const errorBox = document.createElement("div"); errorBox.className = "cesium-cesiumInspector-error"; @@ -306,23 +301,23 @@ function Cesium3DTilesInspector(container, scene) { ); const skipScreenSpaceErrorFactorContainer = document.createElement("div"); skipScreenSpaceErrorFactorContainer.appendChild( - makeRangeInput("skipScreenSpaceErrorFactor", 1, 50, 1, "Skip SSE Factor") + createRangeInput("Skip SSE Factor", "skipScreenSpaceErrorFactor", 1, 50, 1) ); optimizationPanelContents.appendChild(skipScreenSpaceErrorFactorContainer); const baseScreenSpaceError = document.createElement("div"); baseScreenSpaceError.appendChild( - makeRangeInput( + createRangeInput( + "SSE before skipping LOD", "baseScreenSpaceError", 0, 4096, - 1, - "SSE before skipping LOD" + 1 ) ); optimizationPanelContents.appendChild(baseScreenSpaceError); const skipLevelsContainer = document.createElement("div"); skipLevelsContainer.appendChild( - makeRangeInput("skipLevels", 0, 10, 1, "Min. levels to skip") + createRangeInput("Min. levels to skip", "skipLevels", 0, 10, 1) ); optimizationPanelContents.appendChild(skipLevelsContainer); optimizationPanelContents.appendChild( @@ -383,42 +378,4 @@ Cesium3DTilesInspector.prototype.destroy = function () { return destroyObject(this); }; -function makeRangeInput(property, min, max, step, text, displayProperty) { - displayProperty = defaultValue(displayProperty, property); - const input = document.createElement("input"); - input.setAttribute("data-bind", `value: ${displayProperty}`); - input.type = "number"; - - const slider = document.createElement("input"); - slider.type = "range"; - slider.min = min; - slider.max = max; - slider.step = step; - slider.setAttribute("data-bind", `valueUpdate: "input", value: ${property}`); - - const wrapper = document.createElement("div"); - wrapper.appendChild(slider); - - const container = document.createElement("div"); - container.className = "cesium-cesiumInspector-slider"; - container.appendChild(document.createTextNode(text)); - container.appendChild(input); - container.appendChild(wrapper); - - return container; -} - -function makeButton(action, text, active) { - const button = document.createElement("button"); - button.type = "button"; - button.textContent = text; - button.className = "cesium-cesiumInspector-pickButton"; - let binding = `click: ${action}`; - if (defined(active)) { - binding += `, css: {"cesium-cesiumInspector-pickButtonHighlight" : ${active}}`; - } - button.setAttribute("data-bind", binding); - - return button; -} export default Cesium3DTilesInspector; diff --git a/packages/widgets/Source/CesiumInspector/CesiumInspector.js b/packages/widgets/Source/CesiumInspector/CesiumInspector.js index ffb9c14eccf..9152cfd3a8d 100644 --- a/packages/widgets/Source/CesiumInspector/CesiumInspector.js +++ b/packages/widgets/Source/CesiumInspector/CesiumInspector.js @@ -53,7 +53,6 @@ function CesiumInspector(container, scene) { container.appendChild(this._element); const panel = document.createElement("div"); - this._panel = panel; panel.className = "cesium-cesiumInspector-dropDown"; element.appendChild(panel); diff --git a/packages/widgets/Source/InspectorShared.js b/packages/widgets/Source/InspectorShared.js index 5c0488024cc..8d01141b9fd 100644 --- a/packages/widgets/Source/InspectorShared.js +++ b/packages/widgets/Source/InspectorShared.js @@ -1,7 +1,7 @@ -import { Check, defined } from "@cesium/engine"; +import { Check, defaultValue, defined } from "@cesium/engine"; /** - * A static class with helper functions used by the CesiumInspector and Cesium3DTilesInspector + * A static class with helper functions used by CesiumInspector, Cesium3DTilesInspector, and VoxelInspector * @private */ const InspectorShared = {}; @@ -83,4 +83,82 @@ InspectorShared.createSection = function ( section.appendChild(sectionContent); return sectionContent; }; + +/** + * Creates a range input + * @param {String} rangeText The text to display + * @param {String} sliderValueBinding The name of the variable used for slider value binding + * @param {Number} min The minimum value + * @param {Number} max The maximum value + * @param {Number} [step] The step size. Defaults to "any". + * @param {String} [inputValueBinding] The name of the variable used for input value binding + * @return {Element} + */ +InspectorShared.createRangeInput = function ( + rangeText, + sliderValueBinding, + min, + max, + step, + inputValueBinding +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.string("rangeText", rangeText); + Check.typeOf.string("sliderValueBinding", sliderValueBinding); + Check.typeOf.number("min", min); + Check.typeOf.number("max", max); + //>>includeEnd('debug'); + + inputValueBinding = defaultValue(inputValueBinding, sliderValueBinding); + const input = document.createElement("input"); + input.setAttribute("data-bind", `value: ${inputValueBinding}`); + input.type = "number"; + + const slider = document.createElement("input"); + slider.type = "range"; + slider.min = min; + slider.max = max; + slider.step = defaultValue(step, "any"); + slider.setAttribute( + "data-bind", + `valueUpdate: "input", value: ${sliderValueBinding}` + ); + + const wrapper = document.createElement("div"); + wrapper.appendChild(slider); + + const container = document.createElement("div"); + container.className = "cesium-cesiumInspector-slider"; + container.appendChild(document.createTextNode(rangeText)); + container.appendChild(input); + container.appendChild(wrapper); + + return container; +}; + +/** + * Creates a button component + * @param {String} buttonText The button text + * @param {String} clickedBinding The name of the variable used for clicked binding + * @param {String} [activeBinding] The name of the variable used for active binding + * @return {Element} + */ +InspectorShared.createButton = function ( + buttonText, + clickedBinding, + activeBinding +) { + const button = document.createElement("button"); + button.type = "button"; + button.textContent = buttonText; + button.className = "cesium-cesiumInspector-pickButton"; + let binding = `click: ${clickedBinding}`; + if (defined(activeBinding)) { + binding += `, css: {"cesium-cesiumInspector-pickButtonHighlight" : ${activeBinding}}`; + } + button.setAttribute("data-bind", binding); + + return button; +}; + export default InspectorShared; From 5fd8f3d6d6a194b77ece7e30f03bf379e395e5bc Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 15:46:10 -0500 Subject: [PATCH 273/679] Update VoxelInspector --- .../Source/VoxelInspector/VoxelInspector.js | 207 +++++++----------- .../VoxelInspector/VoxelInspectorViewModel.js | 74 ++++++- 2 files changed, 155 insertions(+), 126 deletions(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspector.js b/packages/widgets/Source/VoxelInspector/VoxelInspector.js index dfe67f32ebf..e7ac945dea2 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspector.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspector.js @@ -2,13 +2,11 @@ import { Cartesian3, Math as CesiumMath, Check, - defaultValue, destroyObject, Ellipsoid, getElement, VoxelShapeType, } from "@cesium/engine"; - import knockout from "../ThirdParty/knockout.js"; import InspectorShared from "../InspectorShared.js"; import VoxelInspectorViewModel from "./VoxelInspectorViewModel.js"; @@ -32,89 +30,124 @@ function VoxelInspector(container, scene) { const element = document.createElement("div"); const viewModel = new VoxelInspectorViewModel(scene); + this._viewModel = viewModel; + this._container = container; + this._element = element; + const text = document.createElement("div"); text.textContent = "Voxel Inspector"; text.className = "cesium-cesiumInspector-button"; + text.setAttribute("data-bind", "click: toggleInspector"); element.appendChild(text); - - element.className = - "cesium-cesiumInspector cesium-VoxelInspector cesium-cesiumInspector-hidden"; - text.addEventListener("click", function () { - element.classList.toggle("cesium-cesiumInspector-visible"); - element.classList.toggle("cesium-cesiumInspector-hidden"); - }); - + element.className = "cesium-cesiumInspector cesium-VoxelInspector"; + element.setAttribute( + "data-bind", + 'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}' + ); container.appendChild(element); const panel = document.createElement("div"); panel.className = "cesium-cesiumInspector-dropDown"; element.appendChild(panel); + const createSection = InspectorShared.createSection; + const createCheckbox = InspectorShared.createCheckbox; + const createRangeInput = InspectorShared.createRangeInput; + const createButton = InspectorShared.createButton; + + const displayPanelContents = createSection( + panel, + "Display", + "displayVisible", + "toggleDisplay" + ); + + const transformPanelContents = createSection( + panel, + "Transform", + "transformVisible", + "toggleTransform" + ); + + const boundsPanelContents = createSection( + panel, + "Bounds", + "boundsVisible", + "toggleBounds" + ); + + const clippingPanelContents = createSection( + panel, + "Clipping", + "clippingVisible", + "toggleClipping" + ); + + const shaderPanelContents = createSection( + panel, + "Shader", + "shaderVisible", + "toggleShader" + ); + // Display - const displayPanelContents = createSection(panel, "Display"); - - const { createCheckbox } = InspectorShared; - [ - ["Depth Test", "depthTest"], - ["Show", "show"], - ["Disable Update", "disableUpdate"], - ["Debug Draw", "debugDraw"], - ["Jitter", "jitter"], - ["Nearest Sampling", "nearestSampling"], - ].forEach(([title, variable]) => { - displayPanelContents.appendChild(createCheckbox(title, variable)); - }); + displayPanelContents.appendChild(createCheckbox("Depth Test", "depthTest")); + displayPanelContents.appendChild(createCheckbox("Show", "show")); + displayPanelContents.appendChild( + createCheckbox("Disable Update", "disableUpdate") + ); + displayPanelContents.appendChild(createCheckbox("Debug Draw", "debugDraw")); + displayPanelContents.appendChild(createCheckbox("Jitter", "jitter")); + displayPanelContents.appendChild( + createCheckbox("Nearest Sampling", "nearestSampling") + ); displayPanelContents.appendChild( - makeRangeInput("Level Blend Factor", "levelBlendFactor", 0.0, 1.0) + createRangeInput("Level Blend Factor", "levelBlendFactor", 0.0, 1.0) ); displayPanelContents.appendChild( - makeRangeInput("Screen Space Error", "screenSpaceError", 0, 128) + createRangeInput("Screen Space Error", "screenSpaceError", 0, 128) ); displayPanelContents.appendChild( - makeRangeInput("Step Size", "stepSize", 0.0, 2.0) + createRangeInput("Step Size", "stepSize", 0.0, 2.0) ); // Transform - const transformPanelContents = createSection(panel, "Transform"); - const maxTrans = 20000000.0; const maxScale = 20000000.0; const maxAngle = CesiumMath.PI; transformPanelContents.appendChild( - makeRangeInput("Translation X", "translationX", -maxTrans, +maxTrans) + createRangeInput("Translation X", "translationX", -maxTrans, +maxTrans) ); transformPanelContents.appendChild( - makeRangeInput("Translation Y", "translationY", -maxTrans, +maxTrans) + createRangeInput("Translation Y", "translationY", -maxTrans, +maxTrans) ); transformPanelContents.appendChild( - makeRangeInput("Translation Z", "translationZ", -maxTrans, +maxTrans) + createRangeInput("Translation Z", "translationZ", -maxTrans, +maxTrans) ); transformPanelContents.appendChild( - makeRangeInput("Scale X", "scaleX", -maxScale, +maxScale) + createRangeInput("Scale X", "scaleX", -maxScale, +maxScale) ); transformPanelContents.appendChild( - makeRangeInput("Scale Y", "scaleY", -maxScale, +maxScale) + createRangeInput("Scale Y", "scaleY", -maxScale, +maxScale) ); transformPanelContents.appendChild( - makeRangeInput("Scale Z", "scaleZ", -maxScale, +maxScale) + createRangeInput("Scale Z", "scaleZ", -maxScale, +maxScale) ); transformPanelContents.appendChild( - makeRangeInput("Heading", "angleX", -maxAngle, +maxAngle) + createRangeInput("Heading", "angleX", -maxAngle, +maxAngle) ); transformPanelContents.appendChild( - makeRangeInput("Pitch", "angleY", -maxAngle, +maxAngle) + createRangeInput("Pitch", "angleY", -maxAngle, +maxAngle) ); transformPanelContents.appendChild( - makeRangeInput("Roll", "angleZ", -maxAngle, +maxAngle) + createRangeInput("Roll", "angleZ", -maxAngle, +maxAngle) ); // Bounds - const boundsPanelContents = createSection(panel, "Bounds"); - const boxMinBounds = VoxelShapeType.getMinBounds(VoxelShapeType.BOX); const boxMaxBounds = VoxelShapeType.getMaxBounds(VoxelShapeType.BOX); @@ -196,8 +229,6 @@ function VoxelInspector(container, scene) { ); // Clipping - const clippingPanelContents = createSection(panel, "Clipping"); - makeCoordinateRange( "Max X", "Min X", @@ -256,7 +287,6 @@ function VoxelInspector(container, scene) { ); // Shader - const shaderPanelContents = createSection(panel, "Shader"); const shaderPanelEditor = document.createElement("div"); shaderPanelContents.appendChild(shaderPanelEditor); @@ -267,9 +297,9 @@ function VoxelInspector(container, scene) { ); shaderPanelEditor.className = "cesium-cesiumInspector-styleEditor"; shaderPanelEditor.appendChild(shaderEditor); - const compileShaderButton = makeButton( - "compileShader", - "Compile (Ctrl+Enter)" + const compileShaderButton = createButton( + "Compile (Ctrl+Enter)", + "compileShader" ); shaderPanelEditor.appendChild(compileShaderButton); @@ -282,11 +312,6 @@ function VoxelInspector(container, scene) { shaderPanelEditor.appendChild(compilationText); knockout.applyBindings(viewModel, element); - - this._viewModel = viewModel; - this._container = container; - this._element = element; - this._panel = panel; } Object.defineProperties(VoxelInspector.prototype, { @@ -334,74 +359,6 @@ VoxelInspector.prototype.destroy = function () { return destroyObject(this); }; -/** - * Creates a hide-able section element in an Inspector panel - * Similar to InspectorShared.createSection, but without the knockout dependency - * @param {HTMLElement} panel The parent element - * @param {String} headerText The text to display at the top of the section - * @returns {HTMLElement} An element containing the section content - * @private - */ -function createSection(panel, headerText) { - //>>includeStart('debug', pragmas.debug); - Check.defined("panel", panel); - Check.typeOf.string("headerText", headerText); - //>>includeEnd('debug'); - - const section = document.createElement("div"); - section.className = - "cesium-cesiumInspector-section cesium-cesiumInspector-section-collapsed"; - panel.appendChild(section); - - const sectionHeader = document.createElement("h3"); - sectionHeader.className = "cesium-cesiumInspector-sectionHeader"; - sectionHeader.appendChild(document.createTextNode(headerText)); - sectionHeader.addEventListener("click", function () { - section.classList.toggle("cesium-cesiumInspector-section-collapsed"); - }); - section.appendChild(sectionHeader); - - const sectionContent = document.createElement("div"); - sectionContent.className = "cesium-cesiumInspector-sectionContent"; - section.appendChild(sectionContent); - return sectionContent; -} - -function makeRangeInput(text, property, min, max, step, displayProperty) { - displayProperty = defaultValue(displayProperty, property); - const input = document.createElement("input"); - input.setAttribute("data-bind", `value: ${displayProperty}`); - input.type = "number"; - - const slider = document.createElement("input"); - slider.type = "range"; - slider.min = min; - slider.max = max; - slider.step = defaultValue(step, "any"); - slider.setAttribute("data-bind", `valueUpdate: "input", value: ${property}`); - - const wrapper = document.createElement("div"); - wrapper.appendChild(slider); - - const container = document.createElement("div"); - container.className = "cesium-cesiumInspector-slider"; - container.appendChild(document.createTextNode(text)); - container.appendChild(input); - container.appendChild(wrapper); - - return container; -} - -function makeButton(action, text) { - const button = document.createElement("button"); - button.type = "button"; - button.textContent = text; - button.className = "cesium-cesiumInspector-pickButton"; - const binding = `click: ${action}`; - button.setAttribute("data-bind", binding); - return button; -} - function makeCoordinateRange( maxXTitle, minXTitle, @@ -420,18 +377,20 @@ function makeCoordinateRange( allowedShape, parentContainer ) { + const createRangeInput = InspectorShared.createRangeInput; + const min = defaultMinBounds; const max = defaultMaxBounds; const boundsElement = parentContainer.appendChild( document.createElement("div") ); boundsElement.setAttribute("data-bind", `if: ${allowedShape}`); - boundsElement.appendChild(makeRangeInput(maxXTitle, maxXVar, min.x, max.x)); - boundsElement.appendChild(makeRangeInput(minXTitle, minXVar, min.x, max.x)); - boundsElement.appendChild(makeRangeInput(maxYTitle, maxYVar, min.y, max.y)); - boundsElement.appendChild(makeRangeInput(minYTitle, minYVar, min.y, max.y)); - boundsElement.appendChild(makeRangeInput(maxZTitle, maxZVar, min.z, max.z)); - boundsElement.appendChild(makeRangeInput(minZTitle, minZVar, min.z, max.z)); + boundsElement.appendChild(createRangeInput(maxXTitle, maxXVar, min.x, max.x)); + boundsElement.appendChild(createRangeInput(minXTitle, minXVar, min.x, max.x)); + boundsElement.appendChild(createRangeInput(maxYTitle, maxYVar, min.y, max.y)); + boundsElement.appendChild(createRangeInput(minYTitle, minYVar, min.y, max.y)); + boundsElement.appendChild(createRangeInput(maxZTitle, maxZVar, min.z, max.z)); + boundsElement.appendChild(createRangeInput(minZTitle, minZVar, min.z, max.z)); } export default VoxelInspector; diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index 2fd0a27f00b..282d1f04be6 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -121,6 +121,36 @@ function VoxelInspectorViewModel(scene) { }; } + addProperty({ + name: "inspectorVisible", + initialValue: true, + }); + + addProperty({ + name: "displayVisible", + initialValue: false, + }); + + addProperty({ + name: "transformVisible", + initialValue: false, + }); + + addProperty({ + name: "boundsVisible", + initialValue: false, + }); + + addProperty({ + name: "clippingVisible", + initialValue: false, + }); + + addProperty({ + name: "shaderVisible", + initialValue: false, + }); + addProperty({ name: "shaderString", initialValue: "", @@ -749,9 +779,50 @@ Object.defineProperties(VoxelInspectorViewModel.prototype, { }, }); +/** + * Toggles the inspector visibility + */ +VoxelInspectorViewModel.prototype.toggleInspector = function () { + this.inspectorVisible = !this.inspectorVisible; +}; + +/** + * Toggles the visibility of the display section + */ +VoxelInspectorViewModel.prototype.toggleDisplay = function () { + this.displayVisible = !this.displayVisible; +}; + +/** + * Toggles the visibility of the transform section + */ +VoxelInspectorViewModel.prototype.toggleTransform = function () { + this.transformVisible = !this.transformVisible; +}; + +/** + * Toggles the visibility of the bounds section + */ +VoxelInspectorViewModel.prototype.toggleBounds = function () { + this.boundsVisible = !this.boundsVisible; +}; + +/** + * Toggles the visibility of the clipping section + */ +VoxelInspectorViewModel.prototype.toggleClipping = function () { + this.clippingVisible = !this.clippingVisible; +}; + +/** + * Toggles the visibility of the shader section + */ +VoxelInspectorViewModel.prototype.toggleShader = function () { + this.shaderVisible = !this.shaderVisible; +}; + /** * Compiles the shader in the shader editor. - * @private */ VoxelInspectorViewModel.prototype.compileShader = function () { if (defined(this._voxelPrimitive)) { @@ -765,7 +836,6 @@ VoxelInspectorViewModel.prototype.compileShader = function () { /** * Handles key press events on the shader editor. - * @private */ VoxelInspectorViewModel.prototype.shaderEditorKeyPress = function ( sender, From abd2b0f306b9cc060f86146b33a0025863f94be0 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 15:57:51 -0500 Subject: [PATCH 274/679] Simplify VoxelInspector.css --- .../Source/VoxelInspector/VoxelInspector.css | 96 ------------------- 1 file changed, 96 deletions(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspector.css b/packages/widgets/Source/VoxelInspector/VoxelInspector.css index cdbb905623c..fd97e9b0494 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspector.css +++ b/packages/widgets/Source/VoxelInspector/VoxelInspector.css @@ -1,84 +1,14 @@ -ul.cesium-cesiumInspector-statistics { - margin: 0; - padding-top: 3px; - padding-bottom: 3px; -} - -ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { - border-top: 1px solid #aaa; -} - -.cesium-cesiumInspector-slider { - margin-top: 5px; -} - -.cesium-cesiumInspector-slider input[type="number"] { - text-align: left; - background-color: #222; - outline: none; - border: 1px solid #444; - color: #edffff; - width: 100px; - border-radius: 3px; - padding: 1px; - margin-left: 10px; - cursor: auto; -} - -.cesium-cesiumInspector-slider input[type="number"]::-webkit-outer-spin-button, -.cesium-cesiumInspector-slider input[type="number"]::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} - -.cesium-cesiumInspector-slider input[type="range"] { - margin-left: 5px; - vertical-align: middle; -} - -.cesium-cesiumInspector-hide .cesium-cesiumInspector-styleEditor { - display: none; -} - -.cesium-cesiumInspector-styleEditor { - padding: 10px; - border-radius: 5px; - background: rgba(48, 51, 54, 0.8); - border: 1px solid #444; -} - -.cesium-cesiumInspector-styleEditor textarea { - width: 100%; - height: 300px; - background: transparent; - color: #edffff; - border: none; - padding: 0; - white-space: pre; - overflow-wrap: normal; - overflow-x: auto; -} - .cesium-VoxelInspector { width: 300px; pointer-events: all; } -.cesium-VoxelInspector-statistics { - font-size: 11px; -} - .cesium-VoxelInspector div, .cesium-VoxelInspector input[type="range"] { width: 100%; box-sizing: border-box; } -.cesium-cesiumInspector-error { - color: #ff9e9e; - overflow: auto; -} - .cesium-VoxelInspector .cesium-cesiumInspector-section { margin-top: 3px; } @@ -88,29 +18,3 @@ ul.cesium-cesiumInspector-statistics + ul.cesium-cesiumInspector-statistics { + .cesium-cesiumInspector-show { border-top: 1px solid white; } - -input.cesium-cesiumInspector-url { - overflow: hidden; - white-space: nowrap; - overflow-x: scroll; - background-color: transparent; - color: white; - outline: none; - border: none; - height: 1em; - width: 100%; -} - -.cesium-cesiumInspector .field-group { - display: table; -} - -.cesium-cesiumInspector .field-group > label { - display: table-cell; - font-weight: bold; -} - -.cesium-cesiumInspector .field-group > .field { - display: table-cell; - width: 100%; -} From 8927053511ba6411e925cfed2797ec07238c4911 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 19 Dec 2022 16:40:11 -0500 Subject: [PATCH 275/679] Add checks --- packages/widgets/Source/InspectorShared.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/widgets/Source/InspectorShared.js b/packages/widgets/Source/InspectorShared.js index 8d01141b9fd..f503a1cb935 100644 --- a/packages/widgets/Source/InspectorShared.js +++ b/packages/widgets/Source/InspectorShared.js @@ -148,6 +148,11 @@ InspectorShared.createButton = function ( clickedBinding, activeBinding ) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.string("buttonText", buttonText); + Check.typeOf.string("clickedBinding", clickedBinding); + //>>includeEnd('debug'); + const button = document.createElement("button"); button.type = "button"; button.textContent = buttonText; From 1ab0765b439c98ca3c53208f109df750891ad791 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Tue, 20 Dec 2022 12:27:34 -0500 Subject: [PATCH 276/679] Remove async paths from EOP constructor --- .../EOP-Invalid.json | 4 +- .../Source/Core/EarthOrientationParameters.js | 129 ++--- packages/engine/Source/Core/Transforms.js | 10 +- .../Core/EarthOrientationParametersSpec.js | 41 +- packages/engine/Specs/Core/TransformsSpec.js | 480 +++++++++--------- 5 files changed, 337 insertions(+), 327 deletions(-) diff --git a/Specs/Data/EarthOrientationParameters/EOP-Invalid.json b/Specs/Data/EarthOrientationParameters/EOP-Invalid.json index 76f3ead2ecc..57fc74d9a20 100644 --- a/Specs/Data/EarthOrientationParameters/EOP-Invalid.json +++ b/Specs/Data/EarthOrientationParameters/EOP-Invalid.json @@ -1,4 +1,4 @@ { - 'foo' : ['hi', 'bye'], - 'bar' : 1.23 + "foo" : ["hi", "bye"], + "bar" : 1.23 } diff --git a/packages/engine/Source/Core/EarthOrientationParameters.js b/packages/engine/Source/Core/EarthOrientationParameters.js index e35d19af9d6..cc55befb390 100644 --- a/packages/engine/Source/Core/EarthOrientationParameters.js +++ b/packages/engine/Source/Core/EarthOrientationParameters.js @@ -1,4 +1,5 @@ import binarySearch from "./binarySearch.js"; +import Check from "./Check.js"; import defaultValue from "./defaultValue.js"; import defined from "./defined.js"; import EarthOrientationParametersSample from "./EarthOrientationParametersSample.js"; @@ -19,10 +20,6 @@ import TimeStandard from "./TimeStandard.js"; * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Resource|String} [options.url] The URL from which to obtain EOP data. If neither this - * parameter nor options.data is specified, all EOP values are assumed - * to be 0.0. If options.data is specified, this parameter is - * ignored. * @param {Object} [options.data] The actual EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. @@ -32,22 +29,6 @@ import TimeStandard from "./TimeStandard.js"; * new leap seconds should be handled correctly in the context * of the EOP data but otherwise ignored. * - * @example - * // An example EOP data file, EOP.json: - * { - * "columnNames" : ["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"], - * "samples" : [ - * "2011-07-01T00:00:00Z",55743.0,2.117957047295119e-7,2.111518721609984e-6,-0.2908948,-2.956e-4,3.393695767766752e-11,3.3452143996557983e-10,34.0, - * "2011-07-02T00:00:00Z",55744.0,2.193297093339541e-7,2.115460256837405e-6,-0.29065,-1.824e-4,-8.241832578862112e-11,5.623838700870617e-10,34.0, - * "2011-07-03T00:00:00Z",55745.0,2.262286080161428e-7,2.1191157519929706e-6,-0.2905572,1.9e-6,-3.490658503988659e-10,6.981317007977318e-10,34.0 - * ] - * } - * - * @example - * // Loading the EOP data - * const eop = new Cesium.EarthOrientationParameters({ url : 'Data/EOP.json' }); - * Cesium.Transforms.earthOrientationParameters = eop; - * * @private */ function EarthOrientationParameters(options) { @@ -67,27 +48,11 @@ function EarthOrientationParameters(options) { this._columnCount = 0; this._lastIndex = -1; - this._downloadPromise = undefined; - this._dataError = undefined; - this._addNewLeapSeconds = defaultValue(options.addNewLeapSeconds, true); if (defined(options.data)) { // Use supplied EOP data. onDataReady(this, options.data); - } else if (defined(options.url)) { - const resource = Resource.createIfNeeded(options.url); - - // Download EOP data. - const that = this; - this._downloadPromise = resource - .fetchJson() - .then(function (eopData) { - onDataReady(that, eopData); - }) - .catch(function () { - that._dataError = `An error occurred while retrieving the EOP data from the URL ${resource.url}.`; - }); } else { // Use all zeros for EOP data. onDataReady(this, { @@ -107,13 +72,64 @@ function EarthOrientationParameters(options) { } } +/** + * + * @param {Resource|String} [url] The URL from which to obtain EOP data. If neither this + * parameter nor options.data is specified, all EOP values are assumed + * to be 0.0. If options.data is specified, this parameter is + * ignored. + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.addNewLeapSeconds=true] True if leap seconds that + * are specified in the EOP data but not in {@link JulianDate.leapSeconds} + * should be added to {@link JulianDate.leapSeconds}. False if + * new leap seconds should be handled correctly in the context + * of the EOP data but otherwise ignored. + * + * @example + * // An example EOP data file, EOP.json: + * { + * "columnNames" : ["dateIso8601","modifiedJulianDateUtc","xPoleWanderRadians","yPoleWanderRadians","ut1MinusUtcSeconds","lengthOfDayCorrectionSeconds","xCelestialPoleOffsetRadians","yCelestialPoleOffsetRadians","taiMinusUtcSeconds"], + * "samples" : [ + * "2011-07-01T00:00:00Z",55743.0,2.117957047295119e-7,2.111518721609984e-6,-0.2908948,-2.956e-4,3.393695767766752e-11,3.3452143996557983e-10,34.0, + * "2011-07-02T00:00:00Z",55744.0,2.193297093339541e-7,2.115460256837405e-6,-0.29065,-1.824e-4,-8.241832578862112e-11,5.623838700870617e-10,34.0, + * "2011-07-03T00:00:00Z",55745.0,2.262286080161428e-7,2.1191157519929706e-6,-0.2905572,1.9e-6,-3.490658503988659e-10,6.981317007977318e-10,34.0 + * ] + * } + * + * @example + * // Loading the EOP data + * const eop = await Cesium.EarthOrientationParameters.fromUrl('Data/EOP.json'); + * Cesium.Transforms.earthOrientationParameters = eop; + */ +EarthOrientationParameters.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + const resource = Resource.createIfNeeded(url); + + // Download EOP data. + let eopData; + try { + eopData = await resource.fetchJson(); + } catch (e) { + throw new RuntimeError( + `An error occurred while retrieving the EOP data from the URL ${resource.url}.` + ); + } + + return new EarthOrientationParameters({ + addNewLeapSeconds: options.addNewLeapSeconds, + data: eopData, + }); +}; + /** * A default {@link EarthOrientationParameters} instance that returns zero for all EOP values. */ EarthOrientationParameters.NONE = Object.freeze({ - getPromiseToLoad: function () { - return Promise.resolve(); - }, compute: function (date, result) { if (!defined(result)) { result = new EarthOrientationParametersSample(0.0, 0.0, 0.0, 0.0, 0.0); @@ -128,16 +144,6 @@ EarthOrientationParameters.NONE = Object.freeze({ }, }); -/** - * Gets a promise that, when resolved, indicates that the EOP data has been loaded and is - * ready to use. - * - * @returns {Promise} The promise. - */ -EarthOrientationParameters.prototype.getPromiseToLoad = function () { - return Promise.resolve(this._downloadPromise); -}; - /** * Computes the Earth Orientation Parameters (EOP) for a given date by interpolating. * If the EOP data has not yet been download, this method returns undefined. @@ -151,15 +157,11 @@ EarthOrientationParameters.prototype.getPromiseToLoad = function () { * * @exception {RuntimeError} The loaded EOP data has an error and cannot be used. * - * @see EarthOrientationParameters#getPromiseToLoad + * @see EarthOrientationParameters#fromUrl */ EarthOrientationParameters.prototype.compute = function (date, result) { // We cannot compute until the samples are available. if (!defined(this._samples)) { - if (defined(this._dataError)) { - throw new RuntimeError(this._dataError); - } - return undefined; } @@ -237,15 +239,15 @@ function compareLeapSecondDates(leapSecond, dateToFind) { function onDataReady(eop, eopData) { if (!defined(eopData.columnNames)) { - eop._dataError = - "Error in loaded EOP data: The columnNames property is required."; - return; + throw new RuntimeError( + "Error in loaded EOP data: The columnNames property is required." + ); } if (!defined(eopData.samples)) { - eop._dataError = - "Error in loaded EOP data: The samples property is required."; - return; + throw new RuntimeError( + "Error in loaded EOP data: The samples property is required." + ); } const dateColumn = eopData.columnNames.indexOf("modifiedJulianDateUtc"); @@ -277,9 +279,9 @@ function onDataReady(eop, eopData) { yCelestialPoleOffsetRadiansColumn < 0 || taiMinusUtcSecondsColumn < 0 ) { - eop._dataError = - "Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns"; - return; + throw new RuntimeError( + "Error in loaded EOP data: The columnNames property must include modifiedJulianDateUtc, xPoleWanderRadians, yPoleWanderRadians, ut1MinusUtcSeconds, xCelestialPoleOffsetRadians, yCelestialPoleOffsetRadians, and taiMinusUtcSeconds columns" + ); } const samples = (eop._samples = eopData.samples); @@ -428,4 +430,5 @@ function interpolate(eop, dates, samples, date, before, after, result) { ); return result; } + export default EarthOrientationParameters; diff --git a/packages/engine/Source/Core/Transforms.js b/packages/engine/Source/Core/Transforms.js index ec3e433e47a..1642351d138 100644 --- a/packages/engine/Source/Core/Transforms.js +++ b/packages/engine/Source/Core/Transforms.js @@ -659,9 +659,8 @@ const j2000ttDays = 2451545.0; * * @example * const interval = new Cesium.TimeInterval(...); - * Promise.resolve(Cesium.Transforms.preloadIcrfFixed(interval)).then(function() { - * // the data is now loaded - * }); + * await Cesium.Transforms.preloadIcrfFixed(interval)); + * // the data is now loaded * * @see Transforms.computeIcrfToFixedMatrix * @see Transforms.computeFixedToIcrfMatrix @@ -672,15 +671,12 @@ Transforms.preloadIcrfFixed = function (timeInterval) { const stopDayTT = timeInterval.stop.dayNumber; const stopSecondTT = timeInterval.stop.secondsOfDay + ttMinusTai; - const xysPromise = Transforms.iau2006XysData.preload( + return Transforms.iau2006XysData.preload( startDayTT, startSecondTT, stopDayTT, stopSecondTT ); - const eopPromise = Transforms.earthOrientationParameters.getPromiseToLoad(); - - return Promise.all([xysPromise, eopPromise]); }; /** diff --git a/packages/engine/Specs/Core/EarthOrientationParametersSpec.js b/packages/engine/Specs/Core/EarthOrientationParametersSpec.js index 973c428507d..23e41e19ee2 100644 --- a/packages/engine/Specs/Core/EarthOrientationParametersSpec.js +++ b/packages/engine/Specs/Core/EarthOrientationParametersSpec.js @@ -3,6 +3,7 @@ import { EarthOrientationParameters, JulianDate, TimeStandard, + RuntimeError, } from "../../index.js"; describe("Core/EarthOrientationParameters", function () { @@ -165,7 +166,6 @@ describe("Core/EarthOrientationParameters", function () { it("interpolates data correctly under normal circumstances", function () { const eopDescription = { - url: undefined, data: { columnNames: [ "dateIso8601", @@ -253,7 +253,6 @@ describe("Core/EarthOrientationParameters", function () { it("interpolates UT1 correctly over a leap second", function () { const eopDescription = { - url: undefined, data: { columnNames: [ "dateIso8601", @@ -355,4 +354,42 @@ describe("Core/EarthOrientationParameters", function () { ).toEqual(true); }); }); + + it("fromUrl loads EOP data", async function () { + const eop = await EarthOrientationParameters.fromUrl( + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + expect(eop).toBeInstanceOf(EarthOrientationParameters); + + // 2011-07-03 00:00:00 UTC + const time = new JulianDate(2455745, 43200); + const result = eop.compute(time); + expect(result.xPoleWander).not.toEqual(0); + expect(result.yPoleWander).not.toEqual(0); + expect(result.xPoleOffset).not.toEqual(0); + expect(result.yPoleOffset).not.toEqual(0); + expect(result.ut1MinusUtc).not.toEqual(0); + }); + + it("fromUrl throws a RuntimeError when loading invalid EOP data", async function () { + await expectAsync( + EarthOrientationParameters.fromUrl( + "Data/EarthOrientationParameters/EOP-Invalid.json" + ) + ).toBeRejectedWithError( + RuntimeError, + "Error in loaded EOP data: The columnNames property is required." + ); + }); + + it("fromUrl throws a RuntimeError when using a missing EOP data file", async function () { + await expectAsync( + EarthOrientationParameters.fromUrl( + "Data/EarthOrientationParameters/EOP-DoesNotExist.json" + ) + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while retrieving the EOP data from the URL Data/EarthOrientationParameters/EOP-DoesNotExist.json." + ); + }); }); diff --git a/packages/engine/Specs/Core/TransformsSpec.js b/packages/engine/Specs/Core/TransformsSpec.js index 8dfcbf9a9b6..f1cd9b75b5b 100644 --- a/packages/engine/Specs/Core/TransformsSpec.js +++ b/packages/engine/Specs/Core/TransformsSpec.js @@ -2,6 +2,7 @@ import { Cartesian2, Cartesian3, Cartesian4, + defined, EarthOrientationParameters, Ellipsoid, GeographicProjection, @@ -1221,17 +1222,20 @@ describe("Core/Transforms", function () { }); describe("computeIcrfToFixedMatrix", function () { - function preloadTransformationData(start, stop, eopDescription) { - Transforms.earthOrientationParameters = new EarthOrientationParameters( - eopDescription - ); + async function preloadTransformationData(start, stop, eopUrl) { + if (defined(eopUrl)) { + Transforms.earthOrientationParameters = await EarthOrientationParameters.fromUrl( + eopUrl + ); + } + Transforms.iau2006XysData = new Iau2006XysData(); const preloadInterval = new TimeInterval({ start: start, stop: stop, }); - return Transforms.preloadIcrfFixed(preloadInterval); + await Transforms.preloadIcrfFixed(preloadInterval); } it("throws if the date parameter is not specified", function () { @@ -1244,80 +1248,26 @@ describe("Core/Transforms", function () { }).toThrowDeveloperError(); }); - it("works with data from STK Components", function () { + it("works with data from STK Components", async function () { // This data set represents a set of data encompassing the corresponding EOP data below. // The rotation data from Components span before and after the EOP data so as to test // what happens when we try evaluating at times when we don't have EOP as well as at // times where we do. The samples are not at exact EOP times, in order to test interpolation. - return Resource.fetchJson( + const componentsData = await Resource.fetchJson( "Data/EarthOrientationParameters/IcrfToFixedStkComponentsRotationData.json" - ).then(function (componentsData) { - const start = JulianDate.fromIso8601(componentsData[0].date); - const stop = JulianDate.fromIso8601( - componentsData[componentsData.length - 1].date - ); - - return preloadTransformationData(start, stop, { - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }).then(function () { - for (let i = 0; i < componentsData.length; ++i) { - const time = JulianDate.fromIso8601(componentsData[i].date); - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); - expect(t).toBe(resultT); - - // rotation matrix determinants are 1.0 - const det = - t[0] * t[4] * t[8] + - t[3] * t[7] * t[2] + - t[6] * t[1] * t[5] - - t[6] * t[4] * t[2] - - t[3] * t[1] * t[8] - - t[0] * t[7] * t[5]; - expect(det).toEqualEpsilon(1.0, CesiumMath.EPSILON14); - - // rotation matrix inverses are equal to its transpose - const t4 = Matrix4.fromRotationTranslation(t); - expect(Matrix4.inverse(t4, new Matrix4())).toEqualEpsilon( - Matrix4.inverseTransformation(t4, new Matrix4()), - CesiumMath.EPSILON14 - ); - - const expectedMtx = Matrix3.fromQuaternion( - Quaternion.conjugate( - componentsData[i].icrfToFixedQuaternion, - new Quaternion() - ) - ); - const testInverse = Matrix3.multiply( - Matrix3.transpose(t, new Matrix3()), - expectedMtx, - new Matrix3() - ); - const testDiff = new Matrix3(); - for (let k = 0; k < 9; k++) { - testDiff[k] = t[k] - expectedMtx[k]; - } - expect(testInverse).toEqualEpsilon( - Matrix3.IDENTITY, - CesiumMath.EPSILON14 - ); - expect(testDiff).toEqualEpsilon( - new Matrix3(), - CesiumMath.EPSILON14 - ); - } - }); - }); - }); - - it("works with hard-coded data", function () { - // 2011-07-03 00:00:00 UTC - let time = new JulianDate(2455745, 43200); + ); + const start = JulianDate.fromIso8601(componentsData[0].date); + const stop = JulianDate.fromIso8601( + componentsData[componentsData.length - 1].date + ); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }).then(function () { + await preloadTransformationData( + start, + stop, + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + for (let i = 0; i < componentsData.length; ++i) { + const time = JulianDate.fromIso8601(componentsData[i].date); const resultT = new Matrix3(); const t = Transforms.computeIcrfToFixedMatrix(time, resultT); expect(t).toBe(resultT); @@ -1339,127 +1289,177 @@ describe("Core/Transforms", function () { CesiumMath.EPSILON14 ); - time = JulianDate.addHours(time, 23.93447, new JulianDate()); // add one sidereal day - const resultU = new Matrix3(); - const u = Transforms.computeIcrfToFixedMatrix(time, resultU); - expect(u).toBe(resultU); - const tAngle = Quaternion.computeAngle( - Quaternion.fromRotationMatrix(t) - ); - const uAngle = Quaternion.computeAngle( - Quaternion.fromRotationMatrix(u) + const expectedMtx = Matrix3.fromQuaternion( + Quaternion.conjugate( + componentsData[i].icrfToFixedQuaternion, + new Quaternion() + ) ); - expect(tAngle).toEqualEpsilon(uAngle, CesiumMath.EPSILON6); - - // The rotation matrix from STK Components corresponding to the time and data inputs above - const expectedMtx = new Matrix3( - 0.18264414843630006, - -0.98317906144315947, - -0.00021950336420248503, - 0.98317840915224974, - 0.18264428011734501, - -0.0011325710874539787, - 0.0011536112127187594, - -0.0000089534866085598909, - 0.99999933455028112 - ); - const testInverse = Matrix3.multiply( Matrix3.transpose(t, new Matrix3()), expectedMtx, new Matrix3() ); const testDiff = new Matrix3(); - for (let i = 0; i < 9; i++) { - testDiff[i] = t[i] - expectedMtx[i]; + for (let k = 0; k < 9; k++) { + testDiff[k] = t[k] - expectedMtx[k]; } expect(testInverse).toEqualEpsilon( Matrix3.IDENTITY, CesiumMath.EPSILON14 ); expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); - }); + } }); - it("works over day boundary", function () { - const time = new JulianDate(2455745, 86395); + it("works with hard-coded data", async function () { + // 2011-07-03 00:00:00 UTC + let time = new JulianDate(2455745, 43200); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + await preloadTransformationData( + time, + time, + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + expect(t).toBe(resultT); + + // rotation matrix determinants are 1.0 + const det = + t[0] * t[4] * t[8] + + t[3] * t[7] * t[2] + + t[6] * t[1] * t[5] - + t[6] * t[4] * t[2] - + t[3] * t[1] * t[8] - + t[0] * t[7] * t[5]; + expect(det).toEqualEpsilon(1.0, CesiumMath.EPSILON14); + + // rotation matrix inverses are equal to its transpose + const t4 = Matrix4.fromRotationTranslation(t); + expect(Matrix4.inverse(t4, new Matrix4())).toEqualEpsilon( + Matrix4.inverseTransformation(t4, new Matrix4()), + CesiumMath.EPSILON14 + ); - // The rotation matrix from STK Components corresponding to the time and data inputs above - const expectedMtx = new Matrix3( - -0.19073578935932833, - 0.98164138366748721, - 0.00022919174269963536, - -0.98164073712836186, - -0.19073592679333939, - 0.0011266944449015753, - 0.0011497249933208494, - -0.000010082996932331842, - 0.99999933901516791 - ); + time = JulianDate.addHours(time, 23.93447, new JulianDate()); // add one sidereal day + const resultU = new Matrix3(); + const u = Transforms.computeIcrfToFixedMatrix(time, resultU); + expect(u).toBe(resultU); + const tAngle = Quaternion.computeAngle(Quaternion.fromRotationMatrix(t)); + const uAngle = Quaternion.computeAngle(Quaternion.fromRotationMatrix(u)); + expect(tAngle).toEqualEpsilon(uAngle, CesiumMath.EPSILON6); + + // The rotation matrix from STK Components corresponding to the time and data inputs above + const expectedMtx = new Matrix3( + 0.18264414843630006, + -0.98317906144315947, + -0.00021950336420248503, + 0.98317840915224974, + 0.18264428011734501, + -0.0011325710874539787, + 0.0011536112127187594, + -0.0000089534866085598909, + 0.99999933455028112 + ); - const testInverse = Matrix3.multiply( - Matrix3.transpose(t, new Matrix3()), - expectedMtx, - new Matrix3() - ); - const testDiff = new Matrix3(); - for (let i = 0; i < 9; i++) { - testDiff[i] = t[i] - expectedMtx[i]; - } - expect(testInverse).toEqualEpsilon( - Matrix3.IDENTITY, - CesiumMath.EPSILON14 - ); - expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); - }); + const testInverse = Matrix3.multiply( + Matrix3.transpose(t, new Matrix3()), + expectedMtx, + new Matrix3() + ); + const testDiff = new Matrix3(); + for (let i = 0; i < 9; i++) { + testDiff[i] = t[i] - expectedMtx[i]; + } + expect(testInverse).toEqualEpsilon( + Matrix3.IDENTITY, + CesiumMath.EPSILON14 + ); + expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); }); - it("works over day boundary backwards", function () { - const time = new JulianDate(2455745, 10); + it("works over day boundary", async function () { + const time = new JulianDate(2455745, 86395); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + await preloadTransformationData( + time, + time, + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + + // The rotation matrix from STK Components corresponding to the time and data inputs above + const expectedMtx = new Matrix3( + -0.19073578935932833, + 0.98164138366748721, + 0.00022919174269963536, + -0.98164073712836186, + -0.19073592679333939, + 0.0011266944449015753, + 0.0011497249933208494, + -0.000010082996932331842, + 0.99999933901516791 + ); - //The rotation matrix from STK Components corresponding to the time and data inputs above - const expectedMtx = new Matrix3( - -0.17489910479510423, - 0.984586338811966, - 0.00021110831245616662, - -0.98458569065286827, - -0.17489923190143036, - 0.0011297972845023996, - 0.0011493056536445096, - -0.00001025368996280683, - 0.99999933949547 - ); + const testInverse = Matrix3.multiply( + Matrix3.transpose(t, new Matrix3()), + expectedMtx, + new Matrix3() + ); + const testDiff = new Matrix3(); + for (let i = 0; i < 9; i++) { + testDiff[i] = t[i] - expectedMtx[i]; + } + expect(testInverse).toEqualEpsilon( + Matrix3.IDENTITY, + CesiumMath.EPSILON14 + ); + expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); + }); - const testInverse = Matrix3.multiply( - Matrix3.transpose(t, new Matrix3()), - expectedMtx, - new Matrix3() - ); - const testDiff = new Matrix3(); - for (let i = 0; i < 9; i++) { - testDiff[i] = t[i] - expectedMtx[i]; - } - expect(testInverse).toEqualEpsilon( - Matrix3.IDENTITY, - CesiumMath.EPSILON14 - ); - expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); - }); + it("works over day boundary backwards", async function () { + const time = new JulianDate(2455745, 10); + + await preloadTransformationData( + time, + time, + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + + //The rotation matrix from STK Components corresponding to the time and data inputs above + const expectedMtx = new Matrix3( + -0.17489910479510423, + 0.984586338811966, + 0.00021110831245616662, + -0.98458569065286827, + -0.17489923190143036, + 0.0011297972845023996, + 0.0011493056536445096, + -0.00001025368996280683, + 0.99999933949547 + ); + + const testInverse = Matrix3.multiply( + Matrix3.transpose(t, new Matrix3()), + expectedMtx, + new Matrix3() + ); + const testDiff = new Matrix3(); + for (let i = 0; i < 9; i++) { + testDiff[i] = t[i] - expectedMtx[i]; + } + expect(testInverse).toEqualEpsilon( + Matrix3.IDENTITY, + CesiumMath.EPSILON14 + ); + expect(testDiff).toEqualEpsilon(new Matrix3(), CesiumMath.EPSILON14); }); - it("works with position rotation", function () { + it("works with position rotation", async function () { // GEO Satellite position const inertialPos = new Cartesian3( -7322101.15395708, @@ -1476,63 +1476,59 @@ describe("Core/Transforms", function () { // 2011-07-03 00:00:00 UTC const time = new JulianDate(2455745, 43200); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + await preloadTransformationData( + time, + time, + "Data/EarthOrientationParameters/EOP-2011-July.json" + ); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); - const result = Matrix3.multiplyByVector( - t, - inertialPos, - new Cartesian3() - ); - const error = Cartesian3.subtract( - result, - expectedFixedPos, - new Cartesian3() - ); + const result = Matrix3.multiplyByVector(t, inertialPos, new Cartesian3()); + const error = Cartesian3.subtract( + result, + expectedFixedPos, + new Cartesian3() + ); - // Given the magnitude of the positions involved (1e8) - // this tolerance represents machine precision - expect(error).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON7); - }); + // Given the magnitude of the positions involved (1e8) + // this tolerance represents machine precision + expect(error).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON7); }); - it("undefined prior to 1974", function () { + it("undefined prior to 1974", async function () { // 1970 jan 1 0h UTC const time = new JulianDate(2440587, 43200); // Purposefully do not load EOP! EOP doesn't make a lot of sense before 1972. // Even though we are trying to load the data for 1970, // we don't have the data in Cesium to load. - return preloadTransformationData( + await preloadTransformationData( time, JulianDate.addDays(time, 1, new JulianDate()) - ).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); - // Check that we get undefined, since we don't have ICRF data - expect(t).toEqual(undefined); - }); + ); + + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + // Check that we get undefined, since we don't have ICRF data + expect(t).toEqual(undefined); }); - it("works after 2028", function () { + it("works after 2028", async function () { // 2030 jan 1 0h UTC const time = new JulianDate(2462502, 43200); // Purposefully do not load EOP! EOP doesn't exist yet that far into the future // Even though we are trying to load the data for 2030, // we don't have the data in Cesium to load. - return preloadTransformationData( + await preloadTransformationData( time, JulianDate.addDays(time, 1, new JulianDate()) - ).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); - expect(t).toBeDefined(); - }); + ); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + expect(t).toBeDefined(); }); - it("works without EOP data loaded", function () { + it("works without EOP data loaded", async function () { // GEO Satellite position const inertialPos = new Cartesian3( -7322101.15395708, @@ -1549,51 +1545,40 @@ describe("Core/Transforms", function () { // 2011-07-03 00:00:00 UTC const time = new JulianDate(2455745, 43200); - return preloadTransformationData(time, time, undefined).then(function () { - const resultT = new Matrix3(); - const t = Transforms.computeIcrfToFixedMatrix(time, resultT); - - const result = Matrix3.multiplyByVector( - t, - inertialPos, - new Cartesian3() - ); - const error = Cartesian3.subtract( - result, - expectedFixedPos, - new Cartesian3() - ); - - // Given the magnitude of the positions involved (1e8) - // this tolerance represents machine precision - expect(error).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON7); - }); - }); - - it("throws a RuntimeError when asked to compute with invalid EOP data", function () { - // 2011-07-03 00:00:00 UTC - const time = new JulianDate(2455745, 43200); + Transforms.earthOrientationParameters = new EarthOrientationParameters(); + await preloadTransformationData(time, time); + const resultT = new Matrix3(); + const t = Transforms.computeIcrfToFixedMatrix(time, resultT); + + const result = Matrix3.multiplyByVector(t, inertialPos, new Cartesian3()); + const error = Cartesian3.subtract( + result, + expectedFixedPos, + new Cartesian3() + ); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-Invalid.json", - }).then(function () { - expect(function () { - return Transforms.computeIcrfToFixedMatrix(time); - }).toThrowError(RuntimeError); - }); + // Given the magnitude of the positions involved (1e8) + // this tolerance represents machine precision + expect(error).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON7); }); - it("throws a RuntimeError when asked to compute with a missing EOP data file", function () { + it("throws a RuntimeError when asked to compute with invalid EOP data", async function () { // 2011-07-03 00:00:00 UTC const time = new JulianDate(2455745, 43200); - return preloadTransformationData(time, time, { - url: "Data/EarthOrientationParameters/EOP-DoesNotExist.json", - }).then(function () { - expect(function () { + await expectAsync( + (async function () { + await preloadTransformationData( + time, + time, + "Data/EarthOrientationParameters/EOP-Invalid.json" + ); return Transforms.computeIcrfToFixedMatrix(time); - }).toThrowError(RuntimeError); - }); + })() + ).toBeRejectedWithError( + RuntimeError, + "Error in loaded EOP data: The columnNames property is required." + ); }); it("returns undefined before XYS data is loaded.", function () { @@ -1603,17 +1588,6 @@ describe("Core/Transforms", function () { const time = new JulianDate(2455745, 43200); expect(Transforms.computeIcrfToFixedMatrix(time)).toBeUndefined(); }); - - it("returns undefined before EOP data is loaded.", function () { - const time = new JulianDate(2455745, 43200); - return preloadTransformationData(time, time).then(function () { - expect(Transforms.computeIcrfToFixedMatrix(time)).toBeDefined(); - Transforms.earthOrientationParameters = new EarthOrientationParameters({ - url: "Data/EarthOrientationParameters/EOP-2011-July.json", - }); - expect(Transforms.computeIcrfToFixedMatrix(time)).toBeUndefined(); - }); - }); }); const width = 1024.0; From fcda6786c51aa86efad10677c4985b355b5e5de9 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Tue, 20 Dec 2022 21:03:27 +0100 Subject: [PATCH 277/679] Compare against localized string in tileset specs The labels contain a string that is created with toLocaleString. --- packages/engine/Specs/Scene/Cesium3DTilesetSpec.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 7d7f892096c..fa28b2e70ae 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -2289,7 +2289,9 @@ describe( expect(tileset._tileDebugLabels).toBeDefined(); expect(tileset._tileDebugLabels.length).toEqual(1); - const expected = "Texture Memory: 0\n" + "Geometry Memory: 0.007"; + const expected = + "Texture Memory: 0\n" + + `Geometry Memory: ${(0.007).toLocaleString()}`; expect(tileset._tileDebugLabels._labels[0].text).toEqual(expected); @@ -2318,7 +2320,7 @@ describe( "Triangles: 120\n" + "Features: 10\n" + "Texture Memory: 0\n" + - "Geometry Memory: 0.007\n" + + `Geometry Memory: ${(0.007).toLocaleString()}\n` + "Url: parent.b3dm"; expect(tileset._tileDebugLabels._labels[0].text).toEqual(expected); @@ -2355,7 +2357,7 @@ describe( "Triangles: 120\n" + "Features: 10\n" + "Texture Memory: 0\n" + - "Geometry Memory: 0.007\n" + + `Geometry Memory: ${(0.007).toLocaleString()}\n` + "Url: parent.b3dm"; expect(tileset._tileDebugLabels.get(0).text).toEqual(expected); expect(tileset._tileDebugLabels.get(0).position).toEqual( From 87a9b2010166c5886d69e7475b183bd1002f9eed Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 23 Dec 2022 10:54:44 -0500 Subject: [PATCH 278/679] Remove GltfVoxelProvider --- Apps/Sandcastle/gallery/Voxels.html | 30 -- packages/engine/Source/Core/PrimitiveType.js | 29 +- packages/engine/Source/Scene/GltfLoader.js | 15 - .../engine/Source/Scene/GltfVoxelProvider.js | 365 ------------------ .../engine/Source/Scene/Model/ModelUtility.js | 1 - .../engine/Source/Scene/ModelComponents.js | 48 --- packages/engine/Source/Scene/VoxelProvider.js | 1 - .../engine/Source/Scene/VoxelShapeType.js | 32 +- .../Specs/Scene/GltfVoxelProviderSpec.js | 145 ------- .../engine/Specs/Scene/VoxelShapeTypeSpec.js | 13 - packages/widgets/Specs/Viewer/ViewerSpec.js | 7 +- 11 files changed, 7 insertions(+), 679 deletions(-) delete mode 100644 packages/engine/Source/Scene/GltfVoxelProvider.js delete mode 100644 packages/engine/Specs/Scene/GltfVoxelProviderSpec.js diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index dc2501d937d..03b858e6d9e 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -415,16 +415,6 @@ const primitive = createPrimitive(provider, customShaderColor); }, }, - { - text: "Box - glTF", - onselect: function () { - const provider = new Cesium.GltfVoxelProvider({ - gltf: - "../../SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf", - }); - const primitive = createPrimitive(provider, customShaderAlpha); - }, - }, { text: "Box - 3D Tiles", onselect: function () { @@ -444,16 +434,6 @@ const primitive = createPrimitive(provider, customShaderColor); }, }, - { - text: "Ellipsoid - glTF", - onselect: function () { - const provider = new Cesium.GltfVoxelProvider({ - gltf: - "../../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf", - }); - const primitive = createPrimitive(provider, customShaderAlpha); - }, - }, { text: "Ellipsoid - 3D Tiles", onselect: function () { @@ -473,16 +453,6 @@ const primitive = createPrimitive(provider, customShaderColor); }, }, - { - text: "Cylinder - glTF", - onselect: function () { - const provider = new Cesium.GltfVoxelProvider({ - gltf: - "../../SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf", - }); - const primitive = createPrimitive(provider, customShaderAlpha); - }, - }, { text: "Cylinder - 3D Tiles", onselect: function () { diff --git a/packages/engine/Source/Core/PrimitiveType.js b/packages/engine/Source/Core/PrimitiveType.js index 856d60f194e..19a0887d9f2 100644 --- a/packages/engine/Source/Core/PrimitiveType.js +++ b/packages/engine/Source/Core/PrimitiveType.js @@ -65,30 +65,6 @@ const PrimitiveType = { * @constant */ TRIANGLE_FAN: WebGLConstants.TRIANGLE_FAN, - - /** - * Box voxel primitive from EXT_primitive_voxels. - * - * @type {Number} - * @constant - */ - VOXEL_BOX: 0x80000000, - - /** - * Ellipsoid voxel primitive from EXT_primitive_voxels. - * - * @type {Number} - * @constant - */ - VOXEL_ELLIPSOID: 0x80000001, - - /** - * Cylinder voxel primitive from EXT_primitive_voxels. - * - * @type {Number} - * @constant - */ - VOXEL_CYLINDER: 0x80000002, }; /** @@ -124,10 +100,7 @@ PrimitiveType.validate = function (primitiveType) { primitiveType === PrimitiveType.LINE_STRIP || primitiveType === PrimitiveType.TRIANGLES || primitiveType === PrimitiveType.TRIANGLE_STRIP || - primitiveType === PrimitiveType.TRIANGLE_FAN || - primitiveType === PrimitiveType.VOXEL_BOX || - primitiveType === PrimitiveType.VOXEL_CYLINDER || - primitiveType === PrimitiveType.VOXEL_ELLIPSOID + primitiveType === PrimitiveType.TRIANGLE_FAN ); }; diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index e66c52c4852..20655d764f4 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -1701,21 +1701,6 @@ function loadPrimitive( const loadForClassification = loader._loadForClassification; const draco = extensions.KHR_draco_mesh_compression; - const extVox = extensions.EXT_primitive_voxels; - if (defined(extVox)) { - const voxel = new ModelComponents.Voxel(); - voxel.dimensions = fromArray(Cartesian3, extVox.dimensions); - if (defined(extVox.bounds)) { - voxel.minBounds = fromArray(Cartesian3, extVox.bounds.min); - voxel.maxBounds = fromArray(Cartesian3, extVox.bounds.max); - } - if (defined(extVox.padding)) { - voxel.paddingBefore = fromArray(Cartesian3, extVox.padding.before); - voxel.paddingAfter = fromArray(Cartesian3, extVox.padding.after); - } - primitive.voxel = voxel; - } - let hasFeatureIds = false; const attributes = gltfPrimitive.attributes; if (defined(attributes)) { diff --git a/packages/engine/Source/Scene/GltfVoxelProvider.js b/packages/engine/Source/Scene/GltfVoxelProvider.js deleted file mode 100644 index a7b9b055dde..00000000000 --- a/packages/engine/Source/Scene/GltfVoxelProvider.js +++ /dev/null @@ -1,365 +0,0 @@ -import Cartesian3 from "../Core/Cartesian3.js"; -import Check from "../Core/Check.js"; -import ComponentDatatype from "../Core/ComponentDatatype.js"; -import DeveloperError from "../Core/DeveloperError.js"; -import defaultValue from "../Core/defaultValue.js"; -import defer from "../Core/defer.js"; -import defined from "../Core/defined.js"; -import Resource from "../Core/Resource.js"; -import GltfLoader from "./GltfLoader.js"; -import MetadataComponentType from "./MetadataComponentType.js"; -import MetadataType from "./MetadataType.js"; -import ModelUtility from "./Model/ModelUtility.js"; -import VoxelShapeType from "./VoxelShapeType.js"; - -/** - * A {@link VoxelProvider} that fetches voxel data from a glTF. - * - * @alias GltfVoxelProvider - * @constructor - * - * @param {Object} options Object with the following properties: - * @param {String|Resource|Uint8Array|Object} options.gltf A Resource/URL to a glTF/glb file, a binary glTF buffer, or a JSON object containing the glTF contents - * options.gltf could also have type GltfLoader, but that is a private type - * - * @see Cesium3DTilesVoxelProvider - * @see VoxelProvider - * @see VoxelPrimitive - * @see VoxelShapeType - * - * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. - */ -function GltfVoxelProvider(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - //>>includeStart('debug', pragmas.debug); - Check.defined("options.gltf", options.gltf); - //>>includeEnd('debug'); - - /** - * Gets a value indicating whether or not the provider is ready for use. - * - * @type {Boolean} - * @readonly - */ - this.ready = false; - - /** - * @type {Promise.} - * @private - */ - this._readyPromise = defer(); - - /** - * Gets the promise that will be resolved when the provider is ready for use. - * - * @type {Promise.} - * @readonly - */ - this.readyPromise = this._readyPromise.promise; - - /** - * An optional model matrix that is applied to all tiles - * - * @type {Matrix4|undefined} - * @readonly - */ - this.modelMatrix = undefined; - - /** - * Gets the {@link VoxelShapeType} - * - * @type {VoxelShapeType} - * @readonly - */ - this.shape = undefined; - - /** - * Gets the minimum bounds. - * If undefined, the shape's default minimum bounds will be used instead. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ - this.minBounds = undefined; - - /** - * Gets the maximum bounds. - * If undefined, the shape's default maximum bounds will be used instead. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ - this.maxBounds = undefined; - - /** - * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3} - * @readonly - */ - this.dimensions = undefined; - - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * TODO: mark this optional - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ - this.paddingBefore = undefined; - - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * This should not be called before {@link VoxelProvider#ready} returns true. - * TODO: mark this optional - * - * @type {Cartesian3|undefined} - * @readonly - */ - this.paddingAfter = undefined; - - // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use - - /** - * Gets the metadata names. - * - * @type {String[]} - * @readonly - */ - this.names = new Array(); - - /** - * Gets the metadata types - * - * @type {MetadataType[]} - * @readonly - * @private - */ - this.types = new Array(); - - /** - * Gets the metadata component types - * - * @type {MetadataComponentType[]} - * @readonly - * @private - */ - this.componentTypes = new Array(); - - /** - * Gets the minimum value - * - * @type {Number[][]|undefined} - * @readonly - */ - this.minimumValues = undefined; - - /** - * Gets the maximum value - * - * @type {Number[][]|undefined} - * @readonly - */ - this.maximumValues = undefined; - - /** - * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. - * - * @type {Number|undefined} - * @readonly - */ - this.maximumTileCount = 1; - - /** - * A {@link GltfLoader} that is processed each frame until ready. - * - * @type {GltfLoader} - * @private - */ - this._loader = undefined; - - /** - * The voxel data. - * - * @type {Array[]} - * @private - */ - this._data = undefined; - - const gltf = options.gltf; - let promise; - if (defined(gltf.components) && defined(gltf.components.asset)) { - promise = gltf.promise; - } else { - const gltfResource = Resource.createIfNeeded(gltf); - const loader = new GltfLoader({ - gltfResource: gltfResource, - releaseGltfJson: true, - loadAttributesAsTypedArray: true, - }); - loader.load(); - promise = loader.promise; - this._loader = loader; - } - - const that = this; - promise - .then(function (loader) { - const gltf = loader.components; - const node = gltf.nodes[0]; - const modelMatrix = ModelUtility.getNodeTransform(node); - const gltfPrimitive = node.primitives[0]; - const voxel = gltfPrimitive.voxel; - const primitiveType = gltfPrimitive.primitiveType; - const shape = VoxelShapeType.fromPrimitiveType(primitiveType); - const attributes = gltfPrimitive.attributes; - const attributesLength = attributes.length; - const names = new Array(attributesLength); - const types = new Array(attributesLength); - const componentTypes = new Array(attributesLength); - const minimumValues = undefined; //new Array(length); - const maximumValues = undefined; //new Array(length); - - for (let i = 0; i < attributesLength; i++) { - const attribute = attributes[i]; - const name = attribute.name; - const type = attribute.type; - const componentDatatype = attribute.componentDatatype; - let nameFixed = name.toLowerCase(); - if (nameFixed.charAt(0) === "_") { - nameFixed = nameFixed.slice(1); - } - - names[i] = nameFixed; - types[i] = type; - componentTypes[i] = MetadataComponentType.fromComponentDatatype( - componentDatatype - ); - } - - that.ready = true; - that._readyPromise = Promise.resolve(that); - - that.modelMatrix = modelMatrix; - that.shape = shape; - that.minBounds = defined(voxel.minBounds) - ? Cartesian3.clone(voxel.minBounds, new Cartesian3()) - : undefined; - that.maxBounds = defined(voxel.maxBounds) - ? Cartesian3.clone(voxel.maxBounds, new Cartesian3()) - : undefined; - that.dimensions = Cartesian3.clone(voxel.dimensions, new Cartesian3()); - that.paddingBefore = defined(voxel.paddingBefore) - ? Cartesian3.clone(voxel.paddingBefore, new Cartesian3()) - : undefined; - that.paddingAfter = defined(voxel.paddingAfter) - ? Cartesian3.clone(voxel.paddingAfter, new Cartesian3()) - : undefined; - - // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use - - that.names = names; - that.types = types; - that.componentTypes = componentTypes; - that.minimumValues = minimumValues; - that.maximumValues = maximumValues; - - that._data = new Array(attributesLength); - for (let i = 0; i < attributesLength; i++) { - const attribute = attributes[i]; - const typedArray = attribute.typedArray; - const type = attribute.type; - const componentDatatype = attribute.componentDatatype; - const componentCount = MetadataType.getComponentCount(type); - const totalCount = attribute.count * componentCount; - - that._data[i] = ComponentDatatype.createArrayBufferView( - componentDatatype, - typedArray.buffer, - typedArray.byteOffset + attribute.byteOffset, - totalCount - ); - } - - // Now that the data is loaded the loader can be unloaded. - that._loader.unload(); - that._loader = undefined; - }) - .catch(function (error) { - that.readyPromise = Promise.reject(error); - }); -} - -/** - * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. - * @function - * - * @param {FrameState} frameState - * @private - */ -GltfVoxelProvider.prototype.update = function (frameState) { - const loader = this._loader; - if (defined(loader)) { - loader.process(frameState); - } -}; - -/** - * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. - * Note that there is only one "tile" for a glTF so the only valid input is the "root" tile coordinates. - * This function should not be called before {@link GltfVoxelProvider#ready} returns true. - * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.tileLevel=0] The tile's level. - * @param {Number} [options.tileX=0] The tile's X coordinate. - * @param {Number} [options.tileY=0] The tile's Y coordinate. - * @param {Number} [options.tileZ=0] The tile's Z coordinate. - * @param {Number} [options.keyframe=0] The requested keyframe. - * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. - * - * @exception {DeveloperError} The provider must be ready. - * @exception {DeveloperError} Only level 0 can be requested. - */ -GltfVoxelProvider.prototype.requestData = function (options) { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "requestData must not be called before the provider is ready." - ); - } - //>>includeEnd('debug'); - - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - // glTF current doesn't support level of detail. - const tileLevel = defaultValue(options.tileLevel, 0); - if (tileLevel > 0) { - return undefined; - } - // glTF currently doesn't support time-dynamic. - const keyframe = defaultValue(options.keyframe, 0); - if (keyframe > 0) { - return undefined; - } - - return Promise.resolve(this._data); -}; - -/** - * Check if the data is still being loaded. - * This is intended to be used for unit tests only. - * - * @returns {Boolean} - * - * @private - */ -GltfVoxelProvider.prototype.doneLoading = function () { - return defined(this._data); -}; - -export default GltfVoxelProvider; diff --git a/packages/engine/Source/Scene/Model/ModelUtility.js b/packages/engine/Source/Scene/Model/ModelUtility.js index 105d60c3e70..b99f9e8076b 100644 --- a/packages/engine/Source/Scene/Model/ModelUtility.js +++ b/packages/engine/Source/Scene/Model/ModelUtility.js @@ -363,7 +363,6 @@ ModelUtility.supportedExtensions = { KHR_mesh_quantization: true, KHR_texture_basisu: true, KHR_texture_transform: true, - EXT_primitive_voxels: true, WEB3D_quantized_attributes: true, }; diff --git a/packages/engine/Source/Scene/ModelComponents.js b/packages/engine/Source/Scene/ModelComponents.js index 5e93c9c7dd7..06b3ac503c8 100644 --- a/packages/engine/Source/Scene/ModelComponents.js +++ b/packages/engine/Source/Scene/ModelComponents.js @@ -536,46 +536,6 @@ function MorphTarget() { this.attributes = []; } -/** - * Properties from EXT_primitive_voxels - * - * @alias ModelComponents.Voxel - * @constructor - * - * @private - */ -function Voxel() { - /** - * @type {Cartesian3} - * @private - */ - this.minBounds = undefined; - - /** - * @type {Cartesian3} - * @private - */ - this.maxBounds = undefined; - - /** - * @type {Cartesian3} - * @private - */ - this.dimensions = undefined; - - /** - * @type {Cartesian3} - * @private - */ - this.paddingBefore = undefined; - - /** - * @type {Cartesian3} - * @private - */ - this.paddingAfter = undefined; -} - /** * Geometry to be rendered with a material. * @@ -660,13 +620,6 @@ function Primitive() { * @private */ this.outlineCoordinates = undefined; - - /** - * Properties from EXT_primitive_voxels. - * @type {ModelComponents.Voxel} - * @private - */ - this.voxel = undefined; } /** @@ -1485,7 +1438,6 @@ function Material() { Material.DEFAULT_EMISSIVE_FACTOR = Cartesian3.ZERO; ModelComponents.Quantization = Quantization; -ModelComponents.Voxel = Voxel; ModelComponents.Attribute = Attribute; ModelComponents.Indices = Indices; ModelComponents.FeatureIdAttribute = FeatureIdAttribute; diff --git a/packages/engine/Source/Scene/VoxelProvider.js b/packages/engine/Source/Scene/VoxelProvider.js index 5b61cdd3b31..7a340d0d0cf 100644 --- a/packages/engine/Source/Scene/VoxelProvider.js +++ b/packages/engine/Source/Scene/VoxelProvider.js @@ -8,7 +8,6 @@ import DeveloperError from "../Core/DeveloperError.js"; * @constructor * * @see Cesium3DTilesVoxelProvider - * @see GltfVoxelProvider * @see VoxelPrimitive * @see VoxelShapeType * diff --git a/packages/engine/Source/Scene/VoxelShapeType.js b/packages/engine/Source/Scene/VoxelShapeType.js index 4e11072bd04..5929a722fcc 100644 --- a/packages/engine/Source/Scene/VoxelShapeType.js +++ b/packages/engine/Source/Scene/VoxelShapeType.js @@ -1,12 +1,10 @@ import DeveloperError from "../Core/DeveloperError.js"; -import PrimitiveType from "../Core/PrimitiveType.js"; import VoxelBoxShape from "./VoxelBoxShape.js"; import VoxelCylinderShape from "./VoxelCylinderShape.js"; import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; /** - * An enum of voxel shapes supported by EXT_primitive_voxels. The shape controls - * how the voxel grid is mapped to 3D space. + * An enum of voxel shapes. The shape controls how the voxel grid is mapped to 3D space. * * @enum VoxelShapeType * @@ -40,7 +38,7 @@ const VoxelShapeType = { }; /** - * Gets the minimum bounds as defined by EXT_primitive_voxels. + * Gets the minimum bounds. * @param {VoxelShapeType} shapeType The voxel shape type. * @returns {Cartesian3} The minimum bounds. */ @@ -60,7 +58,7 @@ VoxelShapeType.getMinBounds = function (shapeType) { }; /** - * Gets the maximum bounds as defined by EXT_primitive_voxels. + * Gets the maximum bounds. * @param {VoxelShapeType} shapeType The voxel shape type. * @returns {Cartesian3} The maximum bounds. */ @@ -79,30 +77,6 @@ VoxelShapeType.getMaxBounds = function (shapeType) { } }; -/** - * Converts a primitive type to a voxel shape. glTF voxel primitive types are - * defined by EXT_primitive_voxels. - * - * @param {PrimitiveType} primitiveType The primitive type. - * @returns {VoxelShapeType} The shape type. - * - * @private - */ -VoxelShapeType.fromPrimitiveType = function (primitiveType) { - switch (primitiveType) { - case PrimitiveType.VOXEL_BOX: - return VoxelShapeType.BOX; - case PrimitiveType.VOXEL_ELLIPSOID: - return VoxelShapeType.ELLIPSOID; - case PrimitiveType.VOXEL_CYLINDER: - return VoxelShapeType.CYLINDER; - //>>includeStart('debug', pragmas.debug); - default: - throw new DeveloperError(`Invalid primitive type ${primitiveType}`); - //>>includeEnd('debug'); - } -}; - /** * Converts a shape type to a constructor that can be used to create a shape * object or get per-shape properties like DefaultMinBounds and diff --git a/packages/engine/Specs/Scene/GltfVoxelProviderSpec.js b/packages/engine/Specs/Scene/GltfVoxelProviderSpec.js deleted file mode 100644 index fe8ee8f45e1..00000000000 --- a/packages/engine/Specs/Scene/GltfVoxelProviderSpec.js +++ /dev/null @@ -1,145 +0,0 @@ -import { - Cartesian3, - GltfVoxelProvider, - Matrix4, - MetadataComponentType, - MetadataType, - ResourceCache, - VoxelProvider, - VoxelShapeType, -} from "../../index.js"; -import createScene from "../../../../Specs/createScene.js"; -import pollToPromise from "../../../../Specs/pollToPromise.js"; - -describe( - "Scene/GltfVoxelProvider", - function () { - let scene; - - beforeAll(function () { - scene = createScene(); - }); - - afterAll(function () { - scene.destroyForSpecs(); - }); - - afterEach(function () { - scene.primitives.removeAll(); - ResourceCache.clearForSpecs(); - }); - - it("throws if constructed directly", function () { - expect(() => { - // eslint-disable-next-line no-unused-vars - const provider = new VoxelProvider(); - }).toThrowDeveloperError(); - }); - - it("conforms to VoxelProvider interface", function () { - expect(GltfVoxelProvider).toConformToInterface(VoxelProvider); - }); - - it("constructor works", function () { - const url = - "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; - const provider = new GltfVoxelProvider({ - gltf: url, - }); - - return pollToPromise(function () { - provider.update(scene.frameState); - return provider.ready; - }).then(function () { - expect(provider).toBeDefined(); - expect(provider.ready).toBeTrue(); - expect(provider.modelMatrix).toEqual(Matrix4.IDENTITY); - expect(provider.shape).toEqual(VoxelShapeType.ELLIPSOID); - expect(provider.minBounds).toEqual(new Cartesian3(0.0, 0.0, -1.0)); - expect(provider.maxBounds).toEqual(new Cartesian3(1.0, 1.0, 0.0)); - expect(provider.dimensions).toEqual(new Cartesian3(2, 2, 2)); - expect(provider.paddingBefore).toBeUndefined(); - expect(provider.paddingAfter).toBeUndefined(); - expect(provider.names).toEqual(["a"]); - expect(provider.types).toEqual([MetadataType.SCALAR]); - expect(provider.componentTypes).toEqual([ - MetadataComponentType.FLOAT32, - ]); - expect(provider.minimumValues).toBeUndefined(); - expect(provider.maximumValues).toBeUndefined(); - expect(provider.maximumTileCount).toEqual(1); - }); - }); - - it("constructor throws when gltf option is missing", function () { - expect(function () { - return new GltfVoxelProvider({ - gltf: undefined, - }); - }).toThrowDeveloperError(); - }); - - it("requestData works", function () { - const url = - "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; - const provider = new GltfVoxelProvider({ - gltf: url, - }); - - return pollToPromise(function () { - provider.update(scene.frameState); - return provider.ready; - }).then(function () { - const requestTilePromise = provider.requestData(); - - // need to call update until the promise is ready - return pollToPromise(function () { - provider.update(scene.frameState); - return provider.doneLoading(); - }) - .then(function () { - return requestTilePromise; - }) - .then(function (data) { - expect(data.length).toEqual(1); - - const dimensions = provider.dimensions; - const voxelCount = dimensions.x * dimensions.y * dimensions.z; - const componentCount = MetadataType.getComponentCount( - provider.types[0] - ); - const expectedLength = voxelCount * componentCount; - expect(data[0].length).toEqual(expectedLength); - }); - }); - }); - - it("requestData throws for non-root tiles", function () { - const url = - "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf"; - const provider = new GltfVoxelProvider({ - gltf: url, - }); - expect(function () { - return provider.requestData({ - x: 0, - y: 0, - z: 0, - level: 1, - }); - }).toThrowDeveloperError(); - }); - - it("requestData throws if the provider is not ready", function () { - const url = - "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; - const provider = new GltfVoxelProvider({ - gltf: url, - }); - expect(function () { - return provider.requestData(); - }).toThrowDeveloperError(); - }); - }, - "WebGL" -); diff --git a/packages/engine/Specs/Scene/VoxelShapeTypeSpec.js b/packages/engine/Specs/Scene/VoxelShapeTypeSpec.js index e1c5c3a3e72..19c8268e788 100644 --- a/packages/engine/Specs/Scene/VoxelShapeTypeSpec.js +++ b/packages/engine/Specs/Scene/VoxelShapeTypeSpec.js @@ -1,5 +1,4 @@ import { - PrimitiveType, VoxelBoxShape, VoxelCylinderShape, VoxelEllipsoidShape, @@ -43,18 +42,6 @@ describe("Scene/VoxelShapeType", function () { }).toThrowDeveloperError(); }); - it("fromPrimitiveType works", function () { - expect(VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_BOX)).toBe( - VoxelShapeType.BOX - ); - expect( - VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_ELLIPSOID) - ).toBe(VoxelShapeType.ELLIPSOID); - expect(VoxelShapeType.fromPrimitiveType(PrimitiveType.VOXEL_CYLINDER)).toBe( - VoxelShapeType.CYLINDER - ); - }); - it("fromPrimitiveType throws for invalid type", function () { expect(function () { return VoxelShapeType.fromPrimitiveType("NOT_A_PRIMITIVE_TYPE"); diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index 55cdf81d4dd..9a2a3701b46 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -24,7 +24,7 @@ import { CameraFlightPath, Cesium3DTileset, ImageryLayerCollection, - GltfVoxelProvider, + Cesium3DTilesVoxelProvider, SceneMode, ShadowMode, TimeDynamicPointCloud, @@ -1403,9 +1403,8 @@ describe( function loadVoxelPrimitive(viewer) { const voxelPrimitive = new VoxelPrimitive({ - provider: new GltfVoxelProvider({ - gltf: - "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf", + provider: new Cesium3DTilesVoxelProvider({ + url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", }), }); viewer.scene.primitives.add(voxelPrimitive); From 5b188314425fbb4a83a9ef45dd327656f41c9c9d Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 23 Dec 2022 10:58:16 -0500 Subject: [PATCH 279/679] Add support for 3DTILES_content_voxels and 3DTILES_bounding_volume_cylinder --- .../Source/Scene/Cesium3DTileContentType.js | 19 + .../Scene/Cesium3DTilesVoxelProvider.js | 721 ++++++++---------- .../engine/Source/Scene/ImplicitTileset.js | 5 +- packages/engine/Source/Scene/VoxelContent.js | 169 ++++ packages/engine/Source/Scene/VoxelProvider.js | 22 +- .../Source/Scene/preprocess3DTileContent.js | 8 + 6 files changed, 507 insertions(+), 437 deletions(-) create mode 100644 packages/engine/Source/Scene/VoxelContent.js diff --git a/packages/engine/Source/Scene/Cesium3DTileContentType.js b/packages/engine/Source/Scene/Cesium3DTileContentType.js index 06cd86cf83f..39caeef8579 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContentType.js +++ b/packages/engine/Source/Scene/Cesium3DTileContentType.js @@ -132,6 +132,24 @@ const Cesium3DTileContentType = { * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ GEOJSON: "geoJson", + /** + * Binary voxel content for 3DTILES_content_voxels extension. + * + * @type {String} + * @constant + * @private + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + */ + VOXEL_BINARY: "voxl", + /** + * Binary voxel content for 3DTILES_content_voxels extension. + * + * @type {String} + * @constant + * @private + * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. + */ + VOXEL_JSON: "voxelJson", }; /** @@ -150,6 +168,7 @@ Cesium3DTileContentType.isBinaryFormat = function (contentType) { case Cesium3DTileContentType.VECTOR: case Cesium3DTileContentType.GEOMETRY: case Cesium3DTileContentType.IMPLICIT_SUBTREE: + case Cesium3DTileContentType.VOXEL_BINARY: case Cesium3DTileContentType.GLTF_BINARY: return true; default: diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 5e02dbc9b2e..f8a13784af1 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -1,33 +1,40 @@ import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; -import ComponentDatatype from "../Core/ComponentDatatype.js"; import defaultValue from "../Core/defaultValue.js"; -import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; +import Ellipsoid from "../Core/Ellipsoid.js"; import Matrix4 from "../Core/Matrix4.js"; +import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; import Resource from "../Core/Resource.js"; +import RuntimeError from "../Core/RuntimeError.js"; import Cesium3DTilesetMetadata from "./Cesium3DTilesetMetadata.js"; -import GltfLoader from "./GltfLoader.js"; +import hasExtension from "./hasExtension.js"; import ImplicitSubtree from "./ImplicitSubtree.js"; import ImplicitSubtreeCache from "./ImplicitSubtreeCache.js"; import ImplicitTileCoordinates from "./ImplicitTileCoordinates.js"; import ImplicitTileset from "./ImplicitTileset.js"; -import MetadataComponentType from "./MetadataComponentType.js"; import MetadataType from "./MetadataType.js"; +import preprocess3DTileContent from "./preprocess3DTileContent.js"; import ResourceCache from "./ResourceCache.js"; +import VoxelBoxShape from "./VoxelBoxShape.js"; +import VoxelContent from "./VoxelContent.js"; +import VoxelCylinderShape from "./VoxelCylinderShape.js"; import VoxelShapeType from "./VoxelShapeType.js"; /** * A {@link VoxelProvider} that fetches voxel data from a 3D Tiles tileset. + *

+ * Implements the {@link VoxelProvider} interface. + *

* * @alias Cesium3DTilesVoxelProvider * @constructor + * @augments VoxelProvider * * @param {Object} options Object with the following properties: - * @param {String|Resource|Uint8Array} options.url The URL to the tileset directory + * @param {Resource|String|Promise|Promise} options.url The URL to a tileset JSON file. * - * @see GltfVoxelProvider * @see VoxelProvider * @see VoxelPrimitive * @see VoxelShapeType @@ -40,257 +47,244 @@ function Cesium3DTilesVoxelProvider(options) { Check.defined("options.url", options.url); //>>includeEnd('debug'); - /** - * Gets a value indicating whether or not the provider is ready for use. - * - * @type {Boolean} - * @readonly - */ + /** @inheritdoc */ this.ready = false; - /** - * @type {Promise.} - * @private - */ - this._readyPromise = defer(); - - /** - * Gets the promise that will be resolved when the provider is ready for use. - * - * @type {Promise.} - * @readonly - */ - this.readyPromise = this._readyPromise.promise; - - /** - * An optional model matrix that is applied to all tiles - * - * @type {Matrix4|undefined} - * @readonly - */ - this.modelMatrix = undefined; - - /** - * Gets the {@link VoxelShapeType} - * - * @type {VoxelShapeType} - * @readonly - */ + /** @inheritdoc */ + this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + + /** @inheritdoc */ this.shape = undefined; - /** - * Gets the minimum bounds. - * If undefined, the shape's default minimum bounds will be used instead. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ + /** @inheritdoc */ this.minBounds = undefined; - /** - * Gets the maximum bounds. - * If undefined, the shape's default maximum bounds will be used instead. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ + /** @inheritdoc */ this.maxBounds = undefined; - /** - * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset. - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3} - * @readonly - */ + /** @inheritdoc */ this.dimensions = undefined; - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * TODO: mark this optional - * This should not be called before {@link VoxelProvider#ready} returns true. - * - * @type {Cartesian3|undefined} - * @readonly - */ + /** @inheritdoc */ this.paddingBefore = undefined; - /** - * Gets the number of padding voxels on the edge of a tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. - * This should not be called before {@link VoxelProvider#ready} returns true. - * TODO: mark this optional - * - * @type {Cartesian3|undefined} - * @readonly - */ + /** @inheritdoc */ this.paddingAfter = undefined; - // TODO is there a good user-facing way to set names, types, componentTypes, min, max, etc? MetadataComponents.Primitive is close, but private and has some fields that voxels don't use - - /** - * Gets the metadata names. - * - * @type {String[]} - * @readonly - */ - this.names = new Array(); - - /** - * Gets the metadata types - * - * @type {MetadataType[]} - * @readonly - * @private - */ - this.types = new Array(); - - /** - * Gets the metadata component types - * - * @type {MetadataComponentType[]} - * @readonly - * @private - */ - this.componentTypes = new Array(); - - /** - * Gets the minimum value - * - * @type {Number[][]|undefined} - * @readonly - */ + /** @inheritdoc */ + this.names = undefined; + + /** @inheritdoc */ + this.types = undefined; + + /** @inheritdoc */ + this.componentTypes = undefined; + + /** @inheritdoc */ this.minimumValues = undefined; - /** - * Gets the maximum value - * - * @type {Number[][]|undefined} - * @readonly - */ + /** @inheritdoc */ this.maximumValues = undefined; - /** - * The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be set to 0. - * - * @type {Number|undefined} - * @readonly - */ + /** @inheritdoc */ this.maximumTileCount = undefined; - /** - * @type {ImplicitTileset} - * @private - */ this._implicitTileset = undefined; - - /** - * @type {ImplicitSubtreeCache} - * @private - */ - // TODO: set a default maximumSubtreeCount to limit memory usage this._subtreeCache = new ImplicitSubtreeCache(); - /** - * glTFs that are in the process of being loaded. - * - * @type {GltfLoader[]} - * @private - */ - this._gltfLoaders = new Array(); - - /** - * Subtrees that are in the process of being loaded. - * This member exists for unit test purposes only. See doneLoading. - * - * @type {Subtree[]} - * @private - */ - this._subtreeLoaders = new Array(); - - /** - * Subtree resources that are in the process of being loaded. - * This member exists for unit test purposes only. See doneLoading. - * - * @type {Resource[]} - * @private - */ - this._subtreeResourceLoaders = new Array(); - const that = this; let tilesetJson; - let tileJson; - let metadata; - let implicitTileset; - - // 1. Load tileset.json - // 2. Load schema.json - // 3. Load root glTF to get provider properties - const resource = Resource.createIfNeeded(options.url); - resource - .fetchJson() - .then(function (tileset) { - tilesetJson = tileset; - tileJson = tilesetJson.root; - return getMetadataSchemaLoader(tilesetJson, resource).promise; - }) - .then(function (schemaLoader) { - const metadataSchema = schemaLoader.schema; - metadata = new Cesium3DTilesetMetadata({ - metadataJson: tilesetJson, - schema: metadataSchema, - }); - implicitTileset = new ImplicitTileset(resource, tileJson, metadataSchema); - - // TODO make sure this fails when root tile is not available? - const rootCoord = new ImplicitTileCoordinates({ - subdivisionScheme: implicitTileset.subdivisionScheme, - subtreeLevels: implicitTileset.subtreeLevels, - level: 0, - x: 0, - y: 0, - z: 0, + + this._readyPromise = Promise.resolve(options.url).then(function (url) { + const resource = Resource.createIfNeeded(url); + return resource + .fetchJson() + .then(function (tileset) { + tilesetJson = tileset; + validate(tilesetJson); + return getMetadataSchemaLoader(tilesetJson, resource).promise; + }) + .then(function (schemaLoader) { + const root = tilesetJson.root; + + const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") + ? tilesetJson.extensions["3DTILES_metadata"] + : tilesetJson; + + const metadataSchema = schemaLoader.schema; + const metadata = new Cesium3DTilesetMetadata({ + metadataJson: metadataJson, + schema: metadataSchema, + }); + + addAttributeInfo(metadata, that); + + const implicitTileset = new ImplicitTileset( + resource, + root, + metadataSchema + ); + + const voxel = root.content.extensions["3DTILES_content_voxels"]; + + const { shape, transform, minBounds, maxBounds } = getShape(root); + + that.shape = shape; + that.minBounds = minBounds; + that.maxBounds = maxBounds; + that.dimensions = Cartesian3.unpack(voxel.dimensions); + that.paddingBefore = Cartesian3.unpack(voxel.padding.before); + that.paddingAfter = Cartesian3.unpack(voxel.padding.after); + that.modelMatrix = transform; + + // TODO: this tile class stuff needs to be documented + that.maximumTileCount = metadata.statistics.classes.tile?.count; + + that._implicitTileset = implicitTileset; + that.ready = true; + return that; }); - const rootGltfLoader = getGltfLoader(implicitTileset, rootCoord); - that._gltfLoaders.push(rootGltfLoader); - return rootGltfLoader.promise; - }) - .then(function (rootGltfLoader) { - that._gltfLoaders.splice(that._gltfLoaders.indexOf(rootGltfLoader), 1); + }); +} - addAttributeInfo(metadata, that); +Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, { + /** @inheritdoc */ + readyPromise: { + get: function () { + return this._readyPromise; + }, + }, +}); - const gltfPrimitive = rootGltfLoader.components.nodes[0].primitives[0]; - const { primitiveType, voxel } = gltfPrimitive; +function validate(tileset) { + const root = tileset.root; - that.shape = VoxelShapeType.fromPrimitiveType(primitiveType); + if (!defined(root.content)) { + throw new RuntimeError("Root must have content"); + } - that.minBounds = Cartesian3.clone(voxel.minBounds); - that.maxBounds = Cartesian3.clone(voxel.maxBounds); - that.dimensions = Cartesian3.clone(voxel.dimensions); - that.paddingBefore = Cartesian3.clone(voxel.paddingBefore); - that.paddingAfter = Cartesian3.clone(voxel.paddingAfter); + if (!hasExtension(root.content, "3DTILES_content_voxels")) { + throw new RuntimeError( + "Root tile content must have 3DTILES_content_voxels extension" + ); + } - that.maximumTileCount = metadata.statistics.classes.tile?.count; + if ( + !hasExtension(root, "3DTILES_implicit_tiling") && + !defined(root.implicitTiling) + ) { + throw new RuntimeError("Root tile must have implicit tiling"); + } - that.modelMatrix = Matrix4.clone(tileJson.transform); - that.ready = true; - that._readyPromise.resolve(that); - that._implicitTileset = implicitTileset; - }) - .catch(function (error) { - that._readyPromise.reject(error); - }); + if ( + !defined(tileset.schema) && + !defined(tileset.schemaUri) && + !hasExtension(tileset, "3DTILES_metadata") + ) { + throw new RuntimeError("Tileset must have a metadata schema"); + } +} + +function getShape(tile) { + const boundingVolume = tile.boundingVolume; + + let tileTransform = Matrix4.IDENTITY; + if (defined(tile.transform)) { + tileTransform = Matrix4.unpack(tile.transform); + } + + if (defined(boundingVolume.box)) { + return getBoxShape(boundingVolume.box, tileTransform); + } else if (defined(boundingVolume.region)) { + return getEllipsoidShape(boundingVolume.region); + } else if (hasExtension(boundingVolume, "3DTILES_bounding_volume_cylinder")) { + return getCylinderShape( + boundingVolume.extensions["3DTILES_bounding_volume_cylinder"].cylinder, + tileTransform + ); + } + + throw new RuntimeError( + "Only box, region and 3DTILES_bounding_volume_cylinder are supported in Cesium3DTilesVoxelProvider" + ); +} + +function getEllipsoidShape(region) { + const west = region[0]; + const south = region[1]; + const east = region[2]; + const north = region[3]; + const minHeight = region[4]; + const maxHeight = region[5]; + + const scale = Cartesian3.clone(Ellipsoid.WGS84.radii); + const scaleFromHeight = new Cartesian3(maxHeight, maxHeight, maxHeight); + Cartesian3.add(scale, scaleFromHeight); + + const shapeTransform = Matrix4.fromScale(scale); + + const minBoundsX = west; + const maxBoundsX = east; + const minBoundsY = south; + const maxBoundsY = north; + const minBoundsZ = + (minHeight + Ellipsoid.WGS84.maximumRadius) / + (maxHeight + Ellipsoid.WGS84.maximumRadius); + const maxBoundsZ = 1.0; + + const minBounds = new Cartesian3(minBoundsX, minBoundsY, minBoundsZ); + const maxBounds = new Cartesian3(maxBoundsX, maxBoundsY, maxBoundsZ); + + return { + shape: VoxelShapeType.ELLIPSOID, + minBounds: minBounds, + maxBounds: maxBounds, + transform: shapeTransform, + }; +} + +function getBoxShape(box, tileTransform) { + const obb = OrientedBoundingBox.unpack(box); + const shapeTransform = Matrix4.fromRotationTranslation( + obb.halfAxes, + obb.center + ); + + const transform = Matrix4.multiply( + tileTransform, + shapeTransform, + new Matrix4() + ); + + return { + shape: VoxelShapeType.BOX, + minBounds: Cartesian3.clone(VoxelBoxShape.DefaultMinBounds), + maxBounds: Cartesian3.clone(VoxelBoxShape.DefaultMaxBounds), + transform: transform, + }; +} + +function getCylinderShape(cylinder, tileTransform) { + const obb = OrientedBoundingBox.unpack(cylinder); + const shapeTransform = Matrix4.fromRotationTranslation( + obb.halfAxes, + obb.center + ); + + const transform = Matrix4.multiply( + tileTransform, + shapeTransform, + new Matrix4() + ); + + return { + shape: VoxelShapeType.CYLINDER, + minBounds: Cartesian3.clone(VoxelCylinderShape.DefaultMinBounds), + maxBounds: Cartesian3.clone(VoxelCylinderShape.DefaultMaxBounds), + transform: transform, + }; } -/** - * Get a schema loader to load the metadata schema referenced in a tileset JSON file - * @param {Object} tilesetJson A tileset JSON object describing a 3DTiles tileset - * @param {Resource} resource - * @returns {MetadataSchemaLoader} - * @private - */ function getMetadataSchemaLoader(tilesetJson, resource) { const { schemaUri, schema } = tilesetJson; if (!defined(schemaUri)) { @@ -299,19 +293,11 @@ function getMetadataSchemaLoader(tilesetJson, resource) { return ResourceCache.loadSchema({ resource: resource.getDerivedResource({ url: schemaUri, - preserveQueryParameters: true, }), }); } -/** - * Add info about metadata attributes to a VoxelPrimitive: - * names, types, componentTypes, minimumValues, maximumValues - * @param {Cesium3DTilesetMetadata} metadata - * @param {VoxelPrimitive} primitive - * @private - */ -function addAttributeInfo(metadata, primitive) { +function addAttributeInfo(metadata, provider) { const { schema, statistics } = metadata; // Collect a flattened array of info from all properties in all classes. @@ -333,30 +319,24 @@ function addAttributeInfo(metadata, primitive) { }); } - primitive.names = propertyInfo.map((info) => info.name); - primitive.types = propertyInfo.map((info) => info.type); - primitive.componentTypes = propertyInfo.map((info) => info.componentType); + provider.names = propertyInfo.map((info) => info.name); + provider.types = propertyInfo.map((info) => info.type); + provider.componentTypes = propertyInfo.map((info) => info.componentType); const minimumValues = propertyInfo.map((info) => info.minValue); const maximumValues = propertyInfo.map((info) => info.maxValue); const hasMinimumValues = minimumValues.some(defined); - primitive.minimumValues = hasMinimumValues ? minimumValues : undefined; - primitive.maximumValues = hasMinimumValues ? maximumValues : undefined; + provider.minimumValues = hasMinimumValues ? minimumValues : undefined; + provider.maximumValues = hasMinimumValues ? maximumValues : undefined; } -/** - * Copy input values into a new array of a specified length. - * If the input is not an array, its value will be copied into the first element - * of the returned array. If the input is an array shorter than the returned - * array, the extra elements in the returned array will be undefined. If the - * input is undefined, the return will be undefined. - * @param {*} values The values to copy - * @param {Number} length The length of the returned array - * @returns {Array} A new array filled with the supplied values - * @private - */ function copyArray(values, length) { + // Copy input values into a new array of a specified length. + // If the input is not an array, its value will be copied into the first element + // of the returned array. If the input is an array shorter than the returned + // array, the extra elements in the returned array will be undefined. If the + // input is undefined, the return will be undefined. if (!defined(values)) { return; } @@ -364,20 +344,73 @@ function copyArray(values, length) { return Array.from({ length }, (v, i) => valuesArray[i]); } -/** - * Requests the data for a given tile. The data is a flattened 3D array ordered by X, then Y, then Z. - * This function should not be called before {@link VoxelProvider#ready} returns true. - * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.tileLevel=0] The tile's level. - * @param {Number} [options.tileX=0] The tile's X coordinate. - * @param {Number} [options.tileY=0] The tile's Y coordinate. - * @param {Number} [options.tileZ=0] The tile's Z coordinate. - * @param {Number} [options.keyframe=0] The requested keyframe. - * @returns {Promise|undefined} An array of promises for the requested voxel data or undefined if there was a problem loading the data. - * - * @exception {DeveloperError} The provider must be ready. - */ +function getVoxelPromise(implicitTileset, tileCoordinates) { + const voxelRelative = implicitTileset.contentUriTemplates[0].getDerivedResource( + { + templateValues: tileCoordinates.getTemplateValues(), + } + ); + const voxelResource = implicitTileset.baseResource.getDerivedResource({ + url: voxelRelative.url, + }); + + return voxelResource.fetchArrayBuffer().then(function (arrayBuffer) { + const preprocessed = preprocess3DTileContent(arrayBuffer); + + const voxelContent = new VoxelContent( + voxelResource, + preprocessed.jsonPayload, + preprocessed.binaryPayload, + implicitTileset.metadataSchema + ); + + return voxelContent.readyPromise; + }); +} + +function getSubtreePromise(provider, subtreeCoord) { + const implicitTileset = provider._implicitTileset; + const subtreeCache = provider._subtreeCache; + + // First load the subtree to check if the tile is available. + // If the subtree has been requested previously it might still be in the cache + const subtree = subtreeCache.find(subtreeCoord); + if (defined(subtree)) { + return subtree.readyPromise; + } + + const subtreeRelative = implicitTileset.subtreeUriTemplate.getDerivedResource( + { + templateValues: subtreeCoord.getTemplateValues(), + } + ); + const subtreeResource = implicitTileset.baseResource.getDerivedResource({ + url: subtreeRelative.url, + }); + + return subtreeResource.fetchArrayBuffer().then(function (arrayBuffer) { + // Check one more time if the subtree is in the cache. + // This could happen if there are two in-flight tile requests from the same + // subtree and one finishes before the other. + let subtree = subtreeCache.find(subtreeCoord); + if (defined(subtree)) { + return subtree.readyPromise; + } + + const preprocessed = preprocess3DTileContent(arrayBuffer); + subtree = new ImplicitSubtree( + subtreeResource, + preprocessed.jsonPayload, + preprocessed.binaryPayload, + implicitTileset, + subtreeCoord + ); + subtreeCache.addSubtree(subtree); + return subtree.readyPromise; + }); +} + +/** @inheritdoc */ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { //>>includeStart('debug', pragmas.debug); if (!this.ready) { @@ -400,11 +433,9 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { } // 1. Load the subtree that the tile belongs to (possibly from the subtree cache) - // 2. Load the glTF if available + // 2. Load the voxel content if available const implicitTileset = this._implicitTileset; - const types = this.types; - const componentTypes = this.componentTypes; const names = this.names; // Can't use a scratch variable here because the object is used inside the promise chain. @@ -419,7 +450,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { // Find the coordinates of the parent subtree containing tileCoordinates // If tileCoordinates is a subtree child, use that subtree - // If tileCoords is a subtree root, use its parent subtree + // If tileCoordinates is a subtree root, use its parent subtree const isSubtreeRoot = tileCoordinates.isSubtreeRoot() && tileCoordinates.level > 0; @@ -435,165 +466,17 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { ? subtree.childSubtreeIsAvailableAtCoordinates(tileCoordinates) : subtree.tileIsAvailableAtCoordinates(tileCoordinates); - const subtreeLoaderIndex = that._subtreeLoaders.indexOf(subtree); - if (subtreeLoaderIndex !== -1) { - that._subtreeLoaders.splice(subtreeLoaderIndex, 1); - } if (!available) { return Promise.reject("Tile is not available"); } - const gltfLoader = getGltfLoader(implicitTileset, tileCoordinates); - that._gltfLoaders.push(gltfLoader); - - return gltfLoader.promise; + return getVoxelPromise(implicitTileset, tileCoordinates); }) - .then(function (gltfLoader) { - const node = gltfLoader.components.scene.nodes[0]; - const attributes = node.primitives[0].attributes; - const attributesLength = attributes.length; - - const data = new Array(attributesLength); - for (let i = 0; i < attributesLength; i++) { - // The attributes array from GltfLoader is not in the same order as - // names, types, etc. from the provider. - // Find the appropriate glTF attribute based on its name. - // Note: glTF custom attribute names are prefixed with "_" - const name = `_${names[i]}`; - const attribute = attributes.find((a) => a.name === name); - if (!defined(attribute)) { - continue; - } - - const type = types[i]; - const componentType = componentTypes[i]; - const componentDatatype = MetadataComponentType.toComponentDatatype( - componentType - ); - const componentCount = MetadataType.getComponentCount(type); - const totalCount = attribute.count * componentCount; - data[i] = ComponentDatatype.createArrayBufferView( - componentDatatype, - attribute.typedArray.buffer, - attribute.typedArray.byteOffset + attribute.byteOffset, - totalCount - ); - } - - that._gltfLoaders.splice(that._gltfLoaders.indexOf(gltfLoader), 1); - return data; + .then(function (voxelContent) { + return names.map(function (name) { + return voxelContent.metadataTable.getPropertyTypedArray(name); + }); }); }; -/** - * - * @param {VoxelPrimitive} primitive - * @param {ImplicitTileCoordinates} subtreeCoord - * @returns {Promise.} - * @private - */ -function getSubtreePromise(primitive, subtreeCoord) { - const implicitTileset = primitive._implicitTileset; - const subtreeCache = primitive._subtreeCache; - - // First load the subtree to check if the tile is available. - // If the subtree has been requested previously it might still be in the cache - const subtree = subtreeCache.find(subtreeCoord); - if (defined(subtree)) { - return subtree.readyPromise; - } - - const { subtreeUriTemplate, baseResource } = implicitTileset; - const subtreeRelative = subtreeUriTemplate.getDerivedResource({ - templateValues: subtreeCoord.getTemplateValues(), - }); - const subtreeResource = baseResource.getDerivedResource({ - url: subtreeRelative.url, - }); - primitive._subtreeResourceLoaders.push(subtreeResource); - - return subtreeResource.fetchArrayBuffer().then(addSubtree); - - function addSubtree(arrayBuffer) { - // Check one more time if the subtree is in the cache. - // This could happen if there are two in-flight tile requests from the same - // subtree and one finishes before the other. - let subtree = subtreeCache.find(subtreeCoord); - if (defined(subtree)) { - return subtree.readyPromise; - } - const bufferU8 = new Uint8Array(arrayBuffer); - subtree = new ImplicitSubtree( - subtreeResource, - undefined, - bufferU8, - implicitTileset, - subtreeCoord - ); - subtreeCache.addSubtree(subtree); - primitive._subtreeLoaders.push(subtree); - const subtreeResourceIndex = primitive._subtreeResourceLoaders.indexOf( - subtreeResource - ); - primitive._subtreeResourceLoaders.splice(subtreeResourceIndex, 1); - return subtree.readyPromise; - } -} - -/** - * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. - * @function - * - * @param {FrameState} frameState - * @private - */ -Cesium3DTilesVoxelProvider.prototype.update = function (frameState) { - const loaders = this._gltfLoaders; - for (let i = 0; i < loaders.length; i++) { - loaders[i].process(frameState); - } -}; - -/** - * Check if anything is still being loaded. - * This is intended for unit test purposes only. - * - * @returns {Boolean} - * - * @private - */ -Cesium3DTilesVoxelProvider.prototype.doneLoading = function () { - return ( - this._gltfLoaders.length === 0 && - this._subtreeLoaders.length === 0 && - this._subtreeResourceLoaders.length === 0 - ); -}; - -/** - * Get a loader for a glTF tile from a tileset - * @param {ImplicitTileset} implicitTileset The tileset from which the loader will retrieve a glTF tile - * @param {ImplicitTileCoordinates} tileCoord The coordinates of the desired tile - * @returns {GltfLoader} A loader for the requested tile - * @private - */ -function getGltfLoader(implicitTileset, tileCoord) { - const { contentUriTemplates, baseResource } = implicitTileset; - const gltfRelative = contentUriTemplates[0].getDerivedResource({ - templateValues: tileCoord.getTemplateValues(), - }); - const gltfResource = baseResource.getDerivedResource({ - url: gltfRelative.url, - }); - - const gltfLoader = new GltfLoader({ - gltfResource: gltfResource, - releaseGltfJson: false, - loadAttributesAsTypedArray: true, - }); - - gltfLoader.load(); - return gltfLoader; -} - export default Cesium3DTilesVoxelProvider; diff --git a/packages/engine/Source/Scene/ImplicitTileset.js b/packages/engine/Source/Scene/ImplicitTileset.js index a4e7867b5ee..45473db61de 100644 --- a/packages/engine/Source/Scene/ImplicitTileset.js +++ b/packages/engine/Source/Scene/ImplicitTileset.js @@ -64,10 +64,11 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { if ( !defined(boundingVolume.box) && !defined(boundingVolume.region) && - !hasExtension(boundingVolume, "3DTILES_bounding_volume_S2") + !hasExtension(boundingVolume, "3DTILES_bounding_volume_S2") && + !hasExtension(boundingVolume, "3DTILES_bounding_volume_cylinder") ) { throw new RuntimeError( - "Only box, region and 3DTILES_bounding_volume_S2 are supported for implicit tiling" + "Only box, region, 3DTILES_bounding_volume_S2, and 3DTILES_bounding_volume_cylinder are supported for implicit tiling" ); } diff --git a/packages/engine/Source/Scene/VoxelContent.js b/packages/engine/Source/Scene/VoxelContent.js new file mode 100644 index 00000000000..b57cd815882 --- /dev/null +++ b/packages/engine/Source/Scene/VoxelContent.js @@ -0,0 +1,169 @@ +import Check from "../Core/Check.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import defined from "../Core/defined.js"; +import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js"; +import MetadataTable from "./MetadataTable.js"; + +/** + * An object representing voxel content for a {@link Cesium3DTilesVoxelProvider}. + * + * @alias VoxelContent + * @constructor + * + * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed. + * @param {Object} [json] Voxel JSON contents. Mutually exclusive with binary. + * @param {Uint8Array} [binary] Voxel binary contents. Mutually exclusive with json. + * @param {MetadataSchema} metadataSchema The metadata schema used by property tables in the voxel content + * + * @exception {DeveloperError} One of json and binary must be defined. + * + * @private + * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. + */ +function VoxelContent(resource, json, binary, metadataSchema) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("resource", resource); + if (defined(json) === defined(binary)) { + throw new DeveloperError("One of json and binary must be defined."); + } + //>>includeEnd('debug'); + + this._resource = resource; + this._metadataTable = undefined; + + let chunks; + if (defined(json)) { + chunks = { + json: json, + binary: undefined, + }; + } else { + chunks = parseVoxelChunks(binary); + } + + this._readyPromise = initialize( + this, + chunks.json, + chunks.binary, + metadataSchema + ); +} + +Object.defineProperties(VoxelContent.prototype, { + /** + * A promise that resolves once all buffers are loaded. + * + * @type {Promise} + * @readonly + * @private + */ + readyPromise: { + get: function () { + return this._readyPromise; + }, + }, + + /** + * The {@link MetadataTable} storing voxel property values. + * + * @type {MetadataTable} + * @readonly + * @private + */ + metadataTable: { + get: function () { + return this._metadataTable; + }, + }, +}); + +function initialize(content, json, binary, metadataSchema) { + return requestBuffers(content, json, binary).then(function (buffersU8) { + const bufferViewsU8 = {}; + const bufferViewsLength = json.bufferViews.length; + for (let i = 0; i < bufferViewsLength; ++i) { + const bufferViewJson = json.bufferViews[i]; + const start = bufferViewJson.byteOffset; + const end = start + bufferViewJson.byteLength; + const buffer = buffersU8[bufferViewJson.buffer]; + const bufferView = buffer.subarray(start, end); + bufferViewsU8[i] = bufferView; + } + + const propertyTableIndex = json.voxelTable; + const propertyTableJson = json.propertyTables[propertyTableIndex]; + content._metadataTable = new MetadataTable({ + count: propertyTableJson.count, + properties: propertyTableJson.properties, + class: metadataSchema.classes[propertyTableJson.class], + bufferViews: bufferViewsU8, + }); + return content; + }); +} + +function requestBuffers(content, json, binary) { + const buffersLength = json.buffers.length; + const bufferPromises = new Array(buffersLength); + for (let i = 0; i < buffersLength; i++) { + const buffer = json.buffers[i]; + if (defined(buffer.uri)) { + const baseResource = content._resource; + const bufferResource = baseResource.getDerivedResource({ + url: buffer.uri, + }); + bufferPromises[i] = bufferResource + .fetchArrayBuffer() + .then(function (arrayBuffer) { + return new Uint8Array(arrayBuffer); + }); + } else { + bufferPromises[i] = Promise.resolve(binary); + } + } + + return Promise.all(bufferPromises); +} + +/** + * A helper object for storing the two parts of the binary voxel content + * + * @typedef {Object} VoxelChunks + * @property {Object} json The json chunk of the binary voxel content + * @property {Uint8Array} binary The binary chunk of the binary voxel content. This represents the internal buffer. + * @private + */ + +/** + * Given binary voxel content, split into JSON and binary chunks + * + * @param {Uint8Array} binaryView The binary voxel content + * @returns {VoxelChunks} An object containing the JSON and binary chunks + * @private + */ +function parseVoxelChunks(binaryView) { + // Parse the header + const littleEndian = true; + const reader = new DataView(binaryView.buffer, binaryView.byteOffset); + // Skip to the chunk lengths + let byteOffset = 8; + + // Read the bottom 32 bits of the 64-bit byte length. This is ok for now because: + // 1) not all browsers have native 64-bit operations + // 2) the data is well under 4GB + const jsonByteLength = reader.getUint32(byteOffset, littleEndian); + byteOffset += 8; + const binaryByteLength = reader.getUint32(byteOffset, littleEndian); + byteOffset += 8; + + const json = getJsonFromTypedArray(binaryView, byteOffset, jsonByteLength); + byteOffset += jsonByteLength; + const binary = binaryView.subarray(byteOffset, byteOffset + binaryByteLength); + + return { + json: json, + binary: binary, + }; +} + +export default VoxelContent; diff --git a/packages/engine/Source/Scene/VoxelProvider.js b/packages/engine/Source/Scene/VoxelProvider.js index 7a340d0d0cf..685351f61e3 100644 --- a/packages/engine/Source/Scene/VoxelProvider.js +++ b/packages/engine/Source/Scene/VoxelProvider.js @@ -102,7 +102,7 @@ Object.defineProperties(VoxelProvider.prototype, { }, /** - * Gets the number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If + * Gets the number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype @@ -114,7 +114,7 @@ Object.defineProperties(VoxelProvider.prototype, { }, /** - * Gets the number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. If + * Gets the number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage. * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype @@ -138,26 +138,24 @@ Object.defineProperties(VoxelProvider.prototype, { }, /** - * Gets the metadata types + * Gets the metadata types. * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype * @type {MetadataType[]} * @readonly - * @private */ types: { get: DeveloperError.throwInstantiationError, }, /** - * Gets the metadata component types + * Gets the metadata component types. * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype * @type {MetadataComponentType[]} * @readonly - * @private */ componentTypes: { get: DeveloperError.throwInstantiationError, @@ -165,6 +163,7 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata minimum values. + * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype * @type {Number[][]|undefined} @@ -176,6 +175,7 @@ Object.defineProperties(VoxelProvider.prototype, { /** * Gets the metadata maximum values. + * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype * @type {Number[][]|undefined} @@ -239,14 +239,4 @@ Object.defineProperties(VoxelProvider.prototype, { */ VoxelProvider.prototype.requestData = DeveloperError.throwInstantiationError; -/** - * A hook to update the provider every frame, called from {@link VoxelPrimitive.update}. - * If the provider doesn't need this functionality it should leave this function undefined. - * @function - * - * @param {FrameState} frameState - * @private - */ -VoxelProvider.prototype.update = DeveloperError.throwInstantiationError; - export default VoxelProvider; diff --git a/packages/engine/Source/Scene/preprocess3DTileContent.js b/packages/engine/Source/Scene/preprocess3DTileContent.js index dcbed11b51b..ec8f44b84d4 100644 --- a/packages/engine/Source/Scene/preprocess3DTileContent.js +++ b/packages/engine/Source/Scene/preprocess3DTileContent.js @@ -76,6 +76,14 @@ function preprocess3DTileContent(arrayBuffer) { }; } + if (defined(json.voxelTable)) { + // Most likely a voxel JSON + return { + contentType: Cesium3DTileContentType.VOXEL_JSON, + jsonPayload: json, + }; + } + throw new RuntimeError("Invalid tile content."); } From 9c7eecf6aa072f1a3fb42220e93e0a338f6b5001 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 23 Dec 2022 11:04:28 -0500 Subject: [PATCH 280/679] Remove defer usage in VoxelPrimitive and some cleanup --- .../engine/Source/Scene/VoxelPrimitive.js | 97 ++++++++----------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index 0b959ae67c8..2ea07b0b366 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -7,7 +7,6 @@ import Check from "../Core/Check.js"; import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; -import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; @@ -39,7 +38,6 @@ import CustomShader from "./Model/CustomShader.js"; * * @see VoxelProvider * @see Cesium3DTilesVoxelProvider - * @see GltfVoxelProvider * @see VoxelShapeType * * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. @@ -53,12 +51,6 @@ function VoxelPrimitive(options) { */ this._ready = false; - /** - * @type {Promise.} - * @private - */ - this._readyPromise = defer(); - /** * @type {VoxelProvider} * @private @@ -192,6 +184,7 @@ function VoxelPrimitive(options) { /** * Keeps track of when the clipping planes are enabled / disabled + * * @type {Boolean} * @private */ @@ -203,9 +196,8 @@ function VoxelPrimitive(options) { * @type {Matrix4} * @private */ - this._modelMatrix = defaultValue( - options.modelMatrix, - Matrix4.clone(Matrix4.IDENTITY, new Matrix4()) + this._modelMatrix = Matrix4.clone( + defaultValue(options.modelMatrix, Matrix4.IDENTITY) ); /** @@ -430,9 +422,25 @@ function VoxelPrimitive(options) { // If the provider fails to initialize the primitive will fail too. const provider = this._provider; - const primitive = this; - provider.readyPromise.catch(function (error) { - primitive._readyPromise.reject(error); + this._completeLoad = function (primitive, frameState) {}; + this._readyPromise = initialize(this, provider); +} + +function initialize(primitive, provider) { + const promise = new Promise(function (resolve) { + primitive._completeLoad = function (primitive, frameState) { + // Set the primitive as ready after the first frame render since the user might set up events subscribed to + // the post render event, and the primitive may not be ready for those past the first frame. + frameState.afterRender.push(function () { + primitive._ready = true; + resolve(primitive); + return true; + }); + }; + }); + + return provider.readyPromise.then(function () { + return promise; }); } @@ -459,7 +467,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { */ readyPromise: { get: function () { - return this._readyPromise.promise; + return this._readyPromise; }, }, @@ -538,20 +546,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { Check.typeOf.object("modelMatrix", modelMatrix); //>>includeEnd('debug'); - this._modelMatrix = Matrix4.clone(modelMatrix, new Matrix4()); - }, - }, - - /** - * Gets the compound model matrix - * - * @memberof VoxelPrimitive.prototype - * @type {Matrix4} - * @readonly - */ - compoundModelMatrix: { - get: function () { - return this._compoundModelMatrix; + this._modelMatrix = Matrix4.clone(modelMatrix, this._modelMatrix); }, }, @@ -836,7 +831,8 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** - * Gets or sets the minimum bounds. TODO: fill in the rest later + * Gets or sets the minimum bounds in the shape's local coordinate system. + * Voxel data is stretched or squashed to fit the bounds. * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} @@ -855,7 +851,8 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, /** - * Gets or sets the maximum bounds. TODO: fill in the rest later. + * Gets or sets the maximum bounds in the shape's local coordinate system. + * Voxel data is stretched or squashed to fit the bounds. * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} @@ -876,7 +873,6 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets the minimum clipping location in the shape's local coordinate system. * Any voxel content outside the range is clipped. - * The minimum value is 0 and the maximum value is 1. * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} @@ -900,7 +896,6 @@ Object.defineProperties(VoxelPrimitive.prototype, { /** * Gets or sets the maximum clipping location in the shape's local coordinate system. * Any voxel content outside the range is clipped. - * The minimum value is 0 and the maximum value is 1. * * @memberof VoxelPrimitive.prototype * @type {Cartesian3} @@ -987,9 +982,6 @@ Object.defineProperties(VoxelPrimitive.prototype, { }, }); -// TODO 3-channel + 1-channel metadata is a problem right now -// Individually, they both work, but together the 1-channel is messed up - const scratchDimensions = new Cartesian3(); const scratchIntersect = new Cartesian4(); const scratchNdcAabb = new Cartesian4(); @@ -1014,17 +1006,12 @@ const transformPositionUvToLocal = Matrix4.fromRotationTranslation( /** * Updates the voxel primitive. - * @function * * @param {FrameState} frameState * @private */ VoxelPrimitive.prototype.update = function (frameState) { - // Update the provider, if applicable. const provider = this._provider; - if (defined(provider.update)) { - provider.update(frameState); - } // Update the custom shader in case it has texture uniforms. this._customShader.update(frameState); @@ -1037,15 +1024,10 @@ VoxelPrimitive.prototype.update = function (frameState) { // Initialize from the ready provider. This only happens once. const context = frameState.context; if (!this._ready) { - // Don't make the primitive ready until after its first update because - // external code may want to change some of its properties before it's rendered. - const primitive = this; - frameState.afterRender.push(function () { - primitive._ready = true; - primitive._readyPromise.resolve(primitive); - }); - initFromProvider(this, provider, context); + this._completeLoad(this, frameState); + + // Don't render until the next frame after the ready promise is resolved return; } @@ -1307,19 +1289,20 @@ function checkTransformAndBounds(primitive, provider) { /** * Compare old and new values of a bound and update the old if it is different. - * @param {VoxelPrimitive} The primitive with bounds properties - * @param {String} oldBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 - * @param {String} newBoundKey A key pointing to a bounds property of the same type as the property at oldBoundKey + * @param {VoxelPrimitive} primitive The primitive with bounds properties + * @param {String} newBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 + * @param {String} oldBoundKey A key pointing to a bounds property of the same type as the property at newBoundKey * @returns {Number} 1 if the bound value changed, 0 otherwise * * @private */ function updateBound(primitive, newBoundKey, oldBoundKey) { const newBound = primitive[newBoundKey]; - const BoundClass = newBound.constructor; - const changed = !BoundClass.equals(newBound, primitive[oldBoundKey]); + const oldBound = primitive[oldBoundKey]; + + const changed = !newBound.equals(oldBound); if (changed) { - primitive[oldBoundKey] = BoundClass.clone(newBound, primitive[oldBoundKey]); + newBound.clone(oldBound); } return changed ? 1 : 0; } @@ -1334,7 +1317,7 @@ function updateBound(primitive, newBoundKey, oldBoundKey) { */ function updateShapeAndTransforms(primitive, shape, provider) { const visible = shape.update( - primitive.compoundModelMatrix, + primitive._compoundModelMatrix, primitive.minBounds, primitive.maxBounds, primitive.minClippingBounds, @@ -1370,7 +1353,6 @@ function updateShapeAndTransforms(primitive, shape, provider) { // Set member variables when the shape is dirty const dimensions = provider.dimensions; primitive._stepSizeUv = shape.computeApproximateStepSize(dimensions); - // TODO: check which of the `multiply` can be `multiplyTransformation` primitive._transformPositionWorldToUv = Matrix4.multiply( transformPositionLocalToUv, transformPositionWorldToLocal, @@ -1433,7 +1415,6 @@ function setupTraversal(primitive, provider, context) { /** * Set uniforms that come from the traversal. - * TODO: should this be done in VoxelTraversal? * @param {VoxelTraversal} traversal * @param {Object} uniforms * @private From 7fad96ab796230e5f3d8a0875b65e6a7703b2902 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 23 Dec 2022 13:27:58 -0500 Subject: [PATCH 281/679] Fix setting initial value in VoxelInspector --- .../widgets/Source/VoxelInspector/VoxelInspectorViewModel.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index 282d1f04be6..70122cf7460 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -67,7 +67,6 @@ function VoxelInspectorViewModel(scene) { function addProperty(options) { const { name, initialValue } = options; - that[name] = initialValue; that._definedProperties.push(name); let setPrimitiveFunction = options.setPrimitiveFunction; @@ -110,6 +109,9 @@ function VoxelInspectorViewModel(scene) { } }, }); + + that[name] = initialValue; + return knock; } From c0eee3ff622297b72b6ed2e473b712c53234a4aa Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 23 Dec 2022 16:47:29 -0500 Subject: [PATCH 282/679] Fix OBB calculation for cylinder --- .../engine/Source/Scene/VoxelCylinderShape.js | 161 +++++++++--------- 1 file changed, 82 insertions(+), 79 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index d32467ff387..e36e00d44df 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -728,7 +728,7 @@ VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); */ VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); -const maxTestAngles = 7; +const maxTestAngles = 5; // Preallocated arrays for all of the possible test angle counts /** @@ -737,18 +737,12 @@ const maxTestAngles = 7; */ const scratchTestAngles = new Array(maxTestAngles); -/** - * @type {Cartesian3[][]} - * @ignore - */ -const scratchTestPositions = new Array(maxTestAngles + 1); -for (let i = 0; i <= maxTestAngles; i++) { - const positionsLength = i * 4; - scratchTestPositions[i] = new Array(positionsLength); - for (let j = 0; j < positionsLength; j++) { - scratchTestPositions[i][j] = new Cartesian3(); - } -} +const scratchTranslation = new Cartesian3(); +const scratchRotation = new Matrix3(); +const scratchTranslationMatrix = new Matrix4(); +const scratchRotationMatrix = new Matrix4(); +const scratchScaleMatrix = new Matrix4(); +const scratchMatrix = new Matrix4(); /** * Computes an {@link OrientedBoundingBox} for a subregion of the shape. @@ -783,8 +777,8 @@ function getCylinderChunkObb( const defaultMaxRadius = defaultMaxBounds.x; // 1 const defaultMinHeight = defaultMinBounds.y; // -1 const defaultMaxHeight = defaultMaxBounds.y; // +1 - const defaultMinAngle = defaultMinBounds.z; // -pi/2 - const defaultMaxAngle = defaultMaxBounds.z; // +pi/2 + const defaultMinAngle = defaultMinBounds.z; // -pi + const defaultMaxAngle = defaultMaxBounds.z; // +pi // Return early if using the default bounds if ( @@ -800,84 +794,93 @@ function getCylinderChunkObb( return result; } - // TODO: this is not always working. See OrientedBoundingBox.fromRectangle for ideas to improve. - let testAngleCount = 0; + const isAngleFlipped = angleEnd < angleStart; + + if (isAngleFlipped) { + angleEnd += CesiumMath.TWO_PI; + } + + const angleWidth = angleEnd - angleStart; + const angleMid = angleStart + angleWidth * 0.5; + const testAngles = scratchTestAngles; - const halfPi = CesiumMath.PI_OVER_TWO; + let testAngleCount = 0; testAngles[testAngleCount++] = angleStart; testAngles[testAngleCount++] = angleEnd; + testAngles[testAngleCount++] = angleMid; - if (angleStart > angleEnd) { - if (angleStart <= 0.0 || angleEnd >= 0.0) { - testAngles[testAngleCount++] = 0.0; - } - if (angleStart <= +halfPi || angleEnd >= +halfPi) { - testAngles[testAngleCount++] = +halfPi; - } - if (angleStart <= -halfPi || angleEnd >= -halfPi) { - testAngles[testAngleCount++] = -halfPi; - } - // It will always cross the 180th meridian - testAngles[testAngleCount++] = CesiumMath.PI; - } else { - if (angleStart < 0.0 && angleEnd > 0.0) { - testAngles[testAngleCount++] = 0.0; - } - if (angleStart < +halfPi && angleEnd > +halfPi) { - testAngles[testAngleCount++] = +halfPi; - } - if (angleStart < -halfPi && angleEnd > -halfPi) { - testAngles[testAngleCount++] = -halfPi; - } + if (angleWidth > CesiumMath.PI) { + testAngles[testAngleCount++] = angleMid - CesiumMath.PI_OVER_TWO; + testAngles[testAngleCount++] = angleMid + CesiumMath.PI_OVER_TWO; } - const isAngleFlipped = angleEnd < angleStart; - const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; - const angleWidth = angleEnd - angleStart + isAngleFlipped * defaultAngleWidth; + // Find bounding box in local space relative to angleMid + let minX = 1.0; + let minY = 1.0; + let maxX = -1.0; + let maxY = -1.0; + + for (let i = 0; i < testAngleCount; ++i) { + const angle = testAngles[i] - angleMid; + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + const x1 = cosAngle * radiusStart; + const y1 = sinAngle * radiusStart; + const x2 = cosAngle * radiusEnd; + const y2 = sinAngle * radiusEnd; + + minX = Math.min(minX, x1); + minY = Math.min(minY, y1); + minX = Math.min(minX, x2); + minY = Math.min(minY, y2); + maxX = Math.max(maxX, x1); + maxY = Math.max(maxY, y1); + maxX = Math.max(maxX, x2); + maxY = Math.max(maxY, y2); + } - testAngles[testAngleCount++] = CesiumMath.negativePiToPi( - angleStart + angleWidth * 0.5 + const extentX = maxX - minX; + const extentY = maxY - minY; + const extentZ = heightEnd - heightStart; + + const centerX = (minX + maxX) * 0.5; + const centerY = (minY + maxY) * 0.5; + const centerZ = (heightStart + heightEnd) * 0.5; + + const translation = Cartesian3.fromElements( + centerX, + centerY, + centerZ, + scratchTranslation ); - const positions = scratchTestPositions[testAngleCount]; + const rotation = Matrix3.fromRotationZ(angleMid, scratchRotation); - for (let i = 0; i < testAngleCount; i++) { - const angle = testAngles[i]; - const cosAngle = Math.cos(angle); - const sinAngle = Math.sin(angle); + const scale = Cartesian3.fromElements( + extentX, + extentY, + extentZ, + scratchScale + ); - positions[i * 4 + 0] = Cartesian3.fromElements( - cosAngle * radiusStart, - sinAngle * radiusStart, - heightStart, - positions[i * 4 + 0] - ); - positions[i * 4 + 1] = Cartesian3.fromElements( - cosAngle * radiusEnd, - sinAngle * radiusEnd, - heightStart, - positions[i * 4 + 1] - ); - positions[i * 4 + 2] = Cartesian3.fromElements( - cosAngle * radiusStart, - sinAngle * radiusStart, - heightEnd, - positions[i * 4 + 2] - ); - positions[i * 4 + 3] = Cartesian3.fromElements( - cosAngle * radiusEnd, - sinAngle * radiusEnd, - heightEnd, - positions[i * 4 + 3] - ); - } + const scaleMatrix = Matrix4.fromScale(scale, scratchScaleMatrix); + const rotationMatrix = Matrix4.fromRotation(rotation, scratchRotationMatrix); + const translationMatrix = Matrix4.fromTranslation( + translation, + scratchTranslationMatrix + ); - for (let i = 0; i < testAngleCount * 4; i++) { - positions[i] = Matrix4.multiplyByPoint(matrix, positions[i], positions[i]); - } + // Local matrix = R * T * S + const localMatrix = Matrix4.multiply( + rotationMatrix, + Matrix4.multiply(translationMatrix, scaleMatrix, scratchMatrix), + scratchMatrix + ); - return OrientedBoundingBox.fromPoints(positions, result); + const globalMatrix = Matrix4.multiply(matrix, localMatrix, scratchMatrix); + const obb = OrientedBoundingBox.fromTransformation(globalMatrix, result); + return obb; } export default VoxelCylinderShape; From 9495e635d614b1f069407520219e12308e04346d Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Tue, 27 Dec 2022 12:46:03 +0800 Subject: [PATCH 283/679] support quantizationBits above 16 for draco decode --- CHANGES.md | 1 + packages/engine/Source/WorkersES6/decodeDraco.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5be69c125a6..dcc195ffe8a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ - Fixed a bug where \*.ktx2 images loading fail. [#10869](https://github.com/CesiumGS/cesium/pull/10869) - Fixed a bug where a `Model` would sometimes disappear when loaded in Columbus View. [#10945](https://github.com/CesiumGS/cesium/pull/10945) - Fixed a bug where `result` parameters were omitted from the TypeScript definitions. [#10864](https://github.com/CesiumGS/cesium/issues/10864) +- Fixed a bug where `quantizationBits` in `decodeDraco` above 16 render incorrect. [#10977](https://github.com/CesiumGS/cesium/issues/10977) ### 1.100 - 2022-12-01 diff --git a/packages/engine/Source/WorkersES6/decodeDraco.js b/packages/engine/Source/WorkersES6/decodeDraco.js index a4390e34b32..d8edecd3ac7 100644 --- a/packages/engine/Source/WorkersES6/decodeDraco.js +++ b/packages/engine/Source/WorkersES6/decodeDraco.js @@ -49,7 +49,10 @@ function decodeQuantizedDracoTypedArray( dracoAttribute, attributeData ); - } else { + } else if ( + quantization.quantizationBits > 8 && + quantization.quantizationBits <= 16 + ) { attributeData = new draco.DracoUInt16Array(); vertexArray = new Uint16Array(vertexArrayLength); dracoDecoder.GetAttributeUInt16ForAllPoints( @@ -57,6 +60,14 @@ function decodeQuantizedDracoTypedArray( dracoAttribute, attributeData ); + } else { + attributeData = new draco.DracoFloat32Array(); + vertexArray = new Float32Array(vertexArrayLength); + dracoDecoder.GetAttributeFloatForAllPoints( + dracoGeometry, + dracoAttribute, + attributeData + ); } for (let i = 0; i < vertexArrayLength; ++i) { From e70ffca6af31ac5abc2de63a26eb3603b6ddab21 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Tue, 27 Dec 2022 16:17:39 +0100 Subject: [PATCH 284/679] Replace image with the one that is required by GLB --- .../textured_box_separate/Cesium_Logo_Flat.png | Bin 5383 -> 0 bytes .../textured_box_separate/bricks.jpg | Bin 0 -> 20090 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/Cesium_Logo_Flat.png create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/bricks.jpg diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/Cesium_Logo_Flat.png b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/Cesium_Logo_Flat.png deleted file mode 100644 index 96c01d4d7f02dcbdb4c51b372d5245cee6e1d5c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5383 zcmV+i75M6jP)#by4mp1%-PP57 z&#%rozjNx;z3AAnW6&UF_JN{-hGGO7g*}zhFXyR81C;{1%+Kf|^%F`M zWB~@Gi2dVz1|ceJqBQ{!F}PK9xEdd;#;072Q6{tqCm<9UpiCRO)=s;}Gn+&;dX)jd z0BTkA<9T^s84-XX)H)Z>08|QnlEo1Y#U?X!H2@%DI8lqYp21Zc42^B`*5GVacZxv(o_pg~HNbMVF7Fwyyn4A;Ikol$45k8 zE0z;mNmN3Y9>U(RiC$O$cnK^yEY&Csu1cv>*`fo;LvZT=AR@N>nC#Ukf~!{;V;>z6 z!`VFw5dZ^qe;`*1&J6o zofcwP`v7*6*rfIWU~r~oUamtI$0}g7p(qGN1v>ESGh(GDhU*O&!Bbj{95z@duRu5>1vMVryj#m?xTK=eQWBPgh%b%B*A{0|Z_Y&s(=Fd>DWf0Lejsuuee^0TkD0g)T8%00aa( zOJkV%TvCTi@!tyV@@a~G9dQDJo#(LVuSSIZ=Dmlj+CrvURYx>`5UfA!6m%_bov0?~ z6hl}5Y(9;pHgSxsPNn(#DtSw-PTO{(R^RfXgkfW$pVXMAU5|#&)j``R`(OlHkJtQI zU<94x4R({DXso10DRXObBy${%!V?1+hNg*pvpnfo zjX-D{+;XYEqM|AvTqGBAgfmQx;HXpRZl^)GAdKK>6|`@7=>L1;54pTs89mg7$BR%t{DC<71>7)9JU!O$nooMw~E z5_T)Jq((hhT31x1cvM1I>~S#0KoXEe#yJjSj}%jaSu%*o=_RVyDQWJ&06?(2LKIO1 zJ05%*9h_mgwQr)`BsACw>6UEF>uS{~tMX`T_E-Juv|EauDj=n7O7DbGS#fdl6;-8l zJ1B~9>XfT-Q)v?bC=^OvBtqL>gtDvz!yN+>Gvf_>%9w1C<_&X9$o8$=TTxV{M0r3` z2^*RjcYFVYID^pi6^WuC2$WL)0C+SMp-w{vFf=o6_R!?OKXOfi;puT5m+mb4x!4`e z5d3bqV^AjxFBD_kBmlT^0I2Y?NSxuP3}*C82uk~xAmBXTe3@ehEHK)K!>pYbN)-r){i zrh4SM)HJIUC3G`4GcLDtTyXU$QS<{qg;(E_I3R$>^3qU1mlTkTpEukQ4UQ~fK(|6>vsrEC2Za>N1{dKx>34j`}-SqF7c{$vS^wzeBQJX4{*k(TBV0ZrM&mU zxmMJ^fYIY)()=B)#rpM zV=ySwGG_>HnH(zm@h@witf(mwg$s^FBTBqA<*{4d%kDIg^TCgHmF+y`5?doXPzbw! zL`wg3GiS_~J3d&s^$kLafCT_xj1j6`o8Eu^#Mgawgy({sUfu5AV>bzW?Vmb-c;~aM?dzY;c+bH}KbbHD3uBJ;^oFYFF9+e0)2`P3MhfgYD%{W)Z?`@OyA%iqhhl zf!!$FH87DgVBg7YpMCeHK{7Q>$C=uo8qv@KR6R}{DTLiUC@J2|bN#Qbn5$}D-XyB` z$wfD4q}h$Cc(eHE=(Lv9K1T5L_>Pil8;(JF*+dCl2X-@U~d(=)}?Kiy1PBsCzE{dQ22-6-%@)u(g$dx&18 zmgj;1fP{U+E}IeGH86>5q~HHz&nFlOfy}mc`}_agyOJ|tZmuIM!O#K#jO%6}lF4KJ z@2z>fxV*qm?neB%pfG)^fY5^R>3k!7ZN*$c2sD`z1!>uqmul;H%}H~IIcOwP1I8f5 zD&5*Qfiq_3;f>o5u0sg>1;9@tMrc?@I&)B>)sK;*a7Zgr& zqHCftH#060!N9B1dASam+h_aAr?W*N!~#hZ)zHw4G}$8E+Ly=Ab|3v_`++Y5bp4HG z{jR0o?aSv3xO;F?R-#dN=QFuye2)|pXUxLSA3a}vI$(A#HMj>IZp^eo5Tk^DKY?qc zRYiYZb#EX>+U!@zmX9_)@A6c0#{6zrvW}TC1Bf?^)BEs>xcg3gxBbvM0S9{2P822m zEx@DFIYX0WZVUCRpWYL)kzQV1d2-Q2PG-=-BtAJdO|N)tlJGMVc&xv;{Mc(N?+xm@ zB*D;tr{V?{XTUUABfY6-e6Lilk$&-5X;o498bJuTz0Rc@|G*iO8E?qzYSY3F1}b59 z4^A?18$;gAe=vAgVe#XFjF<&wq;`|QH`4tlf7lU>k@}Ty_I$eK=l|mjxV?Wu*RX@Z zv_A2D(|84+S3a3tT6r>PLM56R#|1F}iyVXxGKu)v>(lv0`s#{%bksfo$f9xCmY1FG za?Y6fBSOy%7=u)+G^u+B&Y15HtT|Y?!!PS^LSwR(=YjyhZa@K=uS(cmgObc#BYk`I zLns2hRT@>F{_A9wD9sJ98iXguhFB&t%Xk6T^`9v#c<1wnL%3}m17=0E|M z);oScx*sDwTX7;1nGph1=dD??{#nkLtOR3T7i+MwKp|{SZZiKk-=9{_Gf3tTem12f z+1AMq3rdvzXEXJw`NSSPBmLpv+R%(NaQXI^{B=7Qa|X=lpV%WMxL|Nw--I3x6Mt2e zJBvg6!IYAe4%herz$Q`A-t^5a2gzqUKiSnwgZmRV>Iks= zoH9tW$=B!DIb*gTTzjx^d&nV;FfGOA4*<&8wFx4ZjI%jIlKHy*(~5aUISwK(l#<^s zxtX(@Z;|nTjq4Z)E43Q@xc=iM`xbujcsMql5SMC{?EZ>z40W?LdsdSH+|ne9x06-L^L`x^u=&ssLAJW6N)Gf!|yU(}@ zVH6;GyMUN1kNac?>5EGY8=07hs~hGkOs z4w>=1?uvrqJsEV6yxIRxrIbAOzvHTE!)*eijAo|~o;B)a%7}j#1OQH_v;L0` zCLs{*Z{3%F?ChS_)jk01IreS-wuJ$N4G2X00Pu$oZ>bE^_17~6qKxT1vq`pwn^_~w z>-7dWdqMG@_trcCQE;3~z~buf-zh9TsLO2YcP%X{`&E}*(r!uWk~okx^;iYm9JO$} z-2vt9n(y^h_whY%OA1E9b01Ex^VWtr&)(zTF5U3odKI#IbQ<1V<*HeDT`rejU+Pg@ zkN;&Hf0wEi1fc~>ZVqRHlck5={Om!KL7!ZbP_1`HUUS)Evj8ZH!uLWYm4(kNnOaj< zfuig-mIzQq&Ds0k9(FFIU7(+iY+kTrO588lT2^qKhW8cGkfCm{APCm_BpPEIv@Ueap|wYw9Xx(Wozzri^xW^fJkDoQ6?9 zcg_{D{KwBGshWxaq1b;$3}cJ|yKwL8`p2Xrgd#?u70vVfo$DpU%c8Nr2(C`(GY6rz zp#6G!jS?udQ+>XxUnc2QAXy>@XMzBr+Knq znla*OPH$|xH0k}v^qG+qm+3!B1uz%skv1wmF11~)fs5H-9ou70%eMO`z1#L~WT|iLoj&}LWa~9Sq>4e6H5_qW`e%)$jJE5# zNy$je8GOynfyCZW0H~MShAl|#(79dLjm0Ee{$tE5!EQ_i4FDn9-FYvDf7+t$$*j>Y z$wJT@Q=#m)*-Xg~OnjF?yCeEH@0>B}sgChEA$&Fz02pHlmW;^*?^9GyyY^M0{ZS@tdnQL#C8uI=bJM zyTGT`g*-`EJr|6zoBBOGq}wFz>cfCil9k$L{`hwhw9*r`FM2@VjG@nt>UGQ220&I? z@A=~ws+up%d35MHQi=D*z7O0mV2wv>)mbfP&M5;P3CHhWEgeVr}fvW0?H?0D(mscmh;9Z^QJQu@rw zdr?68-={Gm0MtuqZNdAS9t9TL?G!5U&AjfJ-s$5a<<%kw07AGD&+FK|iR%84P1MV5vc`}JGp@=vD zm*VsOGvDOzcmvhbrD!IaRGmC{{;)37FcJYGzWvui0000+f|s~|D){oBhnD-4y2i)V zTD`QufR65U=ZNg-R%0@uTFZQI%K>mHSCB-*x;^jiJ^78>Ta6HEb%S7xnhe&S86&0* zd4f@BVFKOK09=aCD)E)qo?89W>&0b9B~fk_7*wJp+dEDj{76PZFIhCVO77A+093ix#tzTEwSzHLB}xm#*q8y}l546z`{(jj z6;=Flvh0^br*?RJE{sKtFh)3#)S3aKlu$+~C88i@rw`0YAKoQtfZ1R(%XWltRFz4h z3xEc!Nx-5YNVVRwQs;?k_xY;YQm3cfqtvLHmoSY`O(P0rR1_qP1W7O$M6)cKECzeB zJtM)ImSoN7U`k_*YDA+M002ovPDHLkV1mu3LJj}` diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/bricks.jpg b/Specs/Data/Cesium3DTiles/Tilesets/TilesetWithExternalResources/textured_box_separate/bricks.jpg new file mode 100644 index 0000000000000000000000000000000000000000..40c28065f31a5792edcfc737d11cda4fb730e47c GIT binary patch literal 20090 zcmbTecU)6l*DV@BR1ifFq=R(n(mQzo0Ric~OD9z6Qe#7uDor|}_uhL{r1##71PHyi zKuFHU=Y7xl?)~eY8-6jHB<#J{T62y$=9p`WoyIPM9w{p*DS&R>!U53$KOpQM0Ur6c z5L*yPNr?k=4+H|?fv9fbfo=gu%D|KQKgU|Y@v~dFf8WOij`@HS5CX48z>^<1CIw!B zlYsnyCve)o-}~>YqLQk{Q+^)4=RATS{^$J9#h(j_KNoq*&o9m=D9$HzbJbh7|Nh0z zKeztJF%EFWo2xAYPu%}p{SI(^=YJfN{g1o4h4b%u)`9Qf{O1_V5Bvf=?*0A2{?9qM zxlQ1T*g23K=-!<>ckkfcyL_wN%@k~}6NrKO^$qotyudCJVg_LPx} ziH7Ex2s_tvK0!f2dNwgBQGQ7t0YUzolib3`$0xi`Nb%qS1wR7~1ONZ^1N#F+eDCI- zaBne!aENc=65qo92GIleiFfPoel4^J;|pSQk#A3p_u4*BvmG$uAK z{(C}VQgT*yPHtX)L19rKApufJYQ-`9=jVY$~hGr}X&A79_J$JSy|i*x1hcPV zW9*_on<@H<1%0E$g1{Yy?{t;b)#b!>5Warr_QMmuu4^m!b}tBABJn3))9*t!SYag* zO&_liD1tDhp|e!c?PK7*RQQ)?&}MWZaQxVIjA5;CpO=6>azRuyOB*eT66|C3RU@B`csUBw)kv**QobP+*cE8wM zHT~D(u{3l)FW9oKE|`&HVFnA5sqDHI#CT~WkH>6@Iyrs(xo*{u43e09Gm|pqEIMOu zJ`%Ts1tB&C_R)n$rhV&=%8#z`jB8p+1}jU91(v+sI&4Ae+OfJdp4R1l`K@%p8?>uq zy!FCvYiC%HL-o0vk&%b5U*HvSs&7CLYjRWc{aVYewtY;kh#i^t3zs4#d2e*clG-L& zq1?w~EJ#^JVlKZ?9`aTUL%gXv&J3}r@s>=(f<}{G|I;Gt=YfuR9E%(|Bja#8Q>`t_ z@Sv8V$#*2*#irD+Q%D+1r26BoC;Dn%}R^i6Wu~>-XSW(f-tr6 z#lpLKwo<^5HW-VD2l9g&s&-h=yPL&>P%HEXc#h3VMvs9R0eejrqV$_E|P6$M>&xI-Z%4C~l|MjZ*=PURzQ`w2ZdUp1=&K+ZN3 z3v$AOPB=2~Oln>W_F+L#-Ww@Ap+= zh`suaafZ=fT&j1Ws8|kpzsX&=B2iVPop|jS`rdK~LfrXqNS!z8_XKrxSjbTQQSqf7 zRqrYO4_98;@6nJ$ocb$xPta#uhuvvlxozH`-h=_gicr3RDd}`WEQl&WOE*ewY+QI* za?mYuCHPKkgIbBrvx2rfAHU|}sEZVJ*cmWWIx_3!+ic=3$m=B_1YCc%$AZG>6)*3^ zkd^C5IGZ6UcOX%C9}W_X;kzjW-mu>}SWx=ui-(Y7BTiWpnxZ~qd$_j3rtD_4)4KE< z=&~*>l2h3UY9Vt2$1245?iWkYZTS zEv3xVZ9TNzO*|+v|IK(4o>*-Qe@&JpFtg`v;aJ4G@w0aYjRgj?Gbr}vA!fgH|4uvz7&}>N19glgvmt>VC z(5}z0n}tryl<4>v#r<*%3(C>1SUD0n#VEw6x7Y)V8r9G>g`#4m_%;szxNd|I={x0y zm>*(b!0IRBIc#K$e~2nS5{i2$&vuZNjW+b-9iM3EIwMOQ0)sKZhQDgc#74Nf^01(5 zg6aoiCnu~?v!^!KCczW=|1sH^9wQaUc+H+U^wxSIZCrBP5X)evgnKgu;{9T#!LGhq z)AP1qY~R#CjFV|57Umfmr;kgZBf0oRoZj?7|Vk9+eSnXp^k`z zxD@!L4{qx#r?D!blsFr5k=$!>{`*Xr#8kkIIpQ;Fjvro?(5rKe?Rs9tHz;`i3O}cV z8D;ZcPIhp*cj-tJ#Y@e2ZkWyCKoZ(srC`>Bv?Q)32q*f4j=6ZPXpQ?Yo=SO5UQocj z%2hjh*|RJ}f4Qrkp+ovBg@TiNq<@JVR-~VNcQfYhC2Q(IMsZzg^CIwRi(Cdpj-ztr z9KfUGhZvoOxH{6uan$N?m(`G0$+q07MD1t?n<__Vo+}S)7%vU9*08$p@$=&ER#X6V zT~`C~u}C{gLT^te?mEVKGhba!ghsFbY{)Hp^Cx(-9GGpg%%H~66X1)c&=Usj`wkFO zkv!{8<h-M8cm-*TyG*EtWU$A5D!bQpyj6YimJK zpmr<>=O%(bKj1WUwrw8yW1#O5FmFw?a$Z!L?QqN884Ef*1^jSS)0va!v(A<*kFwfq z)mdil{K9-fun+Gz;TtJc3FT4VrxOg(**~b^U!a~>6RN(HydaB@n->I8FA)0gko5jQ zOczouhd5Gps17&z8J;|oe)TE6wlrrhC4x!kpEppisH=@h>!oeuR(k^)`=*Rd7$*Qh zLVOpPW98&gy(9Dp)y6T@|AZc)wavMv=twNa3BS}+S6*ltvumoXdi&THb;N%c>Y*ka zdd1;7;XrD?Ira;a?o8AP`I$eHZ3^r|Yf;gXH;Qv7oACv|pH(Bpz-)#_)1erIRJKp+3V6@^fHx|@fp0J@+Dscd={I4Sz$`s3Pz;=p>Tm=A2$f5?z7VXmm#1DZ58E{PI z7+)#40Q5RoS1#mEsRQ)raS8_a#y!-RQISh+W>F_Bqer`}>Um(JKBQ==^V2HI9JAv3 z%L%KJrSxhjq8LNElS;Pa&dZ`_Qe4UWJA&>O3_xxG?CWap7rLB;L0Ft%DHWK5lAseE zqnu`U=BpgEkLY*b3XH7-zN2bB#p~kiT6w$KV`}Yg#c4rJgxTro zOD&~(_J!zL#RHhbq^8;MFA`YA2qzHIj41`^mqf%ijh@`4;wc0oFZ_f_ms-8aj>WPY z3wjHUF#kNdGWBBI$aN34{w;9~z05DZuh0ms&8E)gDI4 z&A4{2`NDl+{W|S`Y~zDO{V>6tw^F))ZVnv@_I&P{3FJc;IZL{u9v4Jr9mUGBllBUh0YF zvc~BqZsu(%^>|;aN_;R@sA2Y88bT9P7b_qm=!T(ifT!ts0kMLX?9i`juZXWm4GdW2 zusnCn`XT~@i{6}V1Y&$^&ptpIHyBfFL}E#I^xvS~4suK#62cD1vpDQGK$oWvyWXFfyyZt`~{X;*+r{~4Qx<^dZUQ^65h1H;;(FMkZh1~Sl z+(c6-9WDCAmHeH6UMwg9&O2Ut3%H{5{&h9R%QTS;r^MJJ|HkUlbh-G#b-}@p=~qalIlF8QfdY0b&hOSoOFu}+PNi7-S*ud2} zlmRgC@VX#Zzc0DF)NuDT){SSibM>hB&zbf`IFPHC`^d-F9L{R4VCBkhtUs^%36b>A zOH%dvYFqr&(s>wT=>f`Fd{xyEZ??3AIN`Qo5 zPET;)ANX1LqTM3O14WR;`Akj`os=;DoIIP$L0oM1r84i@JP`g#d=yjJYj|VPKe%J z%t(<)H_6!x^CrHJ7X+<&%1=jyMC{Msueqf{i8Dop?AA%b14AL+=#iMb+FGwUn|zqL z0PMG}Yuzjn>J1ju-C45j&N&0=cx;I|4@Wi>Xe#q+D-AS#YpO@{nXCV34ZjAgV^8r? z8z7?*l2}k~*9DLdDDe&mXkF3s!`IGlXi@e#3Ja2Yph4!Zwqk|xr^-y$y3o|XFt?c( z2CYS%IT!361GG1bsur(bWAl5uHJ#lO!k4~7cVPbEkNc+Zv*F}Mmb_L%$e>E{NLxvQ z{_D%y_Q((y@P4%B9Ad`@aCs}#ND+w;dn0E5h;&;0^1&1u7c~Z0=m+QzfY392d#$@k zhgUJyKjNEsv&2w`4BuiAWxU`JcoKTcD$6!rcV2t{lHbv>SmsSLmv?&C02_@io72no zP4!w6Q&xb3$E#sM)+7~fu@_^D%o4I?34VSNwa#_qpUM<_Is-Qx3+}B<(Vq>EC)JC4 zEyeJi3rtNd77$QFm_HDQBUz_TEzk0{nT6%a9nfeysScfROU?Ist};*R{=tIkhgLXR zO!{k7Rye-LEe#!0dcrq}mhz8^oBTfJnd7)&%2CPL(g9~fsFgB+#CP+b&-Gz!^XPv= z`NlCgsG!fUOF0j~)qtapsjqX22xa?u9oi6kLZND6<$ix0E2*`nk8a4Q5KE zXfh!6brXnGyUA?vz&tPzB4FywSWtwqnx=wVOum*9%Eu-ynWE<9?O{~WT$^c!$FW~% zfy>Ft^CnxO@>!}9hesWE66~2$2JS*7l!0`uB$;)#>WJ)FXTa!`&qTJq`Rm!(=M;mY zLlp%zE?x$Aua++Hi)U+|#BA~7mrKU*b;TJ=5-HopL#%~fN)}^5d~Gh0G2l-VJ^t%& zl6APthO+sVt}O=a4cWz63%lr>hOSQyt3~!x4oa!XJA;d^P~c1ALi5L{}4HB|QV z(D{~_1;JLK{Eq`eDN(6q(yk7_8Eb`XALKzYypI8zs7$0FKGKo}gm)RIGA{XF&eiQ6 zL&=NrGE1J})7znepQR^nxW0h#EGnvL-vSZEmF(9`&##-QU$*F4aLvqV8nEQ)g^rMA zt)f5Lhh0$XZd2_3358fT9TV&#`k2P`o*Ahxgwi;R$3WWB6-tj^%$gR4N@XLv`qd8! z1~iZLB7OkaDg?_P0+2%YHl^E(#R5;=xK_jBB9niTQ+p>HE$U&+!6+!oDQ?d|S zVdxY8F|RCe9S?XJe0eXY>T6y_i~RNxR6s8UY2WdagTO4<9YkikgH*3TV*H@uRtD;k z`nX#hDyz?D3>mg0ht@fCjMUbv3MrM@rQz8O)$5yJ`n6XLxVsN7pd4P+&JA*#ur(!j zk2gypM}>fcFC7M%7fMwjRsZsj!J_rjSwK1fpy>xVO?!akLL>9AZw*E6+ATb(c#Q?E zb5IP<=+ioM4AfN58TzU;OWVDX7wR6f}Iiyss@O8Vv4y097 z`$6%gdy?SXsTsT(aVVHzq`H$pc-S82^m-4-P1Gxgtny96f~Nrh8_ zKrlhhXuem|-C+t)CHX(lC%)E;KMk&*qwjB>?xHk*mimSx)mwzG%}Dz0m29lRtQX|$ zdMN?05K>-ms*Ip(-5#E(6P|Xv+ulB^WJ4(tslGP;lVW7Kxdp-rzBee9JhZ{Cy7;U} zsVGKu$x72A)Rb{)5Z0^NoE8iZn=KYf`$Er?-He&8C|otah&GPKOhWgI25?f>93jKW z8t&_pvu#VOW|N9&Ra+#}+D+^iQNX>jBuow5gD$heN&$4x(%g)?zOC&kzfkfI_-~NV z#<24N$_9#W7m`!Ruz!F_R~Z{|9+Ml#YXRu+#Gb^;A z&GqdkY#CJF-ANF=nWYJyiJ-19oSJdM{UtZ(a4&a%-SjFBRawH{3N=UG+@= z9kdcXa3k#*d7sYRyqlmVS`GO5JE(vT{L3pKoF-%mTu#PK9;xJQUXe4S(yq6~%Sa<=nO{<4`?YPue@rY6E z?>wt|Gpz4W-a3a46DF>i6e;+~pZL2@>|^XT_nC zgYIjAa9%A;R*Z26JE13D37QnnE9?zqa&>jEel!W?^i0lXcR0cQu zENSx2OkQdb<-1zwIrGo*U3jnWjfR~s^=qq4 z=e5A)_-ocW8O1=Q4gEF6!+L90tfT_R|RF zp{+M0>8+5ExF4C^u3r_V9t&bnQsYa70`xYUkE-Q1U6AYb?a}R=2&JJi@V9~*AT|7& z13uurzC9Ur@%hn>+4Gm=^FP)vbr+;nr#}ItH`$_x?&~!rU1;q~AiFCAU(!B9tFN1? z|0z#c54Ys>yBu8Kegy>id9d$1VZg770cQsh62;u7NW47uwwCUMcya_qDCV{(&iu{hF zDao{zRRH<`8d?>zqWAhf=0lC^y02##Sm3(^z^&dB^wB(W$T`(xjdRKMDxInI&oWo? zXX<*Wfw=2_N#tixl3zKtPuLeRClO`tTB_TS%n0BcfCLIDhg7Dwz#q;=QdnHQl~5?a zF%XQ1$VRhAZ#@>wc--{|Lxwl%>qFQ$$T##yRYFnWRf3fKU=uXj0YA5)riov8McC?{ z!~~(6eu)}aIe3}Ae}d*v*)K<2iCu|zTlVy#qZGI`C@QohW1nKB#DPZMdGpxnq`+Bi z`xCwS+KV=D13P#@WE)jQ4ZA=ETtPV+U#HaconiI?K+dGffBR2UfIpODWMl#FbLKi> z`Q9-qnF+1lqD#L=-gm-ZZA1=els1r$_4`1u*YK@-eRv1DY+K^+D#9i|am+I4_Ab_{DQ^hP|^l|cm?O+4IH26AxO>>aSSIm)kHpzo*ixdg?2o#{Mbi@Iq{Tk+x4(rzOqns)Jv2-JxmT4!{ z)b?j86A|@K*4b);r65Mqg4`N@DDz9QS8WX6pXP#2qPEG4!-R zS;X6deJGk;p--*N_UUHw)cE0bd_M8g0ALQmR)r`>W6i)>z0|vZwFJ_HUjr=YmuM`A zu`KOO5g{p10dZM@VQ;z~f)8T7kc13TNiKDRbzS zvH+}fX3@md*rcSqA)w{;!_&wI4iKW%uWOvmE{g(DMp0J^k9%r*PLGK$wBu8?oitk5 zSni!Y+59@n)v)Y(W1#P7LPy5SZZ|pSjZafUDTmw)i^nykhBp>R;okP!A>Nf@05seL z?p_qdm3*L}2^dVw1p%}JfO6(4%Id%FC!oVAr)Hxf(P=ZEZAaPVq49N>Z{Rz0 zw=fSwR!HofTGO@^?SkyN5=u&e!MC?}U)B1{xCd*e`@@t~RX_f;?M)%wze(Rqo%qBN zODOHQQbzXnvAPYhhRcr#rl?UtB z(>Z}>wtD%HAusvfb9o%~G+a7cXgWMdlQnNg5m<93DR8W=bgC3mDVnDi-t_^m>8@f6Lo|ACZMj{S}RPs(c(C`gsDr zIT|S>`X&&1@>rjDB}wjjZnb}k!ktrJjgOXE(@;VG+zh@bL~Xdadn}w?FQxdcGv9zA zO1|y6I+Fe9_=v1)U|*l2mbJT3=-IRFvFts4yD{)*dbDrhWu**WMzD9+@iLIn*(^`4 z9vTS+!)Dozx|gE9r5^9TFz2^tqqh@nuD>|p-^C|qkAkjgZLx`e%JGLXXv@%MG?;Uk z?oK;1N$QXzMMmlKk4SS$iIOxDgq)j#a?^x9biAR?oV#|Ea3#ym_pk%Z6$DiLkF|M& z$%$4}Rv~fkHoeu|&J{3X$n~>=u+5?%gLD5q3l&fJAxov}<>pQ7bm3G|o*eE?6>F^Z z2P7kpqE~@Hhy)5^w$qjWqJDkhkQLd^R~A^((@x_7i}bq=kz%E*V`bp4R(rhVTO zN&TGn!npP5b49KXp zyMdrYw5_*K+GS%|@_ebK8}0av&2GbU!Z8`hn3!r!2H{ah1#IoFe*5c&sh@6R{B=l( z7O4^r0{WtElBLY--=iJwq5Nu#0;dIPQEy>E-0*{^&{FXp^=a38yVa;k+XrTm1nXv4 zP%Vse$8pKHwGQS=eM${aEU9wTwES9Q?7`J$zKDc?J9IxiFasNvgB|jOuXV#da9hpdw)MV z>=tX+kr86c_i(5V&xi@sU$?$xWCWC3U;OK?e1?cp^EUd8v!w&xb#_HtUG+%tl!AVx z`N?lUQY;qHn5~^pDLVt?tMArl1t%Q~1;3@?-Qxm;y@dvVjD(<%(;A`GxX#*&XLh zU_q;FB0;drd->DoI`Y!ZYE*JAT22gl%a3>1Vx$((J9)663!q#Up#&wYI}?81+iV)p zAO0~?rbtyXVgfFs&-2q+K;7K~CV(2>w6n||8lbbSzoyiBN|-Gqb#UK%8Ss9M-+Ub7 zQ>ZKJB$`8Xu;Mf-1==?ONH2m0V?&pCN0%sQ|KuB??0jffF0#A_J)mXm`|=M|Q)kRg zPar&|Py&br?wgb~SA>LEPzlECHs4ED?fR)!1315&qjlq~Vp8`T`zYdQ)d!_`q08=G_04Zwt(VG2FmH9szb`Y}3fO+J zy?fl#LEC?t)3>SmRvR0v%KP1pg z0Q!gOiu>K62eN|o3h;^z+aGi=SXTD3#y}FN>29#5l)m2LQB(teE0mOmuDB7k?E@(R z{OF(^W3iMi5H!Mj4n%)_vPDz6Z8kPw|G;q3hm%qX2puiSA;L+d2VhfbeT7S#M24&7b)(-BU40M2K3jTUKd;~zV zQAEwxIGYrDz>lZ`N;?e9MjsXO*i9Q3q^okOPV+hvXTrQy2-@St+Ld_%^b z7|DLxHU!#H)O4`_7O)Sicb3&gwI>fzJ7cBKbfxFyi2^8%iqrI%D|8ojoWBS;k2QO_ z{X~)GMnQ3(Rd>!^Op0|0XmKY3#BaO7=|;qkR$Eih=OB*LKL7-)C4;wtGOCVJaecnH zS=ufTUN>ZOCGwnwAc|8bHZP<0^-8wns6N2~rQU4bB~5V(Ft3!W=rh~X*jeQXoN%^ef zgpgiO*zxB2Jpf&+_c}7bWaWM`l6Q8aAwkWZA=fy8Bu#-^ZC#h6V?@b3UqOdl*Z?Tz z6QRQ=q;naSEM9k~kfLBb9+8TE132Yo&~5?sn?Q3(W`i#RmCMQ%Of}kHK*a%j;z|RH z&Ex~Q+Lq8n%kT6C*=hk1~}CnjgLiFJfT{q~B0W@R&CmWO2Tj0|siC zM3!l-BQFdH5=Y3>0(2iCvZou^^HS9IEN_Njd<)nZHSG_`IIO%~^yd>=1NJ5<9(kGX zy-&M)q^`F`#0rXP%|0jEd9khcHT~>3jsi%-E-`$?kqCVsFlZqc%;hX~7IV$9apN(; z8EKO#PH&rBAO;oDbOn0cUKcClfidS*E-7G$nvNOW_ZeS7+1d1hT-1IG7 zFTR@)-pC?1TY{hhS$P#^#mDSa^Q|o@YBkjcYWPd(smJ@LB?3mX`-|_P&CQqEA04=} zIC9xLz~Jt{$ZCI~S%uLz9%#;uz+xVYIz4mc1XYT0#xD4gkYsZ3Z*r{?*Y{l(nOxwcsk|9mCeh~iTIK3;t}x4YS}}h;iY*K<}jvJLT|D}4jUI;%gu#B{Ue@*aEQ^{ znvExI_+@=3G)=nOgkJ!x!!bY1pRetx z5k9DPwqEGGwLPHOM|W!LR@Xa>*muQvvX<=VAlRNA&lF?AYaI*bTY4yC*N_(gz=?Gq zPb0@rS~IYd95ghZ-}SUqelD`LtA}D@#8`d2(L!R*U`dH`w!QCXr+@OhE&UMYfvM|g z3>nM+R!|F9LRhm(URhA8sVQFtDSR&IADL~2CGHPxY8XDhvIY{SqK>h4#&(*Bh?MG| z`|?FIVY#y?$usGARWoZ@Wx?cn5B^o68eu7TygfuE#ke{$1)Nl1{Hi6bPw~m0?FOQ4 z{gW%DUFUMi)w#5^pL>DNl#V~;)4z^C9quTe3c;}aCyOb1CzQ|6oNV(2B22UheFzP$ z%qxe=<+a4Dxi+TX>nfYF#oo|N z?y9}|2Ha~HQsb5!|AN_}r`@W_AC;wJmyh$|Nhh`2w7 z1(6gJT>+c%GWEQDOZ6O~J99)*B1DTmOz_(0!b#Cru=4&1Rp-J-X^rveJM{%yvJVt= z3_QX;ny3AB?rfITTxICnQ%fLQ^~MvZ;xbMF8PI@VaBff(C4idnkoNv^=BA@lS{AHn zM52TPIm59J==X(n0u{1My)rnWvmG-F6(6KBS*&UfJ-((Cd^|%r<@|kYNE#wl6bIW@ zRkF|CeMy81ThsD=QW`UrLOs^YTKqQJh9J%R*sAm;W~l9EW5QsO?)Xcq3IOqrrI823 ziv{a(XYyJ;aj?@$+e4@y#B*)n1R8ZDXqKuTbv&$@UrAnx0e6ojbe$6uEyDqT_lR9j zca&2!WUg<%$FDG?u5EY>Ep?iVjBPMpB%=h<^wF^EWnJ?fEQnc~DsY(c2oC6~Lav(c zcTct{)=bMJ`+?$RNlWr*I$Nw#1rSDkfeF+$=*YZs; zrjC@X^4C@0nH$JJNkUt|ov>o`CBSNL_CIUHXYGZs4QM{=%f7x(%uHs~xqi`+d|~^9vTFsk%*O{fe6)Mk_EZ#_EcZ4tyhN>fX{vMy!lxkq{E6 zgO_#Fl0%DiHz1#VwCcSfj=opQ$R!kkOE5s}6T!>oKpjlHG@|48pG?(u_)~AX+B+~i z563{7Av$4X!wF+uHBu}Nv18QMl(h4Fx>y;1bX}^={Fs2ow=50PLV~4)cx9WY=V*_L3 z+!bP<*daQ@6QQ)H*PDeW`xls-T@D4gz#b9R2Y_}jFJ!DgcFMi^!&iHclAiapAb729 z{=QjYK)beqRSzICq6h4r^%LXg>&(y#MF(wLzk5vTDM%@irsCK3g+)hxk+&fdD|s2ai=b| z3>3D#Kb6y*p9!uVUjNp1oNflZq7XatZ?DK*JiI%2w}Ez%J3zn4Jp$tU1o-#_WJHe$ zi7CjaC@IJ&$f@br7^rDkXvrxUc^Fxqv2${9Qa$Ar;N{?FZ=VS8iUV|6+y=TWDF4%G@qa!7 z+IE0066}8(79Qa~0y;pw9;Zr*O+*fwsrFATW9+?)c;O!Q>I^h8B6G)q~UPmkjSy!Jp@TkC&fPhUt80kA@U-Pd%to z)RXcf7RK{s z($ZmRN6SC!4moAzyN$gF9-Nc>va=0k;=aBcioq^UHamJhj?AhBEr@6?vc!AfegZL%9teL;sRD_N=Y?*&RW zO3TM2_=PRO1mY^UnC@LMEnVW0wAhY9Go<^RduKSeFEy2`uDBGa4F>Lji#8pEL*8g> z)J$83kXZXty#7$<_RY|Z7kQe$JZo9oLV1UwG*Iy}*4#*RlZ6gf&gaPpDec3pLPEj} zX7)3p5+Vk1Iea0D8m;qK(MB2OOlI~WGSYMMm%)w((NmkZ>9U@Gp0lR3PO$pYNH}Ax zW+F8aY8mI$z9n;{uUoMjOMrrN`JvOq;5Um3xEau9^=~KEzsm}&Dgy~0Kkj1z8Cga- zCb##07Zqq~0^fptiEpajB~6{7D2YBKnaF0&R@EpsdwFCX2rHXq+gLP|tz~-|t{0%;+Il(2QiFWHJb-ndl*udijdRv_ZTB)QbS5}V7Y)!P=KWTbqi0qE3d!;*i zzV_Bp2R3E7Y36;}vs~}?XF^aJJr{8|06vO#6$K}8jdWTn)mw|k9L6q?=nJxDv&yhJ zsiV7oC-?GEhMls?*$Os8B9&?aqgOkav&6Vb)yDMP(A2sg;eP+SGzk`L^0Y`L6HJa_g-yY zF|DvLBVK&}{%OzJm!Geh7k$PSD)usxx%<#+A|tk!TtIw*R!qyA+qAVua7D#4@M}TO z9K%i!-&U>Nbh4JU@u?{uSAr2^>aR<-UOfb{a^JM=2QCDo3t;>i%>nHl$z zg>;)F-RoG$eA}a_Y)IY6(3C{(Zf$DzfK%4`SYec@nF+yyU~?$(jmhIuni)NFFs%yE z6%&(}Q`t~q{Om4DIfcqrz}rwm9Jz;N zUJA3^yfysw1#r6imLI0%eq0m0P-Y;beeyH&7k4!8h}w>9_a8EWEELJlp3F=?;%vES zKlYiDNMg<591VBNcD@q^3&Nn_4P`ZznrQtK=WB|_EOt7Lj&1ZvW=lek(z8MfGNS44 z@^N6MPr}A0jE|PxEmvlG!Z_oZ=w%H_X@G{JkuWO35XKX(?&VPqani)f9^2u8FT-7o z=9&B#EM(uW3FL2&MgJHKMhlwb#%9G#3+l`arw!0V-Z4L6)acqU3w5%O(=$F{C#8v4 zwv!dK4~haNoa0}#$G!b;v+4~r+yDcgjHcUr62_nWAEGNCS-9g`9{vaN?|^YoETeOE z9~bULQrP>4C{IR#M|ko!jJ0rPNOB$B^>ZU970Q`t3G}seh6A?dEDJme;l_-{Rr+W}tBE{02Niy$+RqT9Rn^0xuT`z;pkg6rmNke>rXKVD^n*C6n#;AMX##QvS@98#Hpj7JGxrOTS%lE1l(_?)Ew3^-mEblM5`)hfi8_ToMbgMjgpZRkn`p@B`|1u3QgTfA!aDx43qma)| zhw^wIN<@xUj$ZB1LM^|MWDm66|6{0$x5=L;c1KS2549LQv)fv2&llqIs&gy7MCffl z1HD0tjavGw*D`Y2aHW6Bj#e)|2}e>Vr+my#D&CFDGP)D=^7Rkh6;qsCfy3vwW_KlF zjTV|8)mD$eY?*yhv|mfymiq}&?sAJ8y>|`PV8*nxZ8oFgmKU}z1P>ls@XGu?rDY`g zfD(zLGUuF6qNEt`^syX%Y_}ZxE=0RBo{OveQ^~fP(9C;~qIfTr5RM`4ry-1ue8KfF zfhhIj(cIjF+&l!(b^!U>C%^XR!TLBfs#- zh-N5f)w!*=7Y6^Nh4M6=*ezLzx5P!fp0NN?;~hG1c-ed9mt7q}mCCX~_2&T#OTDe# zt|b%Y;MDVqTk32;zU2Sih-{pOBts@%um9=vmaE-kO8F@GQ{mwfM1|=T zdF^w0o-j_89fS4R8y%9p74bCcO15;xeG+r>L)mqb7x!4GXR)A9^=5XE81BL={```E zm`@HZhD`)_(uqD3Wwh7x|4t*nmuB&yJjurSF74PRn&o|hIz(sed)+>#va836i^tWw z@*fX+mN7p>K0d6Ui2p{e`$na|v%7gDvGgH@KbzvVoI=;bG-T5zxp_-}MzW5#rMdy( z@}j7)q#4^tKySuX&+nHB68ATLWp7*aljA~HH@7iKxpP0l?sYU%$tHUHvWC3<+L*8G z%1wIvj}*(VwEJ~z_om9UH_|O4SkKSGC^%h?mT4FQA5YDE{$!Sa&v7T%ftOc+)Mfie z80+aD!4D{xSH@*NY>U2jb(?pjPZOLtkAk`KBGhbvexoDaG=X)TRNP9zRM#@fje{gH zZ;}Q|t5&gSSd(}-JDW)q)b&x`Mu&iBi9Jzy~GsY&%@WZZJ+=_~m6vBn^)nNI z41b%||NbWnkM3lgNk=6=k$q|``+B?l)gw)yvc^OC77^oHjucp14d1El`yHRkN1ZFi z5g6Qgsc)0h7;0@^*dZ|2teYbra#pUtw_qhZ3bYo~E!-C@cW#lxcYlhAXNSZEKQ5bpKh7&0lYf+3s*NB`q57`-HUNOiCzNXfW#jy zL{{{zV}(hFX9UmnXj6ar-a*^Ic%od5%eVp zd7CpDu*g4JA@xN_O%hruYB2T?7ikSqdVBGscar+}cjm|Zs(v9`_4aPWECM0vFHWmI zF_WhFt=19Kbr2Ai5l#rN(BRec0(PXS^+0Ne3cOBWU(USwDsOd<3KEpBNAaf$$G7kq zdl7ssob&nmPs8)E)%(Fyokjz9BQn^{%sN8}4dNn6fx^D~Mw!G@bsP+Y@N2???UO3e zMXSUoo7}fLqZoi)@0|n}+h-n*;z=;G>3SbJ^)Un|QCF2Ip*tdo$w}2PI#|1Wk>#yQ zdsPse;(hL)9fHWk_K-2^^7ihCHLK2k^RDXRai;rEw)XRxF54?)5%`>PJ0MQ|D_eXyvut;!HI9CBF< z@X?H=N&jd?MmgbW%yr}OVEAy}e_UNPQ0w#(U_;G_)k&#e>`J$*jfq((2>&$A)yyBX zl&8Mc$-x%R?P4!rmkY;;XYc682fl1RdH3=D z>@+^FNN`$6GADYPvE*YbCM^}M_h4@>4xY;LtfOM3TQ4ie45M}4O=!;aNS$IIP-~EDXXR>tVs2o{=oIb=wlFs1M=SOKm)#2>QHI%_D z;>yTlN03-^<0#k5mssujI*S+gwj2IWC8o-={{UwdZ6|IeOty$h?)eKsmrPikoy>H* z^#WsW4`r{!G#s(Z@bWTrnE1!1uq`cRw!~nq-`W4f03;Cs00IF70s{a80RR9100001 z01+WEK~aHm!4P4wq0#V>|Jncu0RjO5KM?o8E}f#P>R2`R8y+X7WY^q8Z5lAyf;>PAJO2Q2{U_z{3vqdXW}eVv+yhzKZth|))csY`yO6FmHCxpzS zvTX2A(jcEPSV3LB1r?2%g6Zxj!9~P)yVUnZzlocs~l-;gkvGD+N<{Ao`Jw+`U zv+4+GG!=sk+H$i@DSnu+5iXv0RRC% z5E5_(VRED(CU9o$>ML?^7WkU&9c%~!#8*Ela}j2a2xSOi1ip&?W+5hJnw z5JZ?ppO8eAfKhLuB0w!14S7YAxRtORfqxXhnhG+IJ0VCGSp5$$$0s1ehh)KEHHqgC z1!mSCxsT%g5Qo6z`rsGd86*)$LHtuTf}kOMwri#m+!pk4jZCiF`V+QYZTwMlnU#*D z)9v~o&)?{bKg*0@sage!;SK)BXR4xAO{5BNc_2vzQ$yV?r$W`dc`74tF5eYP8)gBh zfQ3uKx8au4Sc-UyP*Tck#Auzk0J}K;&{3$cy0`%-L>o%+P#_)XTj=b}YOdTIy$D_n ziugFGopGxU7)$&mOk0&%!QqW_kp*w!fB@oa7VQq;RMpu30FFa>o2_;)%0dQK1zsFN zA(Egw9RC1FR!S*RNCB4kooE={1{BrAIGHsGK@%4E)iEL5iVC|+I5k&Sh<=?LHg@S8J0MV{q= z$H2LM$ye`why(mtO1@xKFeP2XcX)(UEeB{{VbvR79;JlB{{Y1?hz5cabVA9hn(j$h zh|+AwFX0u~U3P@3c~M-ti==?Cbzp2nCpWCY`6GRFrP0w7y-;0ycM!s&EpUW>f~s9` z{?QRqxvPkhQOtPwVp5T{ZZ*$u_NnD{)f7L9rwcYyC^~ zC_q)bF>hFcAx_d;n1#IF>foMPh#`(0{-j~pQ*Ysa^uQ`Dm+8?67HPXy-u+Ji9f$Ex5)d6j2u(C6sg98c z_>WLDix!0U5ZU1V=4VA%H?-Hu*?uaHvZ#!VdO=hGDNxL~LX0n{xY$CdPGAtv8Su(B zrzl=tr5J`JydAK6WtJbbZIo8VszyT0@_@SSO11pN2b1`SHH6!>{7gp4V&L^Z|JiL= Beb4{^ literal 0 HcmV?d00001 From 2cfad661b6ac15e704d3aaf4eaf6a867dfe36307 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Tue, 27 Dec 2022 16:34:19 +0100 Subject: [PATCH 285/679] Update colors to be 4D, as defined in the schema --- .../engine/Specs/Scene/Cesium3DTilesetSpec.js | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 7d7f892096c..71916cfecf1 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -3,6 +3,7 @@ import { Camera, Cartesian2, Cartesian3, + Cartesian4, Cartographic, Cesium3DTile, Cesium3DTileColorBlendMode, @@ -6399,27 +6400,27 @@ describe( ).then(function (tileset) { const expected = { "parent.b3dm": { - color: new Cartesian3(0.5, 0.0, 1.0), + color: new Cartesian4(0.5, 0.0, 1.0, 1.0), population: 530, areaPercentage: 100, }, "ll.b3dm": { - color: new Cartesian3(1.0, 1.0, 0.0), + color: new Cartesian4(1.0, 1.0, 0.0, 1.0), population: 50, areaPercentage: 25, }, "lr.b3dm": { - color: new Cartesian3(1.0, 0.0, 0.5), + color: new Cartesian4(1.0, 0.0, 0.5, 1.0), population: 230, areaPercentage: 25, }, "ur.b3dm": { - color: new Cartesian3(1.0, 0.5, 0.0), + color: new Cartesian4(1.0, 0.5, 0.0, 1.0), population: 150, areaPercentage: 25, }, "ul.b3dm": { - color: new Cartesian3(1.0, 0.0, 0.0), + color: new Cartesian4(1.0, 0.0, 0.0, 1.0), population: 100, areaPercentage: 25, }, @@ -6892,27 +6893,27 @@ describe( ).then(function (tileset) { const expected = { "parent.b3dm": { - color: new Cartesian3(0.5, 0.0, 1.0), + color: new Cartesian4(0.5, 0.0, 1.0, 1.0), population: 530, areaPercentage: 100, }, "ll.b3dm": { - color: new Cartesian3(1.0, 1.0, 0.0), + color: new Cartesian4(1.0, 1.0, 0.0, 1.0), population: 50, areaPercentage: 25, }, "lr.b3dm": { - color: new Cartesian3(1.0, 0.0, 0.5), + color: new Cartesian4(1.0, 0.0, 0.5, 1.0), population: 230, areaPercentage: 25, }, "ur.b3dm": { - color: new Cartesian3(1.0, 0.5, 0.0), + color: new Cartesian4(1.0, 0.5, 0.0, 1.0), population: 150, areaPercentage: 25, }, "ul.b3dm": { - color: new Cartesian3(1.0, 0.0, 0.0), + color: new Cartesian4(1.0, 0.0, 0.0, 1.0), population: 100, areaPercentage: 25, }, From ffc6235b6f180b48c98dc00dd187d28ea34f18ba Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sun, 25 Dec 2022 17:10:43 -0500 Subject: [PATCH 286/679] Fix artifacts when shape is infinitely thin --- packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 824cdbb559d..2569c87b169 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -51,7 +51,7 @@ void main() SampleData sampleDatas[SAMPLE_COUNT]; traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - // TODO: + // TODO: // - jitter doesn't affect the first traversal? // - jitter is always > 0? // - jitter is only applied at one step? @@ -71,7 +71,7 @@ void main() for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) { // Read properties from the megatexture based on the traversal state Properties properties = accumulatePropertiesFromMegatexture(sampleDatas); - + // Prepare the custom shader inputs copyPropertiesToMetadata(properties, fragmentInput.metadata); fragmentInput.voxel.positionUv = positionUv; @@ -99,6 +99,11 @@ void main() break; } + if (traversalData.stepT == 0.0) { + // Shape is infinitely thin, no need to traverse further + break; + } + // Keep raymarching currT += traversalData.stepT; positionUv += traversalData.stepT * viewDirUv; From 1a792eaa57de7a2b5de3388d1e801c9eaa1dc34b Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 27 Dec 2022 11:54:14 -0500 Subject: [PATCH 287/679] Fix intersection bug when camera is front of first intersection --- .../Shaders/Voxels/IntersectionUtils.glsl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index d7ab5cde8c9..2ce4010dddb 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -69,7 +69,7 @@ void initializeIntersections(inout Intersections ix) { // The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot // loop with non-constant condition, so it has to break early instead if (i >= n) { break; } - + vec2 intersect0 = ix.intersections[i + 0]; vec2 intersect1 = ix.intersections[i + 1]; @@ -84,7 +84,7 @@ void initializeIntersections(inout Intersections ix) { float bmax = tmin == t0 ? b1 : b0; ix.intersections[i + 0] = vec2(tmin, bmin); - ix.intersections[i + 1] = vec2(tmax, bmax); + ix.intersections[i + 1] = vec2(tmax, bmax); } } @@ -100,6 +100,11 @@ vec2 nextIntersection(inout Intersections ix) { vec2 entryExitT = vec2(NO_HIT); const int passCount = INTERSECTION_COUNT * 2; + + if (ix.index == passCount) { + return entryExitT; + } + for (int i = 0; i < passCount; ++i) { // The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot // loop with non-constant condition, so it has to continue instead. @@ -107,6 +112,8 @@ vec2 nextIntersection(inout Intersections ix) { continue; } + ix.index = i + 1; + vec2 intersect = ix.intersections[i]; float t = intersect.x; bool currShapeIsPositive = intersect.y < 2.0; @@ -114,12 +121,12 @@ vec2 nextIntersection(inout Intersections ix) { ix.surroundCount += enter ? +1 : -1; ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; - + // entering positive or exiting negative if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { entryExitT.x = t; } - + // exiting positive or entering negative after being inside positive // TODO: Can this be simplified? bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; @@ -131,9 +138,6 @@ vec2 nextIntersection(inout Intersections ix) { if (exitPositive) { // After exiting positive shape there is nothing left to intersect, so jump to the end index. ix.index = passCount; - } else { - // There could be more intersections against the positive shape in the future. - ix.index = i + 1; } break; } From 2c81ec6faef4ca0ef79a96d18b12e73e9eeb6cd1 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 27 Dec 2022 11:55:59 -0500 Subject: [PATCH 288/679] Fix whitespace and newlines --- .../Source/Shaders/Voxels/IntersectBox.glsl | 6 +-- .../Voxels/IntersectClippingPlanes.glsl | 2 +- .../Shaders/Voxels/IntersectCylinder.glsl | 50 +++++++++--------- .../Shaders/Voxels/IntersectEllipsoid.glsl | 52 +++++++++---------- .../Source/Shaders/Voxels/Intersection.glsl | 2 +- .../Source/Shaders/Voxels/Megatexture.glsl | 4 +- .../engine/Source/Shaders/Voxels/Octree.glsl | 4 +- .../Shaders/Voxels/convertUvToCylinder.glsl | 6 +-- .../Shaders/Voxels/convertUvToEllipsoid.glsl | 4 +- 9 files changed, 65 insertions(+), 65 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 4ad129993c9..08018e1daff 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -22,7 +22,7 @@ vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] { vec3 o = ray.pos; vec3 d = ray.dir; - + vec3 dInv = 1.0 / d; vec3 od = -o * dInv; vec3 t0 = od - dInv; @@ -31,7 +31,7 @@ vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] vec3 m1 = max(t0, t1); float tMin = max(max(m0.x, m0.y), m0.z); float tMax = min(min(m1.x, m1.y), m1.z); - + if (tMin >= tMax) { return vec2(NO_HIT); } @@ -70,7 +70,7 @@ void intersectShape(Ray ray, inout Intersections ix) #endif #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. + // Direction is scaled as well to be in sync with position. ray.pos = ray.pos * 2.0 - 1.0; ray.dir = ray.dir * 2.0; vec2 entryExit = intersectUnitCube(ray); diff --git a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl index 2e7d06ecd13..f49eba33cae 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl @@ -68,4 +68,4 @@ void intersectClippingPlanes(Ray ray, inout Intersections ix) { #endif } -// export { intersectClippingPlanes }; \ No newline at end of file +// export { intersectClippingPlanes }; diff --git a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl index bcb70498ef1..faf3e87aac4 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl @@ -24,7 +24,7 @@ #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN -#define CYLINDER_INTERSECTION_INDEX_ANGLE +#define CYLINDER_INTERSECTION_INDEX_ANGLE */ // Cylinder uniforms @@ -52,16 +52,16 @@ vec4 intersectHalfPlane(Ray ray, float angle) { vec2 p = o + t * d; bool outside = dot(p, planeDirection) < 0.0; if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - + return vec4(-INF_HIT, t, t, +INF_HIT); } vec2 intersectHalfSpace(Ray ray, float angle) -{ +{ vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; vec2 n = vec2(sin(angle), -cos(angle)); - + float a = dot(o, n); float b = dot(d, n); float t = -a / b; @@ -72,17 +72,17 @@ vec2 intersectHalfSpace(Ray ray, float angle) } vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) -{ +{ vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); - + float a1 = dot(o, n1); float a2 = dot(o, n2); float b1 = dot(d, n1); float b2 = dot(d, n2); - + float t1 = -a1 / b1; float t2 = -a2 / b2; float s1 = sign(a1); @@ -91,13 +91,13 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) float tmin = min(t1, t2); float tmax = max(t1, t2); float smin = tmin == t1 ? s1 : s2; - float smax = tmin == t1 ? s2 : s1; + float smax = tmin == t1 ? s2 : s1; bool e = tmin >= 0.0; bool f = tmax >= 0.0; bool g = smin >= 0.0; bool h = smax >= 0.0; - + if (e != g && f == h) return vec2(tmin, tmax); else if (e == g && f == h) return vec2(-INF_HIT, tmin); else if (e != g && f != h) return vec2(tmax, +INF_HIT); @@ -105,7 +105,7 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) } vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) -{ +{ vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); return vec4(planeIntersectMin, planeIntersectMax); @@ -115,44 +115,44 @@ vec2 intersectUnitCylinder(Ray ray) { vec3 o = ray.pos; vec3 d = ray.dir; - + float a = dot(d.xy, d.xy); float b = dot(o.xy, d.xy); float c = dot(o.xy, o.xy) - 1.0; float det = b * b - a * c; - + if (det < 0.0) { return vec2(NO_HIT); } - + det = sqrt(det); float ta = (-b - det) / a; float tb = (-b + det) / a; float t1 = min(ta, tb); float t2 = max(ta, tb); - + float z1 = o.z + t1 * d.z; float z2 = o.z + t2 * d.z; - + if (abs(z1) >= 1.0) { float tCap = (sign(z1) - o.z) / d.z; t1 = abs(b + a * tCap) < det ? tCap : NO_HIT; } - + if (abs(z2) >= 1.0) { float tCap = (sign(z2) - o.z) / d.z; t2 = abs(b + a * tCap) < det ? tCap : NO_HIT; } - + return vec2(t1, t2); } vec2 intersectUnitCircle(Ray ray) { vec3 o = ray.pos; vec3 d = ray.dir; - + float t = -o.z / d.z; vec2 zPlanePos = o.xy + d.xy * t; float distSqr = dot(zPlanePos, zPlanePos); @@ -160,7 +160,7 @@ vec2 intersectUnitCircle(Ray ray) { if (distSqr > 1.0) { return vec2(NO_HIT); } - + return vec2(t, t); } @@ -168,16 +168,16 @@ vec2 intersectInfiniteUnitCylinder(Ray ray) { vec3 o = ray.pos; vec3 d = ray.dir; - + float a = dot(d.xy, d.xy); float b = dot(o.xy, d.xy); float c = dot(o.xy, o.xy) - 1.0; float det = b * b - a * c; - + if (det < 0.0) { return vec2(NO_HIT); } - + det = sqrt(det); float t1 = (-b - det) / a; float t2 = (-b + det) / a; @@ -214,13 +214,13 @@ void intersectShape(Ray ray, inout Intersections ix) #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) // When the cylinder is perfectly thin it's necessary to sandwich the // inner cylinder intersection inside the outer cylinder intersection. - + // Without this special case, // [outerMin, outerMax, innerMin, innerMax] will bubble sort to // [outerMin, innerMin, outerMax, innerMax] which will cause the back // side of the cylinder to be invisible because it will think the ray // is still inside the inner (negative) cylinder after exiting the - // outer (positive) cylinder. + // outer (positive) cylinder. // With this special case, // [outerMin, innerMin, innerMax, outerMax] will bubble sort to @@ -256,4 +256,4 @@ void intersectShape(Ray ray, inout Intersections ix) #endif } -// export { intersectShape }; \ No newline at end of file +// export { intersectShape }; diff --git a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl index efadd1d3871..3a07302e0f2 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl @@ -56,16 +56,16 @@ vec4 intersectHalfPlane(Ray ray, float angle) { vec2 p = o + t * d; bool outside = dot(p, planeDirection) < 0.0; if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT); - + return vec4(-INF_HIT, t, t, +INF_HIT); } vec2 intersectHalfSpace(Ray ray, float angle) -{ +{ vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; vec2 n = vec2(sin(angle), -cos(angle)); - + float a = dot(o, n); float b = dot(d, n); float t = -a / b; @@ -76,17 +76,17 @@ vec2 intersectHalfSpace(Ray ray, float angle) } vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) -{ +{ vec2 o = ray.pos.xy; vec2 d = ray.dir.xy; vec2 n1 = vec2(sin(minAngle), -cos(minAngle)); vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle)); - + float a1 = dot(o, n1); float a2 = dot(o, n2); float b1 = dot(d, n1); float b2 = dot(d, n2); - + float t1 = -a1 / b1; float t2 = -a2 / b2; float s1 = sign(a1); @@ -95,13 +95,13 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) float tmin = min(t1, t2); float tmax = max(t1, t2); float smin = tmin == t1 ? s1 : s2; - float smax = tmin == t1 ? s2 : s1; + float smax = tmin == t1 ? s2 : s1; bool e = tmin >= 0.0; bool f = tmax >= 0.0; bool g = smin >= 0.0; bool h = smax >= 0.0; - + if (e != g && f == h) return vec2(tmin, tmax); else if (e == g && f == h) return vec2(-INF_HIT, tmin); else if (e != g && f != h) return vec2(tmax, +INF_HIT); @@ -109,7 +109,7 @@ vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) } vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle) -{ +{ vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle); vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi); return vec4(planeIntersectMin, planeIntersectMax); @@ -119,21 +119,21 @@ vec2 intersectUnitSphere(Ray ray) { vec3 o = ray.pos; vec3 d = ray.dir; - + float b = dot(d, o); float c = dot(o, o) - 1.0; float det = b * b - c; - + if (det < 0.0) { return vec2(NO_HIT); } - + det = sqrt(det); float t1 = -b - det; float t2 = -b + det; float tmin = min(t1, t2); float tmax = max(t1, t2); - + return vec2(tmin, tmax); } @@ -141,22 +141,22 @@ vec2 intersectUnitSphereUnnormalizedDirection(Ray ray) { vec3 o = ray.pos; vec3 d = ray.dir; - + float a = dot(d, d); float b = dot(d, o); float c = dot(o, o) - 1.0; float det = b * b - a * c; - + if (det < 0.0) { return vec2(NO_HIT); } - + det = sqrt(det); float t1 = (-b - det) / a; float t2 = (-b + det) / a; float tmin = min(t1, t2); float tmax = max(t1, t2); - + return vec2(tmin, tmax); } @@ -168,11 +168,11 @@ vec2 intersectDoubleEndedCone(Ray ray, float cosSqrHalfAngle) float b = d.z * o.z - dot(o, d) * cosSqrHalfAngle; float c = o.z * o.z - dot(o, o) * cosSqrHalfAngle; float det = b * b - a * c; - + if (det < 0.0) { return vec2(NO_HIT); } - + det = sqrt(det); float t1 = (-b - det) / a; float t2 = (-b + det) / a; @@ -225,10 +225,10 @@ vec2 intersectRegularCone(Ray ray, float cosSqrHalfAngle) { void intersectShape(in Ray ray, inout Intersections ix) { // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. + // Direction is scaled as well to be in sync with position. ray.pos = ray.pos * 2.0 - 1.0; ray.dir *= 2.0; - + // Outer ellipsoid vec2 outerIntersect = intersectUnitSphereUnnormalizedDirection(ray); setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX, outerIntersect); @@ -239,16 +239,16 @@ void intersectShape(in Ray ray, inout Intersections ix) { } // Inner ellipsoid - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) // When the ellipsoid is perfectly thin it's necessary to sandwich the // inner ellipsoid intersection inside the outer ellipsoid intersection. - + // Without this special case, // [outerMin, outerMax, innerMin, innerMax] will bubble sort to // [outerMin, innerMin, outerMax, innerMax] which will cause the back // side of the ellipsoid to be invisible because it will think the ray // is still inside the inner (negative) ellipsoid after exiting the - // outer (positive) ellipsoid. + // outer (positive) ellipsoid. // With this special case, // [outerMin, innerMin, innerMax, outerMax] will bubble sort to @@ -265,7 +265,7 @@ void intersectShape(in Ray ray, inout Intersections ix) { vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); #endif - + // Flip the ray because the intersection function expects a cone growing towards +Z. #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) Ray flippedRay = ray; @@ -286,7 +286,7 @@ void intersectShape(in Ray ray, inout Intersections ix) { setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN + 1, bottomConeIntersection.zw); #endif - // Top cone + // Top cone #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF) vec4 topConeIntersection = intersectFlippedCone(flippedRay, u_ellipsoidRenderLatitudeCosSqrHalfMinMax.y); setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX + 0, topConeIntersection.xy); diff --git a/packages/engine/Source/Shaders/Voxels/Intersection.glsl b/packages/engine/Source/Shaders/Voxels/Intersection.glsl index 4b6d482c17b..ba642243924 100644 --- a/packages/engine/Source/Shaders/Voxels/Intersection.glsl +++ b/packages/engine/Source/Shaders/Voxels/Intersection.glsl @@ -9,7 +9,7 @@ vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { Ray ray = Ray(positionUv, directionUv); - + // Do a ray-shape intersection to find the exact starting and ending points. intersectShape(ray, ix); diff --git a/packages/engine/Source/Shaders/Voxels/Megatexture.glsl b/packages/engine/Source/Shaders/Voxels/Megatexture.glsl index b7ba38b12c1..965d4966ada 100644 --- a/packages/engine/Source/Shaders/Voxels/Megatexture.glsl +++ b/packages/engine/Source/Shaders/Voxels/Megatexture.glsl @@ -83,7 +83,7 @@ Properties getPropertiesFromMegatexture(in SampleData sampleData) { #if defined(NEAREST_SAMPLING) // Round to the center of the nearest voxel - voxelCoord = floor(voxelCoord) + vec3(0.5); + voxelCoord = floor(voxelCoord) + vec3(0.5); #endif // Tile location @@ -135,4 +135,4 @@ Properties accumulatePropertiesFromMegatexture(in SampleData sampleDatas[SAMPLE_ #endif } -// export { accumulatePropertiesFromMegatexture }; \ No newline at end of file +// export { accumulatePropertiesFromMegatexture }; diff --git a/packages/engine/Source/Shaders/Voxels/Octree.glsl b/packages/engine/Source/Shaders/Voxels/Octree.glsl index ab2749d389e..61f5c71527f 100644 --- a/packages/engine/Source/Shaders/Voxels/Octree.glsl +++ b/packages/engine/Source/Shaders/Voxels/Octree.glsl @@ -50,7 +50,7 @@ float normU8x2_toFloat(in vec2 value) { OctreeNodeData getOctreeNodeData(in vec2 octreeUv) { vec4 texData = texture2D(u_octreeInternalNodeTexture, octreeUv); - + OctreeNodeData data; data.data = normU8x2_toInt(texData.xy); data.flag = normU8x2_toInt(texData.zw); @@ -207,7 +207,7 @@ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData trave { traversalData.octreeCoords.xyz /= 2; traversalData.octreeCoords.w -= 1; - + if (!insideTile(shapePosition, traversalData.octreeCoords)) { traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex); } else { diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl index 40af7c87593..6e8a452f630 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl @@ -32,7 +32,7 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { vec3 positionLocal = positionUv * 2.0 - 1.0; // [-1,+1] - + // Compute radius #if defined(CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT) float radius = length(positionLocal.xy); // [0,1] @@ -42,7 +42,7 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { radius = radius * u_cylinderUvToShapeUvRadius.x + u_cylinderUvToShapeUvRadius.y; // x = scale, y = offset #endif #endif - + // Compute height #if defined(CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT) float height = positionUv.z; // [0,1] @@ -78,4 +78,4 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { return vec3(radius, height, angle); } -// export { convertUvToShapeUvSpace }; \ No newline at end of file +// export { convertUvToShapeUvSpace }; diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl index d02e3abe66a..3a7b5256969 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl @@ -67,13 +67,13 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { vec3 posEllipsoid = positionLocal * u_ellipsoidRadiiUv; vec3 normal = normalize(posEllipsoid * u_ellipsoidInverseRadiiSquaredUv); // geodetic surface normal #endif - + // Compute longitude #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO) float longitude = 1.0; #else float longitude = (atan(normal.y, normal.x) + czm_pi) / czm_twoPi; - + // Correct the angle when max < min // Technically this should compare against min longitude - but it has precision problems so compare against the middle of empty space. #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED) From a5bc35152e1aab01ad491048a96437bb7844a40a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 27 Dec 2022 12:22:19 -0500 Subject: [PATCH 289/679] Fix speckle issue with nearest sampling --- packages/engine/Source/Shaders/Voxels/Megatexture.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Shaders/Voxels/Megatexture.glsl b/packages/engine/Source/Shaders/Voxels/Megatexture.glsl index 965d4966ada..a3a2f982d44 100644 --- a/packages/engine/Source/Shaders/Voxels/Megatexture.glsl +++ b/packages/engine/Source/Shaders/Voxels/Megatexture.glsl @@ -83,7 +83,7 @@ Properties getPropertiesFromMegatexture(in SampleData sampleData) { #if defined(NEAREST_SAMPLING) // Round to the center of the nearest voxel - voxelCoord = floor(voxelCoord) + vec3(0.5); + voxelCoord = floor(voxelCoord + vec3(0.5)); #endif // Tile location From c5c68204b500b4fd54d433d81c040144704fb316 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 27 Dec 2022 14:52:03 -0500 Subject: [PATCH 290/679] Fix voxel inspector issues related to zero or negative scale --- .../Source/VoxelInspector/VoxelInspector.js | 10 +- .../VoxelInspector/VoxelInspectorViewModel.js | 97 ++++++++----------- 2 files changed, 48 insertions(+), 59 deletions(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspector.js b/packages/widgets/Source/VoxelInspector/VoxelInspector.js index e7ac945dea2..e43a93b0cf6 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspector.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspector.js @@ -115,8 +115,8 @@ function VoxelInspector(container, scene) { ); // Transform - const maxTrans = 20000000.0; - const maxScale = 20000000.0; + const maxTrans = 10.0; + const maxScale = 10.0; const maxAngle = CesiumMath.PI; transformPanelContents.appendChild( @@ -129,13 +129,13 @@ function VoxelInspector(container, scene) { createRangeInput("Translation Z", "translationZ", -maxTrans, +maxTrans) ); transformPanelContents.appendChild( - createRangeInput("Scale X", "scaleX", -maxScale, +maxScale) + createRangeInput("Scale X", "scaleX", 0, +maxScale) ); transformPanelContents.appendChild( - createRangeInput("Scale Y", "scaleY", -maxScale, +maxScale) + createRangeInput("Scale Y", "scaleY", 0, +maxScale) ); transformPanelContents.appendChild( - createRangeInput("Scale Z", "scaleZ", -maxScale, +maxScale) + createRangeInput("Scale Z", "scaleZ", 0, +maxScale) ); transformPanelContents.appendChild( createRangeInput("Heading", "angleX", -maxAngle, +maxAngle) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index 70122cf7460..38643e767a8 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -619,17 +619,9 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "scaleX", - initialValue: 0.0, - setPrimitiveFunction: function (scaleX) { - const originalScale = Matrix4.getScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - that._voxelPrimitive.modelMatrix = Matrix4.setScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3(scaleX, originalScale.y, originalScale.z), - that._voxelPrimitive.modelMatrix - ); + initialValue: 1.0, + setPrimitiveFunction: function () { + setModelMatrix(that); }, getPrimitiveFunction: function () { that.scaleX = Matrix4.getScale( @@ -640,17 +632,9 @@ function VoxelInspectorViewModel(scene) { }); addProperty({ name: "scaleY", - initialValue: 0.0, - setPrimitiveFunction: function (scaleY) { - const originalScale = Matrix4.getScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - that._voxelPrimitive.modelMatrix = Matrix4.setScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3(originalScale.x, scaleY, originalScale.z), - that._voxelPrimitive.modelMatrix - ); + initialValue: 1.0, + setPrimitiveFunction: function () { + setModelMatrix(that); }, getPrimitiveFunction: function () { that.scaleY = Matrix4.getScale( @@ -661,17 +645,9 @@ function VoxelInspectorViewModel(scene) { }); addProperty({ name: "scaleZ", - initialValue: 0.0, - setPrimitiveFunction: function (scaleZ) { - const originalScale = Matrix4.getScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - that._voxelPrimitive.modelMatrix = Matrix4.setScale( - that._voxelPrimitive.modelMatrix, - new Cartesian3(originalScale.x, originalScale.y, scaleZ), - that._voxelPrimitive.modelMatrix - ); + initialValue: 1.0, + setPrimitiveFunction: function () { + setModelMatrix(that); }, getPrimitiveFunction: function () { that.scaleZ = Matrix4.getScale( @@ -685,13 +661,7 @@ function VoxelInspectorViewModel(scene) { name: "angleX", initialValue: 0.0, setPrimitiveFunction: function () { - that._voxelPrimitive.modelMatrix = Matrix4.setRotation( - that._voxelPrimitive.modelMatrix, - Matrix3.fromHeadingPitchRoll( - new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) - ), - that._voxelPrimitive.modelMatrix - ); + setModelMatrix(that); }, }); @@ -699,13 +669,7 @@ function VoxelInspectorViewModel(scene) { name: "angleY", initialValue: 0.0, setPrimitiveFunction: function () { - that._voxelPrimitive.modelMatrix = Matrix4.setRotation( - that._voxelPrimitive.modelMatrix, - Matrix3.fromHeadingPitchRoll( - new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) - ), - that._voxelPrimitive.modelMatrix - ); + setModelMatrix(that); }, }); @@ -713,17 +677,42 @@ function VoxelInspectorViewModel(scene) { name: "angleZ", initialValue: 0.0, setPrimitiveFunction: function () { - that._voxelPrimitive.modelMatrix = Matrix4.setRotation( - that._voxelPrimitive.modelMatrix, - Matrix3.fromHeadingPitchRoll( - new HeadingPitchRoll(that.angleX, that.angleY, that.angleZ) - ), - that._voxelPrimitive.modelMatrix - ); + setModelMatrix(that); }, }); } +const scratchTranslation = new Cartesian3(); +const scratchScale = new Cartesian3(); +const scratchHeadingPitchRoll = new HeadingPitchRoll(); +const scratchRotation = new Matrix3(); + +function setModelMatrix(viewModel) { + const translation = Cartesian3.fromElements( + viewModel.translationX, + viewModel.translationY, + viewModel.translationZ, + scratchTranslation + ); + const scale = Cartesian3.fromElements( + viewModel.scaleX, + viewModel.scaleY, + viewModel.scaleZ, + scratchScale + ); + const hpr = scratchHeadingPitchRoll; + hpr.heading = viewModel.angleX; + hpr.pitch = viewModel.angleY; + hpr.roll = viewModel.angleZ; + const rotation = Matrix3.fromHeadingPitchRoll(hpr, scratchRotation); + const rotationScale = Matrix3.multiplyByScale(rotation, scale, rotation); + viewModel._voxelPrimitive.modelMatrix = Matrix4.fromRotationTranslation( + rotationScale, + translation, + viewModel._voxelPrimitive.modelMatrix + ); +} + Object.defineProperties(VoxelInspectorViewModel.prototype, { /** * Gets the scene From 047e59ecda7ee3d74e1a33267962883361e2e093 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 28 Dec 2022 10:51:46 -0500 Subject: [PATCH 291/679] Differentiate between shape transform, local tranform (model matrix), and global transform --- .../Scene/Cesium3DTilesVoxelProvider.js | 41 ++++++++++--------- .../engine/Source/Scene/VoxelCylinderShape.js | 4 +- .../engine/Source/Scene/VoxelPrimitive.js | 19 +++++++-- packages/engine/Source/Scene/VoxelProvider.js | 15 ++++++- .../Scene/Cesium3DTilesVoxelProviderSpec.js | 2 +- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index f8a13784af1..474904de39c 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -51,7 +51,10 @@ function Cesium3DTilesVoxelProvider(options) { this.ready = false; /** @inheritdoc */ - this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); + this.shapeTransform = Matrix4.clone(Matrix4.IDENTITY); + + /** @inheritdoc */ + this.globalTransform = Matrix4.clone(Matrix4.IDENTITY); /** @inheritdoc */ this.shape = undefined; @@ -127,7 +130,13 @@ function Cesium3DTilesVoxelProvider(options) { const voxel = root.content.extensions["3DTILES_content_voxels"]; - const { shape, transform, minBounds, maxBounds } = getShape(root); + const { + shape, + minBounds, + maxBounds, + shapeTransform, + globalTransform, + } = getShape(root); that.shape = shape; that.minBounds = minBounds; @@ -135,7 +144,8 @@ function Cesium3DTilesVoxelProvider(options) { that.dimensions = Cartesian3.unpack(voxel.dimensions); that.paddingBefore = Cartesian3.unpack(voxel.padding.before); that.paddingAfter = Cartesian3.unpack(voxel.padding.after); - that.modelMatrix = transform; + that.shapeTransform = shapeTransform; + that.globalTransform = globalTransform; // TODO: this tile class stuff needs to be documented that.maximumTileCount = metadata.statistics.classes.tile?.count; @@ -188,9 +198,11 @@ function validate(tileset) { function getShape(tile) { const boundingVolume = tile.boundingVolume; - let tileTransform = Matrix4.IDENTITY; + let tileTransform; if (defined(tile.transform)) { tileTransform = Matrix4.unpack(tile.transform); + } else { + tileTransform = Matrix4.clone(Matrix4.IDENTITY); } if (defined(boundingVolume.box)) { @@ -239,7 +251,8 @@ function getEllipsoidShape(region) { shape: VoxelShapeType.ELLIPSOID, minBounds: minBounds, maxBounds: maxBounds, - transform: shapeTransform, + shapeTransform: shapeTransform, + globalTransform: Matrix4.clone(Matrix4.IDENTITY), }; } @@ -250,17 +263,12 @@ function getBoxShape(box, tileTransform) { obb.center ); - const transform = Matrix4.multiply( - tileTransform, - shapeTransform, - new Matrix4() - ); - return { shape: VoxelShapeType.BOX, minBounds: Cartesian3.clone(VoxelBoxShape.DefaultMinBounds), maxBounds: Cartesian3.clone(VoxelBoxShape.DefaultMaxBounds), - transform: transform, + shapeTransform: shapeTransform, + globalTransform: tileTransform, }; } @@ -271,17 +279,12 @@ function getCylinderShape(cylinder, tileTransform) { obb.center ); - const transform = Matrix4.multiply( - tileTransform, - shapeTransform, - new Matrix4() - ); - return { shape: VoxelShapeType.CYLINDER, minBounds: Cartesian3.clone(VoxelCylinderShape.DefaultMinBounds), maxBounds: Cartesian3.clone(VoxelCylinderShape.DefaultMaxBounds), - transform: transform, + shapeTransform: shapeTransform, + globalTransform: tileTransform, }; } diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index e36e00d44df..59da39dc668 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -815,7 +815,7 @@ function getCylinderChunkObb( testAngles[testAngleCount++] = angleMid + CesiumMath.PI_OVER_TWO; } - // Find bounding box in local space relative to angleMid + // Find bounding box in shape space relative to angleMid let minX = 1.0; let minY = 1.0; let maxX = -1.0; @@ -871,7 +871,7 @@ function getCylinderChunkObb( scratchTranslationMatrix ); - // Local matrix = R * T * S + // Shape space matrix = R * T * S const localMatrix = Matrix4.multiply( rotationMatrix, Matrix4.multiply(translationMatrix, scaleMatrix, scratchMatrix), diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index 2ea07b0b366..fdfb5e5ac76 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -1269,15 +1269,26 @@ function initFromProvider(primitive, provider, context) { * @private */ function checkTransformAndBounds(primitive, provider) { - const providerTransform = defaultValue( - provider.modelMatrix, + const shapeTransform = defaultValue( + provider.shapeTransform, Matrix4.IDENTITY ); - primitive._compoundModelMatrix = Matrix4.multiplyTransformation( - providerTransform, + const globalTransform = defaultValue( + provider.globalTransform, + Matrix4.IDENTITY + ); + + // Compound model matrix = global transform * model matrix * shape transform + Matrix4.multiplyTransformation( + globalTransform, primitive._modelMatrix, primitive._compoundModelMatrix ); + Matrix4.multiplyTransformation( + primitive._compoundModelMatrix, + shapeTransform, + primitive._compoundModelMatrix + ); const numChanges = updateBound(primitive, "_compoundModelMatrix", "_compoundModelMatrixOld") + updateBound(primitive, "_minBounds", "_minBoundsOld") + diff --git a/packages/engine/Source/Scene/VoxelProvider.js b/packages/engine/Source/Scene/VoxelProvider.js index 685351f61e3..ed0025adc53 100644 --- a/packages/engine/Source/Scene/VoxelProvider.js +++ b/packages/engine/Source/Scene/VoxelProvider.js @@ -41,13 +41,24 @@ Object.defineProperties(VoxelProvider.prototype, { }, /** - * A model matrix that is applied to all tiles. If undefined, the identity matrix will be used instead. + * A transform from local space to global space. If undefined, the identity matrix will be used instead. * * @memberof VoxelProvider.prototype * @type {Matrix4|undefined} * @readonly */ - modelMatrix: { + globalTransform: { + get: DeveloperError.throwInstantiationError, + }, + + /** + * A transform from shape space to local space. If undefined, the identity matrix will be used instead. + * + * @memberof VoxelProvider.prototype + * @type {Matrix4|undefined} + * @readonly + */ + shapeTransform: { get: DeveloperError.throwInstantiationError, }, diff --git a/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js index 5b1ddf58ce6..34ba37ddbf6 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -48,7 +48,7 @@ describe( }).then(function () { expect(provider).toBeDefined(); expect(provider.ready).toBeTrue(); - expect(provider.modelMatrix).toEqualEpsilon( + expect(provider.globalTransform).toEqualEpsilon( Matrix4.fromScale(Ellipsoid.WGS84.radii), CesiumMath.EPSILON10 ); From b52f7a8107dac3fda43d108450de4d4529476bb4 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 28 Dec 2022 11:13:45 -0500 Subject: [PATCH 292/679] Recompute OBB in case of shape space rotation and non-uniform scale --- .../engine/Source/Scene/VoxelCylinderShape.js | 55 +++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index 59da39dc668..2797c176519 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -7,6 +7,7 @@ import CesiumMath from "../Core/Math.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; +import Cartesian4 from "../Core/Cartesian4.js"; /** * A cylinder {@link VoxelShape}. @@ -281,8 +282,8 @@ VoxelCylinderShape.prototype.update = function ( this._maximumRadius = shapeMaxRadius; // [0,1] this._minimumHeight = shapeMinHeight; // [-1,+1] this._maximumHeight = shapeMaxHeight; // [-1,+1] - this._minimumAngle = shapeMinAngle; // [-halfPi,+halfPi] - this._maximumAngle = shapeMaxAngle; // [-halfPi,+halfPi] + this._minimumAngle = shapeMinAngle; // [-pi,+pi] + this._maximumAngle = shapeMaxAngle; // [-pi,+pi] this.shapeTransform = Matrix4.clone(modelMatrix, this.shapeTransform); @@ -743,6 +744,48 @@ const scratchTranslationMatrix = new Matrix4(); const scratchRotationMatrix = new Matrix4(); const scratchScaleMatrix = new Matrix4(); const scratchMatrix = new Matrix4(); +const scratchColumn0 = new Cartesian3(); +const scratchColumn1 = new Cartesian3(); +const scratchColumn2 = new Cartesian3(); +const scratchCorners = new Array(8); +for (let i = 0; i < 8; i++) { + scratchCorners[i] = new Cartesian3(); +} + +function orthogonal(a, b, epsilon) { + return Math.abs(Cartesian4.dot(a, b)) < epsilon; +} + +function isValidOrientedBoundingBoxTransformation(matrix) { + const column0 = Matrix4.getColumn(matrix, 0, scratchColumn0); + const column1 = Matrix4.getColumn(matrix, 1, scratchColumn1); + const column2 = Matrix4.getColumn(matrix, 2, scratchColumn2); + + const epsilon = CesiumMath.EPSILON4; + + return ( + orthogonal(column0, column1, epsilon) && + orthogonal(column1, column2, epsilon) + ); +} + +function computeLooseOrientedBoundingBox(matrix, result) { + const corners = scratchCorners; + Cartesian3.fromElements(-0.5, -0.5, -0.5, corners[0]); + Cartesian3.fromElements(-0.5, -0.5, 0.5, corners[1]); + Cartesian3.fromElements(-0.5, 0.5, -0.5, corners[2]); + Cartesian3.fromElements(-0.5, 0.5, 0.5, corners[3]); + Cartesian3.fromElements(0.5, -0.5, -0.5, corners[4]); + Cartesian3.fromElements(0.5, -0.5, 0.5, corners[5]); + Cartesian3.fromElements(0.5, 0.5, -0.5, corners[6]); + Cartesian3.fromElements(0.5, 0.5, 0.5, corners[7]); + + for (let i = 0; i < 8; ++i) { + Matrix4.multiplyByPoint(matrix, corners[i], corners[i]); + } + + return OrientedBoundingBox.fromPoints(corners, result); +} /** * Computes an {@link OrientedBoundingBox} for a subregion of the shape. @@ -879,8 +922,12 @@ function getCylinderChunkObb( ); const globalMatrix = Matrix4.multiply(matrix, localMatrix, scratchMatrix); - const obb = OrientedBoundingBox.fromTransformation(globalMatrix, result); - return obb; + + if (!isValidOrientedBoundingBoxTransformation(globalMatrix)) { + return computeLooseOrientedBoundingBox(globalMatrix, result); + } + + return OrientedBoundingBox.fromTransformation(globalMatrix, result); } export default VoxelCylinderShape; From 460a12f86b8bb7f80ecbf73cdb9fa424d38f867c Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 28 Dec 2022 14:01:04 -0500 Subject: [PATCH 293/679] Visualize shape obb in debugDraw --- packages/engine/Source/Scene/VoxelPrimitive.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index fdfb5e5ac76..3cdcb9cfbdb 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -1781,10 +1781,6 @@ function orientedBoundingBoxToNdcAabb( return result; } -const colorRed = new Color(1.0, 0.0, 0.0); -const colorGreen = new Color(0.0, 1.0, 0.0); -const colorBlue = new Color(0.0, 0.0, 1.0); - const polylineAxisDistance = 30000000.0; const polylineXAxis = new Cartesian3(polylineAxisDistance, 0.0, 0.0); const polylineYAxis = new Cartesian3(0.0, polylineAxisDistance, 0.0); @@ -1841,7 +1837,7 @@ function debugDraw(that, frameState) { const level = tile.level; const startThickness = 5.0; const thickness = Math.max(1.0, startThickness / Math.pow(2.0, level)); - const colors = [colorRed, colorGreen, colorBlue]; + const colors = [Color.RED, Color.LIME, Color.BLUE]; const color = colors[level % 3]; makePolylineBox(tile.orientedBoundingBox, color, thickness); @@ -1853,25 +1849,27 @@ function debugDraw(that, frameState) { } } + makePolylineBox(that._shape.orientedBoundingBox, Color.WHITE, 5.0); + drawTile(traversal.rootNode); const axisThickness = 10.0; makePolylineLineSegment( Cartesian3.ZERO, polylineXAxis, - colorRed, + Color.RED, axisThickness ); makePolylineLineSegment( Cartesian3.ZERO, polylineYAxis, - colorGreen, + Color.LIME, axisThickness ); makePolylineLineSegment( Cartesian3.ZERO, polylineZAxis, - colorBlue, + Color.BLUE, axisThickness ); From 0b22591d05f63d637717655aba53b4dfa19c5d69 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 30 Dec 2022 10:11:34 -0500 Subject: [PATCH 294/679] Revert getEllipsoidShape changes --- .../Source/Scene/Cesium3DTilesVoxelProvider.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 474904de39c..19f1358d1f4 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -229,20 +229,14 @@ function getEllipsoidShape(region) { const minHeight = region[4]; const maxHeight = region[5]; - const scale = Cartesian3.clone(Ellipsoid.WGS84.radii); - const scaleFromHeight = new Cartesian3(maxHeight, maxHeight, maxHeight); - Cartesian3.add(scale, scaleFromHeight); - - const shapeTransform = Matrix4.fromScale(scale); + const shapeTransform = Matrix4.fromScale(Ellipsoid.WGS84.radii); const minBoundsX = west; const maxBoundsX = east; const minBoundsY = south; const maxBoundsY = north; - const minBoundsZ = - (minHeight + Ellipsoid.WGS84.maximumRadius) / - (maxHeight + Ellipsoid.WGS84.maximumRadius); - const maxBoundsZ = 1.0; + const minBoundsZ = minHeight; + const maxBoundsZ = maxHeight; const minBounds = new Cartesian3(minBoundsX, minBoundsY, minBoundsZ); const maxBounds = new Cartesian3(maxBoundsX, maxBoundsY, maxBoundsZ); From 0669bb8ea0424950a8e897622171f5bcb426081f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 30 Dec 2022 12:03:00 -0500 Subject: [PATCH 295/679] Fix bug where model matrix was being set before all viewModel properties were retrieved from primitive --- .../VoxelInspector/VoxelInspectorViewModel.js | 84 ++++++++----------- 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index 38643e767a8..f3b2dc6597b 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -62,6 +62,7 @@ function VoxelInspectorViewModel(scene) { this._definedProperties = []; this._getPrimitiveFunctions = []; + this._modelMatrixReady = false; const that = this; function addProperty(options) { @@ -542,20 +543,10 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "translationX", initialValue: 0.0, - setPrimitiveFunction: function (translationX) { - const originalTranslation = Matrix4.getTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3( - translationX, - originalTranslation.y, - originalTranslation.z - ), - that._voxelPrimitive.modelMatrix - ); + setPrimitiveFunction: function () { + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.translationX = Matrix4.getTranslation( @@ -567,21 +558,10 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "translationY", initialValue: 0.0, - setPrimitiveFunction: function (translationY) { - const originalTranslation = Matrix4.getTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - - that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3( - originalTranslation.x, - translationY, - originalTranslation.z - ), - that._voxelPrimitive.modelMatrix - ); + setPrimitiveFunction: function () { + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.translationY = Matrix4.getTranslation( @@ -593,21 +573,10 @@ function VoxelInspectorViewModel(scene) { addProperty({ name: "translationZ", initialValue: 0.0, - setPrimitiveFunction: function (translationZ) { - const originalTranslation = Matrix4.getTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3() - ); - - that._voxelPrimitive.modelMatrix = Matrix4.setTranslation( - that._voxelPrimitive.modelMatrix, - new Cartesian3( - originalTranslation.x, - originalTranslation.y, - translationZ - ), - that._voxelPrimitive.modelMatrix - ); + setPrimitiveFunction: function () { + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.translationZ = Matrix4.getTranslation( @@ -621,7 +590,9 @@ function VoxelInspectorViewModel(scene) { name: "scaleX", initialValue: 1.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.scaleX = Matrix4.getScale( @@ -634,7 +605,9 @@ function VoxelInspectorViewModel(scene) { name: "scaleY", initialValue: 1.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.scaleY = Matrix4.getScale( @@ -647,7 +620,9 @@ function VoxelInspectorViewModel(scene) { name: "scaleZ", initialValue: 1.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, getPrimitiveFunction: function () { that.scaleZ = Matrix4.getScale( @@ -661,7 +636,9 @@ function VoxelInspectorViewModel(scene) { name: "angleX", initialValue: 0.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, }); @@ -669,7 +646,9 @@ function VoxelInspectorViewModel(scene) { name: "angleY", initialValue: 0.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, }); @@ -677,7 +656,9 @@ function VoxelInspectorViewModel(scene) { name: "angleZ", initialValue: 0.0, setPrimitiveFunction: function () { - setModelMatrix(that); + if (that._modelMatrixReady) { + setModelMatrix(that); + } }, }); } @@ -761,9 +742,12 @@ Object.defineProperties(VoxelInspectorViewModel.prototype, { } } ); + that._modelMatrixReady = false; for (let i = 0; i < that._getPrimitiveFunctions.length; i++) { that._getPrimitiveFunctions[i](); } + that._modelMatrixReady = true; + setModelMatrix(that); }); } }, From a8b7f6d464dad1399e2d5d123be63e7d8e9f89b8 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 30 Dec 2022 10:20:25 -0500 Subject: [PATCH 296/679] Cleanup VoxelBoxShape and VoxelCylinderShape --- packages/engine/Source/Scene/VoxelBoxShape.js | 76 ++++++------- .../engine/Source/Scene/VoxelCylinderShape.js | 104 +++++++++--------- .../Source/Shaders/Voxels/IntersectBox.glsl | 20 ++-- .../Source/Shaders/Voxels/convertUvToBox.glsl | 12 +- 4 files changed, 103 insertions(+), 109 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelBoxShape.js b/packages/engine/Source/Scene/VoxelBoxShape.js index 4eaa2e0c34d..a5ab727b99a 100644 --- a/packages/engine/Source/Scene/VoxelBoxShape.js +++ b/packages/engine/Source/Scene/VoxelBoxShape.js @@ -76,11 +76,11 @@ function VoxelBoxShape() { * @readonly */ this.shaderUniforms = { - boxTransformUvToRenderBounds: new Matrix4(), - boxScaleUvToRenderBounds: new Cartesian3(), - boxOffsetUvToRenderBounds: new Cartesian3(), - boxScaleUvToShapeBoundsUv: new Cartesian3(), - boxOffsetUvToShapeBoundsUv: new Cartesian3(), + boxUvToRenderBoundsTransform: new Matrix4(), + boxUvToRenderBoundsScale: new Cartesian3(), + boxUvToRenderBoundsTranslate: new Cartesian3(), + boxUvToShapeUvScale: new Cartesian3(), + boxUvToShapeUvTranslate: new Cartesian3(), }; /** @@ -89,8 +89,8 @@ function VoxelBoxShape() { */ this.shaderDefines = { BOX_INTERSECTION_INDEX: undefined, - BOX_HAS_RENDER_BOUND: undefined, - BOX_HAS_SHAPE_BOUND: undefined, + BOX_HAS_RENDER_BOUNDS: undefined, + BOX_HAS_SHAPE_BOUNDS: undefined, BOX_IS_2D: undefined, }; @@ -99,7 +99,7 @@ function VoxelBoxShape() { * @type {Number} * @readonly */ - this.shaderMaximumIntersectionsLength = undefined; + this.shaderMaximumIntersectionsLength = 0; // not known until update } const scratchCenter = new Cartesian3(); @@ -108,6 +108,7 @@ const scratchRotation = new Matrix3(); const scratchTransformLocalToBounds = new Matrix4(); const scratchBoundsTranslation = new Cartesian3(); const scratchBoundsScale = new Cartesian3(); +const scratchBoundsScaleMatrix = new Matrix3(); const scratchClipMinBounds = new Cartesian3(); const scratchClipMaxBounds = new Cartesian3(); const scratchRenderMinBounds = new Cartesian3(); @@ -152,20 +153,12 @@ VoxelBoxShape.prototype.update = function ( clipMinBounds, clipMaxBounds ) { - clipMinBounds = defaultValue( - clipMinBounds, - VoxelBoxShape.DefaultMinBounds.clone() - ); - clipMaxBounds = defaultValue( - clipMaxBounds, - VoxelBoxShape.DefaultMaxBounds.clone() - ); + clipMinBounds = defaultValue(clipMinBounds, VoxelBoxShape.DefaultMinBounds); + clipMaxBounds = defaultValue(clipMaxBounds, VoxelBoxShape.DefaultMaxBounds); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); - Check.typeOf.object("clipMinBounds", clipMinBounds); - Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); const defaultMinBounds = VoxelBoxShape.DefaultMinBounds; @@ -270,7 +263,7 @@ VoxelBoxShape.prototype.update = function ( } } - const hasRenderBound = + const hasRenderBounds = renderMinBounds.x !== defaultMinBounds.x || renderMaxBounds.x !== defaultMaxBounds.x || renderMinBounds.y !== defaultMinBounds.y || @@ -278,7 +271,7 @@ VoxelBoxShape.prototype.update = function ( renderMinBounds.z !== defaultMinBounds.z || renderMaxBounds.z !== defaultMaxBounds.z; - const hasShapeBound = + const hasShapeBounds = minBounds.x !== defaultMinBounds.x || maxBounds.x !== defaultMaxBounds.x || minBounds.y !== defaultMinBounds.y || @@ -286,13 +279,14 @@ VoxelBoxShape.prototype.update = function ( minBounds.z !== defaultMinBounds.z || maxBounds.z !== defaultMaxBounds.z; + // Keep track of how many intersections there are going to be. let intersectionCount = 0; shaderDefines["BOX_INTERSECTION_INDEX"] = intersectionCount; intersectionCount += 1; - if (hasRenderBound) { - shaderDefines["BOX_HAS_RENDER_BOUND"] = true; + if (hasRenderBounds) { + shaderDefines["BOX_HAS_RENDER_BOUNDS"] = true; const min = renderMinBounds; const max = renderMaxBounds; @@ -319,7 +313,7 @@ VoxelBoxShape.prototype.update = function ( ); let transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(scaleLocalToBounds), + Matrix3.fromScale(scaleLocalToBounds, scratchBoundsScaleMatrix), translateLocalToBounds, scratchTransformLocalToBounds ); @@ -335,30 +329,30 @@ VoxelBoxShape.prototype.update = function ( } else if (min.z === max.z) { transformAxisConversion = Matrix4.IDENTITY; } - transformLocalToBounds = Matrix4.multiply( + transformLocalToBounds = Matrix4.multiplyTransformation( transformAxisConversion, transformLocalToBounds, transformLocalToBounds ); } - shaderUniforms.boxTransformUvToRenderBounds = Matrix4.multiplyTransformation( + shaderUniforms.boxUvToRenderBoundsTransform = Matrix4.multiplyTransformation( transformLocalToBounds, transformUvToLocal, - shaderUniforms.boxTransformUvToRenderBounds + shaderUniforms.boxUvToRenderBoundsTransform ); - shaderUniforms.boxScaleUvToRenderBounds = Matrix4.getScale( - shaderUniforms.boxTransformUvToRenderBounds, - shaderUniforms.boxScaleUvToRenderBounds + shaderUniforms.boxUvToRenderBoundsScale = Matrix4.getScale( + shaderUniforms.boxUvToRenderBoundsTransform, + shaderUniforms.boxUvToRenderBoundsScale ); - shaderUniforms.boxOffsetUvToRenderBounds = Matrix4.getTranslation( - shaderUniforms.boxTransformUvToRenderBounds, - shaderUniforms.boxOffsetUvToRenderBounds + shaderUniforms.boxUvToRenderBoundsTranslate = Matrix4.getTranslation( + shaderUniforms.boxUvToRenderBoundsTransform, + shaderUniforms.boxUvToRenderBoundsTranslate ); } - if (hasShapeBound) { - shaderDefines["BOX_HAS_SHAPE_BOUND"] = true; + if (hasShapeBounds) { + shaderDefines["BOX_HAS_SHAPE_BOUNDS"] = true; const min = minBounds; const max = maxBounds; @@ -373,18 +367,18 @@ VoxelBoxShape.prototype.update = function ( // offset = -minBoundsUv / ((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) // offset = -2.0 * (minBounds * 0.5 + 0.5) / (maxBounds - minBounds) // offset = -scale * (minBounds * 0.5 + 0.5) - shaderUniforms.boxScaleUvToShapeBoundsUv = Cartesian3.fromElements( + shaderUniforms.boxUvToShapeUvScale = Cartesian3.fromElements( 2.0 / (min.x === max.x ? 1.0 : max.x - min.x), 2.0 / (min.y === max.y ? 1.0 : max.y - min.y), 2.0 / (min.z === max.z ? 1.0 : max.z - min.z), - shaderUniforms.boxScaleUvToShapeBoundsUv + shaderUniforms.boxUvToShapeUvScale ); - shaderUniforms.boxOffsetUvToShapeBoundsUv = Cartesian3.fromElements( - -shaderUniforms.boxScaleUvToShapeBoundsUv.x * (min.x * 0.5 + 0.5), - -shaderUniforms.boxScaleUvToShapeBoundsUv.y * (min.y * 0.5 + 0.5), - -shaderUniforms.boxScaleUvToShapeBoundsUv.z * (min.z * 0.5 + 0.5), - shaderUniforms.boxOffsetUvToShapeBoundsUv + shaderUniforms.boxUvToShapeUvTranslate = Cartesian3.fromElements( + -shaderUniforms.boxUvToShapeUvScale.x * (min.x * 0.5 + 0.5), + -shaderUniforms.boxUvToShapeUvScale.y * (min.y * 0.5 + 0.5), + -shaderUniforms.boxUvToShapeUvScale.z * (min.z * 0.5 + 0.5), + shaderUniforms.boxUvToShapeUvTranslate ); } diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index 2797c176519..9d35f9af7a6 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -149,6 +149,7 @@ function VoxelCylinderShape() { const scratchScale = new Cartesian3(); const scratchBoundsTranslation = new Cartesian3(); const scratchBoundsScale = new Cartesian3(); +const scratchBoundsScaleMatrix = new Matrix3(); const scratchTransformLocalToBounds = new Matrix4(); const scratchTransformUvToBounds = new Matrix4(); const transformUvToLocal = Matrix4.fromRotationTranslation( @@ -165,6 +166,7 @@ const transformUvToLocal = Matrix4.fromRotationTranslation( * @param {Cartesian3} maxBounds The maximum bounds. * @param {Cartesian3} [clipMinBounds=VoxelCylinderShape.DefaultMinBounds] The minimum clip bounds. * @param {Cartesian3} [clipMaxBounds=VoxelCylinderShape.DefaultMaxBounds] The maximum clip bounds. + * @returns {Boolean} Whether the shape is visible. */ VoxelCylinderShape.prototype.update = function ( modelMatrix, @@ -175,29 +177,26 @@ VoxelCylinderShape.prototype.update = function ( ) { clipMinBounds = defaultValue( clipMinBounds, - VoxelCylinderShape.DefaultMinBounds.clone() + VoxelCylinderShape.DefaultMinBounds ); clipMaxBounds = defaultValue( clipMaxBounds, - VoxelCylinderShape.DefaultMaxBounds.clone() + VoxelCylinderShape.DefaultMaxBounds ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); - Check.typeOf.object("clipMinBounds", clipMinBounds); - Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); - const scale = Matrix4.getScale(modelMatrix, scratchScale); const defaultMinRadius = VoxelCylinderShape.DefaultMinBounds.x; const defaultMaxRadius = VoxelCylinderShape.DefaultMaxBounds.x; const defaultMinHeight = VoxelCylinderShape.DefaultMinBounds.y; const defaultMaxHeight = VoxelCylinderShape.DefaultMaxBounds.y; const defaultMinAngle = VoxelCylinderShape.DefaultMinBounds.z; const defaultMaxAngle = VoxelCylinderShape.DefaultMaxBounds.z; - const defaultAngleWidth = defaultMaxAngle - defaultMinAngle; - const defaultHalfAngleWidth = 0.5 * defaultAngleWidth; + const defaultAngleRange = defaultMaxAngle - defaultMinAngle; + const defaultHalfAngleRange = 0.5 * defaultAngleRange; const zeroScaleEpsilon = CesiumMath.EPSILON10; const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees @@ -259,14 +258,16 @@ VoxelCylinderShape.prototype.update = function ( const renderMinAngle = Math.max(shapeMinAngle, clipMinAngle); const renderMaxAngle = Math.min(shapeMaxAngle, clipMaxAngle); + const scale = Matrix4.getScale(modelMatrix, scratchScale); + // Exit early if the shape is not visible. // Note that minAngle may be greater than maxAngle when crossing the 180th meridian. // Cylinder is not visible if: // - maxRadius is zero (line) + // - minRadius is greater than maxRadius // - minHeight is greater than maxHeight // - scale is 0 for any component (too annoying to reconstruct rotation matrix) - if ( renderMaxRadius === 0.0 || renderMinRadius > renderMaxRadius || @@ -322,18 +323,18 @@ VoxelCylinderShape.prototype.update = function ( renderMaxHeight === defaultMaxHeight; const isAngleReversedShape = shapeMaxAngle < shapeMinAngle; - const shapeAngleWidth = - shapeMaxAngle - shapeMinAngle + isAngleReversedShape * defaultAngleWidth; + const shapeAngleRange = + shapeMaxAngle - shapeMinAngle + isAngleReversedShape * defaultAngleRange; const hasAngleRegularShape = - shapeAngleWidth > defaultHalfAngleWidth + angleEpsilon && - shapeAngleWidth < defaultAngleWidth - angleEpsilon; + shapeAngleRange > defaultHalfAngleRange + angleEpsilon && + shapeAngleRange < defaultAngleRange - angleEpsilon; const hasAngleFlippedShape = - shapeAngleWidth > angleEpsilon && - shapeAngleWidth < defaultHalfAngleWidth - angleEpsilon; + shapeAngleRange > angleEpsilon && + shapeAngleRange < defaultHalfAngleRange - angleEpsilon; const hasAngleFlatShape = - shapeAngleWidth >= defaultHalfAngleWidth - angleEpsilon && - shapeAngleWidth <= defaultHalfAngleWidth + angleEpsilon; - const hasAngleEmptyShape = shapeAngleWidth <= angleEpsilon; + shapeAngleRange >= defaultHalfAngleRange - angleEpsilon && + shapeAngleRange <= defaultHalfAngleRange + angleEpsilon; + const hasAngleEmptyShape = shapeAngleRange <= angleEpsilon; const hasAngleShape = hasAngleRegularShape || hasAngleFlippedShape || @@ -353,18 +354,18 @@ VoxelCylinderShape.prototype.update = function ( ); const isAngleReversedRender = renderMaxAngle < renderMinAngle; - const renderAngleWidth = - renderMaxAngle - renderMinAngle + isAngleReversedRender * defaultAngleWidth; + const renderAngleRange = + renderMaxAngle - renderMinAngle + isAngleReversedRender * defaultAngleRange; const hasAngleRegularRender = - renderAngleWidth > defaultHalfAngleWidth + angleEpsilon && - renderAngleWidth < defaultAngleWidth - angleEpsilon; + renderAngleRange > defaultHalfAngleRange + angleEpsilon && + renderAngleRange < defaultAngleRange - angleEpsilon; const hasAngleFlippedRender = - renderAngleWidth > angleEpsilon && - renderAngleWidth < defaultHalfAngleWidth - angleEpsilon; + renderAngleRange > angleEpsilon && + renderAngleRange < defaultHalfAngleRange - angleEpsilon; const hasAngleFlatRender = - renderAngleWidth >= defaultHalfAngleWidth - angleEpsilon && - renderAngleWidth <= defaultHalfAngleWidth + angleEpsilon; - const hasAngleEmptyRender = renderAngleWidth <= angleEpsilon; + renderAngleRange >= defaultHalfAngleRange - angleEpsilon && + renderAngleRange <= defaultHalfAngleRange + angleEpsilon; + const hasAngleEmptyRender = renderAngleRange <= angleEpsilon; const hasAngleRender = hasAngleRegularRender || hasAngleFlippedRender || @@ -471,7 +472,7 @@ VoxelCylinderShape.prototype.update = function ( scratchBoundsTranslation ); const transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(scaleLocalToBounds), + Matrix3.fromScale(scaleLocalToBounds, scratchBoundsScaleMatrix), translateLocalToBounds, scratchTransformLocalToBounds ); @@ -531,9 +532,9 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY"] = true; } - const minAngleUv = (shapeMinAngle - defaultMinAngle) / defaultAngleWidth; - const maxAngleUv = (shapeMaxAngle - defaultMinAngle) / defaultAngleWidth; - const emptyAngleWidthUv = 1.0 - shapeAngleWidth / defaultAngleWidth; + const minAngleUv = (shapeMinAngle - defaultMinAngle) / defaultAngleRange; + const maxAngleUv = (shapeMaxAngle - defaultMinAngle) / defaultAngleRange; + const emptyAngleRangeUv = 1.0 - shapeAngleRange / defaultAngleRange; shaderUniforms.cylinderShapeUvAngleMinMax = Cartesian2.fromElements( minAngleUv, @@ -541,7 +542,7 @@ VoxelCylinderShape.prototype.update = function ( shaderUniforms.cylinderShapeUvAngleMinMax ); shaderUniforms.cylinderShapeUvAngleEmptyMid = - (maxAngleUv + 0.5 * emptyAngleWidthUv) % 1.0; + (maxAngleUv + 0.5 * emptyAngleRangeUv) % 1.0; // delerp(angleUv, minAngleUv, maxAngleUv) // (angelUv - minAngleUv) / (maxAngleUv - minAngleUv) @@ -552,8 +553,8 @@ VoxelCylinderShape.prototype.update = function ( // offset = -minAngleUv / (maxAngleUv - minAngleUv) // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // offset = -(minAngle - pi) / (maxAngle - minAngle) - const scale = defaultAngleWidth / shapeAngleWidth; - const offset = -(shapeMinAngle - defaultMinAngle) / shapeAngleWidth; + const scale = defaultAngleRange / shapeAngleRange; + const offset = -(shapeMinAngle - defaultMinAngle) / shapeAngleRange; shaderUniforms.cylinderUvToShapeUvAngle = Cartesian2.fromElements( scale, offset, @@ -592,7 +593,6 @@ VoxelCylinderShape.prototype.computeOrientedBoundingBoxForTile = function ( Check.typeOf.object("result", result); //>>includeEnd('debug'); - const rootTransform = this.shapeTransform; const minimumRadius = this._minimumRadius; const maximumRadius = this._maximumRadius; const minimumHeight = this._minimumHeight; @@ -640,7 +640,7 @@ VoxelCylinderShape.prototype.computeOrientedBoundingBoxForTile = function ( heightEnd, angleStart, angleEnd, - rootTransform, + this.shapeTransform, result ); }; @@ -664,8 +664,7 @@ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( Check.typeOf.object("dimensions", dimensions); //>>includeEnd('debug'); - const rootTransform = this.shapeTransform; - + const shapeTransform = this.shapeTransform; const minRadius = this._minimumRadius; const maxRadius = this._maximumRadius; const minHeight = this._minimumHeight; @@ -692,12 +691,12 @@ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( voxelMaximumHeight, voxelMinimumAngle, voxelMaximumAngle, - rootTransform, + shapeTransform, scratchOrientedBoundingBox ); const voxelScale = Matrix3.getScale(voxelObb.halfAxes, scratchVoxelScale); - const rootScale = Matrix4.getScale(rootTransform, scratchRootScale); + const rootScale = Matrix4.getScale(shapeTransform, scratchRootScale); const scaleRatio = Cartesian3.divideComponents( voxelScale, rootScale, @@ -730,14 +729,7 @@ VoxelCylinderShape.DefaultMinBounds = new Cartesian3(0.0, -1.0, -CesiumMath.PI); VoxelCylinderShape.DefaultMaxBounds = new Cartesian3(1.0, +1.0, +CesiumMath.PI); const maxTestAngles = 5; - -// Preallocated arrays for all of the possible test angle counts -/** - * @type {Number[]} - * @ignore - */ const scratchTestAngles = new Array(maxTestAngles); - const scratchTranslation = new Cartesian3(); const scratchRotation = new Matrix3(); const scratchTranslationMatrix = new Matrix4(); @@ -843,8 +835,8 @@ function getCylinderChunkObb( angleEnd += CesiumMath.TWO_PI; } - const angleWidth = angleEnd - angleStart; - const angleMid = angleStart + angleWidth * 0.5; + const angleRange = angleEnd - angleStart; + const angleMid = angleStart + angleRange * 0.5; const testAngles = scratchTestAngles; let testAngleCount = 0; @@ -853,7 +845,7 @@ function getCylinderChunkObb( testAngles[testAngleCount++] = angleEnd; testAngles[testAngleCount++] = angleMid; - if (angleWidth > CesiumMath.PI) { + if (angleRange > CesiumMath.PI) { testAngles[testAngleCount++] = angleMid - CesiumMath.PI_OVER_TWO; testAngles[testAngleCount++] = angleMid + CesiumMath.PI_OVER_TWO; } @@ -915,13 +907,21 @@ function getCylinderChunkObb( ); // Shape space matrix = R * T * S - const localMatrix = Matrix4.multiply( + const localMatrix = Matrix4.multiplyTransformation( rotationMatrix, - Matrix4.multiply(translationMatrix, scaleMatrix, scratchMatrix), + Matrix4.multiplyTransformation( + translationMatrix, + scaleMatrix, + scratchMatrix + ), scratchMatrix ); - const globalMatrix = Matrix4.multiply(matrix, localMatrix, scratchMatrix); + const globalMatrix = Matrix4.multiplyTransformation( + matrix, + localMatrix, + scratchMatrix + ); if (!isValidOrientedBoundingBoxTransformation(globalMatrix)) { return computeLooseOrientedBoundingBox(globalMatrix, result); diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 08018e1daff..4ab10dcb472 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -2,19 +2,19 @@ /* Box defines: #define BOX_INTERSECTION_INDEX ### // always 0 -#define BOX_HAS_RENDER_BOUND +#define BOX_HAS_RENDER_BOUNDS #define BOX_IS_2D */ // Box uniforms: -#if defined(BOX_HAS_RENDER_BOUND) +#if defined(BOX_HAS_RENDER_BOUNDS) #if defined(BOX_IS_2D) // This matrix bakes in an axis conversion so that the math works for XY plane. - uniform mat4 u_boxTransformUvToRenderBounds; + uniform mat4 u_boxUvToRenderBoundsTransform; #else // Similar to u_boxTransformUvToBounds but fewer instructions needed. - uniform vec3 u_boxScaleUvToRenderBounds; - uniform vec3 u_boxOffsetUvToRenderBounds; + uniform vec3 u_boxUvToRenderBoundsScale; + uniform vec3 u_boxUvToRenderBoundsTranslate; #endif #endif @@ -55,17 +55,17 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] void intersectShape(Ray ray, inout Intersections ix) { - #if defined(BOX_HAS_RENDER_BOUND) + #if defined(BOX_HAS_RENDER_BOUNDS) #if defined(BOX_IS_2D) // Transform the ray into unit square space on Z plane // This matrix bakes in an axis conversion so that the math works for XY plane. - ray.pos = vec3(u_boxTransformUvToRenderBounds * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxTransformUvToRenderBounds * vec4(ray.dir, 0.0)); + ray.pos = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.dir, 0.0)); vec2 entryExit = intersectUnitSquare(ray); #else // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxScaleUvToRenderBounds + u_boxOffsetUvToRenderBounds; - ray.dir *= u_boxScaleUvToRenderBounds; + ray.pos = ray.pos * u_boxUvToRenderBoundsScale + u_boxUvToRenderBoundsTranslate; + ray.dir *= u_boxUvToRenderBoundsScale; vec2 entryExit = intersectUnitCube(ray); #endif #else diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl index 09ce687cf1f..7a47fa8389d 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl @@ -1,16 +1,16 @@ /* Box defines: -#define BOX_HAS_SHAPE_BOUND +#define BOX_HAS_SHAPE_BOUNDS */ // Box uniforms: -#if defined(BOX_HAS_SHAPE_BOUND) - uniform vec3 u_boxScaleUvToShapeBoundsUv; - uniform vec3 u_boxOffsetUvToShapeBoundsUv; +#if defined(BOX_HAS_SHAPE_BOUNDS) + uniform vec3 u_boxUvToShapeUvScale; + uniform vec3 u_boxUvToShapeUvTranslate; #endif vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - #if defined(BOX_HAS_SHAPE_BOUND) - return positionUv * u_boxScaleUvToShapeBoundsUv + u_boxOffsetUvToShapeBoundsUv; + #if defined(BOX_HAS_SHAPE_BOUNDS) + return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate; #else return positionUv; #endif From edbc663bf182d46f90e4cbb9bb957509ae6d854a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 30 Dec 2022 14:13:51 -0500 Subject: [PATCH 297/679] Cleanup VoxelEllipsoidShape --- .../engine/Source/Scene/VoxelCylinderShape.js | 186 +++--- .../Source/Scene/VoxelEllipsoidShape.js | 614 ++++++++---------- .../Shaders/Voxels/IntersectCylinder.glsl | 10 +- .../Shaders/Voxels/IntersectEllipsoid.glsl | 4 +- .../Shaders/Voxels/convertUvToCylinder.glsl | 16 +- .../Shaders/Voxels/convertUvToEllipsoid.glsl | 8 +- 6 files changed, 399 insertions(+), 439 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index 9d35f9af7a6..ba5ba554c7d 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -104,7 +104,7 @@ function VoxelCylinderShape() { cylinderUvToShapeUvHeight: new Cartesian2(), cylinderUvToShapeUvAngle: new Cartesian2(), cylinderShapeUvAngleMinMax: new Cartesian2(), - cylinderShapeUvAngleEmptyMid: 0.0, + cylinderShapeUvAngleRangeZeroMid: 0.0, }; /** @@ -118,17 +118,17 @@ function VoxelCylinderShape() { CYLINDER_HAS_RENDER_BOUNDS_HEIGHT: undefined, CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT: undefined, CYLINDER_HAS_RENDER_BOUNDS_ANGLE: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO: undefined, CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF: undefined, + CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF: undefined, CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF: undefined, - CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF: undefined, - CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO: undefined, CYLINDER_HAS_SHAPE_BOUNDS_RADIUS: undefined, CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT: undefined, CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT: undefined, CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT: undefined, CYLINDER_HAS_SHAPE_BOUNDS_ANGLE: undefined, - CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO: undefined, + CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO: undefined, CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY: undefined, CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY: undefined, CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED: undefined, @@ -152,6 +152,7 @@ const scratchBoundsScale = new Cartesian3(); const scratchBoundsScaleMatrix = new Matrix3(); const scratchTransformLocalToBounds = new Matrix4(); const scratchTransformUvToBounds = new Matrix4(); + const transformUvToLocal = Matrix4.fromRotationTranslation( Matrix3.fromUniformScale(2.0, new Matrix3()), new Cartesian3(-1.0, -1.0, -1.0), @@ -196,11 +197,11 @@ VoxelCylinderShape.prototype.update = function ( const defaultMinAngle = VoxelCylinderShape.DefaultMinBounds.z; const defaultMaxAngle = VoxelCylinderShape.DefaultMaxBounds.z; const defaultAngleRange = defaultMaxAngle - defaultMinAngle; - const defaultHalfAngleRange = 0.5 * defaultAngleRange; + const defaultAngleRangeHalf = 0.5 * defaultAngleRange; - const zeroScaleEpsilon = CesiumMath.EPSILON10; - const angleDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees - const angleEpsilon = CesiumMath.EPSILON10; + const epsilonZeroScale = CesiumMath.EPSILON10; + const epsilonAngleDiscontinuity = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const epsilonAngle = CesiumMath.EPSILON10; // Clamp the radii to the valid range const shapeMinRadius = CesiumMath.clamp( @@ -272,9 +273,9 @@ VoxelCylinderShape.prototype.update = function ( renderMaxRadius === 0.0 || renderMinRadius > renderMaxRadius || renderMinHeight > renderMaxHeight || - CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, zeroScaleEpsilon) || - CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, zeroScaleEpsilon) || - CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, zeroScaleEpsilon) + CesiumMath.equalsEpsilon(scale.x, 0.0, undefined, epsilonZeroScale) || + CesiumMath.equalsEpsilon(scale.y, 0.0, undefined, epsilonZeroScale) || + CesiumMath.equalsEpsilon(scale.z, 0.0, undefined, epsilonZeroScale) ) { return false; } @@ -310,67 +311,66 @@ VoxelCylinderShape.prototype.update = function ( this.boundingSphere ); - const isDefaultMaxRadiusShape = shapeMaxRadius === defaultMaxRadius; - const isDefaultMinRadiusShape = shapeMinRadius === defaultMinRadius; - const isDefaultRadiusShape = - isDefaultMinRadiusShape && isDefaultMaxRadiusShape; - const isDefaultMaxRadiusRender = renderMaxRadius === defaultMaxRadius; - const isDefaultMinRadiusRender = renderMinRadius === defaultMinRadius; - const isDefaultHeightShape = + const shapeIsDefaultMaxRadius = shapeMaxRadius === defaultMaxRadius; + const shapeIsDefaultMinRadius = shapeMinRadius === defaultMinRadius; + const shapeIsDefaultRadius = + shapeIsDefaultMinRadius && shapeIsDefaultMaxRadius; + const shapeIsDefaultHeight = shapeMinHeight === defaultMinHeight && shapeMaxHeight === defaultMaxHeight; - const isDefaultHeightRender = - renderMinHeight === defaultMinHeight && - renderMaxHeight === defaultMaxHeight; - - const isAngleReversedShape = shapeMaxAngle < shapeMinAngle; + const shapeIsAngleReversed = shapeMaxAngle < shapeMinAngle; const shapeAngleRange = - shapeMaxAngle - shapeMinAngle + isAngleReversedShape * defaultAngleRange; - const hasAngleRegularShape = - shapeAngleRange > defaultHalfAngleRange + angleEpsilon && - shapeAngleRange < defaultAngleRange - angleEpsilon; - const hasAngleFlippedShape = - shapeAngleRange > angleEpsilon && - shapeAngleRange < defaultHalfAngleRange - angleEpsilon; - const hasAngleFlatShape = - shapeAngleRange >= defaultHalfAngleRange - angleEpsilon && - shapeAngleRange <= defaultHalfAngleRange + angleEpsilon; - const hasAngleEmptyShape = shapeAngleRange <= angleEpsilon; - const hasAngleShape = - hasAngleRegularShape || - hasAngleFlippedShape || - hasAngleFlatShape || - hasAngleEmptyShape; - const hasAngleMinDiscontinuityShape = CesiumMath.equalsEpsilon( + shapeMaxAngle - shapeMinAngle + shapeIsAngleReversed * defaultAngleRange; + const shapeIsAngleRegular = + shapeAngleRange > defaultAngleRangeHalf + epsilonAngle && + shapeAngleRange < defaultAngleRange - epsilonAngle; + const shapeIsAngleFlipped = + shapeAngleRange > epsilonAngle && + shapeAngleRange < defaultAngleRangeHalf - epsilonAngle; + const shapeIsAngleRangeHalf = + shapeAngleRange >= defaultAngleRangeHalf - epsilonAngle && + shapeAngleRange <= defaultAngleRangeHalf + epsilonAngle; + const shapeIsAngleRangeZero = shapeAngleRange <= epsilonAngle; + const shapeHasAngle = + shapeIsAngleRegular || + shapeIsAngleFlipped || + shapeIsAngleRangeHalf || + shapeIsAngleRangeZero; + const shapeIsMinAngleDiscontinuity = CesiumMath.equalsEpsilon( shapeMinAngle, defaultMinAngle, undefined, - angleDiscontinuityEpsilon + epsilonAngleDiscontinuity ); - const hasAngleMaxDiscontinuityShape = CesiumMath.equalsEpsilon( + const shapeIsMaxAngleDiscontinuity = CesiumMath.equalsEpsilon( shapeMaxAngle, defaultMaxAngle, undefined, - angleDiscontinuityEpsilon + epsilonAngleDiscontinuity ); - const isAngleReversedRender = renderMaxAngle < renderMinAngle; + const renderIsDefaultMaxRadius = renderMaxRadius === defaultMaxRadius; + const renderIsDefaultMinRadius = renderMinRadius === defaultMinRadius; + const renderIsDefaultHeight = + renderMinHeight === defaultMinHeight && + renderMaxHeight === defaultMaxHeight; + const renderIsAngleReversed = renderMaxAngle < renderMinAngle; const renderAngleRange = - renderMaxAngle - renderMinAngle + isAngleReversedRender * defaultAngleRange; - const hasAngleRegularRender = - renderAngleRange > defaultHalfAngleRange + angleEpsilon && - renderAngleRange < defaultAngleRange - angleEpsilon; - const hasAngleFlippedRender = - renderAngleRange > angleEpsilon && - renderAngleRange < defaultHalfAngleRange - angleEpsilon; - const hasAngleFlatRender = - renderAngleRange >= defaultHalfAngleRange - angleEpsilon && - renderAngleRange <= defaultHalfAngleRange + angleEpsilon; - const hasAngleEmptyRender = renderAngleRange <= angleEpsilon; - const hasAngleRender = - hasAngleRegularRender || - hasAngleFlippedRender || - hasAngleFlatRender || - hasAngleEmptyRender; + renderMaxAngle - renderMinAngle + renderIsAngleReversed * defaultAngleRange; + const renderIsAngleRegular = + renderAngleRange > defaultAngleRangeHalf + epsilonAngle && + renderAngleRange < defaultAngleRange - epsilonAngle; + const renderIsAngleFlipped = + renderAngleRange > epsilonAngle && + renderAngleRange < defaultAngleRangeHalf - epsilonAngle; + const renderIsAngleRangeHalf = + renderAngleRange >= defaultAngleRangeHalf - epsilonAngle && + renderAngleRange <= defaultAngleRangeHalf + epsilonAngle; + const renderIsAngleRangeZero = renderAngleRange <= epsilonAngle; + const renderHasAngle = + renderIsAngleRegular || + renderIsAngleFlipped || + renderIsAngleRangeHalf || + renderIsAngleRangeZero; const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; @@ -388,7 +388,7 @@ VoxelCylinderShape.prototype.update = function ( shaderDefines["CYLINDER_INTERSECTION_INDEX_RADIUS_MAX"] = intersectionCount; intersectionCount += 1; - if (!isDefaultMinRadiusRender) { + if (!renderIsDefaultMinRadius) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN"] = true; shaderDefines["CYLINDER_INTERSECTION_INDEX_RADIUS_MIN"] = intersectionCount; intersectionCount += 1; @@ -396,13 +396,13 @@ VoxelCylinderShape.prototype.update = function ( shaderUniforms.cylinderUvToRenderRadiusMin = renderMaxRadius / renderMinRadius; } - if (!isDefaultMaxRadiusRender) { + if (!renderIsDefaultMaxRadius) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX"] = true; } if (renderMinRadius === renderMaxRadius) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT"] = true; } - if (!isDefaultHeightRender) { + if (!renderIsDefaultHeight) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_HEIGHT"] = true; } if (renderMinHeight === renderMaxHeight) { @@ -414,7 +414,7 @@ VoxelCylinderShape.prototype.update = function ( if (shapeMinRadius === shapeMaxRadius) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT"] = true; } - if (!isDefaultRadiusShape) { + if (!shapeIsDefaultRadius) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_RADIUS"] = true; // delerp(radius, minRadius, maxRadius) @@ -432,7 +432,7 @@ VoxelCylinderShape.prototype.update = function ( ); } - if (!isDefaultHeightShape) { + if (!shapeIsDefaultHeight) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT"] = true; // delerp(heightUv, minHeightUv, maxHeightUv) @@ -455,7 +455,7 @@ VoxelCylinderShape.prototype.update = function ( ); } - if (!isDefaultMaxRadiusRender || !isDefaultHeightRender) { + if (!renderIsDefaultMaxRadius || !renderIsDefaultHeight) { const heightScale = 0.5 * (renderMaxHeight - renderMinHeight); const scaleLocalToBounds = Cartesian3.fromElements( 1.0 / renderMaxRadius, @@ -491,25 +491,25 @@ VoxelCylinderShape.prototype.update = function ( ); } - if (isAngleReversedShape) { + if (shapeIsAngleReversed) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED"] = true; } - if (hasAngleRender) { + if (renderHasAngle) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE"] = true; shaderDefines["CYLINDER_INTERSECTION_INDEX_ANGLE"] = intersectionCount; - if (hasAngleRegularRender) { + if (renderIsAngleRegular) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF"] = true; intersectionCount += 1; - } else if (hasAngleFlippedRender) { + } else if (renderIsAngleFlipped) { shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF"] = true; intersectionCount += 2; - } else if (hasAngleFlatRender) { - shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF"] = true; + } else if (renderIsAngleRangeHalf) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF"] = true; intersectionCount += 1; - } else if (hasAngleEmptyRender) { - shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO"] = true; + } else if (renderIsAngleRangeZero) { + shaderDefines["CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO"] = true; intersectionCount += 2; } @@ -520,37 +520,37 @@ VoxelCylinderShape.prototype.update = function ( ); } - if (hasAngleShape) { + if (shapeHasAngle) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE"] = true; - if (hasAngleEmptyShape) { - shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO"] = true; + if (shapeIsAngleRangeZero) { + shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO"] = true; } - if (hasAngleMinDiscontinuityShape) { + if (shapeIsMinAngleDiscontinuity) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY"] = true; } - if (hasAngleMaxDiscontinuityShape) { + if (shapeIsMaxAngleDiscontinuity) { shaderDefines["CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY"] = true; } - const minAngleUv = (shapeMinAngle - defaultMinAngle) / defaultAngleRange; - const maxAngleUv = (shapeMaxAngle - defaultMinAngle) / defaultAngleRange; - const emptyAngleRangeUv = 1.0 - shapeAngleRange / defaultAngleRange; + const uvMinAngle = (shapeMinAngle - defaultMinAngle) / defaultAngleRange; + const uvMaxAngle = (shapeMaxAngle - defaultMinAngle) / defaultAngleRange; + const uvAngleRangeZero = 1.0 - shapeAngleRange / defaultAngleRange; shaderUniforms.cylinderShapeUvAngleMinMax = Cartesian2.fromElements( - minAngleUv, - maxAngleUv, + uvMinAngle, + uvMaxAngle, shaderUniforms.cylinderShapeUvAngleMinMax ); - shaderUniforms.cylinderShapeUvAngleEmptyMid = - (maxAngleUv + 0.5 * emptyAngleRangeUv) % 1.0; + shaderUniforms.cylinderShapeUvAngleRangeZeroMid = + (uvMaxAngle + 0.5 * uvAngleRangeZero) % 1.0; - // delerp(angleUv, minAngleUv, maxAngleUv) - // (angelUv - minAngleUv) / (maxAngleUv - minAngleUv) - // angleUv / (maxAngleUv - minAngleUv) - minAngleUv / (maxAngleUv - minAngleUv) - // scale = 1.0 / (maxAngleUv - minAngleUv) + // delerp(angleUv, uvMinAngle, uvMaxAngle) + // (angelUv - uvMinAngle) / (uvMaxAngle - uvMinAngle) + // angleUv / (uvMaxAngle - uvMinAngle) - uvMinAngle / (uvMaxAngle - uvMinAngle) + // scale = 1.0 / (uvMaxAngle - uvMinAngle) // scale = 1.0 / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // scale = 2.0 * pi / (maxAngle - minAngle) - // offset = -minAngleUv / (maxAngleUv - minAngleUv) + // offset = -uvMinAngle / (uvMaxAngle - uvMinAngle) // offset = -((minAngle - pi) / (2.0 * pi)) / (((maxAngle - pi) / (2.0 * pi)) - ((minAngle - pi) / (2.0 * pi))) // offset = -(minAngle - pi) / (maxAngle - minAngle) const scale = defaultAngleRange / shapeAngleRange; @@ -829,9 +829,9 @@ function getCylinderChunkObb( return result; } - const isAngleFlipped = angleEnd < angleStart; + const isAngleReversed = angleEnd < angleStart; - if (isAngleFlipped) { + if (isAngleReversed) { angleEnd += CesiumMath.TWO_PI; } diff --git a/packages/engine/Source/Scene/VoxelEllipsoidShape.js b/packages/engine/Source/Scene/VoxelEllipsoidShape.js index 5cdc0f87ee3..8a111f2406d 100644 --- a/packages/engine/Source/Scene/VoxelEllipsoidShape.js +++ b/packages/engine/Source/Scene/VoxelEllipsoidShape.js @@ -133,7 +133,7 @@ function VoxelEllipsoidShape() { ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO: undefined, ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN: undefined, ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN: undefined, - ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO: undefined, + ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT: undefined, ELLIPSOID_IS_SPHERE: undefined, ELLIPSOID_INTERSECTION_INDEX_LONGITUDE: undefined, ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX: undefined, @@ -152,10 +152,11 @@ function VoxelEllipsoidShape() { const scratchScale = new Cartesian3(); const scratchRotationScale = new Matrix3(); -const scratchOuterExtentShape = new Cartesian3(); -const scratchInnerExtentShape = new Cartesian3(); -const scratchOuterExtentRender = new Cartesian3(); -const scratchInnerExtentRender = new Cartesian3(); +const scratchShapeOuterExtent = new Cartesian3(); +const scratchShapeInnerExtent = new Cartesian3(); +const scratchRenderOuterExtent = new Cartesian3(); +const scratchRenderInnerExtent = new Cartesian3(); +const scratchRenderRectangle = new Rectangle(); /** * Update the shape's state. @@ -176,208 +177,177 @@ VoxelEllipsoidShape.prototype.update = function ( ) { clipMinBounds = defaultValue( clipMinBounds, - VoxelEllipsoidShape.DefaultMinBounds.clone() + VoxelEllipsoidShape.DefaultMinBounds ); clipMaxBounds = defaultValue( clipMaxBounds, - VoxelEllipsoidShape.DefaultMaxBounds.clone() + VoxelEllipsoidShape.DefaultMaxBounds ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("modelMatrix", modelMatrix); Check.typeOf.object("minBounds", minBounds); Check.typeOf.object("maxBounds", maxBounds); - Check.typeOf.object("clipMinBounds", clipMinBounds); - Check.typeOf.object("clipMaxBounds", clipMaxBounds); //>>includeEnd('debug'); - const zeroScaleEpsilon = CesiumMath.EPSILON10; - const longitudeDiscontinuityEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees - const longitudeEpsilon = CesiumMath.EPSILON10; - const latitudeEpsilon = CesiumMath.EPSILON10; - const flatLatitudeEpsilon = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const defaultMinLongitude = VoxelEllipsoidShape.DefaultMinBounds.x; + const defaultMaxLongitude = VoxelEllipsoidShape.DefaultMaxBounds.x; + const defaultLongitudeRange = defaultMaxLongitude - defaultMinLongitude; + const defaultLongitudeRangeHalf = 0.5 * defaultLongitudeRange; + const defaultMinLatitude = VoxelEllipsoidShape.DefaultMinBounds.y; + const defaultMaxLatitude = VoxelEllipsoidShape.DefaultMaxBounds.y; + const defaultLatitudeRange = defaultMaxLatitude - defaultMinLatitude; - const longitudeMinDefault = VoxelEllipsoidShape.DefaultMinBounds.x; - const longitudeMaxDefault = VoxelEllipsoidShape.DefaultMaxBounds.x; - const longitudeRangeDefault = longitudeMaxDefault - longitudeMinDefault; - const longitudeHalfRangeDefault = 0.5 * longitudeRangeDefault; - const latitudeMinDefault = VoxelEllipsoidShape.DefaultMinBounds.y; - const latitudeMaxDefault = VoxelEllipsoidShape.DefaultMaxBounds.y; - const latitudeRangeDefault = latitudeMaxDefault - latitudeMinDefault; + const epsilonZeroScale = CesiumMath.EPSILON10; + const epsilonLongitudeDiscontinuity = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees + const epsilonLongitude = CesiumMath.EPSILON10; + const epsilonLatitude = CesiumMath.EPSILON10; + const epsilonLatitudeFlat = CesiumMath.EPSILON3; // 0.001 radians = 0.05729578 degrees // Clamp the longitude / latitude to the valid range - const longitudeMinShape = CesiumMath.clamp( + const shapeMinLongitude = CesiumMath.clamp( minBounds.x, - longitudeMinDefault, - longitudeMaxDefault + defaultMinLongitude, + defaultMaxLongitude ); - const longitudeMaxShape = CesiumMath.clamp( + const shapeMaxLongitude = CesiumMath.clamp( maxBounds.x, - longitudeMinDefault, - longitudeMaxDefault + defaultMinLongitude, + defaultMaxLongitude ); - const longitudeMinClip = CesiumMath.clamp( + const clipMinLongitude = CesiumMath.clamp( clipMinBounds.x, - longitudeMinDefault, - longitudeMaxDefault + defaultMinLongitude, + defaultMaxLongitude ); - const longitudeMaxClip = CesiumMath.clamp( + const clipMaxLongitude = CesiumMath.clamp( clipMaxBounds.x, - longitudeMinDefault, - longitudeMaxDefault - ); - const longitudeMinRender = CesiumMath.clamp( - longitudeMinClip, - longitudeMinShape, - longitudeMaxShape - ); - const longitudeMaxRender = CesiumMath.clamp( - longitudeMaxShape, - longitudeMinClip, - longitudeMaxClip + defaultMinLongitude, + defaultMaxLongitude ); + const renderMinLongitude = Math.max(shapeMinLongitude, clipMinLongitude); + const renderMaxLongitude = Math.min(shapeMaxLongitude, clipMaxLongitude); - const latitudeMinShape = CesiumMath.clamp( + const shapeMinLatitude = CesiumMath.clamp( minBounds.y, - latitudeMinDefault, - latitudeMaxDefault + defaultMinLatitude, + defaultMaxLatitude ); - const latitudeMaxShape = CesiumMath.clamp( + const shapeMaxLatitude = CesiumMath.clamp( maxBounds.y, - latitudeMinDefault, - latitudeMaxDefault + defaultMinLatitude, + defaultMaxLatitude ); - const latitudeMinClip = CesiumMath.clamp( + const clipMinLatitude = CesiumMath.clamp( clipMinBounds.y, - latitudeMinDefault, - latitudeMaxDefault + defaultMinLatitude, + defaultMaxLatitude ); - const latitudeMaxClip = CesiumMath.clamp( + const clipMaxLatitude = CesiumMath.clamp( clipMaxBounds.y, - latitudeMinDefault, - latitudeMaxDefault - ); - const latitudeMinRender = CesiumMath.clamp( - latitudeMinClip, - latitudeMinShape, - latitudeMaxShape - ); - const latitudeMaxRender = CesiumMath.clamp( - latitudeMaxShape, - latitudeMinClip, - latitudeMaxClip + defaultMinLatitude, + defaultMaxLatitude ); + const renderMinLatitude = Math.max(shapeMinLatitude, clipMinLatitude); + const renderMaxLatitude = Math.min(shapeMaxLatitude, clipMaxLatitude); + // Don't let the height go below the center of the ellipsoid. const radii = Matrix4.getScale(modelMatrix, scratchScale); const isSphere = radii.x === radii.y && radii.y === radii.z; const minRadius = Cartesian3.minimumComponent(radii); - const minHeightShape = Math.max(minBounds.z, -minRadius); - const maxHeightShape = Math.max(maxBounds.z, -minRadius); - const minHeightClip = Math.max(clipMinBounds.z, -minRadius); - const maxHeightClip = Math.max(clipMaxBounds.z, -minRadius); - const minHeightRender = CesiumMath.clamp( - minHeightShape, - minHeightClip, - maxHeightClip - ); - const maxHeightRender = CesiumMath.clamp( - maxHeightShape, - minHeightClip, - maxHeightClip - ); + const shapeMinHeight = Math.max(minBounds.z, -minRadius); + const shapeMaxHeight = Math.max(maxBounds.z, -minRadius); + const clipMinHeight = Math.max(clipMinBounds.z, -minRadius); + const clipMaxHeight = Math.max(clipMaxBounds.z, -minRadius); + const renderMinHeight = Math.max(shapeMinHeight, clipMinHeight); + const renderMaxHeight = Math.min(shapeMaxHeight, clipMaxHeight); // Compute the closest and farthest a point can be from the center of the ellipsoid. - const innerExtentShape = Cartesian3.add( + const shapeInnerExtent = Cartesian3.add( radii, Cartesian3.fromElements( - minHeightShape, - minHeightShape, - minHeightShape, - scratchInnerExtentShape + shapeMinHeight, + shapeMinHeight, + shapeMinHeight, + scratchShapeInnerExtent ), - scratchInnerExtentShape + scratchShapeInnerExtent ); - const outerExtentShape = Cartesian3.add( + const shapeOuterExtent = Cartesian3.add( radii, Cartesian3.fromElements( - maxHeightShape, - maxHeightShape, - maxHeightShape, - scratchOuterExtentShape + shapeMaxHeight, + shapeMaxHeight, + shapeMaxHeight, + scratchShapeOuterExtent ), - scratchOuterExtentShape + scratchShapeOuterExtent ); - const maxExtentShape = Cartesian3.maximumComponent(outerExtentShape); + const shapeMaxExtent = Cartesian3.maximumComponent(shapeOuterExtent); - const innerExtentRender = Cartesian3.add( + const renderInnerExtent = Cartesian3.add( radii, Cartesian3.fromElements( - minHeightRender, - minHeightRender, - minHeightRender, - scratchInnerExtentRender + renderMinHeight, + renderMinHeight, + renderMinHeight, + scratchRenderInnerExtent ), - scratchInnerExtentRender + scratchRenderInnerExtent ); - const outerExtentRender = Cartesian3.add( + const renderOuterExtent = Cartesian3.add( radii, Cartesian3.fromElements( - maxHeightRender, - maxHeightRender, - maxHeightRender, - scratchOuterExtentRender + renderMaxHeight, + renderMaxHeight, + renderMaxHeight, + scratchRenderOuterExtent ), - scratchOuterExtentRender + scratchRenderOuterExtent ); - const maxExtentRender = Cartesian3.maximumComponent(outerExtentRender); + const renderMaxExtent = Cartesian3.maximumComponent(renderOuterExtent); // Exit early if the shape is not visible. // Note that minLongitude may be greater than maxLongitude when crossing the 180th meridian. if ( - latitudeMinRender > latitudeMaxRender || - latitudeMinRender === latitudeMaxDefault || - latitudeMaxRender === latitudeMinDefault || - minHeightRender > maxHeightRender || - maxHeightShape < minHeightClip || - minHeightShape > maxHeightClip || - CesiumMath.equalsEpsilon( - outerExtentRender.x, - 0.0, - undefined, - zeroScaleEpsilon - ) || + renderMinLatitude > renderMaxLatitude || + renderMinLatitude === defaultMaxLatitude || + renderMaxLatitude === defaultMinLatitude || + renderMinHeight > renderMaxHeight || CesiumMath.equalsEpsilon( - outerExtentRender.y, - 0.0, + renderOuterExtent, + Cartesian3.ZERO, undefined, - zeroScaleEpsilon - ) || - CesiumMath.equalsEpsilon( - outerExtentRender.z, - 0.0, - undefined, - zeroScaleEpsilon + epsilonZeroScale ) ) { return false; } this._rectangle = Rectangle.fromRadians( - longitudeMinShape, - latitudeMinShape, - longitudeMaxShape, - latitudeMaxShape + shapeMinLongitude, + shapeMinLatitude, + shapeMaxLongitude, + shapeMaxLatitude ); this._translation = Matrix4.getTranslation(modelMatrix, this._translation); this._rotation = Matrix4.getRotation(modelMatrix, this._rotation); this._ellipsoid = Ellipsoid.fromCartesian3(radii, this._ellipsoid); - this._minimumHeight = minHeightShape; - this._maximumHeight = maxHeightShape; + this._minimumHeight = shapeMinHeight; + this._maximumHeight = shapeMaxHeight; + + const renderRectangle = Rectangle.fromRadians( + renderMinLongitude, + renderMinLatitude, + renderMaxLongitude, + renderMaxLatitude, + scratchRenderRectangle + ); this.orientedBoundingBox = getEllipsoidChunkObb( - this._rectangle, - this._minimumHeight, - this._maximumHeight, + renderRectangle, + renderMinHeight, + renderMaxHeight, this._ellipsoid, this._translation, this._rotation, @@ -385,7 +355,7 @@ VoxelEllipsoidShape.prototype.update = function ( ); this.shapeTransform = Matrix4.fromRotationTranslation( - Matrix3.setScale(this._rotation, outerExtentRender, scratchRotationScale), + Matrix3.setScale(this._rotation, renderOuterExtent, scratchRotationScale), this._translation, this.shapeTransform ); @@ -401,6 +371,120 @@ VoxelEllipsoidShape.prototype.update = function ( this.boundingSphere ); + // Longitude + const renderIsLongitudeReversed = renderMaxLongitude < renderMinLongitude; + const renderLongitudeRange = + renderMaxLongitude - + renderMinLongitude + + renderIsLongitudeReversed * defaultLongitudeRange; + const renderIsLongitudeRangeZero = renderLongitudeRange <= epsilonLongitude; + const renderIsLongitudeRangeUnderHalf = + renderLongitudeRange > defaultLongitudeRangeHalf + epsilonLongitude && + renderLongitudeRange < defaultLongitudeRange - epsilonLongitude; + const renderIsLongitudeRangeHalf = + renderLongitudeRange >= defaultLongitudeRangeHalf - epsilonLongitude && + renderLongitudeRange <= defaultLongitudeRangeHalf + epsilonLongitude; + const renderIsLongitudeRangeOverHalf = + renderLongitudeRange > epsilonLongitude && + renderLongitudeRange < defaultLongitudeRangeHalf - epsilonLongitude; + const renderHasLongitude = + renderIsLongitudeRangeZero || + renderIsLongitudeRangeUnderHalf || + renderIsLongitudeRangeHalf || + renderIsLongitudeRangeOverHalf; + + const shapeIsLongitudeReversed = renderMaxLongitude < renderMinLongitude; + const shapeLongitudeRange = + shapeMaxLongitude - + shapeMinLongitude + + shapeIsLongitudeReversed * defaultLongitudeRange; + const shapeIsLongitudeRangeZero = shapeLongitudeRange <= epsilonLongitude; + const shapeIsLongitudeRangeUnderHalf = + shapeLongitudeRange > defaultLongitudeRangeHalf + epsilonLongitude && + shapeLongitudeRange < defaultLongitudeRange - epsilonLongitude; + const shapeIsLongitudeRangeHalf = + shapeLongitudeRange >= defaultLongitudeRangeHalf - epsilonLongitude && + shapeLongitudeRange <= defaultLongitudeRangeHalf + epsilonLongitude; + const shapeIsLongitudeRangeOverHalf = + shapeLongitudeRange > epsilonLongitude && + shapeLongitudeRange < defaultLongitudeRangeHalf - epsilonLongitude; + const shapeHasLongitude = + shapeIsLongitudeRangeZero || + shapeIsLongitudeRangeUnderHalf || + shapeIsLongitudeRangeHalf || + shapeIsLongitudeRangeOverHalf; + + // Latitude + const renderIsLatitudeMaxUnderHalf = renderMaxLatitude < -epsilonLatitudeFlat; + const renderIsLatitudeMaxHalf = + renderMaxLatitude >= -epsilonLatitudeFlat && + renderMaxLatitude <= +epsilonLatitudeFlat; + const renderIsLatitudeMaxOverHalf = + renderMaxLatitude > +epsilonLatitudeFlat && + renderMaxLatitude < defaultMaxLatitude - epsilonLatitude; + const renderHasLatitudeMax = + renderIsLatitudeMaxUnderHalf || + renderIsLatitudeMaxHalf || + renderIsLatitudeMaxOverHalf; + const renderIsLatitudeMinUnderHalf = + renderMinLatitude > defaultMinLatitude + epsilonLatitude && + renderMinLatitude < -epsilonLatitudeFlat; + const renderIsLatitudeMinHalf = + renderMinLatitude >= -epsilonLatitudeFlat && + renderMinLatitude <= +epsilonLatitudeFlat; + const renderIsLatitudeMinOverHalf = renderMinLatitude > +epsilonLatitudeFlat; + const renderHasLatitudeMin = + renderIsLatitudeMinUnderHalf || + renderIsLatitudeMinHalf || + renderIsLatitudeMinOverHalf; + const renderHasLatitude = renderHasLatitudeMax || renderHasLatitudeMin; + + const shapeLatitudeRange = shapeMaxLatitude - shapeMinLatitude; + const shapeIsLatitudeMaxUnderHalf = shapeMaxLatitude < -epsilonLatitudeFlat; + const shapeIsLatitudeMaxHalf = + shapeMaxLatitude >= -epsilonLatitudeFlat && + shapeMaxLatitude <= +epsilonLatitudeFlat; + const shapeIsLatitudeMaxOverHalf = + shapeMaxLatitude > +epsilonLatitudeFlat && + shapeMaxLatitude < defaultMaxLatitude - epsilonLatitude; + const shapeHasLatitudeMax = + shapeIsLatitudeMaxUnderHalf || + shapeIsLatitudeMaxHalf || + shapeIsLatitudeMaxOverHalf; + const shapeIsLatitudeMinUnderHalf = + shapeMinLatitude > defaultMinLatitude + epsilonLatitude && + shapeMinLatitude < -epsilonLatitudeFlat; + const shapeIsLatitudeMinHalf = + shapeMinLatitude >= -epsilonLatitudeFlat && + shapeMinLatitude <= +epsilonLatitudeFlat; + const shapeIsLatitudeMinOverHalf = shapeMinLatitude > +epsilonLatitudeFlat; + const shapeHasLatitudeMin = + shapeIsLatitudeMinUnderHalf || + shapeIsLatitudeMinHalf || + shapeIsLatitudeMinOverHalf; + const shapeHasLatitude = shapeHasLatitudeMax || shapeHasLatitudeMin; + + // Height + const renderHasMinHeight = !Cartesian3.equals( + renderInnerExtent, + Cartesian3.ZERO + ); + const renderHasMaxHeight = !Cartesian3.equals( + renderOuterExtent, + Cartesian3.ZERO + ); + const renderHasHeight = renderHasMinHeight || renderHasMaxHeight; + const renderHeightRange = renderMaxHeight - renderMinHeight; + const shapeHasMinHeight = !Cartesian3.equals( + shapeInnerExtent, + Cartesian3.ZERO + ); + const shapeHasMaxHeight = !Cartesian3.equals( + shapeOuterExtent, + Cartesian3.ZERO + ); + const shapeHasHeight = shapeHasMinHeight || shapeHasMaxHeight; + const shaderUniforms = this.shaderUniforms; const shaderDefines = this.shaderDefines; @@ -413,8 +497,8 @@ VoxelEllipsoidShape.prototype.update = function ( // The ellipsoid radii scaled to [0,1]. The max ellipsoid radius will be 1.0 and others will be less. shaderUniforms.ellipsoidRadiiUv = Cartesian3.divideByScalar( - outerExtentShape, - maxExtentShape, + shapeOuterExtent, + shapeMaxExtent, shaderUniforms.ellipsoidRadiiUv ); @@ -429,125 +513,6 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipsoidInverseRadiiSquaredUv ); - // Longitude - const isLongitudeMinMaxReversedRender = - longitudeMaxRender < longitudeMinRender; - const longitudeRangeRender = - longitudeMaxRender - - longitudeMinRender + - isLongitudeMinMaxReversedRender * longitudeRangeDefault; - const hasLongitudeRangeEqualZeroRender = - longitudeRangeRender <= longitudeEpsilon; - const hasLongitudeRangeUnderHalfRender = - longitudeRangeRender > longitudeHalfRangeDefault + longitudeEpsilon && - longitudeRangeRender < longitudeRangeDefault - longitudeEpsilon; - const hasLongitudeRangeEqualHalfRender = - longitudeRangeRender >= longitudeHalfRangeDefault - longitudeEpsilon && - longitudeRangeRender <= longitudeHalfRangeDefault + longitudeEpsilon; - const hasLongitudeRangeOverHalfRender = - longitudeRangeRender > longitudeEpsilon && - longitudeRangeRender < longitudeHalfRangeDefault - longitudeEpsilon; - const hasLongitudeRender = - hasLongitudeRangeEqualZeroRender || - hasLongitudeRangeUnderHalfRender || - hasLongitudeRangeEqualHalfRender || - hasLongitudeRangeOverHalfRender; - - const isLongitudeMinMaxReversedShape = - longitudeMaxRender < longitudeMinRender; - const longitudeRangeShape = - longitudeMaxShape - - longitudeMinShape + - isLongitudeMinMaxReversedShape * longitudeRangeDefault; - const hasLongitudeRangeEqualZeroShape = - longitudeRangeShape <= longitudeEpsilon; - const hasLongitudeRangeUnderHalfShape = - longitudeRangeShape > longitudeHalfRangeDefault + longitudeEpsilon && - longitudeRangeShape < longitudeRangeDefault - longitudeEpsilon; - const hasLongitudeRangeEqualHalfShape = - longitudeRangeShape >= longitudeHalfRangeDefault - longitudeEpsilon && - longitudeRangeShape <= longitudeHalfRangeDefault + longitudeEpsilon; - const hasLongitudeRangeOverHalfShape = - longitudeRangeShape > longitudeEpsilon && - longitudeRangeShape < longitudeHalfRangeDefault - longitudeEpsilon; - const hasLongitudeShape = - hasLongitudeRangeEqualZeroShape || - hasLongitudeRangeUnderHalfShape || - hasLongitudeRangeEqualHalfShape || - hasLongitudeRangeOverHalfShape; - - // Latitude - const hasLatitudeMaxUnderHalfRender = - latitudeMaxRender < -flatLatitudeEpsilon; - const hasLatitudeMaxEqualHalfRender = - latitudeMaxRender >= -flatLatitudeEpsilon && - latitudeMaxRender <= +flatLatitudeEpsilon; - const hasLatitudeMaxOverHalfRender = - latitudeMaxRender > +flatLatitudeEpsilon && - latitudeMaxRender < latitudeMaxDefault - latitudeEpsilon; - const hasLatitudeMaxRender = - hasLatitudeMaxUnderHalfRender || - hasLatitudeMaxEqualHalfRender || - hasLatitudeMaxOverHalfRender; - const hasLatitudeMinUnderHalfRender = - latitudeMinRender > latitudeMinDefault + latitudeEpsilon && - latitudeMinRender < -flatLatitudeEpsilon; - const hasLatitudeMinEqualHalfRender = - latitudeMinRender >= -flatLatitudeEpsilon && - latitudeMinRender <= +flatLatitudeEpsilon; - const hasLatitudeMinOverHalfRender = latitudeMinRender > +flatLatitudeEpsilon; - const hasLatitudeMinRender = - hasLatitudeMinUnderHalfRender || - hasLatitudeMinEqualHalfRender || - hasLatitudeMinOverHalfRender; - const hasLatitudeRender = hasLatitudeMaxRender || hasLatitudeMinRender; - - const latitudeRangeShape = latitudeMaxShape - latitudeMinShape; - const hasLatitudeMaxUnderHalfShape = latitudeMaxShape < -flatLatitudeEpsilon; - const hasLatitudeMaxEqualHalfShape = - latitudeMaxShape >= -flatLatitudeEpsilon && - latitudeMaxShape <= +flatLatitudeEpsilon; - const hasLatitudeMaxOverHalfShape = - latitudeMaxShape > +flatLatitudeEpsilon && - latitudeMaxShape < latitudeMaxDefault - latitudeEpsilon; - const hasLatitudeMaxShape = - hasLatitudeMaxUnderHalfShape || - hasLatitudeMaxEqualHalfShape || - hasLatitudeMaxOverHalfShape; - const hasLatitudeMinUnderHalfShape = - latitudeMinShape > latitudeMinDefault + latitudeEpsilon && - latitudeMinShape < -flatLatitudeEpsilon; - const hasLatitudeMinEqualHalfShape = - latitudeMinShape >= -flatLatitudeEpsilon && - latitudeMinShape <= +flatLatitudeEpsilon; - const hasLatitudeMinOverHalfShape = latitudeMinShape > +flatLatitudeEpsilon; - const hasLatitudeMinShape = - hasLatitudeMinUnderHalfShape || - hasLatitudeMinEqualHalfShape || - hasLatitudeMinOverHalfShape; - const hasLatitudeShape = hasLatitudeMaxShape || hasLatitudeMinShape; - - // Height - const hasHeightMinRender = !Cartesian3.equals( - innerExtentRender, - Cartesian3.ZERO - ); - const hasHeightMaxRender = !Cartesian3.equals( - outerExtentRender, - Cartesian3.ZERO - ); - const hasHeightRender = hasHeightMinRender || hasHeightMaxRender; - const heightRangeRender = maxHeightRender - minHeightRender; - const hasHeightMinShape = !Cartesian3.equals( - innerExtentShape, - Cartesian3.ZERO - ); - const hasHeightMaxShape = !Cartesian3.equals( - outerExtentShape, - Cartesian3.ZERO - ); - const hasHeightShape = hasHeightMinShape || hasHeightMaxShape; - // Keep track of how many intersections there are going to be. let intersectionCount = 0; @@ -555,14 +520,12 @@ VoxelEllipsoidShape.prototype.update = function ( shaderDefines["ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MAX"] = intersectionCount; intersectionCount += 1; - if (hasHeightRender) { - if (heightRangeRender === 0.0) { - shaderDefines[ - "ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO" - ] = true; + if (renderHasHeight) { + if (renderHeightRange === 0.0) { + shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_FLAT"] = true; } - if (hasHeightMinRender) { + if (renderHasMinHeight) { shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN"] = true; shaderDefines[ "ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN" @@ -571,19 +534,19 @@ VoxelEllipsoidShape.prototype.update = function ( // The inverse of the percent of space that is taken up by the inner ellipsoid. // 1.0 / (1.0 - thickness) // thickness = percent of space that is between the min and max height. - // 1.0 / (1.0 - (maxHeightRender - minHeightRender) / maxExtentRender) - // maxExtentRender / (maxExtentRender - (maxHeightRender - minHeightRender)) + // 1.0 / (1.0 - (renderMaxHeight - renderMinHeight) / renderMaxExtent) + // renderMaxExtent / (renderMaxExtent - (renderMaxHeight - renderMinHeight)) shaderUniforms.ellipsoidInverseInnerScaleUv = - maxExtentRender / (maxExtentRender - heightRangeRender); + renderMaxExtent / (renderMaxExtent - renderHeightRange); } } - if (hasHeightShape) { - if (hasHeightMinShape) { + if (shapeHasHeight) { + if (shapeHasMinHeight) { shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN"] = true; // The percent of space that is between the inner and outer ellipsoid. - const thickness = (maxHeightShape - minHeightShape) / maxExtentShape; + const thickness = (shapeMaxHeight - shapeMinHeight) / shapeMaxExtent; shaderUniforms.ellipsoidInverseHeightDifferenceUv = 1.0 / thickness; shaderUniforms.ellipseInnerRadiiUv = Cartesian2.fromElements( shaderUniforms.ellipsoidRadiiUv.x * (1.0 - thickness), @@ -591,34 +554,32 @@ VoxelEllipsoidShape.prototype.update = function ( shaderUniforms.ellipseInnerRadiiUv ); } - if (minHeightShape === maxHeightShape) { - shaderDefines[ - "ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO" - ] = true; + if (shapeMinHeight === shapeMaxHeight) { + shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT"] = true; } } // Intersects a wedge for the min and max longitude. - if (hasLongitudeRender) { + if (renderHasLongitude) { shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE"] = true; shaderDefines["ELLIPSOID_INTERSECTION_INDEX_LONGITUDE"] = intersectionCount; - if (hasLongitudeRangeUnderHalfRender) { + if (renderIsLongitudeRangeUnderHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_UNDER_HALF" ] = true; intersectionCount += 1; - } else if (hasLongitudeRangeOverHalfRender) { + } else if (renderIsLongitudeRangeOverHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_OVER_HALF" ] = true; intersectionCount += 2; - } else if (hasLongitudeRangeEqualHalfRender) { + } else if (renderIsLongitudeRangeHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_HALF" ] = true; intersectionCount += 1; - } else if (hasLongitudeRangeEqualZeroRender) { + } else if (renderIsLongitudeRangeZero) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_RANGE_EQUAL_ZERO" ] = true; @@ -626,19 +587,18 @@ VoxelEllipsoidShape.prototype.update = function ( } shaderUniforms.ellipsoidRenderLongitudeMinMax = Cartesian2.fromElements( - longitudeMinRender, - longitudeMaxRender, + renderMinLongitude, + renderMaxLongitude, shaderUniforms.ellipsoidRenderLongitudeMinMax ); } - if (hasLongitudeShape) { + if (shapeHasLongitude) { shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE"] = true; - const isLongitudeMinMaxReversedShape = - longitudeMaxShape < longitudeMinShape; + const shapeIsLongitudeReversed = shapeMaxLongitude < shapeMinLongitude; - if (isLongitudeMinMaxReversedShape) { + if (shapeIsLongitudeReversed) { shaderDefines[ "ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE_MIN_MAX_REVERSED" ] = true; @@ -653,9 +613,9 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = -minLongitudeUv / (maxLongitudeUv - minLongitudeUv) // offset = -((minLongitude - pi) / (2.0 * pi)) / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi))) // offset = -(minLongitude - pi) / (maxLongitude - minLongitude) - const scale = longitudeRangeDefault / longitudeRangeShape; + const scale = defaultLongitudeRange / shapeLongitudeRange; const offset = - -(longitudeMinShape - longitudeMinDefault) / longitudeRangeShape; + -(shapeMinLongitude - defaultMinLongitude) / shapeLongitudeRange; shaderUniforms.ellipsoidUvToShapeUvLongitude = Cartesian2.fromElements( scale, offset, @@ -663,71 +623,71 @@ VoxelEllipsoidShape.prototype.update = function ( ); } - if (hasLongitudeShape || hasLongitudeRender) { - const isMinLongitudeDiscontinuityRender = CesiumMath.equalsEpsilon( - longitudeMinRender, - longitudeMinDefault, + if (renderHasLongitude) { + const renderIsMinLongitudeDiscontinuity = CesiumMath.equalsEpsilon( + renderMinLongitude, + defaultMinLongitude, undefined, - longitudeDiscontinuityEpsilon + epsilonLongitudeDiscontinuity ); - const isMaxLongitudeDiscontinuityRender = CesiumMath.equalsEpsilon( - longitudeMaxRender, - longitudeMaxDefault, + const renderIsMaxLongitudeDiscontinuity = CesiumMath.equalsEpsilon( + renderMaxLongitude, + defaultMaxLongitude, undefined, - longitudeDiscontinuityEpsilon + epsilonLongitudeDiscontinuity ); - if (isMinLongitudeDiscontinuityRender) { + if (renderIsMinLongitudeDiscontinuity) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MIN_DISCONTINUITY" ] = true; } - if (isMaxLongitudeDiscontinuityRender) { + if (renderIsMaxLongitudeDiscontinuity) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LONGITUDE_MAX_DISCONTINUITY" ] = true; } - const longitudeMinShapeUv = - (longitudeMinShape - longitudeMinDefault) / longitudeRangeDefault; - const longitudeMaxShapeUv = - (longitudeMaxShape - longitudeMinDefault) / longitudeRangeDefault; - - const longitudeMaxRenderUv = - (longitudeMaxRender - longitudeMinDefault) / longitudeRangeDefault; - const longitudeRangeEmptyRender = - 1.0 - longitudeRangeRender / longitudeRangeDefault; - const emptyMidLongitudeRenderUv = - (longitudeMaxRenderUv + 0.5 * longitudeRangeEmptyRender) % 1.0; + const uvShapeMinLongitude = + (shapeMinLongitude - defaultMinLongitude) / defaultLongitudeRange; + const uvShapeMaxLongitude = + (shapeMaxLongitude - defaultMinLongitude) / defaultLongitudeRange; + + const uvRenderMaxLongitude = + (renderMaxLongitude - defaultMinLongitude) / defaultLongitudeRange; + const uvRenderLongitudeRangeZero = + 1.0 - renderLongitudeRange / defaultLongitudeRange; + const uvRenderLongitudeRangeZeroMid = + (uvRenderMaxLongitude + 0.5 * uvRenderLongitudeRangeZero) % 1.0; shaderUniforms.ellipsoidShapeUvLongitudeMinMaxMid = Cartesian3.fromElements( - longitudeMinShapeUv, - longitudeMaxShapeUv, - emptyMidLongitudeRenderUv, + uvShapeMinLongitude, + uvShapeMaxLongitude, + uvRenderLongitudeRangeZeroMid, shaderUniforms.ellipsoidShapeUvLongitudeMinMaxMid ); } - if (hasLatitudeRender) { + if (renderHasLatitude) { shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE"] = true; // Intersects a cone for min latitude - if (hasLatitudeMinRender) { + if (renderHasLatitudeMin) { shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN"] = true; shaderDefines[ "ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN" ] = intersectionCount; - if (hasLatitudeMinUnderHalfRender) { + if (renderIsLatitudeMinUnderHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_UNDER_HALF" ] = true; intersectionCount += 1; - } else if (hasLatitudeMinEqualHalfRender) { + } else if (renderIsLatitudeMinHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF" ] = true; intersectionCount += 1; - } else if (hasLatitudeMinOverHalfRender) { + } else if (renderIsLatitudeMinOverHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF" ] = true; @@ -736,23 +696,23 @@ VoxelEllipsoidShape.prototype.update = function ( } // Intersects a cone for max latitude - if (hasLatitudeMaxRender) { + if (renderHasLatitudeMax) { shaderDefines["ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX"] = true; shaderDefines[ "ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX" ] = intersectionCount; - if (hasLatitudeMaxUnderHalfRender) { + if (renderIsLatitudeMaxUnderHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_UNDER_HALF" ] = true; intersectionCount += 2; - } else if (hasLatitudeMaxEqualHalfRender) { + } else if (renderIsLatitudeMaxHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_EQUAL_HALF" ] = true; intersectionCount += 1; - } else if (hasLatitudeMaxOverHalfRender) { + } else if (renderIsLatitudeMaxOverHalf) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MAX_OVER_HALF" ] = true; @@ -760,18 +720,18 @@ VoxelEllipsoidShape.prototype.update = function ( } } - if (latitudeMinRender === latitudeMaxRender) { + if (renderMinLatitude === renderMaxLatitude) { shaderDefines[ "ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO" ] = true; } const minCosHalfAngleSqr = Math.pow( - Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(latitudeMinRender)), + Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(renderMinLatitude)), 2.0 ); const maxCosHalfAngleSqr = Math.pow( - Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(latitudeMaxRender)), + Math.cos(CesiumMath.PI_OVER_TWO - Math.abs(renderMaxLatitude)), 2.0 ); shaderUniforms.ellipsoidRenderLatitudeCosSqrHalfMinMax = Cartesian2.fromElements( @@ -781,10 +741,10 @@ VoxelEllipsoidShape.prototype.update = function ( ); } - if (hasLatitudeShape) { + if (shapeHasLatitude) { shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE"] = true; - if (latitudeMinShape === latitudeMaxShape) { + if (shapeMinLatitude === shapeMaxLatitude) { shaderDefines[ "ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO" ] = true; @@ -800,8 +760,8 @@ VoxelEllipsoidShape.prototype.update = function ( // offset = -((minLatitude - -pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi))) // offset = -(minLatitude - -pi) / (maxLatitude - minLatitude) // offset = (-pi - minLatitude) / (maxLatitude - minLatitude) - const scale = latitudeRangeDefault / latitudeRangeShape; - const offset = (latitudeMinDefault - latitudeMinShape) / latitudeRangeShape; + const scale = defaultLatitudeRange / shapeLatitudeRange; + const offset = (defaultMinLatitude - shapeMinLatitude) / shapeLatitudeRange; shaderUniforms.ellipsoidUvToShapeUvLatitude = Cartesian2.fromElements( scale, offset, diff --git a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl index faf3e87aac4..885fe4ab5f3 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl @@ -9,15 +9,15 @@ #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF -#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF -#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE -#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED @@ -246,10 +246,10 @@ void intersectShape(Ray ray, inout Intersections ix) vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y); setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_HALF) + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF) vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x); setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect); - #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO) vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x); setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy); setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw); diff --git a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl index 3a07302e0f2..791cbd14a63 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl @@ -14,7 +14,7 @@ #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_EQUAL_HALF #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_MIN_OVER_HALF #define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN -#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_FLAT #define ELLIPSOID_INTERSECTION_INDEX_LONGITUDE #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MAX #define ELLIPSOID_INTERSECTION_INDEX_LATITUDE_MIN @@ -239,7 +239,7 @@ void intersectShape(in Ray ray, inout Intersections ix) { } // Inner ellipsoid - #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + #if defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_FLAT) // When the ellipsoid is perfectly thin it's necessary to sandwich the // inner ellipsoid intersection inside the outer ellipsoid intersection. diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl index 6e8a452f630..f2bd4deacd1 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToCylinder.glsl @@ -1,14 +1,14 @@ /* Cylinder defines: #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT -#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE -#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO +#define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED @@ -27,7 +27,7 @@ uniform vec2 u_cylinderShapeUvAngleMinMax; #endif #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) || defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - uniform float u_cylinderShapeUvAngleEmptyMid; + uniform float u_cylinderShapeUvAngleRangeZeroMid; #endif vec3 convertUvToShapeUvSpace(in vec3 positionUv) { @@ -54,21 +54,21 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { #endif // Compute angle - #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_ZERO) + #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO) || defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO) float angle = 1.0; #else float angle = (atan(positionLocal.y, positionLocal.x) + czm_pi) / czm_twoPi; // [0,1] #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE) #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED) - // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleEmptyMid is more conservative. - angle += float(angle < u_cylinderShapeUvAngleEmptyMid); + // Comparing against u_cylinderShapeUvAngleMinMax has precision problems. u_cylinderShapeUvAngleRangeZeroMid is more conservative. + angle += float(angle < u_cylinderShapeUvAngleRangeZeroMid); #endif // Avoid flickering from reading voxels from both sides of the -pi/+pi discontinuity. #if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY) - angle = angle > u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.x : angle; + angle = angle > u_cylinderShapeUvAngleRangeZeroMid ? u_cylinderShapeUvAngleMinMax.x : angle; #elif defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY) - angle = angle < u_cylinderShapeUvAngleEmptyMid ? u_cylinderShapeUvAngleMinMax.y : angle; + angle = angle < u_cylinderShapeUvAngleRangeZeroMid ? u_cylinderShapeUvAngleMinMax.y : angle; #endif angle = angle * u_cylinderUvToShapeUvAngle.x + u_cylinderUvToShapeUvAngle.y; // x = scale, y = offset diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl index 3a7b5256969..4809125c0cd 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToEllipsoid.glsl @@ -8,9 +8,9 @@ #define ELLIPSOID_HAS_RENDER_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE #define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE_RANGE_EQUAL_ZERO -#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_FLAT #define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN -#define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO +#define ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT #define ELLIPSOID_IS_SPHERE */ @@ -27,7 +27,7 @@ uniform vec3 u_ellipsoidRadiiUv; // [0,1] #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE) uniform vec2 u_ellipsoidUvToShapeUvLatitude; // x = scale, y = offset #endif -#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) +#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_MIN) && !defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) uniform float u_ellipsoidInverseHeightDifferenceUv; uniform vec2 u_ellipseInnerRadiiUv; // [0,1] #endif @@ -104,7 +104,7 @@ vec3 convertUvToShapeUvSpace(in vec3 positionUv) { #endif // Compute height - #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_RANGE_EQUAL_ZERO) + #if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_HEIGHT_FLAT) || defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_FLAT) // TODO: This breaks down when minBounds == maxBounds. To fix it, this // function would have to know if ray is intersecting the front or back of the shape // and set the shape space position to 1 (front) or 0 (back) accordingly. From 48d47901ed83adbbb0b5fcd2c245be6b39eef3d4 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Fri, 30 Dec 2022 21:53:01 -0500 Subject: [PATCH 298/679] Fix intersectHalfSpace when it cuts through camera --- .../Shaders/Voxels/IntersectCylinder.glsl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl index 885fe4ab5f3..1f0c64f404d 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectCylinder.glsl @@ -56,6 +56,9 @@ vec4 intersectHalfPlane(Ray ray, float angle) { return vec4(-INF_HIT, t, t, +INF_HIT); } +#define POSITIVE_HIT vec2(t, +INF_HIT); +#define NEGATIVE_HIT vec2(-INF_HIT, t); + vec2 intersectHalfSpace(Ray ray, float angle) { vec2 o = ray.pos.xy; @@ -67,8 +70,20 @@ vec2 intersectHalfSpace(Ray ray, float angle) float t = -a / b; float s = sign(a); - if (t >= 0.0 != s >= 0.0) return vec2(t, +INF_HIT); - else return vec2(-INF_HIT, t); + // Half space cuts right through the camera, pick the side to intersect + if (a == 0.0) { + if (b >= 0.0) { + return POSITIVE_HIT; + } else { + return NEGATIVE_HIT; + } + } + + if (t >= 0.0 != s >= 0.0) { + return POSITIVE_HIT; + } else { + return NEGATIVE_HIT; + } } vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle) From 75afc2434e3cb163c23ce61bc3b2d150adf4681f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 15:16:02 -0500 Subject: [PATCH 299/679] Chose the correct voxel class instead of flattening properties from all classes --- .../Scene/Cesium3DTilesVoxelProvider.js | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 19f1358d1f4..11f85e045d1 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -51,10 +51,10 @@ function Cesium3DTilesVoxelProvider(options) { this.ready = false; /** @inheritdoc */ - this.shapeTransform = Matrix4.clone(Matrix4.IDENTITY); + this.shapeTransform = undefined; /** @inheritdoc */ - this.globalTransform = Matrix4.clone(Matrix4.IDENTITY); + this.globalTransform = undefined; /** @inheritdoc */ this.shape = undefined; @@ -109,6 +109,8 @@ function Cesium3DTilesVoxelProvider(options) { }) .then(function (schemaLoader) { const root = tilesetJson.root; + const voxel = root.content.extensions["3DTILES_content_voxels"]; + const className = voxel.class; const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") ? tilesetJson.extensions["3DTILES_metadata"] @@ -120,7 +122,7 @@ function Cesium3DTilesVoxelProvider(options) { schema: metadataSchema, }); - addAttributeInfo(metadata, that); + addAttributeInfo(that, metadata, className); const implicitTileset = new ImplicitTileset( resource, @@ -128,8 +130,6 @@ function Cesium3DTilesVoxelProvider(options) { metadataSchema ); - const voxel = root.content.extensions["3DTILES_content_voxels"]; - const { shape, minBounds, @@ -142,15 +142,24 @@ function Cesium3DTilesVoxelProvider(options) { that.minBounds = minBounds; that.maxBounds = maxBounds; that.dimensions = Cartesian3.unpack(voxel.dimensions); - that.paddingBefore = Cartesian3.unpack(voxel.padding.before); - that.paddingAfter = Cartesian3.unpack(voxel.padding.after); that.shapeTransform = shapeTransform; that.globalTransform = globalTransform; - // TODO: this tile class stuff needs to be documented - that.maximumTileCount = metadata.statistics.classes.tile?.count; + let paddingBefore; + let paddingAfter; + + if (defined(voxel.padding)) { + paddingBefore = Cartesian3.unpack(voxel.padding.before); + paddingAfter = Cartesian3.unpack(voxel.padding.after); + } + + that.paddingBefore = paddingBefore; + that.paddingAfter = paddingAfter; that._implicitTileset = implicitTileset; + + ResourceCache.unload(schemaLoader); + that.ready = true; return that; }); @@ -294,29 +303,23 @@ function getMetadataSchemaLoader(tilesetJson, resource) { }); } -function addAttributeInfo(metadata, provider) { +function addAttributeInfo(provider, metadata, className) { const { schema, statistics } = metadata; + const classStatistics = statistics?.classes[className]; + const properties = schema.classes[className].properties; + + const propertyInfo = Object.entries(properties).map(([id, property]) => { + const { type, componentType } = property; + const min = classStatistics?.properties[id].min; + const max = classStatistics?.properties[id].max; + const componentCount = MetadataType.getComponentCount(type); + const minValue = copyArray(min, componentCount); + const maxValue = copyArray(max, componentCount); + + return { id, type, componentType, minValue, maxValue }; + }); - // Collect a flattened array of info from all properties in all classes. - const propertyInfo = Object.entries(schema.classes).flatMap(getPropertyInfo); - - function getPropertyInfo([className, classInfo]) { - const classStatistics = statistics.classes[className]; - const { properties } = classInfo; - return Object.entries(properties).map(([name, property]) => { - const { type, componentType } = property; - - const min = classStatistics?.properties[name].min; - const max = classStatistics?.properties[name].max; - const componentCount = MetadataType.getComponentCount(type); - const minValue = copyArray(min, componentCount); - const maxValue = copyArray(max, componentCount); - - return { name, type, componentType, minValue, maxValue }; - }); - } - - provider.names = propertyInfo.map((info) => info.name); + provider.names = propertyInfo.map((info) => info.id); provider.types = propertyInfo.map((info) => info.type); provider.componentTypes = propertyInfo.map((info) => info.componentType); From 97094c8f631ae9e27572a7774908f70cffe4895a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 15:16:24 -0500 Subject: [PATCH 300/679] Update Specs data --- .../Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 88 -------------- .../Voxel/VoxelBox3DTiles/schema.json | 14 --- .../VoxelBox3DTiles/subtrees/0/0/0/0.json | 14 +++ .../Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json | 27 +++++ .../VoxelBox3DTiles/{0 => tiles}/0/0/0/a.bin | Bin .../Voxel/VoxelBox3DTiles/tileset.json | 78 +++++++----- .../VoxelCylinder3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 88 -------------- .../Voxel/VoxelCylinder3DTiles/schema.json | 14 --- .../subtrees/0/0/0/0.json | 14 +++ .../VoxelCylinder3DTiles/tiles/0/0/0/0.json | 27 +++++ .../{0 => tiles}/0/0/0/a.bin | Bin .../Voxel/VoxelCylinder3DTiles/tileset.json | 112 +++++++++++------- .../VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 100 ---------------- .../Voxel/VoxelEllipsoid3DTiles/schema.json | 14 --- .../subtrees/0/0/0/0.json | 14 +++ .../VoxelEllipsoid3DTiles/tiles/0/0/0/0.json | 27 +++++ .../{0 => tiles}/0/0/0/a.bin | Bin .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 78 +++++++----- .../VoxelMultiAttribute3DTiles/README.md | 5 - .../VoxelMultiAttribute3DTiles/schema.json | 27 ----- .../tiles/0/0/0/0.gltf | 91 -------------- .../tiles/0/0/0/0.voxel | Bin 0 -> 432 bytes .../VoxelMultiAttribute3DTiles/tileset.json | 41 +++++-- .../VoxelMultiAttribute3DTiles/voxel2x2.json | 76 ++++++------ 27 files changed, 361 insertions(+), 588 deletions(-) delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json rename Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/{0 => tiles}/0/0/0/a.bin (100%) delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json rename Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/{0 => tiles}/0/0/0/a.bin (100%) delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json rename Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/{0 => tiles}/0/0/0/a.bin (100%) delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json delete mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf create mode 100644 Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.voxel diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index 1cb53f70a4d..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483648, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin rename to Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/a.bin diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 529913b1cb2..9617ab7b581 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -2,26 +2,34 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { "box": [ 0.0, @@ -38,34 +46,46 @@ 1.0 ] }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels" + ], + "extensionsRequired": [ + "3DTILES_content_voxels" + ] +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index d7247ac82e1..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483650, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin rename to Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/a.bin diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 529913b1cb2..95adb663a72 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -2,70 +2,96 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { - "box": [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + "extensions": { + "3DTILES_bounding_volume_cylinder": { + "cylinder": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + } }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels", + "3DTILES_bounding_volume_cylinder" + ], + "extensionsRequired": [ + "3DTILES_content_voxels", + "3DTILES_bounding_volume_cylinder" + ] +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index 5a1815f6d10..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,100 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483649, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ], - "bounds": { - "min": [ - 0.0, - 0.0, - -1.0 - ], - "max": [ - 1.0, - 1.0, - 0.0 - ] - } - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin rename to Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/a.bin diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index a3e86ab1444..d9d9c73346b 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -2,26 +2,34 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { "region": [ 0.0, @@ -32,34 +40,46 @@ 0.0 ] }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 6378137.0, - 0.0, - 0.0, - 0.0, - 0.0, - 6378137.0, - 0.0, - 0.0, - 0.0, - 0.0, - 6356752.314245179, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels" + ], + "extensionsRequired": [ + "3DTILES_content_voxels" + ] +} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md index 468b82060cc..2843e6e346a 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/README.md @@ -4,8 +4,3 @@ The data was generated as follows: 1. Generate 8-sample (2x2 cube) CSV file, voxel2x2.csv 2. Run tiler with the config file voxel2x2.json -3. Modify ./tiles/0/0/0/0.gltf to re-order the meshes.primitives.attributes dictionary. - -Note: in step 3, the (key: index) pairs are left intact. We simply -re-ordered the entries to simulate a bug in Cesium3DTilesVoxelProvider. -The bug has since been fixed. diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json deleted file mode 100644 index 4c989331219..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/schema.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "SCALAR", - "componentType": "FLOAT32", - "required": true, - "noData": -99999.0 - }, - "b": { - "type": "SCALAR", - "componentType": "FLOAT32", - "required": true, - "noData": -99999.0 - }, - "c": { - "type": "SCALAR", - "componentType": "FLOAT32", - "required": true, - "noData": -99999.0 - } - } - } - } -} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf deleted file mode 100644 index 0a987473e24..00000000000 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.gltf +++ /dev/null @@ -1,91 +0,0 @@ -{ - "extensionsUsed": ["EXT_structural_metadata", "EXT_primitive_voxels"], - "extensionsRequired": ["EXT_primitive_voxels"], - "accessors": [{ - "bufferView": 0, - "componentType": 5126, - "count": 8, - "type": "SCALAR" - }, { - "bufferView": 1, - "componentType": 5126, - "count": 8, - "type": "SCALAR" - }, { - "bufferView": 2, - "componentType": 5126, - "count": 8, - "type": "SCALAR" - }], - "asset": { - "version": "2.0" - }, - "buffers": [{ - "uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - "byteLength": 96 - }], - "bufferViews": [{ - "buffer": 0, - "byteLength": 32, - "target": 34962 - }, { - "buffer": 0, - "byteOffset": 32, - "byteLength": 32, - "target": 34962 - }, { - "buffer": 0, - "byteOffset": 64, - "byteLength": 32, - "target": 34962 - }], - "meshes": [{ - "primitives": [{ - "attributes": { - "_c": 0, - "_b": 1, - "_a": 2 - }, - "mode": 2147483648, - "extensions": { - "EXT_structural_metadata": { - "propertyAttributes": [0] - }, - "EXT_primitive_voxels": { - "dimensions": [2, 2, 2], - "bounds": { - "min": [-1.0, -1.0, -1.0], - "max": [1.0, 1.0, 1.0] - } - } - } - }] - }], - "nodes": [{ - "matrix": [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], - "mesh": 0 - }], - "scene": 0, - "scenes": [{ - "nodes": [0] - }], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [{ - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - }, - "b": { - "attribute": "_b" - }, - "c": { - "attribute": "_c" - } - } - }] - } - } -} diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.voxel b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tiles/0/0/0/0.voxel new file mode 100644 index 0000000000000000000000000000000000000000..765dc0b2d2d760e47718ff4601bc6be66b2aeb5d GIT binary patch literal 432 zcma)3%?g7s4DQ}Ua`xbKi1V@+80<238G}`6H=$V3>J%yL(U;aAgbi6CX_D_t`n7Fj zD>j6X$T(bg>j~*0sX1q51@RT*PO&4)AL;M{?PjuIoy4bQB_gOf|aT}(?qaASSo0R5j3)80$fOCouja5CTE7&12wLp pqBbeYgk)LRVj*1?Jgv<$*s1n3ypDDphmiMS-3a2VHvYix?E@@paqs{D literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json index 12d0ff74f87..c9867877b88 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json @@ -1,14 +1,31 @@ { "asset": { - "version": "1.1", - "extras": { - "ion": { - "georeferenced": true, - "movable": true + "version": "1.1" + }, + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true + }, + "b": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true + }, + "c": { + "type": "SCALAR", + "componentType": "FLOAT32", + "required": true + } + } } } }, - "schemaUri": "schema.json", "statistics": { "classes": { "voxel": { @@ -39,7 +56,13 @@ "refine": "REPLACE", "transform": [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0], "content": { - "uri": "tiles/{level}/{x}/{y}/{z}.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.voxel", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [2, 2, 2], + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", @@ -49,5 +72,7 @@ "uri": "subtrees/{level}/{x}/{y}/{z}.subtree" } } - } + }, + "extensionsUsed": ["3DTILES_content_voxels"], + "extensionsRequired": ["3DTILES_content_voxels"] } \ No newline at end of file diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json index db8f5fd0f01..4720172ed53 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/voxel2x2.json @@ -1,40 +1,40 @@ { - "input": { - "path": "./voxel2x2.csv" - }, - "output": { - "path": "./" - }, - "gltf": { - "binary": false - }, - "csv": { - "properties": { - "a": { - "noData": -99999.0, - "type": "FLOAT32" - }, - "b": { - "noData": -99999.0, - "type": "FLOAT32" - }, - "c": { - "noData": -99999.0, - "type": "FLOAT32" - } - } - }, - "pipeline": { - "voxelTiler": { - "properties": ["a", "b", "c"], - "tileDimensions": 2, - "grid": { - "xSpacing": 1, - "ySpacing": 1, - "zSpacing": 1, - "rotation": 0 - } - } - }, - "force": true + "input": { + "path": "./voxel2x2.csv" + }, + "output": { + "path": "./output" + }, + "tileset": { + "voxelContentBinary": true, + "voxelContentCombineBuffers": true, + "includeIonExtras": false, + "includeCesiumExtras": false + }, + "csv": { + "properties": { + "a": { + "type": "FLOAT32" + }, + "b": { + "type": "FLOAT32" + }, + "c": { + "type": "FLOAT32" + } + } + }, + "pipeline": { + "voxelTiler": { + "properties": ["a", "b", "c"], + "tileDimensions": 2, + "grid": { + "xSpacing": 1, + "ySpacing": 1, + "zSpacing": 1, + "rotation": 0 + } + } + }, + "force": true } From 4bbcc2e96de60f4388c381a142f60baac7c500b3 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 15:35:04 -0500 Subject: [PATCH 301/679] Update SampleData --- .../Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf | 88 -------------- .../Voxel/VoxelBox3DTiles/schema.json | 14 --- .../VoxelBox3DTiles/subtrees/0/0/0/0.json | 14 +++ .../Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json | 27 +++++ .../VoxelBox3DTiles/{0 => tiles}/0/0/0/a.bin | Bin .../Voxel/VoxelBox3DTiles/tileset.json | 78 +++++++----- .../Voxel/VoxelBoxGltf/schema.json | 14 --- .../Voxel/VoxelBoxGltf/voxelBox.gltf | 88 -------------- .../VoxelCylinder3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../VoxelCylinder3DTiles/0/0/0/0/tile.gltf | 88 -------------- .../Voxel/VoxelCylinder3DTiles/schema.json | 14 --- .../subtrees/0/0/0/0.json | 14 +++ .../VoxelCylinder3DTiles/tiles/0/0/0/0.json | 27 +++++ .../tiles/0/0/0}/a.bin | Bin .../Voxel/VoxelCylinder3DTiles/tileset.json | 112 +++++++++++------- .../Voxel/VoxelCylinderGltf/a.bin | Bin 32 -> 0 bytes .../Voxel/VoxelCylinderGltf/schema.json | 14 --- .../VoxelCylinderGltf/voxelCylinder.gltf | 88 -------------- .../Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin | Bin 32 -> 0 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin | Bin 312 -> 0 bytes .../VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf | 100 ---------------- .../Voxel/VoxelEllipsoid3DTiles/schema.json | 14 --- .../subtrees/0/0/0/0.json | 14 +++ .../VoxelEllipsoid3DTiles/tiles/0/0/0/0.json | 27 +++++ .../tiles}/0/0/0/a.bin | Bin .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 78 +++++++----- .../Voxel/VoxelEllipsoidGltf/a.bin | Bin 32 -> 0 bytes .../Voxel/VoxelEllipsoidGltf/schema.json | 14 --- .../VoxelEllipsoidGltf/voxelEllipsoid.gltf | 100 ---------------- 30 files changed, 290 insertions(+), 737 deletions(-) delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json rename Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/{0 => tiles}/0/0/0/a.bin (100%) delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json rename Apps/SampleData/Cesium3DTiles/Voxel/{VoxelBoxGltf => VoxelCylinder3DTiles/tiles/0/0/0}/a.bin (100%) delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json create mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json rename Apps/SampleData/Cesium3DTiles/Voxel/{VoxelCylinder3DTiles/0 => VoxelEllipsoid3DTiles/tiles}/0/0/0/a.bin (100%) delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json delete mode 100644 Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index 1cb53f70a4d..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483648, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/0/0/0/0/a.bin rename to Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tiles/0/0/0/a.bin diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 529913b1cb2..9617ab7b581 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -2,26 +2,34 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { "box": [ 0.0, @@ -38,34 +46,46 @@ 1.0 ] }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels" + ], + "extensionsRequired": [ + "3DTILES_content_voxels" + ] +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf deleted file mode 100644 index 0f89c2221c6..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/voxelBox.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483648, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index d7247ac82e1..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483650, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Apps/SampleData/Cesium3DTiles/Voxel/VoxelBoxGltf/a.bin rename to Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tiles/0/0/0/a.bin diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 529913b1cb2..95adb663a72 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -2,70 +2,96 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { - "box": [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 1.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + "extensions": { + "3DTILES_bounding_volume_cylinder": { + "cylinder": [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + } }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels", + "3DTILES_bounding_volume_cylinder" + ], + "extensionsRequired": [ + "3DTILES_content_voxels", + "3DTILES_bounding_volume_cylinder" + ] +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/a.bin deleted file mode 100644 index 6eac4f3e1f1fcfd58880ad428efeb0df90514357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf deleted file mode 100644 index 6ef6eb1759c..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinderGltf/voxelCylinder.gltf +++ /dev/null @@ -1,88 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483650, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ] - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/a.bin deleted file mode 100644 index 6eac4f3e1f1fcfd58880ad428efeb0df90514357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/subtree.bin deleted file mode 100644 index 2518924ca56aa3fb60ed2c89e2e765ead97fb28a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 312 zcmXqZ31MJlU|&E7I!ej;c_pcNCFJPL$jnIzE=?*aN+oEq0obDAl0=XzK-MCh zQLJPYT@B>}<$zL^C8_>tX~n4^r4X)9YF>It2GIQmwXrb0P<=qfa9Ok3*jfb$fCdjV HbQl-_(;r_a diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf deleted file mode 100644 index 5a1815f6d10..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/0/0/0/0/tile.gltf +++ /dev/null @@ -1,100 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483649, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ], - "bounds": { - "min": [ - 0.0, - 0.0, - -1.0 - ], - "max": [ - 1.0, - 1.0, - 0.0 - ] - } - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "../../../../schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json new file mode 100644 index 00000000000..abc8af15e8b --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/subtrees/0/0/0/0.json @@ -0,0 +1,14 @@ +{ + "tileAvailability": { + "availableCount": 1, + "constant": 1 + }, + "contentAvailability": { + "availableCount": 1, + "constant": 1 + }, + "childSubtreeAvailability": { + "availableCount": 0, + "constant": 0 + } +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json new file mode 100644 index 00000000000..688327759af --- /dev/null +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/0.json @@ -0,0 +1,27 @@ +{ + "buffers": [ + { + "uri": "a.bin", + "byteLength": 32 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 32 + } + ], + "propertyTables": [ + { + "class": "voxel", + "count": 8, + "properties": { + "a": { + "values": 0 + } + } + } + ], + "voxelTable": 0 +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/a.bin similarity index 100% rename from Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/0/0/0/0/a.bin rename to Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tiles/0/0/0/a.bin diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index a3e86ab1444..d9d9c73346b 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -2,26 +2,34 @@ "asset": { "version": "1.1" }, - "schemaUri": "schema.json", + "schema": { + "id": "voxel", + "classes": { + "voxel": { + "properties": { + "a": { + "type": "SCALAR", + "componentType": "FLOAT32" + } + } + } + } + }, "statistics": { "classes": { "voxel": { + "count": 8, "properties": { "a": { "min": 0.0, "max": 1.0 } } - }, - "tile": { - "count": 1 } } }, "geometricError": 0.0, "root": { - "geometricError": 0.0, - "refine": "REPLACE", "boundingVolume": { "region": [ 0.0, @@ -32,34 +40,46 @@ 0.0 ] }, + "geometricError": 0.0, + "refine": "REPLACE", "content": { - "uri": "{level}/{x}/{y}/{z}/tile.gltf" + "uri": "tiles/{level}/{x}/{y}/{z}.json", + "extensions": { + "3DTILES_content_voxels": { + "dimensions": [ + 2, + 2, + 2 + ], + "padding": { + "before": [ + 0, + 0, + 0 + ], + "after": [ + 0, + 0, + 0 + ] + }, + "class": "voxel" + } + } }, "implicitTiling": { "subdivisionScheme": "OCTREE", "subtreeLevels": 3, "availableLevels": 1, "subtrees": { - "uri": "{level}/{x}/{y}/{z}/subtree.bin" + "uri": "subtrees/{level}/{x}/{y}/{z}.json" } - }, - "transform": [ - 6378137.0, - 0.0, - 0.0, - 0.0, - 0.0, - 6378137.0, - 0.0, - 0.0, - 0.0, - 0.0, - 6356752.314245179, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] - } -} \ No newline at end of file + } + }, + "extensionsUsed": [ + "3DTILES_content_voxels" + ], + "extensionsRequired": [ + "3DTILES_content_voxels" + ] +} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/a.bin deleted file mode 100644 index 6eac4f3e1f1fcfd58880ad428efeb0df90514357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32 QcmZQzKnD%>3=9Yi02c%T{Qv*} diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json deleted file mode 100644 index d6b1e9d87f0..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/schema.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "voxel", - "classes": { - "voxel": { - "properties": { - "a": { - "type": "FLOAT32", - "required": false - } - } - }, - "tile": {} - } -} \ No newline at end of file diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf deleted file mode 100644 index 39b31e4dd3c..00000000000 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoidGltf/voxelEllipsoid.gltf +++ /dev/null @@ -1,100 +0,0 @@ -{ - "asset": { - "version": "2.0" - }, - "scene": 0, - "scenes": [ - { - "nodes": [ - 0 - ] - } - ], - "nodes": [ - { - "mesh": 0 - } - ], - "meshes": [ - { - "primitives": [ - { - "mode": 2147483649, - "attributes": { - "_a": 0 - }, - "extensions": { - "EXT_primitive_voxels": { - "dimensions": [ - 2, - 2, - 2 - ], - "bounds": { - "min": [ - -3.141592653589793, - -1.5707963267948966, - 1000000.0 - ], - "max": [ - 3.141592653589793, - 1.5707963267948966, - 2000000.0 - ] - } - } - } - } - ] - } - ], - "extensionsUsed": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensionsRequired": [ - "EXT_primitive_voxels", - "EXT_structural_metadata" - ], - "extensions": { - "EXT_structural_metadata": { - "schemaUri": "schema.json", - "propertyAttributes": [ - { - "class": "voxel", - "properties": { - "a": { - "attribute": "_a" - } - } - } - ] - } - }, - "accessors": [ - { - "bufferView": 0, - "type": "SCALAR", - "componentType": 5126, - "min": [ - 0.0 - ], - "max": [ - 1.0 - ], - "count": 8 - } - ], - "bufferViews": [ - { - "buffer": 0, - "byteLength": 32 - } - ], - "buffers": [ - { - "uri": "a.bin", - "byteLength": 32 - } - ] -} \ No newline at end of file From 41e11a30c3dea701cafde33768fd58b79e9e51a6 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 16:23:25 -0500 Subject: [PATCH 302/679] Fix artifacts for large thin ellipsoids --- .../Shaders/Voxels/IntersectEllipsoid.glsl | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl index 791cbd14a63..bdbf5d724cd 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectEllipsoid.glsl @@ -263,7 +263,25 @@ void intersectShape(in Ray ray, inout Intersections ix) { #elif defined(ELLIPSOID_HAS_RENDER_BOUNDS_HEIGHT_MIN) Ray innerRay = Ray(ray.pos * u_ellipsoidInverseInnerScaleUv, ray.dir * u_ellipsoidInverseInnerScaleUv); vec2 innerIntersect = intersectUnitSphereUnnormalizedDirection(innerRay); - setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); + + if (innerIntersect == vec2(NO_HIT)) { + setIntersectionPair(ix, ELLIPSOID_INTERSECTION_INDEX_HEIGHT_MIN, innerIntersect); + } else { + // When the ellipsoid is very large and thin it's possible for floating + // point math to cause the ray to intersect the inner ellipsoid before + // the outer ellipsoid. To prevent this from happening, clamp innerIntersect + // to outerIntersect and sandwhich the intersections like described above. + // + // In theory a similar fix is needed for cylinders, however it's more + // complicated to implement because the inner shape is allowed to be + // intersected first. + innerIntersect.x = max(innerIntersect.x, outerIntersect.x); + innerIntersect.y = min(innerIntersect.y, outerIntersect.y); + setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter + setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter + setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit + setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit + } #endif // Flip the ray because the intersection function expects a cone growing towards +Z. From 240b7df576f1b634d36fdfb3169db3a8d9ad2f4e Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 16:57:31 -0500 Subject: [PATCH 303/679] Remove padding from examples --- .../Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json | 12 ------------ .../Voxel/VoxelCylinder3DTiles/tileset.json | 12 ------------ .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 12 ------------ .../Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json | 12 ------------ .../Voxel/VoxelCylinder3DTiles/tileset.json | 12 ------------ .../Voxel/VoxelEllipsoid3DTiles/tileset.json | 12 ------------ 6 files changed, 72 deletions(-) diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 9617ab7b581..7d704a8f00b 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -57,18 +57,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 95adb663a72..d1652c7e875 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -61,18 +61,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } diff --git a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index d9d9c73346b..cbc44570eba 100644 --- a/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Apps/SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -51,18 +51,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json index 9617ab7b581..7d704a8f00b 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json @@ -57,18 +57,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json index 95adb663a72..d1652c7e875 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json @@ -61,18 +61,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } diff --git a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json index d9d9c73346b..cbc44570eba 100644 --- a/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json +++ b/Specs/Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json @@ -51,18 +51,6 @@ 2, 2 ], - "padding": { - "before": [ - 0, - 0, - 0 - ], - "after": [ - 0, - 0, - 0 - ] - }, "class": "voxel" } } From e6b55e9e5bec90568530cd2cb2928b6cc7799c78 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Sat, 31 Dec 2022 17:14:23 -0500 Subject: [PATCH 304/679] Updated Voxels.html --- Apps/Sandcastle/gallery/Voxels.html | 213 ++++++++++++++-------------- Apps/Sandcastle/gallery/Voxels.jpg | Bin 0 -> 24384 bytes 2 files changed, 103 insertions(+), 110 deletions(-) create mode 100644 Apps/Sandcastle/gallery/Voxels.jpg diff --git a/Apps/Sandcastle/gallery/Voxels.html b/Apps/Sandcastle/gallery/Voxels.html index 03b858e6d9e..1ac05f60689 100644 --- a/Apps/Sandcastle/gallery/Voxels.html +++ b/Apps/Sandcastle/gallery/Voxels.html @@ -7,11 +7,8 @@ name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" /> - - + + Cesium Demo + + + + + +
+

Loading...

+
+ + + From 0b7bf19846ba5047b4ce12aa9e498a6d9c71fc37 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 19 Jan 2023 10:20:12 -0500 Subject: [PATCH 372/679] Add resolution comments --- Apps/Sandcastle/gallery/Aerometrex San Francisco.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Apps/Sandcastle/gallery/Aerometrex San Francisco.html b/Apps/Sandcastle/gallery/Aerometrex San Francisco.html index 1e3274be4d5..ad722934e5e 100755 --- a/Apps/Sandcastle/gallery/Aerometrex San Francisco.html +++ b/Apps/Sandcastle/gallery/Aerometrex San Francisco.html @@ -47,7 +47,7 @@ }) ); - // Ferry Building + // Ferry Building – Street Level Enhanced mesh with a resolution of ~6mm per pixel function viewFerryBuilding() { viewer.scene.camera.flyTo({ destination: new Cesium.Cartesian3( @@ -63,7 +63,7 @@ }); } - // Pier 39 + // Pier 39 - 2 cm/pixel resolution function viewPier39() { viewer.scene.camera.flyTo({ destination: new Cesium.Cartesian3( @@ -79,7 +79,7 @@ }); } - // Skyline + // Skyline - 2 cm/pixel resolution function viewSkyline() { viewer.scene.camera.flyTo({ destination: new Cesium.Cartesian3( @@ -95,7 +95,7 @@ }); } - // Lombard Street + // Lombard Street - 2 cm/pixel resolution function viewLombardStreet() { viewer.scene.camera.flyTo({ destination: new Cesium.Cartesian3( From f956e6eb60003e054da97ce78f94278d43000d0b Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 19 Jan 2023 16:14:11 -0500 Subject: [PATCH 373/679] Cleanup async terrain handling --- Apps/CesiumViewer/CesiumViewer.js | 44 +- .../gallery/3D Tiles Feature Picking.html | 496 +++++----- .../gallery/3D Tiles Feature Styling.html | 294 +++--- .../gallery/3D Tiles Inspector.html | 29 +- .../gallery/3D Tiles Interactivity.html | 331 ++++--- ...es Next Photogrammetry Classification.html | 605 ++++++------ ...D Tiles Photogrammetry Classification.html | 75 +- .../gallery/3D Tiles Photogrammetry.html | 20 +- .../3D Tiles Point Cloud Classification.html | 139 +-- .../gallery/3D Tiles Point Cloud Shading.html | 373 +++---- .../gallery/3D Tiles Point Cloud.html | 44 +- .../3D Tiles Terrain Classification.html | 87 +- .../ArcGIS Tiled Elevation Terrain.html | 16 +- Apps/Sandcastle/gallery/ArcticDEM.html | 157 +-- Apps/Sandcastle/gallery/CZML Path.html | 22 +- Apps/Sandcastle/gallery/Cardboard.html | 260 ++--- .../gallery/Cartographic Limit Rectangle.html | 97 +- Apps/Sandcastle/gallery/Cesium Inspector.html | 132 +-- .../gallery/Cesium OSM Buildings.html | 24 +- .../gallery/Cesium World Terrain.html | 13 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 93 +- Apps/Sandcastle/gallery/Clamp to Terrain.html | 542 +++++----- .../gallery/Classification Types.html | 245 ++--- Apps/Sandcastle/gallery/Classification.html | 552 ++++++----- Apps/Sandcastle/gallery/Clouds.html | 407 ++++---- .../Custom Shaders Property Textures.html | 136 +-- .../gallery/Drawing on Terrain.html | 230 ++--- .../gallery/Elevation Band Material.html | 368 +++---- Apps/Sandcastle/gallery/FXAA.html | 53 +- Apps/Sandcastle/gallery/GPX.html | 188 ++-- .../gallery/Geometry Height Reference.html | 232 ++--- Apps/Sandcastle/gallery/Globe Materials.html | 519 +++++----- .../gallery/Globe Translucency.html | 407 ++++---- .../gallery/Google Earth Enterprise.html | 60 +- .../gallery/High Dynamic Range.html | 101 +- .../gallery/I3S 3D Object Layer.html | 136 +-- .../gallery/I3S Feature Picking.html | 136 +-- .../gallery/I3S IntegratedMesh Layer.html | 21 +- Apps/Sandcastle/gallery/Interpolation.html | 322 +++--- Apps/Sandcastle/gallery/Lighting.html | 376 +++---- Apps/Sandcastle/gallery/MSAA.html | 259 ++--- .../gallery/Montreal Point Cloud.html | 591 +++++------ Apps/Sandcastle/gallery/PAMAP Terrain.html | 194 ++-- .../gallery/Particle System Weather.html | 305 +++--- .../gallery/Physically-Based Materials.html | 269 ++--- .../gallery/Sample Height from 3D Tiles.html | 155 ++- .../gallery/Scene Rendering Performance.html | 406 ++++---- Apps/Sandcastle/gallery/Shadows.html | 460 ++++----- .../gallery/Terrain Clipping Planes.html | 624 ++++++------ .../gallery/Terrain Exaggeration.html | 209 ++-- Apps/Sandcastle/gallery/Terrain.html | 534 +++++----- .../development/BillboardClampToGround.html | 224 ++--- .../development/Billboards Instancing.html | 326 +++--- Apps/Sandcastle/gallery/development/Fog.html | 148 +-- .../development/Ground Polyline Material.html | 152 +-- .../Ground Primitive Materials.html | 929 +++++++++--------- .../gallery/development/Ground Primitive.html | 873 ++++++++-------- .../development/Many Clipping Planes.html | 465 +++++---- .../gallery/development/Multiple Shadows.html | 159 ++- .../development/Polylines On Terrain.html | 540 +++++----- .../development/Terrain Entity Batching.html | 279 +++--- .../development/Terrain Performance.html | 436 ++++---- .../ArcGISTiledElevationTerrainProvider.js | 4 +- .../Source/Core/CesiumTerrainProvider.js | 28 +- .../GoogleEarthEnterpriseTerrainProvider.js | 4 +- .../engine/Source/Core/createWorldTerrain.js | 2 + .../Source/Core/createWorldTerrainAsync.js | 24 +- .../engine/Source/Scene/I3SDataProvider.js | 4 +- packages/engine/Source/Widget/CesiumWidget.js | 52 +- .../engine/Specs/Widget/CesiumWidgetSpec.js | 22 - .../BaseLayerPickerViewModel.js | 31 +- packages/widgets/Source/Viewer/Viewer.js | 75 +- 72 files changed, 8646 insertions(+), 8519 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 4a63883abc7..6a1ba82635a 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -20,7 +20,7 @@ import { viewerDragDropMixin, } from "../../Build/CesiumUnminified/index.js"; -function main() { +async function main() { /* Options parsed from query string: source=url The URL of a CZML/GeoJSON/KML data source to load at startup. @@ -56,7 +56,7 @@ function main() { let terrainProvider; if (hasBaseLayerPicker) { - terrainProvider = createWorldTerrainAsync({ + terrainProvider = await createWorldTerrainAsync({ requestWaterMask: true, requestVertexNormals: true, }); @@ -71,10 +71,8 @@ function main() { }); if (hasBaseLayerPicker) { - Promise.resolve(terrainProvider).then(() => { - const viewModel = viewer.baseLayerPicker.viewModel; - viewModel.selectedTerrain = viewModel.terrainProviderViewModels[1]; - }); + const viewModel = viewer.baseLayerPicker.viewModel; + viewModel.selectedTerrain = viewModel.terrainProviderViewModels[1]; } } catch (exception) { loadingIndicator.style.display = "none"; @@ -151,25 +149,23 @@ function main() { } if (defined(loadPromise)) { - viewer.dataSources - .add(loadPromise) - .then(function (dataSource) { - const lookAt = endUserOptions.lookAt; - if (defined(lookAt)) { - const entity = dataSource.entities.getById(lookAt); - if (defined(entity)) { - viewer.trackedEntity = entity; - } else { - const error = `No entity with id "${lookAt}" exists in the provided data source.`; - showLoadError(source, error); - } - } else if (!defined(view) && endUserOptions.flyTo !== "false") { - viewer.flyTo(dataSource); + try { + const dataSource = await viewer.dataSources.add(loadPromise); + const lookAt = endUserOptions.lookAt; + if (defined(lookAt)) { + const entity = dataSource.entities.getById(lookAt); + if (defined(entity)) { + viewer.trackedEntity = entity; + } else { + const error = `No entity with id "${lookAt}" exists in the provided data source.`; + showLoadError(source, error); } - }) - .catch(function (error) { - showLoadError(source, error); - }); + } else if (!defined(view) && endUserOptions.flyTo !== "false") { + viewer.flyTo(dataSource); + } + } catch (error) { + showLoadError(source, error); + } } } diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index 3c251dc2e37..259ee31640c 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -33,278 +33,278 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // A simple demo of 3D Tiles feature picking with hover and select behavior - // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + // A simple demo of 3D Tiles feature picking with hover and select behavior + // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); - - // Load the NYC buildings tileset - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - viewer.scene.primitives.add(tileset); - - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; - - // Information about the currently selected feature - const selected = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); + // Load the NYC buildings tileset + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + viewer.scene.primitives.add(tileset); - // Get default left click handler for when a feature is not picked on left click - const clickHandler = viewer.screenSpaceEventHandler.getInputAction( - Cesium.ScreenSpaceEventType.LEFT_CLICK - ); + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; - // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. - // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. - if ( - Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) - ) { - // Silhouettes are supported - const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteBlue.uniforms.color = Cesium.Color.BLUE; - silhouetteBlue.uniforms.length = 0.01; - silhouetteBlue.selected = []; + // Information about the currently selected feature + const selected = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteGreen.uniforms.color = Cesium.Color.LIME; - silhouetteGreen.uniforms.length = 0.01; - silhouetteGreen.selected = []; + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); - viewer.scene.postProcessStages.add( - Cesium.PostProcessStageLibrary.createSilhouetteStage([ - silhouetteBlue, - silhouetteGreen, - ]) + // Get default left click handler for when a feature is not picked on left click + const clickHandler = viewer.screenSpaceEventHandler.getInputAction( + Cesium.ScreenSpaceEventType.LEFT_CLICK ); - // Silhouette a feature blue on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement + // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. + // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. + if ( + Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) ) { - // If a feature was previously highlighted, undo the highlight + // Silhouettes are supported + const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteBlue.uniforms.color = Cesium.Color.BLUE; + silhouetteBlue.uniforms.length = 0.01; silhouetteBlue.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } + const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteGreen.uniforms.color = Cesium.Color.LIME; + silhouetteGreen.uniforms.length = 0.01; + silhouetteGreen.selected = []; + + viewer.scene.postProcessStages.add( + Cesium.PostProcessStageLibrary.createSilhouetteStage([ + silhouetteBlue, + silhouetteGreen, + ]) + ); - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const name = pickedFeature.getProperty("BIN"); - nameOverlay.textContent = name; + // Silhouette a feature blue on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + silhouetteBlue.selected = []; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - silhouetteBlue.selected = [pickedFeature]; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } - // Silhouette a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - silhouetteGreen.selected = []; + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const name = pickedFeature.getProperty("BIN"); + nameOverlay.textContent = name; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + silhouetteBlue.selected = [pickedFeature]; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Select the feature if it's not already selected - if (silhouetteGreen.selected[0] === pickedFeature) { - return; - } + // Silhouette a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + silhouetteGreen.selected = []; - // Save the selected feature's original color - const highlightedFeature = silhouetteBlue.selected[0]; - if (pickedFeature === highlightedFeature) { - silhouetteBlue.selected = []; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } - // Highlight newly selected feature - silhouetteGreen.selected = [pickedFeature]; + // Select the feature if it's not already selected + if (silhouetteGreen.selected[0] === pickedFeature) { + return; + } - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading
'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '' + - "` + - `` + - `` + - `
BIN" - }${pickedFeature.getProperty("BIN")}
DOITT ID${pickedFeature.getProperty( - "DOITT_ID" - )}
SOURCE ID${pickedFeature.getProperty( - "SOURCE_ID" - )}
`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } else { - // Silhouettes are not supported. Instead, change the feature color. + // Save the selected feature's original color + const highlightedFeature = silhouetteBlue.selected[0]; + if (pickedFeature === highlightedFeature) { + silhouetteBlue.selected = []; + } - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Highlight newly selected feature + silhouetteGreen.selected = [pickedFeature]; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - let name = pickedFeature.getProperty("name"); - if (!Cesium.defined(name)) { - name = pickedFeature.getProperty("id"); - } - nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading
'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '' + + "` + + `` + + `` + + `
BIN" + }${pickedFeature.getProperty("BIN")}
DOITT ID${pickedFeature.getProperty( + "DOITT_ID" + )}
SOURCE ID${pickedFeature.getProperty( + "SOURCE_ID" + )}
`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } else { + // Silhouettes are not supported. Instead, change the feature color. - // Color a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - if (Cesium.defined(selected.feature)) { - selected.feature.color = selected.originalColor; - selected.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } - // Select the feature if it's not already selected - if (selected.feature === pickedFeature) { - return; - } - selected.feature = pickedFeature; - // Save the selected feature's original color - if (pickedFeature === highlighted.feature) { - Cesium.Color.clone( - highlighted.originalColor, - selected.originalColor - ); - highlighted.feature = undefined; - } else { - Cesium.Color.clone(pickedFeature.color, selected.originalColor); - } - // Highlight newly selected feature - pickedFeature.color = Cesium.Color.LIME; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading
'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '' + - "` + - `` + - `` + - `` + - `` + - `` + - `` + - `
BIN" - }${pickedFeature.getProperty("BIN")}
DOITT ID${pickedFeature.getProperty( - "DOITT_ID" - )}
SOURCE ID${pickedFeature.getProperty( - "SOURCE_ID" - )}
Longitude${pickedFeature.getProperty( - "longitude" - )}
Latitude${pickedFeature.getProperty( - "latitude" - )}
Height${pickedFeature.getProperty( - "height" - )}
Terrain Height (Ellipsoid)${pickedFeature.getProperty( - "TerrainHeight" - )}
`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; + + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + let name = pickedFeature.getProperty("name"); + if (!Cesium.defined(name)) { + name = pickedFeature.getProperty("id"); + } + nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - //Sandcastle_End + // Color a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + if (Cesium.defined(selected.feature)) { + selected.feature.color = selected.originalColor; + selected.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } + // Select the feature if it's not already selected + if (selected.feature === pickedFeature) { + return; + } + selected.feature = pickedFeature; + // Save the selected feature's original color + if (pickedFeature === highlighted.feature) { + Cesium.Color.clone( + highlighted.originalColor, + selected.originalColor + ); + highlighted.feature = undefined; + } else { + Cesium.Color.clone(pickedFeature.color, selected.originalColor); + } + // Highlight newly selected feature + pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading
'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '' + + "` + + `` + + `` + + `` + + `` + + `` + + `` + + `
BIN" + }${pickedFeature.getProperty("BIN")}
DOITT ID${pickedFeature.getProperty( + "DOITT_ID" + )}
SOURCE ID${pickedFeature.getProperty( + "SOURCE_ID" + )}
Longitude${pickedFeature.getProperty( + "longitude" + )}
Latitude${pickedFeature.getProperty( + "latitude" + )}
Height${pickedFeature.getProperty( + "height" + )}
Terrain Height (Ellipsoid)${pickedFeature.getProperty( + "TerrainHeight" + )}
`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index edff6b0f58f..53f338f2103 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -53,162 +53,166 @@

Loading...

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - - // How to use the 3D Tiles Styling language to style individual features, like buildings. - // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); - - // Add Cesium OSM buildings to the scene as our example 3D Tileset. - const osmBuildingsTileset = Cesium.createOsmBuildings(); - viewer.scene.primitives.add(osmBuildingsTileset); - - // Set the initial camera to look at Seattle - viewer.scene.camera.setView({ - destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), - orientation: { - heading: Cesium.Math.toRadians(10), - pitch: Cesium.Math.toRadians(-10), - }, - }); - - // Styling functions - - // Color by material checks for null values since not all - // buildings have the material property. - function colorByMaterial() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - material: "${feature['building:material']}", - }, - color: { - conditions: [ - ["${material} === null", "color('white')"], - ["${material} === 'glass'", "color('skyblue', 0.5)"], - ["${material} === 'concrete'", "color('grey')"], - ["${material} === 'brick'", "color('indianred')"], - ["${material} === 'stone'", "color('lightslategrey')"], - ["${material} === 'metal'", "color('lightgrey')"], - ["${material} === 'steel'", "color('lightsteelblue')"], - ["true", "color('white')"], // This is the else case - ], - }, + (async () => { + // How to use the 3D Tiles Styling language to style individual features, like buildings. + // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - } - - function highlightAllResidentialBuildings() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - [ - "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", - "color('cyan', 0.9)", - ], - [true, "color('white')"], - ], + const handler = new Cesium.ScreenSpaceEventHandler( + viewer.scene.canvas + ); + + // Add Cesium OSM buildings to the scene as our example 3D Tileset. + const osmBuildingsTileset = Cesium.createOsmBuildings(); + viewer.scene.primitives.add(osmBuildingsTileset); + + // Set the initial camera to look at Seattle + viewer.scene.camera.setView({ + destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), + orientation: { + heading: Cesium.Math.toRadians(10), + pitch: Cesium.Math.toRadians(-10), }, }); - } - - function showByBuildingType(buildingType) { - switch (buildingType) { - case "office": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'office'", - }); - break; - case "apartments": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'apartments'", - }); - break; - default: - break; + + // Styling functions + + // Color by material checks for null values since not all + // buildings have the material property. + function colorByMaterial() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + material: "${feature['building:material']}", + }, + color: { + conditions: [ + ["${material} === null", "color('white')"], + ["${material} === 'glass'", "color('skyblue', 0.5)"], + ["${material} === 'concrete'", "color('grey')"], + ["${material} === 'brick'", "color('indianred')"], + ["${material} === 'stone'", "color('lightslategrey')"], + ["${material} === 'metal'", "color('lightgrey')"], + ["${material} === 'steel'", "color('lightsteelblue')"], + ["true", "color('white')"], // This is the else case + ], + }, + }); } - } - // Color the buildings based on their distance from a selected central location - function colorByDistanceToCoordinate(pickedLatitude, pickedLongitude) { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, - }, - color: { - conditions: [ - ["${distance} > 0.014", "color('blue')"], - ["${distance} > 0.010", "color('green')"], - ["${distance} > 0.006", "color('yellow')"], - ["${distance} > 0.0001", "color('red')"], - ["true", "color('white')"], - ], - }, - }); - } + function highlightAllResidentialBuildings() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + [ + "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", + "color('cyan', 0.9)", + ], + [true, "color('white')"], + ], + }, + }); + } - // When dropdown option is not "Color By Distance To Selected Location", - // remove the left click input event for selecting a central location - function removeCoordinatePickingOnLeftClick() { - document.querySelector(".infoPanel").style.visibility = "hidden"; - handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); - } + function showByBuildingType(buildingType) { + switch (buildingType) { + case "office": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'office'", + }); + break; + case "apartments": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'apartments'", + }); + break; + default: + break; + } + } - // Add event listeners to dropdown menu options - document.querySelector(".infoPanel").style.visibility = "hidden"; - const menu = document.getElementById("dropdown"); + // Color the buildings based on their distance from a selected central location + function colorByDistanceToCoordinate( + pickedLatitude, + pickedLongitude + ) { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, + }, + color: { + conditions: [ + ["${distance} > 0.014", "color('blue')"], + ["${distance} > 0.010", "color('green')"], + ["${distance} > 0.006", "color('yellow')"], + ["${distance} > 0.0001", "color('red')"], + ["true", "color('white')"], + ], + }, + }); + } - menu.options[0].onselect = function () { - removeCoordinatePickingOnLeftClick(); - colorByMaterial(); - }; - - menu.options[1].onselect = function () { - // Default to Space Needle as the central location - colorByDistanceToCoordinate(47.62051, -122.34931); - document.querySelector(".infoPanel").style.visibility = "visible"; - // Add left click input to select a building to and extract its coordinates - handler.setInputAction(function (movement) { - viewer.selectedEntity = undefined; - const pickedBuilding = viewer.scene.pick(movement.position); - if (pickedBuilding) { - const pickedLatitude = pickedBuilding.getProperty( - "cesium#latitude" - ); - const pickedLongitude = pickedBuilding.getProperty( - "cesium#longitude" - ); - colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - }; - - menu.options[2].onselect = function () { - removeCoordinatePickingOnLeftClick(); - highlightAllResidentialBuildings(); - }; - - menu.options[3].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("office"); - }; - - menu.options[4].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("apartments"); - }; - - menu.onchange = function () { - Sandcastle.reset(); - const item = menu.options[menu.selectedIndex]; - if (item && typeof item.onselect === "function") { - item.onselect(); + // When dropdown option is not "Color By Distance To Selected Location", + // remove the left click input event for selecting a central location + function removeCoordinatePickingOnLeftClick() { + document.querySelector(".infoPanel").style.visibility = "hidden"; + handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); } - }; - colorByMaterial(); + // Add event listeners to dropdown menu options + document.querySelector(".infoPanel").style.visibility = "hidden"; + const menu = document.getElementById("dropdown"); + + menu.options[0].onselect = function () { + removeCoordinatePickingOnLeftClick(); + colorByMaterial(); + }; + + menu.options[1].onselect = function () { + // Default to Space Needle as the central location + colorByDistanceToCoordinate(47.62051, -122.34931); + document.querySelector(".infoPanel").style.visibility = "visible"; + // Add left click input to select a building to and extract its coordinates + handler.setInputAction(function (movement) { + viewer.selectedEntity = undefined; + const pickedBuilding = viewer.scene.pick(movement.position); + if (pickedBuilding) { + const pickedLatitude = pickedBuilding.getProperty( + "cesium#latitude" + ); + const pickedLongitude = pickedBuilding.getProperty( + "cesium#longitude" + ); + colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + }; + + menu.options[2].onselect = function () { + removeCoordinatePickingOnLeftClick(); + highlightAllResidentialBuildings(); + }; + + menu.options[3].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("office"); + }; + + menu.options[4].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("apartments"); + }; + + menu.onchange = function () { + Sandcastle.reset(); + const item = menu.options[menu.selectedIndex]; + if (item && typeof item.onselect === "function") { + item.onselect(); + } + }; - //Sandcastle_End + colorByMaterial(); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index d810d2ff656..7063dc45545 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -37,22 +37,24 @@ "use strict"; //Sandcastle_Begin // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - enableDebugWireframe: true, - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + enableDebugWireframe: true, + }); + viewer.scene.primitives.add(tileset); + + await tileset.readyPromise; - tileset.readyPromise.then(function () { viewer.zoomTo( tileset, new Cesium.HeadingPitchRange( @@ -61,8 +63,7 @@ tileset.boundingSphere.radius / 4.0 ) ); - }); - //Sandcastle_End + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index 7a1fc33a496..2ebba29bffa 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -74,194 +74,205 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - if (!scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } + const scene = viewer.scene; + if (!scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } - scene.globe.depthTestAgainstTerrain = true; + scene.globe.depthTestAgainstTerrain = true; - const viewModel = { - rightClickAction: "annotate", - middleClickAction: "hide", - }; + const viewModel = { + rightClickAction: "annotate", + middleClickAction: "hide", + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - const annotations = scene.primitives.add(new Cesium.LabelCollection()); + const annotations = scene.primitives.add( + new Cesium.LabelCollection() + ); - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - meta: { - description: "'Building ${BIN} has height ${Height}.'", - }, - }); + // Load the NYC buildings tileset. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + scene.primitives.add(tileset); + tileset.style = new Cesium.Cesium3DTileStyle({ + meta: { + description: "'Building ${BIN} has height ${Height}.'", + }, + }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.rightClickAction; - if (action === "annotate") { - annotate(movement, feature); - } else if (action === "properties") { - printProperties(movement, feature); - } else if (action === "zoom") { - zoom(movement, feature); - } - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + const action = viewModel.rightClickAction; + if (action === "annotate") { + annotate(movement, feature); + } else if (action === "properties") { + printProperties(movement, feature); + } else if (action === "zoom") { + zoom(movement, feature); + } + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.middleClickAction; - if (action === "hide") { - feature.show = false; - } - }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + const action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); - function annotate(movement, feature) { - if (scene.pickPositionSupported) { - const cartesian = scene.pickPosition(movement.position); - if (Cesium.defined(cartesian)) { - const cartographic = Cesium.Cartographic.fromCartesian(cartesian); - const height = `${cartographic.height.toFixed(2)} m`; + function annotate(movement, feature) { + if (scene.pickPositionSupported) { + const cartesian = scene.pickPosition(movement.position); + if (Cesium.defined(cartesian)) { + const cartographic = Cesium.Cartographic.fromCartesian( + cartesian + ); + const height = `${cartographic.height.toFixed(2)} m`; - annotations.add({ - position: cartesian, - text: height, - showBackground: true, - font: "14px monospace", - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - disableDepthTestDistance: Number.POSITIVE_INFINITY, - }); + annotations.add({ + position: cartesian, + text: height, + showBackground: true, + font: "14px monospace", + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + disableDepthTestDistance: Number.POSITIVE_INFINITY, + }); + } } } - } - function printProperties(movement, feature) { - console.log("Properties:"); - const propertyIds = feature.getPropertyIds(); - const length = propertyIds.length; - for (let i = 0; i < length; ++i) { - const propertyId = propertyIds[i]; - console.log(` ${propertyId}: ${feature.getProperty(propertyId)}`); - } + function printProperties(movement, feature) { + console.log("Properties:"); + const propertyIds = feature.getPropertyIds(); + const length = propertyIds.length; + for (let i = 0; i < length; ++i) { + const propertyId = propertyIds[i]; + console.log( + ` ${propertyId}: ${feature.getProperty(propertyId)}` + ); + } - // Evaluate feature description - console.log( - `Description : ${tileset.style.meta.description.evaluate(feature)}` - ); - } + // Evaluate feature description + console.log( + `Description : ${tileset.style.meta.description.evaluate( + feature + )}` + ); + } - function zoom(movement, feature) { - const longitude = Cesium.Math.toRadians( - feature.getProperty("Longitude") - ); - const latitude = Cesium.Math.toRadians( - feature.getProperty("Latitude") - ); - const height = feature.getProperty("Height"); + function zoom(movement, feature) { + const longitude = Cesium.Math.toRadians( + feature.getProperty("Longitude") + ); + const latitude = Cesium.Math.toRadians( + feature.getProperty("Latitude") + ); + const height = feature.getProperty("Height"); - const positionCartographic = new Cesium.Cartographic( - longitude, - latitude, - height * 0.5 - ); - const position = scene.globe.ellipsoid.cartographicToCartesian( - positionCartographic - ); + const positionCartographic = new Cesium.Cartographic( + longitude, + latitude, + height * 0.5 + ); + const position = scene.globe.ellipsoid.cartographicToCartesian( + positionCartographic + ); - const camera = scene.camera; - const heading = camera.heading; - const pitch = camera.pitch; + const camera = scene.camera; + const heading = camera.heading; + const pitch = camera.pitch; - const offset = offsetFromHeadingPitchRange( - heading, - pitch, - height * 2.0 - ); + const offset = offsetFromHeadingPitchRange( + heading, + pitch, + height * 2.0 + ); - const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - Cesium.Matrix4.multiplyByPoint(transform, offset, position); + const transform = Cesium.Transforms.eastNorthUpToFixedFrame( + position + ); + Cesium.Matrix4.multiplyByPoint(transform, offset, position); - camera.flyTo({ - destination: position, - orientation: { - heading: heading, - pitch: pitch, - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - }); - } - - function offsetFromHeadingPitchRange(heading, pitch, range) { - pitch = Cesium.Math.clamp( - pitch, - -Cesium.Math.PI_OVER_TWO, - Cesium.Math.PI_OVER_TWO - ); - heading = Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; + camera.flyTo({ + destination: position, + orientation: { + heading: heading, + pitch: pitch, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + }); + } - const pitchQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Y, - -pitch - ); - const headingQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Z, - -heading - ); - const rotQuat = Cesium.Quaternion.multiply( - headingQuat, - pitchQuat, - headingQuat - ); - const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); + function offsetFromHeadingPitchRange(heading, pitch, range) { + pitch = Cesium.Math.clamp( + pitch, + -Cesium.Math.PI_OVER_TWO, + Cesium.Math.PI_OVER_TWO + ); + heading = + Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; - const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); - Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); - Cesium.Cartesian3.negate(offset, offset); - Cesium.Cartesian3.multiplyByScalar(offset, range, offset); - return offset; - } + const pitchQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Y, + -pitch + ); + const headingQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Z, + -heading + ); + const rotQuat = Cesium.Quaternion.multiply( + headingQuat, + pitchQuat, + headingQuat + ); + const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); - //Sandcastle_End + const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); + Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); + Cesium.Cartesian3.negate(offset, offset); + Cesium.Cartesian3.multiplyByScalar(offset, range, offset); + return offset; + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index f4bbfa87e3b..1f44a122901 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -35,324 +35,329 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // San Francisco Ferry Building photogrammetry model provided by Aerometrex - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - infoBox: false, - orderIndependentTranslucency: false, - }); - - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2021-11-09T20:27:37.016064475348684937Z" - ); - - const scene = viewer.scene; - - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(775877), - }); - - const translation = new Cesium.Cartesian3( - -1.398521324920626, - 0.7823052871729486, - 0.7015244410592609 - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - - tileset.maximumScreenSpaceError = 8.0; - scene.pickTranslucentDepth = true; - scene.light.intensity = 7.0; - - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - - // Fly to a nice overview of the city. - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - -2703640.80485846, - -4261161.990345464, - 3887439.511104276 - ), - orientation: new Cesium.HeadingPitchRoll( - 0.22426651143535548, - -0.2624145362506527, - 0.000006972977223185239 - ), - }); - - // Styles ============================================================================= - - const classificationStyle = new Cesium.Cesium3DTileStyle({ - color: "color(${color})", - }); - - const translucentWindowsStyle = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [["${component} === 'Windows'", "color('gray', 0.7)"]], - }, - }); - - // Shaders ============================================================================ - - // Dummy shader that sets the UNLIT lighting mode. For use with the classification style - const emptyFragmentShader = - "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {}"; - const unlitShader = new Cesium.CustomShader({ - lightingModel: Cesium.LightingModel.UNLIT, - fragmentShaderText: emptyFragmentShader, - }); - - const materialShader = new Cesium.CustomShader({ - lightingModel: Cesium.LightingModel.PBR, - fragmentShaderText: ` - const int WINDOW = 0; - const int FRAME = 1; - const int WALL = 2; - const int ROOF = 3; - const int SKYLIGHT = 4; - const int AIR_CONDITIONER_WHITE = 5; - const int AIR_CONDITIONER_BLACK = 6; - const int AIR_CONDITIONER_TALL = 7; - const int CLOCK = 8; - const int PILLARS = 9; - const int STREET_LIGHT = 10; - const int TRAFFIC_LIGHT = 11; - - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - int featureId = fsInput.featureIds.featureId_0; - - if (featureId == CLOCK) { - // Shiny brass - material.specular = vec3(0.98, 0.90, 0.59); - material.roughness = 0.1; - } else if ( - featureId == STREET_LIGHT || - featureId == AIR_CONDITIONER_BLACK || - featureId == AIR_CONDITIONER_WHITE || - featureId == AIR_CONDITIONER_TALL || - featureId == ROOF - ) { - // dull aluminum - material.specular = vec3(0.91, 0.92, 0.92); - material.roughness = 0.5; - } else if (featureId == WINDOW || featureId == SKYLIGHT) { - // make translucent, but also set an orange emissive color so it looks like - // it's lit from inside - material.emissive = vec3(1.0, 0.3, 0.0); - material.alpha = 0.5; - } else if (featureId == WALL || featureId == FRAME || featureId == PILLARS) { - // paint the walls and pillars white to contrast the brass clock - material.diffuse = mix(material.diffuse, vec3(1.0), 0.8); - material.roughness = 0.9; - } else { - // brighten everything else - material.diffuse += 0.05; - material.roughness = 0.9; - } - } - `, - }); - - const NOTHING_SELECTED = 12; - const selectFeatureShader = new Cesium.CustomShader({ - uniforms: { - u_selectedFeature: { - type: Cesium.UniformType.INT, - value: NOTHING_SELECTED, - }, - }, - lightingModel: Cesium.LightingModel.PBR, - fragmentShaderText: ` - const int NOTHING_SELECTED = 12; - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - int featureId = fsInput.featureIds.featureId_0; - - if (u_selectedFeature < NOTHING_SELECTED && featureId == u_selectedFeature) { - material.specular = vec3(1.00, 0.85, 0.57); - material.roughness = 0.1; - } - } - `, - }); - - const multipleFeatureIdsShader = new Cesium.CustomShader({ - uniforms: { - u_selectedFeature: { - type: Cesium.UniformType.FLOAT, - value: NOTHING_SELECTED, + (async () => { + // San Francisco Ferry Building photogrammetry model provided by Aerometrex + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + infoBox: false, + orderIndependentTranslucency: false, + }); + + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2021-11-09T20:27:37.016064475348684937Z" + ); + + const scene = viewer.scene; + + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(775877), + }); + + const translation = new Cesium.Cartesian3( + -1.398521324920626, + 0.7823052871729486, + 0.7015244410592609 + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + + tileset.maximumScreenSpaceError = 8.0; + scene.pickTranslucentDepth = true; + scene.light.intensity = 7.0; + + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + + // Fly to a nice overview of the city. + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + -2703640.80485846, + -4261161.990345464, + 3887439.511104276 + ), + orientation: new Cesium.HeadingPitchRoll( + 0.22426651143535548, + -0.2624145362506527, + 0.000006972977223185239 + ), + }); + + // Styles ============================================================================= + + const classificationStyle = new Cesium.Cesium3DTileStyle({ + color: "color(${color})", + }); + + const translucentWindowsStyle = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${component} === 'Windows'", "color('gray', 0.7)"], + ], }, - }, - lightingModel: Cesium.LightingModel.UNLIT, - fragmentShaderText: ` - const int IDS0_WINDOW = 0; - const int IDS1_FACADE = 2; - const int IDS1_ROOF = 3; - const vec3 PURPLE = vec3(0.5, 0.0, 1.0); - const vec3 YELLOW = vec3(1.0, 1.0, 0.0); - const vec3 NO_TINT = vec3(1.0); - - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - int featureId0 = fsInput.featureIds.featureId_0; // fine features - int featureId1 = fsInput.featureIds.featureId_1; // coarse features - - // use both feature ID sets to determine where the features are - float isWindow = float(featureId0 == IDS0_WINDOW); - float isFacade = float(featureId1 == IDS1_FACADE); - float isRoof = float(featureId1 == IDS1_ROOF); - - // Tint the roof windows yellow and facade windows purple - vec3 tint = NO_TINT; - tint = mix(tint, YELLOW, isWindow * isRoof); - tint = mix(tint, PURPLE, isWindow * isFacade); - material.diffuse *= tint; - } - `, - }); - - // Demo Functions ===================================================================== - - function defaults() { - tileset.style = undefined; - tileset.customShader = unlitShader; - tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT; - tileset.colorBlendAmount = 0.5; - tileset.featureIdLabel = 0; + }); + + // Shaders ============================================================================ + + // Dummy shader that sets the UNLIT lighting mode. For use with the classification style + const emptyFragmentShader = + "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {}"; + const unlitShader = new Cesium.CustomShader({ + lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: emptyFragmentShader, + }); + + const materialShader = new Cesium.CustomShader({ + lightingModel: Cesium.LightingModel.PBR, + fragmentShaderText: ` + const int WINDOW = 0; + const int FRAME = 1; + const int WALL = 2; + const int ROOF = 3; + const int SKYLIGHT = 4; + const int AIR_CONDITIONER_WHITE = 5; + const int AIR_CONDITIONER_BLACK = 6; + const int AIR_CONDITIONER_TALL = 7; + const int CLOCK = 8; + const int PILLARS = 9; + const int STREET_LIGHT = 10; + const int TRAFFIC_LIGHT = 11; + + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { + int featureId = fsInput.featureIds.featureId_0; + + if (featureId == CLOCK) { + // Shiny brass + material.specular = vec3(0.98, 0.90, 0.59); + material.roughness = 0.1; + } else if ( + featureId == STREET_LIGHT || + featureId == AIR_CONDITIONER_BLACK || + featureId == AIR_CONDITIONER_WHITE || + featureId == AIR_CONDITIONER_TALL || + featureId == ROOF + ) { + // dull aluminum + material.specular = vec3(0.91, 0.92, 0.92); + material.roughness = 0.5; + } else if (featureId == WINDOW || featureId == SKYLIGHT) { + // make translucent, but also set an orange emissive color so it looks like + // it's lit from inside + material.emissive = vec3(1.0, 0.3, 0.0); + material.alpha = 0.5; + } else if (featureId == WALL || featureId == FRAME || featureId == PILLARS) { + // paint the walls and pillars white to contrast the brass clock + material.diffuse = mix(material.diffuse, vec3(1.0), 0.8); + material.roughness = 0.9; + } else { + // brighten everything else + material.diffuse += 0.05; + material.roughness = 0.9; } - - const showPhotogrammetry = defaults; - - function showClassification() { - defaults(); - tileset.style = classificationStyle; - tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX; + } + `, + }); + + const NOTHING_SELECTED = 12; + const selectFeatureShader = new Cesium.CustomShader({ + uniforms: { + u_selectedFeature: { + type: Cesium.UniformType.INT, + value: NOTHING_SELECTED, + }, + }, + lightingModel: Cesium.LightingModel.PBR, + fragmentShaderText: ` + const int NOTHING_SELECTED = 12; + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { + int featureId = fsInput.featureIds.featureId_0; + + if (u_selectedFeature < NOTHING_SELECTED && featureId == u_selectedFeature) { + material.specular = vec3(1.00, 0.85, 0.57); + material.roughness = 0.1; } + } + `, + }); + + const multipleFeatureIdsShader = new Cesium.CustomShader({ + uniforms: { + u_selectedFeature: { + type: Cesium.UniformType.FLOAT, + value: NOTHING_SELECTED, + }, + }, + lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: ` + const int IDS0_WINDOW = 0; + const int IDS1_FACADE = 2; + const int IDS1_ROOF = 3; + const vec3 PURPLE = vec3(0.5, 0.0, 1.0); + const vec3 YELLOW = vec3(1.0, 1.0, 0.0); + const vec3 NO_TINT = vec3(1.0); + + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { + int featureId0 = fsInput.featureIds.featureId_0; // fine features + int featureId1 = fsInput.featureIds.featureId_1; // coarse features + + // use both feature ID sets to determine where the features are + float isWindow = float(featureId0 == IDS0_WINDOW); + float isFacade = float(featureId1 == IDS1_FACADE); + float isRoof = float(featureId1 == IDS1_ROOF); + + // Tint the roof windows yellow and facade windows purple + vec3 tint = NO_TINT; + tint = mix(tint, YELLOW, isWindow * isRoof); + tint = mix(tint, PURPLE, isWindow * isFacade); + material.diffuse *= tint; + } + `, + }); + + // Demo Functions ===================================================================== + + function defaults() { + tileset.style = undefined; + tileset.customShader = unlitShader; + tileset.colorBlendMode = + Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT; + tileset.colorBlendAmount = 0.5; + tileset.featureIdLabel = 0; + } - function showAlternativeClassification() { - showClassification(); - // This dataset has a second feature ID texture. - tileset.featureIdLabel = 1; - } + const showPhotogrammetry = defaults; - function translucentWindows() { - defaults(); - tileset.style = translucentWindowsStyle; - } + function showClassification() { + defaults(); + tileset.style = classificationStyle; + tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX; + } - function pbrMaterials() { - defaults(); - tileset.customShader = materialShader; - } + function showAlternativeClassification() { + showClassification(); + // This dataset has a second feature ID texture. + tileset.featureIdLabel = 1; + } - function goldenTouch() { - defaults(); - tileset.customShader = selectFeatureShader; - } + function translucentWindows() { + defaults(); + tileset.style = translucentWindowsStyle; + } - function multipleFeatureIds() { - defaults(); - tileset.customShader = multipleFeatureIdsShader; - } + function pbrMaterials() { + defaults(); + tileset.customShader = materialShader; + } - // Pick Handlers ====================================================================== + function goldenTouch() { + defaults(); + tileset.customShader = selectFeatureShader; + } - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; - nameOverlay.style.whiteSpace = "pre-line"; - nameOverlay.style.fontSize = "12px"; + function multipleFeatureIds() { + defaults(); + tileset.customShader = multipleFeatureIdsShader; + } - let enablePicking = true; - const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); - handler.setInputAction(function (movement) { - if (enablePicking) { - const pickedObject = viewer.scene.pick(movement.endPosition); - if (pickedObject instanceof Cesium.Cesium3DTileFeature) { - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const component = pickedObject.getProperty("component"); - const message = `Component: ${component}\nFeature ID: ${pickedObject.featureId}`; - nameOverlay.textContent = message; + // Pick Handlers ====================================================================== + + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; + nameOverlay.style.whiteSpace = "pre-line"; + nameOverlay.style.fontSize = "12px"; + + let enablePicking = true; + const handler = new Cesium.ScreenSpaceEventHandler( + viewer.scene.canvas + ); + handler.setInputAction(function (movement) { + if (enablePicking) { + const pickedObject = viewer.scene.pick(movement.endPosition); + if (pickedObject instanceof Cesium.Cesium3DTileFeature) { + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const component = pickedObject.getProperty("component"); + const message = `Component: ${component}\nFeature ID: ${pickedObject.featureId}`; + nameOverlay.textContent = message; + } else { + nameOverlay.style.display = "none"; + } } else { nameOverlay.style.display = "none"; } - } else { - nameOverlay.style.display = "none"; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - - const clickHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (enablePicking) { - const pickedObject = scene.pick(movement.position); - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.featureId) - ) { - selectFeatureShader.setUniform( - "u_selectedFeature", - pickedObject.featureId - ); - } else { - selectFeatureShader.setUniform( - "u_selectedFeature", - NOTHING_SELECTED - ); + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + + const clickHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (enablePicking) { + const pickedObject = scene.pick(movement.position); + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.featureId) + ) { + selectFeatureShader.setUniform( + "u_selectedFeature", + pickedObject.featureId + ); + } else { + selectFeatureShader.setUniform( + "u_selectedFeature", + NOTHING_SELECTED + ); + } } - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - // UI ============================================================================ - - Sandcastle.addToggleButton("Enable picking", enablePicking, function ( - checked - ) { - enablePicking = checked; - }); + // UI ============================================================================ - const demos = [ - { - text: "Photogrammetry", - onselect: showPhotogrammetry, - }, - { - text: "Show Classification", - onselect: showClassification, - }, - { - text: "Show Alternative Classification", - onselect: showAlternativeClassification, - }, - { - text: "Translucent Windows", - onselect: translucentWindows, - }, - { - text: "Stylized PBR Materials", - onselect: pbrMaterials, - }, - { - text: "Golden Touch", - onselect: goldenTouch, - }, - { - text: "Multiple Feature ID Sets", - onselect: multipleFeatureIds, - }, - ]; - Sandcastle.addToolbarMenu(demos); + Sandcastle.addToggleButton("Enable picking", enablePicking, function ( + checked + ) { + enablePicking = checked; + }); - //Sandcastle_End + const demos = [ + { + text: "Photogrammetry", + onselect: showPhotogrammetry, + }, + { + text: "Show Classification", + onselect: showClassification, + }, + { + text: "Show Alternative Classification", + onselect: showAlternativeClassification, + }, + { + text: "Translucent Windows", + onselect: translucentWindows, + }, + { + text: "Stylized PBR Materials", + onselect: pbrMaterials, + }, + { + text: "Golden Touch", + onselect: goldenTouch, + }, + { + text: "Multiple Feature ID Sets", + onselect: multipleFeatureIds, + }, + ]; + Sandcastle.addToolbarMenu(demos); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 06184d5442d..06ac7065e20 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -36,47 +36,48 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // An example of using a b3dm tileset to classify another b3dm tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + // An example of using a b3dm tileset to classify another b3dm tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - // A normal b3dm tileset containing photogrammetry - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + // A normal b3dm tileset containing photogrammetry + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); - const classificationTilesetUrl = - "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; - // A b3dm tileset used to classify the photogrammetry tileset - const classificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(classificationTileset); + const classificationTilesetUrl = + "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; + // A b3dm tileset used to classify the photogrammetry tileset + const classificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(classificationTileset); - // The same b3dm tileset used for classification, but rendered normally for comparison. - const nonClassificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - show: false, - }); - nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(nonClassificationTileset); + // The same b3dm tileset used for classification, but rendered normally for comparison. + const nonClassificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + show: false, + }); + nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(nonClassificationTileset); - Sandcastle.addToggleButton("Show classification", true, function ( - checked - ) { - classificationTileset.show = checked; - nonClassificationTileset.show = !checked; - }); - //Sandcastle_End + Sandcastle.addToggleButton("Show classification", true, function ( + checked + ) { + classificationTileset.show = checked; + nonClassificationTileset.show = !checked; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index 40d3ceceed2..a53e6ff3122 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -36,18 +36,18 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - - //Sandcastle_End + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index ad23625f174..40c6d2a0784 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -36,83 +36,84 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // An example showing a point cloud tileset classified by a Geometry tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + // An example showing a point cloud tileset classified by a Geometry tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - // Geometry Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry - const classificationTileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - viewer.scene.primitives.add(classificationTileset); + // Geometry Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry + const classificationTileset = new Cesium.Cesium3DTileset({ + url: + "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + viewer.scene.primitives.add(classificationTileset); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${id} === 'roof1'", "color('#004FFF', 0.5)"], - ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], - ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], - ["${id} === 'roof2'", "color('#004FFF', 0.5)"], - ["${id} === 'tower3'", "color('#FF8833', 0.5)"], - ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], - ["true", "color('#FFFF00', 0.5)"], - ], - }, - }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${id} === 'roof1'", "color('#004FFF', 0.5)"], + ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], + ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], + ["${id} === 'roof2'", "color('#004FFF', 0.5)"], + ["${id} === 'tower3'", "color('#FF8833', 0.5)"], + ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], + ["true", "color('#FFFF00', 0.5)"], + ], + }, + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index 8b82011be09..252a9d20f60 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -160,220 +160,223 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - let viewModelTileset; + const scene = viewer.scene; + let viewModelTileset; - if (!Cesium.PointCloudShading.isSupported(scene)) { - window.alert("This browser does not support point cloud shading"); - } + if (!Cesium.PointCloudShading.isSupported(scene)) { + window.alert("This browser does not support point cloud shading"); + } - function reset() { - viewer.scene.primitives.remove(viewModelTileset); - viewModelTileset = undefined; - } + function reset() { + viewer.scene.primitives.remove(viewModelTileset); + viewModelTileset = undefined; + } - // The viewModel tracks the state of our mini application. - const pointClouds = ["St. Helens", "Church"]; - const viewModel = { - exampleTypes: pointClouds, - currentExampleType: pointClouds[0], - maximumScreenSpaceError: 16.0, - geometricErrorScale: 1.0, - maximumAttenuation: 0, // Equivalent to undefined - baseResolution: 0, // Equivalent to undefined - eyeDomeLightingStrength: 1.0, - eyeDomeLightingRadius: 1.0, - }; + // The viewModel tracks the state of our mini application. + const pointClouds = ["St. Helens", "Church"]; + const viewModel = { + exampleTypes: pointClouds, + currentExampleType: pointClouds[0], + maximumScreenSpaceError: 16.0, + geometricErrorScale: 1.0, + maximumAttenuation: 0, // Equivalent to undefined + baseResolution: 0, // Equivalent to undefined + eyeDomeLightingStrength: 1.0, + eyeDomeLightingRadius: 1.0, + }; - function tilesetToViewModel(tileset) { - viewModelTileset = tileset; + function tilesetToViewModel(tileset) { + viewModelTileset = tileset; - const pointCloudShading = tileset.pointCloudShading; - viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; - viewModel.geometricErrorScale = pointCloudShading.geometricErrorScale; - viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation - ? pointCloudShading.maximumAttenuation - : 0; - viewModel.baseResolution = pointCloudShading.baseResolution - ? pointCloudShading.baseResolution - : 0; - viewModel.eyeDomeLightingStrength = - pointCloudShading.eyeDomeLightingStrength; - viewModel.eyeDomeLightingRadius = - pointCloudShading.eyeDomeLightingRadius; - } + const pointCloudShading = tileset.pointCloudShading; + viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; + viewModel.geometricErrorScale = + pointCloudShading.geometricErrorScale; + viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation + ? pointCloudShading.maximumAttenuation + : 0; + viewModel.baseResolution = pointCloudShading.baseResolution + ? pointCloudShading.baseResolution + : 0; + viewModel.eyeDomeLightingStrength = + pointCloudShading.eyeDomeLightingStrength; + viewModel.eyeDomeLightingRadius = + pointCloudShading.eyeDomeLightingRadius; + } - function loadStHelens() { - // Set the initial camera view to look at Mt. St. Helens - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + function loadStHelens() { + // Set the initial camera view to look at Mt. St. Helens + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ - // This tileset uses replacement refinement and has geometric error approximately equal to - // the average interpoint distance in each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - viewer.scene.primitives.add(tileset); + // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ + // This tileset uses replacement refinement and has geometric error approximately equal to + // the average interpoint distance in each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead - tileset.pointCloudShading.baseResolution = undefined; - tileset.pointCloudShading.geometricErrorScale = 1.0; - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead + tileset.pointCloudShading.baseResolution = undefined; + tileset.pointCloudShading.geometricErrorScale = 1.0; + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - tilesetToViewModel(tileset); - } + tilesetToViewModel(tileset); + } - function loadChurch() { - // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + function loadChurch() { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. - tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. - tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. + tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. + tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - tilesetToViewModel(tileset); - } + tilesetToViewModel(tileset); + } - function checkZero(newValue) { - const newValueFloat = parseFloat(newValue); - return newValueFloat === 0.0 ? undefined : newValueFloat; - } + function checkZero(newValue) { + const newValueFloat = parseFloat(newValue); + return newValueFloat === 0.0 ? undefined : newValueFloat; + } - loadStHelens(); + loadStHelens(); - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === pointClouds[0]) { - loadStHelens(); - } else if (newValue === pointClouds[1]) { - loadChurch(); - } - }); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === pointClouds[0]) { + loadStHelens(); + } else if (newValue === pointClouds[1]) { + loadChurch(); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumScreenSpaceError") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumScreenSpaceError") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); + } + }); - Cesium.knockout - .getObservable(viewModel, "geometricErrorScale") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "geometricErrorScale") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumAttenuation") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumAttenuation") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "baseResolution") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.baseResolution = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "baseResolution") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.baseResolution = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingStrength") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingStrength") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( + newValue + ); + } + }); + + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingRadius") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingRadius") - .subscribe(function (newValue) { + Sandcastle.addToggleButton("Enable Attenuation", true, function ( + checked + ) { if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( - newValue - ); + viewModelTileset.pointCloudShading.attenuation = checked; } }); - Sandcastle.addToggleButton("Enable Attenuation", true, function ( - checked - ) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.attenuation = checked; - } - }); - - Sandcastle.addToggleButton("Enable Eye Dome Lighting", true, function ( - checked - ) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLighting = checked; - } - }); - - //Sandcastle_End + Sandcastle.addToggleButton( + "Enable Eye Dome Lighting", + true, + function (checked) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLighting = checked; + } + } + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index 83fcb94f69e..babe9cceede 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -36,30 +36,30 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); - - //Sandcastle_End + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index 640cdda4c0e..f298cfd42fe 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -36,56 +36,57 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const geocoder = viewer.geocoder.viewModel; - geocoder.searchText = "Vienna"; - geocoder.flightDuration = 0.0; - geocoder.search(); + const geocoder = viewer.geocoder.viewModel; + geocoder.searchText = "Vienna"; + geocoder.flightDuration = 0.0; + geocoder.search(); - // Vector 3D Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5737), - }); - viewer.scene.primitives.add(tileset); + // Vector 3D Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5737), + }); + viewer.scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 255, 255, 0.5)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 255, 255, 0.5)", + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW; - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW; + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index 9c1f8bde1f5..dce86820a80 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -32,11 +32,17 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ), - }); //Sandcastle_End + (async () => { + try { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index 8f3c1c8baf2..b1fee24a39d 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -35,89 +35,90 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. - // https://www.pgc.umn.edu/data/arcticdem/ - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3956) - ), - }); + (async () => { + // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. + // https://www.pgc.umn.edu/data/arcticdem/ + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3956) + ), + }); - // Add Alaskan locations - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Denali", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6399828792482234, - 1.0993550795541742, - 5795 - ), - orientation: { - heading: 3.8455, - pitch: -0.4535, - roll: 0.0, - }, - }); + // Add Alaskan locations + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Denali", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6399828792482234, + 1.0993550795541742, + 5795 + ), + orientation: { + heading: 3.8455, + pitch: -0.4535, + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Anchorage Area", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.610708034601548, - 1.0671172431736584, - 1900 - ), - orientation: { - heading: 4.6, - pitch: -0.341, - roll: 0.0, - }, - }); + { + text: "Anchorage Area", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.610708034601548, + 1.0671172431736584, + 1900 + ), + orientation: { + heading: 4.6, + pitch: -0.341, + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Peaks", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6928866820212813, - 1.072394255273859, - 3700 - ), - orientation: { - heading: 1.6308222948889464, - pitch: -0.6473480165020193, - roll: 0.0, - }, - }); + { + text: "Peaks", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6928866820212813, + 1.072394255273859, + 3700 + ), + orientation: { + heading: 1.6308222948889464, + pitch: -0.6473480165020193, + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Riverbed", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6395623497608596, - 1.0976443174490356, - 2070 - ), - orientation: { - heading: 6.068794108659519, - pitch: -0.08514161789475816, - roll: 0.0, - }, - }); + { + text: "Riverbed", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6395623497608596, + 1.0976443174490356, + 2070 + ), + orientation: { + heading: 6.068794108659519, + pitch: -0.08514161789475816, + roll: 0.0, + }, + }); + }, }, - }, - ], - "toolbar" - ); - //Sandcastle_End + ], + "toolbar" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/CZML Path.html b/Apps/Sandcastle/gallery/CZML Path.html index 7590b820f83..1732ea900b3 100644 --- a/Apps/Sandcastle/gallery/CZML Path.html +++ b/Apps/Sandcastle/gallery/CZML Path.html @@ -7243,19 +7243,19 @@ }, ]; - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - baseLayerPicker: false, - shouldAnimate: true, - }); - - viewer.dataSources - .add(Cesium.CzmlDataSource.load(czml)) - .then(function (ds) { - viewer.trackedEntity = ds.entities.getById("path"); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + baseLayerPicker: false, + shouldAnimate: true, }); - //Sandcastle_End + const dataSource = await viewer.dataSources.add( + Cesium.CzmlDataSource.load(czml) + ); + + viewer.trackedEntity = dataSource.entities.getById("path"); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Cardboard.html b/Apps/Sandcastle/gallery/Cardboard.html index 9e42e004de6..7304c8a6aab 100644 --- a/Apps/Sandcastle/gallery/Cardboard.html +++ b/Apps/Sandcastle/gallery/Cardboard.html @@ -35,155 +35,155 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - vrButton: true, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - // Click the VR button in the bottom right of the screen to switch to VR mode. - - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; - - // Follow the path of a plane. See the interpolation Sandcastle example. - Cesium.Math.setRandomNumberSeed(3); - - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); - - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; - viewer.clock.shouldAnimate = true; - - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - const startAngle = Cesium.Math.nextRandomNumber() * 360.0; - const endAngle = startAngle + 360.0; - - const increment = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; - for (let i = startAngle; i < endAngle; i += increment) { - const radians = Cesium.Math.toRadians(i); - const timeIncrement = i - startAngle; - const time = Cesium.JulianDate.addSeconds( - start, - timeIncrement, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1800 - ); - property.addSample(time, position); - } - return property; - } - - const longitude = -112.110693; - const latitude = 36.0994841; - const radius = 0.03; - - const modelURI = - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; - const entity = viewer.entities.add({ - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - position: computeCirclularFlight(longitude, latitude, radius), - model: { - uri: modelURI, - minimumPixelSize: 64, - }, - }); - - entity.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); - - // Set initial camera position and orientation to be when in the model's reference frame. - const camera = viewer.camera; - camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); - camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); - camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); - camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); - - viewer.scene.postUpdate.addEventListener(function (scene, time) { - const position = entity.position.getValue(time); - if (!Cesium.defined(position)) { - return; - } - - let transform; - if (!Cesium.defined(entity.orientation)) { - transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - } else { - const orientation = entity.orientation.getValue(time); - if (!Cesium.defined(orientation)) { - return; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + vrButton: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + // Click the VR button in the bottom right of the screen to switch to VR mode. + + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; + + // Follow the path of a plane. See the interpolation Sandcastle example. + Cesium.Math.setRandomNumberSeed(3); + + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() + ); + + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + viewer.clock.shouldAnimate = true; + + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + const startAngle = Cesium.Math.nextRandomNumber() * 360.0; + const endAngle = startAngle + 360.0; + + const increment = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; + for (let i = startAngle; i < endAngle; i += increment) { + const radians = Cesium.Math.toRadians(i); + const timeIncrement = i - startAngle; + const time = Cesium.JulianDate.addSeconds( + start, + timeIncrement, + new Cesium.JulianDate() + ); + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1800 + ); + property.addSample(time, position); } - - transform = Cesium.Matrix4.fromRotationTranslation( - Cesium.Matrix3.fromQuaternion(orientation), - position - ); + return property; } - // Save camera state - const offset = Cesium.Cartesian3.clone(camera.position); - const direction = Cesium.Cartesian3.clone(camera.direction); - const up = Cesium.Cartesian3.clone(camera.up); - - // Set camera to be in model's reference frame. - camera.lookAtTransform(transform); - - // Reset the camera state to the saved state so it appears fixed in the model's frame. - Cesium.Cartesian3.clone(offset, camera.position); - Cesium.Cartesian3.clone(direction, camera.direction); - Cesium.Cartesian3.clone(up, camera.up); - Cesium.Cartesian3.cross(direction, up, camera.right); - }); - - // Add a few more balloons flying with the one the viewer is in. - const numBalloons = 12; - for (let i = 0; i < numBalloons; ++i) { - const balloonRadius = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; - const balloon = viewer.entities.add({ + const longitude = -112.110693; + const latitude = 36.0994841; + const radius = 0.03; + + const modelURI = + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; + const entity = viewer.entities.add({ availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start: start, stop: stop, }), ]), - position: computeCirclularFlight( - longitude, - latitude, - balloonRadius - ), + position: computeCirclularFlight(longitude, latitude, radius), model: { uri: modelURI, minimumPixelSize: 64, }, }); - balloon.position.setInterpolationOptions({ + entity.position.setInterpolationOptions({ interpolationDegree: 2, interpolationAlgorithm: Cesium.HermitePolynomialApproximation, }); - } - //Sandcastle_End + // Set initial camera position and orientation to be when in the model's reference frame. + const camera = viewer.camera; + camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); + camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); + camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); + camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); + + viewer.scene.postUpdate.addEventListener(function (scene, time) { + const position = entity.position.getValue(time); + if (!Cesium.defined(position)) { + return; + } + + let transform; + if (!Cesium.defined(entity.orientation)) { + transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + } else { + const orientation = entity.orientation.getValue(time); + if (!Cesium.defined(orientation)) { + return; + } + + transform = Cesium.Matrix4.fromRotationTranslation( + Cesium.Matrix3.fromQuaternion(orientation), + position + ); + } + + // Save camera state + const offset = Cesium.Cartesian3.clone(camera.position); + const direction = Cesium.Cartesian3.clone(camera.direction); + const up = Cesium.Cartesian3.clone(camera.up); + + // Set camera to be in model's reference frame. + camera.lookAtTransform(transform); + + // Reset the camera state to the saved state so it appears fixed in the model's frame. + Cesium.Cartesian3.clone(offset, camera.position); + Cesium.Cartesian3.clone(direction, camera.direction); + Cesium.Cartesian3.clone(up, camera.up); + Cesium.Cartesian3.cross(direction, up, camera.right); + }); + + // Add a few more balloons flying with the one the viewer is in. + const numBalloons = 12; + for (let i = 0; i < numBalloons; ++i) { + const balloonRadius = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; + const balloon = viewer.entities.add({ + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + position: computeCirclularFlight( + longitude, + latitude, + balloonRadius + ), + model: { + uri: modelURI, + minimumPixelSize: 64, + }, + }); + + balloon.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 1a6a5ea7750..7c32bfee9fa 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -35,61 +35,62 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - // Tropics of Cancer and Capricorn - const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( - -180.0, - -23.43687, - 180.0, - 23.43687 - ); - - globe.cartographicLimitRectangle = coffeeBeltRectangle; - globe.showSkirts = false; - globe.backFaceCulling = false; - globe.undergroundColor = undefined; - scene.skyAtmosphere.show = false; + // Tropics of Cancer and Capricorn + const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( + -180.0, + -23.43687, + 180.0, + 23.43687 + ); - // Add rectangles to show bounds - const rectangles = []; + globe.cartographicLimitRectangle = coffeeBeltRectangle; + globe.showSkirts = false; + globe.backFaceCulling = false; + globe.undergroundColor = undefined; + scene.skyAtmosphere.show = false; - for (let i = 0; i < 10; i++) { - rectangles.push( - viewer.entities.add({ - rectangle: { - coordinates: coffeeBeltRectangle, - material: Cesium.Color.WHITE.withAlpha(0.0), - height: i * 5000.0, - outline: true, - outlineWidth: 4.0, - outlineColor: Cesium.Color.WHITE, - }, - }) - ); - } + // Add rectangles to show bounds + const rectangles = []; - Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { - if (checked) { - viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; - } else { - viewer.scene.globe.cartographicLimitRectangle = undefined; + for (let i = 0; i < 10; i++) { + rectangles.push( + viewer.entities.add({ + rectangle: { + coordinates: coffeeBeltRectangle, + material: Cesium.Color.WHITE.withAlpha(0.0), + height: i * 5000.0, + outline: true, + outlineWidth: 4.0, + outlineColor: Cesium.Color.WHITE, + }, + }) + ); } - }); - Sandcastle.addToggleButton("Show Bounds", true, function (checked) { - const rectanglesLength = rectangles.length; - for (let i = 0; i < rectanglesLength; i++) { - const rectangleEntity = rectangles[i]; - rectangleEntity.show = checked; - } - }); - //Sandcastle_End + Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { + if (checked) { + viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; + } else { + viewer.scene.globe.cartographicLimitRectangle = undefined; + } + }); + + Sandcastle.addToggleButton("Show Bounds", true, function (checked) { + const rectanglesLength = rectangles.length; + for (let i = 0; i < rectanglesLength; i++) { + const rectangleEntity = rectangles[i]; + rectangleEntity.show = checked; + } + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Cesium Inspector.html b/Apps/Sandcastle/gallery/Cesium Inspector.html index d788fa7e798..6d1773608e2 100644 --- a/Apps/Sandcastle/gallery/Cesium Inspector.html +++ b/Apps/Sandcastle/gallery/Cesium Inspector.html @@ -39,75 +39,83 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; - //Add Cesium Inspector - viewer.extend(Cesium.viewerCesiumInspectorMixin); + //Add Cesium Inspector + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //Add Primitives - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), - }), - modelMatrix: Cesium.Matrix4.multiplyByTranslation( - Cesium.Transforms.eastNorthUpToFixedFrame( - Cesium.Cartesian3.fromDegrees(-105.0, 45.0) - ), - new Cesium.Cartesian3(0.0, 0.0, 250000), - new Cesium.Matrix4() - ), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.RED.withAlpha(0.5) - ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance({ - closed: true, - }), - }) - ); - - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -93.0, - 37.0 + //Add Primitives + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3( + 400000.0, + 300000.0, + 500000.0 + ), + }), + modelMatrix: Cesium.Matrix4.multiplyByTranslation( + Cesium.Transforms.eastNorthUpToFixedFrame( + Cesium.Cartesian3.fromDegrees(-105.0, 45.0) + ), + new Cesium.Cartesian3(0.0, 0.0, 250000), + new Cesium.Matrix4() ), - height: 100000, - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.RED.withAlpha(0.5) + ), + }, }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.BLUE - ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance(), - }) - ); + appearance: new Cesium.PerInstanceColorAppearance({ + closed: true, + }), + }) + ); - const billboards = scene.primitives.add( - new Cesium.BillboardCollection() - ); - billboards.add({ - position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 150000), - image: "../images/Cesium_Logo_overlay.png", - }); + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -93.0, + 37.0 + ), + height: 100000, + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.BLUE + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance(), + }) + ); - //Sandcastle_End + const billboards = scene.primitives.add( + new Cesium.BillboardCollection() + ); + billboards.add({ + position: Cesium.Cartesian3.fromDegrees( + -75.59777, + 40.03883, + 150000 + ), + image: "../images/Cesium_Logo_overlay.png", + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index f31894fa20d..ea639ecbb39 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -38,19 +38,21 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.primitives.add(Cesium.createOsmBuildings()); + viewer.scene.primitives.add(Cesium.createOsmBuildings()); - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), - orientation: { - heading: Cesium.Math.toRadians(20), - pitch: Cesium.Math.toRadians(-20), - }, - }); //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), + orientation: { + heading: Cesium.Math.toRadians(20), + pitch: Cesium.Math.toRadians(-20), + }, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 9e6aa03d4f4..016a5720fb5 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -36,10 +36,15 @@ "use strict"; //Sandcastle_Begin // For more information on Cesium World Terrain, see https://cesium.com/platform/cesium-ion/content/cesium-world-terrain/ - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - //Sandcastle_End + (async () => { + try { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index 76e1066c883..57ccc1cb57a 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -35,57 +35,58 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const clock = viewer.clock; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + const clock = viewer.clock; - let entity; - let positionProperty; - const dataSourcePromise = Cesium.CzmlDataSource.load( - "../../SampleData/ClampToGround.czml" - ); - viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { - entity = dataSource.entities.getById("CesiumMilkTruck"); - positionProperty = entity.position; - }); + let entity; + let positionProperty; + const dataSourcePromise = Cesium.CzmlDataSource.load( + "../../SampleData/ClampToGround.czml" + ); + viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { + entity = dataSource.entities.getById("CesiumMilkTruck"); + positionProperty = entity.position; + }); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) + ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1216403.8845586285, - -4736357.493351395, - 4081299.715698949 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.2892217081808806, - -0.4799070147502502, - 6.279789177843313 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1216403.8845586285, + -4736357.493351395, + 4081299.715698949 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.2892217081808806, + -0.4799070147502502, + 6.279789177843313 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - if (scene.clampToHeightSupported) { - tileset.initialTilesLoaded.addEventListener(start); - } else { - window.alert("This browser does not support clampToHeight."); - } + if (scene.clampToHeightSupported) { + tileset.initialTilesLoaded.addEventListener(start); + } else { + window.alert("This browser does not support clampToHeight."); + } - function start() { - clock.shouldAnimate = true; - const objectsToExclude = [entity]; - scene.postRender.addEventListener(function () { - const position = positionProperty.getValue(clock.currentTime); - entity.position = scene.clampToHeight(position, objectsToExclude); - }); - } - //Sandcastle_End + function start() { + clock.shouldAnimate = true; + const objectsToExclude = [entity]; + scene.postRender.addEventListener(function () { + const position = positionProperty.getValue(clock.currentTime); + entity.position = scene.clampToHeight(position, objectsToExclude); + }); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index 6a6aa99db69..a83c15167cc 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -37,255 +37,300 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + viewer.scene.globe.depthTestAgainstTerrain = true; - Sandcastle.addDefaultToolbarMenu( - [ - { - // - // To clamp points or billboards set the heightReference to CLAMP_TO_GROUND or RELATIVE_TO_GROUND - // - text: "Draw Point with Label", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - point: { - color: Cesium.Color.SKYBLUE, - pixelSize: 10, - outlineColor: Cesium.Color.YELLOW, - outlineWidth: 3, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - label: { - text: "Clamped to ground", - font: "14pt sans-serif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BASELINE, - fillColor: Cesium.Color.BLACK, - showBackground: true, - backgroundColor: new Cesium.Color(1, 1, 1, 0.7), - backgroundPadding: new Cesium.Cartesian2(8, 4), - disableDepthTestDistance: Number.POSITIVE_INFINITY, // draws the label in front of terrain - }, - }); + Sandcastle.addDefaultToolbarMenu( + [ + { + // + // To clamp points or billboards set the heightReference to CLAMP_TO_GROUND or RELATIVE_TO_GROUND + // + text: "Draw Point with Label", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + point: { + color: Cesium.Color.SKYBLUE, + pixelSize: 10, + outlineColor: Cesium.Color.YELLOW, + outlineWidth: 3, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + label: { + text: "Clamped to ground", + font: "14pt sans-serif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BASELINE, + fillColor: Cesium.Color.BLACK, + showBackground: true, + backgroundColor: new Cesium.Color(1, 1, 1, 0.7), + backgroundPadding: new Cesium.Cartesian2(8, 4), + disableDepthTestDistance: Number.POSITIVE_INFINITY, // draws the label in front of terrain + }, + }); - viewer.trackedEntity = e; + viewer.trackedEntity = e; + }, }, - }, - { - text: "Draw Billboard", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - billboard: { - image: "../images/facility.gif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + { + text: "Draw Billboard", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + billboard: { + image: "../images/facility.gif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - viewer.trackedEntity = e; + viewer.trackedEntity = e; + }, }, - }, - { - // - // Corridors, polygons and rectangles will be clamped automatically if they are filled with a constant color and - // has no height or extruded height. - // NOTE: Setting height to 0 will disable clamping. - // - text: "Draw Corridor", - onselect: function () { - const e = viewer.entities.add({ - corridor: { - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.19, - 46.1914, - -122.21, - 46.21, - -122.23, - 46.21, - ]), - width: 2000.0, - material: Cesium.Color.GREEN.withAlpha(0.5), - }, - }); + { + // + // Corridors, polygons and rectangles will be clamped automatically if they are filled with a constant color and + // has no height or extruded height. + // NOTE: Setting height to 0 will disable clamping. + // + text: "Draw Corridor", + onselect: function () { + const e = viewer.entities.add({ + corridor: { + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.19, + 46.1914, + -122.21, + 46.21, + -122.23, + 46.21, + ]), + width: 2000.0, + material: Cesium.Color.GREEN.withAlpha(0.5), + }, + }); - viewer.zoomTo(e); + viewer.zoomTo(e); + }, }, - }, - { - text: "Draw Polygon", - onselect: function () { - const e = viewer.entities.add({ - polygon: { - hierarchy: { - positions: [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ], + { + text: "Draw Polygon", + onselect: function () { + const e = viewer.entities.add({ + polygon: { + hierarchy: { + positions: [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ], + }, + material: Cesium.Color.BLUE.withAlpha(0.5), }, - material: Cesium.Color.BLUE.withAlpha(0.5), - }, - }); + }); - viewer.zoomTo(e); + viewer.zoomTo(e); + }, }, - }, - { - text: "Draw Textured Polygon", - onselect: function () { - if ( - !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( - viewer.scene - ) - ) { - window.alert( - "Terrain Entity materials are not supported on this platform" - ); - return; - } + { + text: "Draw Textured Polygon", + onselect: function () { + if ( + !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( + viewer.scene + ) + ) { + window.alert( + "Terrain Entity materials are not supported on this platform" + ); + return; + } - const e = viewer.entities.add({ - polygon: { - hierarchy: { - positions: [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ], + const e = viewer.entities.add({ + polygon: { + hierarchy: { + positions: [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ], + }, + material: "../images/Cesium_Logo_Color.jpg", + classificationType: Cesium.ClassificationType.TERRAIN, + stRotation: Cesium.Math.toRadians(45), }, - material: "../images/Cesium_Logo_Color.jpg", - classificationType: Cesium.ClassificationType.TERRAIN, - stRotation: Cesium.Math.toRadians(45), - }, - }); + }); - viewer.zoomTo(e); + viewer.zoomTo(e); + }, }, - }, - { - text: "Draw Rectangle", - onselect: function () { - const e = viewer.entities.add({ - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.3, - 46.0, - -122.0, - 46.3 - ), - material: Cesium.Color.RED.withAlpha(0.5), - }, - }); + { + text: "Draw Rectangle", + onselect: function () { + const e = viewer.entities.add({ + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.3, + 46.0, + -122.0, + 46.3 + ), + material: Cesium.Color.RED.withAlpha(0.5), + }, + }); - viewer.zoomTo(e); + viewer.zoomTo(e); + }, }, - }, - { - text: "Draw Model", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - minimumPixelSize: 128, - maximumScale: 100, - }, - }); + { + text: "Draw Model", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + minimumPixelSize: 128, + maximumScale: 100, + }, + }); - viewer.trackedEntity = e; + viewer.trackedEntity = e; + }, }, - }, - { - text: "Sample line positions and draw with depth test disabled", - onselect: function () { - const length = 1000; + { + text: "Sample line positions and draw with depth test disabled", + onselect: function () { + const length = 1000; - const startLon = Cesium.Math.toRadians(86.953793); - const endLon = Cesium.Math.toRadians(86.896497); + const startLon = Cesium.Math.toRadians(86.953793); + const endLon = Cesium.Math.toRadians(86.896497); - const lat = Cesium.Math.toRadians(27.988257); + const lat = Cesium.Math.toRadians(27.988257); - const terrainSamplePositions = []; - for (let i = 0; i < length; ++i) { - const lon = Cesium.Math.lerp( - endLon, - startLon, - i / (length - 1) - ); - const position = new Cesium.Cartographic(lon, lat); - terrainSamplePositions.push(position); - } + const terrainSamplePositions = []; + for (let i = 0; i < length; ++i) { + const lon = Cesium.Math.lerp( + endLon, + startLon, + i / (length - 1) + ); + const position = new Cesium.Cartographic(lon, lat); + terrainSamplePositions.push(position); + } + + Promise.resolve( + Cesium.sampleTerrainMostDetailed( + viewer.terrainProvider, + terrainSamplePositions + ) + ).then(function (samples) { + let offset = 10.0; + for (let i = 0; i < samples.length; ++i) { + samples[i].height += offset; + } - Promise.resolve( - Cesium.sampleTerrainMostDetailed( - viewer.terrainProvider, - terrainSamplePositions - ) - ).then(function (samples) { - let offset = 10.0; - for (let i = 0; i < samples.length; ++i) { - samples[i].height += offset; + viewer.entities.add({ + polyline: { + positions: Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray( + samples + ), + arcType: Cesium.ArcType.NONE, + width: 5, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.ORANGE, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty( + { + color: Cesium.Color.RED, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + } + ), + }, + }); + + const target = new Cesium.Cartesian3( + 300770.50872389384, + 5634912.131394585, + 2978152.2865545116 + ); + offset = new Cesium.Cartesian3( + 6344.974098678562, + -793.3419798081741, + 2499.9508860763162 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }); + }, + }, + { + text: "Draw polyline on terrain", + onselect: function () { + if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { + window.alert( + "Polylines on terrain are not supported on this platform" + ); } viewer.entities.add({ polyline: { - positions: Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray( - samples - ), - arcType: Cesium.ArcType.NONE, + positions: Cesium.Cartesian3.fromDegreesArray([ + 86.953793, + 27.928257, + 86.953793, + 27.988257, + 86.896497, + 27.988257, + ]), + clampToGround: true, width: 5, material: new Cesium.PolylineOutlineMaterialProperty({ color: Cesium.Color.ORANGE, outlineWidth: 2, outlineColor: Cesium.Color.BLACK, }), - depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty( - { - color: Cesium.Color.RED, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - } - ), }, }); @@ -294,68 +339,23 @@ 5634912.131394585, 2978152.2865545116 ); - offset = new Cesium.Cartesian3( + const offset = new Cesium.Cartesian3( 6344.974098678562, -793.3419798081741, 2499.9508860763162 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); + }, }, - }, - { - text: "Draw polyline on terrain", - onselect: function () { - if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { - window.alert( - "Polylines on terrain are not supported on this platform" - ); - } - - viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArray([ - 86.953793, - 27.928257, - 86.953793, - 27.988257, - 86.896497, - 27.988257, - ]), - clampToGround: true, - width: 5, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.ORANGE, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - }, - }); - - const target = new Cesium.Cartesian3( - 300770.50872389384, - 5634912.131394585, - 2978152.2865545116 - ); - const offset = new Cesium.Cartesian3( - 6344.974098678562, - -793.3419798081741, - 2499.9508860763162 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }, - }, - ], - "zoomButtons" - ); - - Sandcastle.reset = function () { - viewer.entities.removeAll(); - }; + ], + "zoomButtons" + ); - //Sandcastle_End + Sandcastle.reset = function () { + viewer.entities.removeAll(); + }; + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 747d10e7811..5d61ed4521f 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -35,140 +35,141 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); - tileset.readyPromise.then(function () { - const boundingSphere = tileset.boundingSphere; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - boundingSphere.radius + 500.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); + tileset.readyPromise.then(function () { + const boundingSphere = tileset.boundingSphere; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + boundingSphere.radius + 500.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromRadiansArray([ - -1.3194369277314022, - 0.6988062530900625, - -1.3193955980204217, - 0.6988091578771254, - -1.3193931220959367, - 0.698743632490865, - -1.3194358224045408, - 0.6987471965556998, - ]) - ), - material: Cesium.Color.RED.withAlpha(0.5), - classificationType: Cesium.ClassificationType.BOTH, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromRadiansArray([ + -1.3194369277314022, + 0.6988062530900625, + -1.3193955980204217, + 0.6988091578771254, + -1.3193931220959367, + 0.698743632490865, + -1.3194358224045408, + 0.6987471965556998, + ]) + ), + material: Cesium.Color.RED.withAlpha(0.5), + classificationType: Cesium.ClassificationType.BOTH, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArray([ - -75.60217330403601, - 40.04102882709425, - -75.59968252414251, - 40.04093615560871, - -75.598020153828, - 40.04079437042357, - -75.59674934074435, - 40.040816173283304, - -75.59630042791713, - 40.03986900370842, - -75.59563636849978, - 40.03930996506271, - -75.59492397899098, - 40.03873932846581, - -75.59457991226778, - 40.038392701955786, - -75.59424838652453, - 40.03775403572295, - -75.59387104290336, - 40.03677022167725, - -75.59355000490342, - 40.03588760913535, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArray([ + -75.60217330403601, + 40.04102882709425, + -75.59968252414251, + 40.04093615560871, + -75.598020153828, + 40.04079437042357, + -75.59674934074435, + 40.040816173283304, + -75.59630042791713, + 40.03986900370842, + -75.59563636849978, + 40.03930996506271, + -75.59492397899098, + 40.03873932846581, + -75.59457991226778, + 40.038392701955786, + -75.59424838652453, + 40.03775403572295, + -75.59387104290336, + 40.03677022167725, + -75.59355000490342, + 40.03588760913535, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const classificationOptions = [ - { - text: "Classify Both", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.BOTH; - polyline.polyline.classificationType = - Cesium.ClassificationType.BOTH; + const classificationOptions = [ + { + text: "Classify Both", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.BOTH; + polyline.polyline.classificationType = + Cesium.ClassificationType.BOTH; + }, }, - }, - { - text: "Classify Terrain", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.TERRAIN; - polyline.polyline.classificationType = - Cesium.ClassificationType.TERRAIN; + { + text: "Classify Terrain", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.TERRAIN; + polyline.polyline.classificationType = + Cesium.ClassificationType.TERRAIN; + }, }, - }, - { - text: "Classify 3D Tiles", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.CESIUM_3D_TILE; - polyline.polyline.classificationType = - Cesium.ClassificationType.CESIUM_3D_TILE; + { + text: "Classify 3D Tiles", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.CESIUM_3D_TILE; + polyline.polyline.classificationType = + Cesium.ClassificationType.CESIUM_3D_TILE; + }, }, - }, - ]; + ]; - const materialOptions = [ - { - text: "Red Material", - onselect: function () { - polygon.polygon.material = Cesium.Color.RED.withAlpha(0.5); + const materialOptions = [ + { + text: "Red Material", + onselect: function () { + polygon.polygon.material = Cesium.Color.RED.withAlpha(0.5); + }, }, - }, - { - text: "Textured Material", - onselect: function () { - if ( - !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( - viewer.scene - ) - ) { - window.alert( - "Terrain Entity materials are not supported on this platform" - ); - } - polygon.polygon.material = "../images/Cesium_Logo_Color.jpg"; + { + text: "Textured Material", + onselect: function () { + if ( + !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( + viewer.scene + ) + ) { + window.alert( + "Terrain Entity materials are not supported on this platform" + ); + } + polygon.polygon.material = "../images/Cesium_Logo_Color.jpg"; + }, }, - }, - ]; + ]; - Sandcastle.addToolbarMenu(classificationOptions); - Sandcastle.addToolbarMenu(materialOptions); - //Sandcastle_End + Sandcastle.addToolbarMenu(classificationOptions); + Sandcastle.addToolbarMenu(materialOptions); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index 9dd523dcf77..b9b003fa070 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -79,276 +79,314 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const camera = scene.camera; + const scene = viewer.scene; + const camera = scene.camera; - let center = new Cesium.Cartesian3( - 1216389.3637977627, - -4736323.641980423, - 4081321.7428341154 - ); - let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) - ); - let hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + let center = new Cesium.Cartesian3( + 1216389.3637977627, + -4736323.641980423, + 4081321.7428341154 + ); + let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) + ); + let hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const buildingHighlight = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), + const buildingHighlight = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216409.0189737265, - -4736252.144235287, - 4081393.6027081604 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.4, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216409.0189737265, + -4736252.144235287, + 4081393.6027081604 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.4, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight1 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + const treeHighlight1 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 1", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 1", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216404.8844045496, - -4736255.287065536, - 4081392.010192471 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(-0.25, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216404.8844045496, + -4736255.287065536, + 4081392.010192471 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(-0.25, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight2 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + const treeHighlight2 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 2", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 2", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216398.813990024, - -4736258.039875737, - 4081387.9562678365 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216398.813990024, + -4736258.039875737, + 4081387.9562678365 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight3 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), + const treeHighlight3 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 3", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 3", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216393.6257790313, - -4736259.809075361, - 4081384.4858198245 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -1.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216393.6257790313, + -4736259.809075361, + 4081384.4858198245 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -1.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight4 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.SphereGeometry({ - radius: 2.0, + const treeHighlight4 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.SphereGeometry({ + radius: 2.0, + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 4", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); + + function highlightBuilding() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216394.1392207467, + -4736348.59346919, + 4081293.9160685353 + ), + orientation: { + heading: 0.018509338875732695, + pitch: -0.09272999615872646, }, - id: "volume 4", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + }); + } - function highlightBuilding() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216394.1392207467, - -4736348.59346919, - 4081293.9160685353 - ), - orientation: { - heading: 0.018509338875732695, - pitch: -0.09272999615872646, - }, - }); - } + function highlightTrees() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216435.0352745096, + -4736283.144192113, + 4081368.0920420634 + ), + orientation: { + heading: 5.718380792746039, + pitch: -0.3087010195266797, + }, + }); + } - function highlightTrees() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216435.0352745096, - -4736283.144192113, - 4081368.0920420634 - ), - orientation: { - heading: 5.718380792746039, - pitch: -0.3087010195266797, - }, - }); - } + function invertClassification(checked) { + if (checked && !scene.invertClassificationSupported) { + window.alert( + "This browser does not support invert classification" + ); + } - function invertClassification(checked) { - if (checked && !scene.invertClassificationSupported) { - window.alert("This browser does not support invert classification"); - } + scene.invertClassification = checked; + scene.invertClassificationColor = new Cesium.Color( + 0.25, + 0.25, + 0.25, + 1.0 + ); - scene.invertClassification = checked; - scene.invertClassificationColor = new Cesium.Color( - 0.25, - 0.25, - 0.25, - 1.0 - ); + buildingHighlight.getGeometryInstanceAttributes( + "volume" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight1.getGeometryInstanceAttributes( + "volume 1" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight2.getGeometryInstanceAttributes( + "volume 2" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight3.getGeometryInstanceAttributes( + "volume 3" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight4.getGeometryInstanceAttributes( + "volume 4" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + } - buildingHighlight.getGeometryInstanceAttributes( - "volume" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight1.getGeometryInstanceAttributes( - "volume 1" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight2.getGeometryInstanceAttributes( - "volume 2" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight3.getGeometryInstanceAttributes( - "volume 3" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight4.getGeometryInstanceAttributes( - "volume 4" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - } + function updateAlpha(value) { + scene.invertClassificationColor.alpha = parseFloat(value); + } - function updateAlpha(value) { - scene.invertClassificationColor.alpha = parseFloat(value); - } + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + scene.primitives.add(tileset); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - scene.primitives.add(tileset); + const viewModel = { + inverted: viewer.scene.invertClassification, + invertedAlpha: viewer.scene.invertClassificationColor.alpha, + highlightBuilding: highlightBuilding, + highlightTrees: highlightTrees, + }; + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + Cesium.knockout + .getObservable(viewModel, "inverted") + .subscribe(invertClassification); + Cesium.knockout + .getObservable(viewModel, "invertedAlpha") + .subscribe(updateAlpha); - const viewModel = { - inverted: viewer.scene.invertClassification, - invertedAlpha: viewer.scene.invertClassificationColor.alpha, - highlightBuilding: highlightBuilding, - highlightTrees: highlightTrees, - }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "inverted") - .subscribe(invertClassification); - Cesium.knockout - .getObservable(viewModel, "invertedAlpha") - .subscribe(updateAlpha); + highlightTrees(); - highlightTrees(); + let currentObjectId; + let currentPrimitive; + let currentColor; + let currentShow; + let attributes; - let currentObjectId; - let currentPrimitive; - let currentColor; - let currentShow; - let attributes; + const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.id) + ) { + if (pickedObject.id === currentObjectId) { + return; + } - const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) { - if (pickedObject.id === currentObjectId) { - return; + if (Cesium.defined(currentObjectId)) { + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + attributes.color = currentColor; + attributes.show = currentShow; + currentObjectId = undefined; + currentPrimitive = undefined; + currentColor = undefined; + currentShow = undefined; + } } - if (Cesium.defined(currentObjectId)) { + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.primitive) && + Cesium.defined(pickedObject.id) && + Cesium.defined( + pickedObject.primitive.getGeometryInstanceAttributes + ) + ) { + currentObjectId = pickedObject.id; + currentPrimitive = pickedObject.primitive; + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + currentColor = attributes.color; + currentShow = attributes.show; + if (!scene.invertClassification) { + attributes.color = [255, 0, 255, 128]; + } + attributes.show = [1]; + } else if (Cesium.defined(currentObjectId)) { attributes = currentPrimitive.getGeometryInstanceAttributes( currentObjectId ); @@ -357,39 +395,9 @@ currentObjectId = undefined; currentPrimitive = undefined; currentColor = undefined; - currentShow = undefined; } - } - - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.primitive) && - Cesium.defined(pickedObject.id) && - Cesium.defined(pickedObject.primitive.getGeometryInstanceAttributes) - ) { - currentObjectId = pickedObject.id; - currentPrimitive = pickedObject.primitive; - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - currentColor = attributes.color; - currentShow = attributes.show; - if (!scene.invertClassification) { - attributes.color = [255, 0, 255, 128]; - } - attributes.show = [1]; - } else if (Cesium.defined(currentObjectId)) { - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - attributes.color = currentColor; - attributes.show = currentShow; - currentObjectId = undefined; - currentPrimitive = undefined; - currentColor = undefined; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - //Sandcastle_End + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index 355d49cf6a3..cf6d8466f53 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -32,242 +32,243 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - infoBox: false, - shouldAnimate: true, - }); - - const scene = viewer.scene; - scene.primitives.add(Cesium.createOsmBuildings()); - - /////////////////////////// - // Create clouds - /////////////////////////// + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + infoBox: false, + shouldAnimate: true, + }); - Cesium.Math.setRandomNumberSeed(2.5); - function getRandomNumberInRange(minValue, maxValue) { - return ( - minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) - ); - } + const scene = viewer.scene; + scene.primitives.add(Cesium.createOsmBuildings()); - const clouds = new Cesium.CloudCollection(); + /////////////////////////// + // Create clouds + /////////////////////////// - // manually position clouds in the mountains - function createBackLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), - scale: new Cesium.Cartesian2(1500, 250), - maximumSize: new Cesium.Cartesian3(50, 15, 13), - slice: 0.3, - }); + Cesium.Math.setRandomNumberSeed(2.5); + function getRandomNumberInRange(minValue, maxValue) { + return ( + minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) + ); + } - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), - scale: new Cesium.Cartesian2(1500, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.36, - }); + const clouds = new Cesium.CloudCollection(); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), - scale: new Cesium.Cartesian2(2000, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.49, - }); + // manually position clouds in the mountains + function createBackLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), + scale: new Cesium.Cartesian2(1500, 250), + maximumSize: new Cesium.Cartesian3(50, 15, 13), + slice: 0.3, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(13, 13, 13), - slice: 0.2, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), + scale: new Cesium.Cartesian2(1500, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.36, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), - scale: new Cesium.Cartesian2(1700, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.6, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), + scale: new Cesium.Cartesian2(2000, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.49, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(15, 13, 15), - slice: 0.35, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(13, 13, 13), + slice: 0.2, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), - scale: new Cesium.Cartesian2(1500, 500), - maximumSize: new Cesium.Cartesian3(30, 20, 17), - slice: 0.45, - }); - } + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), + scale: new Cesium.Cartesian2(1700, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.6, + }); - let long, - lat, - height, - scaleX, - scaleY, - aspectRatio, - cloudHeight, - depth, - slice; + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(15, 13, 15), + slice: 0.35, + }); - // randomly generate clouds in a certain area - function createRandomClouds( - numClouds, - startLong, - stopLong, - startLat, - stopLat, - minHeight, - maxHeight - ) { - const rangeLong = stopLong - startLong; - const rangeLat = stopLat - startLat; - for (let i = 0; i < numClouds; i++) { - long = startLong + getRandomNumberInRange(0, rangeLong); - lat = startLat + getRandomNumberInRange(0, rangeLat); - height = getRandomNumberInRange(minHeight, maxHeight); - scaleX = getRandomNumberInRange(150, 350); - scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); - slice = getRandomNumberInRange(0.3, 0.7); - depth = getRandomNumberInRange(5, 20); - aspectRatio = getRandomNumberInRange(1.5, 2.1); - cloudHeight = getRandomNumberInRange(5, 20); clouds.add({ - position: Cesium.Cartesian3.fromDegrees(long, lat, height), - scale: new Cesium.Cartesian2(scaleX, scaleY), - maximumSize: new Cesium.Cartesian3( - aspectRatio * cloudHeight, - cloudHeight, - depth - ), - slice: slice, + position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), + scale: new Cesium.Cartesian2(1500, 500), + maximumSize: new Cesium.Cartesian3(30, 20, 17), + slice: 0.45, }); } - } - // manually position clouds in front - const scratch = new Cesium.Cartesian3(); - function createFrontLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), - scale: new Cesium.Cartesian2(400, 150), - maximumSize: new Cesium.Cartesian3(25, 12, 15), - slice: 0.36, - }); + let long, + lat, + height, + scaleX, + scaleY, + aspectRatio, + cloudHeight, + depth, + slice; - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), - scale: new Cesium.Cartesian2(450, 200), - maximumSize: new Cesium.Cartesian3(25, 14, 12), - slice: 0.3, - }); - } + // randomly generate clouds in a certain area + function createRandomClouds( + numClouds, + startLong, + stopLong, + startLat, + stopLat, + minHeight, + maxHeight + ) { + const rangeLong = stopLong - startLong; + const rangeLat = stopLat - startLat; + for (let i = 0; i < numClouds; i++) { + long = startLong + getRandomNumberInRange(0, rangeLong); + lat = startLat + getRandomNumberInRange(0, rangeLat); + height = getRandomNumberInRange(minHeight, maxHeight); + scaleX = getRandomNumberInRange(150, 350); + scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); + slice = getRandomNumberInRange(0.3, 0.7); + depth = getRandomNumberInRange(5, 20); + aspectRatio = getRandomNumberInRange(1.5, 2.1); + cloudHeight = getRandomNumberInRange(5, 20); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(long, lat, height), + scale: new Cesium.Cartesian2(scaleX, scaleY), + maximumSize: new Cesium.Cartesian3( + aspectRatio * cloudHeight, + cloudHeight, + depth + ), + slice: slice, + }); + } + } - createBackLayerClouds(); - createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); - createFrontLayerClouds(); + // manually position clouds in front + const scratch = new Cesium.Cartesian3(); + function createFrontLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), + scale: new Cesium.Cartesian2(400, 150), + maximumSize: new Cesium.Cartesian3(25, 12, 15), + slice: 0.36, + }); - scene.primitives.add(clouds); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), + scale: new Cesium.Cartesian2(450, 200), + maximumSize: new Cesium.Cartesian3(25, 14, 12), + slice: 0.3, + }); + } - /////////////////////////// - // Create hot air balloons - /////////////////////////// + createBackLayerClouds(); + createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); + createFrontLayerClouds(); - const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); - const stop = Cesium.JulianDate.addSeconds( - start, - 90, - new Cesium.JulianDate() - ); + scene.primitives.add(clouds); - function computeBalloonFlight(long, lat, height0, height1) { - const property = new Cesium.SampledPositionProperty(); - const time0 = start.clone(); - const time1 = Cesium.JulianDate.addSeconds( - time0, - 30, - new Cesium.JulianDate() - ); - const time2 = Cesium.JulianDate.addSeconds( - time1, - 15, - new Cesium.JulianDate() - ); - const time3 = Cesium.JulianDate.addSeconds( - time2, - 30, - new Cesium.JulianDate() - ); - const time4 = Cesium.JulianDate.addSeconds( - time3, - 15, + /////////////////////////// + // Create hot air balloons + /////////////////////////// + + const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); + const stop = Cesium.JulianDate.addSeconds( + start, + 90, new Cesium.JulianDate() ); - const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); - const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); + function computeBalloonFlight(long, lat, height0, height1) { + const property = new Cesium.SampledPositionProperty(); + const time0 = start.clone(); + const time1 = Cesium.JulianDate.addSeconds( + time0, + 30, + new Cesium.JulianDate() + ); + const time2 = Cesium.JulianDate.addSeconds( + time1, + 15, + new Cesium.JulianDate() + ); + const time3 = Cesium.JulianDate.addSeconds( + time2, + 30, + new Cesium.JulianDate() + ); + const time4 = Cesium.JulianDate.addSeconds( + time3, + 15, + new Cesium.JulianDate() + ); - property.addSample(time0, position0); - property.addSample(time1, position1); - property.addSample(time2, position1); - property.addSample(time3, position0); - property.addSample(time4, position0); + const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); + const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); - return property; - } + property.addSample(time0, position0); + property.addSample(time1, position1); + property.addSample(time2, position1); + property.addSample(time3, position0); + property.addSample(time4, position0); - const balloon0 = viewer.entities.add({ - position: computeBalloonFlight(-122.661, 45.524, 400, 500), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + return property; + } - balloon0.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + const balloon0 = viewer.entities.add({ + position: computeBalloonFlight(-122.661, 45.524, 400, 500), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - const balloon1 = viewer.entities.add({ - position: computeBalloonFlight(-122.662, 45.517, 400, 300), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + balloon0.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - balloon1.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + const balloon1 = viewer.entities.add({ + position: computeBalloonFlight(-122.662, 45.517, 400, 300), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; + balloon1.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - // Fly to Portland - scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), - orientation: { - heading: Cesium.Math.toRadians(-115), - pitch: Cesium.Math.toRadians(-12), - roll: 0.0, - }, - }); + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + + // Fly to Portland + scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), + orientation: { + heading: Cesium.Math.toRadians(-115), + pitch: Cesium.Math.toRadians(-12), + roll: 0.0, + }, + }); - scene.fog.density = 1.15e-4; - //Sandcastle_End + scene.fog.density = 1.15e-4; + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index f675f31d9c6..08684647634 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -42,83 +42,83 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = false; + scene.globe.depthTestAgainstTerrain = false; - // MAXAR OWT Muscatatuk photogrammetry dataset with property textures - // containing horizontal and vertical uncertainty - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(905848), - }) - ); + // MAXAR OWT Muscatatuk photogrammetry dataset with property textures + // containing horizontal and vertical uncertainty + const tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(905848), + }) + ); - viewer.zoomTo(tileset); + viewer.zoomTo(tileset); - const shaders = { - NO_TEXTURE: undefined, - UNCERTAINTY_CE90: new Cesium.CustomShader({ - fragmentShaderText: ` - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) - { - int horizontalUncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum; - material.diffuse = vec3(float(horizontalUncertainty) / 255.0); - } - `, - }), - UNCERTAINTY_LE90: new Cesium.CustomShader({ - fragmentShaderText: ` - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) - { - int verticalUncertainty = fsInput.metadata.r3dm_uncertainty_le90sum; - material.diffuse = vec3(float(verticalUncertainty) / 255.0); - } - `, - }), - // combined uncertainty - UNCERTAINTY: new Cesium.CustomShader({ - fragmentShaderText: ` - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) - { - int uncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum + fsInput.metadata.r3dm_uncertainty_le90sum; - material.diffuse = vec3(float(uncertainty) / 255.0); - } - `, - }), - }; + const shaders = { + NO_TEXTURE: undefined, + UNCERTAINTY_CE90: new Cesium.CustomShader({ + fragmentShaderText: ` + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) + { + int horizontalUncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum; + material.diffuse = vec3(float(horizontalUncertainty) / 255.0); + } + `, + }), + UNCERTAINTY_LE90: new Cesium.CustomShader({ + fragmentShaderText: ` + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) + { + int verticalUncertainty = fsInput.metadata.r3dm_uncertainty_le90sum; + material.diffuse = vec3(float(verticalUncertainty) / 255.0); + } + `, + }), + // combined uncertainty + UNCERTAINTY: new Cesium.CustomShader({ + fragmentShaderText: ` + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) + { + int uncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum + fsInput.metadata.r3dm_uncertainty_le90sum; + material.diffuse = vec3(float(uncertainty) / 255.0); + } + `, + }), + }; - Sandcastle.addToolbarMenu([ - { - text: "Default View", - onselect: function () { - tileset.customShader = shaders.NO_TEXTURE; + Sandcastle.addToolbarMenu([ + { + text: "Default View", + onselect: function () { + tileset.customShader = shaders.NO_TEXTURE; + }, }, - }, - { - text: "Horizontal Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY_CE90; + { + text: "Horizontal Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY_CE90; + }, }, - }, - { - text: "Vertical Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY_LE90; + { + text: "Vertical Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY_LE90; + }, }, - }, - { - text: "Combined Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY; + { + text: "Combined Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY; + }, }, - }, - ]); - - //Sandcastle_End + ]); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index 0b4fa1a0564..31ee2ad43f5 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -46,134 +46,138 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - selectionIndicator: false, - infoBox: false, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + selectionIndicator: false, + infoBox: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - if (!viewer.scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } + if (!viewer.scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK - ); - function createPoint(worldPosition) { - const point = viewer.entities.add({ - position: worldPosition, - point: { - color: Cesium.Color.WHITE, - pixelSize: 5, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - return point; - } - let drawingMode = "line"; - function drawShape(positionData) { - let shape; - if (drawingMode === "line") { - shape = viewer.entities.add({ - polyline: { - positions: positionData, - clampToGround: true, - width: 3, - }, - }); - } else if (drawingMode === "polygon") { - shape = viewer.entities.add({ - polygon: { - hierarchy: positionData, - material: new Cesium.ColorMaterialProperty( - Cesium.Color.WHITE.withAlpha(0.7) - ), + viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( + Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK + ); + function createPoint(worldPosition) { + const point = viewer.entities.add({ + position: worldPosition, + point: { + color: Cesium.Color.WHITE, + pixelSize: 5, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, }, }); + return point; } - return shape; - } - let activeShapePoints = []; - let activeShape; - let floatingPoint; - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (event) { - // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that - // we get the correct point when mousing over terrain. - const earthPosition = viewer.scene.pickPosition(event.position); - // `earthPosition` will be undefined if our mouse is not over the globe. - if (Cesium.defined(earthPosition)) { - if (activeShapePoints.length === 0) { - floatingPoint = createPoint(earthPosition); - activeShapePoints.push(earthPosition); - const dynamicPositions = new Cesium.CallbackProperty(function () { - if (drawingMode === "polygon") { - return new Cesium.PolygonHierarchy(activeShapePoints); - } - return activeShapePoints; - }, false); - activeShape = drawShape(dynamicPositions); + let drawingMode = "line"; + function drawShape(positionData) { + let shape; + if (drawingMode === "line") { + shape = viewer.entities.add({ + polyline: { + positions: positionData, + clampToGround: true, + width: 3, + }, + }); + } else if (drawingMode === "polygon") { + shape = viewer.entities.add({ + polygon: { + hierarchy: positionData, + material: new Cesium.ColorMaterialProperty( + Cesium.Color.WHITE.withAlpha(0.7) + ), + }, + }); } - activeShapePoints.push(earthPosition); - createPoint(earthPosition); + return shape; } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + let activeShapePoints = []; + let activeShape; + let floatingPoint; + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + handler.setInputAction(function (event) { + // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that + // we get the correct point when mousing over terrain. + const earthPosition = viewer.scene.pickPosition(event.position); + // `earthPosition` will be undefined if our mouse is not over the globe. + if (Cesium.defined(earthPosition)) { + if (activeShapePoints.length === 0) { + floatingPoint = createPoint(earthPosition); + activeShapePoints.push(earthPosition); + const dynamicPositions = new Cesium.CallbackProperty( + function () { + if (drawingMode === "polygon") { + return new Cesium.PolygonHierarchy(activeShapePoints); + } + return activeShapePoints; + }, + false + ); + activeShape = drawShape(dynamicPositions); + } + activeShapePoints.push(earthPosition); + createPoint(earthPosition); + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - handler.setInputAction(function (event) { - if (Cesium.defined(floatingPoint)) { - const newPosition = viewer.scene.pickPosition(event.endPosition); - if (Cesium.defined(newPosition)) { - floatingPoint.position.setValue(newPosition); - activeShapePoints.pop(); - activeShapePoints.push(newPosition); + handler.setInputAction(function (event) { + if (Cesium.defined(floatingPoint)) { + const newPosition = viewer.scene.pickPosition(event.endPosition); + if (Cesium.defined(newPosition)) { + floatingPoint.position.setValue(newPosition); + activeShapePoints.pop(); + activeShapePoints.push(newPosition); + } } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Redraw the shape so it's not dynamic and remove the dynamic shape. + function terminateShape() { + activeShapePoints.pop(); + drawShape(activeShapePoints); + viewer.entities.remove(floatingPoint); + viewer.entities.remove(activeShape); + floatingPoint = undefined; + activeShape = undefined; + activeShapePoints = []; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Redraw the shape so it's not dynamic and remove the dynamic shape. - function terminateShape() { - activeShapePoints.pop(); - drawShape(activeShapePoints); - viewer.entities.remove(floatingPoint); - viewer.entities.remove(activeShape); - floatingPoint = undefined; - activeShape = undefined; - activeShapePoints = []; - } - handler.setInputAction(function (event) { - terminateShape(); - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + handler.setInputAction(function (event) { + terminateShape(); + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - const options = [ - { - text: "Draw Lines", - onselect: function () { - if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { - window.alert( - "This browser does not support polylines on terrain." - ); - } + const options = [ + { + text: "Draw Lines", + onselect: function () { + if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { + window.alert( + "This browser does not support polylines on terrain." + ); + } - terminateShape(); - drawingMode = "line"; + terminateShape(); + drawingMode = "line"; + }, }, - }, - { - text: "Draw Polygons", - onselect: function () { - terminateShape(); - drawingMode = "polygon"; + { + text: "Draw Polygons", + onselect: function () { + terminateShape(); + drawingMode = "polygon"; + }, }, - }, - ]; + ]; - Sandcastle.addToolbarMenu(options); - // Zoom in to an area with mountains - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - //Sandcastle_End + Sandcastle.addToolbarMenu(options); + // Zoom in to an area with mountains + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Elevation Band Material.html b/Apps/Sandcastle/gallery/Elevation Band Material.html index 3ac4a7669d6..42fc231b535 100644 --- a/Apps/Sandcastle/gallery/Elevation Band Material.html +++ b/Apps/Sandcastle/gallery/Elevation Band Material.html @@ -118,204 +118,220 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); - - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 290637.5534733206, - 5637471.593707632, - 2978256.8126927214 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); - - const viewModel = { - gradient: false, - band1Position: 7000.0, - band2Position: 7500.0, - band3Position: 8000.0, - bandThickness: 100.0, - bandTransparency: 0.5, - backgroundTransparency: 0.75, - }; - - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateMaterial); - } - } + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); - function updateMaterial() { - const gradient = Boolean(viewModel.gradient); - const band1Position = Number(viewModel.band1Position); - const band2Position = Number(viewModel.band2Position); - const band3Position = Number(viewModel.band3Position); - const bandThickness = Number(viewModel.bandThickness); - const bandTransparency = Number(viewModel.bandTransparency); - const backgroundTransparency = Number( - viewModel.backgroundTransparency - ); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 290637.5534733206, + 5637471.593707632, + 2978256.8126927214 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); - const layers = []; - const backgroundLayer = { - entries: [ - { - height: 4200.0, - color: new Cesium.Color(0.0, 0.0, 0.2, backgroundTransparency), - }, - { - height: 8000.0, - color: new Cesium.Color(1.0, 1.0, 1.0, backgroundTransparency), - }, - { - height: 8500.0, - color: new Cesium.Color(1.0, 0.0, 0.0, backgroundTransparency), - }, - ], - extendDownwards: true, - extendUpwards: true, + const viewModel = { + gradient: false, + band1Position: 7000.0, + band2Position: 7500.0, + band3Position: 8000.0, + bandThickness: 100.0, + bandTransparency: 0.5, + backgroundTransparency: 0.75, }; - layers.push(backgroundLayer); - const gridStartHeight = 4200.0; - const gridEndHeight = 8848.0; - const gridCount = 50; - for (let i = 0; i < gridCount; i++) { - const lerper = i / (gridCount - 1); - const heightBelow = Cesium.Math.lerp( - gridStartHeight, - gridEndHeight, - lerper - ); - const heightAbove = heightBelow + 10.0; - const alpha = - Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; - layers.push({ - entries: [ - { - height: heightBelow, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: heightAbove, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - ], - }); + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateMaterial); + } } - const antialias = Math.min(10.0, bandThickness * 0.1); + function updateMaterial() { + const gradient = Boolean(viewModel.gradient); + const band1Position = Number(viewModel.band1Position); + const band2Position = Number(viewModel.band2Position); + const band3Position = Number(viewModel.band3Position); + const bandThickness = Number(viewModel.bandThickness); + const bandTransparency = Number(viewModel.bandTransparency); + const backgroundTransparency = Number( + viewModel.backgroundTransparency + ); - if (!gradient) { - const band1 = { + const layers = []; + const backgroundLayer = { entries: [ { - height: band1Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + height: 4200.0, + color: new Cesium.Color( + 0.0, + 0.0, + 0.2, + backgroundTransparency + ), }, { - height: band1Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + height: 8000.0, + color: new Cesium.Color( + 1.0, + 1.0, + 1.0, + backgroundTransparency + ), }, { - height: band1Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + height: 8500.0, + color: new Cesium.Color( + 1.0, + 0.0, + 0.0, + backgroundTransparency + ), }, ], + extendDownwards: true, + extendUpwards: true, }; + layers.push(backgroundLayer); - const band2 = { - entries: [ - { - height: band2Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - { - height: band2Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - ], - }; + const gridStartHeight = 4200.0; + const gridEndHeight = 8848.0; + const gridCount = 50; + for (let i = 0; i < gridCount; i++) { + const lerper = i / (gridCount - 1); + const heightBelow = Cesium.Math.lerp( + gridStartHeight, + gridEndHeight, + lerper + ); + const heightAbove = heightBelow + 10.0; + const alpha = + Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; + layers.push({ + entries: [ + { + height: heightBelow, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: heightAbove, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + ], + }); + } - const band3 = { - entries: [ - { - height: band3Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - { - height: band3Position - bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - ], - }; + const antialias = Math.min(10.0, bandThickness * 0.1); - layers.push(band1); - layers.push(band2); - layers.push(band3); - } else { - const combinedBand = { - entries: [ - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band2Position, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - ], - }; + if (!gradient) { + const band1 = { + entries: [ + { + height: band1Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + }, + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band1Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band1Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + }, + ], + }; - layers.push(combinedBand); - } + const band2 = { + entries: [ + { + height: band2Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + { + height: band2Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + ], + }; - const material = Cesium.createElevationBandMaterial({ - scene: viewer.scene, - layers: layers, - }); - viewer.scene.globe.material = material; - } + const band3 = { + entries: [ + { + height: band3Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + { + height: band3Position - bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + ], + }; + + layers.push(band1); + layers.push(band2); + layers.push(band3); + } else { + const combinedBand = { + entries: [ + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band2Position, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + ], + }; + + layers.push(combinedBand); + } + + const material = Cesium.createElevationBandMaterial({ + scene: viewer.scene, + layers: layers, + }); + viewer.scene.globe.material = material; + } - updateMaterial(); - //Sandcastle_End + updateMaterial(); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index 30ae5a9d7bf..24325ed8467 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -32,36 +32,37 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); - viewer.scene.postProcessStages.fxaa.enabled = true; + viewer.scene.postProcessStages.fxaa.enabled = true; - Sandcastle.addToggleButton("FXAA", true, function (checked) { - viewer.scene.postProcessStages.fxaa.enabled = checked; - }); - //Sandcastle_End + Sandcastle.addToggleButton("FXAA", true, function (checked) { + viewer.scene.postProcessStages.fxaa.enabled = checked; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index 982d9ae9ef3..d89013be7dc 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -34,110 +34,114 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const pinBuilder = new Cesium.PinBuilder(); + const pinBuilder = new Cesium.PinBuilder(); - Sandcastle.addToolbarMenu( - [ - { - text: "Track with Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/lamina.gpx", - { - clampToGround: true, - } + Sandcastle.addToolbarMenu( + [ + { + text: "Track with Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/lamina.gpx", + { + clampToGround: true, + } + ) ) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); + }, }, - }, - { - text: "Route", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/route.gpx", - { - clampToGround: true, - } + { + text: "Route", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/route.gpx", + { + clampToGround: true, + } + ) ) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); + }, }, - }, - { - text: "Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load("../../SampleData/gpx/wpt.gpx", { - clampToGround: true, - }) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); + { + text: "Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/wpt.gpx", + { + clampToGround: true, + } + ) + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); + }, }, - }, - { - text: "Multiple Tracks with Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/complexTrk.gpx", - { clampToGround: true } + { + text: "Multiple Tracks with Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/complexTrk.gpx", + { clampToGround: true } + ) ) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); + }, }, - }, - { - text: "Symbology Options", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/lamina.gpx", - { - clampToGround: true, - trackColor: Cesium.Color.YELLOW, - waypointImage: pinBuilder.fromMakiIconId( - "bicycle", - Cesium.Color.BLUE, - 48 - ), - } + { + text: "Symbology Options", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/lamina.gpx", + { + clampToGround: true, + trackColor: Cesium.Color.YELLOW, + waypointImage: pinBuilder.fromMakiIconId( + "bicycle", + Cesium.Color.BLUE, + 48 + ), + } + ) ) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); + }, }, - }, - ], - "toolbar" - ); + ], + "toolbar" + ); - Sandcastle.reset = function () { - viewer.dataSources.removeAll(); - viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED; - viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; - }; - //Sandcastle_End + Sandcastle.reset = function () { + viewer.dataSources.removeAll(); + viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED; + viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; + }; + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index b4b07315ac9..2353d15188a 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -35,143 +35,143 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const cesiumTerrainProviderPromise = Cesium.createWorldTerrainAsync(); - const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + (async () => { + const cesiumTerrainProvider = await Cesium.createWorldTerrainAsync(); + const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); - const viewer = new Cesium.Viewer("cesiumContainer", { - baseLayerPicker: false, - terrainProvider: cesiumTerrainProviderPromise, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + baseLayerPicker: false, + terrainProvider: cesiumTerrainProvider, + }); - // depth test against terrain is required to make the polygons clamp to terrain - // instead of showing through it from underground - viewer.scene.globe.depthTestAgainstTerrain = true; + // depth test against terrain is required to make the polygons clamp to terrain + // instead of showing through it from underground + viewer.scene.globe.depthTestAgainstTerrain = true; - Sandcastle.addToolbarMenu([ - { - text: "Polygons", - onselect: function () { - viewer.entities.removeAll(); - addPolygons(); + Sandcastle.addToolbarMenu([ + { + text: "Polygons", + onselect: function () { + viewer.entities.removeAll(); + addPolygons(); + }, }, - }, - { - text: "Boxes, Cylinders and Ellipsoids", - onselect: function () { - viewer.entities.removeAll(); - addGeometries(); + { + text: "Boxes, Cylinders and Ellipsoids", + onselect: function () { + viewer.entities.removeAll(); + addGeometries(); + }, }, - }, - ]); + ]); - Sandcastle.addToolbarMenu([ - { - text: "Terrain Enabled", - onselect: async function () { - const cesiumTerrainProvider = await cesiumTerrainProviderPromise; - viewer.scene.terrainProvider = cesiumTerrainProvider; + Sandcastle.addToolbarMenu([ + { + text: "Terrain Enabled", + onselect: async function () { + viewer.scene.terrainProvider = cesiumTerrainProvider; + }, }, - }, - { - text: "Terrain Disabled", - onselect: function () { - viewer.scene.terrainProvider = ellipsoidTerrainProvider; + { + text: "Terrain Disabled", + onselect: function () { + viewer.scene.terrainProvider = ellipsoidTerrainProvider; + }, }, - }, - ]); + ]); - const longitude = 6.950615989890521; - const latitude = 45.79546589994886; - const delta = 0.001; + const longitude = 6.950615989890521; + const latitude = 45.79546589994886; + const delta = 0.001; - function addGeometry(i, j) { - const west = longitude + delta * i; - const north = latitude + delta * j + delta; + function addGeometry(i, j) { + const west = longitude + delta * i; + const north = latitude + delta * j + delta; - const type = Math.floor(Math.random() * 3); - if (type === 0) { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - box: { - dimensions: new Cesium.Cartesian3(40.0, 30.0, 50.0), - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } else if (type === 1) { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - cylinder: { - length: 50.0, - topRadius: 20.0, - bottomRadius: 20.0, - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } else { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - ellipsoid: { - radii: new Cesium.Cartesian3(20.0, 15.0, 25.0), - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + const type = Math.floor(Math.random() * 3); + if (type === 0) { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + box: { + dimensions: new Cesium.Cartesian3(40.0, 30.0, 50.0), + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } else if (type === 1) { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + cylinder: { + length: 50.0, + topRadius: 20.0, + bottomRadius: 20.0, + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } else { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + ellipsoid: { + radii: new Cesium.Cartesian3(20.0, 15.0, 25.0), + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } } - } - function addGeometries() { - for (let i = 0; i < 4; i++) { - for (let j = 0; j < 4; j++) { - addGeometry(i, j); + function addGeometries() { + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 4; j++) { + addGeometry(i, j); + } } + viewer.zoomTo(viewer.entities); } - viewer.zoomTo(viewer.entities); - } - function addPolygon(i, j) { - const west = longitude + delta * i; - const east = longitude + delta * i + delta; + function addPolygon(i, j) { + const west = longitude + delta * i; + const east = longitude + delta * i + delta; - const south = latitude + delta * j; - const north = latitude + delta * j + delta; - const a = Cesium.Cartesian3.fromDegrees(west, south); - const b = Cesium.Cartesian3.fromDegrees(west, north); - const c = Cesium.Cartesian3.fromDegrees(east, north); - const d = Cesium.Cartesian3.fromDegrees(east, south); + const south = latitude + delta * j; + const north = latitude + delta * j + delta; + const a = Cesium.Cartesian3.fromDegrees(west, south); + const b = Cesium.Cartesian3.fromDegrees(west, north); + const c = Cesium.Cartesian3.fromDegrees(east, north); + const d = Cesium.Cartesian3.fromDegrees(east, south); - const positions = [a, b, c, d]; - viewer.entities.add({ - polygon: { - hierarchy: positions, - material: Cesium.Color.fromRandom({ alpha: 1 }), - height: 40.0, - heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, - extrudedHeight: 0.0, - extrudedHeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } + const positions = [a, b, c, d]; + viewer.entities.add({ + polygon: { + hierarchy: positions, + material: Cesium.Color.fromRandom({ alpha: 1 }), + height: 40.0, + heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, + extrudedHeight: 0.0, + extrudedHeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } - function addPolygons() { - // create 16 polygons that are side-by-side - for (let i = 0; i < 4; i++) { - for (let j = 0; j < 4; j++) { - addPolygon(i, j); + function addPolygons() { + // create 16 polygons that are side-by-side + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 4; j++) { + addPolygon(i, j); + } } + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(longitude, latitude, 1500), + new Cesium.HeadingPitchRange( + -Cesium.Math.PI / 2, + -Cesium.Math.PI_OVER_FOUR, + 2000 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(longitude, latitude, 1500), - new Cesium.HeadingPitchRange( - -Cesium.Math.PI / 2, - -Cesium.Math.PI_OVER_FOUR, - 2000 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } - //Sandcastle_End + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index 4785404f6ae..a262dd6ce7a 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -122,303 +122,304 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); - viewer.scene.globe.enableLighting = true; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); + viewer.scene.globe.enableLighting = true; - function getElevationContourMaterial() { - // Creates a composite material with both elevation shading and contour lines - return new Cesium.Material({ - fabric: { - type: "ElevationColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", + function getElevationContourMaterial() { + // Creates a composite material with both elevation shading and contour lines + return new Cesium.Material({ + fabric: { + type: "ElevationColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", + }, + elevationRampMaterial: { + type: "ElevationRamp", + }, }, - elevationRampMaterial: { - type: "ElevationRamp", + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse", + alpha: + "max(contourMaterial.alpha, elevationRampMaterial.alpha)", }, }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse", - alpha: - "max(contourMaterial.alpha, elevationRampMaterial.alpha)", - }, - }, - translucent: false, - }); - } + translucent: false, + }); + } - function getSlopeContourMaterial() { - // Creates a composite material with both slope shading and contour lines - return new Cesium.Material({ - fabric: { - type: "SlopeColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", + function getSlopeContourMaterial() { + // Creates a composite material with both slope shading and contour lines + return new Cesium.Material({ + fabric: { + type: "SlopeColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", + }, + slopeRampMaterial: { + type: "SlopeRamp", + }, }, - slopeRampMaterial: { - type: "SlopeRamp", + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? slopeRampMaterial.diffuse : contourMaterial.diffuse", + alpha: "max(contourMaterial.alpha, slopeRampMaterial.alpha)", }, }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? slopeRampMaterial.diffuse : contourMaterial.diffuse", - alpha: "max(contourMaterial.alpha, slopeRampMaterial.alpha)", - }, - }, - translucent: false, - }); - } + translucent: false, + }); + } - function getAspectContourMaterial() { - // Creates a composite material with both aspect shading and contour lines - return new Cesium.Material({ - fabric: { - type: "AspectColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", + function getAspectContourMaterial() { + // Creates a composite material with both aspect shading and contour lines + return new Cesium.Material({ + fabric: { + type: "AspectColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", + }, + aspectRampMaterial: { + type: "AspectRamp", + }, }, - aspectRampMaterial: { - type: "AspectRamp", + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? aspectRampMaterial.diffuse : contourMaterial.diffuse", + alpha: "max(contourMaterial.alpha, aspectRampMaterial.alpha)", }, }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? aspectRampMaterial.diffuse : contourMaterial.diffuse", - alpha: "max(contourMaterial.alpha, aspectRampMaterial.alpha)", - }, - }, - translucent: false, - }); - } + translucent: false, + }); + } - const elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0]; - const slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2) / 2, 0.87, 0.91, 1.0]; - const aspectRamp = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0]; - function getColorRamp(selectedShading) { - const ramp = document.createElement("canvas"); - ramp.width = 100; - ramp.height = 1; - const ctx = ramp.getContext("2d"); + const elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0]; + const slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2) / 2, 0.87, 0.91, 1.0]; + const aspectRamp = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0]; + function getColorRamp(selectedShading) { + const ramp = document.createElement("canvas"); + ramp.width = 100; + ramp.height = 1; + const ctx = ramp.getContext("2d"); - let values; - if (selectedShading === "elevation") { - values = elevationRamp; - } else if (selectedShading === "slope") { - values = slopeRamp; - } else if (selectedShading === "aspect") { - values = aspectRamp; - } + let values; + if (selectedShading === "elevation") { + values = elevationRamp; + } else if (selectedShading === "slope") { + values = slopeRamp; + } else if (selectedShading === "aspect") { + values = aspectRamp; + } - const grd = ctx.createLinearGradient(0, 0, 100, 0); - grd.addColorStop(values[0], "#000000"); //black - grd.addColorStop(values[1], "#2747E0"); //blue - grd.addColorStop(values[2], "#D33B7D"); //pink - grd.addColorStop(values[3], "#D33038"); //red - grd.addColorStop(values[4], "#FF9742"); //orange - grd.addColorStop(values[5], "#ffd700"); //yellow - grd.addColorStop(values[6], "#ffffff"); //white + const grd = ctx.createLinearGradient(0, 0, 100, 0); + grd.addColorStop(values[0], "#000000"); //black + grd.addColorStop(values[1], "#2747E0"); //blue + grd.addColorStop(values[2], "#D33B7D"); //pink + grd.addColorStop(values[3], "#D33038"); //red + grd.addColorStop(values[4], "#FF9742"); //orange + grd.addColorStop(values[5], "#ffd700"); //yellow + grd.addColorStop(values[6], "#ffffff"); //white - ctx.fillStyle = grd; - ctx.fillRect(0, 0, 100, 1); + ctx.fillStyle = grd; + ctx.fillRect(0, 0, 100, 1); - return ramp; - } + return ramp; + } - const minHeight = -414.0; // approximate dead sea elevation - const maxHeight = 8777.0; // approximate everest elevation - const contourColor = Cesium.Color.RED.clone(); - let contourUniforms = {}; - let shadingUniforms = {}; + const minHeight = -414.0; // approximate dead sea elevation + const maxHeight = 8777.0; // approximate everest elevation + const contourColor = Cesium.Color.RED.clone(); + let contourUniforms = {}; + let shadingUniforms = {}; - // The viewModel tracks the state of our mini application. - const viewModel = { - enableContour: false, - contourSpacing: 150.0, - contourWidth: 2.0, - selectedShading: "elevation", - changeColor: function () { - contourUniforms.color = Cesium.Color.fromRandom( - { alpha: 1.0 }, - contourColor - ); - }, - }; + // The viewModel tracks the state of our mini application. + const viewModel = { + enableContour: false, + contourSpacing: 150.0, + contourWidth: 2.0, + selectedShading: "elevation", + changeColor: function () { + contourUniforms.color = Cesium.Color.fromRandom( + { alpha: 1.0 }, + contourColor + ); + }, + }; - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - function updateMaterial() { - const hasContour = viewModel.enableContour; - const selectedShading = viewModel.selectedShading; - const globe = viewer.scene.globe; - let material; - if (hasContour) { - if (selectedShading === "elevation") { - material = getElevationContourMaterial(); - shadingUniforms = - material.materials.elevationRampMaterial.uniforms; + function updateMaterial() { + const hasContour = viewModel.enableContour; + const selectedShading = viewModel.selectedShading; + const globe = viewer.scene.globe; + let material; + if (hasContour) { + if (selectedShading === "elevation") { + material = getElevationContourMaterial(); + shadingUniforms = + material.materials.elevationRampMaterial.uniforms; + shadingUniforms.minimumHeight = minHeight; + shadingUniforms.maximumHeight = maxHeight; + contourUniforms = material.materials.contourMaterial.uniforms; + } else if (selectedShading === "slope") { + material = getSlopeContourMaterial(); + shadingUniforms = material.materials.slopeRampMaterial.uniforms; + contourUniforms = material.materials.contourMaterial.uniforms; + } else if (selectedShading === "aspect") { + material = getAspectContourMaterial(); + shadingUniforms = + material.materials.aspectRampMaterial.uniforms; + contourUniforms = material.materials.contourMaterial.uniforms; + } else { + material = Cesium.Material.fromType("ElevationContour"); + contourUniforms = material.uniforms; + } + contourUniforms.width = viewModel.contourWidth; + contourUniforms.spacing = viewModel.contourSpacing; + contourUniforms.color = contourColor; + } else if (selectedShading === "elevation") { + material = Cesium.Material.fromType("ElevationRamp"); + shadingUniforms = material.uniforms; shadingUniforms.minimumHeight = minHeight; shadingUniforms.maximumHeight = maxHeight; - contourUniforms = material.materials.contourMaterial.uniforms; } else if (selectedShading === "slope") { - material = getSlopeContourMaterial(); - shadingUniforms = material.materials.slopeRampMaterial.uniforms; - contourUniforms = material.materials.contourMaterial.uniforms; + material = Cesium.Material.fromType("SlopeRamp"); + shadingUniforms = material.uniforms; } else if (selectedShading === "aspect") { - material = getAspectContourMaterial(); - shadingUniforms = material.materials.aspectRampMaterial.uniforms; - contourUniforms = material.materials.contourMaterial.uniforms; - } else { - material = Cesium.Material.fromType("ElevationContour"); - contourUniforms = material.uniforms; + material = Cesium.Material.fromType("AspectRamp"); + shadingUniforms = material.uniforms; + } + if (selectedShading !== "none") { + shadingUniforms.image = getColorRamp(selectedShading); } - contourUniforms.width = viewModel.contourWidth; - contourUniforms.spacing = viewModel.contourSpacing; - contourUniforms.color = contourColor; - } else if (selectedShading === "elevation") { - material = Cesium.Material.fromType("ElevationRamp"); - shadingUniforms = material.uniforms; - shadingUniforms.minimumHeight = minHeight; - shadingUniforms.maximumHeight = maxHeight; - } else if (selectedShading === "slope") { - material = Cesium.Material.fromType("SlopeRamp"); - shadingUniforms = material.uniforms; - } else if (selectedShading === "aspect") { - material = Cesium.Material.fromType("AspectRamp"); - shadingUniforms = material.uniforms; - } - if (selectedShading !== "none") { - shadingUniforms.image = getColorRamp(selectedShading); - } - globe.material = material; - } + globe.material = material; + } - updateMaterial(); + updateMaterial(); - Cesium.knockout - .getObservable(viewModel, "enableContour") - .subscribe(function (newValue) { - updateMaterial(); - }); + Cesium.knockout + .getObservable(viewModel, "enableContour") + .subscribe(function (newValue) { + updateMaterial(); + }); - Cesium.knockout - .getObservable(viewModel, "contourWidth") - .subscribe(function (newValue) { - contourUniforms.width = parseFloat(newValue); - }); + Cesium.knockout + .getObservable(viewModel, "contourWidth") + .subscribe(function (newValue) { + contourUniforms.width = parseFloat(newValue); + }); - Cesium.knockout - .getObservable(viewModel, "contourSpacing") - .subscribe(function (newValue) { - contourUniforms.spacing = parseFloat(newValue); - }); + Cesium.knockout + .getObservable(viewModel, "contourSpacing") + .subscribe(function (newValue) { + contourUniforms.spacing = parseFloat(newValue); + }); - Cesium.knockout - .getObservable(viewModel, "selectedShading") - .subscribe(function (value) { - updateMaterial(); - }); + Cesium.knockout + .getObservable(viewModel, "selectedShading") + .subscribe(function (value) { + updateMaterial(); + }); - Sandcastle.addToolbarMenu( - [ - { - text: "Himalayas", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 322100.7492728492, - 5917960.047024654, - 3077602.646977297 - ), - orientation: { - heading: 5.988151498702285, - pitch: -1.5614542839414822, - roll: 0, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T04:00:00Z" - ); + Sandcastle.addToolbarMenu( + [ + { + text: "Himalayas", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 322100.7492728492, + 5917960.047024654, + 3077602.646977297 + ), + orientation: { + heading: 5.988151498702285, + pitch: -1.5614542839414822, + roll: 0, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T04:00:00Z" + ); + }, }, - }, - { - text: "Half Dome", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2495709.521843174, - -4391600.804712465, - 3884463.7192916023 - ), - orientation: { - heading: 1.7183056487769202, - pitch: -0.06460370548034144, - roll: 0.0079181631783527, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T18:00:00Z" - ); + { + text: "Half Dome", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2495709.521843174, + -4391600.804712465, + 3884463.7192916023 + ), + orientation: { + heading: 1.7183056487769202, + pitch: -0.06460370548034144, + roll: 0.0079181631783527, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T18:00:00Z" + ); + }, }, - }, - { - text: "Vancouver", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2301222.367751603, - -3485269.915771613, - 4812080.961755785 - ), - orientation: { - heading: 0.11355958593902571, - pitch: -0.260011078090858, - roll: 0.00039019018274721873, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T18:00:00Z" - ); + { + text: "Vancouver", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2301222.367751603, + -3485269.915771613, + 4812080.961755785 + ), + orientation: { + heading: 0.11355958593902571, + pitch: -0.260011078090858, + roll: 0.00039019018274721873, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T18:00:00Z" + ); + }, }, - }, - { - text: "Mount Everest", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 282157.6960889096, - 5638892.465594703, - 2978736.186473513 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T04:00:00Z" - ); + { + text: "Mount Everest", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 282157.6960889096, + 5638892.465594703, + 2978736.186473513 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T04:00:00Z" + ); + }, }, - }, - ], - "zoomButtons" - ); - - //Sandcastle_End + ], + "zoomButtons" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index e9e8b9692ef..87dc0c82f54 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -84,224 +84,225 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - scene.screenSpaceCameraController.enableCollisionDetection = false; - globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( - 400.0, - 0.0, - 800.0, - 1.0 - ); + scene.screenSpaceCameraController.enableCollisionDetection = false; + globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( + 400.0, + 0.0, + 800.0, + 1.0 + ); - const longitude = -3.82518; - const latitude = 53.11728; - const height = 72.8; - const position = Cesium.Cartesian3.fromDegrees( - longitude, - latitude, - height - ); - const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; + const longitude = -3.82518; + const latitude = 53.11728; + const height = 72.8; + const position = Cesium.Cartesian3.fromDegrees( + longitude, + latitude, + height + ); + const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; - const entity = viewer.entities.add({ - name: url, - position: position, - model: { - uri: url, - }, - }); + const entity = viewer.entities.add({ + name: url, + position: position, + model: { + uri: url, + }, + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8152789692233817, - 53.124521420389996, - 200.20779492422255, - -3.8165955002619016, - 53.12555934545405, - 205.85834336951655, - -3.8201599842222054, - 53.12388420656903, - 230.82362697069453, - -3.8198667503545027, - 53.123748567587455, - 225.53297006293968, - -3.8190548496317476, - 53.1240486000822, - 221.82677773619432, - -3.817536387097508, - 53.122763476393764, - 209.94136782255705, - -3.8169125359199336, - 53.12285547981627, - 210.96626238861327, - -3.8166873871853073, - 53.12299403424474, - 211.02223937734595, - -3.8163695374580873, - 53.12300505277307, - 211.25942926271824, - -3.8162743040622313, - 53.12281471203994, - 212.35109129094147, - -3.8159746138174193, - 53.12280996651767, - 214.87977416348798, - -3.815429896849304, - 53.1236135347983, - 209.72496223706005, - ]) - ), - material: Cesium.Color.LIME.withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8152789692233817, + 53.124521420389996, + 200.20779492422255, + -3.8165955002619016, + 53.12555934545405, + 205.85834336951655, + -3.8201599842222054, + 53.12388420656903, + 230.82362697069453, + -3.8198667503545027, + 53.123748567587455, + 225.53297006293968, + -3.8190548496317476, + 53.1240486000822, + 221.82677773619432, + -3.817536387097508, + 53.122763476393764, + 209.94136782255705, + -3.8169125359199336, + 53.12285547981627, + 210.96626238861327, + -3.8166873871853073, + 53.12299403424474, + 211.02223937734595, + -3.8163695374580873, + 53.12300505277307, + 211.25942926271824, + -3.8162743040622313, + 53.12281471203994, + 212.35109129094147, + -3.8159746138174193, + 53.12280996651767, + 214.87977416348798, + -3.815429896849304, + 53.1236135347983, + 209.72496223706005, + ]) + ), + material: Cesium.Color.LIME.withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8098444201746373, - 53.1190304262546, - 286.1875170545701, - -3.8099801237370663, - 53.119539531697576, - 288.7733884242394, - -3.810165716635671, - 53.11979180761567, - 290.9294630315179, - -3.8104840812145357, - 53.12007534956926, - 292.6392327626228, - -3.8105689502073554, - 53.120259094792196, - 292.222036965774, - -3.811027311824268, - 53.120409248874196, - 289.61356291617307, - -3.811530473295422, - 53.12063281057782, - 284.01098712543586, - -3.8120545342562693, - 53.120742539082435, - 280.118191867836, - -3.812444493044727, - 53.120813289759326, - 276.0400221387852, - -3.812779626711285, - 53.12094275348024, - 271.1187399484896, - -3.8133560322579494, - 53.12104757866638, - 263.3495497598578, - -3.8137266493960085, - 53.12120789867194, - 257.73878624321316, - -3.8142552291751133, - 53.121321248522904, - 251.87265828778177, - -3.814322603988525, - 53.12174170121103, - 238.7082749547689, - -3.8143764268391314, - 53.1219492923309, - 235.0371831845662, - -3.8148156514145786, - 53.12210819668669, - 230.2458816627467, - -3.8155394721966163, - 53.1222990144029, - 221.33319292262706, - -3.8159828072920927, - 53.12203093429715, - 223.66664756982703, - -3.816678108944717, - 53.12183939425214, - 223.8787312412801, - -3.817466081093726, - 53.121751900508535, - 224.52293229989735, - -3.8183082996527955, - 53.12173266141031, - 223.3672181535749, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8098444201746373, + 53.1190304262546, + 286.1875170545701, + -3.8099801237370663, + 53.119539531697576, + 288.7733884242394, + -3.810165716635671, + 53.11979180761567, + 290.9294630315179, + -3.8104840812145357, + 53.12007534956926, + 292.6392327626228, + -3.8105689502073554, + 53.120259094792196, + 292.222036965774, + -3.811027311824268, + 53.120409248874196, + 289.61356291617307, + -3.811530473295422, + 53.12063281057782, + 284.01098712543586, + -3.8120545342562693, + 53.120742539082435, + 280.118191867836, + -3.812444493044727, + 53.120813289759326, + 276.0400221387852, + -3.812779626711285, + 53.12094275348024, + 271.1187399484896, + -3.8133560322579494, + 53.12104757866638, + 263.3495497598578, + -3.8137266493960085, + 53.12120789867194, + 257.73878624321316, + -3.8142552291751133, + 53.121321248522904, + 251.87265828778177, + -3.814322603988525, + 53.12174170121103, + 238.7082749547689, + -3.8143764268391314, + 53.1219492923309, + 235.0371831845662, + -3.8148156514145786, + 53.12210819668669, + 230.2458816627467, + -3.8155394721966163, + 53.1222990144029, + 221.33319292262706, + -3.8159828072920927, + 53.12203093429715, + 223.66664756982703, + -3.816678108944717, + 53.12183939425214, + 223.8787312412801, + -3.817466081093726, + 53.121751900508535, + 224.52293229989735, + -3.8183082996527955, + 53.12173266141031, + 223.3672181535749, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const viewModel = { - translucencyEnabled: true, - fadeByDistance: true, - showVectorData: false, - alpha: 0.5, - }; + const viewModel = { + translucencyEnabled: true, + fadeByDistance: true, + showVectorData: false, + alpha: 0.5, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout.getObservable(viewModel, name).subscribe(update); + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout.getObservable(viewModel, name).subscribe(update); + } } - } - function update() { - globe.translucency.enabled = viewModel.translucencyEnabled; + function update() { + globe.translucency.enabled = viewModel.translucencyEnabled; - let alpha = Number(viewModel.alpha); - alpha = !isNaN(alpha) ? alpha : 1.0; - alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); + let alpha = Number(viewModel.alpha); + alpha = !isNaN(alpha) ? alpha : 1.0; + alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); - globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; - globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance - ? 1.0 - : alpha; + globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; + globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance + ? 1.0 + : alpha; - polygon.show = viewModel.showVectorData; - polyline.show = viewModel.showVectorData; - } - update(); + polygon.show = viewModel.showVectorData; + polyline.show = viewModel.showVectorData; + } + update(); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 3826465.9884728403, - -254831.02751468265, - 5081387.671561018 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.3889450556243754, - -0.5276382514771969, - 6.282272566663295 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 3826465.9884728403, + -254831.02751468265, + 5081387.671561018 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.3889450556243754, + -0.5276382514771969, + 6.282272566663295 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.camera.flyTo({ - destination: new Cesium.Cartesian3( - 3827270.552916987, - -255123.18143177085, - 5079147.091351856 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.2624281242239963, - -0.22213535190506972, - 6.282786783842843 - ), - duration: 5.0, - }); - //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: new Cesium.Cartesian3( + 3827270.552916987, + -255123.18143177085, + 5079147.091351856 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.2624281242239963, + -0.22213535190506972, + 6.282786783842843 + ), + duration: 5.0, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index afb11c58d3c..2c7cb0c0461 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -35,38 +35,38 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + (async () => { + try { + const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( + new Cesium.Resource({ + url: "http://www.earthenterprise.org/3d", + proxy: new Cesium.DefaultProxy("/proxy/"), + }) + ); - async function createGoogleEarthEnterpriseProviders() { - const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( - new Cesium.Resource({ - url: "http://www.earthenterprise.org/3d", - proxy: new Cesium.DefaultProxy("/proxy/"), - }) - ); + const viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ + metadata: geeMetadata, + }), + terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( + geeMetadata + ), + baseLayerPicker: false, + }); - const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ - metadata: geeMetadata, - }), - terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( - geeMetadata - ), - baseLayerPicker: false, - }); - - // Start off looking at San Francisco. - viewer.camera.setView({ - destination: Cesium.Rectangle.fromDegrees( - -123.0, - 36.0, - -121.7, - 39.0 - ), - }); - } - - createGoogleEarthEnterpriseProviders(); - //Sandcastle_End + // Start off looking at San Francisco. + viewer.camera.setView({ + destination: Cesium.Rectangle.fromDegrees( + -123.0, + 36.0, + -121.7, + 39.0 + ), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/High Dynamic Range.html b/Apps/Sandcastle/gallery/High Dynamic Range.html index b27998e17b7..abb4f589055 100644 --- a/Apps/Sandcastle/gallery/High Dynamic Range.html +++ b/Apps/Sandcastle/gallery/High Dynamic Range.html @@ -32,62 +32,63 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - shadows: true, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + shadows: true, + }); - if (!viewer.scene.highDynamicRangeSupported) { - window.alert("This browser does not support high dynamic range."); - } + if (!viewer.scene.highDynamicRangeSupported) { + window.alert("This browser does not support high dynamic range."); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -1915097.7863741855, - -4783356.851539908, - 3748887.43462683 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.166004548388564, - -0.043242401760068994, - 0.002179961955988574 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -1915097.7863741855, + -4783356.851539908, + 3748887.43462683 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.166004548388564, + -0.043242401760068994, + 0.002179961955988574 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.highDynamicRange = true; + viewer.scene.highDynamicRange = true; - Sandcastle.addToggleButton("HDR", true, function (checked) { - viewer.scene.highDynamicRange = checked; - }); + Sandcastle.addToggleButton("HDR", true, function (checked) { + viewer.scene.highDynamicRange = checked; + }); - const url = - "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; - const position = Cesium.Cartesian3.fromRadians( - -1.9516424279517286, - 0.6322397098422969, - 1239.0006814631095 - ); - const heading = Cesium.Math.toRadians(-15.0); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const scale = 10.0; + const url = + "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; + const position = Cesium.Cartesian3.fromRadians( + -1.9516424279517286, + 0.6322397098422969, + 1239.0006814631095 + ); + const heading = Cesium.Math.toRadians(-15.0); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const scale = 10.0; - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: scale, - }, - }); - //Sandcastle_End + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: scale, + }, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index a6c1c72d24e..20cf6b8bf87 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -38,13 +38,13 @@

Loading...

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - async function addI3sProvider() { // More datasets to tour can be added here... // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (./SceneServer/layers/) or a collection of scene layers (./SceneServer) from a SceneServer. const tours = { @@ -83,78 +83,78 @@

Loading...

viewer.camera.setView({ destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), }); - } - - addI3sProvider(); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - ''; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += ``; - console.log(`${fieldName}: ${fields[fieldName]}`); - if (!Cesium.defined(name) && isNameProperty(fieldName)) { - name = fields[fieldName]; + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '
${fieldName}`; - description += `${fields[fieldName]}
'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += ``; + console.log(`${fieldName}: ${fields[fieldName]}`); + if ( + !Cesium.defined(name) && + isNameProperty(fieldName) + ) { + name = fields[fieldName]; + } } } + description += `
${fieldName}`; + description += `${fields[fieldName]}
`; + } + if (!Cesium.defined(name)) { + name = "unknown"; } - description += ``; - } - if (!Cesium.defined(name)) { - name = "unknown"; - } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); + } } - } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; + } + return false; } - return false; - } - //Sandcastle_End + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; window.startup(Cesium); diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index 7a9c73595e8..cebdb348a20 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -38,13 +38,13 @@

Loading...

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - async function addI3sProvider() { // More datasets to tour can be added here... // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (./SceneServer/layers/) or a collection of scene layers (./SceneServer) from a SceneServer. const tours = { @@ -83,78 +83,78 @@

Loading...

viewer.camera.setView({ destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), }); - } - - addI3sProvider(); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - ''; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += ``; - console.log(`${fieldName}: ${fields[fieldName]}`); - if (!Cesium.defined(name) && isNameProperty(fieldName)) { - name = fields[fieldName]; + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '
${fieldName}`; - description += `${fields[fieldName]}
'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += ``; + console.log(`${fieldName}: ${fields[fieldName]}`); + if ( + !Cesium.defined(name) && + isNameProperty(fieldName) + ) { + name = fields[fieldName]; + } } } + description += `
${fieldName}`; + description += `${fields[fieldName]}
`; + } + if (!Cesium.defined(name)) { + name = "unknown"; } - description += ``; - } - if (!Cesium.defined(name)) { - name = "unknown"; - } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); + } } - } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; + } + return false; } - return false; - } - //Sandcastle_End + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; window.startup(Cesium); diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 10a05695d89..c57fa51a12e 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -38,15 +38,15 @@

Loading...

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: new Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); - // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry - viewer.scene.globe.depthTestAgainstTerrain = false; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); + // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry + viewer.scene.globe.depthTestAgainstTerrain = false; - async function addI3sProvider() { // More datasets to tour can be added here.. // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (./SceneServer/layers/) or a collection of scene layers (./SceneServer) from a SceneServer. const tours = { @@ -86,10 +86,7 @@

Loading...

viewer.camera.setView({ destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), }); - } - - addI3sProvider(); - //Sandcastle_End + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; window.startup(Cesium); diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index e823652ae7d..61d91ea1cb2 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -37,169 +37,175 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, //Disable InfoBox widget - selectionIndicator: false, //Disable selection indicator - shouldAnimate: true, // Enable animations - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - - //Enable lighting based on the sun position - viewer.scene.globe.enableLighting = true; - - //Enable depth testing so things behind the terrain disappear. - viewer.scene.globe.depthTestAgainstTerrain = true; - - //Set the random number seed for consistent results. - Cesium.Math.setRandomNumberSeed(3); - - //Set bounds of our simulation time - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); - - //Make sure viewer is at the desired time. - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end - viewer.clock.multiplier = 10; - - //Set timeline to simulation bounds - viewer.timeline.zoomTo(start, stop); - - //Generate a random circular pattern with varying heights. - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - for (let i = 0; i <= 360; i += 45) { - const radians = Cesium.Math.toRadians(i); - const time = Cesium.JulianDate.addSeconds( - start, - i, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1750 - ); - property.addSample(time, position); - - //Also create a point for each sample we generate. - viewer.entities.add({ - position: position, - point: { - pixelSize: 8, - color: Cesium.Color.TRANSPARENT, - outlineColor: Cesium.Color.YELLOW, - outlineWidth: 3, - }, - }); - } - return property; - } - - //Compute the entity position property. - const position = computeCirclularFlight(-112.110693, 36.0994841, 0.03); - - //Actually create the entity - const entity = viewer.entities.add({ - //Set the entity availability to the same interval as the simulation time. - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - - //Use our computed positions - position: position, - - //Automatically compute orientation based on position movement. - orientation: new Cesium.VelocityOrientationProperty(position), - - //Load the Cesium plane model to represent the entity - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - minimumPixelSize: 64, - }, - - //Show the path as a pink line sampled in 1 second increments. - path: { - resolution: 1, - material: new Cesium.PolylineGlowMaterialProperty({ - glowPower: 0.1, - color: Cesium.Color.YELLOW, - }), - width: 10, - }, - }); - - //Add button to view the path from the top down - Sandcastle.addDefaultToolbarButton("View Top Down", function () { - viewer.trackedEntity = undefined; - viewer.zoomTo( - viewer.entities, - new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)) + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, //Disable InfoBox widget + selectionIndicator: false, //Disable selection indicator + shouldAnimate: true, // Enable animations + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + + //Enable lighting based on the sun position + viewer.scene.globe.enableLighting = true; + + //Enable depth testing so things behind the terrain disappear. + viewer.scene.globe.depthTestAgainstTerrain = true; + + //Set the random number seed for consistent results. + Cesium.Math.setRandomNumberSeed(3); + + //Set bounds of our simulation time + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() ); - }); - - //Add button to view the path from the side - Sandcastle.addToolbarButton("View Side", function () { - viewer.trackedEntity = undefined; - viewer.zoomTo( - viewer.entities, - new Cesium.HeadingPitchRange( - Cesium.Math.toRadians(-90), - Cesium.Math.toRadians(-15), - 7500 - ) + + //Make sure viewer is at the desired time. + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end + viewer.clock.multiplier = 10; + + //Set timeline to simulation bounds + viewer.timeline.zoomTo(start, stop); + + //Generate a random circular pattern with varying heights. + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + for (let i = 0; i <= 360; i += 45) { + const radians = Cesium.Math.toRadians(i); + const time = Cesium.JulianDate.addSeconds( + start, + i, + new Cesium.JulianDate() + ); + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1750 + ); + property.addSample(time, position); + + //Also create a point for each sample we generate. + viewer.entities.add({ + position: position, + point: { + pixelSize: 8, + color: Cesium.Color.TRANSPARENT, + outlineColor: Cesium.Color.YELLOW, + outlineWidth: 3, + }, + }); + } + return property; + } + + //Compute the entity position property. + const position = computeCirclularFlight( + -112.110693, + 36.0994841, + 0.03 ); - }); - - //Add button to track the entity as it moves - Sandcastle.addToolbarButton("View Aircraft", function () { - viewer.trackedEntity = entity; - }); - - //Add a combo box for selecting each interpolation mode. - Sandcastle.addToolbarMenu( - [ - { - text: "Interpolation: Linear Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 1, - interpolationAlgorithm: Cesium.LinearApproximation, - }); - }, + + //Actually create the entity + const entity = viewer.entities.add({ + //Set the entity availability to the same interval as the simulation time. + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + + //Use our computed positions + position: position, + + //Automatically compute orientation based on position movement. + orientation: new Cesium.VelocityOrientationProperty(position), + + //Load the Cesium plane model to represent the entity + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + minimumPixelSize: 64, }, - { - text: "Interpolation: Lagrange Polynomial Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 5, - interpolationAlgorithm: - Cesium.LagrangePolynomialApproximation, - }); - }, + + //Show the path as a pink line sampled in 1 second increments. + path: { + resolution: 1, + material: new Cesium.PolylineGlowMaterialProperty({ + glowPower: 0.1, + color: Cesium.Color.YELLOW, + }), + width: 10, }, - { - text: "Interpolation: Hermite Polynomial Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + }); + + //Add button to view the path from the top down + Sandcastle.addDefaultToolbarButton("View Top Down", function () { + viewer.trackedEntity = undefined; + viewer.zoomTo( + viewer.entities, + new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)) + ); + }); + + //Add button to view the path from the side + Sandcastle.addToolbarButton("View Side", function () { + viewer.trackedEntity = undefined; + viewer.zoomTo( + viewer.entities, + new Cesium.HeadingPitchRange( + Cesium.Math.toRadians(-90), + Cesium.Math.toRadians(-15), + 7500 + ) + ); + }); + + //Add button to track the entity as it moves + Sandcastle.addToolbarButton("View Aircraft", function () { + viewer.trackedEntity = entity; + }); + + //Add a combo box for selecting each interpolation mode. + Sandcastle.addToolbarMenu( + [ + { + text: "Interpolation: Linear Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 1, + interpolationAlgorithm: Cesium.LinearApproximation, + }); + }, }, - }, - ], - "interpolationMenu" - ); - //Sandcastle_End + { + text: "Interpolation: Lagrange Polynomial Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 5, + interpolationAlgorithm: + Cesium.LagrangePolynomialApproximation, + }); + }, + }, + { + text: "Interpolation: Hermite Polynomial Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: + Cesium.HermitePolynomialApproximation, + }); + }, + }, + ], + "interpolationMenu" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index 4ede13e7f79..a4083d6edb7 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -32,201 +32,205 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); - - const scene = viewer.scene; - scene.globe.enableLighting = true; - - const scratchIcrfToFixed = new Cesium.Matrix3(); - const scratchMoonPosition = new Cesium.Cartesian3(); - const scratchMoonDirection = new Cesium.Cartesian3(); - - function getMoonDirection(result) { - result = Cesium.defined(result) ? result : new Cesium.Cartesian3(); - const icrfToFixed = scratchIcrfToFixed; - const date = viewer.clock.currentTime; - if ( - !Cesium.defined( - Cesium.Transforms.computeIcrfToFixedMatrix(date, icrfToFixed) - ) - ) { - Cesium.Transforms.computeTemeToPseudoFixedMatrix(date, icrfToFixed); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); + + const scene = viewer.scene; + scene.globe.enableLighting = true; + + const scratchIcrfToFixed = new Cesium.Matrix3(); + const scratchMoonPosition = new Cesium.Cartesian3(); + const scratchMoonDirection = new Cesium.Cartesian3(); + + function getMoonDirection(result) { + result = Cesium.defined(result) ? result : new Cesium.Cartesian3(); + const icrfToFixed = scratchIcrfToFixed; + const date = viewer.clock.currentTime; + if ( + !Cesium.defined( + Cesium.Transforms.computeIcrfToFixedMatrix(date, icrfToFixed) + ) + ) { + Cesium.Transforms.computeTemeToPseudoFixedMatrix( + date, + icrfToFixed + ); + } + const moonPosition = Cesium.Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame( + date, + scratchMoonPosition + ); + Cesium.Matrix3.multiplyByVector( + icrfToFixed, + moonPosition, + moonPosition + ); + const moonDirection = Cesium.Cartesian3.normalize( + moonPosition, + scratchMoonDirection + ); + return Cesium.Cartesian3.negate(moonDirection, result); } - const moonPosition = Cesium.Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame( - date, - scratchMoonPosition - ); - Cesium.Matrix3.multiplyByVector( - icrfToFixed, - moonPosition, - moonPosition - ); - const moonDirection = Cesium.Cartesian3.normalize( - moonPosition, - scratchMoonDirection - ); - return Cesium.Cartesian3.negate(moonDirection, result); - } - - const directionalLight = new Cesium.DirectionalLight({ - direction: new Cesium.Cartesian3( - 0.2454278300540191, - 0.8842635425193919, - 0.39729481195458805 - ), - }); - - const flashlight = new Cesium.DirectionalLight({ - direction: scene.camera.directionWC, // Updated every frame - }); - - const moonLight = new Cesium.DirectionalLight({ - direction: getMoonDirection(), // Updated every frame - color: new Cesium.Color(0.9, 0.925, 1.0), - intensity: 0.5, - }); - - const sunLight = new Cesium.SunLight(); - - const customColorLight = new Cesium.DirectionalLight({ - direction: new Cesium.Cartesian3( - -0.2454278300540191, - 0.8842635425193919, - 0.39729481195458805 - ), - color: Cesium.Color.fromCssColorString("#deca7c"), - }); - - scene.preRender.addEventListener(function (scene, time) { - if (scene.light === flashlight) { - scene.light.direction = Cesium.Cartesian3.clone( - scene.camera.directionWC, - scene.light.direction + + const directionalLight = new Cesium.DirectionalLight({ + direction: new Cesium.Cartesian3( + 0.2454278300540191, + 0.8842635425193919, + 0.39729481195458805 + ), + }); + + const flashlight = new Cesium.DirectionalLight({ + direction: scene.camera.directionWC, // Updated every frame + }); + + const moonLight = new Cesium.DirectionalLight({ + direction: getMoonDirection(), // Updated every frame + color: new Cesium.Color(0.9, 0.925, 1.0), + intensity: 0.5, + }); + + const sunLight = new Cesium.SunLight(); + + const customColorLight = new Cesium.DirectionalLight({ + direction: new Cesium.Cartesian3( + -0.2454278300540191, + 0.8842635425193919, + 0.39729481195458805 + ), + color: Cesium.Color.fromCssColorString("#deca7c"), + }); + + scene.preRender.addEventListener(function (scene, time) { + if (scene.light === flashlight) { + scene.light.direction = Cesium.Cartesian3.clone( + scene.camera.directionWC, + scene.light.direction + ); + } else if (scene.light === moonLight) { + scene.light.direction = getMoonDirection(scene.light.direction); + } + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.1463338399937277, + 0.6677959688982861, + 32.18991401746337 + ), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + scale: 7.0, + }, + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.14633449752228, + 0.667796065242357, + 24.47647034111423 + ), + cylinder: { + length: 8.0, + topRadius: 2.0, + bottomRadius: 2.0, + material: Cesium.Color.WHITE, + }, + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.1463332294173365, + 0.6677959755384729, + 26.2876064083145 + ), + ellipsoid: { + radii: new Cesium.Cartesian3(2.5, 2.5, 2.5), + material: Cesium.Color.WHITE.withAlpha(0.5), + }, + }); + + function setTime(iso8601) { + const currentTime = Cesium.JulianDate.fromIso8601(iso8601); + const endTime = Cesium.JulianDate.addDays( + currentTime, + 2, + new Cesium.JulianDate() ); - } else if (scene.light === moonLight) { - scene.light.direction = getMoonDirection(scene.light.direction); + + viewer.clock.currentTime = currentTime; + viewer.timeline.zoomTo(currentTime, endTime); } - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.1463338399937277, - 0.6677959688982861, - 32.18991401746337 - ), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - scale: 7.0, - }, - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.14633449752228, - 0.667796065242357, - 24.47647034111423 - ), - cylinder: { - length: 8.0, - topRadius: 2.0, - bottomRadius: 2.0, - material: Cesium.Color.WHITE, - }, - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.1463332294173365, - 0.6677959755384729, - 26.2876064083145 - ), - ellipsoid: { - radii: new Cesium.Cartesian3(2.5, 2.5, 2.5), - material: Cesium.Color.WHITE.withAlpha(0.5), - }, - }); - - function setTime(iso8601) { - const currentTime = Cesium.JulianDate.fromIso8601(iso8601); - const endTime = Cesium.JulianDate.addDays( - currentTime, - 2, - new Cesium.JulianDate() - ); - - viewer.clock.currentTime = currentTime; - viewer.timeline.zoomTo(currentTime, endTime); - } - - function reset() { - // Set scene defaults - scene.light = sunLight; - scene.globe.dynamicAtmosphereLighting = true; - scene.globe.dynamicAtmosphereLightingFromSun = false; - setTime("2020-01-09T23:00:39.018261982600961346Z"); - } - - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -2729490.8390059783, - -4206389.878855597, - 3928671.2763356343 - ), - orientation: new Cesium.HeadingPitchRoll( - 2.2482480507178426, - -0.20084951548781982, - 0.002593933673552762 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); - - const options = [ - { - text: "Fixed lighting", - onselect: function () { - reset(); - scene.light = directionalLight; + + function reset() { + // Set scene defaults + scene.light = sunLight; + scene.globe.dynamicAtmosphereLighting = true; + scene.globe.dynamicAtmosphereLightingFromSun = false; + setTime("2020-01-09T23:00:39.018261982600961346Z"); + } + + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -2729490.8390059783, + -4206389.878855597, + 3928671.2763356343 + ), + orientation: new Cesium.HeadingPitchRoll( + 2.2482480507178426, + -0.20084951548781982, + 0.002593933673552762 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); + + const options = [ + { + text: "Fixed lighting", + onselect: function () { + reset(); + scene.light = directionalLight; + }, }, - }, - { - text: "Flashlight", - onselect: function () { - reset(); - scene.light = flashlight; - scene.globe.dynamicAtmosphereLighting = false; + { + text: "Flashlight", + onselect: function () { + reset(); + scene.light = flashlight; + scene.globe.dynamicAtmosphereLighting = false; + }, }, - }, - { - text: "Moonlight", - onselect: function () { - reset(); - scene.light = moonLight; - scene.globe.dynamicAtmosphereLightingFromSun = true; - setTime("2020-01-10T05:29:41.17946898164518643Z"); + { + text: "Moonlight", + onselect: function () { + reset(); + scene.light = moonLight; + scene.globe.dynamicAtmosphereLightingFromSun = true; + setTime("2020-01-10T05:29:41.17946898164518643Z"); + }, }, - }, - { - text: "Sunlight", - onselect: function () { - reset(); + { + text: "Sunlight", + onselect: function () { + reset(); + }, }, - }, - { - text: "Custom color", - onselect: function () { - reset(); - scene.light = customColorLight; + { + text: "Custom color", + onselect: function () { + reset(); + scene.light = customColorLight; + }, }, - }, - ]; + ]; - Sandcastle.addToolbarMenu(options); - //Sandcastle_End + Sandcastle.addToolbarMenu(options); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index 3325e32324c..1d3282b5903 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -32,150 +32,151 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - contextOptions: { - requestWebgl1: false, - }, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + contextOptions: { + requestWebgl1: false, + }, + }); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2022-08-01T00:00:00Z" - ); + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2022-08-01T00:00:00Z" + ); - const scene = viewer.scene; - if (!scene.msaaSupported) { - window.alert("This browser does not support MSAA."); - } + const scene = viewer.scene; + if (!scene.msaaSupported) { + window.alert("This browser does not support MSAA."); + } - function createModel(url, height) { - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - height - ); - const heading = Cesium.Math.toRadians(135); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); + function createModel(url, height) { + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + height + ); + const heading = Cesium.Math.toRadians(135); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - minimumPixelSize: 128, - maximumScale: 20000, - }, - }); - const target = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - height + 7.5 - ); - const offset = new Cesium.Cartesian3(50.0, -15.0, 0.0); - viewer.scene.camera.lookAt(target, offset); - } + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + minimumPixelSize: 128, + maximumScale: 20000, + }, + }); + const target = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + height + 7.5 + ); + const offset = new Cesium.Cartesian3(50.0, -15.0, 0.0); + viewer.scene.camera.lookAt(target, offset); + } - const options = [ - { - text: "Statue of Liberty", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + const options = [ + { + text: "Statue of Liberty", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); + }, }, - }, - { - text: "3D Tiles BIM", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - }) - ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1234138.7804841248, - -5086063.633843134, - 3633284.606361642 - ), - orientation: { - heading: 0.4304630387656614, - pitch: -0.16969316864215878, - roll: 6.283184816241989, - }, - }); + { + text: "3D Tiles BIM", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(1240402), + }) + ); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1234138.7804841248, + -5086063.633843134, + 3633284.606361642 + ), + orientation: { + heading: 0.4304630387656614, + pitch: -0.16969316864215878, + roll: 6.283184816241989, + }, + }); + }, }, - }, - { - text: "Hot Air Balloon", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - createModel( - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - 1000.0 - ); + { + text: "Hot Air Balloon", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + createModel( + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + 1000.0 + ); + }, }, - }, - ]; + ]; - const samplingOptions = [ - { - text: "MSAA off", - onselect: function () { - scene.msaaSamples = 1; + const samplingOptions = [ + { + text: "MSAA off", + onselect: function () { + scene.msaaSamples = 1; + }, }, - }, - { - text: "MSAA 2x", - onselect: function () { - scene.msaaSamples = 2; + { + text: "MSAA 2x", + onselect: function () { + scene.msaaSamples = 2; + }, }, - }, - { - text: "MSAA 4x", - onselect: function () { - scene.msaaSamples = 4; + { + text: "MSAA 4x", + onselect: function () { + scene.msaaSamples = 4; + }, }, - }, - { - text: "MSAA 8x", - onselect: function () { - scene.msaaSamples = 8; + { + text: "MSAA 8x", + onselect: function () { + scene.msaaSamples = 8; + }, }, - }, - ]; + ]; - Sandcastle.addToolbarMenu(options); - Sandcastle.addToolbarMenu(samplingOptions); - //Sandcastle_End + Sandcastle.addToolbarMenu(options); + Sandcastle.addToolbarMenu(samplingOptions); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index 5d1600e6788..c6bed6181d4 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -86,343 +86,344 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(28945), - pointCloudShading: { - attenuation: true, - maximumAttenuation: 2, - }, - }) - ); + // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. + const tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(28945), + pointCloudShading: { + attenuation: true, + maximumAttenuation: 2, + }, + }) + ); - // Fly to a nice overview of the city. - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1223285.2286828577, - -4319476.080312792, - 4562579.020145769 - ), - orientation: { - direction: new Cesium.Cartesian3( - 0.63053223097472, - 0.47519958296727743, - -0.6136892226931869 - ), - up: new Cesium.Cartesian3( - 0.7699959023135587, - -0.4824455703743441, - 0.41755548379407276 + // Fly to a nice overview of the city. + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1223285.2286828577, + -4319476.080312792, + 4562579.020145769 ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + 0.63053223097472, + 0.47519958296727743, + -0.6136892226931869 + ), + up: new Cesium.Cartesian3( + 0.7699959023135587, + -0.4824455703743441, + 0.41755548379407276 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); - // Add stored views around Montreal. You can add to this list by capturing camera.position, camera.direction and camera.up. - Sandcastle.addToolbarMenu([ - { - text: "Overview", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1268112.9336926902, - -4347432.089579957, - 4539129.813606778 - ), - orientation: { - direction: new Cesium.Cartesian3( - -0.23288147105081208, - 0.9376599248561527, - -0.25799241415197466 + // Add stored views around Montreal. You can add to this list by capturing camera.position, camera.direction and camera.up. + Sandcastle.addToolbarMenu([ + { + text: "Overview", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1268112.9336926902, + -4347432.089579957, + 4539129.813606778 ), - up: new Cesium.Cartesian3( - -0.015748156073159988, - 0.2616156268422992, - 0.9650436567182887 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + -0.23288147105081208, + 0.9376599248561527, + -0.25799241415197466 + ), + up: new Cesium.Cartesian3( + -0.015748156073159988, + 0.2616156268422992, + 0.9650436567182887 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); + }, }, - }, - { - text: "Highway", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1266560.143870489, - -4278126.842199712, - 4542690.264566619 - ), - orientation: { - direction: new Cesium.Cartesian3( - -0.3402460635871598, - -0.46669052711538217, - -0.8163532128400116 - ), - up: new Cesium.Cartesian3( - 0.08964012922691329, - -0.8802940231336787, - 0.46588311846138497 + { + text: "Highway", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1266560.143870489, + -4278126.842199712, + 4542690.264566619 ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + -0.3402460635871598, + -0.46669052711538217, + -0.8163532128400116 + ), + up: new Cesium.Cartesian3( + 0.08964012922691329, + -0.8802940231336787, + 0.46588311846138497 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); + }, }, - }, - { - text: "Olympic Stadium", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1267081.619536883, - -4290744.917138439, - 4530941.041519919 - ), - orientation: { - direction: new Cesium.Cartesian3( - -0.735813047510908, - 0.6294547560338262, - 0.24973159435503312 + { + text: "Olympic Stadium", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1267081.619536883, + -4290744.917138439, + 4530941.041519919 ), - up: new Cesium.Cartesian3( - -0.09796934684423217, - -0.4638476756625683, - 0.88048131204549 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + -0.735813047510908, + 0.6294547560338262, + 0.24973159435503312 + ), + up: new Cesium.Cartesian3( + -0.09796934684423217, + -0.4638476756625683, + 0.88048131204549 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); + }, }, - }, - { - text: "Biosphere Museum", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1269319.8408991008, - -4293301.826913256, - 4527724.561372451 - ), - orientation: { - direction: new Cesium.Cartesian3( - -0.742505030107832, - -0.3413204607149223, - -0.5763563336703441 - ), - up: new Cesium.Cartesian3( - -0.04655102331027917, - -0.8320643756800384, - 0.5527222421370013 + { + text: "Biosphere Museum", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1269319.8408991008, + -4293301.826913256, + 4527724.561372451 ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + -0.742505030107832, + -0.3413204607149223, + -0.5763563336703441 + ), + up: new Cesium.Cartesian3( + -0.04655102331027917, + -0.8320643756800384, + 0.5527222421370013 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); + }, }, - }, - { - text: "St. Joseph's Oratory of Mount Royal", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1263148.6745904868, - -4297262.506644816, - 4525958.844284831 - ), - orientation: { - direction: new Cesium.Cartesian3( - 0.6550952540993403, - 0.7551122393690295, - 0.025606913355780074 + { + text: "St. Joseph's Oratory of Mount Royal", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1263148.6745904868, + -4297262.506644816, + 4525958.844284831 ), - up: new Cesium.Cartesian3( - 0.46670450470847263, - -0.4310758971098583, - 0.7722437932516845 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + orientation: { + direction: new Cesium.Cartesian3( + 0.6550952540993403, + 0.7551122393690295, + 0.025606913355780074 + ), + up: new Cesium.Cartesian3( + 0.46670450470847263, + -0.4310758971098583, + 0.7722437932516845 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); + }, }, - }, - ]); + ]); + + // Set up checkboxes for toggling the various classification settings. + const viewModel = { + ground: true, + other: true, + buildings: true, + low_vegetation: true, + medium_vegetation: true, + high_vegetation: true, + }; - // Set up checkboxes for toggling the various classification settings. - const viewModel = { - ground: true, - other: true, - buildings: true, - low_vegetation: true, - medium_vegetation: true, - high_vegetation: true, - }; + // Assign colors to each classification type. + const pointStyles = { + unclassified: { + color: "color('#808080')", + show: true, + }, + not_awarded: { + color: "color('#FFDEAD')", + show: true, + }, + ground: { + color: "color('#FFDEAD')", + show: true, + }, + low_vegetation: { + color: "color('#63FF7E')", + show: true, + }, + medium_vegetation: { + color: "color('#63FF7E')", + show: true, + }, + high_vegetation: { + color: "color('#22B33A')", + show: true, + }, + buildings: { + color: "color('#efefef')", + show: true, + }, + low_point: { + color: "color('#808080')", + show: true, + }, + reserved_city_diffusion: { + color: "color('#808080')", + show: true, + }, + }; - // Assign colors to each classification type. - const pointStyles = { - unclassified: { - color: "color('#808080')", - show: true, - }, - not_awarded: { - color: "color('#FFDEAD')", - show: true, - }, - ground: { - color: "color('#FFDEAD')", - show: true, - }, - low_vegetation: { - color: "color('#63FF7E')", - show: true, - }, - medium_vegetation: { - color: "color('#63FF7E')", - show: true, - }, - high_vegetation: { - color: "color('#22B33A')", - show: true, - }, - buildings: { - color: "color('#efefef')", - show: true, - }, - low_point: { - color: "color('#808080')", - show: true, - }, - reserved_city_diffusion: { - color: "color('#808080')", - show: true, - }, - }; + const classificationDictionary = { + not_awarded: 1, + ground: 2, + low_vegetation: 3, + medium_vegetation: 4, + high_vegetation: 5, + buildings: 6, + low_point: 7, + reserved_city_diffusion: 8, + unclassified: -1, + }; - const classificationDictionary = { - not_awarded: 1, - ground: 2, - low_vegetation: 3, - medium_vegetation: 4, - high_vegetation: 5, - buildings: 6, - low_point: 7, - reserved_city_diffusion: 8, - unclassified: -1, - }; + // This is a helper function to re-apply the styles each time the UI/checkboxes are updated. + function applyStyle(tileset, styles) { + const styleObject = {}; + const styleKeys = Object.keys(styles); - // This is a helper function to re-apply the styles each time the UI/checkboxes are updated. - function applyStyle(tileset, styles) { - const styleObject = {}; - const styleKeys = Object.keys(styles); + styleObject.color = { + conditions: [], + }; + styleObject.show = { + conditions: [], + }; - styleObject.color = { - conditions: [], - }; - styleObject.show = { - conditions: [], - }; + let finalCondition; - let finalCondition; + for (let i = 0; i < styleKeys.length; ++i) { + const key = styleKeys[i]; + const id = classificationDictionary[key]; - for (let i = 0; i < styleKeys.length; ++i) { - const key = styleKeys[i]; - const id = classificationDictionary[key]; + const colorCondition = [ + `\${Classification} === ${id}`, + styles[key].color, + ]; + const showCondition = [ + `\${Classification} === ${id}`, + styles[key].show, + ]; - const colorCondition = [ - `\${Classification} === ${id}`, - styles[key].color, - ]; - const showCondition = [ - `\${Classification} === ${id}`, - styles[key].show, - ]; + if (id === -1) { + colorCondition[0] = true; + showCondition[0] = true; - if (id === -1) { - colorCondition[0] = true; - showCondition[0] = true; + finalCondition = { + colorCondition: colorCondition, + showCondition: showCondition, + }; + } else { + styleObject.color.conditions.push(colorCondition); + styleObject.show.conditions.push(showCondition); + } + } - finalCondition = { - colorCondition: colorCondition, - showCondition: showCondition, - }; - } else { - styleObject.color.conditions.push(colorCondition); - styleObject.show.conditions.push(showCondition); + if (Cesium.defined(finalCondition)) { + styleObject.color.conditions.push(finalCondition.colorCondition); + styleObject.show.conditions.push(finalCondition.showCondition); } - } - if (Cesium.defined(finalCondition)) { - styleObject.color.conditions.push(finalCondition.colorCondition); - styleObject.show.conditions.push(finalCondition.showCondition); + tileset.style = new Cesium.Cesium3DTileStyle(styleObject); } - tileset.style = new Cesium.Cesium3DTileStyle(styleObject); - } - - // Apply an initial style. - applyStyle(tileset, pointStyles); + // Apply an initial style. + applyStyle(tileset, pointStyles); - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - // Set up the checkboxes. - Cesium.knockout - .getObservable(viewModel, "ground") - .subscribe(function (show) { - pointStyles.ground.show = show; - pointStyles.not_awarded.show = show; + // Set up the checkboxes. + Cesium.knockout + .getObservable(viewModel, "ground") + .subscribe(function (show) { + pointStyles.ground.show = show; + pointStyles.not_awarded.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "low_vegetation") - .subscribe(function (show) { - pointStyles.low_vegetation.show = show; + Cesium.knockout + .getObservable(viewModel, "low_vegetation") + .subscribe(function (show) { + pointStyles.low_vegetation.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "medium_vegetation") - .subscribe(function (show) { - pointStyles.medium_vegetation.show = show; + Cesium.knockout + .getObservable(viewModel, "medium_vegetation") + .subscribe(function (show) { + pointStyles.medium_vegetation.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "high_vegetation") - .subscribe(function (show) { - pointStyles.high_vegetation.show = show; + Cesium.knockout + .getObservable(viewModel, "high_vegetation") + .subscribe(function (show) { + pointStyles.high_vegetation.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "buildings") - .subscribe(function (show) { - pointStyles.buildings.show = show; + Cesium.knockout + .getObservable(viewModel, "buildings") + .subscribe(function (show) { + pointStyles.buildings.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "other") - .subscribe(function (show) { - pointStyles.low_point.show = show; - pointStyles.reserved_city_diffusion.show = show; - pointStyles.unclassified.show = show; + Cesium.knockout + .getObservable(viewModel, "other") + .subscribe(function (show) { + pointStyles.low_point.show = show; + pointStyles.reserved_city_diffusion.show = show; + pointStyles.unclassified.show = show; - applyStyle(tileset, pointStyles); - }); - //Sandcastle_End + applyStyle(tileset, pointStyles); + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index c28e0dd3c2b..a23ffe72708 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -35,106 +35,112 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) - // http://www.pasda.psu.edu/ - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) - ), - }); + (async () => { + let viewer; + try { + // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) + // http://www.pasda.psu.edu/ + viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3957) + ), + }); + } catch (error) { + console.log(error); + } - // Add PA locations - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Pinnacle", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3324415110874286, - 0.6954224325279967, - 236.6770689945084 - ), - orientation: { - heading: Cesium.Math.toRadians(310), - pitch: Cesium.Math.toRadians(-15), - roll: 0.0, - }, - }); + // Add PA locations + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Pinnacle", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3324415110874286, + 0.6954224325279967, + 236.6770689945084 + ), + orientation: { + heading: Cesium.Math.toRadians(310), + pitch: Cesium.Math.toRadians(-15), + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Mount Nittany", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.358985133937573, - 0.7123252393978314, - 451.05748252867375 - ), - orientation: { - heading: Cesium.Math.toRadians(85), - pitch: Cesium.Math.toRadians(0), - roll: 0.0, - }, - }); + { + text: "Mount Nittany", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.358985133937573, + 0.7123252393978314, + 451.05748252867375 + ), + orientation: { + heading: Cesium.Math.toRadians(85), + pitch: Cesium.Math.toRadians(0), + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Horseshoe Curve", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3700147546199826, - 0.706808606166025, - 993.7916313325215 - ), - orientation: { - heading: Cesium.Math.toRadians(90), - pitch: Cesium.Math.toRadians(-15), - roll: 0.0, - }, - }); + { + text: "Horseshoe Curve", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3700147546199826, + 0.706808606166025, + 993.7916313325215 + ), + orientation: { + heading: Cesium.Math.toRadians(90), + pitch: Cesium.Math.toRadians(-15), + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Jim Thorpe", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3218297501066052, - 0.713358272291525, - 240.87968743408845 - ), - orientation: { - heading: Cesium.Math.toRadians(200), - pitch: Cesium.Math.toRadians(-5), - roll: 0.0, - }, - }); + { + text: "Jim Thorpe", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3218297501066052, + 0.713358272291525, + 240.87968743408845 + ), + orientation: { + heading: Cesium.Math.toRadians(200), + pitch: Cesium.Math.toRadians(-5), + roll: 0.0, + }, + }); + }, }, - }, - { - text: "Grand Canyon of PA", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.349379633251472, - 0.720297672225785, - 656.268309953562 - ), - orientation: { - heading: Cesium.Math.toRadians(200), - pitch: Cesium.Math.toRadians(-5), - roll: 0.0, - }, - }); + { + text: "Grand Canyon of PA", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.349379633251472, + 0.720297672225785, + 656.268309953562 + ), + orientation: { + heading: Cesium.Math.toRadians(200), + pitch: Cesium.Math.toRadians(-5), + roll: 0.0, + }, + }); + }, }, - }, - ], - "toolbar" - ); - //Sandcastle_End + ], + "toolbar" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index 9ed85917eea..c757b3aa3d7 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -35,172 +35,173 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - shouldAnimate: true, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; - const resetCameraFunction = function () { - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 277096.634865404, - 5647834.481964232, - 2985563.7039122293 - ), - orientation: { - heading: 4.731089976107251, - pitch: -0.32003481981370063, - }, + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - }; - resetCameraFunction(); + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; + const resetCameraFunction = function () { + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 277096.634865404, + 5647834.481964232, + 2985563.7039122293 + ), + orientation: { + heading: 4.731089976107251, + pitch: -0.32003481981370063, + }, + }); + }; + resetCameraFunction(); - // snow - const snowParticleSize = 12.0; - const snowRadius = 100000.0; - const minimumSnowImageSize = new Cesium.Cartesian2( - snowParticleSize, - snowParticleSize - ); - const maximumSnowImageSize = new Cesium.Cartesian2( - snowParticleSize * 2.0, - snowParticleSize * 2.0 - ); - let snowGravityScratch = new Cesium.Cartesian3(); - const snowUpdate = function (particle, dt) { - snowGravityScratch = Cesium.Cartesian3.normalize( - particle.position, - snowGravityScratch - ); - Cesium.Cartesian3.multiplyByScalar( - snowGravityScratch, - Cesium.Math.randomBetween(-30.0, -300.0), - snowGravityScratch - ); - particle.velocity = Cesium.Cartesian3.add( - particle.velocity, - snowGravityScratch, - particle.velocity + // snow + const snowParticleSize = 12.0; + const snowRadius = 100000.0; + const minimumSnowImageSize = new Cesium.Cartesian2( + snowParticleSize, + snowParticleSize ); - const distance = Cesium.Cartesian3.distance( - scene.camera.position, - particle.position + const maximumSnowImageSize = new Cesium.Cartesian2( + snowParticleSize * 2.0, + snowParticleSize * 2.0 ); - if (distance > snowRadius) { - particle.endColor.alpha = 0.0; - } else { - particle.endColor.alpha = 1.0 / (distance / snowRadius + 0.1); - } - }; + let snowGravityScratch = new Cesium.Cartesian3(); + const snowUpdate = function (particle, dt) { + snowGravityScratch = Cesium.Cartesian3.normalize( + particle.position, + snowGravityScratch + ); + Cesium.Cartesian3.multiplyByScalar( + snowGravityScratch, + Cesium.Math.randomBetween(-30.0, -300.0), + snowGravityScratch + ); + particle.velocity = Cesium.Cartesian3.add( + particle.velocity, + snowGravityScratch, + particle.velocity + ); + const distance = Cesium.Cartesian3.distance( + scene.camera.position, + particle.position + ); + if (distance > snowRadius) { + particle.endColor.alpha = 0.0; + } else { + particle.endColor.alpha = 1.0 / (distance / snowRadius + 0.1); + } + }; - // rain - const rainParticleSize = 15.0; - const rainRadius = 100000.0; - const rainImageSize = new Cesium.Cartesian2( - rainParticleSize, - rainParticleSize * 2.0 - ); - let rainGravityScratch = new Cesium.Cartesian3(); - const rainUpdate = function (particle, dt) { - rainGravityScratch = Cesium.Cartesian3.normalize( - particle.position, - rainGravityScratch - ); - rainGravityScratch = Cesium.Cartesian3.multiplyByScalar( - rainGravityScratch, - -1050.0, - rainGravityScratch + // rain + const rainParticleSize = 15.0; + const rainRadius = 100000.0; + const rainImageSize = new Cesium.Cartesian2( + rainParticleSize, + rainParticleSize * 2.0 ); + let rainGravityScratch = new Cesium.Cartesian3(); + const rainUpdate = function (particle, dt) { + rainGravityScratch = Cesium.Cartesian3.normalize( + particle.position, + rainGravityScratch + ); + rainGravityScratch = Cesium.Cartesian3.multiplyByScalar( + rainGravityScratch, + -1050.0, + rainGravityScratch + ); - particle.position = Cesium.Cartesian3.add( - particle.position, - rainGravityScratch, - particle.position - ); + particle.position = Cesium.Cartesian3.add( + particle.position, + rainGravityScratch, + particle.position + ); - const distance = Cesium.Cartesian3.distance( - scene.camera.position, - particle.position - ); - if (distance > rainRadius) { - particle.endColor.alpha = 0.0; - } else { - particle.endColor.alpha = - Cesium.Color.BLUE.alpha / (distance / rainRadius + 0.1); - } - }; + const distance = Cesium.Cartesian3.distance( + scene.camera.position, + particle.position + ); + if (distance > rainRadius) { + particle.endColor.alpha = 0.0; + } else { + particle.endColor.alpha = + Cesium.Color.BLUE.alpha / (distance / rainRadius + 0.1); + } + }; - // button - Sandcastle.addToolbarButton("Reset Camera", resetCameraFunction); + // button + Sandcastle.addToolbarButton("Reset Camera", resetCameraFunction); - // drop down - const options = [ - { - text: "Snow", - onselect: function () { - scene.primitives.removeAll(); - scene.primitives.add( - new Cesium.ParticleSystem({ - modelMatrix: new Cesium.Matrix4.fromTranslation( - scene.camera.position - ), - minimumSpeed: -1.0, - maximumSpeed: 0.0, - lifetime: 15.0, - emitter: new Cesium.SphereEmitter(snowRadius), - startScale: 0.5, - endScale: 1.0, - image: "../../SampleData/snowflake_particle.png", - emissionRate: 7000.0, - startColor: Cesium.Color.WHITE.withAlpha(0.0), - endColor: Cesium.Color.WHITE.withAlpha(1.0), - minimumImageSize: minimumSnowImageSize, - maximumImageSize: maximumSnowImageSize, - updateCallback: snowUpdate, - }) - ); + // drop down + const options = [ + { + text: "Snow", + onselect: function () { + scene.primitives.removeAll(); + scene.primitives.add( + new Cesium.ParticleSystem({ + modelMatrix: new Cesium.Matrix4.fromTranslation( + scene.camera.position + ), + minimumSpeed: -1.0, + maximumSpeed: 0.0, + lifetime: 15.0, + emitter: new Cesium.SphereEmitter(snowRadius), + startScale: 0.5, + endScale: 1.0, + image: "../../SampleData/snowflake_particle.png", + emissionRate: 7000.0, + startColor: Cesium.Color.WHITE.withAlpha(0.0), + endColor: Cesium.Color.WHITE.withAlpha(1.0), + minimumImageSize: minimumSnowImageSize, + maximumImageSize: maximumSnowImageSize, + updateCallback: snowUpdate, + }) + ); - scene.skyAtmosphere.hueShift = -0.8; - scene.skyAtmosphere.saturationShift = -0.7; - scene.skyAtmosphere.brightnessShift = -0.33; - scene.fog.density = 0.001; - scene.fog.minimumBrightness = 0.8; + scene.skyAtmosphere.hueShift = -0.8; + scene.skyAtmosphere.saturationShift = -0.7; + scene.skyAtmosphere.brightnessShift = -0.33; + scene.fog.density = 0.001; + scene.fog.minimumBrightness = 0.8; + }, }, - }, - { - text: "Rain", - onselect: function () { - scene.primitives.removeAll(); - scene.primitives.add( - new Cesium.ParticleSystem({ - modelMatrix: new Cesium.Matrix4.fromTranslation( - scene.camera.position - ), - speed: -1.0, - lifetime: 15.0, - emitter: new Cesium.SphereEmitter(rainRadius), - startScale: 1.0, - endScale: 0.0, - image: "../../SampleData/circular_particle.png", - emissionRate: 9000.0, - startColor: new Cesium.Color(0.27, 0.5, 0.7, 0.0), - endColor: new Cesium.Color(0.27, 0.5, 0.7, 0.98), - imageSize: rainImageSize, - updateCallback: rainUpdate, - }) - ); + { + text: "Rain", + onselect: function () { + scene.primitives.removeAll(); + scene.primitives.add( + new Cesium.ParticleSystem({ + modelMatrix: new Cesium.Matrix4.fromTranslation( + scene.camera.position + ), + speed: -1.0, + lifetime: 15.0, + emitter: new Cesium.SphereEmitter(rainRadius), + startScale: 1.0, + endScale: 0.0, + image: "../../SampleData/circular_particle.png", + emissionRate: 9000.0, + startColor: new Cesium.Color(0.27, 0.5, 0.7, 0.0), + endColor: new Cesium.Color(0.27, 0.5, 0.7, 0.98), + imageSize: rainImageSize, + updateCallback: rainUpdate, + }) + ); - scene.skyAtmosphere.hueShift = -0.97; - scene.skyAtmosphere.saturationShift = 0.25; - scene.skyAtmosphere.brightnessShift = -0.4; - scene.fog.density = 0.00025; - scene.fog.minimumBrightness = 0.01; + scene.skyAtmosphere.hueShift = -0.97; + scene.skyAtmosphere.saturationShift = 0.25; + scene.skyAtmosphere.brightnessShift = -0.4; + scene.fog.density = 0.00025; + scene.fog.minimumBrightness = 0.01; + }, }, - }, - ]; - Sandcastle.addToolbarMenu(options); - //Sandcastle_End + ]; + Sandcastle.addToolbarMenu(options); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index c530ef1a973..8b0bc123854 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -45,153 +45,154 @@ shouldAnimate: true, }); - const viewer = new Cesium.Viewer("cesiumContainer", { - clockViewModel: new Cesium.ClockViewModel(clock), - selectionIndicator: false, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + clockViewModel: new Cesium.ClockViewModel(clock), + selectionIndicator: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( - checked - ) { - viewer.shadows = checked; - }); + Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( + checked + ) { + viewer.shadows = checked; + }); - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - const position = new Cesium.Cartesian3( - -1371108.6511167218, - -5508684.080096612, - 2901825.449865087 - ); - const heading = Cesium.Math.toRadians(180); - const pitch = Cesium.Math.toRadians(2); - const roll = Cesium.Math.toRadians(-6); - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); + const position = new Cesium.Cartesian3( + -1371108.6511167218, + -5508684.080096612, + 2901825.449865087 + ); + const heading = Cesium.Math.toRadians(180); + const pitch = Cesium.Math.toRadians(2); + const roll = Cesium.Math.toRadians(-6); + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); - const entity = viewer.entities.add({ - name: "truck", - position: position, - orientation: orientation, - model: { - uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - minimumPixelSize: 128, - maximumScale: 20, - scale: 8.0, - runAnimations: false, - }, - }); + const entity = viewer.entities.add({ + name: "truck", + position: position, + orientation: orientation, + model: { + uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + minimumPixelSize: 128, + maximumScale: 20, + scale: 8.0, + runAnimations: false, + }, + }); - const threeQuartersView = { - destination: new Cesium.Cartesian3( - -1371203.1456494154, - -5508700.033950869, - 2901802.2749172337 - ), - orientation: { - heading: Cesium.Math.toRadians(67.64973594265429), - pitch: Cesium.Math.toRadians(-8.158676059409297), - roll: Cesium.Math.toRadians(359.9999987450017), - }, - maximumHeight: 100, - }; + const threeQuartersView = { + destination: new Cesium.Cartesian3( + -1371203.1456494154, + -5508700.033950869, + 2901802.2749172337 + ), + orientation: { + heading: Cesium.Math.toRadians(67.64973594265429), + pitch: Cesium.Math.toRadians(-8.158676059409297), + roll: Cesium.Math.toRadians(359.9999987450017), + }, + maximumHeight: 100, + }; - const frontView = { - destination: new Cesium.Cartesian3( - -1371214.9554156072, - -5508700.8494476415, - 2901826.794611029 - ), - orientation: { - heading: Cesium.Math.toRadians(80.5354269423926), - pitch: Cesium.Math.toRadians(-15.466062969558285), - roll: Cesium.Math.toRadians(359.9999999526579), - }, - maximumHeight: 100, - }; + const frontView = { + destination: new Cesium.Cartesian3( + -1371214.9554156072, + -5508700.8494476415, + 2901826.794611029 + ), + orientation: { + heading: Cesium.Math.toRadians(80.5354269423926), + pitch: Cesium.Math.toRadians(-15.466062969558285), + roll: Cesium.Math.toRadians(359.9999999526579), + }, + maximumHeight: 100, + }; - const topView = { - destination: new Cesium.Cartesian3( - -1371190.7755780201, - -5508732.668834588, - 2901827.2625979027 - ), - orientation: { - heading: Cesium.Math.toRadians(68.29411482061157), - pitch: Cesium.Math.toRadians(-33.97774554735345), - roll: Cesium.Math.toRadians(359.9999999298912), - }, - maximumHeight: 100, - }; + const topView = { + destination: new Cesium.Cartesian3( + -1371190.7755780201, + -5508732.668834588, + 2901827.2625979027 + ), + orientation: { + heading: Cesium.Math.toRadians(68.29411482061157), + pitch: Cesium.Math.toRadians(-33.97774554735345), + roll: Cesium.Math.toRadians(359.9999999298912), + }, + maximumHeight: 100, + }; - const upwardsView = { - destination: new Cesium.Cartesian3( - -1371052.4616855076, - -5508691.745389906, - 2901861.440673151 - ), - orientation: { - heading: Cesium.Math.toRadians(236.4536374528137), - pitch: Cesium.Math.toRadians(-1.3382025460115552), - roll: Cesium.Math.toRadians(359.9999985917282), - }, - maximumHeight: 100, - }; + const upwardsView = { + destination: new Cesium.Cartesian3( + -1371052.4616855076, + -5508691.745389906, + 2901861.440673151 + ), + orientation: { + heading: Cesium.Math.toRadians(236.4536374528137), + pitch: Cesium.Math.toRadians(-1.3382025460115552), + roll: Cesium.Math.toRadians(359.9999985917282), + }, + maximumHeight: 100, + }; - viewer.scene.camera.flyTo({ - destination: frontView.destination, - orientation: frontView.orientation, - duration: 5.0, - pitchAdjustHeight: 20, - }); - Sandcastle.addToolbarMenu( - [ - { - text: "Front reflection", - onselect: function () { - viewer.scene.camera.flyTo(frontView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T20:00:00Z" - ); + viewer.scene.camera.flyTo({ + destination: frontView.destination, + orientation: frontView.orientation, + duration: 5.0, + pitchAdjustHeight: 20, + }); + Sandcastle.addToolbarMenu( + [ + { + text: "Front reflection", + onselect: function () { + viewer.scene.camera.flyTo(frontView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T20:00:00Z" + ); + }, }, - }, - { - text: "Three quarters sunrise", - onselect: function () { - viewer.scene.camera.flyTo(threeQuartersView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T11:00:00Z" - ); + { + text: "Three quarters sunrise", + onselect: function () { + viewer.scene.camera.flyTo(threeQuartersView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T11:00:00Z" + ); + }, }, - }, - { - text: "Top reflection", - onselect: function () { - viewer.scene.camera.flyTo(topView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T12:00:00Z" - ); + { + text: "Top reflection", + onselect: function () { + viewer.scene.camera.flyTo(topView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T12:00:00Z" + ); + }, }, - }, - { - text: "Upward angle side reflection", - onselect: function () { - viewer.scene.camera.flyTo(upwardsView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T23:00:00Z" - ); + { + text: "Upward angle side reflection", + onselect: function () { + viewer.scene.camera.flyTo(upwardsView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T23:00:00Z" + ); + }, }, - }, - ], - "toolbar" - ); - //Sandcastle_End + ], + "toolbar" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index ede508d69ff..324a20fc79a 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -35,98 +35,97 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - if (!scene.clampToHeightSupported) { - window.alert( - "This browser does not support clampToHeightMostDetailed." + if (!scene.clampToHeightSupported) { + window.alert( + "This browser does not support clampToHeightMostDetailed." + ); + } + + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) ); - } - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1216411.0748779264, + -4736313.10747583, + 4081359.5125561724 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.239925103568368, + -0.4911293834802475, + 6.279849292088564 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1216411.0748779264, - -4736313.10747583, - 4081359.5125561724 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.239925103568368, - -0.4911293834802475, - 6.279849292088564 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + Sandcastle.addToolbarButton("Sample heights", function () { + sampleHeights(); + }); - Sandcastle.addToolbarButton("Sample heights", function () { - sampleHeights(); - }); + async function sampleHeights() { + viewer.entities.removeAll(); - function sampleHeights() { - viewer.entities.removeAll(); + const cartesian1 = new Cesium.Cartesian3( + 1216390.063324395, + -4736314.814479433, + 4081341.9787972216 + ); + const cartesian2 = new Cesium.Cartesian3( + 1216329.5413318684, + -4736272.029009798, + 4081407.9342479417 + ); - const cartesian1 = new Cesium.Cartesian3( - 1216390.063324395, - -4736314.814479433, - 4081341.9787972216 - ); - const cartesian2 = new Cesium.Cartesian3( - 1216329.5413318684, - -4736272.029009798, - 4081407.9342479417 - ); + const count = 30; + const cartesians = new Array(count); + for (let i = 0; i < count; ++i) { + const offset = i / (count - 1); + cartesians[i] = Cesium.Cartesian3.lerp( + cartesian1, + cartesian2, + offset, + new Cesium.Cartesian3() + ); + } - const count = 30; - const cartesians = new Array(count); - for (let i = 0; i < count; ++i) { - const offset = i / (count - 1); - cartesians[i] = Cesium.Cartesian3.lerp( - cartesian1, - cartesian2, - offset, - new Cesium.Cartesian3() + const clampedCartesians = await scene.clampToHeightMostDetailed( + cartesians ); - } - - scene - .clampToHeightMostDetailed(cartesians) - .then(function (clampedCartesians) { - for (let i = 0; i < count; ++i) { - viewer.entities.add({ - position: clampedCartesians[i], - ellipsoid: { - radii: new Cesium.Cartesian3(0.2, 0.2, 0.2), - material: Cesium.Color.RED, - }, - }); - } + for (let i = 0; i < count; ++i) { viewer.entities.add({ - polyline: { - positions: clampedCartesians, - arcType: Cesium.ArcType.NONE, - width: 2, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - }), - depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty( - { - color: Cesium.Color.YELLOW, - } - ), + position: clampedCartesians[i], + ellipsoid: { + radii: new Cesium.Cartesian3(0.2, 0.2, 0.2), + material: Cesium.Color.RED, }, }); + } + + viewer.entities.add({ + polyline: { + positions: clampedCartesians, + arcType: Cesium.ArcType.NONE, + width: 2, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + }), + depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + }), + }, }); - } - //Sandcastle_End + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index 3d46263ce50..ed3c7af6c30 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -141,215 +141,221 @@

Max delta time

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // Create a viewer that won't render a new frame unless - // updates to the scene require it to reduce overall CPU usage. - const viewer = new Cesium.Viewer("cesiumContainer", { - requestRenderMode: true, - maximumRenderTimeChange: Infinity, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - - const scene = viewer.scene; - scene.debugShowFramesPerSecond = true; - - let tileset; - - const viewModel = { - requestRenderMode: true, - showTimeOptions: false, - timeChangeEnabled: false, - maximumRenderTimeChange: 0.0, - lastRenderTime: "", - requestRender: function () { - scene.requestRender(); - }, - }; - - // Clear scene and set default view. - let handler; - function resetScene() { - viewer.trackedEntity = undefined; - viewer.dataSources.removeAll(); - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - viewer.clock.shouldAnimate = false; - handler = handler && handler.destroy(); - scene.skyBox.show = true; - scene.camera.flyHome(0.0); - scene.requestRender(); - viewModel.showTimeOptions = false; - viewModel.timeChangeEnabled = false; - viewModel.maximumRenderTimeChange = 0; - } - - // Load a tileset and set the view. - // No need to call scene.requestRender() - function loadTilesetScenario() { - resetScene(); - - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - } - - // Load an animated model and set the view. - // No need to call scene.requestRender() - // Enable and adjust maximum simulation time change to see - // animations at desired speed. - function loadModelScenario() { - resetScene(); - viewModel.timeChangeEnabled = true; - viewModel.showTimeOptions = true; - - const entity = viewer.entities.add({ - name: "Aircraft", - position: Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 5000.0 - ), - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - minimumPixelSize: 128, - maximumScale: 20000, - }, + (async () => { + // Create a viewer that won't render a new frame unless + // updates to the scene require it to reduce overall CPU usage. + const viewer = new Cesium.Viewer("cesiumContainer", { + requestRenderMode: true, + maximumRenderTimeChange: Infinity, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - viewer.trackedEntity = entity; - viewer.clock.shouldAnimate = true; - } - - // Load CZML DataSource with a model and set the trackedEntity. - // No need to call scene.requestRender() - // Enable and adjust maximum simulation time change to see - // animations at desired speed. - function loadCzmlScenario() { - resetScene(); - viewModel.showTimeOptions = true; - viewModel.timeChangeEnabled = true; - viewModel.maximumRenderTimeChange = 10.0; - - viewer.dataSources.add( - Cesium.CzmlDataSource.load("../../SampleData/simple.czml") - ); - viewer.clock.shouldAnimate = true; - } - - // Pick an entity, only rendering when needed. - function pickingScenario() { - resetScene(); - - let color = Cesium.Color.CORNFLOWERBLUE; - const colorProperty = new Cesium.CallbackProperty(function () { - return color; - }, false); - const entity = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - box: { - dimensions: new Cesium.Cartesian3(1000000.0, 1000000.0, 30000.0), - material: new Cesium.ColorMaterialProperty(colorProperty), + const scene = viewer.scene; + scene.debugShowFramesPerSecond = true; + + let tileset; + + const viewModel = { + requestRenderMode: true, + showTimeOptions: false, + timeChangeEnabled: false, + maximumRenderTimeChange: 0.0, + lastRenderTime: "", + requestRender: function () { + scene.requestRender(); }, - }); + }; + + // Clear scene and set default view. + let handler; + function resetScene() { + viewer.trackedEntity = undefined; + viewer.dataSources.removeAll(); + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + viewer.clock.shouldAnimate = false; + handler = handler && handler.destroy(); + scene.skyBox.show = true; + scene.camera.flyHome(0.0); + scene.requestRender(); + viewModel.showTimeOptions = false; + viewModel.timeChangeEnabled = false; + viewModel.maximumRenderTimeChange = 0; + } + + // Load a tileset and set the view. + // No need to call scene.requestRender() + function loadTilesetScenario() { + resetScene(); + + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + } + + // Load an animated model and set the view. + // No need to call scene.requestRender() + // Enable and adjust maximum simulation time change to see + // animations at desired speed. + function loadModelScenario() { + resetScene(); + viewModel.timeChangeEnabled = true; + viewModel.showTimeOptions = true; + + const entity = viewer.entities.add({ + name: "Aircraft", + position: Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 5000.0 + ), + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + minimumPixelSize: 128, + maximumScale: 20000, + }, + }); + + viewer.trackedEntity = entity; + viewer.clock.shouldAnimate = true; + } + + // Load CZML DataSource with a model and set the trackedEntity. + // No need to call scene.requestRender() + // Enable and adjust maximum simulation time change to see + // animations at desired speed. + function loadCzmlScenario() { + resetScene(); + viewModel.showTimeOptions = true; + viewModel.timeChangeEnabled = true; + viewModel.maximumRenderTimeChange = 10.0; + + viewer.dataSources.add( + Cesium.CzmlDataSource.load("../../SampleData/simple.czml") + ); + viewer.clock.shouldAnimate = true; + } + + // Pick an entity, only rendering when needed. + function pickingScenario() { + resetScene(); + + let color = Cesium.Color.CORNFLOWERBLUE; + const colorProperty = new Cesium.CallbackProperty(function () { + return color; + }, false); + const entity = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + box: { + dimensions: new Cesium.Cartesian3( + 1000000.0, + 1000000.0, + 30000.0 + ), + material: new Cesium.ColorMaterialProperty(colorProperty), + }, + }); - scene.requestRender(); - - // If the mouse is over the box, change its scale and color, - // then request a new render frame. - let lastPicked; - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject) && pickedObject.id === entity) { - if (Cesium.defined(lastPicked)) { - return; + scene.requestRender(); + + // If the mouse is over the box, change its scale and color, + // then request a new render frame. + let lastPicked; + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject) && pickedObject.id === entity) { + if (Cesium.defined(lastPicked)) { + return; + } + color = Cesium.Color.YELLOW; + scene.requestRender(); + lastPicked = pickedObject; + } else if (Cesium.defined(lastPicked)) { + color = Cesium.Color.CORNFLOWERBLUE; + scene.requestRender(); + lastPicked = undefined; } - color = Cesium.Color.YELLOW; - scene.requestRender(); - lastPicked = pickedObject; - } else if (Cesium.defined(lastPicked)) { - color = Cesium.Color.CORNFLOWERBLUE; - scene.requestRender(); - lastPicked = undefined; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - } - - // Changes to the scene with the API will require - // calling requestRender() on change. - function setScenePropertiesScenario() { - resetScene(); - - scene.skyBox.show = false; - scene.backgroundColor = Cesium.Color.CORNFLOWERBLUE; - scene.requestRender(); - } - - // BEGIN SANDCASTLE EXAMPLE UI SETUP - - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); - - Cesium.knockout - .getObservable(viewModel, "requestRenderMode") - .subscribe(function (value) { - scene.requestRenderMode = value; - }); + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + } - Cesium.knockout - .getObservable(viewModel, "timeChangeEnabled") - .subscribe(function (value) { - scene.maximumRenderTimeChange = value - ? viewModel.maximumRenderTimeChange - : Infinity; - }); + // Changes to the scene with the API will require + // calling requestRender() on change. + function setScenePropertiesScenario() { + resetScene(); - Cesium.knockout - .getObservable(viewModel, "maximumRenderTimeChange") - .subscribe(function (value) { - scene.maximumRenderTimeChange = value; + scene.skyBox.show = false; + scene.backgroundColor = Cesium.Color.CORNFLOWERBLUE; + scene.requestRender(); + } + + // BEGIN SANDCASTLE EXAMPLE UI SETUP + + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); + + Cesium.knockout + .getObservable(viewModel, "requestRenderMode") + .subscribe(function (value) { + scene.requestRenderMode = value; + }); + + Cesium.knockout + .getObservable(viewModel, "timeChangeEnabled") + .subscribe(function (value) { + scene.maximumRenderTimeChange = value + ? viewModel.maximumRenderTimeChange + : Infinity; + }); + + Cesium.knockout + .getObservable(viewModel, "maximumRenderTimeChange") + .subscribe(function (value) { + scene.maximumRenderTimeChange = value; + }); + + scene.postRender.addEventListener(function () { + const time = Cesium.JulianDate.toGregorianDate( + scene.lastRenderTime + ); + const value = `${time.hour}:${time.minute}:${ + time.second + }:${time.millisecond.toFixed(0)}`; + Cesium.knockout.getObservable(viewModel, "lastRenderTime")(value); }); - scene.postRender.addEventListener(function () { - const time = Cesium.JulianDate.toGregorianDate(scene.lastRenderTime); - const value = `${time.hour}:${time.minute}:${ - time.second - }:${time.millisecond.toFixed(0)}`; - Cesium.knockout.getObservable(viewModel, "lastRenderTime")(value); - }); - - const scenarios = [ - { - text: "Default view", - onselect: resetScene, - }, - { - text: "Load a 3D tileset and set the view", - onselect: loadTilesetScenario, - }, - { - text: "Mouseover picking", - onselect: pickingScenario, - }, - { - text: "Load time-dynamic CZML", - onselect: loadCzmlScenario, - }, - { - text: "Animated model", - onselect: loadModelScenario, - }, - { - text: "Scene changes with API", - onselect: setScenePropertiesScenario, - }, - ]; - - Sandcastle.addToolbarMenu(scenarios); - - //Sandcastle_End + const scenarios = [ + { + text: "Default view", + onselect: resetScene, + }, + { + text: "Load a 3D tileset and set the view", + onselect: loadTilesetScenario, + }, + { + text: "Mouseover picking", + onselect: pickingScenario, + }, + { + text: "Load time-dynamic CZML", + onselect: loadCzmlScenario, + }, + { + text: "Animated model", + onselect: loadModelScenario, + }, + { + text: "Scene changes with API", + onselect: setScenePropertiesScenario, + }, + ]; + + Sandcastle.addToolbarMenu(scenarios); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 1dc1b7469ff..185bb1315b1 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -35,271 +35,273 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shadows: true, - terrainShadows: Cesium.ShadowMode.ENABLED, - shouldAnimate: true, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - - const shadowMap = viewer.shadowMap; - shadowMap.maximumDistance = 10000.0; - - const cesiumAir = viewer.entities.add({ - name: "Cesium Air", - height: 20.0, - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - }, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shadows: true, + terrainShadows: Cesium.ShadowMode.ENABLED, + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const groundVehicle = viewer.entities.add({ - name: "Ground Vehicle", - height: 0.0, - model: { - uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + const shadowMap = viewer.shadowMap; + shadowMap.maximumDistance = 10000.0; - const cesiumMan = viewer.entities.add({ - name: "Cesium Man", - height: 0.0, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + const cesiumAir = viewer.entities.add({ + name: "Cesium Air", + height: 20.0, + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + }, + }); - const woodTower = viewer.entities.add({ - name: "Wood Tower", - height: 0.0, - model: { - uri: "../../SampleData/models/WoodTower/Wood_Tower.glb", - }, - }); + const groundVehicle = viewer.entities.add({ + name: "Ground Vehicle", + height: 0.0, + model: { + uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - const simpleCity = viewer.entities.add({ - name: "Simple City", - height: 0.0, - model: { - uri: "../../SampleData/models/ShadowTester/Shadow_Tester_4.glb", - }, - }); + const cesiumMan = viewer.entities.add({ + name: "Cesium Man", + height: 0.0, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - const boxEntity = viewer.entities.add({ - name: "Box", - height: 10.0, - box: { - dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), - material: Cesium.Color.RED, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const woodTower = viewer.entities.add({ + name: "Wood Tower", + height: 0.0, + model: { + uri: "../../SampleData/models/WoodTower/Wood_Tower.glb", + }, + }); - const checkerMaterial = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.RED.withAlpha(0.5), - oddColor: Cesium.Color.RED.withAlpha(0.0), - repeat: new Cesium.Cartesian2(5.0, 10.0), - }); + const simpleCity = viewer.entities.add({ + name: "Simple City", + height: 0.0, + model: { + uri: "../../SampleData/models/ShadowTester/Shadow_Tester_4.glb", + }, + }); - const checkerEntity = viewer.entities.add({ - name: "Checkered Box", - height: 10.0, - box: { - dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), - material: checkerMaterial, - outline: true, - outlineColor: Cesium.Color.RED, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const boxEntity = viewer.entities.add({ + name: "Box", + height: 10.0, + box: { + dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), + material: Cesium.Color.RED, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - const sphereEntity = viewer.entities.add({ - name: "Sphere", - height: 20.0, - ellipsoid: { - radii: new Cesium.Cartesian3(15.0, 15.0, 15.0), - material: Cesium.Color.BLUE.withAlpha(0.5), - slicePartitions: 24, - stackPartitions: 36, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const checkerMaterial = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.RED.withAlpha(0.5), + oddColor: Cesium.Color.RED.withAlpha(0.0), + repeat: new Cesium.Cartesian2(5.0, 10.0), + }); - const locations = { - Exton: { - longitude: -1.31968, - latitude: 0.698874, - height: 74.14210186070714, - date: 2457522.154792, - }, - HalfDome: { - longitude: -2.086267733294987, - latitude: 0.6587491773830219, - height: 2640.716312584986, - date: 2457507.247512, - }, - Everest: { - longitude: 1.517132688, - latitude: 0.4884844964, - height: 8773.17824498951, - date: 2457507.620845, - }, - PinnaclePA: { - longitude: -1.3324415110874286, - latitude: 0.6954224325279967, - height: 179.14276256241743, - date: 2457523.04162, - }, - SenecaRocks: { - longitude: -1.3851775172879768, - latitude: 0.6778211831093554, - height: 682.5893300695776, - date: 2457522.097512, - }, - Space: { - longitude: -1.31968, - latitude: 0.698874, - height: 2000000.0, - date: 2457522.154792, - }, - }; + const checkerEntity = viewer.entities.add({ + name: "Checkered Box", + height: 10.0, + box: { + dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), + material: checkerMaterial, + outline: true, + outlineColor: Cesium.Color.RED, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - let i; - const entities = viewer.entities.values; - const entitiesLength = entities.length; + const sphereEntity = viewer.entities.add({ + name: "Sphere", + height: 20.0, + ellipsoid: { + radii: new Cesium.Cartesian3(15.0, 15.0, 15.0), + material: Cesium.Color.BLUE.withAlpha(0.5), + slicePartitions: 24, + stackPartitions: 36, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - function setLocation(location) { - const longitude = location.longitude; - const latitude = location.latitude; - const height = location.height; + const locations = { + Exton: { + longitude: -1.31968, + latitude: 0.698874, + height: 74.14210186070714, + date: 2457522.154792, + }, + HalfDome: { + longitude: -2.086267733294987, + latitude: 0.6587491773830219, + height: 2640.716312584986, + date: 2457507.247512, + }, + Everest: { + longitude: 1.517132688, + latitude: 0.4884844964, + height: 8773.17824498951, + date: 2457507.620845, + }, + PinnaclePA: { + longitude: -1.3324415110874286, + latitude: 0.6954224325279967, + height: 179.14276256241743, + date: 2457523.04162, + }, + SenecaRocks: { + longitude: -1.3851775172879768, + latitude: 0.6778211831093554, + height: 682.5893300695776, + date: 2457522.097512, + }, + Space: { + longitude: -1.31968, + latitude: 0.698874, + height: 2000000.0, + date: 2457522.154792, + }, + }; - for (i = 0; i < entitiesLength; ++i) { - const entity = entities[i]; - entity.position = Cesium.Cartesian3.fromRadians( - longitude, - latitude, - height + entity.height - ); - } + let i; + const entities = viewer.entities.values; + const entitiesLength = entities.length; - viewer.clock.currentTime = new Cesium.JulianDate(location.date); - viewer.clock.multiplier = 1.0; - } + function setLocation(location) { + const longitude = location.longitude; + const latitude = location.latitude; + const height = location.height; - function setLocationFunction(location) { - return function () { - setLocation(location); - }; - } + for (i = 0; i < entitiesLength; ++i) { + const entity = entities[i]; + entity.position = Cesium.Cartesian3.fromRadians( + longitude, + latitude, + height + entity.height + ); + } - const locationToolbarOptions = []; - for (const locationName in locations) { - if (locations.hasOwnProperty(locationName)) { - const location = locations[locationName]; - locationToolbarOptions.push({ - text: locationName, - onselect: setLocationFunction(location), - }); + viewer.clock.currentTime = new Cesium.JulianDate(location.date); + viewer.clock.multiplier = 1.0; } - } - - Sandcastle.addToolbarMenu(locationToolbarOptions); - function setEntity(entity) { - for (i = 0; i < entitiesLength; ++i) { - entities[i].show = false; + function setLocationFunction(location) { + return function () { + setLocation(location); + }; } - entity.show = true; - viewer.trackedEntity = entity; - } - function setEntityFunction(entity) { - return function () { - setEntity(entity); - }; - } + const locationToolbarOptions = []; + for (const locationName in locations) { + if (locations.hasOwnProperty(locationName)) { + const location = locations[locationName]; + locationToolbarOptions.push({ + text: locationName, + onselect: setLocationFunction(location), + }); + } + } - const entityToolbarOptions = []; - for (i = 0; i < entitiesLength; ++i) { - const entity = entities[i]; - entityToolbarOptions.push({ - text: entity.name, - onselect: setEntityFunction(entity), - }); - } + Sandcastle.addToolbarMenu(locationToolbarOptions); - Sandcastle.addToolbarMenu(entityToolbarOptions); + function setEntity(entity) { + for (i = 0; i < entitiesLength; ++i) { + entities[i].show = false; + } + entity.show = true; + viewer.trackedEntity = entity; + } - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( - checked - ) { - viewer.shadows = checked; - }); + function setEntityFunction(entity) { + return function () { + setEntity(entity); + }; + } - Sandcastle.addToggleButton("Entity Shadows", true, function (checked) { - const entityShadows = checked - ? Cesium.ShadowMode.ENABLED - : Cesium.ShadowMode.DISABLED; + const entityToolbarOptions = []; for (i = 0; i < entitiesLength; ++i) { const entity = entities[i]; - const visual = entity.model || entity.box || entity.ellipsoid; - visual.shadows = entityShadows; + entityToolbarOptions.push({ + text: entity.name, + onselect: setEntityFunction(entity), + }); } - }); - Sandcastle.addToggleButton( - "Terrain Shadows", - viewer.terrainShadows === Cesium.ShadowMode.ENABLED, - function (checked) { - viewer.terrainShadows = checked + Sandcastle.addToolbarMenu(entityToolbarOptions); + + Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( + checked + ) { + viewer.shadows = checked; + }); + + Sandcastle.addToggleButton("Entity Shadows", true, function ( + checked + ) { + const entityShadows = checked ? Cesium.ShadowMode.ENABLED : Cesium.ShadowMode.DISABLED; - } - ); + for (i = 0; i < entitiesLength; ++i) { + const entity = entities[i]; + const visual = entity.model || entity.box || entity.ellipsoid; + visual.shadows = entityShadows; + } + }); - Sandcastle.addToggleButton( - "Soft Shadows", - shadowMap.softShadows, - function (checked) { - shadowMap.softShadows = checked; - } - ); + Sandcastle.addToggleButton( + "Terrain Shadows", + viewer.terrainShadows === Cesium.ShadowMode.ENABLED, + function (checked) { + viewer.terrainShadows = checked + ? Cesium.ShadowMode.ENABLED + : Cesium.ShadowMode.DISABLED; + } + ); + + Sandcastle.addToggleButton( + "Soft Shadows", + shadowMap.softShadows, + function (checked) { + shadowMap.softShadows = checked; + } + ); - Sandcastle.addToolbarMenu([ - { - text: "Size : 2048", - onselect: function () { - shadowMap.size = 2048; + Sandcastle.addToolbarMenu([ + { + text: "Size : 2048", + onselect: function () { + shadowMap.size = 2048; + }, }, - }, - { - text: "Size : 1024", - onselect: function () { - shadowMap.size = 1024; + { + text: "Size : 1024", + onselect: function () { + shadowMap.size = 1024; + }, }, - }, - { - text: "Size : 512", - onselect: function () { - shadowMap.size = 512; + { + text: "Size : 512", + onselect: function () { + shadowMap.size = 512; + }, }, - }, - { - text: "Size : 256", - onselect: function () { - shadowMap.size = 256; + { + text: "Size : 256", + onselect: function () { + shadowMap.size = 256; + }, }, - }, - ]); - - setLocation(locations.Exton); - setEntity(cesiumAir); + ]); - //Sandcastle_End + setLocation(locations.Exton); + setEntity(cesiumAir); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index c54baab9d4a..31a3e5a8740 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -61,347 +61,355 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // Use clipping planes to selectively hide parts of the globe surface. + (async () => { + // Use clipping planes to selectively hide parts of the globe surface. + const viewer = new Cesium.Viewer("cesiumContainer", { + skyAtmosphere: false, + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + scene3DOnly: true, + }); + const globe = viewer.scene.globe; - const viewer = new Cesium.Viewer("cesiumContainer", { - skyAtmosphere: false, - shouldAnimate: true, - terrainProvider: Cesium.createWorldTerrainAsync(), - scene3DOnly: true, - }); - const globe = viewer.scene.globe; + const exampleTypes = [ + "Cesium Man", + "St. Helens", + "Grand Canyon Isolated", + ]; + const viewModel = { + exampleTypes: exampleTypes, + currentExampleType: exampleTypes[0], + clippingPlanesEnabled: true, + edgeStylingEnabled: true, + }; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); - const exampleTypes = [ - "Cesium Man", - "St. Helens", - "Grand Canyon Isolated", - ]; - const viewModel = { - exampleTypes: exampleTypes, - currentExampleType: exampleTypes[0], - clippingPlanesEnabled: true, - edgeStylingEnabled: true, - }; - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); + // For tracking state when switching exampleTypes + let clippingPlanesEnabled = true; + let edgeStylingEnabled = true; - // For tracking state when switching exampleTypes - let clippingPlanesEnabled = true; - let edgeStylingEnabled = true; + let tileset; - let tileset; + loadCesiumMan(); - loadCesiumMan(); + function reset() { + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + } - function reset() { - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - } + function loadCesiumMan() { + const position = Cesium.Cartesian3.fromRadians( + -2.0862979473351286, + 0.6586620013036164, + 1400.0 + ); - function loadCesiumMan() { - const position = Cesium.Cartesian3.fromRadians( - -2.0862979473351286, - 0.6586620013036164, - 1400.0 - ); + const entity = viewer.entities.add({ + position: position, + box: { + dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), + material: Cesium.Color.WHITE.withAlpha(0.3), + outline: true, + outlineColor: Cesium.Color.WHITE, + }, + }); - const entity = viewer.entities.add({ - position: position, - box: { - dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), - material: Cesium.Color.WHITE.withAlpha(0.3), - outline: true, - outlineColor: Cesium.Color.WHITE, - }, - }); + viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + maximumScale: 800, + }, + }); - viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - maximumScale: 800, - }, - }); + globe.depthTestAgainstTerrain = true; + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + -700.0 + ), + ], + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - globe.depthTestAgainstTerrain = true; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - -700.0 + viewer.trackedEntity = entity; + } + + function loadStHelens() { + // Create clipping planes for polygon around area to be clipped. + const points = [ + new Cesium.Cartesian3( + -2358434.3501556474, + -3743554.5012105294, + 4581080.771684084 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2357886.4482675144, + -3744467.562778789, + 4581020.9199767085 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2357299.84353055, + -3744954.0879047974, + 4581080.992360969 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2356412.05169956, + -3745385.3013702347, + 4580893.4737207815 ), - ], - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; - - viewer.trackedEntity = entity; - } - - function loadStHelens() { - // Create clipping planes for polygon around area to be clipped. - const points = [ - new Cesium.Cartesian3( - -2358434.3501556474, - -3743554.5012105294, - 4581080.771684084 - ), - new Cesium.Cartesian3( - -2357886.4482675144, - -3744467.562778789, - 4581020.9199767085 - ), - new Cesium.Cartesian3( - -2357299.84353055, - -3744954.0879047974, - 4581080.992360969 - ), - new Cesium.Cartesian3( - -2356412.05169956, - -3745385.3013702347, - 4580893.4737207815 - ), - new Cesium.Cartesian3( - -2355472.889436636, - -3745256.5725702164, - 4581252.3128526565 - ), - new Cesium.Cartesian3( - -2354385.7458722834, - -3744319.3823686405, - 4582372.770031389 - ), - new Cesium.Cartesian3( - -2353758.788158616, - -3743051.0128084184, - 4583356.453176038 - ), - new Cesium.Cartesian3( - -2353663.8128999653, - -3741847.9126874236, - 4584079.428665509 - ), - new Cesium.Cartesian3( - -2354213.667592133, - -3740784.50946316, - 4584502.428203525 - ), - new Cesium.Cartesian3( - -2355596.239450013, - -3739901.0226732804, - 4584515.9652557485 - ), - new Cesium.Cartesian3( - -2356942.4170108805, - -3740342.454698685, - 4583686.690694482 - ), - new Cesium.Cartesian3( - -2357529.554838029, - -3740766.995076834, - 4583145.055348843 - ), - new Cesium.Cartesian3( - -2358106.017822064, - -3741439.438418052, - 4582452.293605261 - ), - new Cesium.Cartesian3( - -2358539.5426236596, - -3742680.720902901, - 4581692.0260975715 - ), - ]; - - const pointsLength = points.length; - - // Create center points for each clipping plane - const clippingPlanes = []; - for (let i = 0; i < pointsLength; ++i) { - const nextIndex = (i + 1) % pointsLength; - let midpoint = Cesium.Cartesian3.add( - points[i], - points[nextIndex], - new Cesium.Cartesian3() - ); - midpoint = Cesium.Cartesian3.multiplyByScalar( - midpoint, - 0.5, - midpoint - ); - - const up = Cesium.Cartesian3.normalize( - midpoint, - new Cesium.Cartesian3() - ); - let right = Cesium.Cartesian3.subtract( - points[nextIndex], - midpoint, - new Cesium.Cartesian3() - ); - right = Cesium.Cartesian3.normalize(right, right); - - let normal = Cesium.Cartesian3.cross( - right, - up, - new Cesium.Cartesian3() - ); - normal = Cesium.Cartesian3.normalize(normal, normal); + new Cesium.Cartesian3( + -2355472.889436636, + -3745256.5725702164, + 4581252.3128526565 + ), + new Cesium.Cartesian3( + -2354385.7458722834, + -3744319.3823686405, + 4582372.770031389 + ), + new Cesium.Cartesian3( + -2353758.788158616, + -3743051.0128084184, + 4583356.453176038 + ), + new Cesium.Cartesian3( + -2353663.8128999653, + -3741847.9126874236, + 4584079.428665509 + ), + new Cesium.Cartesian3( + -2354213.667592133, + -3740784.50946316, + 4584502.428203525 + ), + new Cesium.Cartesian3( + -2355596.239450013, + -3739901.0226732804, + 4584515.9652557485 + ), + new Cesium.Cartesian3( + -2356942.4170108805, + -3740342.454698685, + 4583686.690694482 + ), + new Cesium.Cartesian3( + -2357529.554838029, + -3740766.995076834, + 4583145.055348843 + ), + new Cesium.Cartesian3( + -2358106.017822064, + -3741439.438418052, + 4582452.293605261 + ), + new Cesium.Cartesian3( + -2358539.5426236596, + -3742680.720902901, + 4581692.0260975715 + ), + ]; - // Compute distance by pretending the plane is at the origin - const originCenteredPlane = new Cesium.Plane(normal, 0.0); - const distance = Cesium.Plane.getPointDistance( - originCenteredPlane, - midpoint - ); + const pointsLength = points.length; - clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); - } - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - planes: clippingPlanes, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; - - // Load tileset - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - return tileset.readyPromise - .then(function () { - // Adjust height so tileset is in terrain - const cartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center + // Create center points for each clipping plane + const clippingPlanes = []; + for (let i = 0; i < pointsLength; ++i) { + const nextIndex = (i + 1) % pointsLength; + let midpoint = Cesium.Cartesian3.add( + points[i], + points[nextIndex], + new Cesium.Cartesian3() ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 + midpoint = Cesium.Cartesian3.multiplyByScalar( + midpoint, + 0.5, + midpoint ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - -20.0 + + const up = Cesium.Cartesian3.normalize( + midpoint, + new Cesium.Cartesian3() ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, + let right = Cesium.Cartesian3.subtract( + points[nextIndex], + midpoint, new Cesium.Cartesian3() ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + right = Cesium.Cartesian3.normalize(right, right); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgb(207, 255, 207)", - }); + let normal = Cesium.Cartesian3.cross( + right, + up, + new Cesium.Cartesian3() + ); + normal = Cesium.Cartesian3.normalize(normal, normal); - viewer.scene.primitives.add(tileset); + // Compute distance by pretending the plane is at the origin + const originCenteredPlane = new Cesium.Plane(normal, 0.0); + const distance = Cesium.Plane.getPointDistance( + originCenteredPlane, + midpoint + ); - const boundingSphere = tileset.boundingSphere; + clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); + } + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + planes: clippingPlanes, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; + // Load tileset + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), }); - } + return tileset.readyPromise + .then(function () { + // Adjust height so tileset is in terrain + const cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + -20.0 + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation( + translation + ); - function loadGrandCanyon() { - // Pick a position at the Grand Canyon - const position = Cesium.Cartographic.toCartesian( - new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) - ); - const distance = 3000.0; - const boundingSphere = new Cesium.BoundingSphere(position, distance); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgb(207, 255, 207)", + }); - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - distance - ), - ], - unionClippingRegions: true, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = false; - globe.showSkirts = false; + viewer.scene.primitives.add(tileset); - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + const boundingSphere = tileset.boundingSphere; - Cesium.knockout - .getObservable(viewModel, "clippingPlanesEnabled") - .subscribe(function (value) { - globe.clippingPlanes.enabled = value; - clippingPlanesEnabled = value; - }); + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }) + .catch(function (error) { + throw error; + }); + } - Cesium.knockout - .getObservable(viewModel, "edgeStylingEnabled") - .subscribe(function (value) { - edgeStylingEnabled = value; - globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; - }); + function loadGrandCanyon() { + // Pick a position at the Grand Canyon + const position = Cesium.Cartographic.toCartesian( + new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) + ); + const distance = 3000.0; + const boundingSphere = new Cesium.BoundingSphere( + position, + distance + ); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === exampleTypes[0]) { - loadCesiumMan(); - } else if (newValue === exampleTypes[1]) { - loadStHelens(); - } else if (newValue === exampleTypes[2]) { - loadGrandCanyon(); - } - }); + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + distance + ), + ], + unionClippingRegions: true, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = false; + globe.showSkirts = false; - //Sandcastle_End + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange( + 0.5, + -0.5, + boundingSphere.radius * 5.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + + Cesium.knockout + .getObservable(viewModel, "clippingPlanesEnabled") + .subscribe(function (value) { + globe.clippingPlanes.enabled = value; + clippingPlanesEnabled = value; + }); + + Cesium.knockout + .getObservable(viewModel, "edgeStylingEnabled") + .subscribe(function (value) { + edgeStylingEnabled = value; + globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; + }); + + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === exampleTypes[0]) { + loadCesiumMan(); + } else if (newValue === exampleTypes[1]) { + loadStHelens(); + } else if (newValue === exampleTypes[2]) { + loadGrandCanyon(); + } + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index 62d4665ad36..a3c7936fbae 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -76,122 +76,123 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; - globe.terrainExaggeration = 2.0; - globe.terrainExaggerationRelativeHeight = 2400.0; + const scene = viewer.scene; + const globe = scene.globe; + globe.terrainExaggeration = 2.0; + globe.terrainExaggerationRelativeHeight = 2400.0; - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 336567.0354790703, - 5664688.047602498, - 2923204.3566963132 - ), - orientation: new Cesium.HeadingPitchRoll( - 1.2273281382639265, - -0.32239612370237514, - 0.0027207329018610338 - ), - }); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 336567.0354790703, + 5664688.047602498, + 2923204.3566963132 + ), + orientation: new Cesium.HeadingPitchRoll( + 1.2273281382639265, + -0.32239612370237514, + 0.0027207329018610338 + ), + }); - viewer.entities.add({ - position: new Cesium.Cartesian3( - 314557.3531714575, - 5659723.771882165, - 2923538.5417330978 - ), - ellipsoid: { - radii: new Cesium.Cartesian3(400.0, 400.0, 400.0), - material: Cesium.Color.RED, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + viewer.entities.add({ + position: new Cesium.Cartesian3( + 314557.3531714575, + 5659723.771882165, + 2923538.5417330978 + ), + ellipsoid: { + radii: new Cesium.Cartesian3(400.0, 400.0, 400.0), + material: Cesium.Color.RED, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - let visualizeRelativeHeight = true; + let visualizeRelativeHeight = true; - function updateMaterial() { - if (visualizeRelativeHeight) { - const height = globe.terrainExaggerationRelativeHeight; - const exaggeration = globe.terrainExaggeration; - const alpha = Math.min(1.0, exaggeration * 0.25); - const layer = { - extendUpwards: true, - extendDownwards: true, - entries: [ - { - height: height + 100.0, - color: new Cesium.Color(0.0, 1.0, 0.0, alpha * 0.25), - }, - { - height: height + 50.0, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), - }, - { - height: height, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: height - 50.0, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), - }, - { - height: height - 100.0, - color: new Cesium.Color(1.0, 0.0, 0.0, alpha * 0.25), - }, - ], - }; - scene.globe.material = Cesium.createElevationBandMaterial({ - scene: scene, - layers: [layer], - }); - } else { - scene.globe.material = undefined; + function updateMaterial() { + if (visualizeRelativeHeight) { + const height = globe.terrainExaggerationRelativeHeight; + const exaggeration = globe.terrainExaggeration; + const alpha = Math.min(1.0, exaggeration * 0.25); + const layer = { + extendUpwards: true, + extendDownwards: true, + entries: [ + { + height: height + 100.0, + color: new Cesium.Color(0.0, 1.0, 0.0, alpha * 0.25), + }, + { + height: height + 50.0, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), + }, + { + height: height, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: height - 50.0, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), + }, + { + height: height - 100.0, + color: new Cesium.Color(1.0, 0.0, 0.0, alpha * 0.25), + }, + ], + }; + scene.globe.material = Cesium.createElevationBandMaterial({ + scene: scene, + layers: [layer], + }); + } else { + scene.globe.material = undefined; + } } - } - updateMaterial(); - - const viewModel = { - exaggeration: globe.terrainExaggeration, - relativeHeight: globe.terrainExaggerationRelativeHeight, - }; - - function updateExaggeration() { - globe.terrainExaggeration = Number(viewModel.exaggeration); - globe.terrainExaggerationRelativeHeight = Number( - viewModel.relativeHeight - ); updateMaterial(); - } - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateExaggeration); - } - } + const viewModel = { + exaggeration: globe.terrainExaggeration, + relativeHeight: globe.terrainExaggerationRelativeHeight, + }; - Sandcastle.addToggleButton( - "Visualize Relative Height", - visualizeRelativeHeight, - function (checked) { - visualizeRelativeHeight = checked; + function updateExaggeration() { + globe.terrainExaggeration = Number(viewModel.exaggeration); + globe.terrainExaggerationRelativeHeight = Number( + viewModel.relativeHeight + ); updateMaterial(); } - ); - Sandcastle.addToolbarButton("Remove Exaggeration", function () { - viewModel.exaggeration = 1.0; - viewModel.relativeHeight = 0.0; - }); - //Sandcastle_End + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateExaggeration); + } + } + + Sandcastle.addToggleButton( + "Visualize Relative Height", + visualizeRelativeHeight, + function (checked) { + visualizeRelativeHeight = checked; + updateMaterial(); + } + ); + + Sandcastle.addToolbarButton("Remove Exaggeration", function () { + viewModel.exaggeration = 1.0; + viewModel.relativeHeight = 0.0; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index 4deb80a74b0..fe2218e6cf4 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -39,306 +39,312 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - // set lighting to true - viewer.scene.globe.enableLighting = true; + // set lighting to true + viewer.scene.globe.enableLighting = true; - // setup alternative terrain providers - const ellipsoidProvider = new Cesium.EllipsoidTerrainProvider(); + // setup alternative terrain providers + const ellipsoidProvider = new Cesium.EllipsoidTerrainProvider(); - // Sine wave - const customHeightmapWidth = 32; - const customHeightmapHeight = 32; - const customHeightmapProvider = new Cesium.CustomHeightmapTerrainProvider( - { - width: customHeightmapWidth, - height: customHeightmapHeight, - callback: function (x, y, level) { - const width = customHeightmapWidth; - const height = customHeightmapHeight; - const buffer = new Float32Array(width * height); + // Sine wave + const customHeightmapWidth = 32; + const customHeightmapHeight = 32; + const customHeightmapProvider = new Cesium.CustomHeightmapTerrainProvider( + { + width: customHeightmapWidth, + height: customHeightmapHeight, + callback: function (x, y, level) { + const width = customHeightmapWidth; + const height = customHeightmapHeight; + const buffer = new Float32Array(width * height); - for (let yy = 0; yy < height; yy++) { - for (let xx = 0; xx < width; xx++) { - const u = (x + xx / (width - 1)) / Math.pow(2, level); - const v = (y + yy / (height - 1)) / Math.pow(2, level); + for (let yy = 0; yy < height; yy++) { + for (let xx = 0; xx < width; xx++) { + const u = (x + xx / (width - 1)) / Math.pow(2, level); + const v = (y + yy / (height - 1)) / Math.pow(2, level); - const heightValue = 4000 * (Math.sin(8000 * v) * 0.5 + 0.5); + const heightValue = 4000 * (Math.sin(8000 * v) * 0.5 + 0.5); - const index = yy * width + xx; - buffer[index] = heightValue; + const index = yy * width + xx; + buffer[index] = heightValue; + } } - } - return buffer; - }, - } - ); + return buffer; + }, + } + ); - Sandcastle.addToolbarMenu( - [ - { - text: "CesiumTerrainProvider - Cesium World Terrain", - onselect: async function () { - const provider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - viewer.terrainProvider = provider; - viewer.scene.globe.enableLighting = true; + Sandcastle.addToolbarMenu( + [ + { + text: "CesiumTerrainProvider - Cesium World Terrain", + onselect: async function () { + const provider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + viewer.terrainProvider = provider; + viewer.scene.globe.enableLighting = true; + }, }, - }, - { - text: "CesiumTerrainProvider - Cesium World Terrain - no effects", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + { + text: + "CesiumTerrainProvider - Cesium World Terrain - no effects", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + }, }, - }, - { - text: "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, - }); - viewer.scene.globe.enableLighting = true; + { + text: + "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync( + { + requestVertexNormals: true, + } + ); + viewer.scene.globe.enableLighting = true; + }, }, - }, - { - text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - }); + { + text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync( + { + requestWaterMask: true, + } + ); + }, }, - }, - { - text: "EllipsoidTerrainProvider", - onselect: function () { - viewer.terrainProvider = ellipsoidProvider; + { + text: "EllipsoidTerrainProvider", + onselect: function () { + viewer.terrainProvider = ellipsoidProvider; + }, }, - }, - { - text: "CustomHeightmapTerrainProvider", - onselect: function () { - viewer.terrainProvider = customHeightmapProvider; + { + text: "CustomHeightmapTerrainProvider", + onselect: function () { + viewer.terrainProvider = customHeightmapProvider; + }, }, - }, - { - text: "VRTheWorldTerrainProvider", - onselect: async function () { - const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl( - "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", - { - credit: "Terrain data courtesy VT MÄK", - } - ); - viewer.terrainProvider = provider; + { + text: "VRTheWorldTerrainProvider", + onselect: async function () { + const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl( + "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", + { + credit: "Terrain data courtesy VT MÄK", + } + ); + viewer.terrainProvider = provider; + }, }, - }, - { - text: "ArcGISTerrainProvider", - onselect: async function () { - const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ); - viewer.terrainProvider = provider; + { + text: "ArcGISTerrainProvider", + onselect: async function () { + const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ); + viewer.terrainProvider = provider; + }, }, - }, - ], - "terrainMenu" - ); + ], + "terrainMenu" + ); - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Mount Everest", - onselect: function () { - lookAtMtEverest(); + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Mount Everest", + onselect: function () { + lookAtMtEverest(); + }, }, - }, - { - text: "Half Dome", - onselect: function () { - const target = new Cesium.Cartesian3( - -2489625.0836225147, - -4393941.44443024, - 3882535.9454173897 - ); - const offset = new Cesium.Cartesian3( - -6857.40902037546, - 412.3284835694358, - 2147.5545426812023 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + { + text: "Half Dome", + onselect: function () { + const target = new Cesium.Cartesian3( + -2489625.0836225147, + -4393941.44443024, + 3882535.9454173897 + ); + const offset = new Cesium.Cartesian3( + -6857.40902037546, + 412.3284835694358, + 2147.5545426812023 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }, }, - }, - { - text: "San Francisco Bay", - onselect: function () { - const target = new Cesium.Cartesian3( - -2708814.85583248, - -4254159.450845907, - 3891403.9457429945 - ); - const offset = new Cesium.Cartesian3( - 70642.66030209465, - -31661.517948317807, - 35505.179997143336 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + { + text: "San Francisco Bay", + onselect: function () { + const target = new Cesium.Cartesian3( + -2708814.85583248, + -4254159.450845907, + 3891403.9457429945 + ); + const offset = new Cesium.Cartesian3( + 70642.66030209465, + -31661.517948317807, + 35505.179997143336 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }, }, - }, - ], - "zoomButtons" - ); - - let terrainSamplePositions; - - function lookAtMtEverest() { - const target = new Cesium.Cartesian3( - 300770.50872389384, - 5634912.131394585, - 2978152.2865545116 + ], + "zoomButtons" ); - const offset = new Cesium.Cartesian3( - 6344.974098678562, - -793.3419798081741, - 2499.9508860763162 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } - function sampleTerrainSuccess(terrainSamplePositions) { - const ellipsoid = Cesium.Ellipsoid.WGS84; + let terrainSamplePositions; - //By default, Cesium does not obsure geometry - //behind terrain. Setting this flag enables that. - viewer.scene.globe.depthTestAgainstTerrain = true; + function lookAtMtEverest() { + const target = new Cesium.Cartesian3( + 300770.50872389384, + 5634912.131394585, + 2978152.2865545116 + ); + const offset = new Cesium.Cartesian3( + 6344.974098678562, + -793.3419798081741, + 2499.9508860763162 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - viewer.entities.suspendEvents(); - viewer.entities.removeAll(); + function sampleTerrainSuccess(terrainSamplePositions) { + const ellipsoid = Cesium.Ellipsoid.WGS84; - for (let i = 0; i < terrainSamplePositions.length; ++i) { - const position = terrainSamplePositions[i]; + //By default, Cesium does not obsure geometry + //behind terrain. Setting this flag enables that. + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.entities.add({ - name: position.height.toFixed(1), - position: ellipsoid.cartographicToCartesian(position), - billboard: { - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - scale: 0.7, - image: "../images/facility.gif", - }, - label: { - text: position.height.toFixed(1), - font: "10pt monospace", - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - pixelOffset: new Cesium.Cartesian2(0, -14), - fillColor: Cesium.Color.BLACK, - outlineColor: Cesium.Color.BLACK, - showBackground: true, - backgroundColor: new Cesium.Color(0.9, 0.9, 0.9, 0.7), - backgroundPadding: new Cesium.Cartesian2(4, 3), - }, - }); - } - viewer.entities.resumeEvents(); - } + viewer.entities.suspendEvents(); + viewer.entities.removeAll(); - function createGrid(rectangleHalfSize) { - const gridWidth = 41; - const gridHeight = 41; - const everestLatitude = Cesium.Math.toRadians(27.988257); - const everestLongitude = Cesium.Math.toRadians(86.925145); - const e = new Cesium.Rectangle( - everestLongitude - rectangleHalfSize, - everestLatitude - rectangleHalfSize, - everestLongitude + rectangleHalfSize, - everestLatitude + rectangleHalfSize - ); - const terrainSamplePositions = []; - for (let y = 0; y < gridHeight; ++y) { - for (let x = 0; x < gridWidth; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridWidth - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridHeight - 1) - ); - const position = new Cesium.Cartographic(longitude, latitude); - terrainSamplePositions.push(position); - } - } - return terrainSamplePositions; - } + for (let i = 0; i < terrainSamplePositions.length; ++i) { + const position = terrainSamplePositions[i]; - Sandcastle.addToggleButton( - "Enable Lighting", - viewer.scene.globe.enableLighting, - function (checked) { - viewer.scene.globe.enableLighting = checked; + viewer.entities.add({ + name: position.height.toFixed(1), + position: ellipsoid.cartographicToCartesian(position), + billboard: { + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + scale: 0.7, + image: "../images/facility.gif", + }, + label: { + text: position.height.toFixed(1), + font: "10pt monospace", + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + pixelOffset: new Cesium.Cartesian2(0, -14), + fillColor: Cesium.Color.BLACK, + outlineColor: Cesium.Color.BLACK, + showBackground: true, + backgroundColor: new Cesium.Color(0.9, 0.9, 0.9, 0.7), + backgroundPadding: new Cesium.Cartesian2(4, 3), + }, + }); + } + viewer.entities.resumeEvents(); } - ); - Sandcastle.addToggleButton( - "Enable fog", - viewer.scene.fog.enabled, - function (checked) { - viewer.scene.fog.enabled = checked; + function createGrid(rectangleHalfSize) { + const gridWidth = 41; + const gridHeight = 41; + const everestLatitude = Cesium.Math.toRadians(27.988257); + const everestLongitude = Cesium.Math.toRadians(86.925145); + const e = new Cesium.Rectangle( + everestLongitude - rectangleHalfSize, + everestLatitude - rectangleHalfSize, + everestLongitude + rectangleHalfSize, + everestLatitude + rectangleHalfSize + ); + const terrainSamplePositions = []; + for (let y = 0; y < gridHeight; ++y) { + for (let x = 0; x < gridWidth; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridWidth - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridHeight - 1) + ); + const position = new Cesium.Cartographic(longitude, latitude); + terrainSamplePositions.push(position); + } + } + return terrainSamplePositions; } - ); - Sandcastle.addToolbarButton( - "Sample Everest Terrain at Level 9", - function () { - const terrainSamplePositions = createGrid(0.005); - Promise.resolve( - Cesium.sampleTerrain( - viewer.terrainProvider, - 9, - terrainSamplePositions - ) - ).then(sampleTerrainSuccess); - lookAtMtEverest(); - }, - "sampleButtons" - ); + Sandcastle.addToggleButton( + "Enable Lighting", + viewer.scene.globe.enableLighting, + function (checked) { + viewer.scene.globe.enableLighting = checked; + } + ); - Sandcastle.addToolbarButton( - "Sample Most Detailed Everest Terrain", - function () { - if (!Cesium.defined(viewer.terrainProvider.availability)) { - window.alert( - "sampleTerrainMostDetailed is not supported for the selected terrain provider" - ); - return; + Sandcastle.addToggleButton( + "Enable fog", + viewer.scene.fog.enabled, + function (checked) { + viewer.scene.fog.enabled = checked; } - const terrainSamplePositions = createGrid(0.0005); - Promise.resolve( - Cesium.sampleTerrainMostDetailed( - viewer.terrainProvider, - terrainSamplePositions - ) - ).then(sampleTerrainSuccess); - lookAtMtEverest(); - }, - "sampleButtons" - ); + ); - //Sandcastle_End + Sandcastle.addToolbarButton( + "Sample Everest Terrain at Level 9", + function () { + const terrainSamplePositions = createGrid(0.005); + Promise.resolve( + Cesium.sampleTerrain( + viewer.terrainProvider, + 9, + terrainSamplePositions + ) + ).then(sampleTerrainSuccess); + lookAtMtEverest(); + }, + "sampleButtons" + ); + + Sandcastle.addToolbarButton( + "Sample Most Detailed Everest Terrain", + function () { + if (!Cesium.defined(viewer.terrainProvider.availability)) { + window.alert( + "sampleTerrainMostDetailed is not supported for the selected terrain provider" + ); + return; + } + const terrainSamplePositions = createGrid(0.0005); + Promise.resolve( + Cesium.sampleTerrainMostDetailed( + viewer.terrainProvider, + terrainSamplePositions + ) + ).then(sampleTerrainSuccess); + lookAtMtEverest(); + }, + "sampleButtons" + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 9c3acf786c6..85e0580bc03 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -37,133 +37,137 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + viewer.scene.globe.depthTestAgainstTerrain = true; - const ellipsoid = viewer.scene.globe.ellipsoid; - const billboardCollection = viewer.scene.primitives.add( - new Cesium.BillboardCollection({ - scene: viewer.scene, - }) - ); + const ellipsoid = viewer.scene.globe.ellipsoid; + const billboardCollection = viewer.scene.primitives.add( + new Cesium.BillboardCollection({ + scene: viewer.scene, + }) + ); - // seneca - const centerLongitude = -1.385205433269729; - const centerLatitude = 0.6777926580888163; + // seneca + const centerLongitude = -1.385205433269729; + const centerLatitude = 0.6777926580888163; - const gridWidth = Math.floor(Math.random() * 100.0); - const gridHeight = Math.floor(Math.random() * 100.0); - const rectangleHalfSize = 0.0005; + const gridWidth = Math.floor(Math.random() * 100.0); + const gridHeight = Math.floor(Math.random() * 100.0); + const rectangleHalfSize = 0.0005; - const e = new Cesium.Rectangle( - centerLongitude - rectangleHalfSize, - centerLatitude - rectangleHalfSize, - centerLongitude + rectangleHalfSize, - centerLatitude + rectangleHalfSize - ); + const e = new Cesium.Rectangle( + centerLongitude - rectangleHalfSize, + centerLatitude - rectangleHalfSize, + centerLongitude + rectangleHalfSize, + centerLatitude + rectangleHalfSize + ); - for (let y = 0; y < gridHeight; ++y) { - for (let x = 0; x < gridWidth; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridWidth - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridHeight - 1) - ); - const position = new Cesium.Cartographic(longitude, latitude); + for (let y = 0; y < gridHeight; ++y) { + for (let x = 0; x < gridWidth; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridWidth - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridHeight - 1) + ); + const position = new Cesium.Cartographic(longitude, latitude); - billboardCollection.add({ - position: ellipsoid.cartographicToCartesian(position), - image: "../images/facility.gif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }); + billboardCollection.add({ + position: ellipsoid.cartographicToCartesian(position), + image: "../images/facility.gif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }); + } } - } - let billboard; + let billboard; - Sandcastle.addToolbarButton("Add billboard", function () { - if (!Cesium.defined(billboard)) { - billboard = billboardCollection.add({ - position: ellipsoid.cartographicToCartesian( - new Cesium.Cartographic(centerLongitude, centerLatitude, 1000.0) - ), - image: "../images/Cesium_Logo_overlay.png", - scale: 0.7, - heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, - }); - } - }); + Sandcastle.addToolbarButton("Add billboard", function () { + if (!Cesium.defined(billboard)) { + billboard = billboardCollection.add({ + position: ellipsoid.cartographicToCartesian( + new Cesium.Cartographic( + centerLongitude, + centerLatitude, + 1000.0 + ) + ), + image: "../images/Cesium_Logo_overlay.png", + scale: 0.7, + heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, + }); + } + }); - Sandcastle.addToolbarButton("Remove billboard", function () { - if (Cesium.defined(billboard)) { - billboardCollection.remove(billboard); - billboard = undefined; - } - }); + Sandcastle.addToolbarButton("Remove billboard", function () { + if (Cesium.defined(billboard)) { + billboardCollection.remove(billboard); + billboard = undefined; + } + }); - Sandcastle.addToolbarMenu([ - { - text: "Relative to ground", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = - Cesium.HeightReference.RELATIVE_TO_GROUND; - } + Sandcastle.addToolbarMenu([ + { + text: "Relative to ground", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = + Cesium.HeightReference.RELATIVE_TO_GROUND; + } + }, }, - }, - { - text: "Clamp to ground", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = - Cesium.HeightReference.CLAMP_TO_GROUND; - } + { + text: "Clamp to ground", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = + Cesium.HeightReference.CLAMP_TO_GROUND; + } + }, }, - }, - { - text: "None", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = Cesium.HeightReference.NONE; - } + { + text: "None", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = Cesium.HeightReference.NONE; + } + }, }, - }, - ]); + ]); - const lonGran = 0.00005; + const lonGran = 0.00005; - Sandcastle.addToolbarButton("Increase longitude", function () { - if (Cesium.defined(billboard)) { - const cartographic = ellipsoid.cartesianToCartographic( - billboard.position - ); - cartographic.longitude += lonGran; - billboard.position = ellipsoid.cartographicToCartesian( - cartographic - ); - } - }); - - Sandcastle.addToolbarButton("Decrease longitude", function () { - if (Cesium.defined(billboard)) { - const cartographic = ellipsoid.cartesianToCartographic( - billboard.position - ); - cartographic.longitude -= lonGran; - billboard.position = ellipsoid.cartographicToCartesian( - cartographic - ); - } - }); + Sandcastle.addToolbarButton("Increase longitude", function () { + if (Cesium.defined(billboard)) { + const cartographic = ellipsoid.cartesianToCartographic( + billboard.position + ); + cartographic.longitude += lonGran; + billboard.position = ellipsoid.cartographicToCartesian( + cartographic + ); + } + }); - //Sandcastle_End + Sandcastle.addToolbarButton("Decrease longitude", function () { + if (Cesium.defined(billboard)) { + const cartographic = ellipsoid.cartesianToCartographic( + billboard.position + ); + cartographic.longitude -= lonGran; + billboard.position = ellipsoid.cartographicToCartesian( + cartographic + ); + } + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index 1f91ae7496f..dafe938f95a 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -37,197 +37,201 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const context = scene.context; + const scene = viewer.scene; + const context = scene.context; - scene.debugShowFramesPerSecond = true; + scene.debugShowFramesPerSecond = true; - const ellipsoid = scene.globe.ellipsoid; - let billboardCollection; - let instancingEnabled = true; - const instancedArraysExtension = context._instancedArrays; - let billboardCount = 100489; - let scale = 1.0; + const ellipsoid = scene.globe.ellipsoid; + let billboardCollection; + let instancingEnabled = true; + const instancedArraysExtension = context._instancedArrays; + let billboardCount = 100489; + let scale = 1.0; - // seneca - const centerLongitude = -1.385205433269729; - const centerLatitude = 0.6777926580888163; - const rectangleHalfSize = 0.5; - const e = new Cesium.Rectangle( - centerLongitude - rectangleHalfSize, - centerLatitude - rectangleHalfSize, - centerLongitude + rectangleHalfSize, - centerLatitude + rectangleHalfSize - ); + // seneca + const centerLongitude = -1.385205433269729; + const centerLatitude = 0.6777926580888163; + const rectangleHalfSize = 0.5; + const e = new Cesium.Rectangle( + centerLongitude - rectangleHalfSize, + centerLatitude - rectangleHalfSize, + centerLongitude + rectangleHalfSize, + centerLatitude + rectangleHalfSize + ); - function resetBillboardCollection() { - if (Cesium.defined(billboardCollection)) { - scene.primitives.remove(billboardCollection); - } + function resetBillboardCollection() { + if (Cesium.defined(billboardCollection)) { + scene.primitives.remove(billboardCollection); + } - billboardCollection = scene.primitives.add( - new Cesium.BillboardCollection({ - scene: scene, - }) - ); + billboardCollection = scene.primitives.add( + new Cesium.BillboardCollection({ + scene: scene, + }) + ); - const gridSize = Math.sqrt(billboardCount); - for (let y = 0; y < gridSize; ++y) { - for (let x = 0; x < gridSize; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridSize - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridSize - 1) - ); - const position = new Cesium.Cartographic( - longitude, - latitude, - 10000.0 - ); + const gridSize = Math.sqrt(billboardCount); + for (let y = 0; y < gridSize; ++y) { + for (let x = 0; x < gridSize; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridSize - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridSize - 1) + ); + const position = new Cesium.Cartographic( + longitude, + latitude, + 10000.0 + ); - billboardCollection.add({ - position: ellipsoid.cartographicToCartesian(position), - image: "../images/facility.gif", - scale: scale, - }); + billboardCollection.add({ + position: ellipsoid.cartographicToCartesian(position), + image: "../images/facility.gif", + scale: scale, + }); + } } } - } - const moveAmount = new Cesium.Cartesian3(1000, 0.0, 0.0); - const positionScratch = new Cesium.Cartesian3(); - function animateBillboards() { - const billboards = billboardCollection._billboards; - const length = billboards.length; - for (let i = 0; i < length; ++i) { - const billboard = billboards[i]; - Cesium.Cartesian3.clone(billboard.position, positionScratch); - Cesium.Cartesian3.add(positionScratch, moveAmount, positionScratch); - billboard.position = positionScratch; + const moveAmount = new Cesium.Cartesian3(1000, 0.0, 0.0); + const positionScratch = new Cesium.Cartesian3(); + function animateBillboards() { + const billboards = billboardCollection._billboards; + const length = billboards.length; + for (let i = 0; i < length; ++i) { + const billboard = billboards[i]; + Cesium.Cartesian3.clone(billboard.position, positionScratch); + Cesium.Cartesian3.add( + positionScratch, + moveAmount, + positionScratch + ); + billboard.position = positionScratch; + } } - } - Sandcastle.addToolbarMenu([ - { - text: "Instancing Enabled", - onselect: function () { - if (!instancingEnabled) { - context._instancedArrays = instancedArraysExtension; - instancingEnabled = true; - resetBillboardCollection(); - } + Sandcastle.addToolbarMenu([ + { + text: "Instancing Enabled", + onselect: function () { + if (!instancingEnabled) { + context._instancedArrays = instancedArraysExtension; + instancingEnabled = true; + resetBillboardCollection(); + } + }, }, - }, - { - text: "Instancing Disabled", - onselect: function () { - if (instancingEnabled) { - context._instancedArrays = undefined; - instancingEnabled = false; - resetBillboardCollection(); - } + { + text: "Instancing Disabled", + onselect: function () { + if (instancingEnabled) { + context._instancedArrays = undefined; + instancingEnabled = false; + resetBillboardCollection(); + } + }, }, - }, - ]); + ]); - Sandcastle.addToolbarMenu([ - { - text: "100489 billboards", - onselect: function () { - billboardCount = 100489; - resetBillboardCollection(); + Sandcastle.addToolbarMenu([ + { + text: "100489 billboards", + onselect: function () { + billboardCount = 100489; + resetBillboardCollection(); + }, }, - }, - { - text: "10000 billboards", - onselect: function () { - billboardCount = 10000; - resetBillboardCollection(); + { + text: "10000 billboards", + onselect: function () { + billboardCount = 10000; + resetBillboardCollection(); + }, }, - }, - { - text: "1024 billboards", - onselect: function () { - billboardCount = 1024; - resetBillboardCollection(); + { + text: "1024 billboards", + onselect: function () { + billboardCount = 1024; + resetBillboardCollection(); + }, }, - }, - { - text: "100 billboards", - onselect: function () { - billboardCount = 100; - resetBillboardCollection(); + { + text: "100 billboards", + onselect: function () { + billboardCount = 100; + resetBillboardCollection(); + }, }, - }, - { - text: "25 billboards", - onselect: function () { - billboardCount = 25; - resetBillboardCollection(); + { + text: "25 billboards", + onselect: function () { + billboardCount = 25; + resetBillboardCollection(); + }, }, - }, - { - text: "4 billboard", - onselect: function () { - billboardCount = 4; - resetBillboardCollection(); + { + text: "4 billboard", + onselect: function () { + billboardCount = 4; + resetBillboardCollection(); + }, }, - }, - ]); + ]); - Sandcastle.addToolbarMenu([ - { - text: "Static billboards", - onselect: function () { - resetBillboardCollection(); - scene.preUpdate.removeEventListener(animateBillboards); + Sandcastle.addToolbarMenu([ + { + text: "Static billboards", + onselect: function () { + resetBillboardCollection(); + scene.preUpdate.removeEventListener(animateBillboards); + }, }, - }, - { - text: "Animated billboards", - onselect: function () { - resetBillboardCollection(); - scene.preUpdate.addEventListener(animateBillboards); + { + text: "Animated billboards", + onselect: function () { + resetBillboardCollection(); + scene.preUpdate.addEventListener(animateBillboards); + }, }, - }, - ]); + ]); - Sandcastle.addToolbarMenu([ - { - text: "Scale : 1.0", - onselect: function () { - scale = 1.0; - resetBillboardCollection(); + Sandcastle.addToolbarMenu([ + { + text: "Scale : 1.0", + onselect: function () { + scale = 1.0; + resetBillboardCollection(); + }, }, - }, - { - text: "Scale : 0.5", - onselect: function () { - scale = 0.5; - resetBillboardCollection(); + { + text: "Scale : 0.5", + onselect: function () { + scale = 0.5; + resetBillboardCollection(); + }, }, - }, - { - text: "Scale : 0.1", - onselect: function () { - scale = 0.1; - resetBillboardCollection(); + { + text: "Scale : 0.1", + onselect: function () { + scale = 0.1; + resetBillboardCollection(); + }, }, - }, - ]); - - resetBillboardCollection(); + ]); - //Sandcastle_End + resetBillboardCollection(); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 9e8ea43f69a..3cfa67c975e 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -50,95 +50,95 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.extend(Cesium.viewerCesiumInspectorMixin); + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //The viewModel tracks the state of our mini application. - const viewModel = { - enabled: true, - density: 0, - sse: 0, - }; - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + //The viewModel tracks the state of our mini application. + const viewModel = { + enabled: true, + density: 0, + sse: 0, + }; + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "enabled") - .subscribe(function (newValue) { - viewer.scene.fog.enabled = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "enabled") + .subscribe(function (newValue) { + viewer.scene.fog.enabled = newValue; + }); - Cesium.knockout - .getObservable(viewModel, "density") - .subscribe(function (newValue) { - viewer.scene.fog.density = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "density") + .subscribe(function (newValue) { + viewer.scene.fog.density = newValue; + }); - Cesium.knockout - .getObservable(viewModel, "sse") - .subscribe(function (newValue) { - viewer.scene.fog.screenSpaceErrorFactor = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "sse") + .subscribe(function (newValue) { + viewer.scene.fog.screenSpaceErrorFactor = newValue; + }); - viewModel.enabled = viewer.scene.fog.enabled; - viewModel.density = viewer.scene.fog.density; - viewModel.sse = viewer.scene.fog.screenSpaceErrorFactor; + viewModel.enabled = viewer.scene.fog.enabled; + viewModel.density = viewer.scene.fog.density; + viewModel.sse = viewer.scene.fog.screenSpaceErrorFactor; - Sandcastle.addToolbarButton("Horizon high altitude", function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2467730.5740817646, - -4390507.315824514, - 3906155.113316938 - ), - orientation: { - heading: 4.492211521856625, - pitch: -0.2687139437696304, - }, + Sandcastle.addToolbarButton("Horizon high altitude", function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2467730.5740817646, + -4390507.315824514, + 3906155.113316938 + ), + orientation: { + heading: 4.492211521856625, + pitch: -0.2687139437696304, + }, + }); }); - }); - Sandcastle.addToolbarButton("Horizon low altitude", function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -734001.9511656855, - -4214090.596769834, - 4715898.125886317 - ), - orientation: { - heading: 5.634257362559497, - pitch: -0.019548505785381032, - }, + Sandcastle.addToolbarButton("Horizon low altitude", function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -734001.9511656855, + -4214090.596769834, + 4715898.125886317 + ), + orientation: { + heading: 5.634257362559497, + pitch: -0.019548505785381032, + }, + }); }); - }); - - viewer.scene.globe._surface._debug.enableDebugOutput = true; - Sandcastle.addToolbarButton("Snap", function () { - const container = document.getElementById("cesiumContainer"); - const tmpH = container.style.height; - const tmpW = container.style.width; + viewer.scene.globe._surface._debug.enableDebugOutput = true; - container.style.height = "600px"; - container.style.width = "800px"; + Sandcastle.addToolbarButton("Snap", function () { + const container = document.getElementById("cesiumContainer"); + const tmpH = container.style.height; + const tmpW = container.style.width; - viewer.resize(); - viewer.render(); - window.open(viewer.canvas.toDataURL("image/png")); - container.style.height = tmpH; - container.style.width = tmpW; - viewer.resize(); - viewer.render(); - }); + container.style.height = "600px"; + container.style.width = "800px"; - //Sandcastle_End + viewer.resize(); + viewer.render(); + window.open(viewer.canvas.toDataURL("image/png")); + container.style.height = tmpH; + container.style.width = tmpW; + viewer.resize(); + viewer.render(); + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html index 8f9a0450e26..f3dd165d83f 100644 --- a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html @@ -35,90 +35,90 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); - } + if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." + ); + } - // Polyline Glow - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1955, - -122.1058, - 46.1955, - ]), - width: 10.0, + // Polyline Glow + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1955, + -122.1058, + 46.1955, + ]), + width: 10.0, + }), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineGlowType - ), - }), - }) - ); - - // Polyline Dash - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1975, - -122.1058, - 46.1975, - ]), - width: 10.0, + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineGlowType + ), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineDashType - ), - }), - }) - ); + }) + ); - // Polyline Outline - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1995, - -122.1058, - 46.1995, - ]), - width: 10.0, + // Polyline Dash + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1975, + -122.1058, + 46.1975, + ]), + width: 10.0, + }), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineOutlineType - ), - }), - }) - ); + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineDashType + ), + }), + }) + ); - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + // Polyline Outline + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1995, + -122.1058, + 46.1995, + ]), + width: 10.0, + }), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineOutlineType + ), + }), + }) + ); - //Sandcastle_End + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index 99ff4ea0bcf..7122b8007a0 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -35,519 +35,522 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); - - if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { - window.alert( - "GroundPrimitive materials are not supported on this platform." - ); - } - - let rectangle; - let worldRectangle; - - function applyAlphaMapMaterial(primitive, scene) { - Sandcastle.declare(applyAlphaMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - alphaMaterial: { - type: "AlphaMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - channel: "r", + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); + + if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { + window.alert( + "GroundPrimitive materials are not supported on this platform." + ); + } + + let rectangle; + let worldRectangle; + + function applyAlphaMapMaterial(primitive, scene) { + Sandcastle.declare(applyAlphaMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + alphaMaterial: { + type: "AlphaMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + channel: "r", + }, }, }, + components: { + diffuse: "vec3(1.0)", + alpha: "alphaMaterial.alpha", + }, }, - components: { - diffuse: "vec3(1.0)", - alpha: "alphaMaterial.alpha", - }, - }, - }); - } - - function applyBumpMapMaterial(primitive, scene) { - Sandcastle.declare(applyBumpMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/bumpmap.png", + }); + } + + function applyBumpMapMaterial(primitive, scene) { + Sandcastle.declare(applyBumpMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/bumpmap.png", + }, }, - }, - bumpMaterial: { - type: "BumpMap", - uniforms: { - image: "../images/bumpmap.png", - strength: 0.8, + bumpMaterial: { + type: "BumpMap", + uniforms: { + image: "../images/bumpmap.png", + strength: 0.8, + }, }, }, + components: { + diffuse: "diffuseMaterial.diffuse", + specular: 0.01, + normal: "bumpMaterial.normal", + }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - specular: 0.01, - normal: "bumpMaterial.normal", - }, - }, - }); - } - - function applyCheckerboardMaterial(primitive, scene) { - Sandcastle.declare(applyCheckerboardMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType( - "Checkerboard" - ); - } - - function applyColorMaterial(primitive, scene) { - Sandcastle.declare(applyColorMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Color"); - } - - function applyCompositeMaterial(primitive, scene) { - Sandcastle.declare(applyCompositeMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - uniforms: { - image: "../images/earthspec1k.jpg", - heightField: "../images/earthbump1k.jpg", - }, - materials: { - bumpMap: { - type: "BumpMap", - uniforms: { - image: "../images/earthbump1k.jpg", + }); + } + + function applyCheckerboardMaterial(primitive, scene) { + Sandcastle.declare(applyCheckerboardMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType( + "Checkerboard" + ); + } + + function applyColorMaterial(primitive, scene) { + Sandcastle.declare(applyColorMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Color"); + } + + function applyCompositeMaterial(primitive, scene) { + Sandcastle.declare(applyCompositeMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + uniforms: { + image: "../images/earthspec1k.jpg", + heightField: "../images/earthbump1k.jpg", + }, + materials: { + bumpMap: { + type: "BumpMap", + uniforms: { + image: "../images/earthbump1k.jpg", + }, }, }, + source: + "czm_material czm_getMaterial(czm_materialInput materialInput) {" + + "czm_material material = czm_getDefaultMaterial(materialInput);" + + "float heightValue = texture2D(heightField, materialInput.st).r;" + + "material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);" + + "material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;" + + "material.normal = bumpMap.normal;" + + "material.specular = step(0.1, heightValue);" + // Specular mountain tops + "material.shininess = 8.0;" + // Sharpen highlight + "return material;" + + "}", }, - source: - "czm_material czm_getMaterial(czm_materialInput materialInput) {" + - "czm_material material = czm_getDefaultMaterial(materialInput);" + - "float heightValue = texture2D(heightField, materialInput.st).r;" + - "material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);" + - "material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;" + - "material.normal = bumpMap.normal;" + - "material.specular = step(0.1, heightValue);" + // Specular mountain tops - "material.shininess = 8.0;" + // Sharpen highlight - "return material;" + - "}", - }, - }); - } - - function applyDotMaterial(primitive, scene) { - Sandcastle.declare(applyDotMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Dot"); - } - - function applyDiffuseMaterial(primitive, scene) { - Sandcastle.declare(applyDiffuseMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "DiffuseMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", + }); + } + + function applyDotMaterial(primitive, scene) { + Sandcastle.declare(applyDotMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Dot"); + } + + function applyDiffuseMaterial(primitive, scene) { + Sandcastle.declare(applyDiffuseMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "DiffuseMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + }, }, - }, - }); - } - - function applyEmissionMapMaterial(primitive, scene) { - Sandcastle.declare(applyEmissionMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", + }); + } + + function applyEmissionMapMaterial(primitive, scene) { + Sandcastle.declare(applyEmissionMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + }, }, - }, - emissionMaterial: { - type: "EmissionMap", - uniforms: { - image: "../images/checkerboard.png", - repeat: { - x: 1, - y: 0.5, + emissionMaterial: { + type: "EmissionMap", + uniforms: { + image: "../images/checkerboard.png", + repeat: { + x: 1, + y: 0.5, + }, }, }, }, + components: { + diffuse: "diffuseMaterial.diffuse", + emission: "emissionMaterial.emission * 0.2", + }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - emission: "emissionMaterial.emission * 0.2", - }, - }, - }); - } - - function applyWaterMaterial(primitive, scene) { - Sandcastle.declare(applyWaterMaterial); // For highlighting in Sandcastle. - - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Water", - uniforms: { - specularMap: "../images/earthspec1k.jpg", - normalMap: Cesium.buildModuleUrl( - "Assets/Textures/waterNormals.jpg" - ), - frequency: 10000.0, - animationSpeed: 0.01, - amplitude: 1.0, - }, - }, - }); - } - - function applyGridMaterial(primitive, scene) { - Sandcastle.declare(applyGridMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Grid"); - } - - function applyImageMaterial(primitive, scene) { - Sandcastle.declare(applyImageMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Image", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", + }); + } + + function applyWaterMaterial(primitive, scene) { + Sandcastle.declare(applyWaterMaterial); // For highlighting in Sandcastle. + + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Water", + uniforms: { + specularMap: "../images/earthspec1k.jpg", + normalMap: Cesium.buildModuleUrl( + "Assets/Textures/waterNormals.jpg" + ), + frequency: 10000.0, + animationSpeed: 0.01, + amplitude: 1.0, + }, }, - }, - }); - } - - function applyRepeatedImage(primitive, scene) { - Sandcastle.declare(applyRepeatedImage); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Image", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - repeat: { - x: 10, - y: 2, + }); + } + + function applyGridMaterial(primitive, scene) { + Sandcastle.declare(applyGridMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Grid"); + } + + function applyImageMaterial(primitive, scene) { + Sandcastle.declare(applyImageMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Image", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", }, }, - }, - }); - } - - function applyNormalMapMaterial(primitive, scene) { - Sandcastle.declare(applyNormalMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/bumpmap.png", + }); + } + + function applyRepeatedImage(primitive, scene) { + Sandcastle.declare(applyRepeatedImage); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Image", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + repeat: { + x: 10, + y: 2, }, }, - normalMap: { - type: "NormalMap", - uniforms: { - image: "../images/normalmap.png", - strength: 0.6, + }, + }); + } + + function applyNormalMapMaterial(primitive, scene) { + Sandcastle.declare(applyNormalMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/bumpmap.png", + }, + }, + normalMap: { + type: "NormalMap", + uniforms: { + image: "../images/normalmap.png", + strength: 0.6, + }, }, }, + components: { + diffuse: "diffuseMaterial.diffuse", + specular: 0.01, + normal: "normalMap.normal", + }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - specular: 0.01, - normal: "normalMap.normal", - }, - }, - }); - } - - function applySpecularMapMaterial(primitive, scene) { - Sandcastle.declare(applySpecularMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "SpecularMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - channel: "r", + }); + } + + function applySpecularMapMaterial(primitive, scene) { + Sandcastle.declare(applySpecularMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "SpecularMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + channel: "r", + }, }, - }, - }); - } - - function applyStripeMaterial(primitive, scene) { - Sandcastle.declare(applyStripeMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Stripe"); - } - - function applyRimLightingMaterial(primitive, scene) { - Sandcastle.declare(applyRimLightingMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType( - "RimLighting" - ); - } - - function createButtons(scene) { - function toggleRectangleVisibility() { - rectangle.show = true; - worldRectangle.show = false; + }); } - function toggleWorldRectangleVisibility() { - worldRectangle.show = true; - rectangle.show = false; + function applyStripeMaterial(primitive, scene) { + Sandcastle.declare(applyStripeMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Stripe"); } - Sandcastle.addToolbarMenu([ - { - text: "Common materials", - }, - { - text: "Color", - onselect: function () { - toggleRectangleVisibility(); - applyColorMaterial(rectangle, scene); - Sandcastle.highlight(applyColorMaterial); + function applyRimLightingMaterial(primitive, scene) { + Sandcastle.declare(applyRimLightingMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType( + "RimLighting" + ); + } + + function createButtons(scene) { + function toggleRectangleVisibility() { + rectangle.show = true; + worldRectangle.show = false; + } + + function toggleWorldRectangleVisibility() { + worldRectangle.show = true; + rectangle.show = false; + } + + Sandcastle.addToolbarMenu([ + { + text: "Common materials", }, - }, - { - text: "Image", - onselect: function () { - toggleRectangleVisibility(); - applyImageMaterial(rectangle, scene); - Sandcastle.highlight(applyImageMaterial); + { + text: "Color", + onselect: function () { + toggleRectangleVisibility(); + applyColorMaterial(rectangle, scene); + Sandcastle.highlight(applyColorMaterial); + }, }, - }, - { - text: "Repeated/Rotated Image", - onselect: function () { - toggleRectangleVisibility(); - applyRepeatedImage(rectangle, scene); - Sandcastle.highlight(applyRepeatedImage); + { + text: "Image", + onselect: function () { + toggleRectangleVisibility(); + applyImageMaterial(rectangle, scene); + Sandcastle.highlight(applyImageMaterial); + }, }, - }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Procedural textures", - }, - { - text: "Checkerboard", - onselect: function () { - toggleRectangleVisibility(); - applyCheckerboardMaterial(rectangle, scene); - Sandcastle.highlight(applyCheckerboardMaterial); + { + text: "Repeated/Rotated Image", + onselect: function () { + toggleRectangleVisibility(); + applyRepeatedImage(rectangle, scene); + Sandcastle.highlight(applyRepeatedImage); + }, }, - }, - { - text: "Dot", - onselect: function () { - toggleRectangleVisibility(); - applyDotMaterial(rectangle, scene); - Sandcastle.highlight(applyDotMaterial); + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Procedural textures", }, - }, - { - text: "Grid", - onselect: function () { - toggleRectangleVisibility(rectangle, worldRectangle); - applyGridMaterial(rectangle, scene); - Sandcastle.highlight(applyGridMaterial); + { + text: "Checkerboard", + onselect: function () { + toggleRectangleVisibility(); + applyCheckerboardMaterial(rectangle, scene); + Sandcastle.highlight(applyCheckerboardMaterial); + }, }, - }, - { - text: "Stripe", - onselect: function () { - toggleRectangleVisibility(); - applyStripeMaterial(rectangle, scene); - Sandcastle.highlight(applyStripeMaterial); + { + text: "Dot", + onselect: function () { + toggleRectangleVisibility(); + applyDotMaterial(rectangle, scene); + Sandcastle.highlight(applyDotMaterial); + }, }, - }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Base materials", - }, - { - text: "Alpha Map", - onselect: function () { - toggleRectangleVisibility(); - applyAlphaMapMaterial(rectangle, scene); - Sandcastle.highlight(applyAlphaMapMaterial); + { + text: "Grid", + onselect: function () { + toggleRectangleVisibility(rectangle, worldRectangle); + applyGridMaterial(rectangle, scene); + Sandcastle.highlight(applyGridMaterial); + }, }, - }, - { - text: "Bump Map", - onselect: function () { - toggleRectangleVisibility(); - applyBumpMapMaterial(rectangle, scene); - Sandcastle.highlight(applyBumpMapMaterial); + { + text: "Stripe", + onselect: function () { + toggleRectangleVisibility(); + applyStripeMaterial(rectangle, scene); + Sandcastle.highlight(applyStripeMaterial); + }, }, - }, - { - text: "Diffuse", - onselect: function () { - toggleRectangleVisibility(); - applyDiffuseMaterial(rectangle, scene); - Sandcastle.highlight(applyDiffuseMaterial); + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Base materials", }, - }, - { - text: "Emission Map", - onselect: function () { - toggleRectangleVisibility(); - applyEmissionMapMaterial(rectangle, scene); - Sandcastle.highlight(applyEmissionMapMaterial); + { + text: "Alpha Map", + onselect: function () { + toggleRectangleVisibility(); + applyAlphaMapMaterial(rectangle, scene); + Sandcastle.highlight(applyAlphaMapMaterial); + }, }, - }, - { - text: "Normal Map", - onselect: function () { - toggleRectangleVisibility(); - applyNormalMapMaterial(rectangle, scene); - Sandcastle.highlight(applyNormalMapMaterial); + { + text: "Bump Map", + onselect: function () { + toggleRectangleVisibility(); + applyBumpMapMaterial(rectangle, scene); + Sandcastle.highlight(applyBumpMapMaterial); + }, }, - }, - { - text: "Specular Map", - onselect: function () { - toggleRectangleVisibility(); - applySpecularMapMaterial(rectangle, scene); - Sandcastle.highlight(applySpecularMapMaterial); + { + text: "Diffuse", + onselect: function () { + toggleRectangleVisibility(); + applyDiffuseMaterial(rectangle, scene); + Sandcastle.highlight(applyDiffuseMaterial); + }, }, - }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Misc materials", - }, - { - text: "Rim Lighting", - onselect: function () { - toggleWorldRectangleVisibility(); - applyRimLightingMaterial(worldRectangle, scene); - Sandcastle.highlight(applyRimLightingMaterial); + { + text: "Emission Map", + onselect: function () { + toggleRectangleVisibility(); + applyEmissionMapMaterial(rectangle, scene); + Sandcastle.highlight(applyEmissionMapMaterial); + }, }, - }, - { - text: "Water", - onselect: function () { - toggleWorldRectangleVisibility(); - applyWaterMaterial(worldRectangle, scene); - Sandcastle.highlight(applyWaterMaterial); + { + text: "Normal Map", + onselect: function () { + toggleRectangleVisibility(); + applyNormalMapMaterial(rectangle, scene); + Sandcastle.highlight(applyNormalMapMaterial); + }, }, - }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Example composite materials", - }, - { - text: "Composite Example", - onselect: function () { - toggleWorldRectangleVisibility(); - applyCompositeMaterial(worldRectangle, scene); - Sandcastle.highlight(applyCompositeMaterial); + { + text: "Specular Map", + onselect: function () { + toggleRectangleVisibility(); + applySpecularMapMaterial(rectangle, scene); + Sandcastle.highlight(applySpecularMapMaterial); + }, }, - }, - ]); - - document.getElementById("toolbar").style.width = "10%"; - } - - function createPrimitives(scene) { - rectangle = scene.primitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromCartesianArray([ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Misc materials", + }, + { + text: "Rim Lighting", + onselect: function () { + toggleWorldRectangleVisibility(); + applyRimLightingMaterial(worldRectangle, scene); + Sandcastle.highlight(applyRimLightingMaterial); + }, + }, + { + text: "Water", + onselect: function () { + toggleWorldRectangleVisibility(); + applyWaterMaterial(worldRectangle, scene); + Sandcastle.highlight(applyWaterMaterial); + }, + }, + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Example composite materials", + }, + { + text: "Composite Example", + onselect: function () { + toggleWorldRectangleVisibility(); + applyCompositeMaterial(worldRectangle, scene); + Sandcastle.highlight(applyCompositeMaterial); + }, + }, + ]); + + document.getElementById("toolbar").style.width = "10%"; + } + + function createPrimitives(scene) { + rectangle = scene.primitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromCartesianArray([ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ]), + vertexFormat: + Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + }), + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + worldRectangle = scene.primitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -179.99, + -89.99, + 179.99, + 89.99 ), - ]), - vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + vertexFormat: + Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + }), }), - }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - worldRectangle = scene.primitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -179.99, - -89.99, - 179.99, - 89.99 - ), - vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, }), - }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, - }), - show: false, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); - } + show: false, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); + } - const scene = viewer.scene; - scene.globe.enableLighting = true; + const scene = viewer.scene; + scene.globe.enableLighting = true; - createPrimitives(scene); - createButtons(scene); - //Sandcastle_End + createPrimitives(scene); + createButtons(scene); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index ebb9d4031bc..803764bbf9e 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -35,467 +35,478 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - viewer.extend(Cesium.viewerCesiumInspectorMixin); - - function offsetPositions(positions, degreeOffset) { - positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray( - positions - ); - const delta = Cesium.Math.toRadians(degreeOffset); - for (let i = 0; i < positions.length; ++i) { - const position = positions[i]; - position.latitude += delta; - position.longitude += delta; - } - return scene.globe.ellipsoid.cartographicArrayToCartesianArray( - positions - ); - } - - function createOverlappingPolygons(withAlpha) { - const positions = [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ]; - let polygonHierarchy = { positions: positions }; - - let color = Cesium.Color.RED; - if (withAlpha) { - color = color.withAlpha(0.5); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + viewer.extend(Cesium.viewerCesiumInspectorMixin); + + function offsetPositions(positions, degreeOffset) { + positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray( + positions + ); + const delta = Cesium.Math.toRadians(degreeOffset); + for (let i = 0; i < positions.length; ++i) { + const position = positions[i]; + position.latitude += delta; + position.longitude += delta; + } + return scene.globe.ellipsoid.cartographicArrayToCartesianArray( + positions + ); } - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, + function createOverlappingPolygons(withAlpha) { + const positions = [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ]; + let polygonHierarchy = { positions: positions }; + + let color = Cesium.Color.RED; + if (withAlpha) { + color = color.withAlpha(0.5); + } + + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + color + ), + }, + id: "polygon 1", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), - }, - id: "polygon 1", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Same polygon slightly offset and overlapping. - let positionsOffset = offsetPositions(positions, 0.01); - polygonHierarchy = { positions: positionsOffset }; - - color = Cesium.Color.GREEN; - if (withAlpha) { - color = color.withAlpha(0.5); - } + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Same polygon slightly offset and overlapping. + let positionsOffset = offsetPositions(positions, 0.01); + polygonHierarchy = { positions: positionsOffset }; - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, + color = Cesium.Color.GREEN; + if (withAlpha) { + color = color.withAlpha(0.5); + } + + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + color + ), + }, + id: "polygon 2", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), - }, - id: "polygon 2", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Same polygon slightly offset and overlapping. - positionsOffset = offsetPositions(positions, -0.01); - polygonHierarchy = { positions: positionsOffset }; - - color = Cesium.Color.BLUE; - if (withAlpha) { - color = color.withAlpha(0.5); - } + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, + // Same polygon slightly offset and overlapping. + positionsOffset = offsetPositions(positions, -0.01); + polygonHierarchy = { positions: positionsOffset }; + + color = Cesium.Color.BLUE; + if (withAlpha) { + color = color.withAlpha(0.5); + } + + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + color + ), + }, + id: "polygon 3", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), - }, - id: "polygon 3", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - } - - function viewOverlappingPolygons() { - viewer.camera.lookAt( - new Cesium.Cartesian3( - -2354331.3069306486, - -3742016.2427205616, - 4581875.591571755 - ), - new Cesium.HeadingPitchRange( - Cesium.Math.toRadians(20.0), - Cesium.Math.toRadians(-35.0), - 10000.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } - - let handler; - - Sandcastle.addDefaultToolbarButton("Picking Example", function () { - createOverlappingPolygons(true); - viewOverlappingPolygons(); - - let currentObject; - let lastColor; - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - pickedObject !== currentObject - ) { - if (Cesium.defined(currentObject)) { + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + } + + function viewOverlappingPolygons() { + viewer.camera.lookAt( + new Cesium.Cartesian3( + -2354331.3069306486, + -3742016.2427205616, + 4581875.591571755 + ), + new Cesium.HeadingPitchRange( + Cesium.Math.toRadians(20.0), + Cesium.Math.toRadians(-35.0), + 10000.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + + let handler; + + Sandcastle.addDefaultToolbarButton("Picking Example", function () { + createOverlappingPolygons(true); + viewOverlappingPolygons(); + + let currentObject; + let lastColor; + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + pickedObject !== currentObject + ) { + if (Cesium.defined(currentObject)) { + currentObject.primitive.getGeometryInstanceAttributes( + currentObject.id + ).color = lastColor; + } + + currentObject = pickedObject; + + const attributes = currentObject.primitive.getGeometryInstanceAttributes( + currentObject.id + ); + lastColor = attributes.color; + attributes.color = [255, 255, 0, 128]; + } else if ( + !Cesium.defined(pickedObject) && + Cesium.defined(currentObject) + ) { currentObject.primitive.getGeometryInstanceAttributes( currentObject.id ).color = lastColor; + currentObject = undefined; } - - currentObject = pickedObject; - - const attributes = currentObject.primitive.getGeometryInstanceAttributes( - currentObject.id + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + Sandcastle.addToolbarButton("Z-Order", function () { + createOverlappingPolygons(false); + viewOverlappingPolygons(); + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject)) { + scene.groundPrimitives.raiseToTop(pickedObject.primitive); + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + function createBatchedInstances(color, show) { + const instances = []; + + const width = 0.02561343838881669; + const height = 0.019831817968480436; + + let lat = 46.18147866629652; + let lon = -122.20406057655991; + + const delta = 0.03; + const latDeltas = [0.0, 0.0, delta, 0.0]; + const lonDeltas = [0.0, delta, 0.0, -delta]; + + const length = latDeltas.length; + for (let i = 0; i < length; ++i) { + lon = lon + lonDeltas[i]; + lat = lat + latDeltas[i]; + + const west = lon; + const east = lon + width; + const south = lat; + const north = lat + height; + + instances.push( + new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + west, + south, + east, + north + ), + }), + attributes: { + color: color, + show: show, + }, + id: `rectangle${i}`, + }) ); - lastColor = attributes.color; - attributes.color = [255, 255, 0, 128]; - } else if ( - !Cesium.defined(pickedObject) && - Cesium.defined(currentObject) - ) { - currentObject.primitive.getGeometryInstanceAttributes( - currentObject.id - ).color = lastColor; - currentObject = undefined; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - Sandcastle.addToolbarButton("Z-Order", function () { - createOverlappingPolygons(false); - viewOverlappingPolygons(); - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject)) { - scene.groundPrimitives.raiseToTop(pickedObject.primitive); + + return instances; + } + + Sandcastle.addToolbarButton("Batching", function () { + const color = new Cesium.ColorGeometryInstanceAttribute( + 0.0, + 1.0, + 1.0, + 0.5 + ); + const show = new Cesium.ShowGeometryInstanceAttribute(true); + const instances = createBatchedInstances(color, show); + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + viewOverlappingPolygons(); + }); + + Sandcastle.addToolbarButton("Batch Picking", function () { + let color = new Cesium.ColorGeometryInstanceAttribute( + 0.0, + 1.0, + 1.0, + 0.5 + ); + let show = new Cesium.ShowGeometryInstanceAttribute(true); + let instances = createBatchedInstances(color, show); + + const primitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + color = new Cesium.ColorGeometryInstanceAttribute( + 1.0, + 0.0, + 1.0, + 0.5 + ); + show = new Cesium.ShowGeometryInstanceAttribute(false); + instances = createBatchedInstances(color, show); + + // Edit id to differentiate between picked primitive and normally displayed primitive. + const pickIdPrefix = "pick"; + for (let i = 0; i < instances.length; ++i) { + instances[i].id = pickIdPrefix + instances[i].id; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - function createBatchedInstances(color, show) { - const instances = []; - - const width = 0.02561343838881669; - const height = 0.019831817968480436; - - let lat = 46.18147866629652; - let lon = -122.20406057655991; - - const delta = 0.03; - const latDeltas = [0.0, 0.0, delta, 0.0]; - const lonDeltas = [0.0, delta, 0.0, -delta]; - - const length = latDeltas.length; - for (let i = 0; i < length; ++i) { - lon = lon + lonDeltas[i]; - lat = lat + latDeltas[i]; - - const west = lon; - const east = lon + width; - const south = lat; - const north = lat + height; - - instances.push( - new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - west, - south, - east, - north - ), - }), - attributes: { - color: color, - show: show, - }, - id: `rectangle${i}`, + + const pickPrimitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, }) ); - } - return instances; - } - - Sandcastle.addToolbarButton("Batching", function () { - const color = new Cesium.ColorGeometryInstanceAttribute( - 0.0, - 1.0, - 1.0, - 0.5 - ); - const show = new Cesium.ShowGeometryInstanceAttribute(true); - const instances = createBatchedInstances(color, show); - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - viewOverlappingPolygons(); - }); - - Sandcastle.addToolbarButton("Batch Picking", function () { - let color = new Cesium.ColorGeometryInstanceAttribute( - 0.0, - 1.0, - 1.0, - 0.5 - ); - let show = new Cesium.ShowGeometryInstanceAttribute(true); - let instances = createBatchedInstances(color, show); - - const primitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - color = new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 1.0, 0.5); - show = new Cesium.ShowGeometryInstanceAttribute(false); - instances = createBatchedInstances(color, show); - - // Edit id to differentiate between picked primitive and normally displayed primitive. - const pickIdPrefix = "pick"; - for (let i = 0; i < instances.length; ++i) { - instances[i].id = pickIdPrefix + instances[i].id; - } + viewOverlappingPolygons(); + + let currentObject; + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + pickedObject !== currentObject && + pickedObject.id.indexOf(pickIdPrefix) === -1 + ) { + if (Cesium.defined(currentObject)) { + primitive.getGeometryInstanceAttributes( + currentObject.id + ).show = [1]; + pickPrimitive.getGeometryInstanceAttributes( + pickIdPrefix + currentObject.id + ).show = [0]; + } + + currentObject = pickedObject; - const pickPrimitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - viewOverlappingPolygons(); - - let currentObject; - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - pickedObject !== currentObject && - pickedObject.id.indexOf(pickIdPrefix) === -1 - ) { - if (Cesium.defined(currentObject)) { + primitive.getGeometryInstanceAttributes( + currentObject.id + ).show = [0]; + pickPrimitive.getGeometryInstanceAttributes( + pickIdPrefix + currentObject.id + ).show = [1]; + } else if ( + !Cesium.defined(pickedObject) && + Cesium.defined(currentObject) + ) { primitive.getGeometryInstanceAttributes( currentObject.id ).show = [1]; pickPrimitive.getGeometryInstanceAttributes( pickIdPrefix + currentObject.id ).show = [0]; + currentObject = undefined; } - - currentObject = pickedObject; - - primitive.getGeometryInstanceAttributes(currentObject.id).show = [ - 0, - ]; - pickPrimitive.getGeometryInstanceAttributes( - pickIdPrefix + currentObject.id - ).show = [1]; - } else if ( - !Cesium.defined(pickedObject) && - Cesium.defined(currentObject) - ) { - primitive.getGeometryInstanceAttributes(currentObject.id).show = [ - 1, - ]; - pickPrimitive.getGeometryInstanceAttributes( - pickIdPrefix + currentObject.id - ).show = [0]; - currentObject = undefined; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - Sandcastle.addToolbarButton("Create large polygons", function () { - // Circle geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.CircleGeometry({ - center: Cesium.Cartesian3.fromDegrees(-95.0, 45.0), - radius: 250000.0, + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + Sandcastle.addToolbarButton("Create large polygons", function () { + // Circle geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.CircleGeometry({ + center: Cesium.Cartesian3.fromDegrees(-95.0, 45.0), + radius: 250000.0, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + }, + id: "circle", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - }, - id: "circle", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Ellipse Geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipseGeometry({ - center: Cesium.Cartesian3.fromDegrees(-105.0, 40.0), - semiMinorAxis: 300000.0, - semiMajorAxis: 400000.0, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Ellipse Geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipseGeometry({ + center: Cesium.Cartesian3.fromDegrees(-105.0, 40.0), + semiMinorAxis: 300000.0, + semiMajorAxis: 400000.0, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 1.0, 1.0, 0.5) + ), + }, + id: "ellipse", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 1.0, 1.0, 0.5) - ), - }, - id: "ellipse", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Corridor Geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.CorridorGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -112.0, - 40.0, - -117.0, - 40.0, - -117.0, - 35.0, - ]), - width: 200000.0, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Corridor Geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -112.0, + 40.0, + -117.0, + 40.0, + -117.0, + 35.0, + ]), + width: 200000.0, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 0.0, 1.0, 0.5) + ), + }, + id: "corridor", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 0.0, 1.0, 0.5) - ), - }, - id: "corridor", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Rectangle geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -90.0, - 40.0 - ), - rotation: Cesium.Math.toRadians(45), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Rectangle geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -90.0, + 40.0 + ), + rotation: Cesium.Math.toRadians(45), + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 1.0, 0.0, 0.5) + ), + }, + id: "rectangle", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 1.0, 0.0, 0.5) - ), - }, - id: "rectangle", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Rhumb line polygon geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArray([ - -130, - 55, - -100, - 55, - -100, - 45, - -130, - 45, - ]) - ), - arcType: Cesium.ArcType.RHUMB, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Rhumb line polygon geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArray([ + -130, + 55, + -100, + 55, + -100, + 45, + -130, + 45, + ]) + ), + arcType: Cesium.ArcType.RHUMB, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 1.0, 0.0, 0.5) + ), + }, + id: "rhumbPolygon", }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 1.0, 0.0, 0.5) - ), - }, - id: "rhumbPolygon", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - }); - - Sandcastle.reset = function () { - scene.groundPrimitives.removeAll(); - handler = handler && handler.destroy(); - - //Set the camera to a US centered tilted view and switch back to moving in world coordinates. - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-98.0, 40.0), - new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }; - - //Sandcastle_End + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + }); + + Sandcastle.reset = function () { + scene.groundPrimitives.removeAll(); + handler = handler && handler.destroy(); + + //Set the camera to a US centered tilted view and switch back to moving in world coordinates. + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-98.0, 40.0), + new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }; + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 3d9c63f0d4b..4637910a494 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -67,277 +67,266 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shouldAnimate: true, - projectionPicker: true, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shouldAnimate: true, + projectionPicker: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const globe = viewer.scene.globe; - globe.depthTestAgainstTerrain = true; + const globe = viewer.scene.globe; + globe.depthTestAgainstTerrain = true; - let cylinderRadius = -20.0; - let radiusMultiplier = 1.0; + let cylinderRadius = -20.0; + let radiusMultiplier = 1.0; - let steps = 32; - let clippingPlanes = []; - let modelEntityClippingPlanes; - let clippingModeUnion = false; - let enabled = true; + let steps = 32; + let clippingPlanes = []; + let modelEntityClippingPlanes; + let clippingModeUnion = false; + let enabled = true; - const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; - const viewModel = { - cylinderRadius: cylinderRadius, - exampleTypes: clipObjects, - currentExampleType: clipObjects[0], - planeCount: steps, - }; + const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; + const viewModel = { + cylinderRadius: cylinderRadius, + exampleTypes: clipObjects, + currentExampleType: clipObjects[0], + planeCount: steps, + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "cylinderRadius") - .subscribe(function (newValue) { - cylinderRadius = parseFloat(viewModel.cylinderRadius); - updatePlanes(); - }); + Cesium.knockout + .getObservable(viewModel, "cylinderRadius") + .subscribe(function (newValue) { + cylinderRadius = parseFloat(viewModel.cylinderRadius); + updatePlanes(); + }); - Cesium.knockout - .getObservable(viewModel, "planeCount") - .subscribe(function (newValue) { - const newSteps = parseFloat(viewModel.planeCount); - if (newSteps !== steps) { - steps = newSteps; - modelEntityClippingPlanes.removeAll(); - computePlanes(); - } - }); + Cesium.knockout + .getObservable(viewModel, "planeCount") + .subscribe(function (newValue) { + const newSteps = parseFloat(viewModel.planeCount); + if (newSteps !== steps) { + steps = newSteps; + modelEntityClippingPlanes.removeAll(); + computePlanes(); + } + }); - const scene = viewer.scene; - const planeEntities = []; - let selectedPlane; + const scene = viewer.scene; + const planeEntities = []; + let selectedPlane; - function updatePlanes() { - for (let i = 0; i < clippingPlanes.length; i++) { - const plane = clippingPlanes[i]; - plane.distance = cylinderRadius * radiusMultiplier; + function updatePlanes() { + for (let i = 0; i < clippingPlanes.length; i++) { + const plane = clippingPlanes[i]; + plane.distance = cylinderRadius * radiusMultiplier; + } } - } - function computePlanes() { - const stepDegrees = Cesium.Math.TWO_PI / steps; - clippingPlanes = []; + function computePlanes() { + const stepDegrees = Cesium.Math.TWO_PI / steps; + clippingPlanes = []; - for (let i = 0; i < steps; i++) { - const angle = i * stepDegrees; - const dir = new Cesium.Cartesian3(); - dir.x = 1.0; - dir.y = Math.tan(angle); - if (angle > Cesium.Math.PI_OVER_TWO) { - dir.x = -1.0; - dir.y *= -1.0; - } - if (angle > Cesium.Math.PI) { - dir.x = -1.0; - } - if (angle > Cesium.Math.PI_OVER_TWO * 3) { + for (let i = 0; i < steps; i++) { + const angle = i * stepDegrees; + const dir = new Cesium.Cartesian3(); dir.x = 1.0; - dir.y = -dir.y; + dir.y = Math.tan(angle); + if (angle > Cesium.Math.PI_OVER_TWO) { + dir.x = -1.0; + dir.y *= -1.0; + } + if (angle > Cesium.Math.PI) { + dir.x = -1.0; + } + if (angle > Cesium.Math.PI_OVER_TWO * 3) { + dir.x = 1.0; + dir.y = -dir.y; + } + Cesium.Cartesian3.normalize(dir, dir); + const newPlane = new Cesium.ClippingPlane( + dir, + cylinderRadius * radiusMultiplier + ); + modelEntityClippingPlanes.add(newPlane); + clippingPlanes.push(newPlane); } - Cesium.Cartesian3.normalize(dir, dir); - const newPlane = new Cesium.ClippingPlane( - dir, - cylinderRadius * radiusMultiplier - ); - modelEntityClippingPlanes.add(newPlane); - clippingPlanes.push(newPlane); } - } - function createClippingPlanes(modelMatrix) { - modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.defined(modelMatrix) - ? modelMatrix - : Cesium.Matrix4.IDENTITY, - edgeWidth: 2.0, - edgeColor: Cesium.Color.WHITE, - unionClippingRegions: clippingModeUnion, - enabled: enabled, - }); - computePlanes(); - } + function createClippingPlanes(modelMatrix) { + modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.defined(modelMatrix) + ? modelMatrix + : Cesium.Matrix4.IDENTITY, + edgeWidth: 2.0, + edgeColor: Cesium.Color.WHITE, + unionClippingRegions: clippingModeUnion, + enabled: enabled, + }); + computePlanes(); + } - function updateClippingPlanes() { - return modelEntityClippingPlanes; - } + function updateClippingPlanes() { + return modelEntityClippingPlanes; + } - const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; - const agiHqUrl = Cesium.IonResource.fromAssetId(40866); - const instancedUrl = - "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; - const pointCloudUrl = Cesium.IonResource.fromAssetId(5713); + const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; + const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); + const instancedUrl = + "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; + const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); - function loadModel(url) { - createClippingPlanes(); - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 300.0 - ); - const heading = 0.0; - const pitch = 0.0; - const roll = 0.0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: 20, - minimumPixelSize: 100.0, - clippingPlanes: new Cesium.CallbackProperty( - updateClippingPlanes, - false - ), - }, - }); - viewer.trackedEntity = entity; - } + function loadModel(url) { + createClippingPlanes(); + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 300.0 + ); + const heading = 0.0; + const pitch = 0.0; + const roll = 0.0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: 20, + minimumPixelSize: 100.0, + clippingPlanes: new Cesium.CallbackProperty( + updateClippingPlanes, + false + ), + }, + }); + viewer.trackedEntity = entity; + } - let tileset; - function loadTileset(url, height) { - createClippingPlanes(); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - clippingPlanes: modelEntityClippingPlanes, - enableDebugWireframe: true, - }) - ); + let tileset; + async function loadTileset(url, height) { + createClippingPlanes(); + tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: url, + clippingPlanes: modelEntityClippingPlanes, + enableDebugWireframe: true, + }) + ); - return tileset.readyPromise - .then(function () { - const boundingSphere = tileset.boundingSphere; + await tileset.readyPromise; + const boundingSphere = tileset.boundingSphere; - const cartographic = Cesium.Cartographic.fromCartesian( - boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - height - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + const cartographic = Cesium.Cartographic.fromCartesian( + boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; - }); - } + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - loadModel(modelUrl); + loadModel(modelUrl); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); - if (newValue === clipObjects[0]) { - // Model - loadModel(modelUrl); - } else if (newValue === clipObjects[1]) { - // B3dm photogrammetry - agiHqUrl.then(function (resource) { - return loadTileset(resource, 0.0); - }); - } else if (newValue === clipObjects[2]) { - // Point clouds - radiusMultiplier = 20.0; - pointCloudUrl - .then(function (resource) { - return loadTileset(resource, 0.0); - }) - .then(function () { + if (newValue === clipObjects[0]) { + // Model + loadModel(modelUrl); + } else if (newValue === clipObjects[1]) { + // B3dm photogrammetry + return loadTileset(agiHqUrl, 0.0); + } else if (newValue === clipObjects[2]) { + // Point clouds + radiusMultiplier = 20.0; + return loadTileset(pointCloudUrl, 0.0).then(function () { tileset.pointCloudShading.attenuation = true; }); - } else if (newValue === clipObjects[3]) { - // i3dm - loadTileset(instancedUrl, 100.0); - } else if (newValue === clipObjects[4]) { - // Terrain - const position = Cesium.Cartesian3.fromRadians( - // eslint-disable-next-line no-loss-of-precision - -2.0872979473351286, - 0.6596620013036164, - 2380.0 - ); - const entity = viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - scale: 40, - }, - }); - viewer.trackedEntity = entity; - createClippingPlanes( - entity.computeModelMatrix(Cesium.JulianDate.now()) - ); - globe.clippingPlanes = modelEntityClippingPlanes; - } - updatePlanes(); - }); - - function reset() { - radiusMultiplier = 1.0; - viewModel.cylinderRadius = cylinderRadius; - viewer.entities.removeAll(); - viewer.scene.primitives.removeAll(); - globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any - modelEntityClippingPlanes = undefined; - } + } else if (newValue === clipObjects[3]) { + // i3dm + loadTileset(instancedUrl, 100.0); + } else if (newValue === clipObjects[4]) { + // Terrain + const position = Cesium.Cartesian3.fromRadians( + // eslint-disable-next-line no-loss-of-precision + -2.0872979473351286, + 0.6596620013036164, + 2380.0 + ); + const entity = viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + scale: 40, + }, + }); + viewer.trackedEntity = entity; + createClippingPlanes( + entity.computeModelMatrix(Cesium.JulianDate.now()) + ); + globe.clippingPlanes = modelEntityClippingPlanes; + } + updatePlanes(); + }); - Sandcastle.addToggleButton("union", clippingModeUnion, function ( - checked - ) { - clippingModeUnion = checked; - modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; - }); + function reset() { + radiusMultiplier = 1.0; + viewModel.cylinderRadius = cylinderRadius; + viewer.entities.removeAll(); + viewer.scene.primitives.removeAll(); + globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any + modelEntityClippingPlanes = undefined; + } - Sandcastle.addToggleButton("enabled", enabled, function (checked) { - enabled = checked; - modelEntityClippingPlanes.enabled = enabled; - }); + Sandcastle.addToggleButton("union", clippingModeUnion, function ( + checked + ) { + clippingModeUnion = checked; + modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; + }); - //Sandcastle_End + Sandcastle.addToggleButton("enabled", enabled, function (checked) { + enabled = checked; + modelEntityClippingPlanes.enabled = enabled; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index 8bc6eadbd5d..8fa29968ca9 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -41,103 +41,102 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + scene3DOnly: true, + infoBox: false, + selectionIndicator: false, + timeline: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const viewer = new Cesium.Viewer("cesiumContainer", { - scene3DOnly: true, - infoBox: false, - selectionIndicator: false, - timeline: false, - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - - const scene = viewer.scene; - const camera = scene.camera; - - scene.debugShowFramesPerSecond = true; - - function addPrimitive(lon, lat, height, heading) { - const center = Cesium.Cartesian3.fromRadians(lon, lat, height); + const scene = viewer.scene; + const camera = scene.camera; - const pointLightCamera = new Cesium.Camera(scene); - pointLightCamera.position = center; + scene.debugShowFramesPerSecond = true; - camera.lookAt(center, new Cesium.Cartesian3(25.0, 25.0, 30.0)); - camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + function addPrimitive(lon, lat, height, heading) { + const center = Cesium.Cartesian3.fromRadians(lon, lat, height); - const shadowMap = new Cesium.ShadowMap({ - context: scene.context, - lightCamera: pointLightCamera, - isPointLight: true, - softShadows: false, - }); + const pointLightCamera = new Cesium.Camera(scene); + pointLightCamera.position = center; - shadowMap.enabled = true; - - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: - "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - center, - new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) - ), - }) - ); + camera.lookAt(center, new Cesium.Cartesian3(25.0, 25.0, 30.0)); + camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - model.readyPromise - .then(function (model) { - // Play and loop all animations at half-speed - model.activeAnimations.addAll({ - multiplier: 0.5, - loop: Cesium.ModelAnimationLoop.REPEAT, - }); - }) - .catch(function (error) { - window.alert(error); + const shadowMap = new Cesium.ShadowMap({ + context: scene.context, + lightCamera: pointLightCamera, + isPointLight: true, + softShadows: false, }); - return shadowMap; - } + shadowMap.enabled = true; + + const model = scene.primitives.add( + Cesium.Model.fromGltf({ + url: + "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + center, + new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) + ), + }) + ); + + model.readyPromise + .then(function (model) { + // Play and loop all animations at half-speed + model.activeAnimations.addAll({ + multiplier: 0.5, + loop: Cesium.ModelAnimationLoop.REPEAT, + }); + }) + .catch(function (error) { + window.alert(error); + }); - const longitude = -1.3324415110874286; - const latitude = 0.6954224325279967; - const height = 200.0; + return shadowMap; + } - const shadowMap1 = addPrimitive( - longitude + 0.00005, - latitude, - height, - 0.0 - ); - const shadowMap2 = addPrimitive( - longitude - 0.00005, - latitude, - height, - Math.PI - ); + const longitude = -1.3324415110874286; + const latitude = 0.6954224325279967; + const height = 200.0; - shadowMap1.debugShow = true; - shadowMap2.debugShow = false; + const shadowMap1 = addPrimitive( + longitude + 0.00005, + latitude, + height, + 0.0 + ); + const shadowMap2 = addPrimitive( + longitude - 0.00005, + latitude, + height, + Math.PI + ); - Sandcastle.addToolbarButton("Debug Toggle", function () { - shadowMap1.debugShow = !shadowMap1.debugShow; - shadowMap2.debugShow = !shadowMap2.debugShow; - }); + shadowMap1.debugShow = true; + shadowMap2.debugShow = false; - scene.shadowMap = shadowMap1; + Sandcastle.addToolbarButton("Debug Toggle", function () { + shadowMap1.debugShow = !shadowMap1.debugShow; + shadowMap2.debugShow = !shadowMap2.debugShow; + }); - // TODO : workaround until Cesium supports multiple light sources - const CustomPrimitive = function (shadowMap) { - this.shadowMap = shadowMap; - }; + scene.shadowMap = shadowMap1; - CustomPrimitive.prototype.update = function (frameState) { - frameState.shadowMaps.push(this.shadowMap); - }; + // Workaround until Cesium supports multiple light sources + const CustomPrimitive = function (shadowMap) { + this.shadowMap = shadowMap; + }; - scene.primitives.add(new CustomPrimitive(shadowMap2)); + CustomPrimitive.prototype.update = function (frameState) { + frameState.shadowMaps.push(this.shadowMap); + }; - //Sandcastle_End + scene.primitives.add(new CustomPrimitive(shadowMap2)); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index 68752b18d72..add7bd5fd88 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -53,315 +53,315 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); - } + if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." + ); + } - const polylineIds = ["polyline1", "polyline2"]; - const groundPrimitiveId = "ground primitive"; - let selectedId = polylineIds[0]; - let polylineOnTerrainPrimitive; - let groundPrimitiveOnTop = false; + const polylineIds = ["polyline1", "polyline2"]; + const groundPrimitiveId = "ground primitive"; + let selectedId = polylineIds[0]; + let polylineOnTerrainPrimitive; + let groundPrimitiveOnTop = false; - let lineWidth = 4.0; - const viewModel = { - lineWidth: lineWidth, - }; + let lineWidth = 4.0; + const viewModel = { + lineWidth: lineWidth, + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "lineWidth") - .subscribe(function (newValue) { - lineWidth = parseFloat(viewModel.lineWidth); - if (Cesium.defined(selectedId)) { - const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - selectedId - ); + Cesium.knockout + .getObservable(viewModel, "lineWidth") + .subscribe(function (newValue) { lineWidth = parseFloat(viewModel.lineWidth); - attributes.width = [lineWidth]; + if (Cesium.defined(selectedId)) { + const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + selectedId + ); + lineWidth = parseFloat(viewModel.lineWidth); + attributes.width = [lineWidth]; + } + }); + + const scene = viewer.scene; + + // Add a Rectangle GroundPrimitive to demonstrate Z-indexing with GroundPrimitives + const rectangleGroundPrimitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -112.1340164450331, + 36.05494287836128, + -112.0840164450331, + 36.10494287836128 + ), + vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + }), + id: groundPrimitiveId, + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, + material: Cesium.Material.fromType("Color"), + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + const leftHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + leftHandler.setInputAction(function (movement) { + const pickedObject = viewer.scene.pick(movement.position); + if (Cesium.defined(pickedObject)) { + console.log(pickedObject.id); + // If picked the ground primitive, don't do anything + if (pickedObject.id !== groundPrimitiveId) { + selectedId = pickedObject.id; + + // Sync line width in toolbar with selected + const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + selectedId + ); + viewModel.lineWidth = attributes.width[0]; + } + } else { + selectedId = undefined; } - }); + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - const scene = viewer.scene; + const polylinePositions = Cesium.Cartesian3.fromDegreesArray([ + -112.1340164450331, + 36.05494287836128, + -112.08821010582645, + 36.097804071380715, + -112.13296079730024, + 36.168769146801104, + -112.10828895143331, + 36.20031318533197, + -112.138548165717, + 36.1691100215289, // hairpins + -112.11482556496543, + 36.20127524083297, + -112.15921333464016, + 36.17876011207708, + -112.14700151155604, + 36.21683132404626, + -112.20919883052926, + 36.19475754001766, + ]); - // Add a Rectangle GroundPrimitive to demonstrate Z-indexing with GroundPrimitives - const rectangleGroundPrimitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -112.1340164450331, - 36.05494287836128, - -112.0840164450331, - 36.10494287836128 + const loopPositions = Cesium.Cartesian3.fromDegreesArray([ + -111.94500779274114, + 36.27638678884143, + -111.90983004392696, + 36.07985366173454, + -111.80360100637773, + 36.13694878292542, + -111.85510122419183, + 36.26029588763386, + -111.69141601804614, + 36.05128770351902, + ]); + + function createPolylines(debugShowShadowVolume) { + const instance1 = new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: polylinePositions, + loop: false, + width: 4.0, + }), + id: polylineIds[0], + attributes: { + show: new Cesium.ShowGeometryInstanceAttribute(), + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("green").withAlpha(0.7) ), - vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, + }, + }); + + const instance2 = new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: loopPositions, + loop: true, + width: 8.0, }), - id: groundPrimitiveId, - }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, - material: Cesium.Material.fromType("Color"), - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); + id: polylineIds[1], + attributes: { + show: new Cesium.ShowGeometryInstanceAttribute(), + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#67ADDF").withAlpha(0.7) + ), + }, + }); - const leftHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - leftHandler.setInputAction(function (movement) { - const pickedObject = viewer.scene.pick(movement.position); - if (Cesium.defined(pickedObject)) { - console.log(pickedObject.id); - // If picked the ground primitive, don't do anything - if (pickedObject.id !== groundPrimitiveId) { - selectedId = pickedObject.id; + polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({ + geometryInstances: [instance1, instance2], + debugShowShadowVolume: debugShowShadowVolume, + }); + scene.groundPrimitives.add(polylineOnTerrainPrimitive); + } - // Sync line width in toolbar with selected + function applyPerInstanceColor() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineColorAppearance(); + } + function applyColorMaterial() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("Color", { + color: new Cesium.Color(0.7, 0.0, 1.0, 1.0), + }), + } + ); + } + function applyGlowMaterial() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineGlow", { + innerWidth: 1.0, + }), + } + ); + } + function applyArrow() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineArrow"), + } + ); + } + function applyDash() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineDash", { + color: Cesium.Color.YELLOW, + }), + } + ); + } + function applyOutline() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineOutline"), + } + ); + } + + Sandcastle.addToolbarButton("Toggle instance show", function () { + if (Cesium.defined(selectedId)) { const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( selectedId ); - viewModel.lineWidth = attributes.width[0]; + attributes.show = [attributes.show[0] ? 0 : 1]; } - } else { - selectedId = undefined; - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - - const polylinePositions = Cesium.Cartesian3.fromDegreesArray([ - -112.1340164450331, - 36.05494287836128, - -112.08821010582645, - 36.097804071380715, - -112.13296079730024, - 36.168769146801104, - -112.10828895143331, - 36.20031318533197, - -112.138548165717, - 36.1691100215289, // hairpins - -112.11482556496543, - 36.20127524083297, - -112.15921333464016, - 36.17876011207708, - -112.14700151155604, - 36.21683132404626, - -112.20919883052926, - 36.19475754001766, - ]); - - const loopPositions = Cesium.Cartesian3.fromDegreesArray([ - -111.94500779274114, - 36.27638678884143, - -111.90983004392696, - 36.07985366173454, - -111.80360100637773, - 36.13694878292542, - -111.85510122419183, - 36.26029588763386, - -111.69141601804614, - 36.05128770351902, - ]); - - function createPolylines(debugShowShadowVolume) { - const instance1 = new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: polylinePositions, - loop: false, - width: 4.0, - }), - id: polylineIds[0], - attributes: { - show: new Cesium.ShowGeometryInstanceAttribute(), - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("green").withAlpha(0.7) - ), - }, }); - const instance2 = new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: loopPositions, - loop: true, - width: 8.0, - }), - id: polylineIds[1], - attributes: { - show: new Cesium.ShowGeometryInstanceAttribute(), - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#67ADDF").withAlpha(0.7) - ), - }, - }); - - polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({ - geometryInstances: [instance1, instance2], - debugShowShadowVolume: debugShowShadowVolume, + Sandcastle.addToolbarButton("Show all", function () { + if (Cesium.defined(selectedId)) { + let attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + "polyline1" + ); + attributes.show = [1]; + attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + "polyline2" + ); + attributes.show = [1]; + } }); - scene.groundPrimitives.add(polylineOnTerrainPrimitive); - } - function applyPerInstanceColor() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineColorAppearance(); - } - function applyColorMaterial() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("Color", { - color: new Cesium.Color(0.7, 0.0, 1.0, 1.0), - }), - } - ); - } - function applyGlowMaterial() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineGlow", { - innerWidth: 1.0, - }), - } - ); - } - function applyArrow() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineArrow"), + Sandcastle.addToolbarButton( + "Toggle debugShowShadowVolume", + function () { + const debugShowShadowVolume = !polylineOnTerrainPrimitive.debugShowShadowVolume; + const appearance = polylineOnTerrainPrimitive.appearance; + scene.groundPrimitives.remove(polylineOnTerrainPrimitive); + createPolylines(debugShowShadowVolume); + polylineOnTerrainPrimitive.appearance = appearance; } ); - } - function applyDash() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineDash", { - color: Cesium.Color.YELLOW, - }), - } - ); - } - function applyOutline() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineOutline"), + + Sandcastle.addToolbarButton("Toggle z-index", function () { + if (groundPrimitiveOnTop) { + scene.groundPrimitives.raiseToTop(polylineOnTerrainPrimitive); + } else { + scene.groundPrimitives.lowerToBottom(polylineOnTerrainPrimitive); } - ); - } + groundPrimitiveOnTop = !groundPrimitiveOnTop; + }); - Sandcastle.addToolbarButton("Toggle instance show", function () { - if (Cesium.defined(selectedId)) { - const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - selectedId + function lookAt() { + viewer.camera.lookAt( + polylinePositions[1], + new Cesium.Cartesian3(50000.0, 50000.0, 50000.0) ); - attributes.show = [attributes.show[0] ? 0 : 1]; + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } - }); - Sandcastle.addToolbarButton("Show all", function () { - if (Cesium.defined(selectedId)) { - let attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - "polyline1" - ); - attributes.show = [1]; - attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - "polyline2" - ); - attributes.show = [1]; - } - }); + Sandcastle.addToolbarButton("reset view", function () { + lookAt(); + }); - Sandcastle.addToolbarButton( - "Toggle debugShowShadowVolume", - function () { - const debugShowShadowVolume = !polylineOnTerrainPrimitive.debugShowShadowVolume; - const appearance = polylineOnTerrainPrimitive.appearance; - scene.groundPrimitives.remove(polylineOnTerrainPrimitive); - createPolylines(debugShowShadowVolume); - polylineOnTerrainPrimitive.appearance = appearance; - } - ); + createPolylines(false); + applyPerInstanceColor(); - Sandcastle.addToolbarButton("Toggle z-index", function () { - if (groundPrimitiveOnTop) { - scene.groundPrimitives.raiseToTop(polylineOnTerrainPrimitive); - } else { - scene.groundPrimitives.lowerToBottom(polylineOnTerrainPrimitive); - } - groundPrimitiveOnTop = !groundPrimitiveOnTop; - }); - - function lookAt() { - viewer.camera.lookAt( - polylinePositions[1], - new Cesium.Cartesian3(50000.0, 50000.0, 50000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } - - Sandcastle.addToolbarButton("reset view", function () { lookAt(); - }); - - createPolylines(false); - applyPerInstanceColor(); - - lookAt(); - Sandcastle.addToolbarMenu([ - { - text: "Per Instance Color", - onselect: function () { - applyPerInstanceColor(); - Sandcastle.highlight(applyPerInstanceColor); + Sandcastle.addToolbarMenu([ + { + text: "Per Instance Color", + onselect: function () { + applyPerInstanceColor(); + Sandcastle.highlight(applyPerInstanceColor); + }, }, - }, - { - text: "Color", - onselect: function () { - applyColorMaterial(); - Sandcastle.highlight(applyColorMaterial); + { + text: "Color", + onselect: function () { + applyColorMaterial(); + Sandcastle.highlight(applyColorMaterial); + }, }, - }, - { - text: "Glow", - onselect: function () { - applyGlowMaterial(); - Sandcastle.highlight(applyGlowMaterial); + { + text: "Glow", + onselect: function () { + applyGlowMaterial(); + Sandcastle.highlight(applyGlowMaterial); + }, }, - }, - { - text: "Arrow", - onselect: function () { - applyArrow(); - Sandcastle.highlight(applyArrow); + { + text: "Arrow", + onselect: function () { + applyArrow(); + Sandcastle.highlight(applyArrow); + }, }, - }, - { - text: "Dash", - onselect: function () { - applyDash(); - Sandcastle.highlight(applyDash); + { + text: "Dash", + onselect: function () { + applyDash(); + Sandcastle.highlight(applyDash); + }, }, - }, - { - text: "Outline", - onselect: function () { - applyOutline(); - Sandcastle.highlight(applyOutline); + { + text: "Outline", + onselect: function () { + applyOutline(); + Sandcastle.highlight(applyOutline); + }, }, - }, - ]); - - //Sandcastle_End + ]); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html index 341ccefcf66..3dc40b187da 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html +++ b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html @@ -35,155 +35,156 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - const concavePositions = [ - new Cesium.Cartesian3( - -2353381.4891308164, - -3747386.1222378365, - 4577999.291515961 - ), - new Cesium.Cartesian3( - -2359513.937204245, - -3743087.2343810294, - 4578357.188560644 - ), - new Cesium.Cartesian3( - -2356102.0286082155, - -3739921.552293276, - 4582670.218770547 - ), - new Cesium.Cartesian3( - -2353889.0353209395, - -3741183.2274413602, - 4582776.909071608 - ), - new Cesium.Cartesian3( - -2355072.390487758, - -3742865.615615464, - 4580808.044684757 - ), - new Cesium.Cartesian3( - -2356109.6661414686, - -3741994.0607898533, - 4580985.489703348 - ), - new Cesium.Cartesian3( - -2357041.8328847606, - -3743225.9693035223, - 4579509.2148039425 - ), - new Cesium.Cartesian3( - -2354586.752280607, - -3744890.9511893727, - 4579411.591389144 - ), - new Cesium.Cartesian3( - -2353213.0268325945, - -3743712.1202877173, - 4581070.08828045 - ), - new Cesium.Cartesian3( - -2353637.930711704, - -3743402.9513476435, - 4581104.219550749 - ), - new Cesium.Cartesian3( - -2352875.095159641, - -3742564.819171856, - 4582173.540953957 - ), - new Cesium.Cartesian3( - -2350669.646050987, - -3743751.6823160048, - 4582334.8406995395 - ), - ]; + const concavePositions = [ + new Cesium.Cartesian3( + -2353381.4891308164, + -3747386.1222378365, + 4577999.291515961 + ), + new Cesium.Cartesian3( + -2359513.937204245, + -3743087.2343810294, + 4578357.188560644 + ), + new Cesium.Cartesian3( + -2356102.0286082155, + -3739921.552293276, + 4582670.218770547 + ), + new Cesium.Cartesian3( + -2353889.0353209395, + -3741183.2274413602, + 4582776.909071608 + ), + new Cesium.Cartesian3( + -2355072.390487758, + -3742865.615615464, + 4580808.044684757 + ), + new Cesium.Cartesian3( + -2356109.6661414686, + -3741994.0607898533, + 4580985.489703348 + ), + new Cesium.Cartesian3( + -2357041.8328847606, + -3743225.9693035223, + 4579509.2148039425 + ), + new Cesium.Cartesian3( + -2354586.752280607, + -3744890.9511893727, + 4579411.591389144 + ), + new Cesium.Cartesian3( + -2353213.0268325945, + -3743712.1202877173, + 4581070.08828045 + ), + new Cesium.Cartesian3( + -2353637.930711704, + -3743402.9513476435, + 4581104.219550749 + ), + new Cesium.Cartesian3( + -2352875.095159641, + -3742564.819171856, + 4582173.540953957 + ), + new Cesium.Cartesian3( + -2350669.646050987, + -3743751.6823160048, + 4582334.8406995395 + ), + ]; - // concave polygon - viewer.entities.add({ - name: "concave polygon on surface", - polygon: { - hierarchy: concavePositions, - material: "../images/Cesium_Logo_Color.jpg", - }, - stRotation: 1.0, - }); + // concave polygon + viewer.entities.add({ + name: "concave polygon on surface", + polygon: { + hierarchy: concavePositions, + material: "../images/Cesium_Logo_Color.jpg", + }, + stRotation: 1.0, + }); - // Randomly colored, nonoverlapping squares - const latitude = 46.2522; - const longitude = -122.2534; + // Randomly colored, nonoverlapping squares + const latitude = 46.2522; + const longitude = -122.2534; - Cesium.Math.setRandomNumberSeed(133); + Cesium.Math.setRandomNumberSeed(133); - for (let x = 0; x < 10; ++x) { - for (let y = 0; y < 10; ++y) { - const cornerLat = latitude + 0.01 * x; - const cornerLon = longitude + 0.01 * y; - viewer.entities.add({ - id: `${x} ${y}`, - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - cornerLon, - cornerLat, - cornerLon + 0.009, - cornerLat + 0.009 - ), - material: Cesium.Color.fromRandom().withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + for (let x = 0; x < 10; ++x) { + for (let y = 0; y < 10; ++y) { + const cornerLat = latitude + 0.01 * x; + const cornerLon = longitude + 0.01 * y; + viewer.entities.add({ + id: `${x} ${y}`, + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + cornerLon, + cornerLat, + cornerLon + 0.009, + cornerLat + 0.009 + ), + material: Cesium.Color.fromRandom().withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); + } } - } - // Checkerboard - const checkerboard = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.ORANGE, - oddColor: Cesium.Color.YELLOW, - repeat: new Cesium.Cartesian2(14, 14), - }); + // Checkerboard + const checkerboard = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.ORANGE, + oddColor: Cesium.Color.YELLOW, + repeat: new Cesium.Cartesian2(14, 14), + }); - viewer.entities.add({ - name: "checkerboard rectangle", - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.17778, - 46.36169, - -120.17778, - 48.36169 - ), - material: checkerboard, - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + viewer.entities.add({ + name: "checkerboard rectangle", + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.17778, + 46.36169, + -120.17778, + 48.36169 + ), + material: checkerboard, + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - // Ellipse with texture rotation and repetition - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees( - -121.70711316136793, - 45.943757948892845, - 0.0 - ), - name: "ellipse", - ellipse: { - semiMinorAxis: 15000.0, - semiMajorAxis: 30000.0, - material: new Cesium.ImageMaterialProperty({ - image: "../images/Cesium_Logo_Color.jpg", - repeat: new Cesium.Cartesian2(10, 10), - }), - stRotation: Cesium.Math.toRadians(45), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + // Ellipse with texture rotation and repetition + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees( + -121.70711316136793, + 45.943757948892845, + 0.0 + ), + name: "ellipse", + ellipse: { + semiMinorAxis: 15000.0, + semiMajorAxis: 30000.0, + material: new Cesium.ImageMaterialProperty({ + image: "../images/Cesium_Logo_Color.jpg", + repeat: new Cesium.Cartesian2(10, 10), + }), + stRotation: Cesium.Math.toRadians(45), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - viewer.zoomTo(viewer.entities); - //Sandcastle_End + viewer.zoomTo(viewer.entities); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index 98a87d8ede0..adf9068d00e 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -35,243 +35,245 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const camera = scene.camera; - const globe = scene.globe; - const statistics = Cesium.RequestScheduler.statistics; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + const camera = scene.camera; + const globe = scene.globe; + const statistics = Cesium.RequestScheduler.statistics; - let startTime; - let flightComplete; - let monitor; - let minFrameRate = 1000; - let maxFrameRate = 0; - let sumFrameRate = 0.0; - let frameRateSamples = 0; + let startTime; + let flightComplete; + let monitor; + let minFrameRate = 1000; + let maxFrameRate = 0; + let sumFrameRate = 0.0; + let frameRateSamples = 0; - function startTest() { - flightComplete = false; - statistics.numberOfActiveRequestsEver = 0; - monitor = new Cesium.FrameRateMonitor({ - scene: scene, - samplingWindow: 1.0, - quietPeriod: 0.0, - warmupPeriod: 0.0, - minimumFrameRateDuringWarmup: 0, - minimumFrameRateAfterWarmup: 0, - }); - scene.preUpdate.addEventListener(measureFrameRate); - startTime = window.performance.now(); - window.setTimeout(function () { - scene.postRender.addEventListener(viewReady); - }, 500); - } + function startTest() { + flightComplete = false; + statistics.numberOfActiveRequestsEver = 0; + monitor = new Cesium.FrameRateMonitor({ + scene: scene, + samplingWindow: 1.0, + quietPeriod: 0.0, + warmupPeriod: 0.0, + minimumFrameRateDuringWarmup: 0, + minimumFrameRateAfterWarmup: 0, + }); + scene.preUpdate.addEventListener(measureFrameRate); + startTime = window.performance.now(); + window.setTimeout(function () { + scene.postRender.addEventListener(viewReady); + }, 500); + } + + function measureFrameRate() { + const frameRate = monitor.lastFramesPerSecond; + if (frameRate === undefined || frameRate !== frameRate) { + return; + } - function measureFrameRate() { - const frameRate = monitor.lastFramesPerSecond; - if (frameRate === undefined || frameRate !== frameRate) { - return; + ++frameRateSamples; + sumFrameRate += frameRate; + minFrameRate = Math.min(minFrameRate, frameRate); + maxFrameRate = Math.max(maxFrameRate, frameRate); } - ++frameRateSamples; - sumFrameRate += frameRate; - minFrameRate = Math.min(minFrameRate, frameRate); - maxFrameRate = Math.max(maxFrameRate, frameRate); - } + function viewReady(scene, time) { + const ready = + globe._surface.tileProvider.ready && + globe._surface._tileLoadQueueHigh.length === 0 && + globe._surface._tileLoadQueueMedium.length === 0 && + globe._surface._tileLoadQueueLow.length === 0 && + globe._surface._debug.tilesWaitingForChildren === 0; + if (flightComplete && ready) { + const endTime = window.performance.now(); + const duration = endTime - startTime; + alert( + `${(duration / 1000).toFixed(2)} seconds ${ + statistics.numberOfActiveRequestsEver + } requests, min/max/avg frame FPS ${minFrameRate}/${maxFrameRate}/${ + sumFrameRate / frameRateSamples + }` + ); + scene.postRender.removeEventListener(viewReady); + } + } - function viewReady(scene, time) { - const ready = - globe._surface.tileProvider.ready && - globe._surface._tileLoadQueueHigh.length === 0 && - globe._surface._tileLoadQueueMedium.length === 0 && - globe._surface._tileLoadQueueLow.length === 0 && - globe._surface._debug.tilesWaitingForChildren === 0; - if (flightComplete && ready) { - const endTime = window.performance.now(); - const duration = endTime - startTime; - alert( - `${(duration / 1000).toFixed(2)} seconds ${ - statistics.numberOfActiveRequestsEver - } requests, min/max/avg frame FPS ${minFrameRate}/${maxFrameRate}/${ - sumFrameRate / frameRateSamples - }` + function goToEverestHorizontal() { + camera.position = new Cesium.Cartesian3( + 302950.1757410969, + 5637093.359233209, + 2976894.491577989 + ); + camera.direction = new Cesium.Cartesian3( + -0.9648960658153797, + -0.24110066659365145, + -0.10414437451009724 + ); + camera.right = new Cesium.Cartesian3( + -0.02152846103178338, + 0.46781654381873394, + -0.8835633574877908 + ); + camera.up = new Cesium.Cartesian3( + -0.26174817580950865, + 0.8503047394302772, + 0.456584868959543 ); - scene.postRender.removeEventListener(viewReady); + flightComplete = true; } - } - function goToEverestHorizontal() { - camera.position = new Cesium.Cartesian3( - 302950.1757410969, - 5637093.359233209, - 2976894.491577989 - ); - camera.direction = new Cesium.Cartesian3( - -0.9648960658153797, - -0.24110066659365145, - -0.10414437451009724 - ); - camera.right = new Cesium.Cartesian3( - -0.02152846103178338, - 0.46781654381873394, - -0.8835633574877908 - ); - camera.up = new Cesium.Cartesian3( - -0.26174817580950865, - 0.8503047394302772, - 0.456584868959543 - ); - flightComplete = true; - } - - function goToEverestTopDown() { - camera.position = new Cesium.Cartesian3( - 301989.1870802739, - 5637745.915399717, - 2977153.0443453398 - ); - camera.direction = new Cesium.Cartesian3( - 0.021398841015326783, - -0.8909524564021135, - -0.45359211857597476 - ); - camera.right = new Cesium.Cartesian3( - 0.21237352569072232, - 0.4473925820246778, - -0.8687562161705573 - ); - camera.up = new Cesium.Cartesian3( - -0.9769542339275126, - 0.07774058129659328, - -0.19878839712310903 - ); - flightComplete = true; - } + function goToEverestTopDown() { + camera.position = new Cesium.Cartesian3( + 301989.1870802739, + 5637745.915399717, + 2977153.0443453398 + ); + camera.direction = new Cesium.Cartesian3( + 0.021398841015326783, + -0.8909524564021135, + -0.45359211857597476 + ); + camera.right = new Cesium.Cartesian3( + 0.21237352569072232, + 0.4473925820246778, + -0.8687562161705573 + ); + camera.up = new Cesium.Cartesian3( + -0.9769542339275126, + 0.07774058129659328, + -0.19878839712310903 + ); + flightComplete = true; + } - function goToEverest45Degrees() { - camera.position = new Cesium.Cartesian3( - 302760.41072832496, - 5637092.977453635, - 2977284.6758398763 - ); - camera.direction = new Cesium.Cartesian3( - -0.7254568510163212, - -0.3330925403210976, - -0.6022970337764594 - ); - camera.right = new Cesium.Cartesian3( - 0.4750641658993092, - 0.39087207931336604, - -0.7883736778277414 - ); - camera.up = new Cesium.Cartesian3( - -0.49802248502640617, - 0.8580608237157107, - 0.12532049797395203 - ); - flightComplete = true; - } + function goToEverest45Degrees() { + camera.position = new Cesium.Cartesian3( + 302760.41072832496, + 5637092.977453635, + 2977284.6758398763 + ); + camera.direction = new Cesium.Cartesian3( + -0.7254568510163212, + -0.3330925403210976, + -0.6022970337764594 + ); + camera.right = new Cesium.Cartesian3( + 0.4750641658993092, + 0.39087207931336604, + -0.7883736778277414 + ); + camera.up = new Cesium.Cartesian3( + -0.49802248502640617, + 0.8580608237157107, + 0.12532049797395203 + ); + flightComplete = true; + } - function zoomToEverest() { - const position = new Cesium.Cartesian3( - 302955.90876054496, - 5639614.4908250235, - 2981096.1048591887 - ); - camera.flyTo({ - destination: position, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - complete: function () { - flightComplete = true; - }, - }); - } + function zoomToEverest() { + const position = new Cesium.Cartesian3( + 302955.90876054496, + 5639614.4908250235, + 2981096.1048591887 + ); + camera.flyTo({ + destination: position, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + complete: function () { + flightComplete = true; + }, + }); + } - function panAroundEverest() { - camera.position = new Cesium.Cartesian3( - 302950.1757410969, - 5637093.359233209, - 2976894.491577989 - ); - camera.direction = new Cesium.Cartesian3( - -0.9648960658153797, - -0.24110066659365145, - -0.10414437451009724 - ); - camera.right = new Cesium.Cartesian3( - -0.02152846103178338, - 0.46781654381873394, - -0.8835633574877908 - ); - camera.up = new Cesium.Cartesian3( - -0.26174817580950865, - 0.8503047394302772, - 0.456584868959543 - ); + function panAroundEverest() { + camera.position = new Cesium.Cartesian3( + 302950.1757410969, + 5637093.359233209, + 2976894.491577989 + ); + camera.direction = new Cesium.Cartesian3( + -0.9648960658153797, + -0.24110066659365145, + -0.10414437451009724 + ); + camera.right = new Cesium.Cartesian3( + -0.02152846103178338, + 0.46781654381873394, + -0.8835633574877908 + ); + camera.up = new Cesium.Cartesian3( + -0.26174817580950865, + 0.8503047394302772, + 0.456584868959543 + ); - const startCartographic = Cesium.Cartographic.fromCartesian( - camera.position - ); - let longitude = startCartographic.longitude; - const endLongitude = longitude + 0.01; - const latitude = startCartographic.latitude; - const height = startCartographic.height; - let startTime = window.performance.now(); - const removeCallback = scene.preRender.addEventListener(function ( - scene, - time - ) { - const endTime = window.performance.now(); - const delta = endTime - startTime; - startTime = endTime; - longitude += delta * 0.000001; - if (longitude >= endLongitude) { - flightComplete = true; - removeCallback(); - } - camera.position = Cesium.Cartesian3.fromRadians( - longitude, - latitude, - height + const startCartographic = Cesium.Cartographic.fromCartesian( + camera.position ); - }); - } + let longitude = startCartographic.longitude; + const endLongitude = longitude + 0.01; + const latitude = startCartographic.latitude; + const height = startCartographic.height; + let startTime = window.performance.now(); + const removeCallback = scene.preRender.addEventListener(function ( + scene, + time + ) { + const endTime = window.performance.now(); + const delta = endTime - startTime; + startTime = endTime; + longitude += delta * 0.000001; + if (longitude >= endLongitude) { + flightComplete = true; + removeCallback(); + } + camera.position = Cesium.Cartesian3.fromRadians( + longitude, + latitude, + height + ); + }); + } - Sandcastle.addToolbarButton("Timer Static Horizontal", function () { - startTest(); - goToEverestHorizontal(); - }); + Sandcastle.addToolbarButton("Timer Static Horizontal", function () { + startTest(); + goToEverestHorizontal(); + }); - Sandcastle.addToolbarButton("Timer Static Top Down", function () { - startTest(); - goToEverestTopDown(); - }); + Sandcastle.addToolbarButton("Timer Static Top Down", function () { + startTest(); + goToEverestTopDown(); + }); - Sandcastle.addToolbarButton("Timer Static 45 degrees", function () { - startTest(); - goToEverest45Degrees(); - }); + Sandcastle.addToolbarButton("Timer Static 45 degrees", function () { + startTest(); + goToEverest45Degrees(); + }); - Sandcastle.addToolbarButton("Timer Zoom", function () { - startTest(); - zoomToEverest(); - }); + Sandcastle.addToolbarButton("Timer Zoom", function () { + startTest(); + zoomToEverest(); + }); - Sandcastle.addToolbarButton("Timer Pan", function () { - startTest(); - panAroundEverest(); - }); + Sandcastle.addToolbarButton("Timer Pan", function () { + startTest(); + panAroundEverest(); + }); - Sandcastle.addToolbarButton("Save camera", function () { - const cameraString = - `camera.position = new Cesium.Cartesian3(${camera.positionWC.x}, ${camera.positionWC.y}, ${camera.positionWC.z});\n` + - `camera.direction = new Cesium.Cartesian3(${camera.directionWC.x}, ${camera.directionWC.y}, ${camera.directionWC.z});\n` + - `camera.right = new Cesium.Cartesian3(${camera.rightWC.x}, ${camera.rightWC.y}, ${camera.rightWC.z});\n` + - `camera.up = new Cesium.Cartesian3(${camera.upWC.x}, ${camera.upWC.y}, ${camera.upWC.z});\n`; - console.log(cameraString); - }); //Sandcastle_End + Sandcastle.addToolbarButton("Save camera", function () { + const cameraString = + `camera.position = new Cesium.Cartesian3(${camera.positionWC.x}, ${camera.positionWC.y}, ${camera.positionWC.z});\n` + + `camera.direction = new Cesium.Cartesian3(${camera.directionWC.x}, ${camera.directionWC.y}, ${camera.directionWC.z});\n` + + `camera.right = new Cesium.Cartesian3(${camera.rightWC.x}, ${camera.rightWC.y}, ${camera.rightWC.z});\n` + + `camera.up = new Cesium.Cartesian3(${camera.upWC.x}, ${camera.upWC.y}, ${camera.upWC.z});\n`; + console.log(cameraString); + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js index df5778a7c54..d64225da9f2 100644 --- a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js +++ b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js @@ -229,7 +229,7 @@ async function requestMetadata( * * @example * const terrainProvider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", { - * token : "KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg.." + * token: "KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg.." * }); * viewer.terrainProvider = terrainProvider; * @@ -418,7 +418,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { * * @example * const terrainProvider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl("https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer", { - * token : "KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg.." + * token: "KED1aF_I4UzXOHy3BnhwyBHU4l5oY6rO6walkmHoYqGp4XyIWUd5YZUC1ZrLAzvV40pR6gBXQayh0eFA8m6vPg.." * }); * viewer.terrainProvider = terrainProvider; * diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index 5a91c8ddc81..d22dc413d7f 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -465,12 +465,16 @@ async function requestLayerJson(terrainProviderBuilder, provider) { * * @example * // Create Arctic DEM terrain with normals. - * const viewer = new Cesium.Viewer('cesiumContainer', { - * terrainProvider : Cesium.CesiumTerrainProvider.fromUrl( - * Cesium.IonResource.fromAssetId(3956), { - * requestVertexNormals : true + * try { + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + * Cesium.IonResource.fromAssetId(3956), { + * requestVertexNormals: true * }) - * }); + * }); + * } catch (error) { + * console.log(error); + * } * * @see createWorldTerrain * @see CesiumTerrainProvider.fromUrl @@ -1210,12 +1214,16 @@ CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function ( * * @example * // Create Arctic DEM terrain with normals. - * const viewer = new Cesium.Viewer('cesiumContainer', { - * terrainProvider : Cesium.CesiumTerrainProvider.fromUrl( - * Cesium.IonResource.fromAssetId(3956), { - * requestVertexNormals : true + * try { + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + * Cesium.IonResource.fromAssetId(3956), { + * requestVertexNormals: true * }) - * }); + * }); + * } catch (error) { + * console.log(error); + * } * * @exception {RuntimeError} layer.json does not specify a format * @exception {RuntimeError} layer.json specifies an unknown format diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index 66b92ce22db..b714afa8afd 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -96,7 +96,7 @@ TerrainCache.prototype.tidy = function () { * @see CesiumTerrainProvider * * @example - * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl('http://www.example.com'); + * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl("http://www.example.com"); * const gee = Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata(geeMetadata); * * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} @@ -351,7 +351,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { * @exception {RuntimeError} metadata does not specify terrain * * @example - * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl('http://www.example.com'); + * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl("http://www.example.com"); * const gee = Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata(geeMetadata); */ GoogleEarthEnterpriseTerrainProvider.fromMetadata = function ( diff --git a/packages/engine/Source/Core/createWorldTerrain.js b/packages/engine/Source/Core/createWorldTerrain.js index 47aa51f805f..4642349dc6b 100644 --- a/packages/engine/Source/Core/createWorldTerrain.js +++ b/packages/engine/Source/Core/createWorldTerrain.js @@ -44,6 +44,8 @@ function createWorldTerrain(options) { requestWaterMask: defaultValue(options.requestWaterMask, false), }); + // This is here in order to avoid throwing a second deprecation error + // by using the deprecated url parameter in the constructor above provider._readyPromise = CesiumTerrainProvider._initializeReadyPromise( { url: IonResource.fromAssetId(1), diff --git a/packages/engine/Source/Core/createWorldTerrainAsync.js b/packages/engine/Source/Core/createWorldTerrainAsync.js index 64b9df29d68..983b7e89ba3 100644 --- a/packages/engine/Source/Core/createWorldTerrainAsync.js +++ b/packages/engine/Source/Core/createWorldTerrainAsync.js @@ -16,18 +16,26 @@ import IonResource from "./IonResource.js"; * * @example * // Create Cesium World Terrain with default settings - * const viewer = new Cesium.Viewer('cesiumContainer', { - * terrainProvider : Cesium.createWorldTerrainAsync(); - * }); + * try { + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: await Cesium.createWorldTerrainAsync(); + * }); + * } catch (error) { + * console.log(error); + * } * * @example * // Create Cesium World Terrain with water and normals. - * const viewer1 = new Cesium.Viewer('cesiumContainer', { - * terrainProvider : Cesium.createWorldTerrainAsync({ - * requestWaterMask : true, - * requestVertexNormals : true + * try { + * const viewer1 = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: await Cesium.createWorldTerrainAsync({ + * requestWaterMask: true, + * requestVertexNormals: true * }); - * }); + * }); + * } catch (error) { + * console.log(error); + * } * */ function createWorldTerrainAsync(options) { diff --git a/packages/engine/Source/Scene/I3SDataProvider.js b/packages/engine/Source/Scene/I3SDataProvider.js index 71b66026817..5a9df52c86e 100644 --- a/packages/engine/Source/Scene/I3SDataProvider.js +++ b/packages/engine/Source/Scene/I3SDataProvider.js @@ -512,9 +512,7 @@ I3SDataProvider.prototype._getDecoderTaskProcessor = function () { }; function getCoveredTiles(terrainProvider, extent) { - return terrainProvider.readyPromise.then(function () { - return getTiles(terrainProvider, extent); - }); + return getTiles(terrainProvider, extent); } const scratchCartesian2 = new Cartesian2(); diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 53a19092c88..fbe6ebba276 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -124,7 +124,7 @@ function configureCameraFrustum(widget) { * @param {Object} [options] Object with the following properties: * @param {Clock} [options.clock=new Clock()] The clock to use to control current time. * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to false, no imagery provider will be added. - * @param {TerrainProvider|Promise} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. + * @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. * @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When undefined, the default stars are used. If set to false, no skyBox, Sun, or Moon will be added. * @param {SkyAtmosphere | false} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false to turn it off. * @param {SceneMode} [options.sceneMode=SceneMode.SCENE3D] The initial scene mode. @@ -156,27 +156,31 @@ function configureCameraFrustum(widget) { * // For each example, include a link to CesiumWidget.css stylesheet in HTML head, * // and in the body, include:
* - * //Widget with no terrain and default Bing Maps imagery provider. - * const widget = new Cesium.CesiumWidget('cesiumContainer'); + * // Widget with no terrain and default Bing Maps imagery provider. + * const widget = new Cesium.CesiumWidget("cesiumContainer"); * - * //Widget with ion imagery and Cesium World Terrain. - * const widget2 = new Cesium.CesiumWidget('cesiumContainer', { - * imageryProvider : Cesium.createWorldImagery(), - * terrainProvider : Cesium.createWorldTerrainAsync(), - * skyBox : new Cesium.SkyBox({ - * sources : { - * positiveX : 'stars/TychoSkymapII.t3_08192x04096_80_px.jpg', - * negativeX : 'stars/TychoSkymapII.t3_08192x04096_80_mx.jpg', - * positiveY : 'stars/TychoSkymapII.t3_08192x04096_80_py.jpg', - * negativeY : 'stars/TychoSkymapII.t3_08192x04096_80_my.jpg', - * positiveZ : 'stars/TychoSkymapII.t3_08192x04096_80_pz.jpg', - * negativeZ : 'stars/TychoSkymapII.t3_08192x04096_80_mz.jpg' - * } + * // Widget with ion imagery and Cesium World Terrain. + * try { + * const widget2 = new Cesium.CesiumWidget("cesiumContainer", { + * imageryProvider: Cesium.createWorldImagery(), + * terrainProvider: await Cesium.createWorldTerrainAsync(), + * skyBox: new Cesium.SkyBox({ + * sources: { + * positiveX: "stars/TychoSkymapII.t3_08192x04096_80_px.jpg", + * negativeX: "stars/TychoSkymapII.t3_08192x04096_80_mx.jpg", + * positiveY: "stars/TychoSkymapII.t3_08192x04096_80_py.jpg", + * negativeY: "stars/TychoSkymapII.t3_08192x04096_80_my.jpg", + * positiveZ: "stars/TychoSkymapII.t3_08192x04096_80_pz.jpg", + * negativeZ: "stars/TychoSkymapII.t3_08192x04096_80_mz.jpg" + * } * }), * // Show Columbus View map with Web Mercator projection - * sceneMode : Cesium.SceneMode.COLUMBUS_VIEW, - * mapProjection : new Cesium.WebMercatorProjection() - * }); + * sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, + * mapProjection: new Cesium.WebMercatorProjection() + * }); + * } catch (error) { + * console.log(error); + * } */ function CesiumWidget(container, options) { //>>includeStart('debug', pragmas.debug); @@ -353,15 +357,7 @@ function CesiumWidget(container, options) { //Set the terrain provider if one is provided. if (defined(options.terrainProvider) && options.globe !== false) { - // options.terrainProvider is a promise - // Promise.resolve is not used so that synchronous code can immediately execute - if (defined(options.terrainProvider.then)) { - options.terrainProvider.then((provider) => { - scene.terrainProvider = provider; - }); - } else { - scene.terrainProvider = options.terrainProvider; - } + scene.terrainProvider = options.terrainProvider; } this._screenSpaceEventHandler = new ScreenSpaceEventHandler(canvas); diff --git a/packages/engine/Specs/Widget/CesiumWidgetSpec.js b/packages/engine/Specs/Widget/CesiumWidgetSpec.js index 20d0328bda9..142632e734d 100644 --- a/packages/engine/Specs/Widget/CesiumWidgetSpec.js +++ b/packages/engine/Specs/Widget/CesiumWidgetSpec.js @@ -145,11 +145,6 @@ describe( expect(imageryLayers.length).toEqual(0); }); - it("uses default terrainProvider", function () { - widget = createCesiumWidget(container); - expect(widget.terrainProvider).toBeInstanceOf(EllipsoidTerrainProvider); - }); - it("sets expected options terrainProvider", function () { const options = { terrainProvider: new EllipsoidTerrainProvider(), @@ -162,23 +157,6 @@ describe( expect(widget.terrainProvider).toBe(anotherProvider); }); - it("sets expected options terrainProvider promise", async function () { - const options = { - terrainProvider: Promise.resolve(new EllipsoidTerrainProvider()), - }; - widget = createCesiumWidget(container, options); - const provider = await options.terrainProvider; - expect(widget.terrainProvider).toBe(provider); - }); - - it("sets terrainProvider", function () { - widget = createCesiumWidget(container); - - const anotherProvider = new EllipsoidTerrainProvider(); - widget.terrainProvider = anotherProvider; - expect(widget.terrainProvider).toBe(anotherProvider); - }); - it("does not create a globe if option is false", function () { widget = createCesiumWidget(container, { globe: false, diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js index 5e0883843f0..191b07f5abc 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -181,7 +181,7 @@ function BaseLayerPickerViewModel(options) { get: function () { return selectedImageryViewModel(); }, - set: function (value) { + set: async function (value) { if (selectedImageryViewModel() === value) { this.dropDownVisible = false; return; @@ -256,15 +256,24 @@ function BaseLayerPickerViewModel(options) { selectedTerrainViewModel(value); const updateTerrainProvider = async () => { - const provider = await Promise.resolve(newProvider); - if (!defined(provider)) { - return; + try { + const provider = await Promise.resolve(newProvider); + + if (!defined(provider) || this._globe.isDestroyed()) { + this.dropDownVisible = false; + return; + } + + this._globe.depthTestAgainstTerrain = !( + provider instanceof EllipsoidTerrainProvider + ); + this._globe.terrainProvider = provider; + } catch (error) { + console.log( + `An error occurred while creating the terrain provider: ${error}` + ); } - this._globe.depthTestAgainstTerrain = !( - provider instanceof EllipsoidTerrainProvider - ); - this._globe.terrainProvider = provider; this.dropDownVisible = false; }; @@ -282,14 +291,12 @@ function BaseLayerPickerViewModel(options) { imageryProviderViewModels[0] ); - Promise.resolve( + selectedTerrainViewModel( defaultValue( options.selectedTerrainProviderViewModel, terrainProviderViewModels[0] ) - ).then((provider) => { - this.selectedTerrain = provider; - }); + ); } Object.defineProperties(BaseLayerPickerViewModel.prototype, { diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index d9bb0497db5..2cdde7b667e 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -314,7 +314,7 @@ function enableVRUI(viewer, enabled) { * @property {ProviderViewModel} [selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. - * @property {TerrainProvider|Promise} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use + * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When undefined, the default stars are used. If set to false, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false to turn it off. * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. @@ -369,39 +369,43 @@ function enableVRUI(viewer, enabled) { * @demo {@link https://sandcastle.cesium.com/index.html?src=Hello%20World.html|Cesium Sandcastle Hello World Demo} * * @example - * //Initialize the viewer widget with several custom options and mixins. - * const viewer = new Cesium.Viewer('cesiumContainer', { - * //Start in Columbus Viewer - * sceneMode : Cesium.SceneMode.COLUMBUS_VIEW, - * //Use Cesium World Terrain - * terrainProvider : Cesium.createWorldTerrainAsync(), - * //Hide the base layer picker - * baseLayerPicker : false, - * //Use OpenStreetMaps - * imageryProvider : new Cesium.OpenStreetMapImageryProvider({ - * url : 'https://a.tile.openstreetmap.org/' + * // Initialize the viewer widget with several custom options and mixins. + * try { + * const viewer = new Cesium.Viewer("cesiumContainer", { + * // Start in Columbus Viewer + * sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, + * // Use Cesium World Terrain + * terrainProvider: await Cesium.createWorldTerrainAsync(), + * // Hide the base layer picker + * baseLayerPicker: false, + * // Use OpenStreetMaps + * imageryProvider: new Cesium.OpenStreetMapImageryProvider({ + * url: "https://a.tile.openstreetmap.org/" * }), - * skyBox : new Cesium.SkyBox({ - * sources : { - * positiveX : 'stars/TychoSkymapII.t3_08192x04096_80_px.jpg', - * negativeX : 'stars/TychoSkymapII.t3_08192x04096_80_mx.jpg', - * positiveY : 'stars/TychoSkymapII.t3_08192x04096_80_py.jpg', - * negativeY : 'stars/TychoSkymapII.t3_08192x04096_80_my.jpg', - * positiveZ : 'stars/TychoSkymapII.t3_08192x04096_80_pz.jpg', - * negativeZ : 'stars/TychoSkymapII.t3_08192x04096_80_mz.jpg' - * } + * skyBox: new Cesium.SkyBox({ + * sources: { + * positiveX: "stars/TychoSkymapII.t3_08192x04096_80_px.jpg", + * negativeX: "stars/TychoSkymapII.t3_08192x04096_80_mx.jpg", + * positiveY: "stars/TychoSkymapII.t3_08192x04096_80_py.jpg", + * negativeY: "stars/TychoSkymapII.t3_08192x04096_80_my.jpg", + * positiveZ: "stars/TychoSkymapII.t3_08192x04096_80_pz.jpg", + * negativeZ: "stars/TychoSkymapII.t3_08192x04096_80_mz.jpg" + * } * }), * // Show Columbus View map with Web Mercator projection - * mapProjection : new Cesium.WebMercatorProjection() - * }); + * mapProjection: new Cesium.WebMercatorProjection() + * }); + * } catch (error) { + * console.log(error); + * } * - * //Add basic drag and drop functionality + * // Add basic drag and drop functionality * viewer.extend(Cesium.viewerDragDropMixin); * - * //Show a pop-up alert if we encounter an error when processing a dropped file + * // Show a pop-up alert if we encounter an error when processing a dropped file * viewer.dropError.addEventListener(function(dropHandler, name, error) { - * console.log(error); - * window.alert(error); + * console.log(error); + * window.alert(error); * }); */ function Viewer(container, options) { @@ -680,21 +684,10 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to scene.imageryLayers.addImageryProvider(options.imageryProvider); } if (defined(options.terrainProvider)) { - // options.terrainProvider is a promise - // Promise.resolve is not used so that synchronous code can immediately execute - if (defined(options.terrainProvider.then)) { - options.terrainProvider.then((provider) => { - if (createBaseLayerPicker) { - baseLayerPicker.viewModel.selectedTerrain = undefined; - } - scene.terrainProvider = provider; - }); - } else { - if (createBaseLayerPicker) { - baseLayerPicker.viewModel.selectedTerrain = undefined; - } - scene.terrainProvider = options.terrainProvider; + if (createBaseLayerPicker) { + baseLayerPicker.viewModel.selectedTerrain = undefined; } + scene.terrainProvider = options.terrainProvider; } // Navigation Help Button From e175431d745a3e3e0b7e30a205f98885fa1d0c50 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 20 Jan 2023 10:08:56 -0500 Subject: [PATCH 374/679] Sandcastle tweaks --- ...es Next Photogrammetry Classification.html | 443 ++++----- Apps/Sandcastle/gallery/ArcticDEM.html | 159 +-- Apps/Sandcastle/gallery/Clamp to Terrain.html | 545 +++++----- .../gallery/Classification Types.html | 249 ++--- .../Custom Shaders Property Textures.html | 103 +- .../gallery/Drawing on Terrain.html | 235 ++--- Apps/Sandcastle/gallery/GPX.html | 192 ++-- .../gallery/Geometry Height Reference.html | 241 ++--- Apps/Sandcastle/gallery/Globe Materials.html | 520 +++++----- Apps/Sandcastle/gallery/Interpolation.html | 325 +++--- Apps/Sandcastle/gallery/Lighting.html | 375 +++---- Apps/Sandcastle/gallery/MSAA.html | 264 ++--- .../gallery/Montreal Point Cloud.html | 595 +++++------ Apps/Sandcastle/gallery/PAMAP Terrain.html | 186 ++-- .../gallery/Particle System Weather.html | 311 +++--- .../gallery/Physically-Based Materials.html | 274 +++--- .../gallery/Sample Height from 3D Tiles.html | 153 +-- .../gallery/Scene Rendering Performance.html | 406 ++++---- Apps/Sandcastle/gallery/Shadows.html | 464 ++++----- .../gallery/Terrain Exaggeration.html | 213 ++-- Apps/Sandcastle/gallery/Terrain.html | 533 +++++----- .../development/BillboardClampToGround.html | 227 ++--- .../development/Billboards Instancing.html | 329 +++---- Apps/Sandcastle/gallery/development/Fog.html | 151 +-- .../Ground Primitive Materials.html | 927 +++++++++--------- .../gallery/development/Ground Primitive.html | 877 ++++++++--------- .../gallery/development/Multiple Shadows.html | 176 ++-- .../development/Polylines On Terrain.html | 539 +++++----- .../development/Terrain Performance.html | 441 +++++---- 29 files changed, 5276 insertions(+), 5177 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 1f44a122901..6ad48f0367a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -35,79 +35,83 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + // San Francisco Ferry Building photogrammetry model provided by Aerometrex + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + orderIndependentTranslucency: false, + }); + (async () => { - // San Francisco Ferry Building photogrammetry model provided by Aerometrex - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - infoBox: false, - orderIndependentTranslucency: false, - }); - - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2021-11-09T20:27:37.016064475348684937Z" - ); - - const scene = viewer.scene; - - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(775877), - }); - - const translation = new Cesium.Cartesian3( - -1.398521324920626, - 0.7823052871729486, - 0.7015244410592609 - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - - tileset.maximumScreenSpaceError = 8.0; - scene.pickTranslucentDepth = true; - scene.light.intensity = 7.0; - - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - - // Fly to a nice overview of the city. - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - -2703640.80485846, - -4261161.990345464, - 3887439.511104276 - ), - orientation: new Cesium.HeadingPitchRoll( - 0.22426651143535548, - -0.2624145362506527, - 0.000006972977223185239 - ), - }); - - // Styles ============================================================================= - - const classificationStyle = new Cesium.Cesium3DTileStyle({ - color: "color(${color})", - }); - - const translucentWindowsStyle = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${component} === 'Windows'", "color('gray', 0.7)"], - ], - }, - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2021-11-09T20:27:37.016064475348684937Z" + ); + + const scene = viewer.scene; + + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(775877), + }); + + const translation = new Cesium.Cartesian3( + -1.398521324920626, + 0.7823052871729486, + 0.7015244410592609 + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + + tileset.maximumScreenSpaceError = 8.0; + scene.pickTranslucentDepth = true; + scene.light.intensity = 7.0; + + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + + // Fly to a nice overview of the city. + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + -2703640.80485846, + -4261161.990345464, + 3887439.511104276 + ), + orientation: new Cesium.HeadingPitchRoll( + 0.22426651143535548, + -0.2624145362506527, + 0.000006972977223185239 + ), + }); + + // Styles ============================================================================= - // Shaders ============================================================================ + const classificationStyle = new Cesium.Cesium3DTileStyle({ + color: "color(${color})", + }); - // Dummy shader that sets the UNLIT lighting mode. For use with the classification style - const emptyFragmentShader = - "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {}"; - const unlitShader = new Cesium.CustomShader({ - lightingModel: Cesium.LightingModel.UNLIT, - fragmentShaderText: emptyFragmentShader, - }); + const translucentWindowsStyle = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [["${component} === 'Windows'", "color('gray', 0.7)"]], + }, + }); - const materialShader = new Cesium.CustomShader({ - lightingModel: Cesium.LightingModel.PBR, - fragmentShaderText: ` + // Shaders ============================================================================ + + // Dummy shader that sets the UNLIT lighting mode. For use with the classification style + const emptyFragmentShader = + "void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {}"; + const unlitShader = new Cesium.CustomShader({ + lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: emptyFragmentShader, + }); + + const materialShader = new Cesium.CustomShader({ + lightingModel: Cesium.LightingModel.PBR, + fragmentShaderText: ` const int WINDOW = 0; const int FRAME = 1; const int WALL = 2; @@ -154,18 +158,18 @@ } } `, - }); - - const NOTHING_SELECTED = 12; - const selectFeatureShader = new Cesium.CustomShader({ - uniforms: { - u_selectedFeature: { - type: Cesium.UniformType.INT, - value: NOTHING_SELECTED, - }, + }); + + const NOTHING_SELECTED = 12; + const selectFeatureShader = new Cesium.CustomShader({ + uniforms: { + u_selectedFeature: { + type: Cesium.UniformType.INT, + value: NOTHING_SELECTED, }, - lightingModel: Cesium.LightingModel.PBR, - fragmentShaderText: ` + }, + lightingModel: Cesium.LightingModel.PBR, + fragmentShaderText: ` const int NOTHING_SELECTED = 12; void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { int featureId = fsInput.featureIds.featureId_0; @@ -176,17 +180,17 @@ } } `, - }); - - const multipleFeatureIdsShader = new Cesium.CustomShader({ - uniforms: { - u_selectedFeature: { - type: Cesium.UniformType.FLOAT, - value: NOTHING_SELECTED, - }, + }); + + const multipleFeatureIdsShader = new Cesium.CustomShader({ + uniforms: { + u_selectedFeature: { + type: Cesium.UniformType.FLOAT, + value: NOTHING_SELECTED, }, - lightingModel: Cesium.LightingModel.UNLIT, - fragmentShaderText: ` + }, + lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: ` const int IDS0_WINDOW = 0; const int IDS1_FACADE = 2; const int IDS1_ROOF = 3; @@ -210,154 +214,151 @@ material.diffuse *= tint; } `, - }); + }); - // Demo Functions ===================================================================== + // Demo Functions ===================================================================== - function defaults() { - tileset.style = undefined; - tileset.customShader = unlitShader; - tileset.colorBlendMode = - Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT; - tileset.colorBlendAmount = 0.5; - tileset.featureIdLabel = 0; - } + function defaults() { + tileset.style = undefined; + tileset.customShader = unlitShader; + tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT; + tileset.colorBlendAmount = 0.5; + tileset.featureIdLabel = 0; + } - const showPhotogrammetry = defaults; + const showPhotogrammetry = defaults; - function showClassification() { - defaults(); - tileset.style = classificationStyle; - tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX; - } + function showClassification() { + defaults(); + tileset.style = classificationStyle; + tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX; + } - function showAlternativeClassification() { - showClassification(); - // This dataset has a second feature ID texture. - tileset.featureIdLabel = 1; - } + function showAlternativeClassification() { + showClassification(); + // This dataset has a second feature ID texture. + tileset.featureIdLabel = 1; + } - function translucentWindows() { - defaults(); - tileset.style = translucentWindowsStyle; - } + function translucentWindows() { + defaults(); + tileset.style = translucentWindowsStyle; + } - function pbrMaterials() { - defaults(); - tileset.customShader = materialShader; - } + function pbrMaterials() { + defaults(); + tileset.customShader = materialShader; + } - function goldenTouch() { - defaults(); - tileset.customShader = selectFeatureShader; - } + function goldenTouch() { + defaults(); + tileset.customShader = selectFeatureShader; + } - function multipleFeatureIds() { - defaults(); - tileset.customShader = multipleFeatureIdsShader; - } + function multipleFeatureIds() { + defaults(); + tileset.customShader = multipleFeatureIdsShader; + } + + // Pick Handlers ====================================================================== + + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; + nameOverlay.style.whiteSpace = "pre-line"; + nameOverlay.style.fontSize = "12px"; - // Pick Handlers ====================================================================== - - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; - nameOverlay.style.whiteSpace = "pre-line"; - nameOverlay.style.fontSize = "12px"; - - let enablePicking = true; - const handler = new Cesium.ScreenSpaceEventHandler( - viewer.scene.canvas - ); - handler.setInputAction(function (movement) { - if (enablePicking) { - const pickedObject = viewer.scene.pick(movement.endPosition); - if (pickedObject instanceof Cesium.Cesium3DTileFeature) { - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const component = pickedObject.getProperty("component"); - const message = `Component: ${component}\nFeature ID: ${pickedObject.featureId}`; - nameOverlay.textContent = message; - } else { - nameOverlay.style.display = "none"; - } + let enablePicking = true; + const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); + handler.setInputAction(function (movement) { + if (enablePicking) { + const pickedObject = viewer.scene.pick(movement.endPosition); + if (pickedObject instanceof Cesium.Cesium3DTileFeature) { + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const component = pickedObject.getProperty("component"); + const message = `Component: ${component}\nFeature ID: ${pickedObject.featureId}`; + nameOverlay.textContent = message; } else { nameOverlay.style.display = "none"; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - - const clickHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (enablePicking) { - const pickedObject = scene.pick(movement.position); - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.featureId) - ) { - selectFeatureShader.setUniform( - "u_selectedFeature", - pickedObject.featureId - ); - } else { - selectFeatureShader.setUniform( - "u_selectedFeature", - NOTHING_SELECTED - ); - } + } else { + nameOverlay.style.display = "none"; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + + const clickHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (enablePicking) { + const pickedObject = scene.pick(movement.position); + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.featureId) + ) { + selectFeatureShader.setUniform( + "u_selectedFeature", + pickedObject.featureId + ); + } else { + selectFeatureShader.setUniform( + "u_selectedFeature", + NOTHING_SELECTED + ); } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - // UI ============================================================================ + // UI ============================================================================ - Sandcastle.addToggleButton("Enable picking", enablePicking, function ( - checked - ) { - enablePicking = checked; - }); + Sandcastle.addToggleButton("Enable picking", enablePicking, function ( + checked + ) { + enablePicking = checked; + }); - const demos = [ - { - text: "Photogrammetry", - onselect: showPhotogrammetry, - }, - { - text: "Show Classification", - onselect: showClassification, - }, - { - text: "Show Alternative Classification", - onselect: showAlternativeClassification, - }, - { - text: "Translucent Windows", - onselect: translucentWindows, - }, - { - text: "Stylized PBR Materials", - onselect: pbrMaterials, - }, - { - text: "Golden Touch", - onselect: goldenTouch, - }, - { - text: "Multiple Feature ID Sets", - onselect: multipleFeatureIds, - }, - ]; - Sandcastle.addToolbarMenu(demos); - })(); //Sandcastle_End + const demos = [ + { + text: "Photogrammetry", + onselect: showPhotogrammetry, + }, + { + text: "Show Classification", + onselect: showClassification, + }, + { + text: "Show Alternative Classification", + onselect: showAlternativeClassification, + }, + { + text: "Translucent Windows", + onselect: translucentWindows, + }, + { + text: "Stylized PBR Materials", + onselect: pbrMaterials, + }, + { + text: "Golden Touch", + onselect: goldenTouch, + }, + { + text: "Multiple Feature ID Sets", + onselect: multipleFeatureIds, + }, + ]; + Sandcastle.addToolbarMenu(demos); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index b1fee24a39d..32414bf7eb1 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -35,90 +35,95 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. - // https://www.pgc.umn.edu/data/arcticdem/ - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + try { + // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. + // https://www.pgc.umn.edu/data/arcticdem/ + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( Cesium.IonResource.fromAssetId(3956) - ), - }); + ); + } catch (error) { + console.log(error); + } + })(); - // Add Alaskan locations - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Denali", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6399828792482234, - 1.0993550795541742, - 5795 - ), - orientation: { - heading: 3.8455, - pitch: -0.4535, - roll: 0.0, - }, - }); - }, + // Add Alaskan locations + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Denali", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6399828792482234, + 1.0993550795541742, + 5795 + ), + orientation: { + heading: 3.8455, + pitch: -0.4535, + roll: 0.0, + }, + }); }, - { - text: "Anchorage Area", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.610708034601548, - 1.0671172431736584, - 1900 - ), - orientation: { - heading: 4.6, - pitch: -0.341, - roll: 0.0, - }, - }); - }, + }, + { + text: "Anchorage Area", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.610708034601548, + 1.0671172431736584, + 1900 + ), + orientation: { + heading: 4.6, + pitch: -0.341, + roll: 0.0, + }, + }); }, - { - text: "Peaks", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6928866820212813, - 1.072394255273859, - 3700 - ), - orientation: { - heading: 1.6308222948889464, - pitch: -0.6473480165020193, - roll: 0.0, - }, - }); - }, + }, + { + text: "Peaks", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6928866820212813, + 1.072394255273859, + 3700 + ), + orientation: { + heading: 1.6308222948889464, + pitch: -0.6473480165020193, + roll: 0.0, + }, + }); }, - { - text: "Riverbed", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -2.6395623497608596, - 1.0976443174490356, - 2070 - ), - orientation: { - heading: 6.068794108659519, - pitch: -0.08514161789475816, - roll: 0.0, - }, - }); - }, + }, + { + text: "Riverbed", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -2.6395623497608596, + 1.0976443174490356, + 2070 + ), + orientation: { + heading: 6.068794108659519, + pitch: -0.08514161789475816, + roll: 0.0, + }, + }); }, - ], - "toolbar" - ); - })(); //Sandcastle_End + }, + ], + "toolbar" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index a83c15167cc..f6b20444f25 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -37,300 +37,261 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - viewer.scene.globe.depthTestAgainstTerrain = true; + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - Sandcastle.addDefaultToolbarMenu( - [ - { - // - // To clamp points or billboards set the heightReference to CLAMP_TO_GROUND or RELATIVE_TO_GROUND - // - text: "Draw Point with Label", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - point: { - color: Cesium.Color.SKYBLUE, - pixelSize: 10, - outlineColor: Cesium.Color.YELLOW, - outlineWidth: 3, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - label: { - text: "Clamped to ground", - font: "14pt sans-serif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BASELINE, - fillColor: Cesium.Color.BLACK, - showBackground: true, - backgroundColor: new Cesium.Color(1, 1, 1, 0.7), - backgroundPadding: new Cesium.Cartesian2(8, 4), - disableDepthTestDistance: Number.POSITIVE_INFINITY, // draws the label in front of terrain - }, - }); + Sandcastle.addDefaultToolbarMenu( + [ + { + // + // To clamp points or billboards set the heightReference to CLAMP_TO_GROUND or RELATIVE_TO_GROUND + // + text: "Draw Point with Label", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + point: { + color: Cesium.Color.SKYBLUE, + pixelSize: 10, + outlineColor: Cesium.Color.YELLOW, + outlineWidth: 3, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + label: { + text: "Clamped to ground", + font: "14pt sans-serif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BASELINE, + fillColor: Cesium.Color.BLACK, + showBackground: true, + backgroundColor: new Cesium.Color(1, 1, 1, 0.7), + backgroundPadding: new Cesium.Cartesian2(8, 4), + disableDepthTestDistance: Number.POSITIVE_INFINITY, // draws the label in front of terrain + }, + }); - viewer.trackedEntity = e; - }, + viewer.trackedEntity = e; }, - { - text: "Draw Billboard", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - billboard: { - image: "../images/facility.gif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + }, + { + text: "Draw Billboard", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + billboard: { + image: "../images/facility.gif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - viewer.trackedEntity = e; - }, + viewer.trackedEntity = e; }, - { - // - // Corridors, polygons and rectangles will be clamped automatically if they are filled with a constant color and - // has no height or extruded height. - // NOTE: Setting height to 0 will disable clamping. - // - text: "Draw Corridor", - onselect: function () { - const e = viewer.entities.add({ - corridor: { - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.19, - 46.1914, - -122.21, - 46.21, - -122.23, - 46.21, - ]), - width: 2000.0, - material: Cesium.Color.GREEN.withAlpha(0.5), - }, - }); + }, + { + // + // Corridors, polygons and rectangles will be clamped automatically if they are filled with a constant color and + // has no height or extruded height. + // NOTE: Setting height to 0 will disable clamping. + // + text: "Draw Corridor", + onselect: function () { + const e = viewer.entities.add({ + corridor: { + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.19, + 46.1914, + -122.21, + 46.21, + -122.23, + 46.21, + ]), + width: 2000.0, + material: Cesium.Color.GREEN.withAlpha(0.5), + }, + }); - viewer.zoomTo(e); - }, + viewer.zoomTo(e); }, - { - text: "Draw Polygon", - onselect: function () { - const e = viewer.entities.add({ - polygon: { - hierarchy: { - positions: [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ], - }, - material: Cesium.Color.BLUE.withAlpha(0.5), + }, + { + text: "Draw Polygon", + onselect: function () { + const e = viewer.entities.add({ + polygon: { + hierarchy: { + positions: [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ], }, - }); + material: Cesium.Color.BLUE.withAlpha(0.5), + }, + }); - viewer.zoomTo(e); - }, + viewer.zoomTo(e); }, - { - text: "Draw Textured Polygon", - onselect: function () { - if ( - !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( - viewer.scene - ) - ) { - window.alert( - "Terrain Entity materials are not supported on this platform" - ); - return; - } + }, + { + text: "Draw Textured Polygon", + onselect: function () { + if ( + !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( + viewer.scene + ) + ) { + window.alert( + "Terrain Entity materials are not supported on this platform" + ); + return; + } - const e = viewer.entities.add({ - polygon: { - hierarchy: { - positions: [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ], - }, - material: "../images/Cesium_Logo_Color.jpg", - classificationType: Cesium.ClassificationType.TERRAIN, - stRotation: Cesium.Math.toRadians(45), + const e = viewer.entities.add({ + polygon: { + hierarchy: { + positions: [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ], }, - }); + material: "../images/Cesium_Logo_Color.jpg", + classificationType: Cesium.ClassificationType.TERRAIN, + stRotation: Cesium.Math.toRadians(45), + }, + }); - viewer.zoomTo(e); - }, + viewer.zoomTo(e); }, - { - text: "Draw Rectangle", - onselect: function () { - const e = viewer.entities.add({ - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.3, - 46.0, - -122.0, - 46.3 - ), - material: Cesium.Color.RED.withAlpha(0.5), - }, - }); + }, + { + text: "Draw Rectangle", + onselect: function () { + const e = viewer.entities.add({ + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.3, + 46.0, + -122.0, + 46.3 + ), + material: Cesium.Color.RED.withAlpha(0.5), + }, + }); - viewer.zoomTo(e); - }, + viewer.zoomTo(e); }, - { - text: "Draw Model", - onselect: function () { - const e = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - minimumPixelSize: 128, - maximumScale: 100, - }, - }); + }, + { + text: "Draw Model", + onselect: function () { + const e = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + minimumPixelSize: 128, + maximumScale: 100, + }, + }); - viewer.trackedEntity = e; - }, + viewer.trackedEntity = e; }, - { - text: "Sample line positions and draw with depth test disabled", - onselect: function () { - const length = 1000; + }, + { + text: "Sample line positions and draw with depth test disabled", + onselect: function () { + const length = 1000; - const startLon = Cesium.Math.toRadians(86.953793); - const endLon = Cesium.Math.toRadians(86.896497); - - const lat = Cesium.Math.toRadians(27.988257); - - const terrainSamplePositions = []; - for (let i = 0; i < length; ++i) { - const lon = Cesium.Math.lerp( - endLon, - startLon, - i / (length - 1) - ); - const position = new Cesium.Cartographic(lon, lat); - terrainSamplePositions.push(position); - } + const startLon = Cesium.Math.toRadians(86.953793); + const endLon = Cesium.Math.toRadians(86.896497); - Promise.resolve( - Cesium.sampleTerrainMostDetailed( - viewer.terrainProvider, - terrainSamplePositions - ) - ).then(function (samples) { - let offset = 10.0; - for (let i = 0; i < samples.length; ++i) { - samples[i].height += offset; - } + const lat = Cesium.Math.toRadians(27.988257); - viewer.entities.add({ - polyline: { - positions: Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray( - samples - ), - arcType: Cesium.ArcType.NONE, - width: 5, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.ORANGE, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty( - { - color: Cesium.Color.RED, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - } - ), - }, - }); + const terrainSamplePositions = []; + for (let i = 0; i < length; ++i) { + const lon = Cesium.Math.lerp( + endLon, + startLon, + i / (length - 1) + ); + const position = new Cesium.Cartographic(lon, lat); + terrainSamplePositions.push(position); + } - const target = new Cesium.Cartesian3( - 300770.50872389384, - 5634912.131394585, - 2978152.2865545116 - ); - offset = new Cesium.Cartesian3( - 6344.974098678562, - -793.3419798081741, - 2499.9508860763162 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); - }, - }, - { - text: "Draw polyline on terrain", - onselect: function () { - if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { - window.alert( - "Polylines on terrain are not supported on this platform" - ); + Promise.resolve( + Cesium.sampleTerrainMostDetailed( + viewer.terrainProvider, + terrainSamplePositions + ) + ).then(function (samples) { + let offset = 10.0; + for (let i = 0; i < samples.length; ++i) { + samples[i].height += offset; } viewer.entities.add({ polyline: { - positions: Cesium.Cartesian3.fromDegreesArray([ - 86.953793, - 27.928257, - 86.953793, - 27.988257, - 86.896497, - 27.988257, - ]), - clampToGround: true, + positions: Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray( + samples + ), + arcType: Cesium.ArcType.NONE, width: 5, material: new Cesium.PolylineOutlineMaterialProperty({ color: Cesium.Color.ORANGE, outlineWidth: 2, outlineColor: Cesium.Color.BLACK, }), + depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty( + { + color: Cesium.Color.RED, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + } + ), }, }); @@ -339,23 +300,67 @@ 5634912.131394585, 2978152.2865545116 ); - const offset = new Cesium.Cartesian3( + offset = new Cesium.Cartesian3( 6344.974098678562, -793.3419798081741, 2499.9508860763162 ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }, + }); + }, + }, + { + text: "Draw polyline on terrain", + onselect: function () { + if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { + window.alert( + "Polylines on terrain are not supported on this platform" + ); + } + + viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArray([ + 86.953793, + 27.928257, + 86.953793, + 27.988257, + 86.896497, + 27.988257, + ]), + clampToGround: true, + width: 5, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.ORANGE, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + }, + }); + + const target = new Cesium.Cartesian3( + 300770.50872389384, + 5634912.131394585, + 2978152.2865545116 + ); + const offset = new Cesium.Cartesian3( + 6344.974098678562, + -793.3419798081741, + 2499.9508860763162 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, - ], - "zoomButtons" - ); + }, + ], + "zoomButtons" + ); - Sandcastle.reset = function () { - viewer.entities.removeAll(); - }; - })(); //Sandcastle_End + Sandcastle.reset = function () { + viewer.entities.removeAll(); + }; + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 5d61ed4521f..3ac16b5dc61 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -35,141 +35,146 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); - tileset.readyPromise.then(function () { - const boundingSphere = tileset.boundingSphere; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - boundingSphere.radius + 500.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); + tileset.readyPromise.then(function () { + const boundingSphere = tileset.boundingSphere; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + boundingSphere.radius + 500.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromRadiansArray([ - -1.3194369277314022, - 0.6988062530900625, - -1.3193955980204217, - 0.6988091578771254, - -1.3193931220959367, - 0.698743632490865, - -1.3194358224045408, - 0.6987471965556998, - ]) - ), - material: Cesium.Color.RED.withAlpha(0.5), - classificationType: Cesium.ClassificationType.BOTH, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromRadiansArray([ + -1.3194369277314022, + 0.6988062530900625, + -1.3193955980204217, + 0.6988091578771254, + -1.3193931220959367, + 0.698743632490865, + -1.3194358224045408, + 0.6987471965556998, + ]) + ), + material: Cesium.Color.RED.withAlpha(0.5), + classificationType: Cesium.ClassificationType.BOTH, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArray([ - -75.60217330403601, - 40.04102882709425, - -75.59968252414251, - 40.04093615560871, - -75.598020153828, - 40.04079437042357, - -75.59674934074435, - 40.040816173283304, - -75.59630042791713, - 40.03986900370842, - -75.59563636849978, - 40.03930996506271, - -75.59492397899098, - 40.03873932846581, - -75.59457991226778, - 40.038392701955786, - -75.59424838652453, - 40.03775403572295, - -75.59387104290336, - 40.03677022167725, - -75.59355000490342, - 40.03588760913535, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArray([ + -75.60217330403601, + 40.04102882709425, + -75.59968252414251, + 40.04093615560871, + -75.598020153828, + 40.04079437042357, + -75.59674934074435, + 40.040816173283304, + -75.59630042791713, + 40.03986900370842, + -75.59563636849978, + 40.03930996506271, + -75.59492397899098, + 40.03873932846581, + -75.59457991226778, + 40.038392701955786, + -75.59424838652453, + 40.03775403572295, + -75.59387104290336, + 40.03677022167725, + -75.59355000490342, + 40.03588760913535, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const classificationOptions = [ - { - text: "Classify Both", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.BOTH; - polyline.polyline.classificationType = - Cesium.ClassificationType.BOTH; - }, + const classificationOptions = [ + { + text: "Classify Both", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.BOTH; + polyline.polyline.classificationType = + Cesium.ClassificationType.BOTH; }, - { - text: "Classify Terrain", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.TERRAIN; - polyline.polyline.classificationType = - Cesium.ClassificationType.TERRAIN; - }, + }, + { + text: "Classify Terrain", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.TERRAIN; + polyline.polyline.classificationType = + Cesium.ClassificationType.TERRAIN; }, - { - text: "Classify 3D Tiles", - onselect: function () { - polygon.polygon.classificationType = - Cesium.ClassificationType.CESIUM_3D_TILE; - polyline.polyline.classificationType = - Cesium.ClassificationType.CESIUM_3D_TILE; - }, + }, + { + text: "Classify 3D Tiles", + onselect: function () { + polygon.polygon.classificationType = + Cesium.ClassificationType.CESIUM_3D_TILE; + polyline.polyline.classificationType = + Cesium.ClassificationType.CESIUM_3D_TILE; }, - ]; + }, + ]; - const materialOptions = [ - { - text: "Red Material", - onselect: function () { - polygon.polygon.material = Cesium.Color.RED.withAlpha(0.5); - }, + const materialOptions = [ + { + text: "Red Material", + onselect: function () { + polygon.polygon.material = Cesium.Color.RED.withAlpha(0.5); }, - { - text: "Textured Material", - onselect: function () { - if ( - !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( - viewer.scene - ) - ) { - window.alert( - "Terrain Entity materials are not supported on this platform" - ); - } - polygon.polygon.material = "../images/Cesium_Logo_Color.jpg"; - }, + }, + { + text: "Textured Material", + onselect: function () { + if ( + !Cesium.Entity.supportsMaterialsforEntitiesOnTerrain( + viewer.scene + ) + ) { + window.alert( + "Terrain Entity materials are not supported on this platform" + ); + } + polygon.polygon.material = "../images/Cesium_Logo_Color.jpg"; }, - ]; + }, + ]; - Sandcastle.addToolbarMenu(classificationOptions); - Sandcastle.addToolbarMenu(materialOptions); - })(); //Sandcastle_End + Sandcastle.addToolbarMenu(classificationOptions); + Sandcastle.addToolbarMenu(materialOptions); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index 08684647634..96348e33498 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -42,83 +42,88 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + const scene = viewer.scene; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - scene.globe.depthTestAgainstTerrain = false; + scene.globe.depthTestAgainstTerrain = false; - // MAXAR OWT Muscatatuk photogrammetry dataset with property textures - // containing horizontal and vertical uncertainty - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(905848), - }) - ); + // MAXAR OWT Muscatatuk photogrammetry dataset with property textures + // containing horizontal and vertical uncertainty + const tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(905848), + }) + ); - viewer.zoomTo(tileset); + viewer.zoomTo(tileset); - const shaders = { - NO_TEXTURE: undefined, - UNCERTAINTY_CE90: new Cesium.CustomShader({ - fragmentShaderText: ` + const shaders = { + NO_TEXTURE: undefined, + UNCERTAINTY_CE90: new Cesium.CustomShader({ + fragmentShaderText: ` void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { int horizontalUncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum; material.diffuse = vec3(float(horizontalUncertainty) / 255.0); } `, - }), - UNCERTAINTY_LE90: new Cesium.CustomShader({ - fragmentShaderText: ` + }), + UNCERTAINTY_LE90: new Cesium.CustomShader({ + fragmentShaderText: ` void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { int verticalUncertainty = fsInput.metadata.r3dm_uncertainty_le90sum; material.diffuse = vec3(float(verticalUncertainty) / 255.0); } `, - }), - // combined uncertainty - UNCERTAINTY: new Cesium.CustomShader({ - fragmentShaderText: ` + }), + // combined uncertainty + UNCERTAINTY: new Cesium.CustomShader({ + fragmentShaderText: ` void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { int uncertainty = fsInput.metadata.r3dm_uncertainty_ce90sum + fsInput.metadata.r3dm_uncertainty_le90sum; material.diffuse = vec3(float(uncertainty) / 255.0); } `, - }), - }; + }), + }; - Sandcastle.addToolbarMenu([ - { - text: "Default View", - onselect: function () { - tileset.customShader = shaders.NO_TEXTURE; - }, + Sandcastle.addToolbarMenu([ + { + text: "Default View", + onselect: function () { + tileset.customShader = shaders.NO_TEXTURE; }, - { - text: "Horizontal Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY_CE90; - }, + }, + { + text: "Horizontal Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY_CE90; }, - { - text: "Vertical Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY_LE90; - }, + }, + { + text: "Vertical Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY_LE90; }, - { - text: "Combined Uncertainty", - onselect: function () { - tileset.customShader = shaders.UNCERTAINTY; - }, + }, + { + text: "Combined Uncertainty", + onselect: function () { + tileset.customShader = shaders.UNCERTAINTY; }, - ]); - })(); //Sandcastle_End + }, + ]); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index 31ee2ad43f5..ed942d46dc0 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -46,138 +46,141 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - selectionIndicator: false, - infoBox: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + selectionIndicator: false, + infoBox: false, + }); - if (!viewer.scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); } + })(); - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK - ); - function createPoint(worldPosition) { - const point = viewer.entities.add({ - position: worldPosition, - point: { - color: Cesium.Color.WHITE, - pixelSize: 5, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + if (!viewer.scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } + + viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( + Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK + ); + function createPoint(worldPosition) { + const point = viewer.entities.add({ + position: worldPosition, + point: { + color: Cesium.Color.WHITE, + pixelSize: 5, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + return point; + } + let drawingMode = "line"; + function drawShape(positionData) { + let shape; + if (drawingMode === "line") { + shape = viewer.entities.add({ + polyline: { + positions: positionData, + clampToGround: true, + width: 3, + }, + }); + } else if (drawingMode === "polygon") { + shape = viewer.entities.add({ + polygon: { + hierarchy: positionData, + material: new Cesium.ColorMaterialProperty( + Cesium.Color.WHITE.withAlpha(0.7) + ), }, }); - return point; - } - let drawingMode = "line"; - function drawShape(positionData) { - let shape; - if (drawingMode === "line") { - shape = viewer.entities.add({ - polyline: { - positions: positionData, - clampToGround: true, - width: 3, - }, - }); - } else if (drawingMode === "polygon") { - shape = viewer.entities.add({ - polygon: { - hierarchy: positionData, - material: new Cesium.ColorMaterialProperty( - Cesium.Color.WHITE.withAlpha(0.7) - ), - }, - }); - } - return shape; } - let activeShapePoints = []; - let activeShape; - let floatingPoint; - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (event) { - // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that - // we get the correct point when mousing over terrain. - const earthPosition = viewer.scene.pickPosition(event.position); - // `earthPosition` will be undefined if our mouse is not over the globe. - if (Cesium.defined(earthPosition)) { - if (activeShapePoints.length === 0) { - floatingPoint = createPoint(earthPosition); - activeShapePoints.push(earthPosition); - const dynamicPositions = new Cesium.CallbackProperty( - function () { - if (drawingMode === "polygon") { - return new Cesium.PolygonHierarchy(activeShapePoints); - } - return activeShapePoints; - }, - false - ); - activeShape = drawShape(dynamicPositions); - } + return shape; + } + let activeShapePoints = []; + let activeShape; + let floatingPoint; + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + handler.setInputAction(function (event) { + // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that + // we get the correct point when mousing over terrain. + const earthPosition = viewer.scene.pickPosition(event.position); + // `earthPosition` will be undefined if our mouse is not over the globe. + if (Cesium.defined(earthPosition)) { + if (activeShapePoints.length === 0) { + floatingPoint = createPoint(earthPosition); activeShapePoints.push(earthPosition); - createPoint(earthPosition); + const dynamicPositions = new Cesium.CallbackProperty(function () { + if (drawingMode === "polygon") { + return new Cesium.PolygonHierarchy(activeShapePoints); + } + return activeShapePoints; + }, false); + activeShape = drawShape(dynamicPositions); } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + activeShapePoints.push(earthPosition); + createPoint(earthPosition); + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - handler.setInputAction(function (event) { - if (Cesium.defined(floatingPoint)) { - const newPosition = viewer.scene.pickPosition(event.endPosition); - if (Cesium.defined(newPosition)) { - floatingPoint.position.setValue(newPosition); - activeShapePoints.pop(); - activeShapePoints.push(newPosition); - } + handler.setInputAction(function (event) { + if (Cesium.defined(floatingPoint)) { + const newPosition = viewer.scene.pickPosition(event.endPosition); + if (Cesium.defined(newPosition)) { + floatingPoint.position.setValue(newPosition); + activeShapePoints.pop(); + activeShapePoints.push(newPosition); } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Redraw the shape so it's not dynamic and remove the dynamic shape. - function terminateShape() { - activeShapePoints.pop(); - drawShape(activeShapePoints); - viewer.entities.remove(floatingPoint); - viewer.entities.remove(activeShape); - floatingPoint = undefined; - activeShape = undefined; - activeShapePoints = []; } - handler.setInputAction(function (event) { - terminateShape(); - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Redraw the shape so it's not dynamic and remove the dynamic shape. + function terminateShape() { + activeShapePoints.pop(); + drawShape(activeShapePoints); + viewer.entities.remove(floatingPoint); + viewer.entities.remove(activeShape); + floatingPoint = undefined; + activeShape = undefined; + activeShapePoints = []; + } + handler.setInputAction(function (event) { + terminateShape(); + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - const options = [ - { - text: "Draw Lines", - onselect: function () { - if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { - window.alert( - "This browser does not support polylines on terrain." - ); - } + const options = [ + { + text: "Draw Lines", + onselect: function () { + if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) { + window.alert( + "This browser does not support polylines on terrain." + ); + } - terminateShape(); - drawingMode = "line"; - }, + terminateShape(); + drawingMode = "line"; }, - { - text: "Draw Polygons", - onselect: function () { - terminateShape(); - drawingMode = "polygon"; - }, + }, + { + text: "Draw Polygons", + onselect: function () { + terminateShape(); + drawingMode = "polygon"; }, - ]; + }, + ]; - Sandcastle.addToolbarMenu(options); - // Zoom in to an area with mountains - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - })(); //Sandcastle_End + Sandcastle.addToolbarMenu(options); + // Zoom in to an area with mountains + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index d89013be7dc..05ac4f4bae7 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -34,114 +34,116 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const pinBuilder = new Cesium.PinBuilder(); + const pinBuilder = new Cesium.PinBuilder(); - Sandcastle.addToolbarMenu( - [ - { - text: "Track with Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/lamina.gpx", - { - clampToGround: true, - } - ) + Sandcastle.addToolbarMenu( + [ + { + text: "Track with Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/lamina.gpx", + { + clampToGround: true, + } ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); - }, + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); }, - { - text: "Route", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/route.gpx", - { - clampToGround: true, - } - ) + }, + { + text: "Route", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/route.gpx", + { + clampToGround: true, + } ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); - }, + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); }, - { - text: "Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/wpt.gpx", - { - clampToGround: true, - } - ) - ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); - }, + }, + { + text: "Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load("../../SampleData/gpx/wpt.gpx", { + clampToGround: true, + }) + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); }, - { - text: "Multiple Tracks with Waypoints", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/complexTrk.gpx", - { clampToGround: true } - ) + }, + { + text: "Multiple Tracks with Waypoints", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/complexTrk.gpx", + { clampToGround: true } ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); - }, + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); }, - { - text: "Symbology Options", - onselect: function () { - viewer.dataSources - .add( - Cesium.GpxDataSource.load( - "../../SampleData/gpx/lamina.gpx", - { - clampToGround: true, - trackColor: Cesium.Color.YELLOW, - waypointImage: pinBuilder.fromMakiIconId( - "bicycle", - Cesium.Color.BLUE, - 48 - ), - } - ) + }, + { + text: "Symbology Options", + onselect: function () { + viewer.dataSources + .add( + Cesium.GpxDataSource.load( + "../../SampleData/gpx/lamina.gpx", + { + clampToGround: true, + trackColor: Cesium.Color.YELLOW, + waypointImage: pinBuilder.fromMakiIconId( + "bicycle", + Cesium.Color.BLUE, + 48 + ), + } ) - .then(function (dataSource) { - viewer.flyTo(dataSource.entities); - }); - }, + ) + .then(function (dataSource) { + viewer.flyTo(dataSource.entities); + }); }, - ], - "toolbar" - ); + }, + ], + "toolbar" + ); - Sandcastle.reset = function () { - viewer.dataSources.removeAll(); - viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED; - viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; - }; - })(); //Sandcastle_End + Sandcastle.reset = function () { + viewer.dataSources.removeAll(); + viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED; + viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; + }; + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index 2353d15188a..d2f0b09a20b 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -35,143 +35,152 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const cesiumTerrainProvider = await Cesium.createWorldTerrainAsync(); - const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); - const viewer = new Cesium.Viewer("cesiumContainer", { - baseLayerPicker: false, - terrainProvider: cesiumTerrainProvider, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + baseLayerPicker: false, + }); - // depth test against terrain is required to make the polygons clamp to terrain - // instead of showing through it from underground - viewer.scene.globe.depthTestAgainstTerrain = true; + // depth test against terrain is required to make the polygons clamp to terrain + // instead of showing through it from underground + viewer.scene.globe.depthTestAgainstTerrain = true; - Sandcastle.addToolbarMenu([ - { - text: "Polygons", - onselect: function () { - viewer.entities.removeAll(); - addPolygons(); - }, + Sandcastle.addToolbarMenu([ + { + text: "Polygons", + onselect: function () { + viewer.entities.removeAll(); + addPolygons(); }, - { - text: "Boxes, Cylinders and Ellipsoids", - onselect: function () { - viewer.entities.removeAll(); - addGeometries(); - }, + }, + { + text: "Boxes, Cylinders and Ellipsoids", + onselect: function () { + viewer.entities.removeAll(); + addGeometries(); }, - ]); + }, + ]); - Sandcastle.addToolbarMenu([ - { - text: "Terrain Enabled", - onselect: async function () { - viewer.scene.terrainProvider = cesiumTerrainProvider; - }, + Sandcastle.addToolbarMenu([ + { + text: "Terrain Enabled", + onselect: async function () { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } }, - { - text: "Terrain Disabled", - onselect: function () { - viewer.scene.terrainProvider = ellipsoidTerrainProvider; - }, + }, + { + text: "Terrain Disabled", + onselect: function () { + viewer.scene.terrainProvider = ellipsoidTerrainProvider; }, - ]); + }, + ]); - const longitude = 6.950615989890521; - const latitude = 45.79546589994886; - const delta = 0.001; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - function addGeometry(i, j) { - const west = longitude + delta * i; - const north = latitude + delta * j + delta; + const longitude = 6.950615989890521; + const latitude = 45.79546589994886; + const delta = 0.001; - const type = Math.floor(Math.random() * 3); - if (type === 0) { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - box: { - dimensions: new Cesium.Cartesian3(40.0, 30.0, 50.0), - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } else if (type === 1) { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - cylinder: { - length: 50.0, - topRadius: 20.0, - bottomRadius: 20.0, - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } else { - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), - ellipsoid: { - radii: new Cesium.Cartesian3(20.0, 15.0, 25.0), - material: Cesium.Color.fromRandom({ alpha: 1.0 }), - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } + function addGeometry(i, j) { + const west = longitude + delta * i; + const north = latitude + delta * j + delta; + + const type = Math.floor(Math.random() * 3); + if (type === 0) { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + box: { + dimensions: new Cesium.Cartesian3(40.0, 30.0, 50.0), + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } else if (type === 1) { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + cylinder: { + length: 50.0, + topRadius: 20.0, + bottomRadius: 20.0, + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } else { + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(west, north, 0.0), + ellipsoid: { + radii: new Cesium.Cartesian3(20.0, 15.0, 25.0), + material: Cesium.Color.fromRandom({ alpha: 1.0 }), + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); } + } - function addGeometries() { - for (let i = 0; i < 4; i++) { - for (let j = 0; j < 4; j++) { - addGeometry(i, j); - } + function addGeometries() { + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 4; j++) { + addGeometry(i, j); } - viewer.zoomTo(viewer.entities); } + viewer.zoomTo(viewer.entities); + } - function addPolygon(i, j) { - const west = longitude + delta * i; - const east = longitude + delta * i + delta; + function addPolygon(i, j) { + const west = longitude + delta * i; + const east = longitude + delta * i + delta; - const south = latitude + delta * j; - const north = latitude + delta * j + delta; - const a = Cesium.Cartesian3.fromDegrees(west, south); - const b = Cesium.Cartesian3.fromDegrees(west, north); - const c = Cesium.Cartesian3.fromDegrees(east, north); - const d = Cesium.Cartesian3.fromDegrees(east, south); + const south = latitude + delta * j; + const north = latitude + delta * j + delta; + const a = Cesium.Cartesian3.fromDegrees(west, south); + const b = Cesium.Cartesian3.fromDegrees(west, north); + const c = Cesium.Cartesian3.fromDegrees(east, north); + const d = Cesium.Cartesian3.fromDegrees(east, south); - const positions = [a, b, c, d]; - viewer.entities.add({ - polygon: { - hierarchy: positions, - material: Cesium.Color.fromRandom({ alpha: 1 }), - height: 40.0, - heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, - extrudedHeight: 0.0, - extrudedHeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); - } + const positions = [a, b, c, d]; + viewer.entities.add({ + polygon: { + hierarchy: positions, + material: Cesium.Color.fromRandom({ alpha: 1 }), + height: 40.0, + heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, + extrudedHeight: 0.0, + extrudedHeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); + } - function addPolygons() { - // create 16 polygons that are side-by-side - for (let i = 0; i < 4; i++) { - for (let j = 0; j < 4; j++) { - addPolygon(i, j); - } + function addPolygons() { + // create 16 polygons that are side-by-side + for (let i = 0; i < 4; i++) { + for (let j = 0; j < 4; j++) { + addPolygon(i, j); } - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(longitude, latitude, 1500), - new Cesium.HeadingPitchRange( - -Cesium.Math.PI / 2, - -Cesium.Math.PI_OVER_FOUR, - 2000 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } - })(); //Sandcastle_End + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(longitude, latitude, 1500), + new Cesium.HeadingPitchRange( + -Cesium.Math.PI / 2, + -Cesium.Math.PI_OVER_FOUR, + 2000 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index a262dd6ce7a..c9f92c36190 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -122,304 +122,308 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + viewer.scene.globe.enableLighting = true; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ requestVertexNormals: true, //Needed to visualize slope - }), - }); - viewer.scene.globe.enableLighting = true; + }); + } catch (error) { + console.log(error); + } + })(); - function getElevationContourMaterial() { - // Creates a composite material with both elevation shading and contour lines - return new Cesium.Material({ - fabric: { - type: "ElevationColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", - }, - elevationRampMaterial: { - type: "ElevationRamp", - }, + function getElevationContourMaterial() { + // Creates a composite material with both elevation shading and contour lines + return new Cesium.Material({ + fabric: { + type: "ElevationColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse", - alpha: - "max(contourMaterial.alpha, elevationRampMaterial.alpha)", + elevationRampMaterial: { + type: "ElevationRamp", }, }, - translucent: false, - }); - } + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse", + alpha: + "max(contourMaterial.alpha, elevationRampMaterial.alpha)", + }, + }, + translucent: false, + }); + } - function getSlopeContourMaterial() { - // Creates a composite material with both slope shading and contour lines - return new Cesium.Material({ - fabric: { - type: "SlopeColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", - }, - slopeRampMaterial: { - type: "SlopeRamp", - }, + function getSlopeContourMaterial() { + // Creates a composite material with both slope shading and contour lines + return new Cesium.Material({ + fabric: { + type: "SlopeColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? slopeRampMaterial.diffuse : contourMaterial.diffuse", - alpha: "max(contourMaterial.alpha, slopeRampMaterial.alpha)", + slopeRampMaterial: { + type: "SlopeRamp", }, }, - translucent: false, - }); - } + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? slopeRampMaterial.diffuse : contourMaterial.diffuse", + alpha: "max(contourMaterial.alpha, slopeRampMaterial.alpha)", + }, + }, + translucent: false, + }); + } - function getAspectContourMaterial() { - // Creates a composite material with both aspect shading and contour lines - return new Cesium.Material({ - fabric: { - type: "AspectColorContour", - materials: { - contourMaterial: { - type: "ElevationContour", - }, - aspectRampMaterial: { - type: "AspectRamp", - }, + function getAspectContourMaterial() { + // Creates a composite material with both aspect shading and contour lines + return new Cesium.Material({ + fabric: { + type: "AspectColorContour", + materials: { + contourMaterial: { + type: "ElevationContour", }, - components: { - diffuse: - "contourMaterial.alpha == 0.0 ? aspectRampMaterial.diffuse : contourMaterial.diffuse", - alpha: "max(contourMaterial.alpha, aspectRampMaterial.alpha)", + aspectRampMaterial: { + type: "AspectRamp", }, }, - translucent: false, - }); - } + components: { + diffuse: + "contourMaterial.alpha == 0.0 ? aspectRampMaterial.diffuse : contourMaterial.diffuse", + alpha: "max(contourMaterial.alpha, aspectRampMaterial.alpha)", + }, + }, + translucent: false, + }); + } - const elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0]; - const slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2) / 2, 0.87, 0.91, 1.0]; - const aspectRamp = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0]; - function getColorRamp(selectedShading) { - const ramp = document.createElement("canvas"); - ramp.width = 100; - ramp.height = 1; - const ctx = ramp.getContext("2d"); + const elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0]; + const slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2) / 2, 0.87, 0.91, 1.0]; + const aspectRamp = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0]; + function getColorRamp(selectedShading) { + const ramp = document.createElement("canvas"); + ramp.width = 100; + ramp.height = 1; + const ctx = ramp.getContext("2d"); - let values; - if (selectedShading === "elevation") { - values = elevationRamp; - } else if (selectedShading === "slope") { - values = slopeRamp; - } else if (selectedShading === "aspect") { - values = aspectRamp; - } + let values; + if (selectedShading === "elevation") { + values = elevationRamp; + } else if (selectedShading === "slope") { + values = slopeRamp; + } else if (selectedShading === "aspect") { + values = aspectRamp; + } - const grd = ctx.createLinearGradient(0, 0, 100, 0); - grd.addColorStop(values[0], "#000000"); //black - grd.addColorStop(values[1], "#2747E0"); //blue - grd.addColorStop(values[2], "#D33B7D"); //pink - grd.addColorStop(values[3], "#D33038"); //red - grd.addColorStop(values[4], "#FF9742"); //orange - grd.addColorStop(values[5], "#ffd700"); //yellow - grd.addColorStop(values[6], "#ffffff"); //white + const grd = ctx.createLinearGradient(0, 0, 100, 0); + grd.addColorStop(values[0], "#000000"); //black + grd.addColorStop(values[1], "#2747E0"); //blue + grd.addColorStop(values[2], "#D33B7D"); //pink + grd.addColorStop(values[3], "#D33038"); //red + grd.addColorStop(values[4], "#FF9742"); //orange + grd.addColorStop(values[5], "#ffd700"); //yellow + grd.addColorStop(values[6], "#ffffff"); //white - ctx.fillStyle = grd; - ctx.fillRect(0, 0, 100, 1); + ctx.fillStyle = grd; + ctx.fillRect(0, 0, 100, 1); - return ramp; - } + return ramp; + } - const minHeight = -414.0; // approximate dead sea elevation - const maxHeight = 8777.0; // approximate everest elevation - const contourColor = Cesium.Color.RED.clone(); - let contourUniforms = {}; - let shadingUniforms = {}; + const minHeight = -414.0; // approximate dead sea elevation + const maxHeight = 8777.0; // approximate everest elevation + const contourColor = Cesium.Color.RED.clone(); + let contourUniforms = {}; + let shadingUniforms = {}; - // The viewModel tracks the state of our mini application. - const viewModel = { - enableContour: false, - contourSpacing: 150.0, - contourWidth: 2.0, - selectedShading: "elevation", - changeColor: function () { - contourUniforms.color = Cesium.Color.fromRandom( - { alpha: 1.0 }, - contourColor - ); - }, - }; + // The viewModel tracks the state of our mini application. + const viewModel = { + enableContour: false, + contourSpacing: 150.0, + contourWidth: 2.0, + selectedShading: "elevation", + changeColor: function () { + contourUniforms.color = Cesium.Color.fromRandom( + { alpha: 1.0 }, + contourColor + ); + }, + }; - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - function updateMaterial() { - const hasContour = viewModel.enableContour; - const selectedShading = viewModel.selectedShading; - const globe = viewer.scene.globe; - let material; - if (hasContour) { - if (selectedShading === "elevation") { - material = getElevationContourMaterial(); - shadingUniforms = - material.materials.elevationRampMaterial.uniforms; - shadingUniforms.minimumHeight = minHeight; - shadingUniforms.maximumHeight = maxHeight; - contourUniforms = material.materials.contourMaterial.uniforms; - } else if (selectedShading === "slope") { - material = getSlopeContourMaterial(); - shadingUniforms = material.materials.slopeRampMaterial.uniforms; - contourUniforms = material.materials.contourMaterial.uniforms; - } else if (selectedShading === "aspect") { - material = getAspectContourMaterial(); - shadingUniforms = - material.materials.aspectRampMaterial.uniforms; - contourUniforms = material.materials.contourMaterial.uniforms; - } else { - material = Cesium.Material.fromType("ElevationContour"); - contourUniforms = material.uniforms; - } - contourUniforms.width = viewModel.contourWidth; - contourUniforms.spacing = viewModel.contourSpacing; - contourUniforms.color = contourColor; - } else if (selectedShading === "elevation") { - material = Cesium.Material.fromType("ElevationRamp"); - shadingUniforms = material.uniforms; + function updateMaterial() { + const hasContour = viewModel.enableContour; + const selectedShading = viewModel.selectedShading; + const globe = viewer.scene.globe; + let material; + if (hasContour) { + if (selectedShading === "elevation") { + material = getElevationContourMaterial(); + shadingUniforms = + material.materials.elevationRampMaterial.uniforms; shadingUniforms.minimumHeight = minHeight; shadingUniforms.maximumHeight = maxHeight; + contourUniforms = material.materials.contourMaterial.uniforms; } else if (selectedShading === "slope") { - material = Cesium.Material.fromType("SlopeRamp"); - shadingUniforms = material.uniforms; + material = getSlopeContourMaterial(); + shadingUniforms = material.materials.slopeRampMaterial.uniforms; + contourUniforms = material.materials.contourMaterial.uniforms; } else if (selectedShading === "aspect") { - material = Cesium.Material.fromType("AspectRamp"); - shadingUniforms = material.uniforms; + material = getAspectContourMaterial(); + shadingUniforms = material.materials.aspectRampMaterial.uniforms; + contourUniforms = material.materials.contourMaterial.uniforms; + } else { + material = Cesium.Material.fromType("ElevationContour"); + contourUniforms = material.uniforms; } - if (selectedShading !== "none") { - shadingUniforms.image = getColorRamp(selectedShading); - } - - globe.material = material; + contourUniforms.width = viewModel.contourWidth; + contourUniforms.spacing = viewModel.contourSpacing; + contourUniforms.color = contourColor; + } else if (selectedShading === "elevation") { + material = Cesium.Material.fromType("ElevationRamp"); + shadingUniforms = material.uniforms; + shadingUniforms.minimumHeight = minHeight; + shadingUniforms.maximumHeight = maxHeight; + } else if (selectedShading === "slope") { + material = Cesium.Material.fromType("SlopeRamp"); + shadingUniforms = material.uniforms; + } else if (selectedShading === "aspect") { + material = Cesium.Material.fromType("AspectRamp"); + shadingUniforms = material.uniforms; + } + if (selectedShading !== "none") { + shadingUniforms.image = getColorRamp(selectedShading); } - updateMaterial(); + globe.material = material; + } - Cesium.knockout - .getObservable(viewModel, "enableContour") - .subscribe(function (newValue) { - updateMaterial(); - }); + updateMaterial(); - Cesium.knockout - .getObservable(viewModel, "contourWidth") - .subscribe(function (newValue) { - contourUniforms.width = parseFloat(newValue); - }); + Cesium.knockout + .getObservable(viewModel, "enableContour") + .subscribe(function (newValue) { + updateMaterial(); + }); - Cesium.knockout - .getObservable(viewModel, "contourSpacing") - .subscribe(function (newValue) { - contourUniforms.spacing = parseFloat(newValue); - }); + Cesium.knockout + .getObservable(viewModel, "contourWidth") + .subscribe(function (newValue) { + contourUniforms.width = parseFloat(newValue); + }); - Cesium.knockout - .getObservable(viewModel, "selectedShading") - .subscribe(function (value) { - updateMaterial(); - }); + Cesium.knockout + .getObservable(viewModel, "contourSpacing") + .subscribe(function (newValue) { + contourUniforms.spacing = parseFloat(newValue); + }); - Sandcastle.addToolbarMenu( - [ - { - text: "Himalayas", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 322100.7492728492, - 5917960.047024654, - 3077602.646977297 - ), - orientation: { - heading: 5.988151498702285, - pitch: -1.5614542839414822, - roll: 0, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T04:00:00Z" - ); - }, + Cesium.knockout + .getObservable(viewModel, "selectedShading") + .subscribe(function (value) { + updateMaterial(); + }); + + Sandcastle.addToolbarMenu( + [ + { + text: "Himalayas", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 322100.7492728492, + 5917960.047024654, + 3077602.646977297 + ), + orientation: { + heading: 5.988151498702285, + pitch: -1.5614542839414822, + roll: 0, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T04:00:00Z" + ); }, - { - text: "Half Dome", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2495709.521843174, - -4391600.804712465, - 3884463.7192916023 - ), - orientation: { - heading: 1.7183056487769202, - pitch: -0.06460370548034144, - roll: 0.0079181631783527, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T18:00:00Z" - ); - }, + }, + { + text: "Half Dome", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2495709.521843174, + -4391600.804712465, + 3884463.7192916023 + ), + orientation: { + heading: 1.7183056487769202, + pitch: -0.06460370548034144, + roll: 0.0079181631783527, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T18:00:00Z" + ); }, - { - text: "Vancouver", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2301222.367751603, - -3485269.915771613, - 4812080.961755785 - ), - orientation: { - heading: 0.11355958593902571, - pitch: -0.260011078090858, - roll: 0.00039019018274721873, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T18:00:00Z" - ); - }, + }, + { + text: "Vancouver", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2301222.367751603, + -3485269.915771613, + 4812080.961755785 + ), + orientation: { + heading: 0.11355958593902571, + pitch: -0.260011078090858, + roll: 0.00039019018274721873, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T18:00:00Z" + ); }, - { - text: "Mount Everest", - onselect: function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 282157.6960889096, - 5638892.465594703, - 2978736.186473513 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); - viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( - "2017-09-22T04:00:00Z" - ); - }, + }, + { + text: "Mount Everest", + onselect: function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 282157.6960889096, + 5638892.465594703, + 2978736.186473513 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); + viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601( + "2017-09-22T04:00:00Z" + ); }, - ], - "zoomButtons" - ); - })(); //Sandcastle_End + }, + ], + "zoomButtons" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index 61d91ea1cb2..5c85423b399 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -37,175 +37,176 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, //Disable InfoBox widget - selectionIndicator: false, //Disable selection indicator - shouldAnimate: true, // Enable animations - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - - //Enable lighting based on the sun position - viewer.scene.globe.enableLighting = true; - - //Enable depth testing so things behind the terrain disappear. - viewer.scene.globe.depthTestAgainstTerrain = true; - - //Set the random number seed for consistent results. - Cesium.Math.setRandomNumberSeed(3); - - //Set bounds of our simulation time - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, //Disable InfoBox widget + selectionIndicator: false, //Disable selection indicator + shouldAnimate: true, // Enable animations + }); - //Make sure viewer is at the desired time. - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end - viewer.clock.multiplier = 10; - - //Set timeline to simulation bounds - viewer.timeline.zoomTo(start, stop); - - //Generate a random circular pattern with varying heights. - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - for (let i = 0; i <= 360; i += 45) { - const radians = Cesium.Math.toRadians(i); - const time = Cesium.JulianDate.addSeconds( - start, - i, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1750 - ); - property.addSample(time, position); - - //Also create a point for each sample we generate. - viewer.entities.add({ - position: position, - point: { - pixelSize: 8, - color: Cesium.Color.TRANSPARENT, - outlineColor: Cesium.Color.YELLOW, - outlineWidth: 3, - }, - }); - } - return property; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); } - - //Compute the entity position property. - const position = computeCirclularFlight( - -112.110693, - 36.0994841, - 0.03 - ); - - //Actually create the entity - const entity = viewer.entities.add({ - //Set the entity availability to the same interval as the simulation time. - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - - //Use our computed positions - position: position, - - //Automatically compute orientation based on position movement. - orientation: new Cesium.VelocityOrientationProperty(position), - - //Load the Cesium plane model to represent the entity - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - minimumPixelSize: 64, - }, - - //Show the path as a pink line sampled in 1 second increments. - path: { - resolution: 1, - material: new Cesium.PolylineGlowMaterialProperty({ - glowPower: 0.1, - color: Cesium.Color.YELLOW, - }), - width: 10, - }, - }); - - //Add button to view the path from the top down - Sandcastle.addDefaultToolbarButton("View Top Down", function () { - viewer.trackedEntity = undefined; - viewer.zoomTo( - viewer.entities, - new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)) + })(); + + //Enable lighting based on the sun position + viewer.scene.globe.enableLighting = true; + + //Enable depth testing so things behind the terrain disappear. + viewer.scene.globe.depthTestAgainstTerrain = true; + + //Set the random number seed for consistent results. + Cesium.Math.setRandomNumberSeed(3); + + //Set bounds of our simulation time + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() + ); + + //Make sure viewer is at the desired time. + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end + viewer.clock.multiplier = 10; + + //Set timeline to simulation bounds + viewer.timeline.zoomTo(start, stop); + + //Generate a random circular pattern with varying heights. + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + for (let i = 0; i <= 360; i += 45) { + const radians = Cesium.Math.toRadians(i); + const time = Cesium.JulianDate.addSeconds( + start, + i, + new Cesium.JulianDate() ); - }); - - //Add button to view the path from the side - Sandcastle.addToolbarButton("View Side", function () { - viewer.trackedEntity = undefined; - viewer.zoomTo( - viewer.entities, - new Cesium.HeadingPitchRange( - Cesium.Math.toRadians(-90), - Cesium.Math.toRadians(-15), - 7500 - ) + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1750 ); - }); - - //Add button to track the entity as it moves - Sandcastle.addToolbarButton("View Aircraft", function () { - viewer.trackedEntity = entity; - }); - - //Add a combo box for selecting each interpolation mode. - Sandcastle.addToolbarMenu( - [ - { - text: "Interpolation: Linear Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 1, - interpolationAlgorithm: Cesium.LinearApproximation, - }); - }, + property.addSample(time, position); + + //Also create a point for each sample we generate. + viewer.entities.add({ + position: position, + point: { + pixelSize: 8, + color: Cesium.Color.TRANSPARENT, + outlineColor: Cesium.Color.YELLOW, + outlineWidth: 3, }, - { - text: "Interpolation: Lagrange Polynomial Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 5, - interpolationAlgorithm: - Cesium.LagrangePolynomialApproximation, - }); - }, + }); + } + return property; + } + + //Compute the entity position property. + const position = computeCirclularFlight(-112.110693, 36.0994841, 0.03); + + //Actually create the entity + const entity = viewer.entities.add({ + //Set the entity availability to the same interval as the simulation time. + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + + //Use our computed positions + position: position, + + //Automatically compute orientation based on position movement. + orientation: new Cesium.VelocityOrientationProperty(position), + + //Load the Cesium plane model to represent the entity + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + minimumPixelSize: 64, + }, + + //Show the path as a pink line sampled in 1 second increments. + path: { + resolution: 1, + material: new Cesium.PolylineGlowMaterialProperty({ + glowPower: 0.1, + color: Cesium.Color.YELLOW, + }), + width: 10, + }, + }); + + //Add button to view the path from the top down + Sandcastle.addDefaultToolbarButton("View Top Down", function () { + viewer.trackedEntity = undefined; + viewer.zoomTo( + viewer.entities, + new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)) + ); + }); + + //Add button to view the path from the side + Sandcastle.addToolbarButton("View Side", function () { + viewer.trackedEntity = undefined; + viewer.zoomTo( + viewer.entities, + new Cesium.HeadingPitchRange( + Cesium.Math.toRadians(-90), + Cesium.Math.toRadians(-15), + 7500 + ) + ); + }); + + //Add button to track the entity as it moves + Sandcastle.addToolbarButton("View Aircraft", function () { + viewer.trackedEntity = entity; + }); + + //Add a combo box for selecting each interpolation mode. + Sandcastle.addToolbarMenu( + [ + { + text: "Interpolation: Linear Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 1, + interpolationAlgorithm: Cesium.LinearApproximation, + }); + }, + }, + { + text: "Interpolation: Lagrange Polynomial Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 5, + interpolationAlgorithm: + Cesium.LagrangePolynomialApproximation, + }); }, - { - text: "Interpolation: Hermite Polynomial Approximation", - onselect: function () { - entity.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: - Cesium.HermitePolynomialApproximation, - }); - }, + }, + { + text: "Interpolation: Hermite Polynomial Approximation", + onselect: function () { + entity.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); }, - ], - "interpolationMenu" - ); - })(); //Sandcastle_End + }, + ], + "interpolationMenu" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index a4083d6edb7..38cc8b0ee9c 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -32,205 +32,206 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + const scene = viewer.scene; + scene.globe.enableLighting = true; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ requestWaterMask: true, requestVertexNormals: true, - }), - }); - - const scene = viewer.scene; - scene.globe.enableLighting = true; - - const scratchIcrfToFixed = new Cesium.Matrix3(); - const scratchMoonPosition = new Cesium.Cartesian3(); - const scratchMoonDirection = new Cesium.Cartesian3(); - - function getMoonDirection(result) { - result = Cesium.defined(result) ? result : new Cesium.Cartesian3(); - const icrfToFixed = scratchIcrfToFixed; - const date = viewer.clock.currentTime; - if ( - !Cesium.defined( - Cesium.Transforms.computeIcrfToFixedMatrix(date, icrfToFixed) - ) - ) { - Cesium.Transforms.computeTemeToPseudoFixedMatrix( - date, - icrfToFixed - ); - } - const moonPosition = Cesium.Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame( - date, - scratchMoonPosition - ); - Cesium.Matrix3.multiplyByVector( - icrfToFixed, - moonPosition, - moonPosition - ); - const moonDirection = Cesium.Cartesian3.normalize( - moonPosition, - scratchMoonDirection - ); - return Cesium.Cartesian3.negate(moonDirection, result); + }); + } catch (error) { + console.log(error); } - - const directionalLight = new Cesium.DirectionalLight({ - direction: new Cesium.Cartesian3( - 0.2454278300540191, - 0.8842635425193919, - 0.39729481195458805 - ), - }); - - const flashlight = new Cesium.DirectionalLight({ - direction: scene.camera.directionWC, // Updated every frame - }); - - const moonLight = new Cesium.DirectionalLight({ - direction: getMoonDirection(), // Updated every frame - color: new Cesium.Color(0.9, 0.925, 1.0), - intensity: 0.5, - }); - - const sunLight = new Cesium.SunLight(); - - const customColorLight = new Cesium.DirectionalLight({ - direction: new Cesium.Cartesian3( - -0.2454278300540191, - 0.8842635425193919, - 0.39729481195458805 - ), - color: Cesium.Color.fromCssColorString("#deca7c"), - }); - - scene.preRender.addEventListener(function (scene, time) { - if (scene.light === flashlight) { - scene.light.direction = Cesium.Cartesian3.clone( - scene.camera.directionWC, - scene.light.direction - ); - } else if (scene.light === moonLight) { - scene.light.direction = getMoonDirection(scene.light.direction); - } - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.1463338399937277, - 0.6677959688982861, - 32.18991401746337 - ), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - scale: 7.0, - }, - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.14633449752228, - 0.667796065242357, - 24.47647034111423 - ), - cylinder: { - length: 8.0, - topRadius: 2.0, - bottomRadius: 2.0, - material: Cesium.Color.WHITE, - }, - }); - - viewer.entities.add({ - position: Cesium.Cartesian3.fromRadians( - -2.1463332294173365, - 0.6677959755384729, - 26.2876064083145 - ), - ellipsoid: { - radii: new Cesium.Cartesian3(2.5, 2.5, 2.5), - material: Cesium.Color.WHITE.withAlpha(0.5), - }, - }); - - function setTime(iso8601) { - const currentTime = Cesium.JulianDate.fromIso8601(iso8601); - const endTime = Cesium.JulianDate.addDays( - currentTime, - 2, - new Cesium.JulianDate() - ); - - viewer.clock.currentTime = currentTime; - viewer.timeline.zoomTo(currentTime, endTime); + })(); + + const scratchIcrfToFixed = new Cesium.Matrix3(); + const scratchMoonPosition = new Cesium.Cartesian3(); + const scratchMoonDirection = new Cesium.Cartesian3(); + + function getMoonDirection(result) { + result = Cesium.defined(result) ? result : new Cesium.Cartesian3(); + const icrfToFixed = scratchIcrfToFixed; + const date = viewer.clock.currentTime; + if ( + !Cesium.defined( + Cesium.Transforms.computeIcrfToFixedMatrix(date, icrfToFixed) + ) + ) { + Cesium.Transforms.computeTemeToPseudoFixedMatrix(date, icrfToFixed); } - - function reset() { - // Set scene defaults - scene.light = sunLight; - scene.globe.dynamicAtmosphereLighting = true; - scene.globe.dynamicAtmosphereLightingFromSun = false; - setTime("2020-01-09T23:00:39.018261982600961346Z"); + const moonPosition = Cesium.Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame( + date, + scratchMoonPosition + ); + Cesium.Matrix3.multiplyByVector( + icrfToFixed, + moonPosition, + moonPosition + ); + const moonDirection = Cesium.Cartesian3.normalize( + moonPosition, + scratchMoonDirection + ); + return Cesium.Cartesian3.negate(moonDirection, result); + } + + const directionalLight = new Cesium.DirectionalLight({ + direction: new Cesium.Cartesian3( + 0.2454278300540191, + 0.8842635425193919, + 0.39729481195458805 + ), + }); + + const flashlight = new Cesium.DirectionalLight({ + direction: scene.camera.directionWC, // Updated every frame + }); + + const moonLight = new Cesium.DirectionalLight({ + direction: getMoonDirection(), // Updated every frame + color: new Cesium.Color(0.9, 0.925, 1.0), + intensity: 0.5, + }); + + const sunLight = new Cesium.SunLight(); + + const customColorLight = new Cesium.DirectionalLight({ + direction: new Cesium.Cartesian3( + -0.2454278300540191, + 0.8842635425193919, + 0.39729481195458805 + ), + color: Cesium.Color.fromCssColorString("#deca7c"), + }); + + scene.preRender.addEventListener(function (scene, time) { + if (scene.light === flashlight) { + scene.light.direction = Cesium.Cartesian3.clone( + scene.camera.directionWC, + scene.light.direction + ); + } else if (scene.light === moonLight) { + scene.light.direction = getMoonDirection(scene.light.direction); } - - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -2729490.8390059783, - -4206389.878855597, - 3928671.2763356343 - ), - orientation: new Cesium.HeadingPitchRoll( - 2.2482480507178426, - -0.20084951548781982, - 0.002593933673552762 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); - - const options = [ - { - text: "Fixed lighting", - onselect: function () { - reset(); - scene.light = directionalLight; - }, + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.1463338399937277, + 0.6677959688982861, + 32.18991401746337 + ), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + scale: 7.0, + }, + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.14633449752228, + 0.667796065242357, + 24.47647034111423 + ), + cylinder: { + length: 8.0, + topRadius: 2.0, + bottomRadius: 2.0, + material: Cesium.Color.WHITE, + }, + }); + + viewer.entities.add({ + position: Cesium.Cartesian3.fromRadians( + -2.1463332294173365, + 0.6677959755384729, + 26.2876064083145 + ), + ellipsoid: { + radii: new Cesium.Cartesian3(2.5, 2.5, 2.5), + material: Cesium.Color.WHITE.withAlpha(0.5), + }, + }); + + function setTime(iso8601) { + const currentTime = Cesium.JulianDate.fromIso8601(iso8601); + const endTime = Cesium.JulianDate.addDays( + currentTime, + 2, + new Cesium.JulianDate() + ); + + viewer.clock.currentTime = currentTime; + viewer.timeline.zoomTo(currentTime, endTime); + } + + function reset() { + // Set scene defaults + scene.light = sunLight; + scene.globe.dynamicAtmosphereLighting = true; + scene.globe.dynamicAtmosphereLightingFromSun = false; + setTime("2020-01-09T23:00:39.018261982600961346Z"); + } + + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -2729490.8390059783, + -4206389.878855597, + 3928671.2763356343 + ), + orientation: new Cesium.HeadingPitchRoll( + 2.2482480507178426, + -0.20084951548781982, + 0.002593933673552762 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); + + const options = [ + { + text: "Fixed lighting", + onselect: function () { + reset(); + scene.light = directionalLight; }, - { - text: "Flashlight", - onselect: function () { - reset(); - scene.light = flashlight; - scene.globe.dynamicAtmosphereLighting = false; - }, + }, + { + text: "Flashlight", + onselect: function () { + reset(); + scene.light = flashlight; + scene.globe.dynamicAtmosphereLighting = false; }, - { - text: "Moonlight", - onselect: function () { - reset(); - scene.light = moonLight; - scene.globe.dynamicAtmosphereLightingFromSun = true; - setTime("2020-01-10T05:29:41.17946898164518643Z"); - }, + }, + { + text: "Moonlight", + onselect: function () { + reset(); + scene.light = moonLight; + scene.globe.dynamicAtmosphereLightingFromSun = true; + setTime("2020-01-10T05:29:41.17946898164518643Z"); }, - { - text: "Sunlight", - onselect: function () { - reset(); - }, + }, + { + text: "Sunlight", + onselect: function () { + reset(); }, - { - text: "Custom color", - onselect: function () { - reset(); - scene.light = customColorLight; - }, + }, + { + text: "Custom color", + onselect: function () { + reset(); + scene.light = customColorLight; }, - ]; + }, + ]; - Sandcastle.addToolbarMenu(options); - })(); //Sandcastle_End + Sandcastle.addToolbarMenu(options); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index 1d3282b5903..dd21568c7bb 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -32,151 +32,157 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer", { + contextOptions: { + requestWebgl1: false, + }, + }); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - contextOptions: { - requestWebgl1: false, - }, - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2022-08-01T00:00:00Z" - ); + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2022-08-01T00:00:00Z" + ); - const scene = viewer.scene; - if (!scene.msaaSupported) { - window.alert("This browser does not support MSAA."); - } + const scene = viewer.scene; + if (!scene.msaaSupported) { + window.alert("This browser does not support MSAA."); + } - function createModel(url, height) { - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - height - ); - const heading = Cesium.Math.toRadians(135); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); + function createModel(url, height) { + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + height + ); + const heading = Cesium.Math.toRadians(135); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - minimumPixelSize: 128, - maximumScale: 20000, - }, - }); - const target = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - height + 7.5 - ); - const offset = new Cesium.Cartesian3(50.0, -15.0, 0.0); - viewer.scene.camera.lookAt(target, offset); - } + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + minimumPixelSize: 128, + maximumScale: 20000, + }, + }); + const target = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + height + 7.5 + ); + const offset = new Cesium.Cartesian3(50.0, -15.0, 0.0); + viewer.scene.camera.lookAt(target, offset); + } - const options = [ - { - text: "Statue of Liberty", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + const options = [ + { + text: "Statue of Liberty", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); - }, + scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); }, - { - text: "3D Tiles BIM", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - }) - ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1234138.7804841248, - -5086063.633843134, - 3633284.606361642 - ), - orientation: { - heading: 0.4304630387656614, - pitch: -0.16969316864215878, - roll: 6.283184816241989, - }, - }); - }, + }, + { + text: "3D Tiles BIM", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(1240402), + }) + ); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1234138.7804841248, + -5086063.633843134, + 3633284.606361642 + ), + orientation: { + heading: 0.4304630387656614, + pitch: -0.16969316864215878, + roll: 6.283184816241989, + }, + }); }, - { - text: "Hot Air Balloon", - onselect: function () { - viewer.entities.removeAll(); - scene.primitives.removeAll(); - createModel( - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - 1000.0 - ); - }, + }, + { + text: "Hot Air Balloon", + onselect: function () { + viewer.entities.removeAll(); + scene.primitives.removeAll(); + createModel( + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + 1000.0 + ); }, - ]; + }, + ]; - const samplingOptions = [ - { - text: "MSAA off", - onselect: function () { - scene.msaaSamples = 1; - }, + const samplingOptions = [ + { + text: "MSAA off", + onselect: function () { + scene.msaaSamples = 1; }, - { - text: "MSAA 2x", - onselect: function () { - scene.msaaSamples = 2; - }, + }, + { + text: "MSAA 2x", + onselect: function () { + scene.msaaSamples = 2; }, - { - text: "MSAA 4x", - onselect: function () { - scene.msaaSamples = 4; - }, + }, + { + text: "MSAA 4x", + onselect: function () { + scene.msaaSamples = 4; }, - { - text: "MSAA 8x", - onselect: function () { - scene.msaaSamples = 8; - }, + }, + { + text: "MSAA 8x", + onselect: function () { + scene.msaaSamples = 8; }, - ]; + }, + ]; - Sandcastle.addToolbarMenu(options); - Sandcastle.addToolbarMenu(samplingOptions); - })(); //Sandcastle_End + Sandcastle.addToolbarMenu(options); + Sandcastle.addToolbarMenu(samplingOptions); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index c6bed6181d4..ac71f6fb445 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -86,344 +86,349 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(28945), - pointCloudShading: { - attenuation: true, - maximumAttenuation: 2, - }, - }) - ); + // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. + const tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(28945), + pointCloudShading: { + attenuation: true, + maximumAttenuation: 2, + }, + }) + ); - // Fly to a nice overview of the city. - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1223285.2286828577, - -4319476.080312792, - 4562579.020145769 + // Fly to a nice overview of the city. + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1223285.2286828577, + -4319476.080312792, + 4562579.020145769 + ), + orientation: { + direction: new Cesium.Cartesian3( + 0.63053223097472, + 0.47519958296727743, + -0.6136892226931869 ), - orientation: { - direction: new Cesium.Cartesian3( - 0.63053223097472, - 0.47519958296727743, - -0.6136892226931869 - ), - up: new Cesium.Cartesian3( - 0.7699959023135587, - -0.4824455703743441, - 0.41755548379407276 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); + up: new Cesium.Cartesian3( + 0.7699959023135587, + -0.4824455703743441, + 0.41755548379407276 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); - // Add stored views around Montreal. You can add to this list by capturing camera.position, camera.direction and camera.up. - Sandcastle.addToolbarMenu([ - { - text: "Overview", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1268112.9336926902, - -4347432.089579957, - 4539129.813606778 + // Add stored views around Montreal. You can add to this list by capturing camera.position, camera.direction and camera.up. + Sandcastle.addToolbarMenu([ + { + text: "Overview", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1268112.9336926902, + -4347432.089579957, + 4539129.813606778 + ), + orientation: { + direction: new Cesium.Cartesian3( + -0.23288147105081208, + 0.9376599248561527, + -0.25799241415197466 ), - orientation: { - direction: new Cesium.Cartesian3( - -0.23288147105081208, - 0.9376599248561527, - -0.25799241415197466 - ), - up: new Cesium.Cartesian3( - -0.015748156073159988, - 0.2616156268422992, - 0.9650436567182887 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); - }, + up: new Cesium.Cartesian3( + -0.015748156073159988, + 0.2616156268422992, + 0.9650436567182887 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); }, - { - text: "Highway", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1266560.143870489, - -4278126.842199712, - 4542690.264566619 + }, + { + text: "Highway", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1266560.143870489, + -4278126.842199712, + 4542690.264566619 + ), + orientation: { + direction: new Cesium.Cartesian3( + -0.3402460635871598, + -0.46669052711538217, + -0.8163532128400116 + ), + up: new Cesium.Cartesian3( + 0.08964012922691329, + -0.8802940231336787, + 0.46588311846138497 ), - orientation: { - direction: new Cesium.Cartesian3( - -0.3402460635871598, - -0.46669052711538217, - -0.8163532128400116 - ), - up: new Cesium.Cartesian3( - 0.08964012922691329, - -0.8802940231336787, - 0.46588311846138497 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); - }, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); }, - { - text: "Olympic Stadium", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1267081.619536883, - -4290744.917138439, - 4530941.041519919 + }, + { + text: "Olympic Stadium", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1267081.619536883, + -4290744.917138439, + 4530941.041519919 + ), + orientation: { + direction: new Cesium.Cartesian3( + -0.735813047510908, + 0.6294547560338262, + 0.24973159435503312 ), - orientation: { - direction: new Cesium.Cartesian3( - -0.735813047510908, - 0.6294547560338262, - 0.24973159435503312 - ), - up: new Cesium.Cartesian3( - -0.09796934684423217, - -0.4638476756625683, - 0.88048131204549 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); - }, + up: new Cesium.Cartesian3( + -0.09796934684423217, + -0.4638476756625683, + 0.88048131204549 + ), + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); }, - { - text: "Biosphere Museum", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1269319.8408991008, - -4293301.826913256, - 4527724.561372451 + }, + { + text: "Biosphere Museum", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1269319.8408991008, + -4293301.826913256, + 4527724.561372451 + ), + orientation: { + direction: new Cesium.Cartesian3( + -0.742505030107832, + -0.3413204607149223, + -0.5763563336703441 + ), + up: new Cesium.Cartesian3( + -0.04655102331027917, + -0.8320643756800384, + 0.5527222421370013 ), - orientation: { - direction: new Cesium.Cartesian3( - -0.742505030107832, - -0.3413204607149223, - -0.5763563336703441 - ), - up: new Cesium.Cartesian3( - -0.04655102331027917, - -0.8320643756800384, - 0.5527222421370013 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); - }, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); }, - { - text: "St. Joseph's Oratory of Mount Royal", - onselect: function () { - viewer.camera.flyTo({ - destination: new Cesium.Cartesian3( - 1263148.6745904868, - -4297262.506644816, - 4525958.844284831 + }, + { + text: "St. Joseph's Oratory of Mount Royal", + onselect: function () { + viewer.camera.flyTo({ + destination: new Cesium.Cartesian3( + 1263148.6745904868, + -4297262.506644816, + 4525958.844284831 + ), + orientation: { + direction: new Cesium.Cartesian3( + 0.6550952540993403, + 0.7551122393690295, + 0.025606913355780074 + ), + up: new Cesium.Cartesian3( + 0.46670450470847263, + -0.4310758971098583, + 0.7722437932516845 ), - orientation: { - direction: new Cesium.Cartesian3( - 0.6550952540993403, - 0.7551122393690295, - 0.025606913355780074 - ), - up: new Cesium.Cartesian3( - 0.46670450470847263, - -0.4310758971098583, - 0.7722437932516845 - ), - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, - }); - }, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, + }); }, - ]); - - // Set up checkboxes for toggling the various classification settings. - const viewModel = { - ground: true, - other: true, - buildings: true, - low_vegetation: true, - medium_vegetation: true, - high_vegetation: true, - }; + }, + ]); - // Assign colors to each classification type. - const pointStyles = { - unclassified: { - color: "color('#808080')", - show: true, - }, - not_awarded: { - color: "color('#FFDEAD')", - show: true, - }, - ground: { - color: "color('#FFDEAD')", - show: true, - }, - low_vegetation: { - color: "color('#63FF7E')", - show: true, - }, - medium_vegetation: { - color: "color('#63FF7E')", - show: true, - }, - high_vegetation: { - color: "color('#22B33A')", - show: true, - }, - buildings: { - color: "color('#efefef')", - show: true, - }, - low_point: { - color: "color('#808080')", - show: true, - }, - reserved_city_diffusion: { - color: "color('#808080')", - show: true, - }, - }; + // Set up checkboxes for toggling the various classification settings. + const viewModel = { + ground: true, + other: true, + buildings: true, + low_vegetation: true, + medium_vegetation: true, + high_vegetation: true, + }; - const classificationDictionary = { - not_awarded: 1, - ground: 2, - low_vegetation: 3, - medium_vegetation: 4, - high_vegetation: 5, - buildings: 6, - low_point: 7, - reserved_city_diffusion: 8, - unclassified: -1, - }; + // Assign colors to each classification type. + const pointStyles = { + unclassified: { + color: "color('#808080')", + show: true, + }, + not_awarded: { + color: "color('#FFDEAD')", + show: true, + }, + ground: { + color: "color('#FFDEAD')", + show: true, + }, + low_vegetation: { + color: "color('#63FF7E')", + show: true, + }, + medium_vegetation: { + color: "color('#63FF7E')", + show: true, + }, + high_vegetation: { + color: "color('#22B33A')", + show: true, + }, + buildings: { + color: "color('#efefef')", + show: true, + }, + low_point: { + color: "color('#808080')", + show: true, + }, + reserved_city_diffusion: { + color: "color('#808080')", + show: true, + }, + }; - // This is a helper function to re-apply the styles each time the UI/checkboxes are updated. - function applyStyle(tileset, styles) { - const styleObject = {}; - const styleKeys = Object.keys(styles); + const classificationDictionary = { + not_awarded: 1, + ground: 2, + low_vegetation: 3, + medium_vegetation: 4, + high_vegetation: 5, + buildings: 6, + low_point: 7, + reserved_city_diffusion: 8, + unclassified: -1, + }; - styleObject.color = { - conditions: [], - }; - styleObject.show = { - conditions: [], - }; + // This is a helper function to re-apply the styles each time the UI/checkboxes are updated. + function applyStyle(tileset, styles) { + const styleObject = {}; + const styleKeys = Object.keys(styles); - let finalCondition; + styleObject.color = { + conditions: [], + }; + styleObject.show = { + conditions: [], + }; - for (let i = 0; i < styleKeys.length; ++i) { - const key = styleKeys[i]; - const id = classificationDictionary[key]; + let finalCondition; - const colorCondition = [ - `\${Classification} === ${id}`, - styles[key].color, - ]; - const showCondition = [ - `\${Classification} === ${id}`, - styles[key].show, - ]; + for (let i = 0; i < styleKeys.length; ++i) { + const key = styleKeys[i]; + const id = classificationDictionary[key]; - if (id === -1) { - colorCondition[0] = true; - showCondition[0] = true; + const colorCondition = [ + `\${Classification} === ${id}`, + styles[key].color, + ]; + const showCondition = [ + `\${Classification} === ${id}`, + styles[key].show, + ]; - finalCondition = { - colorCondition: colorCondition, - showCondition: showCondition, - }; - } else { - styleObject.color.conditions.push(colorCondition); - styleObject.show.conditions.push(showCondition); - } - } + if (id === -1) { + colorCondition[0] = true; + showCondition[0] = true; - if (Cesium.defined(finalCondition)) { - styleObject.color.conditions.push(finalCondition.colorCondition); - styleObject.show.conditions.push(finalCondition.showCondition); + finalCondition = { + colorCondition: colorCondition, + showCondition: showCondition, + }; + } else { + styleObject.color.conditions.push(colorCondition); + styleObject.show.conditions.push(showCondition); } + } - tileset.style = new Cesium.Cesium3DTileStyle(styleObject); + if (Cesium.defined(finalCondition)) { + styleObject.color.conditions.push(finalCondition.colorCondition); + styleObject.show.conditions.push(finalCondition.showCondition); } - // Apply an initial style. - applyStyle(tileset, pointStyles); + tileset.style = new Cesium.Cesium3DTileStyle(styleObject); + } - Cesium.knockout.track(viewModel); + // Apply an initial style. + applyStyle(tileset, pointStyles); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + Cesium.knockout.track(viewModel); - // Set up the checkboxes. - Cesium.knockout - .getObservable(viewModel, "ground") - .subscribe(function (show) { - pointStyles.ground.show = show; - pointStyles.not_awarded.show = show; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - applyStyle(tileset, pointStyles); - }); + // Set up the checkboxes. + Cesium.knockout + .getObservable(viewModel, "ground") + .subscribe(function (show) { + pointStyles.ground.show = show; + pointStyles.not_awarded.show = show; - Cesium.knockout - .getObservable(viewModel, "low_vegetation") - .subscribe(function (show) { - pointStyles.low_vegetation.show = show; + applyStyle(tileset, pointStyles); + }); - applyStyle(tileset, pointStyles); - }); + Cesium.knockout + .getObservable(viewModel, "low_vegetation") + .subscribe(function (show) { + pointStyles.low_vegetation.show = show; - Cesium.knockout - .getObservable(viewModel, "medium_vegetation") - .subscribe(function (show) { - pointStyles.medium_vegetation.show = show; + applyStyle(tileset, pointStyles); + }); - applyStyle(tileset, pointStyles); - }); + Cesium.knockout + .getObservable(viewModel, "medium_vegetation") + .subscribe(function (show) { + pointStyles.medium_vegetation.show = show; - Cesium.knockout - .getObservable(viewModel, "high_vegetation") - .subscribe(function (show) { - pointStyles.high_vegetation.show = show; + applyStyle(tileset, pointStyles); + }); - applyStyle(tileset, pointStyles); - }); + Cesium.knockout + .getObservable(viewModel, "high_vegetation") + .subscribe(function (show) { + pointStyles.high_vegetation.show = show; - Cesium.knockout - .getObservable(viewModel, "buildings") - .subscribe(function (show) { - pointStyles.buildings.show = show; + applyStyle(tileset, pointStyles); + }); + + Cesium.knockout + .getObservable(viewModel, "buildings") + .subscribe(function (show) { + pointStyles.buildings.show = show; - applyStyle(tileset, pointStyles); - }); + applyStyle(tileset, pointStyles); + }); - Cesium.knockout - .getObservable(viewModel, "other") - .subscribe(function (show) { - pointStyles.low_point.show = show; - pointStyles.reserved_city_diffusion.show = show; - pointStyles.unclassified.show = show; + Cesium.knockout + .getObservable(viewModel, "other") + .subscribe(function (show) { + pointStyles.low_point.show = show; + pointStyles.reserved_city_diffusion.show = show; + pointStyles.unclassified.show = show; - applyStyle(tileset, pointStyles); - }); - })(); //Sandcastle_End + applyStyle(tileset, pointStyles); + }); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index a23ffe72708..ca33b2cb9af 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -35,112 +35,112 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - let viewer; try { // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) // http://www.pasda.psu.edu/ - viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) - ), - }); + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3957) + ); } catch (error) { console.log(error); } + })(); - // Add PA locations - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Pinnacle", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3324415110874286, - 0.6954224325279967, - 236.6770689945084 - ), - orientation: { - heading: Cesium.Math.toRadians(310), - pitch: Cesium.Math.toRadians(-15), - roll: 0.0, - }, - }); - }, + // Add PA locations + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Pinnacle", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3324415110874286, + 0.6954224325279967, + 236.6770689945084 + ), + orientation: { + heading: Cesium.Math.toRadians(310), + pitch: Cesium.Math.toRadians(-15), + roll: 0.0, + }, + }); }, - { - text: "Mount Nittany", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.358985133937573, - 0.7123252393978314, - 451.05748252867375 - ), - orientation: { - heading: Cesium.Math.toRadians(85), - pitch: Cesium.Math.toRadians(0), - roll: 0.0, - }, - }); - }, + }, + { + text: "Mount Nittany", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.358985133937573, + 0.7123252393978314, + 451.05748252867375 + ), + orientation: { + heading: Cesium.Math.toRadians(85), + pitch: Cesium.Math.toRadians(0), + roll: 0.0, + }, + }); }, - { - text: "Horseshoe Curve", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3700147546199826, - 0.706808606166025, - 993.7916313325215 - ), - orientation: { - heading: Cesium.Math.toRadians(90), - pitch: Cesium.Math.toRadians(-15), - roll: 0.0, - }, - }); - }, + }, + { + text: "Horseshoe Curve", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3700147546199826, + 0.706808606166025, + 993.7916313325215 + ), + orientation: { + heading: Cesium.Math.toRadians(90), + pitch: Cesium.Math.toRadians(-15), + roll: 0.0, + }, + }); }, - { - text: "Jim Thorpe", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.3218297501066052, - 0.713358272291525, - 240.87968743408845 - ), - orientation: { - heading: Cesium.Math.toRadians(200), - pitch: Cesium.Math.toRadians(-5), - roll: 0.0, - }, - }); - }, + }, + { + text: "Jim Thorpe", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.3218297501066052, + 0.713358272291525, + 240.87968743408845 + ), + orientation: { + heading: Cesium.Math.toRadians(200), + pitch: Cesium.Math.toRadians(-5), + roll: 0.0, + }, + }); }, - { - text: "Grand Canyon of PA", - onselect: function () { - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromRadians( - -1.349379633251472, - 0.720297672225785, - 656.268309953562 - ), - orientation: { - heading: Cesium.Math.toRadians(200), - pitch: Cesium.Math.toRadians(-5), - roll: 0.0, - }, - }); - }, + }, + { + text: "Grand Canyon of PA", + onselect: function () { + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromRadians( + -1.349379633251472, + 0.720297672225785, + 656.268309953562 + ), + orientation: { + heading: Cesium.Math.toRadians(200), + pitch: Cesium.Math.toRadians(-5), + roll: 0.0, + }, + }); }, - ], - "toolbar" - ); - })(); //Sandcastle_End + }, + ], + "toolbar" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index c757b3aa3d7..00602ce0216 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -35,173 +35,180 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer", { + shouldAnimate: true, + }); + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + + const resetCameraFunction = function () { + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 277096.634865404, + 5647834.481964232, + 2985563.7039122293 + ), + orientation: { + heading: 4.731089976107251, + pitch: -0.32003481981370063, + }, }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; - const resetCameraFunction = function () { - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 277096.634865404, - 5647834.481964232, - 2985563.7039122293 - ), - orientation: { - heading: 4.731089976107251, - pitch: -0.32003481981370063, - }, - }); - }; - resetCameraFunction(); + }; + resetCameraFunction(); - // snow - const snowParticleSize = 12.0; - const snowRadius = 100000.0; - const minimumSnowImageSize = new Cesium.Cartesian2( - snowParticleSize, - snowParticleSize + // snow + const snowParticleSize = 12.0; + const snowRadius = 100000.0; + const minimumSnowImageSize = new Cesium.Cartesian2( + snowParticleSize, + snowParticleSize + ); + const maximumSnowImageSize = new Cesium.Cartesian2( + snowParticleSize * 2.0, + snowParticleSize * 2.0 + ); + let snowGravityScratch = new Cesium.Cartesian3(); + const snowUpdate = function (particle, dt) { + snowGravityScratch = Cesium.Cartesian3.normalize( + particle.position, + snowGravityScratch + ); + Cesium.Cartesian3.multiplyByScalar( + snowGravityScratch, + Cesium.Math.randomBetween(-30.0, -300.0), + snowGravityScratch ); - const maximumSnowImageSize = new Cesium.Cartesian2( - snowParticleSize * 2.0, - snowParticleSize * 2.0 + particle.velocity = Cesium.Cartesian3.add( + particle.velocity, + snowGravityScratch, + particle.velocity ); - let snowGravityScratch = new Cesium.Cartesian3(); - const snowUpdate = function (particle, dt) { - snowGravityScratch = Cesium.Cartesian3.normalize( - particle.position, - snowGravityScratch - ); - Cesium.Cartesian3.multiplyByScalar( - snowGravityScratch, - Cesium.Math.randomBetween(-30.0, -300.0), - snowGravityScratch - ); - particle.velocity = Cesium.Cartesian3.add( - particle.velocity, - snowGravityScratch, - particle.velocity - ); - const distance = Cesium.Cartesian3.distance( - scene.camera.position, - particle.position - ); - if (distance > snowRadius) { - particle.endColor.alpha = 0.0; - } else { - particle.endColor.alpha = 1.0 / (distance / snowRadius + 0.1); - } - }; + const distance = Cesium.Cartesian3.distance( + scene.camera.position, + particle.position + ); + if (distance > snowRadius) { + particle.endColor.alpha = 0.0; + } else { + particle.endColor.alpha = 1.0 / (distance / snowRadius + 0.1); + } + }; - // rain - const rainParticleSize = 15.0; - const rainRadius = 100000.0; - const rainImageSize = new Cesium.Cartesian2( - rainParticleSize, - rainParticleSize * 2.0 + // rain + const rainParticleSize = 15.0; + const rainRadius = 100000.0; + const rainImageSize = new Cesium.Cartesian2( + rainParticleSize, + rainParticleSize * 2.0 + ); + let rainGravityScratch = new Cesium.Cartesian3(); + const rainUpdate = function (particle, dt) { + rainGravityScratch = Cesium.Cartesian3.normalize( + particle.position, + rainGravityScratch + ); + rainGravityScratch = Cesium.Cartesian3.multiplyByScalar( + rainGravityScratch, + -1050.0, + rainGravityScratch ); - let rainGravityScratch = new Cesium.Cartesian3(); - const rainUpdate = function (particle, dt) { - rainGravityScratch = Cesium.Cartesian3.normalize( - particle.position, - rainGravityScratch - ); - rainGravityScratch = Cesium.Cartesian3.multiplyByScalar( - rainGravityScratch, - -1050.0, - rainGravityScratch - ); - particle.position = Cesium.Cartesian3.add( - particle.position, - rainGravityScratch, - particle.position - ); + particle.position = Cesium.Cartesian3.add( + particle.position, + rainGravityScratch, + particle.position + ); - const distance = Cesium.Cartesian3.distance( - scene.camera.position, - particle.position - ); - if (distance > rainRadius) { - particle.endColor.alpha = 0.0; - } else { - particle.endColor.alpha = - Cesium.Color.BLUE.alpha / (distance / rainRadius + 0.1); - } - }; + const distance = Cesium.Cartesian3.distance( + scene.camera.position, + particle.position + ); + if (distance > rainRadius) { + particle.endColor.alpha = 0.0; + } else { + particle.endColor.alpha = + Cesium.Color.BLUE.alpha / (distance / rainRadius + 0.1); + } + }; - // button - Sandcastle.addToolbarButton("Reset Camera", resetCameraFunction); + // button + Sandcastle.addToolbarButton("Reset Camera", resetCameraFunction); - // drop down - const options = [ - { - text: "Snow", - onselect: function () { - scene.primitives.removeAll(); - scene.primitives.add( - new Cesium.ParticleSystem({ - modelMatrix: new Cesium.Matrix4.fromTranslation( - scene.camera.position - ), - minimumSpeed: -1.0, - maximumSpeed: 0.0, - lifetime: 15.0, - emitter: new Cesium.SphereEmitter(snowRadius), - startScale: 0.5, - endScale: 1.0, - image: "../../SampleData/snowflake_particle.png", - emissionRate: 7000.0, - startColor: Cesium.Color.WHITE.withAlpha(0.0), - endColor: Cesium.Color.WHITE.withAlpha(1.0), - minimumImageSize: minimumSnowImageSize, - maximumImageSize: maximumSnowImageSize, - updateCallback: snowUpdate, - }) - ); + // drop down + const options = [ + { + text: "Snow", + onselect: function () { + scene.primitives.removeAll(); + scene.primitives.add( + new Cesium.ParticleSystem({ + modelMatrix: new Cesium.Matrix4.fromTranslation( + scene.camera.position + ), + minimumSpeed: -1.0, + maximumSpeed: 0.0, + lifetime: 15.0, + emitter: new Cesium.SphereEmitter(snowRadius), + startScale: 0.5, + endScale: 1.0, + image: "../../SampleData/snowflake_particle.png", + emissionRate: 7000.0, + startColor: Cesium.Color.WHITE.withAlpha(0.0), + endColor: Cesium.Color.WHITE.withAlpha(1.0), + minimumImageSize: minimumSnowImageSize, + maximumImageSize: maximumSnowImageSize, + updateCallback: snowUpdate, + }) + ); - scene.skyAtmosphere.hueShift = -0.8; - scene.skyAtmosphere.saturationShift = -0.7; - scene.skyAtmosphere.brightnessShift = -0.33; - scene.fog.density = 0.001; - scene.fog.minimumBrightness = 0.8; - }, + scene.skyAtmosphere.hueShift = -0.8; + scene.skyAtmosphere.saturationShift = -0.7; + scene.skyAtmosphere.brightnessShift = -0.33; + scene.fog.density = 0.001; + scene.fog.minimumBrightness = 0.8; }, - { - text: "Rain", - onselect: function () { - scene.primitives.removeAll(); - scene.primitives.add( - new Cesium.ParticleSystem({ - modelMatrix: new Cesium.Matrix4.fromTranslation( - scene.camera.position - ), - speed: -1.0, - lifetime: 15.0, - emitter: new Cesium.SphereEmitter(rainRadius), - startScale: 1.0, - endScale: 0.0, - image: "../../SampleData/circular_particle.png", - emissionRate: 9000.0, - startColor: new Cesium.Color(0.27, 0.5, 0.7, 0.0), - endColor: new Cesium.Color(0.27, 0.5, 0.7, 0.98), - imageSize: rainImageSize, - updateCallback: rainUpdate, - }) - ); + }, + { + text: "Rain", + onselect: function () { + scene.primitives.removeAll(); + scene.primitives.add( + new Cesium.ParticleSystem({ + modelMatrix: new Cesium.Matrix4.fromTranslation( + scene.camera.position + ), + speed: -1.0, + lifetime: 15.0, + emitter: new Cesium.SphereEmitter(rainRadius), + startScale: 1.0, + endScale: 0.0, + image: "../../SampleData/circular_particle.png", + emissionRate: 9000.0, + startColor: new Cesium.Color(0.27, 0.5, 0.7, 0.0), + endColor: new Cesium.Color(0.27, 0.5, 0.7, 0.98), + imageSize: rainImageSize, + updateCallback: rainUpdate, + }) + ); - scene.skyAtmosphere.hueShift = -0.97; - scene.skyAtmosphere.saturationShift = 0.25; - scene.skyAtmosphere.brightnessShift = -0.4; - scene.fog.density = 0.00025; - scene.fog.minimumBrightness = 0.01; - }, + scene.skyAtmosphere.hueShift = -0.97; + scene.skyAtmosphere.saturationShift = 0.25; + scene.skyAtmosphere.brightnessShift = -0.4; + scene.fog.density = 0.00025; + scene.fog.minimumBrightness = 0.01; }, - ]; - Sandcastle.addToolbarMenu(options); - })(); //Sandcastle_End + }, + ]; + Sandcastle.addToolbarMenu(options); + //Sandcastle_End Sandcastle.finishedLoading(); }; diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index 8b0bc123854..88174baecdb 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -45,154 +45,160 @@ shouldAnimate: true, }); + const viewer = new Cesium.Viewer("cesiumContainer", { + clockViewModel: new Cesium.ClockViewModel(clock), + selectionIndicator: false, + }); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - clockViewModel: new Cesium.ClockViewModel(clock), - selectionIndicator: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( - checked - ) { - viewer.shadows = checked; - }); + Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( + checked + ) { + viewer.shadows = checked; + }); - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - const position = new Cesium.Cartesian3( - -1371108.6511167218, - -5508684.080096612, - 2901825.449865087 - ); - const heading = Cesium.Math.toRadians(180); - const pitch = Cesium.Math.toRadians(2); - const roll = Cesium.Math.toRadians(-6); - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); + const position = new Cesium.Cartesian3( + -1371108.6511167218, + -5508684.080096612, + 2901825.449865087 + ); + const heading = Cesium.Math.toRadians(180); + const pitch = Cesium.Math.toRadians(2); + const roll = Cesium.Math.toRadians(-6); + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); - const entity = viewer.entities.add({ - name: "truck", - position: position, - orientation: orientation, - model: { - uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - minimumPixelSize: 128, - maximumScale: 20, - scale: 8.0, - runAnimations: false, - }, - }); + const entity = viewer.entities.add({ + name: "truck", + position: position, + orientation: orientation, + model: { + uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + minimumPixelSize: 128, + maximumScale: 20, + scale: 8.0, + runAnimations: false, + }, + }); - const threeQuartersView = { - destination: new Cesium.Cartesian3( - -1371203.1456494154, - -5508700.033950869, - 2901802.2749172337 - ), - orientation: { - heading: Cesium.Math.toRadians(67.64973594265429), - pitch: Cesium.Math.toRadians(-8.158676059409297), - roll: Cesium.Math.toRadians(359.9999987450017), - }, - maximumHeight: 100, - }; + const threeQuartersView = { + destination: new Cesium.Cartesian3( + -1371203.1456494154, + -5508700.033950869, + 2901802.2749172337 + ), + orientation: { + heading: Cesium.Math.toRadians(67.64973594265429), + pitch: Cesium.Math.toRadians(-8.158676059409297), + roll: Cesium.Math.toRadians(359.9999987450017), + }, + maximumHeight: 100, + }; - const frontView = { - destination: new Cesium.Cartesian3( - -1371214.9554156072, - -5508700.8494476415, - 2901826.794611029 - ), - orientation: { - heading: Cesium.Math.toRadians(80.5354269423926), - pitch: Cesium.Math.toRadians(-15.466062969558285), - roll: Cesium.Math.toRadians(359.9999999526579), - }, - maximumHeight: 100, - }; + const frontView = { + destination: new Cesium.Cartesian3( + -1371214.9554156072, + -5508700.8494476415, + 2901826.794611029 + ), + orientation: { + heading: Cesium.Math.toRadians(80.5354269423926), + pitch: Cesium.Math.toRadians(-15.466062969558285), + roll: Cesium.Math.toRadians(359.9999999526579), + }, + maximumHeight: 100, + }; - const topView = { - destination: new Cesium.Cartesian3( - -1371190.7755780201, - -5508732.668834588, - 2901827.2625979027 - ), - orientation: { - heading: Cesium.Math.toRadians(68.29411482061157), - pitch: Cesium.Math.toRadians(-33.97774554735345), - roll: Cesium.Math.toRadians(359.9999999298912), - }, - maximumHeight: 100, - }; + const topView = { + destination: new Cesium.Cartesian3( + -1371190.7755780201, + -5508732.668834588, + 2901827.2625979027 + ), + orientation: { + heading: Cesium.Math.toRadians(68.29411482061157), + pitch: Cesium.Math.toRadians(-33.97774554735345), + roll: Cesium.Math.toRadians(359.9999999298912), + }, + maximumHeight: 100, + }; - const upwardsView = { - destination: new Cesium.Cartesian3( - -1371052.4616855076, - -5508691.745389906, - 2901861.440673151 - ), - orientation: { - heading: Cesium.Math.toRadians(236.4536374528137), - pitch: Cesium.Math.toRadians(-1.3382025460115552), - roll: Cesium.Math.toRadians(359.9999985917282), - }, - maximumHeight: 100, - }; + const upwardsView = { + destination: new Cesium.Cartesian3( + -1371052.4616855076, + -5508691.745389906, + 2901861.440673151 + ), + orientation: { + heading: Cesium.Math.toRadians(236.4536374528137), + pitch: Cesium.Math.toRadians(-1.3382025460115552), + roll: Cesium.Math.toRadians(359.9999985917282), + }, + maximumHeight: 100, + }; - viewer.scene.camera.flyTo({ - destination: frontView.destination, - orientation: frontView.orientation, - duration: 5.0, - pitchAdjustHeight: 20, - }); - Sandcastle.addToolbarMenu( - [ - { - text: "Front reflection", - onselect: function () { - viewer.scene.camera.flyTo(frontView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T20:00:00Z" - ); - }, + viewer.scene.camera.flyTo({ + destination: frontView.destination, + orientation: frontView.orientation, + duration: 5.0, + pitchAdjustHeight: 20, + }); + Sandcastle.addToolbarMenu( + [ + { + text: "Front reflection", + onselect: function () { + viewer.scene.camera.flyTo(frontView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T20:00:00Z" + ); }, - { - text: "Three quarters sunrise", - onselect: function () { - viewer.scene.camera.flyTo(threeQuartersView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T11:00:00Z" - ); - }, + }, + { + text: "Three quarters sunrise", + onselect: function () { + viewer.scene.camera.flyTo(threeQuartersView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T11:00:00Z" + ); }, - { - text: "Top reflection", - onselect: function () { - viewer.scene.camera.flyTo(topView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T12:00:00Z" - ); - }, + }, + { + text: "Top reflection", + onselect: function () { + viewer.scene.camera.flyTo(topView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T12:00:00Z" + ); }, - { - text: "Upward angle side reflection", - onselect: function () { - viewer.scene.camera.flyTo(upwardsView); - viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( - "2017-07-11T23:00:00Z" - ); - }, + }, + { + text: "Upward angle side reflection", + onselect: function () { + viewer.scene.camera.flyTo(upwardsView); + viewer.clockViewModel.clock.currentTime = Cesium.JulianDate.fromIso8601( + "2017-07-11T23:00:00Z" + ); }, - ], - "toolbar" - ); - })(); //Sandcastle_End + }, + ], + "toolbar" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index 324a20fc79a..7ea5c50956e 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -35,97 +35,102 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + const viewer = new Cesium.Viewer("cesiumContainer"); + const scene = viewer.scene; - if (!scene.clampToHeightSupported) { - window.alert( - "This browser does not support clampToHeightMostDetailed." - ); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); } + })(); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) + if (!scene.clampToHeightSupported) { + window.alert( + "This browser does not support clampToHeightMostDetailed." ); + } - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1216411.0748779264, - -4736313.10747583, - 4081359.5125561724 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.239925103568368, - -0.4911293834802475, - 6.279849292088564 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) + ); - Sandcastle.addToolbarButton("Sample heights", function () { - sampleHeights(); - }); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1216411.0748779264, + -4736313.10747583, + 4081359.5125561724 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.239925103568368, + -0.4911293834802475, + 6.279849292088564 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - async function sampleHeights() { - viewer.entities.removeAll(); + Sandcastle.addToolbarButton("Sample heights", function () { + sampleHeights(); + }); - const cartesian1 = new Cesium.Cartesian3( - 1216390.063324395, - -4736314.814479433, - 4081341.9787972216 - ); - const cartesian2 = new Cesium.Cartesian3( - 1216329.5413318684, - -4736272.029009798, - 4081407.9342479417 - ); + async function sampleHeights() { + viewer.entities.removeAll(); - const count = 30; - const cartesians = new Array(count); - for (let i = 0; i < count; ++i) { - const offset = i / (count - 1); - cartesians[i] = Cesium.Cartesian3.lerp( - cartesian1, - cartesian2, - offset, - new Cesium.Cartesian3() - ); - } + const cartesian1 = new Cesium.Cartesian3( + 1216390.063324395, + -4736314.814479433, + 4081341.9787972216 + ); + const cartesian2 = new Cesium.Cartesian3( + 1216329.5413318684, + -4736272.029009798, + 4081407.9342479417 + ); - const clampedCartesians = await scene.clampToHeightMostDetailed( - cartesians + const count = 30; + const cartesians = new Array(count); + for (let i = 0; i < count; ++i) { + const offset = i / (count - 1); + cartesians[i] = Cesium.Cartesian3.lerp( + cartesian1, + cartesian2, + offset, + new Cesium.Cartesian3() ); + } - for (let i = 0; i < count; ++i) { - viewer.entities.add({ - position: clampedCartesians[i], - ellipsoid: { - radii: new Cesium.Cartesian3(0.2, 0.2, 0.2), - material: Cesium.Color.RED, - }, - }); - } + const clampedCartesians = await scene.clampToHeightMostDetailed( + cartesians + ); + for (let i = 0; i < count; ++i) { viewer.entities.add({ - polyline: { - positions: clampedCartesians, - arcType: Cesium.ArcType.NONE, - width: 2, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - }), - depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - }), + position: clampedCartesians[i], + ellipsoid: { + radii: new Cesium.Cartesian3(0.2, 0.2, 0.2), + material: Cesium.Color.RED, }, }); } - })(); //Sandcastle_End + + viewer.entities.add({ + polyline: { + positions: clampedCartesians, + arcType: Cesium.ArcType.NONE, + width: 2, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + }), + depthFailMaterial: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + }), + }, + }); + } + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index ed3c7af6c30..a2be63b6796 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -141,221 +141,221 @@

Max delta time

window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // Create a viewer that won't render a new frame unless - // updates to the scene require it to reduce overall CPU usage. - const viewer = new Cesium.Viewer("cesiumContainer", { - requestRenderMode: true, - maximumRenderTimeChange: Infinity, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - - const scene = viewer.scene; - scene.debugShowFramesPerSecond = true; - - let tileset; - - const viewModel = { - requestRenderMode: true, - showTimeOptions: false, - timeChangeEnabled: false, - maximumRenderTimeChange: 0.0, - lastRenderTime: "", - requestRender: function () { - scene.requestRender(); - }, - }; - - // Clear scene and set default view. - let handler; - function resetScene() { - viewer.trackedEntity = undefined; - viewer.dataSources.removeAll(); - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - viewer.clock.shouldAnimate = false; - handler = handler && handler.destroy(); - scene.skyBox.show = true; - scene.camera.flyHome(0.0); - scene.requestRender(); - viewModel.showTimeOptions = false; - viewModel.timeChangeEnabled = false; - viewModel.maximumRenderTimeChange = 0; - } + // Create a viewer that won't render a new frame unless + // updates to the scene require it to reduce overall CPU usage. + const viewer = new Cesium.Viewer("cesiumContainer", { + requestRenderMode: true, + maximumRenderTimeChange: Infinity, + }); - // Load a tileset and set the view. - // No need to call scene.requestRender() - function loadTilesetScenario() { - resetScene(); - - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - } - - // Load an animated model and set the view. - // No need to call scene.requestRender() - // Enable and adjust maximum simulation time change to see - // animations at desired speed. - function loadModelScenario() { - resetScene(); - viewModel.timeChangeEnabled = true; - viewModel.showTimeOptions = true; - - const entity = viewer.entities.add({ - name: "Aircraft", - position: Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 5000.0 - ), - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - minimumPixelSize: 128, - maximumScale: 20000, - }, - }); - - viewer.trackedEntity = entity; - viewer.clock.shouldAnimate = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); } + })(); - // Load CZML DataSource with a model and set the trackedEntity. - // No need to call scene.requestRender() - // Enable and adjust maximum simulation time change to see - // animations at desired speed. - function loadCzmlScenario() { - resetScene(); - viewModel.showTimeOptions = true; - viewModel.timeChangeEnabled = true; - viewModel.maximumRenderTimeChange = 10.0; - - viewer.dataSources.add( - Cesium.CzmlDataSource.load("../../SampleData/simple.czml") - ); - viewer.clock.shouldAnimate = true; - } + const scene = viewer.scene; + scene.debugShowFramesPerSecond = true; - // Pick an entity, only rendering when needed. - function pickingScenario() { - resetScene(); - - let color = Cesium.Color.CORNFLOWERBLUE; - const colorProperty = new Cesium.CallbackProperty(function () { - return color; - }, false); - const entity = viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), - box: { - dimensions: new Cesium.Cartesian3( - 1000000.0, - 1000000.0, - 30000.0 - ), - material: new Cesium.ColorMaterialProperty(colorProperty), - }, - }); + let tileset; + const viewModel = { + requestRenderMode: true, + showTimeOptions: false, + timeChangeEnabled: false, + maximumRenderTimeChange: 0.0, + lastRenderTime: "", + requestRender: function () { scene.requestRender(); + }, + }; + + // Clear scene and set default view. + let handler; + function resetScene() { + viewer.trackedEntity = undefined; + viewer.dataSources.removeAll(); + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + viewer.clock.shouldAnimate = false; + handler = handler && handler.destroy(); + scene.skyBox.show = true; + scene.camera.flyHome(0.0); + scene.requestRender(); + viewModel.showTimeOptions = false; + viewModel.timeChangeEnabled = false; + viewModel.maximumRenderTimeChange = 0; + } + + // Load a tileset and set the view. + // No need to call scene.requestRender() + function loadTilesetScenario() { + resetScene(); + + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + } + + // Load an animated model and set the view. + // No need to call scene.requestRender() + // Enable and adjust maximum simulation time change to see + // animations at desired speed. + function loadModelScenario() { + resetScene(); + viewModel.timeChangeEnabled = true; + viewModel.showTimeOptions = true; + + const entity = viewer.entities.add({ + name: "Aircraft", + position: Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 5000.0 + ), + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + minimumPixelSize: 128, + maximumScale: 20000, + }, + }); - // If the mouse is over the box, change its scale and color, - // then request a new render frame. - let lastPicked; - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject) && pickedObject.id === entity) { - if (Cesium.defined(lastPicked)) { - return; - } - color = Cesium.Color.YELLOW; - scene.requestRender(); - lastPicked = pickedObject; - } else if (Cesium.defined(lastPicked)) { - color = Cesium.Color.CORNFLOWERBLUE; - scene.requestRender(); - lastPicked = undefined; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - } - - // Changes to the scene with the API will require - // calling requestRender() on change. - function setScenePropertiesScenario() { - resetScene(); + viewer.trackedEntity = entity; + viewer.clock.shouldAnimate = true; + } + + // Load CZML DataSource with a model and set the trackedEntity. + // No need to call scene.requestRender() + // Enable and adjust maximum simulation time change to see + // animations at desired speed. + function loadCzmlScenario() { + resetScene(); + viewModel.showTimeOptions = true; + viewModel.timeChangeEnabled = true; + viewModel.maximumRenderTimeChange = 10.0; + + viewer.dataSources.add( + Cesium.CzmlDataSource.load("../../SampleData/simple.czml") + ); + viewer.clock.shouldAnimate = true; + } + + // Pick an entity, only rendering when needed. + function pickingScenario() { + resetScene(); + + let color = Cesium.Color.CORNFLOWERBLUE; + const colorProperty = new Cesium.CallbackProperty(function () { + return color; + }, false); + const entity = viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), + box: { + dimensions: new Cesium.Cartesian3(1000000.0, 1000000.0, 30000.0), + material: new Cesium.ColorMaterialProperty(colorProperty), + }, + }); - scene.skyBox.show = false; - scene.backgroundColor = Cesium.Color.CORNFLOWERBLUE; - scene.requestRender(); - } + scene.requestRender(); + + // If the mouse is over the box, change its scale and color, + // then request a new render frame. + let lastPicked; + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject) && pickedObject.id === entity) { + if (Cesium.defined(lastPicked)) { + return; + } + color = Cesium.Color.YELLOW; + scene.requestRender(); + lastPicked = pickedObject; + } else if (Cesium.defined(lastPicked)) { + color = Cesium.Color.CORNFLOWERBLUE; + scene.requestRender(); + lastPicked = undefined; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + } + + // Changes to the scene with the API will require + // calling requestRender() on change. + function setScenePropertiesScenario() { + resetScene(); + + scene.skyBox.show = false; + scene.backgroundColor = Cesium.Color.CORNFLOWERBLUE; + scene.requestRender(); + } + + // BEGIN SANDCASTLE EXAMPLE UI SETUP + + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); + + Cesium.knockout + .getObservable(viewModel, "requestRenderMode") + .subscribe(function (value) { + scene.requestRenderMode = value; + }); - // BEGIN SANDCASTLE EXAMPLE UI SETUP - - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); - - Cesium.knockout - .getObservable(viewModel, "requestRenderMode") - .subscribe(function (value) { - scene.requestRenderMode = value; - }); - - Cesium.knockout - .getObservable(viewModel, "timeChangeEnabled") - .subscribe(function (value) { - scene.maximumRenderTimeChange = value - ? viewModel.maximumRenderTimeChange - : Infinity; - }); - - Cesium.knockout - .getObservable(viewModel, "maximumRenderTimeChange") - .subscribe(function (value) { - scene.maximumRenderTimeChange = value; - }); - - scene.postRender.addEventListener(function () { - const time = Cesium.JulianDate.toGregorianDate( - scene.lastRenderTime - ); - const value = `${time.hour}:${time.minute}:${ - time.second - }:${time.millisecond.toFixed(0)}`; - Cesium.knockout.getObservable(viewModel, "lastRenderTime")(value); + Cesium.knockout + .getObservable(viewModel, "timeChangeEnabled") + .subscribe(function (value) { + scene.maximumRenderTimeChange = value + ? viewModel.maximumRenderTimeChange + : Infinity; }); - const scenarios = [ - { - text: "Default view", - onselect: resetScene, - }, - { - text: "Load a 3D tileset and set the view", - onselect: loadTilesetScenario, - }, - { - text: "Mouseover picking", - onselect: pickingScenario, - }, - { - text: "Load time-dynamic CZML", - onselect: loadCzmlScenario, - }, - { - text: "Animated model", - onselect: loadModelScenario, - }, - { - text: "Scene changes with API", - onselect: setScenePropertiesScenario, - }, - ]; + Cesium.knockout + .getObservable(viewModel, "maximumRenderTimeChange") + .subscribe(function (value) { + scene.maximumRenderTimeChange = value; + }); - Sandcastle.addToolbarMenu(scenarios); - })(); //Sandcastle_End + scene.postRender.addEventListener(function () { + const time = Cesium.JulianDate.toGregorianDate(scene.lastRenderTime); + const value = `${time.hour}:${time.minute}:${ + time.second + }:${time.millisecond.toFixed(0)}`; + Cesium.knockout.getObservable(viewModel, "lastRenderTime")(value); + }); + + const scenarios = [ + { + text: "Default view", + onselect: resetScene, + }, + { + text: "Load a 3D tileset and set the view", + onselect: loadTilesetScenario, + }, + { + text: "Mouseover picking", + onselect: pickingScenario, + }, + { + text: "Load time-dynamic CZML", + onselect: loadCzmlScenario, + }, + { + text: "Animated model", + onselect: loadModelScenario, + }, + { + text: "Scene changes with API", + onselect: setScenePropertiesScenario, + }, + ]; + + Sandcastle.addToolbarMenu(scenarios); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 185bb1315b1..2f45dff2724 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -35,273 +35,277 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shadows: true, + terrainShadows: Cesium.ShadowMode.ENABLED, + shouldAnimate: true, + }); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shadows: true, - terrainShadows: Cesium.ShadowMode.ENABLED, - shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const shadowMap = viewer.shadowMap; - shadowMap.maximumDistance = 10000.0; + const shadowMap = viewer.shadowMap; + shadowMap.maximumDistance = 10000.0; - const cesiumAir = viewer.entities.add({ - name: "Cesium Air", - height: 20.0, - model: { - uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - }, - }); + const cesiumAir = viewer.entities.add({ + name: "Cesium Air", + height: 20.0, + model: { + uri: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + }, + }); - const groundVehicle = viewer.entities.add({ - name: "Ground Vehicle", - height: 0.0, - model: { - uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + const groundVehicle = viewer.entities.add({ + name: "Ground Vehicle", + height: 0.0, + model: { + uri: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - const cesiumMan = viewer.entities.add({ - name: "Cesium Man", - height: 0.0, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + const cesiumMan = viewer.entities.add({ + name: "Cesium Man", + height: 0.0, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - const woodTower = viewer.entities.add({ - name: "Wood Tower", - height: 0.0, - model: { - uri: "../../SampleData/models/WoodTower/Wood_Tower.glb", - }, - }); + const woodTower = viewer.entities.add({ + name: "Wood Tower", + height: 0.0, + model: { + uri: "../../SampleData/models/WoodTower/Wood_Tower.glb", + }, + }); - const simpleCity = viewer.entities.add({ - name: "Simple City", - height: 0.0, - model: { - uri: "../../SampleData/models/ShadowTester/Shadow_Tester_4.glb", - }, - }); + const simpleCity = viewer.entities.add({ + name: "Simple City", + height: 0.0, + model: { + uri: "../../SampleData/models/ShadowTester/Shadow_Tester_4.glb", + }, + }); - const boxEntity = viewer.entities.add({ - name: "Box", - height: 10.0, - box: { - dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), - material: Cesium.Color.RED, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const boxEntity = viewer.entities.add({ + name: "Box", + height: 10.0, + box: { + dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), + material: Cesium.Color.RED, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - const checkerMaterial = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.RED.withAlpha(0.5), - oddColor: Cesium.Color.RED.withAlpha(0.0), - repeat: new Cesium.Cartesian2(5.0, 10.0), - }); + const checkerMaterial = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.RED.withAlpha(0.5), + oddColor: Cesium.Color.RED.withAlpha(0.0), + repeat: new Cesium.Cartesian2(5.0, 10.0), + }); - const checkerEntity = viewer.entities.add({ - name: "Checkered Box", - height: 10.0, - box: { - dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), - material: checkerMaterial, - outline: true, - outlineColor: Cesium.Color.RED, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const checkerEntity = viewer.entities.add({ + name: "Checkered Box", + height: 10.0, + box: { + dimensions: new Cesium.Cartesian3(10.0, 10.0, 10.0), + material: checkerMaterial, + outline: true, + outlineColor: Cesium.Color.RED, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - const sphereEntity = viewer.entities.add({ - name: "Sphere", - height: 20.0, - ellipsoid: { - radii: new Cesium.Cartesian3(15.0, 15.0, 15.0), - material: Cesium.Color.BLUE.withAlpha(0.5), - slicePartitions: 24, - stackPartitions: 36, - shadows: Cesium.ShadowMode.ENABLED, - }, - }); + const sphereEntity = viewer.entities.add({ + name: "Sphere", + height: 20.0, + ellipsoid: { + radii: new Cesium.Cartesian3(15.0, 15.0, 15.0), + material: Cesium.Color.BLUE.withAlpha(0.5), + slicePartitions: 24, + stackPartitions: 36, + shadows: Cesium.ShadowMode.ENABLED, + }, + }); - const locations = { - Exton: { - longitude: -1.31968, - latitude: 0.698874, - height: 74.14210186070714, - date: 2457522.154792, - }, - HalfDome: { - longitude: -2.086267733294987, - latitude: 0.6587491773830219, - height: 2640.716312584986, - date: 2457507.247512, - }, - Everest: { - longitude: 1.517132688, - latitude: 0.4884844964, - height: 8773.17824498951, - date: 2457507.620845, - }, - PinnaclePA: { - longitude: -1.3324415110874286, - latitude: 0.6954224325279967, - height: 179.14276256241743, - date: 2457523.04162, - }, - SenecaRocks: { - longitude: -1.3851775172879768, - latitude: 0.6778211831093554, - height: 682.5893300695776, - date: 2457522.097512, - }, - Space: { - longitude: -1.31968, - latitude: 0.698874, - height: 2000000.0, - date: 2457522.154792, - }, - }; - - let i; - const entities = viewer.entities.values; - const entitiesLength = entities.length; + const locations = { + Exton: { + longitude: -1.31968, + latitude: 0.698874, + height: 74.14210186070714, + date: 2457522.154792, + }, + HalfDome: { + longitude: -2.086267733294987, + latitude: 0.6587491773830219, + height: 2640.716312584986, + date: 2457507.247512, + }, + Everest: { + longitude: 1.517132688, + latitude: 0.4884844964, + height: 8773.17824498951, + date: 2457507.620845, + }, + PinnaclePA: { + longitude: -1.3324415110874286, + latitude: 0.6954224325279967, + height: 179.14276256241743, + date: 2457523.04162, + }, + SenecaRocks: { + longitude: -1.3851775172879768, + latitude: 0.6778211831093554, + height: 682.5893300695776, + date: 2457522.097512, + }, + Space: { + longitude: -1.31968, + latitude: 0.698874, + height: 2000000.0, + date: 2457522.154792, + }, + }; - function setLocation(location) { - const longitude = location.longitude; - const latitude = location.latitude; - const height = location.height; + let i; + const entities = viewer.entities.values; + const entitiesLength = entities.length; - for (i = 0; i < entitiesLength; ++i) { - const entity = entities[i]; - entity.position = Cesium.Cartesian3.fromRadians( - longitude, - latitude, - height + entity.height - ); - } + function setLocation(location) { + const longitude = location.longitude; + const latitude = location.latitude; + const height = location.height; - viewer.clock.currentTime = new Cesium.JulianDate(location.date); - viewer.clock.multiplier = 1.0; - } - - function setLocationFunction(location) { - return function () { - setLocation(location); - }; + for (i = 0; i < entitiesLength; ++i) { + const entity = entities[i]; + entity.position = Cesium.Cartesian3.fromRadians( + longitude, + latitude, + height + entity.height + ); } - const locationToolbarOptions = []; - for (const locationName in locations) { - if (locations.hasOwnProperty(locationName)) { - const location = locations[locationName]; - locationToolbarOptions.push({ - text: locationName, - onselect: setLocationFunction(location), - }); - } - } + viewer.clock.currentTime = new Cesium.JulianDate(location.date); + viewer.clock.multiplier = 1.0; + } - Sandcastle.addToolbarMenu(locationToolbarOptions); + function setLocationFunction(location) { + return function () { + setLocation(location); + }; + } - function setEntity(entity) { - for (i = 0; i < entitiesLength; ++i) { - entities[i].show = false; - } - entity.show = true; - viewer.trackedEntity = entity; + const locationToolbarOptions = []; + for (const locationName in locations) { + if (locations.hasOwnProperty(locationName)) { + const location = locations[locationName]; + locationToolbarOptions.push({ + text: locationName, + onselect: setLocationFunction(location), + }); } + } - function setEntityFunction(entity) { - return function () { - setEntity(entity); - }; - } + Sandcastle.addToolbarMenu(locationToolbarOptions); - const entityToolbarOptions = []; + function setEntity(entity) { for (i = 0; i < entitiesLength; ++i) { - const entity = entities[i]; - entityToolbarOptions.push({ - text: entity.name, - onselect: setEntityFunction(entity), - }); + entities[i].show = false; } + entity.show = true; + viewer.trackedEntity = entity; + } - Sandcastle.addToolbarMenu(entityToolbarOptions); + function setEntityFunction(entity) { + return function () { + setEntity(entity); + }; + } - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( - checked - ) { - viewer.shadows = checked; + const entityToolbarOptions = []; + for (i = 0; i < entitiesLength; ++i) { + const entity = entities[i]; + entityToolbarOptions.push({ + text: entity.name, + onselect: setEntityFunction(entity), }); + } + + Sandcastle.addToolbarMenu(entityToolbarOptions); + + Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( + checked + ) { + viewer.shadows = checked; + }); + + Sandcastle.addToggleButton("Entity Shadows", true, function (checked) { + const entityShadows = checked + ? Cesium.ShadowMode.ENABLED + : Cesium.ShadowMode.DISABLED; + for (i = 0; i < entitiesLength; ++i) { + const entity = entities[i]; + const visual = entity.model || entity.box || entity.ellipsoid; + visual.shadows = entityShadows; + } + }); - Sandcastle.addToggleButton("Entity Shadows", true, function ( - checked - ) { - const entityShadows = checked + Sandcastle.addToggleButton( + "Terrain Shadows", + viewer.terrainShadows === Cesium.ShadowMode.ENABLED, + function (checked) { + viewer.terrainShadows = checked ? Cesium.ShadowMode.ENABLED : Cesium.ShadowMode.DISABLED; - for (i = 0; i < entitiesLength; ++i) { - const entity = entities[i]; - const visual = entity.model || entity.box || entity.ellipsoid; - visual.shadows = entityShadows; - } - }); - - Sandcastle.addToggleButton( - "Terrain Shadows", - viewer.terrainShadows === Cesium.ShadowMode.ENABLED, - function (checked) { - viewer.terrainShadows = checked - ? Cesium.ShadowMode.ENABLED - : Cesium.ShadowMode.DISABLED; - } - ); + } + ); - Sandcastle.addToggleButton( - "Soft Shadows", - shadowMap.softShadows, - function (checked) { - shadowMap.softShadows = checked; - } - ); + Sandcastle.addToggleButton( + "Soft Shadows", + shadowMap.softShadows, + function (checked) { + shadowMap.softShadows = checked; + } + ); - Sandcastle.addToolbarMenu([ - { - text: "Size : 2048", - onselect: function () { - shadowMap.size = 2048; - }, + Sandcastle.addToolbarMenu([ + { + text: "Size : 2048", + onselect: function () { + shadowMap.size = 2048; }, - { - text: "Size : 1024", - onselect: function () { - shadowMap.size = 1024; - }, + }, + { + text: "Size : 1024", + onselect: function () { + shadowMap.size = 1024; }, - { - text: "Size : 512", - onselect: function () { - shadowMap.size = 512; - }, + }, + { + text: "Size : 512", + onselect: function () { + shadowMap.size = 512; }, - { - text: "Size : 256", - onselect: function () { - shadowMap.size = 256; - }, + }, + { + text: "Size : 256", + onselect: function () { + shadowMap.size = 256; }, - ]); + }, + ]); - setLocation(locations.Exton); - setEntity(cesiumAir); - })(); //Sandcastle_End + setLocation(locations.Exton); + setEntity(cesiumAir); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index a3c7936fbae..b850b26fa29 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -76,123 +76,128 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const scene = viewer.scene; - const globe = scene.globe; - globe.terrainExaggeration = 2.0; - globe.terrainExaggerationRelativeHeight = 2400.0; + const scene = viewer.scene; + const globe = scene.globe; + globe.terrainExaggeration = 2.0; + globe.terrainExaggerationRelativeHeight = 2400.0; - scene.camera.setView({ - destination: new Cesium.Cartesian3( - 336567.0354790703, - 5664688.047602498, - 2923204.3566963132 - ), - orientation: new Cesium.HeadingPitchRoll( - 1.2273281382639265, - -0.32239612370237514, - 0.0027207329018610338 - ), - }); + scene.camera.setView({ + destination: new Cesium.Cartesian3( + 336567.0354790703, + 5664688.047602498, + 2923204.3566963132 + ), + orientation: new Cesium.HeadingPitchRoll( + 1.2273281382639265, + -0.32239612370237514, + 0.0027207329018610338 + ), + }); - viewer.entities.add({ - position: new Cesium.Cartesian3( - 314557.3531714575, - 5659723.771882165, - 2923538.5417330978 - ), - ellipsoid: { - radii: new Cesium.Cartesian3(400.0, 400.0, 400.0), - material: Cesium.Color.RED, - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }, - }); + viewer.entities.add({ + position: new Cesium.Cartesian3( + 314557.3531714575, + 5659723.771882165, + 2923538.5417330978 + ), + ellipsoid: { + radii: new Cesium.Cartesian3(400.0, 400.0, 400.0), + material: Cesium.Color.RED, + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }, + }); - let visualizeRelativeHeight = true; + let visualizeRelativeHeight = true; - function updateMaterial() { - if (visualizeRelativeHeight) { - const height = globe.terrainExaggerationRelativeHeight; - const exaggeration = globe.terrainExaggeration; - const alpha = Math.min(1.0, exaggeration * 0.25); - const layer = { - extendUpwards: true, - extendDownwards: true, - entries: [ - { - height: height + 100.0, - color: new Cesium.Color(0.0, 1.0, 0.0, alpha * 0.25), - }, - { - height: height + 50.0, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), - }, - { - height: height, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: height - 50.0, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), - }, - { - height: height - 100.0, - color: new Cesium.Color(1.0, 0.0, 0.0, alpha * 0.25), - }, - ], - }; - scene.globe.material = Cesium.createElevationBandMaterial({ - scene: scene, - layers: [layer], - }); - } else { - scene.globe.material = undefined; - } + function updateMaterial() { + if (visualizeRelativeHeight) { + const height = globe.terrainExaggerationRelativeHeight; + const exaggeration = globe.terrainExaggeration; + const alpha = Math.min(1.0, exaggeration * 0.25); + const layer = { + extendUpwards: true, + extendDownwards: true, + entries: [ + { + height: height + 100.0, + color: new Cesium.Color(0.0, 1.0, 0.0, alpha * 0.25), + }, + { + height: height + 50.0, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), + }, + { + height: height, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: height - 50.0, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha * 0.5), + }, + { + height: height - 100.0, + color: new Cesium.Color(1.0, 0.0, 0.0, alpha * 0.25), + }, + ], + }; + scene.globe.material = Cesium.createElevationBandMaterial({ + scene: scene, + layers: [layer], + }); + } else { + scene.globe.material = undefined; } - updateMaterial(); + } + updateMaterial(); - const viewModel = { - exaggeration: globe.terrainExaggeration, - relativeHeight: globe.terrainExaggerationRelativeHeight, - }; + const viewModel = { + exaggeration: globe.terrainExaggeration, + relativeHeight: globe.terrainExaggerationRelativeHeight, + }; - function updateExaggeration() { - globe.terrainExaggeration = Number(viewModel.exaggeration); - globe.terrainExaggerationRelativeHeight = Number( - viewModel.relativeHeight - ); - updateMaterial(); - } + function updateExaggeration() { + globe.terrainExaggeration = Number(viewModel.exaggeration); + globe.terrainExaggerationRelativeHeight = Number( + viewModel.relativeHeight + ); + updateMaterial(); + } - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateExaggeration); - } + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateExaggeration); } + } - Sandcastle.addToggleButton( - "Visualize Relative Height", - visualizeRelativeHeight, - function (checked) { - visualizeRelativeHeight = checked; - updateMaterial(); - } - ); + Sandcastle.addToggleButton( + "Visualize Relative Height", + visualizeRelativeHeight, + function (checked) { + visualizeRelativeHeight = checked; + updateMaterial(); + } + ); - Sandcastle.addToolbarButton("Remove Exaggeration", function () { - viewModel.exaggeration = 1.0; - viewModel.relativeHeight = 0.0; - }); - })(); //Sandcastle_End + Sandcastle.addToolbarButton("Remove Exaggeration", function () { + viewModel.exaggeration = 1.0; + viewModel.relativeHeight = 0.0; + }); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index fe2218e6cf4..f1e50500145 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -39,312 +39,311 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ requestWaterMask: true, requestVertexNormals: true, - }), - }); + }); + } catch (error) { + console.log(error); + } + })(); - // set lighting to true - viewer.scene.globe.enableLighting = true; + // set lighting to true + viewer.scene.globe.enableLighting = true; - // setup alternative terrain providers - const ellipsoidProvider = new Cesium.EllipsoidTerrainProvider(); + // setup alternative terrain providers + const ellipsoidProvider = new Cesium.EllipsoidTerrainProvider(); - // Sine wave - const customHeightmapWidth = 32; - const customHeightmapHeight = 32; - const customHeightmapProvider = new Cesium.CustomHeightmapTerrainProvider( - { - width: customHeightmapWidth, - height: customHeightmapHeight, - callback: function (x, y, level) { - const width = customHeightmapWidth; - const height = customHeightmapHeight; - const buffer = new Float32Array(width * height); + // Sine wave + const customHeightmapWidth = 32; + const customHeightmapHeight = 32; + const customHeightmapProvider = new Cesium.CustomHeightmapTerrainProvider( + { + width: customHeightmapWidth, + height: customHeightmapHeight, + callback: function (x, y, level) { + const width = customHeightmapWidth; + const height = customHeightmapHeight; + const buffer = new Float32Array(width * height); - for (let yy = 0; yy < height; yy++) { - for (let xx = 0; xx < width; xx++) { - const u = (x + xx / (width - 1)) / Math.pow(2, level); - const v = (y + yy / (height - 1)) / Math.pow(2, level); + for (let yy = 0; yy < height; yy++) { + for (let xx = 0; xx < width; xx++) { + const u = (x + xx / (width - 1)) / Math.pow(2, level); + const v = (y + yy / (height - 1)) / Math.pow(2, level); - const heightValue = 4000 * (Math.sin(8000 * v) * 0.5 + 0.5); + const heightValue = 4000 * (Math.sin(8000 * v) * 0.5 + 0.5); - const index = yy * width + xx; - buffer[index] = heightValue; - } + const index = yy * width + xx; + buffer[index] = heightValue; } + } - return buffer; - }, - } - ); + return buffer; + }, + } + ); - Sandcastle.addToolbarMenu( - [ - { - text: "CesiumTerrainProvider - Cesium World Terrain", - onselect: async function () { - const provider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - viewer.terrainProvider = provider; - viewer.scene.globe.enableLighting = true; - }, + Sandcastle.addToolbarMenu( + [ + { + text: "CesiumTerrainProvider - Cesium World Terrain", + onselect: async function () { + const provider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + viewer.terrainProvider = provider; + viewer.scene.globe.enableLighting = true; }, - { - text: - "CesiumTerrainProvider - Cesium World Terrain - no effects", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - }, + }, + { + text: "CesiumTerrainProvider - Cesium World Terrain - no effects", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); }, - { - text: - "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync( - { - requestVertexNormals: true, - } - ); - viewer.scene.globe.enableLighting = true; - }, + }, + { + text: "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, + }); + viewer.scene.globe.enableLighting = true; }, - { - text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync( - { - requestWaterMask: true, - } - ); - }, + }, + { + text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", + onselect: async function () { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + }); }, - { - text: "EllipsoidTerrainProvider", - onselect: function () { - viewer.terrainProvider = ellipsoidProvider; - }, + }, + { + text: "EllipsoidTerrainProvider", + onselect: function () { + viewer.terrainProvider = ellipsoidProvider; }, - { - text: "CustomHeightmapTerrainProvider", - onselect: function () { - viewer.terrainProvider = customHeightmapProvider; - }, + }, + { + text: "CustomHeightmapTerrainProvider", + onselect: function () { + viewer.terrainProvider = customHeightmapProvider; }, - { - text: "VRTheWorldTerrainProvider", - onselect: async function () { - const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl( - "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", - { - credit: "Terrain data courtesy VT MÄK", - } - ); - viewer.terrainProvider = provider; - }, + }, + { + text: "VRTheWorldTerrainProvider", + onselect: async function () { + const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl( + "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", + { + credit: "Terrain data courtesy VT MÄK", + } + ); + viewer.terrainProvider = provider; }, - { - text: "ArcGISTerrainProvider", - onselect: async function () { - const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ); - viewer.terrainProvider = provider; - }, + }, + { + text: "ArcGISTerrainProvider", + onselect: async function () { + const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ); + viewer.terrainProvider = provider; }, - ], - "terrainMenu" - ); + }, + ], + "terrainMenu" + ); - Sandcastle.addDefaultToolbarMenu( - [ - { - text: "Mount Everest", - onselect: function () { - lookAtMtEverest(); - }, + Sandcastle.addDefaultToolbarMenu( + [ + { + text: "Mount Everest", + onselect: function () { + lookAtMtEverest(); }, - { - text: "Half Dome", - onselect: function () { - const target = new Cesium.Cartesian3( - -2489625.0836225147, - -4393941.44443024, - 3882535.9454173897 - ); - const offset = new Cesium.Cartesian3( - -6857.40902037546, - 412.3284835694358, - 2147.5545426812023 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }, + }, + { + text: "Half Dome", + onselect: function () { + const target = new Cesium.Cartesian3( + -2489625.0836225147, + -4393941.44443024, + 3882535.9454173897 + ); + const offset = new Cesium.Cartesian3( + -6857.40902037546, + 412.3284835694358, + 2147.5545426812023 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, - { - text: "San Francisco Bay", - onselect: function () { - const target = new Cesium.Cartesian3( - -2708814.85583248, - -4254159.450845907, - 3891403.9457429945 - ); - const offset = new Cesium.Cartesian3( - 70642.66030209465, - -31661.517948317807, - 35505.179997143336 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }, + }, + { + text: "San Francisco Bay", + onselect: function () { + const target = new Cesium.Cartesian3( + -2708814.85583248, + -4254159.450845907, + 3891403.9457429945 + ); + const offset = new Cesium.Cartesian3( + 70642.66030209465, + -31661.517948317807, + 35505.179997143336 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }, - ], - "zoomButtons" - ); + }, + ], + "zoomButtons" + ); - let terrainSamplePositions; + let terrainSamplePositions; - function lookAtMtEverest() { - const target = new Cesium.Cartesian3( - 300770.50872389384, - 5634912.131394585, - 2978152.2865545116 - ); - const offset = new Cesium.Cartesian3( - 6344.974098678562, - -793.3419798081741, - 2499.9508860763162 - ); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + function lookAtMtEverest() { + const target = new Cesium.Cartesian3( + 300770.50872389384, + 5634912.131394585, + 2978152.2865545116 + ); + const offset = new Cesium.Cartesian3( + 6344.974098678562, + -793.3419798081741, + 2499.9508860763162 + ); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - function sampleTerrainSuccess(terrainSamplePositions) { - const ellipsoid = Cesium.Ellipsoid.WGS84; + function sampleTerrainSuccess(terrainSamplePositions) { + const ellipsoid = Cesium.Ellipsoid.WGS84; - //By default, Cesium does not obsure geometry - //behind terrain. Setting this flag enables that. - viewer.scene.globe.depthTestAgainstTerrain = true; + //By default, Cesium does not obsure geometry + //behind terrain. Setting this flag enables that. + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.entities.suspendEvents(); - viewer.entities.removeAll(); + viewer.entities.suspendEvents(); + viewer.entities.removeAll(); - for (let i = 0; i < terrainSamplePositions.length; ++i) { - const position = terrainSamplePositions[i]; + for (let i = 0; i < terrainSamplePositions.length; ++i) { + const position = terrainSamplePositions[i]; - viewer.entities.add({ - name: position.height.toFixed(1), - position: ellipsoid.cartographicToCartesian(position), - billboard: { - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - scale: 0.7, - image: "../images/facility.gif", - }, - label: { - text: position.height.toFixed(1), - font: "10pt monospace", - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - pixelOffset: new Cesium.Cartesian2(0, -14), - fillColor: Cesium.Color.BLACK, - outlineColor: Cesium.Color.BLACK, - showBackground: true, - backgroundColor: new Cesium.Color(0.9, 0.9, 0.9, 0.7), - backgroundPadding: new Cesium.Cartesian2(4, 3), - }, - }); - } - viewer.entities.resumeEvents(); + viewer.entities.add({ + name: position.height.toFixed(1), + position: ellipsoid.cartographicToCartesian(position), + billboard: { + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + scale: 0.7, + image: "../images/facility.gif", + }, + label: { + text: position.height.toFixed(1), + font: "10pt monospace", + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + pixelOffset: new Cesium.Cartesian2(0, -14), + fillColor: Cesium.Color.BLACK, + outlineColor: Cesium.Color.BLACK, + showBackground: true, + backgroundColor: new Cesium.Color(0.9, 0.9, 0.9, 0.7), + backgroundPadding: new Cesium.Cartesian2(4, 3), + }, + }); } + viewer.entities.resumeEvents(); + } - function createGrid(rectangleHalfSize) { - const gridWidth = 41; - const gridHeight = 41; - const everestLatitude = Cesium.Math.toRadians(27.988257); - const everestLongitude = Cesium.Math.toRadians(86.925145); - const e = new Cesium.Rectangle( - everestLongitude - rectangleHalfSize, - everestLatitude - rectangleHalfSize, - everestLongitude + rectangleHalfSize, - everestLatitude + rectangleHalfSize - ); - const terrainSamplePositions = []; - for (let y = 0; y < gridHeight; ++y) { - for (let x = 0; x < gridWidth; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridWidth - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridHeight - 1) - ); - const position = new Cesium.Cartographic(longitude, latitude); - terrainSamplePositions.push(position); - } + function createGrid(rectangleHalfSize) { + const gridWidth = 41; + const gridHeight = 41; + const everestLatitude = Cesium.Math.toRadians(27.988257); + const everestLongitude = Cesium.Math.toRadians(86.925145); + const e = new Cesium.Rectangle( + everestLongitude - rectangleHalfSize, + everestLatitude - rectangleHalfSize, + everestLongitude + rectangleHalfSize, + everestLatitude + rectangleHalfSize + ); + const terrainSamplePositions = []; + for (let y = 0; y < gridHeight; ++y) { + for (let x = 0; x < gridWidth; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridWidth - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridHeight - 1) + ); + const position = new Cesium.Cartographic(longitude, latitude); + terrainSamplePositions.push(position); } - return terrainSamplePositions; } + return terrainSamplePositions; + } - Sandcastle.addToggleButton( - "Enable Lighting", - viewer.scene.globe.enableLighting, - function (checked) { - viewer.scene.globe.enableLighting = checked; - } - ); + Sandcastle.addToggleButton( + "Enable Lighting", + viewer.scene.globe.enableLighting, + function (checked) { + viewer.scene.globe.enableLighting = checked; + } + ); - Sandcastle.addToggleButton( - "Enable fog", - viewer.scene.fog.enabled, - function (checked) { - viewer.scene.fog.enabled = checked; - } - ); + Sandcastle.addToggleButton( + "Enable fog", + viewer.scene.fog.enabled, + function (checked) { + viewer.scene.fog.enabled = checked; + } + ); - Sandcastle.addToolbarButton( - "Sample Everest Terrain at Level 9", - function () { - const terrainSamplePositions = createGrid(0.005); - Promise.resolve( - Cesium.sampleTerrain( - viewer.terrainProvider, - 9, - terrainSamplePositions - ) - ).then(sampleTerrainSuccess); - lookAtMtEverest(); - }, - "sampleButtons" - ); + Sandcastle.addToolbarButton( + "Sample Everest Terrain at Level 9", + function () { + const terrainSamplePositions = createGrid(0.005); + Promise.resolve( + Cesium.sampleTerrain( + viewer.terrainProvider, + 9, + terrainSamplePositions + ) + ).then(sampleTerrainSuccess); + lookAtMtEverest(); + }, + "sampleButtons" + ); - Sandcastle.addToolbarButton( - "Sample Most Detailed Everest Terrain", - function () { - if (!Cesium.defined(viewer.terrainProvider.availability)) { - window.alert( - "sampleTerrainMostDetailed is not supported for the selected terrain provider" - ); - return; - } - const terrainSamplePositions = createGrid(0.0005); - Promise.resolve( - Cesium.sampleTerrainMostDetailed( - viewer.terrainProvider, - terrainSamplePositions - ) - ).then(sampleTerrainSuccess); - lookAtMtEverest(); - }, - "sampleButtons" - ); - })(); //Sandcastle_End + Sandcastle.addToolbarButton( + "Sample Most Detailed Everest Terrain", + function () { + if (!Cesium.defined(viewer.terrainProvider.availability)) { + window.alert( + "sampleTerrainMostDetailed is not supported for the selected terrain provider" + ); + return; + } + const terrainSamplePositions = createGrid(0.0005); + Promise.resolve( + Cesium.sampleTerrainMostDetailed( + viewer.terrainProvider, + terrainSamplePositions + ) + ).then(sampleTerrainSuccess); + lookAtMtEverest(); + }, + "sampleButtons" + ); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 85e0580bc03..2ee1b79cbc6 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -37,137 +37,138 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - viewer.scene.globe.depthTestAgainstTerrain = true; + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const ellipsoid = viewer.scene.globe.ellipsoid; - const billboardCollection = viewer.scene.primitives.add( - new Cesium.BillboardCollection({ - scene: viewer.scene, - }) - ); + const ellipsoid = viewer.scene.globe.ellipsoid; + const billboardCollection = viewer.scene.primitives.add( + new Cesium.BillboardCollection({ + scene: viewer.scene, + }) + ); - // seneca - const centerLongitude = -1.385205433269729; - const centerLatitude = 0.6777926580888163; + // seneca + const centerLongitude = -1.385205433269729; + const centerLatitude = 0.6777926580888163; - const gridWidth = Math.floor(Math.random() * 100.0); - const gridHeight = Math.floor(Math.random() * 100.0); - const rectangleHalfSize = 0.0005; + const gridWidth = Math.floor(Math.random() * 100.0); + const gridHeight = Math.floor(Math.random() * 100.0); + const rectangleHalfSize = 0.0005; - const e = new Cesium.Rectangle( - centerLongitude - rectangleHalfSize, - centerLatitude - rectangleHalfSize, - centerLongitude + rectangleHalfSize, - centerLatitude + rectangleHalfSize - ); + const e = new Cesium.Rectangle( + centerLongitude - rectangleHalfSize, + centerLatitude - rectangleHalfSize, + centerLongitude + rectangleHalfSize, + centerLatitude + rectangleHalfSize + ); - for (let y = 0; y < gridHeight; ++y) { - for (let x = 0; x < gridWidth; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridWidth - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridHeight - 1) - ); - const position = new Cesium.Cartographic(longitude, latitude); + for (let y = 0; y < gridHeight; ++y) { + for (let x = 0; x < gridWidth; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridWidth - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridHeight - 1) + ); + const position = new Cesium.Cartographic(longitude, latitude); - billboardCollection.add({ - position: ellipsoid.cartographicToCartesian(position), - image: "../images/facility.gif", - heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, - }); - } + billboardCollection.add({ + position: ellipsoid.cartographicToCartesian(position), + image: "../images/facility.gif", + heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, + }); } + } - let billboard; + let billboard; - Sandcastle.addToolbarButton("Add billboard", function () { - if (!Cesium.defined(billboard)) { - billboard = billboardCollection.add({ - position: ellipsoid.cartographicToCartesian( - new Cesium.Cartographic( - centerLongitude, - centerLatitude, - 1000.0 - ) - ), - image: "../images/Cesium_Logo_overlay.png", - scale: 0.7, - heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, - }); - } - }); + Sandcastle.addToolbarButton("Add billboard", function () { + if (!Cesium.defined(billboard)) { + billboard = billboardCollection.add({ + position: ellipsoid.cartographicToCartesian( + new Cesium.Cartographic(centerLongitude, centerLatitude, 1000.0) + ), + image: "../images/Cesium_Logo_overlay.png", + scale: 0.7, + heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, + }); + } + }); - Sandcastle.addToolbarButton("Remove billboard", function () { - if (Cesium.defined(billboard)) { - billboardCollection.remove(billboard); - billboard = undefined; - } - }); + Sandcastle.addToolbarButton("Remove billboard", function () { + if (Cesium.defined(billboard)) { + billboardCollection.remove(billboard); + billboard = undefined; + } + }); - Sandcastle.addToolbarMenu([ - { - text: "Relative to ground", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = - Cesium.HeightReference.RELATIVE_TO_GROUND; - } - }, + Sandcastle.addToolbarMenu([ + { + text: "Relative to ground", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = + Cesium.HeightReference.RELATIVE_TO_GROUND; + } }, - { - text: "Clamp to ground", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = - Cesium.HeightReference.CLAMP_TO_GROUND; - } - }, + }, + { + text: "Clamp to ground", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = + Cesium.HeightReference.CLAMP_TO_GROUND; + } }, - { - text: "None", - onselect: function () { - if (Cesium.defined(billboard)) { - billboard.heightReference = Cesium.HeightReference.NONE; - } - }, + }, + { + text: "None", + onselect: function () { + if (Cesium.defined(billboard)) { + billboard.heightReference = Cesium.HeightReference.NONE; + } }, - ]); + }, + ]); - const lonGran = 0.00005; + const lonGran = 0.00005; - Sandcastle.addToolbarButton("Increase longitude", function () { - if (Cesium.defined(billboard)) { - const cartographic = ellipsoid.cartesianToCartographic( - billboard.position - ); - cartographic.longitude += lonGran; - billboard.position = ellipsoid.cartographicToCartesian( - cartographic - ); - } - }); + Sandcastle.addToolbarButton("Increase longitude", function () { + if (Cesium.defined(billboard)) { + const cartographic = ellipsoid.cartesianToCartographic( + billboard.position + ); + cartographic.longitude += lonGran; + billboard.position = ellipsoid.cartographicToCartesian( + cartographic + ); + } + }); - Sandcastle.addToolbarButton("Decrease longitude", function () { - if (Cesium.defined(billboard)) { - const cartographic = ellipsoid.cartesianToCartographic( - billboard.position - ); - cartographic.longitude -= lonGran; - billboard.position = ellipsoid.cartographicToCartesian( - cartographic - ); - } - }); - })(); //Sandcastle_End + Sandcastle.addToolbarButton("Decrease longitude", function () { + if (Cesium.defined(billboard)) { + const cartographic = ellipsoid.cartesianToCartographic( + billboard.position + ); + cartographic.longitude -= lonGran; + billboard.position = ellipsoid.cartographicToCartesian( + cartographic + ); + } + }); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index dafe938f95a..00861a900fa 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -37,201 +37,202 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - const scene = viewer.scene; - const context = scene.context; + const scene = viewer.scene; + const context = scene.context; - scene.debugShowFramesPerSecond = true; + scene.debugShowFramesPerSecond = true; - const ellipsoid = scene.globe.ellipsoid; - let billboardCollection; - let instancingEnabled = true; - const instancedArraysExtension = context._instancedArrays; - let billboardCount = 100489; - let scale = 1.0; + const ellipsoid = scene.globe.ellipsoid; + let billboardCollection; + let instancingEnabled = true; + const instancedArraysExtension = context._instancedArrays; + let billboardCount = 100489; + let scale = 1.0; - // seneca - const centerLongitude = -1.385205433269729; - const centerLatitude = 0.6777926580888163; - const rectangleHalfSize = 0.5; - const e = new Cesium.Rectangle( - centerLongitude - rectangleHalfSize, - centerLatitude - rectangleHalfSize, - centerLongitude + rectangleHalfSize, - centerLatitude + rectangleHalfSize - ); + // seneca + const centerLongitude = -1.385205433269729; + const centerLatitude = 0.6777926580888163; + const rectangleHalfSize = 0.5; + const e = new Cesium.Rectangle( + centerLongitude - rectangleHalfSize, + centerLatitude - rectangleHalfSize, + centerLongitude + rectangleHalfSize, + centerLatitude + rectangleHalfSize + ); - function resetBillboardCollection() { - if (Cesium.defined(billboardCollection)) { - scene.primitives.remove(billboardCollection); - } + function resetBillboardCollection() { + if (Cesium.defined(billboardCollection)) { + scene.primitives.remove(billboardCollection); + } - billboardCollection = scene.primitives.add( - new Cesium.BillboardCollection({ - scene: scene, - }) - ); + billboardCollection = scene.primitives.add( + new Cesium.BillboardCollection({ + scene: scene, + }) + ); - const gridSize = Math.sqrt(billboardCount); - for (let y = 0; y < gridSize; ++y) { - for (let x = 0; x < gridSize; ++x) { - const longitude = Cesium.Math.lerp( - e.west, - e.east, - x / (gridSize - 1) - ); - const latitude = Cesium.Math.lerp( - e.south, - e.north, - y / (gridSize - 1) - ); - const position = new Cesium.Cartographic( - longitude, - latitude, - 10000.0 - ); + const gridSize = Math.sqrt(billboardCount); + for (let y = 0; y < gridSize; ++y) { + for (let x = 0; x < gridSize; ++x) { + const longitude = Cesium.Math.lerp( + e.west, + e.east, + x / (gridSize - 1) + ); + const latitude = Cesium.Math.lerp( + e.south, + e.north, + y / (gridSize - 1) + ); + const position = new Cesium.Cartographic( + longitude, + latitude, + 10000.0 + ); - billboardCollection.add({ - position: ellipsoid.cartographicToCartesian(position), - image: "../images/facility.gif", - scale: scale, - }); - } + billboardCollection.add({ + position: ellipsoid.cartographicToCartesian(position), + image: "../images/facility.gif", + scale: scale, + }); } } + } - const moveAmount = new Cesium.Cartesian3(1000, 0.0, 0.0); - const positionScratch = new Cesium.Cartesian3(); - function animateBillboards() { - const billboards = billboardCollection._billboards; - const length = billboards.length; - for (let i = 0; i < length; ++i) { - const billboard = billboards[i]; - Cesium.Cartesian3.clone(billboard.position, positionScratch); - Cesium.Cartesian3.add( - positionScratch, - moveAmount, - positionScratch - ); - billboard.position = positionScratch; - } + const moveAmount = new Cesium.Cartesian3(1000, 0.0, 0.0); + const positionScratch = new Cesium.Cartesian3(); + function animateBillboards() { + const billboards = billboardCollection._billboards; + const length = billboards.length; + for (let i = 0; i < length; ++i) { + const billboard = billboards[i]; + Cesium.Cartesian3.clone(billboard.position, positionScratch); + Cesium.Cartesian3.add(positionScratch, moveAmount, positionScratch); + billboard.position = positionScratch; } + } - Sandcastle.addToolbarMenu([ - { - text: "Instancing Enabled", - onselect: function () { - if (!instancingEnabled) { - context._instancedArrays = instancedArraysExtension; - instancingEnabled = true; - resetBillboardCollection(); - } - }, + Sandcastle.addToolbarMenu([ + { + text: "Instancing Enabled", + onselect: function () { + if (!instancingEnabled) { + context._instancedArrays = instancedArraysExtension; + instancingEnabled = true; + resetBillboardCollection(); + } }, - { - text: "Instancing Disabled", - onselect: function () { - if (instancingEnabled) { - context._instancedArrays = undefined; - instancingEnabled = false; - resetBillboardCollection(); - } - }, + }, + { + text: "Instancing Disabled", + onselect: function () { + if (instancingEnabled) { + context._instancedArrays = undefined; + instancingEnabled = false; + resetBillboardCollection(); + } }, - ]); + }, + ]); - Sandcastle.addToolbarMenu([ - { - text: "100489 billboards", - onselect: function () { - billboardCount = 100489; - resetBillboardCollection(); - }, + Sandcastle.addToolbarMenu([ + { + text: "100489 billboards", + onselect: function () { + billboardCount = 100489; + resetBillboardCollection(); }, - { - text: "10000 billboards", - onselect: function () { - billboardCount = 10000; - resetBillboardCollection(); - }, + }, + { + text: "10000 billboards", + onselect: function () { + billboardCount = 10000; + resetBillboardCollection(); }, - { - text: "1024 billboards", - onselect: function () { - billboardCount = 1024; - resetBillboardCollection(); - }, + }, + { + text: "1024 billboards", + onselect: function () { + billboardCount = 1024; + resetBillboardCollection(); }, - { - text: "100 billboards", - onselect: function () { - billboardCount = 100; - resetBillboardCollection(); - }, + }, + { + text: "100 billboards", + onselect: function () { + billboardCount = 100; + resetBillboardCollection(); }, - { - text: "25 billboards", - onselect: function () { - billboardCount = 25; - resetBillboardCollection(); - }, + }, + { + text: "25 billboards", + onselect: function () { + billboardCount = 25; + resetBillboardCollection(); }, - { - text: "4 billboard", - onselect: function () { - billboardCount = 4; - resetBillboardCollection(); - }, + }, + { + text: "4 billboard", + onselect: function () { + billboardCount = 4; + resetBillboardCollection(); }, - ]); + }, + ]); - Sandcastle.addToolbarMenu([ - { - text: "Static billboards", - onselect: function () { - resetBillboardCollection(); - scene.preUpdate.removeEventListener(animateBillboards); - }, + Sandcastle.addToolbarMenu([ + { + text: "Static billboards", + onselect: function () { + resetBillboardCollection(); + scene.preUpdate.removeEventListener(animateBillboards); }, - { - text: "Animated billboards", - onselect: function () { - resetBillboardCollection(); - scene.preUpdate.addEventListener(animateBillboards); - }, + }, + { + text: "Animated billboards", + onselect: function () { + resetBillboardCollection(); + scene.preUpdate.addEventListener(animateBillboards); }, - ]); + }, + ]); - Sandcastle.addToolbarMenu([ - { - text: "Scale : 1.0", - onselect: function () { - scale = 1.0; - resetBillboardCollection(); - }, + Sandcastle.addToolbarMenu([ + { + text: "Scale : 1.0", + onselect: function () { + scale = 1.0; + resetBillboardCollection(); }, - { - text: "Scale : 0.5", - onselect: function () { - scale = 0.5; - resetBillboardCollection(); - }, + }, + { + text: "Scale : 0.5", + onselect: function () { + scale = 0.5; + resetBillboardCollection(); }, - { - text: "Scale : 0.1", - onselect: function () { - scale = 0.1; - resetBillboardCollection(); - }, + }, + { + text: "Scale : 0.1", + onselect: function () { + scale = 0.1; + resetBillboardCollection(); }, - ]); + }, + ]); - resetBillboardCollection(); - })(); //Sandcastle_End + resetBillboardCollection(); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 3cfa67c975e..58e3a370260 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -50,95 +50,100 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - viewer.extend(Cesium.viewerCesiumInspectorMixin); + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //The viewModel tracks the state of our mini application. - const viewModel = { - enabled: true, - density: 0, - sse: 0, - }; - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + //The viewModel tracks the state of our mini application. + const viewModel = { + enabled: true, + density: 0, + sse: 0, + }; + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "enabled") - .subscribe(function (newValue) { - viewer.scene.fog.enabled = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "enabled") + .subscribe(function (newValue) { + viewer.scene.fog.enabled = newValue; + }); - Cesium.knockout - .getObservable(viewModel, "density") - .subscribe(function (newValue) { - viewer.scene.fog.density = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "density") + .subscribe(function (newValue) { + viewer.scene.fog.density = newValue; + }); - Cesium.knockout - .getObservable(viewModel, "sse") - .subscribe(function (newValue) { - viewer.scene.fog.screenSpaceErrorFactor = newValue; - }); + Cesium.knockout + .getObservable(viewModel, "sse") + .subscribe(function (newValue) { + viewer.scene.fog.screenSpaceErrorFactor = newValue; + }); - viewModel.enabled = viewer.scene.fog.enabled; - viewModel.density = viewer.scene.fog.density; - viewModel.sse = viewer.scene.fog.screenSpaceErrorFactor; + viewModel.enabled = viewer.scene.fog.enabled; + viewModel.density = viewer.scene.fog.density; + viewModel.sse = viewer.scene.fog.screenSpaceErrorFactor; - Sandcastle.addToolbarButton("Horizon high altitude", function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -2467730.5740817646, - -4390507.315824514, - 3906155.113316938 - ), - orientation: { - heading: 4.492211521856625, - pitch: -0.2687139437696304, - }, - }); + Sandcastle.addToolbarButton("Horizon high altitude", function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -2467730.5740817646, + -4390507.315824514, + 3906155.113316938 + ), + orientation: { + heading: 4.492211521856625, + pitch: -0.2687139437696304, + }, }); + }); - Sandcastle.addToolbarButton("Horizon low altitude", function () { - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - -734001.9511656855, - -4214090.596769834, - 4715898.125886317 - ), - orientation: { - heading: 5.634257362559497, - pitch: -0.019548505785381032, - }, - }); + Sandcastle.addToolbarButton("Horizon low altitude", function () { + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + -734001.9511656855, + -4214090.596769834, + 4715898.125886317 + ), + orientation: { + heading: 5.634257362559497, + pitch: -0.019548505785381032, + }, }); + }); - viewer.scene.globe._surface._debug.enableDebugOutput = true; + viewer.scene.globe._surface._debug.enableDebugOutput = true; - Sandcastle.addToolbarButton("Snap", function () { - const container = document.getElementById("cesiumContainer"); - const tmpH = container.style.height; - const tmpW = container.style.width; + Sandcastle.addToolbarButton("Snap", function () { + const container = document.getElementById("cesiumContainer"); + const tmpH = container.style.height; + const tmpW = container.style.width; - container.style.height = "600px"; - container.style.width = "800px"; + container.style.height = "600px"; + container.style.width = "800px"; - viewer.resize(); - viewer.render(); - window.open(viewer.canvas.toDataURL("image/png")); - container.style.height = tmpH; - container.style.width = tmpW; - viewer.resize(); - viewer.render(); - }); - })(); //Sandcastle_End + viewer.resize(); + viewer.render(); + window.open(viewer.canvas.toDataURL("image/png")); + container.style.height = tmpH; + container.style.width = tmpW; + viewer.resize(); + viewer.render(); + }); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index 7122b8007a0..ed527e23634 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -35,522 +35,525 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ requestWaterMask: true, requestVertexNormals: true, - }), - }); - - if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { - window.alert( - "GroundPrimitive materials are not supported on this platform." - ); + }); + } catch (error) { + console.log(error); } - - let rectangle; - let worldRectangle; - - function applyAlphaMapMaterial(primitive, scene) { - Sandcastle.declare(applyAlphaMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - alphaMaterial: { - type: "AlphaMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - channel: "r", - }, + })(); + + if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { + window.alert( + "GroundPrimitive materials are not supported on this platform." + ); + } + + let rectangle; + let worldRectangle; + + function applyAlphaMapMaterial(primitive, scene) { + Sandcastle.declare(applyAlphaMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + alphaMaterial: { + type: "AlphaMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + channel: "r", }, }, - components: { - diffuse: "vec3(1.0)", - alpha: "alphaMaterial.alpha", - }, }, - }); - } - - function applyBumpMapMaterial(primitive, scene) { - Sandcastle.declare(applyBumpMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/bumpmap.png", - }, - }, - bumpMaterial: { - type: "BumpMap", - uniforms: { - image: "../images/bumpmap.png", - strength: 0.8, - }, + components: { + diffuse: "vec3(1.0)", + alpha: "alphaMaterial.alpha", + }, + }, + }); + } + + function applyBumpMapMaterial(primitive, scene) { + Sandcastle.declare(applyBumpMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/bumpmap.png", }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - specular: 0.01, - normal: "bumpMaterial.normal", + bumpMaterial: { + type: "BumpMap", + uniforms: { + image: "../images/bumpmap.png", + strength: 0.8, + }, }, }, - }); - } - - function applyCheckerboardMaterial(primitive, scene) { - Sandcastle.declare(applyCheckerboardMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType( - "Checkerboard" - ); - } - - function applyColorMaterial(primitive, scene) { - Sandcastle.declare(applyColorMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Color"); - } - - function applyCompositeMaterial(primitive, scene) { - Sandcastle.declare(applyCompositeMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - uniforms: { - image: "../images/earthspec1k.jpg", - heightField: "../images/earthbump1k.jpg", - }, - materials: { - bumpMap: { - type: "BumpMap", - uniforms: { - image: "../images/earthbump1k.jpg", - }, + components: { + diffuse: "diffuseMaterial.diffuse", + specular: 0.01, + normal: "bumpMaterial.normal", + }, + }, + }); + } + + function applyCheckerboardMaterial(primitive, scene) { + Sandcastle.declare(applyCheckerboardMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType( + "Checkerboard" + ); + } + + function applyColorMaterial(primitive, scene) { + Sandcastle.declare(applyColorMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Color"); + } + + function applyCompositeMaterial(primitive, scene) { + Sandcastle.declare(applyCompositeMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + uniforms: { + image: "../images/earthspec1k.jpg", + heightField: "../images/earthbump1k.jpg", + }, + materials: { + bumpMap: { + type: "BumpMap", + uniforms: { + image: "../images/earthbump1k.jpg", }, }, - source: - "czm_material czm_getMaterial(czm_materialInput materialInput) {" + - "czm_material material = czm_getDefaultMaterial(materialInput);" + - "float heightValue = texture2D(heightField, materialInput.st).r;" + - "material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);" + - "material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;" + - "material.normal = bumpMap.normal;" + - "material.specular = step(0.1, heightValue);" + // Specular mountain tops - "material.shininess = 8.0;" + // Sharpen highlight - "return material;" + - "}", }, - }); - } - - function applyDotMaterial(primitive, scene) { - Sandcastle.declare(applyDotMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Dot"); - } - - function applyDiffuseMaterial(primitive, scene) { - Sandcastle.declare(applyDiffuseMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "DiffuseMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - }, + source: + "czm_material czm_getMaterial(czm_materialInput materialInput) {" + + "czm_material material = czm_getDefaultMaterial(materialInput);" + + "float heightValue = texture2D(heightField, materialInput.st).r;" + + "material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);" + + "material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;" + + "material.normal = bumpMap.normal;" + + "material.specular = step(0.1, heightValue);" + // Specular mountain tops + "material.shininess = 8.0;" + // Sharpen highlight + "return material;" + + "}", + }, + }); + } + + function applyDotMaterial(primitive, scene) { + Sandcastle.declare(applyDotMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Dot"); + } + + function applyDiffuseMaterial(primitive, scene) { + Sandcastle.declare(applyDiffuseMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "DiffuseMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", }, - }); - } - - function applyEmissionMapMaterial(primitive, scene) { - Sandcastle.declare(applyEmissionMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - }, + }, + }); + } + + function applyEmissionMapMaterial(primitive, scene) { + Sandcastle.declare(applyEmissionMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", }, - emissionMaterial: { - type: "EmissionMap", - uniforms: { - image: "../images/checkerboard.png", - repeat: { - x: 1, - y: 0.5, - }, + }, + emissionMaterial: { + type: "EmissionMap", + uniforms: { + image: "../images/checkerboard.png", + repeat: { + x: 1, + y: 0.5, }, }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - emission: "emissionMaterial.emission * 0.2", - }, }, - }); - } - - function applyWaterMaterial(primitive, scene) { - Sandcastle.declare(applyWaterMaterial); // For highlighting in Sandcastle. - - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Water", - uniforms: { - specularMap: "../images/earthspec1k.jpg", - normalMap: Cesium.buildModuleUrl( - "Assets/Textures/waterNormals.jpg" - ), - frequency: 10000.0, - animationSpeed: 0.01, - amplitude: 1.0, - }, + components: { + diffuse: "diffuseMaterial.diffuse", + emission: "emissionMaterial.emission * 0.2", }, - }); - } - - function applyGridMaterial(primitive, scene) { - Sandcastle.declare(applyGridMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Grid"); - } - - function applyImageMaterial(primitive, scene) { - Sandcastle.declare(applyImageMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Image", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - }, + }, + }); + } + + function applyWaterMaterial(primitive, scene) { + Sandcastle.declare(applyWaterMaterial); // For highlighting in Sandcastle. + + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Water", + uniforms: { + specularMap: "../images/earthspec1k.jpg", + normalMap: Cesium.buildModuleUrl( + "Assets/Textures/waterNormals.jpg" + ), + frequency: 10000.0, + animationSpeed: 0.01, + amplitude: 1.0, }, - }); - } - - function applyRepeatedImage(primitive, scene) { - Sandcastle.declare(applyRepeatedImage); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "Image", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - repeat: { - x: 10, - y: 2, - }, + }, + }); + } + + function applyGridMaterial(primitive, scene) { + Sandcastle.declare(applyGridMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Grid"); + } + + function applyImageMaterial(primitive, scene) { + Sandcastle.declare(applyImageMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Image", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + }, + }, + }); + } + + function applyRepeatedImage(primitive, scene) { + Sandcastle.declare(applyRepeatedImage); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Image", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + repeat: { + x: 10, + y: 2, }, }, - }); - } - - function applyNormalMapMaterial(primitive, scene) { - Sandcastle.declare(applyNormalMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - materials: { - diffuseMaterial: { - type: "DiffuseMap", - uniforms: { - image: "../images/bumpmap.png", - }, - }, - normalMap: { - type: "NormalMap", - uniforms: { - image: "../images/normalmap.png", - strength: 0.6, - }, + }, + }); + } + + function applyNormalMapMaterial(primitive, scene) { + Sandcastle.declare(applyNormalMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + materials: { + diffuseMaterial: { + type: "DiffuseMap", + uniforms: { + image: "../images/bumpmap.png", }, }, - components: { - diffuse: "diffuseMaterial.diffuse", - specular: 0.01, - normal: "normalMap.normal", + normalMap: { + type: "NormalMap", + uniforms: { + image: "../images/normalmap.png", + strength: 0.6, + }, }, }, - }); - } - - function applySpecularMapMaterial(primitive, scene) { - Sandcastle.declare(applySpecularMapMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = new Cesium.Material({ - fabric: { - type: "SpecularMap", - uniforms: { - image: "../images/Cesium_Logo_Color.jpg", - channel: "r", - }, + components: { + diffuse: "diffuseMaterial.diffuse", + specular: 0.01, + normal: "normalMap.normal", }, - }); - } - - function applyStripeMaterial(primitive, scene) { - Sandcastle.declare(applyStripeMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType("Stripe"); + }, + }); + } + + function applySpecularMapMaterial(primitive, scene) { + Sandcastle.declare(applySpecularMapMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "SpecularMap", + uniforms: { + image: "../images/Cesium_Logo_Color.jpg", + channel: "r", + }, + }, + }); + } + + function applyStripeMaterial(primitive, scene) { + Sandcastle.declare(applyStripeMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType("Stripe"); + } + + function applyRimLightingMaterial(primitive, scene) { + Sandcastle.declare(applyRimLightingMaterial); // For highlighting in Sandcastle. + primitive.appearance.material = Cesium.Material.fromType( + "RimLighting" + ); + } + + function createButtons(scene) { + function toggleRectangleVisibility() { + rectangle.show = true; + worldRectangle.show = false; } - function applyRimLightingMaterial(primitive, scene) { - Sandcastle.declare(applyRimLightingMaterial); // For highlighting in Sandcastle. - primitive.appearance.material = Cesium.Material.fromType( - "RimLighting" - ); + function toggleWorldRectangleVisibility() { + worldRectangle.show = true; + rectangle.show = false; } - function createButtons(scene) { - function toggleRectangleVisibility() { - rectangle.show = true; - worldRectangle.show = false; - } - - function toggleWorldRectangleVisibility() { - worldRectangle.show = true; - rectangle.show = false; - } - - Sandcastle.addToolbarMenu([ - { - text: "Common materials", + Sandcastle.addToolbarMenu([ + { + text: "Common materials", + }, + { + text: "Color", + onselect: function () { + toggleRectangleVisibility(); + applyColorMaterial(rectangle, scene); + Sandcastle.highlight(applyColorMaterial); }, - { - text: "Color", - onselect: function () { - toggleRectangleVisibility(); - applyColorMaterial(rectangle, scene); - Sandcastle.highlight(applyColorMaterial); - }, + }, + { + text: "Image", + onselect: function () { + toggleRectangleVisibility(); + applyImageMaterial(rectangle, scene); + Sandcastle.highlight(applyImageMaterial); }, - { - text: "Image", - onselect: function () { - toggleRectangleVisibility(); - applyImageMaterial(rectangle, scene); - Sandcastle.highlight(applyImageMaterial); - }, + }, + { + text: "Repeated/Rotated Image", + onselect: function () { + toggleRectangleVisibility(); + applyRepeatedImage(rectangle, scene); + Sandcastle.highlight(applyRepeatedImage); }, - { - text: "Repeated/Rotated Image", - onselect: function () { - toggleRectangleVisibility(); - applyRepeatedImage(rectangle, scene); - Sandcastle.highlight(applyRepeatedImage); - }, + }, + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Procedural textures", + }, + { + text: "Checkerboard", + onselect: function () { + toggleRectangleVisibility(); + applyCheckerboardMaterial(rectangle, scene); + Sandcastle.highlight(applyCheckerboardMaterial); }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Procedural textures", + }, + { + text: "Dot", + onselect: function () { + toggleRectangleVisibility(); + applyDotMaterial(rectangle, scene); + Sandcastle.highlight(applyDotMaterial); }, - { - text: "Checkerboard", - onselect: function () { - toggleRectangleVisibility(); - applyCheckerboardMaterial(rectangle, scene); - Sandcastle.highlight(applyCheckerboardMaterial); - }, + }, + { + text: "Grid", + onselect: function () { + toggleRectangleVisibility(rectangle, worldRectangle); + applyGridMaterial(rectangle, scene); + Sandcastle.highlight(applyGridMaterial); }, - { - text: "Dot", - onselect: function () { - toggleRectangleVisibility(); - applyDotMaterial(rectangle, scene); - Sandcastle.highlight(applyDotMaterial); - }, + }, + { + text: "Stripe", + onselect: function () { + toggleRectangleVisibility(); + applyStripeMaterial(rectangle, scene); + Sandcastle.highlight(applyStripeMaterial); }, - { - text: "Grid", - onselect: function () { - toggleRectangleVisibility(rectangle, worldRectangle); - applyGridMaterial(rectangle, scene); - Sandcastle.highlight(applyGridMaterial); - }, + }, + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Base materials", + }, + { + text: "Alpha Map", + onselect: function () { + toggleRectangleVisibility(); + applyAlphaMapMaterial(rectangle, scene); + Sandcastle.highlight(applyAlphaMapMaterial); }, - { - text: "Stripe", - onselect: function () { - toggleRectangleVisibility(); - applyStripeMaterial(rectangle, scene); - Sandcastle.highlight(applyStripeMaterial); - }, + }, + { + text: "Bump Map", + onselect: function () { + toggleRectangleVisibility(); + applyBumpMapMaterial(rectangle, scene); + Sandcastle.highlight(applyBumpMapMaterial); }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Base materials", - }, - { - text: "Alpha Map", - onselect: function () { - toggleRectangleVisibility(); - applyAlphaMapMaterial(rectangle, scene); - Sandcastle.highlight(applyAlphaMapMaterial); - }, + }, + { + text: "Diffuse", + onselect: function () { + toggleRectangleVisibility(); + applyDiffuseMaterial(rectangle, scene); + Sandcastle.highlight(applyDiffuseMaterial); }, - { - text: "Bump Map", - onselect: function () { - toggleRectangleVisibility(); - applyBumpMapMaterial(rectangle, scene); - Sandcastle.highlight(applyBumpMapMaterial); - }, + }, + { + text: "Emission Map", + onselect: function () { + toggleRectangleVisibility(); + applyEmissionMapMaterial(rectangle, scene); + Sandcastle.highlight(applyEmissionMapMaterial); }, - { - text: "Diffuse", - onselect: function () { - toggleRectangleVisibility(); - applyDiffuseMaterial(rectangle, scene); - Sandcastle.highlight(applyDiffuseMaterial); - }, + }, + { + text: "Normal Map", + onselect: function () { + toggleRectangleVisibility(); + applyNormalMapMaterial(rectangle, scene); + Sandcastle.highlight(applyNormalMapMaterial); }, - { - text: "Emission Map", - onselect: function () { - toggleRectangleVisibility(); - applyEmissionMapMaterial(rectangle, scene); - Sandcastle.highlight(applyEmissionMapMaterial); - }, + }, + { + text: "Specular Map", + onselect: function () { + toggleRectangleVisibility(); + applySpecularMapMaterial(rectangle, scene); + Sandcastle.highlight(applySpecularMapMaterial); }, - { - text: "Normal Map", - onselect: function () { - toggleRectangleVisibility(); - applyNormalMapMaterial(rectangle, scene); - Sandcastle.highlight(applyNormalMapMaterial); - }, + }, + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Misc materials", + }, + { + text: "Rim Lighting", + onselect: function () { + toggleWorldRectangleVisibility(); + applyRimLightingMaterial(worldRectangle, scene); + Sandcastle.highlight(applyRimLightingMaterial); }, - { - text: "Specular Map", - onselect: function () { - toggleRectangleVisibility(); - applySpecularMapMaterial(rectangle, scene); - Sandcastle.highlight(applySpecularMapMaterial); - }, + }, + { + text: "Water", + onselect: function () { + toggleWorldRectangleVisibility(); + applyWaterMaterial(worldRectangle, scene); + Sandcastle.highlight(applyWaterMaterial); }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Misc materials", - }, - { - text: "Rim Lighting", - onselect: function () { - toggleWorldRectangleVisibility(); - applyRimLightingMaterial(worldRectangle, scene); - Sandcastle.highlight(applyRimLightingMaterial); - }, - }, - { - text: "Water", - onselect: function () { - toggleWorldRectangleVisibility(); - applyWaterMaterial(worldRectangle, scene); - Sandcastle.highlight(applyWaterMaterial); - }, - }, - ]); - - Sandcastle.addToolbarMenu([ - { - text: "Example composite materials", + }, + ]); + + Sandcastle.addToolbarMenu([ + { + text: "Example composite materials", + }, + { + text: "Composite Example", + onselect: function () { + toggleWorldRectangleVisibility(); + applyCompositeMaterial(worldRectangle, scene); + Sandcastle.highlight(applyCompositeMaterial); }, - { - text: "Composite Example", - onselect: function () { - toggleWorldRectangleVisibility(); - applyCompositeMaterial(worldRectangle, scene); - Sandcastle.highlight(applyCompositeMaterial); - }, - }, - ]); - - document.getElementById("toolbar").style.width = "10%"; - } - - function createPrimitives(scene) { - rectangle = scene.primitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromCartesianArray([ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ]), - vertexFormat: - Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, - }), - }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - worldRectangle = scene.primitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -179.99, - -89.99, - 179.99, - 89.99 + }, + ]); + + document.getElementById("toolbar").style.width = "10%"; + } + + function createPrimitives(scene) { + rectangle = scene.primitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromCartesianArray([ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 ), - vertexFormat: - Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, - }), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ]), + vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + worldRectangle = scene.primitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -179.99, + -89.99, + 179.99, + 89.99 + ), + vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, }), - show: false, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); - } + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, + }), + show: false, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); + } - const scene = viewer.scene; - scene.globe.enableLighting = true; + const scene = viewer.scene; + scene.globe.enableLighting = true; - createPrimitives(scene); - createButtons(scene); - })(); //Sandcastle_End + createPrimitives(scene); + createButtons(scene); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index 803764bbf9e..dfdebecdf7a 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -35,478 +35,473 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - viewer.extend(Cesium.viewerCesiumInspectorMixin); - - function offsetPositions(positions, degreeOffset) { - positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray( - positions - ); - const delta = Cesium.Math.toRadians(degreeOffset); - for (let i = 0; i < positions.length; ++i) { - const position = positions[i]; - position.latitude += delta; - position.longitude += delta; - } - return scene.globe.ellipsoid.cartographicArrayToCartesianArray( - positions - ); + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + + const scene = viewer.scene; + viewer.extend(Cesium.viewerCesiumInspectorMixin); + + function offsetPositions(positions, degreeOffset) { + positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray( + positions + ); + const delta = Cesium.Math.toRadians(degreeOffset); + for (let i = 0; i < positions.length; ++i) { + const position = positions[i]; + position.latitude += delta; + position.longitude += delta; + } + return scene.globe.ellipsoid.cartographicArrayToCartesianArray( + positions + ); + } + + function createOverlappingPolygons(withAlpha) { + const positions = [ + new Cesium.Cartesian3( + -2358138.847340281, + -3744072.459541374, + 4581158.5714175375 + ), + new Cesium.Cartesian3( + -2357231.4925370603, + -3745103.7886602185, + 4580702.9757762635 + ), + new Cesium.Cartesian3( + -2355912.902205431, + -3744249.029778454, + 4582402.154378103 + ), + new Cesium.Cartesian3( + -2357208.0209552636, + -3743553.4420488174, + 4581961.863286629 + ), + ]; + let polygonHierarchy = { positions: positions }; + + let color = Cesium.Color.RED; + if (withAlpha) { + color = color.withAlpha(0.5); } - function createOverlappingPolygons(withAlpha) { - const positions = [ - new Cesium.Cartesian3( - -2358138.847340281, - -3744072.459541374, - 4581158.5714175375 - ), - new Cesium.Cartesian3( - -2357231.4925370603, - -3745103.7886602185, - 4580702.9757762635 - ), - new Cesium.Cartesian3( - -2355912.902205431, - -3744249.029778454, - 4582402.154378103 - ), - new Cesium.Cartesian3( - -2357208.0209552636, - -3743553.4420488174, - 4581961.863286629 - ), - ]; - let polygonHierarchy = { positions: positions }; - - let color = Cesium.Color.RED; - if (withAlpha) { - color = color.withAlpha(0.5); - } - - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - color - ), - }, - id: "polygon 1", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Same polygon slightly offset and overlapping. - let positionsOffset = offsetPositions(positions, 0.01); - polygonHierarchy = { positions: positionsOffset }; - - color = Cesium.Color.GREEN; - if (withAlpha) { - color = color.withAlpha(0.5); - } - - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - color - ), - }, - id: "polygon 2", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Same polygon slightly offset and overlapping. - positionsOffset = offsetPositions(positions, -0.01); - polygonHierarchy = { positions: positionsOffset }; - - color = Cesium.Color.BLUE; - if (withAlpha) { - color = color.withAlpha(0.5); - } - - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: polygonHierarchy, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - color - ), - }, - id: "polygon 3", + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), + }, + id: "polygon 1", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Same polygon slightly offset and overlapping. + let positionsOffset = offsetPositions(positions, 0.01); + polygonHierarchy = { positions: positionsOffset }; + + color = Cesium.Color.GREEN; + if (withAlpha) { + color = color.withAlpha(0.5); } - function viewOverlappingPolygons() { - viewer.camera.lookAt( - new Cesium.Cartesian3( - -2354331.3069306486, - -3742016.2427205616, - 4581875.591571755 - ), - new Cesium.HeadingPitchRange( - Cesium.Math.toRadians(20.0), - Cesium.Math.toRadians(-35.0), - 10000.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), + }, + id: "polygon 2", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Same polygon slightly offset and overlapping. + positionsOffset = offsetPositions(positions, -0.01); + polygonHierarchy = { positions: positionsOffset }; + + color = Cesium.Color.BLUE; + if (withAlpha) { + color = color.withAlpha(0.5); } - let handler; - - Sandcastle.addDefaultToolbarButton("Picking Example", function () { - createOverlappingPolygons(true); - viewOverlappingPolygons(); - - let currentObject; - let lastColor; - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - pickedObject !== currentObject - ) { - if (Cesium.defined(currentObject)) { - currentObject.primitive.getGeometryInstanceAttributes( - currentObject.id - ).color = lastColor; - } - - currentObject = pickedObject; - - const attributes = currentObject.primitive.getGeometryInstanceAttributes( - currentObject.id - ); - lastColor = attributes.color; - attributes.color = [255, 255, 0, 128]; - } else if ( - !Cesium.defined(pickedObject) && - Cesium.defined(currentObject) - ) { + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: polygonHierarchy, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), + }, + id: "polygon 3", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + } + + function viewOverlappingPolygons() { + viewer.camera.lookAt( + new Cesium.Cartesian3( + -2354331.3069306486, + -3742016.2427205616, + 4581875.591571755 + ), + new Cesium.HeadingPitchRange( + Cesium.Math.toRadians(20.0), + Cesium.Math.toRadians(-35.0), + 10000.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + + let handler; + + Sandcastle.addDefaultToolbarButton("Picking Example", function () { + createOverlappingPolygons(true); + viewOverlappingPolygons(); + + let currentObject; + let lastColor; + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + pickedObject !== currentObject + ) { + if (Cesium.defined(currentObject)) { currentObject.primitive.getGeometryInstanceAttributes( currentObject.id ).color = lastColor; - currentObject = undefined; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - Sandcastle.addToolbarButton("Z-Order", function () { - createOverlappingPolygons(false); - viewOverlappingPolygons(); - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject)) { - scene.groundPrimitives.raiseToTop(pickedObject.primitive); - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - function createBatchedInstances(color, show) { - const instances = []; - - const width = 0.02561343838881669; - const height = 0.019831817968480436; - - let lat = 46.18147866629652; - let lon = -122.20406057655991; - - const delta = 0.03; - const latDeltas = [0.0, 0.0, delta, 0.0]; - const lonDeltas = [0.0, delta, 0.0, -delta]; - - const length = latDeltas.length; - for (let i = 0; i < length; ++i) { - lon = lon + lonDeltas[i]; - lat = lat + latDeltas[i]; - - const west = lon; - const east = lon + width; - const south = lat; - const north = lat + height; - - instances.push( - new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - west, - south, - east, - north - ), - }), - attributes: { - color: color, - show: show, - }, - id: `rectangle${i}`, - }) - ); - } - - return instances; - } - - Sandcastle.addToolbarButton("Batching", function () { - const color = new Cesium.ColorGeometryInstanceAttribute( - 0.0, - 1.0, - 1.0, - 0.5 - ); - const show = new Cesium.ShowGeometryInstanceAttribute(true); - const instances = createBatchedInstances(color, show); - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - viewOverlappingPolygons(); - }); - - Sandcastle.addToolbarButton("Batch Picking", function () { - let color = new Cesium.ColorGeometryInstanceAttribute( - 0.0, - 1.0, - 1.0, - 0.5 - ); - let show = new Cesium.ShowGeometryInstanceAttribute(true); - let instances = createBatchedInstances(color, show); - const primitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); + currentObject = pickedObject; - color = new Cesium.ColorGeometryInstanceAttribute( - 1.0, - 0.0, - 1.0, - 0.5 - ); - show = new Cesium.ShowGeometryInstanceAttribute(false); - instances = createBatchedInstances(color, show); - - // Edit id to differentiate between picked primitive and normally displayed primitive. - const pickIdPrefix = "pick"; - for (let i = 0; i < instances.length; ++i) { - instances[i].id = pickIdPrefix + instances[i].id; + const attributes = currentObject.primitive.getGeometryInstanceAttributes( + currentObject.id + ); + lastColor = attributes.color; + attributes.color = [255, 255, 0, 128]; + } else if ( + !Cesium.defined(pickedObject) && + Cesium.defined(currentObject) + ) { + currentObject.primitive.getGeometryInstanceAttributes( + currentObject.id + ).color = lastColor; + currentObject = undefined; } - - const pickPrimitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: instances, - classificationType: Cesium.ClassificationType.TERRAIN, + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + Sandcastle.addToolbarButton("Z-Order", function () { + createOverlappingPolygons(false); + viewOverlappingPolygons(); + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject)) { + scene.groundPrimitives.raiseToTop(pickedObject.primitive); + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + function createBatchedInstances(color, show) { + const instances = []; + + const width = 0.02561343838881669; + const height = 0.019831817968480436; + + let lat = 46.18147866629652; + let lon = -122.20406057655991; + + const delta = 0.03; + const latDeltas = [0.0, 0.0, delta, 0.0]; + const lonDeltas = [0.0, delta, 0.0, -delta]; + + const length = latDeltas.length; + for (let i = 0; i < length; ++i) { + lon = lon + lonDeltas[i]; + lat = lat + latDeltas[i]; + + const west = lon; + const east = lon + width; + const south = lat; + const north = lat + height; + + instances.push( + new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + west, + south, + east, + north + ), + }), + attributes: { + color: color, + show: show, + }, + id: `rectangle${i}`, }) ); + } - viewOverlappingPolygons(); - - let currentObject; - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - pickedObject !== currentObject && - pickedObject.id.indexOf(pickIdPrefix) === -1 - ) { - if (Cesium.defined(currentObject)) { - primitive.getGeometryInstanceAttributes( - currentObject.id - ).show = [1]; - pickPrimitive.getGeometryInstanceAttributes( - pickIdPrefix + currentObject.id - ).show = [0]; - } - - currentObject = pickedObject; + return instances; + } + + Sandcastle.addToolbarButton("Batching", function () { + const color = new Cesium.ColorGeometryInstanceAttribute( + 0.0, + 1.0, + 1.0, + 0.5 + ); + const show = new Cesium.ShowGeometryInstanceAttribute(true); + const instances = createBatchedInstances(color, show); + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + viewOverlappingPolygons(); + }); + + Sandcastle.addToolbarButton("Batch Picking", function () { + let color = new Cesium.ColorGeometryInstanceAttribute( + 0.0, + 1.0, + 1.0, + 0.5 + ); + let show = new Cesium.ShowGeometryInstanceAttribute(true); + let instances = createBatchedInstances(color, show); + + const primitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + color = new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 1.0, 0.5); + show = new Cesium.ShowGeometryInstanceAttribute(false); + instances = createBatchedInstances(color, show); + + // Edit id to differentiate between picked primitive and normally displayed primitive. + const pickIdPrefix = "pick"; + for (let i = 0; i < instances.length; ++i) { + instances[i].id = pickIdPrefix + instances[i].id; + } - primitive.getGeometryInstanceAttributes( - currentObject.id - ).show = [0]; - pickPrimitive.getGeometryInstanceAttributes( - pickIdPrefix + currentObject.id - ).show = [1]; - } else if ( - !Cesium.defined(pickedObject) && - Cesium.defined(currentObject) - ) { + const pickPrimitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: instances, + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + viewOverlappingPolygons(); + + let currentObject; + + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + pickedObject !== currentObject && + pickedObject.id.indexOf(pickIdPrefix) === -1 + ) { + if (Cesium.defined(currentObject)) { primitive.getGeometryInstanceAttributes( currentObject.id ).show = [1]; pickPrimitive.getGeometryInstanceAttributes( pickIdPrefix + currentObject.id ).show = [0]; - currentObject = undefined; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }); - - Sandcastle.addToolbarButton("Create large polygons", function () { - // Circle geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.CircleGeometry({ - center: Cesium.Cartesian3.fromDegrees(-95.0, 45.0), - radius: 250000.0, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - }, - id: "circle", - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - // Ellipse Geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipseGeometry({ - center: Cesium.Cartesian3.fromDegrees(-105.0, 40.0), - semiMinorAxis: 300000.0, - semiMajorAxis: 400000.0, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 1.0, 1.0, 0.5) - ), - }, - id: "ellipse", + currentObject = pickedObject; + + primitive.getGeometryInstanceAttributes(currentObject.id).show = [ + 0, + ]; + pickPrimitive.getGeometryInstanceAttributes( + pickIdPrefix + currentObject.id + ).show = [1]; + } else if ( + !Cesium.defined(pickedObject) && + Cesium.defined(currentObject) + ) { + primitive.getGeometryInstanceAttributes(currentObject.id).show = [ + 1, + ]; + pickPrimitive.getGeometryInstanceAttributes( + pickIdPrefix + currentObject.id + ).show = [0]; + currentObject = undefined; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + }); + + Sandcastle.addToolbarButton("Create large polygons", function () { + // Circle geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.CircleGeometry({ + center: Cesium.Cartesian3.fromDegrees(-95.0, 45.0), + radius: 250000.0, }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Corridor Geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.CorridorGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -112.0, - 40.0, - -117.0, - 40.0, - -117.0, - 35.0, - ]), - width: 200000.0, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 0.0, 1.0, 0.5) - ), - }, - id: "corridor", + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + }, + id: "circle", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Ellipse Geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipseGeometry({ + center: Cesium.Cartesian3.fromDegrees(-105.0, 40.0), + semiMinorAxis: 300000.0, + semiMajorAxis: 400000.0, }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Rectangle geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -90.0, - 40.0 - ), - rotation: Cesium.Math.toRadians(45), - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(0.0, 1.0, 0.0, 0.5) - ), - }, - id: "rectangle", + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 1.0, 1.0, 0.5) + ), + }, + id: "ellipse", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Corridor Geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -112.0, + 40.0, + -117.0, + 40.0, + -117.0, + 35.0, + ]), + width: 200000.0, }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - // Rhumb line polygon geometry - scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.PolygonGeometry({ - polygonHierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArray([ - -130, - 55, - -100, - 55, - -100, - 45, - -130, - 45, - ]) - ), - arcType: Cesium.ArcType.RHUMB, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 1.0, 0.0, 0.5) - ), - }, - id: "rhumbPolygon", + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 0.0, 1.0, 0.5) + ), + }, + id: "corridor", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Rectangle geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -90.0, + 40.0 + ), + rotation: Cesium.Math.toRadians(45), }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - }); - - Sandcastle.reset = function () { - scene.groundPrimitives.removeAll(); - handler = handler && handler.destroy(); - - //Set the camera to a US centered tilted view and switch back to moving in world coordinates. - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-98.0, 40.0), - new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }; - })(); //Sandcastle_End + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(0.0, 1.0, 0.0, 0.5) + ), + }, + id: "rectangle", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + + // Rhumb line polygon geometry + scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.PolygonGeometry({ + polygonHierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArray([ + -130, + 55, + -100, + 55, + -100, + 45, + -130, + 45, + ]) + ), + arcType: Cesium.ArcType.RHUMB, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 1.0, 0.0, 0.5) + ), + }, + id: "rhumbPolygon", + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); + }); + + Sandcastle.reset = function () { + scene.groundPrimitives.removeAll(); + handler = handler && handler.destroy(); + + //Set the camera to a US centered tilted view and switch back to moving in world coordinates. + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-98.0, 40.0), + new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }; + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index 8fa29968ca9..492fed56efe 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -41,102 +41,108 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - scene3DOnly: true, - infoBox: false, - selectionIndicator: false, - timeline: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - - const scene = viewer.scene; - const camera = scene.camera; - - scene.debugShowFramesPerSecond = true; - - function addPrimitive(lon, lat, height, heading) { - const center = Cesium.Cartesian3.fromRadians(lon, lat, height); + const viewer = new Cesium.Viewer("cesiumContainer", { + scene3DOnly: true, + infoBox: false, + selectionIndicator: false, + timeline: false, + }); - const pointLightCamera = new Cesium.Camera(scene); - pointLightCamera.position = center; - - camera.lookAt(center, new Cesium.Cartesian3(25.0, 25.0, 30.0)); - camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - - const shadowMap = new Cesium.ShadowMap({ - context: scene.context, - lightCamera: pointLightCamera, - isPointLight: true, - softShadows: false, - }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); - shadowMap.enabled = true; - - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: - "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - center, - new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) - ), - }) - ); - - model.readyPromise - .then(function (model) { - // Play and loop all animations at half-speed - model.activeAnimations.addAll({ - multiplier: 0.5, - loop: Cesium.ModelAnimationLoop.REPEAT, - }); - }) - .catch(function (error) { - window.alert(error); - }); + const scene = viewer.scene; + const camera = scene.camera; - return shadowMap; - } + scene.debugShowFramesPerSecond = true; - const longitude = -1.3324415110874286; - const latitude = 0.6954224325279967; - const height = 200.0; + function addPrimitive(lon, lat, height, heading) { + const center = Cesium.Cartesian3.fromRadians(lon, lat, height); - const shadowMap1 = addPrimitive( - longitude + 0.00005, - latitude, - height, - 0.0 - ); - const shadowMap2 = addPrimitive( - longitude - 0.00005, - latitude, - height, - Math.PI - ); + const pointLightCamera = new Cesium.Camera(scene); + pointLightCamera.position = center; - shadowMap1.debugShow = true; - shadowMap2.debugShow = false; + camera.lookAt(center, new Cesium.Cartesian3(25.0, 25.0, 30.0)); + camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - Sandcastle.addToolbarButton("Debug Toggle", function () { - shadowMap1.debugShow = !shadowMap1.debugShow; - shadowMap2.debugShow = !shadowMap2.debugShow; + const shadowMap = new Cesium.ShadowMap({ + context: scene.context, + lightCamera: pointLightCamera, + isPointLight: true, + softShadows: false, }); - scene.shadowMap = shadowMap1; - - // Workaround until Cesium supports multiple light sources - const CustomPrimitive = function (shadowMap) { - this.shadowMap = shadowMap; - }; + shadowMap.enabled = true; + + const model = scene.primitives.add( + Cesium.Model.fromGltf({ + url: + "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + center, + new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) + ), + }) + ); - CustomPrimitive.prototype.update = function (frameState) { - frameState.shadowMaps.push(this.shadowMap); - }; + model.readyPromise + .then(function (model) { + // Play and loop all animations at half-speed + model.activeAnimations.addAll({ + multiplier: 0.5, + loop: Cesium.ModelAnimationLoop.REPEAT, + }); + }) + .catch(function (error) { + window.alert(error); + }); - scene.primitives.add(new CustomPrimitive(shadowMap2)); - })(); //Sandcastle_End + return shadowMap; + } + + const longitude = -1.3324415110874286; + const latitude = 0.6954224325279967; + const height = 200.0; + + const shadowMap1 = addPrimitive( + longitude + 0.00005, + latitude, + height, + 0.0 + ); + const shadowMap2 = addPrimitive( + longitude - 0.00005, + latitude, + height, + Math.PI + ); + + shadowMap1.debugShow = true; + shadowMap2.debugShow = false; + + Sandcastle.addToolbarButton("Debug Toggle", function () { + shadowMap1.debugShow = !shadowMap1.debugShow; + shadowMap2.debugShow = !shadowMap2.debugShow; + }); + + scene.shadowMap = shadowMap1; + + // Workaround until Cesium supports multiple light sources + const CustomPrimitive = function (shadowMap) { + this.shadowMap = shadowMap; + }; + + CustomPrimitive.prototype.update = function (frameState) { + frameState.shadowMaps.push(this.shadowMap); + }; + + scene.primitives.add(new CustomPrimitive(shadowMap2)); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index add7bd5fd88..aedb55060ce 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -53,315 +53,320 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + const viewer = new Cesium.Viewer("cesiumContainer"); + (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ requestWaterMask: true, requestVertexNormals: true, - }), - }); - - if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); + }); + } catch (error) { + console.log(error); } + })(); - const polylineIds = ["polyline1", "polyline2"]; - const groundPrimitiveId = "ground primitive"; - let selectedId = polylineIds[0]; - let polylineOnTerrainPrimitive; - let groundPrimitiveOnTop = false; - - let lineWidth = 4.0; - const viewModel = { - lineWidth: lineWidth, - }; + if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." + ); + } - Cesium.knockout.track(viewModel); + const polylineIds = ["polyline1", "polyline2"]; + const groundPrimitiveId = "ground primitive"; + let selectedId = polylineIds[0]; + let polylineOnTerrainPrimitive; + let groundPrimitiveOnTop = false; - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + let lineWidth = 4.0; + const viewModel = { + lineWidth: lineWidth, + }; - Cesium.knockout - .getObservable(viewModel, "lineWidth") - .subscribe(function (newValue) { - lineWidth = parseFloat(viewModel.lineWidth); - if (Cesium.defined(selectedId)) { - const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - selectedId - ); - lineWidth = parseFloat(viewModel.lineWidth); - attributes.width = [lineWidth]; - } - }); + Cesium.knockout.track(viewModel); - const scene = viewer.scene; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - // Add a Rectangle GroundPrimitive to demonstrate Z-indexing with GroundPrimitives - const rectangleGroundPrimitive = scene.groundPrimitives.add( - new Cesium.GroundPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -112.1340164450331, - 36.05494287836128, - -112.0840164450331, - 36.10494287836128 - ), - vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, - }), - id: groundPrimitiveId, - }), - appearance: new Cesium.EllipsoidSurfaceAppearance({ - aboveGround: false, - material: Cesium.Material.fromType("Color"), - }), - classificationType: Cesium.ClassificationType.TERRAIN, - }) - ); - - const leftHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - leftHandler.setInputAction(function (movement) { - const pickedObject = viewer.scene.pick(movement.position); - if (Cesium.defined(pickedObject)) { - console.log(pickedObject.id); - // If picked the ground primitive, don't do anything - if (pickedObject.id !== groundPrimitiveId) { - selectedId = pickedObject.id; - - // Sync line width in toolbar with selected - const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - selectedId - ); - viewModel.lineWidth = attributes.width[0]; - } - } else { - selectedId = undefined; + Cesium.knockout + .getObservable(viewModel, "lineWidth") + .subscribe(function (newValue) { + lineWidth = parseFloat(viewModel.lineWidth); + if (Cesium.defined(selectedId)) { + const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + selectedId + ); + lineWidth = parseFloat(viewModel.lineWidth); + attributes.width = [lineWidth]; } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - - const polylinePositions = Cesium.Cartesian3.fromDegreesArray([ - -112.1340164450331, - 36.05494287836128, - -112.08821010582645, - 36.097804071380715, - -112.13296079730024, - 36.168769146801104, - -112.10828895143331, - 36.20031318533197, - -112.138548165717, - 36.1691100215289, // hairpins - -112.11482556496543, - 36.20127524083297, - -112.15921333464016, - 36.17876011207708, - -112.14700151155604, - 36.21683132404626, - -112.20919883052926, - 36.19475754001766, - ]); + }); - const loopPositions = Cesium.Cartesian3.fromDegreesArray([ - -111.94500779274114, - 36.27638678884143, - -111.90983004392696, - 36.07985366173454, - -111.80360100637773, - 36.13694878292542, - -111.85510122419183, - 36.26029588763386, - -111.69141601804614, - 36.05128770351902, - ]); + const scene = viewer.scene; - function createPolylines(debugShowShadowVolume) { - const instance1 = new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: polylinePositions, - loop: false, - width: 4.0, - }), - id: polylineIds[0], - attributes: { - show: new Cesium.ShowGeometryInstanceAttribute(), - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("green").withAlpha(0.7) + // Add a Rectangle GroundPrimitive to demonstrate Z-indexing with GroundPrimitives + const rectangleGroundPrimitive = scene.groundPrimitives.add( + new Cesium.GroundPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -112.1340164450331, + 36.05494287836128, + -112.0840164450331, + 36.10494287836128 ), - }, - }); - - const instance2 = new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: loopPositions, - loop: true, - width: 8.0, + vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT, }), - id: polylineIds[1], - attributes: { - show: new Cesium.ShowGeometryInstanceAttribute(), - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#67ADDF").withAlpha(0.7) - ), - }, - }); + id: groundPrimitiveId, + }), + appearance: new Cesium.EllipsoidSurfaceAppearance({ + aboveGround: false, + material: Cesium.Material.fromType("Color"), + }), + classificationType: Cesium.ClassificationType.TERRAIN, + }) + ); - polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({ - geometryInstances: [instance1, instance2], - debugShowShadowVolume: debugShowShadowVolume, - }); - scene.groundPrimitives.add(polylineOnTerrainPrimitive); - } + const leftHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + leftHandler.setInputAction(function (movement) { + const pickedObject = viewer.scene.pick(movement.position); + if (Cesium.defined(pickedObject)) { + console.log(pickedObject.id); + // If picked the ground primitive, don't do anything + if (pickedObject.id !== groundPrimitiveId) { + selectedId = pickedObject.id; - function applyPerInstanceColor() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineColorAppearance(); - } - function applyColorMaterial() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("Color", { - color: new Cesium.Color(0.7, 0.0, 1.0, 1.0), - }), - } - ); - } - function applyGlowMaterial() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineGlow", { - innerWidth: 1.0, - }), - } - ); - } - function applyArrow() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineArrow"), - } - ); - } - function applyDash() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineDash", { - color: Cesium.Color.YELLOW, - }), - } - ); - } - function applyOutline() { - polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( - { - material: Cesium.Material.fromType("PolylineOutline"), - } - ); - } - - Sandcastle.addToolbarButton("Toggle instance show", function () { - if (Cesium.defined(selectedId)) { + // Sync line width in toolbar with selected const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( selectedId ); - attributes.show = [attributes.show[0] ? 0 : 1]; + viewModel.lineWidth = attributes.width[0]; } + } else { + selectedId = undefined; + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + + const polylinePositions = Cesium.Cartesian3.fromDegreesArray([ + -112.1340164450331, + 36.05494287836128, + -112.08821010582645, + 36.097804071380715, + -112.13296079730024, + 36.168769146801104, + -112.10828895143331, + 36.20031318533197, + -112.138548165717, + 36.1691100215289, // hairpins + -112.11482556496543, + 36.20127524083297, + -112.15921333464016, + 36.17876011207708, + -112.14700151155604, + 36.21683132404626, + -112.20919883052926, + 36.19475754001766, + ]); + + const loopPositions = Cesium.Cartesian3.fromDegreesArray([ + -111.94500779274114, + 36.27638678884143, + -111.90983004392696, + 36.07985366173454, + -111.80360100637773, + 36.13694878292542, + -111.85510122419183, + 36.26029588763386, + -111.69141601804614, + 36.05128770351902, + ]); + + function createPolylines(debugShowShadowVolume) { + const instance1 = new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: polylinePositions, + loop: false, + width: 4.0, + }), + id: polylineIds[0], + attributes: { + show: new Cesium.ShowGeometryInstanceAttribute(), + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("green").withAlpha(0.7) + ), + }, }); - Sandcastle.addToolbarButton("Show all", function () { - if (Cesium.defined(selectedId)) { - let attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - "polyline1" - ); - attributes.show = [1]; - attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( - "polyline2" - ); - attributes.show = [1]; - } + const instance2 = new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: loopPositions, + loop: true, + width: 8.0, + }), + id: polylineIds[1], + attributes: { + show: new Cesium.ShowGeometryInstanceAttribute(), + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#67ADDF").withAlpha(0.7) + ), + }, + }); + + polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({ + geometryInstances: [instance1, instance2], + debugShowShadowVolume: debugShowShadowVolume, }); + scene.groundPrimitives.add(polylineOnTerrainPrimitive); + } - Sandcastle.addToolbarButton( - "Toggle debugShowShadowVolume", - function () { - const debugShowShadowVolume = !polylineOnTerrainPrimitive.debugShowShadowVolume; - const appearance = polylineOnTerrainPrimitive.appearance; - scene.groundPrimitives.remove(polylineOnTerrainPrimitive); - createPolylines(debugShowShadowVolume); - polylineOnTerrainPrimitive.appearance = appearance; + function applyPerInstanceColor() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineColorAppearance(); + } + function applyColorMaterial() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("Color", { + color: new Cesium.Color(0.7, 0.0, 1.0, 1.0), + }), } ); - - Sandcastle.addToolbarButton("Toggle z-index", function () { - if (groundPrimitiveOnTop) { - scene.groundPrimitives.raiseToTop(polylineOnTerrainPrimitive); - } else { - scene.groundPrimitives.lowerToBottom(polylineOnTerrainPrimitive); + } + function applyGlowMaterial() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineGlow", { + innerWidth: 1.0, + }), } - groundPrimitiveOnTop = !groundPrimitiveOnTop; - }); + ); + } + function applyArrow() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineArrow"), + } + ); + } + function applyDash() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineDash", { + color: Cesium.Color.YELLOW, + }), + } + ); + } + function applyOutline() { + polylineOnTerrainPrimitive.appearance = new Cesium.PolylineMaterialAppearance( + { + material: Cesium.Material.fromType("PolylineOutline"), + } + ); + } - function lookAt() { - viewer.camera.lookAt( - polylinePositions[1], - new Cesium.Cartesian3(50000.0, 50000.0, 50000.0) + Sandcastle.addToolbarButton("Toggle instance show", function () { + if (Cesium.defined(selectedId)) { + const attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + selectedId ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + attributes.show = [attributes.show[0] ? 0 : 1]; } + }); - Sandcastle.addToolbarButton("reset view", function () { - lookAt(); - }); + Sandcastle.addToolbarButton("Show all", function () { + if (Cesium.defined(selectedId)) { + let attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + "polyline1" + ); + attributes.show = [1]; + attributes = polylineOnTerrainPrimitive.getGeometryInstanceAttributes( + "polyline2" + ); + attributes.show = [1]; + } + }); - createPolylines(false); - applyPerInstanceColor(); + Sandcastle.addToolbarButton( + "Toggle debugShowShadowVolume", + function () { + const debugShowShadowVolume = !polylineOnTerrainPrimitive.debugShowShadowVolume; + const appearance = polylineOnTerrainPrimitive.appearance; + scene.groundPrimitives.remove(polylineOnTerrainPrimitive); + createPolylines(debugShowShadowVolume); + polylineOnTerrainPrimitive.appearance = appearance; + } + ); + Sandcastle.addToolbarButton("Toggle z-index", function () { + if (groundPrimitiveOnTop) { + scene.groundPrimitives.raiseToTop(polylineOnTerrainPrimitive); + } else { + scene.groundPrimitives.lowerToBottom(polylineOnTerrainPrimitive); + } + groundPrimitiveOnTop = !groundPrimitiveOnTop; + }); + + function lookAt() { + viewer.camera.lookAt( + polylinePositions[1], + new Cesium.Cartesian3(50000.0, 50000.0, 50000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + + Sandcastle.addToolbarButton("reset view", function () { lookAt(); + }); - Sandcastle.addToolbarMenu([ - { - text: "Per Instance Color", - onselect: function () { - applyPerInstanceColor(); - Sandcastle.highlight(applyPerInstanceColor); - }, + createPolylines(false); + applyPerInstanceColor(); + + lookAt(); + + Sandcastle.addToolbarMenu([ + { + text: "Per Instance Color", + onselect: function () { + applyPerInstanceColor(); + Sandcastle.highlight(applyPerInstanceColor); }, - { - text: "Color", - onselect: function () { - applyColorMaterial(); - Sandcastle.highlight(applyColorMaterial); - }, + }, + { + text: "Color", + onselect: function () { + applyColorMaterial(); + Sandcastle.highlight(applyColorMaterial); }, - { - text: "Glow", - onselect: function () { - applyGlowMaterial(); - Sandcastle.highlight(applyGlowMaterial); - }, + }, + { + text: "Glow", + onselect: function () { + applyGlowMaterial(); + Sandcastle.highlight(applyGlowMaterial); }, - { - text: "Arrow", - onselect: function () { - applyArrow(); - Sandcastle.highlight(applyArrow); - }, + }, + { + text: "Arrow", + onselect: function () { + applyArrow(); + Sandcastle.highlight(applyArrow); }, - { - text: "Dash", - onselect: function () { - applyDash(); - Sandcastle.highlight(applyDash); - }, + }, + { + text: "Dash", + onselect: function () { + applyDash(); + Sandcastle.highlight(applyDash); }, - { - text: "Outline", - onselect: function () { - applyOutline(); - Sandcastle.highlight(applyOutline); - }, + }, + { + text: "Outline", + onselect: function () { + applyOutline(); + Sandcastle.highlight(applyOutline); }, - ]); - })(); //Sandcastle_End + }, + ]); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index adf9068d00e..5ea861d821d 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -35,245 +35,250 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const camera = scene.camera; - const globe = scene.globe; - const statistics = Cesium.RequestScheduler.statistics; - - let startTime; - let flightComplete; - let monitor; - let minFrameRate = 1000; - let maxFrameRate = 0; - let sumFrameRate = 0.0; - let frameRateSamples = 0; + const viewer = new Cesium.Viewer("cesiumContainer", {}); + const scene = viewer.scene; + const camera = scene.camera; + const globe = scene.globe; + const statistics = Cesium.RequestScheduler.statistics; - function startTest() { - flightComplete = false; - statistics.numberOfActiveRequestsEver = 0; - monitor = new Cesium.FrameRateMonitor({ - scene: scene, - samplingWindow: 1.0, - quietPeriod: 0.0, - warmupPeriod: 0.0, - minimumFrameRateDuringWarmup: 0, - minimumFrameRateAfterWarmup: 0, - }); - scene.preUpdate.addEventListener(measureFrameRate); - startTime = window.performance.now(); - window.setTimeout(function () { - scene.postRender.addEventListener(viewReady); - }, 500); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); } + })(); - function measureFrameRate() { - const frameRate = monitor.lastFramesPerSecond; - if (frameRate === undefined || frameRate !== frameRate) { - return; - } + let startTime; + let flightComplete; + let monitor; + let minFrameRate = 1000; + let maxFrameRate = 0; + let sumFrameRate = 0.0; + let frameRateSamples = 0; - ++frameRateSamples; - sumFrameRate += frameRate; - minFrameRate = Math.min(minFrameRate, frameRate); - maxFrameRate = Math.max(maxFrameRate, frameRate); - } + function startTest() { + flightComplete = false; + statistics.numberOfActiveRequestsEver = 0; + monitor = new Cesium.FrameRateMonitor({ + scene: scene, + samplingWindow: 1.0, + quietPeriod: 0.0, + warmupPeriod: 0.0, + minimumFrameRateDuringWarmup: 0, + minimumFrameRateAfterWarmup: 0, + }); + scene.preUpdate.addEventListener(measureFrameRate); + startTime = window.performance.now(); + window.setTimeout(function () { + scene.postRender.addEventListener(viewReady); + }, 500); + } - function viewReady(scene, time) { - const ready = - globe._surface.tileProvider.ready && - globe._surface._tileLoadQueueHigh.length === 0 && - globe._surface._tileLoadQueueMedium.length === 0 && - globe._surface._tileLoadQueueLow.length === 0 && - globe._surface._debug.tilesWaitingForChildren === 0; - if (flightComplete && ready) { - const endTime = window.performance.now(); - const duration = endTime - startTime; - alert( - `${(duration / 1000).toFixed(2)} seconds ${ - statistics.numberOfActiveRequestsEver - } requests, min/max/avg frame FPS ${minFrameRate}/${maxFrameRate}/${ - sumFrameRate / frameRateSamples - }` - ); - scene.postRender.removeEventListener(viewReady); - } + function measureFrameRate() { + const frameRate = monitor.lastFramesPerSecond; + if (frameRate === undefined || frameRate !== frameRate) { + return; } - function goToEverestHorizontal() { - camera.position = new Cesium.Cartesian3( - 302950.1757410969, - 5637093.359233209, - 2976894.491577989 - ); - camera.direction = new Cesium.Cartesian3( - -0.9648960658153797, - -0.24110066659365145, - -0.10414437451009724 - ); - camera.right = new Cesium.Cartesian3( - -0.02152846103178338, - 0.46781654381873394, - -0.8835633574877908 - ); - camera.up = new Cesium.Cartesian3( - -0.26174817580950865, - 0.8503047394302772, - 0.456584868959543 - ); - flightComplete = true; - } + ++frameRateSamples; + sumFrameRate += frameRate; + minFrameRate = Math.min(minFrameRate, frameRate); + maxFrameRate = Math.max(maxFrameRate, frameRate); + } - function goToEverestTopDown() { - camera.position = new Cesium.Cartesian3( - 301989.1870802739, - 5637745.915399717, - 2977153.0443453398 - ); - camera.direction = new Cesium.Cartesian3( - 0.021398841015326783, - -0.8909524564021135, - -0.45359211857597476 - ); - camera.right = new Cesium.Cartesian3( - 0.21237352569072232, - 0.4473925820246778, - -0.8687562161705573 + function viewReady(scene, time) { + const ready = + globe._surface.tileProvider.ready && + globe._surface._tileLoadQueueHigh.length === 0 && + globe._surface._tileLoadQueueMedium.length === 0 && + globe._surface._tileLoadQueueLow.length === 0 && + globe._surface._debug.tilesWaitingForChildren === 0; + if (flightComplete && ready) { + const endTime = window.performance.now(); + const duration = endTime - startTime; + alert( + `${(duration / 1000).toFixed(2)} seconds ${ + statistics.numberOfActiveRequestsEver + } requests, min/max/avg frame FPS ${minFrameRate}/${maxFrameRate}/${ + sumFrameRate / frameRateSamples + }` ); - camera.up = new Cesium.Cartesian3( - -0.9769542339275126, - 0.07774058129659328, - -0.19878839712310903 - ); - flightComplete = true; + scene.postRender.removeEventListener(viewReady); } + } - function goToEverest45Degrees() { - camera.position = new Cesium.Cartesian3( - 302760.41072832496, - 5637092.977453635, - 2977284.6758398763 - ); - camera.direction = new Cesium.Cartesian3( - -0.7254568510163212, - -0.3330925403210976, - -0.6022970337764594 - ); - camera.right = new Cesium.Cartesian3( - 0.4750641658993092, - 0.39087207931336604, - -0.7883736778277414 - ); - camera.up = new Cesium.Cartesian3( - -0.49802248502640617, - 0.8580608237157107, - 0.12532049797395203 - ); - flightComplete = true; - } + function goToEverestHorizontal() { + camera.position = new Cesium.Cartesian3( + 302950.1757410969, + 5637093.359233209, + 2976894.491577989 + ); + camera.direction = new Cesium.Cartesian3( + -0.9648960658153797, + -0.24110066659365145, + -0.10414437451009724 + ); + camera.right = new Cesium.Cartesian3( + -0.02152846103178338, + 0.46781654381873394, + -0.8835633574877908 + ); + camera.up = new Cesium.Cartesian3( + -0.26174817580950865, + 0.8503047394302772, + 0.456584868959543 + ); + flightComplete = true; + } - function zoomToEverest() { - const position = new Cesium.Cartesian3( - 302955.90876054496, - 5639614.4908250235, - 2981096.1048591887 - ); - camera.flyTo({ - destination: position, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - complete: function () { - flightComplete = true; - }, - }); - } - - function panAroundEverest() { - camera.position = new Cesium.Cartesian3( - 302950.1757410969, - 5637093.359233209, - 2976894.491577989 - ); - camera.direction = new Cesium.Cartesian3( - -0.9648960658153797, - -0.24110066659365145, - -0.10414437451009724 - ); - camera.right = new Cesium.Cartesian3( - -0.02152846103178338, - 0.46781654381873394, - -0.8835633574877908 - ); - camera.up = new Cesium.Cartesian3( - -0.26174817580950865, - 0.8503047394302772, - 0.456584868959543 - ); + function goToEverestTopDown() { + camera.position = new Cesium.Cartesian3( + 301989.1870802739, + 5637745.915399717, + 2977153.0443453398 + ); + camera.direction = new Cesium.Cartesian3( + 0.021398841015326783, + -0.8909524564021135, + -0.45359211857597476 + ); + camera.right = new Cesium.Cartesian3( + 0.21237352569072232, + 0.4473925820246778, + -0.8687562161705573 + ); + camera.up = new Cesium.Cartesian3( + -0.9769542339275126, + 0.07774058129659328, + -0.19878839712310903 + ); + flightComplete = true; + } - const startCartographic = Cesium.Cartographic.fromCartesian( - camera.position - ); - let longitude = startCartographic.longitude; - const endLongitude = longitude + 0.01; - const latitude = startCartographic.latitude; - const height = startCartographic.height; - let startTime = window.performance.now(); - const removeCallback = scene.preRender.addEventListener(function ( - scene, - time - ) { - const endTime = window.performance.now(); - const delta = endTime - startTime; - startTime = endTime; - longitude += delta * 0.000001; - if (longitude >= endLongitude) { - flightComplete = true; - removeCallback(); - } - camera.position = Cesium.Cartesian3.fromRadians( - longitude, - latitude, - height - ); - }); - } + function goToEverest45Degrees() { + camera.position = new Cesium.Cartesian3( + 302760.41072832496, + 5637092.977453635, + 2977284.6758398763 + ); + camera.direction = new Cesium.Cartesian3( + -0.7254568510163212, + -0.3330925403210976, + -0.6022970337764594 + ); + camera.right = new Cesium.Cartesian3( + 0.4750641658993092, + 0.39087207931336604, + -0.7883736778277414 + ); + camera.up = new Cesium.Cartesian3( + -0.49802248502640617, + 0.8580608237157107, + 0.12532049797395203 + ); + flightComplete = true; + } - Sandcastle.addToolbarButton("Timer Static Horizontal", function () { - startTest(); - goToEverestHorizontal(); + function zoomToEverest() { + const position = new Cesium.Cartesian3( + 302955.90876054496, + 5639614.4908250235, + 2981096.1048591887 + ); + camera.flyTo({ + destination: position, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + complete: function () { + flightComplete = true; + }, }); + } - Sandcastle.addToolbarButton("Timer Static Top Down", function () { - startTest(); - goToEverestTopDown(); - }); + function panAroundEverest() { + camera.position = new Cesium.Cartesian3( + 302950.1757410969, + 5637093.359233209, + 2976894.491577989 + ); + camera.direction = new Cesium.Cartesian3( + -0.9648960658153797, + -0.24110066659365145, + -0.10414437451009724 + ); + camera.right = new Cesium.Cartesian3( + -0.02152846103178338, + 0.46781654381873394, + -0.8835633574877908 + ); + camera.up = new Cesium.Cartesian3( + -0.26174817580950865, + 0.8503047394302772, + 0.456584868959543 + ); - Sandcastle.addToolbarButton("Timer Static 45 degrees", function () { - startTest(); - goToEverest45Degrees(); + const startCartographic = Cesium.Cartographic.fromCartesian( + camera.position + ); + let longitude = startCartographic.longitude; + const endLongitude = longitude + 0.01; + const latitude = startCartographic.latitude; + const height = startCartographic.height; + let startTime = window.performance.now(); + const removeCallback = scene.preRender.addEventListener(function ( + scene, + time + ) { + const endTime = window.performance.now(); + const delta = endTime - startTime; + startTime = endTime; + longitude += delta * 0.000001; + if (longitude >= endLongitude) { + flightComplete = true; + removeCallback(); + } + camera.position = Cesium.Cartesian3.fromRadians( + longitude, + latitude, + height + ); }); + } - Sandcastle.addToolbarButton("Timer Zoom", function () { - startTest(); - zoomToEverest(); - }); + Sandcastle.addToolbarButton("Timer Static Horizontal", function () { + startTest(); + goToEverestHorizontal(); + }); - Sandcastle.addToolbarButton("Timer Pan", function () { - startTest(); - panAroundEverest(); - }); + Sandcastle.addToolbarButton("Timer Static Top Down", function () { + startTest(); + goToEverestTopDown(); + }); - Sandcastle.addToolbarButton("Save camera", function () { - const cameraString = - `camera.position = new Cesium.Cartesian3(${camera.positionWC.x}, ${camera.positionWC.y}, ${camera.positionWC.z});\n` + - `camera.direction = new Cesium.Cartesian3(${camera.directionWC.x}, ${camera.directionWC.y}, ${camera.directionWC.z});\n` + - `camera.right = new Cesium.Cartesian3(${camera.rightWC.x}, ${camera.rightWC.y}, ${camera.rightWC.z});\n` + - `camera.up = new Cesium.Cartesian3(${camera.upWC.x}, ${camera.upWC.y}, ${camera.upWC.z});\n`; - console.log(cameraString); - }); - })(); //Sandcastle_End + Sandcastle.addToolbarButton("Timer Static 45 degrees", function () { + startTest(); + goToEverest45Degrees(); + }); + + Sandcastle.addToolbarButton("Timer Zoom", function () { + startTest(); + zoomToEverest(); + }); + + Sandcastle.addToolbarButton("Timer Pan", function () { + startTest(); + panAroundEverest(); + }); + + Sandcastle.addToolbarButton("Save camera", function () { + const cameraString = + `camera.position = new Cesium.Cartesian3(${camera.positionWC.x}, ${camera.positionWC.y}, ${camera.positionWC.z});\n` + + `camera.direction = new Cesium.Cartesian3(${camera.directionWC.x}, ${camera.directionWC.y}, ${camera.directionWC.z});\n` + + `camera.right = new Cesium.Cartesian3(${camera.rightWC.x}, ${camera.rightWC.y}, ${camera.rightWC.z});\n` + + `camera.up = new Cesium.Cartesian3(${camera.upWC.x}, ${camera.upWC.y}, ${camera.upWC.z});\n`; + console.log(cameraString); + }); + //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { From d7245d5ab01ecf97d8f02503f648bdfbb036bf75 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 20 Jan 2023 13:18:57 -0500 Subject: [PATCH 375/679] Restore deprecated specs --- Specs/MockTerrainProvider.js | 2 + Specs/TerrainTileProcessor.js | 35 +- .../Source/Core/CesiumTerrainProvider.js | 4 +- .../Core/CustomHeightmapTerrainProvider.js | 1 + .../Source/Core/EllipsoidTerrainProvider.js | 1 + packages/engine/Source/Core/sampleTerrain.js | 5 +- .../Source/Core/sampleTerrainMostDetailed.js | 3 + packages/engine/Source/Scene/Globe.js | 6 +- .../Source/Scene/GlobeSurfaceTileProvider.js | 17 +- .../Scene/computeFlyToLocationForRectangle.js | 2 + ...ArcGISTiledElevationTerrainProviderSpec.js | 305 ++++--- .../Specs/Core/CesiumTerrainProviderSpec.js | 828 ++++++++++++------ .../CustomHeightmapTerrainProviderSpec.js | 19 + .../Core/EllipsoidTerrainProviderSpec.js | 9 + .../Core/GoogleEarthEnterpriseMetadataSpec.js | 191 +++- ...oogleEarthEnterpriseTerrainProviderSpec.js | 361 +++++--- .../Core/VRTheWorldTerrainProviderSpec.js | 208 +++-- .../Core/sampleTerrainMostDetailedSpec.js | 22 + .../engine/Specs/Core/sampleTerrainSpec.js | 42 +- .../Specs/DataSources/ModelVisualizerSpec.js | 191 ++-- .../Specs/Scene/BillboardCollectionSpec.js | 12 +- packages/engine/Specs/Scene/GlobeSpec.js | 217 +++-- .../Scene/GlobeSurfaceTileProviderSpec.js | 33 +- .../Specs/Scene/GlobeSurfaceTileSpec.js | 43 +- .../engine/Specs/Scene/Model/ModelSpec.js | 45 +- packages/engine/Specs/Scene/SceneSpec.js | 37 +- .../BaseLayerPickerViewModelSpec.js | 26 + 27 files changed, 1749 insertions(+), 916 deletions(-) diff --git a/Specs/MockTerrainProvider.js b/Specs/MockTerrainProvider.js index 9a482e38182..84af4db14e9 100644 --- a/Specs/MockTerrainProvider.js +++ b/Specs/MockTerrainProvider.js @@ -17,6 +17,8 @@ function MockTerrainProvider() { this.heightmapWidth, this.tilingScheme.getNumberOfXTilesAtLevel(0) ); + this.ready = this._ready = true; + this.readyPromise = this._readyPromise = Promise.resolve(); this.hasWaterMask = true; this.errorEvent = new Event(); diff --git a/Specs/TerrainTileProcessor.js b/Specs/TerrainTileProcessor.js index f99d48b075c..4e77bb3c2fe 100644 --- a/Specs/TerrainTileProcessor.js +++ b/Specs/TerrainTileProcessor.js @@ -62,27 +62,30 @@ TerrainTileProcessor.prototype.process = function (tiles, maxIterations) { ++that.frameState.frameNumber; // Keep going until all terrain and imagery provider are ready and states are no longer changing. - let changed = false; + let changed = !that.terrainProvider.ready; + for (let i = 0; i < that.imageryLayerCollection.length; ++i) { changed = changed || !that.imageryLayerCollection.get(i).imageryProvider.ready; } - tiles.forEach(function (tile) { - const beforeState = getState(tile); - GlobeSurfaceTile.processStateMachine( - tile, - that.frameState, - that.terrainProvider, - that.imageryLayerCollection - ); - const afterState = getState(tile); - changed = - changed || - tile.data.terrainState === TerrainState.RECEIVING || - tile.data.terrainState === TerrainState.TRANSFORMING || - !statesAreSame(beforeState, afterState); - }); + if (that.terrainProvider.ready) { + tiles.forEach(function (tile) { + const beforeState = getState(tile); + GlobeSurfaceTile.processStateMachine( + tile, + that.frameState, + that.terrainProvider, + that.imageryLayerCollection + ); + const afterState = getState(tile); + changed = + changed || + tile.data.terrainState === TerrainState.RECEIVING || + tile.data.terrainState === TerrainState.TRANSFORMING || + !statesAreSame(beforeState, afterState); + }); + } if (!changed || iterations >= maxIterations) { resolve(iterations); diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index d22dc413d7f..fee236a950d 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -552,10 +552,10 @@ CesiumTerrainProvider._initializeReadyPromise = async function ( options, provider ) { - await Promise.resolve(options.url); + const url = await Promise.resolve(options.url); const terrainProviderBuilder = new TerrainProviderBuilder(options); - const resource = Resource.createIfNeeded(options.url); + const resource = Resource.createIfNeeded(url); resource.appendForwardSlash(); terrainProviderBuilder.lastResource = resource; terrainProviderBuilder.layerJsonResource = terrainProviderBuilder.lastResource.getDerivedResource( diff --git a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js index 375ea8db188..5dce90c49d2 100644 --- a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js +++ b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js @@ -90,6 +90,7 @@ function CustomHeightmapTerrainProvider(options) { } this._credit = credit; + this._ready = true; this._readyPromise = Promise.resolve(true); } diff --git a/packages/engine/Source/Core/EllipsoidTerrainProvider.js b/packages/engine/Source/Core/EllipsoidTerrainProvider.js index 659d170d766..f6beab66584 100644 --- a/packages/engine/Source/Core/EllipsoidTerrainProvider.js +++ b/packages/engine/Source/Core/EllipsoidTerrainProvider.js @@ -43,6 +43,7 @@ function EllipsoidTerrainProvider(options) { ); this._errorEvent = new Event(); + this._ready = true; this._readyPromise = Promise.resolve(true); } diff --git a/packages/engine/Source/Core/sampleTerrain.js b/packages/engine/Source/Core/sampleTerrain.js index d99f1d2cc45..d0f8fe254ec 100644 --- a/packages/engine/Source/Core/sampleTerrain.js +++ b/packages/engine/Source/Core/sampleTerrain.js @@ -34,13 +34,16 @@ import Check from "./Check.js"; * // positions[0].height and positions[1].height have been updated. * // updatedPositions is just a reference to positions. */ -function sampleTerrain(terrainProvider, level, positions) { +async function sampleTerrain(terrainProvider, level, positions) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("terrainProvider", terrainProvider); Check.typeOf.number("level", level); Check.defined("positions", positions); //>>includeEnd('debug'); + // readyPromise has been deprecated; This is here for backwards compatibility + await terrainProvider._readyPromise; + return doSampling(terrainProvider, level, positions); } diff --git a/packages/engine/Source/Core/sampleTerrainMostDetailed.js b/packages/engine/Source/Core/sampleTerrainMostDetailed.js index d62c3be2c80..e0b38929bb0 100644 --- a/packages/engine/Source/Core/sampleTerrainMostDetailed.js +++ b/packages/engine/Source/Core/sampleTerrainMostDetailed.js @@ -39,6 +39,9 @@ async function sampleTerrainMostDetailed(terrainProvider, positions) { const byLevel = []; const maxLevels = []; + // readyPromise has been deprecated; This is here for backwards compatibility + await terrainProvider._readyPromise; + const availability = terrainProvider.availability; //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index 6a21f560442..c6876f2195b 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -982,7 +982,11 @@ Globe.prototype.beginFrame = function (frameState) { const surface = this._surface; const tileProvider = surface.tileProvider; const terrainProvider = this.terrainProvider; - const hasWaterMask = this.showWaterEffect && terrainProvider.hasWaterMask; + const hasWaterMask = + this.showWaterEffect && + terrainProvider.hasWaterMask && + // ready is deprecated; This is here for backwards compatibility + terrainProvider._ready; if (hasWaterMask && this._oceanNormalMapResourceDirty) { // url changed, load new normal map asynchronously diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 7c1e01941ef..42a96649b47 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -237,8 +237,10 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { ready: { get: function () { return ( - this._imageryLayers.length === 0 || - this._imageryLayers.get(0).imageryProvider.ready + // ready is deprecated; This is here for backwards compatibility + this._terrainProvider._ready && + (this._imageryLayers.length === 0 || + this._imageryLayers.get(0).imageryProvider.ready) ); }, }, @@ -347,7 +349,11 @@ GlobeSurfaceTileProvider.prototype.update = function (frameState) { function updateCredits(surface, frameState) { const creditDisplay = frameState.creditDisplay; - if (defined(surface._terrainProvider.credit)) { + if ( + // ready is deprecated; This is here for backwards compatibility + surface._terrainProvider._ready && + defined(surface._terrainProvider.credit) + ) { creditDisplay.addCredit(surface._terrainProvider.credit); } @@ -2119,7 +2125,10 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { tileProvider.hasWaterMask && defined(waterMaskTexture); const oceanNormalMap = tileProvider.oceanNormalMap; const showOceanWaves = showReflectiveOcean && defined(oceanNormalMap); - const hasVertexNormals = tileProvider.terrainProvider.hasVertexNormals; + const hasVertexNormals = + // ready is deprecated; This is here for backwards compatibility + tileProvider.terrainProvider._ready && + tileProvider.terrainProvider.hasVertexNormals; const enableFog = frameState.fog.enabled && frameState.fog.renderable && !cameraUnderground; const showGroundAtmosphere = diff --git a/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js b/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js index 0a984cb7cb3..9fec202c25c 100644 --- a/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js +++ b/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js @@ -31,6 +31,8 @@ async function computeFlyToLocationForRectangle(rectangle, scene) { return positionWithoutTerrain; } + // readyPromise has been deprecated; This is here for backwards compatibility + await terrainProvider._readyPromise; const availability = terrainProvider.availability; if (!defined(availability) || scene.mode === SceneMode.SCENE2D) { diff --git a/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js b/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js index f80e14c4cfa..5dd53d1f84f 100644 --- a/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js @@ -11,6 +11,8 @@ import { Math as CesiumMath, } from "../../index.js"; +import pollToPromise from "../../../../Specs/pollToPromise.js"; + describe("Core/ArcGISTiledElevationTerrainProvider", function () { const lercTileUrl = "Data/Images/Red16x16.png"; let availability; @@ -242,139 +244,224 @@ describe("Core/ArcGISTiledElevationTerrainProvider", function () { ).toBeRejectedWithError("my message"); }); - it("has error event", async function () { - const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( - "made/up/url" - ); + it("resolves readyPromise", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("resolves readyPromise with Resource", function () { + const resource = new Resource({ + url: "made/up/url", + }); + + const provider = new ArcGISTiledElevationTerrainProvider({ + url: resource, + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + it("has error event", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); + + return provider.readyPromise; }); - it("returns reasonable geometric error for various levels", async function () { - const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( - "made/up/url" - ); + it("returns reasonable geometric error for various levels", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); + }); }); - it("credit is undefined if credit is not provided", async function () { + it("logo is undefined if credit is not provided", function () { delete metadata.copyrightText; - const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( - "made/up/url" - ); - expect(provider.credit).toBeUndefined(); + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.credit).toBeUndefined(); + }); }); - it("credit is defined if credit option is provided", async function () { - const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( - "made/up/url", - { - credit: "thanks to our awesome made up contributors!", - } - ); - expect(provider.credit).toBeDefined(); + it("logo is defined if credit is provided", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + credit: "thanks to our awesome made up contributors!", + }); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.credit).toBeDefined(); + }); }); - it("does not have a water mask", async function () { - const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( - "made/up/url" - ); + it("does not have a water mask", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); expect(provider.hasWaterMask).toBe(false); + return provider.readyPromise.catch(function (error) { + expect(error).toBeInstanceOf(RuntimeError); + }); + }); + + it("is not ready immediately", function () { + const provider = new ArcGISTiledElevationTerrainProvider({ + url: "made/up/url", + }); + expect(provider.ready).toBe(false); + return provider.readyPromise.catch(function (error) { + expect(error).toBeInstanceOf(RuntimeError); + }); }); - it("detects WebMercator tiling scheme", async function () { + it("detects WebMercator tiling scheme", function () { const baseUrl = "made/up/url"; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); - expect(terrainProvider.tilingScheme).toBeInstanceOf( - WebMercatorTilingScheme - ); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.tilingScheme).toBeInstanceOf( + WebMercatorTilingScheme + ); + }); }); - it("detects Geographic tiling scheme", async function () { + it("detects Geographic tiling scheme", function () { const baseUrl = "made/up/url"; metadata.spatialReference.latestWkid = 4326; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); - expect(terrainProvider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.tilingScheme).toBeInstanceOf( + GeographicTilingScheme + ); + }); }); - it("fromUrl throws if SRS is not supported", async function () { + it("raises an error if the SRS is not supported", function () { const baseUrl = "made/up/url"; metadata.spatialReference.latestWkid = 1234; - await expectAsync( - ArcGISTiledElevationTerrainProvider.fromUrl(baseUrl) - ).toBeRejectedWithError(RuntimeError, "Invalid spatial reference"); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return terrainProvider.readyPromise.then(fail).catch(function (error) { + expect(error).toBeInstanceOf(RuntimeError); + }); }); - it("raises an error if tileInfo missing", async function () { + it("raises an error if tileInfo missing", function () { const baseUrl = "made/up/url"; delete metadata.tileInfo; - await expectAsync( - ArcGISTiledElevationTerrainProvider.fromUrl(baseUrl) - ).toBeRejectedWithError(RuntimeError, "tileInfo is required"); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return terrainProvider.readyPromise.then(fail).catch(function (error) { + expect(error).toBeInstanceOf(RuntimeError); + }); }); - it("checks availability if TileMap capability exists", async function () { + it("checks availability if TileMap capability exists", function () { const baseUrl = "made/up/url"; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); - expect(terrainProvider._hasAvailability).toBe(true); - expect(terrainProvider._tilesAvailable).toBeDefined(); - expect(terrainProvider._tilesAvailabilityLoaded).toBeDefined(); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider._hasAvailability).toBe(true); + expect(terrainProvider._tilesAvailable).toBeDefined(); + expect(terrainProvider._tilesAvailabilityLoaded).toBeDefined(); + }); }); - it("does not check availability if TileMap capability is missing", async function () { + it("does not check availability if TileMap capability is missing", function () { const baseUrl = "made/up/url"; metadata.capabilities = "Image,Mensuration"; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); - expect(terrainProvider._hasAvailability).toBe(false); - expect(terrainProvider._tilesAvailable).toBeUndefined(); - expect(terrainProvider._tilesAvailabilityLoaded).toBeUndefined(); + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider._hasAvailability).toBe(false); + expect(terrainProvider._tilesAvailable).toBeUndefined(); + expect(terrainProvider._tilesAvailablityLoaded).toBeUndefined(); + }); }); describe("requestTileGeometry", function () { - it("provides HeightmapTerrainData", async function () { + it("provides HeightmapTerrainData", function () { const baseUrl = "made/up/url"; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); - - const promise = terrainProvider.requestTileGeometry(0, 0, 0); - RequestScheduler.update(); - const loadedData = await promise; - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }) + .then(function () { + const promise = terrainProvider.requestTileGeometry(0, 0, 0); + RequestScheduler.update(); + return promise; + }) + .then(function (loadedData) { + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + }); }); - it("returns undefined if too many requests are already in progress", async function () { + it("returns undefined if too many requests are already in progress", function () { const baseUrl = "made/up/url"; const deferreds = []; @@ -388,35 +475,39 @@ describe("Core/ArcGISTiledElevationTerrainProvider", function () { deferreds.push(deferred); }; - const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( - baseUrl - ); - - let promise; - let i; - // Make one less request to account for the additional availability request. - for (i = 0; i < RequestScheduler.maximumRequestsPerServer - 1; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promise = terrainProvider.requestTileGeometry(0, 0, 0, request); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); - - promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); - expect(promise).toBeUndefined(); - - for (i = 0; i < deferreds.length; ++i) { - deferreds[i].resolve(); - } - - return Promise.all( - deferreds.map(function (deferred) { - return deferred.promise; - }) - ); + const terrainProvider = new ArcGISTiledElevationTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + let promise; + let i; + // Make one less request to account for the additional availability request. + for (i = 0; i < RequestScheduler.maximumRequestsPerServer - 1; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider.requestTileGeometry(0, 0, 0, request); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); + + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); + + for (i = 0; i < deferreds.length; ++i) { + deferreds[i].resolve(); + } + + return Promise.all( + deferreds.map(function (deferred) { + return deferred.promise; + }) + ); + }); }); }); }); diff --git a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js index f328f2c5443..f7559617a8f 100644 --- a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js @@ -1,6 +1,5 @@ import { CesiumTerrainProvider, - Credit, Ellipsoid, GeographicTilingScheme, getAbsoluteUri, @@ -11,9 +10,9 @@ import { Request, RequestScheduler, Resource, - RuntimeError, TerrainProvider, } from "../../index.js"; +import pollToPromise from "../../../../Specs/pollToPromise.js"; describe("Core/CesiumTerrainProvider", function () { beforeEach(function () { @@ -188,201 +187,399 @@ describe("Core/CesiumTerrainProvider", function () { ).toBeRejectedWithError("my message"); }); - it("uses geographic tiling scheme by default", async function () { + it("resolves readyPromise", function () { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("resolves readyPromise when url promise is used", function () { + const provider = new CesiumTerrainProvider({ + url: Promise.resolve("made/up/url"), + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("resolves readyPromise with Resource", function () { + const resource = new Resource({ + url: "made/up/url", + }); + + const provider = new CesiumTerrainProvider({ + url: resource, + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("rejects readyPromise when url rejects", function () { + const provider = new CesiumTerrainProvider({ + url: Promise.reject(new Error("my message")), + }); + return provider.readyPromise + .then(function () { + fail("should not resolve"); + }) + .catch(function (result) { + expect(result.message).toBe("my message"); + expect(provider.ready).toBe(false); + }); + }); + + it("uses geographic tiling scheme by default", function () { returnHeightmapTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + }); }); - it("can use a custom ellipsoid", async function () { + it("can use a custom ellipsoid", function () { returnHeightmapTileJson(); const ellipsoid = new Ellipsoid(1, 2, 3); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", ellipsoid: ellipsoid, }); - expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); + }); }); - it("has error event", async function () { - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider.errorEvent).toBeDefined(); - expect(provider.errorEvent).toBe(provider.errorEvent); + it("has error event", function () { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.errorEvent).toBeDefined(); + expect(provider.errorEvent).toBe(provider.errorEvent); + }); }); - it("returns reasonable geometric error for various levels", async function () { + it("returns reasonable geometric error for various levels", function () { returnQuantizedMeshTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return provider.readyPromise.then(function () { + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); + }); }); - it("credit is undefined if credit is not provided", async function () { + it("credit is undefined if credit option is not provided", function () { returnHeightmapTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider.credit).toBeUndefined(); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.credit).toBeUndefined(); + }); }); - it("credit is defined if credit is provided", async function () { + it("credit is defined if credit option is provided", function () { returnHeightmapTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", credit: "thanks to our awesome made up contributors!", }); - expect(provider.credit).toBeInstanceOf(Credit); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.credit).toBeDefined(); + }); }); - it("has a water mask", async function () { + it("has a water mask", function () { returnHeightmapTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider.hasWaterMask).toBe(true); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.hasWaterMask).toBe(true); + }); }); - it("has vertex normals", async function () { + it("has vertex normals", function () { returnOctVertexNormalTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, }); - expect(provider.requestVertexNormals).toBe(true); - expect(provider.hasVertexNormals).toBe(true); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.requestVertexNormals).toBe(true); + expect(provider.hasVertexNormals).toBe(true); + }); }); - it("does not request vertex normals", async function () { + it("does not request vertex normals", function () { returnOctVertexNormalTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: false, }); - expect(provider.requestVertexNormals).toBe(false); - expect(provider.hasVertexNormals).toBe(false); + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider.requestVertexNormals).toBe(false); + expect(provider.hasVertexNormals).toBe(false); + }); }); - it("requests parent layer.json", async function () { + it("requests parent layer.json", function () { returnParentUrlTileJson(); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { + const provider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, requestWaterMask: true, }); - expect(provider._tileCredits[0].html).toBe( - "This is a child tileset! This amazing data is courtesy The Amazing Data Source!" - ); - expect(provider.requestVertexNormals).toBe(true); - expect(provider.requestWaterMask).toBe(true); - expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them - expect(provider.hasWaterMask).toBe(true); // The child tileset has them - expect(provider.availability.isTileAvailable(1, 2, 1)).toBe(true); // Both have this - expect(provider.availability.isTileAvailable(1, 3, 1)).toBe(true); // Parent has this, but child doesn't - expect(provider.availability.isTileAvailable(2, 0, 0)).toBe(false); // Neither has this - - const layers = provider._layers; - expect(layers.length).toBe(2); - expect(layers[0].hasVertexNormals).toBe(false); - expect(layers[0].hasWaterMask).toBe(true); - expect(layers[0].availability.isTileAvailable(1, 2, 1)).toBe(true); - expect(layers[0].availability.isTileAvailable(1, 3, 1)).toBe(false); - expect(layers[0].availability.isTileAvailable(2, 0, 0)).toBe(false); - expect(layers[1].hasVertexNormals).toBe(false); - expect(layers[1].hasWaterMask).toBe(false); - expect(layers[1].availability.isTileAvailable(1, 2, 1)).toBe(true); - expect(layers[1].availability.isTileAvailable(1, 3, 1)).toBe(true); - expect(layers[1].availability.isTileAvailable(2, 0, 0)).toBe(false); - }); - - it("fromUrl throws an error if layer.json does not specify a format", async function () { + return provider.readyPromise.then(function () { + expect(provider._tileCredits[0].html).toBe( + "This is a child tileset! This amazing data is courtesy The Amazing Data Source!" + ); + expect(provider.requestVertexNormals).toBe(true); + expect(provider.requestWaterMask).toBe(true); + expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them + expect(provider.hasWaterMask).toBe(true); // The child tileset has them + expect(provider.availability.isTileAvailable(1, 2, 1)).toBe(true); // Both have this + expect(provider.availability.isTileAvailable(1, 3, 1)).toBe(true); // Parent has this, but child doesn't + expect(provider.availability.isTileAvailable(2, 0, 0)).toBe(false); // Neither has this + + const layers = provider._layers; + expect(layers.length).toBe(2); + expect(layers[0].hasVertexNormals).toBe(false); + expect(layers[0].hasWaterMask).toBe(true); + expect(layers[0].availability.isTileAvailable(1, 2, 1)).toBe(true); + expect(layers[0].availability.isTileAvailable(1, 3, 1)).toBe(false); + expect(layers[0].availability.isTileAvailable(2, 0, 0)).toBe(false); + expect(layers[1].hasVertexNormals).toBe(false); + expect(layers[1].hasWaterMask).toBe(false); + expect(layers[1].availability.isTileAvailable(1, 2, 1)).toBe(true); + expect(layers[1].availability.isTileAvailable(1, 3, 1)).toBe(true); + expect(layers[1].availability.isTileAvailable(2, 0, 0)).toBe(false); + }); + }); + + it("raises an error if layer.json does not specify a format", function () { returnTileJson("Data/CesiumTerrainTileJson/NoFormat.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError( - RuntimeError, - "The tile format is not specified in the layer.json file." - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + let errorListenerCalled = false; + const errorMatcher = function (event) { + expect(event.message).toContain("format is not specified"); + errorListenerCalled = true; + provider.errorEvent.removeEventListener(errorMatcher); + }; + + provider.errorEvent.addEventListener(errorMatcher); + + return provider.readyPromise.then(fail).catch((e) => { + expect(errorListenerCalled).toBe(true); + expect(e.message).toContain( + "The tile format is not specified in the layer.json file." + ); + }); }); - it("fromUrl throws an error if layer.json specifies an unknown format", async function () { + it("raises an error if layer.json specifies an unknown format", function () { returnTileJson("Data/CesiumTerrainTileJson/InvalidFormat.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError( - RuntimeError, - 'The tile format "awesometron-9000.0" is invalid or not supported.' - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + let errorListenerCalled = false; + const errorMatcher = function (event) { + expect(event.message).toContain("invalid or not supported"); + errorListenerCalled = true; + provider.errorEvent.removeEventListener(errorMatcher); + }; + + provider.errorEvent.addEventListener(errorMatcher); + + return provider.readyPromise.then(fail).catch((e) => { + expect(errorListenerCalled).toBe(true); + expect(e.message).toContain( + 'The tile format "awesometron-9000.0" is invalid or not supported.' + ); + }); }); - it("fromUrl throws an error if layer.json does not specify quantized-mesh 1.x format", async function () { + it("raises an error if layer.json does not specify quantized-mesh 1.x format", function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh2.0.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError( - RuntimeError, - 'The tile format "quantized-mesh-2.0" is invalid or not supported.' - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + let errorListenerCalled = false; + const errorMatcher = function (event) { + expect(event.message).toContain("invalid or not supported"); + errorListenerCalled = true; + provider.errorEvent.removeEventListener(errorMatcher); + }; + + provider.errorEvent.addEventListener(errorMatcher); + + return provider.readyPromise.then(fail).catch((e) => { + expect(errorListenerCalled).toBe(true); + expect(e.message).toContain( + 'The tile format "quantized-mesh-2.0" is invalid or not supported.' + ); + }); }); - it("from supports quantized-mesh1.x minor versions", async function () { + it("supports quantized-mesh1.x minor versions", function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh1.1.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeResolved(); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + const errorListener = jasmine.createSpy("error"); + provider.errorEvent.addEventListener(errorListener); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(errorListener).not.toHaveBeenCalled(); + }); }); - it("fromUrl throws an error if layer.json does not specify a tiles property", async function () { + it("raises an error if layer.json does not specify a tiles property", function () { returnTileJson("Data/CesiumTerrainTileJson/NoTiles.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError( - RuntimeError, - "The layer.json file does not specify any tile URL templates." - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + let errorListenerCalled = false; + const errorMatcher = function (event) { + expect(event.message).toContain( + "does not specify any tile URL templates" + ); + errorListenerCalled = true; + provider.errorEvent.removeEventListener(errorMatcher); + }; + + provider.errorEvent.addEventListener(errorMatcher); + + return provider.readyPromise.then(fail).catch((e) => { + expect(errorListenerCalled).toBe(true); + expect(e.message).toContain( + "The layer.json file does not specify any tile URL templates." + ); + }); }); - it("fromUrl throws an error if layer.json tiles property is an empty array", async function () { + it("raises an error if layer.json tiles property is an empty array", function () { returnTileJson("Data/CesiumTerrainTileJson/EmptyTilesArray.tile.json"); - await expectAsync( - CesiumTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError( - RuntimeError, - "The layer.json file does not specify any tile URL templates." - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + let errorListenerCalled = false; + const errorMatcher = function (event) { + expect(event.message).toContain( + "does not specify any tile URL templates" + ); + errorListenerCalled = true; + provider.errorEvent.removeEventListener(errorMatcher); + }; + + provider.errorEvent.addEventListener(errorMatcher); + + return provider.readyPromise.then(fail).catch((e) => { + expect(errorListenerCalled).toBe(true); + expect(e.message).toContain( + "The layer.json file does not specify any tile URL templates." + ); + }); }); - it("uses attribution specified in layer.json", async function () { + it("uses attribution specified in layer.json", function () { returnTileJson("Data/CesiumTerrainTileJson/WithAttribution.tile.json"); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider._tileCredits[0].html).toBe( - "This amazing data is courtesy The Amazing Data Source!" - ); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider._tileCredits[0].html).toBe( + "This amazing data is courtesy The Amazing Data Source!" + ); + }); }); - it("do not add blank attribution if layer.json does not have one", async function () { + it("do not add blank attribution if layer.json does not have one", function () { returnTileJson("Data/CesiumTerrainTileJson/WaterMask.tile.json"); - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - expect(provider._tileCredit).toBeUndefined(); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return provider.ready; + }).then(function () { + expect(provider._tileCredit).toBeUndefined(); + }); }); it("The undefined availability tile is returned at level 0", function () { @@ -454,71 +651,85 @@ describe("Core/CesiumTerrainProvider", function () { }); describe("requestTileGeometry", function () { - async function makeRequest(provider, x, y, z) { - try { - await provider.requestTileGeometry(x, y, z); - } catch { - // Request is expect to fail - } - } - - it("uses multiple urls specified in layer.json", async function () { + it("uses multiple urls specified in layer.json", function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); - spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - - const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - await makeRequest(provider, 0, 0, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo0.com"); + const provider = new CesiumTerrainProvider({ + url: "made/up/url", + }); - await makeRequest(provider, 1, 0, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo1.com"); - - await makeRequest(provider, 1, -1, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo2.com"); + spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - await makeRequest(provider, 1, 0, 1); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo3.com"); + return provider.readyPromise + .then(function () { + return provider.requestTileGeometry(0, 0, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo0.com"); + return provider.requestTileGeometry(1, 0, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo1.com"); + return provider.requestTileGeometry(1, -1, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo2.com"); + return provider.requestTileGeometry(1, 0, 1); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo3.com"); + }); }); - it("supports scheme-less template URLs in layer.json resolved with absolute URL", async function () { + it("supports scheme-less template URLs in layer.json resolved with absolute URL", function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); const url = getAbsoluteUri("Data/CesiumTerrainTileJson"); - spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - - const provider = await CesiumTerrainProvider.fromUrl(url); - await makeRequest(provider, 0, 0, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo0.com"); + const provider = new CesiumTerrainProvider({ + url: url, + }); - await makeRequest(provider, 1, 0, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo1.com"); - - await makeRequest(provider, 1, -1, 0); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo2.com"); + spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - await makeRequest(provider, 1, 0, 1); - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo3.com"); + return provider.readyPromise + .then(function () { + return provider.requestTileGeometry(0, 0, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo0.com"); + return provider.requestTileGeometry(1, 0, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo1.com"); + return provider.requestTileGeometry(1, -1, 0); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo2.com"); + return provider.requestTileGeometry(1, 0, 1); + }) + .catch(function () { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo3.com"); + }); }); - it("provides HeightmapTerrainData", async function () { + it("provides HeightmapTerrainData", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -541,11 +752,12 @@ describe("Core/CesiumTerrainProvider", function () { returnHeightmapTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, false); - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + return waitForTile(0, 0, 0, false, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + }); }); - it("provides QuantizedMeshTerrainData", async function () { + it("provides QuantizedMeshTerrainData", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -567,11 +779,12 @@ describe("Core/CesiumTerrainProvider", function () { returnQuantizedMeshTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + return waitForTile(0, 0, 0, false, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + }); }); - it("provides QuantizedMeshTerrainData with 32bit indices", async function () { + it("provides QuantizedMeshTerrainData with 32bit indices", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -593,12 +806,13 @@ describe("Core/CesiumTerrainProvider", function () { returnQuantizedMeshTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._indices.BYTES_PER_ELEMENT).toBe(4); + return waitForTile(0, 0, 0, false, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._indices.BYTES_PER_ELEMENT).toBe(4); + }); }); - it("provides QuantizedMeshTerrainData with VertexNormals", async function () { + it("provides QuantizedMeshTerrainData with VertexNormals", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -620,12 +834,13 @@ describe("Core/CesiumTerrainProvider", function () { returnVertexNormalTileJson(); - const loadedData = await waitForTile(0, 0, 0, true, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._encodedNormals).toBeDefined(); + return waitForTile(0, 0, 0, true, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with WaterMask", async function () { + it("provides QuantizedMeshTerrainData with WaterMask", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -647,12 +862,13 @@ describe("Core/CesiumTerrainProvider", function () { returnWaterMaskTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, true); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._waterMask).toBeDefined(); + return waitForTile(0, 0, 0, false, true, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._waterMask).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with VertexNormals and WaterMask", async function () { + it("provides QuantizedMeshTerrainData with VertexNormals and WaterMask", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -674,13 +890,14 @@ describe("Core/CesiumTerrainProvider", function () { returnWaterMaskTileJson(); - const loadedData = await waitForTile(0, 0, 0, true, true); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._encodedNormals).toBeDefined(); - expect(loadedData._waterMask).toBeDefined(); + return waitForTile(0, 0, 0, true, true, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + expect(loadedData._waterMask).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with OctVertexNormals", async function () { + it("provides QuantizedMeshTerrainData with OctVertexNormals", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -702,12 +919,13 @@ describe("Core/CesiumTerrainProvider", function () { returnOctVertexNormalTileJson(); - const loadedData = await waitForTile(0, 0, 0, true, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._encodedNormals).toBeDefined(); + return waitForTile(0, 0, 0, true, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with VertexNormals and unknown extensions", async function () { + it("provides QuantizedMeshTerrainData with VertexNormals and unknown extensions", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -729,12 +947,13 @@ describe("Core/CesiumTerrainProvider", function () { returnVertexNormalTileJson(); - const loadedData = await waitForTile(0, 0, 0, true, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._encodedNormals).toBeDefined(); + return waitForTile(0, 0, 0, true, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with OctVertexNormals and unknown extensions", async function () { + it("provides QuantizedMeshTerrainData with OctVertexNormals and unknown extensions", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -756,12 +975,13 @@ describe("Core/CesiumTerrainProvider", function () { returnOctVertexNormalTileJson(); - const loadedData = await waitForTile(0, 0, 0, true, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(loadedData._encodedNormals).toBeDefined(); + return waitForTile(0, 0, 0, true, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + }); }); - it("provides QuantizedMeshTerrainData with unknown extension", async function () { + it("provides QuantizedMeshTerrainData with unknown extension", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -783,11 +1003,12 @@ describe("Core/CesiumTerrainProvider", function () { returnOctVertexNormalTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, false); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + return waitForTile(0, 0, 0, false, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + }); }); - it("provides QuantizedMeshTerrainData with Metadata availability", async function () { + it("provides QuantizedMeshTerrainData with Metadata availability", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -809,21 +1030,37 @@ describe("Core/CesiumTerrainProvider", function () { returnMetadataAvailabilityTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url" - ); - expect(terrainProvider.hasMetadata).toBe(true); - expect(terrainProvider._layers[0].availabilityLevels).toBe(10); - expect(terrainProvider.availability.isTileAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.availability.isTileAvailable(0, 1, 0)).toBe(true); - expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(false); - - const loadedData = await terrainProvider.requestTileGeometry(0, 0, 0); - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }) + .then(function () { + expect(terrainProvider.hasMetadata).toBe(true); + expect(terrainProvider._layers[0].availabilityLevels).toBe(10); + expect(terrainProvider.availability.isTileAvailable(0, 0, 0)).toBe( + true + ); + expect(terrainProvider.availability.isTileAvailable(0, 1, 0)).toBe( + true + ); + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( + false + ); + + return terrainProvider.requestTileGeometry(0, 0, 0); + }) + .then(function (loadedData) { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( + true + ); + }); }); - it("returns undefined if too many requests are already in progress", async function () { + it("returns undefined if too many requests are already in progress", function () { const baseUrl = "made/up/url"; const deferreds = []; @@ -843,39 +1080,40 @@ describe("Core/CesiumTerrainProvider", function () { returnHeightmapTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); - - let i; - const promises = []; - for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promises.push( - expectAsync( - terrainProvider.requestTileGeometry(0, 0, 0, request) - ).toBeRejectedWithError(RuntimeError, "Mesh buffer doesn't exist.") - ); - } - RequestScheduler.update(); - - const promise = terrainProvider.requestTileGeometry( - 0, - 0, - 0, - createRequest() - ); - expect(promise).toBeUndefined(); + const terrainProvider = new CesiumTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + let promise; + let i; + for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider + .requestTileGeometry(0, 0, 0, request) + .then(fail) + .catch((e) => { + expect(e.message).toContain("Mesh buffer doesn't exist."); + }); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); - for (i = 0; i < deferreds.length; ++i) { - deferreds[i].resolve(); - } + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); - return Promise.all(promises); + for (i = 0; i < deferreds.length; ++i) { + deferreds[i].resolve(); + } + }); }); - it("supports getTileDataAvailable()", async function () { + it("supports getTileDataAvailable()", function () { const baseUrl = "made/up/url"; Resource._Implementations.loadWithXhr = function ( @@ -899,22 +1137,36 @@ describe("Core/CesiumTerrainProvider", function () { returnQuantizedMeshTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); + const terrainProvider = new CesiumTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); + }); }); - it("getTileDataAvailable() converts xyz to tms", async function () { + it("getTileDataAvailable() converts xyz to tms", function () { const baseUrl = "made/up/url"; returnPartialAvailabilityTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); - expect(terrainProvider.getTileDataAvailable(1, 3, 2)).toBe(true); - expect(terrainProvider.getTileDataAvailable(1, 0, 2)).toBe(false); + const terrainProvider = new CesiumTerrainProvider({ + url: baseUrl, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.getTileDataAvailable(1, 3, 2)).toBe(true); + expect(terrainProvider.getTileDataAvailable(1, 0, 2)).toBe(false); + }); }); - it("getTileDataAvailable() with Metadata availability", async function () { + it("getTileDataAvailable() with Metadata availability", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -936,18 +1188,25 @@ describe("Core/CesiumTerrainProvider", function () { returnMetadataAvailabilityTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url" - ); - - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBeUndefined(); - - await terrainProvider.requestTileGeometry(0, 0, 0); - expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBe(true); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }) + .then(function () { + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBeUndefined(); + + return terrainProvider.requestTileGeometry(0, 0, 0); + }) + .then(function () { + expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBe(true); + }); }); - it("supports a query string in the base URL", async function () { + it("supports a query string in the base URL", function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -970,28 +1229,31 @@ describe("Core/CesiumTerrainProvider", function () { returnHeightmapTileJson(); - const loadedData = await waitForTile(0, 0, 0, false, false); - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + return waitForTile(0, 0, 0, false, false, function (loadedData) { + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + }); }); - it("Uses query parameter extensions for ion resource", async function () { - const terrainProvider = await CesiumTerrainProvider.fromUrl( - IonResource.fromAssetId(1), - { - requestVertexNormals: true, - requestWaterMask: true, - } - ); - - const getDerivedResource = spyOn( - IonResource.prototype, - "getDerivedResource" - ).and.callThrough(); - terrainProvider.requestTileGeometry(0, 0, 0); - const options = getDerivedResource.calls.argsFor(0)[0]; - expect(options.queryParameters.extensions).toEqual( - "octvertexnormals-watermask-metadata" - ); + it("Uses query parameter extensions for ion resource", function () { + const terrainProvider = new CesiumTerrainProvider({ + url: IonResource.fromAssetId(1), + requestVertexNormals: true, + requestWaterMask: true, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + const getDerivedResource = spyOn( + IonResource.prototype, + "getDerivedResource" + ).and.callThrough(); + terrainProvider.requestTileGeometry(0, 0, 0); + const options = getDerivedResource.calls.argsFor(0)[0]; + expect(options.queryParameters.extensions).toEqual( + "octvertexnormals-watermask-metadata" + ); + }); }); }); }); diff --git a/packages/engine/Specs/Core/CustomHeightmapTerrainProviderSpec.js b/packages/engine/Specs/Core/CustomHeightmapTerrainProviderSpec.js index 226cad01729..4c83e50c879 100644 --- a/packages/engine/Specs/Core/CustomHeightmapTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/CustomHeightmapTerrainProviderSpec.js @@ -87,6 +87,25 @@ describe("Core/CustomHeightmapTerrainProvider", function () { expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); }); + it("resolves readyPromise", function () { + const width = 2; + const height = 2; + const callback = function (x, y, level) { + return new Float32Array(width * height); + }; + + const provider = new CustomHeightmapTerrainProvider({ + callback: callback, + width: width, + height: height, + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + it("has error event", function () { const width = 2; const height = 2; diff --git a/packages/engine/Specs/Core/EllipsoidTerrainProviderSpec.js b/packages/engine/Specs/Core/EllipsoidTerrainProviderSpec.js index f3ed58d94a7..2d7ad4d1080 100644 --- a/packages/engine/Specs/Core/EllipsoidTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/EllipsoidTerrainProviderSpec.js @@ -19,6 +19,15 @@ describe( expect(EllipsoidTerrainProvider).toConformToInterface(TerrainProvider); }); + it("resolves readyPromise", function () { + const provider = new EllipsoidTerrainProvider(); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + it("requestTileGeometry creates terrain data.", function () { const terrain = new EllipsoidTerrainProvider(); const terrainData = terrain.requestTileGeometry(0, 0, 0); diff --git a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js index 7de7107301d..f1e723b7ce4 100644 --- a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js +++ b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js @@ -108,7 +108,7 @@ describe("Core/GoogleEarthEnterpriseMetadata", function () { }).toThrowError(RuntimeError); }); - it("populateSubtree", async function () { + it("populateSubtree", function () { const quad = "0123"; let index = 0; spyOn( @@ -127,36 +127,173 @@ describe("Core/GoogleEarthEnterpriseMetadata", function () { return Promise.resolve(); }); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl( - "http://test.server" - ); + const metadata = new GoogleEarthEnterpriseMetadata({ + url: "http://test.server", + }); const request = new Request({ throttle: true, }); + return metadata.readyPromise + .then(function () { + const tileXY = GoogleEarthEnterpriseMetadata.quadKeyToTileXY(quad); + return metadata.populateSubtree( + tileXY.x, + tileXY.y, + tileXY.level, + request + ); + }) + .then(function () { + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket.calls.count() + ).toEqual(4); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("", 1); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("0", 1, request); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("01", 1, request); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("012", 1, request); + + const tileInfo = metadata._tileInfo; + expect(tileInfo["0"]).toBeDefined(); + expect(tileInfo["01"]).toBeDefined(); + expect(tileInfo["012"]).toBeDefined(); + expect(tileInfo["0123"]).toBeDefined(); + }); + }); + + it("resolves readyPromise", function () { + const baseurl = "http://fake.fake.invalid/"; + + let req = 0; + spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(responseType).toEqual("arraybuffer"); + if (req === 0) { + expect(url).toEqual(`${baseurl}dbRoot.v5?output=proto`); + deferred.reject(); // Reject dbRoot request and use defaults + } else { + expect(url).toEqual(`${baseurl}flatfile?q2-0-q.1`); + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterprise/gee.metadata", + responseType, + method, + data, + headers, + deferred + ); + } + ++req; + }); + + const provider = new GoogleEarthEnterpriseMetadata({ + url: baseurl, + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + + expect(provider.imageryPresent).toBe(true); + expect(provider.protoImagery).toBeUndefined(); + expect(provider.terrainPresent).toBe(true); + expect(provider.negativeAltitudeThreshold).toBe(CesiumMath.EPSILON12); + expect(provider.negativeAltitudeExponentBias).toBe(32); + expect(provider.providers).toEqual({}); + + const tileInfo = provider._tileInfo["0"]; + expect(tileInfo).toBeDefined(); + expect(tileInfo._bits).toEqual(0x40); + expect(tileInfo.cnodeVersion).toEqual(2); + expect(tileInfo.imageryVersion).toEqual(1); + expect(tileInfo.terrainVersion).toEqual(1); + expect(tileInfo.ancestorHasTerrain).toEqual(false); + expect(tileInfo.terrainState).toBeUndefined(); + }); + }); + + it("resolves readyPromise with Resource", function () { + const baseurl = "http://fake.fake.invalid/"; + const resource = new Resource({ + url: baseurl, + }); + + let req = 0; + spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(responseType).toEqual("arraybuffer"); + if (req === 0) { + expect(url).toEqual(`${baseurl}dbRoot.v5?output=proto`); + deferred.reject(); // Reject dbRoot request and use defaults + } else { + expect(url).toEqual(`${baseurl}flatfile?q2-0-q.1`); + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterprise/gee.metadata", + responseType, + method, + data, + headers, + deferred + ); + } + ++req; + }); + + const provider = new GoogleEarthEnterpriseMetadata(resource); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + + expect(provider.imageryPresent).toBe(true); + expect(provider.protoImagery).toBeUndefined(); + expect(provider.terrainPresent).toBe(true); + expect(provider.negativeAltitudeThreshold).toBe(CesiumMath.EPSILON12); + expect(provider.negativeAltitudeExponentBias).toBe(32); + expect(provider.providers).toEqual({}); + + const tileInfo = provider._tileInfo["0"]; + expect(tileInfo).toBeDefined(); + expect(tileInfo._bits).toEqual(0x40); + expect(tileInfo.cnodeVersion).toEqual(2); + expect(tileInfo.imageryVersion).toEqual(1); + expect(tileInfo.terrainVersion).toEqual(1); + expect(tileInfo.ancestorHasTerrain).toEqual(false); + expect(tileInfo.terrainState).toBeUndefined(); + }); + }); + + it("rejects readyPromise on error", function () { + const url = "host.invalid/"; + const provider = new GoogleEarthEnterpriseMetadata({ + url: url, + }); - const tileXY = GoogleEarthEnterpriseMetadata.quadKeyToTileXY(quad); - await metadata.populateSubtree(tileXY.x, tileXY.y, tileXY.level, request); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket.calls.count() - ).toEqual(4); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("", 1); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("0", 1, request); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("01", 1, request); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("012", 1, request); - - const tileInfo = metadata._tileInfo; - expect(tileInfo["0"]).toBeDefined(); - expect(tileInfo["01"]).toBeDefined(); - expect(tileInfo["012"]).toBeDefined(); - expect(tileInfo["0123"]).toBeDefined(); + return provider.readyPromise + .then(function () { + fail("should not resolve"); + }) + .catch(function (e) { + expect(e.message).toContain(url); + }); }); it("from url resolves to GoogleEarthEnterpriseMetadata", async function () { diff --git a/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js b/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js index 7b4066277b7..3b2efb4ebd6 100644 --- a/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js @@ -45,17 +45,23 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { let terrainProvider; - async function waitForTile(level, x, y, f) { - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); - - await pollToPromise(function () { - return terrainProvider.getTileDataAvailable(x, y, level); + function waitForTile(level, x, y, f) { + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", }); - return terrainProvider.requestTileGeometry(level, x, y); + return pollToPromise(function () { + return ( + terrainProvider.ready && + terrainProvider.getTileDataAvailable(x, y, level) + ); + }).then(function () { + const promise = terrainProvider.requestTileGeometry(level, x, y); + + return Promise.resolve(promise, f, function (error) { + expect("requestTileGeometry").toBe("returning a tile."); // test failure + }); + }); } function createRequest() { @@ -100,51 +106,86 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { ); }); - it("uses geographic tiling scheme by default", async function () { + it("resolves readyPromise", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); - expect(terrainProvider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + return terrainProvider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(terrainProvider.ready).toBe(true); + }); }); - it("can use a custom ellipsoid", async function () { + it("resolves readyPromise with Resource", function () { + const resource = new Resource({ + url: "made/up/url", + }); + installMockGetQuadTreePacket(); - const ellipsoid = new Ellipsoid(1, 2, 3); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata, - { - ellipsoid: ellipsoid, - } - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: resource, + }); - expect(terrainProvider.tilingScheme.ellipsoid).toEqual(ellipsoid); + return terrainProvider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(terrainProvider.ready).toBe(true); + }); }); - it("has error event", async function () { + it("uses geographic tiling scheme by default", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.tilingScheme).toBeInstanceOf( + GeographicTilingScheme + ); + }); + }); + it("can use a custom ellipsoid", function () { + installMockGetQuadTreePacket(); + + const ellipsoid = new Ellipsoid(1, 2, 3); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + ellipsoid: ellipsoid, + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.tilingScheme.ellipsoid).toEqual(ellipsoid); + }); + }); + + it("has error event", function () { + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); expect(terrainProvider.errorEvent).toBeDefined(); expect(terrainProvider.errorEvent).toBe(terrainProvider.errorEvent); + + return terrainProvider.readyPromise.catch(function (e) { + expect(terrainProvider.ready).toBe(false); + }); }); - it("returns reasonable geometric error for various levels", async function () { + it("returns reasonable geometric error for various levels", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); expect(terrainProvider.getLevelMaximumGeometricError(0)).toBeGreaterThan( 0.0 @@ -157,53 +198,87 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { terrainProvider.getLevelMaximumGeometricError(2) * 2.0, CesiumMath.EPSILON10 ); + + return terrainProvider.readyPromise; }); - it("credit is undefined if credit is not provided", async function () { + it("readyPromise rejects if there isn't terrain", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + const metadata = new GoogleEarthEnterpriseMetadata({ + url: "made/up/url", + }); - expect(terrainProvider.credit).toBeUndefined(); + metadata.terrainPresent = false; + + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + metadata: metadata, + }); + + return terrainProvider.readyPromise + .then(function () { + fail("Server does not have terrain, so we shouldn't resolve."); + }) + .catch(function (e) { + expect(terrainProvider.ready).toBe(false); + }); }); - it("credit is defined if credit option is provided", async function () { + it("logo is undefined if credit is not provided", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata, - { - credit: "thanks to our awesome made up contributors!", - } - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); - expect(terrainProvider.credit).toBeDefined(); + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.credit).toBeUndefined(); + }); }); - it("has a water mask is false", async function () { + it("logo is defined if credit is provided", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + credit: "thanks to our awesome made up contributors!", + }); - expect(terrainProvider.hasWaterMask).toBe(false); + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.credit).toBeDefined(); + }); }); - it("has vertex normals is false", async function () { + it("has a water mask is false", function () { installMockGetQuadTreePacket(); - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.hasWaterMask).toBe(false); + }); + }); + + it("has vertex normals is false", function () { + installMockGetQuadTreePacket(); - expect(terrainProvider.hasVertexNormals).toBe(false); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: "made/up/url", + }); + + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + expect(terrainProvider.hasVertexNormals).toBe(false); + }); }); describe("requestTileGeometry", function () { @@ -233,7 +308,7 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { }); }); - it("returns undefined if too many requests are already in progress", async function () { + it("provides GoogleEarthEnterpriseTerrainData with fromMetadata", async function () { installMockGetQuadTreePacket(); Resource._Implementations.loadWithXhr = function ( url, @@ -253,52 +328,107 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { deferred ); }; - const baseUrl = "made/up/url"; - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(baseUrl); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl( + "made/up/url" + ); terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( metadata ); - for (let i = 0; i < 10; ++i) { - await terrainProvider.getTileDataAvailable(i, i, i); - } - await terrainProvider.getTileDataAvailable(1, 2, 3); + await pollToPromise(function () { + return terrainProvider.getTileDataAvailable(0, 0, 0); + }); - let promise; - const promises = []; - for (let i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promise = terrainProvider.requestTileGeometry(i, i, i, request); - promises.push(promise); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); - - let terrainData = await terrainProvider.requestTileGeometry( - 1, - 2, - 3, - createRequest() - ); - expect(terrainData).toBeUndefined(); + const loadedData = await terrainProvider.requestTileGeometry(0, 0, 0); - await Promise.all(promises); + expect(loadedData).toBeInstanceOf(GoogleEarthEnterpriseTerrainData); + }); - terrainData = await terrainProvider.requestTileGeometry( - 1, - 2, - 3, - createRequest() - ); + it("returns undefined if too many requests are already in progress", function () { + installMockGetQuadTreePacket(); + const baseUrl = "made/up/url"; + + const deferreds = []; + let loadRealTile = true; + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + if (url.indexOf("dbRoot.v5") !== -1) { + return deferred.reject(); // Just reject dbRoot file and use defaults. + } + + if (loadRealTile) { + loadRealTile = false; + return Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterprise/gee.terrain", + responseType, + method, + data, + headers, + deferred + ); + } + // Do nothing, so requests never complete + deferreds.push(deferred); + }; - expect(terrainData).toBeDefined(); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: baseUrl, + }); + + const promises = []; + return pollToPromise(function () { + return terrainProvider.ready; + }) + .then(function () { + return pollToPromise(function () { + let b = true; + for (let i = 0; i < 10; ++i) { + b = b && terrainProvider.getTileDataAvailable(i, i, i); + } + return b && terrainProvider.getTileDataAvailable(1, 2, 3); + }); + }) + .then(function () { + let promise; + for (let i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider.requestTileGeometry(i, i, i, request); + promises.push(promise); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); + + return terrainProvider.requestTileGeometry(1, 2, 3, createRequest()); + }) + .then(function (terrainData) { + expect(terrainData).toBeUndefined(); + for (let i = 0; i < deferreds.length; ++i) { + deferreds[i].resolve(); + } + + // Parsing terrain will fail, so just eat the errors and request the tile again + return Promise.all(promises).catch(function () { + loadRealTile = true; + return terrainProvider.requestTileGeometry(1, 2, 3); + }); + }) + .then(function (terrainData) { + expect(terrainData).toBeDefined(); + }); }); - it("supports getTileDataAvailable()", async function () { + it("supports getTileDataAvailable()", function () { installMockGetQuadTreePacket(); const baseUrl = "made/up/url"; @@ -321,23 +451,26 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { ); }; - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(baseUrl); - terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( - metadata - ); + terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ + url: baseUrl, + }); - const tileInfo = terrainProvider._metadata._tileInfo; - const info = - tileInfo[GoogleEarthEnterpriseMetadata.tileXYToQuadKey(0, 1, 0)]; - info._bits = 0x7f; // Remove terrain bit from 0,1,0 tile - info.terrainState = 1; // NONE - info.ancestorHasTerrain = true; - - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 1, 0)).toBe(false); - expect(terrainProvider.getTileDataAvailable(1, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(1, 1, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); + return pollToPromise(function () { + return terrainProvider.ready; + }).then(function () { + const tileInfo = terrainProvider._metadata._tileInfo; + const info = + tileInfo[GoogleEarthEnterpriseMetadata.tileXYToQuadKey(0, 1, 0)]; + info._bits = 0x7f; // Remove terrain bit from 0,1,0 tile + info.terrainState = 1; // NONE + info.ancestorHasTerrain = true; + + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 1, 0)).toBe(false); + expect(terrainProvider.getTileDataAvailable(1, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(1, 1, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); + }); }); }); }); diff --git a/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js b/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js index 066728eb722..90f849cc409 100644 --- a/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js @@ -5,7 +5,6 @@ import { Request, RequestScheduler, Resource, - RuntimeError, TerrainProvider, VRTheWorldTerrainProvider, } from "../../index.js"; @@ -112,54 +111,106 @@ describe("Core/VRTheWorldTerrainProvider", function () { expect(provider).toBeInstanceOf(VRTheWorldTerrainProvider); }); - it("has error event", async function () { + it("resolves readyPromise", function () { patchXHRLoad(); - const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("resolves readyPromise with Resource", function () { + patchXHRLoad(); + + const resource = new Resource({ + url: "made/up/url", + }); + + const provider = new VRTheWorldTerrainProvider({ + url: resource, + }); + + return provider.readyPromise.then(function (result) { + expect(result).toBe(true); + expect(provider.ready).toBe(true); + }); + }); + + it("has error event", function () { + patchXHRLoad(); + + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); + return provider.readyPromise; }); - it("returns reasonable geometric error for various levels", async function () { + it("returns reasonable geometric error for various levels", function () { patchXHRLoad(); - const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); + return provider.readyPromise.then(function () { + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); + }); }); - it("credit is undefined if credit is not provided", async function () { + it("credit is undefined if credit option is not provided", function () { patchXHRLoad(); - - const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); expect(provider.credit).toBeUndefined(); + return provider.readyPromise; }); - it("credit is defined if credit option is provided", async function () { + it("credit is defined if credit optoin is provided", function () { patchXHRLoad(); - - const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url", { + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", credit: "thanks to our awesome made up contributors!", }); expect(provider.credit).toBeDefined(); + return provider.readyPromise; }); - it("does not have a water mask", async function () { + it("does not have a water mask", function () { patchXHRLoad(); - - const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); expect(provider.hasWaterMask).toBe(false); + return provider.readyPromise; + }); + + it("is not ready immediately", function () { + patchXHRLoad(); + const provider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); + expect(provider.ready).toBe(false); + return provider.readyPromise; }); - it("fromUrl throws an error if the SRS is not supported", async function () { + it("raises an error if the SRS is not supported", function () { + patchXHRLoad(); Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -196,16 +247,28 @@ describe("Core/VRTheWorldTerrainProvider", function () { }, 1); }; - await expectAsync( - VRTheWorldTerrainProvider.fromUrl("made/up/url") - ).toBeRejectedWithError(RuntimeError, "SRS EPSG:foo is not supported"); + const terrainProvider = new VRTheWorldTerrainProvider({ + url: "made/up/url", + }); + + let called = false; + const errorFunction = function () { + called = true; + }; + + terrainProvider.errorEvent.addEventListener(errorFunction); + + return terrainProvider.readyPromise.then(fail).catch(() => { + expect(called).toBe(true); + }); }); describe("requestTileGeometry", function () { - it("provides HeightmapTerrainData", async function () { - const baseUrl = "made/up/url"; + it("provides HeightmapTerrainData", function () { patchXHRLoad(); + const baseUrl = "made/up/url"; + Resource._Implementations.createImage = function ( request, crossOrigin, @@ -223,18 +286,25 @@ describe("Core/VRTheWorldTerrainProvider", function () { ); }; - const terrainProvider = await VRTheWorldTerrainProvider.fromUrl(baseUrl); - expect(terrainProvider.tilingScheme).toBeInstanceOf( - GeographicTilingScheme - ); - - const loadedData = await terrainProvider.requestTileGeometry(0, 0, 0); - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + const terrainProvider = new VRTheWorldTerrainProvider({ + url: baseUrl, + }); + + return terrainProvider.readyPromise + .then(function () { + expect(terrainProvider.tilingScheme).toBeInstanceOf( + GeographicTilingScheme + ); + return terrainProvider.requestTileGeometry(0, 0, 0); + }) + .then(function (loadedData) { + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); + }); }); - it("returns undefined if too many requests are already in progress", async function () { - const baseUrl = "made/up/url"; + it("returns undefined if too many requests are already in progress", function () { patchXHRLoad(); + const baseUrl = "made/up/url"; const deferreds = []; @@ -247,35 +317,39 @@ describe("Core/VRTheWorldTerrainProvider", function () { deferreds.push(deferred); }; - const terrainProvider = await VRTheWorldTerrainProvider.fromUrl(baseUrl); - - const promises = []; - let promise; - let i; - for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promise = terrainProvider.requestTileGeometry(0, 0, 0, request); - promises.push(promise); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); - - promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); - expect(promise).toBeUndefined(); - - for (i = 0; i < deferreds.length; ++i) { - const deferred = deferreds[i]; - Resource._Implementations.loadImageElement( - "Data/Images/Red16x16.png", - false, - deferred - ); - } - - return Promise.all(promises); + const terrainProvider = new VRTheWorldTerrainProvider({ + url: baseUrl, + }); + + return terrainProvider.readyPromise.then(function () { + const promises = []; + let promise; + let i; + for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider.requestTileGeometry(0, 0, 0, request); + promises.push(promise); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); + + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); + + for (i = 0; i < deferreds.length; ++i) { + const deferred = deferreds[i]; + Resource._Implementations.loadImageElement( + "Data/Images/Red16x16.png", + false, + deferred + ); + } + + return Promise.all(promises); + }); }); }); }); diff --git a/packages/engine/Specs/Core/sampleTerrainMostDetailedSpec.js b/packages/engine/Specs/Core/sampleTerrainMostDetailedSpec.js index 65f26bd683d..39303a907b1 100644 --- a/packages/engine/Specs/Core/sampleTerrainMostDetailedSpec.js +++ b/packages/engine/Specs/Core/sampleTerrainMostDetailedSpec.js @@ -2,6 +2,7 @@ import { Cartographic, CesiumTerrainProvider, createWorldTerrainAsync, + IonResource, sampleTerrainMostDetailed, } from "../../index.js"; @@ -11,6 +12,27 @@ describe("Core/sampleTerrainMostDetailed", function () { worldTerrain = await createWorldTerrainAsync(); }); + it("queries heights from deprecated world terrain", async function () { + const positions = [ + Cartographic.fromDegrees(86.925145, 27.988257), + Cartographic.fromDegrees(87.0, 28.0), + ]; + + const terrain = new CesiumTerrainProvider({ + url: IonResource.fromAssetId(1), + }); + + return sampleTerrainMostDetailed(terrain, positions).then(function ( + passedPositions + ) { + expect(passedPositions).toBe(positions); + expect(positions[0].height).toBeGreaterThan(5000); + expect(positions[0].height).toBeLessThan(10000); + expect(positions[1].height).toBeGreaterThan(5000); + expect(positions[1].height).toBeLessThan(10000); + }); + }); + it("queries heights", async function () { const positions = [ Cartographic.fromDegrees(86.925145, 27.988257), diff --git a/packages/engine/Specs/Core/sampleTerrainSpec.js b/packages/engine/Specs/Core/sampleTerrainSpec.js index bb97e754b3c..6981d21c8ab 100644 --- a/packages/engine/Specs/Core/sampleTerrainSpec.js +++ b/packages/engine/Specs/Core/sampleTerrainSpec.js @@ -4,6 +4,7 @@ import { CesiumTerrainProvider, createWorldTerrainAsync, defined, + IonResource, RequestScheduler, Resource, sampleTerrain, @@ -15,6 +16,27 @@ describe("Core/sampleTerrain", function () { worldTerrain = await createWorldTerrainAsync(); }); + it("queries heights from deprecated world terrain", function () { + const positions = [ + Cartographic.fromDegrees(86.925145, 27.988257), + Cartographic.fromDegrees(87.0, 28.0), + ]; + + const terrain = new CesiumTerrainProvider({ + url: IonResource.fromAssetId(1), + }); + + return sampleTerrain(terrain, 11, positions).then(function ( + passedPositions + ) { + expect(passedPositions).toBe(positions); + expect(positions[0].height).toBeGreaterThan(5000); + expect(positions[0].height).toBeLessThan(10000); + expect(positions[1].height).toBeGreaterThan(5000); + expect(positions[1].height).toBeLessThan(10000); + }); + }); + it("queries heights", function () { const positions = [ Cartographic.fromDegrees(86.925145, 27.988257), @@ -74,24 +96,24 @@ describe("Core/sampleTerrain", function () { }); }); - it("requires terrainProvider, level, and positions", function () { + it("requires terrainProvider, level, and positions", async function () { const positions = [ Cartographic.fromDegrees(86.925145, 27.988257), Cartographic.fromDegrees(0.0, 0.0, 0.0), Cartographic.fromDegrees(87.0, 28.0), ]; - expect(function () { - sampleTerrain(undefined, 11, positions); - }).toThrowDeveloperError(); + await expectAsync( + sampleTerrain(undefined, 11, positions) + ).toBeRejectedWithDeveloperError(); - expect(function () { - sampleTerrain(worldTerrain, undefined, positions); - }).toThrowDeveloperError(); + await expectAsync( + sampleTerrain(worldTerrain, undefined, positions) + ).toBeRejectedWithDeveloperError(); - expect(function () { - sampleTerrain(worldTerrain, 11, undefined); - }).toThrowDeveloperError(); + await expectAsync( + sampleTerrain(worldTerrain, 11, undefined) + ).toBeRejectedWithDeveloperError(); }); it("works for a dodgy point right near the edge of a tile", function () { diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 91380849ab4..27c8c3181f5 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -23,7 +23,7 @@ import { CustomShader, Globe, Cartographic, - createWorldTerrainAsync, + createWorldTerrain, } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; @@ -380,7 +380,7 @@ describe( }); }); - it("Computes bounding sphere with height reference clamp to ground", async function () { + it("Computes bounding sphere with height reference clamp to ground", function () { // Setup a position for the model. const position = Cartesian3.fromDegrees(149.515332, -34.984799); const positionCartographic = Cartographic.fromCartesian(position); @@ -411,43 +411,48 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = await createWorldTerrainAsync(); - - const updatedCartographics = await ModelVisualizer._sampleTerrainMostDetailed( - globe.terrainProvider, - [positionCartographic] - ); - const sampledResultCartographic = updatedCartographics[0]; - const sampledResult = globe.ellipsoid.cartographicToCartesian( - sampledResultCartographic - ); - - // Repeatedly request the bounding sphere until it's ready. - await pollToPromise(function () { - scene.render(); - state = visualizer.getBoundingSphere(testObject, result); - return state !== BoundingSphereState.PENDING; - }); - - expect(state).toBe(BoundingSphereState.DONE); - - // Ensure that flags and results computed for this model are reset. - const modelData = visualizer._modelHash[testObject.id]; - expect(modelData.awaitingSampleTerrain).toBe(false); - expect(modelData.clampedBoundingSphere).toBeUndefined(); - - // Ensure that we only sample the terrain once from the visualizer. - // We check for 2 calls here because we call it once in the test. - expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); - - // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. - // Since sampleTerrainMostDetailed isn't always precise, we account for some error. - const distance = Cartesian3.distance(result.center, sampledResult); - const errorMargin = 100.0; - expect(distance).toBeLessThan(errorMargin); - - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; + globe.terrainProvider = createWorldTerrain(); + + let sampledResultCartographic; + let sampledResult; + + return ModelVisualizer._sampleTerrainMostDetailed(globe.terrainProvider, [ + positionCartographic, + ]) + .then((updatedCartographics) => { + sampledResultCartographic = updatedCartographics[0]; + sampledResult = globe.ellipsoid.cartographicToCartesian( + sampledResultCartographic + ); + + // Repeatedly request the bounding sphere until it's ready. + return pollToPromise(function () { + scene.render(); + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + }) + .then(() => { + expect(state).toBe(BoundingSphereState.DONE); + + // Ensure that flags and results computed for this model are reset. + const modelData = visualizer._modelHash[testObject.id]; + expect(modelData.awaitingSampleTerrain).toBe(false); + expect(modelData.clampedBoundingSphere).toBeUndefined(); + + // Ensure that we only sample the terrain once from the visualizer. + // We check for 2 calls here because we call it once in the test. + expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); + + // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. + // Since sampleTerrainMostDetailed isn't always precise, we account for some error. + const distance = Cartesian3.distance(result.center, sampledResult); + const errorMargin = 100.0; + expect(distance).toBeLessThan(errorMargin); + + // Reset the terrain provider. + globe.terrainProvider = previousTerrainProvider; + }); }); it("Computes bounding sphere with height reference clamp to ground on terrain provider without availability", function () { @@ -502,7 +507,7 @@ describe( }); }); - it("Computes bounding sphere with height reference relative to ground", async function () { + it("Computes bounding sphere with height reference relative to ground", function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -538,44 +543,49 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = await createWorldTerrainAsync(); - - const updatedCartographics = await ModelVisualizer._sampleTerrainMostDetailed( - globe.terrainProvider, - [positionCartographic] - ); - const sampledResultCartographic = updatedCartographics[0]; - const sampledResult = globe.ellipsoid.cartographicToCartesian( - sampledResultCartographic - ); - - // Repeatedly request the bounding sphere until it's ready. - await pollToPromise(function () { - scene.render(); - state = visualizer.getBoundingSphere(testObject, result); - return state !== BoundingSphereState.PENDING; - }); - - expect(state).toBe(BoundingSphereState.DONE); - - // Ensure that flags and results computed for this model are reset. - const modelData = visualizer._modelHash[testObject.id]; - expect(modelData.awaitingSampleTerrain).toBe(false); - expect(modelData.clampedBoundingSphere).toBeUndefined(); - - // Ensure that we only sample the terrain once from the visualizer. - // We check for 2 calls here because we call it once in the test. - expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); - - // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. - // Since sampleTerrainMostDetailed isn't always precise, we account for some error. - const distance = - Cartesian3.distance(result.center, sampledResult) - heightOffset; - const errorMargin = 100.0; - expect(distance).toBeLessThan(errorMargin); - - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; + globe.terrainProvider = createWorldTerrain(); + + let sampledResultCartographic; + let sampledResult; + + return ModelVisualizer._sampleTerrainMostDetailed(globe.terrainProvider, [ + positionCartographic, + ]) + .then((updatedCartographics) => { + sampledResultCartographic = updatedCartographics[0]; + sampledResult = globe.ellipsoid.cartographicToCartesian( + sampledResultCartographic + ); + + // Repeatedly request the bounding sphere until it's ready. + return pollToPromise(function () { + scene.render(); + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + }) + .then(() => { + expect(state).toBe(BoundingSphereState.DONE); + + // Ensure that flags and results computed for this model are reset. + const modelData = visualizer._modelHash[testObject.id]; + expect(modelData.awaitingSampleTerrain).toBe(false); + expect(modelData.clampedBoundingSphere).toBeUndefined(); + + // Ensure that we only sample the terrain once from the visualizer. + // We check for 2 calls here because we call it once in the test. + expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); + + // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. + // Since sampleTerrainMostDetailed isn't always precise, we account for some error. + const distance = + Cartesian3.distance(result.center, sampledResult) - heightOffset; + const errorMargin = 100.0; + expect(distance).toBeLessThan(errorMargin); + + // Reset the terrain provider. + globe.terrainProvider = previousTerrainProvider; + }); }); it("Computes bounding sphere with height reference relative to ground on terrain provider without availability", function () { @@ -660,7 +670,7 @@ describe( }); }); - it("Fails bounding sphere when sampleTerrainMostDetailed fails.", async function () { + it("Fails bounding sphere when sampleTerrainMostDetailed fails.", function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -692,28 +702,29 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = await createWorldTerrainAsync(); + globe.terrainProvider = createWorldTerrain(); // Request the bounding sphere once. const result = new BoundingSphere(); let state; // Repeatedly request the bounding sphere until it's ready. - await pollToPromise(function () { + return pollToPromise(function () { scene.render(); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; - }); - expect(state).toBe(BoundingSphereState.FAILED); + }).then(() => { + expect(state).toBe(BoundingSphereState.FAILED); - // Ensure that flags and results computed for this model are reset. - const modelData = visualizer._modelHash[testObject.id]; - expect(modelData.sampleTerrainFailed).toBe(false); + // Ensure that flags and results computed for this model are reset. + const modelData = visualizer._modelHash[testObject.id]; + expect(modelData.sampleTerrainFailed).toBe(false); - // Ensure that we only sample the terrain once from the visualizer. - expect(sampleTerrainSpy).toHaveBeenCalledTimes(1); - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; + // Ensure that we only sample the terrain once from the visualizer. + expect(sampleTerrainSpy).toHaveBeenCalledTimes(1); + // Reset the terrain provider. + globe.terrainProvider = previousTerrainProvider; + }); }); it("Compute bounding sphere throws without entity.", function () { diff --git a/packages/engine/Specs/Scene/BillboardCollectionSpec.js b/packages/engine/Specs/Scene/BillboardCollectionSpec.js index 529ff904953..2e605eb15d3 100644 --- a/packages/engine/Specs/Scene/BillboardCollectionSpec.js +++ b/packages/engine/Specs/Scene/BillboardCollectionSpec.js @@ -2503,7 +2503,7 @@ describe( expect(b._clampedPosition).toBeUndefined(); }); - it("changing the terrain provider", async function () { + it("changing the terrain provider", function () { const b = billboardsWithHeight.add({ heightReference: HeightReference.CLAMP_TO_GROUND, position: Cartesian3.fromDegrees(-72.0, 40.0), @@ -2512,12 +2512,10 @@ describe( spyOn(b, "_updateClamping").and.callThrough(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { - requestVertexNormals: true, - } - ); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + requestVertexNormals: true, + }); scene.terrainProvider = terrainProvider; diff --git a/packages/engine/Specs/Scene/GlobeSpec.js b/packages/engine/Specs/Scene/GlobeSpec.js index 8dcd26beb14..191b14014bf 100644 --- a/packages/engine/Specs/Scene/GlobeSpec.js +++ b/packages/engine/Specs/Scene/GlobeSpec.js @@ -223,13 +223,11 @@ describe( }); }); - it("terrainProviderChanged event fires", async function () { - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { - requestVertexNormals: true, - } - ); + it("terrainProviderChanged event fires", function () { + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + requestVertexNormals: true, + }); const spyListener = jasmine.createSpy("listener"); globe.terrainProviderChanged.addEventListener(spyListener); @@ -239,7 +237,7 @@ describe( expect(spyListener).toHaveBeenCalledWith(terrainProvider); }); - it("tilesLoaded return true when tile load queue is empty", async function () { + it("tilesLoaded return true when tile load queue is empty", function () { expect(globe.tilesLoaded).toBe(true); globe._surface._tileLoadQueueHigh.length = 2; @@ -260,19 +258,17 @@ describe( globe._surface._tileLoadQueueLow.length = 0; expect(globe.tilesLoaded).toBe(true); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { - requestVertexNormals: true, - } - ); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + requestVertexNormals: true, + }); globe.terrainProvider = terrainProvider; scene.render(); expect(globe.tilesLoaded).toBe(false); }); - it("renders terrain with enableLighting", async function () { + it("renders terrain with enableLighting", function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -285,48 +281,48 @@ describe( url: "Data/Images/Red16x16.png", }); layerCollection.addImageryProvider(imageryProvider); - await imageryProvider.readyPromise; - Resource._Implementations.loadWithXhr = function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + return imageryProvider.readyPromise.then(function () { + Resource._Implementations.loadWithXhr = function ( + url, responseType, method, data, headers, - deferred - ); - }; + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + responseType, + method, + data, + headers, + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, - } - ); + }); - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - await updateUntilDone(globe); - expect(renderOptions).notToRender([0, 0, 0, 255]); + return updateUntilDone(globe).then(function () { + expect(renderOptions).notToRender([0, 0, 0, 255]); - scene.globe.show = false; - expect(renderOptions).toRender([0, 0, 0, 255]); + scene.globe.show = false; + expect(renderOptions).toRender([0, 0, 0, 255]); + }); + }); }); - it("renders terrain with lambertDiffuseMultiplier", async function () { + it("renders terrain with lambertDiffuseMultiplier", function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -339,52 +335,51 @@ describe( url: "Data/Images/Red16x16.png", }); layerCollection.addImageryProvider(imageryProvider); - await imageryProvider.readyPromise; - Resource._Implementations.loadWithXhr = function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + return imageryProvider.readyPromise.then(function () { + Resource._Implementations.loadWithXhr = function ( + url, responseType, method, data, headers, - deferred - ); - }; + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + responseType, + method, + data, + headers, + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, - } - ); - - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + }); - await updateUntilDone(globe); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - let initialRgba; - expect(renderOptions).toRenderAndCall(function (rgba) { - initialRgba = rgba; - expect(renderOptions).notToRender([0, 0, 0, 255]); + return updateUntilDone(globe).then(function () { + let initialRgba; + expect(renderOptions).toRenderAndCall(function (rgba) { + initialRgba = rgba; + expect(renderOptions).notToRender([0, 0, 0, 255]); + }); + globe.lambertDiffuseMultiplier = 10.0; + expect(renderOptions).notToRender(initialRgba); + }); }); - globe.lambertDiffuseMultiplier = 10.0; - expect(renderOptions).notToRender(initialRgba); }); - it("renders terrain with vertexShadowDarkness", async function () { + it("renders terrain with vertexShadowDarkness", function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -397,47 +392,47 @@ describe( url: "Data/Images/Red16x16.png", }); layerCollection.addImageryProvider(imageryProvider); - await imageryProvider.readyPromise; - Resource._Implementations.loadWithXhr = function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + return imageryProvider.readyPromise.then(function () { + Resource._Implementations.loadWithXhr = function ( + url, responseType, method, data, headers, - deferred - ); - }; + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", + responseType, + method, + data, + headers, + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, - } - ); + }); - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - await updateUntilDone(globe); - let initialRgba; - expect(renderOptions).toRenderAndCall(function (rgba) { - initialRgba = rgba; - expect(renderOptions).notToRender([0, 0, 0, 255]); - globe.vertexShadowDarkness = 0.1; - expect(renderOptions).notToRender(initialRgba); + return updateUntilDone(globe).then(function () { + let initialRgba; + expect(renderOptions).toRenderAndCall(function (rgba) { + initialRgba = rgba; + expect(renderOptions).notToRender([0, 0, 0, 255]); + globe.vertexShadowDarkness = 0.1; + expect(renderOptions).notToRender(initialRgba); + }); + }); }); }); diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js index eb475da30d7..12f7b341e9c 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js @@ -895,7 +895,7 @@ describe( }); }); - it("adds terrain and imagery credits to the CreditDisplay", async function () { + it("adds terrain and imagery credits to the CreditDisplay", function () { const CreditDisplayElement = CreditDisplay.CreditDisplayElement; const imageryCredit = new Credit("imagery credit"); scene.imageryLayers.addImageryProvider( @@ -906,23 +906,22 @@ describe( ); const terrainCredit = new Credit("terrain credit"); - scene.terrainProvider = await CesiumTerrainProvider.fromUrl( - "https://s3.amazonaws.com/cesiumjs/smallTerrain", - { - credit: terrainCredit, - } - ); + scene.terrainProvider = new CesiumTerrainProvider({ + url: "https://s3.amazonaws.com/cesiumjs/smallTerrain", + credit: terrainCredit, + }); - await updateUntilDone(scene.globe); - const creditDisplay = scene.frameState.creditDisplay; - creditDisplay.showLightbox(); - expect( - creditDisplay._currentFrameCredits.lightboxCredits.values - ).toContain(new CreditDisplayElement(imageryCredit)); - expect( - creditDisplay._currentFrameCredits.lightboxCredits.values - ).toContain(new CreditDisplayElement(terrainCredit)); - creditDisplay.hideLightbox(); + return updateUntilDone(scene.globe).then(function () { + const creditDisplay = scene.frameState.creditDisplay; + creditDisplay.showLightbox(); + expect( + creditDisplay._currentFrameCredits.lightboxCredits.values + ).toContain(new CreditDisplayElement(imageryCredit)); + expect( + creditDisplay._currentFrameCredits.lightboxCredits.values + ).toContain(new CreditDisplayElement(terrainCredit)); + creditDisplay.hideLightbox(); + }); }); describe( diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileSpec.js index 10a31d4201d..5d4b868e151 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileSpec.js @@ -1,7 +1,7 @@ import { Cartesian3, Cartesian4, - createWorldTerrainAsync, + createWorldTerrain, Ellipsoid, EllipsoidTerrainProvider, GeographicTilingScheme, @@ -335,8 +335,8 @@ describe("Scene/GlobeSurfaceTile", function () { scene.destroyForSpecs(); }); - it("gets correct results even when the mesh includes normals", async function () { - const terrainProvider = await createWorldTerrainAsync({ + it("gets correct results even when the mesh includes normals", function () { + const terrainProvider = createWorldTerrain({ requestVertexNormals: true, requestWaterMask: false, }); @@ -351,24 +351,25 @@ describe("Scene/GlobeSurfaceTile", function () { processor.frameState = scene.frameState; processor.terrainProvider = terrainProvider; - await processor.process([tile]); - const ray = new Ray( - new Cartesian3( - -5052039.459789615, - 2561172.040315167, - -2936276.999965875 - ), - new Cartesian3( - 0.5036332963145244, - 0.6648033332898124, - 0.5517155343926082 - ) - ); - const pickResult = tile.data.pick(ray, undefined, undefined, true); - const cartographic = Ellipsoid.WGS84.cartesianToCartographic( - pickResult - ); - expect(cartographic.height).toBeGreaterThan(-500.0); + return processor.process([tile]).then(function () { + const ray = new Ray( + new Cartesian3( + -5052039.459789615, + 2561172.040315167, + -2936276.999965875 + ), + new Cartesian3( + 0.5036332963145244, + 0.6648033332898124, + 0.5517155343926082 + ) + ); + const pickResult = tile.data.pick(ray, undefined, undefined, true); + const cartographic = Ellipsoid.WGS84.cartesianToCartographic( + pickResult + ); + expect(cartographic.height).toBeGreaterThan(-500.0); + }); }); it("gets correct result when a closer triangle is processed after a farther triangle", function () { diff --git a/packages/engine/Specs/Scene/Model/ModelSpec.js b/packages/engine/Specs/Scene/Model/ModelSpec.js index 7ef0aa8c7a1..180ab45ec0e 100644 --- a/packages/engine/Specs/Scene/Model/ModelSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSpec.js @@ -1314,22 +1314,22 @@ describe( const triangleFanUrl = "./Data/Models/glTF-2.0/TriangleFan/glTF/TriangleFan.gltf"; - let sceneWithWebgl2; + let sceneWithWebgl1; beforeAll(function () { - sceneWithWebgl2 = createScene({ + sceneWithWebgl1 = createScene({ contextOptions: { - requestWebgl1: false, + requestWebgl1: true, }, }); }); afterEach(function () { - sceneWithWebgl2.primitives.removeAll(); + sceneWithWebgl1.primitives.removeAll(); }); afterAll(function () { - sceneWithWebgl2.destroyForSpecs(); + sceneWithWebgl1.destroyForSpecs(); }); it("debugWireframe works for WebGL1 if enableDebugWireframe is true", function () { @@ -1338,7 +1338,7 @@ describe( return loadPromise.then(function (buffer) { return loadAndZoomToModel( { gltf: new Uint8Array(buffer), enableDebugWireframe: true }, - scene + sceneWithWebgl1 ).then(function (model) { verifyDebugWireframe(model, PrimitiveType.TRIANGLES); }); @@ -1351,12 +1351,12 @@ describe( return loadPromise.then(function (buffer) { return loadAndZoomToModel( { gltf: new Uint8Array(buffer), enableDebugWireframe: false }, - scene + sceneWithWebgl1 ).then(function (model) { const commandList = scene.frameState.commandList; const commandCounts = []; let i, command; - scene.renderForSpecs(); + sceneWithWebgl1.renderForSpecs(); for (i = 0; i < commandList.length; i++) { command = commandList[i]; expect(command.primitiveType).toBe(PrimitiveType.TRIANGLES); @@ -1366,7 +1366,7 @@ describe( model.debugWireframe = true; expect(model._drawCommandsBuilt).toBe(false); - scene.renderForSpecs(); + sceneWithWebgl1.renderForSpecs(); for (i = 0; i < commandList.length; i++) { command = commandList[i]; expect(command.primitiveType).toBe(PrimitiveType.TRIANGLES); @@ -1377,7 +1377,7 @@ describe( }); it("debugWireframe works for WebGL2", function () { - if (!sceneWithWebgl2.context.webgl2) { + if (!scene.context.webgl2) { return; } const resource = Resource.createIfNeeded(boxTexturedGlbUrl); @@ -1388,7 +1388,7 @@ describe( scene ).then(function (model) { verifyDebugWireframe(model, PrimitiveType.TRIANGLES, { - scene: sceneWithWebgl2, + scene: scene, }); }); }); @@ -2231,8 +2231,8 @@ describe( }); }); - it("height reference accounts for change in terrain provider", async function () { - const model = await loadAndZoomToModel( + it("height reference accounts for change in terrain provider", function () { + return loadAndZoomToModel( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2242,18 +2242,17 @@ describe( scene: sceneWithMockGlobe, }, sceneWithMockGlobe - ); - expect(model._heightDirty).toBe(false); - const terrainProvider = await CesiumTerrainProvider.fromUrl( - "made/up/url", - { + ).then(function (model) { + expect(model._heightDirty).toBe(false); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", requestVertexNormals: true, - } - ); - sceneWithMockGlobe.terrainProvider = terrainProvider; + }); + sceneWithMockGlobe.terrainProvider = terrainProvider; - expect(model._heightDirty).toBe(true); - sceneWithMockGlobe.terrainProvider = undefined; + expect(model._heightDirty).toBe(true); + sceneWithMockGlobe.terrainProvider = undefined; + }); }); it("throws when initializing height reference with no scene", function () { diff --git a/packages/engine/Specs/Scene/SceneSpec.js b/packages/engine/Specs/Scene/SceneSpec.js index 7f3cb203bae..ac03d760e8a 100644 --- a/packages/engine/Specs/Scene/SceneSpec.js +++ b/packages/engine/Specs/Scene/SceneSpec.js @@ -1495,26 +1495,33 @@ describe( scene.destroyForSpecs(); }); - it("Sets terrainProvider", async function () { + it("Sets terrainProvider", function () { returnQuantizedMeshTileJson(); const scene = createScene(); const globe = (scene.globe = new Globe(Ellipsoid.UNIT_SPHERE)); - scene.terrainProvider = await CesiumTerrainProvider.fromUrl( - "//terrain/tiles" - ); - expect(scene.terrainProvider).toBe(globe.terrainProvider); - - const newProvider = await CesiumTerrainProvider.fromUrl( - "//newTerrain/tiles" - ); - scene.terrainProvider = newProvider; - expect(scene.terrainProvider).toBe(newProvider); - expect(scene.terrainProvider).toBe(globe.terrainProvider); + scene.terrainProvider = new CesiumTerrainProvider({ + url: "//terrain/tiles", + }); - scene.destroyForSpecs(); - Resource._Implementations.loadWithXhr = - Resource._DefaultImplementations.loadWithXhr; + return scene.terrainProvider.readyPromise + .then(() => { + expect(scene.terrainProvider).toBe(globe.terrainProvider); + scene.globe = undefined; + const newProvider = new CesiumTerrainProvider({ + url: "//newTerrain/tiles", + }); + return newProvider.readyPromise.then(() => { + expect(function () { + scene.terrainProvider = newProvider; + }).not.toThrow(); + }); + }) + .finally(() => { + scene.destroyForSpecs(); + Resource._Implementations.loadWithXhr = + Resource._DefaultImplementations.loadWithXhr; + }); }); it("Gets terrainProviderChanged", function () { diff --git a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js index b00b49867fc..4485c03fe46 100644 --- a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js +++ b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js @@ -10,6 +10,7 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { this.imageryLayers = new ImageryLayerCollection(); this.terrainProvider = new EllipsoidTerrainProvider(); } + MockGlobe.prototype.isDestroyed = () => false; const testProvider = {}; const testProvider2 = {}; @@ -42,6 +43,15 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { }, }); + const testProviderViewModelAsync = new ProviderViewModel({ + name: "name3", + tooltip: "tooltip3", + iconUrl: "url3", + creationFunction: async function () { + return testProvider; + }, + }); + it("constructor sets expected values", function () { const imageryViewModels = []; const terrainViewModels = []; @@ -231,6 +241,22 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { expect(globe.terrainProvider).toBe(testProvider3); }); + it("selectedTerrain actually sets async terrainProvider", async function () { + const terrainProviderViewModels = [ + testProviderViewModel, + testProviderViewModelAsync, + ]; + const globe = new MockGlobe(); + const viewModel = new BaseLayerPickerViewModel({ + globe: globe, + terrainProviderViewModels: terrainProviderViewModels, + }); + + viewModel.selectedTerrain = testProviderViewModelAsync; + await testProviderViewModelAsync.creationCommand(); + expect(globe.terrainProvider).toBe(testProvider); + }); + it("settings selectedImagery only removes layers added by view model", function () { const imageryViewModels = [testProviderViewModel]; const globe = new MockGlobe(); From 32d41b2aa59f649fbdc5390c837c336d7f6b5f1d Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 20 Jan 2023 15:20:38 -0500 Subject: [PATCH 376/679] Tweak toBeRejectedWithDeveloperError --- Specs/addDefaultMatchers.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Specs/addDefaultMatchers.js b/Specs/addDefaultMatchers.js index 9cdc8258ee0..46ac8441223 100644 --- a/Specs/addDefaultMatchers.js +++ b/Specs/addDefaultMatchers.js @@ -66,21 +66,21 @@ function makeAsyncThrowFunction(debug, Type, name) { return { compare: function (actualPromise) { return Promise.resolve(actualPromise) - .catch((e) => { - // Ignore any error + .then(() => { return { pass: true }; }) - .finally(() => { + .catch((e) => { + // Ignore any error return { pass: true }; }); }, negativeCompare: function (actualPromise) { return Promise.resolve(actualPromise) - .catch((e) => { - // Ignore any error + .then(() => { return { pass: true }; }) - .finally(() => { + .catch((e) => { + // Ignore any error return { pass: true }; }); }, From 7fa8fbfe3d3a54cfe80b9fa4917441c4c4a8c3bc Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Sat, 21 Jan 2023 13:46:10 -0500 Subject: [PATCH 377/679] Compute exact voxel step size via ray-box intersection --- .../Source/Scene/VoxelRenderResources.js | 7 ++- .../Source/Shaders/Voxels/IntersectBox.glsl | 55 +++++++++++++++++-- .../Voxels/IntersectClippingPlanes.glsl | 4 +- .../Source/Shaders/Voxels/IntersectDepth.glsl | 2 +- .../Source/Shaders/Voxels/Intersection.glsl | 4 +- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 28 +++++++--- .../Source/Shaders/Voxels/convertUvToBox.glsl | 18 ++++-- 7 files changed, 92 insertions(+), 26 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelRenderResources.js b/packages/engine/Source/Scene/VoxelRenderResources.js index 922435690dc..27119de61fc 100644 --- a/packages/engine/Source/Scene/VoxelRenderResources.js +++ b/packages/engine/Source/Scene/VoxelRenderResources.js @@ -88,6 +88,8 @@ function VoxelRenderResources(primitive) { customShader.fragmentShaderText, "#line 0", IntersectionUtils, + Octree, + Megatexture, ]); if (clippingPlanesLength > 0) { @@ -121,10 +123,11 @@ function VoxelRenderResources(primitive) { const shapeType = primitive._provider.shape; if (shapeType === "BOX") { + shaderBuilder.addDefine("SHAPE_BOX", undefined, ShaderDestination.FRAGMENT); shaderBuilder.addFragmentLines([ + convertUvToBox, IntersectBox, Intersection, - convertUvToBox, ]); } else if (shapeType === "CYLINDER") { shaderBuilder.addFragmentLines([ @@ -140,7 +143,7 @@ function VoxelRenderResources(primitive) { ]); } - shaderBuilder.addFragmentLines([Octree, Megatexture, VoxelFS]); + shaderBuilder.addFragmentLines([VoxelFS]); const shape = primitive._shape; const shapeDefines = shape.shaderDefines; diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 249b7df0ec5..b8192d4d641 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -1,4 +1,5 @@ // See IntersectionUtils.glsl for the definitions of Ray and NO_HIT +// See convertUvToBox.glsl for the definition of convertShapeUvToUvSpace /* Box defines (set in Scene/VoxelBoxShape.js) #define BOX_INTERSECTION_INDEX ### // always 0 @@ -17,13 +18,57 @@ #endif #endif -vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] +struct Box { + vec3 p0; + vec3 p1; +}; + +Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) { - vec3 o = ray.pos; - vec3 d = ray.dir; + // Find the min/max cornerpoints of the voxel in tile coordinates + vec3 tileOrigin = vec3(octreeCoords.xyz); + vec3 numSamples = vec3(u_dimensions); + vec3 voxelSize = 1.0 / numSamples; + vec3 coordP0 = floor(tileUv * numSamples) * voxelSize + tileOrigin; + vec3 coordP1 = coordP0 + voxelSize; + + // Transform to the UV coordinates of the scaled tileset + float tileSize = 1.0 / pow(2.0, float(octreeCoords.w)); + vec3 p0 = convertShapeUvToUvSpace(coordP0 * tileSize); + vec3 p1 = convertShapeUvToUvSpace(coordP1 * tileSize); + + return Box(p0, p1); +} + +// Find the distances along a ray at which the ray intersects an axis-aligned box +// See https://tavianator.com/2011/ray_box.html +vec2 intersectBox(in Ray ray, in Box box, in vec2 entryExit) +{ + // Consider the box as the intersection of the space between 3 pairs of parallel planes + // Compute the distance along the ray to each plane + vec3 dInv = 1.0 / ray.dir; // TODO: Input this + vec3 t0 = (box.p0 - ray.pos) * dInv; + vec3 t1 = (box.p1 - ray.pos) * dInv; - vec3 dInv = 1.0 / d; - vec3 od = -o * dInv; + // Identify candidate entries/exits based on distance from ray.pos + vec3 entries = max(min(t0, t1), entryExit.x); + vec3 exits = min(max(t0, t1), entryExit.y); + + // The actual box intersection points are the furthest entry and the closest exit + float entry = max(max(entries.x, entries.y), entries.z); + float exit = min(min(exits.x, exits.y), exits.z); + + if (entry >= exit) { + return vec2(NO_HIT); + } + + return vec2(entry, exit); +} + +vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] +{ + vec3 dInv = 1.0 / ray.dir; // TODO: input this + vec3 od = -ray.pos * dInv; vec3 t0 = od - dInv; vec3 t1 = od + dInv; vec3 m0 = min(t0, t1); diff --git a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl index 145f8013386..3a6c731d9dd 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl @@ -11,7 +11,7 @@ uniform sampler2D u_clippingPlanesTexture; uniform mat4 u_clippingPlanesMatrix; // Plane is in Hessian Normal Form -vec2 intersectPlane(Ray ray, vec4 plane) { +vec2 intersectPlane(in Ray ray, in vec4 plane) { vec3 o = ray.pos; vec3 d = ray.dir; vec3 n = plane.xyz; // normal @@ -28,7 +28,7 @@ vec2 intersectPlane(Ray ray, vec4 plane) { } } -void intersectClippingPlanes(Ray ray, inout Intersections ix) { +void intersectClippingPlanes(in Ray ray, inout Intersections ix) { #if (CLIPPING_PLANES_COUNT == 1) // Union and intersection are the same when there's one clipping plane, and the code // is more simplified. diff --git a/packages/engine/Source/Shaders/Voxels/IntersectDepth.glsl b/packages/engine/Source/Shaders/Voxels/IntersectDepth.glsl index 24a27229032..2f910a2cef1 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectDepth.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectDepth.glsl @@ -7,7 +7,7 @@ uniform mat4 u_transformPositionViewToUv; -void intersectDepth(vec2 screenCoord, Ray ray, inout Intersections ix) { +void intersectDepth(in vec2 screenCoord, in Ray ray, inout Intersections ix) { float logDepthOrDepth = czm_unpackDepth(texture(czm_globeDepthTexture, screenCoord)); if (logDepthOrDepth != 0.0) { // Calculate how far the ray must travel before it hits the depth buffer. diff --git a/packages/engine/Source/Shaders/Voxels/Intersection.glsl b/packages/engine/Source/Shaders/Voxels/Intersection.glsl index b41c6a2c79a..54601d9fa13 100644 --- a/packages/engine/Source/Shaders/Voxels/Intersection.glsl +++ b/packages/engine/Source/Shaders/Voxels/Intersection.glsl @@ -11,9 +11,7 @@ #define INTERSECTION_COUNT ### */ -vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) { - Ray ray = Ray(positionUv, directionUv); - +vec2 intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) { // Do a ray-shape intersection to find the exact starting and ending points. intersectShape(ray, ix); diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 01451ece19d..cc0275889e2 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -28,6 +28,17 @@ float hash(vec2 p) } #endif +float getStepSize(in ivec4 octreeCoords, in vec3 tileUv, in Ray viewRay, in vec2 entryExit) { +#if defined(SHAPE_BOX) + Box voxelBox = constructVoxelBox(octreeCoords, tileUv); + vec2 voxelIntersection = intersectBox(viewRay, voxelBox, entryExit); + return (voxelIntersection.y - voxelIntersection.x); +#else + float dimAtLevel = pow(2.0, float(octreeCoords.w)); + return u_stepSize / dimAtLevel; +#endif +} + void main() { vec4 fragCoord = gl_FragCoord; @@ -36,16 +47,17 @@ void main() vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case vec3 viewPosUv = u_cameraPositionUv; + Ray viewRayUv = Ray(viewPosUv, viewDirUv); Intersections ix; - vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix); + vec2 entryExitT = intersectScene(screenCoord, viewRayUv, ix); // Exit early if the scene was completely missed. if (entryExitT.x == NO_HIT) { discard; } - float currT = entryExitT.x; + float currT = entryExitT.x + 0.00001; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; // TODO: is it possible for this to be out of bounds, and does it matter? @@ -55,8 +67,7 @@ void main() TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - float stepT = u_stepSize / dimAtLevel; + float stepT = getStepSize(traversalData.octreeCoords, sampleDatas[0].tileUv, viewRayUv, entryExitT); // TODO: // - jitter doesn't affect the first traversal? @@ -110,7 +121,8 @@ void main() // Shape is infinitely thin, no need to traverse further // TODO: this doesn't happen? // Even if the shape is thin, won't we have currT > endT? (see below) - break; + //break; + stepT == 0.00001; } // Keep raymarching @@ -137,9 +149,9 @@ void main() // Traverse the tree from the current ray position. // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); - dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w)); - stepT = u_stepSize / dimAtLevel; + //traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); + traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); + stepT = getStepSize(traversalData.octreeCoords, sampleDatas[0].tileUv, viewRayUv, entryExitT); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] diff --git a/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl b/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl index f31a00722aa..5983b1ba770 100644 --- a/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/convertUvToBox.glsl @@ -8,9 +8,17 @@ #endif vec3 convertUvToShapeUvSpace(in vec3 positionUv) { - #if defined(BOX_HAS_SHAPE_BOUNDS) - return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate; - #else - return positionUv; - #endif +#if defined(BOX_HAS_SHAPE_BOUNDS) + return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate; +#else + return positionUv; +#endif +} + +vec3 convertShapeUvToUvSpace(in vec3 shapeUv) { +#if defined(BOX_HAS_SHAPE_BOUNDS) + return (shapeUv - u_boxUvToShapeUvTranslate) / u_boxUvToShapeUvScale; +#else + return shapeUv; +#endif } From c8cea948190bec7e535e23dad5be290ceb842fc1 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 23 Jan 2023 10:40:36 -0500 Subject: [PATCH 378/679] Fix typo in CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 20eb49176f3..8c05516cd6a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ - CesiumJS now defaults to using a WebGL2 context for rendering. WebGL2 is widely supported on all platforms and this results in better feature support across devices, especially mobile. - WebGL1 is supported. If WebGL2 is not available, CesiumJS will automatically fall back to WebGL1. - - In order to work in a WebGL2 context, any custom materials, custom primitive or custom shaders will need to be upgraded to use GLSL 300. + - In order to work in a WebGL2 context, any custom materials, custom primitives or custom shaders will need to be upgraded to use GLSL 300. - Otherwise to request a WebGL 1 context, set `requestWebgl1` to `true` when providing `ContextOptions` as shown below: ```js const viewer = new Viewer("cesiumContainer", { From 05fb024f63e889a1014edb230ca77ec6e7dc56c2 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Mon, 23 Jan 2023 11:29:39 -0500 Subject: [PATCH 379/679] pickPosition -> globe.pick --- Apps/Sandcastle/gallery/Drawing on Terrain.html | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index ed942d46dc0..57e21acb0f6 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -59,10 +59,6 @@ } })(); - if (!viewer.scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK ); @@ -105,9 +101,10 @@ let floatingPoint; const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); handler.setInputAction(function (event) { - // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that + // We use `viewer.scene.globe.pick here instead of `viewer.camera.pickEllipsoid` so that // we get the correct point when mousing over terrain. - const earthPosition = viewer.scene.pickPosition(event.position); + const ray = viewer.camera.getPickRay(event.position); + const earthPosition = viewer.scene.globe.pick(ray, viewer.scene); // `earthPosition` will be undefined if our mouse is not over the globe. if (Cesium.defined(earthPosition)) { if (activeShapePoints.length === 0) { @@ -128,7 +125,8 @@ handler.setInputAction(function (event) { if (Cesium.defined(floatingPoint)) { - const newPosition = viewer.scene.pickPosition(event.endPosition); + const ray = viewer.camera.getPickRay(event.endPosition); + const newPosition = viewer.scene.globe.pick(ray, viewer.scene); if (Cesium.defined(newPosition)) { floatingPoint.position.setValue(newPosition); activeShapePoints.pop(); From 377cfdf6782c17a54d9d55a55ce1b4df5779c844 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Mon, 23 Jan 2023 13:07:15 -0500 Subject: [PATCH 380/679] Fix IS3 sandcastle --- Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html | 2 +- .../engine/Source/Core/ArcGISTiledElevationTerrainProvider.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index c57fa51a12e..67740dbba17 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -57,7 +57,7 @@

Loading...

// height systems (Cesium World Terrain). // If this is not specified, or the URL is invalid no geoid conversion will be applied. // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider( + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" ); diff --git a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js index d64225da9f2..deae10fc148 100644 --- a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js +++ b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js @@ -233,7 +233,7 @@ async function requestMetadata( * }); * viewer.terrainProvider = terrainProvider; * - * @see TerrainProvider + * @see TerrainProvider */ function ArcGISTiledElevationTerrainProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); From 422b8e01c509f0cfe6409017159dcd81b4f2daef Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Mon, 23 Jan 2023 13:46:45 -0500 Subject: [PATCH 381/679] Fix whitespace in widgets README --- packages/widgets/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/README.md b/packages/widgets/README.md index 841d3f4c265..673616faa37 100644 --- a/packages/widgets/README.md +++ b/packages/widgets/README.md @@ -8,7 +8,7 @@ [CesiumJS](../../README.md) is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin. It uses WebGL for hardware-accelerated graphics, and is cross-platform, cross-browser, and tuned for dynamic-data visualization. -`@cesium/widgets` is a widgets library for use with CesiumJS— including the `CesiumViewer` widget plus widgets for common tasks such as animation, base layer selection and geocoding. +`@cesium/widgets` is a widgets library for use with CesiumJS—including the `CesiumViewer` widget plus widgets for common tasks such as animation, base layer selection and geocoding. --- From b2f9e22f9bc6013a5c0d41d476c659fd7b98d01d Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Mon, 23 Jan 2023 14:06:41 -0500 Subject: [PATCH 382/679] README tweaks --- README.md | 2 -- packages/engine/README.md | 2 +- packages/widgets/README.md | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ee086274652..b0059190d52 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,6 @@ import "cesium/Build/Cesium/Widgets/widgets.css"; const viewer = new Viewer("cesiumContainer"); ``` -#### Packages - In addition to the `cesium` package, CesiumJS is also [distributed as scoped npm packages for better dependency management](https://cesium.com/blog/2022/12/07/modular-structure-in-cesiumjs/): - [`@cesium/engine`](./packages/engine/README.md) - CesiumJS's core, rendering, and data APIs diff --git a/packages/engine/README.md b/packages/engine/README.md index 7d1afc2b6ee..62cfe4254bd 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -51,6 +51,6 @@ Have questions? Ask them on the [community forum](https://community.cesium.com/) Interested in contributing? See [CONTRIBUTING.md](../../CONTRIBUTING.md). :heart: -### License +## License [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). CesiumJS is free for both commercial and non-commercial use. diff --git a/packages/widgets/README.md b/packages/widgets/README.md index 841d3f4c265..229a9e53037 100644 --- a/packages/widgets/README.md +++ b/packages/widgets/README.md @@ -51,6 +51,6 @@ Have questions? Ask them on the [community forum](https://community.cesium.com/) Interested in contributing? See [CONTRIBUTING.md](../../CONTRIBUTING.md). :heart: -### License +## License [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). CesiumJS is free for both commercial and non-commercial use. From 76b1392c6f6f231969b71ed304f085c339f6b883 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 24 Jan 2023 14:28:44 -0500 Subject: [PATCH 383/679] Fix voxel step size when reading parent texture --- .../engine/Source/Shaders/Voxels/Octree.glsl | 62 +++++++++---------- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 14 ++--- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/Octree.glsl b/packages/engine/Source/Shaders/Voxels/Octree.glsl index 388feb95ed2..1c9baf51133 100644 --- a/packages/engine/Source/Shaders/Voxels/Octree.glsl +++ b/packages/engine/Source/Shaders/Voxels/Octree.glsl @@ -24,7 +24,7 @@ struct TraversalData { struct SampleData { int megatextureIndex; - bool usingParentMegatextureIndex; + ivec4 tileCoords; vec3 tileUv; #if (SAMPLE_COUNT > 1) float weight; @@ -81,40 +81,40 @@ vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) { return shapePosition * dimAtLevel - vec3(octreeCoords.xyz); } -void setSampleUv(in vec3 shapePosition, in ivec4 octreeCoords, inout SampleData sampleData) { - ivec4 sampleCoords = sampleData.usingParentMegatextureIndex +void getOctreeLeafSampleData(in OctreeNodeData data, in ivec4 octreeCoords, out SampleData sampleData) { + sampleData.megatextureIndex = data.data; + sampleData.tileCoords = (data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT) ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1) : octreeCoords; - sampleData.tileUv = getTileUv(shapePosition, sampleCoords); -} - -void getOctreeLeafSampleData(in OctreeNodeData data, out SampleData sampleData) { - sampleData.megatextureIndex = data.data; - sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT; } #if (SAMPLE_COUNT > 1) -void getOctreeLeafSampleDatas(in OctreeNodeData data, out SampleData sampleData0, out SampleData sampleData1) { +void getOctreeLeafSampleDatas(in OctreeNodeData data, in ivec4 octreeCoords, out SampleData sampleDatas[SAMPLE_COUNT]) { int leafIndex = data.data; int leafNodeTexelCount = 2; // Adding 0.5 moves to the center of the texel float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5; float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5; + // Get an interpolation weight and a flag to determine whether to read the parent texture vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY); - vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); vec4 leafData0 = texture(u_octreeLeafNodeTexture, leafUv0); - vec4 leafData1 = texture(u_octreeLeafNodeTexture, leafUv1); - float lerp = normU8x2_toFloat(leafData0.xy); - - sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy); - sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw); + sampleDatas[0].weight = 1.0 - lerp; + sampleDatas[1].weight = lerp; // TODO: this looks wrong? Should be comparing to OCTREE_FLAG_PACKED_LEAF_FROM_PARENT - sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1; - sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1; - sampleData0.weight = 1.0 - lerp; - sampleData1.weight = lerp; + sampleDatas[0].tileCoords = (normU8_toInt(leafData0.z) == 1) + ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1) + : octreeCoords; + sampleDatas[1].tileCoords = (normU8_toInt(leafData0.w) == 1) + ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1) + : octreeCoords; + + // Get megatexture indices for both samples + vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY); + vec4 leafData1 = texture(u_octreeLeafNodeTexture, leafUv1); + sampleDatas[0].megatextureIndex = normU8x2_toInt(leafData1.xy); + sampleDatas[1].megatextureIndex = normU8x2_toInt(leafData1.zw); } #endif @@ -143,12 +143,12 @@ void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversa } else { // leaf tile - stop traversing #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(childData, sampleDatas[0]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); + getOctreeLeafSampleData(childData, traversalData.octreeCoords, sampleDatas[0]); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); #else - getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]); + getOctreeLeafSampleDatas(childData, traversalData.octreeCoords, sampleDatas); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); #endif return; } @@ -167,12 +167,12 @@ void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traver if (rootData.flag == OCTREE_FLAG_LEAF) { // No child data, only the root tile has data #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(rootData, sampleDatas[0]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); + getOctreeLeafSampleData(rootData, traversalData.octreeCoords, sampleDatas[0]); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); #else - getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]); - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]); + getOctreeLeafSampleDatas(rootData, traversalData.octreeCoords, sampleDatas); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); #endif } else { traverseOctreeDownwards(shapePosition, traversalData, sampleDatas); @@ -193,7 +193,7 @@ bool insideTile(in vec3 shapePosition, in ivec4 octreeCoords) { void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) { if (insideTile(shapePosition, traversalData.octreeCoords)) { for (int i = 0; i < SAMPLE_COUNT; i++) { - setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[i]); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); } return; } diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index cc0275889e2..441e18318a3 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -28,13 +28,13 @@ float hash(vec2 p) } #endif -float getStepSize(in ivec4 octreeCoords, in vec3 tileUv, in Ray viewRay, in vec2 entryExit) { +float getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { #if defined(SHAPE_BOX) - Box voxelBox = constructVoxelBox(octreeCoords, tileUv); + Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); vec2 voxelIntersection = intersectBox(viewRay, voxelBox, entryExit); return (voxelIntersection.y - voxelIntersection.x); #else - float dimAtLevel = pow(2.0, float(octreeCoords.w)); + float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); return u_stepSize / dimAtLevel; #endif } @@ -67,7 +67,7 @@ void main() TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - float stepT = getStepSize(traversalData.octreeCoords, sampleDatas[0].tileUv, viewRayUv, entryExitT); + float stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); // TODO: // - jitter doesn't affect the first traversal? @@ -149,9 +149,9 @@ void main() // Traverse the tree from the current ray position. // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); - //traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); - traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - stepT = getStepSize(traversalData.octreeCoords, sampleDatas[0].tileUv, viewRayUv, entryExitT); + traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); + //traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); + stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From abd4f1cdec3e165a1b50f1c0f74e564263b06c61 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Tue, 24 Jan 2023 17:48:23 -0500 Subject: [PATCH 384/679] Voxels: precompute inverse ray, clean up traversal code --- .../engine/Source/Scene/VoxelTraversal.js | 50 ++++--------- .../Source/Shaders/Voxels/IntersectBox.glsl | 13 ++-- .../Shaders/Voxels/IntersectionUtils.glsl | 3 + .../engine/Source/Shaders/Voxels/Octree.glsl | 71 ++++++++++--------- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 10 ++- 5 files changed, 68 insertions(+), 79 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelTraversal.js b/packages/engine/Source/Scene/VoxelTraversal.js index 97d81bef733..f337ba8d2d6 100644 --- a/packages/engine/Source/Scene/VoxelTraversal.js +++ b/packages/engine/Source/Scene/VoxelTraversal.js @@ -93,25 +93,12 @@ function VoxelTraversal( this._frameNumber = 0; const shape = primitive._shape; - const rootLevel = 0; - const rootX = 0; - const rootY = 0; - const rootZ = 0; - const rootParent = undefined; /** * @type {SpatialNode} * @readonly */ - this.rootNode = new SpatialNode( - rootLevel, - rootX, - rootY, - rootZ, - rootParent, - shape, - dimensions - ); + this.rootNode = new SpatialNode(0, 0, 0, 0, undefined, shape, dimensions); /** * @type {DoubleEndedPriorityQueue} @@ -425,12 +412,6 @@ function requestData(that, keyframeNode) { const primitive = that._primitive; const provider = primitive._provider; - const keyframe = keyframeNode.keyframe; - const spatialNode = keyframeNode.spatialNode; - const tileLevel = spatialNode.level; - const tileX = spatialNode.x; - const tileY = spatialNode.y; - const tileZ = spatialNode.z; function postRequestSuccess(result) { that._simultaneousRequestCount--; @@ -469,11 +450,12 @@ function requestData(that, keyframeNode) { keyframeNode.state = KeyframeNode.LoadState.FAILED; } + const { keyframe, spatialNode } = keyframeNode; const promise = provider.requestData({ - tileLevel: tileLevel, - tileX: tileX, - tileY: tileY, - tileZ: tileZ, + tileLevel: spatialNode.level, + tileX: spatialNode.x, + tileY: spatialNode.y, + tileZ: spatialNode.z, keyframe: keyframe, }); @@ -510,18 +492,17 @@ function loadAndUnload(that, frameState) { const frameNumber = that._frameNumber; const primitive = that._primitive; const shape = primitive._shape; - const voxelDimensions = primitive._provider.dimensions; - const targetScreenSpaceError = primitive._screenSpaceError; + const { dimensions } = primitive; + const targetScreenSpaceError = primitive.screenSpaceError; const priorityQueue = that._priorityQueue; const keyframeLocation = that._keyframeLocation; const keyframeCount = that._keyframeCount; const rootNode = that.rootNode; - const cameraPosition = frameState.camera.positionWC; - const screenSpaceErrorDenominator = frameState.camera.frustum.sseDenominator; - const screenHeight = - frameState.context.drawingBufferHeight / frameState.pixelRatio; - const screenSpaceErrorMultiplier = screenHeight / screenSpaceErrorDenominator; + const { camera, context, pixelRatio } = frameState; + const { positionWC, frustum } = camera; + const screenHeight = context.drawingBufferHeight / pixelRatio; + const screenSpaceErrorMultiplier = screenHeight / frustum.sseDenominator; /** * @ignore @@ -529,10 +510,7 @@ function loadAndUnload(that, frameState) { * @param {Number} visibilityPlaneMask */ function addToQueueRecursive(spatialNode, visibilityPlaneMask) { - spatialNode.computeScreenSpaceError( - cameraPosition, - screenSpaceErrorMultiplier - ); + spatialNode.computeScreenSpaceError(positionWC, screenSpaceErrorMultiplier); visibilityPlaneMask = spatialNode.visibility( frameState, @@ -622,7 +600,7 @@ function loadAndUnload(that, frameState) { z, spatialNode, shape, - voxelDimensions + dimensions ); }); } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index b8192d4d641..dab42c42cb1 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -46,9 +46,8 @@ vec2 intersectBox(in Ray ray, in Box box, in vec2 entryExit) { // Consider the box as the intersection of the space between 3 pairs of parallel planes // Compute the distance along the ray to each plane - vec3 dInv = 1.0 / ray.dir; // TODO: Input this - vec3 t0 = (box.p0 - ray.pos) * dInv; - vec3 t1 = (box.p1 - ray.pos) * dInv; + vec3 t0 = (box.p0 - ray.pos) * ray.dInv; + vec3 t1 = (box.p1 - ray.pos) * ray.dInv; // Identify candidate entries/exits based on distance from ray.pos vec3 entries = max(min(t0, t1), entryExit.x); @@ -65,9 +64,9 @@ vec2 intersectBox(in Ray ray, in Box box, in vec2 entryExit) return vec2(entry, exit); } -vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] +vec2 intersectUnitCube(in Ray ray) // Unit cube from [-1, +1] { - vec3 dInv = 1.0 / ray.dir; // TODO: input this + vec3 dInv = 1.0 / ray.dir; vec3 od = -ray.pos * dInv; vec3 t0 = od - dInv; vec3 t1 = od + dInv; @@ -83,7 +82,7 @@ vec2 intersectUnitCube(Ray ray) // Unit cube from [-1, +1] return vec2(tMin, tMax); } -vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] +vec2 intersectUnitSquare(in Ray ray) // Unit square from [-1, +1] { vec3 o = ray.pos; vec3 d = ray.dir; @@ -97,7 +96,7 @@ vec2 intersectUnitSquare(Ray ray) // Unit square from [-1, +1] return vec2(t, t); } -void intersectShape(Ray ray, inout Intersections ix) +void intersectShape(in Ray ray, inout Intersections ix) { #if defined(BOX_HAS_RENDER_BOUNDS) #if defined(BOX_IS_2D) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 2ce4010dddb..dbc9a9cc488 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -8,6 +8,9 @@ struct Ray { vec3 pos; vec3 dir; +#if defined(SHAPE_BOX) + vec3 dInv; +#endif }; struct Intersections { diff --git a/packages/engine/Source/Shaders/Voxels/Octree.glsl b/packages/engine/Source/Shaders/Voxels/Octree.glsl index 1c9baf51133..40a4ae86730 100644 --- a/packages/engine/Source/Shaders/Voxels/Octree.glsl +++ b/packages/engine/Source/Shaders/Voxels/Octree.glsl @@ -8,9 +8,11 @@ uniform sampler2D u_octreeInternalNodeTexture; uniform vec2 u_octreeInternalNodeTexelSizeUv; uniform int u_octreeInternalNodeTilesPerRow; +#if (SAMPLE_COUNT > 1) uniform sampler2D u_octreeLeafNodeTexture; uniform vec2 u_octreeLeafNodeTexelSizeUv; uniform int u_octreeLeafNodeTilesPerRow; +#endif struct OctreeNodeData { int data; @@ -118,10 +120,11 @@ void getOctreeLeafSampleDatas(in OctreeNodeData data, in ivec4 octreeCoords, out } #endif -void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) { +OctreeNodeData traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData) { float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w)); vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel; vec3 end = start + vec3(sizeAtLevel); + OctreeNodeData childData; for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { // Find out which octree child contains the position @@ -129,30 +132,24 @@ void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversa vec3 center = 0.5 * (start + end); vec3 childCoord = step(center, shapePosition); - OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); - // Get octree coords for the next level down ivec4 octreeCoords = traversalData.octreeCoords; traversalData.octreeCoords = ivec4(octreeCoords.xyz * 2 + ivec3(childCoord), octreeCoords.w + 1); - if (childData.flag == OCTREE_FLAG_INTERNAL) { - // interior tile - keep going deeper - start = mix(start, center, childCoord); - end = mix(center, end, childCoord); - traversalData.parentOctreeIndex = childData.data; - } else { + childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord)); + + if (childData.flag != OCTREE_FLAG_INTERNAL) { // leaf tile - stop traversing - #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(childData, traversalData.octreeCoords, sampleDatas[0]); - sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); - #else - getOctreeLeafSampleDatas(childData, traversalData.octreeCoords, sampleDatas); - sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); - sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); - #endif - return; + break; } + + // interior tile - keep going deeper + start = mix(start, center, childCoord); + end = mix(center, end, childCoord); + traversalData.parentOctreeIndex = childData.data; } + + return childData; } /** @@ -163,20 +160,19 @@ void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traver traversalData.octreeCoords = ivec4(0); traversalData.parentOctreeIndex = 0; - OctreeNodeData rootData = getOctreeNodeData(vec2(0.0)); - if (rootData.flag == OCTREE_FLAG_LEAF) { - // No child data, only the root tile has data - #if (SAMPLE_COUNT == 1) - getOctreeLeafSampleData(rootData, traversalData.octreeCoords, sampleDatas[0]); - sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); - #else - getOctreeLeafSampleDatas(rootData, traversalData.octreeCoords, sampleDatas); - sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); - sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); - #endif - } else { - traverseOctreeDownwards(shapePosition, traversalData, sampleDatas); + OctreeNodeData nodeData = getOctreeNodeData(vec2(0.0)); + if (nodeData.flag != OCTREE_FLAG_LEAF) { + nodeData = traverseOctreeDownwards(shapePosition, traversalData); } + + #if (SAMPLE_COUNT == 1) + getOctreeLeafSampleData(nodeData, traversalData.octreeCoords, sampleDatas[0]); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + #else + getOctreeLeafSampleDatas(nodeData, traversalData.octreeCoords, sampleDatas); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); + #endif } bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) { @@ -198,7 +194,7 @@ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData trave return; } - // Go up tree + // Go up tree until we find a parent tile containing shapePosition for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) { traversalData.octreeCoords.xyz /= 2; traversalData.octreeCoords.w -= 1; @@ -211,5 +207,14 @@ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData trave } // Go down tree - traverseOctreeDownwards(shapePosition, traversalData, sampleDatas); + OctreeNodeData nodeData = traverseOctreeDownwards(shapePosition, traversalData); + + #if (SAMPLE_COUNT == 1) + getOctreeLeafSampleData(nodeData, traversalData.octreeCoords, sampleDatas[0]); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + #else + getOctreeLeafSampleDatas(nodeData, traversalData.octreeCoords, sampleDatas); + sampleDatas[0].tileUv = getTileUv(shapePosition, sampleDatas[0].tileCoords); + sampleDatas[1].tileUv = getTileUv(shapePosition, sampleDatas[1].tileCoords); + #endif } diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 441e18318a3..7ca6fadfb34 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -47,7 +47,12 @@ void main() vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case vec3 viewPosUv = u_cameraPositionUv; - Ray viewRayUv = Ray(viewPosUv, viewDirUv); + #if defined(SHAPE_BOX) + vec3 dInv = 1.0 / viewDirUv; + Ray viewRayUv = Ray(viewPosUv, viewDirUv, dInv); + #else + Ray viewRayUv = Ray(viewPosUv, viewDirUv); + #endif Intersections ix; vec2 entryExitT = intersectScene(screenCoord, viewRayUv, ix); @@ -147,10 +152,9 @@ void main() } // Traverse the tree from the current ray position. - // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step. + // This is similar to traverseOctreeFromBeginning but is faster when the ray is in the same tile as the previous step. positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); - //traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); } From a4cc5259eccd324cc6b4da66e1deb815785a3caa Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 24 Jan 2023 18:12:38 -0500 Subject: [PATCH 385/679] Apply root tile scale to tileset geometric error --- CHANGES.md | 1 + packages/engine/Source/Scene/Cesium3DTile.js | 10 ++++++-- .../engine/Source/Scene/Cesium3DTileset.js | 7 +++++- .../engine/Specs/Scene/Cesium3DTileSpec.js | 23 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5242f7b26ed..0a21096a2ff 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,6 +28,7 @@ - Fixed an edge case in `viewer.flyTo` when flying to a imagery layer with certain terrain providers. [#10937](https://github.com/CesiumGS/cesium/issues/10937) - Fixed a crash in terrain sampling if any points have an indefined position due to being outside the rectangle. [#10931](https://github.com/CesiumGS/cesium/pull/10931) - Fixed label background rendering. [#11040](https://github.com/CesiumGS/cesium/issues/11040) +- Fixed a bug where scale was not being applied to the top-level tileset geometric error. [#11047](https://github.com/CesiumGS/cesium/pull/11047) ### 1.101 - 2023-01-02 diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index e82df6f0faa..4495909c941 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -146,7 +146,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { if (!defined(this._geometricError)) { this._geometricError = defined(parent) - ? parent.geometricError + ? parent._geometricError : tileset._geometricError; Cesium3DTile._deprecationWarning( "geometricErrorUndefined", @@ -874,7 +874,7 @@ Cesium3DTile.prototype.getScreenSpaceError = function ( const heightFraction = defaultValue(progressiveResolutionHeightFraction, 1.0); const parentGeometricError = defined(this.parent) ? this.parent.geometricError - : tileset._geometricError; + : tileset._scaledGeometricError; const geometricError = useParentGeometricError ? parentGeometricError : this.geometricError; @@ -1791,6 +1791,12 @@ Cesium3DTile.prototype.updateGeometricErrorScale = function () { const scale = Matrix4.getScale(this.computedTransform, scratchScale); const uniformScale = Cartesian3.maximumComponent(scale); this.geometricError = this._geometricError * uniformScale; + + if (!defined(this.parent)) { + // Update the tileset's geometric error + const tileset = this._tileset; + tileset._scaledGeometricError = tileset._geometricError * uniformScale; + } }; function applyDebugSettings(tile, tileset, frameState, passOptions) { diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index d3f8209d05c..1c2a9327103 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -167,6 +167,7 @@ function Cesium3DTileset(options) { this._asset = undefined; // Metadata for the entire tileset this._properties = undefined; // Metadata for per-model/point/etc properties this._geometricError = undefined; // Geometric error when the tree is not rendered at all + this._scaledGeometricError = undefined; // Geometric error scaled by root tile scale this._extensionsUsed = undefined; this._extensions = undefined; this._modelUpAxis = undefined; @@ -1007,6 +1008,11 @@ function Cesium3DTileset(options) { return; } + // Set these before loading the tileset since _geometricError + // and _scaledGeometricError get accessed during tile creation + that._geometricError = tilesetJson.geometricError; + that._scaledGeometricError = tilesetJson.geometricError; + that._root = that.loadTileset(resource, tilesetJson); // Handle legacy gltfUpAxis option @@ -1019,7 +1025,6 @@ function Cesium3DTileset(options) { const asset = tilesetJson.asset; that._asset = asset; that._properties = tilesetJson.properties; - that._geometricError = tilesetJson.geometricError; that._extensionsUsed = tilesetJson.extensionsUsed; that._extensions = tilesetJson.extensions; that._modelUpAxis = modelUpAxis; diff --git a/packages/engine/Specs/Scene/Cesium3DTileSpec.js b/packages/engine/Specs/Scene/Cesium3DTileSpec.js index fd71214cf0c..f94cc124f13 100644 --- a/packages/engine/Specs/Scene/Cesium3DTileSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTileSpec.js @@ -123,6 +123,7 @@ describe( debugShowViewerRequestVolume: true, modelMatrix: Matrix4.IDENTITY, _geometricError: 2, + _scaledGeometricError: 2, _heatmap: new Cesium3DTilesetHeatmap(), }; @@ -672,6 +673,28 @@ describe( expect(tile2._priority).toBeGreaterThanOrEqual(foveatedDeferralPenalty); tile2._priorityDeferred = false; }); + + it("tile transform scales geometric error", function () { + const header = clone(tileWithContentBoundingSphere, true); + header.transform = Matrix4.pack( + Matrix4.fromUniformScale(2.0), + new Array(16) + ); + + const mockTilesetScaled = clone(mockTileset, true); + + const tile = new Cesium3DTile( + mockTilesetScaled, + "/some_url", + header, + undefined + ); + + expect(tile._geometricError).toBe(1); + expect(tile.geometricError).toBe(2); + expect(mockTilesetScaled._geometricError).toBe(2); + expect(mockTilesetScaled._scaledGeometricError).toBe(4); + }); }, "WebGL" ); From e61474b66120ca3594ac088ba549a76b5556c939 Mon Sep 17 00:00:00 2001 From: Lakshmi0710 <119604911+Lakshmi0710@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:18:52 +0530 Subject: [PATCH 386/679] Provide Hyperlink to Bing Maps ToU instead of Bing Maps top page --- packages/engine/Source/Scene/BingMapsImageryProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index 374acd1d3e2..39870e4814f 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -177,7 +177,7 @@ function BingMapsImageryProvider(options) { this._proxy = options.proxy; this._credit = new Credit( - `` + `` ); this._tilingScheme = new WebMercatorTilingScheme({ From 5beaa55d2d5367a92c8b1798f6526519703383fb Mon Sep 17 00:00:00 2001 From: Lakshmi0710 <119604911+Lakshmi0710@users.noreply.github.com> Date: Wed, 25 Jan 2023 23:30:49 +0530 Subject: [PATCH 387/679] Added my Name in Contributors List --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7226ec7a92f..80243bd7dd1 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -344,3 +344,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Marcel Wendler](https://github.com/UniquePanda) - [JiaoJianing](https://github.com/JiaoJianing) - [Southjor](https://github.com/Southjor) +- [Lakshmipriya](https://github.com/Lakshmi0710) From 1db357c4db0e99d744c0a2d679ec0a1e7cfea269 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 25 Jan 2023 16:24:44 -0500 Subject: [PATCH 388/679] Adjust starting bias for voxel ray --- packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 7ca6fadfb34..7f0211053b5 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -62,7 +62,7 @@ void main() discard; } - float currT = entryExitT.x + 0.00001; + float currT = entryExitT.x + 0.0001; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; // TODO: is it possible for this to be out of bounds, and does it matter? From 33e32da2ddb29e9e7c09e3bc08ebd9204c323ed8 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 26 Jan 2023 16:33:52 -0500 Subject: [PATCH 389/679] Cleanup specs --- .../Source/Core/VRTheWorldTerrainProvider.js | 12 +- ...ArcGISTiledElevationTerrainProviderSpec.js | 274 +++---- .../Specs/Core/CesiumTerrainProviderSpec.js | 669 ++++++------------ .../Core/GoogleEarthEnterpriseMetadataSpec.js | 64 +- ...oogleEarthEnterpriseTerrainProviderSpec.js | 202 +++--- .../Core/VRTheWorldTerrainProviderSpec.js | 163 ++--- 6 files changed, 529 insertions(+), 855 deletions(-) diff --git a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js index cf5c59be0f5..b8801ac0f18 100644 --- a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js +++ b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js @@ -110,10 +110,12 @@ function metadataSuccess(terrainProviderBuilder, xml) { } function metadataFailure(resource, error, provider) { - const message = defaultValue( - defined(error) ? error.message : undefined, - `An error occurred while accessing ${resource.url}.` - ); + let message = `An error occurred while accessing ${resource.url}`; + + if (defined(error) && defined(error.message)) { + message = `${message}: ${error.message}`; + } + TileProviderError.reportError( undefined, provider, @@ -121,7 +123,7 @@ function metadataFailure(resource, error, provider) { message ); - throw error; + throw new RuntimeError(message); } async function requestMetadata(terrainProviderBuilder, resource, provider) { diff --git a/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js b/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js index 5dd53d1f84f..6b22bcf7965 100644 --- a/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js @@ -11,8 +11,6 @@ import { Math as CesiumMath, } from "../../index.js"; -import pollToPromise from "../../../../Specs/pollToPromise.js"; - describe("Core/ArcGISTiledElevationTerrainProvider", function () { const lercTileUrl = "Data/Images/Red16x16.png"; let availability; @@ -270,68 +268,52 @@ describe("Core/ArcGISTiledElevationTerrainProvider", function () { }); }); - it("has error event", function () { - const provider = new ArcGISTiledElevationTerrainProvider({ - url: "made/up/url", - }); + it("has error event", async function () { + const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( + "made/up/url" + ); expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); - - return provider.readyPromise; }); - it("returns reasonable geometric error for various levels", function () { - const provider = new ArcGISTiledElevationTerrainProvider({ - url: "made/up/url", - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); - }); + it("returns reasonable geometric error for various levels", async function () { + const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( + "made/up/url" + ); + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); }); - it("logo is undefined if credit is not provided", function () { + it("logo is undefined if credit is not provided", async function () { delete metadata.copyrightText; - const provider = new ArcGISTiledElevationTerrainProvider({ - url: "made/up/url", - }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeUndefined(); - }); + const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( + "made/up/url" + ); + expect(provider.credit).toBeUndefined(); }); - it("logo is defined if credit is provided", function () { - const provider = new ArcGISTiledElevationTerrainProvider({ - url: "made/up/url", - credit: "thanks to our awesome made up contributors!", - }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeDefined(); - }); + it("logo is defined if credit is provided", async function () { + const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( + "made/up/url", + { + credit: "thanks to our awesome made up contributors!", + } + ); + expect(provider.credit).toBeDefined(); }); - it("does not have a water mask", function () { - const provider = new ArcGISTiledElevationTerrainProvider({ - url: "made/up/url", - }); + it("does not have a water mask", async function () { + const provider = await ArcGISTiledElevationTerrainProvider.fromUrl( + "made/up/url" + ); expect(provider.hasWaterMask).toBe(false); - return provider.readyPromise.catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); }); it("is not ready immediately", function () { @@ -344,126 +326,88 @@ describe("Core/ArcGISTiledElevationTerrainProvider", function () { }); }); - it("detects WebMercator tiling scheme", function () { + it("detects WebMercator tiling scheme", async function () { const baseUrl = "made/up/url"; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.tilingScheme).toBeInstanceOf( - WebMercatorTilingScheme - ); - }); + expect(terrainProvider.tilingScheme).toBeInstanceOf( + WebMercatorTilingScheme + ); }); - it("detects Geographic tiling scheme", function () { + it("detects Geographic tiling scheme", async function () { const baseUrl = "made/up/url"; - metadata.spatialReference.latestWkid = 4326; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.tilingScheme).toBeInstanceOf( - GeographicTilingScheme - ); - }); + expect(terrainProvider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); }); - it("raises an error if the SRS is not supported", function () { + it("fromUrl throws if the SRS is not supported", async function () { const baseUrl = "made/up/url"; - metadata.spatialReference.latestWkid = 1234; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); - - return terrainProvider.readyPromise.then(fail).catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); + await expectAsync( + ArcGISTiledElevationTerrainProvider.fromUrl(baseUrl) + ).toBeRejectedWithError(RuntimeError, "Invalid spatial reference"); }); - it("raises an error if tileInfo missing", function () { + it("fromUrl throws if tileInfo missing", async function () { const baseUrl = "made/up/url"; - delete metadata.tileInfo; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); - - return terrainProvider.readyPromise.then(fail).catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); + await expectAsync( + ArcGISTiledElevationTerrainProvider.fromUrl(baseUrl) + ).toBeRejectedWithError(RuntimeError, "tileInfo is required"); }); - it("checks availability if TileMap capability exists", function () { + it("checks availability if TileMap capability exists", async function () { const baseUrl = "made/up/url"; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider._hasAvailability).toBe(true); - expect(terrainProvider._tilesAvailable).toBeDefined(); - expect(terrainProvider._tilesAvailabilityLoaded).toBeDefined(); - }); + expect(terrainProvider._hasAvailability).toBe(true); + expect(terrainProvider._tilesAvailable).toBeDefined(); + expect(terrainProvider._tilesAvailabilityLoaded).toBeDefined(); }); - it("does not check availability if TileMap capability is missing", function () { + it("does not check availability if TileMap capability is missing", async function () { const baseUrl = "made/up/url"; - metadata.capabilities = "Image,Mensuration"; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider._hasAvailability).toBe(false); - expect(terrainProvider._tilesAvailable).toBeUndefined(); - expect(terrainProvider._tilesAvailablityLoaded).toBeUndefined(); - }); + expect(terrainProvider._hasAvailability).toBe(false); + expect(terrainProvider._tilesAvailable).toBeUndefined(); + expect(terrainProvider._tilesAvailablityLoaded).toBeUndefined(); }); describe("requestTileGeometry", function () { - it("provides HeightmapTerrainData", function () { + it("provides HeightmapTerrainData", async function () { const baseUrl = "made/up/url"; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); - - return pollToPromise(function () { - return terrainProvider.ready; - }) - .then(function () { - const promise = terrainProvider.requestTileGeometry(0, 0, 0); - RequestScheduler.update(); - return promise; - }) - .then(function (loadedData) { - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); + + const promise = terrainProvider.requestTileGeometry(0, 0, 0); + RequestScheduler.update(); + const loadedData = await promise; + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); }); - it("returns undefined if too many requests are already in progress", function () { + it("returns undefined if too many requests are already in progress", async function () { const baseUrl = "made/up/url"; - const deferreds = []; Resource._Implementations.createImage = function ( @@ -475,39 +419,35 @@ describe("Core/ArcGISTiledElevationTerrainProvider", function () { deferreds.push(deferred); }; - const terrainProvider = new ArcGISTiledElevationTerrainProvider({ - url: baseUrl, - }); - - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - let promise; - let i; - // Make one less request to account for the additional availability request. - for (i = 0; i < RequestScheduler.maximumRequestsPerServer - 1; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promise = terrainProvider.requestTileGeometry(0, 0, 0, request); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); - - promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); - expect(promise).toBeUndefined(); - - for (i = 0; i < deferreds.length; ++i) { - deferreds[i].resolve(); - } - - return Promise.all( - deferreds.map(function (deferred) { - return deferred.promise; - }) - ); - }); + const terrainProvider = await ArcGISTiledElevationTerrainProvider.fromUrl( + baseUrl + ); + + let promise; + let i; + // Make one less request to account for the additional availability request. + for (i = 0; i < RequestScheduler.maximumRequestsPerServer - 1; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider.requestTileGeometry(0, 0, 0, request); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); + + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); + + for (i = 0; i < deferreds.length; ++i) { + deferreds[i].resolve(); + } + + await Promise.all( + deferreds.map(function (deferred) { + return deferred.promise; + }) + ); }); }); }); diff --git a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js index f7559617a8f..28a533b5412 100644 --- a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js @@ -10,9 +10,9 @@ import { Request, RequestScheduler, Resource, + RuntimeError, TerrainProvider, } from "../../index.js"; -import pollToPromise from "../../../../Specs/pollToPromise.js"; describe("Core/CesiumTerrainProvider", function () { beforeEach(function () { @@ -238,348 +238,196 @@ describe("Core/CesiumTerrainProvider", function () { }); }); - it("uses geographic tiling scheme by default", function () { + it("uses geographic tiling scheme by default", async function () { returnHeightmapTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - }); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); }); - it("can use a custom ellipsoid", function () { + it("can use a custom ellipsoid", async function () { returnHeightmapTileJson(); const ellipsoid = new Ellipsoid(1, 2, 3); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", + const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { ellipsoid: ellipsoid, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); - }); + expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); - it("has error event", function () { - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.errorEvent).toBeDefined(); - expect(provider.errorEvent).toBe(provider.errorEvent); - }); + it("has error event", async function () { + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); + expect(provider.errorEvent).toBeDefined(); + expect(provider.errorEvent).toBe(provider.errorEvent); }); - it("returns reasonable geometric error for various levels", function () { + it("returns reasonable geometric error for various levels", async function () { returnQuantizedMeshTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return provider.readyPromise.then(function () { - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); - }); + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); }); - it("credit is undefined if credit option is not provided", function () { + it("credit is undefined if credit option is not provided", async function () { returnHeightmapTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeUndefined(); - }); + expect(provider.credit).toBeUndefined(); }); - it("credit is defined if credit option is provided", function () { + it("credit is defined if credit option is provided", async function () { returnHeightmapTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", + const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { credit: "thanks to our awesome made up contributors!", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeDefined(); - }); + expect(provider.credit).toBeDefined(); }); - it("has a water mask", function () { + it("has a water mask", async function () { returnHeightmapTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.hasWaterMask).toBe(true); - }); + expect(provider.hasWaterMask).toBe(true); }); - it("has vertex normals", function () { + it("has vertex normals", async function () { returnOctVertexNormalTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", + const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { requestVertexNormals: true, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.requestVertexNormals).toBe(true); - expect(provider.hasVertexNormals).toBe(true); - }); + expect(provider.requestVertexNormals).toBe(true); + expect(provider.hasVertexNormals).toBe(true); }); - it("does not request vertex normals", function () { + it("does not request vertex normals", async function () { returnOctVertexNormalTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", + const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { requestVertexNormals: false, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.requestVertexNormals).toBe(false); - expect(provider.hasVertexNormals).toBe(false); - }); + expect(provider.requestVertexNormals).toBe(false); + expect(provider.hasVertexNormals).toBe(false); }); - it("requests parent layer.json", function () { + it("requests parent layer.json", async function () { returnParentUrlTileJson(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", + const provider = await CesiumTerrainProvider.fromUrl("made/up/url", { requestVertexNormals: true, requestWaterMask: true, }); - return provider.readyPromise.then(function () { - expect(provider._tileCredits[0].html).toBe( - "This is a child tileset! This amazing data is courtesy The Amazing Data Source!" - ); - expect(provider.requestVertexNormals).toBe(true); - expect(provider.requestWaterMask).toBe(true); - expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them - expect(provider.hasWaterMask).toBe(true); // The child tileset has them - expect(provider.availability.isTileAvailable(1, 2, 1)).toBe(true); // Both have this - expect(provider.availability.isTileAvailable(1, 3, 1)).toBe(true); // Parent has this, but child doesn't - expect(provider.availability.isTileAvailable(2, 0, 0)).toBe(false); // Neither has this - - const layers = provider._layers; - expect(layers.length).toBe(2); - expect(layers[0].hasVertexNormals).toBe(false); - expect(layers[0].hasWaterMask).toBe(true); - expect(layers[0].availability.isTileAvailable(1, 2, 1)).toBe(true); - expect(layers[0].availability.isTileAvailable(1, 3, 1)).toBe(false); - expect(layers[0].availability.isTileAvailable(2, 0, 0)).toBe(false); - expect(layers[1].hasVertexNormals).toBe(false); - expect(layers[1].hasWaterMask).toBe(false); - expect(layers[1].availability.isTileAvailable(1, 2, 1)).toBe(true); - expect(layers[1].availability.isTileAvailable(1, 3, 1)).toBe(true); - expect(layers[1].availability.isTileAvailable(2, 0, 0)).toBe(false); - }); - }); - - it("raises an error if layer.json does not specify a format", function () { - returnTileJson("Data/CesiumTerrainTileJson/NoFormat.tile.json"); - - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - let errorListenerCalled = false; - const errorMatcher = function (event) { - expect(event.message).toContain("format is not specified"); - errorListenerCalled = true; - provider.errorEvent.removeEventListener(errorMatcher); - }; - - provider.errorEvent.addEventListener(errorMatcher); - - return provider.readyPromise.then(fail).catch((e) => { - expect(errorListenerCalled).toBe(true); - expect(e.message).toContain( - "The tile format is not specified in the layer.json file." - ); - }); + expect(provider._tileCredits[0].html).toBe( + "This is a child tileset! This amazing data is courtesy The Amazing Data Source!" + ); + expect(provider.requestVertexNormals).toBe(true); + expect(provider.requestWaterMask).toBe(true); + expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them + expect(provider.hasWaterMask).toBe(true); // The child tileset has them + expect(provider.availability.isTileAvailable(1, 2, 1)).toBe(true); // Both have this + expect(provider.availability.isTileAvailable(1, 3, 1)).toBe(true); // Parent has this, but child doesn't + expect(provider.availability.isTileAvailable(2, 0, 0)).toBe(false); // Neither has this + + const layers = provider._layers; + expect(layers.length).toBe(2); + expect(layers[0].hasVertexNormals).toBe(false); + expect(layers[0].hasWaterMask).toBe(true); + expect(layers[0].availability.isTileAvailable(1, 2, 1)).toBe(true); + expect(layers[0].availability.isTileAvailable(1, 3, 1)).toBe(false); + expect(layers[0].availability.isTileAvailable(2, 0, 0)).toBe(false); + expect(layers[1].hasVertexNormals).toBe(false); + expect(layers[1].hasWaterMask).toBe(false); + expect(layers[1].availability.isTileAvailable(1, 2, 1)).toBe(true); + expect(layers[1].availability.isTileAvailable(1, 3, 1)).toBe(true); + expect(layers[1].availability.isTileAvailable(2, 0, 0)).toBe(false); }); - it("raises an error if layer.json specifies an unknown format", function () { + it("fromUrl throws if layer.json specifies an unknown format", async function () { returnTileJson("Data/CesiumTerrainTileJson/InvalidFormat.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - let errorListenerCalled = false; - const errorMatcher = function (event) { - expect(event.message).toContain("invalid or not supported"); - errorListenerCalled = true; - provider.errorEvent.removeEventListener(errorMatcher); - }; - - provider.errorEvent.addEventListener(errorMatcher); - - return provider.readyPromise.then(fail).catch((e) => { - expect(errorListenerCalled).toBe(true); - expect(e.message).toContain( - 'The tile format "awesometron-9000.0" is invalid or not supported.' - ); - }); + await expectAsync( + CesiumTerrainProvider.fromUrl("made/up/url") + ).toBeRejectedWithError( + RuntimeError, + 'The tile format "awesometron-9000.0" is invalid or not supported.' + ); }); - it("raises an error if layer.json does not specify quantized-mesh 1.x format", function () { + it("fromUrl throws if layer.json does not specify quantized-mesh 1.x format", async function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh2.0.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - let errorListenerCalled = false; - const errorMatcher = function (event) { - expect(event.message).toContain("invalid or not supported"); - errorListenerCalled = true; - provider.errorEvent.removeEventListener(errorMatcher); - }; - - provider.errorEvent.addEventListener(errorMatcher); - - return provider.readyPromise.then(fail).catch((e) => { - expect(errorListenerCalled).toBe(true); - expect(e.message).toContain( - 'The tile format "quantized-mesh-2.0" is invalid or not supported.' - ); - }); + await expectAsync( + CesiumTerrainProvider.fromUrl("made/up/url") + ).toBeRejectedWithError( + RuntimeError, + 'The tile format "quantized-mesh-2.0" is invalid or not supported.' + ); }); - it("supports quantized-mesh1.x minor versions", function () { + it("fromUrl supports quantized-mesh1.x minor versions", async function () { returnTileJson("Data/CesiumTerrainTileJson/QuantizedMesh1.1.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - const errorListener = jasmine.createSpy("error"); - provider.errorEvent.addEventListener(errorListener); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(errorListener).not.toHaveBeenCalled(); - }); + await expectAsync( + CesiumTerrainProvider.fromUrl("made/up/url") + ).toBeResolved(); }); - it("raises an error if layer.json does not specify a tiles property", function () { + it("fromUrl throws if layer.json does not specify a tiles property", async function () { returnTileJson("Data/CesiumTerrainTileJson/NoTiles.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - let errorListenerCalled = false; - const errorMatcher = function (event) { - expect(event.message).toContain( - "does not specify any tile URL templates" - ); - errorListenerCalled = true; - provider.errorEvent.removeEventListener(errorMatcher); - }; - - provider.errorEvent.addEventListener(errorMatcher); - - return provider.readyPromise.then(fail).catch((e) => { - expect(errorListenerCalled).toBe(true); - expect(e.message).toContain( - "The layer.json file does not specify any tile URL templates." - ); - }); + await expectAsync( + CesiumTerrainProvider.fromUrl("made/up/url") + ).toBeRejectedWithError( + RuntimeError, + "The layer.json file does not specify any tile URL templates." + ); }); - it("raises an error if layer.json tiles property is an empty array", function () { + it("fromUrl throws if layer.json tiles property is an empty array", async function () { returnTileJson("Data/CesiumTerrainTileJson/EmptyTilesArray.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); - - let errorListenerCalled = false; - const errorMatcher = function (event) { - expect(event.message).toContain( - "does not specify any tile URL templates" - ); - errorListenerCalled = true; - provider.errorEvent.removeEventListener(errorMatcher); - }; - - provider.errorEvent.addEventListener(errorMatcher); - - return provider.readyPromise.then(fail).catch((e) => { - expect(errorListenerCalled).toBe(true); - expect(e.message).toContain( - "The layer.json file does not specify any tile URL templates." - ); - }); + await expectAsync( + CesiumTerrainProvider.fromUrl("made/up/url") + ).toBeRejectedWithError( + RuntimeError, + "The layer.json file does not specify any tile URL templates." + ); }); - it("uses attribution specified in layer.json", function () { + it("fromUrl uses attribution specified in layer.json", async function () { returnTileJson("Data/CesiumTerrainTileJson/WithAttribution.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider._tileCredits[0].html).toBe( - "This amazing data is courtesy The Amazing Data Source!" - ); - }); + expect(provider._tileCredits[0].html).toBe( + "This amazing data is courtesy The Amazing Data Source!" + ); }); - it("do not add blank attribution if layer.json does not have one", function () { + it("formUrl does not add blank attribution if layer.json does not have one", async function () { returnTileJson("Data/CesiumTerrainTileJson/WaterMask.tile.json"); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider._tileCredit).toBeUndefined(); - }); + expect(provider._tileCredit).toBeUndefined(); }); it("The undefined availability tile is returned at level 0", function () { @@ -651,82 +499,80 @@ describe("Core/CesiumTerrainProvider", function () { }); describe("requestTileGeometry", function () { - it("uses multiple urls specified in layer.json", function () { + it("uses multiple urls specified in layer.json", async function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); + const provider = await CesiumTerrainProvider.fromUrl("made/up/url"); + spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - const provider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + try { + await provider.requestTileGeometry(0, 0, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo0.com"); + } - spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); + try { + await provider.requestTileGeometry(1, 0, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo1.com"); + } - return provider.readyPromise - .then(function () { - return provider.requestTileGeometry(0, 0, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo0.com"); - return provider.requestTileGeometry(1, 0, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo1.com"); - return provider.requestTileGeometry(1, -1, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo2.com"); - return provider.requestTileGeometry(1, 0, 1); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo3.com"); - }); + try { + await provider.requestTileGeometry(1, -1, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo2.com"); + } + + try { + await provider.requestTileGeometry(1, 0, 1); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo3.com"); + } }); - it("supports scheme-less template URLs in layer.json resolved with absolute URL", function () { + it("supports scheme-less template URLs in layer.json resolved with absolute URL", async function () { returnTileJson("Data/CesiumTerrainTileJson/MultipleUrls.tile.json"); - const url = getAbsoluteUri("Data/CesiumTerrainTileJson"); - - const provider = new CesiumTerrainProvider({ - url: url, - }); + const provider = await CesiumTerrainProvider.fromUrl(url); spyOn(Resource._Implementations, "loadWithXhr").and.callThrough(); - return provider.readyPromise - .then(function () { - return provider.requestTileGeometry(0, 0, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo0.com"); - return provider.requestTileGeometry(1, 0, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo1.com"); - return provider.requestTileGeometry(1, -1, 0); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo2.com"); - return provider.requestTileGeometry(1, 0, 1); - }) - .catch(function () { - expect( - Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] - ).toContain("foo3.com"); - }); + try { + await provider.requestTileGeometry(0, 0, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo0.com"); + } + try { + await provider.requestTileGeometry(1, 0, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo1.com"); + } + + try { + await provider.requestTileGeometry(1, -1, 0); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo2.com"); + } + try { + await provider.requestTileGeometry(1, 0, 1); + } catch (e) { + expect( + Resource._Implementations.loadWithXhr.calls.mostRecent().args[0] + ).toContain("foo3.com"); + } }); it("provides HeightmapTerrainData", function () { @@ -1008,7 +854,7 @@ describe("Core/CesiumTerrainProvider", function () { }); }); - it("provides QuantizedMeshTerrainData with Metadata availability", function () { + it("provides QuantizedMeshTerrainData with Metadata availability", async function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -1030,37 +876,22 @@ describe("Core/CesiumTerrainProvider", function () { returnMetadataAvailabilityTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url" + ); - return pollToPromise(function () { - return terrainProvider.ready; - }) - .then(function () { - expect(terrainProvider.hasMetadata).toBe(true); - expect(terrainProvider._layers[0].availabilityLevels).toBe(10); - expect(terrainProvider.availability.isTileAvailable(0, 0, 0)).toBe( - true - ); - expect(terrainProvider.availability.isTileAvailable(0, 1, 0)).toBe( - true - ); - expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( - false - ); - - return terrainProvider.requestTileGeometry(0, 0, 0); - }) - .then(function (loadedData) { - expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); - expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe( - true - ); - }); + expect(terrainProvider.hasMetadata).toBe(true); + expect(terrainProvider._layers[0].availabilityLevels).toBe(10); + expect(terrainProvider.availability.isTileAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.availability.isTileAvailable(0, 1, 0)).toBe(true); + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(false); + + const loadedData = await terrainProvider.requestTileGeometry(0, 0, 0); + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true); }); - it("returns undefined if too many requests are already in progress", function () { + it("returns undefined if too many requests are already in progress", async function () { const baseUrl = "made/up/url"; const deferreds = []; @@ -1080,40 +911,33 @@ describe("Core/CesiumTerrainProvider", function () { returnHeightmapTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: baseUrl, - }); - - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - let promise; - let i; - for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, + const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); + let promise; + let i; + for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider + .requestTileGeometry(0, 0, 0, request) + .then(fail) + .catch((e) => { + expect(e.message).toContain("Mesh buffer doesn't exist."); }); - promise = terrainProvider - .requestTileGeometry(0, 0, 0, request) - .then(fail) - .catch((e) => { - expect(e.message).toContain("Mesh buffer doesn't exist."); - }); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); - promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); - expect(promise).toBeUndefined(); + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); - for (i = 0; i < deferreds.length; ++i) { - deferreds[i].resolve(); - } - }); + for (i = 0; i < deferreds.length; ++i) { + deferreds[i].resolve(); + } }); - it("supports getTileDataAvailable()", function () { + it("supports getTileDataAvailable()", async function () { const baseUrl = "made/up/url"; Resource._Implementations.loadWithXhr = function ( @@ -1137,36 +961,24 @@ describe("Core/CesiumTerrainProvider", function () { returnQuantizedMeshTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); - }); + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); }); - it("getTileDataAvailable() converts xyz to tms", function () { + it("getTileDataAvailable() converts xyz to tms", async function () { const baseUrl = "made/up/url"; returnPartialAvailabilityTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: baseUrl, - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl(baseUrl); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.getTileDataAvailable(1, 3, 2)).toBe(true); - expect(terrainProvider.getTileDataAvailable(1, 0, 2)).toBe(false); - }); + expect(terrainProvider.getTileDataAvailable(1, 3, 2)).toBe(true); + expect(terrainProvider.getTileDataAvailable(1, 0, 2)).toBe(false); }); - it("getTileDataAvailable() with Metadata availability", function () { + it("getTileDataAvailable() with Metadata availability", async function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -1188,22 +1000,15 @@ describe("Core/CesiumTerrainProvider", function () { returnMetadataAvailabilityTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url" + ); - return pollToPromise(function () { - return terrainProvider.ready; - }) - .then(function () { - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBeUndefined(); - - return terrainProvider.requestTileGeometry(0, 0, 0); - }) - .then(function () { - expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBe(true); - }); + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBeUndefined(); + + await terrainProvider.requestTileGeometry(0, 0, 0); + expect(terrainProvider.getTileDataAvailable(0, 0, 1)).toBe(true); }); it("supports a query string in the base URL", function () { @@ -1234,26 +1039,24 @@ describe("Core/CesiumTerrainProvider", function () { }); }); - it("Uses query parameter extensions for ion resource", function () { - const terrainProvider = new CesiumTerrainProvider({ - url: IonResource.fromAssetId(1), - requestVertexNormals: true, - requestWaterMask: true, - }); + it("Uses query parameter extensions for ion resource", async function () { + const terrainProvider = await CesiumTerrainProvider.fromUrl( + IonResource.fromAssetId(1), + { + requestVertexNormals: true, + requestWaterMask: true, + } + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - const getDerivedResource = spyOn( - IonResource.prototype, - "getDerivedResource" - ).and.callThrough(); - terrainProvider.requestTileGeometry(0, 0, 0); - const options = getDerivedResource.calls.argsFor(0)[0]; - expect(options.queryParameters.extensions).toEqual( - "octvertexnormals-watermask-metadata" - ); - }); + const getDerivedResource = spyOn( + IonResource.prototype, + "getDerivedResource" + ).and.callThrough(); + await terrainProvider.requestTileGeometry(0, 0, 0); + const options = getDerivedResource.calls.argsFor(0)[0]; + expect(options.queryParameters.extensions).toEqual( + "octvertexnormals-watermask-metadata" + ); }); }); }); diff --git a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js index f1e723b7ce4..2af772c023b 100644 --- a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js +++ b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js @@ -108,7 +108,7 @@ describe("Core/GoogleEarthEnterpriseMetadata", function () { }).toThrowError(RuntimeError); }); - it("populateSubtree", function () { + it("populateSubtree", async function () { const quad = "0123"; let index = 0; spyOn( @@ -127,45 +127,35 @@ describe("Core/GoogleEarthEnterpriseMetadata", function () { return Promise.resolve(); }); - const metadata = new GoogleEarthEnterpriseMetadata({ - url: "http://test.server", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl( + "http://test.server" + ); const request = new Request({ throttle: true, }); - return metadata.readyPromise - .then(function () { - const tileXY = GoogleEarthEnterpriseMetadata.quadKeyToTileXY(quad); - return metadata.populateSubtree( - tileXY.x, - tileXY.y, - tileXY.level, - request - ); - }) - .then(function () { - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket.calls.count() - ).toEqual(4); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("", 1); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("0", 1, request); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("01", 1, request); - expect( - GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket - ).toHaveBeenCalledWith("012", 1, request); - - const tileInfo = metadata._tileInfo; - expect(tileInfo["0"]).toBeDefined(); - expect(tileInfo["01"]).toBeDefined(); - expect(tileInfo["012"]).toBeDefined(); - expect(tileInfo["0123"]).toBeDefined(); - }); + const tileXY = GoogleEarthEnterpriseMetadata.quadKeyToTileXY(quad); + await metadata.populateSubtree(tileXY.x, tileXY.y, tileXY.level, request); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket.calls.count() + ).toEqual(4); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("", 1); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("0", 1, request); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("01", 1, request); + expect( + GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket + ).toHaveBeenCalledWith("012", 1, request); + + const tileInfo = metadata._tileInfo; + expect(tileInfo["0"]).toBeDefined(); + expect(tileInfo["01"]).toBeDefined(); + expect(tileInfo["012"]).toBeDefined(); + expect(tileInfo["0123"]).toBeDefined(); }); it("resolves readyPromise", function () { diff --git a/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js b/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js index 3b2efb4ebd6..3f54ac70eeb 100644 --- a/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/GoogleEarthEnterpriseTerrainProviderSpec.js @@ -45,16 +45,13 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { let terrainProvider; - function waitForTile(level, x, y, f) { - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); - + async function waitForTile(level, x, y, f) { + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); return pollToPromise(function () { - return ( - terrainProvider.ready && - terrainProvider.getTileDataAvailable(x, y, level) - ); + return terrainProvider.getTileDataAvailable(x, y, level); }).then(function () { const promise = terrainProvider.requestTileGeometry(level, x, y); @@ -136,56 +133,50 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { }); }); - it("uses geographic tiling scheme by default", function () { + it("uses geographic tiling scheme by default", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.tilingScheme).toBeInstanceOf( - GeographicTilingScheme - ); - }); + expect(terrainProvider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); }); - it("can use a custom ellipsoid", function () { + it("can use a custom ellipsoid", async function () { installMockGetQuadTreePacket(); const ellipsoid = new Ellipsoid(1, 2, 3); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - ellipsoid: ellipsoid, - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata, + { + ellipsoid: ellipsoid, + } + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.tilingScheme.ellipsoid).toEqual(ellipsoid); - }); + expect(terrainProvider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); - it("has error event", function () { - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + it("has error event", async function () { + installMockGetQuadTreePacket(); + + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); expect(terrainProvider.errorEvent).toBeDefined(); expect(terrainProvider.errorEvent).toBe(terrainProvider.errorEvent); - - return terrainProvider.readyPromise.catch(function (e) { - expect(terrainProvider.ready).toBe(false); - }); }); - it("returns reasonable geometric error for various levels", function () { + it("returns reasonable geometric error for various levels", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); expect(terrainProvider.getLevelMaximumGeometricError(0)).toBeGreaterThan( 0.0 @@ -198,8 +189,6 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { terrainProvider.getLevelMaximumGeometricError(2) * 2.0, CesiumMath.EPSILON10 ); - - return terrainProvider.readyPromise; }); it("readyPromise rejects if there isn't terrain", function () { @@ -224,61 +213,51 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { }); }); - it("logo is undefined if credit is not provided", function () { + it("credit is undefined if credit is not provided", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.credit).toBeUndefined(); - }); + expect(terrainProvider.credit).toBeUndefined(); }); - it("logo is defined if credit is provided", function () { + it("logo is defined if credit is provided", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - credit: "thanks to our awesome made up contributors!", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata, + { + credit: "thanks to our awesome made up contributors!", + } + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.credit).toBeDefined(); - }); + expect(terrainProvider.credit).toBeDefined(); }); - it("has a water mask is false", function () { + it("has a water mask is false", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.hasWaterMask).toBe(false); - }); + expect(terrainProvider.hasWaterMask).toBe(false); }); - it("has vertex normals is false", function () { + it("has vertex normals is false", async function () { installMockGetQuadTreePacket(); - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: "made/up/url", - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl("made/up/url"); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - expect(terrainProvider.hasVertexNormals).toBe(false); - }); + expect(terrainProvider.hasVertexNormals).toBe(false); }); describe("requestTileGeometry", function () { @@ -345,7 +324,7 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { expect(loadedData).toBeInstanceOf(GoogleEarthEnterpriseTerrainData); }); - it("returns undefined if too many requests are already in progress", function () { + it("returns undefined if too many requests are already in progress", async function () { installMockGetQuadTreePacket(); const baseUrl = "made/up/url"; @@ -379,23 +358,19 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { deferreds.push(deferred); }; - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: baseUrl, - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(baseUrl); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); const promises = []; return pollToPromise(function () { - return terrainProvider.ready; + let b = true; + for (let i = 0; i < 10; ++i) { + b = b && terrainProvider.getTileDataAvailable(i, i, i); + } + return b && terrainProvider.getTileDataAvailable(1, 2, 3); }) - .then(function () { - return pollToPromise(function () { - let b = true; - for (let i = 0; i < 10; ++i) { - b = b && terrainProvider.getTileDataAvailable(i, i, i); - } - return b && terrainProvider.getTileDataAvailable(1, 2, 3); - }); - }) .then(function () { let promise; for (let i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { @@ -428,7 +403,7 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { }); }); - it("supports getTileDataAvailable()", function () { + it("supports getTileDataAvailable()", async function () { installMockGetQuadTreePacket(); const baseUrl = "made/up/url"; @@ -451,26 +426,23 @@ describe("Core/GoogleEarthEnterpriseTerrainProvider", function () { ); }; - terrainProvider = new GoogleEarthEnterpriseTerrainProvider({ - url: baseUrl, - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(baseUrl); + terrainProvider = GoogleEarthEnterpriseTerrainProvider.fromMetadata( + metadata + ); - return pollToPromise(function () { - return terrainProvider.ready; - }).then(function () { - const tileInfo = terrainProvider._metadata._tileInfo; - const info = - tileInfo[GoogleEarthEnterpriseMetadata.tileXYToQuadKey(0, 1, 0)]; - info._bits = 0x7f; // Remove terrain bit from 0,1,0 tile - info.terrainState = 1; // NONE - info.ancestorHasTerrain = true; - - expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 1, 0)).toBe(false); - expect(terrainProvider.getTileDataAvailable(1, 0, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(1, 1, 0)).toBe(true); - expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); - }); + const tileInfo = terrainProvider._metadata._tileInfo; + const info = + tileInfo[GoogleEarthEnterpriseMetadata.tileXYToQuadKey(0, 1, 0)]; + info._bits = 0x7f; // Remove terrain bit from 0,1,0 tile + info.terrainState = 1; // NONE + info.ancestorHasTerrain = true; + + expect(terrainProvider.getTileDataAvailable(0, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 1, 0)).toBe(false); + expect(terrainProvider.getTileDataAvailable(1, 0, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(1, 1, 0)).toBe(true); + expect(terrainProvider.getTileDataAvailable(0, 0, 2)).toBe(false); }); }); }); diff --git a/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js b/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js index 90f849cc409..e9b4b1dc261 100644 --- a/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/VRTheWorldTerrainProviderSpec.js @@ -5,6 +5,7 @@ import { Request, RequestScheduler, Resource, + RuntimeError, TerrainProvider, VRTheWorldTerrainProvider, } from "../../index.js"; @@ -141,63 +142,48 @@ describe("Core/VRTheWorldTerrainProvider", function () { }); }); - it("has error event", function () { + it("has error event", async function () { patchXHRLoad(); - const provider = new VRTheWorldTerrainProvider({ - url: "made/up/url", - }); + const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); expect(provider.errorEvent).toBeDefined(); expect(provider.errorEvent).toBe(provider.errorEvent); - return provider.readyPromise; }); - it("returns reasonable geometric error for various levels", function () { + it("returns reasonable geometric error for various levels", async function () { patchXHRLoad(); - const provider = new VRTheWorldTerrainProvider({ - url: "made/up/url", - }); + const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); - return provider.readyPromise.then(function () { - expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); - expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(1) * 2.0, - CesiumMath.EPSILON10 - ); - expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( - provider.getLevelMaximumGeometricError(2) * 2.0, - CesiumMath.EPSILON10 - ); - }); + expect(provider.getLevelMaximumGeometricError(0)).toBeGreaterThan(0.0); + expect(provider.getLevelMaximumGeometricError(0)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(1) * 2.0, + CesiumMath.EPSILON10 + ); + expect(provider.getLevelMaximumGeometricError(1)).toEqualEpsilon( + provider.getLevelMaximumGeometricError(2) * 2.0, + CesiumMath.EPSILON10 + ); }); - it("credit is undefined if credit option is not provided", function () { + it("credit is undefined if credit option is not provided", async function () { patchXHRLoad(); - const provider = new VRTheWorldTerrainProvider({ - url: "made/up/url", - }); + const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); expect(provider.credit).toBeUndefined(); - return provider.readyPromise; }); - it("credit is defined if credit optoin is provided", function () { + it("credit is defined if credit option is provided", async function () { patchXHRLoad(); - const provider = new VRTheWorldTerrainProvider({ - url: "made/up/url", + const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url", { credit: "thanks to our awesome made up contributors!", }); expect(provider.credit).toBeDefined(); - return provider.readyPromise; }); - it("does not have a water mask", function () { + it("does not have a water mask", async function () { patchXHRLoad(); - const provider = new VRTheWorldTerrainProvider({ - url: "made/up/url", - }); + const provider = await VRTheWorldTerrainProvider.fromUrl("made/up/url"); expect(provider.hasWaterMask).toBe(false); - return provider.readyPromise; }); it("is not ready immediately", function () { @@ -209,7 +195,7 @@ describe("Core/VRTheWorldTerrainProvider", function () { return provider.readyPromise; }); - it("raises an error if the SRS is not supported", function () { + it("fromUrl throws if the SRS is not supported", async function () { patchXHRLoad(); Resource._Implementations.loadWithXhr = function ( url, @@ -247,24 +233,16 @@ describe("Core/VRTheWorldTerrainProvider", function () { }, 1); }; - const terrainProvider = new VRTheWorldTerrainProvider({ - url: "made/up/url", - }); - - let called = false; - const errorFunction = function () { - called = true; - }; - - terrainProvider.errorEvent.addEventListener(errorFunction); - - return terrainProvider.readyPromise.then(fail).catch(() => { - expect(called).toBe(true); - }); + await expectAsync( + VRTheWorldTerrainProvider.fromUrl("made/up/url") + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing made/up/url: SRS EPSG:foo is not supported" + ); }); describe("requestTileGeometry", function () { - it("provides HeightmapTerrainData", function () { + it("provides HeightmapTerrainData", async function () { patchXHRLoad(); const baseUrl = "made/up/url"; @@ -286,23 +264,16 @@ describe("Core/VRTheWorldTerrainProvider", function () { ); }; - const terrainProvider = new VRTheWorldTerrainProvider({ - url: baseUrl, - }); - - return terrainProvider.readyPromise - .then(function () { - expect(terrainProvider.tilingScheme).toBeInstanceOf( - GeographicTilingScheme - ); - return terrainProvider.requestTileGeometry(0, 0, 0); - }) - .then(function (loadedData) { - expect(loadedData).toBeInstanceOf(HeightmapTerrainData); - }); + const terrainProvider = await VRTheWorldTerrainProvider.fromUrl(baseUrl); + + expect(terrainProvider.tilingScheme).toBeInstanceOf( + GeographicTilingScheme + ); + const loadedData = await terrainProvider.requestTileGeometry(0, 0, 0); + expect(loadedData).toBeInstanceOf(HeightmapTerrainData); }); - it("returns undefined if too many requests are already in progress", function () { + it("returns undefined if too many requests are already in progress", async function () { patchXHRLoad(); const baseUrl = "made/up/url"; @@ -317,39 +288,35 @@ describe("Core/VRTheWorldTerrainProvider", function () { deferreds.push(deferred); }; - const terrainProvider = new VRTheWorldTerrainProvider({ - url: baseUrl, - }); - - return terrainProvider.readyPromise.then(function () { - const promises = []; - let promise; - let i; - for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { - const request = new Request({ - throttle: true, - throttleByServer: true, - }); - promise = terrainProvider.requestTileGeometry(0, 0, 0, request); - promises.push(promise); - } - RequestScheduler.update(); - expect(promise).toBeDefined(); - - promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); - expect(promise).toBeUndefined(); - - for (i = 0; i < deferreds.length; ++i) { - const deferred = deferreds[i]; - Resource._Implementations.loadImageElement( - "Data/Images/Red16x16.png", - false, - deferred - ); - } - - return Promise.all(promises); - }); + const terrainProvider = await VRTheWorldTerrainProvider.fromUrl(baseUrl); + + const promises = []; + let promise; + let i; + for (i = 0; i < RequestScheduler.maximumRequestsPerServer; ++i) { + const request = new Request({ + throttle: true, + throttleByServer: true, + }); + promise = terrainProvider.requestTileGeometry(0, 0, 0, request); + promises.push(promise); + } + RequestScheduler.update(); + expect(promise).toBeDefined(); + + promise = terrainProvider.requestTileGeometry(0, 0, 0, createRequest()); + expect(promise).toBeUndefined(); + + for (i = 0; i < deferreds.length; ++i) { + const deferred = deferreds[i]; + Resource._Implementations.loadImageElement( + "Data/Images/Red16x16.png", + false, + deferred + ); + } + + return Promise.all(promises); }); }); }); From 0286bf29e45ee22ea114bbae4f4c29f8a070e038 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 26 Jan 2023 16:38:44 -0500 Subject: [PATCH 390/679] Tweak viewer app --- Apps/CesiumViewer/CesiumViewer.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 6a1ba82635a..3592c9000ad 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -54,13 +54,10 @@ async function main() { try { const hasBaseLayerPicker = !defined(imageryProvider); - let terrainProvider; - if (hasBaseLayerPicker) { - terrainProvider = await createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } + const terrainProvider = await createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); viewer = new Viewer("cesiumContainer", { imageryProvider: imageryProvider, From 857ab2e1f79f636849018404be5f9c16bf252002 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 26 Jan 2023 16:40:00 -0500 Subject: [PATCH 391/679] Correct merge --- .../engine/Specs/Scene/Model/ModelSpec.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/engine/Specs/Scene/Model/ModelSpec.js b/packages/engine/Specs/Scene/Model/ModelSpec.js index 94e878fcb72..180ab45ec0e 100644 --- a/packages/engine/Specs/Scene/Model/ModelSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSpec.js @@ -1314,22 +1314,22 @@ describe( const triangleFanUrl = "./Data/Models/glTF-2.0/TriangleFan/glTF/TriangleFan.gltf"; - let sceneWithWebgl2; + let sceneWithWebgl1; beforeAll(function () { - sceneWithWebgl2 = createScene({ + sceneWithWebgl1 = createScene({ contextOptions: { - requestWebgl1: false, + requestWebgl1: true, }, }); }); afterEach(function () { - sceneWithWebgl2.primitives.removeAll(); + sceneWithWebgl1.primitives.removeAll(); }); afterAll(function () { - sceneWithWebgl2.destroyForSpecs(); + sceneWithWebgl1.destroyForSpecs(); }); it("debugWireframe works for WebGL1 if enableDebugWireframe is true", function () { @@ -1338,7 +1338,7 @@ describe( return loadPromise.then(function (buffer) { return loadAndZoomToModel( { gltf: new Uint8Array(buffer), enableDebugWireframe: true }, - scene + sceneWithWebgl1 ).then(function (model) { verifyDebugWireframe(model, PrimitiveType.TRIANGLES); }); @@ -1351,12 +1351,12 @@ describe( return loadPromise.then(function (buffer) { return loadAndZoomToModel( { gltf: new Uint8Array(buffer), enableDebugWireframe: false }, - scene + sceneWithWebgl1 ).then(function (model) { const commandList = scene.frameState.commandList; const commandCounts = []; let i, command; - scene.renderForSpecs(); + sceneWithWebgl1.renderForSpecs(); for (i = 0; i < commandList.length; i++) { command = commandList[i]; expect(command.primitiveType).toBe(PrimitiveType.TRIANGLES); @@ -1366,7 +1366,7 @@ describe( model.debugWireframe = true; expect(model._drawCommandsBuilt).toBe(false); - scene.renderForSpecs(); + sceneWithWebgl1.renderForSpecs(); for (i = 0; i < commandList.length; i++) { command = commandList[i]; expect(command.primitiveType).toBe(PrimitiveType.TRIANGLES); @@ -1377,7 +1377,7 @@ describe( }); it("debugWireframe works for WebGL2", function () { - if (!sceneWithWebgl2.context.webgl2) { + if (!scene.context.webgl2) { return; } const resource = Resource.createIfNeeded(boxTexturedGlbUrl); @@ -1388,7 +1388,7 @@ describe( scene ).then(function (model) { verifyDebugWireframe(model, PrimitiveType.TRIANGLES, { - scene: sceneWithWebgl2, + scene: scene, }); }); }); From a1d8c1f32695f8a0df57d853599b104ef5d97942 Mon Sep 17 00:00:00 2001 From: Lakshmi0710 <119604911+Lakshmi0710@users.noreply.github.com> Date: Fri, 27 Jan 2023 12:19:01 +0530 Subject: [PATCH 392/679] Added an item to CHANGES.md to summarize the update --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 0a21096a2ff..c4cabeeab7b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -29,6 +29,7 @@ - Fixed a crash in terrain sampling if any points have an indefined position due to being outside the rectangle. [#10931](https://github.com/CesiumGS/cesium/pull/10931) - Fixed label background rendering. [#11040](https://github.com/CesiumGS/cesium/issues/11040) - Fixed a bug where scale was not being applied to the top-level tileset geometric error. [#11047](https://github.com/CesiumGS/cesium/pull/11047) +- Updating Bing Maps top page hyperlink to Bing Maps ToU hyperlink [#11049](https://github.com/CesiumGS/cesium/pull/11049) ### 1.101 - 2023-01-02 From 2cf7da369da23acf243ae2e6b3653790d27bf9c8 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 27 Jan 2023 13:27:47 -0500 Subject: [PATCH 393/679] Imagery provider ready promise deprecations --- CHANGES.md | 19 +- .../Scene/ArcGisMapServerImageryProvider.js | 596 +++---- .../Source/Scene/BingMapsImageryProvider.js | 488 +++--- .../GoogleEarthEnterpriseImageryProvider.js | 246 ++- .../Source/Scene/GridImageryProvider.js | 39 +- .../engine/Source/Scene/ImageryProvider.js | 38 +- .../engine/Source/Scene/IonImageryProvider.js | 378 +++-- .../Source/Scene/MapboxImageryProvider.js | 46 +- .../Scene/MapboxStyleImageryProvider.js | 47 +- .../Source/Scene/SingleTileImageryProvider.js | 222 ++- .../Scene/TileCoordinatesImageryProvider.js | 39 +- .../Scene/TileMapServiceImageryProvider.js | 257 ++- .../Scene/UrlTemplateImageryProvider.js | 228 ++- .../Scene/WebMapServiceImageryProvider.js | 45 +- .../Scene/WebMapTileServiceImageryProvider.js | 45 +- .../ArcGisMapServerImageryProviderSpec.js | 228 ++- .../Scene/BingMapsImageryProviderSpec.js | 332 ++-- ...oogleEarthEnterpriseImageryProviderSpec.js | 148 +- .../Specs/Scene/IonImageryProviderSpec.js | 286 ++-- .../Scene/SingleTileImageryProviderSpec.js | 133 +- .../TileMapServiceImageryProviderSpec.js | 870 +++++----- .../Scene/UrlTemplateImageryProviderSpec.js | 889 ++++------- .../Scene/WebMapServiceImageryProviderSpec.js | 1396 ++++++++--------- 23 files changed, 3502 insertions(+), 3513 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3a31e757a04..1cb8857d044 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,12 +11,27 @@ ##### Additions :tada: -- Added `ArcGISTiledElevationTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. ##### Deprecated :hourglass_flowing_sand: +- `ImageryProvider.ready` and `ImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `ArcGisMapServerImageryProvider` constructor parameter `url`,`ArcGisMapServerImageryProvider.ready`, and `ArcGisMapServerImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGisMapServerImageryProvider.fromUrl` instead. +- `BingMapsImageryProvider` constructor parameter `url`,`BingMapsImageryProvider.ready`, and `BingMapsImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `BingMapsImageryProvider.fromUrl` instead. +- `GridImageryProvider.ready` and `GridImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `GoogleEarthEnterpriseImageryProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseImageryProvider.ready`, and `GoogleEarthEnterpriseImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseImageryProvider.fromMetadata` instead. +- `IonImageryProvider` constructor parameter `assetId`,`BIonImageryProvider.ready`, and `IonImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `IonImageryProvider.fromAssetId` instead. +- `MapboxImageryProvider.ready` and `MapboxImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `MapboxStyleImageryProvider.ready` and `MapboxStyleImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `OpenStreetMapImageryProvider.ready` and `OpenStreetMapImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `SingleTileImageryProvider` constructor parameter `options.url`, `SingleTileImageryProvider.ready`, and `SingleTileImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `SingleTileImageryProvider.fromUrl` instead. +- `TileCoordinatesImageryProvider.ready` and `TileCoordinatesImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `TileMapServiceImageryProvider` constructor, `TileMapServiceImageryProvider.ready`, and `TileMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `TileMapServiceImageryProvider.fromUrl` instead. +- `UrlTemplateImageryProvider.reinitialize`, `UrlTemplateImageryProvider.ready`, and `UrlTemplateImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `WebMapServiceImageryProvider.ready`, and `WebMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `WebMapTileServiceImageryProvider.ready`, and `WebMapTileServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `ArcGISTiledElevationTerrainProvider `constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. +- `ArcGISTiledElevationTerrainProvider` constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. - `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `CesiumTerrainProvider.fromUrl` instead. - `CustomHeightmapTerrainProvider.ready`, and `CustomHeightmapTerrainProvider.readyPromise` were deprecated in Cesium 1.102. - `EllipsoidTerrainProvider.ready`, and `EllipsoidTerrainProvider.readyPromise` were deprecated in Cesium 1.102. diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index 3c9af4d7afc..0b52a68d790 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -1,10 +1,11 @@ import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartographic from "../Core/Cartographic.js"; +import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import GeographicProjection from "../Core/GeographicProjection.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; @@ -24,8 +25,8 @@ import ImageryProvider from "./ImageryProvider.js"; * * Initialization options for the ArcGisMapServerImageryProvider constructor * - * @property {Resource|String} url The URL of the ArcGIS MapServer service. - * @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. + * @property {Resource|String} [url] The URL of the ArcGIS MapServer service. Deprecated. + * @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. Deprecated. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. If this value is not specified, a default * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a @@ -61,14 +62,19 @@ import ImageryProvider from "./ImageryProvider.js"; */ /** + *
+ * To construct a ArcGisMapServerImageryProvider call {@link ArcGisMapServerImageryProvider.fromUrl}. Do not call the constructor directly. + *
+ * * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are * used, if available. * * @alias ArcGisMapServerImageryProvider * @constructor * - * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options Object describing initialization options + * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options * + * @see ArcGisMapServerImagery.fromUrl * @see BingMapsImageryProvider * @see GoogleEarthEnterpriseMapsProvider * @see OpenStreetMapImageryProvider @@ -78,11 +84,10 @@ import ImageryProvider from "./ImageryProvider.js"; * @see WebMapTileServiceImageryProvider * @see UrlTemplateImageryProvider * - * * @example - * const esri = new Cesium.ArcGisMapServerImageryProvider({ - * url : 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer' - * }); + * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl( + * "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" + * ); * * @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API} * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} @@ -90,12 +95,6 @@ import ImageryProvider from "./ImageryProvider.js"; function ArcGisMapServerImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - if (!defined(options.url)) { - throw new DeveloperError("options.url is required."); - } - //>>includeEnd('debug'); - /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. @@ -182,18 +181,7 @@ function ArcGisMapServerImageryProvider(options) { */ this.defaultMagnificationFilter = undefined; - const resource = Resource.createIfNeeded(options.url); - resource.appendForwardSlash(); - - if (defined(options.token)) { - resource.setQueryParameters({ - token: options.token, - }); - } - - this._resource = resource; this._tileDiscardPolicy = options.tileDiscardPolicy; - this._tileWidth = defaultValue(options.tileWidth, 256); this._tileHeight = defaultValue(options.tileHeight, 256); this._maximumLevel = options.maximumLevel; @@ -207,12 +195,7 @@ function ArcGisMapServerImageryProvider(options) { this._tilingScheme.rectangle ); this._layers = options.layers; - - let credit = options.credit; - if (typeof credit === "string") { - credit = new Credit(credit); - } - this._credit = credit; + this._credit = undefined; /** * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will @@ -228,173 +211,37 @@ function ArcGisMapServerImageryProvider(options) { this._ready = false; - // Grab the details of this MapServer. - const that = this; - let metadataError; - - function metadataSuccess(data) { - const tileInfo = data.tileInfo; - if (!defined(tileInfo)) { - that._useTiles = false; - } else { - that._tileWidth = tileInfo.rows; - that._tileHeight = tileInfo.cols; - - if ( - tileInfo.spatialReference.wkid === 102100 || - tileInfo.spatialReference.wkid === 102113 - ) { - that._tilingScheme = new WebMercatorTilingScheme({ - ellipsoid: options.ellipsoid, - }); - } else if (data.tileInfo.spatialReference.wkid === 4326) { - that._tilingScheme = new GeographicTilingScheme({ - ellipsoid: options.ellipsoid, - }); - } else { - const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message, - undefined, - undefined, - undefined - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(message)); - } - that._maximumLevel = data.tileInfo.lods.length - 1; - - if (defined(data.fullExtent)) { - if ( - defined(data.fullExtent.spatialReference) && - defined(data.fullExtent.spatialReference.wkid) - ) { - if ( - data.fullExtent.spatialReference.wkid === 102100 || - data.fullExtent.spatialReference.wkid === 102113 - ) { - const projection = new WebMercatorProjection(); - const extent = data.fullExtent; - const sw = projection.unproject( - new Cartesian3( - Math.max( - extent.xmin, - -that._tilingScheme.ellipsoid.maximumRadius * Math.PI - ), - Math.max( - extent.ymin, - -that._tilingScheme.ellipsoid.maximumRadius * Math.PI - ), - 0.0 - ) - ); - const ne = projection.unproject( - new Cartesian3( - Math.min( - extent.xmax, - that._tilingScheme.ellipsoid.maximumRadius * Math.PI - ), - Math.min( - extent.ymax, - that._tilingScheme.ellipsoid.maximumRadius * Math.PI - ), - 0.0 - ) - ); - that._rectangle = new Rectangle( - sw.longitude, - sw.latitude, - ne.longitude, - ne.latitude - ); - } else if (data.fullExtent.spatialReference.wkid === 4326) { - that._rectangle = Rectangle.fromDegrees( - data.fullExtent.xmin, - data.fullExtent.ymin, - data.fullExtent.xmax, - data.fullExtent.ymax - ); - } else { - const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - extentMessage, - undefined, - undefined, - undefined - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(extentMessage)); - } - } - } else { - that._rectangle = that._tilingScheme.rectangle; - } + if (defined(options.url)) { + deprecationWarning( + "ArcGisMapServerImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGisMapServerImageryProvider.fromUrl instead." + ); + const resource = Resource.createIfNeeded(options.url); + resource.appendForwardSlash(); - // Install the default tile discard policy if none has been supplied. - if (!defined(that._tileDiscardPolicy)) { - that._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ - missingImageUrl: buildImageResource(that, 0, 0, that._maximumLevel) - .url, - pixelsToCheck: [ - new Cartesian2(0, 0), - new Cartesian2(200, 20), - new Cartesian2(20, 200), - new Cartesian2(80, 110), - new Cartesian2(160, 130), - ], - disableCheckIfAllPixelsAreTransparent: true, - }); - } + this._tileDiscardPolicy = options.tileDiscardPolicy; - that._useTiles = true; + if (defined(options.token)) { + resource.setQueryParameters({ + token: options.token, + }); } - if (defined(data.copyrightText) && data.copyrightText.length > 0) { - that._credit = new Credit(data.copyrightText); + this._resource = resource; + const imageryProviderBuilder = new ImageryProviderBuilder(options); + if (imageryProviderBuilder.useTiles) { + this._readyPromise = requestMetadata( + resource, + imageryProviderBuilder, + this + ).then(() => { + imageryProviderBuilder.build(this); + return true; + }); + } else { + imageryProviderBuilder.build(this); + this._readyPromise = Promise.resolve(true); } - - that._ready = true; - TileProviderError.reportSuccess(metadataError); - return Promise.resolve(true); - } - - function metadataFailure(e) { - const message = `An error occurred while accessing ${that._resource.url}.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message, - undefined, - undefined, - undefined - ); - return Promise.reject(new RuntimeError(message)); - } - function requestMetadata() { - const resource = that._resource.getDerivedResource({ - queryParameters: { - f: "json", - }, - }); - return resource.fetchJsonp().then(metadataSuccess).catch(metadataFailure); - } - - if (this._useTiles) { - this._readyPromise = requestMetadata(); - } else { - this._ready = true; - this._readyPromise = Promise.resolve(true); } } @@ -482,127 +329,73 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof ArcGisMapServerImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof ArcGisMapServerImageryProvider.prototype * @type {Rectangle} * @readonly */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "rectangle must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._rectangle; }, }, @@ -610,22 +403,13 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof ArcGisMapServerImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileDiscardPolicy; }, }, @@ -649,9 +433,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * @memberof ArcGisMapServerImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.ready", + "ArcGisMapServerImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGisMapServerImageryProvider.fromUrl instead." + ); return this._ready; }, }, @@ -661,9 +450,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * @memberof ArcGisMapServerImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.readyPromise", + "ArcGisMapServerImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGisMapServerImageryProvider.fromUrl instead." + ); return this._readyPromise; }, }, @@ -683,9 +477,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets a value indicating whether this imagery provider is using pre-cached tiles from the - * ArcGIS MapServer. If the imagery provider is not yet ready ({@link ArcGisMapServerImageryProvider#ready}), this function - * will return the value of `options.usePreCachedTilesIfAvailable`, even if the MapServer does - * not have pre-cached tiles. + * ArcGIS MapServer. * @memberof ArcGisMapServerImageryProvider.prototype * * @type {Boolean} @@ -729,6 +521,251 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { }, }); +/** + * Used to track creation details while fetching initial metadata + * + * @constructor + * @private + * + * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options An object describing initialization options + */ +function ImageryProviderBuilder(options) { + this.useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); + + const ellipsoid = options.ellipsoid; + this.tilingScheme = defaultValue( + options.tilingScheme, + new GeographicTilingScheme({ ellipsoid: ellipsoid }) + ); + this.rectangle = defaultValue(options.rectangle, this.tilingScheme.rectangle); + this.ellipsoid = ellipsoid; + + let credit = options.credit; + if (typeof credit === "string") { + credit = new Credit(credit); + } + this.credit = credit; + this.tileDiscardPolicy = options.tileDiscardPolicy; + + this.tileWidth = defaultValue(options.tileWidth, 256); + this.tileHeight = defaultValue(options.tileHeight, 256); + this.maximumLevel = options.maximumLevel; +} + +/** + * Complete ArcGisMapServerImageryProvider creation based on builder values. + * + * @private + * + * @param {ArcGisMapServerImageryProvider} provider + */ +ImageryProviderBuilder.prototype.build = function (provider) { + provider._useTiles = this.useTiles; + provider._tilingScheme = this.tilingScheme; + provider._rectangle = this.rectangle; + provider._credit = this.credit; + provider._tileDiscardPolicy = this.tileDiscardPolicy; + provider._tileWidth = this.tileWidth; + provider._tileHeight = this.tileHeight; + provider._maximumLevel = this.maximumLevel; + + // Install the default tile discard policy if none has been supplied. + if (this.useTiles && !defined(this.tileDiscardPolicy)) { + provider._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ + missingImageUrl: buildImageResource(provider, 0, 0, this.maximumLevel) + .url, + pixelsToCheck: [ + new Cartesian2(0, 0), + new Cartesian2(200, 20), + new Cartesian2(20, 200), + new Cartesian2(80, 110), + new Cartesian2(160, 130), + ], + disableCheckIfAllPixelsAreTransparent: true, + }); + } + + provider._ready = true; +}; + +function metadataSuccess(data, imageryProviderBuilder) { + const tileInfo = data.tileInfo; + if (!defined(tileInfo)) { + imageryProviderBuilder.useTiles = false; + } else { + imageryProviderBuilder.tileWidth = tileInfo.rows; + imageryProviderBuilder.tileHeight = tileInfo.cols; + + if ( + tileInfo.spatialReference.wkid === 102100 || + tileInfo.spatialReference.wkid === 102113 + ) { + imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({ + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + } else if (data.tileInfo.spatialReference.wkid === 4326) { + imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({ + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + } else { + const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`; + throw new RuntimeError(message); + } + imageryProviderBuilder.maximumLevel = data.tileInfo.lods.length - 1; + + if (defined(data.fullExtent)) { + if ( + defined(data.fullExtent.spatialReference) && + defined(data.fullExtent.spatialReference.wkid) + ) { + if ( + data.fullExtent.spatialReference.wkid === 102100 || + data.fullExtent.spatialReference.wkid === 102113 + ) { + const projection = new WebMercatorProjection(); + const extent = data.fullExtent; + const sw = projection.unproject( + new Cartesian3( + Math.max( + extent.xmin, + -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + Math.max( + extent.ymin, + -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + 0.0 + ) + ); + const ne = projection.unproject( + new Cartesian3( + Math.min( + extent.xmax, + imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + Math.min( + extent.ymax, + imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + 0.0 + ) + ); + imageryProviderBuilder.rectangle = new Rectangle( + sw.longitude, + sw.latitude, + ne.longitude, + ne.latitude + ); + } else if (data.fullExtent.spatialReference.wkid === 4326) { + imageryProviderBuilder.rectangle = Rectangle.fromDegrees( + data.fullExtent.xmin, + data.fullExtent.ymin, + data.fullExtent.xmax, + data.fullExtent.ymax + ); + } else { + const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`; + throw new RuntimeError(extentMessage); + } + } + } else { + imageryProviderBuilder.rectangle = + imageryProviderBuilder.tilingScheme.rectangle; + } + + imageryProviderBuilder.useTiles = true; + } + + if (defined(data.copyrightText) && data.copyrightText.length > 0) { + imageryProviderBuilder.credit = new Credit(data.copyrightText); + } +} + +function metadataFailure(resource, error, provider) { + let message = `An error occurred while accessing ${resource.url}`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + // When readyPromise is deprecated, TileProviderError.reportError, + // and related parameters can be removed + TileProviderError.reportError( + undefined, + provider, + defined(provider) ? provider._errorEvent : undefined, + message, + undefined, + undefined, + undefined, + error + ); + + throw new RuntimeError(message); +} + +async function requestMetadata(resource, imageryProviderBuilder, provider) { + const jsonResource = resource.getDerivedResource({ + queryParameters: { + f: "json", + }, + }); + + try { + const data = await jsonResource.fetchJsonp(); + metadataSuccess(data, imageryProviderBuilder); + } catch (error) { + metadataFailure(resource, error, provider); + } +} + +/** + * Creates an {@link ImageryProvider} which provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are + * used, if available. + * + * @param {Resource|String} url The URL of the ArcGIS MapServer service. + * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options. + * @returns {Promise} A promise that resolves to the created ArcGisMapServerImageryProvider. + * + * @example + * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl( + * "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" + * ); + * + * @exception {RuntimeError} metadata spatial reference specifies an unknown WKID + * @exception {RuntimeError} metadata fullExtent.spatialReference specifies an unknown WKID + */ +ArcGisMapServerImageryProvider.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + const resource = Resource.createIfNeeded(url); + resource.appendForwardSlash(); + + if (defined(options.token)) { + resource.setQueryParameters({ + token: options.token, + }); + } + + const provider = new ArcGisMapServerImageryProvider(options); + provider._resource = resource; + const imageryProviderBuilder = new ImageryProviderBuilder(options); + const useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); + if (useTiles) { + await requestMetadata(resource, imageryProviderBuilder); + } + + imageryProviderBuilder.build(provider); + return provider; +}; + /** * Gets the credits to be displayed when a given tile is displayed. * @@ -736,8 +773,6 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ ArcGisMapServerImageryProvider.prototype.getTileCredits = function ( x, @@ -748,8 +783,7 @@ ArcGisMapServerImageryProvider.prototype.getTileCredits = function ( }; /** - * Requests the image for a given tile. This function should - * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -757,8 +791,6 @@ ArcGisMapServerImageryProvider.prototype.getTileCredits = function ( * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ ArcGisMapServerImageryProvider.prototype.requestImage = function ( x, @@ -766,14 +798,6 @@ ArcGisMapServerImageryProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return ImageryProvider.loadImage( this, buildImageResource(this, x, y, level, request) @@ -783,7 +807,7 @@ ArcGisMapServerImageryProvider.prototype.requestImage = function ( /** /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * a tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -793,8 +817,6 @@ ArcGisMapServerImageryProvider.prototype.requestImage = function ( * @return {Promise.|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. - * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ ArcGisMapServerImageryProvider.prototype.pickFeatures = function ( x, @@ -803,14 +825,6 @@ ArcGisMapServerImageryProvider.prototype.pickFeatures = function ( longitude, latitude ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "pickFeatures must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - if (!this.enablePickFeatures) { return undefined; } diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index 374acd1d3e2..8d56bd548d9 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -3,7 +3,7 @@ import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import CesiumMath from "../Core/Math.js"; import Rectangle from "../Core/Rectangle.js"; @@ -20,9 +20,9 @@ import ImageryProvider from "./ImageryProvider.js"; * * Initialization options for the BingMapsImageryProvider constructor * - * @property {Resource|String} url The url of the Bing Maps server hosting the imagery. - * @property {String} key The Bing Maps key for your application, which can be - * created at {@link https://www.bingmapsportal.com/}. + * @property {Resource|String} [url] The url of the Bing Maps server hosting the imagery. Deprecated. + * @property {String} [key] The Bing Maps key for your application, which can be + * created at {@link https://www.bingmapsportal.com/}. Deprecated. * @property {String} [tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'. * By default, tiles are loaded using the same protocol as the page. * @property {BingMapsStyle} [mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load. @@ -37,6 +37,10 @@ import ImageryProvider from "./ImageryProvider.js"; */ /** + *
+ * To construct a BingMapsImageryProvider, call {@link BingMapsImageryProvider.fromUrl}. Do not call the constructor directly. + *
+ * * Provides tiled imagery using the Bing Maps Imagery REST API. * * @alias BingMapsImageryProvider @@ -44,6 +48,7 @@ import ImageryProvider from "./ImageryProvider.js"; * * @param {BingMapsImageryProvider.ConstructorOptions} options Object describing initialization options * + * @see BingMapsImageryProvider.fromUrl * @see ArcGisMapServerImageryProvider * @see GoogleEarthEnterpriseMapsProvider * @see OpenStreetMapImageryProvider @@ -53,12 +58,11 @@ import ImageryProvider from "./ImageryProvider.js"; * @see WebMapTileServiceImageryProvider * @see UrlTemplateImageryProvider * - * * @example - * const bing = new Cesium.BingMapsImageryProvider({ - * url : 'https://dev.virtualearth.net', - * key : 'get-yours-at-https://www.bingmapsportal.com/', - * mapStyle : Cesium.BingMapsStyle.AERIAL + * const bing = await Cesium.BingMapsImageryProvider.fromUrl( + * "https://dev.virtualearth.net", + * "get-yours-at-https://www.bingmapsportal.com/", { + * mapStyle: Cesium.BingMapsStyle.AERIAL * }); * * @see {@link http://msdn.microsoft.com/en-us/library/ff701713.aspx|Bing Maps REST Services} @@ -66,16 +70,6 @@ import ImageryProvider from "./ImageryProvider.js"; */ function BingMapsImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - const accessKey = options.key; - - //>>includeStart('debug', pragmas.debug); - if (!defined(options.url)) { - throw new DeveloperError("options.url is required."); - } - if (!defined(accessKey)) { - throw new DeveloperError("options.key is required."); - } - //>>includeEnd('debug'); /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and @@ -163,12 +157,9 @@ function BingMapsImageryProvider(options) { */ this.defaultMagnificationFilter = undefined; - this._key = accessKey; - this._resource = Resource.createIfNeeded(options.url); - this._resource.appendForwardSlash(); - this._tileProtocol = options.tileProtocol; this._mapStyle = defaultValue(options.mapStyle, BingMapsStyle.AERIAL); this._culture = defaultValue(options.culture, ""); + this._key = options.key; this._tileDiscardPolicy = options.tileDiscardPolicy; if (!defined(this._tileDiscardPolicy)) { @@ -195,119 +186,56 @@ function BingMapsImageryProvider(options) { this._errorEvent = new Event(); this._ready = false; + if (defined(options.url)) { + deprecationWarning( + "BingMapsImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use BingMapsImageryProvider.fromUrl instead." + ); - let tileProtocol = this._tileProtocol; - - // For backward compatibility reasons, the tileProtocol may end with - // a `:`. Remove it. - if (defined(tileProtocol)) { - if ( - tileProtocol.length > 0 && - tileProtocol[tileProtocol.length - 1] === ":" - ) { - tileProtocol = tileProtocol.substr(0, tileProtocol.length - 1); - } - } else { - // use http if the document's protocol is http, otherwise use https - const documentProtocol = document.location.protocol; - tileProtocol = documentProtocol === "http:" ? "http" : "https"; - } - - const metadataResource = this._resource.getDerivedResource({ - url: `REST/v1/Imagery/Metadata/${this._mapStyle}`, - queryParameters: { - incl: "ImageryProviders", - key: this._key, - uriScheme: tileProtocol, - }, - }); - const that = this; - let metadataError; - - function metadataSuccess(data) { - if (data.resourceSets.length !== 1) { - return metadataFailure(); - } - const resource = data.resourceSets[0].resources[0]; - - that._tileWidth = resource.imageWidth; - that._tileHeight = resource.imageHeight; - that._maximumLevel = resource.zoomMax - 1; - that._imageUrlSubdomains = resource.imageUrlSubdomains; - that._imageUrlTemplate = resource.imageUrl; - - let attributionList = (that._attributionList = resource.imageryProviders); - if (!attributionList) { - attributionList = that._attributionList = []; - } - - for ( - let attributionIndex = 0, attributionLength = attributionList.length; - attributionIndex < attributionLength; - ++attributionIndex - ) { - const attribution = attributionList[attributionIndex]; - - if (attribution.credit instanceof Credit) { - // If attribution.credit has already been created - // then we are using a cached value, which means - // none of the remaining processing needs to be done. - break; - } + //>>includeStart('debug', pragmas.debug); + Check.defined("options.key", options.key); + //>>includeEnd('debug'); - attribution.credit = new Credit(attribution.attribution); - const coverageAreas = attribution.coverageAreas; + let tileProtocol = options.tileProtocol; - for ( - let areaIndex = 0, areaLength = attribution.coverageAreas.length; - areaIndex < areaLength; - ++areaIndex + // For backward compatibility reasons, the tileProtocol may end with + // a `:`. Remove it. + if (defined(tileProtocol)) { + if ( + tileProtocol.length > 0 && + tileProtocol[tileProtocol.length - 1] === ":" ) { - const area = coverageAreas[areaIndex]; - const bbox = area.bbox; - area.bbox = new Rectangle( - CesiumMath.toRadians(bbox[1]), - CesiumMath.toRadians(bbox[0]), - CesiumMath.toRadians(bbox[3]), - CesiumMath.toRadians(bbox[2]) - ); + tileProtocol = tileProtocol.substr(0, tileProtocol.length - 1); } + } else { + // use http if the document's protocol is http, otherwise use https + const documentProtocol = document.location.protocol; + tileProtocol = documentProtocol === "http:" ? "http" : "https"; } - that._ready = true; - TileProviderError.reportSuccess(metadataError); - return Promise.resolve(true); - } - - function metadataFailure(e) { - const message = `An error occurred while accessing ${metadataResource.url}.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message, - undefined, - undefined, - undefined - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(message)); - } - - const cacheKey = metadataResource.url; - function requestMetadata() { - const promise = metadataResource.fetchJsonp("jsonp"); - BingMapsImageryProvider._metadataCache[cacheKey] = promise; - return promise.then(metadataSuccess).catch(metadataFailure); - } + const resource = Resource.createIfNeeded(options.url); + this._resource = resource; + resource.appendForwardSlash(); + const metadataResource = resource.getDerivedResource({ + url: `REST/v1/Imagery/Metadata/${this._mapStyle}`, + queryParameters: { + incl: "ImageryProviders", + key: options.key, + uriScheme: tileProtocol, + }, + }); - const promise = BingMapsImageryProvider._metadataCache[cacheKey]; - if (defined(promise)) { - this._readyPromise = promise.then(metadataSuccess).catch(metadataFailure); + const imageryProviderBuilder = new ImageryProviderBuilder(options); + this._readyPromise = requestMetadata( + metadataResource, + imageryProviderBuilder, + this + ).then(() => { + imageryProviderBuilder.build(this); + return true; + }); } else { - this._readyPromise = requestMetadata(); + this._readyPromise = Promise.resolve(true); } } @@ -375,127 +303,73 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof BingMapsImageryProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof BingMapsImageryProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof BingMapsImageryProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof BingMapsImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof BingMapsImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof BingMapsImageryProvider.prototype * @type {Rectangle} * @readonly */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "rectangle must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme.rectangle; }, }, @@ -503,22 +377,13 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof BingMapsImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileDiscardPolicy; }, }, @@ -542,9 +407,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * @memberof BingMapsImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "BingMapsImageryProvider.ready", + "BingMapsImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use BingMapsImageryProvider.fromUrl instead." + ); return this._ready; }, }, @@ -554,16 +424,21 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * @memberof BingMapsImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "BingMapsImageryProvider.readyPromise", + "BingMapsImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use BingMapsImageryProvider.fromUrl instead." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link BingMapsImageryProvider#ready} returns true. + * the source of the imagery. * @memberof BingMapsImageryProvider.prototype * @type {Credit} * @readonly @@ -591,6 +466,200 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { }, }); +/** + * Used to track creation details while fetching initial metadata + * + * @constructor + * @private + * + * @param {BingMapsImageryProvider.ConstructorOptions} options An object describing initialization options + */ +function ImageryProviderBuilder(options) { + this.tileWidth = undefined; + this.tileHeight = undefined; + this.maximumLevel = undefined; + this.imageUrlSubdomains = undefined; + this.imageUrlTemplate = undefined; + + this.attributionList = undefined; +} + +/** + * Complete BingMapsImageryProvider creation based on builder values. + * + * @private + * + * @param {BingMapsImageryProvider} provider + */ +ImageryProviderBuilder.prototype.build = function (provider) { + provider._tileWidth = this.tileWidth; + provider._tileHeight = this.tileHeight; + provider._maximumLevel = this.maximumLevel; + provider._imageUrlSubdomains = this.imageUrlSubdomains; + provider._imageUrlTemplate = this.imageUrlTemplate; + + let attributionList = (provider._attributionList = this.attributionList); + if (!attributionList) { + attributionList = []; + } + provider._attributionList = attributionList; + + for ( + let attributionIndex = 0, attributionLength = attributionList.length; + attributionIndex < attributionLength; + ++attributionIndex + ) { + const attribution = attributionList[attributionIndex]; + + if (attribution.credit instanceof Credit) { + // If attribution.credit has already been created + // then we are using a cached value, which means + // none of the remaining processing needs to be done. + break; + } + + attribution.credit = new Credit(attribution.attribution); + const coverageAreas = attribution.coverageAreas; + + for ( + let areaIndex = 0, areaLength = attribution.coverageAreas.length; + areaIndex < areaLength; + ++areaIndex + ) { + const area = coverageAreas[areaIndex]; + const bbox = area.bbox; + area.bbox = new Rectangle( + CesiumMath.toRadians(bbox[1]), + CesiumMath.toRadians(bbox[0]), + CesiumMath.toRadians(bbox[3]), + CesiumMath.toRadians(bbox[2]) + ); + } + } + + provider._ready = true; +}; + +function metadataSuccess(data, imageryProviderBuilder) { + if (data.resourceSets.length !== 1) { + throw new RuntimeError( + "metadata does not specify one resource in resourceSets" + ); + } + + const resource = data.resourceSets[0].resources[0]; + imageryProviderBuilder.tileWidth = resource.imageWidth; + imageryProviderBuilder.tileHeight = resource.imageHeight; + imageryProviderBuilder.maximumLevel = resource.zoomMax - 1; + imageryProviderBuilder.imageUrlSubdomains = resource.imageUrlSubdomains; + imageryProviderBuilder.imageUrlTemplate = resource.imageUrl; + imageryProviderBuilder.attributionList = resource.imageryProviders; +} + +function metadataFailure(metadataResource, error, provider) { + let message = `An error occurred while accessing ${metadataResource.url}`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + TileProviderError.reportError( + undefined, + provider, + defined(provider) ? provider._errorEvent : undefined, + message, + undefined, + undefined, + undefined, + error + ); + + throw new RuntimeError(message); +} + +async function requestMetadata( + metadataResource, + imageryProviderBuilder, + provider +) { + const cacheKey = metadataResource.url; + let promise = BingMapsImageryProvider._metadataCache[cacheKey]; + if (!defined(promise)) { + promise = metadataResource.fetchJsonp("jsonp"); + BingMapsImageryProvider._metadataCache[cacheKey] = promise; + } + + try { + const data = await promise; + return metadataSuccess(data, imageryProviderBuilder); + } catch (e) { + metadataFailure(metadataResource, e, provider); + } +} + +/** + * Creates an {@link ImageryProvider} which provides tiled imagery using the Bing Maps Imagery REST API. + * + * @param {Resource|String} url The url of the Bing Maps server hosting the imagery. + * @param {String} key The Bing Maps key for your application, which can be + * created at {@link https://www.bingmapsportal.com/}. + * @param {BingMapsImageryProvider.ConstructorOptions} options Object describing initialization options + * @returns {Promise} A promise that resolves to the created BingMapsImageryProvider + * + * @example + * const bing = await Cesium.BingMapsImageryProvider.fromUrl( + * "https://dev.virtualearth.net", + * "get-yours-at-https://www.bingmapsportal.com/", { + * mapStyle: Cesium.BingMapsStyle.AERIAL + * }); + * + * @exception {RuntimeError} metadata does not specify one resource in resourceSets + */ +BingMapsImageryProvider.fromUrl = async function (url, key, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + Check.defined("key", key); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + let tileProtocol = options.tileProtocol; + + // For backward compatibility reasons, the tileProtocol may end with + // a `:`. Remove it. + if (defined(tileProtocol)) { + if ( + tileProtocol.length > 0 && + tileProtocol[tileProtocol.length - 1] === ":" + ) { + tileProtocol = tileProtocol.substr(0, tileProtocol.length - 1); + } + } else { + // use http if the document's protocol is http, otherwise use https + const documentProtocol = document.location.protocol; + tileProtocol = documentProtocol === "http:" ? "http" : "https"; + } + + const mapStyle = defaultValue(options.mapStyle, BingMapsStyle.AERIAL); + const resource = Resource.createIfNeeded(url); + resource.appendForwardSlash(); + const metadataResource = resource.getDerivedResource({ + url: `REST/v1/Imagery/Metadata/${mapStyle}`, + queryParameters: { + incl: "ImageryProviders", + key: key, + uriScheme: tileProtocol, + }, + }); + + const provider = new BingMapsImageryProvider(options); + provider._resource = resource; + provider._key = key; + const imageryProviderBuilder = new ImageryProviderBuilder(options); + await requestMetadata(metadataResource, imageryProviderBuilder); + imageryProviderBuilder.build(provider); + return provider; +}; + const rectangleScratch = new Rectangle(); /** @@ -600,18 +669,8 @@ const rectangleScratch = new Rectangle(); * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ BingMapsImageryProvider.prototype.getTileCredits = function (x, y, level) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "getTileCredits must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const rectangle = this._tilingScheme.tileXYToRectangle( x, y, @@ -628,8 +687,7 @@ BingMapsImageryProvider.prototype.getTileCredits = function (x, y, level) { }; /** - * Requests the image for a given tile. This function should - * not be called before {@link BingMapsImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -637,8 +695,6 @@ BingMapsImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ BingMapsImageryProvider.prototype.requestImage = function ( x, @@ -646,14 +702,6 @@ BingMapsImageryProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const promise = ImageryProvider.loadImage( this, buildImageResource(this, x, y, level, request) diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index 556b12bbbde..5ef498722d4 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -1,8 +1,9 @@ +import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import decodeGoogleEarthEnterpriseData from "../Core/decodeGoogleEarthEnterpriseData.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; import GoogleEarthEnterpriseMetadata from "../Core/GoogleEarthEnterpriseMetadata.js"; @@ -47,8 +48,8 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( * * Initialization options for the GoogleEarthEnterpriseImageryProvider constructor * - * @property {Resource|String} url The url of the Google Earth Enterprise server hosting the imagery. - * @property {GoogleEarthEnterpriseMetadata} metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. + * @property {Resource|String} [url] The url of the Google Earth Enterprise server hosting the imagery. Deprecated. + * @property {GoogleEarthEnterpriseMetadata} [metadata] A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. Deprecated. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. If this value is not specified, a default @@ -57,6 +58,10 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( */ /** + *
+ * To construct a GoogleEarthEnterpriseImageryProvider, call {@link GoogleEarthEnterpriseImageryProvider.fromMetadata}. Do not call the constructor directly. + *
+ * * Provides tiled imagery using the Google Earth Enterprise REST API. * * Notes: This provider is for use with the 3D Earth API of Google Earth Enterprise, @@ -67,6 +72,7 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( * * @param {GoogleEarthEnterpriseImageryProvider.ConstructorOptions} options Object describing initialization options * + * @see GoogleEarthEnterpriseImageryProvider.fromMetadata * @see GoogleEarthEnterpriseTerrainProvider * @see ArcGisMapServerImageryProvider * @see GoogleEarthEnterpriseMapsProvider @@ -79,22 +85,14 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( * * * @example - * const geeMetadata = new GoogleEarthEnterpriseMetadata('http://www.example.com'); - * const gee = new Cesium.GoogleEarthEnterpriseImageryProvider({ - * metadata : geeMetadata - * }); + * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl("http://www.example.com"); + * const gee = Cesium.GoogleEarthEnterpriseImageryProvider.fromMetadata(geeMetadata); * * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ function GoogleEarthEnterpriseImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - if (!(defined(options.url) || defined(options.metadata))) { - throw new DeveloperError("options.url or options.metadata is required."); - } - //>>includeEnd('debug'); - /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. @@ -181,14 +179,6 @@ function GoogleEarthEnterpriseImageryProvider(options) { */ this.defaultMagnificationFilter = undefined; - let metadata; - if (defined(options.metadata)) { - metadata = options.metadata; - } else { - const resource = Resource.createIfNeeded(options.url); - metadata = new GoogleEarthEnterpriseMetadata(resource); - } - this._metadata = metadata; this._tileDiscardPolicy = options.tileDiscardPolicy; this._tilingScheme = new GeographicTilingScheme({ @@ -223,12 +213,50 @@ function GoogleEarthEnterpriseImageryProvider(options) { this._ready = false; const that = this; let metadataError; - this._readyPromise = metadata.readyPromise - .then(function (result) { - if (!metadata.imageryPresent) { - const e = new RuntimeError( - `The server ${metadata.url} doesn't have imagery` - ); + let metadata; + if (defined(options.url)) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + ); + const resource = Resource.createIfNeeded(options.url); + metadata = new GoogleEarthEnterpriseMetadata(resource); + } + + if (defined(options.metadata)) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider options.metadata", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + ); + metadata = options.metadata; + } + + this._metadata = metadata; + if (defined(metadata)) { + this._readyPromise = metadata.readyPromise + .then(function (result) { + if (!metadata.imageryPresent) { + const e = new RuntimeError( + `The server ${metadata.url} doesn't have imagery` + ); + metadataError = TileProviderError.reportError( + metadataError, + that, + that._errorEvent, + e.message, + undefined, + undefined, + undefined, + e + ); + return Promise.reject(e); + } + + TileProviderError.reportSuccess(metadataError); + that._ready = result; + return result; + }) + .catch(function (e) { metadataError = TileProviderError.reportError( metadataError, that, @@ -240,25 +268,8 @@ function GoogleEarthEnterpriseImageryProvider(options) { e ); return Promise.reject(e); - } - - TileProviderError.reportSuccess(metadataError); - that._ready = result; - return result; - }) - .catch(function (e) { - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - e.message, - undefined, - undefined, - undefined, - e - ); - return Promise.reject(e); - }); + }); + } } Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { @@ -287,127 +298,73 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Rectangle} * @readonly */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "rectangle must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme.rectangle; }, }, @@ -415,22 +372,13 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileDiscardPolicy; }, }, @@ -454,9 +402,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.ready", + "GoogleEarthEnterpriseImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + ); return this._ready; }, }, @@ -466,16 +419,21 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.readyPromise", + "GoogleEarthEnterpriseImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * the source of the imagery. * @memberof GoogleEarthEnterpriseImageryProvider.prototype * @type {Credit} * @readonly @@ -503,6 +461,37 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { }, }); +/** + * Creates a tiled imagery provider using the Google Earth Enterprise REST API. + * @param {GoogleEarthEnterpriseMetadata} metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. + * @param {GoogleEarthEnterpriseImageryProvider.ConstructorOptions} options Object describing initialization options. + * @returns {GoogleEarthEnterpriseImageryProvider} + * + * @exception {RuntimeError} The metadata url does not have imagery + * + * @example + * const geeMetadata = await GoogleEarthEnterpriseMetadata.fromUrl("http://www.example.com"); + * const gee = Cesium.GoogleEarthEnterpriseImageryProvider.fromMetadata(geeMetadata); + */ +GoogleEarthEnterpriseImageryProvider.fromMetadata = function ( + metadata, + options +) { + //>>includeStart('debug', pragmas.debug); + Check.defined("metadata", metadata); + //>>includeEnd('debug'); + + if (!metadata.imageryPresent) { + throw new RuntimeError(`The server ${metadata.url} doesn't have imagery`); + } + + const provider = new GoogleEarthEnterpriseImageryProvider(options); + provider._metadata = metadata; + provider._ready = true; + provider._readyPromise = Promise.resolve(true); + return provider; +}; + /** * Gets the credits to be displayed when a given tile is displayed. * @@ -510,22 +499,12 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function ( x, y, level ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "getTileCredits must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const metadata = this._metadata; const info = metadata.getTileInformation(x, y, level); if (defined(info)) { @@ -539,8 +518,7 @@ GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function ( }; /** - * Requests the image for a given tile. This function should - * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -548,8 +526,6 @@ GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function ( * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ GoogleEarthEnterpriseImageryProvider.prototype.requestImage = function ( x, @@ -557,14 +533,6 @@ GoogleEarthEnterpriseImageryProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const invalidImage = this._tileDiscardPolicy._image; // Empty image or undefined depending on discard policy const metadata = this._metadata; const quadKey = GoogleEarthEnterpriseMetadata.tileXYToQuadKey(x, y, level); diff --git a/packages/engine/Source/Scene/GridImageryProvider.js b/packages/engine/Source/Scene/GridImageryProvider.js index ba0470f5019..112d6b65bf0 100644 --- a/packages/engine/Source/Scene/GridImageryProvider.js +++ b/packages/engine/Source/Scene/GridImageryProvider.js @@ -1,6 +1,7 @@ import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; @@ -165,8 +166,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof GridImageryProvider.prototype * @type {Number} * @readonly @@ -178,8 +178,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof GridImageryProvider.prototype * @type {Number} * @readonly @@ -191,8 +190,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof GridImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -204,8 +202,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof GridImageryProvider.prototype * @type {Number} * @readonly @@ -217,8 +214,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof GridImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -230,8 +226,7 @@ Object.defineProperties(GridImageryProvider.prototype, { }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof GridImageryProvider.prototype * @type {Rectangle} * @readonly @@ -245,8 +240,7 @@ Object.defineProperties(GridImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof GridImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -276,9 +270,14 @@ Object.defineProperties(GridImageryProvider.prototype, { * @memberof GridImageryProvider.prototype * @type {Boolean} * @readonly + * @deprected */ ready: { get: function () { + deprecationWarning( + "GridImageryProvider.ready", + "GridImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return true; }, }, @@ -288,16 +287,21 @@ Object.defineProperties(GridImageryProvider.prototype, { * @memberof GridImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "GridImageryProvider.readyPromise", + "GridImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GridImageryProvider#ready} returns true. + * the source of the imagery. * @memberof GridImageryProvider.prototype * @type {Credit} * @readonly @@ -392,16 +396,13 @@ GridImageryProvider.prototype._createGridCanvas = function () { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ GridImageryProvider.prototype.getTileCredits = function (x, y, level) { return undefined; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link GridImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. diff --git a/packages/engine/Source/Scene/ImageryProvider.js b/packages/engine/Source/Scene/ImageryProvider.js index 37a66f8df85..453739e4fe8 100644 --- a/packages/engine/Source/Scene/ImageryProvider.js +++ b/packages/engine/Source/Scene/ImageryProvider.js @@ -138,6 +138,7 @@ Object.defineProperties(ImageryProvider.prototype, { * @memberof ImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: DeveloperError.throwInstantiationError, @@ -148,14 +149,14 @@ Object.defineProperties(ImageryProvider.prototype, { * @memberof ImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: DeveloperError.throwInstantiationError, }, /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by the instance. * @memberof ImageryProvider.prototype * @type {Rectangle} * @readonly @@ -165,8 +166,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof ImageryProvider.prototype * @type {Number} * @readonly @@ -176,8 +176,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof ImageryProvider.prototype * @type {Number} * @readonly @@ -187,8 +186,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof ImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -198,8 +196,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link ImageryProvider#ready} returns true. Generally, + * Gets the minimum level-of-detail that can be requested. Generally, * a minimum level should only be used when the rectangle of the imagery is small * enough that the number of tiles at the minimum level is small. An imagery * provider with more than a few tiles at the minimum level will lead to @@ -213,8 +210,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof ImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -226,8 +222,7 @@ Object.defineProperties(ImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof ImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -237,7 +232,7 @@ Object.defineProperties(ImageryProvider.prototype, { }, /** - * Gets an event that is raised when the imagery provider encounters an asynchronous error.. By subscribing + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners * are passed an instance of {@link TileProviderError}. * @memberof ImageryProvider.prototype @@ -250,8 +245,7 @@ Object.defineProperties(ImageryProvider.prototype, { /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * the source of the imagery. * @memberof ImageryProvider.prototype * @type {Credit} * @readonly @@ -292,16 +286,13 @@ Object.defineProperties(ImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ ImageryProvider.prototype.getTileCredits = function (x, y, level) { DeveloperError.throwInstantiationError(); }; /** - * Requests the image for a given tile. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -309,8 +300,6 @@ ImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} Returns a promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ ImageryProvider.prototype.requestImage = function (x, y, level, request) { DeveloperError.throwInstantiationError(); @@ -318,7 +307,7 @@ ImageryProvider.prototype.requestImage = function (x, y, level, request) { /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * a tile. * This function is optional, so it may not exist on all ImageryProviders. * * @function @@ -333,7 +322,6 @@ ImageryProvider.prototype.requestImage = function (x, y, level, request) { * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ ImageryProvider.prototype.pickFeatures = function ( x, diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 99ee11783ec..6af3112fb74 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -1,8 +1,9 @@ import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; +import GoogleEarthEnterpriseMetadata from "../Core/GoogleEarthEnterpriseMetadata.js"; import IonResource from "../Core/IonResource.js"; import RuntimeError from "../Core/RuntimeError.js"; import ArcGisMapServerImageryProvider from "./ArcGisMapServerImageryProvider.js"; @@ -35,17 +36,61 @@ const ImageryProviderMapping = { WMTS: createFactory(WebMapTileServiceImageryProvider), }; +const ImageryProviderAsyncMapping = { + ARCGIS_MAPSERVER: ArcGisMapServerImageryProvider.fromUrl, + BING: BingMapsImageryProvider.fromUrl, + GOOGLE_EARTH: async (url, options) => { + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); + GoogleEarthEnterpriseMapsProvider.fromMetadata(metadata, options); + }, + MAPBOX: (url, options) => { + return new MapboxImageryProvider({ + url: url, + ...options, + }); + }, + SINGLE_TILE: (url, options) => { + return new SingleTileImageryProvider({ + url: url, + ...options, + }); + }, + TMS: TileMapServiceImageryProvider.fromUrl, + URL_TEMPLATE: (url, options) => { + return new UrlTemplateImageryProvider({ + url: url, + ...options, + }); + }, + WMS: (url, options) => { + return new WebMapServiceImageryProvider({ + url: url, + ...options, + }); + }, + WMTS: (url, options) => { + return new WebMapTileServiceImageryProvider({ + url: url, + ...options, + }); + }, +}; + /** * @typedef {Object} IonImageryProvider.ConstructorOptions * * Initialization options for the TileMapServiceImageryProvider constructor * - * @property {Number} assetId An ion imagery asset ID + * @property {Number} [assetId] An ion imagery asset ID. Deprecated. * @property {String} [accessToken=Ion.defaultAccessToken] The access token to use. * @property {String|Resource} [server=Ion.defaultServer] The resource to the Cesium ion API server. */ /** + *
+ * To construct a IonImageryProvider, call {@link IonImageryProvider.fromAssetId}. Do not call the constructor directly. + *
+ * * Provides tiled imagery using the Cesium ion REST API. * * @alias IonImageryProvider @@ -54,16 +99,14 @@ const ImageryProviderMapping = { * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options * * @example - * viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({ assetId : 23489024 })); + * const imageryProvider = await Cesium.IonImageryProvider.fromAssetId(2348902); + * viewer.imageryLayers.addImageryProvider(imageryProvider); + * + * @see IonImageryProvider.fromAssetId */ function IonImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - const assetId = options.assetId; - //>>includeStart('debug', pragmas.debug); - Check.typeOf.number("options.assetId", assetId); - //>>includeEnd('debug'); - /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. @@ -155,67 +198,77 @@ function IonImageryProvider(options) { this._errorEvent = new Event(); const that = this; - const endpointResource = IonResource._createEndpointResource( - assetId, - options - ); + const assetId = options.assetId; + if (defined(assetId)) { + deprecationWarning( + "IonImageryProvider options.assetId", + "options.assetId was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use IonImageryProvider.fromAssetId instead." + ); - // A simple cache to avoid making repeated requests to ion for endpoints we've - // already retrieved. This exists mainly to support Bing caching to reduce - // world imagery sessions, but provides a small boost of performance in general - // if constantly reloading assets - const cacheKey = - options.assetId.toString() + options.accessToken + options.server; - let promise = IonImageryProvider._endpointCache[cacheKey]; - if (!defined(promise)) { - promise = endpointResource.fetchJson(); - IonImageryProvider._endpointCache[cacheKey] = promise; - } + const endpointResource = IonResource._createEndpointResource( + assetId, + options + ); - this._readyPromise = promise.then(function (endpoint) { - if (endpoint.type !== "IMAGERY") { - return Promise.reject( - new RuntimeError(`Cesium ion asset ${assetId} is not an imagery asset.`) - ); + // A simple cache to avoid making repeated requests to ion for endpoints we've + // already retrieved. This exists mainly to support Bing caching to reduce + // world imagery sessions, but provides a small boost of performance in general + // if constantly reloading assets + const cacheKey = + options.assetId.toString() + options.accessToken + options.server; + let promise = IonImageryProvider._endpointCache[cacheKey]; + if (!defined(promise)) { + promise = endpointResource.fetchJson(); + IonImageryProvider._endpointCache[cacheKey] = promise; } - let imageryProvider; - const externalType = endpoint.externalType; - if (!defined(externalType)) { - imageryProvider = new TileMapServiceImageryProvider({ - url: new IonResource(endpoint, endpointResource), - }); - } else { - const factory = ImageryProviderMapping[externalType]; - - if (!defined(factory)) { + this._readyPromise = promise.then(function (endpoint) { + if (endpoint.type !== "IMAGERY") { return Promise.reject( new RuntimeError( - `Unrecognized Cesium ion imagery type: ${externalType}` + `Cesium ion asset ${assetId} is not an imagery asset.` ) ); } - imageryProvider = factory(endpoint.options); - } - that._tileCredits = IonResource.getCreditsFromEndpoint( - endpoint, - endpointResource - ); + let imageryProvider; + const externalType = endpoint.externalType; + if (!defined(externalType)) { + imageryProvider = new TileMapServiceImageryProvider({ + url: new IonResource(endpoint, endpointResource), + }); + } else { + const factory = ImageryProviderMapping[externalType]; + + if (!defined(factory)) { + return Promise.reject( + new RuntimeError( + `Unrecognized Cesium ion imagery type: ${externalType}` + ) + ); + } + imageryProvider = factory(endpoint.options); + } - imageryProvider.errorEvent.addEventListener(function (tileProviderError) { - //Propagate the errorEvent but set the provider to this instance instead - //of the inner instance. - tileProviderError.provider = that; - that._errorEvent.raiseEvent(tileProviderError); - }); + that._tileCredits = IonResource.getCreditsFromEndpoint( + endpoint, + endpointResource + ); + + imageryProvider.errorEvent.addEventListener(function (tileProviderError) { + //Propagate the errorEvent but set the provider to this instance instead + //of the inner instance. + tileProviderError.provider = that; + that._errorEvent.raiseEvent(tileProviderError); + }); - that._imageryProvider = imageryProvider; - return imageryProvider.readyPromise.then(function () { - that._ready = true; - return true; + that._imageryProvider = imageryProvider; + return imageryProvider.readyPromise.then(function () { + that._ready = true; + return true; + }); }); - }); + } } Object.defineProperties(IonImageryProvider.prototype, { @@ -224,9 +277,14 @@ Object.defineProperties(IonImageryProvider.prototype, { * @memberof IonImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "IonImageryProvider.ready", + "IonImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use IonImageryProvider.fromAssetId instead." + ); return this._ready; }, }, @@ -236,96 +294,68 @@ Object.defineProperties(IonImageryProvider.prototype, { * @memberof IonImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "IonImageryProvider.readyPromise", + "IonImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use IonImageryProvider.fromAssetId instead." + ); return this._readyPromise; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by the instance. * @memberof IonImageryProvider.prototype * @type {Rectangle} * @readonly */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.rectangle; }, }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof IonImageryProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof IonImageryProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof IonImageryProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link IonImageryProvider#ready} returns true. Generally, + * Gets the minimum level-of-detail that can be requested. Generally, * a minimum level should only be used when the rectangle of the imagery is small * enough that the number of tiles at the minimum level is small. An imagery * provider with more than a few tiles at the minimum level will lead to @@ -336,33 +366,18 @@ Object.defineProperties(IonImageryProvider.prototype, { */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.minimumLevel; }, }, /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof IonImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.tilingScheme; }, }, @@ -370,21 +385,13 @@ Object.defineProperties(IonImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof IonImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.tileDiscardPolicy; }, }, @@ -405,21 +412,13 @@ Object.defineProperties(IonImageryProvider.prototype, { /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * the source of the imagery. * @memberof IonImageryProvider.prototype * @type {Credit} * @readonly */ credit: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "credit must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.credit; }, }, @@ -436,13 +435,6 @@ Object.defineProperties(IonImageryProvider.prototype, { */ hasAlphaChannel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "hasAlphaChannel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.hasAlphaChannel; }, @@ -461,6 +453,88 @@ Object.defineProperties(IonImageryProvider.prototype, { }, }); +/** + * Creates a provider for tiled imagery using the Cesium ion REST API. + * + * @param {Number} assetId An ion imagery asset ID. + * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options. + * @returns {Promise} A promise which resolves to the created IonImageryProvider. + * + * @example + * const imageryProvider = await Cesium.IonImageryProvider.fromAssetId(2348902); + * viewer.imageryLayers.addImageryProvider(imageryProvider); + * + * @exception {RuntimeError} Cesium ion assetId is not an imagery asset + * @exception {RuntimeError} Unrecognized Cesium ion imagery type + */ +IonImageryProvider.fromAssetId = async function (assetId, options) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("assetId", assetId); + //>>includeEnd('debug'); + + const endpointResource = IonResource._createEndpointResource( + assetId, + options + ); + + // A simple cache to avoid making repeated requests to ion for endpoints we've + // already retrieved. This exists mainly to support Bing caching to reduce + // world imagery sessions, but provides a small boost of performance in general + // if constantly reloading assets + const cacheKey = assetId.toString() + options.accessToken + options.server; + let promise = IonImageryProvider._endpointCache[cacheKey]; + if (!defined(promise)) { + promise = endpointResource.fetchJson(); + IonImageryProvider._endpointCache[cacheKey] = promise; + } + + const endpoint = await promise; + if (endpoint.type !== "IMAGERY") { + throw new RuntimeError( + `Cesium ion asset ${assetId} is not an imagery asset.` + ); + } + + let imageryProvider; + const externalType = endpoint.externalType; + if (!defined(externalType)) { + imageryProvider = await TileMapServiceImageryProvider.fromUrl( + new IonResource(endpoint, endpointResource) + ); + } else { + const factory = ImageryProviderAsyncMapping[externalType]; + + if (!defined(factory)) { + throw new RuntimeError( + `Unrecognized Cesium ion imagery type: ${externalType}` + ); + } + const url = endpoint.options.url; + delete endpoint.options.url; + imageryProvider = await factory(url, endpoint.options); + } + + const provider = new IonImageryProvider(options); + + imageryProvider.errorEvent.addEventListener(function (tileProviderError) { + //Propagate the errorEvent but set the provider to this instance instead + //of the inner instance. + tileProviderError.provider = provider; + provider._errorEvent.raiseEvent(tileProviderError); + }); + + provider._tileCredits = IonResource.getCreditsFromEndpoint( + endpoint, + endpointResource + ); + + provider._imageryProvider = imageryProvider; + provider._ready = true; + provider._readyPromise = Promise.resolve(true); + + return provider; +}; + /** * Gets the credits to be displayed when a given tile is displayed. * @function @@ -469,18 +543,8 @@ Object.defineProperties(IonImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ IonImageryProvider.prototype.getTileCredits = function (x, y, level) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "getTileCredits must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const innerCredits = this._imageryProvider.getTileCredits(x, y, level); if (!defined(innerCredits)) { return this._tileCredits; @@ -490,8 +554,7 @@ IonImageryProvider.prototype.getTileCredits = function (x, y, level) { }; /** - * Requests the image for a given tile. This function should - * not be called before {@link IonImageryProvider#ready} returns true. + * Requests the image for a given tile. * @function * * @param {Number} x The tile X coordinate. @@ -500,24 +563,14 @@ IonImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ IonImageryProvider.prototype.requestImage = function (x, y, level, request) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.requestImage(x, y, level, request); }; /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link IonImageryProvider#ready} returns true. - * This function is optional, so it may not exist on all ImageryProviders. + * a tile. This function is optional, so it may not exist on all ImageryProviders. * * @function * @@ -530,8 +583,6 @@ IonImageryProvider.prototype.requestImage = function (x, y, level, request) { * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. - * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ IonImageryProvider.prototype.pickFeatures = function ( x, @@ -540,13 +591,6 @@ IonImageryProvider.prototype.pickFeatures = function ( longitude, latitude ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "pickFeatures must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._imageryProvider.pickFeatures(x, y, level, longitude, latitude); }; diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index baff4ff617f..4b0b3aecb85 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -1,6 +1,7 @@ import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import Resource from "../Core/Resource.js"; import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; @@ -211,9 +212,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * @memberof MapboxImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "MapboxImageryProvider.ready", + "MapboxImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._imageryProvider.ready; }, }, @@ -223,16 +229,20 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * @memberof MapboxImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "MapboxImageryProvider.readyPromise", + "MapboxImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._imageryProvider.readyPromise; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by the instance. * @memberof MapboxImageryProvider.prototype * @type {Rectangle} * @readonly @@ -244,8 +254,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof MapboxImageryProvider.prototype * @type {Number} * @readonly @@ -257,8 +266,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof MapboxImageryProvider.prototype * @type {Number} * @readonly @@ -270,8 +278,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof MapboxImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -283,8 +290,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. Generally, + * Gets the minimum level-of-detail that can be requested. Generally, * a minimum level should only be used when the rectangle of the imagery is small * enough that the number of tiles at the minimum level is small. An imagery * provider with more than a few tiles at the minimum level will lead to @@ -300,8 +306,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof MapboxImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -315,8 +320,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof MapboxImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -343,8 +347,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * the source of the imagery. * @memberof MapboxImageryProvider.prototype * @type {Credit} * @readonly @@ -391,16 +394,13 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ MapboxImageryProvider.prototype.getTileCredits = function (x, y, level) { return undefined; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link MapboxImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -417,9 +417,7 @@ MapboxImageryProvider.prototype.requestImage = function (x, y, level, request) { /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link MapboxImageryProvider#ready} returns true. - * This function is optional, so it may not exist on all ImageryProviders. - * + * a tile. This function is optional, so it may not exist on all ImageryProviders. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -430,8 +428,6 @@ MapboxImageryProvider.prototype.requestImage = function (x, y, level, request) { * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. - * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ MapboxImageryProvider.prototype.pickFeatures = function ( x, diff --git a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js index 1382fdced6a..25351f3332e 100644 --- a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js @@ -1,6 +1,7 @@ import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import Resource from "../Core/Resource.js"; import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; @@ -215,9 +216,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * @memberof MapboxStyleImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.ready", + "MapboxStyleImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._imageryProvider.ready; }, }, @@ -227,16 +233,20 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * @memberof MapboxStyleImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.readyPromise", + "MapboxStyleImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._imageryProvider.readyPromise; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by the instance. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by the instance. * @memberof MapboxStyleImageryProvider.prototype * @type {Rectangle} * @readonly @@ -248,8 +258,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof MapboxStyleImageryProvider.prototype * @type {Number} * @readonly @@ -261,8 +270,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof MapboxStyleImageryProvider.prototype * @type {Number} * @readonly @@ -274,8 +282,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof MapboxStyleImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -287,8 +294,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. Generally, + * Gets the minimum level-of-detail that can be requested. Generally, * a minimum level should only be used when the rectangle of the imagery is small * enough that the number of tiles at the minimum level is small. An imagery * provider with more than a few tiles at the minimum level will lead to @@ -304,8 +310,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by the provider. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof MapboxStyleImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -319,8 +324,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof MapboxStyleImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -347,8 +351,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * the source of the imagery. * @memberof MapboxStyleImageryProvider.prototype * @type {Credit} * @readonly @@ -395,16 +398,13 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ MapboxStyleImageryProvider.prototype.getTileCredits = function (x, y, level) { return undefined; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link MapboxStyleImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -412,8 +412,6 @@ MapboxStyleImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ MapboxStyleImageryProvider.prototype.requestImage = function ( x, @@ -426,8 +424,7 @@ MapboxStyleImageryProvider.prototype.requestImage = function ( /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link MapboxStyleImageryProvider#ready} returns true. - * This function is optional, so it may not exist on all ImageryProviders. + * a tile. This function is optional, so it may not exist on all ImageryProviders. * * * @param {Number} x The tile X coordinate. @@ -439,8 +436,6 @@ MapboxStyleImageryProvider.prototype.requestImage = function ( * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. - * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ MapboxStyleImageryProvider.prototype.pickFeatures = function ( x, diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index d8d0b7eb6d1..3db8c4c40d4 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -1,7 +1,8 @@ +import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; import Rectangle from "../Core/Rectangle.js"; @@ -15,13 +16,17 @@ import ImageryProvider from "./ImageryProvider.js"; * * Initialization options for the SingleTileImageryProvider constructor * - * @property {Resource|String} url The url for the tile. + * @property {Resource|String} [url] The url for the tile. Deprecated. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. */ /** + *
+ * To construct a SingleTileImageryProvider, call {@link SingleTileImageryProvider.fromUrl}. Do not call the constructor directly. + *
+ * * Provides a single, top-level imagery tile. The single image is assumed to use a * {@link GeographicTilingScheme}. * @@ -41,12 +46,6 @@ import ImageryProvider from "./ImageryProvider.js"; */ function SingleTileImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - if (!defined(options.url)) { - throw new DeveloperError("options.url is required."); - } - //>>includeEnd('debug'); - /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. @@ -133,8 +132,6 @@ function SingleTileImageryProvider(options) { */ this.defaultMagnificationFilter = undefined; - const resource = Resource.createIfNeeded(options.url); - const rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); const tilingScheme = new GeographicTilingScheme({ rectangle: rectangle, @@ -143,7 +140,6 @@ function SingleTileImageryProvider(options) { ellipsoid: options.ellipsoid, }); this._tilingScheme = tilingScheme; - this._resource = resource; this._image = undefined; this._texture = undefined; this._tileWidth = 0; @@ -159,42 +155,23 @@ function SingleTileImageryProvider(options) { } this._credit = credit; - const that = this; - let error; - - function success(image) { - that._image = image; - that._tileWidth = image.width; - that._tileHeight = image.height; - that._ready = true; - TileProviderError.reportSuccess(that._errorEvent); - return Promise.resolve(true); - } - - function failure(e) { - const message = `Failed to load image ${resource.url}.`; - error = TileProviderError.reportError( - error, - that, - that._errorEvent, - message, - 0, - 0, - 0 + if (defined(options.url)) { + deprecationWarning( + "SingleTileImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use SingleTileImageryProvider.fromUrl instead." ); - if (error.retry) { - return doRequest(); - } - return Promise.reject(new RuntimeError(message)); - } - function doRequest() { - return ImageryProvider.loadImage(null, resource) - .then(success) - .catch(failure); + const resource = Resource.createIfNeeded(options.url); + this._resource = resource; + this._readyPromise = doRequest(resource, this).then((image) => { + TileProviderError.reportSuccess(this._errorEvent); + this._image = image; + this._tileWidth = image.width; + this._tileHeight = image.height; + this._ready = true; + return true; + }); } - - this._readyPromise = doRequest(); } Object.defineProperties(SingleTileImageryProvider.prototype, { @@ -223,113 +200,67 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof SingleTileImageryProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof SingleTileImageryProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof SingleTileImageryProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof SingleTileImageryProvider.prototype * @type {Number} * @readonly */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof SingleTileImageryProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof SingleTileImageryProvider.prototype * @type {Rectangle} * @readonly @@ -343,22 +274,13 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof SingleTileImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return undefined; }, }, @@ -382,9 +304,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * @memberof SingleTileImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "SingleTileImageryProvider.ready", + "SingleTileImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use SingleTileImageryProvider.fromUrl instead." + ); return this._ready; }, }, @@ -394,16 +321,21 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * @memberof SingleTileImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "SingleTileImageryProvider.readyPromise", + "SingleTileImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use SingleTileImageryProvider.fromUrl instead." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link SingleTileImageryProvider#ready} returns true. + * the source of the imagery. * @memberof SingleTileImageryProvider.prototype * @type {Credit} * @readonly @@ -431,6 +363,67 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { }, }); +function failure(resource, error, provider, previousError) { + let message = `Failed to load image ${resource.url}`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + // When readyPromise is deprecated, TileProviderError.reportError, + // retry attempts, and related parameters can be removed + const reportedError = TileProviderError.reportError( + previousError, + provider, + defined(provider) ? provider._errorEvent : undefined, + message, + 0, + 0, + 0, + error + ); + if (reportedError.retry) { + return doRequest(resource, provider, reportedError); + } + + throw new RuntimeError(message); +} + +async function doRequest(resource, provider, previousError) { + try { + const image = await ImageryProvider.loadImage(null, resource); + return image; + } catch (error) { + return failure(resource, error, provider, previousError); + } +} + +/** + * Creates a provider for a single, top-level imagery tile. The single image is assumed to use a + * @param {Resource|String} url The url for the tile + * @param {SingleTileImageryProvider.ConstructorOptions} [options] Object describing initialization options. + * + * @example + * const provider = await SingleTileImageryProvider.fromUrl("https://yoururl.com/image.png"); + */ +SingleTileImageryProvider.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); + + const resource = Resource.createIfNeeded(url); + const image = await doRequest(resource); + + const provider = new SingleTileImageryProvider(options); + provider._resource = resource; + provider._image = image; + provider._tileWidth = image.width; + provider._tileHeight = image.height; + provider._ready = true; + provider._readyPromise = Promise.resolve(true); + + return provider; +}; + /** * Gets the credits to be displayed when a given tile is displayed. * @@ -438,24 +431,19 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ SingleTileImageryProvider.prototype.getTileCredits = function (x, y, level) { return undefined; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link SingleTileImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} The resolved image - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ SingleTileImageryProvider.prototype.requestImage = function ( x, @@ -463,14 +451,6 @@ SingleTileImageryProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - if (!defined(this._image)) { return; } diff --git a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js index 4618a09d96b..757e30aefda 100644 --- a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js +++ b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js @@ -1,6 +1,7 @@ import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; @@ -141,8 +142,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly @@ -154,8 +154,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly @@ -167,8 +166,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof TileCoordinatesImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -180,8 +178,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof TileCoordinatesImageryProvider.prototype * @type {Number} * @readonly @@ -193,8 +190,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof TileCoordinatesImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -206,8 +202,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof TileCoordinatesImageryProvider.prototype * @type {Rectangle} * @readonly @@ -221,8 +216,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof TileCoordinatesImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -252,9 +246,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * @memberof TileCoordinatesImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.ready", + "TileCoordinatesImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return true; }, }, @@ -264,16 +263,21 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * @memberof TileCoordinatesImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.readyPromise", + "TileCoordinatesImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * the source of the imagery. * @memberof TileCoordinatesImageryProvider.prototype * @type {Credit} * @readonly @@ -308,8 +312,6 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ TileCoordinatesImageryProvider.prototype.getTileCredits = function ( x, @@ -320,8 +322,7 @@ TileCoordinatesImageryProvider.prototype.getTileCredits = function ( }; /** - * Requests the image for a given tile. This function should - * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index 8054dd12933..749e94ef673 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -1,8 +1,8 @@ import Cartesian2 from "../Core/Cartesian2.js"; import Cartographic from "../Core/Cartographic.js"; +import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; import GeographicProjection from "../Core/GeographicProjection.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; import Rectangle from "../Core/Rectangle.js"; @@ -18,7 +18,7 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; * * Initialization options for the TileMapServiceImageryProvider constructor * - * @property {Resource|String|Promise|Promise} [url='.'] Path to image tiles on server. + * @property {Resource|String|Promise|Promise} [url] Path to image tiles on server. Deprecated * @property {String} [fileExtension='png'] The file extension for images on the server. * @property {Credit|String} [credit=''] A credit for the data source, which is displayed on the canvas. * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying @@ -35,10 +35,15 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; * @property {Number} [tileWidth=256] Pixel width of image tiles. * @property {Number} [tileHeight=256] Pixel height of image tiles. * @property {Boolean} [flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml. + * @property {TileDiscardPolicy} [tileDiscardPolicy] A policy for discarding tile images according to some criteria * Specifying this option will do the same, allowing for loading of these incorrect tilesets. */ /** + *
+ * To construct a TileMapServiceImageryProvider, call {@link TileMapServiceImageryProvider.fromUrl}. Do not call the constructor directly. + *
+ * * An imagery provider that provides tiled imagery as generated by * {@link http://www.maptiler.org/|MapTiler}, {@link http://www.klokan.cz/projects/gdal2tiles/|GDAL2Tiles}, etc. * @@ -58,11 +63,11 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; * @see UrlTemplateImageryProvider * * @example - * const tms = new Cesium.TileMapServiceImageryProvider({ - * url : '../images/cesium_maptiler/Cesium_Logo_Color', - * fileExtension: 'png', - * maximumLevel: 4, - * rectangle: new Cesium.Rectangle( + * const tms = await Cesium.TileMapServiceImageryProvider.fromUrl( + * '../images/cesium_maptiler/Cesium_Logo_Color', { + * fileExtension: 'png', + * maximumLevel: 4, + * rectangle: new Cesium.Rectangle( * Cesium.Math.toRadians(-120.0), * Cesium.Math.toRadians(20.0), * Cesium.Math.toRadians(-60.0), @@ -72,42 +77,115 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; function TileMapServiceImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - if (!defined(options.url)) { - throw new DeveloperError("options.url is required."); + if (defined(options.url)) { + this._metadataError = undefined; + + let resource; + const that = this; + const promise = Promise.resolve(options.url) + .then(function (url) { + resource = Resource.createIfNeeded(url); + resource.appendForwardSlash(); + + that._tmsResource = resource; + that._xmlResource = resource.getDerivedResource({ + url: "tilemapresource.xml", + }); + + return TileMapServiceImageryProvider._requestMetadata( + options, + that._tmsResource, + that._xmlResource, + that + ); + }) + .catch((e) => { + return Promise.reject(e); + }); + + UrlTemplateImageryProvider.call(this, promise); + this._promise = promise; } + + // After readyPromise deprecation, this should become just + // UrlTemplateImageryProvider.call(this, options); +} + +TileMapServiceImageryProvider._requestMetadata = async function ( + options, + tmsResource, + xmlResource, + provider +) { + // Try to load remaining parameters from XML + try { + const xml = await xmlResource.fetchXML(); + return TileMapServiceImageryProvider._metadataSuccess( + xml, + options, + tmsResource, + xmlResource, + provider + ); + } catch (e) { + if (e instanceof RequestErrorEvent) { + return TileMapServiceImageryProvider._metadataFailure( + options, + tmsResource + ); + } + + throw e; + } +}; +/** + * Creates a TileMapServiceImageryProvider from the specified url. + * + * @param {Resource|String} url Path to image tiles on server. + * @param {TileMapServiceImageryProvider.ConstructorOptions} [options] Object describing initialization options. + * @returns {Promise} A promise that resolves to the created TileMapServiceImageryProvider. + * + * @example + * const tms = await Cesium.TileMapServiceImageryProvider.fromUrl( + * '../images/cesium_maptiler/Cesium_Logo_Color', { + * fileExtension: 'png', + * maximumLevel: 4, + * rectangle: new Cesium.Rectangle( + * Cesium.Math.toRadians(-120.0), + * Cesium.Math.toRadians(20.0), + * Cesium.Math.toRadians(-60.0), + * Cesium.Math.toRadians(40.0)) + * }); + * + * @exception {RuntimeError} Unable to find expected tilesets or bbox attributes in tilemapresource.xml + * @exception {RuntimeError} tilemapresource.xml specifies an unsupported profile attribute + */ +TileMapServiceImageryProvider.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); //>>includeEnd('debug'); - this._tmsResource = undefined; - this._xmlResource = undefined; - this._options = options; - this._metadataError = undefined; - - this._metadataSuccess = this._metadataSuccess.bind(this); - this._metadataFailure = this._metadataFailure.bind(this); - this._requestMetadata = this._requestMetadata.bind(this); - - let resource; - const that = this; - const promise = Promise.resolve(options.url) - .then(function (url) { - resource = Resource.createIfNeeded(url); - resource.appendForwardSlash(); - - that._tmsResource = resource; - that._xmlResource = resource.getDerivedResource({ - url: "tilemapresource.xml", - }); + const resource = Resource.createIfNeeded(url); + resource.appendForwardSlash(); + + const tmsResource = resource; + const xmlResource = resource.getDerivedResource({ + url: "tilemapresource.xml", + }); - return that._requestMetadata(); - }) - .catch((e) => { - return Promise.reject(e); - }); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const metadata = await TileMapServiceImageryProvider._requestMetadata( + options, + tmsResource, + xmlResource + ); - UrlTemplateImageryProvider.call(this, promise); - this._promise = promise; -} + // Once the deprecated behavior is removed, this can become + // return new TileMapServiceImageryProvider(metadata); + const provider = new TileMapServiceImageryProvider(); + UrlTemplateImageryProvider.call(provider, metadata); + return provider; +}; if (defined(Object.create)) { TileMapServiceImageryProvider.prototype = Object.create( @@ -116,19 +194,6 @@ if (defined(Object.create)) { TileMapServiceImageryProvider.prototype.constructor = TileMapServiceImageryProvider; } -TileMapServiceImageryProvider.prototype._requestMetadata = function () { - // Try to load remaining parameters from XML - return this._xmlResource - .fetchXML() - .then(this._metadataSuccess) - .catch((e) => { - if (e instanceof RequestErrorEvent) { - return this._metadataFailure(); - } - return Promise.reject(e); - }); -}; - /** * Mutates the properties of a given rectangle so it does not extend outside of the given tiling scheme's rectangle * @private @@ -173,16 +238,31 @@ function calculateSafeMinimumDetailLevel( return minimumLevel; } -TileMapServiceImageryProvider.prototype._metadataSuccess = function (xml) { +/** + * Parses the results of a successful xml request + * @private + * + * @param {Object} xml + * @param {TileMapServiceImageryProvider.ConstructorOptions} options + * @param {Resource} tmsResource + * @param {Resource} xmlResource + * @returns {UrlTemplateImageryProvider.ConstructorOptions} + */ +TileMapServiceImageryProvider._metadataSuccess = function ( + xml, + options, + tmsResource, + xmlResource, + provider +) { const tileFormatRegex = /tileformat/i; const tileSetRegex = /tileset/i; const tileSetsRegex = /tilesets/i; const bboxRegex = /boundingbox/i; let format, bbox, tilesets; const tilesetsList = []; //list of TileSets - const xmlResource = this._xmlResource; - let metadataError = this._metadataError; - const requestMetadata = this._requestMetadata; + + // TODO: Check for error? https://github.com/CesiumGS/cesium/issues/6242 // Allowing options properties (already copied to that) to override XML values @@ -209,20 +289,18 @@ TileMapServiceImageryProvider.prototype._metadataSuccess = function (xml) { let message; if (!defined(tilesets) || !defined(bbox)) { message = `Unable to find expected tilesets or bbox attributes in ${xmlResource.url}.`; - metadataError = TileProviderError.reportError( - metadataError, - this, - this.errorEvent, - message - ); - if (metadataError.retry) { - this._metadataError = metadataError; - return requestMetadata(); + if (defined(provider)) { + TileProviderError.reportError( + undefined, + provider, + provider.errorEvent, + message + ); } - return Promise.reject(new RuntimeError(message)); + + throw new RuntimeError(message); } - const options = this._options; const fileExtension = defaultValue( options.fileExtension, format.getAttribute("extension") @@ -262,18 +340,17 @@ TileMapServiceImageryProvider.prototype._metadataSuccess = function (xml) { ellipsoid: options.ellipsoid, }); } else { - message = `${xmlResource.url}specifies an unsupported profile attribute, ${tilingSchemeName}.`; - metadataError = TileProviderError.reportError( - metadataError, - this, - this.errorEvent, - message - ); - if (metadataError.retry) { - this._metadataError = metadataError; - return requestMetadata(); + message = `${xmlResource.url} specifies an unsupported profile attribute, ${tilingSchemeName}.`; + if (defined(provider)) { + TileProviderError.reportError( + undefined, + provider, + provider.errorEvent, + message + ); } - return Promise.reject(new RuntimeError(message)); + + throw new RuntimeError(message); } } @@ -344,11 +421,11 @@ TileMapServiceImageryProvider.prototype._metadataSuccess = function (xml) { minimumLevel ); - const templateResource = this._tmsResource.getDerivedResource({ + const templateResource = tmsResource.getDerivedResource({ url: `{z}/{x}/{reverseY}.${fileExtension}`, }); - return Promise.resolve({ + return { url: templateResource, tilingScheme: tilingScheme, rectangle: rectangle, @@ -358,12 +435,22 @@ TileMapServiceImageryProvider.prototype._metadataSuccess = function (xml) { maximumLevel: maximumLevel, tileDiscardPolicy: options.tileDiscardPolicy, credit: options.credit, - }); + }; }; -TileMapServiceImageryProvider.prototype._metadataFailure = function () { +/** + * Handle xml request failure by providing the default values + * @private + * + * @param {TileMapServiceImageryProvider.ConstructorOptions} options + * @param {Resource} tmsResource + * @returns {UrlTemplateImageryProvider.ConstructorOptions} + */ +TileMapServiceImageryProvider._metadataFailure = function ( + options, + tmsResource +) { // Can't load XML, still allow options and defaults - const options = this._options; const fileExtension = defaultValue(options.fileExtension, "png"); const tileWidth = defaultValue(options.tileWidth, 256); const tileHeight = defaultValue(options.tileHeight, 256); @@ -383,11 +470,11 @@ TileMapServiceImageryProvider.prototype._metadataFailure = function () { options.minimumLevel ); - const templateResource = this._tmsResource.getDerivedResource({ + const templateResource = tmsResource.getDerivedResource({ url: `{z}/{x}/{reverseY}.${fileExtension}`, }); - return Promise.resolve({ + return { url: templateResource, tilingScheme: tilingScheme, rectangle: rectangle, @@ -397,7 +484,7 @@ TileMapServiceImageryProvider.prototype._metadataFailure = function () { maximumLevel: maximumLevel, tileDiscardPolicy: options.tileDiscardPolicy, credit: options.credit, - }); + }; }; export default TileMapServiceImageryProvider; diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index a6aa08654ee..3feb3ce5b5a 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -1,10 +1,12 @@ import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartographic from "../Core/Cartographic.js"; +import Check from "../Core/Check.js"; import combine from "../Core/combine.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import Event from "../Core/Event.js"; import GeographicProjection from "../Core/GeographicProjection.js"; @@ -134,6 +136,7 @@ const pickFeaturesTags = combine(tags, { * source does not support picking features or if you don't want this provider's features to be pickable. Note * that this can be dynamically overridden by modifying the {@link UriTemplateImageryProvider#enablePickFeatures} * property. + * @property {TileDiscardPolicy} [tileDiscardPolicy] A policy for discarding tile images according to some criteria * @property {Object} [customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values. */ @@ -188,32 +191,71 @@ const pickFeaturesTags = combine(tags, { * @see WebMapTileServiceImageryProvider */ function UrlTemplateImageryProvider(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + this._errorEvent = new Event(); + + if (defined(options.then)) { + this._reinitialize(options); + return; + } + //>>includeStart('debug', pragmas.debug); - if (!defined(options)) { - throw new DeveloperError("options is required."); + Check.defined("options.url", options.url); + //>>includeEnd('debug'); + + const resource = Resource.createIfNeeded(options.url); + const pickFeaturesResource = Resource.createIfNeeded(options.pickFeaturesUrl); + + this._resource = resource; + this._urlSchemeZeroPadding = options.urlSchemeZeroPadding; + this._getFeatureInfoFormats = options.getFeatureInfoFormats; + this._pickFeaturesResource = pickFeaturesResource; + + let subdomains = options.subdomains; + if (Array.isArray(subdomains)) { + subdomains = subdomains.slice(); + } else if (defined(subdomains) && subdomains.length > 0) { + subdomains = subdomains.split(""); + } else { + subdomains = ["a", "b", "c"]; } - if (!defined(options.then) && !defined(options.url)) { - throw new DeveloperError("options is required."); + this._subdomains = subdomains; + + this._tileWidth = defaultValue(options.tileWidth, 256); + this._tileHeight = defaultValue(options.tileHeight, 256); + this._minimumLevel = defaultValue(options.minimumLevel, 0); + this._maximumLevel = options.maximumLevel; + this._tilingScheme = defaultValue( + options.tilingScheme, + new WebMercatorTilingScheme({ ellipsoid: options.ellipsoid }) + ); + + this._rectangle = defaultValue( + options.rectangle, + this._tilingScheme.rectangle + ); + this._rectangle = Rectangle.intersection( + this._rectangle, + this._tilingScheme.rectangle + ); + + this._tileDiscardPolicy = options.tileDiscardPolicy; + + let credit = options.credit; + if (typeof credit === "string") { + credit = new Credit(credit); } - //>>includeEnd('debug'); + this._credit = credit; + this._hasAlphaChannel = defaultValue(options.hasAlphaChannel, true); - this._errorEvent = new Event(); + const customTags = options.customTags; + const allTags = combine(tags, customTags); + const allPickFeaturesTags = combine(pickFeaturesTags, customTags); + this._tags = allTags; + this._pickFeaturesTags = allPickFeaturesTags; - this._resource = undefined; - this._urlSchemeZeroPadding = undefined; - this._pickFeaturesResource = undefined; - this._tileWidth = undefined; - this._tileHeight = undefined; - this._maximumLevel = undefined; - this._minimumLevel = undefined; - this._tilingScheme = undefined; - this._rectangle = undefined; - this._tileDiscardPolicy = undefined; - this._credit = undefined; - this._hasAlphaChannel = undefined; - this._readyPromise = undefined; - this._tags = undefined; - this._pickFeaturesTags = undefined; + this._readyPromise = Promise.resolve(true); /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and @@ -310,9 +352,7 @@ function UrlTemplateImageryProvider(options) { * @type {Boolean} * @default true */ - this.enablePickFeatures = true; - - this.reinitialize(options); + this.enablePickFeatures = defaultValue(options.enablePickFeatures, true); } Object.defineProperties(UrlTemplateImageryProvider.prototype, { @@ -411,8 +451,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof UrlTemplateImageryProvider.prototype * @type {Number} * @readonly @@ -420,20 +459,12 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof UrlTemplateImageryProvider.prototype * @type {Number} * @readonly @@ -441,20 +472,12 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._tileHeight; }, }, /** * Gets the maximum level-of-detail that can be requested, or undefined if there is no limit. - * This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -462,20 +485,12 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof UrlTemplateImageryProvider.prototype * @type {Number} * @readonly @@ -483,20 +498,12 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._minimumLevel; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof UrlTemplateImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -504,20 +511,12 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._tilingScheme; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof UrlTemplateImageryProvider.prototype * @type {Rectangle} * @readonly @@ -525,13 +524,6 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "rectangle must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._rectangle; }, }, @@ -539,8 +531,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof UrlTemplateImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -548,13 +539,6 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._tileDiscardPolicy; }, }, @@ -578,9 +562,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * @memberof UrlTemplateImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.ready", + "UrlTemplateImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return defined(this._resource); }, }, @@ -590,16 +579,21 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * @memberof UrlTemplateImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.readyPromise", + "UrlTemplateImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. + * the source of the imagery. * @memberof UrlTemplateImageryProvider.prototype * @type {Credit} * @readonly @@ -607,13 +601,6 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ credit: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "credit must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._credit; }, }, @@ -623,8 +610,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * include an alpha channel. If this property is false, an alpha channel, if present, will * be ignored. If this property is true, any images without an alpha channel will be treated * as if their alpha is 1.0 everywhere. When this property is false, memory usage - * and texture upload time are reduced. This function should - * not be called before {@link ImageryProvider#ready} returns true. + * and texture upload time are reduced. * @memberof UrlTemplateImageryProvider.prototype * @type {Boolean} * @readonly @@ -632,13 +618,6 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { */ hasAlphaChannel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "hasAlphaChannel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return this._hasAlphaChannel; }, }, @@ -647,11 +626,25 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { /** * Reinitializes this instance. Reinitializing an instance already in use is supported, but it is not * recommended because existing tiles provided by the imagery provider will not be updated. + * @deprecated * * @param {Promise.|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. */ UrlTemplateImageryProvider.prototype.reinitialize = function (options) { + deprecationWarning( + "UrlTemplateImageryProvider.reinitialize", + "UrlTemplateImageryProvider.reinitialize was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); + + return this._reinitialize(options); +}; + +/** + * @private + */ +UrlTemplateImageryProvider.prototype._reinitialize = function (options) { const that = this; + that._readyPromise = Promise.resolve(options).then(function (properties) { //>>includeStart('debug', pragmas.debug); if (!defined(properties)) { @@ -730,24 +723,12 @@ UrlTemplateImageryProvider.prototype.reinitialize = function (options) { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ UrlTemplateImageryProvider.prototype.getTileCredits = function (x, y, level) { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "getTileCredits must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return undefined; }; /** - * Requests the image for a given tile. This function should - * not be called before {@link UrlTemplateImageryProvider#ready} returns true. - * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level. @@ -761,13 +742,6 @@ UrlTemplateImageryProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); return ImageryProvider.loadImage( this, buildImageResource(this, x, y, level, request) @@ -776,7 +750,7 @@ UrlTemplateImageryProvider.prototype.requestImage = function ( /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * a tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -795,14 +769,6 @@ UrlTemplateImageryProvider.prototype.pickFeatures = function ( longitude, latitude ) { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "pickFeatures must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - if ( !this.enablePickFeatures || !defined(this._pickFeaturesResource) || diff --git a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js index 8364208a249..2f552db8ff3 100644 --- a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js @@ -1,5 +1,6 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; import Resource from "../Core/Resource.js"; @@ -410,8 +411,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof WebMapServiceImageryProvider.prototype * @type {Number} * @readonly @@ -423,8 +423,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof WebMapServiceImageryProvider.prototype * @type {Number} * @readonly @@ -436,8 +435,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof WebMapServiceImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -449,8 +447,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof WebMapServiceImageryProvider.prototype * @type {Number} * @readonly @@ -462,8 +459,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof WebMapServiceImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -475,8 +471,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof WebMapServiceImageryProvider.prototype * @type {Rectangle} * @readonly @@ -490,8 +485,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof WebMapServiceImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -521,9 +515,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * @memberof WebMapServiceImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.ready", + "WebMapServiceImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._tileProvider.ready; }, }, @@ -533,16 +532,21 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * @memberof WebMapServiceImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.readyPromise", + "WebMapServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._tileProvider.readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * the source of the imagery. * @memberof WebMapServiceImageryProvider.prototype * @type {Credit} * @readonly @@ -637,16 +641,13 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ WebMapServiceImageryProvider.prototype.getTileCredits = function (x, y, level) { return this._tileProvider.getTileCredits(x, y, level); }; /** - * Requests the image for a given tile. This function should - * not be called before {@link WebMapServiceImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -654,8 +655,6 @@ WebMapServiceImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ WebMapServiceImageryProvider.prototype.requestImage = function ( x, @@ -688,7 +687,7 @@ WebMapServiceImageryProvider.prototype.requestImage = function ( /** * Asynchronously determines what features, if any, are located at a given longitude and latitude within - * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. + * a tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -698,8 +697,6 @@ WebMapServiceImageryProvider.prototype.requestImage = function ( * @return {Promise.|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. - * - * @exception {DeveloperError} pickFeatures must not be called before the imagery provider is ready. */ WebMapServiceImageryProvider.prototype.pickFeatures = function ( x, diff --git a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js index 18eb431deb2..e544e5871fd 100644 --- a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js @@ -2,6 +2,7 @@ import combine from "../Core/combine.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import Event from "../Core/Event.js"; import Rectangle from "../Core/Rectangle.js"; @@ -412,8 +413,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly @@ -425,8 +425,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly @@ -438,8 +437,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number|undefined} * @readonly @@ -451,8 +449,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Number} * @readonly @@ -464,8 +461,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof WebMapTileServiceImageryProvider.prototype * @type {TilingScheme} * @readonly @@ -477,8 +473,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Rectangle} * @readonly @@ -492,8 +487,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof WebMapTileServiceImageryProvider.prototype * @type {TileDiscardPolicy} * @readonly @@ -535,9 +529,16 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * @memberof WebMapTileServiceImageryProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { - value: true, + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.ready", + "WebMapTileServiceImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); + return true; + }, }, /** @@ -545,16 +546,21 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * @memberof WebMapTileServiceImageryProvider.prototype * @type {Promise.} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.readyPromise", + "WebMapTileServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * the source of the imagery. * @memberof WebMapTileServiceImageryProvider.prototype * @type {Credit} * @readonly @@ -635,8 +641,6 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ WebMapTileServiceImageryProvider.prototype.getTileCredits = function ( x, @@ -647,8 +651,7 @@ WebMapTileServiceImageryProvider.prototype.getTileCredits = function ( }; /** - * Requests the image for a given tile. This function should - * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -656,8 +659,6 @@ WebMapTileServiceImageryProvider.prototype.getTileCredits = function ( * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} requestImage must not be called before the imagery provider is ready. */ WebMapTileServiceImageryProvider.prototype.requestImage = function ( x, diff --git a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js index 510e05e2db2..6e5e86fb3cc 100644 --- a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js @@ -20,6 +20,7 @@ import { Request, RequestScheduler, Resource, + RuntimeError, WebMercatorProjection, WebMercatorTilingScheme, } from "../../index.js"; @@ -100,12 +101,6 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { ); }); - it("constructor throws if url is not specified", function () { - expect(function () { - return new ArcGisMapServerImageryProvider({}); - }).toThrowDeveloperError(); - }); - const webMercatorResult = { currentVersion: 10.01, copyrightText: "Test copyright text", @@ -190,6 +185,169 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); }); + it("fromUrl throws if url is not provided", async function () { + await expectAsync( + ArcGisMapServerImageryProvider.fromUrl() + ).toBeRejectedWithDeveloperError( + "url is required, actual value was undefined" + ); + }); + + it("fromUrl resolves with created provider", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + stubJSONPCall(baseUrl, webMercatorResult); + + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); + expect(provider).toBeInstanceOf(ArcGisMapServerImageryProvider); + expect(provider.url).toEqual(baseUrl); + }); + + it("fromUrl resolves with created provider with Resource parameter", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + stubJSONPCall(baseUrl, webMercatorResult); + + const resource = new Resource({ + url: baseUrl, + }); + + const provider = await ArcGisMapServerImageryProvider.fromUrl(resource); + expect(provider).toBeInstanceOf(ArcGisMapServerImageryProvider); + expect(provider.url).toEqual(baseUrl); + }); + + it("fromUrl throws if request fails", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + await expectAsync( + ArcGisMapServerImageryProvider.fromUrl(baseUrl) + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing //tiledArcGisMapServer.invalid/" + ); + }); + + it("fromUrl throws on unsupported WKID", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + const unsupportedWKIDResult = { + currentVersion: 10.01, + copyrightText: "Test copyright text", + tileInfo: { + rows: 128, + cols: 256, + origin: { + x: -180, + y: 90, + }, + spatialReference: { + wkid: 1234, + }, + lods: [ + { + level: 0, + resolution: 0.3515625, + scale: 147748799.285417, + }, + { + level: 1, + resolution: 0.17578125, + scale: 73874399.6427087, + }, + { + level: 2, + resolution: 0.087890625, + scale: 36937199.8213544, + }, + ], + }, + }; + + stubJSONPCall(baseUrl, unsupportedWKIDResult); + + await expectAsync( + ArcGisMapServerImageryProvider.fromUrl(baseUrl) + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing //tiledArcGisMapServer.invalid/: Tile spatial reference WKID 1234 is not supported." + ); + }); + + it("fromUrl throws if request fails", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + const unsupportedFullExtentWKIDResult = { + currentVersion: 10.01, + copyrightText: "Test copyright text", + tileInfo: { + rows: 128, + cols: 256, + origin: { + x: -20037508.342787, + y: 20037508.342787, + }, + spatialReference: { + wkid: 102100, + }, + lods: [ + { + level: 0, + resolution: 156543.033928, + scale: 591657527.591555, + }, + { + level: 1, + resolution: 78271.5169639999, + scale: 295828763.795777, + }, + { + level: 2, + resolution: 39135.7584820001, + scale: 147914381.897889, + }, + ], + }, + fullExtent: { + xmin: 1.1148026611962173e7, + ymin: -6443518.758206591, + xmax: 1.8830976498143446e7, + ymax: -265936.19697360107, + spatialReference: { + wkid: 1234, + }, + }, + }; + + stubJSONPCall(baseUrl, unsupportedFullExtentWKIDResult); + + await expectAsync( + ArcGisMapServerImageryProvider.fromUrl(baseUrl) + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing //tiledArcGisMapServer.invalid/: fullExtent.spatialReference WKID 1234 is not supported." + ); + }); + + it("fromUrl creates provider for tiled servers in web mercator projection", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + stubJSONPCall(baseUrl, webMercatorResult); + + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); + expect(provider.tileWidth).toEqual(128); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(2); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeInstanceOf( + DiscardMissingTileImagePolicy + ); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(true); + expect(provider.hasAlphaChannel).toBeDefined(); + }); + it("supports tiled servers in web mercator projection", function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; @@ -382,6 +540,24 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); }); + it("fromUrl creates provider for tiled servers in geographic projection", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid"; + + stubJSONPCall(baseUrl, geographicResult); + + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); + expect(provider.tileWidth).toEqual(128); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(2); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeInstanceOf( + DiscardMissingTileImagePolicy + ); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(true); + }); + it("supports non-tiled servers", function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; @@ -445,6 +621,26 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); }); + it("fromUrl creates provider for non-tiled servers", async function () { + const baseUrl = "//tiledArcGisMapServer.invalid/"; + + stubJSONPCall(baseUrl, { + currentVersion: 10.01, + copyrightText: "Test copyright text", + }); + + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeUndefined(); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(false); + expect(provider.enablePickFeatures).toBe(true); + }); + it("supports non-tiled servers with various constructor parameters", function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; const token = "5e(u|2!7Y"; @@ -662,12 +858,8 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { let tries = 0; provider.errorEvent.addEventListener(function (error) { const isWKIDError = error.message.indexOf("WKID") >= 0; - if (isWKIDError) { - ++tries; - if (tries < 3) { - error.retry = true; - } - } + expect(isWKIDError).toBeTrue(); + tries++; }); return provider.readyPromise @@ -676,7 +868,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }) .catch(function () { expect(provider.ready).toEqual(false); - expect(tries).toEqual(3); + expect(tries).toEqual(1); }); }); @@ -1019,12 +1211,8 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { let tries = 0; provider.errorEvent.addEventListener(function (error) { const isWKIDError = error.message.indexOf("WKID") >= 0; - if (isWKIDError) { - ++tries; - if (tries < 3) { - error.retry = true; - } - } + expect(isWKIDError).toBeTrue(); + ++tries; }); return provider.readyPromise @@ -1033,7 +1221,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }) .catch(function () { expect(provider.ready).toEqual(false); - expect(tries).toEqual(3); + expect(tries).toEqual(1); }); }); diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index 92dc50b1e28..16a452069e1 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -12,6 +12,7 @@ import { queryToObject, RequestScheduler, Resource, + RuntimeError, WebMercatorTilingScheme, } from "../../index.js"; @@ -80,16 +81,6 @@ describe("Scene/BingMapsImageryProvider", function () { expect(BingMapsImageryProvider).toConformToInterface(ImageryProvider); }); - it("constructor throws when url is not specified", function () { - function constructWithoutServer() { - return new BingMapsImageryProvider({ - mapStyle: BingMapsStyle.AERIAL, - key: "", - }); - } - expect(constructWithoutServer).toThrowDeveloperError(); - }); - it("constructor throws when key is not specified", function () { function constructWithoutServer() { return new BingMapsImageryProvider({ @@ -431,73 +422,210 @@ describe("Scene/BingMapsImageryProvider", function () { }); }); - it("returns valid value for hasAlphaChannel", function () { - const url = "http://fake.fake.invalid"; - const mapStyle = BingMapsStyle.AERIAL; + it("fromUrl throws if url is not provided", async function () { + await expectAsync( + BingMapsImageryProvider.fromUrl() + ).toBeRejectedWithDeveloperError( + "url is required, actual value was undefined" + ); + }); + + it("fromUrl throws if key is not provided", async function () { + await expectAsync( + BingMapsImageryProvider.fromUrl("http://fake.fake.invalid/") + ).toBeRejectedWithDeveloperError( + "key is required, actual value was undefined" + ); + }); + + it("fromUrl resolves with created provider", async function () { + const url = "http://fake.fake.invalid/"; + const mapStyle = BingMapsStyle.ROAD; installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = new BingMapsImageryProvider({ + const provider = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, + }); + expect(provider).toBeInstanceOf(BingMapsImageryProvider); + expect(provider.url).toEqual(url); + }); + + it("fromUrl uses cached metadata result", async function () { + const url = "http://fake.fake.invalid/"; + const mapStyle = BingMapsStyle.ROAD; + + installFakeMetadataRequest(url, mapStyle); + installFakeImageRequest(); + + const provider = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, + }); + const provider2 = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, + }); + + //These are the same instance only if the cache has been used + expect(provider._attributionList).toBe(provider2._attributionList); + + installFakeMetadataRequest(url, BingMapsStyle.AERIAL); + installFakeImageRequest(); + + const provider3 = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: BingMapsStyle.AERIAL, + }); + + // Because the road is different, a non-cached request should have happened + expect(provider3._attributionList).not.toBe(provider._attributionList); + }); + + it("fromUrl resolves with a path", async function () { + const url = "http://fake.fake.invalid/some/subdirectory"; + const mapStyle = BingMapsStyle.ROAD; + + installFakeMetadataRequest(url, mapStyle); + installFakeImageRequest(); + + const provider = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, + }); + expect(provider).toBeInstanceOf(BingMapsImageryProvider); + expect(provider.url).toEqual(`${url}/`); + }); + + it("fromUrl resolves with a path ending with a slash", async function () { + const url = "http://fake.fake.invalid/some/subdirectory/"; + const mapStyle = BingMapsStyle.ROAD; + + installFakeMetadataRequest(url, mapStyle); + installFakeImageRequest(); + + const provider = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, + }); + expect(provider).toBeInstanceOf(BingMapsImageryProvider); + expect(provider.url).toEqual(url); + }); + + it("fromUrl resolves with Resource", async function () { + const url = "http://fake.fake.invalid/"; + const mapStyle = BingMapsStyle.ROAD; + + installFakeMetadataRequest(url, mapStyle); + installFakeImageRequest(); + + const resource = new Resource({ url: url, + }); + + const provider = await BingMapsImageryProvider.fromUrl(resource, "", { mapStyle: mapStyle, - key: "", }); + expect(provider).toBeInstanceOf(BingMapsImageryProvider); + expect(provider.url).toEqual(url); + }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(typeof provider.hasAlphaChannel).toBe("boolean"); + it("fromUrl throws if request fails", async function () { + const url = "http://fake.fake.invalid"; + + await expectAsync( + BingMapsImageryProvider.fromUrl(url, "") + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial?jsonp=loadJsonp321911&incl=ImageryProviders&key=&uriScheme=http" + ); + }); + + it("fromUrl throws if metadata does not specify one resource in resourceSets", async function () { + const url = "http://fake.fake.invalid"; + + const baseUri = new Uri(appendForwardSlash(url)); + const expectedUri = new Uri( + `REST/v1/Imagery/Metadata/${BingMapsStyle.AERIAL}` + ).absoluteTo(baseUri); + + Resource._Implementations.loadAndExecuteScript = function ( + url, + functionName + ) { + const uri = new Uri(url); + const query = queryToObject(uri.query()); + expect(query.jsonp).toBeDefined(); + expect(query.incl).toEqual("ImageryProviders"); + expect(query.key).toBeDefined(); + + uri.query(""); + expect(uri.toString()).toStartWith(expectedUri.toString()); + + setTimeout(function () { + const response = createFakeMetadataResponse(BingMapsStyle.AERIAL); + response.resourceSets = []; + window[functionName](response); + }, 1); + }; + installFakeImageRequest(); + + await expectAsync( + BingMapsImageryProvider.fromUrl(url, "") + ).toBeRejectedWithError( + RuntimeError, + "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial?jsonp=loadJsonp700536&incl=ImageryProviders&key=&uriScheme=http: metadata does not specify one resource in resourceSets" + ); + }); + + it("returns valid value for hasAlphaChannel", async function () { + const url = "http://fake.fake.invalid"; + const mapStyle = BingMapsStyle.AERIAL; + + installFakeMetadataRequest(url, mapStyle); + installFakeImageRequest(); + + const provider = await BingMapsImageryProvider.fromUrl(url, "", { + mapStyle: mapStyle, }); + + expect(typeof provider.hasAlphaChannel).toBe("boolean"); }); - it("can provide a root tile", function () { + it("can provide a root tile", async function () { const url = "http://fake.fake.invalid"; const mapStyle = BingMapsStyle.ROAD; installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = new BingMapsImageryProvider({ - url: url, + const provider = await BingMapsImageryProvider.fromUrl(url, "fake Key", { mapStyle: mapStyle, - key: "fake Key", }); expect(provider.url).toStartWith(url); expect(provider.key).toBeDefined(); expect(provider.mapStyle).toEqual(mapStyle); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toEqual(20); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.tileDiscardPolicy).toBeInstanceOf( - DiscardEmptyTileImagePolicy - ); - expect(provider.rectangle).toEqual( - new WebMercatorTilingScheme().rectangle - ); - expect(provider.credit).toBeInstanceOf(Object); - - installFakeImageRequest( - "http://ecn.t0.tiles.virtualearth.net.fake.invalid/tiles/r0.jpeg", - { - g: "3031", - mkt: "", - } - ); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(20); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.tileDiscardPolicy).toBeInstanceOf( + DiscardEmptyTileImagePolicy + ); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); + expect(provider.credit).toBeInstanceOf(Object); + + installFakeImageRequest( + "http://ecn.t0.tiles.virtualearth.net.fake.invalid/tiles/r0.jpeg", + { + g: "3031", + mkt: "", + } + ); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); - }); + const image = await provider.requestImage(0, 0, 0); + expect(image).toBeImageOrImageBitmap(); }); - it("sets correct culture in tile requests", function () { + it("sets correct culture in tile requests", async function () { const url = "http://fake.fake.invalid"; const mapStyle = BingMapsStyle.AERIAL_WITH_LABELS; @@ -506,66 +634,34 @@ describe("Scene/BingMapsImageryProvider", function () { const culture = "ja-jp"; - const provider = new BingMapsImageryProvider({ - url: url, + const provider = await BingMapsImageryProvider.fromUrl(url, "", { mapStyle: mapStyle, culture: culture, - key: "", }); expect(provider.culture).toEqual(culture); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - installFakeImageRequest( - "http://ecn.t0.tiles.virtualearth.net.fake.invalid/tiles/h0.jpeg", - { - g: "3031", - mkt: "ja-jp", - } - ); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); - }); - }); - - it("raises error on invalid url", function () { - const url = "http://host.invalid"; - const provider = new BingMapsImageryProvider({ - url: url, - key: "", - }); - - let errorEventRaised = false; - provider.errorEvent.addEventListener(function (error) { - expect(error.message).toContain(url); - errorEventRaised = true; - }); + installFakeImageRequest( + "http://ecn.t0.tiles.virtualearth.net.fake.invalid/tiles/h0.jpeg", + { + g: "3031", + mkt: "ja-jp", + } + ); - return provider.readyPromise - .then(function () { - fail(); - }) - .catch(function () { - expect(provider.ready).toEqual(false); - expect(errorEventRaised).toEqual(true); - }); + const image = await provider.requestImage(0, 0, 0); + expect(image).toBeImageOrImageBitmap(); }); - it("raises error event when image cannot be loaded", function () { + it("raises error event when image cannot be loaded", async function () { const url = "http://foo.bar.invalid"; const mapStyle = BingMapsStyle.ROAD; installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = new BingMapsImageryProvider({ - url: url, + const provider = await BingMapsImageryProvider.fromUrl(url, "", { mapStyle: mapStyle, - key: "", }); const layer = new ImageryLayer(provider); @@ -637,34 +733,28 @@ describe("Scene/BingMapsImageryProvider", function () { } }; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBeImageOrImageBitmap(); - expect(tries).toEqual(2); - imagery.releaseReference(); - }); + expect(imagery.image).toBeImageOrImageBitmap(); + expect(tries).toEqual(2); + imagery.releaseReference(); }); }); - it("correctly handles empty tiles", function () { + it("correctly handles empty tiles", async function () { const url = "http://foo.bar.invalid"; const mapStyle = BingMapsStyle.ROAD_ON_DEMAND; installFakeMetadataRequest(url, mapStyle); - const provider = new BingMapsImageryProvider({ - url: url, + const provider = await BingMapsImageryProvider.fromUrl(url, "", { mapStyle: mapStyle, - key: "", }); const layer = new ImageryLayer(provider); @@ -676,20 +766,16 @@ describe("Scene/BingMapsImageryProvider", function () { return Promise.reject(e); }); + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBe(DiscardEmptyTileImagePolicy.EMPTY_IMAGE); - imagery.releaseReference(); - }); + expect(imagery.image).toBe(DiscardEmptyTileImagePolicy.EMPTY_IMAGE); + imagery.releaseReference(); }); }); }); diff --git a/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js b/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js index 6ae93422a6f..d834e8925ae 100644 --- a/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/GoogleEarthEnterpriseImageryProviderSpec.js @@ -16,6 +16,7 @@ import { Request, RequestScheduler, Resource, + RuntimeError, } from "../../index.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; @@ -26,13 +27,12 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { }); let supportsImageBitmapOptions; - beforeAll(function () { + beforeAll(async function () { decodeGoogleEarthEnterpriseData.passThroughDataForTesting = true; // This suite spies on requests. Resource.supportsImageBitmapOptions needs to make a request to a data URI. // We run it here to avoid interfering with the tests. - return Resource.supportsImageBitmapOptions().then(function (result) { - supportsImageBitmapOptions = result; - }); + const result = Resource.supportsImageBitmapOptions(); + supportsImageBitmapOptions = result; }); afterAll(function () { @@ -53,14 +53,6 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { ); }); - it("constructor throws when url is not specified", function () { - function constructWithoutServer() { - return new GoogleEarthEnterpriseImageryProvider({}); - } - - expect(constructWithoutServer).toThrowDeveloperError(); - }); - function installMockGetQuadTreePacket() { spyOn( GoogleEarthEnterpriseMetadata.prototype, @@ -230,56 +222,84 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { }); }); - it("returns false for hasAlphaChannel", function () { + it("fromMetadata throws without metadata", function () { + expect(() => + GoogleEarthEnterpriseImageryProvider.fromMetadata() + ).toThrowDeveloperError(""); + }); + + it("fromMetadata throws if there isn't imagery", async function () { installMockGetQuadTreePacket(); - const url = "http://fake.fake.invalid"; - imageryProvider = new GoogleEarthEnterpriseImageryProvider({ - url: url, + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl({ + url: "made/up/url", }); - return pollToPromise(function () { - return imageryProvider.ready; - }).then(function () { - expect(typeof imageryProvider.hasAlphaChannel).toBe("boolean"); - expect(imageryProvider.hasAlphaChannel).toBe(false); - }); + metadata.imageryPresent = false; + + expect(() => + GoogleEarthEnterpriseImageryProvider.fromMetadata(metadata) + ).toThrowError( + RuntimeError, + "The server made/up/url/ doesn't have imagery" + ); }); - it("can provide a root tile", function () { + it("fromMetadata resolves to created provider", async function () { + installMockGetQuadTreePacket(); + const url = "http://fake.fake.invalid"; + + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); + imageryProvider = GoogleEarthEnterpriseImageryProvider.fromMetadata( + metadata + ); + + expect(imageryProvider).toBeInstanceOf( + GoogleEarthEnterpriseImageryProvider + ); + }); + + it("returns false for hasAlphaChannel", async function () { + installMockGetQuadTreePacket(); + const url = "http://fake.fake.invalid"; + + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); + imageryProvider = GoogleEarthEnterpriseImageryProvider.fromMetadata( + metadata + ); + + expect(typeof imageryProvider.hasAlphaChannel).toBe("boolean"); + expect(imageryProvider.hasAlphaChannel).toBe(false); + }); + + it("can provide a root tile", async function () { installMockGetQuadTreePacket(); const url = "http://fake.fake.invalid/"; - imageryProvider = new GoogleEarthEnterpriseImageryProvider({ - url: url, - }); + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); + imageryProvider = GoogleEarthEnterpriseImageryProvider.fromMetadata( + metadata + ); expect(imageryProvider.url).toEqual(url); - return pollToPromise(function () { - return imageryProvider.ready; - }).then(function () { - expect(imageryProvider.tileWidth).toEqual(256); - expect(imageryProvider.tileHeight).toEqual(256); - expect(imageryProvider.maximumLevel).toEqual(23); - expect(imageryProvider.tilingScheme).toBeInstanceOf( - GeographicTilingScheme - ); - // Defaults to custom tile policy - expect(imageryProvider.tileDiscardPolicy).not.toBeInstanceOf( - DiscardMissingTileImagePolicy - ); - expect(imageryProvider.rectangle).toEqual( - new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI) - ); - expect(imageryProvider.credit).toBeUndefined(); + expect(imageryProvider.tileWidth).toEqual(256); + expect(imageryProvider.tileHeight).toEqual(256); + expect(imageryProvider.maximumLevel).toEqual(23); + expect(imageryProvider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + // Defaults to custom tile policy + expect(imageryProvider.tileDiscardPolicy).not.toBeInstanceOf( + DiscardMissingTileImagePolicy + ); + expect(imageryProvider.rectangle).toEqual( + new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI) + ); + expect(imageryProvider.credit).toBeUndefined(); - installFakeImageRequest("http://fake.fake.invalid/flatfile?f1-03-i.1"); + installFakeImageRequest("http://fake.fake.invalid/flatfile?f1-03-i.1"); - return imageryProvider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); - }); + const image = await imageryProvider.requestImage(0, 0, 0); + expect(image).toBeImageOrImageBitmap(); }); it("raises error on invalid url", function () { @@ -307,14 +327,14 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { }); }); - it("raises error event when image cannot be loaded", function () { + it("raises error event when image cannot be loaded", async function () { installMockGetQuadTreePacket(); const url = "http://foo.bar.invalid"; - imageryProvider = new GoogleEarthEnterpriseImageryProvider({ - url: url, - }); - + const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); + imageryProvider = GoogleEarthEnterpriseImageryProvider.fromMetadata( + metadata + ); const layer = new ImageryLayer(imageryProvider); let tries = 0; @@ -356,21 +376,17 @@ describe("Scene/GoogleEarthEnterpriseImageryProvider", function () { } }; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return imageryProvider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBeImageOrImageBitmap(); - expect(tries).toEqual(2); - imagery.releaseReference(); - }); + expect(imagery.image).toBeImageOrImageBitmap(); + expect(tries).toEqual(2); + imagery.releaseReference(); }); }); }); diff --git a/packages/engine/Specs/Scene/IonImageryProviderSpec.js b/packages/engine/Specs/Scene/IonImageryProviderSpec.js index fa220d08f2e..efc9c4f7c88 100644 --- a/packages/engine/Specs/Scene/IonImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/IonImageryProviderSpec.js @@ -49,6 +49,37 @@ describe("Scene/IonImageryProvider", function () { return provider; } + async function createTestProviderAsync(endpointData) { + endpointData = defaultValue(endpointData, { + type: "IMAGERY", + url: "http://test.invalid/layer", + accessToken: "not_really_a_refresh_token", + attributions: [], + }); + + const assetId = 12335; + const options = {}; + const endpointResource = IonResource._createEndpointResource( + assetId, + options + ); + spyOn(IonResource, "_createEndpointResource").and.returnValue( + endpointResource + ); + + spyOn(endpointResource, "fetchJson").and.returnValue( + Promise.resolve(endpointData) + ); + + const provider = await IonImageryProvider.fromAssetId(assetId, options); + + expect(IonResource._createEndpointResource).toHaveBeenCalledWith( + assetId, + options + ); + return provider; + } + beforeEach(function () { RequestScheduler.clearForSpecs(); IonImageryProvider._endpointCache = {}; @@ -58,12 +89,6 @@ describe("Scene/IonImageryProvider", function () { expect(IonImageryProvider).toConformToInterface(ImageryProvider); }); - it("throws without asset ID", function () { - expect(function () { - return new IonImageryProvider({}); - }).toThrowDeveloperError(ImageryProvider); - }); - it("readyPromise rejects with non-imagery asset", function () { const provider = createTestProvider({ type: "3DTILES", @@ -111,7 +136,56 @@ describe("Scene/IonImageryProvider", function () { }); }); - it("Uses previously fetched endpoint cache", function () { + it("fromAssetId throws without assetId", async function () { + await expectAsync( + createTestProviderAsync({ + type: "3DTILES", + url: "http://test.invalid/layer", + accessToken: "not_really_a_refresh_token", + attributions: [], + }) + ).toBeRejectedWithDeveloperError(); + }); + + it("fromAssetId throws with non-imagery asset", async function () { + await expectAsync( + createTestProviderAsync({ + type: "3DTILES", + url: "http://test.invalid/layer", + accessToken: "not_really_a_refresh_token", + attributions: [], + }) + ).toBeRejectedWithError( + RuntimeError, + "Cesium ion asset 12335 is not an imagery asset." + ); + }); + + it("fromAssetId rejects with unknown external asset type", async function () { + await expectAsync( + createTestProviderAsync({ + type: "IMAGERY", + externalType: "TUBELCANE", + options: { url: "http://test.invalid/layer" }, + attributions: [], + }) + ).toBeRejectedWithError( + RuntimeError, + "Unrecognized Cesium ion imagery type: TUBELCANE" + ); + }); + + it("fromAssetId resolves to created provider", async function () { + const provider = await createTestProviderAsync(); + expect(provider).toBeInstanceOf(IonImageryProvider); + expect(provider.errorEvent).toBeDefined(); + expect(provider.ready).toBe(true); + expect(provider._imageryProvider).toBeInstanceOf( + UrlTemplateImageryProvider + ); + }); + + it("Uses previously fetched endpoint cache", async function () { const endpointData = { type: "IMAGERY", url: "http://test.invalid/layer", @@ -121,7 +195,6 @@ describe("Scene/IonImageryProvider", function () { const assetId = 12335; const options = { - assetId: assetId, accessToken: "token", server: "http://test.invalid", }; @@ -137,165 +210,88 @@ describe("Scene/IonImageryProvider", function () { ); expect(endpointResource.fetchJson.calls.count()).toBe(0); - const provider = new IonImageryProvider(options); - let provider2; - return provider.readyPromise - .then(function () { - expect(provider.ready).toBe(true); - expect(endpointResource.fetchJson.calls.count()).toBe(1); - - // Same as options but in a different order to verify cache is order independant. - const options2 = { - accessToken: "token", - server: "http://test.invalid", - assetId: assetId, - }; - provider2 = new IonImageryProvider(options2); - return provider2.readyPromise; - }) - .then(function () { - //Since the data is cached, fetchJson is not called again. - expect(endpointResource.fetchJson.calls.count()).toBe(1); - expect(provider2.ready).toBe(true); - }); - }); + const provider = await IonImageryProvider.fromAssetId(assetId, options); + expect(provider.ready).toBe(true); + expect(endpointResource.fetchJson.calls.count()).toBe(1); - it("propagates called to underlying imagery provider resolves when ready", function () { - const provider = createTestProvider(); - let internalProvider; - - return provider.readyPromise - .then(function () { - internalProvider = provider._imageryProvider; - expect(provider.rectangle).toBe(internalProvider.rectangle); - expect(provider.tileWidth).toBe(internalProvider.tileWidth); - expect(provider.tileHeight).toBe(internalProvider.tileHeight); - expect(provider.maximumLevel).toBe(internalProvider.maximumLevel); - expect(provider.minimumLevel).toBe(internalProvider.minimumLevel); - expect(provider.tilingScheme).toBe(internalProvider.tilingScheme); - expect(provider.tileDiscardPolicy).toBe( - internalProvider.tileDiscardPolicy - ); - expect(provider.credit).toBe(internalProvider.credit); - expect(provider.hasAlphaChannel).toBe(internalProvider.hasAlphaChannel); - - const image = new Image(); - const request = {}; - spyOn(internalProvider, "requestImage").and.returnValue( - Promise.resolve(image) - ); - return provider.requestImage(1, 2, 3, request).then(function (result) { - expect(internalProvider.requestImage).toHaveBeenCalledWith( - 1, - 2, - 3, - request - ); - expect(result).toBe(image); - }); - }) - .then(function () { - const info = {}; - spyOn(internalProvider, "pickFeatures").and.returnValue( - Promise.resolve(info) - ); - return provider.pickFeatures(1, 2, 3, 4, 5).then(function (result) { - expect(internalProvider.pickFeatures).toHaveBeenCalledWith( - 1, - 2, - 3, - 4, - 5 - ); - expect(result).toBe(info); - }); - }) - .then(function () { - const innerCredit = new Credit("Data provided"); - spyOn(internalProvider, "getTileCredits").and.returnValue([ - innerCredit, - ]); - const credits = provider.getTileCredits(1, 2, 3); - expect(internalProvider.getTileCredits).toHaveBeenCalledWith(1, 2, 3); - expect(credits).toContain(innerCredit); - }); + // Same as options but in a different order to verify cache is order independant. + const options2 = { + accessToken: "token", + server: "http://test.invalid", + }; + const provider2 = await IonImageryProvider.fromAssetId(assetId, options2); + //Since the data is cached, fetchJson is not called again. + expect(endpointResource.fetchJson.calls.count()).toBe(1); + expect(provider2.ready).toBe(true); }); - it("throws developer errors when not ready", function () { - const provider = createTestProvider(); - provider._ready = false; - - expect(function () { - return provider.rectangle; - }).toThrowDeveloperError(); - expect(function () { - return provider.tileWidth; - }).toThrowDeveloperError(); - expect(function () { - return provider.tileHeight; - }).toThrowDeveloperError(); - expect(function () { - return provider.maximumLevel; - }).toThrowDeveloperError(); - expect(function () { - return provider.minimumLevel; - }).toThrowDeveloperError(); - expect(function () { - return provider.tilingScheme; - }).toThrowDeveloperError(); - expect(function () { - return provider.tileDiscardPolicy; - }).toThrowDeveloperError(); - expect(function () { - return provider.credit; - }).toThrowDeveloperError(); - expect(function () { - return provider.hasAlphaChannel; - }).toThrowDeveloperError(); - expect(function () { - return provider.requestImage(1, 2, 3, {}); - }).toThrowDeveloperError(); - expect(function () { - return provider.pickFeatures(1, 2, 3, 4, 5); - }).toThrowDeveloperError(); - expect(function () { - return provider.getTileCredits(1, 2, 3); - }).toThrowDeveloperError(); - - return provider.readyPromise; + it("propagates called to underlying imagery provider resolves when ready", async function () { + const provider = await createTestProviderAsync(); + const internalProvider = provider._imageryProvider; + expect(provider.rectangle).toBe(internalProvider.rectangle); + expect(provider.tileWidth).toBe(internalProvider.tileWidth); + expect(provider.tileHeight).toBe(internalProvider.tileHeight); + expect(provider.maximumLevel).toBe(internalProvider.maximumLevel); + expect(provider.minimumLevel).toBe(internalProvider.minimumLevel); + expect(provider.tilingScheme).toBe(internalProvider.tilingScheme); + expect(provider.tileDiscardPolicy).toBe(internalProvider.tileDiscardPolicy); + expect(provider.credit).toBe(internalProvider.credit); + expect(provider.hasAlphaChannel).toBe(internalProvider.hasAlphaChannel); + + const image = new Image(); + const request = {}; + spyOn(internalProvider, "requestImage").and.returnValue( + Promise.resolve(image) + ); + let result = await provider.requestImage(1, 2, 3, request); + expect(internalProvider.requestImage).toHaveBeenCalledWith( + 1, + 2, + 3, + request + ); + expect(result).toBe(image); + const info = {}; + spyOn(internalProvider, "pickFeatures").and.returnValue( + Promise.resolve(info) + ); + result = await provider.pickFeatures(1, 2, 3, 4, 5); + expect(internalProvider.pickFeatures).toHaveBeenCalledWith(1, 2, 3, 4, 5); + expect(result).toBe(info); + const innerCredit = new Credit("Data provided"); + spyOn(internalProvider, "getTileCredits").and.returnValue([innerCredit]); + const credits = provider.getTileCredits(1, 2, 3); + expect(internalProvider.getTileCredits).toHaveBeenCalledWith(1, 2, 3); + expect(credits).toContain(innerCredit); }); - it("handles server-sent credits", function () { + it("handles server-sent credits", async function () { const serverCredit = { html: 'Text', collapsible: false, }; - const provider = createTestProvider({ + const provider = await createTestProviderAsync({ type: "IMAGERY", url: "http://test.invalid/layer", accessToken: "not_really_a_refresh_token", attributions: [serverCredit], }); - return provider.readyPromise.then(function () { - const credits = provider.getTileCredits(0, 0, 0); - const credit = credits[0]; - expect(credit).toBeInstanceOf(Credit); - expect(credit.html).toEqual(serverCredit.html); - expect(credit.showOnScreen).toEqual(!serverCredit.collapsible); - }); + const credits = provider.getTileCredits(0, 0, 0); + const credit = credits[0]; + expect(credit).toBeInstanceOf(Credit); + expect(credit.html).toEqual(serverCredit.html); + expect(credit.showOnScreen).toEqual(!serverCredit.collapsible); }); - function testExternalImagery(type, options, ImageryClass) { - const provider = createTestProvider({ + async function testExternalImagery(type, options, ImageryClass) { + const provider = await createTestProviderAsync({ type: "IMAGERY", externalType: type, options: options, attributions: [], }); - return provider.readyPromise.then(function () { - expect(provider._imageryProvider).toBeInstanceOf(ImageryClass); - }); + expect(provider._imageryProvider).toBeInstanceOf(ImageryClass); } it("createImageryProvider works with ARCGIS_MAPSERVER", function () { diff --git a/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js b/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js index 3d84d381ab7..4cb6cdcb111 100644 --- a/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js @@ -4,6 +4,7 @@ import { Rectangle, Request, Resource, + RuntimeError, Imagery, ImageryLayer, ImageryProvider, @@ -64,24 +65,50 @@ describe("Scene/SingleTileImageryProvider", function () { }); }); - it("returns valid value for hasAlphaChannel", function () { - const provider = new SingleTileImageryProvider({ + it("fromUrl throws without url", async function () { + await expectAsync( + SingleTileImageryProvider.fromUrl() + ).toBeRejectedWithDeveloperError(); + }); + + it("fromUrl resolves to created provider", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); + expect(provider).toBeInstanceOf(SingleTileImageryProvider); + }); + + it("fromUrl with Resource resolves to created provider", async function () { + const resource = new Resource({ url: "Data/Images/Red16x16.png", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(typeof provider.hasAlphaChannel).toBe("boolean"); - }); + const provider = await SingleTileImageryProvider.fromUrl(resource); + expect(provider).toBeInstanceOf(SingleTileImageryProvider); }); - it("properties are gettable", function () { + it("fromUrl throws on failed request", async function () { + await expectAsync( + SingleTileImageryProvider.fromUrl("invalid.image.url") + ).toBeRejectedWithError( + RuntimeError, + "Failed to load image invalid.image.url" + ); + }); + + it("returns valid value for hasAlphaChannel", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); + + expect(typeof provider.hasAlphaChannel).toBe("boolean"); + }); + + it("properties are gettable", async function () { const url = "Data/Images/Red16x16.png"; const rectangle = new Rectangle(0.1, 0.2, 0.3, 0.4); const credit = "hi"; - const provider = new SingleTileImageryProvider({ - url: url, + const provider = await SingleTileImageryProvider.fromUrl(url, { rectangle: rectangle, credit: credit, }); @@ -90,40 +117,27 @@ describe("Scene/SingleTileImageryProvider", function () { expect(provider.rectangle).toEqual(rectangle); expect(provider.hasAlphaChannel).toEqual(true); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.tilingScheme.rectangle).toEqual(rectangle); - expect(provider.tileWidth).toEqual(16); - expect(provider.tileHeight).toEqual(16); - expect(provider.maximumLevel).toEqual(0); - expect(provider.tileDiscardPolicy).toBeUndefined(); - }); - }); - - it("url is required", function () { - function constructWithoutUrl() { - return new SingleTileImageryProvider({}); - } - expect(constructWithoutUrl).toThrowDeveloperError(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.tilingScheme.rectangle).toEqual(rectangle); + expect(provider.tileWidth).toEqual(16); + expect(provider.tileHeight).toEqual(16); + expect(provider.maximumLevel).toEqual(0); + expect(provider.tileDiscardPolicy).toBeUndefined(); }); - it("can use a custom ellipsoid", function () { + it("can use a custom ellipsoid", async function () { const ellipsoid = new Ellipsoid(1, 2, 3); - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - ellipsoid: ellipsoid, - }); + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png", + { + ellipsoid: ellipsoid, + } + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); - }); + expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); - it("requests the single image immediately upon construction", function () { + it("requests the single image immediately upon construction", async function () { const imageUrl = "Data/Images/Red16x16.png"; spyOn(Resource._Implementations, "createImage").and.callFake(function ( @@ -140,44 +154,29 @@ describe("Scene/SingleTileImageryProvider", function () { ); }); - const provider = new SingleTileImageryProvider({ - url: imageUrl, - }); + const provider = await SingleTileImageryProvider.fromUrl(imageUrl); expect(Resource._Implementations.createImage).toHaveBeenCalled(); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - return Promise.resolve(provider.requestImage(0, 0, 0)).then(function ( - image - ) { - expect(image).toBeImageOrImageBitmap(); - }); - }); + const image = await Promise.resolve(provider.requestImage(0, 0, 0)); + expect(image).toBeImageOrImageBitmap(); }); - it("turns the supplied credit into a logo", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + it("turns the supplied credit into a logo", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeUndefined(); + expect(provider.credit).toBeUndefined(); - const providerWithCredit = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", + const providerWithCredit = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png", + { credit: "Thanks to our awesome made up source of this imagery!", - }); + } + ); - return pollToPromise(function () { - return providerWithCredit.ready; - }).then(function () { - expect(providerWithCredit.credit).toBeDefined(); - }); - }); + expect(providerWithCredit.credit).toBeDefined(); }); it("raises error event when image cannot be loaded", function () { diff --git a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js index 19c182b306c..4a193561f4b 100644 --- a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js @@ -1,7 +1,6 @@ import { Cartesian2, Cartographic, - defer, GeographicProjection, GeographicTilingScheme, getAbsoluteUri, @@ -10,6 +9,7 @@ import { RequestErrorEvent, RequestScheduler, Resource, + RuntimeError, WebMercatorProjection, WebMercatorTilingScheme, TileMapServiceImageryProvider, @@ -209,187 +209,215 @@ describe("Scene/TileMapServiceImageryProvider", function () { }); }); - it("requires the url to be specified", function () { - function createWithoutUrl() { - return new TileMapServiceImageryProvider({}); - } + it("fromUrl throws without url", async function () { + await expectAsync( + TileMapServiceImageryProvider.fromUrl() + ).toBeRejectedWithDeveloperError(); + }); - expect(createWithoutUrl).toThrowDeveloperError(); + it("fromUrl resolves to created provider", async function () { + patchRequestScheduler(validSampleXmlString); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server/" + ); + expect(provider).toBeInstanceOf(TileMapServiceImageryProvider); }); - it("returns valid value for hasAlphaChannel", function () { + it("fromUrl resolves to created provider with Resource", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ + const resource = new Resource({ url: "made/up/tms/server/", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(typeof provider.hasAlphaChannel).toBe("boolean"); - }); + const provider = await TileMapServiceImageryProvider.fromUrl(resource); + expect(provider).toBeInstanceOf(TileMapServiceImageryProvider); }); - it("supports a slash at the end of the URL", function () { + it("fromUrl throws on unsupported profile attribute", async function () { + const xmlString = + '' + + " " + + " <Abstract/>" + + " <SRS>EPSG:4326</SRS>" + + ' <BoundingBox minx="-10.0" miny="-123.0" maxx="11.0" maxy="-110.0"/>' + + ' <Origin x="-90.0" y="-180.0"/>' + + ' <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>' + + ' <TileSets profile="foobar">' + + ' <TileSet href="2" units-per-pixel="39135.75848201024200" order="2"/>' + + ' <TileSet href="3" units-per-pixel="19567.87924100512100" order="3"/>' + + " </TileSets>" + + "</TileMap>"; + patchRequestScheduler(xmlString); + await expectAsync( + TileMapServiceImageryProvider.fromUrl("made/up/tms/server") + ).toBeRejectedWithError( + RuntimeError, + "http://localhost:9876/made/up/tms/server/tilemapresource.xmlspecifies an unsupported profile attribute, foobar." + ); + }); + + it("fromUrl throws on invalid xml", async function () { + const xmlString = + '<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">' + + " <Title/>" + + " <Abstract/>" + + " <SRS>EPSG:4326</SRS>" + + ' <Origin x="-90.0" y="-180.0"/>' + + ' <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>' + + ' <TileSets profile="foobar">' + + ' <TileSet href="2" units-per-pixel="39135.75848201024200" order="2"/>' + + ' <TileSet href="3" units-per-pixel="19567.87924100512100" order="3"/>' + + " </TileSets>" + + "</TileMap>"; + patchRequestScheduler(xmlString); + await expectAsync( + TileMapServiceImageryProvider.fromUrl("made/up/tms/server") + ).toBeRejectedWithError( + RuntimeError, + "Unable to find expected tilesets or bbox attributes in http://localhost:9876/made/up/tms/server/tilemapresource.xml." + ); + }); + + it("returns valid value for hasAlphaChannel", async function () { + patchRequestScheduler(validSampleXmlString); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server/" + ); + + expect(typeof provider.hasAlphaChannel).toBe("boolean"); + }); + + it("supports a slash at the end of the URL", async function () { patchRequestScheduler(validSampleXmlString); const baseUrl = "made/up/tms/server/"; - const provider = new TileMapServiceImageryProvider({ - url: baseUrl, - }); + const provider = await TileMapServiceImageryProvider.fromUrl(baseUrl); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toStartWith(getAbsoluteUri(baseUrl)); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toStartWith(getAbsoluteUri(baseUrl)); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + ); }); + + const image = await provider.requestImage(0, 0, 0); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); - it("supports no slash at the endof the URL", function () { + it("supports no slash at the end of the URL", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ - url: "http://made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "http://made/up/tms/server" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toContain("made/up/tms/server/"); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toContain("made/up/tms/server/"); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + ); }); + + const image = await provider.requestImage(0, 0, 0); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); - it("supports a query string at the end of the URL", function () { + it("supports a query string at the end of the URL", async function () { patchRequestScheduler(validSampleXmlString); const baseUrl = "made/up/tms/server/"; - const provider = new TileMapServiceImageryProvider({ - url: `${baseUrl}?a=some&b=query`, - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + `${baseUrl}?a=some&b=query` + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toStartWith(getAbsoluteUri(baseUrl)); + expect(request.url).toContain("?a=some&b=query"); + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toStartWith(getAbsoluteUri(baseUrl)); - expect(request.url).toContain("?a=some&b=query"); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + ); }); + + const image = await provider.requestImage(0, 0, 0); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); - it("requestImage returns a promise for an image and loads it for cross-origin use", function () { + it("requestImage returns a promise for an image and loads it for cross-origin use", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server/", - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - // check some details about the tilemapresourcel.xml so we know we got parsed/configured properly - let url = getAbsoluteUri("made/up/tms/server/{z}/{x}/{reverseY}.jpg"); - // Uri.absoluteTo() escapes the placeholders. Undo that. - url = url.replace(/%7B/g, "{").replace(/%7D/g, "}"); - expect(provider.url).toEqual(url); - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server/" + ); + + // check some details about the tilemapresourcel.xml so we know we got parsed/configured properly + let url = getAbsoluteUri("made/up/tms/server/{z}/{x}/{reverseY}.jpg"); + // Uri.absoluteTo() escapes the placeholders. Undo that. + url = url.replace(/%7B/g, "{").replace(/%7D/g, "}"); + expect(provider.url).toEqual(url); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + ); }); + + const image = await provider.requestImage(0, 0, 0); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); - it("when no credit is supplied, the provider has no logo", function () { + it("when no credit is supplied, the provider has no logo", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.credit).toBeUndefined(); - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server/" + ); + expect(provider.credit).toBeUndefined(); }); - it("turns the supplied credit into a logo", function () { + it("turns the supplied credit into a logo", async function () { patchRequestScheduler(validSampleXmlString); - const providerWithCredit = new TileMapServiceImageryProvider({ - url: "made/up/gms/server", - credit: "Thanks to our awesome made up source of this imagery!", - }); - return pollToPromise(function () { - return providerWithCredit.ready; - }).then(function () { - expect(providerWithCredit.credit).toBeDefined(); - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/gms/server", + { + credit: "Thanks to our awesome made up source of this imagery!", + } + ); + expect(provider.credit).toBeDefined(); }); - it("resource request takes a query string", function () { + it("resource request takes a query string", async function () { /*eslint-disable no-unused-vars*/ - const requestMetadata = defer(); spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( url, responseType, @@ -399,100 +427,87 @@ describe("Scene/TileMapServiceImageryProvider", function () { deferred, overrideMimeType ) { - requestMetadata.resolve(url); + expect(/\?query=1$/.test(url)).toEqual(true); deferred.reject(new RequestErrorEvent(404)); //since the TMS server doesn't exist (and doesn't need too) we can just reject here. }); - const provider = new TileMapServiceImageryProvider({ - url: "http://server.invalid?query=1", - }); - - return requestMetadata.promise - .then(function (url) { - expect(/\?query=1$/.test(url)).toEqual(true); - }) - .then(() => { - return provider.readyPromise; - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "http://server.invalid?query=1" + ); }); - it("rectangle passed to constructor does not affect tile numbering", function () { + it("rectangle passed to constructor does not affect tile numbering", async function () { patchRequestScheduler(validSampleXmlString); const rectangle = new Rectangle(0.1, 0.2, 0.3, 0.4); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - rectangle: rectangle, - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - // check some values coming from tilemapresource.xml - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toEqual(2); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - // check our rectangle from the constructor is correctly used - expect(provider.rectangle.west).toEqualEpsilon( - rectangle.west, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.east).toEqualEpsilon( - rectangle.east, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toEqualEpsilon( - rectangle.north, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.south).toEqualEpsilon( - rectangle.south, - CesiumMath.EPSILON14 - ); - expect(provider.tileDiscardPolicy).toBeUndefined(); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + rectangle: rectangle, + } + ); + + // check some values coming from tilemapresource.xml + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(2); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + // check our rectangle from the constructor is correctly used + expect(provider.rectangle.west).toEqualEpsilon( + rectangle.west, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.east).toEqualEpsilon( + rectangle.east, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toEqualEpsilon( + rectangle.north, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.south).toEqualEpsilon( + rectangle.south, + CesiumMath.EPSILON14 + ); + expect(provider.tileDiscardPolicy).toBeUndefined(); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toContain("/0/0/0"); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toContain("/0/0/0"); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); - - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + ); }); + + const image = await provider.requestImage(0, 0, 0); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); - it("uses maximumLevel passed to constructor", function () { + it("uses maximumLevel passed to constructor", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - maximumLevel: 5, - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + maximumLevel: 5, + } + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.maximumLevel).toEqual(5); - }); + expect(provider.maximumLevel).toEqual(5); }); - it("raises error event when image cannot be loaded", function () { + it("raises error event when image cannot be loaded", async function () { patchRequestScheduler(validSampleXmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); const layer = new ImageryLayer(provider); @@ -528,25 +543,21 @@ describe("Scene/TileMapServiceImageryProvider", function () { } }; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBeImageOrImageBitmap(); - expect(tries).toEqual(2); - imagery.releaseReference(); - }); + expect(imagery.image).toBeImageOrImageBitmap(); + expect(tries).toEqual(2); + imagery.releaseReference(); }); }); - it("keeps the rectangle within the bounds allowed by the tiling scheme no matter what the tilemapresource.xml says.", function () { + it("keeps the rectangle within the bounds allowed by the tiling scheme no matter what the tilemapresource.xml says.", async function () { const xmlString = "<TileMap version='1.0.0' tilemapservice='http://tms.osgeo.org/1.0.0'>" + " <Title>dnb_land_ocean_ice.2012.54000x27000_geo.tif" + @@ -560,45 +571,41 @@ describe("Scene/TileMapServiceImageryProvider", function () { " " + ""; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.rectangle.west).toEqualEpsilon( - CesiumMath.toRadians(-180.0), - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.west).toBeGreaterThanOrEqual( - provider.tilingScheme.rectangle.west - ); - expect(provider.rectangle.east).toEqualEpsilon( - CesiumMath.toRadians(180.0), - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.east).toBeLessThanOrEqual( - provider.tilingScheme.rectangle.east - ); - expect(provider.rectangle.south).toEqualEpsilon( - -WebMercatorProjection.MaximumLatitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.south).toBeGreaterThanOrEqual( - provider.tilingScheme.rectangle.south - ); - expect(provider.rectangle.north).toEqualEpsilon( - WebMercatorProjection.MaximumLatitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toBeLessThanOrEqual( - provider.tilingScheme.rectangle.north - ); - }); - }); - - it("uses a minimum level if the tilemapresource.xml specifies one and it is reasonable", function () { + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); + + expect(provider.rectangle.west).toEqualEpsilon( + CesiumMath.toRadians(-180.0), + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.west).toBeGreaterThanOrEqual( + provider.tilingScheme.rectangle.west + ); + expect(provider.rectangle.east).toEqualEpsilon( + CesiumMath.toRadians(180.0), + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.east).toBeLessThanOrEqual( + provider.tilingScheme.rectangle.east + ); + expect(provider.rectangle.south).toEqualEpsilon( + -WebMercatorProjection.MaximumLatitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.south).toBeGreaterThanOrEqual( + provider.tilingScheme.rectangle.south + ); + expect(provider.rectangle.north).toEqualEpsilon( + WebMercatorProjection.MaximumLatitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toBeLessThanOrEqual( + provider.tilingScheme.rectangle.north + ); + }); + + it("uses a minimum level if the tilemapresource.xml specifies one and it is reasonable", async function () { const xmlString = "" + " dnb_land_ocean_ice.2012.54000x27000_geo.tif" + @@ -614,19 +621,15 @@ describe("Scene/TileMapServiceImageryProvider", function () { ""; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.maximumLevel).toBe(8); - expect(provider.minimumLevel).toBe(7); - }); + expect(provider.maximumLevel).toBe(8); + expect(provider.minimumLevel).toBe(7); }); - it("ignores the minimum level in the tilemapresource.xml if it is unreasonable", function () { + it("ignores the minimum level in the tilemapresource.xml if it is unreasonable", async function () { const xmlString = "" + " dnb_land_ocean_ice.2012.54000x27000_geo.tif" + @@ -642,19 +645,15 @@ describe("Scene/TileMapServiceImageryProvider", function () { ""; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.maximumLevel).toBe(8); - expect(provider.minimumLevel).toBe(0); - }); + expect(provider.maximumLevel).toBe(8); + expect(provider.minimumLevel).toBe(0); }); - it("handles XML with casing differences", function () { + it("handles XML with casing differences", async function () { const xmlString = "" + " dnb_land_ocean_ice.2012.54000x27000_geo.tif" + @@ -670,19 +669,15 @@ describe("Scene/TileMapServiceImageryProvider", function () { ""; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.maximumLevel).toBe(8); - expect(provider.minimumLevel).toBe(7); - }); + expect(provider.maximumLevel).toBe(8); + expect(provider.minimumLevel).toBe(7); }); - it("supports the global-mercator profile with a non-flipped, mercator bounding box", function () { + it("supports the global-mercator profile with a non-flipped, mercator bounding box", async function () { const xmlString = '' + " " + @@ -698,37 +693,33 @@ describe("Scene/TileMapServiceImageryProvider", function () { "</TileMap>"; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.tilingScheme.projection).toBeInstanceOf( - WebMercatorProjection - ); - - const projection = provider.tilingScheme.projection; - const expectedSW = projection.unproject( - new Cartesian2(-11877789.667642293, 1707163.7595205167) - ); - const expectedNE = projection.unproject( - new Cartesian2(-4696205.4540757351, 7952627.0736533012) - ); - - expect(provider.rectangle.west).toEqual(expectedSW.longitude); - expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( - expectedNE.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toEqual(expectedNE.latitude); - }); - }); - - it("supports the global-geodetic profile with a non-flipped, geographic bounding box", function () { + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); + + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.tilingScheme.projection).toBeInstanceOf( + WebMercatorProjection + ); + + const projection = provider.tilingScheme.projection; + const expectedSW = projection.unproject( + new Cartesian2(-11877789.667642293, 1707163.7595205167) + ); + const expectedNE = projection.unproject( + new Cartesian2(-4696205.4540757351, 7952627.0736533012) + ); + + expect(provider.rectangle.west).toEqual(expectedSW.longitude); + expect(provider.rectangle.south).toEqual(expectedSW.latitude); + expect(provider.rectangle.east).toBeCloseTo( + expectedNE.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toEqual(expectedNE.latitude); + }); + + it("supports the global-geodetic profile with a non-flipped, geographic bounding box", async function () { const xmlString = '<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">' + " <Title/>" + @@ -744,35 +735,31 @@ describe("Scene/TileMapServiceImageryProvider", function () { "</TileMap>"; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server" + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.tilingScheme.projection).toBeInstanceOf( - GeographicProjection - ); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.tilingScheme.projection).toBeInstanceOf( + GeographicProjection + ); - const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); - const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); + const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); + const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - expect(provider.rectangle.west).toBeCloseTo( - expectedSW.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( - expectedNE.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toEqual(expectedNE.latitude); - }); + expect(provider.rectangle.west).toBeCloseTo( + expectedSW.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.south).toEqual(expectedSW.latitude); + expect(provider.rectangle.east).toBeCloseTo( + expectedNE.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toEqual(expectedNE.latitude); }); - it("supports the old mercator profile with a flipped, geographic bounding box", function () { + it("supports the old mercator profile with a flipped, geographic bounding box", async function () { const xmlString = '<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">' + " <Title/>" + @@ -788,36 +775,34 @@ describe("Scene/TileMapServiceImageryProvider", function () { "</TileMap>"; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - flipXY: true, - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + flipXY: true, + } + ); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.tilingScheme.projection).toBeInstanceOf( - WebMercatorProjection - ); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.tilingScheme.projection).toBeInstanceOf( + WebMercatorProjection + ); - const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); - const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); + const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); + const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - expect(provider.rectangle.west).toBeCloseTo( - expectedSW.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( - expectedNE.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toEqual(expectedNE.latitude); - }); + expect(provider.rectangle.west).toBeCloseTo( + expectedSW.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.south).toEqual(expectedSW.latitude); + expect(provider.rectangle.east).toBeCloseTo( + expectedNE.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toEqual(expectedNE.latitude); }); - it("supports the old geodetic profile with a flipped, geographic bounding box", function () { + it("supports the old geodetic profile with a flipped, geographic bounding box", async function () { const xmlString = '<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">' + " <Title/>" + @@ -833,108 +818,71 @@ describe("Scene/TileMapServiceImageryProvider", function () { "</TileMap>"; patchRequestScheduler(xmlString); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - flipXY: true, - }); - - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.tilingScheme.projection).toBeInstanceOf( - GeographicProjection - ); - - const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); - const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - - expect(provider.rectangle.west).toBeCloseTo( - expectedSW.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.south).toEqual(expectedSW.latitude); - expect(provider.rectangle.east).toBeCloseTo( - expectedNE.longitude, - CesiumMath.EPSILON14 - ); - expect(provider.rectangle.north).toEqual(expectedNE.latitude); - }); - }); - - it("raises an error if tilemapresource.xml specifies an unsupported profile", function () { - const xmlString = - '<TileMap version="1.0.0" tilemapservice="http://tms.osgeo.org/1.0.0">' + - " <Title/>" + - " <Abstract/>" + - " <SRS>EPSG:4326</SRS>" + - ' <BoundingBox minx="-10.0" miny="-123.0" maxx="11.0" maxy="-110.0"/>' + - ' <Origin x="-90.0" y="-180.0"/>' + - ' <TileFormat width="256" height="256" mime-type="image/png" extension="png"/>' + - ' <TileSets profile="foobar">' + - ' <TileSet href="2" units-per-pixel="39135.75848201024200" order="2"/>' + - ' <TileSet href="3" units-per-pixel="19567.87924100512100" order="3"/>' + - " </TileSets>" + - "</TileMap>"; - patchRequestScheduler(xmlString); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + flipXY: true, + } + ); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server", - }); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.tilingScheme.projection).toBeInstanceOf( + GeographicProjection + ); - let errorRaised = false; - provider.errorEvent.addEventListener(function (e) { - expect(e.message).toContain("unsupported profile"); - errorRaised = true; - }); + const expectedSW = Cartographic.fromDegrees(-123.0, -10.0); + const expectedNE = Cartographic.fromDegrees(-110.0, 11.0); - return provider.readyPromise - .then(function () { - fail(); - }) - .catch(function (e) { - expect(errorRaised).toBe(true); - }); + expect(provider.rectangle.west).toBeCloseTo( + expectedSW.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.south).toEqual(expectedSW.latitude); + expect(provider.rectangle.east).toBeCloseTo( + expectedNE.longitude, + CesiumMath.EPSILON14 + ); + expect(provider.rectangle.north).toEqual(expectedNE.latitude); }); - it("forces minimum detail level to zero if the tilemapresource.xml request fails and the constructor minimum level is too high", function () { + it("forces minimum detail level to zero if the tilemapresource.xml request fails and the constructor minimum level is too high", async function () { patchRequestSchedulerToRejectRequest(); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server/", - minimumLevel: 10, - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + minimumLevel: 10, + } + ); // we expect that our minimum detail level was forced to 0, even though we requested 10. // this is because, our rectangle has been set to the entire world (the default), so a minimum // detail level of 10 would hang the browser with too many tile requests. // Forcing detail level to zero to is safe. - return provider.readyPromise.then(function () { - expect(provider.minimumLevel).toBe(0); - }); + expect(provider.minimumLevel).toBe(0); }); - it("allows the constructor minimum detail level if the tilemapresource.xml request fails but the constructor rectangle is small enough", function () { + it("allows the constructor minimum detail level if the tilemapresource.xml request fails but the constructor rectangle is small enough", async function () { patchRequestSchedulerToRejectRequest(); - const provider = new TileMapServiceImageryProvider({ - url: "made/up/tms/server/", - // a high minimum detail level - minimumLevel: 12, - // and a very small rectangle - rectangle: new Rectangle( - CesiumMath.toRadians(131.020889), - CesiumMath.toRadians(-25.35473), - CesiumMath.toRadians(131.054363), - CesiumMath.toRadians(-25.335803) - ), - }); + const provider = await TileMapServiceImageryProvider.fromUrl( + "made/up/tms/server", + { + // a high minimum detail level + minimumLevel: 12, + // and a very small rectangle + rectangle: new Rectangle( + CesiumMath.toRadians(131.020889), + CesiumMath.toRadians(-25.35473), + CesiumMath.toRadians(131.054363), + CesiumMath.toRadians(-25.335803) + ), + } + ); // we expect that our minimum detail level remains at 12, which is quite high, but that's okay // because our rectangle is still small enough that it's not too many tiles. - return provider.readyPromise.then(function () { - expect(provider.minimumLevel).toBe(12); - // just make sure we're actually still using a small rectangle - expect(provider.rectangle.width).toBeLessThan(0.001); - expect(provider.rectangle.height).toBeLessThan(0.001); - }); + expect(provider.minimumLevel).toBe(12); + // just make sure we're actually still using a small rectangle + expect(provider.rectangle.width).toBeLessThan(0.001); + expect(provider.rectangle.height).toBeLessThan(0.001); }); }); diff --git a/packages/engine/Specs/Scene/UrlTemplateImageryProviderSpec.js b/packages/engine/Specs/Scene/UrlTemplateImageryProviderSpec.js index 46f6a97a5d7..7725fd94cfc 100644 --- a/packages/engine/Specs/Scene/UrlTemplateImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/UrlTemplateImageryProviderSpec.js @@ -71,11 +71,7 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "made/up/tms/server/", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(typeof provider.hasAlphaChannel).toBe("boolean"); - }); + expect(typeof provider.hasAlphaChannel).toBe("boolean"); }); it("requestImage returns a promise for an image and loads it for cross-origin use", function () { @@ -83,36 +79,30 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "made/up/tms/server/{Z}/{X}/{reverseY}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.url).toEqual("made/up/tms/server/{Z}/{X}/{reverseY}"); - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.minimumLevel).toBe(0); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.rectangle).toEqual( - new WebMercatorTilingScheme().rectangle - ); + expect(provider.url).toEqual("made/up/tms/server/{Z}/{X}/{reverseY}"); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.minimumLevel).toBe(0); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -120,9 +110,7 @@ describe("Scene/UrlTemplateImageryProvider", function () { const provider = new UrlTemplateImageryProvider({ url: "made/up/tms/server", }); - return provider.readyPromise.then(function () { - expect(provider.credit).toBeUndefined(); - }); + expect(provider.credit).toBeUndefined(); }); it("turns the supplied credit into a logo", function () { @@ -130,9 +118,7 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "made/up/gms/server", credit: "Thanks to our awesome made up source of this imagery!", }); - return providerWithCredit.readyPromise.then(function () { - expect(providerWithCredit.credit).toBeDefined(); - }); + expect(providerWithCredit.credit).toBeDefined(); }); it("rectangle passed to constructor does not affect tile numbering", function () { @@ -142,39 +128,32 @@ describe("Scene/UrlTemplateImageryProvider", function () { rectangle: rectangle, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.minimumLevel).toBe(0); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.rectangle).toEqualEpsilon( - rectangle, - CesiumMath.EPSILON14 - ); - expect(provider.tileDiscardPolicy).toBeUndefined(); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.minimumLevel).toBe(0); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.rectangle).toEqualEpsilon(rectangle, CesiumMath.EPSILON14); + expect(provider.tileDiscardPolicy).toBeUndefined(); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toContain("/0/0/0"); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toContain("/0/0/0"); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -185,12 +164,8 @@ describe("Scene/UrlTemplateImageryProvider", function () { maximumLevel: 5, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.minimumLevel).toEqual(1); - expect(provider.maximumLevel).toEqual(5); - }); + expect(provider.minimumLevel).toEqual(1); + expect(provider.maximumLevel).toEqual(5); }); it("raises error event when image cannot be loaded", function () { @@ -232,21 +207,17 @@ describe("Scene/UrlTemplateImageryProvider", function () { } }; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBeImageOrImageBitmap(); - expect(tries).toEqual(2); - imagery.releaseReference(); - }); + expect(imagery.image).toBeImageOrImageBitmap(); + expect(tries).toEqual(2); + imagery.releaseReference(); }); }); @@ -258,28 +229,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { maximumLevel: 6, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual("made/up/tms/server/2/3/2/1/4/3.PNG"); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual("made/up/tms/server/2/3/2/1/4/3.PNG"); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -296,30 +263,26 @@ describe("Scene/UrlTemplateImageryProvider", function () { maximumLevel: 6, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual( + "made/up/tms/server/0002/3/2/0001/4/0003.PNG" + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual( - "made/up/tms/server/0002/3/2/0001/4/0003.PNG" - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -336,30 +299,26 @@ describe("Scene/UrlTemplateImageryProvider", function () { maximumLevel: 6, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual( + "made/up/tms/server/2/0003/0002/1/0004/3.PNG" + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual( - "made/up/tms/server/2/0003/0002/1/0004/3.PNG" - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -376,30 +335,26 @@ describe("Scene/UrlTemplateImageryProvider", function () { maximumLevel: 6, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual( + "made/up/tms/server/0005/0/21/0010/51/0012.PNG" + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual( - "made/up/tms/server/0005/0/21/0010/51/0012.PNG" - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(12, 10, 5).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(12, 10, 5).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -409,28 +364,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { tilingScheme: new GeographicTilingScheme(), }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon(45.0, CesiumMath.EPSILON11); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon(45.0, CesiumMath.EPSILON11); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -440,28 +391,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { tilingScheme: new GeographicTilingScheme(), }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon(0.0, CesiumMath.EPSILON11); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon(0.0, CesiumMath.EPSILON11); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -471,28 +418,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { tilingScheme: new GeographicTilingScheme(), }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon(0.0, CesiumMath.EPSILON11); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon(0.0, CesiumMath.EPSILON11); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -502,28 +445,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { tilingScheme: new GeographicTilingScheme(), }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon(-45.0, CesiumMath.EPSILON11); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon(-45.0, CesiumMath.EPSILON11); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -533,31 +472,27 @@ describe("Scene/UrlTemplateImageryProvider", function () { tilingScheme: new WebMercatorTilingScheme(), }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon( + (Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, + CesiumMath.EPSILON11 + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon( - (Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, - CesiumMath.EPSILON11 - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -566,31 +501,27 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "{southProjected}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon( + (Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, + CesiumMath.EPSILON11 + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon( - (Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, - CesiumMath.EPSILON11 - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 0, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 0, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -599,31 +530,27 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "{eastProjected}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon( + (-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, + CesiumMath.EPSILON11 + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon( - (-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, - CesiumMath.EPSILON11 - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -632,31 +559,27 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "{westProjected}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqualEpsilon( + (-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, + CesiumMath.EPSILON11 + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqualEpsilon( - (-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0, - CesiumMath.EPSILON11 - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(1, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(1, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -666,36 +589,32 @@ describe("Scene/UrlTemplateImageryProvider", function () { "{westDegrees} {westProjected} {southProjected} {southDegrees} {eastProjected} {eastDegrees} {northDegrees} {northProjected}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual( + `-90 ${(-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0} ` + + `0 ` + + `0 ` + + `0 ` + + `0 ${CesiumMath.toDegrees( + WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI / 2) + )} ${(Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0}` + ); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual( - `-90 ${(-Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0} ` + - `0 ` + - `0 ` + - `0 ` + - `0 ${CesiumMath.toDegrees( - WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI / 2) - )} ${(Math.PI * Ellipsoid.WGS84.maximumRadius) / 2.0}` - ); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(1, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(1, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -704,28 +623,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { url: "{s}", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(["a", "b", "c"].indexOf(request.url)).toBeGreaterThanOrEqual(0); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(["a", "b", "c"].indexOf(request.url)).toBeGreaterThanOrEqual(0); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -735,28 +650,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { subdomains: "123", }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(["1", "2", "3"].indexOf(request.url)).toBeGreaterThanOrEqual(0); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(["1", "2", "3"].indexOf(request.url)).toBeGreaterThanOrEqual(0); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -766,28 +677,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { subdomains: ["foo", "bar"], }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(["foo", "bar"].indexOf(request.url)).toBeGreaterThanOrEqual(0); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(["foo", "bar"].indexOf(request.url)).toBeGreaterThanOrEqual(0); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -806,28 +713,24 @@ describe("Scene/UrlTemplateImageryProvider", function () { }, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + expect(request.url).toEqual("made/up/tms/server/foo/bar/2/1/3.PNG"); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - expect(request.url).toEqual("made/up/tms/server/foo/bar/2/1/3.PNG"); - - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(3, 1, 2).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(3, 1, 2).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -843,11 +746,7 @@ describe("Scene/UrlTemplateImageryProvider", function () { enablePickFeatures: false, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).toBeUndefined(); - }); + expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).toBeUndefined(); }); it("does not return undefined when enablePickFeatures is subsequently set to true", function () { @@ -861,12 +760,8 @@ describe("Scene/UrlTemplateImageryProvider", function () { enablePickFeatures: false, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - provider.enablePickFeatures = true; - expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).not.toBeUndefined(); - }); + provider.enablePickFeatures = true; + expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).not.toBeUndefined(); }); it("returns undefined when enablePickFeatures is initialized as true and set to false", function () { @@ -880,108 +775,8 @@ describe("Scene/UrlTemplateImageryProvider", function () { enablePickFeatures: true, }); - return pollToPromise(function () { - return provider.ready; - }).then(function () { - provider.enablePickFeatures = false; - expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).toBeUndefined(); - }); + provider.enablePickFeatures = false; + expect(provider.pickFeatures(0, 0, 0, 0.0, 0.0)).toBeUndefined(); }); }); - - it("throws if tileWidth called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.tileWidth(); - }).toThrowDeveloperError(); - }); - - it("throws if tileHeight called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.tileHeight(); - }).toThrowDeveloperError(); - }); - - it("throws if maximumLevel called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.maximumLevel(); - }).toThrowDeveloperError(); - }); - - it("throws if minimumLevel called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.minimumLevel(); - }).toThrowDeveloperError(); - }); - - it("throws if tilingScheme called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.tilingScheme(); - }).toThrowDeveloperError(); - }); - - it("throws if rectangle called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.rectangle(); - }).toThrowDeveloperError(); - }); - - it("throws if tileDiscardPolicy called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.tileDiscardPolicy(); - }).toThrowDeveloperError(); - }); - - it("throws if credit called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.credit(); - }).toThrowDeveloperError(); - }); - - it("throws if hasAlphaChannel called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.hasAlphaChannel(); - }).toThrowDeveloperError(); - }); - - it("throws if getTileCredits called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.getTileCredits(); - }).toThrowDeveloperError(); - }); - - it("throws if requestImage called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.requestImage(); - }).toThrowDeveloperError(); - }); - - it("throws if pickFeatures called before provider is ready", function () { - const provider = new UrlTemplateImageryProvider({ url: "/foo/bar" }); - - expect(function () { - return provider.pickFeatures(); - }).toThrowDeveloperError(); - }); }); diff --git a/packages/engine/Specs/Scene/WebMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/WebMapServiceImageryProviderSpec.js index 3d0250c5d78..bdb725e8d89 100644 --- a/packages/engine/Specs/Scene/WebMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/WebMapServiceImageryProviderSpec.js @@ -95,9 +95,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - expect(typeof provider.hasAlphaChannel).toBe("boolean"); - }); + expect(typeof provider.hasAlphaChannel).toBe("boolean"); }); it("can use a custom ellipsoid", function () { @@ -108,9 +106,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { ellipsoid: ellipsoid, }); - return provider.readyPromise.then(function () { - expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); - }); + expect(provider.tilingScheme.ellipsoid).toEqual(ellipsoid); }); it("includes specified parameters in URL", function () { @@ -124,25 +120,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.something).toEqual("foo"); - expect(params.another).toEqual("false"); - expect(params.version).toEqual("1.3.0"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.something).toEqual("foo"); + expect(params.another).toEqual("false"); + expect(params.version).toEqual("1.3.0"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -156,24 +150,22 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.crs).toEqual("CRS:27"); - expect(params.version).toEqual("1.3.0"); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.crs).toEqual("CRS:27"); + expect(params.version).toEqual("1.3.0"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -187,25 +179,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.crs).toEqual("EPSG:4326"); - expect(params.version).toEqual("1.3.0"); - expect(params.bbox).toEqual("-90,-180,90,0"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.crs).toEqual("EPSG:4326"); + expect(params.version).toEqual("1.3.0"); + expect(params.bbox).toEqual("-90,-180,90,0"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -219,25 +209,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.crs).toEqual("EPSG:4321"); - expect(params.version).toEqual("1.3.0"); - expect(params.bbox).toEqual("-90,-180,90,0"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.crs).toEqual("EPSG:4321"); + expect(params.version).toEqual("1.3.0"); + expect(params.bbox).toEqual("-90,-180,90,0"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -251,25 +239,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.crs).toEqual("EPSG:3035"); - expect(params.version).toEqual("1.3.0"); - expect(params.bbox).toEqual("-90,-180,90,0"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.crs).toEqual("EPSG:3035"); + expect(params.version).toEqual("1.3.0"); + expect(params.bbox).toEqual("-90,-180,90,0"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -283,25 +269,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.crs).toEqual("EPSG:4559"); - expect(params.version).toEqual("1.3.0"); - expect(params.bbox).toEqual("-180,-90,0,90"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.crs).toEqual("EPSG:4559"); + expect(params.version).toEqual("1.3.0"); + expect(params.bbox).toEqual("-180,-90,0,90"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -315,24 +299,22 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.srs).toEqual("EPSG:4326"); - expect(params.version).toEqual("1.1.0"); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.srs).toEqual("EPSG:4326"); + expect(params.version).toEqual("1.1.0"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -346,24 +328,22 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.srs).toEqual("IAU2000:30118"); - expect(params.version).toEqual("1.1.0"); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.srs).toEqual("IAU2000:30118"); + expect(params.version).toEqual("1.1.0"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -377,25 +357,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - expect(params.srs).toEqual("EPSG:4326"); - expect(params.version).toEqual("1.1.0"); - expect(params.bbox).toEqual("-180,-90,0,90"); - - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + expect(params.srs).toEqual("EPSG:4326"); + expect(params.version).toEqual("1.1.0"); + expect(params.bbox).toEqual("-180,-90,0,90"); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); + + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -408,11 +386,9 @@ describe("Scene/WebMapServiceImageryProvider", function () { spyOn(ImageryProvider, "loadImage"); - return provider.readyPromise.then(function () { - provider.requestImage(0, 0, 0); - const url = ImageryProvider.loadImage.calls.mostRecent().args[1].url; - expect("123".indexOf(url.substring(0, 1))).toBeGreaterThanOrEqual(0); - }); + provider.requestImage(0, 0, 0); + const url = ImageryProvider.loadImage.calls.mostRecent().args[1].url; + expect("123".indexOf(url.substring(0, 1))).toBeGreaterThanOrEqual(0); }); it("supports subdomains array in URL", function () { @@ -423,13 +399,11 @@ describe("Scene/WebMapServiceImageryProvider", function () { }); spyOn(ImageryProvider, "loadImage"); - return provider.readyPromise.then(function () { - provider.requestImage(0, 0, 0); - const url = ImageryProvider.loadImage.calls.mostRecent().args[1].url; - expect( - ["foo", "bar"].indexOf(url.substring(0, 3)) - ).toBeGreaterThanOrEqual(0); - }); + provider.requestImage(0, 0, 0); + const url = ImageryProvider.loadImage.calls.mostRecent().args[1].url; + expect(["foo", "bar"].indexOf(url.substring(0, 3))).toBeGreaterThanOrEqual( + 0 + ); }); it("supports a question mark at the end of the URL", function () { @@ -438,22 +412,20 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const questionMarkCount = request.url.match(/\?/g).length; - expect(questionMarkCount).toEqual(1); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const questionMarkCount = request.url.match(/\?/g).length; + expect(questionMarkCount).toEqual(1); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -463,24 +435,22 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const url = request.url; - const questionMarkCount = url.match(/\?/g).length; - expect(questionMarkCount).toEqual(1); - expect(url).not.toContain("&&"); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + const questionMarkCount = url.match(/\?/g).length; + expect(questionMarkCount).toEqual(1); + expect(url).not.toContain("&&"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -490,28 +460,26 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const url = request.url; - const questionMarkCount = url.match(/\?/g).length; - expect(questionMarkCount).toEqual(1); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + const questionMarkCount = url.match(/\?/g).length; + expect(questionMarkCount).toEqual(1); - const uri = new Uri(url); - const params = queryToObject(uri.query()); - expect(params.foo).toEqual("bar"); + const uri = new Uri(url); + const params = queryToObject(uri.query()); + expect(params.foo).toEqual("bar"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - provider.requestImage(0, 0, 0); + provider.requestImage(0, 0, 0); - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); it("defaults WMS version to 1.1.1", function () { @@ -520,25 +488,23 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const url = request.url; - const uri = new Uri(url); - const params = queryToObject(uri.query()); - expect(params.version).toEqual("1.1.1"); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + const uri = new Uri(url); + const params = queryToObject(uri.query()); + expect(params.version).toEqual("1.1.1"); - // Don't need to actually load image, but satisfy the request. - deferred.resolve(true); - }); + // Don't need to actually load image, but satisfy the request. + deferred.resolve(true); + }); - provider.requestImage(0, 0, 0); + provider.requestImage(0, 0, 0); - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); it("requestImage returns a promise for an image and loads it for cross-origin use", function () { @@ -550,32 +516,28 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle - ); - - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -590,42 +552,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.rectangle).toEqual( - new WebMercatorTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.srs).toEqual("EPSG:3857"); + expect(params.version).toEqual("1.1.1"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.srs).toEqual("EPSG:3857"); - expect(params.version).toEqual("1.1.1"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -643,42 +601,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.rectangle).toEqual( - new WebMercatorTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.crs).toEqual("EPSG:3857"); + expect(params.version).toEqual("1.3.0"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.crs).toEqual("EPSG:3857"); - expect(params.version).toEqual("1.3.0"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -693,42 +647,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.srs).toEqual("EPSG:4326"); + expect(params.version).toEqual("1.1.1"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.srs).toEqual("EPSG:4326"); - expect(params.version).toEqual("1.1.1"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -746,42 +696,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.srs).toEqual("EPSG:4326"); + expect(params.version).toEqual("1.1.0"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.srs).toEqual("EPSG:4326"); - expect(params.version).toEqual("1.1.0"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -799,42 +745,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.crs).toEqual("CRS:84"); + expect(params.version).toEqual("1.3.0"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.crs).toEqual("CRS:84"); - expect(params.version).toEqual("1.3.0"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -852,42 +794,38 @@ describe("Scene/WebMapServiceImageryProvider", function () { expect(provider.url).toEqual("made/up/wms/server"); expect(provider.layers).toEqual("someLayer"); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); + + expect(params.crs).toEqual("CRS:84"); + expect(params.version).toEqual("1.3.1"); + + const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); + expect(params.bbox).toEqual( + `${rect.west},${rect.south},${rect.east},${rect.north}` ); - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), crossOrigin, deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); - - expect(params.crs).toEqual("CRS:84"); - expect(params.version).toEqual("1.3.1"); - - const rect = tilingScheme.tileXYToNativeRectangle(0, 0, 0); - expect(params.bbox).toEqual( - `${rect.west},${rect.south},${rect.east},${rect.north}` - ); - - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + expect(image).toBeImageOrImageBitmap(); }); }); @@ -900,29 +838,27 @@ describe("Scene/WebMapServiceImageryProvider", function () { }, }); - return provider.readyPromise.then(function () { - spyOn(Resource._Implementations, "createImage").and.callFake(function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); - expect(params.format).toEqual("foo"); - expect(params.format).not.toEqual("image/jpeg"); + expect(params.format).toEqual("foo"); + expect(params.format).not.toEqual("image/jpeg"); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }); + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + }); - return provider.requestImage(0, 0, 0).then(function (image) { - expect(Resource._Implementations.createImage).toHaveBeenCalled(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(Resource._Implementations.createImage).toHaveBeenCalled(); }); }); @@ -931,18 +867,14 @@ describe("Scene/WebMapServiceImageryProvider", function () { url: "made/up/wms/server?foo=bar", layers: "someLayer", }); - expect(function () { - return provider.credit; - }).toThrowDeveloperError(); + expect(provider.credit).toBeUndefined(); const providerWithCredit = new WebMapServiceImageryProvider({ url: "made/up/wms/server?foo=bar", layers: "someLayer", credit: "Thanks to our awesome made up source of this imagery!", }); - return provider.readyPromise.then(function () { - expect(providerWithCredit.credit).toBeDefined(); - }); + expect(providerWithCredit.credit).toBeDefined(); }); it("uses rectangle passed to constructor", function () { @@ -953,17 +885,12 @@ describe("Scene/WebMapServiceImageryProvider", function () { rectangle: rectangle, }); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.rectangle).toEqualEpsilon( - rectangle, - CesiumMath.EPSILON14 - ); - expect(provider.tileDiscardPolicy).toBeUndefined(); - }); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.rectangle).toEqualEpsilon(rectangle, CesiumMath.EPSILON14); + expect(provider.tileDiscardPolicy).toBeUndefined(); }); it("uses maximumLevel passed to constructor", function () { @@ -972,9 +899,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", maximumLevel: 5, }); - return provider.readyPromise.then(function () { - expect(provider.maximumLevel).toEqual(5); - }); + expect(provider.maximumLevel).toEqual(5); }); it("uses minimumLevel passed to constructor", function () { @@ -983,9 +908,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", minimumLevel: 1, }); - return provider.readyPromise.then(function () { - expect(provider.minimumLevel).toEqual(1); - }); + expect(provider.minimumLevel).toEqual(1); }); it("uses tilingScheme passed to constructor", function () { @@ -995,9 +918,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", tilingScheme: tilingScheme, }); - return provider.readyPromise.then(function () { - expect(provider.tilingScheme).toBe(tilingScheme); - }); + expect(provider.tilingScheme).toBe(tilingScheme); }); it("uses tileWidth passed to constructor", function () { @@ -1006,9 +927,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", tileWidth: 123, }); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toBe(123); - }); + expect(provider.tileWidth).toBe(123); }); it("uses tileHeight passed to constructor", function () { @@ -1017,9 +936,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", tileWidth: 456, }); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toBe(456); - }); + expect(provider.tileWidth).toBe(456); }); it("raises error event when image cannot be loaded", function () { @@ -1028,53 +945,51 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - const layer = new ImageryLayer(provider); + const layer = new ImageryLayer(provider); - let tries = 0; - provider.errorEvent.addEventListener(function (error) { - expect(error.timesRetried).toEqual(tries); - ++tries; - if (tries < 3) { - error.retry = true; - } + let tries = 0; + provider.errorEvent.addEventListener(function (error) { + expect(error.timesRetried).toEqual(tries); + ++tries; + if (tries < 3) { + error.retry = true; + } + setTimeout(function () { + RequestScheduler.update(); + }, 1); + }); + + Resource._Implementations.createImage = function ( + request, + crossOrigin, + deferred + ) { + if (tries === 2) { + // Succeed after 2 tries + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + } else { + // fail setTimeout(function () { - RequestScheduler.update(); + deferred.reject(); }, 1); - }); + } + }; - Resource._Implementations.createImage = function ( - request, - crossOrigin, - deferred - ) { - if (tries === 2) { - // Succeed after 2 tries - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - } else { - // fail - setTimeout(function () { - deferred.reject(); - }, 1); - } - }; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - expect(imagery.image).toBeImageOrImageBitmap(); - expect(tries).toEqual(2); - imagery.releaseReference(); - }); + return pollToPromise(function () { + return imagery.state === ImageryState.RECEIVED; + }).then(function () { + expect(imagery.image).toBeImageOrImageBitmap(); + expect(tries).toEqual(2); + imagery.releaseReference(); }); }); @@ -1106,21 +1021,19 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("TOP TANK"); - expect(firstResult.description).toContain("GEOSCIENCE AUSTRALIA"); - expect(firstResult.position).toEqual( - Cartographic.fromDegrees(145.91299, -30.19445) - ); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("TOP TANK"); + expect(firstResult.description).toContain("GEOSCIENCE AUSTRALIA"); + expect(firstResult.position).toEqual( + Cartographic.fromDegrees(145.91299, -30.19445) + ); + }); }); it("works with MapInfo MXP responses", function () { @@ -1150,18 +1063,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("SPRINGWOOD"); - expect(firstResult.description).toContain("NSW"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("SPRINGWOOD"); + expect(firstResult.description).toContain("NSW"); + }); }); it("works with Esri WMS responses", function () { @@ -1191,18 +1102,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("Kyogle (A)"); - expect(firstResult.description).toContain("New South Wales"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("Kyogle (A)"); + expect(firstResult.description).toContain("New South Wales"); + }); }); it("works with THREDDS XML format", function () { @@ -1232,18 +1141,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(+firstResult.properties.value).toBe(42); - expect(firstResult.description).toContain("42"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(+firstResult.properties.value).toBe(42); + expect(firstResult.description).toContain("42"); + }); }); it("works with msGMLOutput format", function () { @@ -1273,18 +1180,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("Hovercraft"); - expect(firstResult.description).toContain("Hovercraft"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("Hovercraft"); + expect(firstResult.description).toContain("Hovercraft"); + }); }); it("works with unknown XML responses", function () { @@ -1314,18 +1219,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBeUndefined(); - expect(firstResult.description).toContain("<FooFeature>"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBeUndefined(); + expect(firstResult.description).toContain("<FooFeature>"); + }); }); it("resolves to undefined on a ServiceException", function () { @@ -1355,13 +1258,11 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult).toBeUndefined(); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult).toBeUndefined(); + }); }); it("returns undefined if list of feature info formats is empty", function () { @@ -1370,10 +1271,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", getFeatureInfoFormats: [], }); - - return provider.readyPromise.then(function () { - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); - }); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); }); it("returns undefined if enablePickFeatures is false", function () { @@ -1382,11 +1280,8 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", enablePickFeatures: false, }); - - return provider.readyPromise.then(function () { - expect(provider.enablePickFeatures).toBe(false); - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); - }); + expect(provider.enablePickFeatures).toBe(false); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); }); it("returns undefined if enablePickFeatures is set to false after initialization", function () { @@ -1396,11 +1291,9 @@ describe("Scene/WebMapServiceImageryProvider", function () { enablePickFeatures: true, }); - return provider.readyPromise.then(function () { - provider.enablePickFeatures = false; - expect(provider.enablePickFeatures).toBe(false); - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); - }); + provider.enablePickFeatures = false; + expect(provider.enablePickFeatures).toBe(false); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); }); it("does not return undefined if enablePickFeatures is set to true after initialization as false", function () { @@ -1410,11 +1303,9 @@ describe("Scene/WebMapServiceImageryProvider", function () { enablePickFeatures: false, }); - return provider.readyPromise.then(function () { - provider.enablePickFeatures = true; - expect(provider.enablePickFeatures).toBe(true); - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).not.toBeUndefined(); - }); + provider.enablePickFeatures = true; + expect(provider.enablePickFeatures).toBe(true); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).not.toBeUndefined(); }); it("requests XML exclusively if specified in getFeatureInfoFormats", function () { @@ -1446,18 +1337,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("SPRINGWOOD"); - expect(firstResult.description).toContain("NSW"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("SPRINGWOOD"); + expect(firstResult.description).toContain("NSW"); + }); }); it("requests GeoJSON exclusively if specified in getFeatureInfoFormats", function () { @@ -1467,41 +1356,39 @@ describe("Scene/WebMapServiceImageryProvider", function () { getFeatureInfoFormats: [new GetFeatureInfoFormat("json")], }); - return provider.readyPromise.then(function () { - Resource._Implementations.loadWithXhr = function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - expect(url).toContain("GetFeatureInfo"); - - if (url.indexOf("json") >= 0) { - deferred.reject(); - } else { - // this should not happen - Resource._DefaultImplementations.loadWithXhr( - "Data/WMS/GetFeatureInfo-MapInfoMXP.xml", - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ); - } - }; - - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (features) { - expect(features.length).toBe(0); - }) - .catch(function () {}); - }); + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(url).toContain("GetFeatureInfo"); + + if (url.indexOf("json") >= 0) { + deferred.reject(); + } else { + // this should not happen + Resource._DefaultImplementations.loadWithXhr( + "Data/WMS/GetFeatureInfo-MapInfoMXP.xml", + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ); + } + }; + + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (features) { + expect(features.length).toBe(0); + }) + .catch(function () {}); }); it("generates correct getFeatureInfo link, WMS 1.1.1, version in getFeatureInfoParameters", function () { @@ -1540,9 +1427,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider.pickFeatures(0, 0, 0, 0.5, 0.5); - }); + return provider.pickFeatures(0, 0, 0, 0.5, 0.5); }); it("generates correct getFeatureInfo link, WMS 1.3.0, version in getFeatureInfoParameters", function () { @@ -1581,9 +1466,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider.pickFeatures(0, 0, 0, 0.5, 0.5); - }); + return provider.pickFeatures(0, 0, 0, 0.5, 0.5); }); it("generates correct getFeatureInfo link, WMS 1.1.1, default version", function () { @@ -1618,9 +1501,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { overrideMimeType ); }; - return provider.readyPromise.then(function () { - return provider.pickFeatures(0, 0, 0, 0.5, 0.5); - }); + return provider.pickFeatures(0, 0, 0, 0.5, 0.5); }); it("uses custom GetFeatureInfo handling function if specified", function () { @@ -1640,39 +1521,35 @@ describe("Scene/WebMapServiceImageryProvider", function () { ], }); - return provider.readyPromise.then(function () { - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(url).toContain("GetFeatureInfo"); + + if (url.indexOf(encodeURIComponent("application/foo")) < 0) { + deferred.reject(); + } + + return Resource._DefaultImplementations.loadWithXhr( + "Data/WMS/GetFeatureInfo-Custom.json", responseType, method, data, headers, deferred, overrideMimeType - ) { - expect(url).toContain("GetFeatureInfo"); - - if (url.indexOf(encodeURIComponent("application/foo")) < 0) { - deferred.reject(); - } + ); + }; - return Resource._DefaultImplementations.loadWithXhr( - "Data/WMS/GetFeatureInfo-Custom.json", - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ); - }; - - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (features) { - expect(features.length).toBe(1); - expect(features[0].name).toEqual("Foo processed!"); - }); + return provider.pickFeatures(0, 0, 0, 0.5, 0.5).then(function (features) { + expect(features.length).toBe(1); + expect(features[0].name).toEqual("Foo processed!"); }); }); @@ -1706,18 +1583,16 @@ describe("Scene/WebMapServiceImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.name).toBe("HTML yeah!"); - expect(firstResult.description).toContain("great information"); - }); - }); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.name).toBe("HTML yeah!"); + expect(firstResult.description).toContain("great information"); + }); }); }); @@ -1769,11 +1644,9 @@ describe("Scene/WebMapServiceImageryProvider", function () { }; let entry; - return provider.readyPromise - .then(function () { - clock.currentTime = JulianDate.fromIso8601("2017-04-26T23:59:56Z"); - return provider.requestImage(0, 0, 0, new Request()); - }) + clock.currentTime = JulianDate.fromIso8601("2017-04-26T23:59:56Z"); + return provider + .requestImage(0, 0, 0, new Request()) .then(function () { RequestScheduler.update(); @@ -1826,10 +1699,8 @@ describe("Scene/WebMapServiceImageryProvider", function () { }; let entry; - return provider.readyPromise - .then(function () { - return provider.requestImage(0, 0, 0, new Request()); - }) + return provider + .requestImage(0, 0, 0, new Request()) .then(function () { // Test tile 0,0,0 wasn't prefetched const cache = provider._timeDynamicImagery._tileCache; @@ -1891,11 +1762,9 @@ describe("Scene/WebMapServiceImageryProvider", function () { provider._reload = jasmine.createSpy(); spyOn(provider._timeDynamicImagery, "getFromCache").and.callThrough(); - return provider.readyPromise - .then(function () { - clock.currentTime = JulianDate.fromIso8601("2017-04-26T23:59:59Z"); - return provider.requestImage(0, 0, 0, new Request()); - }) + clock.currentTime = JulianDate.fromIso8601("2017-04-26T23:59:59Z"); + return provider + .requestImage(0, 0, 0, new Request()) .then(function () { RequestScheduler.update(); clock.tick(); @@ -1951,16 +1820,12 @@ describe("Scene/WebMapServiceImageryProvider", function () { provider._reload = jasmine.createSpy(); spyOn(provider._timeDynamicImagery, "getFromCache").and.callThrough(); - return provider.readyPromise - .then(function () { - return provider.requestImage(0, 0, 0, new Request()); - }) - .then(function () { - const queryParameters = - provider._tileProvider._resource.queryParameters; - expect(queryParameters.Time).toEqual("2017-04-26T00:00:00Z"); - expect(queryParameters.Test).toEqual("testValue"); - }); + return provider.requestImage(0, 0, 0, new Request()).then(function () { + const queryParameters = + provider._tileProvider._resource.queryParameters; + expect(queryParameters.Time).toEqual("2017-04-26T00:00:00Z"); + expect(queryParameters.Test).toEqual("testValue"); + }); }); }); @@ -1971,10 +1836,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", getFeatureInfoUrl: featureUrl, }); - - return provider.readyPromise.then(function () { - expect(provider._pickFeaturesResource.url).toContain(featureUrl); - }); + expect(provider._pickFeaturesResource.url).toContain(featureUrl); }); it("uses url in options if getFeatureInfoUrl is absent for pickResources", function () { @@ -1985,9 +1847,7 @@ describe("Scene/WebMapServiceImageryProvider", function () { layers: "someLayer", }); - return provider.readyPromise.then(function () { - expect(provider._pickFeaturesResource.url).not.toContain(featureUrl); - expect(provider._pickFeaturesResource.url).toContain(getCapabilitiesUrl); - }); + expect(provider._pickFeaturesResource.url).not.toContain(featureUrl); + expect(provider._pickFeaturesResource.url).toContain(getCapabilitiesUrl); }); }); From 52f27c1bbb6ea5841563dec3345f5bf971e32d29 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 27 Jan 2023 15:48:08 -0500 Subject: [PATCH 394/679] Draft --- Specs/MockImageryProvider.js | 4 +- .../Source/DataSources/ModelVisualizer.js | 3 +- packages/engine/Source/Scene/Globe.js | 1 + .../engine/Source/Scene/GlobeSurfaceTile.js | 3 +- .../Source/Scene/GlobeSurfaceTileProvider.js | 17 ++--- packages/engine/Source/Scene/ImageryLayer.js | 11 ++-- .../engine/Source/Scene/IonImageryProvider.js | 3 +- .../Source/Scene/MapboxImageryProvider.js | 2 +- .../engine/Source/Scene/QuadtreePrimitive.js | 2 + .../Source/Scene/QuadtreeTileProvider.js | 20 +----- .../Scene/BingMapsImageryProviderSpec.js | 8 ++- packages/engine/Specs/Scene/GlobeSpec.js | 64 +++++++++---------- .../Specs/Scene/QuadtreePrimitiveSpec.js | 4 -- 13 files changed, 65 insertions(+), 77 deletions(-) diff --git a/Specs/MockImageryProvider.js b/Specs/MockImageryProvider.js index 0d0c915cef9..fa374cf56aa 100644 --- a/Specs/MockImageryProvider.js +++ b/Specs/MockImageryProvider.js @@ -9,7 +9,7 @@ import { function MockImageryProvider() { this.tilingScheme = new GeographicTilingScheme(); - this.ready = false; + this.ready = this._ready = false; this.rectangle = this.tilingScheme.rectangle; this.tileWidth = 256; this.tileHeight = 256; @@ -18,7 +18,7 @@ function MockImageryProvider() { const that = this; Resource.fetchImage("./Data/Images/Green.png").then(function (image) { - that.ready = true; + this.ready = that._ready = true; that._image = image; }); } diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index b86c061ffc5..4715285684d 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -386,7 +386,8 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { if (hasHeightReference) { // We cannot query the availability of the terrain provider till its ready, so the // bounding sphere state will remain pending till the terrain provider is ready. - if (!terrainProvider.ready) { + // ready is deprecated. This is here for backwards compatibility + if (!terrainProvider._ready) { return BoundingSphereState.PENDING; } diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index c6876f2195b..e0ef1c26132 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -436,6 +436,7 @@ Object.defineProperties(Globe.prototype, { return true; } return ( + // ready is deprecated. This is here for backwards compatibility this._surface.tileProvider.ready && this._surface._tileLoadQueueHigh.length === 0 && this._surface._tileLoadQueueMedium.length === 0 && diff --git a/packages/engine/Source/Scene/GlobeSurfaceTile.js b/packages/engine/Source/Scene/GlobeSurfaceTile.js index 0798fa1845f..84bb2cb9e4e 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTile.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTile.js @@ -345,7 +345,8 @@ GlobeSurfaceTile.prototype.processImagery = function ( if (tileImagery.loadingImagery.state === ImageryState.PLACEHOLDER) { const imageryLayer = tileImagery.loadingImagery.imageryLayer; - if (imageryLayer.imageryProvider.ready) { + // ready is deprecated. This is here for backwards compatibility + if (imageryLayer.imageryProvider._ready) { // Remove the placeholder and add the actual skeletons (if any) // at the same position. Then continue the loop at the same index. tileImagery.freeResources(); diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 42a96649b47..6c868eb93ea 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -233,6 +233,7 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { * Gets a value indicating whether or not the provider is ready for use. * @memberof GlobeSurfaceTileProvider.prototype * @type {Boolean} + * @deprecated */ ready: { get: function () { @@ -240,14 +241,13 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { // ready is deprecated; This is here for backwards compatibility this._terrainProvider._ready && (this._imageryLayers.length === 0 || - this._imageryLayers.get(0).imageryProvider.ready) + this._imageryLayers.get(0).imageryProvider._ready) ); }, }, /** - * Gets the tiling scheme used by the provider. This property should - * not be accessed before {@link GlobeSurfaceTileProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof GlobeSurfaceTileProvider.prototype * @type {TilingScheme} */ @@ -360,7 +360,8 @@ function updateCredits(surface, frameState) { const imageryLayers = surface._imageryLayers; for (let i = 0, len = imageryLayers.length; i < len; ++i) { const imageryProvider = imageryLayers.get(i).imageryProvider; - if (imageryProvider.ready && defined(imageryProvider.credit)) { + // ready is deprecated; This is here for backwards compatibility + if (imageryProvider._ready && defined(imageryProvider.credit)) { creditDisplay.addCredit(imageryProvider.credit); } } @@ -564,8 +565,7 @@ GlobeSurfaceTileProvider.prototype.cancelReprojections = function () { }; /** - * Gets the maximum geometric error allowed in a tile at a given level, in meters. This function should not be - * called before {@link GlobeSurfaceTileProvider#ready} returns true. + * Gets the maximum geometric error allowed in a tile at a given level, in meters. * * @param {Number} level The tile level for which to get the maximum geometric error. * @returns {Number} The maximum geometric error in meters. @@ -578,13 +578,10 @@ GlobeSurfaceTileProvider.prototype.getLevelMaximumGeometricError = function ( /** * Loads, or continues loading, a given tile. This function will continue to be called - * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. This function should - * not be called before {@link GlobeSurfaceTileProvider#ready} returns true. + * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. * * @param {FrameState} frameState The frame state. * @param {QuadtreeTile} tile The tile to load. - * - * @exception {DeveloperError} <code>loadTile</code> must not be called before the tile provider is ready. */ GlobeSurfaceTileProvider.prototype.loadTile = function (frameState, tile) { // We don't want to load imagery until we're certain that the terrain tiles are actually visible. diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 497e80cba98..600fe0a5573 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -496,12 +496,12 @@ const terrainRectangleScratch = new Rectangle(); * }); * }); */ -ImageryLayer.prototype.getViewableRectangle = function () { +ImageryLayer.prototype.getViewableRectangle = async function () { const imageryProvider = this._imageryProvider; const rectangle = this._rectangle; - return imageryProvider.readyPromise.then(function () { - return Rectangle.intersection(imageryProvider.rectangle, rectangle); - }); + // readyPromise has been deprecated. This is here for backward compatibility and can be removed with readyPromise. + await imageryProvider._readyPromise; + return Rectangle.intersection(imageryProvider.rectangle, rectangle); }; /** @@ -541,7 +541,8 @@ ImageryLayer.prototype._createTileImagerySkeletons = function ( insertionPoint = surfaceTile.imagery.length; } - if (!imageryProvider.ready) { + // ready is deprecated. This is here for backwards compatibility + if (!imageryProvider._ready) { // The imagery provider is not ready, so we can't create skeletons, yet. // Instead, add a placeholder so that we'll know to create // the skeletons once the provider is ready. diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 6af3112fb74..ac7b6dddef3 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -263,7 +263,8 @@ function IonImageryProvider(options) { }); that._imageryProvider = imageryProvider; - return imageryProvider.readyPromise.then(function () { + // readyPromise is deprecated. This is here for backwards compatibility + return imageryProvider._readyPromise.then(function () { that._ready = true; return true; }); diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index 4b0b3aecb85..15d9fe0540d 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -237,7 +237,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { "MapboxImageryProvider.readyPromise", "MapboxImageryProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." ); - return this._imageryProvider.readyPromise; + return this._imageryProvider._readyPromise; }, }, diff --git a/packages/engine/Source/Scene/QuadtreePrimitive.js b/packages/engine/Source/Scene/QuadtreePrimitive.js index 795b71bf78e..ff1454383ed 100644 --- a/packages/engine/Source/Scene/QuadtreePrimitive.js +++ b/packages/engine/Source/Scene/QuadtreePrimitive.js @@ -520,6 +520,7 @@ function selectTilesForRendering(primitive, frameState) { let i; const tileProvider = primitive._tileProvider; if (!defined(primitive._levelZeroTiles)) { + // ready is deprecated. This is here for backwards compatibility if (tileProvider.ready) { const tilingScheme = tileProvider.tilingScheme; primitive._levelZeroTiles = QuadtreeTile.createLevelZeroTiles( @@ -1387,6 +1388,7 @@ const scratchPosition = new Cartesian3(); const scratchArray = []; function updateHeights(primitive, frameState) { + // ready is deprecated. This is here for backwards compatibility. if (!primitive.tileProvider.ready) { return; } diff --git a/packages/engine/Source/Scene/QuadtreeTileProvider.js b/packages/engine/Source/Scene/QuadtreeTileProvider.js index 92c6a90a983..e135704c012 100644 --- a/packages/engine/Source/Scene/QuadtreeTileProvider.js +++ b/packages/engine/Source/Scene/QuadtreeTileProvider.js @@ -43,17 +43,7 @@ Object.defineProperties(QuadtreeTileProvider.prototype, { }, /** - * Gets a value indicating whether or not the provider is ready for use. - * @memberof QuadtreeTileProvider.prototype - * @type {Boolean} - */ - ready: { - get: DeveloperError.throwInstantiationError, - }, - - /** - * Gets the tiling scheme used by the provider. This property should - * not be accessed before {@link QuadtreeTileProvider#ready} returns true. + * Gets the tiling scheme used by the provider. * @memberof QuadtreeTileProvider.prototype * @type {TilingScheme} */ @@ -112,8 +102,7 @@ QuadtreeTileProvider.prototype.endUpdate = DeveloperError.throwInstantiationError; /** - * Gets the maximum geometric error allowed in a tile at a given level, in meters. This function should not be - * called before {@link QuadtreeTileProvider#ready} returns true. + * Gets the maximum geometric error allowed in a tile at a given level, in meters. * * @see QuadtreeTileProvider#computeDefaultLevelZeroMaximumGeometricError * @@ -128,8 +117,7 @@ QuadtreeTileProvider.prototype.getLevelMaximumGeometricError = /** * Loads, or continues loading, a given tile. This function will continue to be called - * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. This function should - * not be called before {@link QuadtreeTileProvider#ready} returns true. + * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}. * * @memberof QuadtreeTileProvider * @function @@ -137,8 +125,6 @@ QuadtreeTileProvider.prototype.getLevelMaximumGeometricError = * @param {Context} context The rendering context. * @param {FrameState} frameState The frame state. * @param {QuadtreeTile} tile The tile to load. - * - * @exception {DeveloperError} <code>loadTile</code> must not be called before the tile provider is ready. */ QuadtreeTileProvider.prototype.loadTile = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index 16a452069e1..c2ccd6d6a58 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -533,7 +533,9 @@ describe("Scene/BingMapsImageryProvider", function () { BingMapsImageryProvider.fromUrl(url, "") ).toBeRejectedWithError( RuntimeError, - "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial?jsonp=loadJsonp321911&incl=ImageryProviders&key=&uriScheme=http" + jasmine.stringContaining( + "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial" + ) ); }); @@ -570,7 +572,9 @@ describe("Scene/BingMapsImageryProvider", function () { BingMapsImageryProvider.fromUrl(url, "") ).toBeRejectedWithError( RuntimeError, - "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial?jsonp=loadJsonp700536&incl=ImageryProviders&key=&uriScheme=http: metadata does not specify one resource in resourceSets" + jasmine.stringContaining( + "metadata does not specify one resource in resourceSets" + ) ); }); diff --git a/packages/engine/Specs/Scene/GlobeSpec.js b/packages/engine/Specs/Scene/GlobeSpec.js index 191b14014bf..27d578a814e 100644 --- a/packages/engine/Specs/Scene/GlobeSpec.js +++ b/packages/engine/Specs/Scene/GlobeSpec.js @@ -268,7 +268,7 @@ describe( expect(globe.tilesLoaded).toBe(false); }); - it("renders terrain with enableLighting", function () { + it("renders terrain with enableLighting", async function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -277,48 +277,46 @@ describe( const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - const imageryProvider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + const imageryProvider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); layerCollection.addImageryProvider(imageryProvider); - return imageryProvider.readyPromise.then(function () { - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", responseType, method, data, headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", - responseType, - method, - data, - headers, - deferred - ); - }; + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - requestVertexNormals: true, - }); + const terrainProvider = new CesiumTerrainProvider({ + url: "made/up/url", + requestVertexNormals: true, + }); - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - return updateUntilDone(globe).then(function () { - expect(renderOptions).notToRender([0, 0, 0, 255]); + return updateUntilDone(globe).then(function () { + expect(renderOptions).notToRender([0, 0, 0, 255]); - scene.globe.show = false; - expect(renderOptions).toRender([0, 0, 0, 255]); - }); + scene.globe.show = false; + expect(renderOptions).toRender([0, 0, 0, 255]); }); }); diff --git a/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js b/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js index b63255c2017..aceed88b756 100644 --- a/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js +++ b/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js @@ -606,7 +606,6 @@ describe("Scene/QuadtreePrimitive", function () { const result = jasmine.createSpyObj("tileProvider", [ "getQuadtree", "setQuadtree", - "getReady", "getTilingScheme", "getErrorEvent", "initialize", @@ -628,9 +627,6 @@ describe("Scene/QuadtreePrimitive", function () { get: result.getQuadtree, set: result.setQuadtree, }, - ready: { - get: result.getReady, - }, tilingScheme: { get: result.getTilingScheme, }, From e2b6769461f6b14bcf397b0eba5cd5a30ab926bf Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 27 Jan 2023 14:07:41 -0500 Subject: [PATCH 395/679] Remove ready promise from OctahedralProjectedCubeMap, fix fail condition --- .../engine/Source/Scene/ImageBasedLighting.js | 16 +++-- .../Scene/OctahedralProjectedCubeMap.js | 59 ++++++++----------- .../Scene/OctahedralProjectedCubeMapSpec.js | 17 +++--- 3 files changed, 41 insertions(+), 51 deletions(-) diff --git a/packages/engine/Source/Scene/ImageBasedLighting.js b/packages/engine/Source/Scene/ImageBasedLighting.js index efbd2e00cd8..632e1f9dc88 100644 --- a/packages/engine/Source/Scene/ImageBasedLighting.js +++ b/packages/engine/Source/Scene/ImageBasedLighting.js @@ -102,6 +102,7 @@ function ImageBasedLighting(options) { ); this._previousLuminanceAtZenith = luminanceAtZenith; this._previousSphericalHarmonicCoefficients = sphericalHarmonicCoefficients; + this._removeErrorListener = undefined; } Object.defineProperties(ImageBasedLighting.prototype, { @@ -359,13 +360,11 @@ function createSpecularEnvironmentMapAtlas(imageBasedLighting, context) { ); imageBasedLighting._specularEnvironmentMapAtlas = atlas; - atlas.readyPromise - .then(function () { - imageBasedLighting._specularEnvironmentMapLoaded = true; - }) - .catch(function (error) { + imageBasedLighting._removeErrorListener = atlas.errorEvent.addEventListener( + (error) => { console.error(`Error loading specularEnvironmentMaps: ${error}`); - }); + } + ); } // Regenerate shaders so they do not use an environment map. @@ -436,6 +435,9 @@ ImageBasedLighting.prototype.update = function (frameState) { if (defined(this._specularEnvironmentMapAtlas)) { this._specularEnvironmentMapAtlas.update(frameState); + if (this._specularEnvironmentMapAtlas.ready) { + this._specularEnvironmentMapLoaded = true; + } } const recompileWithDefaultAtlas = @@ -504,6 +506,8 @@ ImageBasedLighting.prototype.destroy = function () { this._specularEnvironmentMapAtlas = this._specularEnvironmentMapAtlas && this._specularEnvironmentMapAtlas.destroy(); + this._removeErrorListener = + this._removeErrorListener && this._removeErrorListener(); return destroyObject(this); }; diff --git a/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js b/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js index e5c8713958d..ff54df0c5a0 100644 --- a/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js +++ b/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js @@ -2,6 +2,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import ComponentDatatype from "../Core/ComponentDatatype.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; +import Event from "../Core/Event.js"; import IndexDatatype from "../Core/IndexDatatype.js"; import loadKTX2 from "../Core/loadKTX2.js"; import PixelFormat from "../Core/PixelFormat.js"; @@ -43,26 +44,7 @@ function OctahedralProjectedCubeMap(url) { this._loading = false; this._ready = false; - const cubeMap = this; - this._readyPromise = new Promise((resolve, reject) => { - cubeMap._completeLoadFromCache = (cachedTexture) => { - cleanupResources(this); - this._texture = cachedTexture; - this._maximumMipmapLevel = this._texture.maximumMipmapLevel; - this._ready = true; - resolve(); - return; - }; - - cubeMap._failLoad = (error) => { - reject(error); - }; - - cubeMap._completeLoad = () => { - this._ready = true; - resolve(); - }; - }); + this._errorEvent = new Event(); } Object.defineProperties(OctahedralProjectedCubeMap.prototype, { @@ -77,6 +59,18 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, { return this._url; }, }, + /** + * Gets an event that is raised when encountering an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. + * @memberof OctahedralProjectedCubeMap.prototype + * @type {Event} + * @readonly + */ + errorEvent: { + get: function () { + return this._errorEvent; + }, + }, /** * A texture containing all the packed convolutions. * @memberof OctahedralProjectedCubeMap.prototype @@ -110,17 +104,6 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, { return this._ready; }, }, - /** - * Gets a promise that resolves when the texture atlas is ready to use. - * @memberof OctahedralProjectedCubeMap.prototype - * @type {Promise<void>} - * @readonly - */ - readyPromise: { - get: function () { - return this._readyPromise; - }, - }, }); OctahedralProjectedCubeMap.isSupported = function (context) { @@ -298,7 +281,10 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { if (!defined(this._texture) && !this._loading) { const cachedTexture = frameState.context.textureCache.getTexture(this._url); if (defined(cachedTexture)) { - this._completeLoadFromCache(cachedTexture); + cleanupResources(this); + this._texture = cachedTexture; + this._maximumMipmapLevel = this._texture.maximumMipmapLevel; + this._ready = true; } } @@ -310,8 +296,11 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { that._cubeMapBuffers = buffers; that._loading = false; }) - .catch(function (e) { - that._failLoad(e); + .catch(function (error) { + if (that.isDestroyed()) { + return; + } + that._errorEvent.raiseEvent(error); }); this._loading = true; } @@ -417,7 +406,7 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { }); frameState.commandList.push(atlasCommand); - this._completeLoad(); + this._ready = true; }; /** diff --git a/packages/engine/Specs/Scene/OctahedralProjectedCubeMapSpec.js b/packages/engine/Specs/Scene/OctahedralProjectedCubeMapSpec.js index c8cda34593e..4d888da1355 100644 --- a/packages/engine/Specs/Scene/OctahedralProjectedCubeMapSpec.js +++ b/packages/engine/Specs/Scene/OctahedralProjectedCubeMapSpec.js @@ -208,7 +208,7 @@ describe( }); }); - it("rejects when environment map fails to load.", function () { + it("raises error event when environment map fails to load.", function () { if (!OctahedralProjectedCubeMap.isSupported(context)) { return; } @@ -217,15 +217,12 @@ describe( const frameState = createFrameState(context); let error; - projection.readyPromise - .then(function () { - fail("Should not resolve."); - }) - .catch(function (e) { - error = e; - expect(error).toBeDefined(); - expect(projection.ready).toEqual(false); - }); + const removeListener = projection.errorEvent.addEventListener((e) => { + error = e; + expect(error).toBeDefined(); + expect(projection.ready).toEqual(false); + removeListener(); + }); return pollToPromise(function () { projection.update(frameState); From 119fd5e7b2b4e13d654eef717e5d9702435575b8 Mon Sep 17 00:00:00 2001 From: Janine Liu <janine.h.liu@gmail.com> Date: Mon, 30 Jan 2023 11:18:42 -0500 Subject: [PATCH 396/679] Fix decodeRGB565 spec --- packages/engine/Specs/Core/AttributeCompressionSpec.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/engine/Specs/Core/AttributeCompressionSpec.js b/packages/engine/Specs/Core/AttributeCompressionSpec.js index 54edecd3244..c288d01c4d1 100644 --- a/packages/engine/Specs/Core/AttributeCompressionSpec.js +++ b/packages/engine/Specs/Core/AttributeCompressionSpec.js @@ -1298,7 +1298,7 @@ describe("Core/AttributeCompression", function () { const input = new Uint16Array([ 0, //0b00001_000001_00001 - 2881, + 2081, //0b10000_100000_01000 33800, //0b11111_111111_11111 @@ -1319,10 +1319,11 @@ describe("Core/AttributeCompression", function () { 31 / 31, ]); - const result = new Float32Array(input.length * 3); + const resultLength = input.length * 3; + const result = new Float32Array(resultLength); AttributeCompression.decodeRGB565(input, result); - for (let i = 0; i < input.length; i++) { + for (let i = 0; i < resultLength; i++) { expect(result[i]).toEqual(expected[i]); } }); From 65fb9fed8f7d71ce6227038679186c39076ee4b5 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 31 Jan 2023 16:06:57 -0500 Subject: [PATCH 397/679] draft --- Specs/MockImageryProvider.js | 2 +- packages/engine/Source/Scene/Globe.js | 4 +- .../engine/Source/Scene/IonImageryProvider.js | 133 +++++++++--------- .../Scene/TileMapServiceImageryProvider.js | 1 + .../Scene/UrlTemplateImageryProvider.js | 4 +- .../engine/Source/Scene/createWorldImagery.js | 14 +- .../Source/Scene/createWorldImageryAsync.js | 36 +++++ .../Scene/BingMapsImageryProviderSpec.js | 8 +- .../Scene/GlobeSurfaceTileProviderSpec.js | 2 +- .../Specs/Scene/ImageryLayerCollectionSpec.js | 9 ++ .../Specs/Scene/IonImageryProviderSpec.js | 7 +- .../Specs/Scene/QuadtreePrimitiveSpec.js | 4 + .../TileMapServiceImageryProviderSpec.js | 2 +- .../Scene/createWorldImageryAsyncSpec.js | 9 ++ 14 files changed, 149 insertions(+), 86 deletions(-) create mode 100644 packages/engine/Source/Scene/createWorldImageryAsync.js create mode 100644 packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js diff --git a/Specs/MockImageryProvider.js b/Specs/MockImageryProvider.js index fa374cf56aa..f90c072834e 100644 --- a/Specs/MockImageryProvider.js +++ b/Specs/MockImageryProvider.js @@ -18,7 +18,7 @@ function MockImageryProvider() { const that = this; Resource.fetchImage("./Data/Images/Green.png").then(function (image) { - this.ready = that._ready = true; + that.ready = that._ready = true; that._image = image; }); } diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index e0ef1c26132..de07599f29e 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -985,9 +985,9 @@ Globe.prototype.beginFrame = function (frameState) { const terrainProvider = this.terrainProvider; const hasWaterMask = this.showWaterEffect && - terrainProvider.hasWaterMask && // ready is deprecated; This is here for backwards compatibility - terrainProvider._ready; + terrainProvider._ready && + terrainProvider.hasWaterMask; if (hasWaterMask && this._oceanNormalMapResourceDirty) { // url changed, load new normal map asynchronously diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index ac7b6dddef3..63b173dd9b8 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -197,7 +197,6 @@ function IonImageryProvider(options) { this._tileCredits = undefined; this._errorEvent = new Event(); - const that = this; const assetId = options.assetId; if (defined(assetId)) { deprecationWarning( @@ -205,70 +204,7 @@ function IonImageryProvider(options) { "options.assetId was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use IonImageryProvider.fromAssetId instead." ); - const endpointResource = IonResource._createEndpointResource( - assetId, - options - ); - - // A simple cache to avoid making repeated requests to ion for endpoints we've - // already retrieved. This exists mainly to support Bing caching to reduce - // world imagery sessions, but provides a small boost of performance in general - // if constantly reloading assets - const cacheKey = - options.assetId.toString() + options.accessToken + options.server; - let promise = IonImageryProvider._endpointCache[cacheKey]; - if (!defined(promise)) { - promise = endpointResource.fetchJson(); - IonImageryProvider._endpointCache[cacheKey] = promise; - } - - this._readyPromise = promise.then(function (endpoint) { - if (endpoint.type !== "IMAGERY") { - return Promise.reject( - new RuntimeError( - `Cesium ion asset ${assetId} is not an imagery asset.` - ) - ); - } - - let imageryProvider; - const externalType = endpoint.externalType; - if (!defined(externalType)) { - imageryProvider = new TileMapServiceImageryProvider({ - url: new IonResource(endpoint, endpointResource), - }); - } else { - const factory = ImageryProviderMapping[externalType]; - - if (!defined(factory)) { - return Promise.reject( - new RuntimeError( - `Unrecognized Cesium ion imagery type: ${externalType}` - ) - ); - } - imageryProvider = factory(endpoint.options); - } - - that._tileCredits = IonResource.getCreditsFromEndpoint( - endpoint, - endpointResource - ); - - imageryProvider.errorEvent.addEventListener(function (tileProviderError) { - //Propagate the errorEvent but set the provider to this instance instead - //of the inner instance. - tileProviderError.provider = that; - that._errorEvent.raiseEvent(tileProviderError); - }); - - that._imageryProvider = imageryProvider; - // readyPromise is deprecated. This is here for backwards compatibility - return imageryProvider._readyPromise.then(function () { - that._ready = true; - return true; - }); - }); + IonImageryProvider._initialize(this, assetId, options); } } @@ -454,6 +390,72 @@ Object.defineProperties(IonImageryProvider.prototype, { }, }); +// This is here for backwards compatibility +IonImageryProvider._initialize = function (provider, assetId, options) { + const endpointResource = IonResource._createEndpointResource( + assetId, + options + ); + + // A simple cache to avoid making repeated requests to ion for endpoints we've + // already retrieved. This exists mainly to support Bing caching to reduce + // world imagery sessions, but provides a small boost of performance in general + // if constantly reloading assets + const cacheKey = + options.assetId.toString() + options.accessToken + options.server; + let promise = IonImageryProvider._endpointCache[cacheKey]; + if (!defined(promise)) { + promise = endpointResource.fetchJson(); + IonImageryProvider._endpointCache[cacheKey] = promise; + } + + provider._readyPromise = promise.then(function (endpoint) { + if (endpoint.type !== "IMAGERY") { + return Promise.reject( + new RuntimeError(`Cesium ion asset ${assetId} is not an imagery asset.`) + ); + } + + let imageryProvider; + const externalType = endpoint.externalType; + if (!defined(externalType)) { + imageryProvider = new TileMapServiceImageryProvider({ + url: new IonResource(endpoint, endpointResource), + }); + } else { + const factory = ImageryProviderMapping[externalType]; + + if (!defined(factory)) { + return Promise.reject( + new RuntimeError( + `Unrecognized Cesium ion imagery type: ${externalType}` + ) + ); + } + imageryProvider = factory(endpoint.options); + } + + provider._tileCredits = IonResource.getCreditsFromEndpoint( + endpoint, + endpointResource + ); + + imageryProvider.errorEvent.addEventListener(function (tileProviderError) { + //Propagate the errorEvent but set the provider to this instance instead + //of the inner instance. + tileProviderError.provider = provider; + provider._errorEvent.raiseEvent(tileProviderError); + }); + + provider._imageryProvider = imageryProvider; + // readyPromise is deprecated. This is here for backwards compatibility + return imageryProvider._readyPromise.then(function () { + provider._ready = true; + return true; + }); + }); +}; + /** * Creates a provider for tiled imagery using the Cesium ion REST API. * @@ -473,6 +475,7 @@ IonImageryProvider.fromAssetId = async function (assetId, options) { Check.typeOf.number("assetId", assetId); //>>includeEnd('debug'); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); const endpointResource = IonResource._createEndpointResource( assetId, options diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index 749e94ef673..e440344598f 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -79,6 +79,7 @@ function TileMapServiceImageryProvider(options) { if (defined(options.url)) { this._metadataError = undefined; + this._ready = false; let resource; const that = this; diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index 3feb3ce5b5a..2f47420ae1b 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -256,6 +256,7 @@ function UrlTemplateImageryProvider(options) { this._pickFeaturesTags = allPickFeaturesTags; this._readyPromise = Promise.resolve(true); + this._ready = true; /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and @@ -570,7 +571,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { "UrlTemplateImageryProvider.ready", "UrlTemplateImageryProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." ); - return defined(this._resource); + return this._ready && defined(this._resource); }, }, @@ -711,6 +712,7 @@ UrlTemplateImageryProvider.prototype._reinitialize = function (options) { that._tags = allTags; that._pickFeaturesResource = pickFeaturesResource; that._pickFeaturesTags = allPickFeaturesTags; + that._ready = true; return true; }); diff --git a/packages/engine/Source/Scene/createWorldImagery.js b/packages/engine/Source/Scene/createWorldImagery.js index 36d07b0e7f8..227e3d47fb2 100644 --- a/packages/engine/Source/Scene/createWorldImagery.js +++ b/packages/engine/Source/Scene/createWorldImagery.js @@ -1,4 +1,5 @@ import defaultValue from "../Core/defaultValue.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import IonImageryProvider from "./IonImageryProvider.js"; import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; @@ -29,10 +30,17 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * */ function createWorldImagery(options) { + deprecationWarning( + "createWorldImagery", + "createWorldImagery was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use createWorldImageryAsync instead." + ); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); const style = defaultValue(options.style, IonWorldImageryStyle.AERIAL); - return new IonImageryProvider({ - assetId: style, - }); + const provider = new IonImageryProvider(); + + // This is here for backwards compatibility + IonImageryProvider._initialize(provider, style, options); + return provider; } export default createWorldImagery; diff --git a/packages/engine/Source/Scene/createWorldImageryAsync.js b/packages/engine/Source/Scene/createWorldImageryAsync.js new file mode 100644 index 00000000000..801baf1cb98 --- /dev/null +++ b/packages/engine/Source/Scene/createWorldImageryAsync.js @@ -0,0 +1,36 @@ +import defaultValue from "../Core/defaultValue.js"; +import IonImageryProvider from "./IonImageryProvider.js"; +import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; + +/** + * Creates an {@link IonImageryProvider} instance for ion's default global base imagery layer, currently Bing Maps. + * + * @function + * + * @param {Object} [options] Object with the following properties: + * @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. + * @returns {IonImageryProvider} + * + * @see Ion + * + * @example + * // Create Cesium World Terrain with default settings + * const viewer = new Cesium.Viewer("cesiumContainer", { + * imageryProvider: await Cesium.createWorldImageryAsync(); + * }); + * + * @example + * // Create Cesium World Terrain with water and normals. + * const viewer = new Cesium.Viewer("cesiumContainer", { + * imageryProvider: await Cesium.createWorldImageryAsync({ + * style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS + * }) + * }); + * + */ +function createWorldImageryAsync(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const style = defaultValue(options.style, IonWorldImageryStyle.AERIAL); + return IonImageryProvider.fromAssetId(style); +} +export default createWorldImageryAsync; diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index c2ccd6d6a58..03ec459bf09 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -533,9 +533,7 @@ describe("Scene/BingMapsImageryProvider", function () { BingMapsImageryProvider.fromUrl(url, "") ).toBeRejectedWithError( RuntimeError, - jasmine.stringContaining( - "An error occurred while accessing http://fake.fake.invalid/REST/v1/Imagery/Metadata/Aerial" - ) + new RegExp("An error occurred while accessing") ); }); @@ -572,9 +570,7 @@ describe("Scene/BingMapsImageryProvider", function () { BingMapsImageryProvider.fromUrl(url, "") ).toBeRejectedWithError( RuntimeError, - jasmine.stringContaining( - "metadata does not specify one resource in resourceSets" - ) + new RegExp("metadata does not specify one resource in resourceSets") ); }); diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js index 12f7b341e9c..a9852226bab 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js @@ -712,7 +712,7 @@ describe( }); }); - it("renders imagery cutout", function () { + it("renders imagery cutout", async function () { expect(scene).toRender([0, 0, 0, 255]); const layer = scene.imageryLayers.addImageryProvider( diff --git a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js index e0a90dfc689..ec2914dd4de 100644 --- a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js @@ -352,6 +352,7 @@ describe( it("returns imagery from one layer", function () { const provider = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -386,6 +387,7 @@ describe( it("returns imagery from two layers", function () { const provider1 = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -403,6 +405,7 @@ describe( const provider2 = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -492,6 +495,7 @@ describe( it("returns undefined when ImageryProvider does not implement pickFeatures", function () { const provider = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -527,6 +531,7 @@ describe( it("returns undefined when ImageryProvider.pickFeatures returns undefined", function () { const provider = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -566,6 +571,7 @@ describe( it("returns features from one layer", function () { const provider = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -621,6 +627,7 @@ describe( it("returns features from two layers", function () { const provider1 = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -650,6 +657,7 @@ describe( const provider2 = { ready: true, + _ready: true, rectangle: Rectangle.MAX_VALUE, tileWidth: 256, tileHeight: 256, @@ -708,6 +716,7 @@ describe( it("correctly picks from a terrain tile that is partially covered by correct-level imagery and partially covered by imagery from an ancestor level", function () { const provider = { ready: true, + _ready: true, rectangle: new Rectangle( -Math.PI, -WebMercatorProjection.MaximumLatitude, diff --git a/packages/engine/Specs/Scene/IonImageryProviderSpec.js b/packages/engine/Specs/Scene/IonImageryProviderSpec.js index efc9c4f7c88..60cf3b780a5 100644 --- a/packages/engine/Specs/Scene/IonImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/IonImageryProviderSpec.js @@ -138,12 +138,7 @@ describe("Scene/IonImageryProvider", function () { it("fromAssetId throws without assetId", async function () { await expectAsync( - createTestProviderAsync({ - type: "3DTILES", - url: "http://test.invalid/layer", - accessToken: "not_really_a_refresh_token", - attributions: [], - }) + IonImageryProvider.fromAssetId() ).toBeRejectedWithDeveloperError(); }); diff --git a/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js b/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js index aceed88b756..b63255c2017 100644 --- a/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js +++ b/packages/engine/Specs/Scene/QuadtreePrimitiveSpec.js @@ -606,6 +606,7 @@ describe("Scene/QuadtreePrimitive", function () { const result = jasmine.createSpyObj("tileProvider", [ "getQuadtree", "setQuadtree", + "getReady", "getTilingScheme", "getErrorEvent", "initialize", @@ -627,6 +628,9 @@ describe("Scene/QuadtreePrimitive", function () { get: result.getQuadtree, set: result.setQuadtree, }, + ready: { + get: result.getReady, + }, tilingScheme: { get: result.getTilingScheme, }, diff --git a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js index 4a193561f4b..3ffa7be62b4 100644 --- a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js @@ -252,7 +252,7 @@ describe("Scene/TileMapServiceImageryProvider", function () { TileMapServiceImageryProvider.fromUrl("made/up/tms/server") ).toBeRejectedWithError( RuntimeError, - "http://localhost:9876/made/up/tms/server/tilemapresource.xmlspecifies an unsupported profile attribute, foobar." + "http://localhost:9876/made/up/tms/server/tilemapresource.xml specifies an unsupported profile attribute, foobar." ); }); diff --git a/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js b/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js new file mode 100644 index 00000000000..81372557917 --- /dev/null +++ b/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js @@ -0,0 +1,9 @@ +import { createWorldImageryAsync, IonImageryProvider } from "../../index.js"; + +describe("Core/createWorldImageryAsync", function () { + it("resolves to IonImageryProvider instance with default parameters", async function () { + const provider = await createWorldImageryAsync(); + expect(provider).toBeInstanceOf(IonImageryProvider); + expect(provider.assetId).toBe(2); + }); +}); From bf80efa061816c77918d19d89631c8ca608ce35a Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 31 Jan 2023 16:59:38 -0500 Subject: [PATCH 398/679] Use top level await in Sandcastle --- Apps/Sandcastle/Sandcastle-helpers.js | 8 +- .../gallery/3D Models Coloring.html | 8 +- Apps/Sandcastle/gallery/3D Models.html | 8 +- .../gallery/3D Tiles Adjust Height.html | 8 +- Apps/Sandcastle/gallery/3D Tiles BIM.html | 8 +- .../3D Tiles Batch Table Hierarchy.html | 8 +- .../gallery/3D Tiles Clipping Planes.html | 8 +- Apps/Sandcastle/gallery/3D Tiles Compare.html | 8 +- .../gallery/3D Tiles Feature Picking.html | 504 +++++++------- .../gallery/3D Tiles Feature Styling.html | 301 +++++---- Apps/Sandcastle/gallery/3D Tiles Formats.html | 8 +- .../gallery/3D Tiles Inspector.html | 50 +- .../gallery/3D Tiles Interactivity.html | 337 +++++----- .../Sandcastle/gallery/3D Tiles Interior.html | 8 +- .../gallery/3D Tiles Next CDB Yemen.html | 8 +- ...es Next Photogrammetry Classification.html | 17 +- .../gallery/3D Tiles Next S2 Globe.html | 8 +- ...D Tiles Photogrammetry Classification.html | 82 +-- .../gallery/3D Tiles Photogrammetry.html | 26 +- .../3D Tiles Point Cloud Classification.html | 146 ++-- .../gallery/3D Tiles Point Cloud Shading.html | 379 ++++++----- .../gallery/3D Tiles Point Cloud Styling.html | 8 +- .../gallery/3D Tiles Point Cloud.html | 50 +- .../3D Tiles Terrain Classification.html | 94 +-- .../Sandcastle/gallery/Ambient Occlusion.html | 8 +- Apps/Sandcastle/gallery/ArcGIS MapServer.html | 8 +- .../ArcGIS Tiled Elevation Terrain.html | 24 +- Apps/Sandcastle/gallery/ArcticDEM.html | 28 +- Apps/Sandcastle/gallery/Atmosphere.html | 8 +- Apps/Sandcastle/gallery/Billboards.html | 8 +- Apps/Sandcastle/gallery/Bloom.html | 8 +- Apps/Sandcastle/gallery/Blue Marble.html | 8 +- Apps/Sandcastle/gallery/Box.html | 8 +- Apps/Sandcastle/gallery/CZML 3D Tiles.html | 8 +- .../gallery/CZML Billboard and Label.html | 8 +- Apps/Sandcastle/gallery/CZML Box.html | 8 +- .../gallery/CZML Circles and Ellipses.html | 8 +- Apps/Sandcastle/gallery/CZML Colors.html | 8 +- .../gallery/CZML Cones and Cylinders.html | 8 +- Apps/Sandcastle/gallery/CZML Corridor.html | 8 +- .../gallery/CZML Custom Properties.html | 8 +- .../CZML Model - Node Transformations.html | 8 +- .../gallery/CZML Model Articulations.html | 8 +- .../gallery/CZML Model Data URL.html | 8 +- Apps/Sandcastle/gallery/CZML Model.html | 8 +- Apps/Sandcastle/gallery/CZML Path.html | 28 +- .../gallery/CZML Point - Time Dynamic.html | 8 +- Apps/Sandcastle/gallery/CZML Point.html | 8 +- ...ML Polygon - Interpolating References.html | 8 +- ...ZML Polygon - Intervals, Availability.html | 8 +- Apps/Sandcastle/gallery/CZML Polygon.html | 8 +- .../gallery/CZML Polyline Volume.html | 8 +- Apps/Sandcastle/gallery/CZML Polyline.html | 8 +- .../gallery/CZML Position Definitions.html | 8 +- Apps/Sandcastle/gallery/CZML Rectangle.html | 8 +- .../gallery/CZML Reference Properties.html | 8 +- .../gallery/CZML Spheres and Ellipsoids.html | 8 +- Apps/Sandcastle/gallery/CZML Wall.html | 8 +- Apps/Sandcastle/gallery/CZML ZIndex.html | 8 +- Apps/Sandcastle/gallery/CZML.html | 8 +- .../Sandcastle/gallery/Callback Property.html | 8 +- Apps/Sandcastle/gallery/Camera Tutorial.html | 8 +- Apps/Sandcastle/gallery/Camera.html | 8 +- Apps/Sandcastle/gallery/Cardboard.html | 268 ++++---- .../gallery/Cartographic Limit Rectangle.html | 104 +-- Apps/Sandcastle/gallery/Cesium Inspector.html | 138 ++-- .../gallery/Cesium OSM Buildings.html | 32 +- Apps/Sandcastle/gallery/Cesium Widget.html | 8 +- .../gallery/Cesium World Terrain.html | 20 +- .../gallery/Circles and Ellipses.html | 8 +- .../Sandcastle/gallery/Clamp to 3D Model.html | 8 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 100 +-- Apps/Sandcastle/gallery/Clamp to Terrain.html | 20 +- .../gallery/Classification Types.html | 20 +- Apps/Sandcastle/gallery/Classification.html | 559 ++++++++-------- Apps/Sandcastle/gallery/Clock.html | 8 +- Apps/Sandcastle/gallery/Cloud Parameters.html | 8 +- Apps/Sandcastle/gallery/Clouds.html | 414 ++++++------ Apps/Sandcastle/gallery/Clustering.html | 8 +- Apps/Sandcastle/gallery/Corridor.html | 8 +- .../Sandcastle/gallery/Custom DataSource.html | 8 +- Apps/Sandcastle/gallery/Custom Geocoder.html | 8 +- .../Custom Per-Feature Post Process.html | 8 +- .../gallery/Custom Post Process.html | 8 +- .../gallery/Custom Shaders 3D Tiles.html | 8 +- .../gallery/Custom Shaders Models.html | 8 +- .../Custom Shaders Property Textures.html | 21 +- .../gallery/Cylinders and Cones.html | 8 +- .../gallery/DataSource Ordering.html | 8 +- Apps/Sandcastle/gallery/Depth of Field.html | 8 +- .../gallery/Distance Display Conditions.html | 8 +- .../gallery/Drawing on Terrain.html | 17 +- Apps/Sandcastle/gallery/Earth at Night.html | 8 +- .../gallery/Elevation Band Material.html | 375 +++++------ Apps/Sandcastle/gallery/Export KML.html | 8 +- Apps/Sandcastle/gallery/FXAA.html | 60 +- Apps/Sandcastle/gallery/Fog Post Process.html | 8 +- Apps/Sandcastle/gallery/GPX.html | 20 +- .../gallery/GeoJSON and TopoJSON.html | 8 +- .../gallery/GeoJSON simplestyle.html | 8 +- .../gallery/Geometry Height Reference.html | 17 +- .../gallery/Geometry and Appearances.html | 8 +- Apps/Sandcastle/gallery/Globe Interior.html | 8 +- Apps/Sandcastle/gallery/Globe Materials.html | 24 +- .../gallery/Globe Translucency.html | 414 ++++++------ .../gallery/Google Earth Enterprise.html | 57 +- Apps/Sandcastle/gallery/HTML Overlays.html | 8 +- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 8 +- Apps/Sandcastle/gallery/Hello World.html | 8 +- .../gallery/High Dynamic Range.html | 108 +-- .../gallery/I3S 3D Object Layer.html | 209 +++--- .../gallery/I3S Feature Picking.html | 209 +++--- .../gallery/I3S IntegratedMesh Layer.html | 94 +-- .../gallery/Image-Based Lighting.html | 8 +- .../gallery/Imagery Adjustment.html | 8 +- .../gallery/Imagery Color To Alpha.html | 8 +- Apps/Sandcastle/gallery/Imagery Cutout.html | 8 +- .../gallery/Imagery Layers Manipulation.html | 8 +- .../gallery/Imagery Layers Split.html | 8 +- .../Imagery Layers Texture Filters.html | 8 +- Apps/Sandcastle/gallery/Imagery Layers.html | 8 +- Apps/Sandcastle/gallery/Interpolation.html | 17 +- Apps/Sandcastle/gallery/KML Tours.html | 8 +- Apps/Sandcastle/gallery/KML.html | 8 +- Apps/Sandcastle/gallery/Labels.html | 8 +- Apps/Sandcastle/gallery/LensFlare.html | 8 +- Apps/Sandcastle/gallery/Lighting.html | 26 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 8 +- Apps/Sandcastle/gallery/MSAA.html | 17 +- .../Manually Controlled Animation.html | 8 +- Apps/Sandcastle/gallery/Map Pins.html | 8 +- Apps/Sandcastle/gallery/Materials.html | 8 +- .../gallery/Montreal Point Cloud.html | 20 +- Apps/Sandcastle/gallery/Multi-part CZML.html | 8 +- .../gallery/Multiple Synced Views.html | 8 +- Apps/Sandcastle/gallery/Natural Earth II.html | 8 +- Apps/Sandcastle/gallery/Offline.html | 8 +- Apps/Sandcastle/gallery/PAMAP Terrain.html | 28 +- .../gallery/Parallels and Meridians.html | 8 +- .../gallery/Partial Ellipsoids.html | 8 +- .../gallery/Particle System Fireworks.html | 8 +- .../gallery/Particle System Tails.html | 8 +- .../gallery/Particle System Weather.html | 17 +- Apps/Sandcastle/gallery/Particle System.html | 8 +- .../gallery/Per-Feature Post Processing.html | 8 +- .../gallery/Physically-Based Materials.html | 17 +- Apps/Sandcastle/gallery/Picking.html | 8 +- Apps/Sandcastle/gallery/Plane.html | 8 +- Apps/Sandcastle/gallery/Points.html | 8 +- Apps/Sandcastle/gallery/Polygon.html | 8 +- Apps/Sandcastle/gallery/Polyline Dash.html | 8 +- Apps/Sandcastle/gallery/Polyline Volume.html | 8 +- Apps/Sandcastle/gallery/Polyline.html | 8 +- .../gallery/Polylines on 3D Tiles.html | 8 +- Apps/Sandcastle/gallery/Post Processing.html | 8 +- .../gallery/Procedural Terrain.html | 8 +- Apps/Sandcastle/gallery/Projection.html | 8 +- Apps/Sandcastle/gallery/Rectangle.html | 8 +- .../gallery/Resolution Scaling.html | 8 +- Apps/Sandcastle/gallery/Rotatable 2D Map.html | 8 +- .../gallery/Sample Height from 3D Tiles.html | 20 +- .../gallery/Scene Rendering Performance.html | 17 +- Apps/Sandcastle/gallery/Sentinel-2.html | 8 +- Apps/Sandcastle/gallery/Shadows.html | 17 +- .../gallery/Show or Hide Entities.html | 8 +- .../gallery/Spheres and Ellipsoids.html | 8 +- Apps/Sandcastle/gallery/Star Burst.html | 8 +- .../gallery/Terrain Clipping Planes.html | 633 +++++++++--------- .../gallery/Terrain Exaggeration.html | 20 +- Apps/Sandcastle/gallery/Terrain.html | 26 +- .../gallery/Time Dynamic Point Cloud.html | 8 +- .../gallery/Time Dynamic Wheels.html | 8 +- .../Sandcastle/gallery/Underground Color.html | 8 +- Apps/Sandcastle/gallery/Video.html | 8 +- Apps/Sandcastle/gallery/Wall.html | 8 +- .../gallery/Washington DC 2017.html | 8 +- .../gallery/Web Map Service (WMS).html | 8 +- .../Web Map Tile Service with Time.html | 8 +- .../gallery/Z-Indexing Geometry.html | 8 +- .../development/3D Models Articulations.html | 8 +- .../development/3D Models Node Explorer.html | 8 +- .../gallery/development/3D Models.html | 8 +- .../3D Tiles Performance Testing.html | 8 +- .../gallery/development/3D Tiles Split.html | 8 +- .../development/BillboardClampToGround.html | 20 +- .../development/Billboards Instancing.html | 20 +- .../gallery/development/Billboards.html | 8 +- .../gallery/development/Box Outline.html | 8 +- Apps/Sandcastle/gallery/development/Box.html | 8 +- .../gallery/development/Circle Outline.html | 8 +- .../gallery/development/Circle.html | 8 +- .../development/Coplanar Polygon Outline.html | 8 +- .../gallery/development/Coplanar Polygon.html | 8 +- .../gallery/development/Corridor Outline.html | 8 +- .../gallery/development/Corridor.html | 8 +- .../gallery/development/Custom Primitive.html | 8 +- .../gallery/development/Cylinder Outline.html | 8 +- .../gallery/development/Cylinder.html | 8 +- .../development/Display Conditions.html | 8 +- .../gallery/development/Ellipse Outline.html | 8 +- .../gallery/development/Ellipse.html | 8 +- .../development/Ellipsoid Outline.html | 8 +- .../development/Ellipsoid Surface.html | 8 +- .../gallery/development/Ellipsoid.html | 8 +- Apps/Sandcastle/gallery/development/Fog.html | 20 +- .../gallery/development/Frustum.html | 8 +- ...fset Attribute box cylinder ellipsoid.html | 8 +- .../Geometry Offset Attribute.html | 8 +- .../development/Geometry and Appearances.html | 8 +- .../development/Ground Polyline Material.html | 158 ++--- .../Ground Primitive Materials.html | 26 +- .../gallery/development/Ground Primitive.html | 20 +- .../gallery/development/Labels.html | 8 +- .../development/Many Clipping Planes.html | 464 ++++++------- .../gallery/development/Material.html | 8 +- .../gallery/development/Multiple Shadows.html | 17 +- .../development/Per Instance Color.html | 8 +- .../gallery/development/Pick From Ray.html | 8 +- .../gallery/development/Picking.html | 8 +- .../gallery/development/PointPrimitives.html | 8 +- .../gallery/development/Polygon Outline.html | 8 +- .../Polygon Texture Coordinates.html | 8 +- .../gallery/development/Polygon.html | 8 +- .../gallery/development/Polyline Color.html | 8 +- .../development/Polyline Material.html | 8 +- .../development/Polyline Volume Outline.html | 8 +- .../gallery/development/Polyline Volume.html | 8 +- .../gallery/development/Polyline.html | 8 +- .../development/Polylines On Terrain.html | 26 +- .../gallery/development/Polylines.html | 8 +- .../development/Rectangle Outline.html | 8 +- .../gallery/development/Rectangle.html | 8 +- .../gallery/development/Shadows.html | 8 +- .../gallery/development/Simple Polyline.html | 8 +- .../gallery/development/Sphere Outline.html | 8 +- .../gallery/development/Sphere.html | 8 +- .../development/Terrain Entity Batching.html | 286 ++++---- .../development/Terrain Performance.html | 20 +- .../gallery/development/Terrain Tweaks.html | 8 +- .../gallery/development/Volumes.html | 8 +- .../gallery/development/Voxels.html | 8 +- .../gallery/development/Wall Outline.html | 8 +- Apps/Sandcastle/gallery/development/Wall.html | 8 +- Apps/Sandcastle/load-cesium-es6.js | 6 +- 244 files changed, 4713 insertions(+), 4067 deletions(-) diff --git a/Apps/Sandcastle/Sandcastle-helpers.js b/Apps/Sandcastle/Sandcastle-helpers.js index 0323fbaf286..18196646744 100644 --- a/Apps/Sandcastle/Sandcastle-helpers.js +++ b/Apps/Sandcastle/Sandcastle-helpers.js @@ -4,7 +4,7 @@ window.embedInSandcastleTemplate = function (code, addExtraLine) { return ( `${ - "window.startup = function (Cesium) {\n" + + "window.startup = async function (Cesium) {\n" + " 'use strict';\n" + "//Sandcastle_Begin\n" }${addExtraLine ? "\n" : ""}${code}//Sandcastle_End\n` + @@ -12,7 +12,11 @@ `};\n` + `if (typeof Cesium !== 'undefined') {\n` + ` window.startupCalled = true;\n` + - ` window.startup(Cesium);\n` + + ` try {\n` + + ` window.startup(Cesium);\n` + + ` } catch (error) {\n` + + ` console.error(error);\n` + + ` }\n` + `}\n` ); }; diff --git a/Apps/Sandcastle/gallery/3D Models Coloring.html b/Apps/Sandcastle/gallery/3D Models Coloring.html index 8cd0e510ee4..f2a5fc94d79 100644 --- a/Apps/Sandcastle/gallery/3D Models Coloring.html +++ b/Apps/Sandcastle/gallery/3D Models Coloring.html @@ -133,7 +133,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -326,7 +326,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Models.html b/Apps/Sandcastle/gallery/3D Models.html index 67e632f6dd6..579834c1e19 100644 --- a/Apps/Sandcastle/gallery/3D Models.html +++ b/Apps/Sandcastle/gallery/3D Models.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -173,7 +173,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html index 6b70acb401c..74ab58f2483 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html +++ b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html @@ -53,7 +53,7 @@ <input type="text" size="5" data-bind="value: height" /> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -125,7 +125,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles BIM.html b/Apps/Sandcastle/gallery/3D Tiles BIM.html index 1060beb35bf..f0355936169 100644 --- a/Apps/Sandcastle/gallery/3D Tiles BIM.html +++ b/Apps/Sandcastle/gallery/3D Tiles BIM.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -221,7 +221,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html index c5ecda6317b..e5fd0b06118 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -216,7 +216,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index 192ea241f8f..574423894d3 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -62,7 +62,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Add a clipping plane, a plane geometry to show the representation of the @@ -347,7 +347,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Compare.html b/Apps/Sandcastle/gallery/3D Tiles Compare.html index ce4070b6ec0..eaabf87c978 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Compare.html +++ b/Apps/Sandcastle/gallery/3D Tiles Compare.html @@ -49,7 +49,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -110,7 +110,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index 259ee31640c..aa1c5cd304a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -30,286 +30,288 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // A simple demo of 3D Tiles feature picking with hover and select behavior - // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // A simple demo of 3D Tiles feature picking with hover and select behavior + // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - viewer.scene.primitives.add(tileset); + // Load the NYC buildings tileset + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + viewer.scene.primitives.add(tileset); - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; - // Information about the currently selected feature - const selected = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently selected feature + const selected = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); - // Get default left click handler for when a feature is not picked on left click - const clickHandler = viewer.screenSpaceEventHandler.getInputAction( - Cesium.ScreenSpaceEventType.LEFT_CLICK - ); + // Get default left click handler for when a feature is not picked on left click + const clickHandler = viewer.screenSpaceEventHandler.getInputAction( + Cesium.ScreenSpaceEventType.LEFT_CLICK + ); - // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. - // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. - if ( - Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) - ) { - // Silhouettes are supported - const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteBlue.uniforms.color = Cesium.Color.BLUE; - silhouetteBlue.uniforms.length = 0.01; - silhouetteBlue.selected = []; + // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. + // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. + if ( + Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) + ) { + // Silhouettes are supported + const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteBlue.uniforms.color = Cesium.Color.BLUE; + silhouetteBlue.uniforms.length = 0.01; + silhouetteBlue.selected = []; - const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteGreen.uniforms.color = Cesium.Color.LIME; - silhouetteGreen.uniforms.length = 0.01; - silhouetteGreen.selected = []; + const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteGreen.uniforms.color = Cesium.Color.LIME; + silhouetteGreen.uniforms.length = 0.01; + silhouetteGreen.selected = []; - viewer.scene.postProcessStages.add( - Cesium.PostProcessStageLibrary.createSilhouetteStage([ - silhouetteBlue, - silhouetteGreen, - ]) - ); + viewer.scene.postProcessStages.add( + Cesium.PostProcessStageLibrary.createSilhouetteStage([ + silhouetteBlue, + silhouetteGreen, + ]) + ); - // Silhouette a feature blue on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - silhouetteBlue.selected = []; + // Silhouette a feature blue on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + silhouetteBlue.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const name = pickedFeature.getProperty("BIN"); - nameOverlay.textContent = name; + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const name = pickedFeature.getProperty("BIN"); + nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - silhouetteBlue.selected = [pickedFeature]; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + silhouetteBlue.selected = [pickedFeature]; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Silhouette a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - silhouetteGreen.selected = []; + // Silhouette a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + silhouetteGreen.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } - // Select the feature if it's not already selected - if (silhouetteGreen.selected[0] === pickedFeature) { - return; - } + // Select the feature if it's not already selected + if (silhouetteGreen.selected[0] === pickedFeature) { + return; + } - // Save the selected feature's original color - const highlightedFeature = silhouetteBlue.selected[0]; - if (pickedFeature === highlightedFeature) { - silhouetteBlue.selected = []; - } + // Save the selected feature's original color + const highlightedFeature = silhouetteBlue.selected[0]; + if (pickedFeature === highlightedFeature) { + silhouetteBlue.selected = []; + } - // Highlight newly selected feature - silhouetteGreen.selected = [pickedFeature]; + // Highlight newly selected feature + silhouetteGreen.selected = [pickedFeature]; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } else { - // Silhouettes are not supported. Instead, change the feature color. + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } else { + // Silhouettes are not supported. Instead, change the feature color. - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - let name = pickedFeature.getProperty("name"); - if (!Cesium.defined(name)) { - name = pickedFeature.getProperty("id"); - } - nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + let name = pickedFeature.getProperty("name"); + if (!Cesium.defined(name)) { + name = pickedFeature.getProperty("id"); + } + nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Color a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - if (Cesium.defined(selected.feature)) { - selected.feature.color = selected.originalColor; - selected.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } - // Select the feature if it's not already selected - if (selected.feature === pickedFeature) { - return; - } - selected.feature = pickedFeature; - // Save the selected feature's original color - if (pickedFeature === highlighted.feature) { - Cesium.Color.clone( - highlighted.originalColor, - selected.originalColor - ); - highlighted.feature = undefined; - } else { - Cesium.Color.clone(pickedFeature.color, selected.originalColor); - } - // Highlight newly selected feature - pickedFeature.color = Cesium.Color.LIME; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `<tr><th>Longitude</th><td>${pickedFeature.getProperty( - "longitude" - )}</td></tr>` + - `<tr><th>Latitude</th><td>${pickedFeature.getProperty( - "latitude" - )}</td></tr>` + - `<tr><th>Height</th><td>${pickedFeature.getProperty( - "height" - )}</td></tr>` + - `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( - "TerrainHeight" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } - })(); //Sandcastle_End + // Color a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + if (Cesium.defined(selected.feature)) { + selected.feature.color = selected.originalColor; + selected.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } + // Select the feature if it's not already selected + if (selected.feature === pickedFeature) { + return; + } + selected.feature = pickedFeature; + // Save the selected feature's original color + if (pickedFeature === highlighted.feature) { + Cesium.Color.clone( + highlighted.originalColor, + selected.originalColor + ); + highlighted.feature = undefined; + } else { + Cesium.Color.clone(pickedFeature.color, selected.originalColor); + } + // Highlight newly selected feature + pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `<tr><th>Longitude</th><td>${pickedFeature.getProperty( + "longitude" + )}</td></tr>` + + `<tr><th>Latitude</th><td>${pickedFeature.getProperty( + "latitude" + )}</td></tr>` + + `<tr><th>Height</th><td>${pickedFeature.getProperty( + "height" + )}</td></tr>` + + `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( + "TerrainHeight" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index 53f338f2103..9ce7e057456 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -50,174 +50,171 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // How to use the 3D Tiles Styling language to style individual features, like buildings. - // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const handler = new Cesium.ScreenSpaceEventHandler( - viewer.scene.canvas - ); - - // Add Cesium OSM buildings to the scene as our example 3D Tileset. - const osmBuildingsTileset = Cesium.createOsmBuildings(); - viewer.scene.primitives.add(osmBuildingsTileset); - - // Set the initial camera to look at Seattle - viewer.scene.camera.setView({ - destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), - orientation: { - heading: Cesium.Math.toRadians(10), - pitch: Cesium.Math.toRadians(-10), + // How to use the 3D Tiles Styling language to style individual features, like buildings. + // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); + + // Add Cesium OSM buildings to the scene as our example 3D Tileset. + const osmBuildingsTileset = Cesium.createOsmBuildings(); + viewer.scene.primitives.add(osmBuildingsTileset); + + // Set the initial camera to look at Seattle + viewer.scene.camera.setView({ + destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), + orientation: { + heading: Cesium.Math.toRadians(10), + pitch: Cesium.Math.toRadians(-10), + }, + }); + + // Styling functions + + // Color by material checks for null values since not all + // buildings have the material property. + function colorByMaterial() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + material: "${feature['building:material']}", + }, + color: { + conditions: [ + ["${material} === null", "color('white')"], + ["${material} === 'glass'", "color('skyblue', 0.5)"], + ["${material} === 'concrete'", "color('grey')"], + ["${material} === 'brick'", "color('indianred')"], + ["${material} === 'stone'", "color('lightslategrey')"], + ["${material} === 'metal'", "color('lightgrey')"], + ["${material} === 'steel'", "color('lightsteelblue')"], + ["true", "color('white')"], // This is the else case + ], }, }); - - // Styling functions - - // Color by material checks for null values since not all - // buildings have the material property. - function colorByMaterial() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - material: "${feature['building:material']}", - }, - color: { - conditions: [ - ["${material} === null", "color('white')"], - ["${material} === 'glass'", "color('skyblue', 0.5)"], - ["${material} === 'concrete'", "color('grey')"], - ["${material} === 'brick'", "color('indianred')"], - ["${material} === 'stone'", "color('lightslategrey')"], - ["${material} === 'metal'", "color('lightgrey')"], - ["${material} === 'steel'", "color('lightsteelblue')"], - ["true", "color('white')"], // This is the else case - ], - }, - }); - } - - function highlightAllResidentialBuildings() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - [ - "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", - "color('cyan', 0.9)", - ], - [true, "color('white')"], + } + + function highlightAllResidentialBuildings() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + [ + "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", + "color('cyan', 0.9)", ], - }, - }); + [true, "color('white')"], + ], + }, + }); + } + + function showByBuildingType(buildingType) { + switch (buildingType) { + case "office": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'office'", + }); + break; + case "apartments": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'apartments'", + }); + break; + default: + break; } + } - function showByBuildingType(buildingType) { - switch (buildingType) { - case "office": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'office'", - }); - break; - case "apartments": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'apartments'", - }); - break; - default: - break; - } - } + // Color the buildings based on their distance from a selected central location + function colorByDistanceToCoordinate(pickedLatitude, pickedLongitude) { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, + }, + color: { + conditions: [ + ["${distance} > 0.014", "color('blue')"], + ["${distance} > 0.010", "color('green')"], + ["${distance} > 0.006", "color('yellow')"], + ["${distance} > 0.0001", "color('red')"], + ["true", "color('white')"], + ], + }, + }); + } - // Color the buildings based on their distance from a selected central location - function colorByDistanceToCoordinate( - pickedLatitude, - pickedLongitude - ) { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, - }, - color: { - conditions: [ - ["${distance} > 0.014", "color('blue')"], - ["${distance} > 0.010", "color('green')"], - ["${distance} > 0.006", "color('yellow')"], - ["${distance} > 0.0001", "color('red')"], - ["true", "color('white')"], - ], - }, - }); - } + // When dropdown option is not "Color By Distance To Selected Location", + // remove the left click input event for selecting a central location + function removeCoordinatePickingOnLeftClick() { + document.querySelector(".infoPanel").style.visibility = "hidden"; + handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); + } - // When dropdown option is not "Color By Distance To Selected Location", - // remove the left click input event for selecting a central location - function removeCoordinatePickingOnLeftClick() { - document.querySelector(".infoPanel").style.visibility = "hidden"; - handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); - } + // Add event listeners to dropdown menu options + document.querySelector(".infoPanel").style.visibility = "hidden"; + const menu = document.getElementById("dropdown"); - // Add event listeners to dropdown menu options - document.querySelector(".infoPanel").style.visibility = "hidden"; - const menu = document.getElementById("dropdown"); - - menu.options[0].onselect = function () { - removeCoordinatePickingOnLeftClick(); - colorByMaterial(); - }; - - menu.options[1].onselect = function () { - // Default to Space Needle as the central location - colorByDistanceToCoordinate(47.62051, -122.34931); - document.querySelector(".infoPanel").style.visibility = "visible"; - // Add left click input to select a building to and extract its coordinates - handler.setInputAction(function (movement) { - viewer.selectedEntity = undefined; - const pickedBuilding = viewer.scene.pick(movement.position); - if (pickedBuilding) { - const pickedLatitude = pickedBuilding.getProperty( - "cesium#latitude" - ); - const pickedLongitude = pickedBuilding.getProperty( - "cesium#longitude" - ); - colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - }; - - menu.options[2].onselect = function () { - removeCoordinatePickingOnLeftClick(); - highlightAllResidentialBuildings(); - }; - - menu.options[3].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("office"); - }; - - menu.options[4].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("apartments"); - }; - - menu.onchange = function () { - Sandcastle.reset(); - const item = menu.options[menu.selectedIndex]; - if (item && typeof item.onselect === "function") { - item.onselect(); + menu.options[0].onselect = function () { + removeCoordinatePickingOnLeftClick(); + colorByMaterial(); + }; + + menu.options[1].onselect = function () { + // Default to Space Needle as the central location + colorByDistanceToCoordinate(47.62051, -122.34931); + document.querySelector(".infoPanel").style.visibility = "visible"; + // Add left click input to select a building to and extract its coordinates + handler.setInputAction(function (movement) { + viewer.selectedEntity = undefined; + const pickedBuilding = viewer.scene.pick(movement.position); + if (pickedBuilding) { + const pickedLatitude = pickedBuilding.getProperty( + "cesium#latitude" + ); + const pickedLongitude = pickedBuilding.getProperty( + "cesium#longitude" + ); + colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); } - }; + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + }; + + menu.options[2].onselect = function () { + removeCoordinatePickingOnLeftClick(); + highlightAllResidentialBuildings(); + }; + + menu.options[3].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("office"); + }; + + menu.options[4].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("apartments"); + }; + + menu.onchange = function () { + Sandcastle.reset(); + const item = menu.options[menu.selectedIndex]; + if (item && typeof item.onselect === "function") { + item.onselect(); + } + }; - colorByMaterial(); - })(); //Sandcastle_End + colorByMaterial(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Formats.html b/Apps/Sandcastle/gallery/3D Tiles Formats.html index 04c5b08da1f..8ff139e995d 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Formats.html +++ b/Apps/Sandcastle/gallery/3D Tiles Formats.html @@ -38,7 +38,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -222,7 +222,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index 7063dc45545..d07f605b952 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -33,42 +33,44 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - enableDebugWireframe: true, - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + enableDebugWireframe: true, + }); + viewer.scene.primitives.add(tileset); - await tileset.readyPromise; + await tileset.readyPromise; - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - tileset.boundingSphere.radius / 4.0 - ) - ); - })(); //Sandcastle_End + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + tileset.boundingSphere.radius / 4.0 + ) + ); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index 2ebba29bffa..c5fdd242ec0 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -71,213 +71,204 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - if (!scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } + const scene = viewer.scene; + if (!scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } - scene.globe.depthTestAgainstTerrain = true; + scene.globe.depthTestAgainstTerrain = true; - const viewModel = { - rightClickAction: "annotate", - middleClickAction: "hide", - }; + const viewModel = { + rightClickAction: "annotate", + middleClickAction: "hide", + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - const annotations = scene.primitives.add( - new Cesium.LabelCollection() - ); + const annotations = scene.primitives.add(new Cesium.LabelCollection()); - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - meta: { - description: "'Building ${BIN} has height ${Height}.'", - }, - }); + // Load the NYC buildings tileset. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + scene.primitives.add(tileset); + tileset.style = new Cesium.Cesium3DTileStyle({ + meta: { + description: "'Building ${BIN} has height ${Height}.'", + }, + }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.rightClickAction; - if (action === "annotate") { - annotate(movement, feature); - } else if (action === "properties") { - printProperties(movement, feature); - } else if (action === "zoom") { - zoom(movement, feature); - } - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + const action = viewModel.rightClickAction; + if (action === "annotate") { + annotate(movement, feature); + } else if (action === "properties") { + printProperties(movement, feature); + } else if (action === "zoom") { + zoom(movement, feature); + } + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.middleClickAction; - if (action === "hide") { - feature.show = false; - } - }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + const action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); - function annotate(movement, feature) { - if (scene.pickPositionSupported) { - const cartesian = scene.pickPosition(movement.position); - if (Cesium.defined(cartesian)) { - const cartographic = Cesium.Cartographic.fromCartesian( - cartesian - ); - const height = `${cartographic.height.toFixed(2)} m`; + function annotate(movement, feature) { + if (scene.pickPositionSupported) { + const cartesian = scene.pickPosition(movement.position); + if (Cesium.defined(cartesian)) { + const cartographic = Cesium.Cartographic.fromCartesian(cartesian); + const height = `${cartographic.height.toFixed(2)} m`; - annotations.add({ - position: cartesian, - text: height, - showBackground: true, - font: "14px monospace", - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - disableDepthTestDistance: Number.POSITIVE_INFINITY, - }); - } + annotations.add({ + position: cartesian, + text: height, + showBackground: true, + font: "14px monospace", + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + disableDepthTestDistance: Number.POSITIVE_INFINITY, + }); } } + } - function printProperties(movement, feature) { - console.log("Properties:"); - const propertyIds = feature.getPropertyIds(); - const length = propertyIds.length; - for (let i = 0; i < length; ++i) { - const propertyId = propertyIds[i]; - console.log( - ` ${propertyId}: ${feature.getProperty(propertyId)}` - ); - } - - // Evaluate feature description - console.log( - `Description : ${tileset.style.meta.description.evaluate( - feature - )}` - ); + function printProperties(movement, feature) { + console.log("Properties:"); + const propertyIds = feature.getPropertyIds(); + const length = propertyIds.length; + for (let i = 0; i < length; ++i) { + const propertyId = propertyIds[i]; + console.log(` ${propertyId}: ${feature.getProperty(propertyId)}`); } - function zoom(movement, feature) { - const longitude = Cesium.Math.toRadians( - feature.getProperty("Longitude") - ); - const latitude = Cesium.Math.toRadians( - feature.getProperty("Latitude") - ); - const height = feature.getProperty("Height"); + // Evaluate feature description + console.log( + `Description : ${tileset.style.meta.description.evaluate(feature)}` + ); + } - const positionCartographic = new Cesium.Cartographic( - longitude, - latitude, - height * 0.5 - ); - const position = scene.globe.ellipsoid.cartographicToCartesian( - positionCartographic - ); + function zoom(movement, feature) { + const longitude = Cesium.Math.toRadians( + feature.getProperty("Longitude") + ); + const latitude = Cesium.Math.toRadians( + feature.getProperty("Latitude") + ); + const height = feature.getProperty("Height"); - const camera = scene.camera; - const heading = camera.heading; - const pitch = camera.pitch; + const positionCartographic = new Cesium.Cartographic( + longitude, + latitude, + height * 0.5 + ); + const position = scene.globe.ellipsoid.cartographicToCartesian( + positionCartographic + ); - const offset = offsetFromHeadingPitchRange( - heading, - pitch, - height * 2.0 - ); + const camera = scene.camera; + const heading = camera.heading; + const pitch = camera.pitch; - const transform = Cesium.Transforms.eastNorthUpToFixedFrame( - position - ); - Cesium.Matrix4.multiplyByPoint(transform, offset, position); + const offset = offsetFromHeadingPitchRange( + heading, + pitch, + height * 2.0 + ); - camera.flyTo({ - destination: position, - orientation: { - heading: heading, - pitch: pitch, - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - }); - } + const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + Cesium.Matrix4.multiplyByPoint(transform, offset, position); - function offsetFromHeadingPitchRange(heading, pitch, range) { - pitch = Cesium.Math.clamp( - pitch, - -Cesium.Math.PI_OVER_TWO, - Cesium.Math.PI_OVER_TWO - ); - heading = - Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; + camera.flyTo({ + destination: position, + orientation: { + heading: heading, + pitch: pitch, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + }); + } - const pitchQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Y, - -pitch - ); - const headingQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Z, - -heading - ); - const rotQuat = Cesium.Quaternion.multiply( - headingQuat, - pitchQuat, - headingQuat - ); - const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); + function offsetFromHeadingPitchRange(heading, pitch, range) { + pitch = Cesium.Math.clamp( + pitch, + -Cesium.Math.PI_OVER_TWO, + Cesium.Math.PI_OVER_TWO + ); + heading = Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; - const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); - Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); - Cesium.Cartesian3.negate(offset, offset); - Cesium.Cartesian3.multiplyByScalar(offset, range, offset); - return offset; - } - })(); //Sandcastle_End + const pitchQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Y, + -pitch + ); + const headingQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Z, + -heading + ); + const rotQuat = Cesium.Quaternion.multiply( + headingQuat, + pitchQuat, + headingQuat + ); + const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); + + const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); + Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); + Cesium.Cartesian3.negate(offset, offset); + Cesium.Cartesian3.multiplyByScalar(offset, range, offset); + return offset; + } //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interior.html b/Apps/Sandcastle/gallery/3D Tiles Interior.html index 55689cb4697..2a95807f28b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interior.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interior.html @@ -33,7 +33,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // San Miguel model created by Guillermo M. Leal Llaguno. Cleaned up and hosted by Morgan McGuire: http://graphics.cs.williams.edu/data/meshes.xml @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index 97a59a9aadc..0308a4d5949 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -453,7 +453,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 6ad48f0367a..6ed0f78f7c8 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -32,23 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // San Francisco Ferry Building photogrammetry model provided by Aerometrex const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, orderIndependentTranslucency: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2021-11-09T20:27:37.016064475348684937Z" ); @@ -363,7 +356,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html index 26091096f6a..2b995547174 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -232,7 +232,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 06ac7065e20..233b9d36d80 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -33,56 +33,58 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // An example of using a b3dm tileset to classify another b3dm tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // An example of using a b3dm tileset to classify another b3dm tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - // A normal b3dm tileset containing photogrammetry - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + // A normal b3dm tileset containing photogrammetry + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); - const classificationTilesetUrl = - "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; - // A b3dm tileset used to classify the photogrammetry tileset - const classificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(classificationTileset); + const classificationTilesetUrl = + "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; + // A b3dm tileset used to classify the photogrammetry tileset + const classificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(classificationTileset); - // The same b3dm tileset used for classification, but rendered normally for comparison. - const nonClassificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - show: false, - }); - nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(nonClassificationTileset); + // The same b3dm tileset used for classification, but rendered normally for comparison. + const nonClassificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + show: false, + }); + nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(nonClassificationTileset); - Sandcastle.addToggleButton("Show classification", true, function ( - checked - ) { - classificationTileset.show = checked; - nonClassificationTileset.show = !checked; - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("Show classification", true, function ( + checked + ) { + classificationTileset.show = checked; + nonClassificationTileset.show = !checked; + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index a53e6ff3122..6e7becd497a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -33,26 +33,28 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - })(); //Sandcastle_End + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index 40c6d2a0784..0d26e51e9c4 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -33,92 +33,94 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // An example showing a point cloud tileset classified by a Geometry tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // An example showing a point cloud tileset classified by a Geometry tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - // Geometry Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry - const classificationTileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - viewer.scene.primitives.add(classificationTileset); + // Geometry Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry + const classificationTileset = new Cesium.Cesium3DTileset({ + url: + "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + viewer.scene.primitives.add(classificationTileset); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${id} === 'roof1'", "color('#004FFF', 0.5)"], - ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], - ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], - ["${id} === 'roof2'", "color('#004FFF', 0.5)"], - ["${id} === 'tower3'", "color('#FF8833', 0.5)"], - ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], - ["true", "color('#FFFF00', 0.5)"], - ], - }, - }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${id} === 'roof1'", "color('#004FFF', 0.5)"], + ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], + ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], + ["${id} === 'roof2'", "color('#004FFF', 0.5)"], + ["${id} === 'tower3'", "color('#FF8833', 0.5)"], + ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], + ["true", "color('#FFFF00', 0.5)"], + ], + }, + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index 252a9d20f60..cbbb50ece83 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -157,231 +157,230 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - let viewModelTileset; + const scene = viewer.scene; + let viewModelTileset; - if (!Cesium.PointCloudShading.isSupported(scene)) { - window.alert("This browser does not support point cloud shading"); - } + if (!Cesium.PointCloudShading.isSupported(scene)) { + window.alert("This browser does not support point cloud shading"); + } - function reset() { - viewer.scene.primitives.remove(viewModelTileset); - viewModelTileset = undefined; - } + function reset() { + viewer.scene.primitives.remove(viewModelTileset); + viewModelTileset = undefined; + } - // The viewModel tracks the state of our mini application. - const pointClouds = ["St. Helens", "Church"]; - const viewModel = { - exampleTypes: pointClouds, - currentExampleType: pointClouds[0], - maximumScreenSpaceError: 16.0, - geometricErrorScale: 1.0, - maximumAttenuation: 0, // Equivalent to undefined - baseResolution: 0, // Equivalent to undefined - eyeDomeLightingStrength: 1.0, - eyeDomeLightingRadius: 1.0, - }; + // The viewModel tracks the state of our mini application. + const pointClouds = ["St. Helens", "Church"]; + const viewModel = { + exampleTypes: pointClouds, + currentExampleType: pointClouds[0], + maximumScreenSpaceError: 16.0, + geometricErrorScale: 1.0, + maximumAttenuation: 0, // Equivalent to undefined + baseResolution: 0, // Equivalent to undefined + eyeDomeLightingStrength: 1.0, + eyeDomeLightingRadius: 1.0, + }; - function tilesetToViewModel(tileset) { - viewModelTileset = tileset; - - const pointCloudShading = tileset.pointCloudShading; - viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; - viewModel.geometricErrorScale = - pointCloudShading.geometricErrorScale; - viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation - ? pointCloudShading.maximumAttenuation - : 0; - viewModel.baseResolution = pointCloudShading.baseResolution - ? pointCloudShading.baseResolution - : 0; - viewModel.eyeDomeLightingStrength = - pointCloudShading.eyeDomeLightingStrength; - viewModel.eyeDomeLightingRadius = - pointCloudShading.eyeDomeLightingRadius; - } + function tilesetToViewModel(tileset) { + viewModelTileset = tileset; - function loadStHelens() { - // Set the initial camera view to look at Mt. St. Helens - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + const pointCloudShading = tileset.pointCloudShading; + viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; + viewModel.geometricErrorScale = pointCloudShading.geometricErrorScale; + viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation + ? pointCloudShading.maximumAttenuation + : 0; + viewModel.baseResolution = pointCloudShading.baseResolution + ? pointCloudShading.baseResolution + : 0; + viewModel.eyeDomeLightingStrength = + pointCloudShading.eyeDomeLightingStrength; + viewModel.eyeDomeLightingRadius = + pointCloudShading.eyeDomeLightingRadius; + } - // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ - // This tileset uses replacement refinement and has geometric error approximately equal to - // the average interpoint distance in each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - viewer.scene.primitives.add(tileset); - - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead - tileset.pointCloudShading.baseResolution = undefined; - tileset.pointCloudShading.geometricErrorScale = 1.0; - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + function loadStHelens() { + // Set the initial camera view to look at Mt. St. Helens + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - tilesetToViewModel(tileset); - } + // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ + // This tileset uses replacement refinement and has geometric error approximately equal to + // the average interpoint distance in each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + viewer.scene.primitives.add(tileset); - function loadChurch() { - // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead + tileset.pointCloudShading.baseResolution = undefined; + tileset.pointCloudShading.geometricErrorScale = 1.0; + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. - tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. - tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tilesetToViewModel(tileset); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + function loadChurch() { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - tilesetToViewModel(tileset); - } + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. + tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. + tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - function checkZero(newValue) { - const newValueFloat = parseFloat(newValue); - return newValueFloat === 0.0 ? undefined : newValueFloat; - } + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - loadStHelens(); + tilesetToViewModel(tileset); + } - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + function checkZero(newValue) { + const newValueFloat = parseFloat(newValue); + return newValueFloat === 0.0 ? undefined : newValueFloat; + } - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + loadStHelens(); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === pointClouds[0]) { - loadStHelens(); - } else if (newValue === pointClouds[1]) { - loadChurch(); - } - }); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - Cesium.knockout - .getObservable(viewModel, "maximumScreenSpaceError") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); - } - }); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "geometricErrorScale") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === pointClouds[0]) { + loadStHelens(); + } else if (newValue === pointClouds[1]) { + loadChurch(); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumAttenuation") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumScreenSpaceError") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); + } + }); - Cesium.knockout - .getObservable(viewModel, "baseResolution") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.baseResolution = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "geometricErrorScale") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingStrength") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumAttenuation") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingRadius") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "baseResolution") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.baseResolution = checkZero( + newValue + ); + } + }); - Sandcastle.addToggleButton("Enable Attenuation", true, function ( - checked - ) { + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingStrength") + .subscribe(function (newValue) { if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.attenuation = checked; + viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( + newValue + ); } }); - Sandcastle.addToggleButton( - "Enable Eye Dome Lighting", - true, - function (checked) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLighting = checked; - } + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingRadius") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( + newValue + ); } - ); - })(); //Sandcastle_End + }); + + Sandcastle.addToggleButton("Enable Attenuation", true, function ( + checked + ) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.attenuation = checked; + } + }); + + Sandcastle.addToggleButton("Enable Eye Dome Lighting", true, function ( + checked + ) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLighting = checked; + } + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html index 217312d33f9..d944b98091c 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -238,7 +238,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index babe9cceede..8779b985f8e 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -33,38 +33,40 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); - })(); //Sandcastle_End + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index f298cfd42fe..f527e2b3a72 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -33,65 +33,67 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const geocoder = viewer.geocoder.viewModel; - geocoder.searchText = "Vienna"; - geocoder.flightDuration = 0.0; - geocoder.search(); + const geocoder = viewer.geocoder.viewModel; + geocoder.searchText = "Vienna"; + geocoder.flightDuration = 0.0; + geocoder.search(); - // Vector 3D Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5737), - }); - viewer.scene.primitives.add(tileset); + // Vector 3D Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5737), + }); + viewer.scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 255, 255, 0.5)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 255, 255, 0.5)", + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW; - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW; + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Ambient Occlusion.html b/Apps/Sandcastle/gallery/Ambient Occlusion.html index 650b1cfb618..5575c9ebe55 100644 --- a/Apps/Sandcastle/gallery/Ambient Occlusion.html +++ b/Apps/Sandcastle/gallery/Ambient Occlusion.html @@ -110,7 +110,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -207,7 +207,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS MapServer.html b/Apps/Sandcastle/gallery/ArcGIS MapServer.html index 0c286155613..55e7acbdb07 100644 --- a/Apps/Sandcastle/gallery/ArcGIS MapServer.html +++ b/Apps/Sandcastle/gallery/ArcGIS MapServer.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -43,7 +43,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index dce86820a80..e16d10af0b5 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -29,25 +29,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - try { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index 32414bf7eb1..b37f9b3367b 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -32,22 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. - // https://www.pgc.umn.edu/data/arcticdem/ - viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3956) - ); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. + // https://www.pgc.umn.edu/data/arcticdem/ + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3956) + ), + }); // Add Alaskan locations Sandcastle.addDefaultToolbarMenu( @@ -128,7 +122,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Atmosphere.html b/Apps/Sandcastle/gallery/Atmosphere.html index 69382766603..faf8adb19dd 100644 --- a/Apps/Sandcastle/gallery/Atmosphere.html +++ b/Apps/Sandcastle/gallery/Atmosphere.html @@ -665,7 +665,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -1030,7 +1030,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Billboards.html b/Apps/Sandcastle/gallery/Billboards.html index b166b6398d8..e1dd3499eb3 100644 --- a/Apps/Sandcastle/gallery/Billboards.html +++ b/Apps/Sandcastle/gallery/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -366,7 +366,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Bloom.html b/Apps/Sandcastle/gallery/Bloom.html index 21d7f82fc7e..bf83ff22e21 100644 --- a/Apps/Sandcastle/gallery/Bloom.html +++ b/Apps/Sandcastle/gallery/Bloom.html @@ -105,7 +105,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -183,7 +183,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Blue Marble.html b/Apps/Sandcastle/gallery/Blue Marble.html index ba4a89bef39..c39d97c695d 100644 --- a/Apps/Sandcastle/gallery/Blue Marble.html +++ b/Apps/Sandcastle/gallery/Blue Marble.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Blue Marble Next Generation July, 2004 imagery from NASA @@ -44,7 +44,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Box.html b/Apps/Sandcastle/gallery/Box.html index 0860eb90f7c..b8ea549e062 100644 --- a/Apps/Sandcastle/gallery/Box.html +++ b/Apps/Sandcastle/gallery/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -71,7 +71,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML 3D Tiles.html b/Apps/Sandcastle/gallery/CZML 3D Tiles.html index 898cb91dfb5..5adc46102e2 100644 --- a/Apps/Sandcastle/gallery/CZML 3D Tiles.html +++ b/Apps/Sandcastle/gallery/CZML 3D Tiles.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -68,7 +68,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Billboard and Label.html b/Apps/Sandcastle/gallery/CZML Billboard and Label.html index 358e1002c8c..3e337e70566 100644 --- a/Apps/Sandcastle/gallery/CZML Billboard and Label.html +++ b/Apps/Sandcastle/gallery/CZML Billboard and Label.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -82,7 +82,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Box.html b/Apps/Sandcastle/gallery/CZML Box.html index fe4ce90b875..411335c7978 100644 --- a/Apps/Sandcastle/gallery/CZML Box.html +++ b/Apps/Sandcastle/gallery/CZML Box.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -109,7 +109,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html index db1ac667a79..b38bc389e5a 100644 --- a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -115,7 +115,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Colors.html b/Apps/Sandcastle/gallery/CZML Colors.html index 4be19a1fd54..3ab17adf809 100644 --- a/Apps/Sandcastle/gallery/CZML Colors.html +++ b/Apps/Sandcastle/gallery/CZML Colors.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -91,7 +91,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html index 2630386eda0..5e172193e1a 100644 --- a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html +++ b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -93,7 +93,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Corridor.html b/Apps/Sandcastle/gallery/CZML Corridor.html index d74d3b838e5..467563570a4 100644 --- a/Apps/Sandcastle/gallery/CZML Corridor.html +++ b/Apps/Sandcastle/gallery/CZML Corridor.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -145,7 +145,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Custom Properties.html b/Apps/Sandcastle/gallery/CZML Custom Properties.html index 7b6dbc16212..7217a1083e6 100644 --- a/Apps/Sandcastle/gallery/CZML Custom Properties.html +++ b/Apps/Sandcastle/gallery/CZML Custom Properties.html @@ -32,7 +32,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -176,7 +176,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html index d08df40e333..65ac6a0db75 100644 --- a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html +++ b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -113,7 +113,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Articulations.html b/Apps/Sandcastle/gallery/CZML Model Articulations.html index b5964db15fa..7f78d628a68 100644 --- a/Apps/Sandcastle/gallery/CZML Model Articulations.html +++ b/Apps/Sandcastle/gallery/CZML Model Articulations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -98,7 +98,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Data URL.html b/Apps/Sandcastle/gallery/CZML Model Data URL.html index 891c5528630..b0561778dcd 100644 --- a/Apps/Sandcastle/gallery/CZML Model Data URL.html +++ b/Apps/Sandcastle/gallery/CZML Model Data URL.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const gltf = { @@ -176,7 +176,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model.html b/Apps/Sandcastle/gallery/CZML Model.html index a9299d5aa2d..a16f3aa6fe1 100644 --- a/Apps/Sandcastle/gallery/CZML Model.html +++ b/Apps/Sandcastle/gallery/CZML Model.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -76,7 +76,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Path.html b/Apps/Sandcastle/gallery/CZML Path.html index 1732ea900b3..c5342b3cf26 100644 --- a/Apps/Sandcastle/gallery/CZML Path.html +++ b/Apps/Sandcastle/gallery/CZML Path.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -7243,24 +7243,26 @@ }, ]; - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - baseLayerPicker: false, - shouldAnimate: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + baseLayerPicker: false, + shouldAnimate: true, + }); - const dataSource = await viewer.dataSources.add( - Cesium.CzmlDataSource.load(czml) - ); + const dataSource = await viewer.dataSources.add( + Cesium.CzmlDataSource.load(czml) + ); - viewer.trackedEntity = dataSource.entities.getById("path"); - })(); //Sandcastle_End + viewer.trackedEntity = dataSource.entities.getById("path"); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html index 63470fd2f66..3ca62d6746d 100644 --- a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html +++ b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -87,7 +87,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point.html b/Apps/Sandcastle/gallery/CZML Point.html index 5bc606f8ffb..19f338f6188 100644 --- a/Apps/Sandcastle/gallery/CZML Point.html +++ b/Apps/Sandcastle/gallery/CZML Point.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -68,7 +68,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html index 9a37834493f..f964655c8fe 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -212,7 +212,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html index 902d2757502..76b13a2234b 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -227,7 +227,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon.html b/Apps/Sandcastle/gallery/CZML Polygon.html index f5ade1d453e..90b8d1f92b0 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon.html +++ b/Apps/Sandcastle/gallery/CZML Polygon.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -224,7 +224,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline Volume.html b/Apps/Sandcastle/gallery/CZML Polyline Volume.html index 56970ce3fdd..16689e8847c 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline Volume.html +++ b/Apps/Sandcastle/gallery/CZML Polyline Volume.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -153,7 +153,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline.html b/Apps/Sandcastle/gallery/CZML Polyline.html index 15e2ae74b29..c603956074f 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline.html +++ b/Apps/Sandcastle/gallery/CZML Polyline.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -145,7 +145,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Position Definitions.html b/Apps/Sandcastle/gallery/CZML Position Definitions.html index 43df14ff7cb..6520d1bd165 100644 --- a/Apps/Sandcastle/gallery/CZML Position Definitions.html +++ b/Apps/Sandcastle/gallery/CZML Position Definitions.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -107,7 +107,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Rectangle.html b/Apps/Sandcastle/gallery/CZML Rectangle.html index 1a98dda45eb..83cddbc5493 100644 --- a/Apps/Sandcastle/gallery/CZML Rectangle.html +++ b/Apps/Sandcastle/gallery/CZML Rectangle.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -130,7 +130,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Reference Properties.html b/Apps/Sandcastle/gallery/CZML Reference Properties.html index 24c7cf38921..172a0294e0a 100644 --- a/Apps/Sandcastle/gallery/CZML Reference Properties.html +++ b/Apps/Sandcastle/gallery/CZML Reference Properties.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -134,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html index e5f437e4680..639034a5093 100644 --- a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -114,7 +114,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Wall.html b/Apps/Sandcastle/gallery/CZML Wall.html index e35de4ada58..56809d83e00 100644 --- a/Apps/Sandcastle/gallery/CZML Wall.html +++ b/Apps/Sandcastle/gallery/CZML Wall.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -100,7 +100,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML ZIndex.html b/Apps/Sandcastle/gallery/CZML ZIndex.html index ead9d1c59fa..492f9ba8868 100644 --- a/Apps/Sandcastle/gallery/CZML ZIndex.html +++ b/Apps/Sandcastle/gallery/CZML ZIndex.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -150,7 +150,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML.html b/Apps/Sandcastle/gallery/CZML.html index d76fb8b77c5..75f35dc6a7b 100644 --- a/Apps/Sandcastle/gallery/CZML.html +++ b/Apps/Sandcastle/gallery/CZML.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -69,7 +69,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Callback Property.html b/Apps/Sandcastle/gallery/Callback Property.html index 5d63d5ad719..8747ff39473 100644 --- a/Apps/Sandcastle/gallery/Callback Property.html +++ b/Apps/Sandcastle/gallery/Callback Property.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // This example illustrates a Callback Property, a property whose @@ -122,7 +122,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera Tutorial.html b/Apps/Sandcastle/gallery/Camera Tutorial.html index ef38bd93a4d..2d2cce53a8d 100644 --- a/Apps/Sandcastle/gallery/Camera Tutorial.html +++ b/Apps/Sandcastle/gallery/Camera Tutorial.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -190,7 +190,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera.html b/Apps/Sandcastle/gallery/Camera.html index b4d3d8af64c..340b5f18bf6 100644 --- a/Apps/Sandcastle/gallery/Camera.html +++ b/Apps/Sandcastle/gallery/Camera.html @@ -42,7 +42,7 @@ <div id="cameraChanged">Camera Changed</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -489,7 +489,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cardboard.html b/Apps/Sandcastle/gallery/Cardboard.html index 7304c8a6aab..581d2d1cee2 100644 --- a/Apps/Sandcastle/gallery/Cardboard.html +++ b/Apps/Sandcastle/gallery/Cardboard.html @@ -32,163 +32,165 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - vrButton: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - // Click the VR button in the bottom right of the screen to switch to VR mode. - - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; - - // Follow the path of a plane. See the interpolation Sandcastle example. - Cesium.Math.setRandomNumberSeed(3); - - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); - - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; - viewer.clock.shouldAnimate = true; - - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - const startAngle = Cesium.Math.nextRandomNumber() * 360.0; - const endAngle = startAngle + 360.0; - - const increment = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; - for (let i = startAngle; i < endAngle; i += increment) { - const radians = Cesium.Math.toRadians(i); - const timeIncrement = i - startAngle; - const time = Cesium.JulianDate.addSeconds( - start, - timeIncrement, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1800 - ); - property.addSample(time, position); - } - return property; + const viewer = new Cesium.Viewer("cesiumContainer", { + vrButton: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + // Click the VR button in the bottom right of the screen to switch to VR mode. + + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; + + // Follow the path of a plane. See the interpolation Sandcastle example. + Cesium.Math.setRandomNumberSeed(3); + + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() + ); + + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + viewer.clock.shouldAnimate = true; + + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + const startAngle = Cesium.Math.nextRandomNumber() * 360.0; + const endAngle = startAngle + 360.0; + + const increment = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; + for (let i = startAngle; i < endAngle; i += increment) { + const radians = Cesium.Math.toRadians(i); + const timeIncrement = i - startAngle; + const time = Cesium.JulianDate.addSeconds( + start, + timeIncrement, + new Cesium.JulianDate() + ); + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1800 + ); + property.addSample(time, position); + } + return property; + } + + const longitude = -112.110693; + const latitude = 36.0994841; + const radius = 0.03; + + const modelURI = + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; + const entity = viewer.entities.add({ + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + position: computeCirclularFlight(longitude, latitude, radius), + model: { + uri: modelURI, + minimumPixelSize: 64, + }, + }); + + entity.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); + + // Set initial camera position and orientation to be when in the model's reference frame. + const camera = viewer.camera; + camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); + camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); + camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); + camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); + + viewer.scene.postUpdate.addEventListener(function (scene, time) { + const position = entity.position.getValue(time); + if (!Cesium.defined(position)) { + return; } - const longitude = -112.110693; - const latitude = 36.0994841; - const radius = 0.03; + let transform; + if (!Cesium.defined(entity.orientation)) { + transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + } else { + const orientation = entity.orientation.getValue(time); + if (!Cesium.defined(orientation)) { + return; + } + + transform = Cesium.Matrix4.fromRotationTranslation( + Cesium.Matrix3.fromQuaternion(orientation), + position + ); + } - const modelURI = - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; - const entity = viewer.entities.add({ + // Save camera state + const offset = Cesium.Cartesian3.clone(camera.position); + const direction = Cesium.Cartesian3.clone(camera.direction); + const up = Cesium.Cartesian3.clone(camera.up); + + // Set camera to be in model's reference frame. + camera.lookAtTransform(transform); + + // Reset the camera state to the saved state so it appears fixed in the model's frame. + Cesium.Cartesian3.clone(offset, camera.position); + Cesium.Cartesian3.clone(direction, camera.direction); + Cesium.Cartesian3.clone(up, camera.up); + Cesium.Cartesian3.cross(direction, up, camera.right); + }); + + // Add a few more balloons flying with the one the viewer is in. + const numBalloons = 12; + for (let i = 0; i < numBalloons; ++i) { + const balloonRadius = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; + const balloon = viewer.entities.add({ availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start: start, stop: stop, }), ]), - position: computeCirclularFlight(longitude, latitude, radius), + position: computeCirclularFlight( + longitude, + latitude, + balloonRadius + ), model: { uri: modelURI, minimumPixelSize: 64, }, }); - entity.position.setInterpolationOptions({ + balloon.position.setInterpolationOptions({ interpolationDegree: 2, interpolationAlgorithm: Cesium.HermitePolynomialApproximation, }); - - // Set initial camera position and orientation to be when in the model's reference frame. - const camera = viewer.camera; - camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); - camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); - camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); - camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); - - viewer.scene.postUpdate.addEventListener(function (scene, time) { - const position = entity.position.getValue(time); - if (!Cesium.defined(position)) { - return; - } - - let transform; - if (!Cesium.defined(entity.orientation)) { - transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - } else { - const orientation = entity.orientation.getValue(time); - if (!Cesium.defined(orientation)) { - return; - } - - transform = Cesium.Matrix4.fromRotationTranslation( - Cesium.Matrix3.fromQuaternion(orientation), - position - ); - } - - // Save camera state - const offset = Cesium.Cartesian3.clone(camera.position); - const direction = Cesium.Cartesian3.clone(camera.direction); - const up = Cesium.Cartesian3.clone(camera.up); - - // Set camera to be in model's reference frame. - camera.lookAtTransform(transform); - - // Reset the camera state to the saved state so it appears fixed in the model's frame. - Cesium.Cartesian3.clone(offset, camera.position); - Cesium.Cartesian3.clone(direction, camera.direction); - Cesium.Cartesian3.clone(up, camera.up); - Cesium.Cartesian3.cross(direction, up, camera.right); - }); - - // Add a few more balloons flying with the one the viewer is in. - const numBalloons = 12; - for (let i = 0; i < numBalloons; ++i) { - const balloonRadius = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; - const balloon = viewer.entities.add({ - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - position: computeCirclularFlight( - longitude, - latitude, - balloonRadius - ), - model: { - uri: modelURI, - minimumPixelSize: 64, - }, - }); - - balloon.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); - } - })(); //Sandcastle_End + } //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 7c32bfee9fa..043814d13fe 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -32,70 +32,72 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - // Tropics of Cancer and Capricorn - const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( - -180.0, - -23.43687, - 180.0, - 23.43687 - ); + // Tropics of Cancer and Capricorn + const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( + -180.0, + -23.43687, + 180.0, + 23.43687 + ); - globe.cartographicLimitRectangle = coffeeBeltRectangle; - globe.showSkirts = false; - globe.backFaceCulling = false; - globe.undergroundColor = undefined; - scene.skyAtmosphere.show = false; + globe.cartographicLimitRectangle = coffeeBeltRectangle; + globe.showSkirts = false; + globe.backFaceCulling = false; + globe.undergroundColor = undefined; + scene.skyAtmosphere.show = false; - // Add rectangles to show bounds - const rectangles = []; + // Add rectangles to show bounds + const rectangles = []; - for (let i = 0; i < 10; i++) { - rectangles.push( - viewer.entities.add({ - rectangle: { - coordinates: coffeeBeltRectangle, - material: Cesium.Color.WHITE.withAlpha(0.0), - height: i * 5000.0, - outline: true, - outlineWidth: 4.0, - outlineColor: Cesium.Color.WHITE, - }, - }) - ); - } + for (let i = 0; i < 10; i++) { + rectangles.push( + viewer.entities.add({ + rectangle: { + coordinates: coffeeBeltRectangle, + material: Cesium.Color.WHITE.withAlpha(0.0), + height: i * 5000.0, + outline: true, + outlineWidth: 4.0, + outlineColor: Cesium.Color.WHITE, + }, + }) + ); + } - Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { - if (checked) { - viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; - } else { - viewer.scene.globe.cartographicLimitRectangle = undefined; - } - }); + Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { + if (checked) { + viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; + } else { + viewer.scene.globe.cartographicLimitRectangle = undefined; + } + }); - Sandcastle.addToggleButton("Show Bounds", true, function (checked) { - const rectanglesLength = rectangles.length; - for (let i = 0; i < rectanglesLength; i++) { - const rectangleEntity = rectangles[i]; - rectangleEntity.show = checked; - } - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("Show Bounds", true, function (checked) { + const rectanglesLength = rectangles.length; + for (let i = 0; i < rectanglesLength; i++) { + const rectangleEntity = rectangles[i]; + rectangleEntity.show = checked; + } + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Inspector.html b/Apps/Sandcastle/gallery/Cesium Inspector.html index 6d1773608e2..b67cbaf296a 100644 --- a/Apps/Sandcastle/gallery/Cesium Inspector.html +++ b/Apps/Sandcastle/gallery/Cesium Inspector.html @@ -36,91 +36,85 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; - //Add Cesium Inspector - viewer.extend(Cesium.viewerCesiumInspectorMixin); + //Add Cesium Inspector + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //Add Primitives - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3( - 400000.0, - 300000.0, - 500000.0 - ), - }), - modelMatrix: Cesium.Matrix4.multiplyByTranslation( - Cesium.Transforms.eastNorthUpToFixedFrame( - Cesium.Cartesian3.fromDegrees(-105.0, 45.0) - ), - new Cesium.Cartesian3(0.0, 0.0, 250000), - new Cesium.Matrix4() - ), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.RED.withAlpha(0.5) - ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance({ - closed: true, + //Add Primitives + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), }), - }) - ); + modelMatrix: Cesium.Matrix4.multiplyByTranslation( + Cesium.Transforms.eastNorthUpToFixedFrame( + Cesium.Cartesian3.fromDegrees(-105.0, 45.0) + ), + new Cesium.Cartesian3(0.0, 0.0, 250000), + new Cesium.Matrix4() + ), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.RED.withAlpha(0.5) + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance({ + closed: true, + }), + }) + ); - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -93.0, - 37.0 - ), - height: 100000, - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.BLUE - ), - }, + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -93.0, + 37.0 + ), + height: 100000, + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, }), - appearance: new Cesium.PerInstanceColorAppearance(), - }) - ); + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.BLUE + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance(), + }) + ); - const billboards = scene.primitives.add( - new Cesium.BillboardCollection() - ); - billboards.add({ - position: Cesium.Cartesian3.fromDegrees( - -75.59777, - 40.03883, - 150000 - ), - image: "../images/Cesium_Logo_overlay.png", - }); - })(); //Sandcastle_End + const billboards = scene.primitives.add( + new Cesium.BillboardCollection() + ); + billboards.add({ + position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 150000), + image: "../images/Cesium_Logo_overlay.png", + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index ea639ecbb39..faa969bead0 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -35,29 +35,31 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.primitives.add(Cesium.createOsmBuildings()); + viewer.scene.primitives.add(Cesium.createOsmBuildings()); - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), - orientation: { - heading: Cesium.Math.toRadians(20), - pitch: Cesium.Math.toRadians(-20), - }, - }); - })(); //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), + orientation: { + heading: Cesium.Math.toRadians(20), + pitch: Cesium.Math.toRadians(-20), + }, + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Widget.html b/Apps/Sandcastle/gallery/Cesium Widget.html index 55e1f10e93e..25c30fbc958 100644 --- a/Apps/Sandcastle/gallery/Cesium Widget.html +++ b/Apps/Sandcastle/gallery/Cesium Widget.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Cesium.CesiumWidget is similar to Cesium.Viewer, but @@ -46,7 +46,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 016a5720fb5..0e4162731d7 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -32,24 +32,22 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // For more information on Cesium World Terrain, see https://cesium.com/platform/cesium-ion/content/cesium-world-terrain/ - (async () => { - try { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Circles and Ellipses.html b/Apps/Sandcastle/gallery/Circles and Ellipses.html index c112576c519..e0dc4a87134 100644 --- a/Apps/Sandcastle/gallery/Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/Circles and Ellipses.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -78,7 +78,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Model.html b/Apps/Sandcastle/gallery/Clamp to 3D Model.html index fd91a1ab475..84f7a352fe0 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Model.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Model.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -112,7 +112,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index 57ccc1cb57a..048b34bad1b 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -32,66 +32,68 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const clock = viewer.clock; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + const clock = viewer.clock; - let entity; - let positionProperty; - const dataSourcePromise = Cesium.CzmlDataSource.load( - "../../SampleData/ClampToGround.czml" - ); - viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { - entity = dataSource.entities.getById("CesiumMilkTruck"); - positionProperty = entity.position; - }); + let entity; + let positionProperty; + const dataSourcePromise = Cesium.CzmlDataSource.load( + "../../SampleData/ClampToGround.czml" + ); + viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { + entity = dataSource.entities.getById("CesiumMilkTruck"); + positionProperty = entity.position; + }); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) + ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1216403.8845586285, - -4736357.493351395, - 4081299.715698949 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.2892217081808806, - -0.4799070147502502, - 6.279789177843313 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1216403.8845586285, + -4736357.493351395, + 4081299.715698949 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.2892217081808806, + -0.4799070147502502, + 6.279789177843313 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - if (scene.clampToHeightSupported) { - tileset.initialTilesLoaded.addEventListener(start); - } else { - window.alert("This browser does not support clampToHeight."); - } + if (scene.clampToHeightSupported) { + tileset.initialTilesLoaded.addEventListener(start); + } else { + window.alert("This browser does not support clampToHeight."); + } - function start() { - clock.shouldAnimate = true; - const objectsToExclude = [entity]; - scene.postRender.addEventListener(function () { - const position = positionProperty.getValue(clock.currentTime); - entity.position = scene.clampToHeight(position, objectsToExclude); - }); - } - })(); //Sandcastle_End + function start() { + clock.shouldAnimate = true; + const objectsToExclude = [entity]; + scene.postRender.addEventListener(function () { + const position = positionProperty.getValue(clock.currentTime); + entity.position = scene.clampToHeight(position, objectsToExclude); + }); + } //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index f6b20444f25..fd4346836b9 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -34,20 +34,14 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - Sandcastle.addDefaultToolbarMenu( [ { @@ -365,7 +359,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 3ac16b5dc61..e74ffe9ec77 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -32,18 +32,12 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(40866), @@ -179,7 +173,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index b9b003fa070..a20994b8790 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -76,317 +76,279 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const camera = scene.camera; + const scene = viewer.scene; + const camera = scene.camera; - let center = new Cesium.Cartesian3( - 1216389.3637977627, - -4736323.641980423, - 4081321.7428341154 - ); - let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) - ); - let hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + let center = new Cesium.Cartesian3( + 1216389.3637977627, + -4736323.641980423, + 4081321.7428341154 + ); + let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) + ); + let hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const buildingHighlight = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume", + const buildingHighlight = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216409.0189737265, - -4736252.144235287, - 4081393.6027081604 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.4, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216409.0189737265, + -4736252.144235287, + 4081393.6027081604 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.4, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight1 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 1", + const treeHighlight1 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 1", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216404.8844045496, - -4736255.287065536, - 4081392.010192471 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(-0.25, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216404.8844045496, + -4736255.287065536, + 4081392.010192471 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(-0.25, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight2 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 2", + const treeHighlight2 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 2", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216398.813990024, - -4736258.039875737, - 4081387.9562678365 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216398.813990024, + -4736258.039875737, + 4081387.9562678365 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight3 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 3", + const treeHighlight3 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 3", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216393.6257790313, - -4736259.809075361, - 4081384.4858198245 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -1.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216393.6257790313, + -4736259.809075361, + 4081384.4858198245 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -1.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight4 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.SphereGeometry({ - radius: 2.0, - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 4", + const treeHighlight4 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.SphereGeometry({ + radius: 2.0, }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); - - function highlightBuilding() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216394.1392207467, - -4736348.59346919, - 4081293.9160685353 - ), - orientation: { - heading: 0.018509338875732695, - pitch: -0.09272999615872646, - }, - }); - } - - function highlightTrees() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216435.0352745096, - -4736283.144192113, - 4081368.0920420634 - ), - orientation: { - heading: 5.718380792746039, - pitch: -0.3087010195266797, + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), }, - }); - } + id: "volume 4", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - function invertClassification(checked) { - if (checked && !scene.invertClassificationSupported) { - window.alert( - "This browser does not support invert classification" - ); - } + function highlightBuilding() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216394.1392207467, + -4736348.59346919, + 4081293.9160685353 + ), + orientation: { + heading: 0.018509338875732695, + pitch: -0.09272999615872646, + }, + }); + } - scene.invertClassification = checked; - scene.invertClassificationColor = new Cesium.Color( - 0.25, - 0.25, - 0.25, - 1.0 - ); + function highlightTrees() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216435.0352745096, + -4736283.144192113, + 4081368.0920420634 + ), + orientation: { + heading: 5.718380792746039, + pitch: -0.3087010195266797, + }, + }); + } - buildingHighlight.getGeometryInstanceAttributes( - "volume" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight1.getGeometryInstanceAttributes( - "volume 1" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight2.getGeometryInstanceAttributes( - "volume 2" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight3.getGeometryInstanceAttributes( - "volume 3" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight4.getGeometryInstanceAttributes( - "volume 4" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + function invertClassification(checked) { + if (checked && !scene.invertClassificationSupported) { + window.alert("This browser does not support invert classification"); } - function updateAlpha(value) { - scene.invertClassificationColor.alpha = parseFloat(value); - } + scene.invertClassification = checked; + scene.invertClassificationColor = new Cesium.Color( + 0.25, + 0.25, + 0.25, + 1.0 + ); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - scene.primitives.add(tileset); + buildingHighlight.getGeometryInstanceAttributes( + "volume" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight1.getGeometryInstanceAttributes( + "volume 1" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight2.getGeometryInstanceAttributes( + "volume 2" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight3.getGeometryInstanceAttributes( + "volume 3" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight4.getGeometryInstanceAttributes( + "volume 4" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + } + + function updateAlpha(value) { + scene.invertClassificationColor.alpha = parseFloat(value); + } - const viewModel = { - inverted: viewer.scene.invertClassification, - invertedAlpha: viewer.scene.invertClassificationColor.alpha, - highlightBuilding: highlightBuilding, - highlightTrees: highlightTrees, - }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "inverted") - .subscribe(invertClassification); - Cesium.knockout - .getObservable(viewModel, "invertedAlpha") - .subscribe(updateAlpha); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + scene.primitives.add(tileset); - highlightTrees(); + const viewModel = { + inverted: viewer.scene.invertClassification, + invertedAlpha: viewer.scene.invertClassificationColor.alpha, + highlightBuilding: highlightBuilding, + highlightTrees: highlightTrees, + }; + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + Cesium.knockout + .getObservable(viewModel, "inverted") + .subscribe(invertClassification); + Cesium.knockout + .getObservable(viewModel, "invertedAlpha") + .subscribe(updateAlpha); - let currentObjectId; - let currentPrimitive; - let currentColor; - let currentShow; - let attributes; + highlightTrees(); - const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.id) - ) { - if (pickedObject.id === currentObjectId) { - return; - } + let currentObjectId; + let currentPrimitive; + let currentColor; + let currentShow; + let attributes; - if (Cesium.defined(currentObjectId)) { - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - attributes.color = currentColor; - attributes.show = currentShow; - currentObjectId = undefined; - currentPrimitive = undefined; - currentColor = undefined; - currentShow = undefined; - } + const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) { + if (pickedObject.id === currentObjectId) { + return; } - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.primitive) && - Cesium.defined(pickedObject.id) && - Cesium.defined( - pickedObject.primitive.getGeometryInstanceAttributes - ) - ) { - currentObjectId = pickedObject.id; - currentPrimitive = pickedObject.primitive; - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - currentColor = attributes.color; - currentShow = attributes.show; - if (!scene.invertClassification) { - attributes.color = [255, 0, 255, 128]; - } - attributes.show = [1]; - } else if (Cesium.defined(currentObjectId)) { + if (Cesium.defined(currentObjectId)) { attributes = currentPrimitive.getGeometryInstanceAttributes( currentObjectId ); @@ -395,14 +357,47 @@ currentObjectId = undefined; currentPrimitive = undefined; currentColor = undefined; + currentShow = undefined; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End + } + + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.primitive) && + Cesium.defined(pickedObject.id) && + Cesium.defined(pickedObject.primitive.getGeometryInstanceAttributes) + ) { + currentObjectId = pickedObject.id; + currentPrimitive = pickedObject.primitive; + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + currentColor = attributes.color; + currentShow = attributes.show; + if (!scene.invertClassification) { + attributes.color = [255, 0, 255, 128]; + } + attributes.show = [1]; + } else if (Cesium.defined(currentObjectId)) { + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + attributes.color = currentColor; + attributes.show = currentShow; + currentObjectId = undefined; + currentPrimitive = undefined; + currentColor = undefined; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clock.html b/Apps/Sandcastle/gallery/Clock.html index 21364613c02..aedacb0ce17 100644 --- a/Apps/Sandcastle/gallery/Clock.html +++ b/Apps/Sandcastle/gallery/Clock.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create a clock that loops on Christmas day 2013 and runs in 4000x real time. @@ -66,7 +66,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cloud Parameters.html b/Apps/Sandcastle/gallery/Cloud Parameters.html index ce3b961b758..45d1e6d1418 100644 --- a/Apps/Sandcastle/gallery/Cloud Parameters.html +++ b/Apps/Sandcastle/gallery/Cloud Parameters.html @@ -159,7 +159,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -314,7 +314,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index cf6d8466f53..f275991e71a 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -29,251 +29,253 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - infoBox: false, - shouldAnimate: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + infoBox: false, + shouldAnimate: true, + }); - const scene = viewer.scene; - scene.primitives.add(Cesium.createOsmBuildings()); + const scene = viewer.scene; + scene.primitives.add(Cesium.createOsmBuildings()); - /////////////////////////// - // Create clouds - /////////////////////////// + /////////////////////////// + // Create clouds + /////////////////////////// - Cesium.Math.setRandomNumberSeed(2.5); - function getRandomNumberInRange(minValue, maxValue) { - return ( - minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) - ); - } + Cesium.Math.setRandomNumberSeed(2.5); + function getRandomNumberInRange(minValue, maxValue) { + return ( + minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) + ); + } - const clouds = new Cesium.CloudCollection(); + const clouds = new Cesium.CloudCollection(); - // manually position clouds in the mountains - function createBackLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), - scale: new Cesium.Cartesian2(1500, 250), - maximumSize: new Cesium.Cartesian3(50, 15, 13), - slice: 0.3, - }); + // manually position clouds in the mountains + function createBackLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), + scale: new Cesium.Cartesian2(1500, 250), + maximumSize: new Cesium.Cartesian3(50, 15, 13), + slice: 0.3, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), - scale: new Cesium.Cartesian2(1500, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.36, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), + scale: new Cesium.Cartesian2(1500, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.36, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), - scale: new Cesium.Cartesian2(2000, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.49, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), + scale: new Cesium.Cartesian2(2000, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.49, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(13, 13, 13), - slice: 0.2, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(13, 13, 13), + slice: 0.2, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), - scale: new Cesium.Cartesian2(1700, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.6, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), + scale: new Cesium.Cartesian2(1700, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.6, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(15, 13, 15), - slice: 0.35, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(15, 13, 15), + slice: 0.35, + }); + + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), + scale: new Cesium.Cartesian2(1500, 500), + maximumSize: new Cesium.Cartesian3(30, 20, 17), + slice: 0.45, + }); + } + let long, + lat, + height, + scaleX, + scaleY, + aspectRatio, + cloudHeight, + depth, + slice; + + // randomly generate clouds in a certain area + function createRandomClouds( + numClouds, + startLong, + stopLong, + startLat, + stopLat, + minHeight, + maxHeight + ) { + const rangeLong = stopLong - startLong; + const rangeLat = stopLat - startLat; + for (let i = 0; i < numClouds; i++) { + long = startLong + getRandomNumberInRange(0, rangeLong); + lat = startLat + getRandomNumberInRange(0, rangeLat); + height = getRandomNumberInRange(minHeight, maxHeight); + scaleX = getRandomNumberInRange(150, 350); + scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); + slice = getRandomNumberInRange(0.3, 0.7); + depth = getRandomNumberInRange(5, 20); + aspectRatio = getRandomNumberInRange(1.5, 2.1); + cloudHeight = getRandomNumberInRange(5, 20); clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), - scale: new Cesium.Cartesian2(1500, 500), - maximumSize: new Cesium.Cartesian3(30, 20, 17), - slice: 0.45, + position: Cesium.Cartesian3.fromDegrees(long, lat, height), + scale: new Cesium.Cartesian2(scaleX, scaleY), + maximumSize: new Cesium.Cartesian3( + aspectRatio * cloudHeight, + cloudHeight, + depth + ), + slice: slice, }); } + } - let long, - lat, - height, - scaleX, - scaleY, - aspectRatio, - cloudHeight, - depth, - slice; - - // randomly generate clouds in a certain area - function createRandomClouds( - numClouds, - startLong, - stopLong, - startLat, - stopLat, - minHeight, - maxHeight - ) { - const rangeLong = stopLong - startLong; - const rangeLat = stopLat - startLat; - for (let i = 0; i < numClouds; i++) { - long = startLong + getRandomNumberInRange(0, rangeLong); - lat = startLat + getRandomNumberInRange(0, rangeLat); - height = getRandomNumberInRange(minHeight, maxHeight); - scaleX = getRandomNumberInRange(150, 350); - scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); - slice = getRandomNumberInRange(0.3, 0.7); - depth = getRandomNumberInRange(5, 20); - aspectRatio = getRandomNumberInRange(1.5, 2.1); - cloudHeight = getRandomNumberInRange(5, 20); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(long, lat, height), - scale: new Cesium.Cartesian2(scaleX, scaleY), - maximumSize: new Cesium.Cartesian3( - aspectRatio * cloudHeight, - cloudHeight, - depth - ), - slice: slice, - }); - } - } + // manually position clouds in front + const scratch = new Cesium.Cartesian3(); + function createFrontLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), + scale: new Cesium.Cartesian2(400, 150), + maximumSize: new Cesium.Cartesian3(25, 12, 15), + slice: 0.36, + }); - // manually position clouds in front - const scratch = new Cesium.Cartesian3(); - function createFrontLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), - scale: new Cesium.Cartesian2(400, 150), - maximumSize: new Cesium.Cartesian3(25, 12, 15), - slice: 0.36, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), + scale: new Cesium.Cartesian2(450, 200), + maximumSize: new Cesium.Cartesian3(25, 14, 12), + slice: 0.3, + }); + } - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), - scale: new Cesium.Cartesian2(450, 200), - maximumSize: new Cesium.Cartesian3(25, 14, 12), - slice: 0.3, - }); - } + createBackLayerClouds(); + createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); + createFrontLayerClouds(); - createBackLayerClouds(); - createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); - createFrontLayerClouds(); + scene.primitives.add(clouds); - scene.primitives.add(clouds); + /////////////////////////// + // Create hot air balloons + /////////////////////////// - /////////////////////////// - // Create hot air balloons - /////////////////////////// + const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); + const stop = Cesium.JulianDate.addSeconds( + start, + 90, + new Cesium.JulianDate() + ); - const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); - const stop = Cesium.JulianDate.addSeconds( - start, - 90, + function computeBalloonFlight(long, lat, height0, height1) { + const property = new Cesium.SampledPositionProperty(); + const time0 = start.clone(); + const time1 = Cesium.JulianDate.addSeconds( + time0, + 30, + new Cesium.JulianDate() + ); + const time2 = Cesium.JulianDate.addSeconds( + time1, + 15, + new Cesium.JulianDate() + ); + const time3 = Cesium.JulianDate.addSeconds( + time2, + 30, + new Cesium.JulianDate() + ); + const time4 = Cesium.JulianDate.addSeconds( + time3, + 15, new Cesium.JulianDate() ); - function computeBalloonFlight(long, lat, height0, height1) { - const property = new Cesium.SampledPositionProperty(); - const time0 = start.clone(); - const time1 = Cesium.JulianDate.addSeconds( - time0, - 30, - new Cesium.JulianDate() - ); - const time2 = Cesium.JulianDate.addSeconds( - time1, - 15, - new Cesium.JulianDate() - ); - const time3 = Cesium.JulianDate.addSeconds( - time2, - 30, - new Cesium.JulianDate() - ); - const time4 = Cesium.JulianDate.addSeconds( - time3, - 15, - new Cesium.JulianDate() - ); - - const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); - const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); + const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); + const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); - property.addSample(time0, position0); - property.addSample(time1, position1); - property.addSample(time2, position1); - property.addSample(time3, position0); - property.addSample(time4, position0); + property.addSample(time0, position0); + property.addSample(time1, position1); + property.addSample(time2, position1); + property.addSample(time3, position0); + property.addSample(time4, position0); - return property; - } + return property; + } - const balloon0 = viewer.entities.add({ - position: computeBalloonFlight(-122.661, 45.524, 400, 500), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + const balloon0 = viewer.entities.add({ + position: computeBalloonFlight(-122.661, 45.524, 400, 500), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - balloon0.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + balloon0.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - const balloon1 = viewer.entities.add({ - position: computeBalloonFlight(-122.662, 45.517, 400, 300), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + const balloon1 = viewer.entities.add({ + position: computeBalloonFlight(-122.662, 45.517, 400, 300), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - balloon1.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + balloon1.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; - // Fly to Portland - scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), - orientation: { - heading: Cesium.Math.toRadians(-115), - pitch: Cesium.Math.toRadians(-12), - roll: 0.0, - }, - }); + // Fly to Portland + scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), + orientation: { + heading: Cesium.Math.toRadians(-115), + pitch: Cesium.Math.toRadians(-12), + roll: 0.0, + }, + }); - scene.fog.density = 1.15e-4; - })(); //Sandcastle_End + scene.fog.density = 1.15e-4; //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clustering.html b/Apps/Sandcastle/gallery/Clustering.html index 517f3bbe1c2..bb7e98fb501 100644 --- a/Apps/Sandcastle/gallery/Clustering.html +++ b/Apps/Sandcastle/gallery/Clustering.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -214,7 +214,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Corridor.html b/Apps/Sandcastle/gallery/Corridor.html index 32aeb401817..a8067ee9929 100644 --- a/Apps/Sandcastle/gallery/Corridor.html +++ b/Apps/Sandcastle/gallery/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -96,7 +96,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 991d384e2c3..4a234981789 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -406,7 +406,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Geocoder.html b/Apps/Sandcastle/gallery/Custom Geocoder.html index 2804297cf80..5e6c82b4ebf 100644 --- a/Apps/Sandcastle/gallery/Custom Geocoder.html +++ b/Apps/Sandcastle/gallery/Custom Geocoder.html @@ -42,7 +42,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -94,7 +94,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html index 7c50573d81d..862b8184a9b 100644 --- a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -99,7 +99,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Post Process.html b/Apps/Sandcastle/gallery/Custom Post Process.html index 213efedaded..2e5b56fa077 100644 --- a/Apps/Sandcastle/gallery/Custom Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Post Process.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -82,7 +82,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html index 379785a1d35..a2574c83403 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -80,7 +80,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Models.html b/Apps/Sandcastle/gallery/Custom Shaders Models.html index 6349c9fa5c1..7bb052eba6f 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Models.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Models.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -480,7 +480,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index 96348e33498..f4f6d71ce81 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -39,20 +39,13 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - scene.globe.depthTestAgainstTerrain = false; // MAXAR OWT Muscatatuk photogrammetry dataset with property textures @@ -128,7 +121,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cylinders and Cones.html b/Apps/Sandcastle/gallery/Cylinders and Cones.html index 988dee263ca..675d9c33288 100644 --- a/Apps/Sandcastle/gallery/Cylinders and Cones.html +++ b/Apps/Sandcastle/gallery/Cylinders and Cones.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/DataSource Ordering.html b/Apps/Sandcastle/gallery/DataSource Ordering.html index a7dec9729ec..bb198bd2d8e 100644 --- a/Apps/Sandcastle/gallery/DataSource Ordering.html +++ b/Apps/Sandcastle/gallery/DataSource Ordering.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml1 = [ @@ -132,7 +132,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Depth of Field.html b/Apps/Sandcastle/gallery/Depth of Field.html index 4dc901ab722..bf42dbe65bb 100644 --- a/Apps/Sandcastle/gallery/Depth of Field.html +++ b/Apps/Sandcastle/gallery/Depth of Field.html @@ -89,7 +89,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -174,7 +174,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Distance Display Conditions.html b/Apps/Sandcastle/gallery/Distance Display Conditions.html index ad18acdf621..dbd67502df3 100644 --- a/Apps/Sandcastle/gallery/Distance Display Conditions.html +++ b/Apps/Sandcastle/gallery/Distance Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -126,7 +126,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index 57e21acb0f6..48aa17c1a5a 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -43,22 +43,15 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { selectionIndicator: false, infoBox: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK ); @@ -183,7 +176,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Earth at Night.html b/Apps/Sandcastle/gallery/Earth at Night.html index 0768b531127..4df50fd541b 100644 --- a/Apps/Sandcastle/gallery/Earth at Night.html +++ b/Apps/Sandcastle/gallery/Earth at Night.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // The Earth at Night, also known as Black Marble 2017 and Night Lights @@ -78,7 +78,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Elevation Band Material.html b/Apps/Sandcastle/gallery/Elevation Band Material.html index 42fc231b535..7b3abd2b84f 100644 --- a/Apps/Sandcastle/gallery/Elevation Band Material.html +++ b/Apps/Sandcastle/gallery/Elevation Band Material.html @@ -115,228 +115,215 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 290637.5534733206, - 5637471.593707632, - 2978256.8126927214 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 290637.5534733206, + 5637471.593707632, + 2978256.8126927214 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); - const viewModel = { - gradient: false, - band1Position: 7000.0, - band2Position: 7500.0, - band3Position: 8000.0, - bandThickness: 100.0, - bandTransparency: 0.5, - backgroundTransparency: 0.75, - }; + const viewModel = { + gradient: false, + band1Position: 7000.0, + band2Position: 7500.0, + band3Position: 8000.0, + bandThickness: 100.0, + bandTransparency: 0.5, + backgroundTransparency: 0.75, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateMaterial); - } + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateMaterial); } + } + + function updateMaterial() { + const gradient = Boolean(viewModel.gradient); + const band1Position = Number(viewModel.band1Position); + const band2Position = Number(viewModel.band2Position); + const band3Position = Number(viewModel.band3Position); + const bandThickness = Number(viewModel.bandThickness); + const bandTransparency = Number(viewModel.bandTransparency); + const backgroundTransparency = Number( + viewModel.backgroundTransparency + ); - function updateMaterial() { - const gradient = Boolean(viewModel.gradient); - const band1Position = Number(viewModel.band1Position); - const band2Position = Number(viewModel.band2Position); - const band3Position = Number(viewModel.band3Position); - const bandThickness = Number(viewModel.bandThickness); - const bandTransparency = Number(viewModel.bandTransparency); - const backgroundTransparency = Number( - viewModel.backgroundTransparency + const layers = []; + const backgroundLayer = { + entries: [ + { + height: 4200.0, + color: new Cesium.Color(0.0, 0.0, 0.2, backgroundTransparency), + }, + { + height: 8000.0, + color: new Cesium.Color(1.0, 1.0, 1.0, backgroundTransparency), + }, + { + height: 8500.0, + color: new Cesium.Color(1.0, 0.0, 0.0, backgroundTransparency), + }, + ], + extendDownwards: true, + extendUpwards: true, + }; + layers.push(backgroundLayer); + + const gridStartHeight = 4200.0; + const gridEndHeight = 8848.0; + const gridCount = 50; + for (let i = 0; i < gridCount; i++) { + const lerper = i / (gridCount - 1); + const heightBelow = Cesium.Math.lerp( + gridStartHeight, + gridEndHeight, + lerper ); + const heightAbove = heightBelow + 10.0; + const alpha = + Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; + layers.push({ + entries: [ + { + height: heightBelow, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: heightAbove, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + ], + }); + } - const layers = []; - const backgroundLayer = { + const antialias = Math.min(10.0, bandThickness * 0.1); + + if (!gradient) { + const band1 = { entries: [ { - height: 4200.0, - color: new Cesium.Color( - 0.0, - 0.0, - 0.2, - backgroundTransparency - ), + height: band1Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + }, + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), }, { - height: 8000.0, - color: new Cesium.Color( - 1.0, - 1.0, - 1.0, - backgroundTransparency - ), + height: band1Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), }, { - height: 8500.0, - color: new Cesium.Color( - 1.0, - 0.0, - 0.0, - backgroundTransparency - ), + height: band1Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), }, ], - extendDownwards: true, - extendUpwards: true, }; - layers.push(backgroundLayer); - - const gridStartHeight = 4200.0; - const gridEndHeight = 8848.0; - const gridCount = 50; - for (let i = 0; i < gridCount; i++) { - const lerper = i / (gridCount - 1); - const heightBelow = Cesium.Math.lerp( - gridStartHeight, - gridEndHeight, - lerper - ); - const heightAbove = heightBelow + 10.0; - const alpha = - Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; - layers.push({ - entries: [ - { - height: heightBelow, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: heightAbove, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - ], - }); - } - - const antialias = Math.min(10.0, bandThickness * 0.1); - - if (!gradient) { - const band1 = { - entries: [ - { - height: band1Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band1Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band1Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - ], - }; - - const band2 = { - entries: [ - { - height: band2Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - { - height: band2Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - ], - }; - const band3 = { - entries: [ - { - height: band3Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - { - height: band3Position - bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - ], - }; + const band2 = { + entries: [ + { + height: band2Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + { + height: band2Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + ], + }; - layers.push(band1); - layers.push(band2); - layers.push(band3); - } else { - const combinedBand = { - entries: [ - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band2Position, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - ], - }; + const band3 = { + entries: [ + { + height: band3Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + { + height: band3Position - bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + ], + }; - layers.push(combinedBand); - } + layers.push(band1); + layers.push(band2); + layers.push(band3); + } else { + const combinedBand = { + entries: [ + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band2Position, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + ], + }; - const material = Cesium.createElevationBandMaterial({ - scene: viewer.scene, - layers: layers, - }); - viewer.scene.globe.material = material; + layers.push(combinedBand); } - updateMaterial(); - })(); //Sandcastle_End + const material = Cesium.createElevationBandMaterial({ + scene: viewer.scene, + layers: layers, + }); + viewer.scene.globe.material = material; + } + + updateMaterial(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Export KML.html b/Apps/Sandcastle/gallery/Export KML.html index 379f8efa34f..ad571fa82b8 100644 --- a/Apps/Sandcastle/gallery/Export KML.html +++ b/Apps/Sandcastle/gallery/Export KML.html @@ -35,7 +35,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -160,7 +160,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index 24325ed8467..dc5d0be7e25 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -29,45 +29,47 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); - viewer.scene.postProcessStages.fxaa.enabled = true; + viewer.scene.postProcessStages.fxaa.enabled = true; - Sandcastle.addToggleButton("FXAA", true, function (checked) { - viewer.scene.postProcessStages.fxaa.enabled = checked; - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("FXAA", true, function (checked) { + viewer.scene.postProcessStages.fxaa.enabled = checked; + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Fog Post Process.html b/Apps/Sandcastle/gallery/Fog Post Process.html index 3cedae53ed7..7c9bc4a0366 100644 --- a/Apps/Sandcastle/gallery/Fog Post Process.html +++ b/Apps/Sandcastle/gallery/Fog Post Process.html @@ -27,7 +27,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -110,7 +110,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index 05ac4f4bae7..8f1f31fdcff 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -31,18 +31,12 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const pinBuilder = new Cesium.PinBuilder(); @@ -148,7 +142,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html index 2cab2f0f6fd..4c30f772d3e 100644 --- a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html +++ b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -127,7 +127,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html index ee2179d9cca..94c310132ea 100644 --- a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html +++ b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin //Load a GeoJSON file containing simplestyle information. @@ -57,7 +57,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index d2f0b09a20b..1ac2145e111 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -32,13 +32,14 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayerPicker: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); // depth test against terrain is required to make the polygons clamp to terrain @@ -81,14 +82,6 @@ }, ]); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const longitude = 6.950615989890521; const latitude = 45.79546589994886; const delta = 0.001; @@ -185,7 +178,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry and Appearances.html b/Apps/Sandcastle/gallery/Geometry and Appearances.html index 72551e7e97f..f5a37940312 100644 --- a/Apps/Sandcastle/gallery/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -639,7 +639,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Interior.html b/Apps/Sandcastle/gallery/Globe Interior.html index 5d5d60f81d8..193ba773d20 100644 --- a/Apps/Sandcastle/gallery/Globe Interior.html +++ b/Apps/Sandcastle/gallery/Globe Interior.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -183,7 +183,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index c9f92c36190..45e79c272f0 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -119,22 +119,16 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); viewer.scene.globe.enableLighting = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }); - } catch (error) { - console.log(error); - } - })(); - function getElevationContourMaterial() { // Creates a composite material with both elevation shading and contour lines return new Cesium.Material({ @@ -428,7 +422,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index 87dc0c82f54..aedfafce413 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -81,233 +81,235 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - scene.screenSpaceCameraController.enableCollisionDetection = false; - globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( - 400.0, - 0.0, - 800.0, - 1.0 - ); + scene.screenSpaceCameraController.enableCollisionDetection = false; + globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( + 400.0, + 0.0, + 800.0, + 1.0 + ); - const longitude = -3.82518; - const latitude = 53.11728; - const height = 72.8; - const position = Cesium.Cartesian3.fromDegrees( - longitude, - latitude, - height - ); - const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; + const longitude = -3.82518; + const latitude = 53.11728; + const height = 72.8; + const position = Cesium.Cartesian3.fromDegrees( + longitude, + latitude, + height + ); + const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; - const entity = viewer.entities.add({ - name: url, - position: position, - model: { - uri: url, - }, - }); + const entity = viewer.entities.add({ + name: url, + position: position, + model: { + uri: url, + }, + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8152789692233817, - 53.124521420389996, - 200.20779492422255, - -3.8165955002619016, - 53.12555934545405, - 205.85834336951655, - -3.8201599842222054, - 53.12388420656903, - 230.82362697069453, - -3.8198667503545027, - 53.123748567587455, - 225.53297006293968, - -3.8190548496317476, - 53.1240486000822, - 221.82677773619432, - -3.817536387097508, - 53.122763476393764, - 209.94136782255705, - -3.8169125359199336, - 53.12285547981627, - 210.96626238861327, - -3.8166873871853073, - 53.12299403424474, - 211.02223937734595, - -3.8163695374580873, - 53.12300505277307, - 211.25942926271824, - -3.8162743040622313, - 53.12281471203994, - 212.35109129094147, - -3.8159746138174193, - 53.12280996651767, - 214.87977416348798, - -3.815429896849304, - 53.1236135347983, - 209.72496223706005, - ]) - ), - material: Cesium.Color.LIME.withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8152789692233817, + 53.124521420389996, + 200.20779492422255, + -3.8165955002619016, + 53.12555934545405, + 205.85834336951655, + -3.8201599842222054, + 53.12388420656903, + 230.82362697069453, + -3.8198667503545027, + 53.123748567587455, + 225.53297006293968, + -3.8190548496317476, + 53.1240486000822, + 221.82677773619432, + -3.817536387097508, + 53.122763476393764, + 209.94136782255705, + -3.8169125359199336, + 53.12285547981627, + 210.96626238861327, + -3.8166873871853073, + 53.12299403424474, + 211.02223937734595, + -3.8163695374580873, + 53.12300505277307, + 211.25942926271824, + -3.8162743040622313, + 53.12281471203994, + 212.35109129094147, + -3.8159746138174193, + 53.12280996651767, + 214.87977416348798, + -3.815429896849304, + 53.1236135347983, + 209.72496223706005, + ]) + ), + material: Cesium.Color.LIME.withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8098444201746373, - 53.1190304262546, - 286.1875170545701, - -3.8099801237370663, - 53.119539531697576, - 288.7733884242394, - -3.810165716635671, - 53.11979180761567, - 290.9294630315179, - -3.8104840812145357, - 53.12007534956926, - 292.6392327626228, - -3.8105689502073554, - 53.120259094792196, - 292.222036965774, - -3.811027311824268, - 53.120409248874196, - 289.61356291617307, - -3.811530473295422, - 53.12063281057782, - 284.01098712543586, - -3.8120545342562693, - 53.120742539082435, - 280.118191867836, - -3.812444493044727, - 53.120813289759326, - 276.0400221387852, - -3.812779626711285, - 53.12094275348024, - 271.1187399484896, - -3.8133560322579494, - 53.12104757866638, - 263.3495497598578, - -3.8137266493960085, - 53.12120789867194, - 257.73878624321316, - -3.8142552291751133, - 53.121321248522904, - 251.87265828778177, - -3.814322603988525, - 53.12174170121103, - 238.7082749547689, - -3.8143764268391314, - 53.1219492923309, - 235.0371831845662, - -3.8148156514145786, - 53.12210819668669, - 230.2458816627467, - -3.8155394721966163, - 53.1222990144029, - 221.33319292262706, - -3.8159828072920927, - 53.12203093429715, - 223.66664756982703, - -3.816678108944717, - 53.12183939425214, - 223.8787312412801, - -3.817466081093726, - 53.121751900508535, - 224.52293229989735, - -3.8183082996527955, - 53.12173266141031, - 223.3672181535749, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8098444201746373, + 53.1190304262546, + 286.1875170545701, + -3.8099801237370663, + 53.119539531697576, + 288.7733884242394, + -3.810165716635671, + 53.11979180761567, + 290.9294630315179, + -3.8104840812145357, + 53.12007534956926, + 292.6392327626228, + -3.8105689502073554, + 53.120259094792196, + 292.222036965774, + -3.811027311824268, + 53.120409248874196, + 289.61356291617307, + -3.811530473295422, + 53.12063281057782, + 284.01098712543586, + -3.8120545342562693, + 53.120742539082435, + 280.118191867836, + -3.812444493044727, + 53.120813289759326, + 276.0400221387852, + -3.812779626711285, + 53.12094275348024, + 271.1187399484896, + -3.8133560322579494, + 53.12104757866638, + 263.3495497598578, + -3.8137266493960085, + 53.12120789867194, + 257.73878624321316, + -3.8142552291751133, + 53.121321248522904, + 251.87265828778177, + -3.814322603988525, + 53.12174170121103, + 238.7082749547689, + -3.8143764268391314, + 53.1219492923309, + 235.0371831845662, + -3.8148156514145786, + 53.12210819668669, + 230.2458816627467, + -3.8155394721966163, + 53.1222990144029, + 221.33319292262706, + -3.8159828072920927, + 53.12203093429715, + 223.66664756982703, + -3.816678108944717, + 53.12183939425214, + 223.8787312412801, + -3.817466081093726, + 53.121751900508535, + 224.52293229989735, + -3.8183082996527955, + 53.12173266141031, + 223.3672181535749, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const viewModel = { - translucencyEnabled: true, - fadeByDistance: true, - showVectorData: false, - alpha: 0.5, - }; + const viewModel = { + translucencyEnabled: true, + fadeByDistance: true, + showVectorData: false, + alpha: 0.5, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout.getObservable(viewModel, name).subscribe(update); - } + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout.getObservable(viewModel, name).subscribe(update); } + } - function update() { - globe.translucency.enabled = viewModel.translucencyEnabled; + function update() { + globe.translucency.enabled = viewModel.translucencyEnabled; - let alpha = Number(viewModel.alpha); - alpha = !isNaN(alpha) ? alpha : 1.0; - alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); + let alpha = Number(viewModel.alpha); + alpha = !isNaN(alpha) ? alpha : 1.0; + alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); - globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; - globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance - ? 1.0 - : alpha; + globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; + globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance + ? 1.0 + : alpha; - polygon.show = viewModel.showVectorData; - polyline.show = viewModel.showVectorData; - } - update(); + polygon.show = viewModel.showVectorData; + polyline.show = viewModel.showVectorData; + } + update(); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 3826465.9884728403, - -254831.02751468265, - 5081387.671561018 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.3889450556243754, - -0.5276382514771969, - 6.282272566663295 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 3826465.9884728403, + -254831.02751468265, + 5081387.671561018 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.3889450556243754, + -0.5276382514771969, + 6.282272566663295 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.camera.flyTo({ - destination: new Cesium.Cartesian3( - 3827270.552916987, - -255123.18143177085, - 5079147.091351856 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.2624281242239963, - -0.22213535190506972, - 6.282786783842843 - ), - duration: 5.0, - }); - })(); //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: new Cesium.Cartesian3( + 3827270.552916987, + -255123.18143177085, + 5079147.091351856 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.2624281242239963, + -0.22213535190506972, + 6.282786783842843 + ), + duration: 5.0, + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index 2c7cb0c0461..c0294f30c3e 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -32,46 +32,39 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - try { - const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( - new Cesium.Resource({ - url: "http://www.earthenterprise.org/3d", - proxy: new Cesium.DefaultProxy("/proxy/"), - }) - ); + const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( + new Cesium.Resource({ + url: "http://www.earthenterprise.org/3d", + proxy: new Cesium.DefaultProxy("/proxy/"), + }) + ); - const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ - metadata: geeMetadata, - }), - terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( - geeMetadata - ), - baseLayerPicker: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ + metadata: geeMetadata, + }), + terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( + geeMetadata + ), + baseLayerPicker: false, + }); - // Start off looking at San Francisco. - viewer.camera.setView({ - destination: Cesium.Rectangle.fromDegrees( - -123.0, - 36.0, - -121.7, - 39.0 - ), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End + // Start off looking at San Francisco. + viewer.camera.setView({ + destination: Cesium.Rectangle.fromDegrees(-123.0, 36.0, -121.7, 39.0), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/HTML Overlays.html b/Apps/Sandcastle/gallery/HTML Overlays.html index 79f78d5ff98..350edead2a5 100644 --- a/Apps/Sandcastle/gallery/HTML Overlays.html +++ b/Apps/Sandcastle/gallery/HTML Overlays.html @@ -37,7 +37,7 @@ src="../images/Cesium_Logo_overlay.png" /> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index e3c2dd80cfb..2e3de8a0ac6 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -71,7 +71,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -265,7 +265,11 @@ <h1>Loading...</h1> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 992c9b3f04f..649bb10945c 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -41,7 +41,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/High Dynamic Range.html b/Apps/Sandcastle/gallery/High Dynamic Range.html index abb4f589055..dce70daa0c1 100644 --- a/Apps/Sandcastle/gallery/High Dynamic Range.html +++ b/Apps/Sandcastle/gallery/High Dynamic Range.html @@ -29,71 +29,73 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - shadows: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + shadows: true, + }); - if (!viewer.scene.highDynamicRangeSupported) { - window.alert("This browser does not support high dynamic range."); - } + if (!viewer.scene.highDynamicRangeSupported) { + window.alert("This browser does not support high dynamic range."); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -1915097.7863741855, - -4783356.851539908, - 3748887.43462683 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.166004548388564, - -0.043242401760068994, - 0.002179961955988574 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -1915097.7863741855, + -4783356.851539908, + 3748887.43462683 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.166004548388564, + -0.043242401760068994, + 0.002179961955988574 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.highDynamicRange = true; + viewer.scene.highDynamicRange = true; - Sandcastle.addToggleButton("HDR", true, function (checked) { - viewer.scene.highDynamicRange = checked; - }); + Sandcastle.addToggleButton("HDR", true, function (checked) { + viewer.scene.highDynamicRange = checked; + }); - const url = - "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; - const position = Cesium.Cartesian3.fromRadians( - -1.9516424279517286, - 0.6322397098422969, - 1239.0006814631095 - ); - const heading = Cesium.Math.toRadians(-15.0); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const scale = 10.0; + const url = + "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; + const position = Cesium.Cartesian3.fromRadians( + -1.9516424279517286, + 0.6322397098422969, + 1239.0006814631095 + ); + const heading = Cesium.Math.toRadians(-15.0); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const scale = 10.0; - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: scale, - }, - }); - })(); //Sandcastle_End + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: scale, + }, + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 20cf6b8bf87..52d15402f4a 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -35,129 +35,128 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "San Francisco": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["San Francisco"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "San Francisco": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["San Francisco"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if ( - !Cesium.defined(name) && - isNameProperty(fieldName) - ) { - name = fields[fieldName]; - } + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if (!Cesium.defined(name) && isNameProperty(fieldName)) { + name = fields[fieldName]; } } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); - } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; + } + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; - } - return false; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; } - })(); //Sandcastle_End + return false; + } //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index cebdb348a20..10052a04dbf 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -35,129 +35,128 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "New York": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["New York"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "New York": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["New York"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if ( - !Cesium.defined(name) && - isNameProperty(fieldName) - ) { - name = fields[fieldName]; - } + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if (!Cesium.defined(name) && isNameProperty(fieldName)) { + name = fields[fieldName]; } } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); - } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; + } + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; - } - return false; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; } - })(); //Sandcastle_End + return false; + } //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 67740dbba17..305d18ae14a 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -35,61 +35,63 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); - // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry - viewer.scene.globe.depthTestAgainstTerrain = false; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); + // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry + viewer.scene.globe.depthTestAgainstTerrain = false; - // More datasets to tour can be added here.. - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - Frankfurt: - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); + // More datasets to tour can be added here.. + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + Frankfurt: + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours.Frankfurt, - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours.Frankfurt, + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); - })(); //Sandcastle_End + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/Image-Based Lighting.html b/Apps/Sandcastle/gallery/Image-Based Lighting.html index b3d86ab57a1..2373af5bf4a 100644 --- a/Apps/Sandcastle/gallery/Image-Based Lighting.html +++ b/Apps/Sandcastle/gallery/Image-Based Lighting.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -211,7 +211,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Adjustment.html b/Apps/Sandcastle/gallery/Imagery Adjustment.html index 8bbad64dee0..85c0ef7d7b5 100644 --- a/Apps/Sandcastle/gallery/Imagery Adjustment.html +++ b/Apps/Sandcastle/gallery/Imagery Adjustment.html @@ -112,7 +112,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -170,7 +170,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html index a67c9850665..1f8f2a00ac5 100644 --- a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html +++ b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -97,7 +97,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Cutout.html b/Apps/Sandcastle/gallery/Imagery Cutout.html index 0b2164e24f9..42f6849d594 100644 --- a/Apps/Sandcastle/gallery/Imagery Cutout.html +++ b/Apps/Sandcastle/gallery/Imagery Cutout.html @@ -46,7 +46,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -186,7 +186,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html index 80b2ccff9b0..2543e34d8d0 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html @@ -104,7 +104,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -329,7 +329,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Split.html b/Apps/Sandcastle/gallery/Imagery Layers Split.html index 5ea11e8c89c..8a05cdf5c3f 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Split.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Split.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -115,7 +115,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html index f0103e83eaa..23c723f7286 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -120,7 +120,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers.html b/Apps/Sandcastle/gallery/Imagery Layers.html index e439295682c..29bdf0e9148 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers.html +++ b/Apps/Sandcastle/gallery/Imagery Layers.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index 5c85423b399..c5fb3897f13 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -34,23 +34,16 @@ <div id="interpolationMenu"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, //Disable InfoBox widget selectionIndicator: false, //Disable selection indicator shouldAnimate: true, // Enable animations + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - //Enable lighting based on the sun position viewer.scene.globe.enableLighting = true; @@ -211,7 +204,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML Tours.html b/Apps/Sandcastle/gallery/KML Tours.html index 8b2d6d51e06..9a8a065f6ea 100644 --- a/Apps/Sandcastle/gallery/KML Tours.html +++ b/Apps/Sandcastle/gallery/KML Tours.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -81,7 +81,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML.html b/Apps/Sandcastle/gallery/KML.html index b2d1ef68b40..1c61653e0a6 100644 --- a/Apps/Sandcastle/gallery/KML.html +++ b/Apps/Sandcastle/gallery/KML.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -102,7 +102,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Labels.html b/Apps/Sandcastle/gallery/Labels.html index ccb621e2fda..dc6f65433af 100644 --- a/Apps/Sandcastle/gallery/Labels.html +++ b/Apps/Sandcastle/gallery/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -272,7 +272,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/LensFlare.html b/Apps/Sandcastle/gallery/LensFlare.html index c081194cd14..97fb4a52785 100644 --- a/Apps/Sandcastle/gallery/LensFlare.html +++ b/Apps/Sandcastle/gallery/LensFlare.html @@ -101,7 +101,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -172,7 +172,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index 38cc8b0ee9c..4b759cce2de 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -29,24 +29,18 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); const scene = viewer.scene; scene.globe.enableLighting = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); - const scratchIcrfToFixed = new Cesium.Matrix3(); const scratchMoonPosition = new Cesium.Cartesian3(); const scratchMoonDirection = new Cesium.Cartesian3(); @@ -236,7 +230,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 77761084409..3fed0aaf87a 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -62,7 +62,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -278,7 +278,11 @@ <h1>Loading...</h1> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index dd21568c7bb..dc532f40c75 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -29,23 +29,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { contextOptions: { requestWebgl1: false, }, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2022-08-01T00:00:00Z" ); @@ -187,7 +180,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Manually Controlled Animation.html b/Apps/Sandcastle/gallery/Manually Controlled Animation.html index 4eda60808f5..c93b14eb6cb 100644 --- a/Apps/Sandcastle/gallery/Manually Controlled Animation.html +++ b/Apps/Sandcastle/gallery/Manually Controlled Animation.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -160,7 +160,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Map Pins.html b/Apps/Sandcastle/gallery/Map Pins.html index cc92aea49ca..5a5e8fecf57 100644 --- a/Apps/Sandcastle/gallery/Map Pins.html +++ b/Apps/Sandcastle/gallery/Map Pins.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -97,7 +97,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index f6815a30fc0..85c50917828 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin let rectangle; @@ -625,7 +625,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index ac71f6fb445..d2feabfc90c 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -83,18 +83,12 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. const tileset = viewer.scene.primitives.add( @@ -433,7 +427,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multi-part CZML.html b/Apps/Sandcastle/gallery/Multi-part CZML.html index c5f9823e327..75f97dbe17b 100644 --- a/Apps/Sandcastle/gallery/Multi-part CZML.html +++ b/Apps/Sandcastle/gallery/Multi-part CZML.html @@ -36,7 +36,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -174,7 +174,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multiple Synced Views.html b/Apps/Sandcastle/gallery/Multiple Synced Views.html index 48fc895f15d..e7502566cb7 100644 --- a/Apps/Sandcastle/gallery/Multiple Synced Views.html +++ b/Apps/Sandcastle/gallery/Multiple Synced Views.html @@ -48,7 +48,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // We want our two views to be synced across time, so we create @@ -124,7 +124,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Natural Earth II.html b/Apps/Sandcastle/gallery/Natural Earth II.html index 9e93c6ee30f..22d2a482f6c 100644 --- a/Apps/Sandcastle/gallery/Natural Earth II.html +++ b/Apps/Sandcastle/gallery/Natural Earth II.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Natural Earth II with Shaded Relief, Water, and Drainages from http://www.naturalearthdata.com @@ -44,7 +44,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Offline.html b/Apps/Sandcastle/gallery/Offline.html index 3f16e831458..6cc44971b78 100644 --- a/Apps/Sandcastle/gallery/Offline.html +++ b/Apps/Sandcastle/gallery/Offline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // This is an example of using Cesium "Offline", meaning disconnected from the @@ -52,7 +52,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index ca33b2cb9af..89d228bd397 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -32,22 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) - // http://www.pasda.psu.edu/ - viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) - ); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) + // http://www.pasda.psu.edu/ + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3957) + ), + }); // Add PA locations Sandcastle.addDefaultToolbarMenu( @@ -145,7 +139,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Parallels and Meridians.html b/Apps/Sandcastle/gallery/Parallels and Meridians.html index ef643aea418..34a030ac97c 100644 --- a/Apps/Sandcastle/gallery/Parallels and Meridians.html +++ b/Apps/Sandcastle/gallery/Parallels and Meridians.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -315,7 +315,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Partial Ellipsoids.html b/Apps/Sandcastle/gallery/Partial Ellipsoids.html index ee2c0507e63..486ecc790d3 100644 --- a/Apps/Sandcastle/gallery/Partial Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Partial Ellipsoids.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -218,7 +218,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Fireworks.html b/Apps/Sandcastle/gallery/Particle System Fireworks.html index 394ec79af33..d93d8a0b526 100644 --- a/Apps/Sandcastle/gallery/Particle System Fireworks.html +++ b/Apps/Sandcastle/gallery/Particle System Fireworks.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -216,7 +216,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Tails.html b/Apps/Sandcastle/gallery/Particle System Tails.html index 460e1d34123..532e8b25534 100644 --- a/Apps/Sandcastle/gallery/Particle System Tails.html +++ b/Apps/Sandcastle/gallery/Particle System Tails.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -301,7 +301,11 @@ if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index 00602ce0216..10d17b9fe9e 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -32,23 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const resetCameraFunction = function () { scene.camera.setView({ destination: new Cesium.Cartesian3( @@ -214,7 +207,11 @@ if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System.html b/Apps/Sandcastle/gallery/Particle System.html index ee7a74cd7ed..31c140e4c84 100644 --- a/Apps/Sandcastle/gallery/Particle System.html +++ b/Apps/Sandcastle/gallery/Particle System.html @@ -184,7 +184,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -464,7 +464,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html index aa0ae29f9f1..04d565700b7 100644 --- a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html +++ b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -115,7 +115,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index 88174baecdb..2053d9277ff 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const clock = new Cesium.Clock({ @@ -48,16 +48,9 @@ const viewer = new Cesium.Viewer("cesiumContainer", { clockViewModel: new Cesium.ClockViewModel(clock), selectionIndicator: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( checked ) { @@ -203,7 +196,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Picking.html b/Apps/Sandcastle/gallery/Picking.html index 19756c17f4d..c9f020738ff 100644 --- a/Apps/Sandcastle/gallery/Picking.html +++ b/Apps/Sandcastle/gallery/Picking.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -285,7 +285,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Plane.html b/Apps/Sandcastle/gallery/Plane.html index 0d8572df798..10e384b04f2 100644 --- a/Apps/Sandcastle/gallery/Plane.html +++ b/Apps/Sandcastle/gallery/Plane.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -74,7 +74,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Points.html b/Apps/Sandcastle/gallery/Points.html index 65068c79586..f331ae9571c 100644 --- a/Apps/Sandcastle/gallery/Points.html +++ b/Apps/Sandcastle/gallery/Points.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -190,7 +190,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polygon.html b/Apps/Sandcastle/gallery/Polygon.html index e275ab7416a..22d3ab1ce1e 100644 --- a/Apps/Sandcastle/gallery/Polygon.html +++ b/Apps/Sandcastle/gallery/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -310,7 +310,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Dash.html b/Apps/Sandcastle/gallery/Polyline Dash.html index 10143d01cba..3a7f51ae46c 100644 --- a/Apps/Sandcastle/gallery/Polyline Dash.html +++ b/Apps/Sandcastle/gallery/Polyline Dash.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Volume.html b/Apps/Sandcastle/gallery/Polyline Volume.html index f84d3fc48d5..58a248c9240 100644 --- a/Apps/Sandcastle/gallery/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline.html b/Apps/Sandcastle/gallery/Polyline.html index 9a61abfa196..4231f442c9d 100644 --- a/Apps/Sandcastle/gallery/Polyline.html +++ b/Apps/Sandcastle/gallery/Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html index 9ce5117991f..12047e59746 100644 --- a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -187,7 +187,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Post Processing.html b/Apps/Sandcastle/gallery/Post Processing.html index c46168a33d1..1da345d7ece 100644 --- a/Apps/Sandcastle/gallery/Post Processing.html +++ b/Apps/Sandcastle/gallery/Post Processing.html @@ -77,7 +77,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -156,7 +156,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Procedural Terrain.html b/Apps/Sandcastle/gallery/Procedural Terrain.html index 5812bdb4928..0a9f70ffc1b 100644 --- a/Apps/Sandcastle/gallery/Procedural Terrain.html +++ b/Apps/Sandcastle/gallery/Procedural Terrain.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -167,7 +167,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Projection.html b/Apps/Sandcastle/gallery/Projection.html index 214d3d04385..f2e5dc4b963 100644 --- a/Apps/Sandcastle/gallery/Projection.html +++ b/Apps/Sandcastle/gallery/Projection.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Click the projection picker to switch between orthographic and perspective projections. @@ -73,7 +73,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rectangle.html b/Apps/Sandcastle/gallery/Rectangle.html index 17df5070eef..b2b95834db1 100644 --- a/Apps/Sandcastle/gallery/Rectangle.html +++ b/Apps/Sandcastle/gallery/Rectangle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -92,7 +92,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Resolution Scaling.html b/Apps/Sandcastle/gallery/Resolution Scaling.html index ef9d6bb7bc0..3d888e60f2d 100644 --- a/Apps/Sandcastle/gallery/Resolution Scaling.html +++ b/Apps/Sandcastle/gallery/Resolution Scaling.html @@ -59,7 +59,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // When browser recommended resolution is enabled, the viewer renders at @@ -106,7 +106,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rotatable 2D Map.html b/Apps/Sandcastle/gallery/Rotatable 2D Map.html index e99ceead9c5..1c2b6dc30dc 100644 --- a/Apps/Sandcastle/gallery/Rotatable 2D Map.html +++ b/Apps/Sandcastle/gallery/Rotatable 2D Map.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -51,7 +51,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index 7ea5c50956e..f396cb09286 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -32,20 +32,14 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - if (!scene.clampToHeightSupported) { window.alert( "This browser does not support clampToHeightMostDetailed." @@ -135,7 +129,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index a2be63b6796..f5834c0a62b 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -138,7 +138,7 @@ <h4>Max delta time</h4> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create a viewer that won't render a new frame unless @@ -146,16 +146,9 @@ <h4>Max delta time</h4> const viewer = new Cesium.Viewer("cesiumContainer", { requestRenderMode: true, maximumRenderTimeChange: Infinity, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const scene = viewer.scene; scene.debugShowFramesPerSecond = true; @@ -360,7 +353,11 @@ <h4>Max delta time</h4> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sentinel-2.html b/Apps/Sandcastle/gallery/Sentinel-2.html index 2af73b5912e..ff28abd86b5 100644 --- a/Apps/Sandcastle/gallery/Sentinel-2.html +++ b/Apps/Sandcastle/gallery/Sentinel-2.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Sentinel-2 (mostly) cloudless global imagery between 10 and 60 meter resolution. @@ -44,7 +44,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 2f45dff2724..0835e725e7d 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -41,16 +41,9 @@ shadows: true, terrainShadows: Cesium.ShadowMode.ENABLED, shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const shadowMap = viewer.shadowMap; shadowMap.maximumDistance = 10000.0; @@ -310,7 +303,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Show or Hide Entities.html b/Apps/Sandcastle/gallery/Show or Hide Entities.html index 0a970559a77..4cfef9d98d6 100644 --- a/Apps/Sandcastle/gallery/Show or Hide Entities.html +++ b/Apps/Sandcastle/gallery/Show or Hide Entities.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin //Set the random seed for reproducible random colors. @@ -92,7 +92,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html index 13dd56c02c8..f5852df28f8 100644 --- a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -73,7 +73,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Star Burst.html b/Apps/Sandcastle/gallery/Star Burst.html index bc998f384fd..85b8cc3147b 100644 --- a/Apps/Sandcastle/gallery/Star Burst.html +++ b/Apps/Sandcastle/gallery/Star Burst.html @@ -31,7 +31,7 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -412,7 +412,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index 31a3e5a8740..12df605a50d 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -58,363 +58,356 @@ Edge styling enabled </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // Use clipping planes to selectively hide parts of the globe surface. - const viewer = new Cesium.Viewer("cesiumContainer", { - skyAtmosphere: false, - shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - scene3DOnly: true, - }); - const globe = viewer.scene.globe; + // Use clipping planes to selectively hide parts of the globe surface. + const viewer = new Cesium.Viewer("cesiumContainer", { + skyAtmosphere: false, + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + scene3DOnly: true, + }); + const globe = viewer.scene.globe; - const exampleTypes = [ - "Cesium Man", - "St. Helens", - "Grand Canyon Isolated", - ]; - const viewModel = { - exampleTypes: exampleTypes, - currentExampleType: exampleTypes[0], - clippingPlanesEnabled: true, - edgeStylingEnabled: true, - }; - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); + const exampleTypes = [ + "Cesium Man", + "St. Helens", + "Grand Canyon Isolated", + ]; + const viewModel = { + exampleTypes: exampleTypes, + currentExampleType: exampleTypes[0], + clippingPlanesEnabled: true, + edgeStylingEnabled: true, + }; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); - // For tracking state when switching exampleTypes - let clippingPlanesEnabled = true; - let edgeStylingEnabled = true; + // For tracking state when switching exampleTypes + let clippingPlanesEnabled = true; + let edgeStylingEnabled = true; - let tileset; + let tileset; - loadCesiumMan(); + loadCesiumMan(); - function reset() { - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - } + function reset() { + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + } - function loadCesiumMan() { - const position = Cesium.Cartesian3.fromRadians( - -2.0862979473351286, - 0.6586620013036164, - 1400.0 - ); + function loadCesiumMan() { + const position = Cesium.Cartesian3.fromRadians( + -2.0862979473351286, + 0.6586620013036164, + 1400.0 + ); - const entity = viewer.entities.add({ - position: position, - box: { - dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), - material: Cesium.Color.WHITE.withAlpha(0.3), - outline: true, - outlineColor: Cesium.Color.WHITE, - }, - }); - - viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - maximumScale: 800, - }, - }); - - globe.depthTestAgainstTerrain = true; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - -700.0 - ), - ], - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; + const entity = viewer.entities.add({ + position: position, + box: { + dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), + material: Cesium.Color.WHITE.withAlpha(0.3), + outline: true, + outlineColor: Cesium.Color.WHITE, + }, + }); - viewer.trackedEntity = entity; - } + viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + maximumScale: 800, + }, + }); - function loadStHelens() { - // Create clipping planes for polygon around area to be clipped. - const points = [ - new Cesium.Cartesian3( - -2358434.3501556474, - -3743554.5012105294, - 4581080.771684084 - ), - new Cesium.Cartesian3( - -2357886.4482675144, - -3744467.562778789, - 4581020.9199767085 - ), - new Cesium.Cartesian3( - -2357299.84353055, - -3744954.0879047974, - 4581080.992360969 - ), - new Cesium.Cartesian3( - -2356412.05169956, - -3745385.3013702347, - 4580893.4737207815 - ), - new Cesium.Cartesian3( - -2355472.889436636, - -3745256.5725702164, - 4581252.3128526565 - ), - new Cesium.Cartesian3( - -2354385.7458722834, - -3744319.3823686405, - 4582372.770031389 - ), - new Cesium.Cartesian3( - -2353758.788158616, - -3743051.0128084184, - 4583356.453176038 + globe.depthTestAgainstTerrain = true; + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2353663.8128999653, - -3741847.9126874236, - 4584079.428665509 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2354213.667592133, - -3740784.50946316, - 4584502.428203525 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2355596.239450013, - -3739901.0226732804, - 4584515.9652557485 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2356942.4170108805, - -3740342.454698685, - 4583686.690694482 - ), - new Cesium.Cartesian3( - -2357529.554838029, - -3740766.995076834, - 4583145.055348843 - ), - new Cesium.Cartesian3( - -2358106.017822064, - -3741439.438418052, - 4582452.293605261 - ), - new Cesium.Cartesian3( - -2358539.5426236596, - -3742680.720902901, - 4581692.0260975715 - ), - ]; - - const pointsLength = points.length; + ], + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - // Create center points for each clipping plane - const clippingPlanes = []; - for (let i = 0; i < pointsLength; ++i) { - const nextIndex = (i + 1) % pointsLength; - let midpoint = Cesium.Cartesian3.add( - points[i], - points[nextIndex], - new Cesium.Cartesian3() - ); - midpoint = Cesium.Cartesian3.multiplyByScalar( - midpoint, - 0.5, - midpoint - ); + viewer.trackedEntity = entity; + } - const up = Cesium.Cartesian3.normalize( - midpoint, - new Cesium.Cartesian3() - ); - let right = Cesium.Cartesian3.subtract( - points[nextIndex], - midpoint, - new Cesium.Cartesian3() - ); - right = Cesium.Cartesian3.normalize(right, right); + function loadStHelens() { + // Create clipping planes for polygon around area to be clipped. + const points = [ + new Cesium.Cartesian3( + -2358434.3501556474, + -3743554.5012105294, + 4581080.771684084 + ), + new Cesium.Cartesian3( + -2357886.4482675144, + -3744467.562778789, + 4581020.9199767085 + ), + new Cesium.Cartesian3( + -2357299.84353055, + -3744954.0879047974, + 4581080.992360969 + ), + new Cesium.Cartesian3( + -2356412.05169956, + -3745385.3013702347, + 4580893.4737207815 + ), + new Cesium.Cartesian3( + -2355472.889436636, + -3745256.5725702164, + 4581252.3128526565 + ), + new Cesium.Cartesian3( + -2354385.7458722834, + -3744319.3823686405, + 4582372.770031389 + ), + new Cesium.Cartesian3( + -2353758.788158616, + -3743051.0128084184, + 4583356.453176038 + ), + new Cesium.Cartesian3( + -2353663.8128999653, + -3741847.9126874236, + 4584079.428665509 + ), + new Cesium.Cartesian3( + -2354213.667592133, + -3740784.50946316, + 4584502.428203525 + ), + new Cesium.Cartesian3( + -2355596.239450013, + -3739901.0226732804, + 4584515.9652557485 + ), + new Cesium.Cartesian3( + -2356942.4170108805, + -3740342.454698685, + 4583686.690694482 + ), + new Cesium.Cartesian3( + -2357529.554838029, + -3740766.995076834, + 4583145.055348843 + ), + new Cesium.Cartesian3( + -2358106.017822064, + -3741439.438418052, + 4582452.293605261 + ), + new Cesium.Cartesian3( + -2358539.5426236596, + -3742680.720902901, + 4581692.0260975715 + ), + ]; - let normal = Cesium.Cartesian3.cross( - right, - up, - new Cesium.Cartesian3() - ); - normal = Cesium.Cartesian3.normalize(normal, normal); + const pointsLength = points.length; - // Compute distance by pretending the plane is at the origin - const originCenteredPlane = new Cesium.Plane(normal, 0.0); - const distance = Cesium.Plane.getPointDistance( - originCenteredPlane, - midpoint - ); + // Create center points for each clipping plane + const clippingPlanes = []; + for (let i = 0; i < pointsLength; ++i) { + const nextIndex = (i + 1) % pointsLength; + let midpoint = Cesium.Cartesian3.add( + points[i], + points[nextIndex], + new Cesium.Cartesian3() + ); + midpoint = Cesium.Cartesian3.multiplyByScalar( + midpoint, + 0.5, + midpoint + ); - clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); - } - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - planes: clippingPlanes, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; + const up = Cesium.Cartesian3.normalize( + midpoint, + new Cesium.Cartesian3() + ); + let right = Cesium.Cartesian3.subtract( + points[nextIndex], + midpoint, + new Cesium.Cartesian3() + ); + right = Cesium.Cartesian3.normalize(right, right); - // Load tileset - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - return tileset.readyPromise - .then(function () { - // Adjust height so tileset is in terrain - const cartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - -20.0 - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation( - translation - ); + let normal = Cesium.Cartesian3.cross( + right, + up, + new Cesium.Cartesian3() + ); + normal = Cesium.Cartesian3.normalize(normal, normal); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgb(207, 255, 207)", - }); + // Compute distance by pretending the plane is at the origin + const originCenteredPlane = new Cesium.Plane(normal, 0.0); + const distance = Cesium.Plane.getPointDistance( + originCenteredPlane, + midpoint + ); - viewer.scene.primitives.add(tileset); + clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); + } + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + planes: clippingPlanes, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - const boundingSphere = tileset.boundingSphere; + // Load tileset + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + return tileset.readyPromise + .then(function () { + // Adjust height so tileset is in terrain + const cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + -20.0 + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgb(207, 255, 207)", }); - } - function loadGrandCanyon() { - // Pick a position at the Grand Canyon - const position = Cesium.Cartographic.toCartesian( - new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) - ); - const distance = 3000.0; - const boundingSphere = new Cesium.BoundingSphere( - position, - distance - ); + viewer.scene.primitives.add(tileset); + + const boundingSphere = tileset.boundingSphere; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - distance - ), - ], - unionClippingRegions: true, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }) + .catch(function (error) { + throw error; }); - globe.backFaceCulling = false; - globe.showSkirts = false; + } - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange( - 0.5, - -0.5, - boundingSphere.radius * 5.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + function loadGrandCanyon() { + // Pick a position at the Grand Canyon + const position = Cesium.Cartographic.toCartesian( + new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) + ); + const distance = 3000.0; + const boundingSphere = new Cesium.BoundingSphere(position, distance); - Cesium.knockout - .getObservable(viewModel, "clippingPlanesEnabled") - .subscribe(function (value) { - globe.clippingPlanes.enabled = value; - clippingPlanesEnabled = value; - }); + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + distance + ), + ], + unionClippingRegions: true, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = false; + globe.showSkirts = false; - Cesium.knockout - .getObservable(viewModel, "edgeStylingEnabled") - .subscribe(function (value) { - edgeStylingEnabled = value; - globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; - }); + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === exampleTypes[0]) { - loadCesiumMan(); - } else if (newValue === exampleTypes[1]) { - loadStHelens(); - } else if (newValue === exampleTypes[2]) { - loadGrandCanyon(); - } - }); - })(); //Sandcastle_End + Cesium.knockout + .getObservable(viewModel, "clippingPlanesEnabled") + .subscribe(function (value) { + globe.clippingPlanes.enabled = value; + clippingPlanesEnabled = value; + }); + + Cesium.knockout + .getObservable(viewModel, "edgeStylingEnabled") + .subscribe(function (value) { + edgeStylingEnabled = value; + globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; + }); + + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === exampleTypes[0]) { + loadCesiumMan(); + } else if (newValue === exampleTypes[1]) { + loadStHelens(); + } else if (newValue === exampleTypes[2]) { + loadGrandCanyon(); + } + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index b850b26fa29..21e990af927 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -73,18 +73,12 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const globe = scene.globe; @@ -202,7 +196,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index f1e50500145..594bfecd7c3 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -36,21 +36,15 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); // set lighting to true viewer.scene.globe.enableLighting = true; @@ -348,7 +342,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html index e24fa0d05ab..a70d68ce8ce 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -98,7 +98,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html index 06875313330..67183196b03 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -164,7 +164,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Underground Color.html b/Apps/Sandcastle/gallery/Underground Color.html index 8365de68ee2..d613c3f7a68 100644 --- a/Apps/Sandcastle/gallery/Underground Color.html +++ b/Apps/Sandcastle/gallery/Underground Color.html @@ -108,7 +108,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -223,7 +223,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Video.html b/Apps/Sandcastle/gallery/Video.html index 7aae2fc83d5..80f821680a6 100644 --- a/Apps/Sandcastle/gallery/Video.html +++ b/Apps/Sandcastle/gallery/Video.html @@ -54,7 +54,7 @@ Your browser does not support the <code>video</code> element. </video> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -149,7 +149,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Wall.html b/Apps/Sandcastle/gallery/Wall.html index cae9bcbfa0e..a9657fc6012 100644 --- a/Apps/Sandcastle/gallery/Wall.html +++ b/Apps/Sandcastle/gallery/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -139,7 +139,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Washington DC 2017.html b/Apps/Sandcastle/gallery/Washington DC 2017.html index 8423c0500b9..7b12ae52697 100644 --- a/Apps/Sandcastle/gallery/Washington DC 2017.html +++ b/Apps/Sandcastle/gallery/Washington DC 2017.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // 3 inch (0.08m) resolution imagery of Washington DC collected in 2017 @@ -47,7 +47,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Service (WMS).html b/Apps/Sandcastle/gallery/Web Map Service (WMS).html index 4f40bb976dd..c5c840e7304 100644 --- a/Apps/Sandcastle/gallery/Web Map Service (WMS).html +++ b/Apps/Sandcastle/gallery/Web Map Service (WMS).html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html index d9459c56ed5..65577b66c7d 100644 --- a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html +++ b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -98,7 +98,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html index 6a6ef173d75..142a89d16da 100644 --- a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html +++ b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -145,7 +145,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Articulations.html b/Apps/Sandcastle/gallery/development/3D Models Articulations.html index 45167af0546..fe0e56fdf4c 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Articulations.html +++ b/Apps/Sandcastle/gallery/development/3D Models Articulations.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -186,7 +186,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html index 6a04aad8b4a..0839cb27f7a 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html +++ b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html @@ -189,7 +189,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -373,7 +373,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models.html b/Apps/Sandcastle/gallery/development/3D Models.html index 8cfd8dd20d7..0b8f9fb4da7 100644 --- a/Apps/Sandcastle/gallery/development/3D Models.html +++ b/Apps/Sandcastle/gallery/development/3D Models.html @@ -90,7 +90,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -309,7 +309,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html index f7622c5f4de..ebada4cc901 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /* @@ -266,7 +266,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Split.html b/Apps/Sandcastle/gallery/development/3D Tiles Split.html index 2d96e548c97..b94905a7200 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Split.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Split.html @@ -57,7 +57,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -287,7 +287,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 2ee1b79cbc6..07751bff1ae 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -34,20 +34,14 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const ellipsoid = viewer.scene.globe.ellipsoid; const billboardCollection = viewer.scene.primitives.add( new Cesium.BillboardCollection({ @@ -173,7 +167,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index 00861a900fa..930719ba457 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -34,18 +34,12 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const context = scene.context; @@ -237,7 +231,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards.html b/Apps/Sandcastle/gallery/development/Billboards.html index 21d2f91c95e..c175f593235 100644 --- a/Apps/Sandcastle/gallery/development/Billboards.html +++ b/Apps/Sandcastle/gallery/development/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -427,7 +427,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box Outline.html b/Apps/Sandcastle/gallery/development/Box Outline.html index 31747ce8366..19c2c40d95d 100644 --- a/Apps/Sandcastle/gallery/development/Box Outline.html +++ b/Apps/Sandcastle/gallery/development/Box Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -84,7 +84,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box.html b/Apps/Sandcastle/gallery/development/Box.html index 442fc703307..8d9484ffb43 100644 --- a/Apps/Sandcastle/gallery/development/Box.html +++ b/Apps/Sandcastle/gallery/development/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -78,7 +78,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle Outline.html b/Apps/Sandcastle/gallery/development/Circle Outline.html index c31e527b256..59df803fcb3 100644 --- a/Apps/Sandcastle/gallery/development/Circle Outline.html +++ b/Apps/Sandcastle/gallery/development/Circle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -103,7 +103,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle.html b/Apps/Sandcastle/gallery/development/Circle.html index 0a6e4395712..a056d327cb1 100644 --- a/Apps/Sandcastle/gallery/development/Circle.html +++ b/Apps/Sandcastle/gallery/development/Circle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -134,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html index 65189eb90ee..4045af73867 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -140,7 +140,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html index f88679c18cf..f03639448db 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -174,7 +174,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor Outline.html b/Apps/Sandcastle/gallery/development/Corridor Outline.html index 0102e56700c..750f89e3502 100644 --- a/Apps/Sandcastle/gallery/development/Corridor Outline.html +++ b/Apps/Sandcastle/gallery/development/Corridor Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -102,7 +102,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor.html b/Apps/Sandcastle/gallery/development/Corridor.html index 3be94a10825..e9ecfa088a5 100644 --- a/Apps/Sandcastle/gallery/development/Corridor.html +++ b/Apps/Sandcastle/gallery/development/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer @@ -158,7 +158,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Custom Primitive.html b/Apps/Sandcastle/gallery/development/Custom Primitive.html index 335fb1f214c..fb1c79983cf 100644 --- a/Apps/Sandcastle/gallery/development/Custom Primitive.html +++ b/Apps/Sandcastle/gallery/development/Custom Primitive.html @@ -37,7 +37,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -328,7 +328,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder Outline.html b/Apps/Sandcastle/gallery/development/Cylinder Outline.html index 4a1b698cd67..31cadcf70f9 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder Outline.html +++ b/Apps/Sandcastle/gallery/development/Cylinder Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -83,7 +83,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder.html b/Apps/Sandcastle/gallery/development/Cylinder.html index d6c2e7c4dce..bc644cc7c45 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder.html +++ b/Apps/Sandcastle/gallery/development/Cylinder.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -112,7 +112,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Display Conditions.html b/Apps/Sandcastle/gallery/development/Display Conditions.html index dbf4b1cc881..52d5fe5b2c1 100644 --- a/Apps/Sandcastle/gallery/development/Display Conditions.html +++ b/Apps/Sandcastle/gallery/development/Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -133,7 +133,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse Outline.html b/Apps/Sandcastle/gallery/development/Ellipse Outline.html index 3f129932c8e..0a8d1af1784 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipse Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -100,7 +100,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse.html b/Apps/Sandcastle/gallery/development/Ellipse.html index 5baa25dad20..07b4284314f 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse.html +++ b/Apps/Sandcastle/gallery/development/Ellipse.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -124,7 +124,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html index f31a39aecdc..0bae3b4c016 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -80,7 +80,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html index 74e834b6ddc..a1764183ba7 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -126,7 +126,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid.html b/Apps/Sandcastle/gallery/development/Ellipsoid.html index ee5d71f4f9a..7497ad56a22 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,7 +79,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 58e3a370260..4361adadab8 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -47,18 +47,12 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -148,7 +142,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index 8dba93dd07f..f57297e1450 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -117,7 +117,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html index 216ff9d59d8..60d96361eb1 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -290,7 +290,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html index 4f3d5741196..c1bac66e74f 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -267,7 +267,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html index 407000421de..9434cb35d2f 100644 --- a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -1282,7 +1282,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html index f3dd165d83f..b9600e634cc 100644 --- a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html @@ -32,98 +32,100 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); - } - - // Polyline Glow - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1955, - -122.1058, - 46.1955, - ]), - width: 10.0, - }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineGlowType - ), - }), - }) + if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." ); + } - // Polyline Dash - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1975, - -122.1058, - 46.1975, - ]), - width: 10.0, - }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineDashType - ), + // Polyline Glow + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1955, + -122.1058, + 46.1955, + ]), + width: 10.0, }), - }) - ); + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineGlowType + ), + }), + }) + ); - // Polyline Outline - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1995, - -122.1058, - 46.1995, - ]), - width: 10.0, - }), + // Polyline Dash + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1975, + -122.1058, + 46.1975, + ]), + width: 10.0, }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineOutlineType - ), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineDashType + ), + }), + }) + ); + + // Polyline Outline + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1995, + -122.1058, + 46.1995, + ]), + width: 10.0, }), - }) - ); + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineOutlineType + ), + }), + }) + ); - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - })(); //Sandcastle_End + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index ed527e23634..1a50b20e624 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -32,21 +32,15 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { window.alert( @@ -558,7 +552,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index dfdebecdf7a..91416960959 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -32,18 +32,12 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -506,7 +500,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Labels.html b/Apps/Sandcastle/gallery/development/Labels.html index a7ef679f397..819dc2b71cf 100644 --- a/Apps/Sandcastle/gallery/development/Labels.html +++ b/Apps/Sandcastle/gallery/development/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -220,7 +220,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 4637910a494..25bdf20a5f0 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -64,274 +64,276 @@ ></select> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shouldAnimate: true, - projectionPicker: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shouldAnimate: true, + projectionPicker: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const globe = viewer.scene.globe; - globe.depthTestAgainstTerrain = true; + const globe = viewer.scene.globe; + globe.depthTestAgainstTerrain = true; - let cylinderRadius = -20.0; - let radiusMultiplier = 1.0; + let cylinderRadius = -20.0; + let radiusMultiplier = 1.0; - let steps = 32; - let clippingPlanes = []; - let modelEntityClippingPlanes; - let clippingModeUnion = false; - let enabled = true; + let steps = 32; + let clippingPlanes = []; + let modelEntityClippingPlanes; + let clippingModeUnion = false; + let enabled = true; - const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; - const viewModel = { - cylinderRadius: cylinderRadius, - exampleTypes: clipObjects, - currentExampleType: clipObjects[0], - planeCount: steps, - }; + const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; + const viewModel = { + cylinderRadius: cylinderRadius, + exampleTypes: clipObjects, + currentExampleType: clipObjects[0], + planeCount: steps, + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "cylinderRadius") - .subscribe(function (newValue) { - cylinderRadius = parseFloat(viewModel.cylinderRadius); - updatePlanes(); - }); + Cesium.knockout + .getObservable(viewModel, "cylinderRadius") + .subscribe(function (newValue) { + cylinderRadius = parseFloat(viewModel.cylinderRadius); + updatePlanes(); + }); - Cesium.knockout - .getObservable(viewModel, "planeCount") - .subscribe(function (newValue) { - const newSteps = parseFloat(viewModel.planeCount); - if (newSteps !== steps) { - steps = newSteps; - modelEntityClippingPlanes.removeAll(); - computePlanes(); - } - }); + Cesium.knockout + .getObservable(viewModel, "planeCount") + .subscribe(function (newValue) { + const newSteps = parseFloat(viewModel.planeCount); + if (newSteps !== steps) { + steps = newSteps; + modelEntityClippingPlanes.removeAll(); + computePlanes(); + } + }); - const scene = viewer.scene; - const planeEntities = []; - let selectedPlane; + const scene = viewer.scene; + const planeEntities = []; + let selectedPlane; - function updatePlanes() { - for (let i = 0; i < clippingPlanes.length; i++) { - const plane = clippingPlanes[i]; - plane.distance = cylinderRadius * radiusMultiplier; - } + function updatePlanes() { + for (let i = 0; i < clippingPlanes.length; i++) { + const plane = clippingPlanes[i]; + plane.distance = cylinderRadius * radiusMultiplier; } + } - function computePlanes() { - const stepDegrees = Cesium.Math.TWO_PI / steps; - clippingPlanes = []; + function computePlanes() { + const stepDegrees = Cesium.Math.TWO_PI / steps; + clippingPlanes = []; - for (let i = 0; i < steps; i++) { - const angle = i * stepDegrees; - const dir = new Cesium.Cartesian3(); + for (let i = 0; i < steps; i++) { + const angle = i * stepDegrees; + const dir = new Cesium.Cartesian3(); + dir.x = 1.0; + dir.y = Math.tan(angle); + if (angle > Cesium.Math.PI_OVER_TWO) { + dir.x = -1.0; + dir.y *= -1.0; + } + if (angle > Cesium.Math.PI) { + dir.x = -1.0; + } + if (angle > Cesium.Math.PI_OVER_TWO * 3) { dir.x = 1.0; - dir.y = Math.tan(angle); - if (angle > Cesium.Math.PI_OVER_TWO) { - dir.x = -1.0; - dir.y *= -1.0; - } - if (angle > Cesium.Math.PI) { - dir.x = -1.0; - } - if (angle > Cesium.Math.PI_OVER_TWO * 3) { - dir.x = 1.0; - dir.y = -dir.y; - } - Cesium.Cartesian3.normalize(dir, dir); - const newPlane = new Cesium.ClippingPlane( - dir, - cylinderRadius * radiusMultiplier - ); - modelEntityClippingPlanes.add(newPlane); - clippingPlanes.push(newPlane); + dir.y = -dir.y; } + Cesium.Cartesian3.normalize(dir, dir); + const newPlane = new Cesium.ClippingPlane( + dir, + cylinderRadius * radiusMultiplier + ); + modelEntityClippingPlanes.add(newPlane); + clippingPlanes.push(newPlane); } + } - function createClippingPlanes(modelMatrix) { - modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.defined(modelMatrix) - ? modelMatrix - : Cesium.Matrix4.IDENTITY, - edgeWidth: 2.0, - edgeColor: Cesium.Color.WHITE, - unionClippingRegions: clippingModeUnion, - enabled: enabled, - }); - computePlanes(); - } + function createClippingPlanes(modelMatrix) { + modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.defined(modelMatrix) + ? modelMatrix + : Cesium.Matrix4.IDENTITY, + edgeWidth: 2.0, + edgeColor: Cesium.Color.WHITE, + unionClippingRegions: clippingModeUnion, + enabled: enabled, + }); + computePlanes(); + } - function updateClippingPlanes() { - return modelEntityClippingPlanes; - } + function updateClippingPlanes() { + return modelEntityClippingPlanes; + } - const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; - const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); - const instancedUrl = - "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; - const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); + const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; + const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); + const instancedUrl = + "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; + const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); - function loadModel(url) { - createClippingPlanes(); - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 300.0 - ); - const heading = 0.0; - const pitch = 0.0; - const roll = 0.0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: 20, - minimumPixelSize: 100.0, - clippingPlanes: new Cesium.CallbackProperty( - updateClippingPlanes, - false - ), - }, - }); - viewer.trackedEntity = entity; - } + function loadModel(url) { + createClippingPlanes(); + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 300.0 + ); + const heading = 0.0; + const pitch = 0.0; + const roll = 0.0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: 20, + minimumPixelSize: 100.0, + clippingPlanes: new Cesium.CallbackProperty( + updateClippingPlanes, + false + ), + }, + }); + viewer.trackedEntity = entity; + } - let tileset; - async function loadTileset(url, height) { - createClippingPlanes(); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - clippingPlanes: modelEntityClippingPlanes, - enableDebugWireframe: true, - }) - ); + let tileset; + async function loadTileset(url, height) { + createClippingPlanes(); + tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: url, + clippingPlanes: modelEntityClippingPlanes, + enableDebugWireframe: true, + }) + ); - await tileset.readyPromise; - const boundingSphere = tileset.boundingSphere; + await tileset.readyPromise; + const boundingSphere = tileset.boundingSphere; - const cartographic = Cesium.Cartographic.fromCartesian( - boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - height - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + const cartographic = Cesium.Cartographic.fromCartesian( + boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - loadModel(modelUrl); + loadModel(modelUrl); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); - if (newValue === clipObjects[0]) { - // Model - loadModel(modelUrl); - } else if (newValue === clipObjects[1]) { - // B3dm photogrammetry - return loadTileset(agiHqUrl, 0.0); - } else if (newValue === clipObjects[2]) { - // Point clouds - radiusMultiplier = 20.0; - return loadTileset(pointCloudUrl, 0.0).then(function () { - tileset.pointCloudShading.attenuation = true; - }); - } else if (newValue === clipObjects[3]) { - // i3dm - loadTileset(instancedUrl, 100.0); - } else if (newValue === clipObjects[4]) { - // Terrain - const position = Cesium.Cartesian3.fromRadians( - // eslint-disable-next-line no-loss-of-precision - -2.0872979473351286, - 0.6596620013036164, - 2380.0 - ); - const entity = viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - scale: 40, - }, - }); - viewer.trackedEntity = entity; - createClippingPlanes( - entity.computeModelMatrix(Cesium.JulianDate.now()) - ); - globe.clippingPlanes = modelEntityClippingPlanes; - } - updatePlanes(); - }); + if (newValue === clipObjects[0]) { + // Model + loadModel(modelUrl); + } else if (newValue === clipObjects[1]) { + // B3dm photogrammetry + return loadTileset(agiHqUrl, 0.0); + } else if (newValue === clipObjects[2]) { + // Point clouds + radiusMultiplier = 20.0; + return loadTileset(pointCloudUrl, 0.0).then(function () { + tileset.pointCloudShading.attenuation = true; + }); + } else if (newValue === clipObjects[3]) { + // i3dm + loadTileset(instancedUrl, 100.0); + } else if (newValue === clipObjects[4]) { + // Terrain + const position = Cesium.Cartesian3.fromRadians( + // eslint-disable-next-line no-loss-of-precision + -2.0872979473351286, + 0.6596620013036164, + 2380.0 + ); + const entity = viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + scale: 40, + }, + }); + viewer.trackedEntity = entity; + createClippingPlanes( + entity.computeModelMatrix(Cesium.JulianDate.now()) + ); + globe.clippingPlanes = modelEntityClippingPlanes; + } + updatePlanes(); + }); - function reset() { - radiusMultiplier = 1.0; - viewModel.cylinderRadius = cylinderRadius; - viewer.entities.removeAll(); - viewer.scene.primitives.removeAll(); - globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any - modelEntityClippingPlanes = undefined; - } + function reset() { + radiusMultiplier = 1.0; + viewModel.cylinderRadius = cylinderRadius; + viewer.entities.removeAll(); + viewer.scene.primitives.removeAll(); + globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any + modelEntityClippingPlanes = undefined; + } - Sandcastle.addToggleButton("union", clippingModeUnion, function ( - checked - ) { - clippingModeUnion = checked; - modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; - }); + Sandcastle.addToggleButton("union", clippingModeUnion, function ( + checked + ) { + clippingModeUnion = checked; + modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; + }); - Sandcastle.addToggleButton("enabled", enabled, function (checked) { - enabled = checked; - modelEntityClippingPlanes.enabled = enabled; - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("enabled", enabled, function (checked) { + enabled = checked; + modelEntityClippingPlanes.enabled = enabled; + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Material.html b/Apps/Sandcastle/gallery/development/Material.html index 2f3789fe57c..0e8d00af43d 100644 --- a/Apps/Sandcastle/gallery/development/Material.html +++ b/Apps/Sandcastle/gallery/development/Material.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -91,7 +91,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index 492fed56efe..3779ce43690 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -38,7 +38,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -46,16 +46,9 @@ infoBox: false, selectionIndicator: false, timeline: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const scene = viewer.scene; const camera = scene.camera; @@ -147,7 +140,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Per Instance Color.html b/Apps/Sandcastle/gallery/development/Per Instance Color.html index 104de111419..4adbc365ee2 100644 --- a/Apps/Sandcastle/gallery/development/Per Instance Color.html +++ b/Apps/Sandcastle/gallery/development/Per Instance Color.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -69,7 +69,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Pick From Ray.html b/Apps/Sandcastle/gallery/development/Pick From Ray.html index e8c68eed20d..f39d5637e71 100644 --- a/Apps/Sandcastle/gallery/development/Pick From Ray.html +++ b/Apps/Sandcastle/gallery/development/Pick From Ray.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -194,7 +194,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Picking.html b/Apps/Sandcastle/gallery/development/Picking.html index 3b9fd338be0..ebc5ecfbe66 100644 --- a/Apps/Sandcastle/gallery/development/Picking.html +++ b/Apps/Sandcastle/gallery/development/Picking.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -624,7 +624,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/PointPrimitives.html b/Apps/Sandcastle/gallery/development/PointPrimitives.html index 7efb0a1983f..1416f469c8b 100644 --- a/Apps/Sandcastle/gallery/development/PointPrimitives.html +++ b/Apps/Sandcastle/gallery/development/PointPrimitives.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -275,7 +275,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Outline.html b/Apps/Sandcastle/gallery/development/Polygon Outline.html index ccdaf2d5145..161562aa986 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Polygon Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -152,7 +152,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html index 00116b09de3..8f435f05956 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html +++ b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -436,7 +436,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon.html b/Apps/Sandcastle/gallery/development/Polygon.html index e1924903069..ac514033872 100644 --- a/Apps/Sandcastle/gallery/development/Polygon.html +++ b/Apps/Sandcastle/gallery/development/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -358,7 +358,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Color.html b/Apps/Sandcastle/gallery/development/Polyline Color.html index b7ea8361ede..c49725afcbd 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Color.html +++ b/Apps/Sandcastle/gallery/development/Polyline Color.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -92,7 +92,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Material.html b/Apps/Sandcastle/gallery/development/Polyline Material.html index 5b953d41d4b..dfd105fcab5 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Polyline Material.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -111,7 +111,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html index 073f0455b30..7afd2311560 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -122,7 +122,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume.html b/Apps/Sandcastle/gallery/development/Polyline Volume.html index 1037d48d357..07a9ea3836c 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -170,7 +170,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline.html b/Apps/Sandcastle/gallery/development/Polyline.html index 7025f9e1bba..f7fad4cee28 100644 --- a/Apps/Sandcastle/gallery/development/Polyline.html +++ b/Apps/Sandcastle/gallery/development/Polyline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -96,7 +96,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index aedb55060ce..68e4c221004 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -50,21 +50,15 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { window.alert( @@ -371,7 +365,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines.html b/Apps/Sandcastle/gallery/development/Polylines.html index 7046bd1e060..ea310cc0c48 100644 --- a/Apps/Sandcastle/gallery/development/Polylines.html +++ b/Apps/Sandcastle/gallery/development/Polylines.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -196,7 +196,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle Outline.html b/Apps/Sandcastle/gallery/development/Rectangle Outline.html index d5f90c1725a..749ced2286e 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle Outline.html +++ b/Apps/Sandcastle/gallery/development/Rectangle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -67,7 +67,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle.html b/Apps/Sandcastle/gallery/development/Rectangle.html index 587b72bbf33..d8968440335 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle.html +++ b/Apps/Sandcastle/gallery/development/Rectangle.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -84,7 +84,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index 2f4a6fe40cd..75714782252 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -302,7 +302,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -1086,7 +1086,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Simple Polyline.html b/Apps/Sandcastle/gallery/development/Simple Polyline.html index 18688e29147..2627c54aedd 100644 --- a/Apps/Sandcastle/gallery/development/Simple Polyline.html +++ b/Apps/Sandcastle/gallery/development/Simple Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -116,7 +116,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere Outline.html b/Apps/Sandcastle/gallery/development/Sphere Outline.html index d2fa6a09f14..b4b2ff1c0e6 100644 --- a/Apps/Sandcastle/gallery/development/Sphere Outline.html +++ b/Apps/Sandcastle/gallery/development/Sphere Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,7 +79,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere.html b/Apps/Sandcastle/gallery/development/Sphere.html index 6e0bfbc8575..706928eed45 100644 --- a/Apps/Sandcastle/gallery/development/Sphere.html +++ b/Apps/Sandcastle/gallery/development/Sphere.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,7 +79,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html index 3dc40b187da..6ef629b7d3a 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html +++ b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html @@ -32,164 +32,166 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - const concavePositions = [ - new Cesium.Cartesian3( - -2353381.4891308164, - -3747386.1222378365, - 4577999.291515961 - ), - new Cesium.Cartesian3( - -2359513.937204245, - -3743087.2343810294, - 4578357.188560644 - ), - new Cesium.Cartesian3( - -2356102.0286082155, - -3739921.552293276, - 4582670.218770547 - ), - new Cesium.Cartesian3( - -2353889.0353209395, - -3741183.2274413602, - 4582776.909071608 - ), - new Cesium.Cartesian3( - -2355072.390487758, - -3742865.615615464, - 4580808.044684757 - ), - new Cesium.Cartesian3( - -2356109.6661414686, - -3741994.0607898533, - 4580985.489703348 - ), - new Cesium.Cartesian3( - -2357041.8328847606, - -3743225.9693035223, - 4579509.2148039425 - ), - new Cesium.Cartesian3( - -2354586.752280607, - -3744890.9511893727, - 4579411.591389144 - ), - new Cesium.Cartesian3( - -2353213.0268325945, - -3743712.1202877173, - 4581070.08828045 - ), - new Cesium.Cartesian3( - -2353637.930711704, - -3743402.9513476435, - 4581104.219550749 - ), - new Cesium.Cartesian3( - -2352875.095159641, - -3742564.819171856, - 4582173.540953957 - ), - new Cesium.Cartesian3( - -2350669.646050987, - -3743751.6823160048, - 4582334.8406995395 - ), - ]; + const concavePositions = [ + new Cesium.Cartesian3( + -2353381.4891308164, + -3747386.1222378365, + 4577999.291515961 + ), + new Cesium.Cartesian3( + -2359513.937204245, + -3743087.2343810294, + 4578357.188560644 + ), + new Cesium.Cartesian3( + -2356102.0286082155, + -3739921.552293276, + 4582670.218770547 + ), + new Cesium.Cartesian3( + -2353889.0353209395, + -3741183.2274413602, + 4582776.909071608 + ), + new Cesium.Cartesian3( + -2355072.390487758, + -3742865.615615464, + 4580808.044684757 + ), + new Cesium.Cartesian3( + -2356109.6661414686, + -3741994.0607898533, + 4580985.489703348 + ), + new Cesium.Cartesian3( + -2357041.8328847606, + -3743225.9693035223, + 4579509.2148039425 + ), + new Cesium.Cartesian3( + -2354586.752280607, + -3744890.9511893727, + 4579411.591389144 + ), + new Cesium.Cartesian3( + -2353213.0268325945, + -3743712.1202877173, + 4581070.08828045 + ), + new Cesium.Cartesian3( + -2353637.930711704, + -3743402.9513476435, + 4581104.219550749 + ), + new Cesium.Cartesian3( + -2352875.095159641, + -3742564.819171856, + 4582173.540953957 + ), + new Cesium.Cartesian3( + -2350669.646050987, + -3743751.6823160048, + 4582334.8406995395 + ), + ]; - // concave polygon - viewer.entities.add({ - name: "concave polygon on surface", - polygon: { - hierarchy: concavePositions, - material: "../images/Cesium_Logo_Color.jpg", - }, - stRotation: 1.0, - }); + // concave polygon + viewer.entities.add({ + name: "concave polygon on surface", + polygon: { + hierarchy: concavePositions, + material: "../images/Cesium_Logo_Color.jpg", + }, + stRotation: 1.0, + }); - // Randomly colored, nonoverlapping squares - const latitude = 46.2522; - const longitude = -122.2534; + // Randomly colored, nonoverlapping squares + const latitude = 46.2522; + const longitude = -122.2534; - Cesium.Math.setRandomNumberSeed(133); + Cesium.Math.setRandomNumberSeed(133); - for (let x = 0; x < 10; ++x) { - for (let y = 0; y < 10; ++y) { - const cornerLat = latitude + 0.01 * x; - const cornerLon = longitude + 0.01 * y; - viewer.entities.add({ - id: `${x} ${y}`, - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - cornerLon, - cornerLat, - cornerLon + 0.009, - cornerLat + 0.009 - ), - material: Cesium.Color.fromRandom().withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); - } + for (let x = 0; x < 10; ++x) { + for (let y = 0; y < 10; ++y) { + const cornerLat = latitude + 0.01 * x; + const cornerLon = longitude + 0.01 * y; + viewer.entities.add({ + id: `${x} ${y}`, + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + cornerLon, + cornerLat, + cornerLon + 0.009, + cornerLat + 0.009 + ), + material: Cesium.Color.fromRandom().withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); } + } - // Checkerboard - const checkerboard = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.ORANGE, - oddColor: Cesium.Color.YELLOW, - repeat: new Cesium.Cartesian2(14, 14), - }); - - viewer.entities.add({ - name: "checkerboard rectangle", - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.17778, - 46.36169, - -120.17778, - 48.36169 - ), - material: checkerboard, - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + // Checkerboard + const checkerboard = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.ORANGE, + oddColor: Cesium.Color.YELLOW, + repeat: new Cesium.Cartesian2(14, 14), + }); - // Ellipse with texture rotation and repetition - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees( - -121.70711316136793, - 45.943757948892845, - 0.0 + viewer.entities.add({ + name: "checkerboard rectangle", + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.17778, + 46.36169, + -120.17778, + 48.36169 ), - name: "ellipse", - ellipse: { - semiMinorAxis: 15000.0, - semiMajorAxis: 30000.0, - material: new Cesium.ImageMaterialProperty({ - image: "../images/Cesium_Logo_Color.jpg", - repeat: new Cesium.Cartesian2(10, 10), - }), - stRotation: Cesium.Math.toRadians(45), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + material: checkerboard, + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); + + // Ellipse with texture rotation and repetition + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees( + -121.70711316136793, + 45.943757948892845, + 0.0 + ), + name: "ellipse", + ellipse: { + semiMinorAxis: 15000.0, + semiMajorAxis: 30000.0, + material: new Cesium.ImageMaterialProperty({ + image: "../images/Cesium_Logo_Color.jpg", + repeat: new Cesium.Cartesian2(10, 10), + }), + stRotation: Cesium.Math.toRadians(45), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - viewer.zoomTo(viewer.entities); - })(); //Sandcastle_End + viewer.zoomTo(viewer.entities); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index 5ea861d821d..6aa97449f49 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -32,23 +32,17 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", {}); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const camera = scene.camera; const globe = scene.globe; const statistics = Cesium.RequestScheduler.statistics; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - let startTime; let flightComplete; let monitor; @@ -283,7 +277,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html index 16308f1bd67..88eadd2aa7a 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html +++ b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html @@ -91,7 +91,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -157,7 +157,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Volumes.html b/Apps/Sandcastle/gallery/development/Volumes.html index 8ff67043449..4449c45a055 100644 --- a/Apps/Sandcastle/gallery/development/Volumes.html +++ b/Apps/Sandcastle/gallery/development/Volumes.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -71,7 +71,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Voxels.html b/Apps/Sandcastle/gallery/development/Voxels.html index a3b2b3590fc..740794a2087 100644 --- a/Apps/Sandcastle/gallery/development/Voxels.html +++ b/Apps/Sandcastle/gallery/development/Voxels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -473,7 +473,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall Outline.html b/Apps/Sandcastle/gallery/development/Wall Outline.html index a314a70d61a..4dc0898026e 100644 --- a/Apps/Sandcastle/gallery/development/Wall Outline.html +++ b/Apps/Sandcastle/gallery/development/Wall Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -71,7 +71,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall.html b/Apps/Sandcastle/gallery/development/Wall.html index e22ffb9df6a..bda56781445 100644 --- a/Apps/Sandcastle/gallery/development/Wall.html +++ b/Apps/Sandcastle/gallery/development/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -174,7 +174,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/load-cesium-es6.js b/Apps/Sandcastle/load-cesium-es6.js index 0b7dfc4cd51..bd8a8c98ca4 100644 --- a/Apps/Sandcastle/load-cesium-es6.js +++ b/Apps/Sandcastle/load-cesium-es6.js @@ -7,5 +7,9 @@ window.Cesium = Cesium; // Since ES6 modules have no guaranteed load order, // only call startup if it's already defined but hasn't been called yet if (!window.startupCalled && typeof window.startup === "function") { - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } From 0370548f447311b38b713c20e70a8731ab696a76 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 1 Feb 2023 10:02:06 +0800 Subject: [PATCH 399/679] implement inertiaZoom in aggregator --- .../engine/Source/Scene/CameraEventAggregator.js | 15 +++++++++++++++ .../Source/Scene/ScreenSpaceCameraController.js | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 19bff9d4e0b..2e0063393e7 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -133,6 +133,9 @@ function listenToPinch(aggregator, modifier, canvas) { function listenToWheel(aggregator, modifier) { const key = getKey(CameraEventType.WHEEL, modifier); + const pressTime = aggregator._pressTime; + const releaseTime = aggregator._releaseTime; + const update = aggregator._update; update[key] = true; @@ -141,6 +144,15 @@ function listenToWheel(aggregator, modifier) { movement = aggregator._movement[key] = {}; } + let lastMovement = aggregator._lastMovement[key]; + if (!defined(lastMovement)) { + lastMovement = aggregator._lastMovement[key] = { + startPosition: new Cartesian2(), + endPosition: new Cartesian2(), + valid: false, + }; + } + movement.startPosition = new Cartesian2(); movement.endPosition = new Cartesian2(); @@ -156,6 +168,9 @@ function listenToWheel(aggregator, modifier) { movement.endPosition.y = arcLength; update[key] = false; } + Cartesian2.clone(movement.endPosition, lastMovement.endPosition); + lastMovement.valid = true; + pressTime[key] = releaseTime[key] = new Date(); }, ScreenSpaceEventType.WHEEL, modifier diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 0763865ddec..a96605d33f1 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -108,9 +108,9 @@ function ScreenSpaceCameraController(scene) { * the camera will continue to zoom because of inertia. * With value of zero, the camera will have no inertia. * @type {Number} - * @default 0.8 + * @default 0.5 */ - this.inertiaZoom = 0.8; + this.inertiaZoom = 0.5; /** * A parameter in the range <code>[0, 1)</code> used to limit the range * of various user inputs to a percentage of the window width/height per animation frame. From b41528040d659604964021a7d6e60b24471b0dbd Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 1 Feb 2023 10:20:40 +0800 Subject: [PATCH 400/679] add changes in CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c4cabeeab7b..b91d2457f0f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.103 - 2023-03-01 + +#### @cesium/engine + +##### Additions :tada: + +- Added smooth zoom with mouse wheel. [#11062](https://github.com/CesiumGS/cesium/pull/11062) + ### 1.102 - 2023-02-01 #### @cesium/engine From cb58d18e08f42e5c43de33e1d85ea36776044710 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 1 Feb 2023 10:49:05 +0800 Subject: [PATCH 401/679] update lastMovement copy in aggregator --- packages/engine/Source/Scene/CameraEventAggregator.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 2e0063393e7..1afcd267863 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -130,6 +130,10 @@ function listenToPinch(aggregator, modifier, canvas) { ); } +function cloneZoomMovement(zoomMovement, result) { + Cartesian2.clone(zoomMovement.endPosition, result.endPosition); +} + function listenToWheel(aggregator, modifier) { const key = getKey(CameraEventType.WHEEL, modifier); @@ -160,17 +164,18 @@ function listenToWheel(aggregator, modifier) { function (delta) { // TODO: magic numbers const arcLength = 15.0 * CesiumMath.toRadians(delta); + pressTime[key] = releaseTime[key] = new Date(); if (!update[key]) { + cloneZoomMovement(movement, lastMovement); movement.endPosition.y = movement.endPosition.y + arcLength; } else { Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); movement.endPosition.x = 0.0; movement.endPosition.y = arcLength; + cloneZoomMovement(movement, lastMovement); + lastMovement.valid = true; update[key] = false; } - Cartesian2.clone(movement.endPosition, lastMovement.endPosition); - lastMovement.valid = true; - pressTime[key] = releaseTime[key] = new Date(); }, ScreenSpaceEventType.WHEEL, modifier From df469b807f852dc2b307044d6943410a9b5a6c74 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 1 Feb 2023 15:37:00 +0800 Subject: [PATCH 402/679] use debounce simlulate wheel start and end --- .../Source/Scene/CameraEventAggregator.js | 27 +++++++++---------- .../Scene/ScreenSpaceCameraController.js | 12 ++++----- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 1afcd267863..8b720b48773 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -130,10 +130,6 @@ function listenToPinch(aggregator, modifier, canvas) { ); } -function cloneZoomMovement(zoomMovement, result) { - Cartesian2.clone(zoomMovement.endPosition, result.endPosition); -} - function listenToWheel(aggregator, modifier) { const key = getKey(CameraEventType.WHEEL, modifier); @@ -160,22 +156,25 @@ function listenToWheel(aggregator, modifier) { movement.startPosition = new Cartesian2(); movement.endPosition = new Cartesian2(); + let debounceZoom; + aggregator._eventHandler.setInputAction( function (delta) { // TODO: magic numbers const arcLength = 15.0 * CesiumMath.toRadians(delta); pressTime[key] = releaseTime[key] = new Date(); - if (!update[key]) { - cloneZoomMovement(movement, lastMovement); - movement.endPosition.y = movement.endPosition.y + arcLength; - } else { - Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); - movement.endPosition.x = 0.0; - movement.endPosition.y = arcLength; - cloneZoomMovement(movement, lastMovement); - lastMovement.valid = true; - update[key] = false; + Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); + movement.endPosition.x = 0.0; + movement.endPosition.y = arcLength; + Cartesian2.clone(movement.endPosition, lastMovement.endPosition); + lastMovement.valid = true; + if (debounceZoom) { + clearTimeout(debounceZoom); + debounceZoom = setTimeout(function () { + update[key] = true; + }, 10); } + update[key] = false; }, ScreenSpaceEventType.WHEEL, modifier diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index a96605d33f1..779cea26441 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -108,9 +108,9 @@ function ScreenSpaceCameraController(scene) { * the camera will continue to zoom because of inertia. * With value of zero, the camera will have no inertia. * @type {Number} - * @default 0.5 + * @default 0.8 */ - this.inertiaZoom = 0.5; + this.inertiaZoom = 0.8; /** * A parameter in the range <code>[0, 1)</code> used to limit the range * of various user inputs to a percentage of the window width/height per animation frame. @@ -301,7 +301,7 @@ function ScreenSpaceCameraController(scene) { ); // Constants, Make any of these public? - this._zoomFactor = 5.0; + this._zoomFactor = 2.0; this._rotateFactor = undefined; this._rotateRateRangeAdjustment = undefined; this._maximumRotateRate = 1.77; @@ -591,9 +591,9 @@ function handleZoom( return; } - const sameStartPosition = Cartesian2.equals( - startPosition, - object._zoomMouseStart + const sameStartPosition = defaultValue( + movement.inertiaEnabled, + Cartesian2.equals(startPosition, object._zoomMouseStart) ); let zoomingOnVector = object._zoomingOnVector; let rotatingZoom = object._rotatingZoom; From a8998f4c0c532367c42a539b02bc9c7f649a92c9 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 1 Feb 2023 15:57:03 +0800 Subject: [PATCH 403/679] fix debounce not work --- packages/engine/Source/Scene/CameraEventAggregator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 8b720b48773..10b2af499aa 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -170,10 +170,10 @@ function listenToWheel(aggregator, modifier) { lastMovement.valid = true; if (debounceZoom) { clearTimeout(debounceZoom); - debounceZoom = setTimeout(function () { - update[key] = true; - }, 10); } + debounceZoom = setTimeout(function () { + update[key] = true; + }, 10); update[key] = false; }, ScreenSpaceEventType.WHEEL, From 7978ff39594beaf77be7fc32cb40bab151adc46b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 09:29:47 -0500 Subject: [PATCH 404/679] Update Coding Guide with note about deprecations Add a note to the coding guide stating deprecated APIs should be mentioned in CHANGES.md upon their removal --- Documentation/Contributors/CodingGuide/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Contributors/CodingGuide/README.md b/Documentation/Contributors/CodingGuide/README.md index 3b6218e9597..2a67ebe53e3 100644 --- a/Documentation/Contributors/CodingGuide/README.md +++ b/Documentation/Contributors/CodingGuide/README.md @@ -940,6 +940,7 @@ function Foo() { - Remove all use of the deprecated API inside Cesium except for unit tests that specifically test the deprecated API. - Mention the deprecation in the `Deprecated` section of [`CHANGES.md`](https://github.com/CesiumGS/cesium/blob/main/CHANGES.md). Include what Cesium version it will be removed in. - Create an [issue](https://github.com/CesiumGS/cesium/issues) to remove the API with the appropriate `remove in [version]` label. +- Upon removal of the API, add a mention of it in the `Breaking Changes` section of [`CHANGES.md`](https://github.com/CesiumGS/cesium/blob/main/CHANGES.md). ## Third-Party Libraries From 8f0a65f844dd772aef32c4895d9d64eb8efccb87 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Feb 2023 10:12:00 -0500 Subject: [PATCH 405/679] Update markdownlint-cli --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ea6829be4a8..a6794faa266 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "karma-safari-launcher": "^1.0.0", "karma-sourcemap-loader": "^0.3.8", "karma-spec-reporter": "^0.0.36", - "markdownlint-cli": "^0.32.2", + "markdownlint-cli": "^0.33.0", "merge-stream": "^2.0.0", "mime": "^3.0.0", "mkdirp": "^1.0.4", @@ -166,4 +166,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} From 71908d41950ac6483b0beb61197c2434e268d795 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Feb 2023 10:14:40 -0500 Subject: [PATCH 406/679] Update mkdirp --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a6794faa266..1cd8508837c 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "markdownlint-cli": "^0.33.0", "merge-stream": "^2.0.0", "mime": "^3.0.0", - "mkdirp": "^1.0.4", + "mkdirp": "^2.1.3", "node-fetch": "^3.2.10", "open": "^8.2.1", "p-limit": "^4.0.0", From 1a7c59a4e50b02a70609e39354f423190bb6b044 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Feb 2023 10:18:14 -0500 Subject: [PATCH 407/679] Update rimraf --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1cd8508837c..9d59edc7bf6 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "prettier": "2.1.2", "prismjs": "^1.28.0", "request": "^2.79.0", - "rimraf": "^3.0.2", + "rimraf": "^4.1.2", "rollup": "^2.79.1", "rollup-plugin-strip-pragma": "^1.0.0", "rollup-plugin-terser": "^7.0.2", From 9e5baf6384fd3e0eabf0c1df5d4ff4ba6a3372fe Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 10:33:33 -0500 Subject: [PATCH 408/679] Audit last few CHNAGES.md release notes for breaking changes from deprecations --- CHANGES.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index c4cabeeab7b..beb4a30ceb6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -91,6 +91,10 @@ - `Widgets`(CSS files only) - The ability to import modules and TypeScript definitions from individual files has been removed. Any imports should originate from the `cesium` module (`import { Cartesian3 } from "cesium";`) or the combined `Cesium.js` file (`import { Cartesian3 } from "Source/Cesium.js";`); +#### Breaking Changes :mega: + +- The viewer parameter in `KmlTour.prototype.play` was removed. Instead of a `Viewer`, pass a `CesiumWidget` instead. [#10845](https://github.com/CesiumGS/cesium/pull/10845) + ### 1.99 - 2022-11-01 #### Major Announcements :loudspeaker: @@ -107,6 +111,10 @@ - `Widgets`(CSS files only) - The ability to import modules and TypeScript definitions from individual files will been removed. Any imports should originate from the `cesium` module (`import { Cartesian3 } from "cesium";`) or the combined `Cesium.js` file (`import { Cartesian3 } from "Source/Cesium.js";`); +#### Breaking Changes :mega: + +- The polyfills `requestAnimationFrame` and `cancelAnimationFrame` have been removed. Use the native browser methods instead. [#10579](https://github.com/CesiumGS/cesium/pull/10579) + ##### Additions :tada: - Added support for I3S 3D Object and IntegratedMesh Layers. [#9634](https://github.com/CesiumGS/cesium/pull/9634) @@ -130,6 +138,7 @@ #### Breaking Changes :mega: - As of the previous release (1.97), `new Model()` is an internal constructor and must not be used directly. Use `Model.fromGltf()` instead. [#10778](https://github.com/CesiumGS/cesium/pull/10778) +- The `.getPropertyNames` methods of `Cesium3DTileFeature`, `Cesium3DTilePointFeature`, and `ModelFeature` have been removed. Use the `.getPropertyIds` methods instead. ##### Additions :tada: @@ -205,6 +214,7 @@ ##### Breaking Changes :mega: - `Model.boundingSphere` now returns the bounding sphere in ECEF coordinates instead of the local coordinate system. [#10589](https://github.com/CesiumGS/cesium/pull/10589) +- `Cesium3DTileStyle.readyPromise` and `Cesium3DTileStyle.ready` have been removed. If loading a style from a url, use `Cesium3DTileStyle.fromUrl` instead. [#10348](https://github.com/CesiumGS/cesium/pull/10348) ##### Additions :tada: @@ -296,7 +306,7 @@ - Removed individual image-based lighting parameters from `Model` and `Cesium3DTileset`. [#10388](https://github.com/CesiumGS/cesium/pull/10388) - Models and tilesets rendered with `ModelExperimental` must set `enableDebugWireframe` to true in order for `debugWireframe` to work in WebGL1. [#10344](https://github.com/CesiumGS/cesium/pull/10344) - Removed `ImagerySplitPosition` and `Scene.imagerySplitPosition`. Use `SplitDirection` and `Scene.splitPosition` instead.[#10418](https://github.com/CesiumGS/cesium/pull/10418) -- Removed restriction on enabling `Scene.orderIndependentTranslucency` on iPad and iOS. [#10417](https://github.com/CesiumGS/cesium/pull/10417) +- Tilesets and models should now specify image-based lighting parameters in `ImageBasedLighting` instead of as individual options. [#10226](https://github.com/CesiumGS/cesium/pull/10226) ##### Additions :tada: From b8a0e7b8ae35dce2bdcdc3fcd2333897ee8e171d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 10:53:16 -0500 Subject: [PATCH 409/679] Fixup clean task --- gulpfile.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 02760e4d96f..a31f29bfc60 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -318,10 +318,9 @@ const filesToClean = [ ]; export async function clean() { - const rimrafAsync = (file) => new Promise((resolve) => rimraf(file, resolve)); - await rimrafAsync("Build"); + await rimraf("Build"); const files = await globby(filesToClean); - return Promise.all(files.map(rimrafAsync)); + return Promise.all(files.map((file) => rimraf(file))); } async function clocSource() { From 8a181824cf9d41d53df1f4a1507c4de9853995d8 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 11:23:28 -0500 Subject: [PATCH 410/679] Update ThirdParty.json --- ThirdParty.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ThirdParty.json b/ThirdParty.json index c5a7cf07d6e..c1a2f184970 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -36,7 +36,7 @@ "license": [ "Apache-2.0" ], - "version": "2.4.1", + "version": "2.4.3", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -150,7 +150,7 @@ "license": [ "BSD-3-Clause" ], - "version": "7.1.2", + "version": "7.2.0", "url": "https://www.npmjs.com/package/protobufjs" }, { From 1330875b4ca526eda2e1d9e7ffb398a44774b33c Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 12:58:23 -0500 Subject: [PATCH 411/679] Updates for 1.102 --- CHANGES.md | 4 ++-- package.json | 8 ++++---- packages/engine/Source/Core/Ion.js | 3 +-- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index beb4a30ceb6..c02cf295458 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,10 +24,10 @@ ##### Fixes :wrench: +- Fixed label background rendering. [#11040](https://github.com/CesiumGS/cesium/issues/11040) - Fixed a bug decoding glTF Draco attributes with quantization bits above 16. [#7471](https://github.com/CesiumGS/cesium/issues/7471) - Fixed an edge case in `viewer.flyTo` when flying to a imagery layer with certain terrain providers. [#10937](https://github.com/CesiumGS/cesium/issues/10937) -- Fixed a crash in terrain sampling if any points have an indefined position due to being outside the rectangle. [#10931](https://github.com/CesiumGS/cesium/pull/10931) -- Fixed label background rendering. [#11040](https://github.com/CesiumGS/cesium/issues/11040) +- Fixed a crash in terrain sampling if any points have an undefined position due to being outside the rectangle. [#10931](https://github.com/CesiumGS/cesium/pull/10931) - Fixed a bug where scale was not being applied to the top-level tileset geometric error. [#11047](https://github.com/CesiumGS/cesium/pull/11047) - Updating Bing Maps top page hyperlink to Bing Maps ToU hyperlink [#11049](https://github.com/CesiumGS/cesium/pull/11049) diff --git a/package.json b/package.json index 9d59edc7bf6..ecf93bcc4bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.101.0", + "version": "1.102.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "1.1.0", - "@cesium/widgets": "1.1.0" + "@cesium/engine": "2.0.0", + "@cesium/widgets": "2.0.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^23.0.5", @@ -166,4 +166,4 @@ "packages/engine", "packages/widgets" ] -} +} \ No newline at end of file diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index 2fd9a1f4e72..a1daf6ecd06 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,8 +4,7 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyZTlhMmUzMS1iZjI3LTRhMmQtYjFkZi02MDhlMDZjZDlmNDIiLCJpZCI6MjU5LCJpYXQiOjE2NzI2ODQyMDR9.GfS2oIjtP-hkhYm4g_Y6Vvpdp954z30qPWJnlNBF-co"; - + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3NTUwMzYxOS04YmYzLTRkMzAtYjIyMy03ZmY3MjExZWNiNzciLCJpZCI6MjU5LCJpYXQiOjE2NzUyNzM5NjF9.rR_X1Phio3WgkIiwLJfSPMVTJEdSHKzj6GY9oNwttfo"; /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/package.json b/packages/engine/package.json index b70179482a3..6c53c51ce46 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "1.1.0", + "version": "2.0.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 86d4bd43098..9b4524f050d 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "1.1.0", + "version": "2.0.0", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "1.1.0", + "@cesium/engine": "2.0.0", "nosleep.js": "^0.12.0" }, "type": "module", From 05eebc7e9ad38d9f49f629b28171a63f0c82ec66 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Feb 2023 13:34:54 -0500 Subject: [PATCH 412/679] Add Sandcastle thumbnail --- .../gallery/Aerometrex San Francisco.jpg | Bin 0 -> 15668 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Apps/Sandcastle/gallery/Aerometrex San Francisco.jpg diff --git a/Apps/Sandcastle/gallery/Aerometrex San Francisco.jpg b/Apps/Sandcastle/gallery/Aerometrex San Francisco.jpg new file mode 100644 index 0000000000000000000000000000000000000000..955edf652ebfadd52ee03a8929a9bf701684e237 GIT binary patch literal 15668 zcmeHtWmH_v)@CEYC0KB`03o<L1P@Md3EFAg9XcUFLU00vV8PvjH11A-;6Z}BHr9Ce zbl!XK`+aNHomn&UckVuY&Z*jG*HiWEstoksjZtO6dZDXA&}P*4B>732XxtN~UP z{Xq5rfQANu6952U0Un_c1JIBu6yyOwp#nVmD-8gsp-}&w)<xk5pd$68$kQYO1VI0% zjSKSrN07*WO8?`|&&w|$&dVpxC&s|XE6y(>F31Z2Jc>vA8=*QL{qJ<|H<bUX{Tu4v z$ZOxw{!XX-sp8+E{yQCF4g2zqmzSG3508uIb1Pd{YrE$*uFgDuR&G3e&v|(Ok}`g7 zRyK}yUJTZDK#+?R(@9GQ69dRripfw&gIB{%!R`%6CBVZ@FF;e@Ccx1~%$7+;nnBV} z+|Sv~+0M&~!Oz*r#Z%l*is>(Kab)_Bnum$uFB30EDJCNgZ3YEb4?6~-=Yr39nUJMD zZ0*H$Unu>vEHWp>^v_26`uaZi6?pFI0p#Hm6BFa%<>%q&=SEs^d-}V0S^06hcryPB z;f0;2jR(lh3*_p;@CVV#+SS`jiV0csKbqw1_BZUm<^C^2w>Pd{uAXmP{}<+eKmN;M ze+s#YYq;8i?EPO@dD%%Z{c$@tFCRCbnEt;y_#Z|J9(G8B|Bcb#$l`yD{$Y-E{J#U_ zL3)knpKkk;{M-N14F8e;c;G)C_>Twv<AMKp;6EPt|IY*e6~WoLAfpFgWPAod90B~a z{}t9S2t4Nnh{~&Kp#KR}0RR~q6cYd%HLEfWGKfV5pwghq05JG?`9%bIX;7sBSbyRV zUOqlC8dQ=0o{{{Q(Lb<Q|H69Qh0df0<30uLRQ1Qb`1BSB(Fq{J0;B-e&`_8Fs6;4e zL@0<}06j7weuVOu{8bEjK|w`Be}sXFg^h!YG^l?JKt(}ALq$h>^yp7BQG$`r0q8`J zh#C3hFi3Q)Fqzy*`QIhvU@^<rbdl*!Kv@K=JwmZ@o{&>eQn9kJKjq*Q6cQE@6%$u@ zp{S&+qN=8+|H{D7$k@cj*3KUI2IS!B<?Z9^=O6I?Ls)o3<j1JQq|eDIsbA8*=H}%W z6c!bilzy+Rt8aibHZ^zm^!D`+3=R!XPEF6u&i$HSSX<xN+}hsR-P=DsJHNPuU0vVY z{^5lT*Z)BadHn~o|A`k7k{2pEIvP6WA6_V^zJG`lp+92e!yuN^!L)KGVd8&>MJk_= zQ`3dbET9V|v-X(4dBP&N#(MgP+F#86&xnQoKQa58*nja_1SkMd{}MD*RJ2EEXlRcx z9w7w-3*(Pq;b8qGIR6y9zl7kA5dJL)BnXlz8ag^UCi3?f7aRBS|Fs}~BUe3yhy?&1 z8VYhSp%DRO0Jm|&`DZbX{%Di&U6$3J^bu!iY|N@#RI_(df?Y>iU&LNk@hl{b2$jJ+ zRh&m@y0`2NQ$UiX(`Wc}az#IA%16!~N+dfRrq85G@F?=WJo_>JG(gv1dZuVo_aQ5r z_t5S}VKQ|XR>8xRI#lq3OF&>4R&dr<rZtGX5f;#N+1vYj`P<jszu(h*vYpE7k!CI9 z0I`>Bx``a5G@^T_eAm~Aw(l@EKWg_|y{OC0x}!11oc9G^RkkR=mN?s8;1@(_6-be+ zjx%Qrf&+hU{sJ137EFpG00{wHfqEeBe3vOj=DLW()7rN`7C)Y2plo_saP&*4`>}*c z_MHpYJWuqtye2HL6>eyNF>9YOh7WBMl`WaI2qgMMf4-4pk0y8|&O@?yya7yH?AS>@ zMc;~oQa^lCo;KXR*m)`>+GbF+S8qkx*R8Ic^ZErLb3ADIm4?kT@{ikcB)N17f}c2v z;6o-qA4eM=h??nEsR<dR$}se;nd406|30*fEa~Q)ejKRxL3(EHhdYuyr`w0wqNF2D zBHe9zj^xd3HOZts6Sz*^u;9(WFc|Uk?#1F%$e5$kVxXP|q&_5XEJR??n%Z;kR@WbM zvH?D>3JVBY8?^SPo1Vg~cL~m3PCDEnz3CgYx}lr)r<;MmJeB81>3)j6lwn?oW4JX~ znIC1JAFr2o_Yfc-lD_cAHw6Q4b%V3_ltq!6K?lkAyN<4h2!NXOSa9(Ufs!?{n$$s9 zMHR#3L&n6IG*Uq~-L72k9GrnvOzsfqkq-);)5i%`gqVArXimAj6y|ozArepVQr^UK z5nCcSga(%#h}jS+vQ%Xj7sO&{0*2OG1zueze>1gr7SVDnOG+Vrnfr{!hJlwSBY;Qk zdg<2P;cEyu2X-%o(N=cxp#Fr8czUt(i8$>~8AnJ<YzV2H@>jDAuMM$24_!Y47{-fq z&5Xh7{wR4ME9>XzqrDN^V8`|;*H&-|2(y>dCR!kJ61{<Sc!xT6dr3KH)qSD%=w4$Z z6_T>9E*A0GW>_k{Eadc6BVZ@ym-Gjsg?0;$`8UCV^;Z&LY$IG5e9$Zkm4GXjc{y(n zUEXZ7R_&}|xXmf|MBu0uqdE|;n2eUDxq-mfXJhK?LHp>DWsY4f0$?8%0#3WBbbfT% zRKIn@Oe4#&EL)M_e5A%bUJ#J=^VA;?%<^Xt)W8CK=l25T&M4qo^>kWDw`RrFPQu=A z${;2lu<p1;4rhL*TdBev?oQssjYuVlApo_y!Jp^kU?y6%I!BKVV*?LIRbe*fg!3iR zBU%fLfy`NVe0hfhlg;$CR9dxEAwQ)O#)H4y>cDLFkVY}|_R^mNWnnLO+J}Rm-tk>j zMj&nDYU$Oaz6G**uGmR`&bF6Mp7>`8<vK#!u|T9n>K{bHS}N%uZ(#2ZW5Iu^ipYKj zf0=-pNaYgRdLlWCR#BxYPdZm^w=^}X6s7$dbl$-7oIVDpMY#B)SSkdkw0qB0RWeMQ zyjivWnOQL6uQNa?SxfA;SX-|tk<}w~?q4^heFKk}*{s=uW%Eq$txnYCSZ$}{k7lm4 zGXJ<YOS(UJrkG1z5Gx^;w-me9Lq^}iAVU4#O;aE?;9@)38-@JC(ebfQxx|F+xovl3 z&+4(8_-nlC1GB#Ig-b`#;|kkw>H%PKCG~a+n?f>HQN~7-WB|>2E4f}W7xP|4@VFTi zmW^)VDbJ#P%_32Ibuh$yR+)X6H`#;$0BX&D2}Td!dmEmU-Vfx(<{<zx<_N%iSa2)> zNarK8DMn(Q_3S>Hr<PF7@_U@x?>ix$`L;610-fb|KIzdT%_r*(ebpC5xR!G23vu%l zU?6F5hQY~vT)|&mqT7~+n0!zX?wL%7xjHNpaj+`C>Q@Q?CS-S~4$>uGgv`?u?^4j) z!Se5(UR1sxr2CvDdy%)u0K>qXS1zEpBkR~CRMTQ!$Zn9oZF&c@bdVl7GVMoM(t)|} zDc8$gdZHb+ovI@ByV7G)Pw&KUb&leL&351;N6PcTW#8^ZFY=I>58nyPGLWQ#i|=^q zz373K$k%|>Q`n$%<?G<2h1A3LnYKT8^8*Du4)6E33Fm`LLWa2l4>u;`7y@*Tv;)xq z3sAqR#CyfH#g<HKi8hhpC{+{L$rfRoW!^F7yYJEyVJqF2sO?j{cywIb>R)=Nn0M$D zY6(5hc`mDXC}v(H9Bn~iE|v^&s^8%~@P1o*dn_j0-EXfANiZW$5P$}p=LLARPl@X) z9y^Yf&+Cq67A13*8x|^CI8Nja#nD}+W2CxblsqpFYrTuK3G0%1{_7JjL%`M;7-v)a zliE&&PgVqYm5ZWcGSEori4c7m{myI~36j^)HOAw~6&f!r8DXJ486aKq!DPt@dR#`I zZkxdmnc6@dWUnkCy;N|9S>Sl2Gj#Zp&l%aL%QJNh$cZhu7&aKv+jl2YPj8QWSF$g} zA%6~Zy@;u<hYT=iqzz5?y6BXo-y}O*xUHzC%=niXdEaclg=~D@^OI*RY)>O`yPrxP z3EdJxdtm9;{-=7crs||9>SJ>PX%1)SViR6gVHw~)MlWCcoYX|U)lY%yZW+q7ej*QP ztdA^Hb<-a%@c0(%Lj#OWLv7*aKZeigHKaWKG3zl_gv*{XOn~vKadG^VhneiWy3e3+ zQcLTaJrhfAk9&NNWW3?rWNA25AII1i&?)V+8MwMJhf!jFK*g4&GA)GbsEe`An)di@ zVCD}lD7%umtHr6%R)2kP06XuEbK+rN4g&Csn9}Isr>cC2Hm*&{xRv8tCT_2<uE{{D z!}sAV!x0u<!A{;0JOKoNP;5YQhwQND$=2qZ>Y@FR<%R3i9+AN_<9(QCc@Up^<e-K7 z_~?Mp=ylaPq=yiVBB`H_YfA7V8+D%gr{Y;<wB~QDkvo$ete1qLw~sROT|LWGJ;tmD z&k{1xN`jKl<x_CV1AL^D)98CvP;1Tw)%TteLnBjtvWmQh-yWlzd)qO1@M2R`4vx9L z5D5>Reh8_%E`avmsl-_{oLZ#ZdVNdISbk9~4-Gj-8<=cG0L&hWrBVHY8_fN>C--VH zjIp0107jpq;X*f`JfZDVhKAq2PXm?tUTm^vJY7==sybhClcPW@rY*Um$GSLJ3=E_` zAsQu2X7W$eaK#&{%fgsx!dt9XTGqN!*)t6IaEAk2xE(keg>KmkXAw{GTz>RJRc$ct zNpurvt%Xy28k^7`Ev`9cn%+_OT9CC>r!%-fvN+E8MmR-MdI`5INjtha2o{DOlIcHH z9IYy`3<zg>;nu9y9%n>XufA0oP&?$7rr4`#!Q~+}##Vdu@H=^!?5Sr9mwTdn7iP4s zL+NyZTGDPvqMs`);hJYXFtYsUUXeEJ$0ny@u@cPg7tG)@y3K{dl@QJ@i$W8HE$`;z zz);bu0b@9xxp^H724}2qxYK<?)R677@>Gmq*hSh7E&AfB%!2CL^pvEBIL5L^hGeHU z(WurH#$`Gk`Lqi!zJ5x!(@RXgBbim~@=ZiUoB|9D_dtzYN~~%q#&JNV;cR$TT;!AB zT_egoI$U3P$_zhmo3D=FNo*Vdd3n`&T16V9{!rmHzgBbV`^ow6Zs?is3Cr7n*2l`^ zXp5A43K=O!l!5fjS0eV}ag#~7mJzcn6mVt*s!uYJzGqr3GD4NP-)KDRgJ6T>lJDaR zyl=?|s%Yfx8c*qaGnI}(SPR@6U+0Moi}d4Zu0-i>${*^YjKIt=b=(8huuHNVW!F1J zM-ruKNKDl_!^2J{<n^V@>B*RczW7}K3fT%sQ_wZ4Ii@m)3cjjEgNx1JM(-rA32s%r zLU&hRR4EFVF*0H!WX`EdvX0qkZ1xTAR;7G<L4ij9h5fW@eCjk0mf3{u5W;4H)x&0N zhvT#9V!plfWN`3Odgf{qcD1dpfEM!(qLDO%LqERVRY95ov5${nSR55LT_IG>D_^9Y z(fhGei>g&67d4w9`BNn!Gj?}PbrW^ut=~6}4>vF67!iO1>qW2w0^qtlDw)4G>Wtc* zMnQrB7TloRQuEN1iU^79`{iPiH4bf%VOv<Ir1n%K#nF11Jcw+dQTOd!CzwQ<!7s1# zCn)jS(Y$Grr8)8S`ZBJ6Z#Q3eW2Py9Bmsgc<rp;;B6jcF{K$INHVqt>)jjSn<==%y zu{SVVlaXIw`+BvYOy=cVy{WIf^*4?ceg_+c9gZv}MIXI2#4&DSrU_j^G$@)LLG?pu zg#?}!BxUf44l>tz!o!XTI;rV<b^H|T#`Z>BJp8Bh9^@Y}(;(MFW~goy@v`GtHZZ>9 zkX2_||NNU^N9fxilZVpu$6e+7p}IE$tY>0YU2w)|JRiA!M;ra?(K~Ik$liALnSS0D z?yPxFNOXqP_nwk5frU5_W8l;5CJE_|WNPFYf`b5b4?g6{?An}?!_mR8eVH}ekcsRI zzUxm20IJNLx3s@6eT_0=`kL}tJ+8T%pZmo;eEN>$M?5ilY_`Y=za9%++IWy*!EOj? zGbC1a0wW4U^fu@wp)@qjY{Nz6Q5140UeR$(38wn<98E4S3-M5yWXl{O>viuu{B?4B zSsFrdU0_8}73f>Ko45}v!@84{9U?9(v0)YkY>FpqH{Q5UCk=F!8vS^g`plo)@B!Q< zo~IN>X%1m-g&NtlIg1)gD1GNJe!^x<I27*6*ZKUdXTQK@g)7<aTndT0f00Q<7AO%! z%V;C0sLx^Nv=I;3q!X~1%D>L3|AGKO4l5={f~zGaMVwo@(Aczv6S|WDL}tL4%ag}@ zRPy^&tWjFRz2|Awvi))rZiFGdcXLydISv*>BQE)3MeNLM)CaVl8lgP~_<=ah2`n|A zf3&DvcD}}@p$YNU(}BWrD$GnRjjrEOIu#k?w<a9RD*!Y%8OmsL)E_IOF_rJ$jum)* zGuofSX85G7{F|!Zt(0IA>$L|qMOjMoQD%M1;;6&vui+Lfh^+yhCOjWM;!W3rulGh9 zQE&H$N!Jxc@u2<RlpD9l+3ODkXRv)(|2nnLS77Wq21(&;avJ|gBF1DBa;Z$q8Jo1e zd-(|?it9rbOPax}g_cC68%?!MlIWdmwW~5(pY9XY>b6M+5RnbOtLW<qwb};HZTufy zhRH`avn*c?!@Lh>TW0IhO_R`Fa=lla)VY9wfw!aC>&(&KRn}se(snpC4i5$^b3azI zh;?R(@5aiy#8cYV7ah00Vtt&L#BZ|4XL4b9zS;{A-rS*aw|HML|Exl&zpTJi-SJI& znpJcB;DfC8x;zSXb9L9jG|pKt>eLJ9VL(M?ify2?2O;P2@|nCbsqF_<VQ7f8|B}i^ zfhU!HJ{)uM<RT8UA|YF!4>Qr{+^0Y0tuR|x3;w%|ohh;*Q@%Vh4!I-9rDrZF&~7Zw zu0294Yn!W$N4=$5KkVC$t9tzV+$SIclmVO$9#0+Pw(T!j2FWg`jgg$#Y_S?qA-a+6 z_K#71yK(id2iux=txFsUnyKj=!H2_Em4+mIU$k<1gxFkXalN0B1g{$#P-`f38u0cS zEO9OFdqg-VdPKc&@F`lBisd^o^Q!s0ljjrsRTa)U^wiPy2kcWe`N}Bed!6YjmRP0% z=Otb<PJWny?UF#;novqA9X;O{>GAy0aO;qXLQK|nYt7YR)f=sVKFF-3jE9AeyU_Re z#i+&vC8(xP!&E;Z*i{YGHpT9DvFL0vY`RCPR--BTk&ba2^&s9u;9dN$)pIkBMSI`f zTUwi*B1;KuC&99B6l{ZqE%iMZe5<6H4flhF?-rW5a68aIP?ot{0pq2SbNd<AX{*Hv z3NiD2<A9h(DG&cj?h9;JAR$@QxRbpBu>#x4XR{PtpOoDQuqIaNSD(mpqqf;>*0F4_ zYLjoWi~6rc_3apdE}~=NKer@YaQNB>fX?pFP}9Z89@BnRy}JVr8yq8G;>2tF1W6HS zs!m%Yk%PE(HP>06Tg|(KjD&>P`iNlI5w^8&!U+%02MuP?&KP3J<~8w6D4|R1Meg>( z`q-JOi*@M!hVC1K1%{l*&%0OJ?8k&-8&7`fZfCnWup6>>cVI35R;2y-p~QSGH-lys zDjI)!Z8)KQ9oI+1cz(DV@7&4AVj+Xt-7ekw)6262?66N|`xpc@kqq^~91o{?o5$GH zFT+_9$R1JdHF(K%8<R*Zt8U*&5GKLTxVjqJo>!n-p)0{Bt{s?dPfxyYEo(Qmj@fZy zWCKxBD?tFT4XWp5>>9KQ(L57X5rDUIL(S54;~q78?flafuVQ)6pNv=Yhf@wXtVBB) zI&Uvt4;Z$@<?xMB@dr!4=&THju1xK_p=gzo9xy!xueD}VT1{Hb*{Lf|6sGvawA!V8 zee=UP@rI)75M?yz6Buf#Jt4&P>)GMSR`}@eSBc%bl&EiIjdk#xG~E;W<@PMP*2z<b z=u}%3%X&>c!pTW^MEA~o2eeGeRxeI9GBfju{6<WojFp)6iv7bn$9QX9Sl%H3a|JZ| zC;kp1O2XfNp4F~`LVh?4;mf@a8}uaWY<-{MOGq&UxZS9DW9;WZZ5K5=VmM_JL+-%o zfE9%r4In)lpcSpknY~*t_;z;G>R8M>p#JF%`@lLWmC~t9Kh|}+(ZorDGU|a!*S(7S zeQA5`vP@+1lLlbqq94$-5mjA%m-ROUg(sKgWN+ebBWfb9+d@#K7plzntPeAlvq|(= zxM^^QHUL)jGO5>sBc87nnjI#j<g|Ij+dyb`Utzps{J0|>49!zbYsRQ;!Qv0bm>8v7 zrv1|Pxg|sSp1B>l&6ec}2R~%eLu0QG;Qr$`2ms7`7VNNVd7)Z}0CXY%@HYB|X7UGO zPzO{70jSbi?5QQR<6%b3Ko2tYRIBNHa=h89JW<XjX*=xWXyyDV<@wMrWTS$)O5?gL zxKCFi4(rQkmAVI%{N-XqT5Tv9BNb)GA(Z`xe5(O-Wgu~x@K#ouggrjt+%fW?Ia!Jq zpAxB_%A!g6Gu2PssT=h5{@5d0Gf$4A*v-*@D}!e!NosRq(pPt4JKW&vTHqJ3(vufF z81a#%5$DWI#O&x%Xkh@_dBC};@Pxxv!!WCMnwax2z`Tv@G2Xl5fuw~z;|p_^u*?r0 z?SN&<w78nHF8Hg4=6vl$>2bbCGbm?q%Pvdn>CPA2EYY}4+1ei#6rXp7jnw95#J(?- zd1>Feek*oZU@CDLbAMwE$Y-LU{q%?hbxi*}5&Pb;Ca}%sWxMpN(!REj!1OSpCp(YK ztlBXA3ffYYPVsxGf+m$Y^GoFgT$Px=NqC;cyU8+3jrw0!A6KwtJrIQHjty?z%a9%3 z*4=7kgm^h_%SXx1le+J`F>e&rmWGOL*B4H%LbuZ-!%5Fbt}4$UOP&L)Hw&tl_YPdY zVxvspzioxx6TUoiUUXsrk0^>t7~U;qY}9-C&@oO4ed%uD?pn+iXMIkv5%&dsQ1bOo z&Oy{z7^a4&h;P->EtP6XU{UJ++>Tz9k)ZmBqq)*ASA43E397rcied`^z_<zzh&1V` zbQ74Yy%o0L&?(}d09l~y>cPN}v{QjId5FIzvPfQ!3ro2TTX(qCRV~`*ZQuQ^lOpCm zEv>S;lgtcS-FWMW*5i|Rlxo7(WXBqIufW0ba!P^kcPOPVezd^7*haR4XO~r()`F(^ zjW@rGyTQxfDYOm?bAy8&4QY6;PbEyzof$?bhL34IFfS_&;Y8eIY=$Y@>)o<%6=?^J z_4yxu*AfVClt`4-CrVT>?G8w9rmTRLi+q=9f;Jdz!2wmuCG%!Uu0Eey&-$glA%}Ou z_n2$Lpz7((cG590h_z`upeVxS5_c=xaw>Yk?1TTt%P%14AZkMI?E5Q*%px~!)kA*A zg6eBms9tYb-hN7!;Pkyz1t`VPC(1ir#pUQ@GvoZ%^-iV1$I%|&Y>LN)=2&C$F*MXw z5)IP)7oCpFG2GAP1A^uHC9IoZ)6U12qOOZ-AltgM$+gW7a$*Zbpc~~eT(8#z!H%4M z0ba+6E91BKqof)2ic?UL4gB^zx`MUFidImrhG6Vf0QaWhJLbgIVO%92t?nAU()`l5 z7><ckLiCghIV-zxrjKjWhlfX&BHBZg<iyWDvP35Vd|YHZJ!C73^e3FWXY|%i9$Weu z>e@7ORIChoClx<zDsYc$%N`3DD8H2!bAaQw*PRaZ+H4FoyxglE^pR?K^`S9EzUpZb z*I8=?gyyk-fo?R7D|wamhE9ob@-wzq4O7p(MZ%9yFRpcdn~r?^#q&e27?7n52?&AE z$nSaMws5%WQYdiOJ!NH#b6fJj^l)>0e?79MzQ}`Rxv-=l9cwZ^GUdYERo_t4Xp7S! z?m}l0GhA8`uXg7C3eMn|^?ZuEt{?g<itF<k*;oJYd8P%CFst|RVl<%|o=-<T_GUic zxLh6vU=+a2P1PrvjW(mY*OE;`tdlX|{6#VY({#VNOmHcl)!~lpvVxpXbj9SWZ>mWc zHj+l&&#u3}X%#4NX#S+kdXl=WLGfBecl8NlB*RmQSS^Q|H7%OmEFS3Z2iS)Zk@?m- zR9>aSeseNkK8p<Kubr=5Bg#3YntMw#(6}&3Dc4GMzl1KqY<r`~UubbWqSoS<;|@Fb zHftBNOlRDi;ZqM7Z<IFbFd7%nt=v>@G{I^G&|0&$meU4E;l9bH_=oTIhl|((Qs0RO zOJ!GiwEg>))pp>Vj?x?rQBs6mv%M=CSc&SnQ7?7YLOBJvV*1*Y0OKAUJiRWn;!@07 zwbkkR`i)T=N5qQ!x$!UE`#(O`8)DCh4?c*Sae@!6OUdYW)YdjNeza5faKXc;1fsmO z>bhwmCagX%Y^Qg~VrrdWsXq-;YyQj~KSCrAJ*HNFTw2i9I9{MXcgTHj6I?i+yDyxp zj_LEJAUIKUsR)Gv7*j7Yr@iaTr@`70RV8G4r+(E!r|*u%LcCZQ5cBS{?G<a_WwG;R zNzQ4(CA_FY3q<@u#mO$RTtf8*Vx`J6hCvN2k9%?r?jyclc{y8mK*=&S>j)Npv*_}Z zb?6z&kT#*D_4oT%>s*WUAD;vS`Fix=|Nfne6^^HAA&+(Q`TSkd`z#JKpsmo6tIlcP zu+eXm7~(O8mrA_0nTwT_kz5eEh{;-MhU@lVYKtkaU`~8#mL?2U7gvgBa(XFd-$b2! z$7ur%MNSFLs0=^3FsQ5h&-#s!JX1_}^JpY!WUdDVDMO&!3FXGEw;qvOujCoy<)Vv$ zFflaRrxRhLC)Y-F7zjXi8*++7MF4Iuz}=ltk^6@|1mKz+8AMc(!{>i?>@4rV;avzo z@5DoG4tTt6{Ndp}0`ReDWRoi!F}ttzPMYO9;6b^M`w1aI4+9Xg;!6{?oBwpBx(1EK z7H&4Dmp8OlveEL%X!>GszVoS7*op0p7PDi+U?)ZY3|qb6k(S|UP~spY*YwM<a|(>; z>8q|aW`j=VL~Qn~`XLLyDof~Wu2)%^5%=t9cieL_18<90(-%9%gI!W(Tw-e5bE=ej zdtY&vzVPsH|EMf@_et$bOR*@c{(TQ6r4+vd;q{9;Z}#EF>A?*qF8dd+4thw!r7&g2 zT0UO3ES?e+lwCLFk(6+7cIHe2sj>P|*t2^ki$_b}=v3VrM!DL4iZ7uG`fhXbL_4o! zUt+fT0^WfpC7!W=O|I$Tv)9~u_E?@n#byk1nIT(mp>AW6X_C>HsvEwrAi~jZ`lY+B zaZRlfo5qVNFY2yGH~V{1x%t?g$dl*RH<9c%90<UrZ#mb4Yxj;eyyrWlsebwezD%n3 z^F2JVerOR(=n}A~0H}K(lZ@-hoKpu;AF`{1yd7c$47F(Ai93zUzK=6Izbr2s$L-4> z5w5VaDqJi>04hFMY;7;N89gRF8PIGxdBy#ln{m3Mc2U(_cl}aLks@A6X`<;DkaDAV z^UlzUHmgkV)MQ{yf`Q0ac%8I{nRbYR7OG*VWyJMWbwRUFL-<NjC3!t%d4I}ZS9z4X z^#jm0(!XCyx}K#W#kYi_I((k8=2^lAa+3b<bac#5d@%>)J5JmLEP(5ohP_m-QFSA> z)l(N!EYWPy<1E@Wk=FbpTaC61XUYr#7Zoi?@`@r~?K>W&d=|=(s_pYS0!hYn@@tOZ z3Oc;4iDn>t+s4n8)$AaBFuj`xWGSdwG46<{WDlRE2yG2}FX_0Mxv%-MG`+RJ$vty0 z;E1f+W(rTsF}Tpwd|nWE_0Gnre>4&2s0ZLb?1ENFI+u98X!NP4`Av#nimDJHr(C4v zXj=FTXo(BUxrc$89AwiqVA3}!sV-b!K3-@dHJf#a-c1&-Vmm(*yBZaZX+SaF=BCVB zM0v+qWtmo9?08Ifvi1p#-B*|beW-3}AXbNf1gf2Xd1>+10DN9q1K_*GLBNMk1;3=* z$_C)?sq*cdzk%5KB_0{*e%MlS>j4dz_u3k!SvWM9NKP*AK|-AG1`Buji+N%xw#X8` z@cf2bx7rNIP&hrm7h3O!7S;q@jSFJI=2E8mha+t9m_Q*0c6PwQB@aKzs7tXEa!ydj z<ooTb`Ag|kpf5OY-r-guxUw5L>xfpyyXw0q#75_P-5A+Sez{8d#QeO9+IWa!=Ld!z z+VYD<{y3i{u0Bbrb$a@)RWSa_-duG*Yu$l*ewJjWDzQHBP;ei6@%xt#Gb2d!e` z#orDoy2@;OPn5&8Sg|z*r0pp^{5p3XX0kRL7eqP+PpsRrx__D*nUUDvr*@kyBKN#) zb@g9g`o+yQo{+PLKCi25I+ac$JIR*hW10PaV{}fzXy=!fcVn24Z28i<$=^Fhs=K{p zYcG5!EXifY$E90w0kgr7dA7;43Vnzm)tjsrLe-XTH%IU;Sqsf83dJom?W5>w)<waa zz{%YgCIPhBG3_KKei1$VZvyc5j0`3!Hi#Kxfr_-uS=@tWRWEs2F8cg--iBa1SYk;E zRaBfTl#^&TM{VJE8W`wNDaZeixZM$Bp*q&nX-){sN_Tg+g<ygGQ3e2>nXN>NH*;2N zt{=aS*2w_dJ7OikTpmJm*lZIS-;v)&_VsNqB%`1<u{qKXAerW?6T91+Oif}9)huf0 zi1PHIG~;z`pLMTjE2Iu0YdVtZq`@WNWJkm2KIY%&w{j#^?DrkBw!T(<ks9PQ1Pog$ zZGM@L_Ds<ysGwc%Dq^yI)7-L$YOKi9Q#t|o8sa_}=a>7Y;JM+|>t@w@5t=Lj#m@Uz zl}ApK3)C^DJyaHXf@Z<r14U0vf!f6<jVReVC$lXjXKF5^duQN}1eycGE49-L$>W_z zY<@+iMM*l-SE_>Lo27%L*}|%#1C&x+nCsveN!2x13O`}SEmgacl|`eaMM?J&np|KH zFN>=|7t7<o*HO2pmn|F=JijVZNbR{uefIEdd<4#35P7)q2Yg*^^<2{mU*-;$Fqst` zsBimOXj%r0+SXzoiw+7~M}FO>d7mw(>9)0944Xj!%rOdbm9zJyS?2_+B0uHE5Fao0 z=sM$;EG*SIVl!+NL_;)s=)GbUeW<{_>hrD2GT}#TiR-fy$szNBt|XmjWGnAj?C6V5 zHz<+YD4JFN?qug$cx6J};+sICV#&91lv1(a3ZT~0wwlC^mobHD`HR)BnS?`L%U<kk zj|ROEP&-=oN^Y3EyPu!3o5(6+t60;p)Th#{%~@RD_r+!@g^tuLF<V8;zw{bh6@GJ? z6}P%VDG6Fvy~O9p6^l;y!I9P|dX_T{4fd<zg-i+I(gq#O>9n4(@RG(@ZpAQK4;&|= zI6(nJ1MF?S0c}~?Wqx0K`p$21_m^iTXC$|ctPF25lFeM~nQ7in(Rf$M*_2EcCaW%k zp$LF?$Ld#cQ2zQuP@D(?5XJ*Nfkz>y?iCI=DY!fJ+7|&(L;;_CMgVY*&utI@84u*M z0c1|#zh?&SbS;OjkqZd{*c-&$K@er}r~?m+Di!XB54>l?H4CCaE)*<2gC#uoI%_9H z7J`Ptx5*bN*dxvT?`de?_VcSA3`qo@ImS$!tf;qzA7(BRu+XMahf~}d<~kUPPZKLO z)3&wDi<eiE-iXxfb()dv<DxoZJ~uW_FYvNkIPjU>R4BZ5FpNoei?s(nzg~?F<;S!T z*In^D*PV>r$X_s4`=uWxPZ_!I(=Tnk-1<txnlREN?4x>ULyssn^@pTw^x#!Ly4E?y ze80fHtS8Opy3{NrobjqStH(5(JMOo$?I*fI;-62e;#eD+8fzQWRp$5y@vL}@&^Yr` zcG?v^#2Y%+DXP{ii66e0e(^C?$rdcvdIp$3t14a@f<NZGuy{6IVQ<$~6T81JtF!g2 zUuoPbR6iI{P=890O=3cE2n2C=MaM}Nzh0h46FV@Q@n3SLI5u+*Y)}AIR@Q=v-#~b9 z)e{r*2~HE=qL%M<-w`{S-bq;eW=T?H%dKI=`)RS2Dy1|85QAZU&GD?-JDyxD{CY~s zpN|dwmNfl7UNhk9_$gs@t2x+3uuWp*dyG#>B0u_vSpG33Sp>jKUvVaCONXNv;?wi0 z4jSH)AGwowyRch%z3}Q>SnRGm|3U1M#(*$Pnn}eg1?u~Wn`v4w{q6p!V02C7_gBmO zbi4zxuNvu1=Ahd}j=A%LUz3}fr&+A&bPtColHv)12~;>St4w-M*_w(ROg=&&U*;w6 zo(LyuoObIaYKO6^6XaDqQz$NJQW6Qtdv91j%I(<?GYKgv1?hC!{$%Ic<W7vMbBz@; z%D=gCjTBv8C4sP<2^je<i$mFxon8Ie(jJ=1mP-8#_as}4&J(Fb2S(YMPoy#YSBWeF zVchtv!2-t9JCJw`+vXSknLRt7v8Py8f$WqULgUMeU2M5$#-@==#KXM9BLtnY=ABP$ zGInU87>;W|&S8=I^uQai<-6s=V7oQiH-0Nxkk*MK*ZL-g-yMgl_$lcmp?)NTk!Hm= zM#T(|l^ycRv{(<f$BYHjTM`(Rqr`~UZJBG205ra$RjD0o95YVs<7<4y%?oJ@1}O73 z_VIXxYiJ4Qn=~*=u_^=T(OS(<*X8vCZ4ThGRBcoF$n;HnG1=GK@`MbkS8_B!p}B~@ zegU0yRmVUCz~C<NCX=|tdv>R6$q(F1-uyym&$-Z)1w~izP9_a2(z7PinNb<S=}+5d z)C>*YiT`e*mOjo#{9_^`R!!jb#({oBgtr{kL&H(L3Yv?&s;-jTqLzh!Nkx!|%fZ&l zii)`$UkS3B<rXuVx#^N&YAGoK5sL8~519xHmL&Nk<A!hnJlC3^X7Zzru(MB?V`6)u zVwFr&Ch*bZg-HdM;V&z=c9uy^Mg)AF8|TGB&L%y|bxA5S^@8Cb5-!RgYx)gn7%x~o z_p-Zdy^c7KdDviFk;fn2h4we1f5gCIjNHNec64GiR~4DDMx|r0zr5leRX|bn!@T}9 zZ;za#e5s;0ozg%6=)9who+wOK5X%ep%_{GFE|A4#V|H3tvi`BszCKkc=~ZT)$ljwm z?cvBs)Y?e6dqTJ_V7#Q#WJPuA0s#=@F8Qv%n6fTF6&;hFieJ5ROcLkd1fDmfI%-W( zV)h}c6?~*nTHIy80(3-){mnI6rAZ1>A}%=zIPjeduDF(IlRwLfT=+WhDp4pDMj9>_ z<sX6RGTY^ZzCWy_OnG!*+Q6s&Xex$T=W%llj^qlvA6?WcP<p+|TtW8~@2jMbZ=(NA z>JIRA>|>E(+D=TG^LVYC%iW#YiS{06Qlj?h<?pT%`NXeD`#t0R`+32f<vcY#=UVz- z4V@o`S1JpnLB>KQrB@>4tf~4_d5zxA1@YzlB!?qskS(*yCi)1TL=FCxS8<xiF9p5R zq=HWKUDO-scs|d>VU_P+%p$jHDP*H=h<?N~%G#+$B_aT#lsEEQwFxH{&K~i8?{%|Z zHK*VUubDHS7d~QYdZsz^NRu>939ZURixPWQzf{9RL#j>U0^UIVUT0ff?+YFEX={w5 zFKx>75Wgy)d}$tYxW=J}{{SVKvi6Mg#U~Ey?|!=5%ht9El+icQ{+;ZSNy%f%Y;8FB z0fg8V99f&cT%EXFdNsx{DC`KdY(^!Fr!F*%+S|R-RV#~<cmiqE?5uu<4!m!9Hw7UZ z`m)MlwHv5XLB26hhTSAV)0UD$wwz3MR1A_Y?0jV`-zaL0W}A=!C&RDrnm$e%w<6_D z^gU*9m3$2>KIwBd*>Cu%E>yos_bTS=BjVi5F}ckz{ir2}7+|XXP3Z6C7?Js5lcgap z0r`ea6}(_2zNC0DF|@s?GmsVU^_L>-{N}<6``hQYN4F_kEW`8J@Q|a9(-k;p^f+>! z^jWz^{;!8j>+DkI=G1aHjz<r<E+)G#n}&B<{@Gss($<lH_*ueYYWiyqxQ3f%@19oz z_y+t?y;K|!uM|L6KcqEnsIi)TLx`Mh%~oy<ghHNxFphPnc`kQ4o-~J@@zeewej3zP zLFeX6&f4tWSsuebXE<|`7jKri7BP0*7ap+sI%;~RV^g>Tws<=ehlv0T{Jf2tq{crs zs=l@>{c*sw+(Q*U*lF!2>D6aZd+qG(SLj&Q9~UTXAcRT5;x-B=J226@Ex4VLl6XMQ z5&>Edc(eQ^T*tamqLCr=Z%8C#I7P9#+^XIxiEq#V+g=9otd*Hw)jMj5ZN-fmByImH z3tP-MH!rBVhadn!;9a4Q{s;i$E&^~cfdE`E>W#8bJ2R)YXs}^``DbiH1-EcG79oYp z8G(jh_lftK3(ky9Ov_a{a7MOrp8{we8?w7yR>{qPXMTelXSN#X&uAhJ9`Nzmz54x9 zBU=TE<{f$$RIVOrhn@o{FcLn>qBuoAM{^72Gs|6C`u!Uu(x58|S)4IY-F!XjJQz!! z;LCURE2xNa0U%w!7s8GJ#OJRZ$2}03oIT*erM<xU;9C;I-gQQbCKhkn*>^?8<_@Y) zN+{Zzf&QDxaErIR0F*^cz|~GgfEpTG8unD@_l7J=tZ+uiPPkdgGlIj@IWZ~6Q0U2h zv<$3Y>j5wawn6|H)Cq65yb*vrs@A8fLxT4R0CSaH&aWWJIo5XQ$et-W$eD}FiTXtx z``B1OW-o+YGRtwiTu4gc4tyu=|4CwtNbZL}o|x15M2n#+6atsKTDgSETs*22UxX_M zf^T<MM!9}_Cgy#}yi~tW-LxVrk2A8w?jB~bS4s69BN82d`BuYh8cqRHbz+A!#;YxD z24zaQf8E2p4-~mW0A`yr72uNV$cO*|;Jg*DXQwn4Fp}qwaym7a=_XoUvV3!OrNLs) zaz^_uQSq6|7KBG$^uQu`og32vIxQj|`!SfBwOyfG{{_W2O4iUpQ>hTw@wULMBxJYm zbsS_^-tv`&o(|l<^R_JS7&Mq>q@30LtQQiwm6hPb^~NWl_f{&rs-nJ8L$)}k;>v{@ zzU$>gSb~4;Q_0*9=bXFeDh8b?f}FXNdtQ?;-+W7|AN$>CA#N2LTsHemX7dHK<8JnH zU4~L-dKY{-jR5Q_wMpu#wc0pSfy2t(ty1}Y#qS7-m&^pYoj&0>Sj&-Sq}ky3WW@Zs ziQK88yQy@c7E15^YWRWsBcyRU#FOcvYd_fcwcD@3%femo>B-v4oinoMOsYUDXU0K1 z@HM!GWukauiN#dl$fa@(H{)(V-^sg*Bk76Y{2xCbvD)hTNyQo-S4*8?IKH3Z3H!{f zTwM>Tez--Qow#v0BfINES!nfMjLvf7vp7f2=M29U;LY?8IPLy(9h;mTmlxT$_`zC_ z=SpZ;NG<zVvJ2852t_c<S_CWW2ER=ug0x9TDwk4NxKRB!618X@g2h}eOm|xqfF2VK z=<nZ**tP3r?6A`WbHb~T*edO{V8PNW`ZLT3coPr&1J^dq*ZO9`xsrX8+f4F%?lw<& sV8_E<-2GGJA^=he9!CcL9q!1qKR($G0^qm--q~607@V3{s6ovC4**q7tN;K2 literal 0 HcmV?d00001 From 19cf7d71f7e1491287d8533c337bd8035b07620d Mon Sep 17 00:00:00 2001 From: zhouhai <850168627@qq.com> Date: Thu, 2 Feb 2023 16:45:14 +0800 Subject: [PATCH 413/679] optimize performance when the cache exists, the attribute _lastPerInstanceAttributeIndex will fail --- packages/engine/Source/Scene/Primitive.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index 2ac5e23c073..e0dc421958f 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -2426,6 +2426,8 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { if (index === -1) { return undefined; } + + this._lastPerInstanceAttributeIndex = index; let attributes = this._perInstanceAttributeCache[index]; if (defined(attributes)) { @@ -2451,7 +2453,6 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { createPickIdProperty(this, properties, index); Object.defineProperties(attributes, properties); - this._lastPerInstanceAttributeIndex = index; this._perInstanceAttributeCache[index] = attributes; return attributes; }; From bbfafdf20af16b8703cbf1feeeca3caf96854038 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 13:14:48 -0500 Subject: [PATCH 414/679] Flatten if blocks in IntersectBox.glsl --- .../Source/Shaders/Voxels/IntersectBox.glsl | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index dab42c42cb1..8ac488ee151 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -7,15 +7,13 @@ #define BOX_IS_2D */ -#if defined(BOX_HAS_RENDER_BOUNDS) - #if defined(BOX_IS_2D) - // This matrix bakes in an axis conversion so that the math works for XY plane. - uniform mat4 u_boxUvToRenderBoundsTransform; - #else - // Similar to u_boxTransformUvToBounds but fewer instructions needed. - uniform vec3 u_boxUvToRenderBoundsScale; - uniform vec3 u_boxUvToRenderBoundsTranslate; - #endif +#if defined(BOX_IS_2D) + // This matrix bakes in an axis conversion so that the math works for XY plane. + uniform mat4 u_boxUvToRenderBoundsTransform; +#elif defined(BOX_HAS_RENDER_BOUNDS) + // Similar to u_boxTransformUvToBounds but fewer instructions needed. + uniform vec3 u_boxUvToRenderBoundsScale; + uniform vec3 u_boxUvToRenderBoundsTranslate; #endif struct Box { @@ -98,19 +96,17 @@ vec2 intersectUnitSquare(in Ray ray) // Unit square from [-1, +1] void intersectShape(in Ray ray, inout Intersections ix) { - #if defined(BOX_HAS_RENDER_BOUNDS) - #if defined(BOX_IS_2D) - // Transform the ray into unit square space on Z plane - // This matrix bakes in an axis conversion so that the math works for XY plane. - ray.pos = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.dir, 0.0)); - vec2 entryExit = intersectUnitSquare(ray); - #else - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxUvToRenderBoundsScale + u_boxUvToRenderBoundsTranslate; - ray.dir *= u_boxUvToRenderBoundsScale; - vec2 entryExit = intersectUnitCube(ray); - #endif + #if defined(BOX_IS_2D) + // Transform the ray into unit square space on Z plane + // This matrix bakes in an axis conversion so that the math works for XY plane. + ray.pos = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.pos, 1.0)); + ray.dir = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.dir, 0.0)); + vec2 entryExit = intersectUnitSquare(ray); + #elif defined(BOX_HAS_RENDER_BOUNDS) + // Transform the ray into unit cube space + ray.pos = ray.pos * u_boxUvToRenderBoundsScale + u_boxUvToRenderBoundsTranslate; + ray.dir *= u_boxUvToRenderBoundsScale; + vec2 entryExit = intersectUnitCube(ray); #else // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. // Direction is scaled as well to be in sync with position. From f82d59a92b9cdbaa2240d4c726ddd247e12e64f7 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 14:23:49 -0500 Subject: [PATCH 415/679] voxels: simplify box intersections --- .../engine/Source/Shaders/Voxels/IntersectBox.glsl | 13 +++++-------- packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 6 ++++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 8ac488ee151..bcbce252d21 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -40,7 +40,7 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) // Find the distances along a ray at which the ray intersects an axis-aligned box // See https://tavianator.com/2011/ray_box.html -vec2 intersectBox(in Ray ray, in Box box, in vec2 entryExit) +vec2 intersectBox(in Ray ray, in Box box) { // Consider the box as the intersection of the space between 3 pairs of parallel planes // Compute the distance along the ray to each plane @@ -48,8 +48,8 @@ vec2 intersectBox(in Ray ray, in Box box, in vec2 entryExit) vec3 t1 = (box.p1 - ray.pos) * ray.dInv; // Identify candidate entries/exits based on distance from ray.pos - vec3 entries = max(min(t0, t1), entryExit.x); - vec3 exits = min(max(t0, t1), entryExit.y); + vec3 entries = min(t0, t1); + vec3 exits = max(t0, t1); // The actual box intersection points are the furthest entry and the closest exit float entry = max(max(entries.x, entries.y), entries.z); @@ -108,11 +108,8 @@ void intersectShape(in Ray ray, inout Intersections ix) ray.dir *= u_boxUvToRenderBoundsScale; vec2 entryExit = intersectUnitCube(ray); #else - // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1]. - // Direction is scaled as well to be in sync with position. - ray.pos = ray.pos * 2.0 - 1.0; - ray.dir = ray.dir * 2.0; - vec2 entryExit = intersectUnitCube(ray); + Box box = Box(vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0)); + vec2 entryExit = intersectBox(ray, box); #endif setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 7f0211053b5..009838a3ed9 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -31,8 +31,10 @@ float hash(vec2 p) float getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); - vec2 voxelIntersection = intersectBox(viewRay, voxelBox, entryExit); - return (voxelIntersection.y - voxelIntersection.x); + vec2 voxelIntersection = intersectBox(viewRay, voxelBox); + float entry = max(voxelIntersection.x, entryExit.x); + float exit = min(voxelIntersection.y, entryExit.y); + return (exit - entry); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); return u_stepSize / dimAtLevel; From f1c491a8d87cd4e21cf18b03096cb55eab2df205 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 16:18:30 -0500 Subject: [PATCH 416/679] voxels: simplify box render bounds --- packages/engine/Source/Scene/VoxelBoxShape.js | 127 +++--------------- .../Source/Shaders/Voxels/IntersectBox.glsl | 63 +-------- 2 files changed, 22 insertions(+), 168 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelBoxShape.js b/packages/engine/Source/Scene/VoxelBoxShape.js index a08e333f73a..d379850a0a4 100644 --- a/packages/engine/Source/Scene/VoxelBoxShape.js +++ b/packages/engine/Source/Scene/VoxelBoxShape.js @@ -76,9 +76,8 @@ function VoxelBoxShape() { * @readonly */ this.shaderUniforms = { - boxUvToRenderBoundsTransform: new Matrix4(), - boxUvToRenderBoundsScale: new Cartesian3(), - boxUvToRenderBoundsTranslate: new Cartesian3(), + renderMinBounds: new Cartesian3(), + renderMaxBounds: new Cartesian3(), boxUvToShapeUvScale: new Cartesian3(), boxUvToShapeUvTranslate: new Cartesian3(), }; @@ -89,9 +88,7 @@ function VoxelBoxShape() { */ this.shaderDefines = { BOX_INTERSECTION_INDEX: undefined, - BOX_HAS_RENDER_BOUNDS: undefined, BOX_HAS_SHAPE_BOUNDS: undefined, - BOX_IS_2D: undefined, }; /** @@ -105,34 +102,14 @@ function VoxelBoxShape() { const scratchCenter = new Cartesian3(); const scratchScale = new Cartesian3(); const scratchRotation = new Matrix3(); -const scratchTransformLocalToBounds = new Matrix4(); -const scratchBoundsTranslation = new Cartesian3(); -const scratchBoundsScale = new Cartesian3(); -const scratchBoundsScaleMatrix = new Matrix3(); const scratchClipMinBounds = new Cartesian3(); const scratchClipMaxBounds = new Cartesian3(); const scratchRenderMinBounds = new Cartesian3(); const scratchRenderMaxBounds = new Cartesian3(); -const transformUvToLocal = Matrix4.fromRotationTranslation( - Matrix3.fromUniformScale(2.0, new Matrix3()), - new Cartesian3(-1.0, -1.0, -1.0), - new Matrix4() -); - -const transformXYZToZYX = Matrix4.fromRotation( - Matrix3.fromColumnMajorArray( - [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0], - new Matrix3() - ), - new Matrix4() -); - -const transformXYZToXZY = Matrix4.fromRotation( - Matrix3.fromColumnMajorArray( - [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0], - new Matrix3() - ), +const transformLocalToUv = Matrix4.fromRotationTranslation( + Matrix3.fromUniformScale(0.5, new Matrix3()), + new Cartesian3(0.5, 0.5, 0.5), new Matrix4() ); @@ -253,8 +230,7 @@ VoxelBoxShape.prototype.update = function ( this.boundingSphere ); - const shaderUniforms = this.shaderUniforms; - const shaderDefines = this.shaderDefines; + const { shaderUniforms, shaderDefines } = this; // To keep things simple, clear the defines every time for (const key in shaderDefines) { @@ -263,21 +239,9 @@ VoxelBoxShape.prototype.update = function ( } } - const hasRenderBounds = - renderMinBounds.x !== defaultMinBounds.x || - renderMaxBounds.x !== defaultMaxBounds.x || - renderMinBounds.y !== defaultMinBounds.y || - renderMaxBounds.y !== defaultMaxBounds.y || - renderMinBounds.z !== defaultMinBounds.z || - renderMaxBounds.z !== defaultMaxBounds.z; - const hasShapeBounds = - minBounds.x !== defaultMinBounds.x || - maxBounds.x !== defaultMaxBounds.x || - minBounds.y !== defaultMinBounds.y || - maxBounds.y !== defaultMaxBounds.y || - minBounds.z !== defaultMinBounds.z || - maxBounds.z !== defaultMaxBounds.z; + !Cartesian3.equals(minBounds, defaultMinBounds) || + !Cartesian3.equals(maxBounds, defaultMaxBounds); // Keep track of how many intersections there are going to be. let intersectionCount = 0; @@ -285,71 +249,16 @@ VoxelBoxShape.prototype.update = function ( shaderDefines["BOX_INTERSECTION_INDEX"] = intersectionCount; intersectionCount += 1; - if (hasRenderBounds) { - shaderDefines["BOX_HAS_RENDER_BOUNDS"] = true; - - const min = renderMinBounds; - const max = renderMaxBounds; - - // inverse(scale) - // inverse(maxBoundsUv - minBoundsUv) - // inverse((maxBounds * 0.5 + 0.5) - (minBounds * 0.5 + 0.5)) - // inverse(0.5 * (maxBounds - minBounds)) - // 2.0 / (maxBounds - minBounds) // with divide by zero protection - const scaleLocalToBounds = Cartesian3.fromElements( - 2.0 / (min.x === max.x ? 1.0 : max.x - min.x), - 2.0 / (min.y === max.y ? 1.0 : max.y - min.y), - 2.0 / (min.z === max.z ? 1.0 : max.z - min.z), - scratchBoundsScale - ); - - // -inverse(scale) * translation // affine inverse - // -inverse(scale) * 0.5 * (minBounds + maxBounds) - const translateLocalToBounds = Cartesian3.fromElements( - -scaleLocalToBounds.x * 0.5 * (min.x + max.x), - -scaleLocalToBounds.y * 0.5 * (min.y + max.y), - -scaleLocalToBounds.z * 0.5 * (min.z + max.z), - scratchBoundsTranslation - ); - - let transformLocalToBounds = Matrix4.fromRotationTranslation( - Matrix3.fromScale(scaleLocalToBounds, scratchBoundsScaleMatrix), - translateLocalToBounds, - scratchTransformLocalToBounds - ); - - if (min.x === max.x || min.y === max.y || min.z === max.z) { - shaderDefines["BOX_IS_2D"] = true; - - let transformAxisConversion; - if (min.x === max.x) { - transformAxisConversion = transformXYZToZYX; - } else if (min.y === max.y) { - transformAxisConversion = transformXYZToXZY; - } else if (min.z === max.z) { - transformAxisConversion = Matrix4.IDENTITY; - } - transformLocalToBounds = Matrix4.multiplyTransformation( - transformAxisConversion, - transformLocalToBounds, - transformLocalToBounds - ); - } - - shaderUniforms.boxUvToRenderBoundsTransform = Matrix4.multiplyTransformation( - transformLocalToBounds, - transformUvToLocal, - shaderUniforms.boxUvToRenderBoundsTransform - ); - shaderUniforms.boxUvToRenderBoundsScale = Matrix4.getScale( - shaderUniforms.boxUvToRenderBoundsTransform, - shaderUniforms.boxUvToRenderBoundsScale - ); - shaderUniforms.boxUvToRenderBoundsTranslate = Matrix4.getTranslation( - shaderUniforms.boxUvToRenderBoundsTransform, - shaderUniforms.boxUvToRenderBoundsTranslate - ); - } + shaderUniforms.renderMinBounds = Matrix4.multiplyByPoint( + transformLocalToUv, + renderMinBounds, + shaderUniforms.renderMinBounds + ); + shaderUniforms.renderMaxBounds = Matrix4.multiplyByPoint( + transformLocalToUv, + renderMaxBounds, + shaderUniforms.renderMaxBounds + ); if (hasShapeBounds) { shaderDefines["BOX_HAS_SHAPE_BOUNDS"] = true; diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index bcbce252d21..33e72b5a516 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -3,18 +3,10 @@ /* Box defines (set in Scene/VoxelBoxShape.js) #define BOX_INTERSECTION_INDEX ### // always 0 -#define BOX_HAS_RENDER_BOUNDS -#define BOX_IS_2D */ -#if defined(BOX_IS_2D) - // This matrix bakes in an axis conversion so that the math works for XY plane. - uniform mat4 u_boxUvToRenderBoundsTransform; -#elif defined(BOX_HAS_RENDER_BOUNDS) - // Similar to u_boxTransformUvToBounds but fewer instructions needed. - uniform vec3 u_boxUvToRenderBoundsScale; - uniform vec3 u_boxUvToRenderBoundsTranslate; -#endif +uniform vec3 u_renderMinBounds; +uniform vec3 u_renderMaxBounds; struct Box { vec3 p0; @@ -55,62 +47,15 @@ vec2 intersectBox(in Ray ray, in Box box) float entry = max(max(entries.x, entries.y), entries.z); float exit = min(min(exits.x, exits.y), exits.z); - if (entry >= exit) { + if (entry > exit) { return vec2(NO_HIT); } return vec2(entry, exit); } -vec2 intersectUnitCube(in Ray ray) // Unit cube from [-1, +1] -{ - vec3 dInv = 1.0 / ray.dir; - vec3 od = -ray.pos * dInv; - vec3 t0 = od - dInv; - vec3 t1 = od + dInv; - vec3 m0 = min(t0, t1); - vec3 m1 = max(t0, t1); - float tMin = max(max(m0.x, m0.y), m0.z); - float tMax = min(min(m1.x, m1.y), m1.z); - - if (tMin >= tMax) { - return vec2(NO_HIT); - } - - return vec2(tMin, tMax); -} - -vec2 intersectUnitSquare(in Ray ray) // Unit square from [-1, +1] -{ - vec3 o = ray.pos; - vec3 d = ray.dir; - - float t = -o.z / d.z; - vec2 planePos = o.xy + d.xy * t; - if (any(greaterThan(abs(planePos), vec2(1.0)))) { - return vec2(NO_HIT); - } - - return vec2(t, t); -} - void intersectShape(in Ray ray, inout Intersections ix) { - #if defined(BOX_IS_2D) - // Transform the ray into unit square space on Z plane - // This matrix bakes in an axis conversion so that the math works for XY plane. - ray.pos = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.pos, 1.0)); - ray.dir = vec3(u_boxUvToRenderBoundsTransform * vec4(ray.dir, 0.0)); - vec2 entryExit = intersectUnitSquare(ray); - #elif defined(BOX_HAS_RENDER_BOUNDS) - // Transform the ray into unit cube space - ray.pos = ray.pos * u_boxUvToRenderBoundsScale + u_boxUvToRenderBoundsTranslate; - ray.dir *= u_boxUvToRenderBoundsScale; - vec2 entryExit = intersectUnitCube(ray); - #else - Box box = Box(vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0)); - vec2 entryExit = intersectBox(ray, box); - #endif - + vec2 entryExit = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds)); setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); } From 6cc387df3404958389fc96121a7c1a50748050b7 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 16:30:00 -0500 Subject: [PATCH 417/679] Resolve TODO comments --- .../Source/Shaders/Voxels/IntersectionUtils.glsl | 1 - packages/engine/Source/Shaders/Voxels/Octree.glsl | 2 +- packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 11 ++--------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index dbc9a9cc488..58c19b58119 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -131,7 +131,6 @@ vec2 nextIntersection(inout Intersections ix) { } // exiting positive or entering negative after being inside positive - // TODO: Can this be simplified? bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; if (exitPositive || enterNegativeFromPositive) { diff --git a/packages/engine/Source/Shaders/Voxels/Octree.glsl b/packages/engine/Source/Shaders/Voxels/Octree.glsl index 40a4ae86730..5d27cad9053 100644 --- a/packages/engine/Source/Shaders/Voxels/Octree.glsl +++ b/packages/engine/Source/Shaders/Voxels/Octree.glsl @@ -78,7 +78,7 @@ int getOctreeParentIndex(in int octreeIndex) { * into the uv-space of a tile within the tileset */ vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) { - // TODO: use bit-shifting (only in WebGL2) + // PERFORMANCE_IDEA: use bit-shifting (only in WebGL2) float dimAtLevel = pow(2.0, float(octreeCoords.w)); return shapePosition * dimAtLevel - vec3(octreeCoords.xyz); } diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 009838a3ed9..cdae445b2c7 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -67,7 +67,6 @@ void main() float currT = entryExitT.x + 0.0001; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; - // TODO: is it possible for this to be out of bounds, and does it matter? vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); // Traverse the tree from the start position @@ -76,10 +75,6 @@ void main() traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); float stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); - // TODO: - // - jitter doesn't affect the first traversal? - // - jitter is always > 0? - // - jitter is only applied at one step? #if defined(JITTER) float noise = hash(screenCoord); // [0,1] currT += noise * stepT; @@ -125,10 +120,8 @@ void main() } if (stepT == 0.0) { - // Shape is infinitely thin, no need to traverse further - // TODO: this doesn't happen? - // Even if the shape is thin, won't we have currT > endT? (see below) - //break; + // Shape is infinitely thin. The ray may have hit the edge of a + // foreground voxel. Step ahead slightly to check for more voxels stepT == 0.00001; } From fc949a7db4608e9a4a60d000c07506e2c32bfa06 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 19:06:44 -0500 Subject: [PATCH 418/679] Always use vec2s for intersections --- .../Shaders/Voxels/IntersectionUtils.glsl | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 58c19b58119..01d92202819 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -16,50 +16,30 @@ struct Ray { struct Intersections { // Don't access these member variables directly - call the functions instead. - #if (INTERSECTION_COUNT > 1) - // Store an array of intersections. Each intersection is composed of: - // x for the T value - // y for the shape type - which encodes positive vs negative and entering vs exiting - // For example: - // y = 0: positive shape entry - // y = 1: positive shape exit - // y = 2: negative shape entry - // y = 3: negative shape exit - vec2 intersections[INTERSECTION_COUNT * 2]; + // Store an array of intersections. Each intersection is composed of: + // x for the T value + // y for the shape type - which encodes positive vs negative and entering vs exiting + // For example: + // y = 0: positive shape entry + // y = 1: positive shape exit + // y = 2: negative shape entry + // y = 3: negative shape exit + vec2 intersections[INTERSECTION_COUNT * 2]; + #if (INTERSECTION_COUNT > 1) // Maintain state for future nextIntersection calls int index; int surroundCount; bool surroundIsPositive; - #else - // When there's only one positive shape intersection none of the extra stuff is needed. - float intersections[2]; #endif }; -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x -#else - #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)] -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. +// Use defines instead of real functions because WebGL1 cannot access array with non-constant index. +#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x #define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) -#else - #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t) -#endif - -// Using a define instead of a real function because WebGL1 cannot access array with non-constant index. -#if (INTERSECTION_COUNT > 1) - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) -#else - #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y -#endif +#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) +#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) #if (INTERSECTION_COUNT > 1) void initializeIntersections(inout Intersections ix) { @@ -150,4 +130,3 @@ vec2 nextIntersection(inout Intersections ix) { #endif // NOTE: initializeIntersections, nextIntersection aren't even declared unless INTERSECTION_COUNT > 1 -// export { NO_HIT, INF_HIT, Ray, Intersections, getIntersectionPair, setIntersectionPair, initializeIntersections, nextIntersection }; From 16a8e31c6224ece2383e4e3626e101c9ebf5a60f Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 19:10:57 -0500 Subject: [PATCH 419/679] voxels: simplify initializeIntersections --- .../Source/Shaders/Voxels/IntersectionUtils.glsl | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 01d92202819..1efa4581f10 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -56,18 +56,10 @@ void initializeIntersections(inout Intersections ix) { vec2 intersect0 = ix.intersections[i + 0]; vec2 intersect1 = ix.intersections[i + 1]; - float t0 = intersect0.x; - float t1 = intersect1.x; - float b0 = intersect0.y; - float b1 = intersect1.y; - - float tmin = min(t0, t1); - float tmax = max(t0, t1); - float bmin = tmin == t0 ? b0 : b1; - float bmax = tmin == t0 ? b1 : b0; - - ix.intersections[i + 0] = vec2(tmin, bmin); - ix.intersections[i + 1] = vec2(tmax, bmax); + bool inOrder = intersect0.x <= intersect1.x; + + ix.intersections[i + 0] = inOrder ? intersect0 : intersect1; + ix.intersections[i + 1] = inOrder ? intersect1 : intersect0; } } From dfe5b2c9b56197d045ea3ad9b0b75a8fa4dfd959 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 19:17:33 -0500 Subject: [PATCH 420/679] voxels: Add surfaceNormal to fsInput, fill with dummy --- packages/engine/Source/Scene/processVoxelProperties.js | 1 + packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/engine/Source/Scene/processVoxelProperties.js b/packages/engine/Source/Scene/processVoxelProperties.js index 46dc60fd613..b4197beff2d 100644 --- a/packages/engine/Source/Scene/processVoxelProperties.js +++ b/packages/engine/Source/Scene/processVoxelProperties.js @@ -151,6 +151,7 @@ function processVoxelProperties(renderResources, primitive) { shaderBuilder.addStructField(voxelStructId, "vec3", "positionUvLocal"); shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirUv"); shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld"); + shaderBuilder.addStructField(voxelStructId, "vec3", "surfaceNormal"); shaderBuilder.addStructField(voxelStructId, "float", "travelDistance"); // FragmentInput struct diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index cdae445b2c7..8f41c3c1fe3 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -99,6 +99,7 @@ void main() fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv; fragmentInput.voxel.viewDirUv = viewDirUv; fragmentInput.voxel.viewDirWorld = viewDirWorld; + fragmentInput.voxel.surfaceNormal = viewRayUv.dir; fragmentInput.voxel.travelDistance = stepT; // Run the custom shader From 19c61e6c86485c4409df1207214f019594728a9d Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 19:28:01 -0500 Subject: [PATCH 421/679] voxels: use vec4s for intersections --- .../Shaders/Voxels/IntersectionUtils.glsl | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 1efa4581f10..14ae017c52e 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -17,14 +17,14 @@ struct Intersections { // Don't access these member variables directly - call the functions instead. // Store an array of intersections. Each intersection is composed of: - // x for the T value + // w for the T value // y for the shape type - which encodes positive vs negative and entering vs exiting // For example: // y = 0: positive shape entry // y = 1: positive shape exit // y = 2: negative shape entry // y = 3: negative shape exit - vec2 intersections[INTERSECTION_COUNT * 2]; + vec4 intersections[INTERSECTION_COUNT * 2]; #if (INTERSECTION_COUNT > 1) // Maintain state for future nextIntersection calls @@ -35,11 +35,11 @@ struct Intersections { }; // Use defines instead of real functions because WebGL1 cannot access array with non-constant index. -#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x +#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].w #define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) -#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter)) -#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0) +#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec4(0.0, float(!positive) * 2.0 + float(!enter), 0.0, (t)) +#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec4(0.0, float((index) > 0) * 2.0 + 0.0, 0.0, (entryExit).x); (ix).intersections[(index) * 2 + 1] = vec4(0.0, float((index) > 0) * 2.0 + 1.0, 0.0, (entryExit).y) #if (INTERSECTION_COUNT > 1) void initializeIntersections(inout Intersections ix) { @@ -53,10 +53,10 @@ void initializeIntersections(inout Intersections ix) { // loop with non-constant condition, so it has to break early instead if (i >= n) { break; } - vec2 intersect0 = ix.intersections[i + 0]; - vec2 intersect1 = ix.intersections[i + 1]; + vec4 intersect0 = ix.intersections[i + 0]; + vec4 intersect1 = ix.intersections[i + 1]; - bool inOrder = intersect0.x <= intersect1.x; + bool inOrder = intersect0.w <= intersect1.w; ix.intersections[i + 0] = inOrder ? intersect0 : intersect1; ix.intersections[i + 1] = inOrder ? intersect1 : intersect0; @@ -89,8 +89,8 @@ vec2 nextIntersection(inout Intersections ix) { ix.index = i + 1; - vec2 intersect = ix.intersections[i]; - float t = intersect.x; + vec4 intersect = ix.intersections[i]; + float t = intersect.w; bool currShapeIsPositive = intersect.y < 2.0; bool enter = mod(intersect.y, 2.0) == 0.0; From 8d9a30992eb5d62d7c21f33c484dc1c8b9f01f50 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 19:51:08 -0500 Subject: [PATCH 422/679] voxels: use normal length to encode intersection type --- .../Shaders/Voxels/IntersectionUtils.glsl | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 14ae017c52e..19b4c6e2174 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -16,14 +16,16 @@ struct Ray { struct Intersections { // Don't access these member variables directly - call the functions instead. - // Store an array of intersections. Each intersection is composed of: - // w for the T value - // y for the shape type - which encodes positive vs negative and entering vs exiting - // For example: - // y = 0: positive shape entry - // y = 1: positive shape exit - // y = 2: negative shape entry - // y = 3: negative shape exit + // Store an array of ray-surface intersections. Each intersection is composed of: + // .xyz for the surface normal at the intersection point + // .w for the T value + // The scale of the normal encodes the shape intersection type: + // length(intersection.xyz) = 1: positive shape entry + // length(intersection.xyz) = 2: positive shape exit + // length(intersection.xyz) = 3: negative shape entry + // length(intersection.xyz) = 4: negative shape exit + // INTERSECTION_COUNT is the number of ray-*shape* (volume) intersections, + // so we need twice as many to track ray-*surface* intersections vec4 intersections[INTERSECTION_COUNT * 2]; #if (INTERSECTION_COUNT > 1) @@ -38,8 +40,8 @@ struct Intersections { #define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].w #define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) -#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec4(0.0, float(!positive) * 2.0 + float(!enter), 0.0, (t)) -#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec4(0.0, float((index) > 0) * 2.0 + 0.0, 0.0, (entryExit).x); (ix).intersections[(index) * 2 + 1] = vec4(0.0, float((index) > 0) * 2.0 + 1.0, 0.0, (entryExit).y) +#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*bool*/ enter) (ix).intersections[(index)] = vec4(0.0, float(!positive) * 2.0 + float(!enter) + 1.0, 0.0, (t)) +#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec4(0.0, float((index) > 0) * 2.0 + 1.0, 0.0, (entryExit).x); (ix).intersections[(index) * 2 + 1] = vec4(0.0, float((index) > 0) * 2.0 + 2.0, 0.0, (entryExit).y) #if (INTERSECTION_COUNT > 1) void initializeIntersections(inout Intersections ix) { @@ -91,8 +93,9 @@ vec2 nextIntersection(inout Intersections ix) { vec4 intersect = ix.intersections[i]; float t = intersect.w; - bool currShapeIsPositive = intersect.y < 2.0; - bool enter = mod(intersect.y, 2.0) == 0.0; + float intersectionType = length(intersect.xyz) - 1.0; + bool currShapeIsPositive = intersectionType < 2.0; + bool enter = mod(intersectionType, 2.0) == 0.0; ix.surroundCount += enter ? +1 : -1; ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; From 69457caffa3f6fb0c94da817e9860185e050b890 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 20:15:31 -0500 Subject: [PATCH 423/679] voxels: define struct for shape intersections --- .../Source/Shaders/Voxels/IntersectBox.glsl | 19 +++++++++++-------- .../Shaders/Voxels/IntersectionUtils.glsl | 6 ++++++ .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 6 +++--- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 33e72b5a516..6305ff657e0 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -32,7 +32,7 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) // Find the distances along a ray at which the ray intersects an axis-aligned box // See https://tavianator.com/2011/ray_box.html -vec2 intersectBox(in Ray ray, in Box box) +RayShapeIntersection intersectBox(in Ray ray, in Box box) { // Consider the box as the intersection of the space between 3 pairs of parallel planes // Compute the distance along the ray to each plane @@ -44,18 +44,21 @@ vec2 intersectBox(in Ray ray, in Box box) vec3 exits = max(t0, t1); // The actual box intersection points are the furthest entry and the closest exit - float entry = max(max(entries.x, entries.y), entries.z); - float exit = min(min(exits.x, exits.y), exits.z); + float entryT = max(max(entries.x, entries.y), entries.z); + float exitT = min(min(exits.x, exits.y), exits.z); - if (entry > exit) { - return vec2(NO_HIT); + if (entryT > exitT) { + return RayShapeIntersection(vec3(NO_HIT), NO_HIT, NO_HIT); } - return vec2(entry, exit); + vec3 entryPoint = ray.pos + entryT * ray.dir; + vec3 normal = normalize(step(box.p1, entryPoint) - step(entryPoint, box.p0)); + + return RayShapeIntersection(normal, entryT, exitT); } void intersectShape(in Ray ray, inout Intersections ix) { - vec2 entryExit = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds)); - setIntersectionPair(ix, BOX_INTERSECTION_INDEX, entryExit); + RayShapeIntersection intersection = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds)); + setIntersectionPair(ix, BOX_INTERSECTION_INDEX, vec2(intersection.entryT, intersection.exitT)); } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 19b4c6e2174..0498c358b11 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -13,6 +13,12 @@ struct Ray { #endif }; +struct RayShapeIntersection { + vec3 normal; + float entryT; + float exitT; +}; + struct Intersections { // Don't access these member variables directly - call the functions instead. diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 8f41c3c1fe3..a7fb01e3d9c 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -31,9 +31,9 @@ float hash(vec2 p) float getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); - vec2 voxelIntersection = intersectBox(viewRay, voxelBox); - float entry = max(voxelIntersection.x, entryExit.x); - float exit = min(voxelIntersection.y, entryExit.y); + RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); + float entry = max(voxelIntersection.entryT, entryExit.x); + float exit = min(voxelIntersection.exitT, entryExit.y); return (exit - entry); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); From 9939a5bb6b566d21beb8a7beff53ff72b29bfe87 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Feb 2023 23:30:58 -0500 Subject: [PATCH 424/679] voxels: return vec4 from intersectPlane --- .../Voxels/IntersectClippingPlanes.glsl | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl index 3a6c731d9dd..a1609d0c79c 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl @@ -11,21 +11,15 @@ uniform sampler2D u_clippingPlanesTexture; uniform mat4 u_clippingPlanesMatrix; // Plane is in Hessian Normal Form -vec2 intersectPlane(in Ray ray, in vec4 plane) { - vec3 o = ray.pos; - vec3 d = ray.dir; +vec4 intersectPlane(in Ray ray, in vec4 plane) { vec3 n = plane.xyz; // normal float w = plane.w; // -dot(pointOnPlane, normal) - float a = dot(o, n); - float b = dot(d, n); + float a = dot(ray.pos, n); + float b = dot(ray.dir, n); float t = -(w + a) / b; - if (dot(d, n) > 0.0) { - return vec2(t, +INF_HIT); - } else { - return vec2(-INF_HIT, t); - } + return vec4(n, t); } void intersectClippingPlanes(in Ray ray, inout Intersections ix) { @@ -33,18 +27,21 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) { // Union and intersection are the same when there's one clipping plane, and the code // is more simplified. vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, intersection); + vec4 intersection = intersectPlane(ray, planeUv); + vec2 entryExitT = dot(ray.dir, planeUv.xyz) > 0.0 + ? vec2(intersection.w, +INF_HIT) + : vec2(-INF_HIT, intersection.w); + setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, entryExitT); #elif defined(CLIPPING_PLANES_UNION) float minPositiveT = +INF_HIT; float maxNegativeT = -INF_HIT; for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - if (intersection.y == +INF_HIT) { - minPositiveT = min(minPositiveT, intersection.x); + vec4 intersection = intersectPlane(ray, planeUv); + if (dot(ray.dir, planeUv.xyz) > 0.0) { + minPositiveT = min(minPositiveT, intersection.w); } else { - maxNegativeT = max(maxNegativeT, intersection.y); + maxNegativeT = max(maxNegativeT, intersection.w); } } setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); @@ -54,11 +51,11 @@ void intersectClippingPlanes(in Ray ray, inout Intersections ix) { float minNegativeT = +INF_HIT; for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); - vec2 intersection = intersectPlane(ray, planeUv); - if (intersection.y == +INF_HIT) { - maxPositiveT = max(maxPositiveT, intersection.x); + vec4 intersection = intersectPlane(ray, planeUv); + if (dot(ray.dir, planeUv.xyz) > 0.0) { + maxPositiveT = max(maxPositiveT, intersection.w); } else { - minNegativeT = min(minNegativeT, intersection.y); + minNegativeT = min(minNegativeT, intersection.w); } } if (maxPositiveT < minNegativeT) { From 4f71d1a9b415366e3cad898d636d9498653b295a Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng90@live.com> Date: Fri, 3 Feb 2023 20:18:17 +0800 Subject: [PATCH 425/679] simplify and remove useless debouce --- packages/engine/Source/Scene/CameraEventAggregator.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 10b2af499aa..99aaa0da8c1 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -154,26 +154,18 @@ function listenToWheel(aggregator, modifier) { } movement.startPosition = new Cartesian2(); + Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); movement.endPosition = new Cartesian2(); - let debounceZoom; - aggregator._eventHandler.setInputAction( function (delta) { // TODO: magic numbers const arcLength = 15.0 * CesiumMath.toRadians(delta); pressTime[key] = releaseTime[key] = new Date(); - Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); movement.endPosition.x = 0.0; movement.endPosition.y = arcLength; Cartesian2.clone(movement.endPosition, lastMovement.endPosition); lastMovement.valid = true; - if (debounceZoom) { - clearTimeout(debounceZoom); - } - debounceZoom = setTimeout(function () { - update[key] = true; - }, 10); update[key] = false; }, ScreenSpaceEventType.WHEEL, From b6545c4c12265e6319c65491b2fd9b1a844bcde4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 3 Feb 2023 10:03:58 -0500 Subject: [PATCH 426/679] voxels: return normal from box intersection --- .../Source/Shaders/Voxels/IntersectBox.glsl | 16 +++++++++--- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 26 +++++++++---------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 6305ff657e0..df8e63a5f5c 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -30,6 +30,14 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) return Box(p0, p1); } +vec3 getBoxNormal(in vec3 entryPoint, in Box box) +{ + vec3 epsilon = (box.p1 - box.p0) * 0.00001; + vec3 lower = step(entryPoint - epsilon, box.p0); + vec3 upper = step(box.p1, entryPoint + epsilon); + return normalize(upper - lower); +} + // Find the distances along a ray at which the ray intersects an axis-aligned box // See https://tavianator.com/2011/ray_box.html RayShapeIntersection intersectBox(in Ray ray, in Box box) @@ -47,13 +55,13 @@ RayShapeIntersection intersectBox(in Ray ray, in Box box) float entryT = max(max(entries.x, entries.y), entries.z); float exitT = min(min(exits.x, exits.y), exits.z); + vec3 entryPoint = ray.pos + entryT * ray.dir; + vec3 normal = getBoxNormal(entryPoint, box); + if (entryT > exitT) { - return RayShapeIntersection(vec3(NO_HIT), NO_HIT, NO_HIT); + return RayShapeIntersection(normal, NO_HIT, NO_HIT); } - vec3 entryPoint = ray.pos + entryT * ray.dir; - vec3 normal = normalize(step(box.p1, entryPoint) - step(entryPoint, box.p0)); - return RayShapeIntersection(normal, entryT, exitT); } diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index a7fb01e3d9c..b451995378e 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -28,16 +28,16 @@ float hash(vec2 p) } #endif -float getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { +vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); float entry = max(voxelIntersection.entryT, entryExit.x); float exit = min(voxelIntersection.exitT, entryExit.y); - return (exit - entry); + return vec4(voxelIntersection.normal, exit - entry); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); - return u_stepSize / dimAtLevel; + return vec4(viewRay.dir, u_stepSize / dimAtLevel); #endif } @@ -73,12 +73,12 @@ void main() TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - float stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); + vec4 step = getStepSize(sampleDatas[0], viewRayUv, entryExitT); #if defined(JITTER) float noise = hash(screenCoord); // [0,1] - currT += noise * stepT; - positionUv += noise * stepT * viewDirUv; + currT += noise * step.w; + positionUv += noise * step.w * viewDirUv; #endif FragmentInput fragmentInput; @@ -99,8 +99,8 @@ void main() fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv; fragmentInput.voxel.viewDirUv = viewDirUv; fragmentInput.voxel.viewDirWorld = viewDirWorld; - fragmentInput.voxel.surfaceNormal = viewRayUv.dir; - fragmentInput.voxel.travelDistance = stepT; + fragmentInput.voxel.surfaceNormal = step.xyz; + fragmentInput.voxel.travelDistance = step.w; // Run the custom shader czm_modelMaterial materialOutput; @@ -120,15 +120,15 @@ void main() break; } - if (stepT == 0.0) { + if (step.w == 0.0) { // Shape is infinitely thin. The ray may have hit the edge of a // foreground voxel. Step ahead slightly to check for more voxels - stepT == 0.00001; + step.w == 0.00001; } // Keep raymarching - currT += stepT; - positionUv += stepT * viewDirUv; + currT += step.w; + positionUv += step.w * viewDirUv; // Check if there's more intersections. if (currT > endT) { @@ -151,7 +151,7 @@ void main() // This is similar to traverseOctreeFromBeginning but is faster when the ray is in the same tile as the previous step. positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); - stepT = getStepSize(sampleDatas[0], viewRayUv, entryExitT); + step = getStepSize(sampleDatas[0], viewRayUv, entryExitT); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From 3f6608f66e3297ff6a701550c39e041277c9e0f4 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 31 Jan 2023 16:59:38 -0500 Subject: [PATCH 427/679] Use top level await in Sandcastle --- Apps/Sandcastle/Sandcastle-helpers.js | 6 +- .../gallery/3D Models Coloring.html | 9 +- Apps/Sandcastle/gallery/3D Models.html | 9 +- .../gallery/3D Tiles Adjust Height.html | 9 +- Apps/Sandcastle/gallery/3D Tiles BIM.html | 9 +- .../3D Tiles Batch Table Hierarchy.html | 9 +- .../gallery/3D Tiles Clipping Planes.html | 9 +- Apps/Sandcastle/gallery/3D Tiles Compare.html | 9 +- .../gallery/3D Tiles Feature Picking.html | 505 +++++++------- .../gallery/3D Tiles Feature Styling.html | 302 ++++----- Apps/Sandcastle/gallery/3D Tiles Formats.html | 9 +- .../gallery/3D Tiles Inspector.html | 50 +- .../gallery/3D Tiles Interactivity.html | 338 +++++----- .../Sandcastle/gallery/3D Tiles Interior.html | 8 +- .../gallery/3D Tiles Next CDB Yemen.html | 9 +- ...es Next Photogrammetry Classification.html | 17 +- .../gallery/3D Tiles Next S2 Globe.html | 9 +- ...D Tiles Photogrammetry Classification.html | 82 +-- .../gallery/3D Tiles Photogrammetry.html | 27 +- .../3D Tiles Point Cloud Classification.html | 147 ++-- .../gallery/3D Tiles Point Cloud Shading.html | 379 ++++++----- .../gallery/3D Tiles Point Cloud Styling.html | 9 +- .../gallery/3D Tiles Point Cloud.html | 50 +- .../3D Tiles Terrain Classification.html | 95 +-- .../Sandcastle/gallery/Ambient Occlusion.html | 8 +- Apps/Sandcastle/gallery/ArcGIS MapServer.html | 9 +- .../ArcGIS Tiled Elevation Terrain.html | 24 +- Apps/Sandcastle/gallery/ArcticDEM.html | 29 +- Apps/Sandcastle/gallery/Atmosphere.html | 9 +- Apps/Sandcastle/gallery/Billboards.html | 9 +- Apps/Sandcastle/gallery/Bloom.html | 9 +- Apps/Sandcastle/gallery/Blue Marble.html | 9 +- Apps/Sandcastle/gallery/Box.html | 9 +- Apps/Sandcastle/gallery/CZML 3D Tiles.html | 9 +- .../gallery/CZML Billboard and Label.html | 9 +- Apps/Sandcastle/gallery/CZML Box.html | 8 +- .../gallery/CZML Circles and Ellipses.html | 9 +- Apps/Sandcastle/gallery/CZML Colors.html | 8 +- .../gallery/CZML Cones and Cylinders.html | 9 +- Apps/Sandcastle/gallery/CZML Corridor.html | 9 +- .../gallery/CZML Custom Properties.html | 8 +- .../CZML Model - Node Transformations.html | 9 +- .../gallery/CZML Model Articulations.html | 9 +- .../gallery/CZML Model Data URL.html | 8 +- Apps/Sandcastle/gallery/CZML Model.html | 9 +- Apps/Sandcastle/gallery/CZML Path.html | 29 +- .../gallery/CZML Point - Time Dynamic.html | 8 +- Apps/Sandcastle/gallery/CZML Point.html | 9 +- ...ML Polygon - Interpolating References.html | 9 +- ...ZML Polygon - Intervals, Availability.html | 9 +- Apps/Sandcastle/gallery/CZML Polygon.html | 9 +- .../gallery/CZML Polyline Volume.html | 9 +- Apps/Sandcastle/gallery/CZML Polyline.html | 9 +- .../gallery/CZML Position Definitions.html | 8 +- Apps/Sandcastle/gallery/CZML Rectangle.html | 9 +- .../gallery/CZML Reference Properties.html | 9 +- .../gallery/CZML Spheres and Ellipsoids.html | 9 +- Apps/Sandcastle/gallery/CZML Wall.html | 9 +- Apps/Sandcastle/gallery/CZML ZIndex.html | 8 +- Apps/Sandcastle/gallery/CZML.html | 9 +- .../Sandcastle/gallery/Callback Property.html | 8 +- Apps/Sandcastle/gallery/Camera Tutorial.html | 9 +- Apps/Sandcastle/gallery/Camera.html | 8 +- Apps/Sandcastle/gallery/Cardboard.html | 269 ++++---- .../gallery/Cartographic Limit Rectangle.html | 104 +-- Apps/Sandcastle/gallery/Cesium Inspector.html | 139 ++-- .../gallery/Cesium OSM Buildings.html | 33 +- Apps/Sandcastle/gallery/Cesium Widget.html | 9 +- .../gallery/Cesium World Terrain.html | 20 +- .../gallery/Circles and Ellipses.html | 9 +- .../Sandcastle/gallery/Clamp to 3D Model.html | 9 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 100 +-- Apps/Sandcastle/gallery/Clamp to Terrain.html | 21 +- .../gallery/Classification Types.html | 21 +- Apps/Sandcastle/gallery/Classification.html | 560 ++++++++-------- Apps/Sandcastle/gallery/Clock.html | 8 +- Apps/Sandcastle/gallery/Cloud Parameters.html | 9 +- Apps/Sandcastle/gallery/Clouds.html | 414 ++++++------ Apps/Sandcastle/gallery/Clustering.html | 9 +- Apps/Sandcastle/gallery/Corridor.html | 9 +- .../Sandcastle/gallery/Custom DataSource.html | 9 +- Apps/Sandcastle/gallery/Custom Geocoder.html | 8 +- .../Custom Per-Feature Post Process.html | 9 +- .../gallery/Custom Post Process.html | 8 +- .../gallery/Custom Shaders 3D Tiles.html | 9 +- .../gallery/Custom Shaders Models.html | 9 +- .../Custom Shaders Property Textures.html | 22 +- .../gallery/Cylinders and Cones.html | 9 +- .../gallery/DataSource Ordering.html | 9 +- Apps/Sandcastle/gallery/Depth of Field.html | 9 +- .../gallery/Distance Display Conditions.html | 9 +- .../gallery/Drawing on Terrain.html | 18 +- Apps/Sandcastle/gallery/Earth at Night.html | 9 +- .../gallery/Elevation Band Material.html | 376 +++++------ Apps/Sandcastle/gallery/Export KML.html | 9 +- Apps/Sandcastle/gallery/FXAA.html | 61 +- Apps/Sandcastle/gallery/Fog Post Process.html | 9 +- Apps/Sandcastle/gallery/GPX.html | 21 +- .../gallery/GeoJSON and TopoJSON.html | 9 +- .../gallery/GeoJSON simplestyle.html | 9 +- .../gallery/Geometry Height Reference.html | 17 +- .../gallery/Geometry and Appearances.html | 9 +- Apps/Sandcastle/gallery/Globe Interior.html | 9 +- Apps/Sandcastle/gallery/Globe Materials.html | 25 +- .../gallery/Globe Translucency.html | 415 ++++++------ .../gallery/Google Earth Enterprise.html | 58 +- Apps/Sandcastle/gallery/HTML Overlays.html | 9 +- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 9 +- Apps/Sandcastle/gallery/Hello World.html | 10 +- .../gallery/High Dynamic Range.html | 109 +-- .../gallery/I3S 3D Object Layer.html | 209 +++--- .../gallery/I3S Feature Picking.html | 209 +++--- .../gallery/I3S IntegratedMesh Layer.html | 94 +-- .../gallery/Image-Based Lighting.html | 9 +- .../gallery/Imagery Adjustment.html | 9 +- .../gallery/Imagery Color To Alpha.html | 9 +- Apps/Sandcastle/gallery/Imagery Cutout.html | 9 +- .../gallery/Imagery Layers Manipulation.html | 9 +- .../gallery/Imagery Layers Split.html | 9 +- .../Imagery Layers Texture Filters.html | 10 +- Apps/Sandcastle/gallery/Imagery Layers.html | 9 +- Apps/Sandcastle/gallery/Interpolation.html | 18 +- Apps/Sandcastle/gallery/KML Tours.html | 9 +- Apps/Sandcastle/gallery/KML.html | 9 +- Apps/Sandcastle/gallery/Labels.html | 8 +- Apps/Sandcastle/gallery/LensFlare.html | 9 +- Apps/Sandcastle/gallery/Lighting.html | 27 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 9 +- Apps/Sandcastle/gallery/MSAA.html | 18 +- .../Manually Controlled Animation.html | 9 +- Apps/Sandcastle/gallery/Map Pins.html | 9 +- Apps/Sandcastle/gallery/Materials.html | 9 +- .../gallery/Montreal Point Cloud.html | 21 +- Apps/Sandcastle/gallery/Multi-part CZML.html | 9 +- .../gallery/Multiple Synced Views.html | 9 +- Apps/Sandcastle/gallery/Natural Earth II.html | 9 +- Apps/Sandcastle/gallery/Offline.html | 9 +- Apps/Sandcastle/gallery/PAMAP Terrain.html | 29 +- .../gallery/Parallels and Meridians.html | 9 +- .../gallery/Partial Ellipsoids.html | 9 +- .../gallery/Particle System Fireworks.html | 9 +- .../gallery/Particle System Tails.html | 9 +- .../gallery/Particle System Weather.html | 18 +- Apps/Sandcastle/gallery/Particle System.html | 9 +- .../gallery/Per-Feature Post Processing.html | 9 +- .../gallery/Physically-Based Materials.html | 18 +- Apps/Sandcastle/gallery/Picking.html | 9 +- Apps/Sandcastle/gallery/Plane.html | 9 +- Apps/Sandcastle/gallery/Points.html | 9 +- Apps/Sandcastle/gallery/Polygon.html | 9 +- Apps/Sandcastle/gallery/Polyline Dash.html | 9 +- Apps/Sandcastle/gallery/Polyline Volume.html | 9 +- Apps/Sandcastle/gallery/Polyline.html | 9 +- .../gallery/Polylines on 3D Tiles.html | 9 +- Apps/Sandcastle/gallery/Post Processing.html | 9 +- .../gallery/Procedural Terrain.html | 9 +- Apps/Sandcastle/gallery/Projection.html | 9 +- Apps/Sandcastle/gallery/Rectangle.html | 9 +- .../gallery/Resolution Scaling.html | 9 +- Apps/Sandcastle/gallery/Rotatable 2D Map.html | 9 +- .../gallery/Sample Height from 3D Tiles.html | 21 +- .../gallery/Scene Rendering Performance.html | 18 +- Apps/Sandcastle/gallery/Sentinel-2.html | 9 +- Apps/Sandcastle/gallery/Shadows.html | 18 +- .../gallery/Show or Hide Entities.html | 9 +- .../gallery/Spheres and Ellipsoids.html | 9 +- Apps/Sandcastle/gallery/Star Burst.html | 9 +- .../gallery/Terrain Clipping Planes.html | 634 +++++++++--------- .../gallery/Terrain Exaggeration.html | 21 +- Apps/Sandcastle/gallery/Terrain.html | 27 +- .../gallery/Time Dynamic Point Cloud.html | 9 +- .../gallery/Time Dynamic Wheels.html | 9 +- .../Sandcastle/gallery/Underground Color.html | 9 +- Apps/Sandcastle/gallery/Video.html | 9 +- Apps/Sandcastle/gallery/Wall.html | 9 +- .../gallery/Washington DC 2017.html | 9 +- .../gallery/Web Map Service (WMS).html | 9 +- .../Web Map Tile Service with Time.html | 9 +- .../gallery/Z-Indexing Geometry.html | 9 +- .../development/3D Models Articulations.html | 9 +- .../development/3D Models Node Explorer.html | 9 +- .../gallery/development/3D Models.html | 9 +- .../3D Tiles Performance Testing.html | 9 +- .../gallery/development/3D Tiles Split.html | 9 +- .../development/BillboardClampToGround.html | 21 +- .../development/Billboards Instancing.html | 21 +- .../gallery/development/Billboards.html | 9 +- .../gallery/development/Box Outline.html | 9 +- Apps/Sandcastle/gallery/development/Box.html | 9 +- .../gallery/development/Circle Outline.html | 9 +- .../gallery/development/Circle.html | 9 +- .../development/Coplanar Polygon Outline.html | 9 +- .../gallery/development/Coplanar Polygon.html | 9 +- .../gallery/development/Corridor Outline.html | 8 +- .../gallery/development/Corridor.html | 9 +- .../gallery/development/Custom Primitive.html | 9 +- .../gallery/development/Cylinder Outline.html | 9 +- .../gallery/development/Cylinder.html | 9 +- .../development/Display Conditions.html | 9 +- .../gallery/development/Ellipse Outline.html | 9 +- .../gallery/development/Ellipse.html | 9 +- .../development/Ellipsoid Outline.html | 9 +- .../development/Ellipsoid Surface.html | 9 +- .../gallery/development/Ellipsoid.html | 9 +- Apps/Sandcastle/gallery/development/Fog.html | 21 +- .../gallery/development/Frustum.html | 9 +- ...fset Attribute box cylinder ellipsoid.html | 9 +- .../Geometry Offset Attribute.html | 9 +- .../development/Geometry and Appearances.html | 9 +- .../development/Ground Polyline Material.html | 159 ++--- .../Ground Primitive Materials.html | 27 +- .../gallery/development/Ground Primitive.html | 21 +- .../gallery/development/Labels.html | 9 +- .../development/Many Clipping Planes.html | 465 ++++++------- .../gallery/development/Material.html | 9 +- .../gallery/development/Multiple Shadows.html | 18 +- .../development/Per Instance Color.html | 9 +- .../gallery/development/Pick From Ray.html | 9 +- .../gallery/development/Picking.html | 9 +- .../gallery/development/PointPrimitives.html | 9 +- .../gallery/development/Polygon Outline.html | 9 +- .../Polygon Texture Coordinates.html | 9 +- .../gallery/development/Polygon.html | 10 +- .../gallery/development/Polyline Color.html | 9 +- .../development/Polyline Material.html | 9 +- .../development/Polyline Volume Outline.html | 9 +- .../gallery/development/Polyline Volume.html | 9 +- .../gallery/development/Polyline.html | 9 +- .../development/Polylines On Terrain.html | 27 +- .../gallery/development/Polylines.html | 9 +- .../development/Rectangle Outline.html | 9 +- .../gallery/development/Rectangle.html | 9 +- .../gallery/development/Shadows.html | 9 +- .../gallery/development/Simple Polyline.html | 9 +- .../gallery/development/Sphere Outline.html | 9 +- .../gallery/development/Sphere.html | 9 +- .../development/Terrain Entity Batching.html | 287 ++++---- .../development/Terrain Performance.html | 21 +- .../gallery/development/Terrain Tweaks.html | 9 +- .../gallery/development/Volumes.html | 9 +- .../gallery/development/Voxels.html | 9 +- .../gallery/development/Wall Outline.html | 9 +- Apps/Sandcastle/gallery/development/Wall.html | 9 +- Apps/Sandcastle/load-cesium-es6.js | 5 +- 244 files changed, 4711 insertions(+), 4281 deletions(-) diff --git a/Apps/Sandcastle/Sandcastle-helpers.js b/Apps/Sandcastle/Sandcastle-helpers.js index 0323fbaf286..cdb6b971625 100644 --- a/Apps/Sandcastle/Sandcastle-helpers.js +++ b/Apps/Sandcastle/Sandcastle-helpers.js @@ -4,7 +4,7 @@ window.embedInSandcastleTemplate = function (code, addExtraLine) { return ( `${ - "window.startup = function (Cesium) {\n" + + "window.startup = async function (Cesium) {\n" + " 'use strict';\n" + "//Sandcastle_Begin\n" }${addExtraLine ? "\n" : ""}${code}//Sandcastle_End\n` + @@ -12,7 +12,9 @@ `};\n` + `if (typeof Cesium !== 'undefined') {\n` + ` window.startupCalled = true;\n` + - ` window.startup(Cesium);\n` + + ` window.startup(Cesium).catch((error) => {\n` + + ` console.error(error);\n` + + ` });\n` + `}\n` ); }; diff --git a/Apps/Sandcastle/gallery/3D Models Coloring.html b/Apps/Sandcastle/gallery/3D Models Coloring.html index 8cd0e510ee4..3f43b292dc4 100644 --- a/Apps/Sandcastle/gallery/3D Models Coloring.html +++ b/Apps/Sandcastle/gallery/3D Models Coloring.html @@ -133,7 +133,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -322,11 +322,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Models.html b/Apps/Sandcastle/gallery/3D Models.html index 67e632f6dd6..6153306c0eb 100644 --- a/Apps/Sandcastle/gallery/3D Models.html +++ b/Apps/Sandcastle/gallery/3D Models.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -169,11 +169,14 @@ Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html index 6b70acb401c..c8e8f6c139a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html +++ b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html @@ -53,7 +53,7 @@ <input type="text" size="5" data-bind="value: height" /> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -121,11 +121,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles BIM.html b/Apps/Sandcastle/gallery/3D Tiles BIM.html index 1060beb35bf..2f403e73091 100644 --- a/Apps/Sandcastle/gallery/3D Tiles BIM.html +++ b/Apps/Sandcastle/gallery/3D Tiles BIM.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -217,11 +217,14 @@ processTileFeatures(tile, unloadFeature); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html index c5ecda6317b..de0497ca1f4 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -212,11 +212,14 @@ feature.show = false; }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index 192ea241f8f..9547272431f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -62,7 +62,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Add a clipping plane, a plane geometry to show the representation of the @@ -343,11 +343,14 @@ } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Compare.html b/Apps/Sandcastle/gallery/3D Tiles Compare.html index ce4070b6ec0..5f494f9abe7 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Compare.html +++ b/Apps/Sandcastle/gallery/3D Tiles Compare.html @@ -49,7 +49,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -106,11 +106,14 @@ moveActive = false; }, Cesium.ScreenSpaceEventType.PINCH_END); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index 259ee31640c..97033e63157 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -30,286 +30,287 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // A simple demo of 3D Tiles feature picking with hover and select behavior - // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // A simple demo of 3D Tiles feature picking with hover and select behavior + // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - viewer.scene.primitives.add(tileset); + // Load the NYC buildings tileset + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + viewer.scene.primitives.add(tileset); - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; - // Information about the currently selected feature - const selected = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently selected feature + const selected = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); - // Get default left click handler for when a feature is not picked on left click - const clickHandler = viewer.screenSpaceEventHandler.getInputAction( - Cesium.ScreenSpaceEventType.LEFT_CLICK - ); + // Get default left click handler for when a feature is not picked on left click + const clickHandler = viewer.screenSpaceEventHandler.getInputAction( + Cesium.ScreenSpaceEventType.LEFT_CLICK + ); - // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. - // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. - if ( - Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) - ) { - // Silhouettes are supported - const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteBlue.uniforms.color = Cesium.Color.BLUE; - silhouetteBlue.uniforms.length = 0.01; - silhouetteBlue.selected = []; + // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. + // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. + if ( + Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) + ) { + // Silhouettes are supported + const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteBlue.uniforms.color = Cesium.Color.BLUE; + silhouetteBlue.uniforms.length = 0.01; + silhouetteBlue.selected = []; - const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteGreen.uniforms.color = Cesium.Color.LIME; - silhouetteGreen.uniforms.length = 0.01; - silhouetteGreen.selected = []; + const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteGreen.uniforms.color = Cesium.Color.LIME; + silhouetteGreen.uniforms.length = 0.01; + silhouetteGreen.selected = []; - viewer.scene.postProcessStages.add( - Cesium.PostProcessStageLibrary.createSilhouetteStage([ - silhouetteBlue, - silhouetteGreen, - ]) - ); + viewer.scene.postProcessStages.add( + Cesium.PostProcessStageLibrary.createSilhouetteStage([ + silhouetteBlue, + silhouetteGreen, + ]) + ); - // Silhouette a feature blue on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - silhouetteBlue.selected = []; + // Silhouette a feature blue on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + silhouetteBlue.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const name = pickedFeature.getProperty("BIN"); - nameOverlay.textContent = name; + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const name = pickedFeature.getProperty("BIN"); + nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - silhouetteBlue.selected = [pickedFeature]; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + silhouetteBlue.selected = [pickedFeature]; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Silhouette a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - silhouetteGreen.selected = []; + // Silhouette a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + silhouetteGreen.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } - // Select the feature if it's not already selected - if (silhouetteGreen.selected[0] === pickedFeature) { - return; - } + // Select the feature if it's not already selected + if (silhouetteGreen.selected[0] === pickedFeature) { + return; + } - // Save the selected feature's original color - const highlightedFeature = silhouetteBlue.selected[0]; - if (pickedFeature === highlightedFeature) { - silhouetteBlue.selected = []; - } + // Save the selected feature's original color + const highlightedFeature = silhouetteBlue.selected[0]; + if (pickedFeature === highlightedFeature) { + silhouetteBlue.selected = []; + } - // Highlight newly selected feature - silhouetteGreen.selected = [pickedFeature]; + // Highlight newly selected feature + silhouetteGreen.selected = [pickedFeature]; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } else { - // Silhouettes are not supported. Instead, change the feature color. + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } else { + // Silhouettes are not supported. Instead, change the feature color. - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - let name = pickedFeature.getProperty("name"); - if (!Cesium.defined(name)) { - name = pickedFeature.getProperty("id"); - } - nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + let name = pickedFeature.getProperty("name"); + if (!Cesium.defined(name)) { + name = pickedFeature.getProperty("id"); + } + nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Color a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - if (Cesium.defined(selected.feature)) { - selected.feature.color = selected.originalColor; - selected.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } - // Select the feature if it's not already selected - if (selected.feature === pickedFeature) { - return; - } - selected.feature = pickedFeature; - // Save the selected feature's original color - if (pickedFeature === highlighted.feature) { - Cesium.Color.clone( - highlighted.originalColor, - selected.originalColor - ); - highlighted.feature = undefined; - } else { - Cesium.Color.clone(pickedFeature.color, selected.originalColor); - } - // Highlight newly selected feature - pickedFeature.color = Cesium.Color.LIME; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `<tr><th>Longitude</th><td>${pickedFeature.getProperty( - "longitude" - )}</td></tr>` + - `<tr><th>Latitude</th><td>${pickedFeature.getProperty( - "latitude" - )}</td></tr>` + - `<tr><th>Height</th><td>${pickedFeature.getProperty( - "height" - )}</td></tr>` + - `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( - "TerrainHeight" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + // Color a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + if (Cesium.defined(selected.feature)) { + selected.feature.color = selected.originalColor; + selected.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } + // Select the feature if it's not already selected + if (selected.feature === pickedFeature) { + return; + } + selected.feature = pickedFeature; + // Save the selected feature's original color + if (pickedFeature === highlighted.feature) { + Cesium.Color.clone( + highlighted.originalColor, + selected.originalColor + ); + highlighted.feature = undefined; + } else { + Cesium.Color.clone(pickedFeature.color, selected.originalColor); + } + // Highlight newly selected feature + pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `<tr><th>Longitude</th><td>${pickedFeature.getProperty( + "longitude" + )}</td></tr>` + + `<tr><th>Latitude</th><td>${pickedFeature.getProperty( + "latitude" + )}</td></tr>` + + `<tr><th>Height</th><td>${pickedFeature.getProperty( + "height" + )}</td></tr>` + + `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( + "TerrainHeight" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index 53f338f2103..4340727762f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -50,174 +50,170 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // How to use the 3D Tiles Styling language to style individual features, like buildings. - // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const handler = new Cesium.ScreenSpaceEventHandler( - viewer.scene.canvas - ); - - // Add Cesium OSM buildings to the scene as our example 3D Tileset. - const osmBuildingsTileset = Cesium.createOsmBuildings(); - viewer.scene.primitives.add(osmBuildingsTileset); - - // Set the initial camera to look at Seattle - viewer.scene.camera.setView({ - destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), - orientation: { - heading: Cesium.Math.toRadians(10), - pitch: Cesium.Math.toRadians(-10), + // How to use the 3D Tiles Styling language to style individual features, like buildings. + // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); + + // Add Cesium OSM buildings to the scene as our example 3D Tileset. + const osmBuildingsTileset = Cesium.createOsmBuildings(); + viewer.scene.primitives.add(osmBuildingsTileset); + + // Set the initial camera to look at Seattle + viewer.scene.camera.setView({ + destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), + orientation: { + heading: Cesium.Math.toRadians(10), + pitch: Cesium.Math.toRadians(-10), + }, + }); + + // Styling functions + + // Color by material checks for null values since not all + // buildings have the material property. + function colorByMaterial() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + material: "${feature['building:material']}", + }, + color: { + conditions: [ + ["${material} === null", "color('white')"], + ["${material} === 'glass'", "color('skyblue', 0.5)"], + ["${material} === 'concrete'", "color('grey')"], + ["${material} === 'brick'", "color('indianred')"], + ["${material} === 'stone'", "color('lightslategrey')"], + ["${material} === 'metal'", "color('lightgrey')"], + ["${material} === 'steel'", "color('lightsteelblue')"], + ["true", "color('white')"], // This is the else case + ], }, }); - - // Styling functions - - // Color by material checks for null values since not all - // buildings have the material property. - function colorByMaterial() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - material: "${feature['building:material']}", - }, - color: { - conditions: [ - ["${material} === null", "color('white')"], - ["${material} === 'glass'", "color('skyblue', 0.5)"], - ["${material} === 'concrete'", "color('grey')"], - ["${material} === 'brick'", "color('indianred')"], - ["${material} === 'stone'", "color('lightslategrey')"], - ["${material} === 'metal'", "color('lightgrey')"], - ["${material} === 'steel'", "color('lightsteelblue')"], - ["true", "color('white')"], // This is the else case - ], - }, - }); - } - - function highlightAllResidentialBuildings() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - [ - "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", - "color('cyan', 0.9)", - ], - [true, "color('white')"], + } + + function highlightAllResidentialBuildings() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + [ + "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", + "color('cyan', 0.9)", ], - }, - }); + [true, "color('white')"], + ], + }, + }); + } + + function showByBuildingType(buildingType) { + switch (buildingType) { + case "office": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'office'", + }); + break; + case "apartments": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'apartments'", + }); + break; + default: + break; } + } - function showByBuildingType(buildingType) { - switch (buildingType) { - case "office": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'office'", - }); - break; - case "apartments": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'apartments'", - }); - break; - default: - break; - } - } + // Color the buildings based on their distance from a selected central location + function colorByDistanceToCoordinate(pickedLatitude, pickedLongitude) { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, + }, + color: { + conditions: [ + ["${distance} > 0.014", "color('blue')"], + ["${distance} > 0.010", "color('green')"], + ["${distance} > 0.006", "color('yellow')"], + ["${distance} > 0.0001", "color('red')"], + ["true", "color('white')"], + ], + }, + }); + } - // Color the buildings based on their distance from a selected central location - function colorByDistanceToCoordinate( - pickedLatitude, - pickedLongitude - ) { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, - }, - color: { - conditions: [ - ["${distance} > 0.014", "color('blue')"], - ["${distance} > 0.010", "color('green')"], - ["${distance} > 0.006", "color('yellow')"], - ["${distance} > 0.0001", "color('red')"], - ["true", "color('white')"], - ], - }, - }); - } + // When dropdown option is not "Color By Distance To Selected Location", + // remove the left click input event for selecting a central location + function removeCoordinatePickingOnLeftClick() { + document.querySelector(".infoPanel").style.visibility = "hidden"; + handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); + } - // When dropdown option is not "Color By Distance To Selected Location", - // remove the left click input event for selecting a central location - function removeCoordinatePickingOnLeftClick() { - document.querySelector(".infoPanel").style.visibility = "hidden"; - handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); - } + // Add event listeners to dropdown menu options + document.querySelector(".infoPanel").style.visibility = "hidden"; + const menu = document.getElementById("dropdown"); - // Add event listeners to dropdown menu options - document.querySelector(".infoPanel").style.visibility = "hidden"; - const menu = document.getElementById("dropdown"); - - menu.options[0].onselect = function () { - removeCoordinatePickingOnLeftClick(); - colorByMaterial(); - }; - - menu.options[1].onselect = function () { - // Default to Space Needle as the central location - colorByDistanceToCoordinate(47.62051, -122.34931); - document.querySelector(".infoPanel").style.visibility = "visible"; - // Add left click input to select a building to and extract its coordinates - handler.setInputAction(function (movement) { - viewer.selectedEntity = undefined; - const pickedBuilding = viewer.scene.pick(movement.position); - if (pickedBuilding) { - const pickedLatitude = pickedBuilding.getProperty( - "cesium#latitude" - ); - const pickedLongitude = pickedBuilding.getProperty( - "cesium#longitude" - ); - colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - }; - - menu.options[2].onselect = function () { - removeCoordinatePickingOnLeftClick(); - highlightAllResidentialBuildings(); - }; - - menu.options[3].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("office"); - }; - - menu.options[4].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("apartments"); - }; - - menu.onchange = function () { - Sandcastle.reset(); - const item = menu.options[menu.selectedIndex]; - if (item && typeof item.onselect === "function") { - item.onselect(); + menu.options[0].onselect = function () { + removeCoordinatePickingOnLeftClick(); + colorByMaterial(); + }; + + menu.options[1].onselect = function () { + // Default to Space Needle as the central location + colorByDistanceToCoordinate(47.62051, -122.34931); + document.querySelector(".infoPanel").style.visibility = "visible"; + // Add left click input to select a building to and extract its coordinates + handler.setInputAction(function (movement) { + viewer.selectedEntity = undefined; + const pickedBuilding = viewer.scene.pick(movement.position); + if (pickedBuilding) { + const pickedLatitude = pickedBuilding.getProperty( + "cesium#latitude" + ); + const pickedLongitude = pickedBuilding.getProperty( + "cesium#longitude" + ); + colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); } - }; + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + }; + + menu.options[2].onselect = function () { + removeCoordinatePickingOnLeftClick(); + highlightAllResidentialBuildings(); + }; + + menu.options[3].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("office"); + }; + + menu.options[4].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("apartments"); + }; + + menu.onchange = function () { + Sandcastle.reset(); + const item = menu.options[menu.selectedIndex]; + if (item && typeof item.onselect === "function") { + item.onselect(); + } + }; - colorByMaterial(); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + colorByMaterial(); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Formats.html b/Apps/Sandcastle/gallery/3D Tiles Formats.html index 04c5b08da1f..e141b25e538 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Formats.html +++ b/Apps/Sandcastle/gallery/3D Tiles Formats.html @@ -38,7 +38,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -218,11 +218,14 @@ } }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index 7063dc45545..d07f605b952 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -33,42 +33,44 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - enableDebugWireframe: true, - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + enableDebugWireframe: true, + }); + viewer.scene.primitives.add(tileset); - await tileset.readyPromise; + await tileset.readyPromise; - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - tileset.boundingSphere.radius / 4.0 - ) - ); - })(); //Sandcastle_End + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + tileset.boundingSphere.radius / 4.0 + ) + ); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index 2ebba29bffa..904e4eaa3f8 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -71,213 +71,203 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - if (!scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } + const scene = viewer.scene; + if (!scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } - scene.globe.depthTestAgainstTerrain = true; + scene.globe.depthTestAgainstTerrain = true; - const viewModel = { - rightClickAction: "annotate", - middleClickAction: "hide", - }; + const viewModel = { + rightClickAction: "annotate", + middleClickAction: "hide", + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - const annotations = scene.primitives.add( - new Cesium.LabelCollection() - ); + const annotations = scene.primitives.add(new Cesium.LabelCollection()); - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - meta: { - description: "'Building ${BIN} has height ${Height}.'", - }, - }); + // Load the NYC buildings tileset. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + scene.primitives.add(tileset); + tileset.style = new Cesium.Cesium3DTileStyle({ + meta: { + description: "'Building ${BIN} has height ${Height}.'", + }, + }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.rightClickAction; - if (action === "annotate") { - annotate(movement, feature); - } else if (action === "properties") { - printProperties(movement, feature); - } else if (action === "zoom") { - zoom(movement, feature); - } - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + const action = viewModel.rightClickAction; + if (action === "annotate") { + annotate(movement, feature); + } else if (action === "properties") { + printProperties(movement, feature); + } else if (action === "zoom") { + zoom(movement, feature); + } + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.middleClickAction; - if (action === "hide") { - feature.show = false; - } - }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + const action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); - function annotate(movement, feature) { - if (scene.pickPositionSupported) { - const cartesian = scene.pickPosition(movement.position); - if (Cesium.defined(cartesian)) { - const cartographic = Cesium.Cartographic.fromCartesian( - cartesian - ); - const height = `${cartographic.height.toFixed(2)} m`; + function annotate(movement, feature) { + if (scene.pickPositionSupported) { + const cartesian = scene.pickPosition(movement.position); + if (Cesium.defined(cartesian)) { + const cartographic = Cesium.Cartographic.fromCartesian(cartesian); + const height = `${cartographic.height.toFixed(2)} m`; - annotations.add({ - position: cartesian, - text: height, - showBackground: true, - font: "14px monospace", - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - disableDepthTestDistance: Number.POSITIVE_INFINITY, - }); - } + annotations.add({ + position: cartesian, + text: height, + showBackground: true, + font: "14px monospace", + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + disableDepthTestDistance: Number.POSITIVE_INFINITY, + }); } } + } - function printProperties(movement, feature) { - console.log("Properties:"); - const propertyIds = feature.getPropertyIds(); - const length = propertyIds.length; - for (let i = 0; i < length; ++i) { - const propertyId = propertyIds[i]; - console.log( - ` ${propertyId}: ${feature.getProperty(propertyId)}` - ); - } - - // Evaluate feature description - console.log( - `Description : ${tileset.style.meta.description.evaluate( - feature - )}` - ); + function printProperties(movement, feature) { + console.log("Properties:"); + const propertyIds = feature.getPropertyIds(); + const length = propertyIds.length; + for (let i = 0; i < length; ++i) { + const propertyId = propertyIds[i]; + console.log(` ${propertyId}: ${feature.getProperty(propertyId)}`); } - function zoom(movement, feature) { - const longitude = Cesium.Math.toRadians( - feature.getProperty("Longitude") - ); - const latitude = Cesium.Math.toRadians( - feature.getProperty("Latitude") - ); - const height = feature.getProperty("Height"); + // Evaluate feature description + console.log( + `Description : ${tileset.style.meta.description.evaluate(feature)}` + ); + } - const positionCartographic = new Cesium.Cartographic( - longitude, - latitude, - height * 0.5 - ); - const position = scene.globe.ellipsoid.cartographicToCartesian( - positionCartographic - ); + function zoom(movement, feature) { + const longitude = Cesium.Math.toRadians( + feature.getProperty("Longitude") + ); + const latitude = Cesium.Math.toRadians( + feature.getProperty("Latitude") + ); + const height = feature.getProperty("Height"); - const camera = scene.camera; - const heading = camera.heading; - const pitch = camera.pitch; + const positionCartographic = new Cesium.Cartographic( + longitude, + latitude, + height * 0.5 + ); + const position = scene.globe.ellipsoid.cartographicToCartesian( + positionCartographic + ); + + const camera = scene.camera; + const heading = camera.heading; + const pitch = camera.pitch; - const offset = offsetFromHeadingPitchRange( - heading, - pitch, - height * 2.0 - ); + const offset = offsetFromHeadingPitchRange( + heading, + pitch, + height * 2.0 + ); - const transform = Cesium.Transforms.eastNorthUpToFixedFrame( - position - ); - Cesium.Matrix4.multiplyByPoint(transform, offset, position); + const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + Cesium.Matrix4.multiplyByPoint(transform, offset, position); - camera.flyTo({ - destination: position, - orientation: { - heading: heading, - pitch: pitch, - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - }); - } + camera.flyTo({ + destination: position, + orientation: { + heading: heading, + pitch: pitch, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + }); + } - function offsetFromHeadingPitchRange(heading, pitch, range) { - pitch = Cesium.Math.clamp( - pitch, - -Cesium.Math.PI_OVER_TWO, - Cesium.Math.PI_OVER_TWO - ); - heading = - Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; + function offsetFromHeadingPitchRange(heading, pitch, range) { + pitch = Cesium.Math.clamp( + pitch, + -Cesium.Math.PI_OVER_TWO, + Cesium.Math.PI_OVER_TWO + ); + heading = Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; - const pitchQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Y, - -pitch - ); - const headingQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Z, - -heading - ); - const rotQuat = Cesium.Quaternion.multiply( - headingQuat, - pitchQuat, - headingQuat - ); - const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); + const pitchQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Y, + -pitch + ); + const headingQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Z, + -heading + ); + const rotQuat = Cesium.Quaternion.multiply( + headingQuat, + pitchQuat, + headingQuat + ); + const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); - const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); - Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); - Cesium.Cartesian3.negate(offset, offset); - Cesium.Cartesian3.multiplyByScalar(offset, range, offset); - return offset; - } - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); + Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); + Cesium.Cartesian3.negate(offset, offset); + Cesium.Cartesian3.multiplyByScalar(offset, range, offset); + return offset; + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interior.html b/Apps/Sandcastle/gallery/3D Tiles Interior.html index 55689cb4697..2a95807f28b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interior.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interior.html @@ -33,7 +33,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // San Miguel model created by Guillermo M. Leal Llaguno. Cleaned up and hosted by Morgan McGuire: http://graphics.cs.williams.edu/data/meshes.xml @@ -64,7 +64,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index 97a59a9aadc..515f30909f2 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -449,11 +449,14 @@ ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 6ad48f0367a..6ed0f78f7c8 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -32,23 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // San Francisco Ferry Building photogrammetry model provided by Aerometrex const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, orderIndependentTranslucency: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2021-11-09T20:27:37.016064475348684937Z" ); @@ -363,7 +356,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html index 26091096f6a..f1d18063448 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -228,11 +228,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 06ac7065e20..233b9d36d80 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -33,56 +33,58 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // An example of using a b3dm tileset to classify another b3dm tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // An example of using a b3dm tileset to classify another b3dm tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - // A normal b3dm tileset containing photogrammetry - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + // A normal b3dm tileset containing photogrammetry + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); - const classificationTilesetUrl = - "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; - // A b3dm tileset used to classify the photogrammetry tileset - const classificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(classificationTileset); + const classificationTilesetUrl = + "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; + // A b3dm tileset used to classify the photogrammetry tileset + const classificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(classificationTileset); - // The same b3dm tileset used for classification, but rendered normally for comparison. - const nonClassificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - show: false, - }); - nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(nonClassificationTileset); + // The same b3dm tileset used for classification, but rendered normally for comparison. + const nonClassificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + show: false, + }); + nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(nonClassificationTileset); - Sandcastle.addToggleButton("Show classification", true, function ( - checked - ) { - classificationTileset.show = checked; - nonClassificationTileset.show = !checked; - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("Show classification", true, function ( + checked + ) { + classificationTileset.show = checked; + nonClassificationTileset.show = !checked; + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index a53e6ff3122..68b2f6f3eda 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -33,26 +33,27 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index 40c6d2a0784..a2f0a3618ce 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -33,92 +33,93 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // An example showing a point cloud tileset classified by a Geometry tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + // An example showing a point cloud tileset classified by a Geometry tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - // Geometry Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry - const classificationTileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - viewer.scene.primitives.add(classificationTileset); + // Geometry Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry + const classificationTileset = new Cesium.Cesium3DTileset({ + url: + "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + viewer.scene.primitives.add(classificationTileset); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${id} === 'roof1'", "color('#004FFF', 0.5)"], - ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], - ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], - ["${id} === 'roof2'", "color('#004FFF', 0.5)"], - ["${id} === 'tower3'", "color('#FF8833', 0.5)"], - ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], - ["true", "color('#FFFF00', 0.5)"], - ], - }, - }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${id} === 'roof1'", "color('#004FFF', 0.5)"], + ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], + ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], + ["${id} === 'roof2'", "color('#004FFF', 0.5)"], + ["${id} === 'tower3'", "color('#FF8833', 0.5)"], + ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], + ["true", "color('#FFFF00', 0.5)"], + ], + }, + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index 252a9d20f60..cbbb50ece83 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -157,231 +157,230 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - let viewModelTileset; + const scene = viewer.scene; + let viewModelTileset; - if (!Cesium.PointCloudShading.isSupported(scene)) { - window.alert("This browser does not support point cloud shading"); - } + if (!Cesium.PointCloudShading.isSupported(scene)) { + window.alert("This browser does not support point cloud shading"); + } - function reset() { - viewer.scene.primitives.remove(viewModelTileset); - viewModelTileset = undefined; - } + function reset() { + viewer.scene.primitives.remove(viewModelTileset); + viewModelTileset = undefined; + } - // The viewModel tracks the state of our mini application. - const pointClouds = ["St. Helens", "Church"]; - const viewModel = { - exampleTypes: pointClouds, - currentExampleType: pointClouds[0], - maximumScreenSpaceError: 16.0, - geometricErrorScale: 1.0, - maximumAttenuation: 0, // Equivalent to undefined - baseResolution: 0, // Equivalent to undefined - eyeDomeLightingStrength: 1.0, - eyeDomeLightingRadius: 1.0, - }; + // The viewModel tracks the state of our mini application. + const pointClouds = ["St. Helens", "Church"]; + const viewModel = { + exampleTypes: pointClouds, + currentExampleType: pointClouds[0], + maximumScreenSpaceError: 16.0, + geometricErrorScale: 1.0, + maximumAttenuation: 0, // Equivalent to undefined + baseResolution: 0, // Equivalent to undefined + eyeDomeLightingStrength: 1.0, + eyeDomeLightingRadius: 1.0, + }; - function tilesetToViewModel(tileset) { - viewModelTileset = tileset; - - const pointCloudShading = tileset.pointCloudShading; - viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; - viewModel.geometricErrorScale = - pointCloudShading.geometricErrorScale; - viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation - ? pointCloudShading.maximumAttenuation - : 0; - viewModel.baseResolution = pointCloudShading.baseResolution - ? pointCloudShading.baseResolution - : 0; - viewModel.eyeDomeLightingStrength = - pointCloudShading.eyeDomeLightingStrength; - viewModel.eyeDomeLightingRadius = - pointCloudShading.eyeDomeLightingRadius; - } + function tilesetToViewModel(tileset) { + viewModelTileset = tileset; - function loadStHelens() { - // Set the initial camera view to look at Mt. St. Helens - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + const pointCloudShading = tileset.pointCloudShading; + viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; + viewModel.geometricErrorScale = pointCloudShading.geometricErrorScale; + viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation + ? pointCloudShading.maximumAttenuation + : 0; + viewModel.baseResolution = pointCloudShading.baseResolution + ? pointCloudShading.baseResolution + : 0; + viewModel.eyeDomeLightingStrength = + pointCloudShading.eyeDomeLightingStrength; + viewModel.eyeDomeLightingRadius = + pointCloudShading.eyeDomeLightingRadius; + } - // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ - // This tileset uses replacement refinement and has geometric error approximately equal to - // the average interpoint distance in each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - viewer.scene.primitives.add(tileset); - - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead - tileset.pointCloudShading.baseResolution = undefined; - tileset.pointCloudShading.geometricErrorScale = 1.0; - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + function loadStHelens() { + // Set the initial camera view to look at Mt. St. Helens + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - tilesetToViewModel(tileset); - } + // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ + // This tileset uses replacement refinement and has geometric error approximately equal to + // the average interpoint distance in each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + viewer.scene.primitives.add(tileset); - function loadChurch() { - // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead + tileset.pointCloudShading.baseResolution = undefined; + tileset.pointCloudShading.geometricErrorScale = 1.0; + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. - tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. - tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tilesetToViewModel(tileset); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + function loadChurch() { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - tilesetToViewModel(tileset); - } + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. + tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. + tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - function checkZero(newValue) { - const newValueFloat = parseFloat(newValue); - return newValueFloat === 0.0 ? undefined : newValueFloat; - } + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - loadStHelens(); + tilesetToViewModel(tileset); + } - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + function checkZero(newValue) { + const newValueFloat = parseFloat(newValue); + return newValueFloat === 0.0 ? undefined : newValueFloat; + } - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + loadStHelens(); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === pointClouds[0]) { - loadStHelens(); - } else if (newValue === pointClouds[1]) { - loadChurch(); - } - }); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - Cesium.knockout - .getObservable(viewModel, "maximumScreenSpaceError") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); - } - }); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "geometricErrorScale") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === pointClouds[0]) { + loadStHelens(); + } else if (newValue === pointClouds[1]) { + loadChurch(); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumAttenuation") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumScreenSpaceError") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); + } + }); - Cesium.knockout - .getObservable(viewModel, "baseResolution") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.baseResolution = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "geometricErrorScale") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingStrength") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumAttenuation") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingRadius") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "baseResolution") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.baseResolution = checkZero( + newValue + ); + } + }); - Sandcastle.addToggleButton("Enable Attenuation", true, function ( - checked - ) { + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingStrength") + .subscribe(function (newValue) { if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.attenuation = checked; + viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( + newValue + ); } }); - Sandcastle.addToggleButton( - "Enable Eye Dome Lighting", - true, - function (checked) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLighting = checked; - } + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingRadius") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( + newValue + ); } - ); - })(); //Sandcastle_End + }); + + Sandcastle.addToggleButton("Enable Attenuation", true, function ( + checked + ) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.attenuation = checked; + } + }); + + Sandcastle.addToggleButton("Enable Eye Dome Lighting", true, function ( + checked + ) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLighting = checked; + } + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html index 217312d33f9..c0d8b25038f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -234,11 +234,14 @@ Sandcastle.addToolbarMenu(styleOptions); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index babe9cceede..8779b985f8e 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -33,38 +33,40 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); - })(); //Sandcastle_End + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index f298cfd42fe..1093592f986 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -33,65 +33,66 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const geocoder = viewer.geocoder.viewModel; - geocoder.searchText = "Vienna"; - geocoder.flightDuration = 0.0; - geocoder.search(); + const geocoder = viewer.geocoder.viewModel; + geocoder.searchText = "Vienna"; + geocoder.flightDuration = 0.0; + geocoder.search(); - // Vector 3D Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5737), - }); - viewer.scene.primitives.add(tileset); + // Vector 3D Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5737), + }); + viewer.scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 255, 255, 0.5)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 255, 255, 0.5)", + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW; - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW; + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Ambient Occlusion.html b/Apps/Sandcastle/gallery/Ambient Occlusion.html index 650b1cfb618..5575c9ebe55 100644 --- a/Apps/Sandcastle/gallery/Ambient Occlusion.html +++ b/Apps/Sandcastle/gallery/Ambient Occlusion.html @@ -110,7 +110,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -207,7 +207,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS MapServer.html b/Apps/Sandcastle/gallery/ArcGIS MapServer.html index 0c286155613..6ef348f9b27 100644 --- a/Apps/Sandcastle/gallery/ArcGIS MapServer.html +++ b/Apps/Sandcastle/gallery/ArcGIS MapServer.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -39,11 +39,14 @@ }), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index dce86820a80..e16d10af0b5 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -29,25 +29,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - try { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index 32414bf7eb1..63898c9c0cb 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -32,22 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. - // https://www.pgc.umn.edu/data/arcticdem/ - viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3956) - ); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. + // https://www.pgc.umn.edu/data/arcticdem/ + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3956) + ), + }); // Add Alaskan locations Sandcastle.addDefaultToolbarMenu( @@ -124,11 +118,14 @@ "toolbar" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Atmosphere.html b/Apps/Sandcastle/gallery/Atmosphere.html index 69382766603..f72de2db6aa 100644 --- a/Apps/Sandcastle/gallery/Atmosphere.html +++ b/Apps/Sandcastle/gallery/Atmosphere.html @@ -665,7 +665,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -1026,11 +1026,14 @@ }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Billboards.html b/Apps/Sandcastle/gallery/Billboards.html index b166b6398d8..2a84a6bd5be 100644 --- a/Apps/Sandcastle/gallery/Billboards.html +++ b/Apps/Sandcastle/gallery/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -362,11 +362,14 @@ } }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Bloom.html b/Apps/Sandcastle/gallery/Bloom.html index 21d7f82fc7e..24f13bc3775 100644 --- a/Apps/Sandcastle/gallery/Bloom.html +++ b/Apps/Sandcastle/gallery/Bloom.html @@ -105,7 +105,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -179,11 +179,14 @@ ); viewer.scene.camera.lookAt(target, offset); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Blue Marble.html b/Apps/Sandcastle/gallery/Blue Marble.html index ba4a89bef39..f6bf5104167 100644 --- a/Apps/Sandcastle/gallery/Blue Marble.html +++ b/Apps/Sandcastle/gallery/Blue Marble.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Blue Marble Next Generation July, 2004 imagery from NASA @@ -40,11 +40,14 @@ imageryProvider: new Cesium.IonImageryProvider({ assetId: 3845 }), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Box.html b/Apps/Sandcastle/gallery/Box.html index 0860eb90f7c..a6a97eac612 100644 --- a/Apps/Sandcastle/gallery/Box.html +++ b/Apps/Sandcastle/gallery/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -67,11 +67,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML 3D Tiles.html b/Apps/Sandcastle/gallery/CZML 3D Tiles.html index 898cb91dfb5..3b1e28b2bea 100644 --- a/Apps/Sandcastle/gallery/CZML 3D Tiles.html +++ b/Apps/Sandcastle/gallery/CZML 3D Tiles.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -64,11 +64,14 @@ window.alert(error); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Billboard and Label.html b/Apps/Sandcastle/gallery/CZML Billboard and Label.html index 358e1002c8c..c63aa7c703f 100644 --- a/Apps/Sandcastle/gallery/CZML Billboard and Label.html +++ b/Apps/Sandcastle/gallery/CZML Billboard and Label.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -78,11 +78,14 @@ const viewer = new Cesium.Viewer("cesiumContainer"); viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Box.html b/Apps/Sandcastle/gallery/CZML Box.html index fe4ce90b875..411335c7978 100644 --- a/Apps/Sandcastle/gallery/CZML Box.html +++ b/Apps/Sandcastle/gallery/CZML Box.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -109,7 +109,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html index db1ac667a79..09233ee270d 100644 --- a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -111,11 +111,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Colors.html b/Apps/Sandcastle/gallery/CZML Colors.html index 4be19a1fd54..3ab17adf809 100644 --- a/Apps/Sandcastle/gallery/CZML Colors.html +++ b/Apps/Sandcastle/gallery/CZML Colors.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -91,7 +91,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html index 2630386eda0..65bab8ed840 100644 --- a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html +++ b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -89,11 +89,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Corridor.html b/Apps/Sandcastle/gallery/CZML Corridor.html index d74d3b838e5..3a80bd54291 100644 --- a/Apps/Sandcastle/gallery/CZML Corridor.html +++ b/Apps/Sandcastle/gallery/CZML Corridor.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -141,11 +141,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Custom Properties.html b/Apps/Sandcastle/gallery/CZML Custom Properties.html index 7b6dbc16212..7217a1083e6 100644 --- a/Apps/Sandcastle/gallery/CZML Custom Properties.html +++ b/Apps/Sandcastle/gallery/CZML Custom Properties.html @@ -32,7 +32,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -176,7 +176,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html index d08df40e333..10c8329c6c3 100644 --- a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html +++ b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -109,11 +109,14 @@ .catch(function (error) { window.alert(error); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Articulations.html b/Apps/Sandcastle/gallery/CZML Model Articulations.html index b5964db15fa..b0646be054d 100644 --- a/Apps/Sandcastle/gallery/CZML Model Articulations.html +++ b/Apps/Sandcastle/gallery/CZML Model Articulations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -94,11 +94,14 @@ console.error(error); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Data URL.html b/Apps/Sandcastle/gallery/CZML Model Data URL.html index 891c5528630..b0561778dcd 100644 --- a/Apps/Sandcastle/gallery/CZML Model Data URL.html +++ b/Apps/Sandcastle/gallery/CZML Model Data URL.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const gltf = { @@ -176,7 +176,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model.html b/Apps/Sandcastle/gallery/CZML Model.html index a9299d5aa2d..dd11df82b26 100644 --- a/Apps/Sandcastle/gallery/CZML Model.html +++ b/Apps/Sandcastle/gallery/CZML Model.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -72,11 +72,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Path.html b/Apps/Sandcastle/gallery/CZML Path.html index 1732ea900b3..88705898430 100644 --- a/Apps/Sandcastle/gallery/CZML Path.html +++ b/Apps/Sandcastle/gallery/CZML Path.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -7243,24 +7243,25 @@ }, ]; - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - baseLayerPicker: false, - shouldAnimate: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + baseLayerPicker: false, + shouldAnimate: true, + }); - const dataSource = await viewer.dataSources.add( - Cesium.CzmlDataSource.load(czml) - ); + const dataSource = await viewer.dataSources.add( + Cesium.CzmlDataSource.load(czml) + ); - viewer.trackedEntity = dataSource.entities.getById("path"); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + viewer.trackedEntity = dataSource.entities.getById("path"); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html index 63470fd2f66..3ca62d6746d 100644 --- a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html +++ b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -87,7 +87,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point.html b/Apps/Sandcastle/gallery/CZML Point.html index 5bc606f8ffb..078e3b4d0b6 100644 --- a/Apps/Sandcastle/gallery/CZML Point.html +++ b/Apps/Sandcastle/gallery/CZML Point.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -64,11 +64,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html index 9a37834493f..0d6dc2a7271 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -208,11 +208,14 @@ viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html index 902d2757502..ad1790d3678 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -223,11 +223,14 @@ viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon.html b/Apps/Sandcastle/gallery/CZML Polygon.html index f5ade1d453e..547eeb9cdce 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon.html +++ b/Apps/Sandcastle/gallery/CZML Polygon.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -220,11 +220,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline Volume.html b/Apps/Sandcastle/gallery/CZML Polyline Volume.html index 56970ce3fdd..0b90904f91f 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline Volume.html +++ b/Apps/Sandcastle/gallery/CZML Polyline Volume.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -149,11 +149,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline.html b/Apps/Sandcastle/gallery/CZML Polyline.html index 15e2ae74b29..87e571605e8 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline.html +++ b/Apps/Sandcastle/gallery/CZML Polyline.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -141,11 +141,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Position Definitions.html b/Apps/Sandcastle/gallery/CZML Position Definitions.html index 43df14ff7cb..6520d1bd165 100644 --- a/Apps/Sandcastle/gallery/CZML Position Definitions.html +++ b/Apps/Sandcastle/gallery/CZML Position Definitions.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -107,7 +107,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Rectangle.html b/Apps/Sandcastle/gallery/CZML Rectangle.html index 1a98dda45eb..b324fae6e2b 100644 --- a/Apps/Sandcastle/gallery/CZML Rectangle.html +++ b/Apps/Sandcastle/gallery/CZML Rectangle.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -126,11 +126,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Reference Properties.html b/Apps/Sandcastle/gallery/CZML Reference Properties.html index 24c7cf38921..34a606fb798 100644 --- a/Apps/Sandcastle/gallery/CZML Reference Properties.html +++ b/Apps/Sandcastle/gallery/CZML Reference Properties.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -130,11 +130,14 @@ const viewer = new Cesium.Viewer("cesiumContainer"); viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html index e5f437e4680..13f7d81192e 100644 --- a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -110,11 +110,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Wall.html b/Apps/Sandcastle/gallery/CZML Wall.html index e35de4ada58..ce0c7c2f947 100644 --- a/Apps/Sandcastle/gallery/CZML Wall.html +++ b/Apps/Sandcastle/gallery/CZML Wall.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -96,11 +96,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML ZIndex.html b/Apps/Sandcastle/gallery/CZML ZIndex.html index ead9d1c59fa..492f9ba8868 100644 --- a/Apps/Sandcastle/gallery/CZML ZIndex.html +++ b/Apps/Sandcastle/gallery/CZML ZIndex.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -150,7 +150,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML.html b/Apps/Sandcastle/gallery/CZML.html index d76fb8b77c5..fb751de1aa4 100644 --- a/Apps/Sandcastle/gallery/CZML.html +++ b/Apps/Sandcastle/gallery/CZML.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -65,11 +65,14 @@ viewer.dataSources.removeAll(); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Callback Property.html b/Apps/Sandcastle/gallery/Callback Property.html index 5d63d5ad719..8747ff39473 100644 --- a/Apps/Sandcastle/gallery/Callback Property.html +++ b/Apps/Sandcastle/gallery/Callback Property.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // This example illustrates a Callback Property, a property whose @@ -122,7 +122,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera Tutorial.html b/Apps/Sandcastle/gallery/Camera Tutorial.html index ef38bd93a4d..5e0ebb73a2d 100644 --- a/Apps/Sandcastle/gallery/Camera Tutorial.html +++ b/Apps/Sandcastle/gallery/Camera Tutorial.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -186,11 +186,14 @@ } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera.html b/Apps/Sandcastle/gallery/Camera.html index b4d3d8af64c..340b5f18bf6 100644 --- a/Apps/Sandcastle/gallery/Camera.html +++ b/Apps/Sandcastle/gallery/Camera.html @@ -42,7 +42,7 @@ <div id="cameraChanged">Camera Changed</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -489,7 +489,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cardboard.html b/Apps/Sandcastle/gallery/Cardboard.html index 7304c8a6aab..ad7cf758ecd 100644 --- a/Apps/Sandcastle/gallery/Cardboard.html +++ b/Apps/Sandcastle/gallery/Cardboard.html @@ -32,163 +32,164 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - vrButton: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - // Click the VR button in the bottom right of the screen to switch to VR mode. - - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; - - // Follow the path of a plane. See the interpolation Sandcastle example. - Cesium.Math.setRandomNumberSeed(3); - - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); - - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; - viewer.clock.shouldAnimate = true; - - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - const startAngle = Cesium.Math.nextRandomNumber() * 360.0; - const endAngle = startAngle + 360.0; - - const increment = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; - for (let i = startAngle; i < endAngle; i += increment) { - const radians = Cesium.Math.toRadians(i); - const timeIncrement = i - startAngle; - const time = Cesium.JulianDate.addSeconds( - start, - timeIncrement, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1800 - ); - property.addSample(time, position); - } - return property; + const viewer = new Cesium.Viewer("cesiumContainer", { + vrButton: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + // Click the VR button in the bottom right of the screen to switch to VR mode. + + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; + + // Follow the path of a plane. See the interpolation Sandcastle example. + Cesium.Math.setRandomNumberSeed(3); + + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() + ); + + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + viewer.clock.shouldAnimate = true; + + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + const startAngle = Cesium.Math.nextRandomNumber() * 360.0; + const endAngle = startAngle + 360.0; + + const increment = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; + for (let i = startAngle; i < endAngle; i += increment) { + const radians = Cesium.Math.toRadians(i); + const timeIncrement = i - startAngle; + const time = Cesium.JulianDate.addSeconds( + start, + timeIncrement, + new Cesium.JulianDate() + ); + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1800 + ); + property.addSample(time, position); + } + return property; + } + + const longitude = -112.110693; + const latitude = 36.0994841; + const radius = 0.03; + + const modelURI = + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; + const entity = viewer.entities.add({ + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + position: computeCirclularFlight(longitude, latitude, radius), + model: { + uri: modelURI, + minimumPixelSize: 64, + }, + }); + + entity.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); + + // Set initial camera position and orientation to be when in the model's reference frame. + const camera = viewer.camera; + camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); + camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); + camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); + camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); + + viewer.scene.postUpdate.addEventListener(function (scene, time) { + const position = entity.position.getValue(time); + if (!Cesium.defined(position)) { + return; } - const longitude = -112.110693; - const latitude = 36.0994841; - const radius = 0.03; + let transform; + if (!Cesium.defined(entity.orientation)) { + transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + } else { + const orientation = entity.orientation.getValue(time); + if (!Cesium.defined(orientation)) { + return; + } - const modelURI = - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; - const entity = viewer.entities.add({ + transform = Cesium.Matrix4.fromRotationTranslation( + Cesium.Matrix3.fromQuaternion(orientation), + position + ); + } + + // Save camera state + const offset = Cesium.Cartesian3.clone(camera.position); + const direction = Cesium.Cartesian3.clone(camera.direction); + const up = Cesium.Cartesian3.clone(camera.up); + + // Set camera to be in model's reference frame. + camera.lookAtTransform(transform); + + // Reset the camera state to the saved state so it appears fixed in the model's frame. + Cesium.Cartesian3.clone(offset, camera.position); + Cesium.Cartesian3.clone(direction, camera.direction); + Cesium.Cartesian3.clone(up, camera.up); + Cesium.Cartesian3.cross(direction, up, camera.right); + }); + + // Add a few more balloons flying with the one the viewer is in. + const numBalloons = 12; + for (let i = 0; i < numBalloons; ++i) { + const balloonRadius = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; + const balloon = viewer.entities.add({ availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start: start, stop: stop, }), ]), - position: computeCirclularFlight(longitude, latitude, radius), + position: computeCirclularFlight( + longitude, + latitude, + balloonRadius + ), model: { uri: modelURI, minimumPixelSize: 64, }, }); - entity.position.setInterpolationOptions({ + balloon.position.setInterpolationOptions({ interpolationDegree: 2, interpolationAlgorithm: Cesium.HermitePolynomialApproximation, }); - - // Set initial camera position and orientation to be when in the model's reference frame. - const camera = viewer.camera; - camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); - camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); - camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); - camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); - - viewer.scene.postUpdate.addEventListener(function (scene, time) { - const position = entity.position.getValue(time); - if (!Cesium.defined(position)) { - return; - } - - let transform; - if (!Cesium.defined(entity.orientation)) { - transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - } else { - const orientation = entity.orientation.getValue(time); - if (!Cesium.defined(orientation)) { - return; - } - - transform = Cesium.Matrix4.fromRotationTranslation( - Cesium.Matrix3.fromQuaternion(orientation), - position - ); - } - - // Save camera state - const offset = Cesium.Cartesian3.clone(camera.position); - const direction = Cesium.Cartesian3.clone(camera.direction); - const up = Cesium.Cartesian3.clone(camera.up); - - // Set camera to be in model's reference frame. - camera.lookAtTransform(transform); - - // Reset the camera state to the saved state so it appears fixed in the model's frame. - Cesium.Cartesian3.clone(offset, camera.position); - Cesium.Cartesian3.clone(direction, camera.direction); - Cesium.Cartesian3.clone(up, camera.up); - Cesium.Cartesian3.cross(direction, up, camera.right); - }); - - // Add a few more balloons flying with the one the viewer is in. - const numBalloons = 12; - for (let i = 0; i < numBalloons; ++i) { - const balloonRadius = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; - const balloon = viewer.entities.add({ - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - position: computeCirclularFlight( - longitude, - latitude, - balloonRadius - ), - model: { - uri: modelURI, - minimumPixelSize: 64, - }, - }); - - balloon.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); - } - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 7c32bfee9fa..043814d13fe 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -32,70 +32,72 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - // Tropics of Cancer and Capricorn - const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( - -180.0, - -23.43687, - 180.0, - 23.43687 - ); + // Tropics of Cancer and Capricorn + const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( + -180.0, + -23.43687, + 180.0, + 23.43687 + ); - globe.cartographicLimitRectangle = coffeeBeltRectangle; - globe.showSkirts = false; - globe.backFaceCulling = false; - globe.undergroundColor = undefined; - scene.skyAtmosphere.show = false; + globe.cartographicLimitRectangle = coffeeBeltRectangle; + globe.showSkirts = false; + globe.backFaceCulling = false; + globe.undergroundColor = undefined; + scene.skyAtmosphere.show = false; - // Add rectangles to show bounds - const rectangles = []; + // Add rectangles to show bounds + const rectangles = []; - for (let i = 0; i < 10; i++) { - rectangles.push( - viewer.entities.add({ - rectangle: { - coordinates: coffeeBeltRectangle, - material: Cesium.Color.WHITE.withAlpha(0.0), - height: i * 5000.0, - outline: true, - outlineWidth: 4.0, - outlineColor: Cesium.Color.WHITE, - }, - }) - ); - } + for (let i = 0; i < 10; i++) { + rectangles.push( + viewer.entities.add({ + rectangle: { + coordinates: coffeeBeltRectangle, + material: Cesium.Color.WHITE.withAlpha(0.0), + height: i * 5000.0, + outline: true, + outlineWidth: 4.0, + outlineColor: Cesium.Color.WHITE, + }, + }) + ); + } - Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { - if (checked) { - viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; - } else { - viewer.scene.globe.cartographicLimitRectangle = undefined; - } - }); + Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { + if (checked) { + viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; + } else { + viewer.scene.globe.cartographicLimitRectangle = undefined; + } + }); - Sandcastle.addToggleButton("Show Bounds", true, function (checked) { - const rectanglesLength = rectangles.length; - for (let i = 0; i < rectanglesLength; i++) { - const rectangleEntity = rectangles[i]; - rectangleEntity.show = checked; - } - }); - })(); //Sandcastle_End + Sandcastle.addToggleButton("Show Bounds", true, function (checked) { + const rectanglesLength = rectangles.length; + for (let i = 0; i < rectanglesLength; i++) { + const rectangleEntity = rectangles[i]; + rectangleEntity.show = checked; + } + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Inspector.html b/Apps/Sandcastle/gallery/Cesium Inspector.html index 6d1773608e2..4a11858124b 100644 --- a/Apps/Sandcastle/gallery/Cesium Inspector.html +++ b/Apps/Sandcastle/gallery/Cesium Inspector.html @@ -36,91 +36,84 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; - //Add Cesium Inspector - viewer.extend(Cesium.viewerCesiumInspectorMixin); + //Add Cesium Inspector + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //Add Primitives - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3( - 400000.0, - 300000.0, - 500000.0 - ), - }), - modelMatrix: Cesium.Matrix4.multiplyByTranslation( - Cesium.Transforms.eastNorthUpToFixedFrame( - Cesium.Cartesian3.fromDegrees(-105.0, 45.0) - ), - new Cesium.Cartesian3(0.0, 0.0, 250000), - new Cesium.Matrix4() - ), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.RED.withAlpha(0.5) - ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance({ - closed: true, + //Add Primitives + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), }), - }) - ); + modelMatrix: Cesium.Matrix4.multiplyByTranslation( + Cesium.Transforms.eastNorthUpToFixedFrame( + Cesium.Cartesian3.fromDegrees(-105.0, 45.0) + ), + new Cesium.Cartesian3(0.0, 0.0, 250000), + new Cesium.Matrix4() + ), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.RED.withAlpha(0.5) + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance({ + closed: true, + }), + }) + ); - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -93.0, - 37.0 - ), - height: 100000, - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.BLUE - ), - }, + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -93.0, + 37.0 + ), + height: 100000, + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, }), - appearance: new Cesium.PerInstanceColorAppearance(), - }) - ); + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.BLUE + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance(), + }) + ); - const billboards = scene.primitives.add( - new Cesium.BillboardCollection() - ); - billboards.add({ - position: Cesium.Cartesian3.fromDegrees( - -75.59777, - 40.03883, - 150000 - ), - image: "../images/Cesium_Logo_overlay.png", - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + const billboards = scene.primitives.add( + new Cesium.BillboardCollection() + ); + billboards.add({ + position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 150000), + image: "../images/Cesium_Logo_overlay.png", + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index ea639ecbb39..6472a4ae6c5 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -35,29 +35,30 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.primitives.add(Cesium.createOsmBuildings()); + viewer.scene.primitives.add(Cesium.createOsmBuildings()); - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), - orientation: { - heading: Cesium.Math.toRadians(20), - pitch: Cesium.Math.toRadians(-20), - }, - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), + orientation: { + heading: Cesium.Math.toRadians(20), + pitch: Cesium.Math.toRadians(-20), + }, + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Widget.html b/Apps/Sandcastle/gallery/Cesium Widget.html index 55e1f10e93e..18eb5692f8b 100644 --- a/Apps/Sandcastle/gallery/Cesium Widget.html +++ b/Apps/Sandcastle/gallery/Cesium Widget.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Cesium.CesiumWidget is similar to Cesium.Viewer, but @@ -42,11 +42,14 @@ // Knockout library. const widget = new Cesium.CesiumWidget("cesiumContainer"); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 016a5720fb5..0e4162731d7 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -32,24 +32,22 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // For more information on Cesium World Terrain, see https://cesium.com/platform/cesium-ion/content/cesium-world-terrain/ - (async () => { - try { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Circles and Ellipses.html b/Apps/Sandcastle/gallery/Circles and Ellipses.html index c112576c519..b453cc28d76 100644 --- a/Apps/Sandcastle/gallery/Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/Circles and Ellipses.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -74,11 +74,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Model.html b/Apps/Sandcastle/gallery/Clamp to 3D Model.html index fd91a1ab475..c90373786dd 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Model.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Model.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -108,11 +108,14 @@ } viewer.trackedEntity = entity; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index 57ccc1cb57a..048b34bad1b 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -32,66 +32,68 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const clock = viewer.clock; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + const clock = viewer.clock; - let entity; - let positionProperty; - const dataSourcePromise = Cesium.CzmlDataSource.load( - "../../SampleData/ClampToGround.czml" - ); - viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { - entity = dataSource.entities.getById("CesiumMilkTruck"); - positionProperty = entity.position; - }); + let entity; + let positionProperty; + const dataSourcePromise = Cesium.CzmlDataSource.load( + "../../SampleData/ClampToGround.czml" + ); + viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { + entity = dataSource.entities.getById("CesiumMilkTruck"); + positionProperty = entity.position; + }); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) + ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1216403.8845586285, - -4736357.493351395, - 4081299.715698949 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.2892217081808806, - -0.4799070147502502, - 6.279789177843313 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1216403.8845586285, + -4736357.493351395, + 4081299.715698949 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.2892217081808806, + -0.4799070147502502, + 6.279789177843313 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - if (scene.clampToHeightSupported) { - tileset.initialTilesLoaded.addEventListener(start); - } else { - window.alert("This browser does not support clampToHeight."); - } + if (scene.clampToHeightSupported) { + tileset.initialTilesLoaded.addEventListener(start); + } else { + window.alert("This browser does not support clampToHeight."); + } - function start() { - clock.shouldAnimate = true; - const objectsToExclude = [entity]; - scene.postRender.addEventListener(function () { - const position = positionProperty.getValue(clock.currentTime); - entity.position = scene.clampToHeight(position, objectsToExclude); - }); - } - })(); //Sandcastle_End + function start() { + clock.shouldAnimate = true; + const objectsToExclude = [entity]; + scene.postRender.addEventListener(function () { + const position = positionProperty.getValue(clock.currentTime); + entity.position = scene.clampToHeight(position, objectsToExclude); + }); + } //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index f6b20444f25..5a8442b19e6 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -34,20 +34,14 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - Sandcastle.addDefaultToolbarMenu( [ { @@ -361,11 +355,14 @@ viewer.entities.removeAll(); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 3ac16b5dc61..48a91083aea 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -32,18 +32,12 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(40866), @@ -175,11 +169,14 @@ Sandcastle.addToolbarMenu(classificationOptions); Sandcastle.addToolbarMenu(materialOptions); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index b9b003fa070..fe0c96719a9 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -76,317 +76,279 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const camera = scene.camera; + const scene = viewer.scene; + const camera = scene.camera; - let center = new Cesium.Cartesian3( - 1216389.3637977627, - -4736323.641980423, - 4081321.7428341154 - ); - let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) - ); - let hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + let center = new Cesium.Cartesian3( + 1216389.3637977627, + -4736323.641980423, + 4081321.7428341154 + ); + let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) + ); + let hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const buildingHighlight = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume", + const buildingHighlight = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216409.0189737265, - -4736252.144235287, - 4081393.6027081604 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.4, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216409.0189737265, + -4736252.144235287, + 4081393.6027081604 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.4, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight1 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 1", + const treeHighlight1 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 1", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216404.8844045496, - -4736255.287065536, - 4081392.010192471 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(-0.25, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216404.8844045496, + -4736255.287065536, + 4081392.010192471 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(-0.25, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight2 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 2", + const treeHighlight2 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 2", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216398.813990024, - -4736258.039875737, - 4081387.9562678365 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216398.813990024, + -4736258.039875737, + 4081387.9562678365 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight3 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 3", + const treeHighlight3 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 3", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216393.6257790313, - -4736259.809075361, - 4081384.4858198245 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -1.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216393.6257790313, + -4736259.809075361, + 4081384.4858198245 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -1.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight4 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.SphereGeometry({ - radius: 2.0, - }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 4", + const treeHighlight4 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.SphereGeometry({ + radius: 2.0, }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); - - function highlightBuilding() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216394.1392207467, - -4736348.59346919, - 4081293.9160685353 - ), - orientation: { - heading: 0.018509338875732695, - pitch: -0.09272999615872646, + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), }, - }); - } - - function highlightTrees() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216435.0352745096, - -4736283.144192113, - 4081368.0920420634 - ), - orientation: { - heading: 5.718380792746039, - pitch: -0.3087010195266797, - }, - }); - } + id: "volume 4", + }), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - function invertClassification(checked) { - if (checked && !scene.invertClassificationSupported) { - window.alert( - "This browser does not support invert classification" - ); - } + function highlightBuilding() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216394.1392207467, + -4736348.59346919, + 4081293.9160685353 + ), + orientation: { + heading: 0.018509338875732695, + pitch: -0.09272999615872646, + }, + }); + } - scene.invertClassification = checked; - scene.invertClassificationColor = new Cesium.Color( - 0.25, - 0.25, - 0.25, - 1.0 - ); + function highlightTrees() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216435.0352745096, + -4736283.144192113, + 4081368.0920420634 + ), + orientation: { + heading: 5.718380792746039, + pitch: -0.3087010195266797, + }, + }); + } - buildingHighlight.getGeometryInstanceAttributes( - "volume" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight1.getGeometryInstanceAttributes( - "volume 1" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight2.getGeometryInstanceAttributes( - "volume 2" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight3.getGeometryInstanceAttributes( - "volume 3" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight4.getGeometryInstanceAttributes( - "volume 4" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + function invertClassification(checked) { + if (checked && !scene.invertClassificationSupported) { + window.alert("This browser does not support invert classification"); } - function updateAlpha(value) { - scene.invertClassificationColor.alpha = parseFloat(value); - } + scene.invertClassification = checked; + scene.invertClassificationColor = new Cesium.Color( + 0.25, + 0.25, + 0.25, + 1.0 + ); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - scene.primitives.add(tileset); + buildingHighlight.getGeometryInstanceAttributes( + "volume" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight1.getGeometryInstanceAttributes( + "volume 1" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight2.getGeometryInstanceAttributes( + "volume 2" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight3.getGeometryInstanceAttributes( + "volume 3" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight4.getGeometryInstanceAttributes( + "volume 4" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + } - const viewModel = { - inverted: viewer.scene.invertClassification, - invertedAlpha: viewer.scene.invertClassificationColor.alpha, - highlightBuilding: highlightBuilding, - highlightTrees: highlightTrees, - }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "inverted") - .subscribe(invertClassification); - Cesium.knockout - .getObservable(viewModel, "invertedAlpha") - .subscribe(updateAlpha); + function updateAlpha(value) { + scene.invertClassificationColor.alpha = parseFloat(value); + } - highlightTrees(); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + scene.primitives.add(tileset); - let currentObjectId; - let currentPrimitive; - let currentColor; - let currentShow; - let attributes; + const viewModel = { + inverted: viewer.scene.invertClassification, + invertedAlpha: viewer.scene.invertClassificationColor.alpha, + highlightBuilding: highlightBuilding, + highlightTrees: highlightTrees, + }; + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + Cesium.knockout + .getObservable(viewModel, "inverted") + .subscribe(invertClassification); + Cesium.knockout + .getObservable(viewModel, "invertedAlpha") + .subscribe(updateAlpha); - const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.id) - ) { - if (pickedObject.id === currentObjectId) { - return; - } + highlightTrees(); - if (Cesium.defined(currentObjectId)) { - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - attributes.color = currentColor; - attributes.show = currentShow; - currentObjectId = undefined; - currentPrimitive = undefined; - currentColor = undefined; - currentShow = undefined; - } + let currentObjectId; + let currentPrimitive; + let currentColor; + let currentShow; + let attributes; + + const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) { + if (pickedObject.id === currentObjectId) { + return; } - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.primitive) && - Cesium.defined(pickedObject.id) && - Cesium.defined( - pickedObject.primitive.getGeometryInstanceAttributes - ) - ) { - currentObjectId = pickedObject.id; - currentPrimitive = pickedObject.primitive; - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - currentColor = attributes.color; - currentShow = attributes.show; - if (!scene.invertClassification) { - attributes.color = [255, 0, 255, 128]; - } - attributes.show = [1]; - } else if (Cesium.defined(currentObjectId)) { + if (Cesium.defined(currentObjectId)) { attributes = currentPrimitive.getGeometryInstanceAttributes( currentObjectId ); @@ -395,14 +357,46 @@ currentObjectId = undefined; currentPrimitive = undefined; currentColor = undefined; + currentShow = undefined; } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + } + + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.primitive) && + Cesium.defined(pickedObject.id) && + Cesium.defined(pickedObject.primitive.getGeometryInstanceAttributes) + ) { + currentObjectId = pickedObject.id; + currentPrimitive = pickedObject.primitive; + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + currentColor = attributes.color; + currentShow = attributes.show; + if (!scene.invertClassification) { + attributes.color = [255, 0, 255, 128]; + } + attributes.show = [1]; + } else if (Cesium.defined(currentObjectId)) { + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + attributes.color = currentColor; + attributes.show = currentShow; + currentObjectId = undefined; + currentPrimitive = undefined; + currentColor = undefined; + } + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clock.html b/Apps/Sandcastle/gallery/Clock.html index 21364613c02..aedacb0ce17 100644 --- a/Apps/Sandcastle/gallery/Clock.html +++ b/Apps/Sandcastle/gallery/Clock.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create a clock that loops on Christmas day 2013 and runs in 4000x real time. @@ -66,7 +66,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cloud Parameters.html b/Apps/Sandcastle/gallery/Cloud Parameters.html index ce3b961b758..2d4a629c8fa 100644 --- a/Apps/Sandcastle/gallery/Cloud Parameters.html +++ b/Apps/Sandcastle/gallery/Cloud Parameters.html @@ -159,7 +159,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -310,11 +310,14 @@ viewer.camera.lookAt(position, new Cesium.Cartesian3(30, 30, -10)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index cf6d8466f53..f275991e71a 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -29,251 +29,253 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - infoBox: false, - shouldAnimate: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + infoBox: false, + shouldAnimate: true, + }); - const scene = viewer.scene; - scene.primitives.add(Cesium.createOsmBuildings()); + const scene = viewer.scene; + scene.primitives.add(Cesium.createOsmBuildings()); - /////////////////////////// - // Create clouds - /////////////////////////// + /////////////////////////// + // Create clouds + /////////////////////////// - Cesium.Math.setRandomNumberSeed(2.5); - function getRandomNumberInRange(minValue, maxValue) { - return ( - minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) - ); - } + Cesium.Math.setRandomNumberSeed(2.5); + function getRandomNumberInRange(minValue, maxValue) { + return ( + minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) + ); + } - const clouds = new Cesium.CloudCollection(); + const clouds = new Cesium.CloudCollection(); - // manually position clouds in the mountains - function createBackLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), - scale: new Cesium.Cartesian2(1500, 250), - maximumSize: new Cesium.Cartesian3(50, 15, 13), - slice: 0.3, - }); + // manually position clouds in the mountains + function createBackLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), + scale: new Cesium.Cartesian2(1500, 250), + maximumSize: new Cesium.Cartesian3(50, 15, 13), + slice: 0.3, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), - scale: new Cesium.Cartesian2(1500, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.36, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), + scale: new Cesium.Cartesian2(1500, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.36, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), - scale: new Cesium.Cartesian2(2000, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.49, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), + scale: new Cesium.Cartesian2(2000, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.49, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(13, 13, 13), - slice: 0.2, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(13, 13, 13), + slice: 0.2, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), - scale: new Cesium.Cartesian2(1700, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.6, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), + scale: new Cesium.Cartesian2(1700, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.6, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(15, 13, 15), - slice: 0.35, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(15, 13, 15), + slice: 0.35, + }); + + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), + scale: new Cesium.Cartesian2(1500, 500), + maximumSize: new Cesium.Cartesian3(30, 20, 17), + slice: 0.45, + }); + } + let long, + lat, + height, + scaleX, + scaleY, + aspectRatio, + cloudHeight, + depth, + slice; + + // randomly generate clouds in a certain area + function createRandomClouds( + numClouds, + startLong, + stopLong, + startLat, + stopLat, + minHeight, + maxHeight + ) { + const rangeLong = stopLong - startLong; + const rangeLat = stopLat - startLat; + for (let i = 0; i < numClouds; i++) { + long = startLong + getRandomNumberInRange(0, rangeLong); + lat = startLat + getRandomNumberInRange(0, rangeLat); + height = getRandomNumberInRange(minHeight, maxHeight); + scaleX = getRandomNumberInRange(150, 350); + scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); + slice = getRandomNumberInRange(0.3, 0.7); + depth = getRandomNumberInRange(5, 20); + aspectRatio = getRandomNumberInRange(1.5, 2.1); + cloudHeight = getRandomNumberInRange(5, 20); clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), - scale: new Cesium.Cartesian2(1500, 500), - maximumSize: new Cesium.Cartesian3(30, 20, 17), - slice: 0.45, + position: Cesium.Cartesian3.fromDegrees(long, lat, height), + scale: new Cesium.Cartesian2(scaleX, scaleY), + maximumSize: new Cesium.Cartesian3( + aspectRatio * cloudHeight, + cloudHeight, + depth + ), + slice: slice, }); } + } - let long, - lat, - height, - scaleX, - scaleY, - aspectRatio, - cloudHeight, - depth, - slice; - - // randomly generate clouds in a certain area - function createRandomClouds( - numClouds, - startLong, - stopLong, - startLat, - stopLat, - minHeight, - maxHeight - ) { - const rangeLong = stopLong - startLong; - const rangeLat = stopLat - startLat; - for (let i = 0; i < numClouds; i++) { - long = startLong + getRandomNumberInRange(0, rangeLong); - lat = startLat + getRandomNumberInRange(0, rangeLat); - height = getRandomNumberInRange(minHeight, maxHeight); - scaleX = getRandomNumberInRange(150, 350); - scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); - slice = getRandomNumberInRange(0.3, 0.7); - depth = getRandomNumberInRange(5, 20); - aspectRatio = getRandomNumberInRange(1.5, 2.1); - cloudHeight = getRandomNumberInRange(5, 20); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(long, lat, height), - scale: new Cesium.Cartesian2(scaleX, scaleY), - maximumSize: new Cesium.Cartesian3( - aspectRatio * cloudHeight, - cloudHeight, - depth - ), - slice: slice, - }); - } - } + // manually position clouds in front + const scratch = new Cesium.Cartesian3(); + function createFrontLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), + scale: new Cesium.Cartesian2(400, 150), + maximumSize: new Cesium.Cartesian3(25, 12, 15), + slice: 0.36, + }); - // manually position clouds in front - const scratch = new Cesium.Cartesian3(); - function createFrontLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), - scale: new Cesium.Cartesian2(400, 150), - maximumSize: new Cesium.Cartesian3(25, 12, 15), - slice: 0.36, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), + scale: new Cesium.Cartesian2(450, 200), + maximumSize: new Cesium.Cartesian3(25, 14, 12), + slice: 0.3, + }); + } - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), - scale: new Cesium.Cartesian2(450, 200), - maximumSize: new Cesium.Cartesian3(25, 14, 12), - slice: 0.3, - }); - } + createBackLayerClouds(); + createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); + createFrontLayerClouds(); - createBackLayerClouds(); - createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); - createFrontLayerClouds(); + scene.primitives.add(clouds); - scene.primitives.add(clouds); + /////////////////////////// + // Create hot air balloons + /////////////////////////// - /////////////////////////// - // Create hot air balloons - /////////////////////////// + const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); + const stop = Cesium.JulianDate.addSeconds( + start, + 90, + new Cesium.JulianDate() + ); - const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); - const stop = Cesium.JulianDate.addSeconds( - start, - 90, + function computeBalloonFlight(long, lat, height0, height1) { + const property = new Cesium.SampledPositionProperty(); + const time0 = start.clone(); + const time1 = Cesium.JulianDate.addSeconds( + time0, + 30, + new Cesium.JulianDate() + ); + const time2 = Cesium.JulianDate.addSeconds( + time1, + 15, + new Cesium.JulianDate() + ); + const time3 = Cesium.JulianDate.addSeconds( + time2, + 30, + new Cesium.JulianDate() + ); + const time4 = Cesium.JulianDate.addSeconds( + time3, + 15, new Cesium.JulianDate() ); - function computeBalloonFlight(long, lat, height0, height1) { - const property = new Cesium.SampledPositionProperty(); - const time0 = start.clone(); - const time1 = Cesium.JulianDate.addSeconds( - time0, - 30, - new Cesium.JulianDate() - ); - const time2 = Cesium.JulianDate.addSeconds( - time1, - 15, - new Cesium.JulianDate() - ); - const time3 = Cesium.JulianDate.addSeconds( - time2, - 30, - new Cesium.JulianDate() - ); - const time4 = Cesium.JulianDate.addSeconds( - time3, - 15, - new Cesium.JulianDate() - ); - - const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); - const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); + const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); + const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); - property.addSample(time0, position0); - property.addSample(time1, position1); - property.addSample(time2, position1); - property.addSample(time3, position0); - property.addSample(time4, position0); + property.addSample(time0, position0); + property.addSample(time1, position1); + property.addSample(time2, position1); + property.addSample(time3, position0); + property.addSample(time4, position0); - return property; - } + return property; + } - const balloon0 = viewer.entities.add({ - position: computeBalloonFlight(-122.661, 45.524, 400, 500), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + const balloon0 = viewer.entities.add({ + position: computeBalloonFlight(-122.661, 45.524, 400, 500), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - balloon0.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + balloon0.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - const balloon1 = viewer.entities.add({ - position: computeBalloonFlight(-122.662, 45.517, 400, 300), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + const balloon1 = viewer.entities.add({ + position: computeBalloonFlight(-122.662, 45.517, 400, 300), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - balloon1.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + balloon1.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; - // Fly to Portland - scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), - orientation: { - heading: Cesium.Math.toRadians(-115), - pitch: Cesium.Math.toRadians(-12), - roll: 0.0, - }, - }); + // Fly to Portland + scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), + orientation: { + heading: Cesium.Math.toRadians(-115), + pitch: Cesium.Math.toRadians(-12), + roll: 0.0, + }, + }); - scene.fog.density = 1.15e-4; - })(); //Sandcastle_End + scene.fog.density = 1.15e-4; //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clustering.html b/Apps/Sandcastle/gallery/Clustering.html index 517f3bbe1c2..14ce64eaa7c 100644 --- a/Apps/Sandcastle/gallery/Clustering.html +++ b/Apps/Sandcastle/gallery/Clustering.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -210,11 +210,14 @@ }, Cesium.ScreenSpaceEventType.LEFT_CLICK); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Corridor.html b/Apps/Sandcastle/gallery/Corridor.html index 32aeb401817..6c86612c17c 100644 --- a/Apps/Sandcastle/gallery/Corridor.html +++ b/Apps/Sandcastle/gallery/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -92,11 +92,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 991d384e2c3..05b76cc4d8a 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -402,11 +402,14 @@ viewer.dataSources.add(dataSource); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Geocoder.html b/Apps/Sandcastle/gallery/Custom Geocoder.html index 2804297cf80..5e6c82b4ebf 100644 --- a/Apps/Sandcastle/gallery/Custom Geocoder.html +++ b/Apps/Sandcastle/gallery/Custom Geocoder.html @@ -42,7 +42,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -94,7 +94,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html index 7c50573d81d..b6e5224eb00 100644 --- a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -95,11 +95,14 @@ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Post Process.html b/Apps/Sandcastle/gallery/Custom Post Process.html index 213efedaded..2e5b56fa077 100644 --- a/Apps/Sandcastle/gallery/Custom Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Post Process.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -82,7 +82,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html index 379785a1d35..6347bd97b1f 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -76,11 +76,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Models.html b/Apps/Sandcastle/gallery/Custom Shaders Models.html index 6349c9fa5c1..ecbc4d47bb2 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Models.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Models.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -476,11 +476,14 @@ }, Cesium.ScreenSpaceEventType.LEFT_UP); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index 96348e33498..d9834b847ef 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -39,20 +39,13 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - scene.globe.depthTestAgainstTerrain = false; // MAXAR OWT Muscatatuk photogrammetry dataset with property textures @@ -124,11 +117,14 @@ }, ]); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cylinders and Cones.html b/Apps/Sandcastle/gallery/Cylinders and Cones.html index 988dee263ca..12e7e6560b3 100644 --- a/Apps/Sandcastle/gallery/Cylinders and Cones.html +++ b/Apps/Sandcastle/gallery/Cylinders and Cones.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -60,11 +60,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/DataSource Ordering.html b/Apps/Sandcastle/gallery/DataSource Ordering.html index a7dec9729ec..c258f0d0ab6 100644 --- a/Apps/Sandcastle/gallery/DataSource Ordering.html +++ b/Apps/Sandcastle/gallery/DataSource Ordering.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const czml1 = [ @@ -128,11 +128,14 @@ } }); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Depth of Field.html b/Apps/Sandcastle/gallery/Depth of Field.html index 4dc901ab722..ba4d136e4cf 100644 --- a/Apps/Sandcastle/gallery/Depth of Field.html +++ b/Apps/Sandcastle/gallery/Depth of Field.html @@ -89,7 +89,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -170,11 +170,14 @@ ); viewer.scene.camera.lookAt(target, offset); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Distance Display Conditions.html b/Apps/Sandcastle/gallery/Distance Display Conditions.html index ad18acdf621..8571526a0c4 100644 --- a/Apps/Sandcastle/gallery/Distance Display Conditions.html +++ b/Apps/Sandcastle/gallery/Distance Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -122,11 +122,14 @@ }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index 57e21acb0f6..d851d5510eb 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -43,22 +43,15 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { selectionIndicator: false, infoBox: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK ); @@ -179,11 +172,14 @@ ); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Earth at Night.html b/Apps/Sandcastle/gallery/Earth at Night.html index 0768b531127..7e01e2c8eb4 100644 --- a/Apps/Sandcastle/gallery/Earth at Night.html +++ b/Apps/Sandcastle/gallery/Earth at Night.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // The Earth at Night, also known as Black Marble 2017 and Night Lights @@ -74,11 +74,14 @@ } ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Elevation Band Material.html b/Apps/Sandcastle/gallery/Elevation Band Material.html index 42fc231b535..d25df198fc7 100644 --- a/Apps/Sandcastle/gallery/Elevation Band Material.html +++ b/Apps/Sandcastle/gallery/Elevation Band Material.html @@ -115,228 +115,214 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 290637.5534733206, - 5637471.593707632, - 2978256.8126927214 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 290637.5534733206, + 5637471.593707632, + 2978256.8126927214 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); - const viewModel = { - gradient: false, - band1Position: 7000.0, - band2Position: 7500.0, - band3Position: 8000.0, - bandThickness: 100.0, - bandTransparency: 0.5, - backgroundTransparency: 0.75, - }; + const viewModel = { + gradient: false, + band1Position: 7000.0, + band2Position: 7500.0, + band3Position: 8000.0, + bandThickness: 100.0, + bandTransparency: 0.5, + backgroundTransparency: 0.75, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateMaterial); - } + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateMaterial); } + } + + function updateMaterial() { + const gradient = Boolean(viewModel.gradient); + const band1Position = Number(viewModel.band1Position); + const band2Position = Number(viewModel.band2Position); + const band3Position = Number(viewModel.band3Position); + const bandThickness = Number(viewModel.bandThickness); + const bandTransparency = Number(viewModel.bandTransparency); + const backgroundTransparency = Number( + viewModel.backgroundTransparency + ); - function updateMaterial() { - const gradient = Boolean(viewModel.gradient); - const band1Position = Number(viewModel.band1Position); - const band2Position = Number(viewModel.band2Position); - const band3Position = Number(viewModel.band3Position); - const bandThickness = Number(viewModel.bandThickness); - const bandTransparency = Number(viewModel.bandTransparency); - const backgroundTransparency = Number( - viewModel.backgroundTransparency + const layers = []; + const backgroundLayer = { + entries: [ + { + height: 4200.0, + color: new Cesium.Color(0.0, 0.0, 0.2, backgroundTransparency), + }, + { + height: 8000.0, + color: new Cesium.Color(1.0, 1.0, 1.0, backgroundTransparency), + }, + { + height: 8500.0, + color: new Cesium.Color(1.0, 0.0, 0.0, backgroundTransparency), + }, + ], + extendDownwards: true, + extendUpwards: true, + }; + layers.push(backgroundLayer); + + const gridStartHeight = 4200.0; + const gridEndHeight = 8848.0; + const gridCount = 50; + for (let i = 0; i < gridCount; i++) { + const lerper = i / (gridCount - 1); + const heightBelow = Cesium.Math.lerp( + gridStartHeight, + gridEndHeight, + lerper ); + const heightAbove = heightBelow + 10.0; + const alpha = + Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; + layers.push({ + entries: [ + { + height: heightBelow, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: heightAbove, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + ], + }); + } + + const antialias = Math.min(10.0, bandThickness * 0.1); - const layers = []; - const backgroundLayer = { + if (!gradient) { + const band1 = { entries: [ { - height: 4200.0, - color: new Cesium.Color( - 0.0, - 0.0, - 0.2, - backgroundTransparency - ), + height: band1Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), }, { - height: 8000.0, - color: new Cesium.Color( - 1.0, - 1.0, - 1.0, - backgroundTransparency - ), + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), }, { - height: 8500.0, - color: new Cesium.Color( - 1.0, - 0.0, - 0.0, - backgroundTransparency - ), + height: band1Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band1Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), }, ], - extendDownwards: true, - extendUpwards: true, }; - layers.push(backgroundLayer); - - const gridStartHeight = 4200.0; - const gridEndHeight = 8848.0; - const gridCount = 50; - for (let i = 0; i < gridCount; i++) { - const lerper = i / (gridCount - 1); - const heightBelow = Cesium.Math.lerp( - gridStartHeight, - gridEndHeight, - lerper - ); - const heightAbove = heightBelow + 10.0; - const alpha = - Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; - layers.push({ - entries: [ - { - height: heightBelow, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: heightAbove, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - ], - }); - } - - const antialias = Math.min(10.0, bandThickness * 0.1); - if (!gradient) { - const band1 = { - entries: [ - { - height: band1Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band1Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band1Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - ], - }; - - const band2 = { - entries: [ - { - height: band2Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - { - height: band2Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - ], - }; - - const band3 = { - entries: [ - { - height: band3Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - { - height: band3Position - bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - ], - }; + const band2 = { + entries: [ + { + height: band2Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + { + height: band2Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + ], + }; - layers.push(band1); - layers.push(band2); - layers.push(band3); - } else { - const combinedBand = { - entries: [ - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band2Position, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - ], - }; + const band3 = { + entries: [ + { + height: band3Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + { + height: band3Position - bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + ], + }; - layers.push(combinedBand); - } + layers.push(band1); + layers.push(band2); + layers.push(band3); + } else { + const combinedBand = { + entries: [ + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band2Position, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + ], + }; - const material = Cesium.createElevationBandMaterial({ - scene: viewer.scene, - layers: layers, - }); - viewer.scene.globe.material = material; + layers.push(combinedBand); } - updateMaterial(); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + const material = Cesium.createElevationBandMaterial({ + scene: viewer.scene, + layers: layers, + }); + viewer.scene.globe.material = material; + } + + updateMaterial(); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Export KML.html b/Apps/Sandcastle/gallery/Export KML.html index 379f8efa34f..d0e44c7e9bf 100644 --- a/Apps/Sandcastle/gallery/Export KML.html +++ b/Apps/Sandcastle/gallery/Export KML.html @@ -35,7 +35,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -156,11 +156,14 @@ .catch(console.error); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index 24325ed8467..22cfa7bc706 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -29,45 +29,46 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); - viewer.scene.postProcessStages.fxaa.enabled = true; + viewer.scene.postProcessStages.fxaa.enabled = true; - Sandcastle.addToggleButton("FXAA", true, function (checked) { - viewer.scene.postProcessStages.fxaa.enabled = checked; - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + Sandcastle.addToggleButton("FXAA", true, function (checked) { + viewer.scene.postProcessStages.fxaa.enabled = checked; + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Fog Post Process.html b/Apps/Sandcastle/gallery/Fog Post Process.html index 3cedae53ed7..dbfa9eef950 100644 --- a/Apps/Sandcastle/gallery/Fog Post Process.html +++ b/Apps/Sandcastle/gallery/Fog Post Process.html @@ -27,7 +27,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -106,11 +106,14 @@ }, }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index 05ac4f4bae7..aae9a2644ca 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -31,18 +31,12 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const pinBuilder = new Cesium.PinBuilder(); @@ -144,11 +138,14 @@ viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html index 2cab2f0f6fd..cd7100cbf2e 100644 --- a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html +++ b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -123,11 +123,14 @@ viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html index ee2179d9cca..b1aa48eacbe 100644 --- a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html +++ b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin //Load a GeoJSON file containing simplestyle information. @@ -53,11 +53,14 @@ viewer.dataSources.add(dataSource); viewer.zoomTo(dataSource); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index d2f0b09a20b..1ac2145e111 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -32,13 +32,14 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayerPicker: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); // depth test against terrain is required to make the polygons clamp to terrain @@ -81,14 +82,6 @@ }, ]); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const longitude = 6.950615989890521; const latitude = 45.79546589994886; const delta = 0.001; @@ -185,7 +178,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry and Appearances.html b/Apps/Sandcastle/gallery/Geometry and Appearances.html index 72551e7e97f..60133cd465f 100644 --- a/Apps/Sandcastle/gallery/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -635,11 +635,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Interior.html b/Apps/Sandcastle/gallery/Globe Interior.html index 5d5d60f81d8..cd01f50f821 100644 --- a/Apps/Sandcastle/gallery/Globe Interior.html +++ b/Apps/Sandcastle/gallery/Globe Interior.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -179,11 +179,14 @@ Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index c9f92c36190..6f5d1152ecd 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -119,22 +119,16 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); viewer.scene.globe.enableLighting = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }); - } catch (error) { - console.log(error); - } - })(); - function getElevationContourMaterial() { // Creates a composite material with both elevation shading and contour lines return new Cesium.Material({ @@ -424,11 +418,14 @@ "zoomButtons" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index 87dc0c82f54..2eb52f1cc43 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -81,233 +81,234 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - scene.screenSpaceCameraController.enableCollisionDetection = false; - globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( - 400.0, - 0.0, - 800.0, - 1.0 - ); + scene.screenSpaceCameraController.enableCollisionDetection = false; + globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( + 400.0, + 0.0, + 800.0, + 1.0 + ); - const longitude = -3.82518; - const latitude = 53.11728; - const height = 72.8; - const position = Cesium.Cartesian3.fromDegrees( - longitude, - latitude, - height - ); - const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; + const longitude = -3.82518; + const latitude = 53.11728; + const height = 72.8; + const position = Cesium.Cartesian3.fromDegrees( + longitude, + latitude, + height + ); + const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; - const entity = viewer.entities.add({ - name: url, - position: position, - model: { - uri: url, - }, - }); + const entity = viewer.entities.add({ + name: url, + position: position, + model: { + uri: url, + }, + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8152789692233817, - 53.124521420389996, - 200.20779492422255, - -3.8165955002619016, - 53.12555934545405, - 205.85834336951655, - -3.8201599842222054, - 53.12388420656903, - 230.82362697069453, - -3.8198667503545027, - 53.123748567587455, - 225.53297006293968, - -3.8190548496317476, - 53.1240486000822, - 221.82677773619432, - -3.817536387097508, - 53.122763476393764, - 209.94136782255705, - -3.8169125359199336, - 53.12285547981627, - 210.96626238861327, - -3.8166873871853073, - 53.12299403424474, - 211.02223937734595, - -3.8163695374580873, - 53.12300505277307, - 211.25942926271824, - -3.8162743040622313, - 53.12281471203994, - 212.35109129094147, - -3.8159746138174193, - 53.12280996651767, - 214.87977416348798, - -3.815429896849304, - 53.1236135347983, - 209.72496223706005, - ]) - ), - material: Cesium.Color.LIME.withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8152789692233817, + 53.124521420389996, + 200.20779492422255, + -3.8165955002619016, + 53.12555934545405, + 205.85834336951655, + -3.8201599842222054, + 53.12388420656903, + 230.82362697069453, + -3.8198667503545027, + 53.123748567587455, + 225.53297006293968, + -3.8190548496317476, + 53.1240486000822, + 221.82677773619432, + -3.817536387097508, + 53.122763476393764, + 209.94136782255705, + -3.8169125359199336, + 53.12285547981627, + 210.96626238861327, + -3.8166873871853073, + 53.12299403424474, + 211.02223937734595, + -3.8163695374580873, + 53.12300505277307, + 211.25942926271824, + -3.8162743040622313, + 53.12281471203994, + 212.35109129094147, + -3.8159746138174193, + 53.12280996651767, + 214.87977416348798, + -3.815429896849304, + 53.1236135347983, + 209.72496223706005, + ]) + ), + material: Cesium.Color.LIME.withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8098444201746373, - 53.1190304262546, - 286.1875170545701, - -3.8099801237370663, - 53.119539531697576, - 288.7733884242394, - -3.810165716635671, - 53.11979180761567, - 290.9294630315179, - -3.8104840812145357, - 53.12007534956926, - 292.6392327626228, - -3.8105689502073554, - 53.120259094792196, - 292.222036965774, - -3.811027311824268, - 53.120409248874196, - 289.61356291617307, - -3.811530473295422, - 53.12063281057782, - 284.01098712543586, - -3.8120545342562693, - 53.120742539082435, - 280.118191867836, - -3.812444493044727, - 53.120813289759326, - 276.0400221387852, - -3.812779626711285, - 53.12094275348024, - 271.1187399484896, - -3.8133560322579494, - 53.12104757866638, - 263.3495497598578, - -3.8137266493960085, - 53.12120789867194, - 257.73878624321316, - -3.8142552291751133, - 53.121321248522904, - 251.87265828778177, - -3.814322603988525, - 53.12174170121103, - 238.7082749547689, - -3.8143764268391314, - 53.1219492923309, - 235.0371831845662, - -3.8148156514145786, - 53.12210819668669, - 230.2458816627467, - -3.8155394721966163, - 53.1222990144029, - 221.33319292262706, - -3.8159828072920927, - 53.12203093429715, - 223.66664756982703, - -3.816678108944717, - 53.12183939425214, - 223.8787312412801, - -3.817466081093726, - 53.121751900508535, - 224.52293229989735, - -3.8183082996527955, - 53.12173266141031, - 223.3672181535749, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8098444201746373, + 53.1190304262546, + 286.1875170545701, + -3.8099801237370663, + 53.119539531697576, + 288.7733884242394, + -3.810165716635671, + 53.11979180761567, + 290.9294630315179, + -3.8104840812145357, + 53.12007534956926, + 292.6392327626228, + -3.8105689502073554, + 53.120259094792196, + 292.222036965774, + -3.811027311824268, + 53.120409248874196, + 289.61356291617307, + -3.811530473295422, + 53.12063281057782, + 284.01098712543586, + -3.8120545342562693, + 53.120742539082435, + 280.118191867836, + -3.812444493044727, + 53.120813289759326, + 276.0400221387852, + -3.812779626711285, + 53.12094275348024, + 271.1187399484896, + -3.8133560322579494, + 53.12104757866638, + 263.3495497598578, + -3.8137266493960085, + 53.12120789867194, + 257.73878624321316, + -3.8142552291751133, + 53.121321248522904, + 251.87265828778177, + -3.814322603988525, + 53.12174170121103, + 238.7082749547689, + -3.8143764268391314, + 53.1219492923309, + 235.0371831845662, + -3.8148156514145786, + 53.12210819668669, + 230.2458816627467, + -3.8155394721966163, + 53.1222990144029, + 221.33319292262706, + -3.8159828072920927, + 53.12203093429715, + 223.66664756982703, + -3.816678108944717, + 53.12183939425214, + 223.8787312412801, + -3.817466081093726, + 53.121751900508535, + 224.52293229989735, + -3.8183082996527955, + 53.12173266141031, + 223.3672181535749, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const viewModel = { - translucencyEnabled: true, - fadeByDistance: true, - showVectorData: false, - alpha: 0.5, - }; + const viewModel = { + translucencyEnabled: true, + fadeByDistance: true, + showVectorData: false, + alpha: 0.5, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout.getObservable(viewModel, name).subscribe(update); - } + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout.getObservable(viewModel, name).subscribe(update); } + } - function update() { - globe.translucency.enabled = viewModel.translucencyEnabled; + function update() { + globe.translucency.enabled = viewModel.translucencyEnabled; - let alpha = Number(viewModel.alpha); - alpha = !isNaN(alpha) ? alpha : 1.0; - alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); + let alpha = Number(viewModel.alpha); + alpha = !isNaN(alpha) ? alpha : 1.0; + alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); - globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; - globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance - ? 1.0 - : alpha; + globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; + globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance + ? 1.0 + : alpha; - polygon.show = viewModel.showVectorData; - polyline.show = viewModel.showVectorData; - } - update(); + polygon.show = viewModel.showVectorData; + polyline.show = viewModel.showVectorData; + } + update(); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 3826465.9884728403, - -254831.02751468265, - 5081387.671561018 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.3889450556243754, - -0.5276382514771969, - 6.282272566663295 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 3826465.9884728403, + -254831.02751468265, + 5081387.671561018 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.3889450556243754, + -0.5276382514771969, + 6.282272566663295 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.camera.flyTo({ - destination: new Cesium.Cartesian3( - 3827270.552916987, - -255123.18143177085, - 5079147.091351856 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.2624281242239963, - -0.22213535190506972, - 6.282786783842843 - ), - duration: 5.0, - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + viewer.scene.camera.flyTo({ + destination: new Cesium.Cartesian3( + 3827270.552916987, + -255123.18143177085, + 5079147.091351856 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.2624281242239963, + -0.22213535190506972, + 6.282786783842843 + ), + duration: 5.0, + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index 2c7cb0c0461..e72a3fffba0 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -32,46 +32,38 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - try { - const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( - new Cesium.Resource({ - url: "http://www.earthenterprise.org/3d", - proxy: new Cesium.DefaultProxy("/proxy/"), - }) - ); + const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( + new Cesium.Resource({ + url: "http://www.earthenterprise.org/3d", + proxy: new Cesium.DefaultProxy("/proxy/"), + }) + ); - const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ - metadata: geeMetadata, - }), - terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( - geeMetadata - ), - baseLayerPicker: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ + metadata: geeMetadata, + }), + terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( + geeMetadata + ), + baseLayerPicker: false, + }); - // Start off looking at San Francisco. - viewer.camera.setView({ - destination: Cesium.Rectangle.fromDegrees( - -123.0, - 36.0, - -121.7, - 39.0 - ), - }); - } catch (error) { - console.log(error); - } - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + // Start off looking at San Francisco. + viewer.camera.setView({ + destination: Cesium.Rectangle.fromDegrees(-123.0, 36.0, -121.7, 39.0), + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/HTML Overlays.html b/Apps/Sandcastle/gallery/HTML Overlays.html index 79f78d5ff98..a2b0a9528ac 100644 --- a/Apps/Sandcastle/gallery/HTML Overlays.html +++ b/Apps/Sandcastle/gallery/HTML Overlays.html @@ -37,7 +37,7 @@ src="../images/Cesium_Logo_overlay.png" /> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -60,11 +60,14 @@ } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index e3c2dd80cfb..3863beec47e 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -71,7 +71,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -261,11 +261,14 @@ <h1>Loading...</h1> speedSpan.innerHTML = speed.toFixed(1); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 992c9b3f04f..d0309eaf2ea 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -32,16 +32,20 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); //Sandcastle_End - Sandcastle.finishedLoading(); }; + if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/High Dynamic Range.html b/Apps/Sandcastle/gallery/High Dynamic Range.html index abb4f589055..a4bf40b32d6 100644 --- a/Apps/Sandcastle/gallery/High Dynamic Range.html +++ b/Apps/Sandcastle/gallery/High Dynamic Range.html @@ -29,71 +29,72 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - shadows: true, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + shadows: true, + }); - if (!viewer.scene.highDynamicRangeSupported) { - window.alert("This browser does not support high dynamic range."); - } + if (!viewer.scene.highDynamicRangeSupported) { + window.alert("This browser does not support high dynamic range."); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -1915097.7863741855, - -4783356.851539908, - 3748887.43462683 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.166004548388564, - -0.043242401760068994, - 0.002179961955988574 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -1915097.7863741855, + -4783356.851539908, + 3748887.43462683 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.166004548388564, + -0.043242401760068994, + 0.002179961955988574 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.highDynamicRange = true; + viewer.scene.highDynamicRange = true; - Sandcastle.addToggleButton("HDR", true, function (checked) { - viewer.scene.highDynamicRange = checked; - }); + Sandcastle.addToggleButton("HDR", true, function (checked) { + viewer.scene.highDynamicRange = checked; + }); - const url = - "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; - const position = Cesium.Cartesian3.fromRadians( - -1.9516424279517286, - 0.6322397098422969, - 1239.0006814631095 - ); - const heading = Cesium.Math.toRadians(-15.0); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const scale = 10.0; + const url = + "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; + const position = Cesium.Cartesian3.fromRadians( + -1.9516424279517286, + 0.6322397098422969, + 1239.0006814631095 + ); + const heading = Cesium.Math.toRadians(-15.0); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const scale = 10.0; - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: scale, - }, - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: scale, + }, + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 20cf6b8bf87..52d15402f4a 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -35,129 +35,128 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "San Francisco": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["San Francisco"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "San Francisco": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["San Francisco"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if ( - !Cesium.defined(name) && - isNameProperty(fieldName) - ) { - name = fields[fieldName]; - } + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if (!Cesium.defined(name) && isNameProperty(fieldName)) { + name = fields[fieldName]; } } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); - } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; + } + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; - } - return false; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; } - })(); //Sandcastle_End + return false; + } //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index cebdb348a20..10052a04dbf 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -35,129 +35,128 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "New York": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["New York"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "New York": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["New York"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if ( - !Cesium.defined(name) && - isNameProperty(fieldName) - ) { - name = fields[fieldName]; - } + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if (!Cesium.defined(name) && isNameProperty(fieldName)) { + name = fields[fieldName]; } } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); - } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; + } + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; - } - return false; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; } - })(); //Sandcastle_End + return false; + } //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 67740dbba17..305d18ae14a 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -35,61 +35,63 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); - // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry - viewer.scene.globe.depthTestAgainstTerrain = false; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); + // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry + viewer.scene.globe.depthTestAgainstTerrain = false; - // More datasets to tour can be added here.. - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - Frankfurt: - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); + // More datasets to tour can be added here.. + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + Frankfurt: + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours.Frankfurt, - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours.Frankfurt, + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); - })(); //Sandcastle_End + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } }; </script> diff --git a/Apps/Sandcastle/gallery/Image-Based Lighting.html b/Apps/Sandcastle/gallery/Image-Based Lighting.html index b3d86ab57a1..e65402087ff 100644 --- a/Apps/Sandcastle/gallery/Image-Based Lighting.html +++ b/Apps/Sandcastle/gallery/Image-Based Lighting.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -207,11 +207,14 @@ window.alert(error); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Adjustment.html b/Apps/Sandcastle/gallery/Imagery Adjustment.html index 8bbad64dee0..ad433a97d7d 100644 --- a/Apps/Sandcastle/gallery/Imagery Adjustment.html +++ b/Apps/Sandcastle/gallery/Imagery Adjustment.html @@ -112,7 +112,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -166,11 +166,14 @@ imageryLayers.layerMoved.addEventListener(updateViewModel); updateViewModel(); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html index a67c9850665..fd5d119da27 100644 --- a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html +++ b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -93,11 +93,14 @@ viewModel.threshold ); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Cutout.html b/Apps/Sandcastle/gallery/Imagery Cutout.html index 0b2164e24f9..c18078ebd9e 100644 --- a/Apps/Sandcastle/gallery/Imagery Cutout.html +++ b/Apps/Sandcastle/gallery/Imagery Cutout.html @@ -46,7 +46,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -182,11 +182,14 @@ } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html index 80b2ccff9b0..77ca2e9616e 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html @@ -104,7 +104,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -325,11 +325,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Split.html b/Apps/Sandcastle/gallery/Imagery Layers Split.html index 5ea11e8c89c..803fa48e8b9 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Split.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Split.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -111,11 +111,14 @@ }, Cesium.ScreenSpaceEventType.PINCH_END); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html index f0103e83eaa..a419e3c913b 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -115,12 +115,14 @@ viewer.scene.splitPosition = splitPosition; } //Sandcastle_End - - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers.html b/Apps/Sandcastle/gallery/Imagery Layers.html index e439295682c..2687b6662ad 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers.html +++ b/Apps/Sandcastle/gallery/Imagery Layers.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -60,11 +60,14 @@ rectangle: Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75), }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index 5c85423b399..bfdfd13be5f 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -34,23 +34,16 @@ <div id="interpolationMenu"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, //Disable InfoBox widget selectionIndicator: false, //Disable selection indicator shouldAnimate: true, // Enable animations + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - //Enable lighting based on the sun position viewer.scene.globe.enableLighting = true; @@ -207,11 +200,14 @@ "interpolationMenu" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML Tours.html b/Apps/Sandcastle/gallery/KML Tours.html index 8b2d6d51e06..9c462078196 100644 --- a/Apps/Sandcastle/gallery/KML Tours.html +++ b/Apps/Sandcastle/gallery/KML Tours.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -77,11 +77,14 @@ viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML.html b/Apps/Sandcastle/gallery/KML.html index b2d1ef68b40..4539bf976e4 100644 --- a/Apps/Sandcastle/gallery/KML.html +++ b/Apps/Sandcastle/gallery/KML.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -98,11 +98,14 @@ viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Labels.html b/Apps/Sandcastle/gallery/Labels.html index ccb621e2fda..dc6f65433af 100644 --- a/Apps/Sandcastle/gallery/Labels.html +++ b/Apps/Sandcastle/gallery/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -272,7 +272,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/LensFlare.html b/Apps/Sandcastle/gallery/LensFlare.html index c081194cd14..9942d728869 100644 --- a/Apps/Sandcastle/gallery/LensFlare.html +++ b/Apps/Sandcastle/gallery/LensFlare.html @@ -101,7 +101,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -168,11 +168,14 @@ 27399.860215000022 ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index 38cc8b0ee9c..c7d4f7d58ac 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -29,24 +29,18 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); const scene = viewer.scene; scene.globe.enableLighting = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); - const scratchIcrfToFixed = new Cesium.Matrix3(); const scratchMoonPosition = new Cesium.Cartesian3(); const scratchMoonDirection = new Cesium.Cartesian3(); @@ -232,11 +226,14 @@ Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 77761084409..1539df70542 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -62,7 +62,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -274,11 +274,14 @@ <h1>Loading...</h1> rollSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.roll).toFixed(1); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index dd21568c7bb..d7ca20bcb7a 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -29,23 +29,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { contextOptions: { requestWebgl1: false, }, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2022-08-01T00:00:00Z" ); @@ -183,11 +176,14 @@ Sandcastle.addToolbarMenu(options); Sandcastle.addToolbarMenu(samplingOptions); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Manually Controlled Animation.html b/Apps/Sandcastle/gallery/Manually Controlled Animation.html index 4eda60808f5..7ee0b66ed6a 100644 --- a/Apps/Sandcastle/gallery/Manually Controlled Animation.html +++ b/Apps/Sandcastle/gallery/Manually Controlled Animation.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -156,11 +156,14 @@ viewer.trackedEntity = modelLabel; modelLabel.viewFrom = new Cesium.Cartesian3(-30.0, -10.0, 10.0); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Map Pins.html b/Apps/Sandcastle/gallery/Map Pins.html index cc92aea49ca..b0d9b6709ad 100644 --- a/Apps/Sandcastle/gallery/Map Pins.html +++ b/Apps/Sandcastle/gallery/Map Pins.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -93,11 +93,14 @@ ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index f6815a30fc0..9b759b46b48 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin let rectangle; @@ -621,11 +621,14 @@ createPrimitives(scene); createButtons(scene); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index ac71f6fb445..b95bcac4a31 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -83,18 +83,12 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. const tileset = viewer.scene.primitives.add( @@ -429,11 +423,14 @@ applyStyle(tileset, pointStyles); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multi-part CZML.html b/Apps/Sandcastle/gallery/Multi-part CZML.html index c5f9823e327..213b7472994 100644 --- a/Apps/Sandcastle/gallery/Multi-part CZML.html +++ b/Apps/Sandcastle/gallery/Multi-part CZML.html @@ -36,7 +36,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -170,11 +170,14 @@ fuelDisplay.style.marginTop = "5px"; document.getElementById("toolbar").appendChild(fuelDisplay); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multiple Synced Views.html b/Apps/Sandcastle/gallery/Multiple Synced Views.html index 48fc895f15d..13f6272c40f 100644 --- a/Apps/Sandcastle/gallery/Multiple Synced Views.html +++ b/Apps/Sandcastle/gallery/Multiple Synced Views.html @@ -48,7 +48,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // We want our two views to be synced across time, so we create @@ -120,11 +120,14 @@ view2D.scene.screenSpaceCameraController.enableTilt = false; view2D.scene.screenSpaceCameraController.enableLook = false; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Natural Earth II.html b/Apps/Sandcastle/gallery/Natural Earth II.html index 9e93c6ee30f..51d4cbbff0a 100644 --- a/Apps/Sandcastle/gallery/Natural Earth II.html +++ b/Apps/Sandcastle/gallery/Natural Earth II.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Natural Earth II with Shaded Relief, Water, and Drainages from http://www.naturalearthdata.com @@ -40,11 +40,14 @@ imageryProvider: new Cesium.IonImageryProvider({ assetId: 3813 }), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Offline.html b/Apps/Sandcastle/gallery/Offline.html index 3f16e831458..2ca33ce8782 100644 --- a/Apps/Sandcastle/gallery/Offline.html +++ b/Apps/Sandcastle/gallery/Offline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // This is an example of using Cesium "Offline", meaning disconnected from the @@ -48,11 +48,14 @@ geocoder: false, }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index ca33b2cb9af..58bd496fd15 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -32,22 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) - // http://www.pasda.psu.edu/ - viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) - ); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) + // http://www.pasda.psu.edu/ + terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3957) + ), + }); // Add PA locations Sandcastle.addDefaultToolbarMenu( @@ -141,11 +135,14 @@ "toolbar" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Parallels and Meridians.html b/Apps/Sandcastle/gallery/Parallels and Meridians.html index ef643aea418..5dfbde37d23 100644 --- a/Apps/Sandcastle/gallery/Parallels and Meridians.html +++ b/Apps/Sandcastle/gallery/Parallels and Meridians.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -311,11 +311,14 @@ } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Partial Ellipsoids.html b/Apps/Sandcastle/gallery/Partial Ellipsoids.html index ee2c0507e63..14981aa8e42 100644 --- a/Apps/Sandcastle/gallery/Partial Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Partial Ellipsoids.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -214,11 +214,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Fireworks.html b/Apps/Sandcastle/gallery/Particle System Fireworks.html index 394ec79af33..6293257b738 100644 --- a/Apps/Sandcastle/gallery/Particle System Fireworks.html +++ b/Apps/Sandcastle/gallery/Particle System Fireworks.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -212,11 +212,14 @@ ); camera.lookUp(angle); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Tails.html b/Apps/Sandcastle/gallery/Particle System Tails.html index 460e1d34123..1b919b50897 100644 --- a/Apps/Sandcastle/gallery/Particle System Tails.html +++ b/Apps/Sandcastle/gallery/Particle System Tails.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -296,12 +296,15 @@ ]; Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index 00602ce0216..5a422f13c8f 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -32,23 +32,16 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const resetCameraFunction = function () { scene.camera.setView({ destination: new Cesium.Cartesian3( @@ -209,12 +202,15 @@ ]; Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System.html b/Apps/Sandcastle/gallery/Particle System.html index ee7a74cd7ed..163c9a214cd 100644 --- a/Apps/Sandcastle/gallery/Particle System.html +++ b/Apps/Sandcastle/gallery/Particle System.html @@ -184,7 +184,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -460,11 +460,14 @@ Sandcastle.addToolbarMenu(options); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html index aa0ae29f9f1..82ff512c91a 100644 --- a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html +++ b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -111,11 +111,14 @@ }, ]); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index 88174baecdb..9e55d885c24 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const clock = new Cesium.Clock({ @@ -48,16 +48,9 @@ const viewer = new Cesium.Viewer("cesiumContainer", { clockViewModel: new Cesium.ClockViewModel(clock), selectionIndicator: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( checked ) { @@ -199,11 +192,14 @@ "toolbar" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Picking.html b/Apps/Sandcastle/gallery/Picking.html index 19756c17f4d..d6404489b64 100644 --- a/Apps/Sandcastle/gallery/Picking.html +++ b/Apps/Sandcastle/gallery/Picking.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -281,11 +281,14 @@ handler = handler && handler.destroy(); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Plane.html b/Apps/Sandcastle/gallery/Plane.html index 0d8572df798..9def7814cbe 100644 --- a/Apps/Sandcastle/gallery/Plane.html +++ b/Apps/Sandcastle/gallery/Plane.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -70,11 +70,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Points.html b/Apps/Sandcastle/gallery/Points.html index 65068c79586..5f8626910a0 100644 --- a/Apps/Sandcastle/gallery/Points.html +++ b/Apps/Sandcastle/gallery/Points.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -186,11 +186,14 @@ viewer.entities.removeAll(); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polygon.html b/Apps/Sandcastle/gallery/Polygon.html index e275ab7416a..1629c38b80c 100644 --- a/Apps/Sandcastle/gallery/Polygon.html +++ b/Apps/Sandcastle/gallery/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -306,11 +306,14 @@ }); viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Dash.html b/Apps/Sandcastle/gallery/Polyline Dash.html index 10143d01cba..39404d17430 100644 --- a/Apps/Sandcastle/gallery/Polyline Dash.html +++ b/Apps/Sandcastle/gallery/Polyline Dash.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -130,11 +130,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Volume.html b/Apps/Sandcastle/gallery/Polyline Volume.html index f84d3fc48d5..ebe05f3354f 100644 --- a/Apps/Sandcastle/gallery/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -130,11 +130,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline.html b/Apps/Sandcastle/gallery/Polyline.html index 9a61abfa196..5cb479e116a 100644 --- a/Apps/Sandcastle/gallery/Polyline.html +++ b/Apps/Sandcastle/gallery/Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -130,11 +130,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html index 9ce5117991f..304324bbcba 100644 --- a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -183,11 +183,14 @@ }, }, ]); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Post Processing.html b/Apps/Sandcastle/gallery/Post Processing.html index c46168a33d1..ad33bb13c0c 100644 --- a/Apps/Sandcastle/gallery/Post Processing.html +++ b/Apps/Sandcastle/gallery/Post Processing.html @@ -77,7 +77,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -152,11 +152,14 @@ } updatePostProcess(); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Procedural Terrain.html b/Apps/Sandcastle/gallery/Procedural Terrain.html index 5812bdb4928..9ccae27cc1c 100644 --- a/Apps/Sandcastle/gallery/Procedural Terrain.html +++ b/Apps/Sandcastle/gallery/Procedural Terrain.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -163,11 +163,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Projection.html b/Apps/Sandcastle/gallery/Projection.html index 214d3d04385..db56148bbc8 100644 --- a/Apps/Sandcastle/gallery/Projection.html +++ b/Apps/Sandcastle/gallery/Projection.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Click the projection picker to switch between orthographic and perspective projections. @@ -69,11 +69,14 @@ }); viewer.trackedEntity = entity; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rectangle.html b/Apps/Sandcastle/gallery/Rectangle.html index 17df5070eef..675f9750034 100644 --- a/Apps/Sandcastle/gallery/Rectangle.html +++ b/Apps/Sandcastle/gallery/Rectangle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -88,11 +88,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Resolution Scaling.html b/Apps/Sandcastle/gallery/Resolution Scaling.html index ef9d6bb7bc0..4cd03e6b44d 100644 --- a/Apps/Sandcastle/gallery/Resolution Scaling.html +++ b/Apps/Sandcastle/gallery/Resolution Scaling.html @@ -59,7 +59,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // When browser recommended resolution is enabled, the viewer renders at @@ -102,11 +102,14 @@ } update(); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rotatable 2D Map.html b/Apps/Sandcastle/gallery/Rotatable 2D Map.html index e99ceead9c5..3321a102014 100644 --- a/Apps/Sandcastle/gallery/Rotatable 2D Map.html +++ b/Apps/Sandcastle/gallery/Rotatable 2D Map.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -47,11 +47,14 @@ }, }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index 7ea5c50956e..822ee54a6ad 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -32,20 +32,14 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - if (!scene.clampToHeightSupported) { window.alert( "This browser does not support clampToHeightMostDetailed." @@ -131,11 +125,14 @@ }); } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index a2be63b6796..c19e6f795f2 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -138,7 +138,7 @@ <h4>Max delta time</h4> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create a viewer that won't render a new frame unless @@ -146,16 +146,9 @@ <h4>Max delta time</h4> const viewer = new Cesium.Viewer("cesiumContainer", { requestRenderMode: true, maximumRenderTimeChange: Infinity, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const scene = viewer.scene; scene.debugShowFramesPerSecond = true; @@ -356,11 +349,14 @@ <h4>Max delta time</h4> Sandcastle.addToolbarMenu(scenarios); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sentinel-2.html b/Apps/Sandcastle/gallery/Sentinel-2.html index 2af73b5912e..5f9199e39ef 100644 --- a/Apps/Sandcastle/gallery/Sentinel-2.html +++ b/Apps/Sandcastle/gallery/Sentinel-2.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Sentinel-2 (mostly) cloudless global imagery between 10 and 60 meter resolution. @@ -40,11 +40,14 @@ imageryProvider: new Cesium.IonImageryProvider({ assetId: 3954 }), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 2f45dff2724..816b5cf7e49 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -41,16 +41,9 @@ shadows: true, terrainShadows: Cesium.ShadowMode.ENABLED, shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const shadowMap = viewer.shadowMap; shadowMap.maximumDistance = 10000.0; @@ -306,11 +299,14 @@ setLocation(locations.Exton); setEntity(cesiumAir); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Show or Hide Entities.html b/Apps/Sandcastle/gallery/Show or Hide Entities.html index 0a970559a77..3a14a798bc8 100644 --- a/Apps/Sandcastle/gallery/Show or Hide Entities.html +++ b/Apps/Sandcastle/gallery/Show or Hide Entities.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin //Set the random seed for reproducible random colors. @@ -88,11 +88,14 @@ spheres.show = !spheres.show; }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html index 13dd56c02c8..c7a477d501b 100644 --- a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -69,11 +69,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Star Burst.html b/Apps/Sandcastle/gallery/Star Burst.html index bc998f384fd..ba67dfb41de 100644 --- a/Apps/Sandcastle/gallery/Star Burst.html +++ b/Apps/Sandcastle/gallery/Star Burst.html @@ -31,7 +31,7 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -408,11 +408,14 @@ } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index 31a3e5a8740..8b20e699b29 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -58,363 +58,355 @@ Edge styling enabled </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - // Use clipping planes to selectively hide parts of the globe surface. - const viewer = new Cesium.Viewer("cesiumContainer", { - skyAtmosphere: false, - shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - scene3DOnly: true, - }); - const globe = viewer.scene.globe; - - const exampleTypes = [ - "Cesium Man", - "St. Helens", - "Grand Canyon Isolated", - ]; - const viewModel = { - exampleTypes: exampleTypes, - currentExampleType: exampleTypes[0], - clippingPlanesEnabled: true, - edgeStylingEnabled: true, - }; - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Use clipping planes to selectively hide parts of the globe surface. + const viewer = new Cesium.Viewer("cesiumContainer", { + skyAtmosphere: false, + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + scene3DOnly: true, + }); + const globe = viewer.scene.globe; - // For tracking state when switching exampleTypes - let clippingPlanesEnabled = true; - let edgeStylingEnabled = true; + const exampleTypes = [ + "Cesium Man", + "St. Helens", + "Grand Canyon Isolated", + ]; + const viewModel = { + exampleTypes: exampleTypes, + currentExampleType: exampleTypes[0], + clippingPlanesEnabled: true, + edgeStylingEnabled: true, + }; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); - let tileset; + // For tracking state when switching exampleTypes + let clippingPlanesEnabled = true; + let edgeStylingEnabled = true; - loadCesiumMan(); - - function reset() { - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - } + let tileset; - function loadCesiumMan() { - const position = Cesium.Cartesian3.fromRadians( - -2.0862979473351286, - 0.6586620013036164, - 1400.0 - ); + loadCesiumMan(); - const entity = viewer.entities.add({ - position: position, - box: { - dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), - material: Cesium.Color.WHITE.withAlpha(0.3), - outline: true, - outlineColor: Cesium.Color.WHITE, - }, - }); + function reset() { + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + } - viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - maximumScale: 800, - }, - }); + function loadCesiumMan() { + const position = Cesium.Cartesian3.fromRadians( + -2.0862979473351286, + 0.6586620013036164, + 1400.0 + ); - globe.depthTestAgainstTerrain = true; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - -700.0 - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - -700.0 - ), - ], - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; + const entity = viewer.entities.add({ + position: position, + box: { + dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), + material: Cesium.Color.WHITE.withAlpha(0.3), + outline: true, + outlineColor: Cesium.Color.WHITE, + }, + }); - viewer.trackedEntity = entity; - } + viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + maximumScale: 800, + }, + }); - function loadStHelens() { - // Create clipping planes for polygon around area to be clipped. - const points = [ - new Cesium.Cartesian3( - -2358434.3501556474, - -3743554.5012105294, - 4581080.771684084 - ), - new Cesium.Cartesian3( - -2357886.4482675144, - -3744467.562778789, - 4581020.9199767085 - ), - new Cesium.Cartesian3( - -2357299.84353055, - -3744954.0879047974, - 4581080.992360969 - ), - new Cesium.Cartesian3( - -2356412.05169956, - -3745385.3013702347, - 4580893.4737207815 - ), - new Cesium.Cartesian3( - -2355472.889436636, - -3745256.5725702164, - 4581252.3128526565 - ), - new Cesium.Cartesian3( - -2354385.7458722834, - -3744319.3823686405, - 4582372.770031389 - ), - new Cesium.Cartesian3( - -2353758.788158616, - -3743051.0128084184, - 4583356.453176038 - ), - new Cesium.Cartesian3( - -2353663.8128999653, - -3741847.9126874236, - 4584079.428665509 + globe.depthTestAgainstTerrain = true; + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2354213.667592133, - -3740784.50946316, - 4584502.428203525 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2355596.239450013, - -3739901.0226732804, - 4584515.9652557485 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2356942.4170108805, - -3740342.454698685, - 4583686.690694482 + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + -700.0 ), - new Cesium.Cartesian3( - -2357529.554838029, - -3740766.995076834, - 4583145.055348843 - ), - new Cesium.Cartesian3( - -2358106.017822064, - -3741439.438418052, - 4582452.293605261 - ), - new Cesium.Cartesian3( - -2358539.5426236596, - -3742680.720902901, - 4581692.0260975715 - ), - ]; + ], + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - const pointsLength = points.length; + viewer.trackedEntity = entity; + } - // Create center points for each clipping plane - const clippingPlanes = []; - for (let i = 0; i < pointsLength; ++i) { - const nextIndex = (i + 1) % pointsLength; - let midpoint = Cesium.Cartesian3.add( - points[i], - points[nextIndex], - new Cesium.Cartesian3() - ); - midpoint = Cesium.Cartesian3.multiplyByScalar( - midpoint, - 0.5, - midpoint - ); - - const up = Cesium.Cartesian3.normalize( - midpoint, - new Cesium.Cartesian3() - ); - let right = Cesium.Cartesian3.subtract( - points[nextIndex], - midpoint, - new Cesium.Cartesian3() - ); - right = Cesium.Cartesian3.normalize(right, right); + function loadStHelens() { + // Create clipping planes for polygon around area to be clipped. + const points = [ + new Cesium.Cartesian3( + -2358434.3501556474, + -3743554.5012105294, + 4581080.771684084 + ), + new Cesium.Cartesian3( + -2357886.4482675144, + -3744467.562778789, + 4581020.9199767085 + ), + new Cesium.Cartesian3( + -2357299.84353055, + -3744954.0879047974, + 4581080.992360969 + ), + new Cesium.Cartesian3( + -2356412.05169956, + -3745385.3013702347, + 4580893.4737207815 + ), + new Cesium.Cartesian3( + -2355472.889436636, + -3745256.5725702164, + 4581252.3128526565 + ), + new Cesium.Cartesian3( + -2354385.7458722834, + -3744319.3823686405, + 4582372.770031389 + ), + new Cesium.Cartesian3( + -2353758.788158616, + -3743051.0128084184, + 4583356.453176038 + ), + new Cesium.Cartesian3( + -2353663.8128999653, + -3741847.9126874236, + 4584079.428665509 + ), + new Cesium.Cartesian3( + -2354213.667592133, + -3740784.50946316, + 4584502.428203525 + ), + new Cesium.Cartesian3( + -2355596.239450013, + -3739901.0226732804, + 4584515.9652557485 + ), + new Cesium.Cartesian3( + -2356942.4170108805, + -3740342.454698685, + 4583686.690694482 + ), + new Cesium.Cartesian3( + -2357529.554838029, + -3740766.995076834, + 4583145.055348843 + ), + new Cesium.Cartesian3( + -2358106.017822064, + -3741439.438418052, + 4582452.293605261 + ), + new Cesium.Cartesian3( + -2358539.5426236596, + -3742680.720902901, + 4581692.0260975715 + ), + ]; - let normal = Cesium.Cartesian3.cross( - right, - up, - new Cesium.Cartesian3() - ); - normal = Cesium.Cartesian3.normalize(normal, normal); + const pointsLength = points.length; - // Compute distance by pretending the plane is at the origin - const originCenteredPlane = new Cesium.Plane(normal, 0.0); - const distance = Cesium.Plane.getPointDistance( - originCenteredPlane, - midpoint - ); + // Create center points for each clipping plane + const clippingPlanes = []; + for (let i = 0; i < pointsLength; ++i) { + const nextIndex = (i + 1) % pointsLength; + let midpoint = Cesium.Cartesian3.add( + points[i], + points[nextIndex], + new Cesium.Cartesian3() + ); + midpoint = Cesium.Cartesian3.multiplyByScalar( + midpoint, + 0.5, + midpoint + ); - clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); - } - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - planes: clippingPlanes, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; + const up = Cesium.Cartesian3.normalize( + midpoint, + new Cesium.Cartesian3() + ); + let right = Cesium.Cartesian3.subtract( + points[nextIndex], + midpoint, + new Cesium.Cartesian3() + ); + right = Cesium.Cartesian3.normalize(right, right); - // Load tileset - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - return tileset.readyPromise - .then(function () { - // Adjust height so tileset is in terrain - const cartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - -20.0 - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation( - translation - ); + let normal = Cesium.Cartesian3.cross( + right, + up, + new Cesium.Cartesian3() + ); + normal = Cesium.Cartesian3.normalize(normal, normal); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgb(207, 255, 207)", - }); + // Compute distance by pretending the plane is at the origin + const originCenteredPlane = new Cesium.Plane(normal, 0.0); + const distance = Cesium.Plane.getPointDistance( + originCenteredPlane, + midpoint + ); - viewer.scene.primitives.add(tileset); + clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); + } + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + planes: clippingPlanes, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - const boundingSphere = tileset.boundingSphere; + // Load tileset + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + return tileset.readyPromise + .then(function () { + // Adjust height so tileset is in terrain + const cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + -20.0 + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgb(207, 255, 207)", }); - } - function loadGrandCanyon() { - // Pick a position at the Grand Canyon - const position = Cesium.Cartographic.toCartesian( - new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) - ); - const distance = 3000.0; - const boundingSphere = new Cesium.BoundingSphere( - position, - distance - ); + viewer.scene.primitives.add(tileset); + + const boundingSphere = tileset.boundingSphere; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - distance - ), - ], - unionClippingRegions: true, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }) + .catch(function (error) { + throw error; }); - globe.backFaceCulling = false; - globe.showSkirts = false; + } - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange( - 0.5, - -0.5, - boundingSphere.radius * 5.0 - ) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + function loadGrandCanyon() { + // Pick a position at the Grand Canyon + const position = Cesium.Cartographic.toCartesian( + new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) + ); + const distance = 3000.0; + const boundingSphere = new Cesium.BoundingSphere(position, distance); - Cesium.knockout - .getObservable(viewModel, "clippingPlanesEnabled") - .subscribe(function (value) { - globe.clippingPlanes.enabled = value; - clippingPlanesEnabled = value; - }); + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + distance + ), + ], + unionClippingRegions: true, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = false; + globe.showSkirts = false; - Cesium.knockout - .getObservable(viewModel, "edgeStylingEnabled") - .subscribe(function (value) { - edgeStylingEnabled = value; - globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; - }); + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === exampleTypes[0]) { - loadCesiumMan(); - } else if (newValue === exampleTypes[1]) { - loadStHelens(); - } else if (newValue === exampleTypes[2]) { - loadGrandCanyon(); - } - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + Cesium.knockout + .getObservable(viewModel, "clippingPlanesEnabled") + .subscribe(function (value) { + globe.clippingPlanes.enabled = value; + clippingPlanesEnabled = value; + }); + + Cesium.knockout + .getObservable(viewModel, "edgeStylingEnabled") + .subscribe(function (value) { + edgeStylingEnabled = value; + globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; + }); + + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === exampleTypes[0]) { + loadCesiumMan(); + } else if (newValue === exampleTypes[1]) { + loadStHelens(); + } else if (newValue === exampleTypes[2]) { + loadGrandCanyon(); + } + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index b850b26fa29..9f403cb3cfb 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -73,18 +73,12 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const globe = scene.globe; @@ -198,11 +192,14 @@ viewModel.relativeHeight = 0.0; }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index f1e50500145..6ec6977016a 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -36,21 +36,15 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); // set lighting to true viewer.scene.globe.enableLighting = true; @@ -344,11 +338,14 @@ "sampleButtons" ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html index e24fa0d05ab..b1e8c9c48b9 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -94,11 +94,14 @@ new Cesium.HeadingPitchRange(0.0, -0.5, 50.0) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html index 06875313330..a860726eeac 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -160,11 +160,14 @@ viewer.trackedEntity = vehicleEntity; vehicleEntity.viewFrom = new Cesium.Cartesian3(-10.0, 7.0, 4.0); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Underground Color.html b/Apps/Sandcastle/gallery/Underground Color.html index 8365de68ee2..126b95e196f 100644 --- a/Apps/Sandcastle/gallery/Underground Color.html +++ b/Apps/Sandcastle/gallery/Underground Color.html @@ -108,7 +108,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -219,11 +219,14 @@ globe.undergroundColorAlphaByDistance.farValue = farAlpha; } update(); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Video.html b/Apps/Sandcastle/gallery/Video.html index 7aae2fc83d5..ddfd4226673 100644 --- a/Apps/Sandcastle/gallery/Video.html +++ b/Apps/Sandcastle/gallery/Video.html @@ -54,7 +54,7 @@ Your browser does not support the <code>video</code> element. </video> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -145,11 +145,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Wall.html b/Apps/Sandcastle/gallery/Wall.html index cae9bcbfa0e..8ab9df06417 100644 --- a/Apps/Sandcastle/gallery/Wall.html +++ b/Apps/Sandcastle/gallery/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -135,11 +135,14 @@ }); viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Washington DC 2017.html b/Apps/Sandcastle/gallery/Washington DC 2017.html index 8423c0500b9..269ea111f2c 100644 --- a/Apps/Sandcastle/gallery/Washington DC 2017.html +++ b/Apps/Sandcastle/gallery/Washington DC 2017.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // 3 inch (0.08m) resolution imagery of Washington DC collected in 2017 @@ -43,11 +43,14 @@ ); viewer.flyTo(imageryLayer); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Service (WMS).html b/Apps/Sandcastle/gallery/Web Map Service (WMS).html index 4f40bb976dd..c94994aa7e0 100644 --- a/Apps/Sandcastle/gallery/Web Map Service (WMS).html +++ b/Apps/Sandcastle/gallery/Web Map Service (WMS).html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -60,11 +60,14 @@ -5.73 ), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html index d9459c56ed5..b97e963e228 100644 --- a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html +++ b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -94,11 +94,14 @@ layer.alpha = 0.5; }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html index 6a6ef173d75..17d6581b37c 100644 --- a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html +++ b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -141,11 +141,14 @@ viewer.zoomTo(viewer.entities); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Articulations.html b/Apps/Sandcastle/gallery/development/3D Models Articulations.html index 45167af0546..d276ccb100e 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Articulations.html +++ b/Apps/Sandcastle/gallery/development/3D Models Articulations.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -182,11 +182,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html index 6a04aad8b4a..84165f2d7a4 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html +++ b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html @@ -189,7 +189,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -369,11 +369,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models.html b/Apps/Sandcastle/gallery/development/3D Models.html index 8cfd8dd20d7..d182236569f 100644 --- a/Apps/Sandcastle/gallery/development/3D Models.html +++ b/Apps/Sandcastle/gallery/development/3D Models.html @@ -90,7 +90,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -305,11 +305,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html index f7622c5f4de..7748ce8edac 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin /* @@ -262,11 +262,14 @@ });` ); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Split.html b/Apps/Sandcastle/gallery/development/3D Tiles Split.html index 2d96e548c97..0eb53386039 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Split.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Split.html @@ -57,7 +57,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -283,11 +283,14 @@ moveActive = false; }, Cesium.ScreenSpaceEventType.PINCH_END); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 2ee1b79cbc6..5464114add0 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -34,20 +34,14 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.scene.globe.depthTestAgainstTerrain = true; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const ellipsoid = viewer.scene.globe.ellipsoid; const billboardCollection = viewer.scene.primitives.add( new Cesium.BillboardCollection({ @@ -169,11 +163,14 @@ } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index 00861a900fa..f2b3d42b8aa 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -34,18 +34,12 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const context = scene.context; @@ -233,11 +227,14 @@ resetBillboardCollection(); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards.html b/Apps/Sandcastle/gallery/development/Billboards.html index 21d2f91c95e..1d03e06817a 100644 --- a/Apps/Sandcastle/gallery/development/Billboards.html +++ b/Apps/Sandcastle/gallery/development/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -423,11 +423,14 @@ }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box Outline.html b/Apps/Sandcastle/gallery/development/Box Outline.html index 31747ce8366..97a9e0a5b2c 100644 --- a/Apps/Sandcastle/gallery/development/Box Outline.html +++ b/Apps/Sandcastle/gallery/development/Box Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -80,11 +80,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box.html b/Apps/Sandcastle/gallery/development/Box.html index 442fc703307..7729332f063 100644 --- a/Apps/Sandcastle/gallery/development/Box.html +++ b/Apps/Sandcastle/gallery/development/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -74,11 +74,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle Outline.html b/Apps/Sandcastle/gallery/development/Circle Outline.html index c31e527b256..f88e4adc29d 100644 --- a/Apps/Sandcastle/gallery/development/Circle Outline.html +++ b/Apps/Sandcastle/gallery/development/Circle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -99,11 +99,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle.html b/Apps/Sandcastle/gallery/development/Circle.html index 0a6e4395712..47ff4f66d84 100644 --- a/Apps/Sandcastle/gallery/development/Circle.html +++ b/Apps/Sandcastle/gallery/development/Circle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -130,11 +130,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html index 65189eb90ee..c0a1de8a556 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -136,11 +136,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html index f88679c18cf..eecb78f4f0c 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -170,11 +170,14 @@ }), }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor Outline.html b/Apps/Sandcastle/gallery/development/Corridor Outline.html index 0102e56700c..750f89e3502 100644 --- a/Apps/Sandcastle/gallery/development/Corridor Outline.html +++ b/Apps/Sandcastle/gallery/development/Corridor Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -102,7 +102,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + try { + window.startup(Cesium); + } catch (error) { + console.error(error); + } } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor.html b/Apps/Sandcastle/gallery/development/Corridor.html index 3be94a10825..f0e96be9599 100644 --- a/Apps/Sandcastle/gallery/development/Corridor.html +++ b/Apps/Sandcastle/gallery/development/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer @@ -154,11 +154,14 @@ }), }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Custom Primitive.html b/Apps/Sandcastle/gallery/development/Custom Primitive.html index 335fb1f214c..bc96757c92a 100644 --- a/Apps/Sandcastle/gallery/development/Custom Primitive.html +++ b/Apps/Sandcastle/gallery/development/Custom Primitive.html @@ -37,7 +37,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -324,11 +324,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder Outline.html b/Apps/Sandcastle/gallery/development/Cylinder Outline.html index 4a1b698cd67..83db47d86e6 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder Outline.html +++ b/Apps/Sandcastle/gallery/development/Cylinder Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,11 +79,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder.html b/Apps/Sandcastle/gallery/development/Cylinder.html index d6c2e7c4dce..5a57f3d3621 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder.html +++ b/Apps/Sandcastle/gallery/development/Cylinder.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -108,11 +108,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Display Conditions.html b/Apps/Sandcastle/gallery/development/Display Conditions.html index dbf4b1cc881..f3838c40208 100644 --- a/Apps/Sandcastle/gallery/development/Display Conditions.html +++ b/Apps/Sandcastle/gallery/development/Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -129,11 +129,14 @@ }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse Outline.html b/Apps/Sandcastle/gallery/development/Ellipse Outline.html index 3f129932c8e..9201ba04d34 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipse Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -96,11 +96,14 @@ }), }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse.html b/Apps/Sandcastle/gallery/development/Ellipse.html index 5baa25dad20..e0eb58f1d6c 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse.html +++ b/Apps/Sandcastle/gallery/development/Ellipse.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -120,11 +120,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html index f31a39aecdc..867c86da985 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -76,11 +76,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html index 74e834b6ddc..f46de33cf41 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -122,11 +122,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid.html b/Apps/Sandcastle/gallery/development/Ellipsoid.html index ee5d71f4f9a..27720c6d4ad 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -75,11 +75,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 58e3a370260..6ee1da4951b 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -47,18 +47,12 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -144,11 +138,14 @@ viewer.render(); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index 8dba93dd07f..ce5e4eee3ac 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -113,11 +113,14 @@ scene.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html index 216ff9d59d8..9c93e561567 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -286,11 +286,14 @@ ); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html index 4f3d5741196..c101eea0c94 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -263,11 +263,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html index 407000421de..95f22d7cfd0 100644 --- a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -1278,11 +1278,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html index f3dd165d83f..50c3720ef8b 100644 --- a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html @@ -32,98 +32,99 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); - } - - // Polyline Glow - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1955, - -122.1058, - 46.1955, - ]), - width: 10.0, - }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineGlowType - ), - }), - }) + if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." ); + } - // Polyline Dash - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1975, - -122.1058, - 46.1975, - ]), - width: 10.0, - }), + // Polyline Glow + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1955, + -122.1058, + 46.1955, + ]), + width: 10.0, }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineDashType - ), - }), - }) - ); + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineGlowType + ), + }), + }) + ); - // Polyline Outline - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1995, - -122.1058, - 46.1995, - ]), - width: 10.0, - }), + // Polyline Dash + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1975, + -122.1058, + 46.1975, + ]), + width: 10.0, }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineOutlineType - ), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineDashType + ), + }), + }) + ); + + // Polyline Outline + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1995, + -122.1058, + 46.1995, + ]), + width: 10.0, }), - }) - ); + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineOutlineType + ), + }), + }) + ); - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index ed527e23634..025e7273b5c 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -32,21 +32,15 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { window.alert( @@ -554,11 +548,14 @@ createPrimitives(scene); createButtons(scene); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index dfdebecdf7a..03d4b8c4ca9 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -32,18 +32,12 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -502,11 +496,14 @@ viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Labels.html b/Apps/Sandcastle/gallery/development/Labels.html index a7ef679f397..0caa1262523 100644 --- a/Apps/Sandcastle/gallery/development/Labels.html +++ b/Apps/Sandcastle/gallery/development/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -216,11 +216,14 @@ }, ]); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 4637910a494..00dfb8d73d8 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -64,274 +64,275 @@ ></select> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shouldAnimate: true, - projectionPicker: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shouldAnimate: true, + projectionPicker: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const globe = viewer.scene.globe; - globe.depthTestAgainstTerrain = true; + const globe = viewer.scene.globe; + globe.depthTestAgainstTerrain = true; - let cylinderRadius = -20.0; - let radiusMultiplier = 1.0; + let cylinderRadius = -20.0; + let radiusMultiplier = 1.0; - let steps = 32; - let clippingPlanes = []; - let modelEntityClippingPlanes; - let clippingModeUnion = false; - let enabled = true; + let steps = 32; + let clippingPlanes = []; + let modelEntityClippingPlanes; + let clippingModeUnion = false; + let enabled = true; - const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; - const viewModel = { - cylinderRadius: cylinderRadius, - exampleTypes: clipObjects, - currentExampleType: clipObjects[0], - planeCount: steps, - }; + const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; + const viewModel = { + cylinderRadius: cylinderRadius, + exampleTypes: clipObjects, + currentExampleType: clipObjects[0], + planeCount: steps, + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "cylinderRadius") - .subscribe(function (newValue) { - cylinderRadius = parseFloat(viewModel.cylinderRadius); - updatePlanes(); - }); + Cesium.knockout + .getObservable(viewModel, "cylinderRadius") + .subscribe(function (newValue) { + cylinderRadius = parseFloat(viewModel.cylinderRadius); + updatePlanes(); + }); - Cesium.knockout - .getObservable(viewModel, "planeCount") - .subscribe(function (newValue) { - const newSteps = parseFloat(viewModel.planeCount); - if (newSteps !== steps) { - steps = newSteps; - modelEntityClippingPlanes.removeAll(); - computePlanes(); - } - }); + Cesium.knockout + .getObservable(viewModel, "planeCount") + .subscribe(function (newValue) { + const newSteps = parseFloat(viewModel.planeCount); + if (newSteps !== steps) { + steps = newSteps; + modelEntityClippingPlanes.removeAll(); + computePlanes(); + } + }); - const scene = viewer.scene; - const planeEntities = []; - let selectedPlane; + const scene = viewer.scene; + const planeEntities = []; + let selectedPlane; - function updatePlanes() { - for (let i = 0; i < clippingPlanes.length; i++) { - const plane = clippingPlanes[i]; - plane.distance = cylinderRadius * radiusMultiplier; - } + function updatePlanes() { + for (let i = 0; i < clippingPlanes.length; i++) { + const plane = clippingPlanes[i]; + plane.distance = cylinderRadius * radiusMultiplier; } + } - function computePlanes() { - const stepDegrees = Cesium.Math.TWO_PI / steps; - clippingPlanes = []; + function computePlanes() { + const stepDegrees = Cesium.Math.TWO_PI / steps; + clippingPlanes = []; - for (let i = 0; i < steps; i++) { - const angle = i * stepDegrees; - const dir = new Cesium.Cartesian3(); + for (let i = 0; i < steps; i++) { + const angle = i * stepDegrees; + const dir = new Cesium.Cartesian3(); + dir.x = 1.0; + dir.y = Math.tan(angle); + if (angle > Cesium.Math.PI_OVER_TWO) { + dir.x = -1.0; + dir.y *= -1.0; + } + if (angle > Cesium.Math.PI) { + dir.x = -1.0; + } + if (angle > Cesium.Math.PI_OVER_TWO * 3) { dir.x = 1.0; - dir.y = Math.tan(angle); - if (angle > Cesium.Math.PI_OVER_TWO) { - dir.x = -1.0; - dir.y *= -1.0; - } - if (angle > Cesium.Math.PI) { - dir.x = -1.0; - } - if (angle > Cesium.Math.PI_OVER_TWO * 3) { - dir.x = 1.0; - dir.y = -dir.y; - } - Cesium.Cartesian3.normalize(dir, dir); - const newPlane = new Cesium.ClippingPlane( - dir, - cylinderRadius * radiusMultiplier - ); - modelEntityClippingPlanes.add(newPlane); - clippingPlanes.push(newPlane); + dir.y = -dir.y; } + Cesium.Cartesian3.normalize(dir, dir); + const newPlane = new Cesium.ClippingPlane( + dir, + cylinderRadius * radiusMultiplier + ); + modelEntityClippingPlanes.add(newPlane); + clippingPlanes.push(newPlane); } + } - function createClippingPlanes(modelMatrix) { - modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.defined(modelMatrix) - ? modelMatrix - : Cesium.Matrix4.IDENTITY, - edgeWidth: 2.0, - edgeColor: Cesium.Color.WHITE, - unionClippingRegions: clippingModeUnion, - enabled: enabled, - }); - computePlanes(); - } + function createClippingPlanes(modelMatrix) { + modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.defined(modelMatrix) + ? modelMatrix + : Cesium.Matrix4.IDENTITY, + edgeWidth: 2.0, + edgeColor: Cesium.Color.WHITE, + unionClippingRegions: clippingModeUnion, + enabled: enabled, + }); + computePlanes(); + } - function updateClippingPlanes() { - return modelEntityClippingPlanes; - } + function updateClippingPlanes() { + return modelEntityClippingPlanes; + } - const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; - const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); - const instancedUrl = - "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; - const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); + const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; + const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); + const instancedUrl = + "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; + const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); - function loadModel(url) { - createClippingPlanes(); - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 300.0 - ); - const heading = 0.0; - const pitch = 0.0; - const roll = 0.0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: 20, - minimumPixelSize: 100.0, - clippingPlanes: new Cesium.CallbackProperty( - updateClippingPlanes, - false - ), - }, - }); - viewer.trackedEntity = entity; - } + function loadModel(url) { + createClippingPlanes(); + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 300.0 + ); + const heading = 0.0; + const pitch = 0.0; + const roll = 0.0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: 20, + minimumPixelSize: 100.0, + clippingPlanes: new Cesium.CallbackProperty( + updateClippingPlanes, + false + ), + }, + }); + viewer.trackedEntity = entity; + } - let tileset; - async function loadTileset(url, height) { - createClippingPlanes(); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - clippingPlanes: modelEntityClippingPlanes, - enableDebugWireframe: true, - }) - ); + let tileset; + async function loadTileset(url, height) { + createClippingPlanes(); + tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: url, + clippingPlanes: modelEntityClippingPlanes, + enableDebugWireframe: true, + }) + ); - await tileset.readyPromise; - const boundingSphere = tileset.boundingSphere; + await tileset.readyPromise; + const boundingSphere = tileset.boundingSphere; - const cartographic = Cesium.Cartographic.fromCartesian( - boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - height - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + const cartographic = Cesium.Cartographic.fromCartesian( + boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - loadModel(modelUrl); + loadModel(modelUrl); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); - if (newValue === clipObjects[0]) { - // Model - loadModel(modelUrl); - } else if (newValue === clipObjects[1]) { - // B3dm photogrammetry - return loadTileset(agiHqUrl, 0.0); - } else if (newValue === clipObjects[2]) { - // Point clouds - radiusMultiplier = 20.0; - return loadTileset(pointCloudUrl, 0.0).then(function () { - tileset.pointCloudShading.attenuation = true; - }); - } else if (newValue === clipObjects[3]) { - // i3dm - loadTileset(instancedUrl, 100.0); - } else if (newValue === clipObjects[4]) { - // Terrain - const position = Cesium.Cartesian3.fromRadians( - // eslint-disable-next-line no-loss-of-precision - -2.0872979473351286, - 0.6596620013036164, - 2380.0 - ); - const entity = viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - scale: 40, - }, - }); - viewer.trackedEntity = entity; - createClippingPlanes( - entity.computeModelMatrix(Cesium.JulianDate.now()) - ); - globe.clippingPlanes = modelEntityClippingPlanes; - } - updatePlanes(); - }); + if (newValue === clipObjects[0]) { + // Model + loadModel(modelUrl); + } else if (newValue === clipObjects[1]) { + // B3dm photogrammetry + return loadTileset(agiHqUrl, 0.0); + } else if (newValue === clipObjects[2]) { + // Point clouds + radiusMultiplier = 20.0; + return loadTileset(pointCloudUrl, 0.0).then(function () { + tileset.pointCloudShading.attenuation = true; + }); + } else if (newValue === clipObjects[3]) { + // i3dm + loadTileset(instancedUrl, 100.0); + } else if (newValue === clipObjects[4]) { + // Terrain + const position = Cesium.Cartesian3.fromRadians( + // eslint-disable-next-line no-loss-of-precision + -2.0872979473351286, + 0.6596620013036164, + 2380.0 + ); + const entity = viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + scale: 40, + }, + }); + viewer.trackedEntity = entity; + createClippingPlanes( + entity.computeModelMatrix(Cesium.JulianDate.now()) + ); + globe.clippingPlanes = modelEntityClippingPlanes; + } + updatePlanes(); + }); - function reset() { - radiusMultiplier = 1.0; - viewModel.cylinderRadius = cylinderRadius; - viewer.entities.removeAll(); - viewer.scene.primitives.removeAll(); - globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any - modelEntityClippingPlanes = undefined; - } + function reset() { + radiusMultiplier = 1.0; + viewModel.cylinderRadius = cylinderRadius; + viewer.entities.removeAll(); + viewer.scene.primitives.removeAll(); + globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any + modelEntityClippingPlanes = undefined; + } - Sandcastle.addToggleButton("union", clippingModeUnion, function ( - checked - ) { - clippingModeUnion = checked; - modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; - }); + Sandcastle.addToggleButton("union", clippingModeUnion, function ( + checked + ) { + clippingModeUnion = checked; + modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; + }); - Sandcastle.addToggleButton("enabled", enabled, function (checked) { - enabled = checked; - modelEntityClippingPlanes.enabled = enabled; - }); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + Sandcastle.addToggleButton("enabled", enabled, function (checked) { + enabled = checked; + modelEntityClippingPlanes.enabled = enabled; + }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Material.html b/Apps/Sandcastle/gallery/development/Material.html index 2f3789fe57c..083e1f48a0f 100644 --- a/Apps/Sandcastle/gallery/development/Material.html +++ b/Apps/Sandcastle/gallery/development/Material.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -87,11 +87,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index 492fed56efe..af859df2067 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -38,7 +38,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -46,16 +46,9 @@ infoBox: false, selectionIndicator: false, timeline: false, + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - const scene = viewer.scene; const camera = scene.camera; @@ -143,11 +136,14 @@ scene.primitives.add(new CustomPrimitive(shadowMap2)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Per Instance Color.html b/Apps/Sandcastle/gallery/development/Per Instance Color.html index 104de111419..35f37ec47f0 100644 --- a/Apps/Sandcastle/gallery/development/Per Instance Color.html +++ b/Apps/Sandcastle/gallery/development/Per Instance Color.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -65,11 +65,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Pick From Ray.html b/Apps/Sandcastle/gallery/development/Pick From Ray.html index e8c68eed20d..a24c5a563f9 100644 --- a/Apps/Sandcastle/gallery/development/Pick From Ray.html +++ b/Apps/Sandcastle/gallery/development/Pick From Ray.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -190,11 +190,14 @@ pickFromRay(); }, 2000.0); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Picking.html b/Apps/Sandcastle/gallery/development/Picking.html index 3b9fd338be0..4e1dee21557 100644 --- a/Apps/Sandcastle/gallery/development/Picking.html +++ b/Apps/Sandcastle/gallery/development/Picking.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -620,11 +620,14 @@ } }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/PointPrimitives.html b/Apps/Sandcastle/gallery/development/PointPrimitives.html index 7efb0a1983f..8539616d169 100644 --- a/Apps/Sandcastle/gallery/development/PointPrimitives.html +++ b/Apps/Sandcastle/gallery/development/PointPrimitives.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -271,11 +271,14 @@ }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Outline.html b/Apps/Sandcastle/gallery/development/Polygon Outline.html index ccdaf2d5145..f1399271500 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Polygon Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -148,11 +148,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html index 00116b09de3..e9e307bcc8e 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html +++ b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -432,11 +432,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon.html b/Apps/Sandcastle/gallery/development/Polygon.html index e1924903069..9dc7d26fe3b 100644 --- a/Apps/Sandcastle/gallery/development/Polygon.html +++ b/Apps/Sandcastle/gallery/development/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -354,11 +354,13 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { - window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Color.html b/Apps/Sandcastle/gallery/development/Polyline Color.html index b7ea8361ede..4023d162a6e 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Color.html +++ b/Apps/Sandcastle/gallery/development/Polyline Color.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -88,11 +88,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Material.html b/Apps/Sandcastle/gallery/development/Polyline Material.html index 5b953d41d4b..9c5680eb86f 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Polyline Material.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -107,11 +107,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html index 073f0455b30..e2df012ef97 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -118,11 +118,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume.html b/Apps/Sandcastle/gallery/development/Polyline Volume.html index 1037d48d357..058bf9b26a2 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -166,11 +166,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline.html b/Apps/Sandcastle/gallery/development/Polyline.html index 7025f9e1bba..1a1bef62af5 100644 --- a/Apps/Sandcastle/gallery/development/Polyline.html +++ b/Apps/Sandcastle/gallery/development/Polyline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -92,11 +92,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index aedb55060ce..9a6325466b2 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -50,21 +50,15 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { window.alert( @@ -367,11 +361,14 @@ }, ]); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines.html b/Apps/Sandcastle/gallery/development/Polylines.html index 7046bd1e060..7a24afd2447 100644 --- a/Apps/Sandcastle/gallery/development/Polylines.html +++ b/Apps/Sandcastle/gallery/development/Polylines.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -192,11 +192,14 @@ createPrimitives(viewer.scene); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle Outline.html b/Apps/Sandcastle/gallery/development/Rectangle Outline.html index d5f90c1725a..b466066cc8f 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle Outline.html +++ b/Apps/Sandcastle/gallery/development/Rectangle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -63,11 +63,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle.html b/Apps/Sandcastle/gallery/development/Rectangle.html index 587b72bbf33..4123baa8643 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle.html +++ b/Apps/Sandcastle/gallery/development/Rectangle.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -80,11 +80,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index 2f4a6fe40cd..cef7861a6f1 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -302,7 +302,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin @@ -1082,11 +1082,14 @@ }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Simple Polyline.html b/Apps/Sandcastle/gallery/development/Simple Polyline.html index 18688e29147..91e2b69cf05 100644 --- a/Apps/Sandcastle/gallery/development/Simple Polyline.html +++ b/Apps/Sandcastle/gallery/development/Simple Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -112,11 +112,14 @@ ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere Outline.html b/Apps/Sandcastle/gallery/development/Sphere Outline.html index d2fa6a09f14..ed0e8ad49e9 100644 --- a/Apps/Sandcastle/gallery/development/Sphere Outline.html +++ b/Apps/Sandcastle/gallery/development/Sphere Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -75,11 +75,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere.html b/Apps/Sandcastle/gallery/development/Sphere.html index 6e0bfbc8575..3eaa3590650 100644 --- a/Apps/Sandcastle/gallery/development/Sphere.html +++ b/Apps/Sandcastle/gallery/development/Sphere.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -75,11 +75,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html index 3dc40b187da..4f15619d76c 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html +++ b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html @@ -32,164 +32,165 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - (async () => { - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - const concavePositions = [ - new Cesium.Cartesian3( - -2353381.4891308164, - -3747386.1222378365, - 4577999.291515961 - ), - new Cesium.Cartesian3( - -2359513.937204245, - -3743087.2343810294, - 4578357.188560644 - ), - new Cesium.Cartesian3( - -2356102.0286082155, - -3739921.552293276, - 4582670.218770547 - ), - new Cesium.Cartesian3( - -2353889.0353209395, - -3741183.2274413602, - 4582776.909071608 - ), - new Cesium.Cartesian3( - -2355072.390487758, - -3742865.615615464, - 4580808.044684757 - ), - new Cesium.Cartesian3( - -2356109.6661414686, - -3741994.0607898533, - 4580985.489703348 - ), - new Cesium.Cartesian3( - -2357041.8328847606, - -3743225.9693035223, - 4579509.2148039425 - ), - new Cesium.Cartesian3( - -2354586.752280607, - -3744890.9511893727, - 4579411.591389144 - ), - new Cesium.Cartesian3( - -2353213.0268325945, - -3743712.1202877173, - 4581070.08828045 - ), - new Cesium.Cartesian3( - -2353637.930711704, - -3743402.9513476435, - 4581104.219550749 - ), - new Cesium.Cartesian3( - -2352875.095159641, - -3742564.819171856, - 4582173.540953957 - ), - new Cesium.Cartesian3( - -2350669.646050987, - -3743751.6823160048, - 4582334.8406995395 - ), - ]; + const concavePositions = [ + new Cesium.Cartesian3( + -2353381.4891308164, + -3747386.1222378365, + 4577999.291515961 + ), + new Cesium.Cartesian3( + -2359513.937204245, + -3743087.2343810294, + 4578357.188560644 + ), + new Cesium.Cartesian3( + -2356102.0286082155, + -3739921.552293276, + 4582670.218770547 + ), + new Cesium.Cartesian3( + -2353889.0353209395, + -3741183.2274413602, + 4582776.909071608 + ), + new Cesium.Cartesian3( + -2355072.390487758, + -3742865.615615464, + 4580808.044684757 + ), + new Cesium.Cartesian3( + -2356109.6661414686, + -3741994.0607898533, + 4580985.489703348 + ), + new Cesium.Cartesian3( + -2357041.8328847606, + -3743225.9693035223, + 4579509.2148039425 + ), + new Cesium.Cartesian3( + -2354586.752280607, + -3744890.9511893727, + 4579411.591389144 + ), + new Cesium.Cartesian3( + -2353213.0268325945, + -3743712.1202877173, + 4581070.08828045 + ), + new Cesium.Cartesian3( + -2353637.930711704, + -3743402.9513476435, + 4581104.219550749 + ), + new Cesium.Cartesian3( + -2352875.095159641, + -3742564.819171856, + 4582173.540953957 + ), + new Cesium.Cartesian3( + -2350669.646050987, + -3743751.6823160048, + 4582334.8406995395 + ), + ]; - // concave polygon - viewer.entities.add({ - name: "concave polygon on surface", - polygon: { - hierarchy: concavePositions, - material: "../images/Cesium_Logo_Color.jpg", - }, - stRotation: 1.0, - }); + // concave polygon + viewer.entities.add({ + name: "concave polygon on surface", + polygon: { + hierarchy: concavePositions, + material: "../images/Cesium_Logo_Color.jpg", + }, + stRotation: 1.0, + }); - // Randomly colored, nonoverlapping squares - const latitude = 46.2522; - const longitude = -122.2534; + // Randomly colored, nonoverlapping squares + const latitude = 46.2522; + const longitude = -122.2534; - Cesium.Math.setRandomNumberSeed(133); + Cesium.Math.setRandomNumberSeed(133); - for (let x = 0; x < 10; ++x) { - for (let y = 0; y < 10; ++y) { - const cornerLat = latitude + 0.01 * x; - const cornerLon = longitude + 0.01 * y; - viewer.entities.add({ - id: `${x} ${y}`, - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - cornerLon, - cornerLat, - cornerLon + 0.009, - cornerLat + 0.009 - ), - material: Cesium.Color.fromRandom().withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); - } + for (let x = 0; x < 10; ++x) { + for (let y = 0; y < 10; ++y) { + const cornerLat = latitude + 0.01 * x; + const cornerLon = longitude + 0.01 * y; + viewer.entities.add({ + id: `${x} ${y}`, + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + cornerLon, + cornerLat, + cornerLon + 0.009, + cornerLat + 0.009 + ), + material: Cesium.Color.fromRandom().withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); } + } - // Checkerboard - const checkerboard = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.ORANGE, - oddColor: Cesium.Color.YELLOW, - repeat: new Cesium.Cartesian2(14, 14), - }); - - viewer.entities.add({ - name: "checkerboard rectangle", - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.17778, - 46.36169, - -120.17778, - 48.36169 - ), - material: checkerboard, - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + // Checkerboard + const checkerboard = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.ORANGE, + oddColor: Cesium.Color.YELLOW, + repeat: new Cesium.Cartesian2(14, 14), + }); - // Ellipse with texture rotation and repetition - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees( - -121.70711316136793, - 45.943757948892845, - 0.0 + viewer.entities.add({ + name: "checkerboard rectangle", + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.17778, + 46.36169, + -120.17778, + 48.36169 ), - name: "ellipse", - ellipse: { - semiMinorAxis: 15000.0, - semiMajorAxis: 30000.0, - material: new Cesium.ImageMaterialProperty({ - image: "../images/Cesium_Logo_Color.jpg", - repeat: new Cesium.Cartesian2(10, 10), - }), - stRotation: Cesium.Math.toRadians(45), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + material: checkerboard, + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - viewer.zoomTo(viewer.entities); - })(); //Sandcastle_End - Sandcastle.finishedLoading(); + // Ellipse with texture rotation and repetition + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees( + -121.70711316136793, + 45.943757948892845, + 0.0 + ), + name: "ellipse", + ellipse: { + semiMinorAxis: 15000.0, + semiMajorAxis: 30000.0, + material: new Cesium.ImageMaterialProperty({ + image: "../images/Cesium_Logo_Color.jpg", + repeat: new Cesium.Cartesian2(10, 10), + }), + stRotation: Cesium.Math.toRadians(45), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); + + viewer.zoomTo(viewer.entities); //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index 5ea861d821d..83d8c0f9e0d 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -32,23 +32,17 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", {}); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); const scene = viewer.scene; const camera = scene.camera; const globe = scene.globe; const statistics = Cesium.RequestScheduler.statistics; - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } - })(); - let startTime; let flightComplete; let monitor; @@ -279,11 +273,14 @@ console.log(cameraString); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html index 16308f1bd67..18d98e71114 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html +++ b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html @@ -91,7 +91,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -153,11 +153,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Volumes.html b/Apps/Sandcastle/gallery/development/Volumes.html index 8ff67043449..319f3ecbf2a 100644 --- a/Apps/Sandcastle/gallery/development/Volumes.html +++ b/Apps/Sandcastle/gallery/development/Volumes.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -67,11 +67,14 @@ createPrimitives(viewer.scene); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Voxels.html b/Apps/Sandcastle/gallery/development/Voxels.html index a3b2b3590fc..58abbc206ad 100644 --- a/Apps/Sandcastle/gallery/development/Voxels.html +++ b/Apps/Sandcastle/gallery/development/Voxels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -469,11 +469,14 @@ console.log(pickedPrimitive); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall Outline.html b/Apps/Sandcastle/gallery/development/Wall Outline.html index a314a70d61a..0ecd0d637a9 100644 --- a/Apps/Sandcastle/gallery/development/Wall Outline.html +++ b/Apps/Sandcastle/gallery/development/Wall Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -67,11 +67,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall.html b/Apps/Sandcastle/gallery/development/Wall.html index e22ffb9df6a..223e3cc8637 100644 --- a/Apps/Sandcastle/gallery/development/Wall.html +++ b/Apps/Sandcastle/gallery/development/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -170,11 +170,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/load-cesium-es6.js b/Apps/Sandcastle/load-cesium-es6.js index 0b7dfc4cd51..3eb3470d6e6 100644 --- a/Apps/Sandcastle/load-cesium-es6.js +++ b/Apps/Sandcastle/load-cesium-es6.js @@ -7,5 +7,8 @@ window.Cesium = Cesium; // Since ES6 modules have no guaranteed load order, // only call startup if it's already defined but hasn't been called yet if (!window.startupCalled && typeof window.startup === "function") { - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + console.error(error); + }); + Sandcastle.finishedLoading(); } From 3fe60dc82c8fba58feae6825b6d82aff89500c7c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 3 Feb 2023 15:15:15 -0500 Subject: [PATCH 428/679] voxels: use t-dependent epsilon for box normals --- packages/engine/Source/Shaders/Voxels/IntersectBox.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index df8e63a5f5c..9eb28a4854a 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -30,9 +30,10 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) return Box(p0, p1); } -vec3 getBoxNormal(in vec3 entryPoint, in Box box) +vec3 getBoxNormal(in Box box, in Ray ray, in float entryT) { - vec3 epsilon = (box.p1 - box.p0) * 0.00001; + vec3 entryPoint = ray.pos + entryT * ray.dir; + vec3 epsilon = vec3(entryT * 0.000001); vec3 lower = step(entryPoint - epsilon, box.p0); vec3 upper = step(box.p1, entryPoint + epsilon); return normalize(upper - lower); @@ -55,8 +56,7 @@ RayShapeIntersection intersectBox(in Ray ray, in Box box) float entryT = max(max(entries.x, entries.y), entries.z); float exitT = min(min(exits.x, exits.y), exits.z); - vec3 entryPoint = ray.pos + entryT * ray.dir; - vec3 normal = getBoxNormal(entryPoint, box); + vec3 normal = getBoxNormal(box, ray, entryT); if (entryT > exitT) { return RayShapeIntersection(normal, NO_HIT, NO_HIT); From aa82d9a542230f8c030b416d5c2b2bc6e0d71930 Mon Sep 17 00:00:00 2001 From: zhouhai <850168627@qq.com> Date: Sat, 4 Feb 2023 09:18:42 +0800 Subject: [PATCH 429/679] optimize Primitive.prototype.getGeometryInstanceAttributes performance Primitive.prototype.getGeometryInstanceAttributes --- packages/engine/Source/Scene/Primitive.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index e0dc421958f..1d9da3d018b 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -314,7 +314,7 @@ function Primitive(options) { this._boundingSphereCV = []; this._boundingSphere2D = []; this._boundingSphereMorph = []; - this._perInstanceAttributeCache = []; + this._perInstanceAttributeCache = new Map(); this._instanceIds = []; this._lastPerInstanceAttributeIndex = 0; @@ -2411,6 +2411,11 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { } //>>includeEnd('debug'); + let attributes = this._perInstanceAttributeCache.get(id); + if (defined(attributes)) { + return attributes; + } + let index = -1; const lastIndex = this._lastPerInstanceAttributeIndex; const ids = this._instanceIds; @@ -2426,13 +2431,6 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { if (index === -1) { return undefined; } - - this._lastPerInstanceAttributeIndex = index; - - let attributes = this._perInstanceAttributeCache[index]; - if (defined(attributes)) { - return attributes; - } const batchTable = this._batchTable; const perInstanceAttributeIndices = this._batchTableAttributeIndices; @@ -2453,7 +2451,8 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { createPickIdProperty(this, properties, index); Object.defineProperties(attributes, properties); - this._perInstanceAttributeCache[index] = attributes; + this._lastPerInstanceAttributeIndex = index; + this._perInstanceAttributeCache.set(id, attributes); return attributes; }; From a003b21d5ca30391742b6be3e68a3e12d17fcacd Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Mon, 6 Feb 2023 09:38:59 +0800 Subject: [PATCH 430/679] use last frame pick result when zoom inertia --- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 779cea26441..56a6ec76ce3 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -301,7 +301,7 @@ function ScreenSpaceCameraController(scene) { ); // Constants, Make any of these public? - this._zoomFactor = 2.0; + this._zoomFactor = 5.0; this._rotateFactor = undefined; this._rotateRateRangeAdjustment = undefined; this._maximumRotateRate = 1.77; @@ -2162,6 +2162,7 @@ function zoom3D(controller, startPosition, movement) { if (defined(movement.distance)) { movement = movement.distance; } + const inertiaMovement = movement.inertiaEnabled; const ellipsoid = controller._ellipsoid; const scene = controller._scene; @@ -2187,7 +2188,7 @@ function zoom3D(controller, startPosition, movement) { camera.position, zoom3DCartographic ).height; - if (height < controller._minimumPickingTerrainHeight) { + if (height < controller._minimumPickingTerrainHeight && !inertiaMovement) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); } From cf97444752194a216f6a07958af7b6962074c00a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Feb 2023 10:37:38 -0500 Subject: [PATCH 431/679] voxels: remove ray shift for normals calculation --- packages/engine/Source/Shaders/Voxels/IntersectBox.glsl | 7 +++---- .../engine/Source/Shaders/Voxels/IntersectionUtils.glsl | 1 + packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 9eb28a4854a..6ad10e6c314 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -32,10 +32,9 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) vec3 getBoxNormal(in Box box, in Ray ray, in float entryT) { - vec3 entryPoint = ray.pos + entryT * ray.dir; - vec3 epsilon = vec3(entryT * 0.000001); - vec3 lower = step(entryPoint - epsilon, box.p0); - vec3 upper = step(box.p1, entryPoint + epsilon); + vec3 entryPoint = ray.pos + (entryT - RAY_SHIFT) * ray.dir; + vec3 lower = step(entryPoint, box.p0); + vec3 upper = step(box.p1, entryPoint); return normalize(upper - lower); } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 0498c358b11..fc1a996a822 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -4,6 +4,7 @@ #define NO_HIT (-czm_infinity) #define INF_HIT (czm_infinity * 0.5) +#define RAY_SHIFT (czm_epsilon4) struct Ray { vec3 pos; diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index b451995378e..e46ae16e9d9 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -64,7 +64,7 @@ void main() discard; } - float currT = entryExitT.x + 0.0001; + float currT = entryExitT.x + RAY_SHIFT; float endT = entryExitT.y; vec3 positionUv = viewPosUv + currT * viewDirUv; vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); From 9fff2746f615c2b2812d3a31c7588e6bfb438548 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 6 Feb 2023 13:05:06 -0500 Subject: [PATCH 432/679] Remove irrelevevant changes --- Apps/Sandcastle/Sandcastle-helpers.js | 8 +- .../gallery/3D Models Coloring.html | 8 +- Apps/Sandcastle/gallery/3D Models.html | 8 +- .../gallery/3D Tiles Adjust Height.html | 8 +- Apps/Sandcastle/gallery/3D Tiles BIM.html | 8 +- .../3D Tiles Batch Table Hierarchy.html | 8 +- .../gallery/3D Tiles Clipping Planes.html | 8 +- Apps/Sandcastle/gallery/3D Tiles Compare.html | 8 +- .../gallery/3D Tiles Feature Picking.html | 504 +++++++------- .../gallery/3D Tiles Feature Styling.html | 301 ++++----- Apps/Sandcastle/gallery/3D Tiles Formats.html | 8 +- .../gallery/3D Tiles Inspector.html | 50 +- .../gallery/3D Tiles Interactivity.html | 337 +++++----- .../Sandcastle/gallery/3D Tiles Interior.html | 8 +- .../gallery/3D Tiles Next CDB Yemen.html | 8 +- ...es Next Photogrammetry Classification.html | 17 +- .../gallery/3D Tiles Next S2 Globe.html | 8 +- ...D Tiles Photogrammetry Classification.html | 82 ++- .../gallery/3D Tiles Photogrammetry.html | 26 +- .../3D Tiles Point Cloud Classification.html | 146 ++-- .../gallery/3D Tiles Point Cloud Shading.html | 379 +++++------ .../gallery/3D Tiles Point Cloud Styling.html | 8 +- .../gallery/3D Tiles Point Cloud.html | 50 +- .../3D Tiles Terrain Classification.html | 94 ++- .../Sandcastle/gallery/Ambient Occlusion.html | 8 +- Apps/Sandcastle/gallery/ArcGIS MapServer.html | 8 +- .../ArcGIS Tiled Elevation Terrain.html | 24 +- Apps/Sandcastle/gallery/ArcticDEM.html | 28 +- Apps/Sandcastle/gallery/Atmosphere.html | 8 +- Apps/Sandcastle/gallery/Billboards.html | 8 +- Apps/Sandcastle/gallery/Bloom.html | 8 +- Apps/Sandcastle/gallery/Blue Marble.html | 8 +- Apps/Sandcastle/gallery/Box.html | 8 +- Apps/Sandcastle/gallery/CZML 3D Tiles.html | 8 +- .../gallery/CZML Billboard and Label.html | 8 +- Apps/Sandcastle/gallery/CZML Box.html | 8 +- .../gallery/CZML Circles and Ellipses.html | 8 +- Apps/Sandcastle/gallery/CZML Colors.html | 8 +- .../gallery/CZML Cones and Cylinders.html | 8 +- Apps/Sandcastle/gallery/CZML Corridor.html | 8 +- .../gallery/CZML Custom Properties.html | 8 +- .../CZML Model - Node Transformations.html | 8 +- .../gallery/CZML Model Articulations.html | 8 +- .../gallery/CZML Model Data URL.html | 8 +- Apps/Sandcastle/gallery/CZML Model.html | 8 +- Apps/Sandcastle/gallery/CZML Path.html | 28 +- .../gallery/CZML Point - Time Dynamic.html | 8 +- Apps/Sandcastle/gallery/CZML Point.html | 8 +- ...ML Polygon - Interpolating References.html | 8 +- ...ZML Polygon - Intervals, Availability.html | 8 +- Apps/Sandcastle/gallery/CZML Polygon.html | 8 +- .../gallery/CZML Polyline Volume.html | 8 +- Apps/Sandcastle/gallery/CZML Polyline.html | 8 +- .../gallery/CZML Position Definitions.html | 8 +- Apps/Sandcastle/gallery/CZML Rectangle.html | 8 +- .../gallery/CZML Reference Properties.html | 8 +- .../gallery/CZML Spheres and Ellipsoids.html | 8 +- Apps/Sandcastle/gallery/CZML Wall.html | 8 +- Apps/Sandcastle/gallery/CZML ZIndex.html | 8 +- Apps/Sandcastle/gallery/CZML.html | 8 +- .../Sandcastle/gallery/Callback Property.html | 8 +- Apps/Sandcastle/gallery/Camera Tutorial.html | 8 +- Apps/Sandcastle/gallery/Camera.html | 8 +- Apps/Sandcastle/gallery/Cardboard.html | 268 ++++---- .../gallery/Cartographic Limit Rectangle.html | 104 ++- Apps/Sandcastle/gallery/Cesium Inspector.html | 138 ++-- .../gallery/Cesium OSM Buildings.html | 32 +- Apps/Sandcastle/gallery/Cesium Widget.html | 8 +- .../gallery/Cesium World Terrain.html | 20 +- .../gallery/Circles and Ellipses.html | 8 +- .../Sandcastle/gallery/Clamp to 3D Model.html | 8 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 100 ++- Apps/Sandcastle/gallery/Clamp to Terrain.html | 20 +- .../gallery/Classification Types.html | 20 +- Apps/Sandcastle/gallery/Classification.html | 559 ++++++++-------- Apps/Sandcastle/gallery/Clock.html | 8 +- Apps/Sandcastle/gallery/Cloud Parameters.html | 8 +- Apps/Sandcastle/gallery/Clouds.html | 414 ++++++------ Apps/Sandcastle/gallery/Clustering.html | 8 +- Apps/Sandcastle/gallery/Corridor.html | 8 +- .../Sandcastle/gallery/Custom DataSource.html | 8 +- Apps/Sandcastle/gallery/Custom Geocoder.html | 8 +- .../Custom Per-Feature Post Process.html | 8 +- .../gallery/Custom Post Process.html | 8 +- .../gallery/Custom Shaders 3D Tiles.html | 8 +- .../gallery/Custom Shaders Models.html | 8 +- .../Custom Shaders Property Textures.html | 21 +- .../gallery/Cylinders and Cones.html | 8 +- .../gallery/DataSource Ordering.html | 8 +- Apps/Sandcastle/gallery/Depth of Field.html | 8 +- .../gallery/Distance Display Conditions.html | 8 +- .../gallery/Drawing on Terrain.html | 17 +- Apps/Sandcastle/gallery/Earth at Night.html | 8 +- .../gallery/Elevation Band Material.html | 375 ++++++----- Apps/Sandcastle/gallery/Export KML.html | 8 +- Apps/Sandcastle/gallery/FXAA.html | 60 +- Apps/Sandcastle/gallery/Fog Post Process.html | 8 +- Apps/Sandcastle/gallery/GPX.html | 20 +- .../gallery/GeoJSON and TopoJSON.html | 8 +- .../gallery/GeoJSON simplestyle.html | 8 +- .../gallery/Geometry Height Reference.html | 17 +- .../gallery/Geometry and Appearances.html | 8 +- Apps/Sandcastle/gallery/Globe Interior.html | 8 +- Apps/Sandcastle/gallery/Globe Materials.html | 24 +- .../gallery/Globe Translucency.html | 414 ++++++------ .../gallery/Google Earth Enterprise.html | 57 +- Apps/Sandcastle/gallery/HTML Overlays.html | 8 +- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 8 +- Apps/Sandcastle/gallery/Hello World.html | 8 +- .../gallery/High Dynamic Range.html | 108 ++- .../gallery/I3S 3D Object Layer.html | 209 +++--- .../gallery/I3S Feature Picking.html | 209 +++--- .../gallery/I3S IntegratedMesh Layer.html | 94 ++- .../gallery/Image-Based Lighting.html | 8 +- .../gallery/Imagery Adjustment.html | 8 +- .../gallery/Imagery Color To Alpha.html | 8 +- Apps/Sandcastle/gallery/Imagery Cutout.html | 8 +- .../gallery/Imagery Layers Manipulation.html | 8 +- .../gallery/Imagery Layers Split.html | 8 +- .../Imagery Layers Texture Filters.html | 8 +- Apps/Sandcastle/gallery/Imagery Layers.html | 8 +- Apps/Sandcastle/gallery/Interpolation.html | 17 +- Apps/Sandcastle/gallery/KML Tours.html | 8 +- Apps/Sandcastle/gallery/KML.html | 8 +- Apps/Sandcastle/gallery/Labels.html | 8 +- Apps/Sandcastle/gallery/LensFlare.html | 8 +- Apps/Sandcastle/gallery/Lighting.html | 26 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 8 +- Apps/Sandcastle/gallery/MSAA.html | 17 +- .../Manually Controlled Animation.html | 8 +- Apps/Sandcastle/gallery/Map Pins.html | 8 +- Apps/Sandcastle/gallery/Materials.html | 8 +- .../gallery/Montreal Point Cloud.html | 20 +- Apps/Sandcastle/gallery/Multi-part CZML.html | 8 +- .../gallery/Multiple Synced Views.html | 8 +- Apps/Sandcastle/gallery/Natural Earth II.html | 8 +- Apps/Sandcastle/gallery/Offline.html | 8 +- Apps/Sandcastle/gallery/PAMAP Terrain.html | 28 +- .../gallery/Parallels and Meridians.html | 8 +- .../gallery/Partial Ellipsoids.html | 8 +- .../gallery/Particle System Fireworks.html | 8 +- .../gallery/Particle System Tails.html | 8 +- .../gallery/Particle System Weather.html | 17 +- Apps/Sandcastle/gallery/Particle System.html | 8 +- .../gallery/Per-Feature Post Processing.html | 8 +- .../gallery/Physically-Based Materials.html | 17 +- Apps/Sandcastle/gallery/Picking.html | 8 +- Apps/Sandcastle/gallery/Plane.html | 8 +- Apps/Sandcastle/gallery/Points.html | 8 +- Apps/Sandcastle/gallery/Polygon.html | 8 +- Apps/Sandcastle/gallery/Polyline Dash.html | 8 +- Apps/Sandcastle/gallery/Polyline Volume.html | 8 +- Apps/Sandcastle/gallery/Polyline.html | 8 +- .../gallery/Polylines on 3D Tiles.html | 8 +- Apps/Sandcastle/gallery/Post Processing.html | 8 +- .../gallery/Procedural Terrain.html | 8 +- Apps/Sandcastle/gallery/Projection.html | 8 +- Apps/Sandcastle/gallery/Rectangle.html | 8 +- .../gallery/Resolution Scaling.html | 8 +- Apps/Sandcastle/gallery/Rotatable 2D Map.html | 8 +- .../gallery/Sample Height from 3D Tiles.html | 20 +- .../gallery/Scene Rendering Performance.html | 17 +- Apps/Sandcastle/gallery/Sentinel-2.html | 8 +- Apps/Sandcastle/gallery/Shadows.html | 17 +- .../gallery/Show or Hide Entities.html | 8 +- .../gallery/Spheres and Ellipsoids.html | 8 +- Apps/Sandcastle/gallery/Star Burst.html | 8 +- .../gallery/Terrain Clipping Planes.html | 633 +++++++++--------- .../gallery/Terrain Exaggeration.html | 20 +- Apps/Sandcastle/gallery/Terrain.html | 26 +- .../gallery/Time Dynamic Point Cloud.html | 8 +- .../gallery/Time Dynamic Wheels.html | 8 +- .../Sandcastle/gallery/Underground Color.html | 8 +- Apps/Sandcastle/gallery/Video.html | 8 +- Apps/Sandcastle/gallery/Wall.html | 8 +- .../gallery/Washington DC 2017.html | 8 +- .../gallery/Web Map Service (WMS).html | 8 +- .../Web Map Tile Service with Time.html | 8 +- .../gallery/Z-Indexing Geometry.html | 8 +- .../development/3D Models Articulations.html | 8 +- .../development/3D Models Node Explorer.html | 8 +- .../gallery/development/3D Models.html | 8 +- .../3D Tiles Performance Testing.html | 8 +- .../gallery/development/3D Tiles Split.html | 8 +- .../development/BillboardClampToGround.html | 20 +- .../development/Billboards Instancing.html | 20 +- .../gallery/development/Billboards.html | 8 +- .../gallery/development/Box Outline.html | 8 +- Apps/Sandcastle/gallery/development/Box.html | 8 +- .../gallery/development/Circle Outline.html | 8 +- .../gallery/development/Circle.html | 8 +- .../development/Coplanar Polygon Outline.html | 8 +- .../gallery/development/Coplanar Polygon.html | 8 +- .../gallery/development/Corridor Outline.html | 8 +- .../gallery/development/Corridor.html | 8 +- .../gallery/development/Custom Primitive.html | 8 +- .../gallery/development/Cylinder Outline.html | 8 +- .../gallery/development/Cylinder.html | 8 +- .../development/Display Conditions.html | 8 +- .../gallery/development/Ellipse Outline.html | 8 +- .../gallery/development/Ellipse.html | 8 +- .../development/Ellipsoid Outline.html | 8 +- .../development/Ellipsoid Surface.html | 8 +- .../gallery/development/Ellipsoid.html | 8 +- Apps/Sandcastle/gallery/development/Fog.html | 20 +- .../gallery/development/Frustum.html | 8 +- ...fset Attribute box cylinder ellipsoid.html | 8 +- .../Geometry Offset Attribute.html | 8 +- .../development/Geometry and Appearances.html | 8 +- .../development/Ground Polyline Material.html | 158 +++-- .../Ground Primitive Materials.html | 26 +- .../gallery/development/Ground Primitive.html | 20 +- .../gallery/development/Labels.html | 8 +- .../development/Many Clipping Planes.html | 464 +++++++------ .../gallery/development/Material.html | 8 +- .../gallery/development/Multiple Shadows.html | 17 +- .../development/Per Instance Color.html | 8 +- .../gallery/development/Pick From Ray.html | 8 +- .../gallery/development/Picking.html | 8 +- .../gallery/development/PointPrimitives.html | 8 +- .../gallery/development/Polygon Outline.html | 8 +- .../Polygon Texture Coordinates.html | 8 +- .../gallery/development/Polygon.html | 8 +- .../gallery/development/Polyline Color.html | 8 +- .../development/Polyline Material.html | 8 +- .../development/Polyline Volume Outline.html | 8 +- .../gallery/development/Polyline Volume.html | 8 +- .../gallery/development/Polyline.html | 8 +- .../development/Polylines On Terrain.html | 26 +- .../gallery/development/Polylines.html | 8 +- .../development/Rectangle Outline.html | 8 +- .../gallery/development/Rectangle.html | 8 +- .../gallery/development/Shadows.html | 8 +- .../gallery/development/Simple Polyline.html | 8 +- .../gallery/development/Sphere Outline.html | 8 +- .../gallery/development/Sphere.html | 8 +- .../development/Terrain Entity Batching.html | 286 ++++---- .../development/Terrain Performance.html | 20 +- .../gallery/development/Terrain Tweaks.html | 8 +- .../gallery/development/Volumes.html | 8 +- .../gallery/development/Voxels.html | 8 +- .../gallery/development/Wall Outline.html | 8 +- Apps/Sandcastle/gallery/development/Wall.html | 8 +- Apps/Sandcastle/load-cesium-es6.js | 6 +- 244 files changed, 4067 insertions(+), 4713 deletions(-) diff --git a/Apps/Sandcastle/Sandcastle-helpers.js b/Apps/Sandcastle/Sandcastle-helpers.js index 18196646744..0323fbaf286 100644 --- a/Apps/Sandcastle/Sandcastle-helpers.js +++ b/Apps/Sandcastle/Sandcastle-helpers.js @@ -4,7 +4,7 @@ window.embedInSandcastleTemplate = function (code, addExtraLine) { return ( `${ - "window.startup = async function (Cesium) {\n" + + "window.startup = function (Cesium) {\n" + " 'use strict';\n" + "//Sandcastle_Begin\n" }${addExtraLine ? "\n" : ""}${code}//Sandcastle_End\n` + @@ -12,11 +12,7 @@ `};\n` + `if (typeof Cesium !== 'undefined') {\n` + ` window.startupCalled = true;\n` + - ` try {\n` + - ` window.startup(Cesium);\n` + - ` } catch (error) {\n` + - ` console.error(error);\n` + - ` }\n` + + ` window.startup(Cesium);\n` + `}\n` ); }; diff --git a/Apps/Sandcastle/gallery/3D Models Coloring.html b/Apps/Sandcastle/gallery/3D Models Coloring.html index f2a5fc94d79..8cd0e510ee4 100644 --- a/Apps/Sandcastle/gallery/3D Models Coloring.html +++ b/Apps/Sandcastle/gallery/3D Models Coloring.html @@ -133,7 +133,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -326,11 +326,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Models.html b/Apps/Sandcastle/gallery/3D Models.html index 579834c1e19..67e632f6dd6 100644 --- a/Apps/Sandcastle/gallery/3D Models.html +++ b/Apps/Sandcastle/gallery/3D Models.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -173,11 +173,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html index 74ab58f2483..6b70acb401c 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html +++ b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html @@ -53,7 +53,7 @@ <input type="text" size="5" data-bind="value: height" /> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -125,11 +125,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles BIM.html b/Apps/Sandcastle/gallery/3D Tiles BIM.html index f0355936169..1060beb35bf 100644 --- a/Apps/Sandcastle/gallery/3D Tiles BIM.html +++ b/Apps/Sandcastle/gallery/3D Tiles BIM.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -221,11 +221,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html index e5fd0b06118..c5ecda6317b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -216,11 +216,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index 574423894d3..192ea241f8f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -62,7 +62,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Add a clipping plane, a plane geometry to show the representation of the @@ -347,11 +347,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Compare.html b/Apps/Sandcastle/gallery/3D Tiles Compare.html index eaabf87c978..ce4070b6ec0 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Compare.html +++ b/Apps/Sandcastle/gallery/3D Tiles Compare.html @@ -49,7 +49,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -110,11 +110,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index aa1c5cd304a..259ee31640c 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -30,288 +30,286 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // A simple demo of 3D Tiles feature picking with hover and select behavior - // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + // A simple demo of 3D Tiles feature picking with hover and select behavior + // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); - - // Load the NYC buildings tileset - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - viewer.scene.primitives.add(tileset); - - // HTML overlay for showing feature name on mouseover - const nameOverlay = document.createElement("div"); - viewer.container.appendChild(nameOverlay); - nameOverlay.className = "backdrop"; - nameOverlay.style.display = "none"; - nameOverlay.style.position = "absolute"; - nameOverlay.style.bottom = "0"; - nameOverlay.style.left = "0"; - nameOverlay.style["pointer-events"] = "none"; - nameOverlay.style.padding = "4px"; - nameOverlay.style.backgroundColor = "black"; - - // Information about the currently selected feature - const selected = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); + // Load the NYC buildings tileset + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + viewer.scene.primitives.add(tileset); - // Get default left click handler for when a feature is not picked on left click - const clickHandler = viewer.screenSpaceEventHandler.getInputAction( - Cesium.ScreenSpaceEventType.LEFT_CLICK - ); + // HTML overlay for showing feature name on mouseover + const nameOverlay = document.createElement("div"); + viewer.container.appendChild(nameOverlay); + nameOverlay.className = "backdrop"; + nameOverlay.style.display = "none"; + nameOverlay.style.position = "absolute"; + nameOverlay.style.bottom = "0"; + nameOverlay.style.left = "0"; + nameOverlay.style["pointer-events"] = "none"; + nameOverlay.style.padding = "4px"; + nameOverlay.style.backgroundColor = "black"; - // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. - // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. - if ( - Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) - ) { - // Silhouettes are supported - const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteBlue.uniforms.color = Cesium.Color.BLUE; - silhouetteBlue.uniforms.length = 0.01; - silhouetteBlue.selected = []; + // Information about the currently selected feature + const selected = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); - silhouetteGreen.uniforms.color = Cesium.Color.LIME; - silhouetteGreen.uniforms.length = 0.01; - silhouetteGreen.selected = []; + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); - viewer.scene.postProcessStages.add( - Cesium.PostProcessStageLibrary.createSilhouetteStage([ - silhouetteBlue, - silhouetteGreen, - ]) + // Get default left click handler for when a feature is not picked on left click + const clickHandler = viewer.screenSpaceEventHandler.getInputAction( + Cesium.ScreenSpaceEventType.LEFT_CLICK ); - // Silhouette a feature blue on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement + // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. + // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. + if ( + Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene) ) { - // If a feature was previously highlighted, undo the highlight + // Silhouettes are supported + const silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteBlue.uniforms.color = Cesium.Color.BLUE; + silhouetteBlue.uniforms.length = 0.01; silhouetteBlue.selected = []; - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } + const silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage(); + silhouetteGreen.uniforms.color = Cesium.Color.LIME; + silhouetteGreen.uniforms.length = 0.01; + silhouetteGreen.selected = []; - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const name = pickedFeature.getProperty("BIN"); - nameOverlay.textContent = name; + viewer.scene.postProcessStages.add( + Cesium.PostProcessStageLibrary.createSilhouetteStage([ + silhouetteBlue, + silhouetteGreen, + ]) + ); - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - silhouetteBlue.selected = [pickedFeature]; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Silhouette a feature blue on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + silhouetteBlue.selected = []; - // Silhouette a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - silhouetteGreen.selected = []; + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + const name = pickedFeature.getProperty("BIN"); + nameOverlay.textContent = name; - // Select the feature if it's not already selected - if (silhouetteGreen.selected[0] === pickedFeature) { - return; - } + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + silhouetteBlue.selected = [pickedFeature]; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); - // Save the selected feature's original color - const highlightedFeature = silhouetteBlue.selected[0]; - if (pickedFeature === highlightedFeature) { - silhouetteBlue.selected = []; - } + // Silhouette a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + silhouetteGreen.selected = []; - // Highlight newly selected feature - silhouetteGreen.selected = [pickedFeature]; + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } else { - // Silhouettes are not supported. Instead, change the feature color. + // Select the feature if it's not already selected + if (silhouetteGreen.selected[0] === pickedFeature) { + return; + } - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Save the selected feature's original color + const highlightedFeature = silhouetteBlue.selected[0]; + if (pickedFeature === highlightedFeature) { + silhouetteBlue.selected = []; + } - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; - return; - } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - let name = pickedFeature.getProperty("name"); - if (!Cesium.defined(name)) { - name = pickedFeature.getProperty("id"); - } - nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. - if (pickedFeature !== selected.feature) { - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - } - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); + // Highlight newly selected feature + silhouetteGreen.selected = [pickedFeature]; - // Color a feature on selection and show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // If a feature was previously selected, undo the highlight - if (Cesium.defined(selected.feature)) { - selected.feature.color = selected.originalColor; - selected.feature = undefined; - } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - clickHandler(movement); - return; - } - // Select the feature if it's not already selected - if (selected.feature === pickedFeature) { - return; - } - selected.feature = pickedFeature; - // Save the selected feature's original color - if (pickedFeature === highlighted.feature) { - Cesium.Color.clone( - highlighted.originalColor, - selected.originalColor - ); - highlighted.feature = undefined; - } else { - Cesium.Color.clone(pickedFeature.color, selected.originalColor); - } - // Highlight newly selected feature - pickedFeature.color = Cesium.Color.LIME; - // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; - viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `<tr><th>Longitude</th><td>${pickedFeature.getProperty( - "longitude" - )}</td></tr>` + - `<tr><th>Latitude</th><td>${pickedFeature.getProperty( - "latitude" - )}</td></tr>` + - `<tr><th>Height</th><td>${pickedFeature.getProperty( - "height" - )}</td></tr>` + - `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( - "TerrainHeight" - )}</td></tr>` + - `</tbody></table>`; - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); - } //Sandcastle_End + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } else { + // Silhouettes are not supported. Instead, change the feature color. + + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; + + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show it's overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - movement.endPosition.y + }px`; + nameOverlay.style.left = `${movement.endPosition.x}px`; + let name = pickedFeature.getProperty("name"); + if (!Cesium.defined(name)) { + name = pickedFeature.getProperty("id"); + } + nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. + if (pickedFeature !== selected.feature) { + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + } + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); + + // Color a feature on selection and show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // If a feature was previously selected, undo the highlight + if (Cesium.defined(selected.feature)) { + selected.feature.color = selected.originalColor; + selected.feature = undefined; + } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + clickHandler(movement); + return; + } + // Select the feature if it's not already selected + if (selected.feature === pickedFeature) { + return; + } + selected.feature = pickedFeature; + // Save the selected feature's original color + if (pickedFeature === highlighted.feature) { + Cesium.Color.clone( + highlighted.originalColor, + selected.originalColor + ); + highlighted.feature = undefined; + } else { + Cesium.Color.clone(pickedFeature.color, selected.originalColor); + } + // Highlight newly selected feature + pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description + const featureName = pickedFeature.getProperty("name"); + selectedEntity.name = featureName; + selectedEntity.description = + 'Loading <div class="cesium-infoBox-loading"></div>'; + viewer.selectedEntity = selectedEntity; + selectedEntity.description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `<tr><th>Longitude</th><td>${pickedFeature.getProperty( + "longitude" + )}</td></tr>` + + `<tr><th>Latitude</th><td>${pickedFeature.getProperty( + "latitude" + )}</td></tr>` + + `<tr><th>Height</th><td>${pickedFeature.getProperty( + "height" + )}</td></tr>` + + `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( + "TerrainHeight" + )}</td></tr>` + + `</tbody></table>`; + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index 9ce7e057456..53f338f2103 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -50,171 +50,174 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // How to use the 3D Tiles Styling language to style individual features, like buildings. - // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); - - // Add Cesium OSM buildings to the scene as our example 3D Tileset. - const osmBuildingsTileset = Cesium.createOsmBuildings(); - viewer.scene.primitives.add(osmBuildingsTileset); - - // Set the initial camera to look at Seattle - viewer.scene.camera.setView({ - destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), - orientation: { - heading: Cesium.Math.toRadians(10), - pitch: Cesium.Math.toRadians(-10), - }, - }); - - // Styling functions - - // Color by material checks for null values since not all - // buildings have the material property. - function colorByMaterial() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - material: "${feature['building:material']}", - }, - color: { - conditions: [ - ["${material} === null", "color('white')"], - ["${material} === 'glass'", "color('skyblue', 0.5)"], - ["${material} === 'concrete'", "color('grey')"], - ["${material} === 'brick'", "color('indianred')"], - ["${material} === 'stone'", "color('lightslategrey')"], - ["${material} === 'metal'", "color('lightgrey')"], - ["${material} === 'steel'", "color('lightsteelblue')"], - ["true", "color('white')"], // This is the else case - ], - }, + (async () => { + // How to use the 3D Tiles Styling language to style individual features, like buildings. + // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), }); - } - - function highlightAllResidentialBuildings() { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - [ - "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", - "color('cyan', 0.9)", - ], - [true, "color('white')"], - ], + const handler = new Cesium.ScreenSpaceEventHandler( + viewer.scene.canvas + ); + + // Add Cesium OSM buildings to the scene as our example 3D Tileset. + const osmBuildingsTileset = Cesium.createOsmBuildings(); + viewer.scene.primitives.add(osmBuildingsTileset); + + // Set the initial camera to look at Seattle + viewer.scene.camera.setView({ + destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370), + orientation: { + heading: Cesium.Math.toRadians(10), + pitch: Cesium.Math.toRadians(-10), }, }); - } - - function showByBuildingType(buildingType) { - switch (buildingType) { - case "office": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'office'", - }); - break; - case "apartments": - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - show: "${feature['building']} === 'apartments'", - }); - break; - default: - break; + + // Styling functions + + // Color by material checks for null values since not all + // buildings have the material property. + function colorByMaterial() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + material: "${feature['building:material']}", + }, + color: { + conditions: [ + ["${material} === null", "color('white')"], + ["${material} === 'glass'", "color('skyblue', 0.5)"], + ["${material} === 'concrete'", "color('grey')"], + ["${material} === 'brick'", "color('indianred')"], + ["${material} === 'stone'", "color('lightslategrey')"], + ["${material} === 'metal'", "color('lightgrey')"], + ["${material} === 'steel'", "color('lightsteelblue')"], + ["true", "color('white')"], // This is the else case + ], + }, + }); } - } - // Color the buildings based on their distance from a selected central location - function colorByDistanceToCoordinate(pickedLatitude, pickedLongitude) { - osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ - defines: { - distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, - }, - color: { - conditions: [ - ["${distance} > 0.014", "color('blue')"], - ["${distance} > 0.010", "color('green')"], - ["${distance} > 0.006", "color('yellow')"], - ["${distance} > 0.0001", "color('red')"], - ["true", "color('white')"], - ], - }, - }); - } + function highlightAllResidentialBuildings() { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + [ + "${feature['building']} === 'apartments' || ${feature['building']} === 'residential'", + "color('cyan', 0.9)", + ], + [true, "color('white')"], + ], + }, + }); + } - // When dropdown option is not "Color By Distance To Selected Location", - // remove the left click input event for selecting a central location - function removeCoordinatePickingOnLeftClick() { - document.querySelector(".infoPanel").style.visibility = "hidden"; - handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); - } + function showByBuildingType(buildingType) { + switch (buildingType) { + case "office": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'office'", + }); + break; + case "apartments": + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + show: "${feature['building']} === 'apartments'", + }); + break; + default: + break; + } + } - // Add event listeners to dropdown menu options - document.querySelector(".infoPanel").style.visibility = "hidden"; - const menu = document.getElementById("dropdown"); + // Color the buildings based on their distance from a selected central location + function colorByDistanceToCoordinate( + pickedLatitude, + pickedLongitude + ) { + osmBuildingsTileset.style = new Cesium.Cesium3DTileStyle({ + defines: { + distance: `distance(vec2(\${feature['cesium#longitude']}, \${feature['cesium#latitude']}), vec2(${pickedLongitude},${pickedLatitude}))`, + }, + color: { + conditions: [ + ["${distance} > 0.014", "color('blue')"], + ["${distance} > 0.010", "color('green')"], + ["${distance} > 0.006", "color('yellow')"], + ["${distance} > 0.0001", "color('red')"], + ["true", "color('white')"], + ], + }, + }); + } - menu.options[0].onselect = function () { - removeCoordinatePickingOnLeftClick(); - colorByMaterial(); - }; - - menu.options[1].onselect = function () { - // Default to Space Needle as the central location - colorByDistanceToCoordinate(47.62051, -122.34931); - document.querySelector(".infoPanel").style.visibility = "visible"; - // Add left click input to select a building to and extract its coordinates - handler.setInputAction(function (movement) { - viewer.selectedEntity = undefined; - const pickedBuilding = viewer.scene.pick(movement.position); - if (pickedBuilding) { - const pickedLatitude = pickedBuilding.getProperty( - "cesium#latitude" - ); - const pickedLongitude = pickedBuilding.getProperty( - "cesium#longitude" - ); - colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); - } - }, Cesium.ScreenSpaceEventType.LEFT_CLICK); - }; - - menu.options[2].onselect = function () { - removeCoordinatePickingOnLeftClick(); - highlightAllResidentialBuildings(); - }; - - menu.options[3].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("office"); - }; - - menu.options[4].onselect = function () { - removeCoordinatePickingOnLeftClick(); - showByBuildingType("apartments"); - }; - - menu.onchange = function () { - Sandcastle.reset(); - const item = menu.options[menu.selectedIndex]; - if (item && typeof item.onselect === "function") { - item.onselect(); + // When dropdown option is not "Color By Distance To Selected Location", + // remove the left click input event for selecting a central location + function removeCoordinatePickingOnLeftClick() { + document.querySelector(".infoPanel").style.visibility = "hidden"; + handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); } - }; - colorByMaterial(); //Sandcastle_End + // Add event listeners to dropdown menu options + document.querySelector(".infoPanel").style.visibility = "hidden"; + const menu = document.getElementById("dropdown"); + + menu.options[0].onselect = function () { + removeCoordinatePickingOnLeftClick(); + colorByMaterial(); + }; + + menu.options[1].onselect = function () { + // Default to Space Needle as the central location + colorByDistanceToCoordinate(47.62051, -122.34931); + document.querySelector(".infoPanel").style.visibility = "visible"; + // Add left click input to select a building to and extract its coordinates + handler.setInputAction(function (movement) { + viewer.selectedEntity = undefined; + const pickedBuilding = viewer.scene.pick(movement.position); + if (pickedBuilding) { + const pickedLatitude = pickedBuilding.getProperty( + "cesium#latitude" + ); + const pickedLongitude = pickedBuilding.getProperty( + "cesium#longitude" + ); + colorByDistanceToCoordinate(pickedLatitude, pickedLongitude); + } + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + }; + + menu.options[2].onselect = function () { + removeCoordinatePickingOnLeftClick(); + highlightAllResidentialBuildings(); + }; + + menu.options[3].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("office"); + }; + + menu.options[4].onselect = function () { + removeCoordinatePickingOnLeftClick(); + showByBuildingType("apartments"); + }; + + menu.onchange = function () { + Sandcastle.reset(); + const item = menu.options[menu.selectedIndex]; + if (item && typeof item.onselect === "function") { + item.onselect(); + } + }; + + colorByMaterial(); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Formats.html b/Apps/Sandcastle/gallery/3D Tiles Formats.html index 8ff139e995d..04c5b08da1f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Formats.html +++ b/Apps/Sandcastle/gallery/3D Tiles Formats.html @@ -38,7 +38,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -222,11 +222,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index d07f605b952..7063dc45545 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -33,44 +33,42 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.scene.globe.depthTestAgainstTerrain = true; - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - enableDebugWireframe: true, - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + enableDebugWireframe: true, + }); + viewer.scene.primitives.add(tileset); - await tileset.readyPromise; + await tileset.readyPromise; - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - tileset.boundingSphere.radius / 4.0 - ) - ); //Sandcastle_End + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + tileset.boundingSphere.radius / 4.0 + ) + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index c5fdd242ec0..2ebba29bffa 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -71,204 +71,213 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - if (!scene.pickPositionSupported) { - window.alert("This browser does not support pickPosition."); - } + const scene = viewer.scene; + if (!scene.pickPositionSupported) { + window.alert("This browser does not support pickPosition."); + } - scene.globe.depthTestAgainstTerrain = true; + scene.globe.depthTestAgainstTerrain = true; - const viewModel = { - rightClickAction: "annotate", - middleClickAction: "hide", - }; + const viewModel = { + rightClickAction: "annotate", + middleClickAction: "hide", + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - const annotations = scene.primitives.add(new Cesium.LabelCollection()); + const annotations = scene.primitives.add( + new Cesium.LabelCollection() + ); - // Set the initial camera view to look at Manhattan - const initialPosition = Cesium.Cartesian3.fromDegrees( - -74.01881302800248, - 40.69114333714821, - 753 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 21.27879878293835, - -21.34390550872461, - 0.0716951918898415 - ); - scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + // Set the initial camera view to look at Manhattan + const initialPosition = Cesium.Cartesian3.fromDegrees( + -74.01881302800248, + 40.69114333714821, + 753 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 21.27879878293835, + -21.34390550872461, + 0.0716951918898415 + ); + scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Load the NYC buildings tileset. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - meta: { - description: "'Building ${BIN} has height ${Height}.'", - }, - }); + // Load the NYC buildings tileset. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }); + scene.primitives.add(tileset); + tileset.style = new Cesium.Cesium3DTileStyle({ + meta: { + description: "'Building ${BIN} has height ${Height}.'", + }, + }); - const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); + const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.rightClickAction; - if (action === "annotate") { - annotate(movement, feature); - } else if (action === "properties") { - printProperties(movement, feature); - } else if (action === "zoom") { - zoom(movement, feature); - } - }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); + const action = viewModel.rightClickAction; + if (action === "annotate") { + annotate(movement, feature); + } else if (action === "properties") { + printProperties(movement, feature); + } else if (action === "zoom") { + zoom(movement, feature); + } + }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); - handler.setInputAction(function (movement) { - const feature = scene.pick(movement.position); - if (!Cesium.defined(feature)) { - return; - } + handler.setInputAction(function (movement) { + const feature = scene.pick(movement.position); + if (!Cesium.defined(feature)) { + return; + } - const action = viewModel.middleClickAction; - if (action === "hide") { - feature.show = false; - } - }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); + const action = viewModel.middleClickAction; + if (action === "hide") { + feature.show = false; + } + }, Cesium.ScreenSpaceEventType.MIDDLE_CLICK); - function annotate(movement, feature) { - if (scene.pickPositionSupported) { - const cartesian = scene.pickPosition(movement.position); - if (Cesium.defined(cartesian)) { - const cartographic = Cesium.Cartographic.fromCartesian(cartesian); - const height = `${cartographic.height.toFixed(2)} m`; + function annotate(movement, feature) { + if (scene.pickPositionSupported) { + const cartesian = scene.pickPosition(movement.position); + if (Cesium.defined(cartesian)) { + const cartographic = Cesium.Cartographic.fromCartesian( + cartesian + ); + const height = `${cartographic.height.toFixed(2)} m`; - annotations.add({ - position: cartesian, - text: height, - showBackground: true, - font: "14px monospace", - horizontalOrigin: Cesium.HorizontalOrigin.LEFT, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - disableDepthTestDistance: Number.POSITIVE_INFINITY, - }); + annotations.add({ + position: cartesian, + text: height, + showBackground: true, + font: "14px monospace", + horizontalOrigin: Cesium.HorizontalOrigin.LEFT, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + disableDepthTestDistance: Number.POSITIVE_INFINITY, + }); + } } } - } - function printProperties(movement, feature) { - console.log("Properties:"); - const propertyIds = feature.getPropertyIds(); - const length = propertyIds.length; - for (let i = 0; i < length; ++i) { - const propertyId = propertyIds[i]; - console.log(` ${propertyId}: ${feature.getProperty(propertyId)}`); + function printProperties(movement, feature) { + console.log("Properties:"); + const propertyIds = feature.getPropertyIds(); + const length = propertyIds.length; + for (let i = 0; i < length; ++i) { + const propertyId = propertyIds[i]; + console.log( + ` ${propertyId}: ${feature.getProperty(propertyId)}` + ); + } + + // Evaluate feature description + console.log( + `Description : ${tileset.style.meta.description.evaluate( + feature + )}` + ); } - // Evaluate feature description - console.log( - `Description : ${tileset.style.meta.description.evaluate(feature)}` - ); - } + function zoom(movement, feature) { + const longitude = Cesium.Math.toRadians( + feature.getProperty("Longitude") + ); + const latitude = Cesium.Math.toRadians( + feature.getProperty("Latitude") + ); + const height = feature.getProperty("Height"); - function zoom(movement, feature) { - const longitude = Cesium.Math.toRadians( - feature.getProperty("Longitude") - ); - const latitude = Cesium.Math.toRadians( - feature.getProperty("Latitude") - ); - const height = feature.getProperty("Height"); + const positionCartographic = new Cesium.Cartographic( + longitude, + latitude, + height * 0.5 + ); + const position = scene.globe.ellipsoid.cartographicToCartesian( + positionCartographic + ); - const positionCartographic = new Cesium.Cartographic( - longitude, - latitude, - height * 0.5 - ); - const position = scene.globe.ellipsoid.cartographicToCartesian( - positionCartographic - ); + const camera = scene.camera; + const heading = camera.heading; + const pitch = camera.pitch; - const camera = scene.camera; - const heading = camera.heading; - const pitch = camera.pitch; - - const offset = offsetFromHeadingPitchRange( - heading, - pitch, - height * 2.0 - ); + const offset = offsetFromHeadingPitchRange( + heading, + pitch, + height * 2.0 + ); - const transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - Cesium.Matrix4.multiplyByPoint(transform, offset, position); + const transform = Cesium.Transforms.eastNorthUpToFixedFrame( + position + ); + Cesium.Matrix4.multiplyByPoint(transform, offset, position); - camera.flyTo({ - destination: position, - orientation: { - heading: heading, - pitch: pitch, - }, - easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, - }); - } + camera.flyTo({ + destination: position, + orientation: { + heading: heading, + pitch: pitch, + }, + easingFunction: Cesium.EasingFunction.QUADRATIC_OUT, + }); + } - function offsetFromHeadingPitchRange(heading, pitch, range) { - pitch = Cesium.Math.clamp( - pitch, - -Cesium.Math.PI_OVER_TWO, - Cesium.Math.PI_OVER_TWO - ); - heading = Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; + function offsetFromHeadingPitchRange(heading, pitch, range) { + pitch = Cesium.Math.clamp( + pitch, + -Cesium.Math.PI_OVER_TWO, + Cesium.Math.PI_OVER_TWO + ); + heading = + Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO; - const pitchQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Y, - -pitch - ); - const headingQuat = Cesium.Quaternion.fromAxisAngle( - Cesium.Cartesian3.UNIT_Z, - -heading - ); - const rotQuat = Cesium.Quaternion.multiply( - headingQuat, - pitchQuat, - headingQuat - ); - const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); + const pitchQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Y, + -pitch + ); + const headingQuat = Cesium.Quaternion.fromAxisAngle( + Cesium.Cartesian3.UNIT_Z, + -heading + ); + const rotQuat = Cesium.Quaternion.multiply( + headingQuat, + pitchQuat, + headingQuat + ); + const rotMatrix = Cesium.Matrix3.fromQuaternion(rotQuat); - const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); - Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); - Cesium.Cartesian3.negate(offset, offset); - Cesium.Cartesian3.multiplyByScalar(offset, range, offset); - return offset; - } //Sandcastle_End + const offset = Cesium.Cartesian3.clone(Cesium.Cartesian3.UNIT_X); + Cesium.Matrix3.multiplyByVector(rotMatrix, offset, offset); + Cesium.Cartesian3.negate(offset, offset); + Cesium.Cartesian3.multiplyByScalar(offset, range, offset); + return offset; + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interior.html b/Apps/Sandcastle/gallery/3D Tiles Interior.html index 2a95807f28b..55689cb4697 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interior.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interior.html @@ -33,7 +33,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // San Miguel model created by Guillermo M. Leal Llaguno. Cleaned up and hosted by Morgan McGuire: http://graphics.cs.williams.edu/data/meshes.xml @@ -64,11 +64,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index 0308a4d5949..97a59a9aadc 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -453,11 +453,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 6ed0f78f7c8..6ad48f0367a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -32,16 +32,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // San Francisco Ferry Building photogrammetry model provided by Aerometrex const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, orderIndependentTranslucency: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2021-11-09T20:27:37.016064475348684937Z" ); @@ -356,11 +363,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html index 2b995547174..26091096f6a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html @@ -41,7 +41,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -232,11 +232,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 233b9d36d80..06ac7065e20 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -33,58 +33,56 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // An example of using a b3dm tileset to classify another b3dm tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + // An example of using a b3dm tileset to classify another b3dm tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - // A normal b3dm tileset containing photogrammetry - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + // A normal b3dm tileset containing photogrammetry + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); - const classificationTilesetUrl = - "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; - // A b3dm tileset used to classify the photogrammetry tileset - const classificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(classificationTileset); + const classificationTilesetUrl = + "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; + // A b3dm tileset used to classify the photogrammetry tileset + const classificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(classificationTileset); - // The same b3dm tileset used for classification, but rendered normally for comparison. - const nonClassificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - show: false, - }); - nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(nonClassificationTileset); + // The same b3dm tileset used for classification, but rendered normally for comparison. + const nonClassificationTileset = new Cesium.Cesium3DTileset({ + url: classificationTilesetUrl, + show: false, + }); + nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(nonClassificationTileset); - Sandcastle.addToggleButton("Show classification", true, function ( - checked - ) { - classificationTileset.show = checked; - nonClassificationTileset.show = !checked; - }); //Sandcastle_End + Sandcastle.addToggleButton("Show classification", true, function ( + checked + ) { + classificationTileset.show = checked; + nonClassificationTileset.show = !checked; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index 6e7becd497a..a53e6ff3122 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -33,28 +33,26 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); //Sandcastle_End + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index 0d26e51e9c4..40c6d2a0784 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -33,94 +33,92 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // An example showing a point cloud tileset classified by a Geometry tileset. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + // An example showing a point cloud tileset classified by a Geometry tileset. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - // Geometry Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry - const classificationTileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - viewer.scene.primitives.add(classificationTileset); + // Geometry Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry + const classificationTileset = new Cesium.Cesium3DTileset({ + url: + "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }); + viewer.scene.primitives.add(classificationTileset); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${id} === 'roof1'", "color('#004FFF', 0.5)"], - ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], - ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], - ["${id} === 'roof2'", "color('#004FFF', 0.5)"], - ["${id} === 'tower3'", "color('#FF8833', 0.5)"], - ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], - ["true", "color('#FFFF00', 0.5)"], - ], - }, - }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${id} === 'roof1'", "color('#004FFF', 0.5)"], + ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], + ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], + ["${id} === 'roof2'", "color('#004FFF', 0.5)"], + ["${id} === 'tower3'", "color('#FF8833', 0.5)"], + ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], + ["true", "color('#FFFF00', 0.5)"], + ], + }, + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index cbbb50ece83..252a9d20f60 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -157,230 +157,231 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - let viewModelTileset; + const scene = viewer.scene; + let viewModelTileset; - if (!Cesium.PointCloudShading.isSupported(scene)) { - window.alert("This browser does not support point cloud shading"); - } + if (!Cesium.PointCloudShading.isSupported(scene)) { + window.alert("This browser does not support point cloud shading"); + } - function reset() { - viewer.scene.primitives.remove(viewModelTileset); - viewModelTileset = undefined; - } + function reset() { + viewer.scene.primitives.remove(viewModelTileset); + viewModelTileset = undefined; + } - // The viewModel tracks the state of our mini application. - const pointClouds = ["St. Helens", "Church"]; - const viewModel = { - exampleTypes: pointClouds, - currentExampleType: pointClouds[0], - maximumScreenSpaceError: 16.0, - geometricErrorScale: 1.0, - maximumAttenuation: 0, // Equivalent to undefined - baseResolution: 0, // Equivalent to undefined - eyeDomeLightingStrength: 1.0, - eyeDomeLightingRadius: 1.0, - }; + // The viewModel tracks the state of our mini application. + const pointClouds = ["St. Helens", "Church"]; + const viewModel = { + exampleTypes: pointClouds, + currentExampleType: pointClouds[0], + maximumScreenSpaceError: 16.0, + geometricErrorScale: 1.0, + maximumAttenuation: 0, // Equivalent to undefined + baseResolution: 0, // Equivalent to undefined + eyeDomeLightingStrength: 1.0, + eyeDomeLightingRadius: 1.0, + }; - function tilesetToViewModel(tileset) { - viewModelTileset = tileset; + function tilesetToViewModel(tileset) { + viewModelTileset = tileset; - const pointCloudShading = tileset.pointCloudShading; - viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; - viewModel.geometricErrorScale = pointCloudShading.geometricErrorScale; - viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation - ? pointCloudShading.maximumAttenuation - : 0; - viewModel.baseResolution = pointCloudShading.baseResolution - ? pointCloudShading.baseResolution - : 0; - viewModel.eyeDomeLightingStrength = - pointCloudShading.eyeDomeLightingStrength; - viewModel.eyeDomeLightingRadius = - pointCloudShading.eyeDomeLightingRadius; - } + const pointCloudShading = tileset.pointCloudShading; + viewModel.maximumScreenSpaceError = tileset.maximumScreenSpaceError; + viewModel.geometricErrorScale = + pointCloudShading.geometricErrorScale; + viewModel.maximumAttenuation = pointCloudShading.maximumAttenuation + ? pointCloudShading.maximumAttenuation + : 0; + viewModel.baseResolution = pointCloudShading.baseResolution + ? pointCloudShading.baseResolution + : 0; + viewModel.eyeDomeLightingStrength = + pointCloudShading.eyeDomeLightingStrength; + viewModel.eyeDomeLightingRadius = + pointCloudShading.eyeDomeLightingRadius; + } - function loadStHelens() { - // Set the initial camera view to look at Mt. St. Helens - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + function loadStHelens() { + // Set the initial camera view to look at Mt. St. Helens + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ - // This tileset uses replacement refinement and has geometric error approximately equal to - // the average interpoint distance in each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - viewer.scene.primitives.add(tileset); + // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ + // This tileset uses replacement refinement and has geometric error approximately equal to + // the average interpoint distance in each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), + }); + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead - tileset.pointCloudShading.baseResolution = undefined; - tileset.pointCloudShading.geometricErrorScale = 1.0; - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead + tileset.pointCloudShading.baseResolution = undefined; + tileset.pointCloudShading.geometricErrorScale = 1.0; + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - tilesetToViewModel(tileset); - } + tilesetToViewModel(tileset); + } - function loadChurch() { - // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + function loadChurch() { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. - tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. - tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. + tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. + tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - tilesetToViewModel(tileset); - } + tilesetToViewModel(tileset); + } - function checkZero(newValue) { - const newValueFloat = parseFloat(newValue); - return newValueFloat === 0.0 ? undefined : newValueFloat; - } + function checkZero(newValue) { + const newValueFloat = parseFloat(newValue); + return newValueFloat === 0.0 ? undefined : newValueFloat; + } - loadStHelens(); + loadStHelens(); - // Convert the viewModel members into knockout observables. - Cesium.knockout.track(viewModel); + // Convert the viewModel members into knockout observables. + Cesium.knockout.track(viewModel); - // Bind the viewModel to the DOM elements of the UI that call for it. - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + // Bind the viewModel to the DOM elements of the UI that call for it. + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === pointClouds[0]) { - loadStHelens(); - } else if (newValue === pointClouds[1]) { - loadChurch(); - } - }); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === pointClouds[0]) { + loadStHelens(); + } else if (newValue === pointClouds[1]) { + loadChurch(); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumScreenSpaceError") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumScreenSpaceError") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.maximumScreenSpaceError = parseFloat(newValue); + } + }); - Cesium.knockout - .getObservable(viewModel, "geometricErrorScale") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "geometricErrorScale") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.geometricErrorScale = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "maximumAttenuation") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "maximumAttenuation") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.maximumAttenuation = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "baseResolution") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.baseResolution = checkZero( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "baseResolution") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.baseResolution = checkZero( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingStrength") - .subscribe(function (newValue) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( - newValue - ); - } - }); + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingStrength") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingStrength = parseFloat( + newValue + ); + } + }); - Cesium.knockout - .getObservable(viewModel, "eyeDomeLightingRadius") - .subscribe(function (newValue) { + Cesium.knockout + .getObservable(viewModel, "eyeDomeLightingRadius") + .subscribe(function (newValue) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( + newValue + ); + } + }); + + Sandcastle.addToggleButton("Enable Attenuation", true, function ( + checked + ) { if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLightingRadius = parseFloat( - newValue - ); + viewModelTileset.pointCloudShading.attenuation = checked; } }); - Sandcastle.addToggleButton("Enable Attenuation", true, function ( - checked - ) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.attenuation = checked; - } - }); - - Sandcastle.addToggleButton("Enable Eye Dome Lighting", true, function ( - checked - ) { - if (Cesium.defined(viewModelTileset)) { - viewModelTileset.pointCloudShading.eyeDomeLighting = checked; - } - }); //Sandcastle_End + Sandcastle.addToggleButton( + "Enable Eye Dome Lighting", + true, + function (checked) { + if (Cesium.defined(viewModelTileset)) { + viewModelTileset.pointCloudShading.eyeDomeLighting = checked; + } + } + ); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html index d944b98091c..217312d33f9 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html @@ -36,7 +36,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -238,11 +238,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index 8779b985f8e..babe9cceede 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -33,40 +33,38 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(16421), + }); + viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); //Sandcastle_End + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index f527e2b3a72..f298cfd42fe 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -33,67 +33,65 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const geocoder = viewer.geocoder.viewModel; - geocoder.searchText = "Vienna"; - geocoder.flightDuration = 0.0; - geocoder.search(); + const geocoder = viewer.geocoder.viewModel; + geocoder.searchText = "Vienna"; + geocoder.flightDuration = 0.0; + geocoder.search(); - // Vector 3D Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5737), - }); - viewer.scene.primitives.add(tileset); + // Vector 3D Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5737), + }); + viewer.scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 255, 255, 0.5)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 255, 255, 0.5)", + }); - // Information about the currently highlighted feature - const highlighted = { - feature: undefined, - originalColor: new Cesium.Color(), - }; + // Information about the currently highlighted feature + const highlighted = { + feature: undefined, + originalColor: new Cesium.Color(), + }; - // Color a feature yellow on hover. - viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( - movement - ) { - // If a feature was previously highlighted, undo the highlight - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } + // Color a feature yellow on hover. + viewer.screenSpaceEventHandler.setInputAction(function onMouseMove( + movement + ) { + // If a feature was previously highlighted, undo the highlight + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.endPosition); - if (!Cesium.defined(pickedFeature)) { - return; - } + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } - // Highlight the feature - highlighted.feature = pickedFeature; - Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); - pickedFeature.color = Cesium.Color.YELLOW; - }, - Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End + // Highlight the feature + highlighted.feature = pickedFeature; + Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); + pickedFeature.color = Cesium.Color.YELLOW; + }, + Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Ambient Occlusion.html b/Apps/Sandcastle/gallery/Ambient Occlusion.html index 5575c9ebe55..650b1cfb618 100644 --- a/Apps/Sandcastle/gallery/Ambient Occlusion.html +++ b/Apps/Sandcastle/gallery/Ambient Occlusion.html @@ -110,7 +110,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -207,11 +207,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS MapServer.html b/Apps/Sandcastle/gallery/ArcGIS MapServer.html index 55e7acbdb07..0c286155613 100644 --- a/Apps/Sandcastle/gallery/ArcGIS MapServer.html +++ b/Apps/Sandcastle/gallery/ArcGIS MapServer.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -43,11 +43,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index e16d10af0b5..dce86820a80 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -29,23 +29,25 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ), - }); //Sandcastle_End + (async () => { + try { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index b37f9b3367b..32414bf7eb1 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -32,16 +32,22 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. - // https://www.pgc.umn.edu/data/arcticdem/ - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3956) - ), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. + // https://www.pgc.umn.edu/data/arcticdem/ + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3956) + ); + } catch (error) { + console.log(error); + } + })(); // Add Alaskan locations Sandcastle.addDefaultToolbarMenu( @@ -122,11 +128,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Atmosphere.html b/Apps/Sandcastle/gallery/Atmosphere.html index faf8adb19dd..69382766603 100644 --- a/Apps/Sandcastle/gallery/Atmosphere.html +++ b/Apps/Sandcastle/gallery/Atmosphere.html @@ -665,7 +665,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -1030,11 +1030,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Billboards.html b/Apps/Sandcastle/gallery/Billboards.html index e1dd3499eb3..b166b6398d8 100644 --- a/Apps/Sandcastle/gallery/Billboards.html +++ b/Apps/Sandcastle/gallery/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -366,11 +366,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Bloom.html b/Apps/Sandcastle/gallery/Bloom.html index bf83ff22e21..21d7f82fc7e 100644 --- a/Apps/Sandcastle/gallery/Bloom.html +++ b/Apps/Sandcastle/gallery/Bloom.html @@ -105,7 +105,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -183,11 +183,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Blue Marble.html b/Apps/Sandcastle/gallery/Blue Marble.html index c39d97c695d..ba4a89bef39 100644 --- a/Apps/Sandcastle/gallery/Blue Marble.html +++ b/Apps/Sandcastle/gallery/Blue Marble.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Blue Marble Next Generation July, 2004 imagery from NASA @@ -44,11 +44,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Box.html b/Apps/Sandcastle/gallery/Box.html index b8ea549e062..0860eb90f7c 100644 --- a/Apps/Sandcastle/gallery/Box.html +++ b/Apps/Sandcastle/gallery/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -71,11 +71,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML 3D Tiles.html b/Apps/Sandcastle/gallery/CZML 3D Tiles.html index 5adc46102e2..898cb91dfb5 100644 --- a/Apps/Sandcastle/gallery/CZML 3D Tiles.html +++ b/Apps/Sandcastle/gallery/CZML 3D Tiles.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -68,11 +68,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Billboard and Label.html b/Apps/Sandcastle/gallery/CZML Billboard and Label.html index 3e337e70566..358e1002c8c 100644 --- a/Apps/Sandcastle/gallery/CZML Billboard and Label.html +++ b/Apps/Sandcastle/gallery/CZML Billboard and Label.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -82,11 +82,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Box.html b/Apps/Sandcastle/gallery/CZML Box.html index 411335c7978..fe4ce90b875 100644 --- a/Apps/Sandcastle/gallery/CZML Box.html +++ b/Apps/Sandcastle/gallery/CZML Box.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -109,11 +109,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html index b38bc389e5a..db1ac667a79 100644 --- a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -115,11 +115,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Colors.html b/Apps/Sandcastle/gallery/CZML Colors.html index 3ab17adf809..4be19a1fd54 100644 --- a/Apps/Sandcastle/gallery/CZML Colors.html +++ b/Apps/Sandcastle/gallery/CZML Colors.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -91,11 +91,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html index 5e172193e1a..2630386eda0 100644 --- a/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html +++ b/Apps/Sandcastle/gallery/CZML Cones and Cylinders.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -93,11 +93,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Corridor.html b/Apps/Sandcastle/gallery/CZML Corridor.html index 467563570a4..d74d3b838e5 100644 --- a/Apps/Sandcastle/gallery/CZML Corridor.html +++ b/Apps/Sandcastle/gallery/CZML Corridor.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -145,11 +145,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Custom Properties.html b/Apps/Sandcastle/gallery/CZML Custom Properties.html index 7217a1083e6..7b6dbc16212 100644 --- a/Apps/Sandcastle/gallery/CZML Custom Properties.html +++ b/Apps/Sandcastle/gallery/CZML Custom Properties.html @@ -32,7 +32,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -176,11 +176,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html index 65ac6a0db75..d08df40e333 100644 --- a/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html +++ b/Apps/Sandcastle/gallery/CZML Model - Node Transformations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -113,11 +113,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Articulations.html b/Apps/Sandcastle/gallery/CZML Model Articulations.html index 7f78d628a68..b5964db15fa 100644 --- a/Apps/Sandcastle/gallery/CZML Model Articulations.html +++ b/Apps/Sandcastle/gallery/CZML Model Articulations.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -98,11 +98,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Data URL.html b/Apps/Sandcastle/gallery/CZML Model Data URL.html index b0561778dcd..891c5528630 100644 --- a/Apps/Sandcastle/gallery/CZML Model Data URL.html +++ b/Apps/Sandcastle/gallery/CZML Model Data URL.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const gltf = { @@ -176,11 +176,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model.html b/Apps/Sandcastle/gallery/CZML Model.html index a16f3aa6fe1..a9299d5aa2d 100644 --- a/Apps/Sandcastle/gallery/CZML Model.html +++ b/Apps/Sandcastle/gallery/CZML Model.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -76,11 +76,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Path.html b/Apps/Sandcastle/gallery/CZML Path.html index c5342b3cf26..1732ea900b3 100644 --- a/Apps/Sandcastle/gallery/CZML Path.html +++ b/Apps/Sandcastle/gallery/CZML Path.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -7243,26 +7243,24 @@ }, ]; - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - baseLayerPicker: false, - shouldAnimate: true, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + baseLayerPicker: false, + shouldAnimate: true, + }); - const dataSource = await viewer.dataSources.add( - Cesium.CzmlDataSource.load(czml) - ); + const dataSource = await viewer.dataSources.add( + Cesium.CzmlDataSource.load(czml) + ); - viewer.trackedEntity = dataSource.entities.getById("path"); //Sandcastle_End + viewer.trackedEntity = dataSource.entities.getById("path"); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html index 3ca62d6746d..63470fd2f66 100644 --- a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html +++ b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -87,11 +87,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point.html b/Apps/Sandcastle/gallery/CZML Point.html index 19f338f6188..5bc606f8ffb 100644 --- a/Apps/Sandcastle/gallery/CZML Point.html +++ b/Apps/Sandcastle/gallery/CZML Point.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -68,11 +68,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html index f964655c8fe..9a37834493f 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Interpolating References.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -212,11 +212,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html index 76b13a2234b..902d2757502 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html +++ b/Apps/Sandcastle/gallery/CZML Polygon - Intervals, Availability.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -227,11 +227,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polygon.html b/Apps/Sandcastle/gallery/CZML Polygon.html index 90b8d1f92b0..f5ade1d453e 100644 --- a/Apps/Sandcastle/gallery/CZML Polygon.html +++ b/Apps/Sandcastle/gallery/CZML Polygon.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -224,11 +224,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline Volume.html b/Apps/Sandcastle/gallery/CZML Polyline Volume.html index 16689e8847c..56970ce3fdd 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline Volume.html +++ b/Apps/Sandcastle/gallery/CZML Polyline Volume.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -153,11 +153,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Polyline.html b/Apps/Sandcastle/gallery/CZML Polyline.html index c603956074f..15e2ae74b29 100644 --- a/Apps/Sandcastle/gallery/CZML Polyline.html +++ b/Apps/Sandcastle/gallery/CZML Polyline.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -145,11 +145,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Position Definitions.html b/Apps/Sandcastle/gallery/CZML Position Definitions.html index 6520d1bd165..43df14ff7cb 100644 --- a/Apps/Sandcastle/gallery/CZML Position Definitions.html +++ b/Apps/Sandcastle/gallery/CZML Position Definitions.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -107,11 +107,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Rectangle.html b/Apps/Sandcastle/gallery/CZML Rectangle.html index 83cddbc5493..1a98dda45eb 100644 --- a/Apps/Sandcastle/gallery/CZML Rectangle.html +++ b/Apps/Sandcastle/gallery/CZML Rectangle.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -130,11 +130,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Reference Properties.html b/Apps/Sandcastle/gallery/CZML Reference Properties.html index 172a0294e0a..24c7cf38921 100644 --- a/Apps/Sandcastle/gallery/CZML Reference Properties.html +++ b/Apps/Sandcastle/gallery/CZML Reference Properties.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -134,11 +134,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html index 639034a5093..e5f437e4680 100644 --- a/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/CZML Spheres and Ellipsoids.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -114,11 +114,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Wall.html b/Apps/Sandcastle/gallery/CZML Wall.html index 56809d83e00..e35de4ada58 100644 --- a/Apps/Sandcastle/gallery/CZML Wall.html +++ b/Apps/Sandcastle/gallery/CZML Wall.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -100,11 +100,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML ZIndex.html b/Apps/Sandcastle/gallery/CZML ZIndex.html index 492f9ba8868..ead9d1c59fa 100644 --- a/Apps/Sandcastle/gallery/CZML ZIndex.html +++ b/Apps/Sandcastle/gallery/CZML ZIndex.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml = [ @@ -150,11 +150,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML.html b/Apps/Sandcastle/gallery/CZML.html index 75f35dc6a7b..d76fb8b77c5 100644 --- a/Apps/Sandcastle/gallery/CZML.html +++ b/Apps/Sandcastle/gallery/CZML.html @@ -33,7 +33,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -69,11 +69,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Callback Property.html b/Apps/Sandcastle/gallery/Callback Property.html index 8747ff39473..5d63d5ad719 100644 --- a/Apps/Sandcastle/gallery/Callback Property.html +++ b/Apps/Sandcastle/gallery/Callback Property.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // This example illustrates a Callback Property, a property whose @@ -122,11 +122,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera Tutorial.html b/Apps/Sandcastle/gallery/Camera Tutorial.html index 2d2cce53a8d..ef38bd93a4d 100644 --- a/Apps/Sandcastle/gallery/Camera Tutorial.html +++ b/Apps/Sandcastle/gallery/Camera Tutorial.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -190,11 +190,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera.html b/Apps/Sandcastle/gallery/Camera.html index 340b5f18bf6..b4d3d8af64c 100644 --- a/Apps/Sandcastle/gallery/Camera.html +++ b/Apps/Sandcastle/gallery/Camera.html @@ -42,7 +42,7 @@ <div id="cameraChanged">Camera Changed</div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -489,11 +489,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cardboard.html b/Apps/Sandcastle/gallery/Cardboard.html index 581d2d1cee2..7304c8a6aab 100644 --- a/Apps/Sandcastle/gallery/Cardboard.html +++ b/Apps/Sandcastle/gallery/Cardboard.html @@ -32,165 +32,163 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - vrButton: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - // Click the VR button in the bottom right of the screen to switch to VR mode. - - viewer.scene.globe.enableLighting = true; - viewer.scene.globe.depthTestAgainstTerrain = true; - - // Follow the path of a plane. See the interpolation Sandcastle example. - Cesium.Math.setRandomNumberSeed(3); - - const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); - const stop = Cesium.JulianDate.addSeconds( - start, - 360, - new Cesium.JulianDate() - ); - - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; - viewer.clock.shouldAnimate = true; - - function computeCirclularFlight(lon, lat, radius) { - const property = new Cesium.SampledPositionProperty(); - const startAngle = Cesium.Math.nextRandomNumber() * 360.0; - const endAngle = startAngle + 360.0; - - const increment = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; - for (let i = startAngle; i < endAngle; i += increment) { - const radians = Cesium.Math.toRadians(i); - const timeIncrement = i - startAngle; - const time = Cesium.JulianDate.addSeconds( - start, - timeIncrement, - new Cesium.JulianDate() - ); - const position = Cesium.Cartesian3.fromDegrees( - lon + radius * 1.5 * Math.cos(radians), - lat + radius * Math.sin(radians), - Cesium.Math.nextRandomNumber() * 500 + 1800 - ); - property.addSample(time, position); - } - return property; - } - - const longitude = -112.110693; - const latitude = 36.0994841; - const radius = 0.03; - - const modelURI = - "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; - const entity = viewer.entities.add({ - availability: new Cesium.TimeIntervalCollection([ - new Cesium.TimeInterval({ - start: start, - stop: stop, - }), - ]), - position: computeCirclularFlight(longitude, latitude, radius), - model: { - uri: modelURI, - minimumPixelSize: 64, - }, - }); - - entity.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); - - // Set initial camera position and orientation to be when in the model's reference frame. - const camera = viewer.camera; - camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); - camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); - camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); - camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); - - viewer.scene.postUpdate.addEventListener(function (scene, time) { - const position = entity.position.getValue(time); - if (!Cesium.defined(position)) { - return; - } - - let transform; - if (!Cesium.defined(entity.orientation)) { - transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); - } else { - const orientation = entity.orientation.getValue(time); - if (!Cesium.defined(orientation)) { - return; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + vrButton: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + // Click the VR button in the bottom right of the screen to switch to VR mode. + + viewer.scene.globe.enableLighting = true; + viewer.scene.globe.depthTestAgainstTerrain = true; + + // Follow the path of a plane. See the interpolation Sandcastle example. + Cesium.Math.setRandomNumberSeed(3); + + const start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16)); + const stop = Cesium.JulianDate.addSeconds( + start, + 360, + new Cesium.JulianDate() + ); + + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + viewer.clock.shouldAnimate = true; + + function computeCirclularFlight(lon, lat, radius) { + const property = new Cesium.SampledPositionProperty(); + const startAngle = Cesium.Math.nextRandomNumber() * 360.0; + const endAngle = startAngle + 360.0; + + const increment = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 10.0 + 45.0; + for (let i = startAngle; i < endAngle; i += increment) { + const radians = Cesium.Math.toRadians(i); + const timeIncrement = i - startAngle; + const time = Cesium.JulianDate.addSeconds( + start, + timeIncrement, + new Cesium.JulianDate() + ); + const position = Cesium.Cartesian3.fromDegrees( + lon + radius * 1.5 * Math.cos(radians), + lat + radius * Math.sin(radians), + Cesium.Math.nextRandomNumber() * 500 + 1800 + ); + property.addSample(time, position); } - - transform = Cesium.Matrix4.fromRotationTranslation( - Cesium.Matrix3.fromQuaternion(orientation), - position - ); + return property; } - // Save camera state - const offset = Cesium.Cartesian3.clone(camera.position); - const direction = Cesium.Cartesian3.clone(camera.direction); - const up = Cesium.Cartesian3.clone(camera.up); - - // Set camera to be in model's reference frame. - camera.lookAtTransform(transform); - - // Reset the camera state to the saved state so it appears fixed in the model's frame. - Cesium.Cartesian3.clone(offset, camera.position); - Cesium.Cartesian3.clone(direction, camera.direction); - Cesium.Cartesian3.clone(up, camera.up); - Cesium.Cartesian3.cross(direction, up, camera.right); - }); - - // Add a few more balloons flying with the one the viewer is in. - const numBalloons = 12; - for (let i = 0; i < numBalloons; ++i) { - const balloonRadius = - (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; - const balloon = viewer.entities.add({ + const longitude = -112.110693; + const latitude = 36.0994841; + const radius = 0.03; + + const modelURI = + "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb"; + const entity = viewer.entities.add({ availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start: start, stop: stop, }), ]), - position: computeCirclularFlight( - longitude, - latitude, - balloonRadius - ), + position: computeCirclularFlight(longitude, latitude, radius), model: { uri: modelURI, minimumPixelSize: 64, }, }); - balloon.position.setInterpolationOptions({ + entity.position.setInterpolationOptions({ interpolationDegree: 2, interpolationAlgorithm: Cesium.HermitePolynomialApproximation, }); - } //Sandcastle_End + + // Set initial camera position and orientation to be when in the model's reference frame. + const camera = viewer.camera; + camera.position = new Cesium.Cartesian3(0.25, 0.0, 0.0); + camera.direction = new Cesium.Cartesian3(1.0, 0.0, 0.0); + camera.up = new Cesium.Cartesian3(0.0, 0.0, 1.0); + camera.right = new Cesium.Cartesian3(0.0, -1.0, 0.0); + + viewer.scene.postUpdate.addEventListener(function (scene, time) { + const position = entity.position.getValue(time); + if (!Cesium.defined(position)) { + return; + } + + let transform; + if (!Cesium.defined(entity.orientation)) { + transform = Cesium.Transforms.eastNorthUpToFixedFrame(position); + } else { + const orientation = entity.orientation.getValue(time); + if (!Cesium.defined(orientation)) { + return; + } + + transform = Cesium.Matrix4.fromRotationTranslation( + Cesium.Matrix3.fromQuaternion(orientation), + position + ); + } + + // Save camera state + const offset = Cesium.Cartesian3.clone(camera.position); + const direction = Cesium.Cartesian3.clone(camera.direction); + const up = Cesium.Cartesian3.clone(camera.up); + + // Set camera to be in model's reference frame. + camera.lookAtTransform(transform); + + // Reset the camera state to the saved state so it appears fixed in the model's frame. + Cesium.Cartesian3.clone(offset, camera.position); + Cesium.Cartesian3.clone(direction, camera.direction); + Cesium.Cartesian3.clone(up, camera.up); + Cesium.Cartesian3.cross(direction, up, camera.right); + }); + + // Add a few more balloons flying with the one the viewer is in. + const numBalloons = 12; + for (let i = 0; i < numBalloons; ++i) { + const balloonRadius = + (Cesium.Math.nextRandomNumber() * 2.0 - 1.0) * 0.01 + radius; + const balloon = viewer.entities.add({ + availability: new Cesium.TimeIntervalCollection([ + new Cesium.TimeInterval({ + start: start, + stop: stop, + }), + ]), + position: computeCirclularFlight( + longitude, + latitude, + balloonRadius + ), + model: { + uri: modelURI, + minimumPixelSize: 64, + }, + }); + + balloon.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 043814d13fe..7c32bfee9fa 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -32,72 +32,70 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - // Tropics of Cancer and Capricorn - const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( - -180.0, - -23.43687, - 180.0, - 23.43687 - ); - - globe.cartographicLimitRectangle = coffeeBeltRectangle; - globe.showSkirts = false; - globe.backFaceCulling = false; - globe.undergroundColor = undefined; - scene.skyAtmosphere.show = false; + // Tropics of Cancer and Capricorn + const coffeeBeltRectangle = Cesium.Rectangle.fromDegrees( + -180.0, + -23.43687, + 180.0, + 23.43687 + ); - // Add rectangles to show bounds - const rectangles = []; + globe.cartographicLimitRectangle = coffeeBeltRectangle; + globe.showSkirts = false; + globe.backFaceCulling = false; + globe.undergroundColor = undefined; + scene.skyAtmosphere.show = false; - for (let i = 0; i < 10; i++) { - rectangles.push( - viewer.entities.add({ - rectangle: { - coordinates: coffeeBeltRectangle, - material: Cesium.Color.WHITE.withAlpha(0.0), - height: i * 5000.0, - outline: true, - outlineWidth: 4.0, - outlineColor: Cesium.Color.WHITE, - }, - }) - ); - } + // Add rectangles to show bounds + const rectangles = []; - Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { - if (checked) { - viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; - } else { - viewer.scene.globe.cartographicLimitRectangle = undefined; + for (let i = 0; i < 10; i++) { + rectangles.push( + viewer.entities.add({ + rectangle: { + coordinates: coffeeBeltRectangle, + material: Cesium.Color.WHITE.withAlpha(0.0), + height: i * 5000.0, + outline: true, + outlineWidth: 4.0, + outlineColor: Cesium.Color.WHITE, + }, + }) + ); } - }); - Sandcastle.addToggleButton("Show Bounds", true, function (checked) { - const rectanglesLength = rectangles.length; - for (let i = 0; i < rectanglesLength; i++) { - const rectangleEntity = rectangles[i]; - rectangleEntity.show = checked; - } - }); //Sandcastle_End + Sandcastle.addToggleButton("Limit Enabled", true, function (checked) { + if (checked) { + viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle; + } else { + viewer.scene.globe.cartographicLimitRectangle = undefined; + } + }); + + Sandcastle.addToggleButton("Show Bounds", true, function (checked) { + const rectanglesLength = rectangles.length; + for (let i = 0; i < rectanglesLength; i++) { + const rectangleEntity = rectangles[i]; + rectangleEntity.show = checked; + } + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Inspector.html b/Apps/Sandcastle/gallery/Cesium Inspector.html index b67cbaf296a..6d1773608e2 100644 --- a/Apps/Sandcastle/gallery/Cesium Inspector.html +++ b/Apps/Sandcastle/gallery/Cesium Inspector.html @@ -36,85 +36,91 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - scene.globe.depthTestAgainstTerrain = true; + const scene = viewer.scene; + scene.globe.depthTestAgainstTerrain = true; - //Add Cesium Inspector - viewer.extend(Cesium.viewerCesiumInspectorMixin); + //Add Cesium Inspector + viewer.extend(Cesium.viewerCesiumInspectorMixin); - //Add Primitives - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), - }), - modelMatrix: Cesium.Matrix4.multiplyByTranslation( - Cesium.Transforms.eastNorthUpToFixedFrame( - Cesium.Cartesian3.fromDegrees(-105.0, 45.0) - ), - new Cesium.Cartesian3(0.0, 0.0, 250000), - new Cesium.Matrix4() - ), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.RED.withAlpha(0.5) + //Add Primitives + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3( + 400000.0, + 300000.0, + 500000.0 + ), + }), + modelMatrix: Cesium.Matrix4.multiplyByTranslation( + Cesium.Transforms.eastNorthUpToFixedFrame( + Cesium.Cartesian3.fromDegrees(-105.0, 45.0) + ), + new Cesium.Cartesian3(0.0, 0.0, 250000), + new Cesium.Matrix4() ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance({ - closed: true, - }), - }) - ); + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.RED.withAlpha(0.5) + ), + }, + }), + appearance: new Cesium.PerInstanceColorAppearance({ + closed: true, + }), + }) + ); - scene.primitives.add( - new Cesium.Primitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.RectangleGeometry({ - rectangle: Cesium.Rectangle.fromDegrees( - -100.0, - 30.0, - -93.0, - 37.0 - ), - height: 100000, - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + scene.primitives.add( + new Cesium.Primitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.RectangleGeometry({ + rectangle: Cesium.Rectangle.fromDegrees( + -100.0, + 30.0, + -93.0, + 37.0 + ), + height: 100000, + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.BLUE + ), + }, }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.BLUE - ), - }, - }), - appearance: new Cesium.PerInstanceColorAppearance(), - }) - ); + appearance: new Cesium.PerInstanceColorAppearance(), + }) + ); - const billboards = scene.primitives.add( - new Cesium.BillboardCollection() - ); - billboards.add({ - position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 150000), - image: "../images/Cesium_Logo_overlay.png", - }); //Sandcastle_End + const billboards = scene.primitives.add( + new Cesium.BillboardCollection() + ); + billboards.add({ + position: Cesium.Cartesian3.fromDegrees( + -75.59777, + 40.03883, + 150000 + ), + image: "../images/Cesium_Logo_overlay.png", + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index faa969bead0..ea639ecbb39 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -35,31 +35,29 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.primitives.add(Cesium.createOsmBuildings()); + viewer.scene.primitives.add(Cesium.createOsmBuildings()); - viewer.scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), - orientation: { - heading: Cesium.Math.toRadians(20), - pitch: Cesium.Math.toRadians(-20), - }, - }); //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), + orientation: { + heading: Cesium.Math.toRadians(20), + pitch: Cesium.Math.toRadians(-20), + }, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium Widget.html b/Apps/Sandcastle/gallery/Cesium Widget.html index 25c30fbc958..55e1f10e93e 100644 --- a/Apps/Sandcastle/gallery/Cesium Widget.html +++ b/Apps/Sandcastle/gallery/Cesium Widget.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Cesium.CesiumWidget is similar to Cesium.Viewer, but @@ -46,11 +46,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 0e4162731d7..016a5720fb5 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -32,22 +32,24 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // For more information on Cesium World Terrain, see https://cesium.com/platform/cesium-ion/content/cesium-world-terrain/ - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); //Sandcastle_End + (async () => { + try { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Circles and Ellipses.html b/Apps/Sandcastle/gallery/Circles and Ellipses.html index e0dc4a87134..c112576c519 100644 --- a/Apps/Sandcastle/gallery/Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/Circles and Ellipses.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -78,11 +78,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Model.html b/Apps/Sandcastle/gallery/Clamp to 3D Model.html index 84f7a352fe0..fd91a1ab475 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Model.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Model.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -112,11 +112,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index 048b34bad1b..57ccc1cb57a 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -32,68 +32,66 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; - const clock = viewer.clock; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; + const clock = viewer.clock; - let entity; - let positionProperty; - const dataSourcePromise = Cesium.CzmlDataSource.load( - "../../SampleData/ClampToGround.czml" - ); - viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { - entity = dataSource.entities.getById("CesiumMilkTruck"); - positionProperty = entity.position; - }); + let entity; + let positionProperty; + const dataSourcePromise = Cesium.CzmlDataSource.load( + "../../SampleData/ClampToGround.czml" + ); + viewer.dataSources.add(dataSourcePromise).then(function (dataSource) { + entity = dataSource.entities.getById("CesiumMilkTruck"); + positionProperty = entity.position; + }); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + const tileset = scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }) + ); - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 1216403.8845586285, - -4736357.493351395, - 4081299.715698949 - ), - orientation: new Cesium.HeadingPitchRoll( - 4.2892217081808806, - -0.4799070147502502, - 6.279789177843313 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 1216403.8845586285, + -4736357.493351395, + 4081299.715698949 + ), + orientation: new Cesium.HeadingPitchRoll( + 4.2892217081808806, + -0.4799070147502502, + 6.279789177843313 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - if (scene.clampToHeightSupported) { - tileset.initialTilesLoaded.addEventListener(start); - } else { - window.alert("This browser does not support clampToHeight."); - } + if (scene.clampToHeightSupported) { + tileset.initialTilesLoaded.addEventListener(start); + } else { + window.alert("This browser does not support clampToHeight."); + } - function start() { - clock.shouldAnimate = true; - const objectsToExclude = [entity]; - scene.postRender.addEventListener(function () { - const position = positionProperty.getValue(clock.currentTime); - entity.position = scene.clampToHeight(position, objectsToExclude); - }); - } //Sandcastle_End + function start() { + clock.shouldAnimate = true; + const objectsToExclude = [entity]; + scene.postRender.addEventListener(function () { + const position = positionProperty.getValue(clock.currentTime); + entity.position = scene.clampToHeight(position, objectsToExclude); + }); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index fd4346836b9..f6b20444f25 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -34,14 +34,20 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + Sandcastle.addDefaultToolbarMenu( [ { @@ -359,11 +365,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index e74ffe9ec77..3ac16b5dc61 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -32,12 +32,18 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); const tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(40866), @@ -173,11 +179,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index a20994b8790..b9b003fa070 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -76,279 +76,317 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const camera = scene.camera; + const scene = viewer.scene; + const camera = scene.camera; - let center = new Cesium.Cartesian3( - 1216389.3637977627, - -4736323.641980423, - 4081321.7428341154 - ); - let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) - ); - let hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + let center = new Cesium.Cartesian3( + 1216389.3637977627, + -4736323.641980423, + 4081321.7428341154 + ); + let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(2.619728786416368, 0.0, 0.0) + ); + let hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const buildingHighlight = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: Cesium.BoxGeometry.fromDimensions({ - vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), + const buildingHighlight = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: Cesium.BoxGeometry.fromDimensions({ + vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions: new Cesium.Cartesian3(8.0, 5.0, 8.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + new Cesium.Color(1.0, 0.0, 0.0, 0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - new Cesium.Color(1.0, 0.0, 0.0, 0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216409.0189737265, - -4736252.144235287, - 4081393.6027081604 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(0.4, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216409.0189737265, + -4736252.144235287, + 4081393.6027081604 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(0.4, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight1 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + const treeHighlight1 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 1", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F26419").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 1", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216404.8844045496, - -4736255.287065536, - 4081392.010192471 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) - ); - hpr = Cesium.Matrix4.fromRotationTranslation( - hprRotation, - new Cesium.Cartesian3(-0.25, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); + center = new Cesium.Cartesian3( + 1216404.8844045496, + -4736255.287065536, + 4081392.010192471 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + hprRotation = Cesium.Matrix3.fromHeadingPitchRoll( + new Cesium.HeadingPitchRoll(5.785339046755887, 0.0, 0.0) + ); + hpr = Cesium.Matrix4.fromRotationTranslation( + hprRotation, + new Cesium.Cartesian3(-0.25, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix); - const treeHighlight2 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + const treeHighlight2 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(3.25, 5.0, 4.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 2", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#F03A47").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 2", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216398.813990024, - -4736258.039875737, - 4081387.9562678365 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - let translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -2.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216398.813990024, + -4736258.039875737, + 4081387.9562678365 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + let translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -2.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight3 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.EllipsoidGeometry({ - radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), + const treeHighlight3 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.EllipsoidGeometry({ + radii: new Cesium.Cartesian3(2.45, 2.45, 3.0), + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 3", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#004FFF").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), - }, - id: "volume 3", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); - center = new Cesium.Cartesian3( - 1216393.6257790313, - -4736259.809075361, - 4081384.4858198245 - ); - modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); - translation = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, -1.0) - ); - Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); + center = new Cesium.Cartesian3( + 1216393.6257790313, + -4736259.809075361, + 4081384.4858198245 + ); + modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center); + translation = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, -1.0) + ); + Cesium.Matrix4.multiply(modelMatrix, translation, modelMatrix); - const treeHighlight4 = scene.primitives.add( - new Cesium.ClassificationPrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.SphereGeometry({ - radius: 2.0, + const treeHighlight4 = scene.primitives.add( + new Cesium.ClassificationPrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.SphereGeometry({ + radius: 2.0, + }), + modelMatrix: modelMatrix, + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor( + Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) + ), + show: new Cesium.ShowGeometryInstanceAttribute(true), + }, + id: "volume 4", }), - modelMatrix: modelMatrix, - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor( - Cesium.Color.fromCssColorString("#55DDE0").withAlpha(0.5) - ), - show: new Cesium.ShowGeometryInstanceAttribute(true), + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + }) + ); + + function highlightBuilding() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216394.1392207467, + -4736348.59346919, + 4081293.9160685353 + ), + orientation: { + heading: 0.018509338875732695, + pitch: -0.09272999615872646, }, - id: "volume 4", - }), - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }) - ); + }); + } - function highlightBuilding() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216394.1392207467, - -4736348.59346919, - 4081293.9160685353 - ), - orientation: { - heading: 0.018509338875732695, - pitch: -0.09272999615872646, - }, - }); - } + function highlightTrees() { + camera.setView({ + destination: new Cesium.Cartesian3( + 1216435.0352745096, + -4736283.144192113, + 4081368.0920420634 + ), + orientation: { + heading: 5.718380792746039, + pitch: -0.3087010195266797, + }, + }); + } - function highlightTrees() { - camera.setView({ - destination: new Cesium.Cartesian3( - 1216435.0352745096, - -4736283.144192113, - 4081368.0920420634 - ), - orientation: { - heading: 5.718380792746039, - pitch: -0.3087010195266797, - }, - }); - } + function invertClassification(checked) { + if (checked && !scene.invertClassificationSupported) { + window.alert( + "This browser does not support invert classification" + ); + } - function invertClassification(checked) { - if (checked && !scene.invertClassificationSupported) { - window.alert("This browser does not support invert classification"); - } + scene.invertClassification = checked; + scene.invertClassificationColor = new Cesium.Color( + 0.25, + 0.25, + 0.25, + 1.0 + ); - scene.invertClassification = checked; - scene.invertClassificationColor = new Cesium.Color( - 0.25, - 0.25, - 0.25, - 1.0 - ); + buildingHighlight.getGeometryInstanceAttributes( + "volume" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight1.getGeometryInstanceAttributes( + "volume 1" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight2.getGeometryInstanceAttributes( + "volume 2" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight3.getGeometryInstanceAttributes( + "volume 3" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + treeHighlight4.getGeometryInstanceAttributes( + "volume 4" + ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); + } - buildingHighlight.getGeometryInstanceAttributes( - "volume" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight1.getGeometryInstanceAttributes( - "volume 1" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight2.getGeometryInstanceAttributes( - "volume 2" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight3.getGeometryInstanceAttributes( - "volume 3" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - treeHighlight4.getGeometryInstanceAttributes( - "volume 4" - ).show = Cesium.ShowGeometryInstanceAttribute.toValue(!checked); - } + function updateAlpha(value) { + scene.invertClassificationColor.alpha = parseFloat(value); + } - function updateAlpha(value) { - scene.invertClassificationColor.alpha = parseFloat(value); - } + const tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(40866), + }); + scene.primitives.add(tileset); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - scene.primitives.add(tileset); + const viewModel = { + inverted: viewer.scene.invertClassification, + invertedAlpha: viewer.scene.invertClassificationColor.alpha, + highlightBuilding: highlightBuilding, + highlightTrees: highlightTrees, + }; + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + Cesium.knockout + .getObservable(viewModel, "inverted") + .subscribe(invertClassification); + Cesium.knockout + .getObservable(viewModel, "invertedAlpha") + .subscribe(updateAlpha); - const viewModel = { - inverted: viewer.scene.invertClassification, - invertedAlpha: viewer.scene.invertClassificationColor.alpha, - highlightBuilding: highlightBuilding, - highlightTrees: highlightTrees, - }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "inverted") - .subscribe(invertClassification); - Cesium.knockout - .getObservable(viewModel, "invertedAlpha") - .subscribe(updateAlpha); + highlightTrees(); - highlightTrees(); + let currentObjectId; + let currentPrimitive; + let currentColor; + let currentShow; + let attributes; - let currentObjectId; - let currentPrimitive; - let currentColor; - let currentShow; - let attributes; + const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + const pickedObject = scene.pick(movement.endPosition); + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.id) + ) { + if (pickedObject.id === currentObjectId) { + return; + } - const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - const pickedObject = scene.pick(movement.endPosition); - if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) { - if (pickedObject.id === currentObjectId) { - return; + if (Cesium.defined(currentObjectId)) { + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + attributes.color = currentColor; + attributes.show = currentShow; + currentObjectId = undefined; + currentPrimitive = undefined; + currentColor = undefined; + currentShow = undefined; + } } - if (Cesium.defined(currentObjectId)) { + if ( + Cesium.defined(pickedObject) && + Cesium.defined(pickedObject.primitive) && + Cesium.defined(pickedObject.id) && + Cesium.defined( + pickedObject.primitive.getGeometryInstanceAttributes + ) + ) { + currentObjectId = pickedObject.id; + currentPrimitive = pickedObject.primitive; + attributes = currentPrimitive.getGeometryInstanceAttributes( + currentObjectId + ); + currentColor = attributes.color; + currentShow = attributes.show; + if (!scene.invertClassification) { + attributes.color = [255, 0, 255, 128]; + } + attributes.show = [1]; + } else if (Cesium.defined(currentObjectId)) { attributes = currentPrimitive.getGeometryInstanceAttributes( currentObjectId ); @@ -357,47 +395,14 @@ currentObjectId = undefined; currentPrimitive = undefined; currentColor = undefined; - currentShow = undefined; } - } - - if ( - Cesium.defined(pickedObject) && - Cesium.defined(pickedObject.primitive) && - Cesium.defined(pickedObject.id) && - Cesium.defined(pickedObject.primitive.getGeometryInstanceAttributes) - ) { - currentObjectId = pickedObject.id; - currentPrimitive = pickedObject.primitive; - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - currentColor = attributes.color; - currentShow = attributes.show; - if (!scene.invertClassification) { - attributes.color = [255, 0, 255, 128]; - } - attributes.show = [1]; - } else if (Cesium.defined(currentObjectId)) { - attributes = currentPrimitive.getGeometryInstanceAttributes( - currentObjectId - ); - attributes.color = currentColor; - attributes.show = currentShow; - currentObjectId = undefined; - currentPrimitive = undefined; - currentColor = undefined; - } - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clock.html b/Apps/Sandcastle/gallery/Clock.html index aedacb0ce17..21364613c02 100644 --- a/Apps/Sandcastle/gallery/Clock.html +++ b/Apps/Sandcastle/gallery/Clock.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create a clock that loops on Christmas day 2013 and runs in 4000x real time. @@ -66,11 +66,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cloud Parameters.html b/Apps/Sandcastle/gallery/Cloud Parameters.html index 45d1e6d1418..ce3b961b758 100644 --- a/Apps/Sandcastle/gallery/Cloud Parameters.html +++ b/Apps/Sandcastle/gallery/Cloud Parameters.html @@ -159,7 +159,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -314,11 +314,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index f275991e71a..cf6d8466f53 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -29,253 +29,251 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - infoBox: false, - shouldAnimate: true, - }); - - const scene = viewer.scene; - scene.primitives.add(Cesium.createOsmBuildings()); - - /////////////////////////// - // Create clouds - /////////////////////////// + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + infoBox: false, + shouldAnimate: true, + }); - Cesium.Math.setRandomNumberSeed(2.5); - function getRandomNumberInRange(minValue, maxValue) { - return ( - minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) - ); - } + const scene = viewer.scene; + scene.primitives.add(Cesium.createOsmBuildings()); - const clouds = new Cesium.CloudCollection(); + /////////////////////////// + // Create clouds + /////////////////////////// - // manually position clouds in the mountains - function createBackLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), - scale: new Cesium.Cartesian2(1500, 250), - maximumSize: new Cesium.Cartesian3(50, 15, 13), - slice: 0.3, - }); + Cesium.Math.setRandomNumberSeed(2.5); + function getRandomNumberInRange(minValue, maxValue) { + return ( + minValue + Cesium.Math.nextRandomNumber() * (maxValue - minValue) + ); + } - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), - scale: new Cesium.Cartesian2(1500, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.36, - }); + const clouds = new Cesium.CloudCollection(); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), - scale: new Cesium.Cartesian2(2000, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.49, - }); + // manually position clouds in the mountains + function createBackLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6908, 45.496, 300), + scale: new Cesium.Cartesian2(1500, 250), + maximumSize: new Cesium.Cartesian3(50, 15, 13), + slice: 0.3, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(13, 13, 13), - slice: 0.2, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.5, 335), + scale: new Cesium.Cartesian2(1500, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.36, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), - scale: new Cesium.Cartesian2(1700, 300), - maximumSize: new Cesium.Cartesian3(50, 12, 15), - slice: 0.6, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.72, 45.51, 260), + scale: new Cesium.Cartesian2(2000, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.49, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), - scale: new Cesium.Cartesian2(230, 110), - maximumSize: new Cesium.Cartesian3(15, 13, 15), - slice: 0.35, - }); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.52, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(13, 13, 13), + slice: 0.2, + }); - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), - scale: new Cesium.Cartesian2(1500, 500), - maximumSize: new Cesium.Cartesian3(30, 20, 17), - slice: 0.45, - }); - } + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.71, 45.522, 270), + scale: new Cesium.Cartesian2(1700, 300), + maximumSize: new Cesium.Cartesian3(50, 12, 15), + slice: 0.6, + }); - let long, - lat, - height, - scaleX, - scaleY, - aspectRatio, - cloudHeight, - depth, - slice; + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.705, 45.525, 250), + scale: new Cesium.Cartesian2(230, 110), + maximumSize: new Cesium.Cartesian3(15, 13, 15), + slice: 0.35, + }); - // randomly generate clouds in a certain area - function createRandomClouds( - numClouds, - startLong, - stopLong, - startLat, - stopLat, - minHeight, - maxHeight - ) { - const rangeLong = stopLong - startLong; - const rangeLat = stopLat - startLat; - for (let i = 0; i < numClouds; i++) { - long = startLong + getRandomNumberInRange(0, rangeLong); - lat = startLat + getRandomNumberInRange(0, rangeLat); - height = getRandomNumberInRange(minHeight, maxHeight); - scaleX = getRandomNumberInRange(150, 350); - scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); - slice = getRandomNumberInRange(0.3, 0.7); - depth = getRandomNumberInRange(5, 20); - aspectRatio = getRandomNumberInRange(1.5, 2.1); - cloudHeight = getRandomNumberInRange(5, 20); clouds.add({ - position: Cesium.Cartesian3.fromDegrees(long, lat, height), - scale: new Cesium.Cartesian2(scaleX, scaleY), - maximumSize: new Cesium.Cartesian3( - aspectRatio * cloudHeight, - cloudHeight, - depth - ), - slice: slice, + position: Cesium.Cartesian3.fromDegrees(-122.721, 45.53, 220), + scale: new Cesium.Cartesian2(1500, 500), + maximumSize: new Cesium.Cartesian3(30, 20, 17), + slice: 0.45, }); } - } - // manually position clouds in front - const scratch = new Cesium.Cartesian3(); - function createFrontLayerClouds() { - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), - scale: new Cesium.Cartesian2(400, 150), - maximumSize: new Cesium.Cartesian3(25, 12, 15), - slice: 0.36, - }); + let long, + lat, + height, + scaleX, + scaleY, + aspectRatio, + cloudHeight, + depth, + slice; - clouds.add({ - position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), - scale: new Cesium.Cartesian2(450, 200), - maximumSize: new Cesium.Cartesian3(25, 14, 12), - slice: 0.3, - }); - } + // randomly generate clouds in a certain area + function createRandomClouds( + numClouds, + startLong, + stopLong, + startLat, + stopLat, + minHeight, + maxHeight + ) { + const rangeLong = stopLong - startLong; + const rangeLat = stopLat - startLat; + for (let i = 0; i < numClouds; i++) { + long = startLong + getRandomNumberInRange(0, rangeLong); + lat = startLat + getRandomNumberInRange(0, rangeLat); + height = getRandomNumberInRange(minHeight, maxHeight); + scaleX = getRandomNumberInRange(150, 350); + scaleY = scaleX / 2.0 - getRandomNumberInRange(0, scaleX / 4.0); + slice = getRandomNumberInRange(0.3, 0.7); + depth = getRandomNumberInRange(5, 20); + aspectRatio = getRandomNumberInRange(1.5, 2.1); + cloudHeight = getRandomNumberInRange(5, 20); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(long, lat, height), + scale: new Cesium.Cartesian2(scaleX, scaleY), + maximumSize: new Cesium.Cartesian3( + aspectRatio * cloudHeight, + cloudHeight, + depth + ), + slice: slice, + }); + } + } - createBackLayerClouds(); - createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); - createFrontLayerClouds(); + // manually position clouds in front + const scratch = new Cesium.Cartesian3(); + function createFrontLayerClouds() { + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.666, 45.5126, 97), + scale: new Cesium.Cartesian2(400, 150), + maximumSize: new Cesium.Cartesian3(25, 12, 15), + slice: 0.36, + }); - scene.primitives.add(clouds); + clouds.add({ + position: Cesium.Cartesian3.fromDegrees(-122.6665, 45.5262, 76), + scale: new Cesium.Cartesian2(450, 200), + maximumSize: new Cesium.Cartesian3(25, 14, 12), + slice: 0.3, + }); + } - /////////////////////////// - // Create hot air balloons - /////////////////////////// + createBackLayerClouds(); + createRandomClouds(8, -122.685, -122.67, 45.51, 45.525, 50, 250); + createFrontLayerClouds(); - const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); - const stop = Cesium.JulianDate.addSeconds( - start, - 90, - new Cesium.JulianDate() - ); + scene.primitives.add(clouds); - function computeBalloonFlight(long, lat, height0, height1) { - const property = new Cesium.SampledPositionProperty(); - const time0 = start.clone(); - const time1 = Cesium.JulianDate.addSeconds( - time0, - 30, - new Cesium.JulianDate() - ); - const time2 = Cesium.JulianDate.addSeconds( - time1, - 15, - new Cesium.JulianDate() - ); - const time3 = Cesium.JulianDate.addSeconds( - time2, - 30, - new Cesium.JulianDate() - ); - const time4 = Cesium.JulianDate.addSeconds( - time3, - 15, + /////////////////////////// + // Create hot air balloons + /////////////////////////// + + const start = Cesium.JulianDate.fromDate(new Date(2021, 7, 21, 12)); + const stop = Cesium.JulianDate.addSeconds( + start, + 90, new Cesium.JulianDate() ); - const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); - const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); + function computeBalloonFlight(long, lat, height0, height1) { + const property = new Cesium.SampledPositionProperty(); + const time0 = start.clone(); + const time1 = Cesium.JulianDate.addSeconds( + time0, + 30, + new Cesium.JulianDate() + ); + const time2 = Cesium.JulianDate.addSeconds( + time1, + 15, + new Cesium.JulianDate() + ); + const time3 = Cesium.JulianDate.addSeconds( + time2, + 30, + new Cesium.JulianDate() + ); + const time4 = Cesium.JulianDate.addSeconds( + time3, + 15, + new Cesium.JulianDate() + ); - property.addSample(time0, position0); - property.addSample(time1, position1); - property.addSample(time2, position1); - property.addSample(time3, position0); - property.addSample(time4, position0); + const position0 = Cesium.Cartesian3.fromDegrees(long, lat, height0); + const position1 = Cesium.Cartesian3.fromDegrees(long, lat, height1); - return property; - } + property.addSample(time0, position0); + property.addSample(time1, position1); + property.addSample(time2, position1); + property.addSample(time3, position0); + property.addSample(time4, position0); - const balloon0 = viewer.entities.add({ - position: computeBalloonFlight(-122.661, 45.524, 400, 500), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + return property; + } - balloon0.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + const balloon0 = viewer.entities.add({ + position: computeBalloonFlight(-122.661, 45.524, 400, 500), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - const balloon1 = viewer.entities.add({ - position: computeBalloonFlight(-122.662, 45.517, 400, 300), - model: { - uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", - mininumPixelSize: 128, - maximumScale: 20000, - }, - }); + balloon0.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - balloon1.position.setInterpolationOptions({ - interpolationDegree: 2, - interpolationAlgorithm: Cesium.HermitePolynomialApproximation, - }); + const balloon1 = viewer.entities.add({ + position: computeBalloonFlight(-122.662, 45.517, 400, 300), + model: { + uri: "../../SampleData/models/CesiumBalloon/CesiumBalloon.glb", + mininumPixelSize: 128, + maximumScale: 20000, + }, + }); - viewer.clock.startTime = start.clone(); - viewer.clock.stopTime = stop.clone(); - viewer.clock.currentTime = start.clone(); - viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; - viewer.clock.multiplier = 1.0; + balloon1.position.setInterpolationOptions({ + interpolationDegree: 2, + interpolationAlgorithm: Cesium.HermitePolynomialApproximation, + }); - // Fly to Portland - scene.camera.flyTo({ - destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), - orientation: { - heading: Cesium.Math.toRadians(-115), - pitch: Cesium.Math.toRadians(-12), - roll: 0.0, - }, - }); + viewer.clock.startTime = start.clone(); + viewer.clock.stopTime = stop.clone(); + viewer.clock.currentTime = start.clone(); + viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; + viewer.clock.multiplier = 1.0; + + // Fly to Portland + scene.camera.flyTo({ + destination: Cesium.Cartesian3.fromDegrees(-122.6515, 45.5252, 525), + orientation: { + heading: Cesium.Math.toRadians(-115), + pitch: Cesium.Math.toRadians(-12), + roll: 0.0, + }, + }); - scene.fog.density = 1.15e-4; //Sandcastle_End + scene.fog.density = 1.15e-4; + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clustering.html b/Apps/Sandcastle/gallery/Clustering.html index bb7e98fb501..517f3bbe1c2 100644 --- a/Apps/Sandcastle/gallery/Clustering.html +++ b/Apps/Sandcastle/gallery/Clustering.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -214,11 +214,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Corridor.html b/Apps/Sandcastle/gallery/Corridor.html index a8067ee9929..32aeb401817 100644 --- a/Apps/Sandcastle/gallery/Corridor.html +++ b/Apps/Sandcastle/gallery/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -96,11 +96,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 4a234981789..991d384e2c3 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -406,11 +406,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Geocoder.html b/Apps/Sandcastle/gallery/Custom Geocoder.html index 5e6c82b4ebf..2804297cf80 100644 --- a/Apps/Sandcastle/gallery/Custom Geocoder.html +++ b/Apps/Sandcastle/gallery/Custom Geocoder.html @@ -42,7 +42,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin /** @@ -94,11 +94,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html index 862b8184a9b..7c50573d81d 100644 --- a/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -99,11 +99,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Post Process.html b/Apps/Sandcastle/gallery/Custom Post Process.html index 2e5b56fa077..213efedaded 100644 --- a/Apps/Sandcastle/gallery/Custom Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Post Process.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -82,11 +82,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html index a2574c83403..379785a1d35 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -80,11 +80,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Models.html b/Apps/Sandcastle/gallery/Custom Shaders Models.html index 7bb052eba6f..6349c9fa5c1 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Models.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Models.html @@ -39,7 +39,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -480,11 +480,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index f4f6d71ce81..96348e33498 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -39,13 +39,20 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); const scene = viewer.scene; + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + scene.globe.depthTestAgainstTerrain = false; // MAXAR OWT Muscatatuk photogrammetry dataset with property textures @@ -121,11 +128,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cylinders and Cones.html b/Apps/Sandcastle/gallery/Cylinders and Cones.html index 675d9c33288..988dee263ca 100644 --- a/Apps/Sandcastle/gallery/Cylinders and Cones.html +++ b/Apps/Sandcastle/gallery/Cylinders and Cones.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,11 +64,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/DataSource Ordering.html b/Apps/Sandcastle/gallery/DataSource Ordering.html index bb198bd2d8e..a7dec9729ec 100644 --- a/Apps/Sandcastle/gallery/DataSource Ordering.html +++ b/Apps/Sandcastle/gallery/DataSource Ordering.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const czml1 = [ @@ -132,11 +132,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Depth of Field.html b/Apps/Sandcastle/gallery/Depth of Field.html index bf42dbe65bb..4dc901ab722 100644 --- a/Apps/Sandcastle/gallery/Depth of Field.html +++ b/Apps/Sandcastle/gallery/Depth of Field.html @@ -89,7 +89,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -174,11 +174,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Distance Display Conditions.html b/Apps/Sandcastle/gallery/Distance Display Conditions.html index dbd67502df3..ad18acdf621 100644 --- a/Apps/Sandcastle/gallery/Distance Display Conditions.html +++ b/Apps/Sandcastle/gallery/Distance Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -126,11 +126,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index 48aa17c1a5a..57e21acb0f6 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -43,15 +43,22 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { selectionIndicator: false, infoBox: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK ); @@ -176,11 +183,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Earth at Night.html b/Apps/Sandcastle/gallery/Earth at Night.html index 4df50fd541b..0768b531127 100644 --- a/Apps/Sandcastle/gallery/Earth at Night.html +++ b/Apps/Sandcastle/gallery/Earth at Night.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // The Earth at Night, also known as Black Marble 2017 and Night Lights @@ -78,11 +78,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Elevation Band Material.html b/Apps/Sandcastle/gallery/Elevation Band Material.html index 7b3abd2b84f..42fc231b535 100644 --- a/Apps/Sandcastle/gallery/Elevation Band Material.html +++ b/Apps/Sandcastle/gallery/Elevation Band Material.html @@ -115,215 +115,228 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); - - viewer.camera.setView({ - destination: new Cesium.Cartesian3( - 290637.5534733206, - 5637471.593707632, - 2978256.8126927214 - ), - orientation: { - heading: 4.747266966349747, - pitch: -0.2206998858596192, - roll: 6.280340554587955, - }, - }); - - const viewModel = { - gradient: false, - band1Position: 7000.0, - band2Position: 7500.0, - band3Position: 8000.0, - bandThickness: 100.0, - bandTransparency: 0.5, - backgroundTransparency: 0.75, - }; - - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout - .getObservable(viewModel, name) - .subscribe(updateMaterial); - } - } + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }), + }); - function updateMaterial() { - const gradient = Boolean(viewModel.gradient); - const band1Position = Number(viewModel.band1Position); - const band2Position = Number(viewModel.band2Position); - const band3Position = Number(viewModel.band3Position); - const bandThickness = Number(viewModel.bandThickness); - const bandTransparency = Number(viewModel.bandTransparency); - const backgroundTransparency = Number( - viewModel.backgroundTransparency - ); + viewer.camera.setView({ + destination: new Cesium.Cartesian3( + 290637.5534733206, + 5637471.593707632, + 2978256.8126927214 + ), + orientation: { + heading: 4.747266966349747, + pitch: -0.2206998858596192, + roll: 6.280340554587955, + }, + }); - const layers = []; - const backgroundLayer = { - entries: [ - { - height: 4200.0, - color: new Cesium.Color(0.0, 0.0, 0.2, backgroundTransparency), - }, - { - height: 8000.0, - color: new Cesium.Color(1.0, 1.0, 1.0, backgroundTransparency), - }, - { - height: 8500.0, - color: new Cesium.Color(1.0, 0.0, 0.0, backgroundTransparency), - }, - ], - extendDownwards: true, - extendUpwards: true, + const viewModel = { + gradient: false, + band1Position: 7000.0, + band2Position: 7500.0, + band3Position: 8000.0, + bandThickness: 100.0, + bandTransparency: 0.5, + backgroundTransparency: 0.75, }; - layers.push(backgroundLayer); - const gridStartHeight = 4200.0; - const gridEndHeight = 8848.0; - const gridCount = 50; - for (let i = 0; i < gridCount; i++) { - const lerper = i / (gridCount - 1); - const heightBelow = Cesium.Math.lerp( - gridStartHeight, - gridEndHeight, - lerper - ); - const heightAbove = heightBelow + 10.0; - const alpha = - Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; - layers.push({ - entries: [ - { - height: heightBelow, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - { - height: heightAbove, - color: new Cesium.Color(1.0, 1.0, 1.0, alpha), - }, - ], - }); + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout + .getObservable(viewModel, name) + .subscribe(updateMaterial); + } } - const antialias = Math.min(10.0, bandThickness * 0.1); + function updateMaterial() { + const gradient = Boolean(viewModel.gradient); + const band1Position = Number(viewModel.band1Position); + const band2Position = Number(viewModel.band2Position); + const band3Position = Number(viewModel.band3Position); + const bandThickness = Number(viewModel.bandThickness); + const bandTransparency = Number(viewModel.bandTransparency); + const backgroundTransparency = Number( + viewModel.backgroundTransparency + ); - if (!gradient) { - const band1 = { + const layers = []; + const backgroundLayer = { entries: [ { - height: band1Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), - }, - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + height: 4200.0, + color: new Cesium.Color( + 0.0, + 0.0, + 0.2, + backgroundTransparency + ), }, { - height: band1Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + height: 8000.0, + color: new Cesium.Color( + 1.0, + 1.0, + 1.0, + backgroundTransparency + ), }, { - height: band1Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + height: 8500.0, + color: new Cesium.Color( + 1.0, + 0.0, + 0.0, + backgroundTransparency + ), }, ], + extendDownwards: true, + extendUpwards: true, }; + layers.push(backgroundLayer); - const band2 = { - entries: [ - { - height: band2Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - { - height: band2Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band2Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), - }, - ], - }; + const gridStartHeight = 4200.0; + const gridEndHeight = 8848.0; + const gridCount = 50; + for (let i = 0; i < gridCount; i++) { + const lerper = i / (gridCount - 1); + const heightBelow = Cesium.Math.lerp( + gridStartHeight, + gridEndHeight, + lerper + ); + const heightAbove = heightBelow + 10.0; + const alpha = + Cesium.Math.lerp(0.2, 0.4, lerper) * backgroundTransparency; + layers.push({ + entries: [ + { + height: heightBelow, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + { + height: heightAbove, + color: new Cesium.Color(1.0, 1.0, 1.0, alpha), + }, + ], + }); + } - const band3 = { - entries: [ - { - height: band3Position - bandThickness * 0.5 - antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - { - height: band3Position - bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5 + antialias, - color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), - }, - ], - }; + const antialias = Math.min(10.0, bandThickness * 0.1); - layers.push(band1); - layers.push(band2); - layers.push(band3); - } else { - const combinedBand = { - entries: [ - { - height: band1Position - bandThickness * 0.5, - color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), - }, - { - height: band2Position, - color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), - }, - { - height: band3Position + bandThickness * 0.5, - color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), - }, - ], - }; + if (!gradient) { + const band1 = { + entries: [ + { + height: band1Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + }, + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band1Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band1Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 0.0, 1.0, 0.0), + }, + ], + }; - layers.push(combinedBand); - } + const band2 = { + entries: [ + { + height: band2Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + { + height: band2Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band2Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(0.0, 1.0, 0.0, 0.0), + }, + ], + }; - const material = Cesium.createElevationBandMaterial({ - scene: viewer.scene, - layers: layers, - }); - viewer.scene.globe.material = material; - } + const band3 = { + entries: [ + { + height: band3Position - bandThickness * 0.5 - antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + { + height: band3Position - bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5 + antialias, + color: new Cesium.Color(1.0, 0.0, 0.0, 0.0), + }, + ], + }; + + layers.push(band1); + layers.push(band2); + layers.push(band3); + } else { + const combinedBand = { + entries: [ + { + height: band1Position - bandThickness * 0.5, + color: new Cesium.Color(0.0, 0.0, 1.0, bandTransparency), + }, + { + height: band2Position, + color: new Cesium.Color(0.0, 1.0, 0.0, bandTransparency), + }, + { + height: band3Position + bandThickness * 0.5, + color: new Cesium.Color(1.0, 0.0, 0.0, bandTransparency), + }, + ], + }; + + layers.push(combinedBand); + } + + const material = Cesium.createElevationBandMaterial({ + scene: viewer.scene, + layers: layers, + }); + viewer.scene.globe.material = material; + } - updateMaterial(); //Sandcastle_End + updateMaterial(); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Export KML.html b/Apps/Sandcastle/gallery/Export KML.html index ad571fa82b8..379f8efa34f 100644 --- a/Apps/Sandcastle/gallery/Export KML.html +++ b/Apps/Sandcastle/gallery/Export KML.html @@ -35,7 +35,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -160,11 +160,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index dc5d0be7e25..24325ed8467 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -29,47 +29,45 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 1331419.302230775, - -4656681.5022043325, - 4136232.6465900405 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.032455545102689, - -0.056832496140112765, - 6.282360923090216 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 1331419.302230775, + -4656681.5022043325, + 4136232.6465900405 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.032455545102689, + -0.056832496140112765, + 6.282360923090216 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(75343), + }) + ); - viewer.scene.postProcessStages.fxaa.enabled = true; + viewer.scene.postProcessStages.fxaa.enabled = true; - Sandcastle.addToggleButton("FXAA", true, function (checked) { - viewer.scene.postProcessStages.fxaa.enabled = checked; - }); //Sandcastle_End + Sandcastle.addToggleButton("FXAA", true, function (checked) { + viewer.scene.postProcessStages.fxaa.enabled = checked; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Fog Post Process.html b/Apps/Sandcastle/gallery/Fog Post Process.html index 7c9bc4a0366..3cedae53ed7 100644 --- a/Apps/Sandcastle/gallery/Fog Post Process.html +++ b/Apps/Sandcastle/gallery/Fog Post Process.html @@ -27,7 +27,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -110,11 +110,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index 8f1f31fdcff..05ac4f4bae7 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -31,12 +31,18 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); const pinBuilder = new Cesium.PinBuilder(); @@ -142,11 +148,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html index 4c30f772d3e..2cab2f0f6fd 100644 --- a/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html +++ b/Apps/Sandcastle/gallery/GeoJSON and TopoJSON.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -127,11 +127,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html index 94c310132ea..ee2179d9cca 100644 --- a/Apps/Sandcastle/gallery/GeoJSON simplestyle.html +++ b/Apps/Sandcastle/gallery/GeoJSON simplestyle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin //Load a GeoJSON file containing simplestyle information. @@ -57,11 +57,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index 1ac2145e111..d2f0b09a20b 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -32,14 +32,13 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayerPicker: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); // depth test against terrain is required to make the polygons clamp to terrain @@ -82,6 +81,14 @@ }, ]); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const longitude = 6.950615989890521; const latitude = 45.79546589994886; const delta = 0.001; @@ -178,11 +185,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry and Appearances.html b/Apps/Sandcastle/gallery/Geometry and Appearances.html index f5a37940312..72551e7e97f 100644 --- a/Apps/Sandcastle/gallery/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -639,11 +639,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Interior.html b/Apps/Sandcastle/gallery/Globe Interior.html index 193ba773d20..5d5d60f81d8 100644 --- a/Apps/Sandcastle/gallery/Globe Interior.html +++ b/Apps/Sandcastle/gallery/Globe Interior.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -183,11 +183,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index 45e79c272f0..c9f92c36190 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -119,16 +119,22 @@ </div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, //Needed to visualize slope - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); viewer.scene.globe.enableLighting = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestVertexNormals: true, //Needed to visualize slope + }); + } catch (error) { + console.log(error); + } + })(); + function getElevationContourMaterial() { // Creates a composite material with both elevation shading and contour lines return new Cesium.Material({ @@ -422,11 +428,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index aedfafce413..87dc0c82f54 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -81,235 +81,233 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - const scene = viewer.scene; - const globe = scene.globe; + const scene = viewer.scene; + const globe = scene.globe; - scene.screenSpaceCameraController.enableCollisionDetection = false; - globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( - 400.0, - 0.0, - 800.0, - 1.0 - ); + scene.screenSpaceCameraController.enableCollisionDetection = false; + globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar( + 400.0, + 0.0, + 800.0, + 1.0 + ); - const longitude = -3.82518; - const latitude = 53.11728; - const height = 72.8; - const position = Cesium.Cartesian3.fromDegrees( - longitude, - latitude, - height - ); - const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; + const longitude = -3.82518; + const latitude = 53.11728; + const height = 72.8; + const position = Cesium.Cartesian3.fromDegrees( + longitude, + latitude, + height + ); + const url = "../../SampleData/models/ParcLeadMine/ParcLeadMine.glb"; - const entity = viewer.entities.add({ - name: url, - position: position, - model: { - uri: url, - }, - }); + const entity = viewer.entities.add({ + name: url, + position: position, + model: { + uri: url, + }, + }); - const polygon = viewer.entities.add({ - polygon: { - hierarchy: new Cesium.PolygonHierarchy( - Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8152789692233817, - 53.124521420389996, - 200.20779492422255, - -3.8165955002619016, - 53.12555934545405, - 205.85834336951655, - -3.8201599842222054, - 53.12388420656903, - 230.82362697069453, - -3.8198667503545027, - 53.123748567587455, - 225.53297006293968, - -3.8190548496317476, - 53.1240486000822, - 221.82677773619432, - -3.817536387097508, - 53.122763476393764, - 209.94136782255705, - -3.8169125359199336, - 53.12285547981627, - 210.96626238861327, - -3.8166873871853073, - 53.12299403424474, - 211.02223937734595, - -3.8163695374580873, - 53.12300505277307, - 211.25942926271824, - -3.8162743040622313, - 53.12281471203994, - 212.35109129094147, - -3.8159746138174193, - 53.12280996651767, - 214.87977416348798, - -3.815429896849304, - 53.1236135347983, - 209.72496223706005, - ]) - ), - material: Cesium.Color.LIME.withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + const polygon = viewer.entities.add({ + polygon: { + hierarchy: new Cesium.PolygonHierarchy( + Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8152789692233817, + 53.124521420389996, + 200.20779492422255, + -3.8165955002619016, + 53.12555934545405, + 205.85834336951655, + -3.8201599842222054, + 53.12388420656903, + 230.82362697069453, + -3.8198667503545027, + 53.123748567587455, + 225.53297006293968, + -3.8190548496317476, + 53.1240486000822, + 221.82677773619432, + -3.817536387097508, + 53.122763476393764, + 209.94136782255705, + -3.8169125359199336, + 53.12285547981627, + 210.96626238861327, + -3.8166873871853073, + 53.12299403424474, + 211.02223937734595, + -3.8163695374580873, + 53.12300505277307, + 211.25942926271824, + -3.8162743040622313, + 53.12281471203994, + 212.35109129094147, + -3.8159746138174193, + 53.12280996651767, + 214.87977416348798, + -3.815429896849304, + 53.1236135347983, + 209.72496223706005, + ]) + ), + material: Cesium.Color.LIME.withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - const polyline = viewer.entities.add({ - polyline: { - positions: Cesium.Cartesian3.fromDegreesArrayHeights([ - -3.8098444201746373, - 53.1190304262546, - 286.1875170545701, - -3.8099801237370663, - 53.119539531697576, - 288.7733884242394, - -3.810165716635671, - 53.11979180761567, - 290.9294630315179, - -3.8104840812145357, - 53.12007534956926, - 292.6392327626228, - -3.8105689502073554, - 53.120259094792196, - 292.222036965774, - -3.811027311824268, - 53.120409248874196, - 289.61356291617307, - -3.811530473295422, - 53.12063281057782, - 284.01098712543586, - -3.8120545342562693, - 53.120742539082435, - 280.118191867836, - -3.812444493044727, - 53.120813289759326, - 276.0400221387852, - -3.812779626711285, - 53.12094275348024, - 271.1187399484896, - -3.8133560322579494, - 53.12104757866638, - 263.3495497598578, - -3.8137266493960085, - 53.12120789867194, - 257.73878624321316, - -3.8142552291751133, - 53.121321248522904, - 251.87265828778177, - -3.814322603988525, - 53.12174170121103, - 238.7082749547689, - -3.8143764268391314, - 53.1219492923309, - 235.0371831845662, - -3.8148156514145786, - 53.12210819668669, - 230.2458816627467, - -3.8155394721966163, - 53.1222990144029, - 221.33319292262706, - -3.8159828072920927, - 53.12203093429715, - 223.66664756982703, - -3.816678108944717, - 53.12183939425214, - 223.8787312412801, - -3.817466081093726, - 53.121751900508535, - 224.52293229989735, - -3.8183082996527955, - 53.12173266141031, - 223.3672181535749, - ]), - width: 8, - material: new Cesium.PolylineOutlineMaterialProperty({ - color: Cesium.Color.YELLOW, - outlineWidth: 2, - outlineColor: Cesium.Color.BLACK, - }), - clampToGround: true, - }, - }); + const polyline = viewer.entities.add({ + polyline: { + positions: Cesium.Cartesian3.fromDegreesArrayHeights([ + -3.8098444201746373, + 53.1190304262546, + 286.1875170545701, + -3.8099801237370663, + 53.119539531697576, + 288.7733884242394, + -3.810165716635671, + 53.11979180761567, + 290.9294630315179, + -3.8104840812145357, + 53.12007534956926, + 292.6392327626228, + -3.8105689502073554, + 53.120259094792196, + 292.222036965774, + -3.811027311824268, + 53.120409248874196, + 289.61356291617307, + -3.811530473295422, + 53.12063281057782, + 284.01098712543586, + -3.8120545342562693, + 53.120742539082435, + 280.118191867836, + -3.812444493044727, + 53.120813289759326, + 276.0400221387852, + -3.812779626711285, + 53.12094275348024, + 271.1187399484896, + -3.8133560322579494, + 53.12104757866638, + 263.3495497598578, + -3.8137266493960085, + 53.12120789867194, + 257.73878624321316, + -3.8142552291751133, + 53.121321248522904, + 251.87265828778177, + -3.814322603988525, + 53.12174170121103, + 238.7082749547689, + -3.8143764268391314, + 53.1219492923309, + 235.0371831845662, + -3.8148156514145786, + 53.12210819668669, + 230.2458816627467, + -3.8155394721966163, + 53.1222990144029, + 221.33319292262706, + -3.8159828072920927, + 53.12203093429715, + 223.66664756982703, + -3.816678108944717, + 53.12183939425214, + 223.8787312412801, + -3.817466081093726, + 53.121751900508535, + 224.52293229989735, + -3.8183082996527955, + 53.12173266141031, + 223.3672181535749, + ]), + width: 8, + material: new Cesium.PolylineOutlineMaterialProperty({ + color: Cesium.Color.YELLOW, + outlineWidth: 2, + outlineColor: Cesium.Color.BLACK, + }), + clampToGround: true, + }, + }); - const viewModel = { - translucencyEnabled: true, - fadeByDistance: true, - showVectorData: false, - alpha: 0.5, - }; + const viewModel = { + translucencyEnabled: true, + fadeByDistance: true, + showVectorData: false, + alpha: 0.5, + }; - Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); - for (const name in viewModel) { - if (viewModel.hasOwnProperty(name)) { - Cesium.knockout.getObservable(viewModel, name).subscribe(update); + Cesium.knockout.track(viewModel); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); + for (const name in viewModel) { + if (viewModel.hasOwnProperty(name)) { + Cesium.knockout.getObservable(viewModel, name).subscribe(update); + } } - } - function update() { - globe.translucency.enabled = viewModel.translucencyEnabled; + function update() { + globe.translucency.enabled = viewModel.translucencyEnabled; - let alpha = Number(viewModel.alpha); - alpha = !isNaN(alpha) ? alpha : 1.0; - alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); + let alpha = Number(viewModel.alpha); + alpha = !isNaN(alpha) ? alpha : 1.0; + alpha = Cesium.Math.clamp(alpha, 0.0, 1.0); - globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; - globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance - ? 1.0 - : alpha; + globe.translucency.frontFaceAlphaByDistance.nearValue = alpha; + globe.translucency.frontFaceAlphaByDistance.farValue = viewModel.fadeByDistance + ? 1.0 + : alpha; - polygon.show = viewModel.showVectorData; - polyline.show = viewModel.showVectorData; - } - update(); + polygon.show = viewModel.showVectorData; + polyline.show = viewModel.showVectorData; + } + update(); - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 3826465.9884728403, - -254831.02751468265, - 5081387.671561018 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.3889450556243754, - -0.5276382514771969, - 6.282272566663295 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 3826465.9884728403, + -254831.02751468265, + 5081387.671561018 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.3889450556243754, + -0.5276382514771969, + 6.282272566663295 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.camera.flyTo({ - destination: new Cesium.Cartesian3( - 3827270.552916987, - -255123.18143177085, - 5079147.091351856 - ), - orientation: new Cesium.HeadingPitchRoll( - 3.2624281242239963, - -0.22213535190506972, - 6.282786783842843 - ), - duration: 5.0, - }); //Sandcastle_End + viewer.scene.camera.flyTo({ + destination: new Cesium.Cartesian3( + 3827270.552916987, + -255123.18143177085, + 5079147.091351856 + ), + orientation: new Cesium.HeadingPitchRoll( + 3.2624281242239963, + -0.22213535190506972, + 6.282786783842843 + ), + duration: 5.0, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index c0294f30c3e..2c7cb0c0461 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -32,39 +32,46 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( - new Cesium.Resource({ - url: "http://www.earthenterprise.org/3d", - proxy: new Cesium.DefaultProxy("/proxy/"), - }) - ); + (async () => { + try { + const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( + new Cesium.Resource({ + url: "http://www.earthenterprise.org/3d", + proxy: new Cesium.DefaultProxy("/proxy/"), + }) + ); - const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ - metadata: geeMetadata, - }), - terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( - geeMetadata - ), - baseLayerPicker: false, - }); + const viewer = new Cesium.Viewer("cesiumContainer", { + imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ + metadata: geeMetadata, + }), + terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( + geeMetadata + ), + baseLayerPicker: false, + }); - // Start off looking at San Francisco. - viewer.camera.setView({ - destination: Cesium.Rectangle.fromDegrees(-123.0, 36.0, -121.7, 39.0), - }); //Sandcastle_End + // Start off looking at San Francisco. + viewer.camera.setView({ + destination: Cesium.Rectangle.fromDegrees( + -123.0, + 36.0, + -121.7, + 39.0 + ), + }); + } catch (error) { + console.log(error); + } + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/HTML Overlays.html b/Apps/Sandcastle/gallery/HTML Overlays.html index 350edead2a5..79f78d5ff98 100644 --- a/Apps/Sandcastle/gallery/HTML Overlays.html +++ b/Apps/Sandcastle/gallery/HTML Overlays.html @@ -37,7 +37,7 @@ src="../images/Cesium_Logo_overlay.png" /> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,11 +64,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index 2e3de8a0ac6..e3c2dd80cfb 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -71,7 +71,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -265,11 +265,7 @@ <h1>Loading...</h1> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 649bb10945c..992c9b3f04f 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -41,11 +41,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/High Dynamic Range.html b/Apps/Sandcastle/gallery/High Dynamic Range.html index dce70daa0c1..abb4f589055 100644 --- a/Apps/Sandcastle/gallery/High Dynamic Range.html +++ b/Apps/Sandcastle/gallery/High Dynamic Range.html @@ -29,73 +29,71 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - shadows: true, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + shadows: true, + }); - if (!viewer.scene.highDynamicRangeSupported) { - window.alert("This browser does not support high dynamic range."); - } + if (!viewer.scene.highDynamicRangeSupported) { + window.alert("This browser does not support high dynamic range."); + } - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - -1915097.7863741855, - -4783356.851539908, - 3748887.43462683 - ), - orientation: new Cesium.HeadingPitchRoll( - 6.166004548388564, - -0.043242401760068994, - 0.002179961955988574 - ), - endTransform: Cesium.Matrix4.IDENTITY, - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + -1915097.7863741855, + -4783356.851539908, + 3748887.43462683 + ), + orientation: new Cesium.HeadingPitchRoll( + 6.166004548388564, + -0.043242401760068994, + 0.002179961955988574 + ), + endTransform: Cesium.Matrix4.IDENTITY, + }); - viewer.scene.highDynamicRange = true; + viewer.scene.highDynamicRange = true; - Sandcastle.addToggleButton("HDR", true, function (checked) { - viewer.scene.highDynamicRange = checked; - }); + Sandcastle.addToggleButton("HDR", true, function (checked) { + viewer.scene.highDynamicRange = checked; + }); - const url = - "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; - const position = Cesium.Cartesian3.fromRadians( - -1.9516424279517286, - 0.6322397098422969, - 1239.0006814631095 - ); - const heading = Cesium.Math.toRadians(-15.0); - const pitch = 0; - const roll = 0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const scale = 10.0; + const url = + "../../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf"; + const position = Cesium.Cartesian3.fromRadians( + -1.9516424279517286, + 0.6322397098422969, + 1239.0006814631095 + ); + const heading = Cesium.Math.toRadians(-15.0); + const pitch = 0; + const roll = 0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const scale = 10.0; - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: scale, - }, - }); //Sandcastle_End + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: scale, + }, + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 52d15402f4a..20cf6b8bf87 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -35,128 +35,129 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "San Francisco": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["San Francisco"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "San Francisco": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["San Francisco"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if (!Cesium.defined(name) && isNameProperty(fieldName)) { - name = fields[fieldName]; + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if ( + !Cesium.defined(name) && + isNameProperty(fieldName) + ) { + name = fields[fieldName]; + } } } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; - } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); + } } - } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; + } + return false; } - return false; - } //Sandcastle_End + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index 10052a04dbf..cebdb348a20 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -35,128 +35,129 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); - // More datasets to tour can be added here... - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - "New York": - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["New York"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // More datasets to tour can be added here... + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + "New York": + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours["New York"], + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); - // An entity object which will hold info about the currently selected feature for infobox display - const selectedEntity = new Cesium.Entity(); - // Show metadata in the InfoBox. - viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( - movement - ) { - // Pick a new feature - const pickedFeature = viewer.scene.pick(movement.position); - if (!Cesium.defined(pickedFeature)) { - return; - } + // An entity object which will hold info about the currently selected feature for infobox display + const selectedEntity = new Cesium.Entity(); + // Show metadata in the InfoBox. + viewer.screenSpaceEventHandler.setInputAction(function onLeftClick( + movement + ) { + // Pick a new feature + const pickedFeature = viewer.scene.pick(movement.position); + if (!Cesium.defined(pickedFeature)) { + return; + } - const pickedPosition = viewer.scene.pickPosition(movement.position); + const pickedPosition = viewer.scene.pickPosition(movement.position); - if ( - Cesium.defined(pickedFeature.content) && - Cesium.defined(pickedFeature.content.tile.i3sNode) - ) { - const i3sNode = pickedFeature.content.tile.i3sNode; - if (pickedPosition) { - i3sNode.loadFields().then(function () { - let description = "No attributes"; - let name; - console.log( - `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` - ); + if ( + Cesium.defined(pickedFeature.content) && + Cesium.defined(pickedFeature.content.tile.i3sNode) + ) { + const i3sNode = pickedFeature.content.tile.i3sNode; + if (pickedPosition) { + i3sNode.loadFields().then(function () { + let description = "No attributes"; + let name; + console.log( + `pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}` + ); - const fields = i3sNode.getFieldsForPickedPosition( - pickedPosition - ); - if (Object.keys(fields).length > 0) { - description = - '<table class="cesium-infoBox-defaultTable"><tbody>'; - for (const fieldName in fields) { - if (i3sNode.fields.hasOwnProperty(fieldName)) { - description += `<tr><th>${fieldName}</th><td>`; - description += `${fields[fieldName]}</td></tr>`; - console.log(`${fieldName}: ${fields[fieldName]}`); - if (!Cesium.defined(name) && isNameProperty(fieldName)) { - name = fields[fieldName]; + const fields = i3sNode.getFieldsForPickedPosition( + pickedPosition + ); + if (Object.keys(fields).length > 0) { + description = + '<table class="cesium-infoBox-defaultTable"><tbody>'; + for (const fieldName in fields) { + if (i3sNode.fields.hasOwnProperty(fieldName)) { + description += `<tr><th>${fieldName}</th><td>`; + description += `${fields[fieldName]}</td></tr>`; + console.log(`${fieldName}: ${fields[fieldName]}`); + if ( + !Cesium.defined(name) && + isNameProperty(fieldName) + ) { + name = fields[fieldName]; + } } } + description += `</tbody></table>`; + } + if (!Cesium.defined(name)) { + name = "unknown"; } - description += `</tbody></table>`; - } - if (!Cesium.defined(name)) { - name = "unknown"; - } - selectedEntity.name = name; - selectedEntity.description = description; - viewer.selectedEntity = selectedEntity; - }); + selectedEntity.name = name; + selectedEntity.description = description; + viewer.selectedEntity = selectedEntity; + }); + } } - } - }, - Cesium.ScreenSpaceEventType.LEFT_CLICK); + }, + Cesium.ScreenSpaceEventType.LEFT_CLICK); - function isNameProperty(propertyName) { - const name = propertyName.toLowerCase(); - if ( - name.localeCompare("name") === 0 || - name.localeCompare("objname") === 0 - ) { - return true; + function isNameProperty(propertyName) { + const name = propertyName.toLowerCase(); + if ( + name.localeCompare("name") === 0 || + name.localeCompare("objname") === 0 + ) { + return true; + } + return false; } - return false; - } //Sandcastle_End + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } }; </script> diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 305d18ae14a..67740dbba17 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -35,63 +35,61 @@ <h1>Loading...</h1> </div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - animation: false, - timeline: false, - }); - // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry - viewer.scene.globe.depthTestAgainstTerrain = false; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + animation: false, + timeline: false, + }); + // Suppress terrain data to avoid clashing with IntegratedMesh layer geometry + viewer.scene.globe.depthTestAgainstTerrain = false; - // More datasets to tour can be added here.. - // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. - const tours = { - Frankfurt: - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", - }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); + // More datasets to tour can be added here.. + // The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer. + const tours = { + Frankfurt: + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", + }; + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours.Frankfurt, - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + url: tours.Frankfurt, + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); //Sandcastle_End + // Center camera on I3S once it's loaded + await i3sProvider.readyPromise; + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); + })(); //Sandcastle_End if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } }; </script> diff --git a/Apps/Sandcastle/gallery/Image-Based Lighting.html b/Apps/Sandcastle/gallery/Image-Based Lighting.html index 2373af5bf4a..b3d86ab57a1 100644 --- a/Apps/Sandcastle/gallery/Image-Based Lighting.html +++ b/Apps/Sandcastle/gallery/Image-Based Lighting.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -211,11 +211,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Adjustment.html b/Apps/Sandcastle/gallery/Imagery Adjustment.html index 85c0ef7d7b5..8bbad64dee0 100644 --- a/Apps/Sandcastle/gallery/Imagery Adjustment.html +++ b/Apps/Sandcastle/gallery/Imagery Adjustment.html @@ -112,7 +112,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -170,11 +170,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html index 1f8f2a00ac5..a67c9850665 100644 --- a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html +++ b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html @@ -54,7 +54,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -97,11 +97,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Cutout.html b/Apps/Sandcastle/gallery/Imagery Cutout.html index 42f6849d594..0b2164e24f9 100644 --- a/Apps/Sandcastle/gallery/Imagery Cutout.html +++ b/Apps/Sandcastle/gallery/Imagery Cutout.html @@ -46,7 +46,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -186,11 +186,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html index 2543e34d8d0..80b2ccff9b0 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html @@ -104,7 +104,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -329,11 +329,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Split.html b/Apps/Sandcastle/gallery/Imagery Layers Split.html index 8a05cdf5c3f..5ea11e8c89c 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Split.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Split.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -115,11 +115,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html index 23c723f7286..f0103e83eaa 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html @@ -53,7 +53,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -120,11 +120,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Imagery Layers.html b/Apps/Sandcastle/gallery/Imagery Layers.html index 29bdf0e9148..e439295682c 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers.html +++ b/Apps/Sandcastle/gallery/Imagery Layers.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -64,11 +64,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index c5fb3897f13..5c85423b399 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -34,16 +34,23 @@ <div id="interpolationMenu"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, //Disable InfoBox widget selectionIndicator: false, //Disable selection indicator shouldAnimate: true, // Enable animations - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + //Enable lighting based on the sun position viewer.scene.globe.enableLighting = true; @@ -204,11 +211,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML Tours.html b/Apps/Sandcastle/gallery/KML Tours.html index 9a8a065f6ea..8b2d6d51e06 100644 --- a/Apps/Sandcastle/gallery/KML Tours.html +++ b/Apps/Sandcastle/gallery/KML Tours.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -81,11 +81,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/KML.html b/Apps/Sandcastle/gallery/KML.html index 1c61653e0a6..b2d1ef68b40 100644 --- a/Apps/Sandcastle/gallery/KML.html +++ b/Apps/Sandcastle/gallery/KML.html @@ -30,7 +30,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -102,11 +102,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Labels.html b/Apps/Sandcastle/gallery/Labels.html index dc6f65433af..ccb621e2fda 100644 --- a/Apps/Sandcastle/gallery/Labels.html +++ b/Apps/Sandcastle/gallery/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -272,11 +272,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/LensFlare.html b/Apps/Sandcastle/gallery/LensFlare.html index 97fb4a52785..c081194cd14 100644 --- a/Apps/Sandcastle/gallery/LensFlare.html +++ b/Apps/Sandcastle/gallery/LensFlare.html @@ -101,7 +101,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -172,11 +172,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index 4b759cce2de..38cc8b0ee9c 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -29,18 +29,24 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); const scene = viewer.scene; scene.globe.enableLighting = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + } catch (error) { + console.log(error); + } + })(); + const scratchIcrfToFixed = new Cesium.Matrix3(); const scratchMoonPosition = new Cesium.Cartesian3(); const scratchMoonDirection = new Cesium.Cartesian3(); @@ -230,11 +236,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 3fed0aaf87a..77761084409 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -62,7 +62,7 @@ <h1>Loading...</h1> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -278,11 +278,7 @@ <h1>Loading...</h1> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index dc532f40c75..dd21568c7bb 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -29,16 +29,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { contextOptions: { requestWebgl1: false, }, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( "2022-08-01T00:00:00Z" ); @@ -180,11 +187,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Manually Controlled Animation.html b/Apps/Sandcastle/gallery/Manually Controlled Animation.html index c93b14eb6cb..4eda60808f5 100644 --- a/Apps/Sandcastle/gallery/Manually Controlled Animation.html +++ b/Apps/Sandcastle/gallery/Manually Controlled Animation.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -160,11 +160,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Map Pins.html b/Apps/Sandcastle/gallery/Map Pins.html index 5a5e8fecf57..cc92aea49ca 100644 --- a/Apps/Sandcastle/gallery/Map Pins.html +++ b/Apps/Sandcastle/gallery/Map Pins.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -97,11 +97,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index 85c50917828..f6815a30fc0 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin let rectangle; @@ -625,11 +625,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index d2feabfc90c..ac71f6fb445 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -83,12 +83,18 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. const tileset = viewer.scene.primitives.add( @@ -427,11 +433,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multi-part CZML.html b/Apps/Sandcastle/gallery/Multi-part CZML.html index 75f97dbe17b..c5f9823e327 100644 --- a/Apps/Sandcastle/gallery/Multi-part CZML.html +++ b/Apps/Sandcastle/gallery/Multi-part CZML.html @@ -36,7 +36,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -174,11 +174,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Multiple Synced Views.html b/Apps/Sandcastle/gallery/Multiple Synced Views.html index e7502566cb7..48fc895f15d 100644 --- a/Apps/Sandcastle/gallery/Multiple Synced Views.html +++ b/Apps/Sandcastle/gallery/Multiple Synced Views.html @@ -48,7 +48,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // We want our two views to be synced across time, so we create @@ -124,11 +124,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Natural Earth II.html b/Apps/Sandcastle/gallery/Natural Earth II.html index 22d2a482f6c..9e93c6ee30f 100644 --- a/Apps/Sandcastle/gallery/Natural Earth II.html +++ b/Apps/Sandcastle/gallery/Natural Earth II.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Natural Earth II with Shaded Relief, Water, and Drainages from http://www.naturalearthdata.com @@ -44,11 +44,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Offline.html b/Apps/Sandcastle/gallery/Offline.html index 6cc44971b78..3f16e831458 100644 --- a/Apps/Sandcastle/gallery/Offline.html +++ b/Apps/Sandcastle/gallery/Offline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // This is an example of using Cesium "Offline", meaning disconnected from the @@ -52,11 +52,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index 89d228bd397..ca33b2cb9af 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -32,16 +32,22 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) - // http://www.pasda.psu.edu/ - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) - ), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) + // http://www.pasda.psu.edu/ + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( + Cesium.IonResource.fromAssetId(3957) + ); + } catch (error) { + console.log(error); + } + })(); // Add PA locations Sandcastle.addDefaultToolbarMenu( @@ -139,11 +145,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Parallels and Meridians.html b/Apps/Sandcastle/gallery/Parallels and Meridians.html index 34a030ac97c..ef643aea418 100644 --- a/Apps/Sandcastle/gallery/Parallels and Meridians.html +++ b/Apps/Sandcastle/gallery/Parallels and Meridians.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -315,11 +315,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Partial Ellipsoids.html b/Apps/Sandcastle/gallery/Partial Ellipsoids.html index 486ecc790d3..ee2c0507e63 100644 --- a/Apps/Sandcastle/gallery/Partial Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Partial Ellipsoids.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -218,11 +218,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Fireworks.html b/Apps/Sandcastle/gallery/Particle System Fireworks.html index d93d8a0b526..394ec79af33 100644 --- a/Apps/Sandcastle/gallery/Particle System Fireworks.html +++ b/Apps/Sandcastle/gallery/Particle System Fireworks.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -216,11 +216,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Tails.html b/Apps/Sandcastle/gallery/Particle System Tails.html index 532e8b25534..460e1d34123 100644 --- a/Apps/Sandcastle/gallery/Particle System Tails.html +++ b/Apps/Sandcastle/gallery/Particle System Tails.html @@ -35,7 +35,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -301,11 +301,7 @@ if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index 10d17b9fe9e..00602ce0216 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -32,16 +32,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const resetCameraFunction = function () { scene.camera.setView({ destination: new Cesium.Cartesian3( @@ -207,11 +214,7 @@ if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Particle System.html b/Apps/Sandcastle/gallery/Particle System.html index 31c140e4c84..ee7a74cd7ed 100644 --- a/Apps/Sandcastle/gallery/Particle System.html +++ b/Apps/Sandcastle/gallery/Particle System.html @@ -184,7 +184,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -464,11 +464,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html index 04d565700b7..aa0ae29f9f1 100644 --- a/Apps/Sandcastle/gallery/Per-Feature Post Processing.html +++ b/Apps/Sandcastle/gallery/Per-Feature Post Processing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -115,11 +115,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index 2053d9277ff..88174baecdb 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const clock = new Cesium.Clock({ @@ -48,9 +48,16 @@ const viewer = new Cesium.Viewer("cesiumContainer", { clockViewModel: new Cesium.ClockViewModel(clock), selectionIndicator: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( checked ) { @@ -196,11 +203,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Picking.html b/Apps/Sandcastle/gallery/Picking.html index c9f020738ff..19756c17f4d 100644 --- a/Apps/Sandcastle/gallery/Picking.html +++ b/Apps/Sandcastle/gallery/Picking.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -285,11 +285,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Plane.html b/Apps/Sandcastle/gallery/Plane.html index 10e384b04f2..0d8572df798 100644 --- a/Apps/Sandcastle/gallery/Plane.html +++ b/Apps/Sandcastle/gallery/Plane.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -74,11 +74,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Points.html b/Apps/Sandcastle/gallery/Points.html index f331ae9571c..65068c79586 100644 --- a/Apps/Sandcastle/gallery/Points.html +++ b/Apps/Sandcastle/gallery/Points.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -190,11 +190,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polygon.html b/Apps/Sandcastle/gallery/Polygon.html index 22d3ab1ce1e..e275ab7416a 100644 --- a/Apps/Sandcastle/gallery/Polygon.html +++ b/Apps/Sandcastle/gallery/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -310,11 +310,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Dash.html b/Apps/Sandcastle/gallery/Polyline Dash.html index 3a7f51ae46c..10143d01cba 100644 --- a/Apps/Sandcastle/gallery/Polyline Dash.html +++ b/Apps/Sandcastle/gallery/Polyline Dash.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,11 +134,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline Volume.html b/Apps/Sandcastle/gallery/Polyline Volume.html index 58a248c9240..f84d3fc48d5 100644 --- a/Apps/Sandcastle/gallery/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,11 +134,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polyline.html b/Apps/Sandcastle/gallery/Polyline.html index 4231f442c9d..9a61abfa196 100644 --- a/Apps/Sandcastle/gallery/Polyline.html +++ b/Apps/Sandcastle/gallery/Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -134,11 +134,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html index 12047e59746..9ce5117991f 100644 --- a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Power Plant design model provided by Bentley Systems @@ -187,11 +187,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Post Processing.html b/Apps/Sandcastle/gallery/Post Processing.html index 1da345d7ece..c46168a33d1 100644 --- a/Apps/Sandcastle/gallery/Post Processing.html +++ b/Apps/Sandcastle/gallery/Post Processing.html @@ -77,7 +77,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -156,11 +156,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Procedural Terrain.html b/Apps/Sandcastle/gallery/Procedural Terrain.html index 0a9f70ffc1b..5812bdb4928 100644 --- a/Apps/Sandcastle/gallery/Procedural Terrain.html +++ b/Apps/Sandcastle/gallery/Procedural Terrain.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -167,11 +167,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Projection.html b/Apps/Sandcastle/gallery/Projection.html index f2e5dc4b963..214d3d04385 100644 --- a/Apps/Sandcastle/gallery/Projection.html +++ b/Apps/Sandcastle/gallery/Projection.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Click the projection picker to switch between orthographic and perspective projections. @@ -73,11 +73,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rectangle.html b/Apps/Sandcastle/gallery/Rectangle.html index b2b95834db1..17df5070eef 100644 --- a/Apps/Sandcastle/gallery/Rectangle.html +++ b/Apps/Sandcastle/gallery/Rectangle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -92,11 +92,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Resolution Scaling.html b/Apps/Sandcastle/gallery/Resolution Scaling.html index 3d888e60f2d..ef9d6bb7bc0 100644 --- a/Apps/Sandcastle/gallery/Resolution Scaling.html +++ b/Apps/Sandcastle/gallery/Resolution Scaling.html @@ -59,7 +59,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // When browser recommended resolution is enabled, the viewer renders at @@ -106,11 +106,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Rotatable 2D Map.html b/Apps/Sandcastle/gallery/Rotatable 2D Map.html index 1c2b6dc30dc..e99ceead9c5 100644 --- a/Apps/Sandcastle/gallery/Rotatable 2D Map.html +++ b/Apps/Sandcastle/gallery/Rotatable 2D Map.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -51,11 +51,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index f396cb09286..7ea5c50956e 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -32,14 +32,20 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); const scene = viewer.scene; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + if (!scene.clampToHeightSupported) { window.alert( "This browser does not support clampToHeightMostDetailed." @@ -129,11 +135,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index f5834c0a62b..a2be63b6796 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -138,7 +138,7 @@ <h4>Max delta time</h4> </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create a viewer that won't render a new frame unless @@ -146,9 +146,16 @@ <h4>Max delta time</h4> const viewer = new Cesium.Viewer("cesiumContainer", { requestRenderMode: true, maximumRenderTimeChange: Infinity, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const scene = viewer.scene; scene.debugShowFramesPerSecond = true; @@ -353,11 +360,7 @@ <h4>Max delta time</h4> }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Sentinel-2.html b/Apps/Sandcastle/gallery/Sentinel-2.html index ff28abd86b5..2af73b5912e 100644 --- a/Apps/Sandcastle/gallery/Sentinel-2.html +++ b/Apps/Sandcastle/gallery/Sentinel-2.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Sentinel-2 (mostly) cloudless global imagery between 10 and 60 meter resolution. @@ -44,11 +44,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 0835e725e7d..2f45dff2724 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -41,9 +41,16 @@ shadows: true, terrainShadows: Cesium.ShadowMode.ENABLED, shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const shadowMap = viewer.shadowMap; shadowMap.maximumDistance = 10000.0; @@ -303,11 +310,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Show or Hide Entities.html b/Apps/Sandcastle/gallery/Show or Hide Entities.html index 4cfef9d98d6..0a970559a77 100644 --- a/Apps/Sandcastle/gallery/Show or Hide Entities.html +++ b/Apps/Sandcastle/gallery/Show or Hide Entities.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin //Set the random seed for reproducible random colors. @@ -92,11 +92,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html index f5852df28f8..13dd56c02c8 100644 --- a/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html +++ b/Apps/Sandcastle/gallery/Spheres and Ellipsoids.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -73,11 +73,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Star Burst.html b/Apps/Sandcastle/gallery/Star Burst.html index 85b8cc3147b..bc998f384fd 100644 --- a/Apps/Sandcastle/gallery/Star Burst.html +++ b/Apps/Sandcastle/gallery/Star Burst.html @@ -31,7 +31,7 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -412,11 +412,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index 12df605a50d..31a3e5a8740 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -58,356 +58,363 @@ Edge styling enabled </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - // Use clipping planes to selectively hide parts of the globe surface. - const viewer = new Cesium.Viewer("cesiumContainer", { - skyAtmosphere: false, - shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - scene3DOnly: true, - }); - const globe = viewer.scene.globe; + (async () => { + // Use clipping planes to selectively hide parts of the globe surface. + const viewer = new Cesium.Viewer("cesiumContainer", { + skyAtmosphere: false, + shouldAnimate: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + scene3DOnly: true, + }); + const globe = viewer.scene.globe; - const exampleTypes = [ - "Cesium Man", - "St. Helens", - "Grand Canyon Isolated", - ]; - const viewModel = { - exampleTypes: exampleTypes, - currentExampleType: exampleTypes[0], - clippingPlanesEnabled: true, - edgeStylingEnabled: true, - }; - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.track(viewModel); - Cesium.knockout.applyBindings(viewModel, toolbar); + const exampleTypes = [ + "Cesium Man", + "St. Helens", + "Grand Canyon Isolated", + ]; + const viewModel = { + exampleTypes: exampleTypes, + currentExampleType: exampleTypes[0], + clippingPlanesEnabled: true, + edgeStylingEnabled: true, + }; + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.track(viewModel); + Cesium.knockout.applyBindings(viewModel, toolbar); - // For tracking state when switching exampleTypes - let clippingPlanesEnabled = true; - let edgeStylingEnabled = true; + // For tracking state when switching exampleTypes + let clippingPlanesEnabled = true; + let edgeStylingEnabled = true; - let tileset; + let tileset; - loadCesiumMan(); + loadCesiumMan(); - function reset() { - viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); - } + function reset() { + viewer.entities.removeAll(); + viewer.scene.primitives.remove(tileset); + } - function loadCesiumMan() { - const position = Cesium.Cartesian3.fromRadians( - -2.0862979473351286, - 0.6586620013036164, - 1400.0 - ); + function loadCesiumMan() { + const position = Cesium.Cartesian3.fromRadians( + -2.0862979473351286, + 0.6586620013036164, + 1400.0 + ); - const entity = viewer.entities.add({ - position: position, - box: { - dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), - material: Cesium.Color.WHITE.withAlpha(0.3), - outline: true, - outlineColor: Cesium.Color.WHITE, - }, - }); + const entity = viewer.entities.add({ + position: position, + box: { + dimensions: new Cesium.Cartesian3(1400.0, 1400.0, 2800.0), + material: Cesium.Color.WHITE.withAlpha(0.3), + outline: true, + outlineColor: Cesium.Color.WHITE, + }, + }); - viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - maximumScale: 800, - }, - }); + viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + maximumScale: 800, + }, + }); + + globe.depthTestAgainstTerrain = true; + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + -700.0 + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + -700.0 + ), + ], + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; + + viewer.trackedEntity = entity; + } - globe.depthTestAgainstTerrain = true; - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: entity.computeModelMatrix(Cesium.JulianDate.now()), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - -700.0 + function loadStHelens() { + // Create clipping planes for polygon around area to be clipped. + const points = [ + new Cesium.Cartesian3( + -2358434.3501556474, + -3743554.5012105294, + 4581080.771684084 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2357886.4482675144, + -3744467.562778789, + 4581020.9199767085 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2357299.84353055, + -3744954.0879047974, + 4581080.992360969 ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - -700.0 + new Cesium.Cartesian3( + -2356412.05169956, + -3745385.3013702347, + 4580893.4737207815 ), - ], - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; - - viewer.trackedEntity = entity; - } - - function loadStHelens() { - // Create clipping planes for polygon around area to be clipped. - const points = [ - new Cesium.Cartesian3( - -2358434.3501556474, - -3743554.5012105294, - 4581080.771684084 - ), - new Cesium.Cartesian3( - -2357886.4482675144, - -3744467.562778789, - 4581020.9199767085 - ), - new Cesium.Cartesian3( - -2357299.84353055, - -3744954.0879047974, - 4581080.992360969 - ), - new Cesium.Cartesian3( - -2356412.05169956, - -3745385.3013702347, - 4580893.4737207815 - ), - new Cesium.Cartesian3( - -2355472.889436636, - -3745256.5725702164, - 4581252.3128526565 - ), - new Cesium.Cartesian3( - -2354385.7458722834, - -3744319.3823686405, - 4582372.770031389 - ), - new Cesium.Cartesian3( - -2353758.788158616, - -3743051.0128084184, - 4583356.453176038 - ), - new Cesium.Cartesian3( - -2353663.8128999653, - -3741847.9126874236, - 4584079.428665509 - ), - new Cesium.Cartesian3( - -2354213.667592133, - -3740784.50946316, - 4584502.428203525 - ), - new Cesium.Cartesian3( - -2355596.239450013, - -3739901.0226732804, - 4584515.9652557485 - ), - new Cesium.Cartesian3( - -2356942.4170108805, - -3740342.454698685, - 4583686.690694482 - ), - new Cesium.Cartesian3( - -2357529.554838029, - -3740766.995076834, - 4583145.055348843 - ), - new Cesium.Cartesian3( - -2358106.017822064, - -3741439.438418052, - 4582452.293605261 - ), - new Cesium.Cartesian3( - -2358539.5426236596, - -3742680.720902901, - 4581692.0260975715 - ), - ]; - - const pointsLength = points.length; - - // Create center points for each clipping plane - const clippingPlanes = []; - for (let i = 0; i < pointsLength; ++i) { - const nextIndex = (i + 1) % pointsLength; - let midpoint = Cesium.Cartesian3.add( - points[i], - points[nextIndex], - new Cesium.Cartesian3() - ); - midpoint = Cesium.Cartesian3.multiplyByScalar( - midpoint, - 0.5, - midpoint - ); - - const up = Cesium.Cartesian3.normalize( - midpoint, - new Cesium.Cartesian3() - ); - let right = Cesium.Cartesian3.subtract( - points[nextIndex], - midpoint, - new Cesium.Cartesian3() - ); - right = Cesium.Cartesian3.normalize(right, right); - - let normal = Cesium.Cartesian3.cross( - right, - up, - new Cesium.Cartesian3() - ); - normal = Cesium.Cartesian3.normalize(normal, normal); - - // Compute distance by pretending the plane is at the origin - const originCenteredPlane = new Cesium.Plane(normal, 0.0); - const distance = Cesium.Plane.getPointDistance( - originCenteredPlane, - midpoint - ); + new Cesium.Cartesian3( + -2355472.889436636, + -3745256.5725702164, + 4581252.3128526565 + ), + new Cesium.Cartesian3( + -2354385.7458722834, + -3744319.3823686405, + 4582372.770031389 + ), + new Cesium.Cartesian3( + -2353758.788158616, + -3743051.0128084184, + 4583356.453176038 + ), + new Cesium.Cartesian3( + -2353663.8128999653, + -3741847.9126874236, + 4584079.428665509 + ), + new Cesium.Cartesian3( + -2354213.667592133, + -3740784.50946316, + 4584502.428203525 + ), + new Cesium.Cartesian3( + -2355596.239450013, + -3739901.0226732804, + 4584515.9652557485 + ), + new Cesium.Cartesian3( + -2356942.4170108805, + -3740342.454698685, + 4583686.690694482 + ), + new Cesium.Cartesian3( + -2357529.554838029, + -3740766.995076834, + 4583145.055348843 + ), + new Cesium.Cartesian3( + -2358106.017822064, + -3741439.438418052, + 4582452.293605261 + ), + new Cesium.Cartesian3( + -2358539.5426236596, + -3742680.720902901, + 4581692.0260975715 + ), + ]; - clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); - } - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - planes: clippingPlanes, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = true; - globe.showSkirts = true; + const pointsLength = points.length; - // Load tileset - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - return tileset.readyPromise - .then(function () { - // Adjust height so tileset is in terrain - const cartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center + // Create center points for each clipping plane + const clippingPlanes = []; + for (let i = 0; i < pointsLength; ++i) { + const nextIndex = (i + 1) % pointsLength; + let midpoint = Cesium.Cartesian3.add( + points[i], + points[nextIndex], + new Cesium.Cartesian3() ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 + midpoint = Cesium.Cartesian3.multiplyByScalar( + midpoint, + 0.5, + midpoint ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - -20.0 + + const up = Cesium.Cartesian3.normalize( + midpoint, + new Cesium.Cartesian3() ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, + let right = Cesium.Cartesian3.subtract( + points[nextIndex], + midpoint, new Cesium.Cartesian3() ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + right = Cesium.Cartesian3.normalize(right, right); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgb(207, 255, 207)", - }); + let normal = Cesium.Cartesian3.cross( + right, + up, + new Cesium.Cartesian3() + ); + normal = Cesium.Cartesian3.normalize(normal, normal); - viewer.scene.primitives.add(tileset); + // Compute distance by pretending the plane is at the origin + const originCenteredPlane = new Cesium.Plane(normal, 0.0); + const distance = Cesium.Plane.getPointDistance( + originCenteredPlane, + midpoint + ); - const boundingSphere = tileset.boundingSphere; + clippingPlanes.push(new Cesium.ClippingPlane(normal, distance)); + } + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + planes: clippingPlanes, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = true; + globe.showSkirts = true; - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; + // Load tileset + tileset = new Cesium.Cesium3DTileset({ + url: Cesium.IonResource.fromAssetId(5713), }); - } + return tileset.readyPromise + .then(function () { + // Adjust height so tileset is in terrain + const cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + -20.0 + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation( + translation + ); - function loadGrandCanyon() { - // Pick a position at the Grand Canyon - const position = Cesium.Cartographic.toCartesian( - new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) - ); - const distance = 3000.0; - const boundingSphere = new Cesium.BoundingSphere(position, distance); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgb(207, 255, 207)", + }); - globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), - planes: [ - new Cesium.ClippingPlane( - new Cesium.Cartesian3(1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(-1.0, 0.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, 1.0, 0.0), - distance - ), - new Cesium.ClippingPlane( - new Cesium.Cartesian3(0.0, -1.0, 0.0), - distance - ), - ], - unionClippingRegions: true, - edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, - edgeColor: Cesium.Color.WHITE, - enabled: clippingPlanesEnabled, - }); - globe.backFaceCulling = false; - globe.showSkirts = false; + viewer.scene.primitives.add(tileset); - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + const boundingSphere = tileset.boundingSphere; - Cesium.knockout - .getObservable(viewModel, "clippingPlanesEnabled") - .subscribe(function (value) { - globe.clippingPlanes.enabled = value; - clippingPlanesEnabled = value; - }); + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }) + .catch(function (error) { + throw error; + }); + } - Cesium.knockout - .getObservable(viewModel, "edgeStylingEnabled") - .subscribe(function (value) { - edgeStylingEnabled = value; - globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; - }); + function loadGrandCanyon() { + // Pick a position at the Grand Canyon + const position = Cesium.Cartographic.toCartesian( + new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100) + ); + const distance = 3000.0; + const boundingSphere = new Cesium.BoundingSphere( + position, + distance + ); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); - if (newValue === exampleTypes[0]) { - loadCesiumMan(); - } else if (newValue === exampleTypes[1]) { - loadStHelens(); - } else if (newValue === exampleTypes[2]) { - loadGrandCanyon(); - } - }); //Sandcastle_End + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), + planes: [ + new Cesium.ClippingPlane( + new Cesium.Cartesian3(1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(-1.0, 0.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, 1.0, 0.0), + distance + ), + new Cesium.ClippingPlane( + new Cesium.Cartesian3(0.0, -1.0, 0.0), + distance + ), + ], + unionClippingRegions: true, + edgeWidth: edgeStylingEnabled ? 1.0 : 0.0, + edgeColor: Cesium.Color.WHITE, + enabled: clippingPlanesEnabled, + }); + globe.backFaceCulling = false; + globe.showSkirts = false; + + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange( + 0.5, + -0.5, + boundingSphere.radius * 5.0 + ) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } + + Cesium.knockout + .getObservable(viewModel, "clippingPlanesEnabled") + .subscribe(function (value) { + globe.clippingPlanes.enabled = value; + clippingPlanesEnabled = value; + }); + + Cesium.knockout + .getObservable(viewModel, "edgeStylingEnabled") + .subscribe(function (value) { + edgeStylingEnabled = value; + globe.clippingPlanes.edgeWidth = edgeStylingEnabled ? 1.0 : 0.0; + }); + + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); + if (newValue === exampleTypes[0]) { + loadCesiumMan(); + } else if (newValue === exampleTypes[1]) { + loadStHelens(); + } else if (newValue === exampleTypes[2]) { + loadGrandCanyon(); + } + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index 21e990af927..b850b26fa29 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -73,12 +73,18 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); const scene = viewer.scene; const globe = scene.globe; @@ -196,11 +202,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index 594bfecd7c3..f1e50500145 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -36,15 +36,21 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + } catch (error) { + console.log(error); + } + })(); // set lighting to true viewer.scene.globe.enableLighting = true; @@ -342,11 +348,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html index a70d68ce8ce..e24fa0d05ab 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Point Cloud.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -98,11 +98,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html index 67183196b03..06875313330 100644 --- a/Apps/Sandcastle/gallery/Time Dynamic Wheels.html +++ b/Apps/Sandcastle/gallery/Time Dynamic Wheels.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -164,11 +164,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Underground Color.html b/Apps/Sandcastle/gallery/Underground Color.html index d613c3f7a68..8365de68ee2 100644 --- a/Apps/Sandcastle/gallery/Underground Color.html +++ b/Apps/Sandcastle/gallery/Underground Color.html @@ -108,7 +108,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -223,11 +223,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Video.html b/Apps/Sandcastle/gallery/Video.html index 80f821680a6..7aae2fc83d5 100644 --- a/Apps/Sandcastle/gallery/Video.html +++ b/Apps/Sandcastle/gallery/Video.html @@ -54,7 +54,7 @@ Your browser does not support the <code>video</code> element. </video> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -149,11 +149,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Wall.html b/Apps/Sandcastle/gallery/Wall.html index a9657fc6012..cae9bcbfa0e 100644 --- a/Apps/Sandcastle/gallery/Wall.html +++ b/Apps/Sandcastle/gallery/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -139,11 +139,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Washington DC 2017.html b/Apps/Sandcastle/gallery/Washington DC 2017.html index 7b12ae52697..8423c0500b9 100644 --- a/Apps/Sandcastle/gallery/Washington DC 2017.html +++ b/Apps/Sandcastle/gallery/Washington DC 2017.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // 3 inch (0.08m) resolution imagery of Washington DC collected in 2017 @@ -47,11 +47,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Service (WMS).html b/Apps/Sandcastle/gallery/Web Map Service (WMS).html index c5c840e7304..4f40bb976dd 100644 --- a/Apps/Sandcastle/gallery/Web Map Service (WMS).html +++ b/Apps/Sandcastle/gallery/Web Map Service (WMS).html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -64,11 +64,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html index 65577b66c7d..d9459c56ed5 100644 --- a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html +++ b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -98,11 +98,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html index 142a89d16da..6a6ef173d75 100644 --- a/Apps/Sandcastle/gallery/Z-Indexing Geometry.html +++ b/Apps/Sandcastle/gallery/Z-Indexing Geometry.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -145,11 +145,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Articulations.html b/Apps/Sandcastle/gallery/development/3D Models Articulations.html index fe0e56fdf4c..45167af0546 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Articulations.html +++ b/Apps/Sandcastle/gallery/development/3D Models Articulations.html @@ -74,7 +74,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -186,11 +186,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html index 0839cb27f7a..6a04aad8b4a 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html +++ b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html @@ -189,7 +189,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // this can be changed to any glTF model @@ -373,11 +373,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Models.html b/Apps/Sandcastle/gallery/development/3D Models.html index 0b8f9fb4da7..8cfd8dd20d7 100644 --- a/Apps/Sandcastle/gallery/development/3D Models.html +++ b/Apps/Sandcastle/gallery/development/3D Models.html @@ -90,7 +90,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -309,11 +309,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html index ebada4cc901..f7622c5f4de 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin /* @@ -266,11 +266,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Split.html b/Apps/Sandcastle/gallery/development/3D Tiles Split.html index b94905a7200..2d96e548c97 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Split.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Split.html @@ -57,7 +57,7 @@ <div><input type="checkbox" data-bind="checked: shadows" /> Shadows</div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -287,11 +287,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 07751bff1ae..2ee1b79cbc6 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -34,14 +34,20 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); viewer.scene.globe.depthTestAgainstTerrain = true; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const ellipsoid = viewer.scene.globe.ellipsoid; const billboardCollection = viewer.scene.primitives.add( new Cesium.BillboardCollection({ @@ -167,11 +173,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index 930719ba457..00861a900fa 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -34,12 +34,18 @@ <div id="sampleButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); const scene = viewer.scene; const context = scene.context; @@ -231,11 +237,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Billboards.html b/Apps/Sandcastle/gallery/development/Billboards.html index c175f593235..21d2f91c95e 100644 --- a/Apps/Sandcastle/gallery/development/Billboards.html +++ b/Apps/Sandcastle/gallery/development/Billboards.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -427,11 +427,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box Outline.html b/Apps/Sandcastle/gallery/development/Box Outline.html index 19c2c40d95d..31747ce8366 100644 --- a/Apps/Sandcastle/gallery/development/Box Outline.html +++ b/Apps/Sandcastle/gallery/development/Box Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -84,11 +84,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Box.html b/Apps/Sandcastle/gallery/development/Box.html index 8d9484ffb43..442fc703307 100644 --- a/Apps/Sandcastle/gallery/development/Box.html +++ b/Apps/Sandcastle/gallery/development/Box.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -78,11 +78,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle Outline.html b/Apps/Sandcastle/gallery/development/Circle Outline.html index 59df803fcb3..c31e527b256 100644 --- a/Apps/Sandcastle/gallery/development/Circle Outline.html +++ b/Apps/Sandcastle/gallery/development/Circle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -103,11 +103,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Circle.html b/Apps/Sandcastle/gallery/development/Circle.html index a056d327cb1..0a6e4395712 100644 --- a/Apps/Sandcastle/gallery/development/Circle.html +++ b/Apps/Sandcastle/gallery/development/Circle.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -134,11 +134,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html index 4045af73867..65189eb90ee 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon Outline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -140,11 +140,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html index f03639448db..f88679c18cf 100644 --- a/Apps/Sandcastle/gallery/development/Coplanar Polygon.html +++ b/Apps/Sandcastle/gallery/development/Coplanar Polygon.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -174,11 +174,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor Outline.html b/Apps/Sandcastle/gallery/development/Corridor Outline.html index 750f89e3502..0102e56700c 100644 --- a/Apps/Sandcastle/gallery/development/Corridor Outline.html +++ b/Apps/Sandcastle/gallery/development/Corridor Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -102,11 +102,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor.html b/Apps/Sandcastle/gallery/development/Corridor.html index e9ecfa088a5..3be94a10825 100644 --- a/Apps/Sandcastle/gallery/development/Corridor.html +++ b/Apps/Sandcastle/gallery/development/Corridor.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer @@ -158,11 +158,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Custom Primitive.html b/Apps/Sandcastle/gallery/development/Custom Primitive.html index fb1c79983cf..335fb1f214c 100644 --- a/Apps/Sandcastle/gallery/development/Custom Primitive.html +++ b/Apps/Sandcastle/gallery/development/Custom Primitive.html @@ -37,7 +37,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -328,11 +328,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder Outline.html b/Apps/Sandcastle/gallery/development/Cylinder Outline.html index 31cadcf70f9..4a1b698cd67 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder Outline.html +++ b/Apps/Sandcastle/gallery/development/Cylinder Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -83,11 +83,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Cylinder.html b/Apps/Sandcastle/gallery/development/Cylinder.html index bc644cc7c45..d6c2e7c4dce 100644 --- a/Apps/Sandcastle/gallery/development/Cylinder.html +++ b/Apps/Sandcastle/gallery/development/Cylinder.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -112,11 +112,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Display Conditions.html b/Apps/Sandcastle/gallery/development/Display Conditions.html index 52d5fe5b2c1..dbf4b1cc881 100644 --- a/Apps/Sandcastle/gallery/development/Display Conditions.html +++ b/Apps/Sandcastle/gallery/development/Display Conditions.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -133,11 +133,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse Outline.html b/Apps/Sandcastle/gallery/development/Ellipse Outline.html index 0a8d1af1784..3f129932c8e 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipse Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -100,11 +100,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipse.html b/Apps/Sandcastle/gallery/development/Ellipse.html index 07b4284314f..5baa25dad20 100644 --- a/Apps/Sandcastle/gallery/development/Ellipse.html +++ b/Apps/Sandcastle/gallery/development/Ellipse.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -124,11 +124,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html index 0bae3b4c016..f31a39aecdc 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -80,11 +80,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html index a1764183ba7..74e834b6ddc 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid Surface.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -126,11 +126,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ellipsoid.html b/Apps/Sandcastle/gallery/development/Ellipsoid.html index 7497ad56a22..ee5d71f4f9a 100644 --- a/Apps/Sandcastle/gallery/development/Ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,11 +79,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 4361adadab8..58e3a370260 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -47,12 +47,18 @@ <div id="zoomButtons"></div> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -142,11 +148,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index f57297e1450..8dba93dd07f 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -117,11 +117,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html index 60d96361eb1..216ff9d59d8 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute box cylinder ellipsoid.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -290,11 +290,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html index c1bac66e74f..4f3d5741196 100644 --- a/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html +++ b/Apps/Sandcastle/gallery/development/Geometry Offset Attribute.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -267,11 +267,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html index 9434cb35d2f..407000421de 100644 --- a/Apps/Sandcastle/gallery/development/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/development/Geometry and Appearances.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin Cesium.Math.setRandomNumberSeed(1234); @@ -1282,11 +1282,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html index b9600e634cc..f3dd165d83f 100644 --- a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html @@ -32,100 +32,98 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); - const scene = viewer.scene; + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); + const scene = viewer.scene; - if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { - window.alert( - "Polylines on terrain are not supported on this platform." - ); - } + if (!Cesium.GroundPolylinePrimitive.isSupported(scene)) { + window.alert( + "Polylines on terrain are not supported on this platform." + ); + } - // Polyline Glow - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1955, - -122.1058, - 46.1955, - ]), - width: 10.0, + // Polyline Glow + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1955, + -122.1058, + 46.1955, + ]), + width: 10.0, + }), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineGlowType + ), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineGlowType - ), - }), - }) - ); + }) + ); - // Polyline Dash - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1975, - -122.1058, - 46.1975, - ]), - width: 10.0, + // Polyline Dash + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1975, + -122.1058, + 46.1975, + ]), + width: 10.0, + }), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineDashType + ), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineDashType - ), - }), - }) - ); + }) + ); - // Polyline Outline - scene.groundPrimitives.add( - new Cesium.GroundPolylinePrimitive({ - geometryInstances: new Cesium.GeometryInstance({ - geometry: new Cesium.GroundPolylineGeometry({ - positions: Cesium.Cartesian3.fromDegreesArray([ - -122.2558, - 46.1995, - -122.1058, - 46.1995, - ]), - width: 10.0, + // Polyline Outline + scene.groundPrimitives.add( + new Cesium.GroundPolylinePrimitive({ + geometryInstances: new Cesium.GeometryInstance({ + geometry: new Cesium.GroundPolylineGeometry({ + positions: Cesium.Cartesian3.fromDegreesArray([ + -122.2558, + 46.1995, + -122.1058, + 46.1995, + ]), + width: 10.0, + }), + }), + appearance: new Cesium.PolylineMaterialAppearance({ + material: Cesium.Material.fromType( + Cesium.Material.PolylineOutlineType + ), }), - }), - appearance: new Cesium.PolylineMaterialAppearance({ - material: Cesium.Material.fromType( - Cesium.Material.PolylineOutlineType - ), - }), - }) - ); + }) + ); - viewer.camera.lookAt( - Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), - new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //Sandcastle_End + viewer.camera.lookAt( + Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), + new Cesium.Cartesian3(5000.0, 5000.0, 5000.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index 1a50b20e624..ed527e23634 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -32,15 +32,21 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + } catch (error) { + console.log(error); + } + })(); if (!Cesium.GroundPrimitive.supportsMaterials(viewer.scene)) { window.alert( @@ -552,11 +558,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index 91416960959..dfdebecdf7a 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -32,12 +32,18 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); const scene = viewer.scene; viewer.extend(Cesium.viewerCesiumInspectorMixin); @@ -500,11 +506,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Labels.html b/Apps/Sandcastle/gallery/development/Labels.html index 819dc2b71cf..a7ef679f397 100644 --- a/Apps/Sandcastle/gallery/development/Labels.html +++ b/Apps/Sandcastle/gallery/development/Labels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -220,11 +220,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 25bdf20a5f0..4637910a494 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -64,276 +64,274 @@ ></select> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - infoBox: false, - selectionIndicator: false, - shouldAnimate: true, - projectionPicker: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + infoBox: false, + selectionIndicator: false, + shouldAnimate: true, + projectionPicker: true, + terrainProvider: await Cesium.createWorldTerrainAsync(), + }); - viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); + viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); - const globe = viewer.scene.globe; - globe.depthTestAgainstTerrain = true; + const globe = viewer.scene.globe; + globe.depthTestAgainstTerrain = true; - let cylinderRadius = -20.0; - let radiusMultiplier = 1.0; + let cylinderRadius = -20.0; + let radiusMultiplier = 1.0; - let steps = 32; - let clippingPlanes = []; - let modelEntityClippingPlanes; - let clippingModeUnion = false; - let enabled = true; + let steps = 32; + let clippingPlanes = []; + let modelEntityClippingPlanes; + let clippingModeUnion = false; + let enabled = true; - const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; - const viewModel = { - cylinderRadius: cylinderRadius, - exampleTypes: clipObjects, - currentExampleType: clipObjects[0], - planeCount: steps, - }; + const clipObjects = ["model", "b3dm", "pnts", "i3dm", "terrain"]; + const viewModel = { + cylinderRadius: cylinderRadius, + exampleTypes: clipObjects, + currentExampleType: clipObjects[0], + planeCount: steps, + }; - Cesium.knockout.track(viewModel); + Cesium.knockout.track(viewModel); - const toolbar = document.getElementById("toolbar"); - Cesium.knockout.applyBindings(viewModel, toolbar); + const toolbar = document.getElementById("toolbar"); + Cesium.knockout.applyBindings(viewModel, toolbar); - Cesium.knockout - .getObservable(viewModel, "cylinderRadius") - .subscribe(function (newValue) { - cylinderRadius = parseFloat(viewModel.cylinderRadius); - updatePlanes(); - }); + Cesium.knockout + .getObservable(viewModel, "cylinderRadius") + .subscribe(function (newValue) { + cylinderRadius = parseFloat(viewModel.cylinderRadius); + updatePlanes(); + }); - Cesium.knockout - .getObservable(viewModel, "planeCount") - .subscribe(function (newValue) { - const newSteps = parseFloat(viewModel.planeCount); - if (newSteps !== steps) { - steps = newSteps; - modelEntityClippingPlanes.removeAll(); - computePlanes(); - } - }); + Cesium.knockout + .getObservable(viewModel, "planeCount") + .subscribe(function (newValue) { + const newSteps = parseFloat(viewModel.planeCount); + if (newSteps !== steps) { + steps = newSteps; + modelEntityClippingPlanes.removeAll(); + computePlanes(); + } + }); - const scene = viewer.scene; - const planeEntities = []; - let selectedPlane; + const scene = viewer.scene; + const planeEntities = []; + let selectedPlane; - function updatePlanes() { - for (let i = 0; i < clippingPlanes.length; i++) { - const plane = clippingPlanes[i]; - plane.distance = cylinderRadius * radiusMultiplier; + function updatePlanes() { + for (let i = 0; i < clippingPlanes.length; i++) { + const plane = clippingPlanes[i]; + plane.distance = cylinderRadius * radiusMultiplier; + } } - } - function computePlanes() { - const stepDegrees = Cesium.Math.TWO_PI / steps; - clippingPlanes = []; + function computePlanes() { + const stepDegrees = Cesium.Math.TWO_PI / steps; + clippingPlanes = []; - for (let i = 0; i < steps; i++) { - const angle = i * stepDegrees; - const dir = new Cesium.Cartesian3(); - dir.x = 1.0; - dir.y = Math.tan(angle); - if (angle > Cesium.Math.PI_OVER_TWO) { - dir.x = -1.0; - dir.y *= -1.0; - } - if (angle > Cesium.Math.PI) { - dir.x = -1.0; - } - if (angle > Cesium.Math.PI_OVER_TWO * 3) { + for (let i = 0; i < steps; i++) { + const angle = i * stepDegrees; + const dir = new Cesium.Cartesian3(); dir.x = 1.0; - dir.y = -dir.y; + dir.y = Math.tan(angle); + if (angle > Cesium.Math.PI_OVER_TWO) { + dir.x = -1.0; + dir.y *= -1.0; + } + if (angle > Cesium.Math.PI) { + dir.x = -1.0; + } + if (angle > Cesium.Math.PI_OVER_TWO * 3) { + dir.x = 1.0; + dir.y = -dir.y; + } + Cesium.Cartesian3.normalize(dir, dir); + const newPlane = new Cesium.ClippingPlane( + dir, + cylinderRadius * radiusMultiplier + ); + modelEntityClippingPlanes.add(newPlane); + clippingPlanes.push(newPlane); } - Cesium.Cartesian3.normalize(dir, dir); - const newPlane = new Cesium.ClippingPlane( - dir, - cylinderRadius * radiusMultiplier - ); - modelEntityClippingPlanes.add(newPlane); - clippingPlanes.push(newPlane); } - } - function createClippingPlanes(modelMatrix) { - modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ - modelMatrix: Cesium.defined(modelMatrix) - ? modelMatrix - : Cesium.Matrix4.IDENTITY, - edgeWidth: 2.0, - edgeColor: Cesium.Color.WHITE, - unionClippingRegions: clippingModeUnion, - enabled: enabled, - }); - computePlanes(); - } + function createClippingPlanes(modelMatrix) { + modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix: Cesium.defined(modelMatrix) + ? modelMatrix + : Cesium.Matrix4.IDENTITY, + edgeWidth: 2.0, + edgeColor: Cesium.Color.WHITE, + unionClippingRegions: clippingModeUnion, + enabled: enabled, + }); + computePlanes(); + } - function updateClippingPlanes() { - return modelEntityClippingPlanes; - } + function updateClippingPlanes() { + return modelEntityClippingPlanes; + } - const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; - const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); - const instancedUrl = - "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; - const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); + const modelUrl = "../../SampleData/models/CesiumAir/Cesium_Air.glb"; + const agiHqUrl = await Cesium.IonResource.fromAssetId(40866); + const instancedUrl = + "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json"; + const pointCloudUrl = await Cesium.IonResource.fromAssetId(5713); - function loadModel(url) { - createClippingPlanes(); - const position = Cesium.Cartesian3.fromDegrees( - -123.0744619, - 44.0503706, - 300.0 - ); - const heading = 0.0; - const pitch = 0.0; - const roll = 0.0; - const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); - const orientation = Cesium.Transforms.headingPitchRollQuaternion( - position, - hpr - ); - const entity = viewer.entities.add({ - name: url, - position: position, - orientation: orientation, - model: { - uri: url, - scale: 20, - minimumPixelSize: 100.0, - clippingPlanes: new Cesium.CallbackProperty( - updateClippingPlanes, - false - ), - }, - }); - viewer.trackedEntity = entity; - } + function loadModel(url) { + createClippingPlanes(); + const position = Cesium.Cartesian3.fromDegrees( + -123.0744619, + 44.0503706, + 300.0 + ); + const heading = 0.0; + const pitch = 0.0; + const roll = 0.0; + const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); + const orientation = Cesium.Transforms.headingPitchRollQuaternion( + position, + hpr + ); + const entity = viewer.entities.add({ + name: url, + position: position, + orientation: orientation, + model: { + uri: url, + scale: 20, + minimumPixelSize: 100.0, + clippingPlanes: new Cesium.CallbackProperty( + updateClippingPlanes, + false + ), + }, + }); + viewer.trackedEntity = entity; + } - let tileset; - async function loadTileset(url, height) { - createClippingPlanes(); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - clippingPlanes: modelEntityClippingPlanes, - enableDebugWireframe: true, - }) - ); + let tileset; + async function loadTileset(url, height) { + createClippingPlanes(); + tileset = viewer.scene.primitives.add( + new Cesium.Cesium3DTileset({ + url: url, + clippingPlanes: modelEntityClippingPlanes, + enableDebugWireframe: true, + }) + ); - await tileset.readyPromise; - const boundingSphere = tileset.boundingSphere; + await tileset.readyPromise; + const boundingSphere = tileset.boundingSphere; - const cartographic = Cesium.Cartographic.fromCartesian( - boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - height - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + const cartographic = Cesium.Cartographic.fromCartesian( + boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + height + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - } + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } - loadModel(modelUrl); + loadModel(modelUrl); - Cesium.knockout - .getObservable(viewModel, "currentExampleType") - .subscribe(function (newValue) { - reset(); + Cesium.knockout + .getObservable(viewModel, "currentExampleType") + .subscribe(function (newValue) { + reset(); - if (newValue === clipObjects[0]) { - // Model - loadModel(modelUrl); - } else if (newValue === clipObjects[1]) { - // B3dm photogrammetry - return loadTileset(agiHqUrl, 0.0); - } else if (newValue === clipObjects[2]) { - // Point clouds - radiusMultiplier = 20.0; - return loadTileset(pointCloudUrl, 0.0).then(function () { - tileset.pointCloudShading.attenuation = true; - }); - } else if (newValue === clipObjects[3]) { - // i3dm - loadTileset(instancedUrl, 100.0); - } else if (newValue === clipObjects[4]) { - // Terrain - const position = Cesium.Cartesian3.fromRadians( - // eslint-disable-next-line no-loss-of-precision - -2.0872979473351286, - 0.6596620013036164, - 2380.0 - ); - const entity = viewer.entities.add({ - position: position, - model: { - uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - minimumPixelSize: 128, - scale: 40, - }, - }); - viewer.trackedEntity = entity; - createClippingPlanes( - entity.computeModelMatrix(Cesium.JulianDate.now()) - ); - globe.clippingPlanes = modelEntityClippingPlanes; - } - updatePlanes(); - }); + if (newValue === clipObjects[0]) { + // Model + loadModel(modelUrl); + } else if (newValue === clipObjects[1]) { + // B3dm photogrammetry + return loadTileset(agiHqUrl, 0.0); + } else if (newValue === clipObjects[2]) { + // Point clouds + radiusMultiplier = 20.0; + return loadTileset(pointCloudUrl, 0.0).then(function () { + tileset.pointCloudShading.attenuation = true; + }); + } else if (newValue === clipObjects[3]) { + // i3dm + loadTileset(instancedUrl, 100.0); + } else if (newValue === clipObjects[4]) { + // Terrain + const position = Cesium.Cartesian3.fromRadians( + // eslint-disable-next-line no-loss-of-precision + -2.0872979473351286, + 0.6596620013036164, + 2380.0 + ); + const entity = viewer.entities.add({ + position: position, + model: { + uri: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + minimumPixelSize: 128, + scale: 40, + }, + }); + viewer.trackedEntity = entity; + createClippingPlanes( + entity.computeModelMatrix(Cesium.JulianDate.now()) + ); + globe.clippingPlanes = modelEntityClippingPlanes; + } + updatePlanes(); + }); - function reset() { - radiusMultiplier = 1.0; - viewModel.cylinderRadius = cylinderRadius; - viewer.entities.removeAll(); - viewer.scene.primitives.removeAll(); - globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any - modelEntityClippingPlanes = undefined; - } + function reset() { + radiusMultiplier = 1.0; + viewModel.cylinderRadius = cylinderRadius; + viewer.entities.removeAll(); + viewer.scene.primitives.removeAll(); + globe.clippingPlanes = undefined; // destroy Globe clipping planes, if any + modelEntityClippingPlanes = undefined; + } - Sandcastle.addToggleButton("union", clippingModeUnion, function ( - checked - ) { - clippingModeUnion = checked; - modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; - }); + Sandcastle.addToggleButton("union", clippingModeUnion, function ( + checked + ) { + clippingModeUnion = checked; + modelEntityClippingPlanes.unionClippingRegions = clippingModeUnion; + }); - Sandcastle.addToggleButton("enabled", enabled, function (checked) { - enabled = checked; - modelEntityClippingPlanes.enabled = enabled; - }); //Sandcastle_End + Sandcastle.addToggleButton("enabled", enabled, function (checked) { + enabled = checked; + modelEntityClippingPlanes.enabled = enabled; + }); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Material.html b/Apps/Sandcastle/gallery/development/Material.html index 0e8d00af43d..2f3789fe57c 100644 --- a/Apps/Sandcastle/gallery/development/Material.html +++ b/Apps/Sandcastle/gallery/development/Material.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -91,11 +91,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index 3779ce43690..492fed56efe 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -38,7 +38,7 @@ <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -46,9 +46,16 @@ infoBox: false, selectionIndicator: false, timeline: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), }); + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + const scene = viewer.scene; const camera = scene.camera; @@ -140,11 +147,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Per Instance Color.html b/Apps/Sandcastle/gallery/development/Per Instance Color.html index 4adbc365ee2..104de111419 100644 --- a/Apps/Sandcastle/gallery/development/Per Instance Color.html +++ b/Apps/Sandcastle/gallery/development/Per Instance Color.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -69,11 +69,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Pick From Ray.html b/Apps/Sandcastle/gallery/development/Pick From Ray.html index f39d5637e71..e8c68eed20d 100644 --- a/Apps/Sandcastle/gallery/development/Pick From Ray.html +++ b/Apps/Sandcastle/gallery/development/Pick From Ray.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -194,11 +194,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Picking.html b/Apps/Sandcastle/gallery/development/Picking.html index ebc5ecfbe66..3b9fd338be0 100644 --- a/Apps/Sandcastle/gallery/development/Picking.html +++ b/Apps/Sandcastle/gallery/development/Picking.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -624,11 +624,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/PointPrimitives.html b/Apps/Sandcastle/gallery/development/PointPrimitives.html index 1416f469c8b..7efb0a1983f 100644 --- a/Apps/Sandcastle/gallery/development/PointPrimitives.html +++ b/Apps/Sandcastle/gallery/development/PointPrimitives.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -275,11 +275,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Outline.html b/Apps/Sandcastle/gallery/development/Polygon Outline.html index 161562aa986..ccdaf2d5145 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Outline.html +++ b/Apps/Sandcastle/gallery/development/Polygon Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -152,11 +152,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html index 8f435f05956..00116b09de3 100644 --- a/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html +++ b/Apps/Sandcastle/gallery/development/Polygon Texture Coordinates.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -436,11 +436,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polygon.html b/Apps/Sandcastle/gallery/development/Polygon.html index ac514033872..e1924903069 100644 --- a/Apps/Sandcastle/gallery/development/Polygon.html +++ b/Apps/Sandcastle/gallery/development/Polygon.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -358,11 +358,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Color.html b/Apps/Sandcastle/gallery/development/Polyline Color.html index c49725afcbd..b7ea8361ede 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Color.html +++ b/Apps/Sandcastle/gallery/development/Polyline Color.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -92,11 +92,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Material.html b/Apps/Sandcastle/gallery/development/Polyline Material.html index dfd105fcab5..5b953d41d4b 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Polyline Material.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -111,11 +111,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html index 7afd2311560..073f0455b30 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -122,11 +122,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline Volume.html b/Apps/Sandcastle/gallery/development/Polyline Volume.html index 07a9ea3836c..1037d48d357 100644 --- a/Apps/Sandcastle/gallery/development/Polyline Volume.html +++ b/Apps/Sandcastle/gallery/development/Polyline Volume.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -170,11 +170,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polyline.html b/Apps/Sandcastle/gallery/development/Polyline.html index f7fad4cee28..7025f9e1bba 100644 --- a/Apps/Sandcastle/gallery/development/Polyline.html +++ b/Apps/Sandcastle/gallery/development/Polyline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -96,11 +96,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index 68e4c221004..aedb55060ce 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -50,15 +50,21 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); + + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }); + } catch (error) { + console.log(error); + } + })(); if (!Cesium.GroundPolylinePrimitive.isSupported(viewer.scene)) { window.alert( @@ -365,11 +371,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Polylines.html b/Apps/Sandcastle/gallery/development/Polylines.html index ea310cc0c48..7046bd1e060 100644 --- a/Apps/Sandcastle/gallery/development/Polylines.html +++ b/Apps/Sandcastle/gallery/development/Polylines.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -196,11 +196,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle Outline.html b/Apps/Sandcastle/gallery/development/Rectangle Outline.html index 749ced2286e..d5f90c1725a 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle Outline.html +++ b/Apps/Sandcastle/gallery/development/Rectangle Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -67,11 +67,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Rectangle.html b/Apps/Sandcastle/gallery/development/Rectangle.html index d8968440335..587b72bbf33 100644 --- a/Apps/Sandcastle/gallery/development/Rectangle.html +++ b/Apps/Sandcastle/gallery/development/Rectangle.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -84,11 +84,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index 75714782252..2f4a6fe40cd 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -302,7 +302,7 @@ </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin @@ -1086,11 +1086,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Simple Polyline.html b/Apps/Sandcastle/gallery/development/Simple Polyline.html index 2627c54aedd..18688e29147 100644 --- a/Apps/Sandcastle/gallery/development/Simple Polyline.html +++ b/Apps/Sandcastle/gallery/development/Simple Polyline.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -116,11 +116,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere Outline.html b/Apps/Sandcastle/gallery/development/Sphere Outline.html index b4b2ff1c0e6..d2fa6a09f14 100644 --- a/Apps/Sandcastle/gallery/development/Sphere Outline.html +++ b/Apps/Sandcastle/gallery/development/Sphere Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,11 +79,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Sphere.html b/Apps/Sandcastle/gallery/development/Sphere.html index 706928eed45..6e0bfbc8575 100644 --- a/Apps/Sandcastle/gallery/development/Sphere.html +++ b/Apps/Sandcastle/gallery/development/Sphere.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -79,11 +79,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html index 6ef629b7d3a..3dc40b187da 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html +++ b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html @@ -32,166 +32,164 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }), - }); + (async () => { + const viewer = new Cesium.Viewer("cesiumContainer", { + terrainProvider: await Cesium.createWorldTerrainAsync({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); - const concavePositions = [ - new Cesium.Cartesian3( - -2353381.4891308164, - -3747386.1222378365, - 4577999.291515961 - ), - new Cesium.Cartesian3( - -2359513.937204245, - -3743087.2343810294, - 4578357.188560644 - ), - new Cesium.Cartesian3( - -2356102.0286082155, - -3739921.552293276, - 4582670.218770547 - ), - new Cesium.Cartesian3( - -2353889.0353209395, - -3741183.2274413602, - 4582776.909071608 - ), - new Cesium.Cartesian3( - -2355072.390487758, - -3742865.615615464, - 4580808.044684757 - ), - new Cesium.Cartesian3( - -2356109.6661414686, - -3741994.0607898533, - 4580985.489703348 - ), - new Cesium.Cartesian3( - -2357041.8328847606, - -3743225.9693035223, - 4579509.2148039425 - ), - new Cesium.Cartesian3( - -2354586.752280607, - -3744890.9511893727, - 4579411.591389144 - ), - new Cesium.Cartesian3( - -2353213.0268325945, - -3743712.1202877173, - 4581070.08828045 - ), - new Cesium.Cartesian3( - -2353637.930711704, - -3743402.9513476435, - 4581104.219550749 - ), - new Cesium.Cartesian3( - -2352875.095159641, - -3742564.819171856, - 4582173.540953957 - ), - new Cesium.Cartesian3( - -2350669.646050987, - -3743751.6823160048, - 4582334.8406995395 - ), - ]; + const concavePositions = [ + new Cesium.Cartesian3( + -2353381.4891308164, + -3747386.1222378365, + 4577999.291515961 + ), + new Cesium.Cartesian3( + -2359513.937204245, + -3743087.2343810294, + 4578357.188560644 + ), + new Cesium.Cartesian3( + -2356102.0286082155, + -3739921.552293276, + 4582670.218770547 + ), + new Cesium.Cartesian3( + -2353889.0353209395, + -3741183.2274413602, + 4582776.909071608 + ), + new Cesium.Cartesian3( + -2355072.390487758, + -3742865.615615464, + 4580808.044684757 + ), + new Cesium.Cartesian3( + -2356109.6661414686, + -3741994.0607898533, + 4580985.489703348 + ), + new Cesium.Cartesian3( + -2357041.8328847606, + -3743225.9693035223, + 4579509.2148039425 + ), + new Cesium.Cartesian3( + -2354586.752280607, + -3744890.9511893727, + 4579411.591389144 + ), + new Cesium.Cartesian3( + -2353213.0268325945, + -3743712.1202877173, + 4581070.08828045 + ), + new Cesium.Cartesian3( + -2353637.930711704, + -3743402.9513476435, + 4581104.219550749 + ), + new Cesium.Cartesian3( + -2352875.095159641, + -3742564.819171856, + 4582173.540953957 + ), + new Cesium.Cartesian3( + -2350669.646050987, + -3743751.6823160048, + 4582334.8406995395 + ), + ]; - // concave polygon - viewer.entities.add({ - name: "concave polygon on surface", - polygon: { - hierarchy: concavePositions, - material: "../images/Cesium_Logo_Color.jpg", - }, - stRotation: 1.0, - }); + // concave polygon + viewer.entities.add({ + name: "concave polygon on surface", + polygon: { + hierarchy: concavePositions, + material: "../images/Cesium_Logo_Color.jpg", + }, + stRotation: 1.0, + }); - // Randomly colored, nonoverlapping squares - const latitude = 46.2522; - const longitude = -122.2534; + // Randomly colored, nonoverlapping squares + const latitude = 46.2522; + const longitude = -122.2534; - Cesium.Math.setRandomNumberSeed(133); + Cesium.Math.setRandomNumberSeed(133); - for (let x = 0; x < 10; ++x) { - for (let y = 0; y < 10; ++y) { - const cornerLat = latitude + 0.01 * x; - const cornerLon = longitude + 0.01 * y; - viewer.entities.add({ - id: `${x} ${y}`, - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - cornerLon, - cornerLat, - cornerLon + 0.009, - cornerLat + 0.009 - ), - material: Cesium.Color.fromRandom().withAlpha(0.5), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + for (let x = 0; x < 10; ++x) { + for (let y = 0; y < 10; ++y) { + const cornerLat = latitude + 0.01 * x; + const cornerLon = longitude + 0.01 * y; + viewer.entities.add({ + id: `${x} ${y}`, + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + cornerLon, + cornerLat, + cornerLon + 0.009, + cornerLat + 0.009 + ), + material: Cesium.Color.fromRandom().withAlpha(0.5), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); + } } - } - // Checkerboard - const checkerboard = new Cesium.CheckerboardMaterialProperty({ - evenColor: Cesium.Color.ORANGE, - oddColor: Cesium.Color.YELLOW, - repeat: new Cesium.Cartesian2(14, 14), - }); + // Checkerboard + const checkerboard = new Cesium.CheckerboardMaterialProperty({ + evenColor: Cesium.Color.ORANGE, + oddColor: Cesium.Color.YELLOW, + repeat: new Cesium.Cartesian2(14, 14), + }); - viewer.entities.add({ - name: "checkerboard rectangle", - rectangle: { - coordinates: Cesium.Rectangle.fromDegrees( - -122.17778, - 46.36169, - -120.17778, - 48.36169 - ), - material: checkerboard, - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + viewer.entities.add({ + name: "checkerboard rectangle", + rectangle: { + coordinates: Cesium.Rectangle.fromDegrees( + -122.17778, + 46.36169, + -120.17778, + 48.36169 + ), + material: checkerboard, + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - // Ellipse with texture rotation and repetition - viewer.entities.add({ - position: Cesium.Cartesian3.fromDegrees( - -121.70711316136793, - 45.943757948892845, - 0.0 - ), - name: "ellipse", - ellipse: { - semiMinorAxis: 15000.0, - semiMajorAxis: 30000.0, - material: new Cesium.ImageMaterialProperty({ - image: "../images/Cesium_Logo_Color.jpg", - repeat: new Cesium.Cartesian2(10, 10), - }), - stRotation: Cesium.Math.toRadians(45), - classificationType: Cesium.ClassificationType.TERRAIN, - }, - }); + // Ellipse with texture rotation and repetition + viewer.entities.add({ + position: Cesium.Cartesian3.fromDegrees( + -121.70711316136793, + 45.943757948892845, + 0.0 + ), + name: "ellipse", + ellipse: { + semiMinorAxis: 15000.0, + semiMajorAxis: 30000.0, + material: new Cesium.ImageMaterialProperty({ + image: "../images/Cesium_Logo_Color.jpg", + repeat: new Cesium.Cartesian2(10, 10), + }), + stRotation: Cesium.Math.toRadians(45), + classificationType: Cesium.ClassificationType.TERRAIN, + }, + }); - viewer.zoomTo(viewer.entities); //Sandcastle_End + viewer.zoomTo(viewer.entities); + })(); //Sandcastle_End Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index 6aa97449f49..5ea861d821d 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -32,17 +32,23 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer", {}); const scene = viewer.scene; const camera = scene.camera; const globe = scene.globe; const statistics = Cesium.RequestScheduler.statistics; + (async () => { + try { + viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(error); + } + })(); + let startTime; let flightComplete; let monitor; @@ -277,11 +283,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html index 88eadd2aa7a..16308f1bd67 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Tweaks.html +++ b/Apps/Sandcastle/gallery/development/Terrain Tweaks.html @@ -91,7 +91,7 @@ </table> </div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); @@ -157,11 +157,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Volumes.html b/Apps/Sandcastle/gallery/development/Volumes.html index 4449c45a055..8ff67043449 100644 --- a/Apps/Sandcastle/gallery/development/Volumes.html +++ b/Apps/Sandcastle/gallery/development/Volumes.html @@ -32,7 +32,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin function createPrimitives(scene) { @@ -71,11 +71,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Voxels.html b/Apps/Sandcastle/gallery/development/Voxels.html index 740794a2087..a3b2b3590fc 100644 --- a/Apps/Sandcastle/gallery/development/Voxels.html +++ b/Apps/Sandcastle/gallery/development/Voxels.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { @@ -473,11 +473,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall Outline.html b/Apps/Sandcastle/gallery/development/Wall Outline.html index 4dc0898026e..a314a70d61a 100644 --- a/Apps/Sandcastle/gallery/development/Wall Outline.html +++ b/Apps/Sandcastle/gallery/development/Wall Outline.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -71,11 +71,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Wall.html b/Apps/Sandcastle/gallery/development/Wall.html index bda56781445..e22ffb9df6a 100644 --- a/Apps/Sandcastle/gallery/development/Wall.html +++ b/Apps/Sandcastle/gallery/development/Wall.html @@ -29,7 +29,7 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = async function (Cesium) { + window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin // Create the viewer. @@ -174,11 +174,7 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } </script> </body> diff --git a/Apps/Sandcastle/load-cesium-es6.js b/Apps/Sandcastle/load-cesium-es6.js index bd8a8c98ca4..0b7dfc4cd51 100644 --- a/Apps/Sandcastle/load-cesium-es6.js +++ b/Apps/Sandcastle/load-cesium-es6.js @@ -7,9 +7,5 @@ window.Cesium = Cesium; // Since ES6 modules have no guaranteed load order, // only call startup if it's already defined but hasn't been called yet if (!window.startupCalled && typeof window.startup === "function") { - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } + window.startup(Cesium); } From 0e2f4daa8d565bd4ceb4c3ecc115d29c3afc66ce Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Feb 2023 13:18:44 -0500 Subject: [PATCH 433/679] voxels: use RayShapeIntersection struct for utilities --- .../Source/Shaders/Voxels/Intersection.glsl | 20 ++++++------- .../Shaders/Voxels/IntersectionUtils.glsl | 30 +++++++++++-------- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 26 ++++++++-------- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/Intersection.glsl b/packages/engine/Source/Shaders/Voxels/Intersection.glsl index 54601d9fa13..a01c51906df 100644 --- a/packages/engine/Source/Shaders/Voxels/Intersection.glsl +++ b/packages/engine/Source/Shaders/Voxels/Intersection.glsl @@ -5,21 +5,21 @@ // Scene/VoxelRenderResources.js. // See also IntersectClippingPlane.glsl and IntersectDepth.glsl. // See IntersectionUtils.glsl for the definitions of Ray, NO_HIT, -// getIntersectionPair, initializeIntersections, nextIntersection. +// getFirstIntersection, initializeIntersections, nextIntersection. /* Intersection defines (set in Scene/VoxelRenderResources.js) #define INTERSECTION_COUNT ### */ -vec2 intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) { +RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) { // Do a ray-shape intersection to find the exact starting and ending points. intersectShape(ray, ix); // Exit early if the positive shape was completely missed or behind the ray. - vec2 entryExitT = getIntersectionPair(ix, 0); - if (entryExitT.x == NO_HIT) { + RayShapeIntersection intersection = getFirstIntersection(ix); + if (intersection.entryT == NO_HIT) { // Positive shape was completely missed - so exit early. - return vec2(NO_HIT); + return intersection; } // Clipping planes @@ -36,17 +36,17 @@ vec2 intersectScene(in vec2 screenCoord, in Ray ray, out Intersections ix) { #if (INTERSECTION_COUNT > 1) initializeIntersections(ix); for (int i = 0; i < INTERSECTION_COUNT; ++i) { - entryExitT = nextIntersection(ix); - if (entryExitT.y > 0.0) { + intersection = nextIntersection(ix); + if (intersection.exitT > 0.0) { // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); + intersection.entryT = max(intersection.entryT, 0.0); break; } } #else // Set start to 0.0 when ray is inside the shape. - entryExitT.x = max(entryExitT.x, 0.0); + intersection.entryT = max(intersection.entryT, 0.0); #endif - return entryExitT; + return intersection; } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index fc1a996a822..979e20ad909 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -43,10 +43,15 @@ struct Intersections { #endif }; -// Use defines instead of real functions because WebGL1 cannot access array with non-constant index. -#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].w -#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1)) +RayShapeIntersection getFirstIntersection(in Intersections ix) +{ + vec3 normal = ix.intersections[0].xyz; + float entryT = ix.intersections[0].w; + float exitT = ix.intersections[1].w; + return RayShapeIntersection(normal, entryT, exitT); +} +// Use defines instead of real functions because WebGL1 cannot access array with non-constant index. #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*bool*/ enter) (ix).intersections[(index)] = vec4(0.0, float(!positive) * 2.0 + float(!enter) + 1.0, 0.0, (t)) #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec4(0.0, float((index) > 0) * 2.0 + 1.0, 0.0, (entryExit).x); (ix).intersections[(index) * 2 + 1] = vec4(0.0, float((index) > 0) * 2.0 + 2.0, 0.0, (entryExit).y) @@ -80,13 +85,13 @@ void initializeIntersections(inout Intersections ix) { #endif #if (INTERSECTION_COUNT > 1) -vec2 nextIntersection(inout Intersections ix) { - vec2 entryExitT = vec2(NO_HIT); +RayShapeIntersection nextIntersection(inout Intersections ix) { + RayShapeIntersection shapeIntersection = RayShapeIntersection(vec3(0.0), NO_HIT, NO_HIT); const int passCount = INTERSECTION_COUNT * 2; if (ix.index == passCount) { - return entryExitT; + return shapeIntersection; } for (int i = 0; i < passCount; ++i) { @@ -98,9 +103,9 @@ vec2 nextIntersection(inout Intersections ix) { ix.index = i + 1; - vec4 intersect = ix.intersections[i]; - float t = intersect.w; - float intersectionType = length(intersect.xyz) - 1.0; + vec4 surfaceIntersection = ix.intersections[i]; + float t = surfaceIntersection.w; + float intersectionType = length(surfaceIntersection.xyz) - 1.0; bool currShapeIsPositive = intersectionType < 2.0; bool enter = mod(intersectionType, 2.0) == 0.0; @@ -109,14 +114,15 @@ vec2 nextIntersection(inout Intersections ix) { // entering positive or exiting negative if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { - entryExitT.x = t; + shapeIntersection.normal = surfaceIntersection.xyz; + shapeIntersection.entryT = t; } // exiting positive or entering negative after being inside positive bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; if (exitPositive || enterNegativeFromPositive) { - entryExitT.y = t; + shapeIntersection.exitT = t; // entry and exit have been found, so the loop can stop if (exitPositive) { @@ -127,7 +133,7 @@ vec2 nextIntersection(inout Intersections ix) { } } - return entryExitT; + return shapeIntersection; } #endif diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index e46ae16e9d9..dd7a39244a8 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -28,12 +28,12 @@ float hash(vec2 p) } #endif -vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in vec2 entryExit) { +vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersection shapeIntersection) { #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); - float entry = max(voxelIntersection.entryT, entryExit.x); - float exit = min(voxelIntersection.exitT, entryExit.y); + float entry = max(voxelIntersection.entryT, shapeIntersection.entryT); + float exit = min(voxelIntersection.exitT, shapeIntersection.exitT); return vec4(voxelIntersection.normal, exit - entry); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); @@ -57,15 +57,15 @@ void main() #endif Intersections ix; - vec2 entryExitT = intersectScene(screenCoord, viewRayUv, ix); + RayShapeIntersection shapeIntersection = intersectScene(screenCoord, viewRayUv, ix); // Exit early if the scene was completely missed. - if (entryExitT.x == NO_HIT) { + if (shapeIntersection.entryT == NO_HIT) { discard; } - float currT = entryExitT.x + RAY_SHIFT; - float endT = entryExitT.y; + float currT = shapeIntersection.entryT + RAY_SHIFT; + float endT = shapeIntersection.exitT; vec3 positionUv = viewPosUv + currT * viewDirUv; vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); @@ -73,7 +73,7 @@ void main() TraversalData traversalData; SampleData sampleDatas[SAMPLE_COUNT]; traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas); - vec4 step = getStepSize(sampleDatas[0], viewRayUv, entryExitT); + vec4 step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection); #if defined(JITTER) float noise = hash(screenCoord); // [0,1] @@ -135,13 +135,13 @@ void main() #if (INTERSECTION_COUNT == 1) break; #else - vec2 entryExitT = nextIntersection(ix); - if (entryExitT.x == NO_HIT) { + shapeIntersection = nextIntersection(ix); + if (shapeIntersection.entryT == NO_HIT) { break; } else { // Found another intersection. Resume raymarching there - currT = entryExitT.x; - endT = entryExitT.y; + currT = shapeIntersection.entryT; + endT = shapeIntersection.exitT; positionUv = viewPosUv + currT * viewDirUv; } #endif @@ -151,7 +151,7 @@ void main() // This is similar to traverseOctreeFromBeginning but is faster when the ray is in the same tile as the previous step. positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas); - step = getStepSize(sampleDatas[0], viewRayUv, entryExitT); + step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection); } // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1] From 1eab81fc56dd30057743cf2118064e6e54e46155 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 6 Feb 2023 15:08:58 -0500 Subject: [PATCH 434/679] Cleanup --- CHANGES.md | 6 +- .../GoogleEarthEnterpriseTerrainProvider.js | 11 +- .../Scene/ArcGisMapServerImageryProvider.js | 403 +++++++++--------- .../Source/Scene/BingMapsImageryProvider.js | 264 ++++++------ packages/engine/Source/Scene/ImageryLayer.js | 26 ++ .../Source/Scene/QuadtreeTileProvider.js | 10 + .../Scene/TileMapServiceImageryProvider.js | 8 +- .../Source/Scene/createWorldImageryAsync.js | 2 +- .../Scene/BingMapsImageryProviderSpec.js | 80 +--- .../engine/Specs/Scene/ImageryLayerSpec.js | 19 + .../Scene/createWorldImageryAsyncSpec.js | 14 +- .../createFakeBingMapsMetadataResponse.js | 73 ++++ 12 files changed, 492 insertions(+), 424 deletions(-) create mode 100644 packages/engine/Specs/createFakeBingMapsMetadataResponse.js diff --git a/CHANGES.md b/CHANGES.md index 1cb8857d044..e64c819b31e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,19 +18,21 @@ - `ImageryProvider.ready` and `ImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `ArcGisMapServerImageryProvider` constructor parameter `url`,`ArcGisMapServerImageryProvider.ready`, and `ArcGisMapServerImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGisMapServerImageryProvider.fromUrl` instead. - `BingMapsImageryProvider` constructor parameter `url`,`BingMapsImageryProvider.ready`, and `BingMapsImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `BingMapsImageryProvider.fromUrl` instead. -- `GridImageryProvider.ready` and `GridImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `GoogleEarthEnterpriseImageryProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseImageryProvider.ready`, and `GoogleEarthEnterpriseImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseImageryProvider.fromMetadata` instead. +- `GridImageryProvider.ready` and `GridImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `IonImageryProvider` constructor parameter `assetId`,`BIonImageryProvider.ready`, and `IonImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `IonImageryProvider.fromAssetId` instead. - `MapboxImageryProvider.ready` and `MapboxImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `MapboxStyleImageryProvider.ready` and `MapboxStyleImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `OpenStreetMapImageryProvider.ready` and `OpenStreetMapImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `SingleTileImageryProvider` constructor parameter `options.url`, `SingleTileImageryProvider.ready`, and `SingleTileImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `SingleTileImageryProvider.fromUrl` instead. - `TileCoordinatesImageryProvider.ready` and `TileCoordinatesImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `TileMapServiceImageryProvider` constructor, `TileMapServiceImageryProvider.ready`, and `TileMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `TileMapServiceImageryProvider.fromUrl` instead. +- `TileMapServiceImageryProvider` constructor parameter `options.url`, `TileMapServiceImageryProvider.ready`, and `TileMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `TileMapServiceImageryProvider.fromUrl` instead. - `UrlTemplateImageryProvider.reinitialize`, `UrlTemplateImageryProvider.ready`, and `UrlTemplateImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `WebMapServiceImageryProvider.ready`, and `WebMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `WebMapTileServiceImageryProvider.ready`, and `WebMapTileServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `ImageryLayer.getViewableRectangle` was deprecated in Cesium 1.102. It will be removed in 1.104. Use `ImageryLayer.getImageryRectangle` instead. +- `createWorldImagery` was deprecated in Cesium 1.102. It will be removed in 1.104. Use `createWorldImageryAsync` instead. - `ArcGISTiledElevationTerrainProvider` constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. - `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `CesiumTerrainProvider.fromUrl` instead. - `CustomHeightmapTerrainProvider.ready`, and `CustomHeightmapTerrainProvider.readyPromise` were deprecated in Cesium 1.102. diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index b714afa8afd..5182a5eb86d 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -146,16 +146,7 @@ function GoogleEarthEnterpriseTerrainProvider(options) { const e = new RuntimeError( `The server ${metadata.url} doesn't have terrain` ); - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - e.message, - undefined, - undefined, - undefined, - e - ); + return Promise.reject(e); } diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index 0b52a68d790..c219a737902 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -61,6 +61,207 @@ import ImageryProvider from "./ImageryProvider.js"; * a tiled server. */ +/** + * Used to track creation details while fetching initial metadata + * + * @constructor + * @private + * + * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options An object describing initialization options + */ +function ImageryProviderBuilder(options) { + this.useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); + + const ellipsoid = options.ellipsoid; + this.tilingScheme = defaultValue( + options.tilingScheme, + new GeographicTilingScheme({ ellipsoid: ellipsoid }) + ); + this.rectangle = defaultValue(options.rectangle, this.tilingScheme.rectangle); + this.ellipsoid = ellipsoid; + + let credit = options.credit; + if (typeof credit === "string") { + credit = new Credit(credit); + } + this.credit = credit; + this.tileDiscardPolicy = options.tileDiscardPolicy; + + this.tileWidth = defaultValue(options.tileWidth, 256); + this.tileHeight = defaultValue(options.tileHeight, 256); + this.maximumLevel = options.maximumLevel; +} + +/** + * Complete ArcGisMapServerImageryProvider creation based on builder values. + * + * @private + * + * @param {ArcGisMapServerImageryProvider} provider + */ +ImageryProviderBuilder.prototype.build = function (provider) { + provider._useTiles = this.useTiles; + provider._tilingScheme = this.tilingScheme; + provider._rectangle = this.rectangle; + provider._credit = this.credit; + provider._tileDiscardPolicy = this.tileDiscardPolicy; + provider._tileWidth = this.tileWidth; + provider._tileHeight = this.tileHeight; + provider._maximumLevel = this.maximumLevel; + + // Install the default tile discard policy if none has been supplied. + if (this.useTiles && !defined(this.tileDiscardPolicy)) { + provider._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ + missingImageUrl: buildImageResource(provider, 0, 0, this.maximumLevel) + .url, + pixelsToCheck: [ + new Cartesian2(0, 0), + new Cartesian2(200, 20), + new Cartesian2(20, 200), + new Cartesian2(80, 110), + new Cartesian2(160, 130), + ], + disableCheckIfAllPixelsAreTransparent: true, + }); + } + + provider._ready = true; +}; + +function metadataSuccess(data, imageryProviderBuilder) { + const tileInfo = data.tileInfo; + if (!defined(tileInfo)) { + imageryProviderBuilder.useTiles = false; + } else { + imageryProviderBuilder.tileWidth = tileInfo.rows; + imageryProviderBuilder.tileHeight = tileInfo.cols; + + if ( + tileInfo.spatialReference.wkid === 102100 || + tileInfo.spatialReference.wkid === 102113 + ) { + imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({ + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + } else if (data.tileInfo.spatialReference.wkid === 4326) { + imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({ + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + } else { + const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`; + throw new RuntimeError(message); + } + imageryProviderBuilder.maximumLevel = data.tileInfo.lods.length - 1; + + if (defined(data.fullExtent)) { + if ( + defined(data.fullExtent.spatialReference) && + defined(data.fullExtent.spatialReference.wkid) + ) { + if ( + data.fullExtent.spatialReference.wkid === 102100 || + data.fullExtent.spatialReference.wkid === 102113 + ) { + const projection = new WebMercatorProjection(); + const extent = data.fullExtent; + const sw = projection.unproject( + new Cartesian3( + Math.max( + extent.xmin, + -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + Math.max( + extent.ymin, + -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + 0.0 + ) + ); + const ne = projection.unproject( + new Cartesian3( + Math.min( + extent.xmax, + imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + Math.min( + extent.ymax, + imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * + Math.PI + ), + 0.0 + ) + ); + imageryProviderBuilder.rectangle = new Rectangle( + sw.longitude, + sw.latitude, + ne.longitude, + ne.latitude + ); + } else if (data.fullExtent.spatialReference.wkid === 4326) { + imageryProviderBuilder.rectangle = Rectangle.fromDegrees( + data.fullExtent.xmin, + data.fullExtent.ymin, + data.fullExtent.xmax, + data.fullExtent.ymax + ); + } else { + const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`; + throw new RuntimeError(extentMessage); + } + } + } else { + imageryProviderBuilder.rectangle = + imageryProviderBuilder.tilingScheme.rectangle; + } + + imageryProviderBuilder.useTiles = true; + } + + if (defined(data.copyrightText) && data.copyrightText.length > 0) { + imageryProviderBuilder.credit = new Credit(data.copyrightText); + } +} + +function metadataFailure(resource, error, provider) { + let message = `An error occurred while accessing ${resource.url}`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + // When readyPromise is deprecated, TileProviderError.reportError, + // and related parameters can be removed + TileProviderError.reportError( + undefined, + provider, + defined(provider) ? provider._errorEvent : undefined, + message, + undefined, + undefined, + undefined, + error + ); + + throw new RuntimeError(message); +} + +async function requestMetadata(resource, imageryProviderBuilder, provider) { + const jsonResource = resource.getDerivedResource({ + queryParameters: { + f: "json", + }, + }); + + try { + const data = await jsonResource.fetchJsonp(); + metadataSuccess(data, imageryProviderBuilder); + } catch (error) { + metadataFailure(resource, error, provider); + } +} + /** * <div class="notice"> * To construct a ArcGisMapServerImageryProvider call {@link ArcGisMapServerImageryProvider.fromUrl}. Do not call the constructor directly. @@ -521,207 +722,6 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { }, }); -/** - * Used to track creation details while fetching initial metadata - * - * @constructor - * @private - * - * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options An object describing initialization options - */ -function ImageryProviderBuilder(options) { - this.useTiles = defaultValue(options.usePreCachedTilesIfAvailable, true); - - const ellipsoid = options.ellipsoid; - this.tilingScheme = defaultValue( - options.tilingScheme, - new GeographicTilingScheme({ ellipsoid: ellipsoid }) - ); - this.rectangle = defaultValue(options.rectangle, this.tilingScheme.rectangle); - this.ellipsoid = ellipsoid; - - let credit = options.credit; - if (typeof credit === "string") { - credit = new Credit(credit); - } - this.credit = credit; - this.tileDiscardPolicy = options.tileDiscardPolicy; - - this.tileWidth = defaultValue(options.tileWidth, 256); - this.tileHeight = defaultValue(options.tileHeight, 256); - this.maximumLevel = options.maximumLevel; -} - -/** - * Complete ArcGisMapServerImageryProvider creation based on builder values. - * - * @private - * - * @param {ArcGisMapServerImageryProvider} provider - */ -ImageryProviderBuilder.prototype.build = function (provider) { - provider._useTiles = this.useTiles; - provider._tilingScheme = this.tilingScheme; - provider._rectangle = this.rectangle; - provider._credit = this.credit; - provider._tileDiscardPolicy = this.tileDiscardPolicy; - provider._tileWidth = this.tileWidth; - provider._tileHeight = this.tileHeight; - provider._maximumLevel = this.maximumLevel; - - // Install the default tile discard policy if none has been supplied. - if (this.useTiles && !defined(this.tileDiscardPolicy)) { - provider._tileDiscardPolicy = new DiscardMissingTileImagePolicy({ - missingImageUrl: buildImageResource(provider, 0, 0, this.maximumLevel) - .url, - pixelsToCheck: [ - new Cartesian2(0, 0), - new Cartesian2(200, 20), - new Cartesian2(20, 200), - new Cartesian2(80, 110), - new Cartesian2(160, 130), - ], - disableCheckIfAllPixelsAreTransparent: true, - }); - } - - provider._ready = true; -}; - -function metadataSuccess(data, imageryProviderBuilder) { - const tileInfo = data.tileInfo; - if (!defined(tileInfo)) { - imageryProviderBuilder.useTiles = false; - } else { - imageryProviderBuilder.tileWidth = tileInfo.rows; - imageryProviderBuilder.tileHeight = tileInfo.cols; - - if ( - tileInfo.spatialReference.wkid === 102100 || - tileInfo.spatialReference.wkid === 102113 - ) { - imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({ - ellipsoid: imageryProviderBuilder.ellipsoid, - }); - } else if (data.tileInfo.spatialReference.wkid === 4326) { - imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({ - ellipsoid: imageryProviderBuilder.ellipsoid, - }); - } else { - const message = `Tile spatial reference WKID ${data.tileInfo.spatialReference.wkid} is not supported.`; - throw new RuntimeError(message); - } - imageryProviderBuilder.maximumLevel = data.tileInfo.lods.length - 1; - - if (defined(data.fullExtent)) { - if ( - defined(data.fullExtent.spatialReference) && - defined(data.fullExtent.spatialReference.wkid) - ) { - if ( - data.fullExtent.spatialReference.wkid === 102100 || - data.fullExtent.spatialReference.wkid === 102113 - ) { - const projection = new WebMercatorProjection(); - const extent = data.fullExtent; - const sw = projection.unproject( - new Cartesian3( - Math.max( - extent.xmin, - -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * - Math.PI - ), - Math.max( - extent.ymin, - -imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * - Math.PI - ), - 0.0 - ) - ); - const ne = projection.unproject( - new Cartesian3( - Math.min( - extent.xmax, - imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * - Math.PI - ), - Math.min( - extent.ymax, - imageryProviderBuilder.tilingScheme.ellipsoid.maximumRadius * - Math.PI - ), - 0.0 - ) - ); - imageryProviderBuilder.rectangle = new Rectangle( - sw.longitude, - sw.latitude, - ne.longitude, - ne.latitude - ); - } else if (data.fullExtent.spatialReference.wkid === 4326) { - imageryProviderBuilder.rectangle = Rectangle.fromDegrees( - data.fullExtent.xmin, - data.fullExtent.ymin, - data.fullExtent.xmax, - data.fullExtent.ymax - ); - } else { - const extentMessage = `fullExtent.spatialReference WKID ${data.fullExtent.spatialReference.wkid} is not supported.`; - throw new RuntimeError(extentMessage); - } - } - } else { - imageryProviderBuilder.rectangle = - imageryProviderBuilder.tilingScheme.rectangle; - } - - imageryProviderBuilder.useTiles = true; - } - - if (defined(data.copyrightText) && data.copyrightText.length > 0) { - imageryProviderBuilder.credit = new Credit(data.copyrightText); - } -} - -function metadataFailure(resource, error, provider) { - let message = `An error occurred while accessing ${resource.url}`; - if (defined(error) && defined(error.message)) { - message += `: ${error.message}`; - } - - // When readyPromise is deprecated, TileProviderError.reportError, - // and related parameters can be removed - TileProviderError.reportError( - undefined, - provider, - defined(provider) ? provider._errorEvent : undefined, - message, - undefined, - undefined, - undefined, - error - ); - - throw new RuntimeError(message); -} - -async function requestMetadata(resource, imageryProviderBuilder, provider) { - const jsonResource = resource.getDerivedResource({ - queryParameters: { - f: "json", - }, - }); - - try { - const data = await jsonResource.fetchJsonp(); - metadataSuccess(data, imageryProviderBuilder); - } catch (error) { - metadataFailure(resource, error, provider); - } -} - /** * Creates an {@link ImageryProvider} which provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are * used, if available. @@ -763,6 +763,7 @@ ArcGisMapServerImageryProvider.fromUrl = async function (url, options) { } imageryProviderBuilder.build(provider); + provider._readyPromise = Promise.resolve(true); return provider; }; diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index 8d56bd548d9..8e6db34c6c6 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -36,6 +36,136 @@ import ImageryProvider from "./ImageryProvider.js"; * To ensure that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this parameter. */ +/** + * Used to track creation details while fetching initial metadata + * + * @constructor + * @private + * + * @param {BingMapsImageryProvider.ConstructorOptions} options An object describing initialization options + */ +function ImageryProviderBuilder(options) { + this.tileWidth = undefined; + this.tileHeight = undefined; + this.maximumLevel = undefined; + this.imageUrlSubdomains = undefined; + this.imageUrlTemplate = undefined; + + this.attributionList = undefined; +} + +/** + * Complete BingMapsImageryProvider creation based on builder values. + * + * @private + * + * @param {BingMapsImageryProvider} provider + */ +ImageryProviderBuilder.prototype.build = function (provider) { + provider._tileWidth = this.tileWidth; + provider._tileHeight = this.tileHeight; + provider._maximumLevel = this.maximumLevel; + provider._imageUrlSubdomains = this.imageUrlSubdomains; + provider._imageUrlTemplate = this.imageUrlTemplate; + + let attributionList = (provider._attributionList = this.attributionList); + if (!attributionList) { + attributionList = []; + } + provider._attributionList = attributionList; + + for ( + let attributionIndex = 0, attributionLength = attributionList.length; + attributionIndex < attributionLength; + ++attributionIndex + ) { + const attribution = attributionList[attributionIndex]; + + if (attribution.credit instanceof Credit) { + // If attribution.credit has already been created + // then we are using a cached value, which means + // none of the remaining processing needs to be done. + break; + } + + attribution.credit = new Credit(attribution.attribution); + const coverageAreas = attribution.coverageAreas; + + for ( + let areaIndex = 0, areaLength = attribution.coverageAreas.length; + areaIndex < areaLength; + ++areaIndex + ) { + const area = coverageAreas[areaIndex]; + const bbox = area.bbox; + area.bbox = new Rectangle( + CesiumMath.toRadians(bbox[1]), + CesiumMath.toRadians(bbox[0]), + CesiumMath.toRadians(bbox[3]), + CesiumMath.toRadians(bbox[2]) + ); + } + } + + provider._ready = true; +}; + +function metadataSuccess(data, imageryProviderBuilder) { + if (data.resourceSets.length !== 1) { + throw new RuntimeError( + "metadata does not specify one resource in resourceSets" + ); + } + + const resource = data.resourceSets[0].resources[0]; + imageryProviderBuilder.tileWidth = resource.imageWidth; + imageryProviderBuilder.tileHeight = resource.imageHeight; + imageryProviderBuilder.maximumLevel = resource.zoomMax - 1; + imageryProviderBuilder.imageUrlSubdomains = resource.imageUrlSubdomains; + imageryProviderBuilder.imageUrlTemplate = resource.imageUrl; + imageryProviderBuilder.attributionList = resource.imageryProviders; +} + +function metadataFailure(metadataResource, error, provider) { + let message = `An error occurred while accessing ${metadataResource.url}`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + TileProviderError.reportError( + undefined, + provider, + defined(provider) ? provider._errorEvent : undefined, + message, + undefined, + undefined, + undefined, + error + ); + + throw new RuntimeError(message); +} + +async function requestMetadata( + metadataResource, + imageryProviderBuilder, + provider +) { + const cacheKey = metadataResource.url; + let promise = BingMapsImageryProvider._metadataCache[cacheKey]; + if (!defined(promise)) { + promise = metadataResource.fetchJsonp("jsonp"); + BingMapsImageryProvider._metadataCache[cacheKey] = promise; + } + + try { + const data = await promise; + return metadataSuccess(data, imageryProviderBuilder); + } catch (e) { + metadataFailure(metadataResource, e, provider); + } +} + /** * <div class="notice"> * To construct a BingMapsImageryProvider, call {@link BingMapsImageryProvider.fromUrl}. Do not call the constructor directly. @@ -182,6 +312,7 @@ function BingMapsImageryProvider(options) { this._maximumLevel = undefined; this._imageUrlTemplate = undefined; this._imageUrlSubdomains = undefined; + this._attributionList = undefined; this._errorEvent = new Event(); @@ -234,8 +365,6 @@ function BingMapsImageryProvider(options) { imageryProviderBuilder.build(this); return true; }); - } else { - this._readyPromise = Promise.resolve(true); } } @@ -466,136 +595,6 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { }, }); -/** - * Used to track creation details while fetching initial metadata - * - * @constructor - * @private - * - * @param {BingMapsImageryProvider.ConstructorOptions} options An object describing initialization options - */ -function ImageryProviderBuilder(options) { - this.tileWidth = undefined; - this.tileHeight = undefined; - this.maximumLevel = undefined; - this.imageUrlSubdomains = undefined; - this.imageUrlTemplate = undefined; - - this.attributionList = undefined; -} - -/** - * Complete BingMapsImageryProvider creation based on builder values. - * - * @private - * - * @param {BingMapsImageryProvider} provider - */ -ImageryProviderBuilder.prototype.build = function (provider) { - provider._tileWidth = this.tileWidth; - provider._tileHeight = this.tileHeight; - provider._maximumLevel = this.maximumLevel; - provider._imageUrlSubdomains = this.imageUrlSubdomains; - provider._imageUrlTemplate = this.imageUrlTemplate; - - let attributionList = (provider._attributionList = this.attributionList); - if (!attributionList) { - attributionList = []; - } - provider._attributionList = attributionList; - - for ( - let attributionIndex = 0, attributionLength = attributionList.length; - attributionIndex < attributionLength; - ++attributionIndex - ) { - const attribution = attributionList[attributionIndex]; - - if (attribution.credit instanceof Credit) { - // If attribution.credit has already been created - // then we are using a cached value, which means - // none of the remaining processing needs to be done. - break; - } - - attribution.credit = new Credit(attribution.attribution); - const coverageAreas = attribution.coverageAreas; - - for ( - let areaIndex = 0, areaLength = attribution.coverageAreas.length; - areaIndex < areaLength; - ++areaIndex - ) { - const area = coverageAreas[areaIndex]; - const bbox = area.bbox; - area.bbox = new Rectangle( - CesiumMath.toRadians(bbox[1]), - CesiumMath.toRadians(bbox[0]), - CesiumMath.toRadians(bbox[3]), - CesiumMath.toRadians(bbox[2]) - ); - } - } - - provider._ready = true; -}; - -function metadataSuccess(data, imageryProviderBuilder) { - if (data.resourceSets.length !== 1) { - throw new RuntimeError( - "metadata does not specify one resource in resourceSets" - ); - } - - const resource = data.resourceSets[0].resources[0]; - imageryProviderBuilder.tileWidth = resource.imageWidth; - imageryProviderBuilder.tileHeight = resource.imageHeight; - imageryProviderBuilder.maximumLevel = resource.zoomMax - 1; - imageryProviderBuilder.imageUrlSubdomains = resource.imageUrlSubdomains; - imageryProviderBuilder.imageUrlTemplate = resource.imageUrl; - imageryProviderBuilder.attributionList = resource.imageryProviders; -} - -function metadataFailure(metadataResource, error, provider) { - let message = `An error occurred while accessing ${metadataResource.url}`; - if (defined(error) && defined(error.message)) { - message += `: ${error.message}`; - } - - TileProviderError.reportError( - undefined, - provider, - defined(provider) ? provider._errorEvent : undefined, - message, - undefined, - undefined, - undefined, - error - ); - - throw new RuntimeError(message); -} - -async function requestMetadata( - metadataResource, - imageryProviderBuilder, - provider -) { - const cacheKey = metadataResource.url; - let promise = BingMapsImageryProvider._metadataCache[cacheKey]; - if (!defined(promise)) { - promise = metadataResource.fetchJsonp("jsonp"); - BingMapsImageryProvider._metadataCache[cacheKey] = promise; - } - - try { - const data = await promise; - return metadataSuccess(data, imageryProviderBuilder); - } catch (e) { - metadataFailure(metadataResource, e, provider); - } -} - /** * Creates an {@link ImageryProvider} which provides tiled imagery using the Bing Maps Imagery REST API. * @@ -657,6 +656,7 @@ BingMapsImageryProvider.fromUrl = async function (url, key, options) { const imageryProviderBuilder = new ImageryProviderBuilder(options); await requestMetadata(metadataResource, imageryProviderBuilder); imageryProviderBuilder.build(provider); + provider._readyPromise = Promise.resolve(true); return provider; }; diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 600fe0a5573..86ebff22798 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -3,6 +3,7 @@ import Cartesian4 from "../Core/Cartesian4.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import FeatureDetection from "../Core/FeatureDetection.js"; import GeographicProjection from "../Core/GeographicProjection.js"; @@ -497,6 +498,11 @@ const terrainRectangleScratch = new Rectangle(); * }); */ ImageryLayer.prototype.getViewableRectangle = async function () { + deprecationWarning( + "ImageryLayer.getViewableRectangle", + "ImageryLayer.getViewableRectangle was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.getImageryRectangle instead." + ); + const imageryProvider = this._imageryProvider; const rectangle = this._rectangle; // readyPromise has been deprecated. This is here for backward compatibility and can be removed with readyPromise. @@ -504,6 +510,26 @@ ImageryLayer.prototype.getViewableRectangle = async function () { return Rectangle.intersection(imageryProvider.rectangle, rectangle); }; +/** + * Computes the intersection of this layer's rectangle with the imagery provider's availability rectangle, + * producing the overall bounds of imagery that can be produced by this layer. + * + * @returns {Rectangle} A promise to a rectangle which defines the overall bounds of imagery that can be produced by this layer. + * + * @example + * // Zoom to an imagery layer. + * const imageryRectangle = imageryLayer.getImageryRectangle(); + * scene.camera.flyTo({ + * destination: rectangle + * }); + * + */ +ImageryLayer.prototype.getImageryRectangle = function () { + const imageryProvider = this._imageryProvider; + const rectangle = this._rectangle; + return Rectangle.intersection(imageryProvider.rectangle, rectangle); +}; + /** * Create skeletons for the imagery tiles that partially or completely overlap a given terrain * tile. diff --git a/packages/engine/Source/Scene/QuadtreeTileProvider.js b/packages/engine/Source/Scene/QuadtreeTileProvider.js index e135704c012..0385d35ffd0 100644 --- a/packages/engine/Source/Scene/QuadtreeTileProvider.js +++ b/packages/engine/Source/Scene/QuadtreeTileProvider.js @@ -42,6 +42,16 @@ Object.defineProperties(QuadtreeTileProvider.prototype, { set: DeveloperError.throwInstantiationError, }, + /** + * Gets a value indicating whether or not the provider is ready for use. + * @memberof QuadtreeTileProvider.prototype + * @type {Boolean} + * @deprecated + */ + ready: { + get: DeveloperError.throwInstantiationError, + }, + /** * Gets the tiling scheme used by the provider. * @memberof QuadtreeTileProvider.prototype diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index e440344598f..93abda78c04 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -3,6 +3,7 @@ import Cartographic from "../Core/Cartographic.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import GeographicProjection from "../Core/GeographicProjection.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; import Rectangle from "../Core/Rectangle.js"; @@ -64,7 +65,7 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; * * @example * const tms = await Cesium.TileMapServiceImageryProvider.fromUrl( - * '../images/cesium_maptiler/Cesium_Logo_Color', { + * "../images/cesium_maptiler/Cesium_Logo_Color", { * fileExtension: 'png', * maximumLevel: 4, * rectangle: new Cesium.Rectangle( @@ -78,6 +79,11 @@ function TileMapServiceImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); if (defined(options.url)) { + deprecationWarning( + "TileMapServiceImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use TileMapServiceImageryProvider.fromUrl instead." + ); + this._metadataError = undefined; this._ready = false; diff --git a/packages/engine/Source/Scene/createWorldImageryAsync.js b/packages/engine/Source/Scene/createWorldImageryAsync.js index 801baf1cb98..9b2f0b26b5b 100644 --- a/packages/engine/Source/Scene/createWorldImageryAsync.js +++ b/packages/engine/Source/Scene/createWorldImageryAsync.js @@ -9,7 +9,7 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * * @param {Object} [options] Object with the following properties: * @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. - * @returns {IonImageryProvider} + * @returns {Promise<IonImageryProvide>} * * @see Ion * diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index 03ec459bf09..9d9315b7b9a 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -17,6 +17,7 @@ import { } from "../../index.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; +import createFakeBingMapsMetadataResponse from "../createFakeBingMapsMetadataResponse.js"; describe("Scene/BingMapsImageryProvider", function () { let supportsImageBitmapOptions; @@ -91,79 +92,6 @@ describe("Scene/BingMapsImageryProvider", function () { expect(constructWithoutServer).toThrowDeveloperError(); }); - function createFakeMetadataResponse(mapStyle) { - let stylePrefix = "a"; - switch (mapStyle) { - case BingMapsStyle.AERIAL_WITH_LABELS: - stylePrefix = "h"; - break; - case BingMapsStyle.ROAD: - stylePrefix = "r"; - break; - } - - return { - authenticationResultCode: "ValidCredentials", - brandLogoUri: "http://dev.virtualearth.net/Branding/logo_powered_by.png", - copyright: - "Copyright © 2014 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", - resourceSets: [ - { - estimatedTotal: 1, - resources: [ - { - __type: - "ImageryMetadata:http://schemas.microsoft.com/search/local/ws/rest/v1", - imageHeight: 256, - imageUrl: `http://ecn.{subdomain}.tiles.virtualearth.net.fake.invalid/tiles/${stylePrefix}{quadkey}.jpeg?g=3031&mkt={culture}`, - imageUrlSubdomains: ["t0", "t1", "t2", "t3"], - imageWidth: 256, - imageryProviders: [ - { - attribution: "© 2014 DigitalGlobe", - coverageAreas: [ - { - bbox: [-67, -179.99, 27, 0], - zoomMax: 21, - zoomMin: 14, - }, - { - bbox: [27, -179.99, 87, -126.5], - zoomMax: 21, - zoomMin: 14, - }, - { - bbox: [48.4, -126.5, 87, -5.75], - zoomMax: 21, - zoomMin: 14, - }, - ], - }, - { - attribution: "Image courtesy of NASA", - coverageAreas: [ - { - bbox: [-90, -180, 90, 180], - zoomMax: 8, - zoomMin: 1, - }, - ], - }, - ], - vintageEnd: null, - vintageStart: null, - zoomMax: 21, - zoomMin: 1, - }, - ], - }, - ], - statusCode: 200, - statusDescription: "OK", - traceId: "ea754a48ccdb4dd297c8f35350e0f0d9|BN20130533|02.00.106.1600|", - }; - } - function installFakeMetadataRequest(url, mapStyle, proxy) { const baseUri = new Uri(appendForwardSlash(url)); const expectedUri = new Uri( @@ -188,7 +116,7 @@ describe("Scene/BingMapsImageryProvider", function () { expect(uri.toString()).toStartWith(expectedUri.toString()); setTimeout(function () { - window[functionName](createFakeMetadataResponse(mapStyle)); + window[functionName](createFakeBingMapsMetadataResponse(mapStyle)); }, 1); }; } @@ -559,7 +487,9 @@ describe("Scene/BingMapsImageryProvider", function () { expect(uri.toString()).toStartWith(expectedUri.toString()); setTimeout(function () { - const response = createFakeMetadataResponse(BingMapsStyle.AERIAL); + const response = createFakeBingMapsMetadataResponse( + BingMapsStyle.AERIAL + ); response.resourceSets = []; window[functionName](response); }, 1); diff --git a/packages/engine/Specs/Scene/ImageryLayerSpec.js b/packages/engine/Specs/Scene/ImageryLayerSpec.js index 5114c683577..d3e87ec0e37 100644 --- a/packages/engine/Specs/Scene/ImageryLayerSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerSpec.js @@ -568,6 +568,25 @@ describe( }); }); + it("getImageryRectangle works", async function () { + const providerRectangle = Rectangle.fromDegrees(8.2, 61.09, 8.5, 61.7); + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png", + { + rectangle: providerRectangle, + } + ); + + const layerRectangle = Rectangle.fromDegrees(7.2, 60.9, 9.0, 61.7); + const layer = new ImageryLayer(provider, { + rectangle: layerRectangle, + }); + + expect(layer.getImageryRectangle()).toEqual( + Rectangle.intersection(providerRectangle, layerRectangle) + ); + }); + describe("createTileImagerySkeletons", function () { it("handles a base layer that does not cover the entire globe", function () { const provider = new TileMapServiceImageryProvider({ diff --git a/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js b/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js index 81372557917..085fe985cec 100644 --- a/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js +++ b/packages/engine/Specs/Scene/createWorldImageryAsyncSpec.js @@ -1,9 +1,19 @@ -import { createWorldImageryAsync, IonImageryProvider } from "../../index.js"; +import { + createWorldImageryAsync, + BingMapsStyle, + IonImageryProvider, + Resource, +} from "../../index.js"; + +import createFakeBingMapsMetadataResponse from "../createFakeBingMapsMetadataResponse.js"; describe("Core/createWorldImageryAsync", function () { it("resolves to IonImageryProvider instance with default parameters", async function () { + spyOn(Resource.prototype, "fetchJsonp").and.callFake(() => + Promise.resolve(createFakeBingMapsMetadataResponse(BingMapsStyle.AERIAL)) + ); + const provider = await createWorldImageryAsync(); expect(provider).toBeInstanceOf(IonImageryProvider); - expect(provider.assetId).toBe(2); }); }); diff --git a/packages/engine/Specs/createFakeBingMapsMetadataResponse.js b/packages/engine/Specs/createFakeBingMapsMetadataResponse.js new file mode 100644 index 00000000000..a1d6c1f0ff3 --- /dev/null +++ b/packages/engine/Specs/createFakeBingMapsMetadataResponse.js @@ -0,0 +1,73 @@ +import { BingMapsStyle } from "@cesium/engine"; + +export default function (mapStyle) { + let stylePrefix = "a"; + switch (mapStyle) { + case BingMapsStyle.AERIAL_WITH_LABELS: + stylePrefix = "h"; + break; + case BingMapsStyle.ROAD: + stylePrefix = "r"; + break; + } + return { + authenticationResultCode: "ValidCredentials", + brandLogoUri: "http://dev.virtualearth.net/Branding/logo_powered_by.png", + copyright: + "Copyright © 2014 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", + resourceSets: [ + { + estimatedTotal: 1, + resources: [ + { + __type: + "ImageryMetadata:http://schemas.microsoft.com/search/local/ws/rest/v1", + imageHeight: 256, + imageUrl: `http://ecn.{subdomain}.tiles.virtualearth.net.fake.invalid/tiles/${stylePrefix}{quadkey}.jpeg?g=3031&mkt={culture}`, + imageUrlSubdomains: ["t0", "t1", "t2", "t3"], + imageWidth: 256, + imageryProviders: [ + { + attribution: "© 2014 DigitalGlobe", + coverageAreas: [ + { + bbox: [-67, -179.99, 27, 0], + zoomMax: 21, + zoomMin: 14, + }, + { + bbox: [27, -179.99, 87, -126.5], + zoomMax: 21, + zoomMin: 14, + }, + { + bbox: [48.4, -126.5, 87, -5.75], + zoomMax: 21, + zoomMin: 14, + }, + ], + }, + { + attribution: "Image courtesy of NASA", + coverageAreas: [ + { + bbox: [-90, -180, 90, 180], + zoomMax: 8, + zoomMin: 1, + }, + ], + }, + ], + vintageEnd: null, + vintageStart: null, + zoomMax: 21, + zoomMin: 1, + }, + ], + }, + ], + statusCode: 200, + statusDescription: "OK", + traceId: "ea754a48ccdb4dd297c8f35350e0f0d9|BN20130533|02.00.106.1600|", + }; +} From 78e066c46de3a26b101f5223b5233543e10e8855 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Feb 2023 16:37:24 -0500 Subject: [PATCH 435/679] voxels: simplify RayShapeIntersection struct --- .../Source/Shaders/Voxels/IntersectBox.glsl | 12 ++++++----- .../Source/Shaders/Voxels/Intersection.glsl | 8 ++++---- .../Shaders/Voxels/IntersectionUtils.glsl | 20 ++++++++----------- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 18 ++++++++--------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index 6ad10e6c314..c56a7d4cf50 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -55,17 +55,19 @@ RayShapeIntersection intersectBox(in Ray ray, in Box box) float entryT = max(max(entries.x, entries.y), entries.z); float exitT = min(min(exits.x, exits.y), exits.z); - vec3 normal = getBoxNormal(box, ray, entryT); - + vec3 entryNormal = getBoxNormal(box, ray, entryT); + vec3 exitNormal = getBoxNormal(box, ray, exitT); + if (entryT > exitT) { - return RayShapeIntersection(normal, NO_HIT, NO_HIT); + entryT = NO_HIT; + exitT = NO_HIT; } - return RayShapeIntersection(normal, entryT, exitT); + return RayShapeIntersection(vec4(entryNormal, entryT), vec4(exitNormal, exitT)); } void intersectShape(in Ray ray, inout Intersections ix) { RayShapeIntersection intersection = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds)); - setIntersectionPair(ix, BOX_INTERSECTION_INDEX, vec2(intersection.entryT, intersection.exitT)); + setIntersectionPair(ix, BOX_INTERSECTION_INDEX, vec2(intersection.entry.w, intersection.exit.w)); } diff --git a/packages/engine/Source/Shaders/Voxels/Intersection.glsl b/packages/engine/Source/Shaders/Voxels/Intersection.glsl index a01c51906df..da201b085ad 100644 --- a/packages/engine/Source/Shaders/Voxels/Intersection.glsl +++ b/packages/engine/Source/Shaders/Voxels/Intersection.glsl @@ -17,7 +17,7 @@ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Interse // Exit early if the positive shape was completely missed or behind the ray. RayShapeIntersection intersection = getFirstIntersection(ix); - if (intersection.entryT == NO_HIT) { + if (intersection.entry.w == NO_HIT) { // Positive shape was completely missed - so exit early. return intersection; } @@ -37,15 +37,15 @@ RayShapeIntersection intersectScene(in vec2 screenCoord, in Ray ray, out Interse initializeIntersections(ix); for (int i = 0; i < INTERSECTION_COUNT; ++i) { intersection = nextIntersection(ix); - if (intersection.exitT > 0.0) { + if (intersection.exit.w > 0.0) { // Set start to 0.0 when ray is inside the shape. - intersection.entryT = max(intersection.entryT, 0.0); + intersection.entry.w = max(intersection.entry.w, 0.0); break; } } #else // Set start to 0.0 when ray is inside the shape. - intersection.entryT = max(intersection.entryT, 0.0); + intersection.entry.w = max(intersection.entry.w, 0.0); #endif return intersection; diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 979e20ad909..a595a51c171 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -15,9 +15,8 @@ struct Ray { }; struct RayShapeIntersection { - vec3 normal; - float entryT; - float exitT; + vec4 entry; + vec4 exit; }; struct Intersections { @@ -45,10 +44,7 @@ struct Intersections { RayShapeIntersection getFirstIntersection(in Intersections ix) { - vec3 normal = ix.intersections[0].xyz; - float entryT = ix.intersections[0].w; - float exitT = ix.intersections[1].w; - return RayShapeIntersection(normal, entryT, exitT); + return RayShapeIntersection(ix.intersections[0], ix.intersections[1]); } // Use defines instead of real functions because WebGL1 cannot access array with non-constant index. @@ -86,7 +82,8 @@ void initializeIntersections(inout Intersections ix) { #if (INTERSECTION_COUNT > 1) RayShapeIntersection nextIntersection(inout Intersections ix) { - RayShapeIntersection shapeIntersection = RayShapeIntersection(vec3(0.0), NO_HIT, NO_HIT); + vec4 surfaceIntersection = vec4(0.0, 0.0, 0.0, NO_HIT); + RayShapeIntersection shapeIntersection = RayShapeIntersection(surfaceIntersection, surfaceIntersection); const int passCount = INTERSECTION_COUNT * 2; @@ -103,7 +100,7 @@ RayShapeIntersection nextIntersection(inout Intersections ix) { ix.index = i + 1; - vec4 surfaceIntersection = ix.intersections[i]; + surfaceIntersection = ix.intersections[i]; float t = surfaceIntersection.w; float intersectionType = length(surfaceIntersection.xyz) - 1.0; bool currShapeIsPositive = intersectionType < 2.0; @@ -114,15 +111,14 @@ RayShapeIntersection nextIntersection(inout Intersections ix) { // entering positive or exiting negative if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) { - shapeIntersection.normal = surfaceIntersection.xyz; - shapeIntersection.entryT = t; + shapeIntersection.entry = surfaceIntersection; } // exiting positive or entering negative after being inside positive bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0; bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive; if (exitPositive || enterNegativeFromPositive) { - shapeIntersection.exitT = t; + shapeIntersection.exit = surfaceIntersection; // entry and exit have been found, so the loop can stop if (exitPositive) { diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index dd7a39244a8..88120c660fe 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -32,9 +32,9 @@ vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersecti #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); - float entry = max(voxelIntersection.entryT, shapeIntersection.entryT); - float exit = min(voxelIntersection.exitT, shapeIntersection.exitT); - return vec4(voxelIntersection.normal, exit - entry); + float entry = max(voxelIntersection.entry.w, shapeIntersection.entry.w); + float exit = min(voxelIntersection.exit.w, shapeIntersection.exit.w); + return vec4(voxelIntersection.entry.xyz, exit - entry); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); return vec4(viewRay.dir, u_stepSize / dimAtLevel); @@ -60,12 +60,12 @@ void main() RayShapeIntersection shapeIntersection = intersectScene(screenCoord, viewRayUv, ix); // Exit early if the scene was completely missed. - if (shapeIntersection.entryT == NO_HIT) { + if (shapeIntersection.entry.w == NO_HIT) { discard; } - float currT = shapeIntersection.entryT + RAY_SHIFT; - float endT = shapeIntersection.exitT; + float currT = shapeIntersection.entry.w + RAY_SHIFT; + float endT = shapeIntersection.exit.w; vec3 positionUv = viewPosUv + currT * viewDirUv; vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); @@ -136,12 +136,12 @@ void main() break; #else shapeIntersection = nextIntersection(ix); - if (shapeIntersection.entryT == NO_HIT) { + if (shapeIntersection.entry.w == NO_HIT) { break; } else { // Found another intersection. Resume raymarching there - currT = shapeIntersection.entryT; - endT = shapeIntersection.exitT; + currT = shapeIntersection.entry.w; + endT = shapeIntersection.exit.w; positionUv = viewPosUv + currT * viewDirUv; } #endif From 79acbf28d4ad2798812588cd25a02c481267236f Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 6 Feb 2023 16:49:56 -0500 Subject: [PATCH 436/679] Spec cleanup --- .../Source/Core/CesiumTerrainProvider.js | 6 +- .../Source/Scene/MapboxImageryProvider.js | 3 + .../Scene/MapboxStyleImageryProvider.js | 3 + .../Scene/WebMapServiceImageryProvider.js | 3 + .../ArcGisMapServerImageryProviderSpec.js | 149 ++- packages/engine/Specs/Scene/GlobeSpec.js | 263 +++--- .../Scene/GlobeSurfaceTileProviderSpec.js | 875 ++++++++---------- .../engine/Specs/Scene/ImageryLayerSpec.js | 835 ++++++++--------- .../Specs/Scene/MapboxImageryProviderSpec.js | 16 +- .../Scene/MapboxStyleImageryProviderSpec.js | 16 +- packages/engine/Specs/Scene/SceneSpec.js | 37 +- 11 files changed, 1008 insertions(+), 1198 deletions(-) diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index fee236a950d..b969d361a59 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -381,11 +381,7 @@ function parseMetadataFailure(terrainProviderBuilder, error, provider) { return requestLayerJson(terrainProviderBuilder, provider); } - const runtimeError = new RuntimeError(error); - - // preserve the original stack as that's where the error originated - runtimeError.stack = error.stack; - throw runtimeError; + throw new RuntimeError(message); } async function metadataSuccess(terrainProviderBuilder, data, provider) { diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index 15d9fe0540d..1b3b2399179 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -192,6 +192,9 @@ function MapboxImageryProvider(options) { maximumLevel: options.maximumLevel, rectangle: options.rectangle, }); + + this._ready = true; + this._readyPromise = Promise.resolve(true); } Object.defineProperties(MapboxImageryProvider.prototype, { diff --git a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js index 25351f3332e..391eac23105 100644 --- a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js @@ -196,6 +196,9 @@ function MapboxStyleImageryProvider(options) { maximumLevel: options.maximumLevel, rectangle: options.rectangle, }); + + this._ready = true; + this._readyPromise = Promise.resolve(true); } Object.defineProperties(MapboxStyleImageryProvider.prototype, { diff --git a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js index 2f552db8ff3..2bf6fd5454b 100644 --- a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js @@ -341,6 +341,9 @@ function WebMapServiceImageryProvider(options) { ), enablePickFeatures: options.enablePickFeatures, }); + + this._ready = true; + this._readyPromise = Promise.resolve(true); } function requestImage(imageryProvider, col, row, level, request, interval) { diff --git a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js index 6e5e86fb3cc..b0717a912ed 100644 --- a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js @@ -1226,11 +1226,13 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); describe("pickFeatures", function () { - it("works with WebMercator geometry", function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - }); + it("works with WebMercator geometry", async function () { + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + } + ); Resource._Implementations.loadWithXhr = function ( url, @@ -1253,25 +1255,20 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.description).toContain("Hummock Grasses"); - expect(firstResult.position).toEqual( - new WebMercatorProjection().unproject( - new Cartesian3(1.481682457042425e7, -2710890.117898505) - ) - ); - }); - }); + const pickResult = await provider.pickFeatures(0, 0, 0, 0.5, 0.5); + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.description).toContain("Hummock Grasses"); + expect(firstResult.position).toEqual( + new WebMercatorProjection().unproject( + new Cartesian3(1.481682457042425e7, -2710890.117898505) + ) + ); }); - it("works with Geographic geometry", function () { + it("works with Geographic geometry", async function () { const provider = new ArcGisMapServerImageryProvider({ url: "made/up/map/server", usePreCachedTilesIfAvailable: false, @@ -1298,54 +1295,50 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { ); }; - return provider.readyPromise.then(function () { - return provider - .pickFeatures(0, 0, 0, 0.5, 0.5) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.description).toContain("Hummock Grasses"); - expect(firstResult.position).toEqual( - Cartographic.fromDegrees(123.45, -34.2) - ); - }); - }); + const pickResult = await provider.pickFeatures(0, 0, 0, 0.5, 0.5); + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.description).toContain("Hummock Grasses"); + expect(firstResult.position).toEqual( + Cartographic.fromDegrees(123.45, -34.2) + ); }); - it("returns undefined if enablePickFeatures is false", function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - enablePickFeatures: false, - }); + it("returns undefined if enablePickFeatures is false", async function () { + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + enablePickFeatures: false, + } + ); - return provider.readyPromise.then(function () { - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); - }); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); }); - it("returns undefined if enablePickFeatures is dynamically set to false", function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - enablePickFeatures: true, - }); + it("returns undefined if enablePickFeatures is dynamically set to false", async function () { + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + enablePickFeatures: true, + } + ); provider.enablePickFeatures = false; - - return provider.readyPromise.then(function () { - expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); - }); + expect(provider.pickFeatures(0, 0, 0, 0.5, 0.5)).toBeUndefined(); }); - it("does not return undefined if enablePickFeatures is dynamically set to true", function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - enablePickFeatures: false, - }); + it("does not return undefined if enablePickFeatures is dynamically set to true", async function () { + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + enablePickFeatures: false, + } + ); provider.enablePickFeatures = true; @@ -1370,22 +1363,11 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { ); }; - return provider.readyPromise - .then(function () { - return provider.pickFeatures(0, 0, 0, 0.5, 0.5); - }) - .then(function (value) { - expect(value).toBeDefined(); - }); + const value = await provider.pickFeatures(0, 0, 0, 0.5, 0.5); + expect(value).toBeDefined(); }); - it("picks from individual layers", function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - layers: "someLayer,anotherLayerYay", - }); - + it("picks from individual layers", async function () { Resource._Implementations.loadWithXhr = function ( url, responseType, @@ -1410,13 +1392,16 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { ); }; - return provider.readyPromise - .then(function () { - return provider.pickFeatures(0, 0, 0, 0.5, 0.5); - }) - .then(function (pickResult) { - expect(pickResult.length).toBe(1); - }); + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + layers: "someLayer,anotherLayerYay", + } + ); + + const pickResult = await provider.pickFeatures(0, 0, 0, 0.5, 0.5); + expect(pickResult.length).toBe(1); }); }); }); diff --git a/packages/engine/Specs/Scene/GlobeSpec.js b/packages/engine/Specs/Scene/GlobeSpec.js index 27d578a814e..cfc2b6a5f68 100644 --- a/packages/engine/Specs/Scene/GlobeSpec.js +++ b/packages/engine/Specs/Scene/GlobeSpec.js @@ -92,14 +92,15 @@ describe( }); } - it("renders with enableLighting", function () { + it("renders with enableLighting", async function () { globe.enableLighting = true; const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + layerCollection.addImageryProvider(provider); scene.camera.setView({ destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), @@ -113,15 +114,16 @@ describe( }); }); - it("renders with dynamicAtmosphereLighting", function () { + it("renders with dynamicAtmosphereLighting", async function () { globe.enableLighting = true; globe.dynamicAtmosphereLighting = true; const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + layerCollection.addImageryProvider(provider); scene.camera.setView({ destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), @@ -135,16 +137,17 @@ describe( }); }); - it("renders with dynamicAtmosphereLightingFromSun", function () { + it("renders with dynamicAtmosphereLightingFromSun", async function () { globe.enableLighting = true; globe.dynamicAtmosphereLighting = true; globe.dynamicAtmosphereLightingFromSun = true; const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + layerCollection.addImageryProvider(provider); scene.camera.setView({ destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), @@ -158,15 +161,17 @@ describe( }); }); - it("renders with showWaterEffect set to false", function () { + it("renders with showWaterEffect set to false", async function () { globe.showWaterEffect = false; const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + layerCollection.addImageryProvider(provider); + scene.camera.setView({ destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), }); @@ -179,7 +184,7 @@ describe( }); }); - it("ImageryLayersUpdated event fires when layer is added, hidden, shown, moved, or removed", function () { + it("ImageryLayersUpdated event fires when layer is added, hidden, shown, moved, or removed", async function () { let timesEventRaised = 0; globe.imageryLayersUpdatedEvent.addEventListener(function () { ++timesEventRaised; @@ -187,12 +192,11 @@ describe( const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - const layer = layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) - ); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Red16x16.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = layerCollection.addImageryProvider(provider); + layerCollection.addImageryProvider(provider); return updateUntilDone(globe) .then(function () { expect(timesEventRaised).toEqual(2); @@ -312,15 +316,14 @@ describe( destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), }); - return updateUntilDone(globe).then(function () { - expect(renderOptions).notToRender([0, 0, 0, 255]); + await updateUntilDone(globe); + expect(renderOptions).notToRender([0, 0, 0, 255]); - scene.globe.show = false; - expect(renderOptions).toRender([0, 0, 0, 255]); - }); + scene.globe.show = false; + expect(renderOptions).toRender([0, 0, 0, 255]); }); - it("renders terrain with lambertDiffuseMultiplier", function () { + it("renders terrain with lambertDiffuseMultiplier", async function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -329,55 +332,54 @@ describe( const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - const imageryProvider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + const imageryProvider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); layerCollection.addImageryProvider(imageryProvider); - return imageryProvider.readyPromise.then(function () { - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", responseType, method, data, headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", - responseType, - method, - data, - headers, - deferred - ); - }; + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { requestVertexNormals: true, - }); + } + ); - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - return updateUntilDone(globe).then(function () { - let initialRgba; - expect(renderOptions).toRenderAndCall(function (rgba) { - initialRgba = rgba; - expect(renderOptions).notToRender([0, 0, 0, 255]); - }); - globe.lambertDiffuseMultiplier = 10.0; - expect(renderOptions).notToRender(initialRgba); - }); + await updateUntilDone(globe); + let initialRgba; + expect(renderOptions).toRenderAndCall(function (rgba) { + initialRgba = rgba; + expect(renderOptions).notToRender([0, 0, 0, 255]); }); + globe.lambertDiffuseMultiplier = 10.0; + expect(renderOptions).notToRender(initialRgba); }); - it("renders terrain with vertexShadowDarkness", function () { + it("renders terrain with vertexShadowDarkness", async function () { const renderOptions = { scene: scene, time: new JulianDate(2557522.0), @@ -386,117 +388,116 @@ describe( const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - const imageryProvider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + const imageryProvider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); layerCollection.addImageryProvider(imageryProvider); - return imageryProvider.readyPromise.then(function () { - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", responseType, method, data, headers, - deferred, - overrideMimeType - ) { - Resource._DefaultImplementations.loadWithXhr( - "Data/CesiumTerrainTileJson/tile.vertexnormals.terrain", - responseType, - method, - data, - headers, - deferred - ); - }; + deferred + ); + }; - returnVertexNormalTileJson(); + returnVertexNormalTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { requestVertexNormals: true, - }); + } + ); - globe.terrainProvider = terrainProvider; - scene.camera.setView({ - destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), - }); + globe.terrainProvider = terrainProvider; + scene.camera.setView({ + destination: new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), + }); - return updateUntilDone(globe).then(function () { - let initialRgba; - expect(renderOptions).toRenderAndCall(function (rgba) { - initialRgba = rgba; - expect(renderOptions).notToRender([0, 0, 0, 255]); - globe.vertexShadowDarkness = 0.1; - expect(renderOptions).notToRender(initialRgba); - }); - }); + await updateUntilDone(globe); + let initialRgba; + expect(renderOptions).toRenderAndCall(function (rgba) { + initialRgba = rgba; + expect(renderOptions).notToRender([0, 0, 0, 255]); + globe.vertexShadowDarkness = 0.1; + expect(renderOptions).notToRender(initialRgba); }); }); - it("renders with hue shift", function () { + it("renders with hue shift", async function () { const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Blue.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Blue.png" ); + layerCollection.addImageryProvider(provider); scene.camera.flyHome(0.0); - return updateUntilDone(globe).then(function () { - scene.globe.show = false; - expect(scene).toRender([0, 0, 0, 255]); - scene.globe.show = true; + await updateUntilDone(globe); + scene.globe.show = false; + expect(scene).toRender([0, 0, 0, 255]); + scene.globe.show = true; + expect(scene).notToRender([0, 0, 0, 255]); + expect(scene).toRenderAndCall(function (rgba) { + scene.globe.atmosphereHueShift = 0.1; expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).toRenderAndCall(function (rgba) { - scene.globe.atmosphereHueShift = 0.1; - expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).notToRender(rgba); - }); + expect(scene).notToRender(rgba); }); }); - it("renders with saturation shift", function () { + it("renders with saturation shift", async function () { const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Blue.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Blue.png" ); + layerCollection.addImageryProvider(provider); scene.camera.flyHome(0.0); - return updateUntilDone(globe).then(function () { - scene.globe.show = false; - expect(scene).toRender([0, 0, 0, 255]); - scene.globe.show = true; + await updateUntilDone(globe); + scene.globe.show = false; + expect(scene).toRender([0, 0, 0, 255]); + scene.globe.show = true; + expect(scene).notToRender([0, 0, 0, 255]); + expect(scene).toRenderAndCall(function (rgba) { + scene.globe.atmosphereSaturationShift = 0.1; expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).toRenderAndCall(function (rgba) { - scene.globe.atmosphereSaturationShift = 0.1; - expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).notToRender(rgba); - }); + expect(scene).notToRender(rgba); }); }); - it("renders with brightness shift", function () { + it("renders with brightness shift", async function () { const layerCollection = globe.imageryLayers; layerCollection.removeAll(); - layerCollection.addImageryProvider( - new SingleTileImageryProvider({ url: "Data/Images/Blue.png" }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Blue.png" ); + layerCollection.addImageryProvider(provider); scene.camera.flyHome(0.0); - return updateUntilDone(globe).then(function () { - scene.globe.show = false; - expect(scene).toRender([0, 0, 0, 255]); - scene.globe.show = true; + await updateUntilDone(globe); + scene.globe.show = false; + expect(scene).toRender([0, 0, 0, 255]); + scene.globe.show = true; + expect(scene).notToRender([0, 0, 0, 255]); + expect(scene).toRenderAndCall(function (rgba) { + scene.globe.atmosphereBrightnessShift = 0.1; expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).toRenderAndCall(function (rgba) { - scene.globe.atmosphereBrightnessShift = 0.1; - expect(scene).notToRender([0, 0, 0, 255]); - expect(scene).notToRender(rgba); - }); + expect(scene).notToRender(rgba); }); }); diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js index a9852226bab..cf6581f13a4 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js @@ -70,7 +70,6 @@ describe( return pollToPromise(function () { scene.renderForSpecs(); return ( - globe._surface.tileProvider.ready && globe._surface._tileLoadQueueHigh.length === 0 && globe._surface._tileLoadQueueMedium.length === 0 && globe._surface._tileLoadQueueLow.length === 0 && @@ -156,356 +155,323 @@ describe( describe( "layer updating", function () { - it("removing a layer removes it from all tiles", function () { - const layer = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("removing a layer removes it from all tiles", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = scene.imageryLayers.addImageryProvider(provider); - return updateUntilDone(scene.globe).then(function () { - // All tiles should have one or more associated images. - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBeGreaterThan(0); - for (let i = 0; i < tile.data.imagery.length; ++i) { - const imagery = defaultValue( - tile.data.imagery[i].readyImagery, - tile.data.imagery[i].loadingImagery - ); - expect(imagery.imageryLayer).toEqual(layer); - } - }); + await updateUntilDone(scene.globe); + // All tiles should have one or more associated images. + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBeGreaterThan(0); + for (let i = 0; i < tile.data.imagery.length; ++i) { + const imagery = defaultValue( + tile.data.imagery[i].readyImagery, + tile.data.imagery[i].loadingImagery + ); + expect(imagery.imageryLayer).toEqual(layer); + } + }); - scene.imageryLayers.remove(layer); + scene.imageryLayers.remove(layer); - // All associated images should be gone. - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toEqual(0); - }); + // All associated images should be gone. + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toEqual(0); }); }); - it("adding a layer adds it to all tiles after update", function () { - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("adding a layer adds it to all tiles after update", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); - return updateUntilDone(scene.globe).then(function () { - // Add another layer - const layer2 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }) - ); + await updateUntilDone(scene.globe); + const provider2 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" + ); + // Add another layer + const layer2 = scene.imageryLayers.addImageryProvider(provider2); - return updateUntilDone(scene.globe).then(function () { - // All tiles should have one or more associated images. - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBeGreaterThan(0); - let hasImageFromLayer2 = false; - for (let i = 0; i < tile.data.imagery.length; ++i) { - let imageryTile = tile.data.imagery[i].readyImagery; - if (!defined(imageryTile)) { - imageryTile = tile.data.imagery[i].loadingImagery; - } - if (imageryTile.imageryLayer === layer2) { - hasImageFromLayer2 = true; - } - } - expect(hasImageFromLayer2).toEqual(true); - }); - }); + await updateUntilDone(scene.globe); + // All tiles should have one or more associated images. + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBeGreaterThan(0); + let hasImageFromLayer2 = false; + for (let i = 0; i < tile.data.imagery.length; ++i) { + let imageryTile = tile.data.imagery[i].readyImagery; + if (!defined(imageryTile)) { + imageryTile = tile.data.imagery[i].loadingImagery; + } + if (imageryTile.imageryLayer === layer2) { + hasImageFromLayer2 = true; + } + } + expect(hasImageFromLayer2).toEqual(true); }); }); - it("moving a layer moves the corresponding TileImagery instances on every tile", function () { - const layer1 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("moving a layer moves the corresponding TileImagery instances on every tile", async function () { + const provider1 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); - const layer2 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }) + const layer1 = scene.imageryLayers.addImageryProvider(provider1); + const provider2 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" ); + const layer2 = scene.imageryLayers.addImageryProvider(provider2); - return updateUntilDone(scene.globe).then(function () { - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBeGreaterThan(0); - let indexOfFirstLayer1 = tile.data.imagery.length; - let indexOfLastLayer1 = -1; - let indexOfFirstLayer2 = tile.data.imagery.length; - for (let i = 0; i < tile.data.imagery.length; ++i) { - const imagery = defaultValue( - tile.data.imagery[i].readyImagery, - tile.data.imagery[i].loadingImagery - ); - if (imagery.imageryLayer === layer1) { - indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i); - indexOfLastLayer1 = i; - } else { - expect(imagery.imageryLayer).toEqual(layer2); - indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i); - } + await updateUntilDone(scene.globe); + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBeGreaterThan(0); + let indexOfFirstLayer1 = tile.data.imagery.length; + let indexOfLastLayer1 = -1; + let indexOfFirstLayer2 = tile.data.imagery.length; + for (let i = 0; i < tile.data.imagery.length; ++i) { + const imagery = defaultValue( + tile.data.imagery[i].readyImagery, + tile.data.imagery[i].loadingImagery + ); + if (imagery.imageryLayer === layer1) { + indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i); + indexOfLastLayer1 = i; + } else { + expect(imagery.imageryLayer).toEqual(layer2); + indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i); } - expect(indexOfFirstLayer1).toBeLessThan(indexOfFirstLayer2); - expect(indexOfLastLayer1).toBeLessThan(indexOfFirstLayer2); - }); + } + expect(indexOfFirstLayer1).toBeLessThan(indexOfFirstLayer2); + expect(indexOfLastLayer1).toBeLessThan(indexOfFirstLayer2); + }); - scene.imageryLayers.raiseToTop(layer1); - - return updateUntilDone(scene.globe).then(function () { - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBeGreaterThan(0); - let indexOfFirstLayer2 = tile.data.imagery.length; - let indexOfLastLayer2 = -1; - let indexOfFirstLayer1 = tile.data.imagery.length; - for (let i = 0; i < tile.data.imagery.length; ++i) { - if ( - tile.data.imagery[i].readyImagery.imageryLayer === layer2 - ) { - indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i); - indexOfLastLayer2 = i; - } else { - expect( - tile.data.imagery[i].readyImagery.imageryLayer - ).toEqual(layer1); - indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i); - } - } - expect(indexOfFirstLayer2).toBeLessThan(indexOfFirstLayer1); - expect(indexOfLastLayer2).toBeLessThan(indexOfFirstLayer1); - }); - }); + scene.imageryLayers.raiseToTop(layer1); + + await updateUntilDone(scene.globe); + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBeGreaterThan(0); + let indexOfFirstLayer2 = tile.data.imagery.length; + let indexOfLastLayer2 = -1; + let indexOfFirstLayer1 = tile.data.imagery.length; + for (let i = 0; i < tile.data.imagery.length; ++i) { + if (tile.data.imagery[i].readyImagery.imageryLayer === layer2) { + indexOfFirstLayer2 = Math.min(indexOfFirstLayer2, i); + indexOfLastLayer2 = i; + } else { + expect(tile.data.imagery[i].readyImagery.imageryLayer).toEqual( + layer1 + ); + indexOfFirstLayer1 = Math.min(indexOfFirstLayer1, i); + } + } + expect(indexOfFirstLayer2).toBeLessThan(indexOfFirstLayer1); + expect(indexOfLastLayer2).toBeLessThan(indexOfFirstLayer1); }); }); - it("adding a layer creates its skeletons only once", function () { - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("adding a layer creates its skeletons only once", async function () { + const provider1 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider1); - return updateUntilDone(scene.globe).then(function () { - // Add another layer - const layer2 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }) - ); + await updateUntilDone(scene.globe); + // Add another layer + const provider2 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" + ); + const layer2 = scene.imageryLayers.addImageryProvider(provider2); - return updateUntilDone(scene.globe).then(function () { - // All tiles should have one or more associated images. - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBeGreaterThan(0); - let tilesFromLayer2 = 0; - for (let i = 0; i < tile.data.imagery.length; ++i) { - let imageryTile = tile.data.imagery[i].readyImagery; - if (!defined(imageryTile)) { - imageryTile = tile.data.imagery[i].loadingImagery; - } - if (imageryTile.imageryLayer === layer2) { - ++tilesFromLayer2; - } - } - expect(tilesFromLayer2).toBe(1); - }); - }); + await updateUntilDone(scene.globe); + // All tiles should have one or more associated images. + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBeGreaterThan(0); + let tilesFromLayer2 = 0; + for (let i = 0; i < tile.data.imagery.length; ++i) { + let imageryTile = tile.data.imagery[i].readyImagery; + if (!defined(imageryTile)) { + imageryTile = tile.data.imagery[i].loadingImagery; + } + if (imageryTile.imageryLayer === layer2) { + ++tilesFromLayer2; + } + } + expect(tilesFromLayer2).toBe(1); }); }); - it("calling _reload adds a callback per layer per tile", function () { - const layer1 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("calling _reload adds a callback per layer per tile", async function () { + const provider1 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer1 = scene.imageryLayers.addImageryProvider(provider1); - const layer2 = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }) + const provider2 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" ); + const layer2 = scene.imageryLayers.addImageryProvider(provider2); - return updateUntilDone(scene.globe).then(function () { - // Verify that each tile has 2 imagery objects and no loaded callbacks - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBe(2); - expect(Object.keys(tile._loadedCallbacks).length).toBe(0); - }); + await updateUntilDone(scene.globe); + // Verify that each tile has 2 imagery objects and no loaded callbacks + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBe(2); + expect(Object.keys(tile._loadedCallbacks).length).toBe(0); + }); - // Reload each layer - layer1._imageryProvider._reload(); - layer2._imageryProvider._reload(); + // Reload each layer + layer1._imageryProvider._reload(); + layer2._imageryProvider._reload(); - // These should be ignored - layer1._imageryProvider._reload(); - layer2._imageryProvider._reload(); + // These should be ignored + layer1._imageryProvider._reload(); + layer2._imageryProvider._reload(); - // Verify that each tile has 4 imagery objects (the old imagery and the reloaded imagery for each layer) - // and also has 2 callbacks so the old imagery will be removed once loaded. - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBe(4); - expect(Object.keys(tile._loadedCallbacks).length).toBe(2); - }); + // Verify that each tile has 4 imagery objects (the old imagery and the reloaded imagery for each layer) + // and also has 2 callbacks so the old imagery will be removed once loaded. + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBe(4); + expect(Object.keys(tile._loadedCallbacks).length).toBe(2); + }); - return updateUntilDone(scene.globe).then(function () { - // Verify the old imagery was removed and the callbacks are no longer there - forEachRenderedTile(scene.globe._surface, 1, undefined, function ( - tile - ) { - expect(tile.data.imagery.length).toBe(2); - expect(Object.keys(tile._loadedCallbacks).length).toBe(0); - }); - }); + await updateUntilDone(scene.globe); + // Verify the old imagery was removed and the callbacks are no longer there + forEachRenderedTile(scene.globe._surface, 1, undefined, function ( + tile + ) { + expect(tile.data.imagery.length).toBe(2); + expect(Object.keys(tile._loadedCallbacks).length).toBe(0); }); }); }, "WebGL" ); - it("renders in 2D geographic", function () { + it("renders in 2D geographic", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE2D, new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); - it("renders in 2D web mercator", function () { + it("renders in 2D web mercator", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE2D, new WebMercatorProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); - it("renders in Columbus View geographic", function () { + it("renders in Columbus View geographic", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.COLUMBUS_VIEW, new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); - it("renders in Columbus View web mercator", function () { + it("renders in Columbus View web mercator", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.COLUMBUS_VIEW, new WebMercatorProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); - it("renders in 3D", function () { + it("renders in 3D", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); - it("renders in 3D (2)", function () { + it("renders in 3D (2)", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); describe("fog", function () { - it("culls tiles in full fog", function () { + it("culls tiles in full fog", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); const oldFog = scene.fog; scene.fog = new Fog(); switchViewMode( @@ -514,26 +480,24 @@ describe( ); scene.camera.lookUp(1.2); // Horizon-view - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - scene.fog.enabled = true; - scene.fog.density = 1.0; - scene.fog.screenSpaceErrorFactor = 0.0; + scene.fog.enabled = true; + scene.fog.density = 1.0; + scene.fog.screenSpaceErrorFactor = 0.0; - expect(scene).toRender([0, 0, 0, 255]); + expect(scene).toRender([0, 0, 0, 255]); - scene.fog = oldFog; - }); + scene.fog = oldFog; }); - it("culls tiles but does not render fog visuals when renderable is false", function () { + it("culls tiles but does not render fog visuals when renderable is false", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); const oldFog = scene.fog; scene.fog = new Fog(); switchViewMode( @@ -542,34 +506,32 @@ describe( ); scene.camera.lookUp(1.2); // Horizon-view - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - scene.fog.enabled = true; - scene.fog.density = 0.001; - scene.fog.screenSpaceErrorFactor = 0.0; + scene.fog.enabled = true; + scene.fog.density = 0.001; + scene.fog.screenSpaceErrorFactor = 0.0; - let result; - expect(scene).toRenderAndCall(function (rgba) { - result = rgba; - expect(rgba).not.toEqual([0, 0, 0, 255]); - }); + let result; + expect(scene).toRenderAndCall(function (rgba) { + result = rgba; + expect(rgba).not.toEqual([0, 0, 0, 255]); + }); - scene.fog.renderable = false; - expect(scene).notToRender(result); - expect(scene).notToRender([0, 0, 0, 255]); + scene.fog.renderable = false; + expect(scene).notToRender(result); + expect(scene).notToRender([0, 0, 0, 255]); - scene.fog = oldFog; - }); + scene.fog = oldFog; }); - it("culls tiles because of increased SSE", function () { + it("culls tiles because of increased SSE", async function () { expect(scene).toRender([0, 0, 0, 255]); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); const oldFog = scene.fog; scene.fog = new Fog(); switchViewMode( @@ -578,24 +540,23 @@ describe( ); scene.camera.lookUp(1.2); // Horizon-view - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - scene.fog.enabled = true; - scene.fog.density = 0.001; - scene.fog.screenSpaceErrorFactor = 0.0; - let result; - expect(scene).toRenderAndCall(function (rgba) { - result = rgba; - expect(rgba).not.toEqual([0, 0, 0, 255]); - }); + scene.fog.enabled = true; + scene.fog.density = 0.001; + scene.fog.screenSpaceErrorFactor = 0.0; + let result; + expect(scene).toRenderAndCall(function (rgba) { + result = rgba; + expect(rgba).not.toEqual([0, 0, 0, 255]); + }); - scene.fog.screenSpaceErrorFactor = 10000.0; + scene.fog.screenSpaceErrorFactor = 10000.0; - expect(scene).notToRender(result); + expect(scene).notToRender(result); - scene.fog = oldFog; - }); + scene.fog = oldFog; }); }); @@ -613,29 +574,26 @@ describe( }); }); - it("renders in 3D and then Columbus View", function () { - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("renders in 3D and then Columbus View", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE3D, new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - switchViewMode( - SceneMode.COLUMBUS_VIEW, - new GeographicProjection(Ellipsoid.WGS84) - ); + switchViewMode( + SceneMode.COLUMBUS_VIEW, + new GeographicProjection(Ellipsoid.WGS84) + ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); - }); - }); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); }); it("renders even if imagery root tiles fail to load", function () { @@ -657,14 +615,13 @@ describe( }); }); - it("passes layer adjustment values as uniforms", function () { + it("passes layer adjustment values as uniforms", async function () { expect(scene).toRender([0, 0, 0, 255]); - const layer = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = scene.imageryLayers.addImageryProvider(provider); layer.alpha = 0.123; layer.nightAlpha = 0.658; @@ -681,45 +638,43 @@ describe( new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - let tileCommandCount = 0; - const commandList = scene.frameState.commandList; + let tileCommandCount = 0; + const commandList = scene.frameState.commandList; - for (let i = 0; i < commandList.length; ++i) { - const command = commandList[i]; + for (let i = 0; i < commandList.length; ++i) { + const command = commandList[i]; - const uniforms = command.uniformMap; - if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { - continue; - } - - ++tileCommandCount; - - expect(uniforms.u_dayTextureAlpha()).toEqual([0.123]); - expect(uniforms.u_dayTextureNightAlpha()).toEqual([0.658]); - expect(uniforms.u_dayTextureDayAlpha()).toEqual([0.356]); - expect(uniforms.u_dayTextureBrightness()).toEqual([0.456]); - expect(uniforms.u_dayTextureContrast()).toEqual([0.654]); - expect(uniforms.u_dayTextureOneOverGamma()).toEqual([1.0 / 0.321]); - expect(uniforms.u_dayTextureSaturation()).toEqual([0.123]); - expect(uniforms.u_dayTextureHue()).toEqual([0.456]); - expect(uniforms.u_dayTextureSplit()).toEqual([SplitDirection.LEFT]); + const uniforms = command.uniformMap; + if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { + continue; } - expect(tileCommandCount).toBeGreaterThan(0); - }); + ++tileCommandCount; + + expect(uniforms.u_dayTextureAlpha()).toEqual([0.123]); + expect(uniforms.u_dayTextureNightAlpha()).toEqual([0.658]); + expect(uniforms.u_dayTextureDayAlpha()).toEqual([0.356]); + expect(uniforms.u_dayTextureBrightness()).toEqual([0.456]); + expect(uniforms.u_dayTextureContrast()).toEqual([0.654]); + expect(uniforms.u_dayTextureOneOverGamma()).toEqual([1.0 / 0.321]); + expect(uniforms.u_dayTextureSaturation()).toEqual([0.123]); + expect(uniforms.u_dayTextureHue()).toEqual([0.456]); + expect(uniforms.u_dayTextureSplit()).toEqual([SplitDirection.LEFT]); + } + + expect(tileCommandCount).toBeGreaterThan(0); }); it("renders imagery cutout", async function () { expect(scene).toRender([0, 0, 0, 255]); - const layer = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = scene.imageryLayers.addImageryProvider(provider); layer.cutoutRectangle = cameraDestination; switchViewMode( @@ -728,32 +683,27 @@ describe( ); let baseColor; - return updateUntilDone(scene.globe) - .then(function () { - expect(scene).toRenderAndCall(function (rgba) { - baseColor = rgba; - expect(rgba).not.toEqual([0, 0, 0, 255]); - }); - layer.cutoutRectangle = undefined; + await updateUntilDone(scene.globe); + expect(scene).toRenderAndCall(function (rgba) { + baseColor = rgba; + expect(rgba).not.toEqual([0, 0, 0, 255]); + }); + layer.cutoutRectangle = undefined; - return updateUntilDone(scene.globe); - }) - .then(function () { - expect(scene).toRenderAndCall(function (rgba) { - expect(rgba).not.toEqual(baseColor); - expect(rgba).not.toEqual([0, 0, 0, 255]); - }); - }); + await updateUntilDone(scene.globe); + expect(scene).toRenderAndCall(function (rgba) { + expect(rgba).not.toEqual(baseColor); + expect(rgba).not.toEqual([0, 0, 0, 255]); + }); }); - it("renders imagery with color-to-alpha", function () { + it("renders imagery with color-to-alpha", async function () { expect(scene).toRender([0, 0, 0, 255]); - const layer = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = scene.imageryLayers.addImageryProvider(provider); switchViewMode( SceneMode.SCENE3D, @@ -761,48 +711,43 @@ describe( ); let layerColor; - return updateUntilDone(scene.globe) - .then(function () { - expect(scene).toRenderAndCall(function (rgba) { - layerColor = rgba; - // Expect the layer color to be mostly red - expect(layerColor[0]).toBeGreaterThan(layerColor[1]); - expect(layerColor[0]).toBeGreaterThan(layerColor[2]); - }); + await updateUntilDone(scene.globe); + expect(scene).toRenderAndCall(function (rgba) { + layerColor = rgba; + // Expect the layer color to be mostly red + expect(layerColor[0]).toBeGreaterThan(layerColor[1]); + expect(layerColor[0]).toBeGreaterThan(layerColor[2]); + }); - layer.colorToAlpha = new Color(1.0, 0.0, 0.0); - layer.colorToAlphaThreshold = 0.1; + layer.colorToAlpha = new Color(1.0, 0.0, 0.0); + layer.colorToAlphaThreshold = 0.1; - return updateUntilDone(scene.globe); - }) - .then(function () { - const commandList = scene.frameState.commandList; + await updateUntilDone(scene.globe); + const commandList = scene.frameState.commandList; - for (let i = 0; i < commandList.length; ++i) { - const command = commandList[i]; + for (let i = 0; i < commandList.length; ++i) { + const command = commandList[i]; - const uniforms = command.uniformMap; - if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { - continue; - } + const uniforms = command.uniformMap; + if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { + continue; + } - expect(uniforms.u_colorsToAlpha()).toEqual([ - new Cartesian4(1.0, 0.0, 0.0, 0.1), - ]); - } + expect(uniforms.u_colorsToAlpha()).toEqual([ + new Cartesian4(1.0, 0.0, 0.0, 0.1), + ]); + } - expect(scene).toRenderAndCall(function (rgba) { - expect(rgba).not.toEqual(layerColor); - }); - }); + expect(scene).toRenderAndCall(function (rgba) { + expect(rgba).not.toEqual(layerColor); + }); }); - it("skips layer with uniform alpha value of zero", function () { - const layer = scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + it("skips layer with uniform alpha value of zero", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + const layer = scene.imageryLayers.addImageryProvider(provider); layer.alpha = 0.0; @@ -811,36 +756,34 @@ describe( new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - let tileCommandCount = 0; - const commandList = scene.frameState.commandList; + let tileCommandCount = 0; + const commandList = scene.frameState.commandList; - for (let i = 0; i < commandList.length; ++i) { - const command = commandList[i]; + for (let i = 0; i < commandList.length; ++i) { + const command = commandList[i]; - const uniforms = command.uniformMap; - if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { - continue; - } + const uniforms = command.uniformMap; + if (!defined(uniforms) || !defined(uniforms.u_dayTextureAlpha)) { + continue; + } - ++tileCommandCount; + ++tileCommandCount; - expect(uniforms.u_dayTextureAlpha()).toEqual([]); - } + expect(uniforms.u_dayTextureAlpha()).toEqual([]); + } - expect(tileCommandCount).toBeGreaterThan(0); - }); + expect(tileCommandCount).toBeGreaterThan(0); }); - it("can render more imagery layers than the available texture units", function () { + it("can render more imagery layers than the available texture units", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); for (let i = 0; i < ContextLimits.maximumTextureImageUnits + 1; ++i) { - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) - ); + scene.imageryLayers.addImageryProvider(provider); } switchViewMode( @@ -848,80 +791,82 @@ describe( new GeographicProjection(Ellipsoid.WGS84) ); - return updateUntilDone(scene.globe).then(function () { - expect(scene).notToRender([0, 0, 0, 255]); + await updateUntilDone(scene.globe); + expect(scene).notToRender([0, 0, 0, 255]); - const renderStateWithAlphaBlending = RenderState.fromCache({ - blending: BlendingState.ALPHA_BLEND, - }); + const renderStateWithAlphaBlending = RenderState.fromCache({ + blending: BlendingState.ALPHA_BLEND, + }); - const drawCommandsPerTile = {}; - const commandList = scene.frameState.commandList; + const drawCommandsPerTile = {}; + const commandList = scene.frameState.commandList; - for (let i = 0; i < commandList.length; ++i) { - const command = commandList[i]; + for (let i = 0; i < commandList.length; ++i) { + const command = commandList[i]; - if (command.owner instanceof QuadtreeTile) { - const tile = command.owner; - const key = `L${tile.level}X${tile.x}Y${tile.y}`; - if (!defined(drawCommandsPerTile[key])) { - drawCommandsPerTile[key] = 0; + if (command.owner instanceof QuadtreeTile) { + const tile = command.owner; + const key = `L${tile.level}X${tile.x}Y${tile.y}`; + if (!defined(drawCommandsPerTile[key])) { + drawCommandsPerTile[key] = 0; - // The first draw command for each tile should use a non-alpha-blending render state. - expect(command.renderState.blending).not.toEqual( - renderStateWithAlphaBlending.blending - ); - } else { - // Successive draw commands per tile should alpha blend. - expect(command.renderState.blending).toEqual( - renderStateWithAlphaBlending.blending - ); - expect(command.uniformMap.u_initialColor().w).toEqual(0.0); - } - - ++drawCommandsPerTile[key]; + // The first draw command for each tile should use a non-alpha-blending render state. + expect(command.renderState.blending).not.toEqual( + renderStateWithAlphaBlending.blending + ); + } else { + // Successive draw commands per tile should alpha blend. + expect(command.renderState.blending).toEqual( + renderStateWithAlphaBlending.blending + ); + expect(command.uniformMap.u_initialColor().w).toEqual(0.0); } + + ++drawCommandsPerTile[key]; } + } - let tileCount = 0; - for (const tileID in drawCommandsPerTile) { - if (drawCommandsPerTile.hasOwnProperty(tileID)) { - ++tileCount; - expect(drawCommandsPerTile[tileID]).toBeGreaterThanOrEqual(2); - } + let tileCount = 0; + for (const tileID in drawCommandsPerTile) { + if (drawCommandsPerTile.hasOwnProperty(tileID)) { + ++tileCount; + expect(drawCommandsPerTile[tileID]).toBeGreaterThanOrEqual(2); } + } - expect(tileCount).toBeGreaterThanOrEqual(1); - }); + expect(tileCount).toBeGreaterThanOrEqual(1); }); - it("adds terrain and imagery credits to the CreditDisplay", function () { + it("adds terrain and imagery credits to the CreditDisplay", async function () { const CreditDisplayElement = CreditDisplay.CreditDisplayElement; const imageryCredit = new Credit("imagery credit"); - scene.imageryLayers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", + + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png", + { credit: imageryCredit, - }) + } ); + scene.imageryLayers.addImageryProvider(provider); const terrainCredit = new Credit("terrain credit"); - scene.terrainProvider = new CesiumTerrainProvider({ - url: "https://s3.amazonaws.com/cesiumjs/smallTerrain", - credit: terrainCredit, - }); + scene.terrainProvider = await CesiumTerrainProvider.fromUrl( + "https://s3.amazonaws.com/cesiumjs/smallTerrain", + { + credit: terrainCredit, + } + ); - return updateUntilDone(scene.globe).then(function () { - const creditDisplay = scene.frameState.creditDisplay; - creditDisplay.showLightbox(); - expect( - creditDisplay._currentFrameCredits.lightboxCredits.values - ).toContain(new CreditDisplayElement(imageryCredit)); - expect( - creditDisplay._currentFrameCredits.lightboxCredits.values - ).toContain(new CreditDisplayElement(terrainCredit)); - creditDisplay.hideLightbox(); - }); + await updateUntilDone(scene.globe); + const creditDisplay = scene.frameState.creditDisplay; + creditDisplay.showLightbox(); + expect( + creditDisplay._currentFrameCredits.lightboxCredits.values + ).toContain(new CreditDisplayElement(imageryCredit)); + expect( + creditDisplay._currentFrameCredits.lightboxCredits.values + ).toContain(new CreditDisplayElement(terrainCredit)); + creditDisplay.hideLightbox(); }); describe( diff --git a/packages/engine/Specs/Scene/ImageryLayerSpec.js b/packages/engine/Specs/Scene/ImageryLayerSpec.js index d3e87ec0e37..255b576440f 100644 --- a/packages/engine/Specs/Scene/ImageryLayerSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerSpec.js @@ -106,26 +106,22 @@ describe( const layer = new ImageryLayer(provider); + discardPolicy.shouldDiscard = true; + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - discardPolicy.shouldDiscard = true; - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - layer._createTexture(scene.context, imagery); - expect(imagery.state).toEqual(ImageryState.INVALID); - imagery.releaseReference(); - }); + layer._createTexture(scene.context, imagery); + expect(imagery.state).toEqual(ImageryState.INVALID); + imagery.releaseReference(); }); }); - function createWebMercatorProvider() { + async function createWebMercatorProvider() { Resource._Implementations.loadAndExecuteScript = function ( url, functionName @@ -195,141 +191,128 @@ describe( ); }; - return new BingMapsImageryProvider({ - url: "http://host.invalid", + return BingMapsImageryProvider.fromUrl("http://host.invalid", { key: "", tileDiscardPolicy: new NeverTileDiscardPolicy(), }); } - it("reprojects web mercator images when necessary", function () { - const provider = createWebMercatorProvider(); + it("reprojects web mercator images when necessary", async function () { + const provider = await createWebMercatorProvider(); const layer = new ImageryLayer(provider); + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); + layer._createTexture(scene.context, imagery); return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; + return imagery.state === ImageryState.TEXTURE_LOADED; }).then(function () { - layer._createTexture(scene.context, imagery); + const textureBeforeReprojection = imagery.textureWebMercator; + layer._reprojectTexture(scene.frameState, imagery, true); + layer.queueReprojectionCommands(scene.frameState); + scene.frameState.commandList[0].execute(computeEngine); return pollToPromise(function () { - return imagery.state === ImageryState.TEXTURE_LOADED; + return imagery.state === ImageryState.READY; }).then(function () { - const textureBeforeReprojection = imagery.textureWebMercator; - layer._reprojectTexture(scene.frameState, imagery, true); - layer.queueReprojectionCommands(scene.frameState); - scene.frameState.commandList[0].execute(computeEngine); - - return pollToPromise(function () { - return imagery.state === ImageryState.READY; - }).then(function () { - expect(imagery.texture).toBeDefined(); - expect(imagery.texture.sampler).toBeDefined(); - expect(imagery.texture.sampler.minificationFilter).toEqual( - TextureMinificationFilter.LINEAR_MIPMAP_LINEAR - ); - expect(imagery.texture.sampler.magnificationFilter).toEqual( - TextureMinificationFilter.LINEAR - ); - expect(textureBeforeReprojection).not.toEqual(imagery.texture); - imagery.releaseReference(); - }); + expect(imagery.texture).toBeDefined(); + expect(imagery.texture.sampler).toBeDefined(); + expect(imagery.texture.sampler.minificationFilter).toEqual( + TextureMinificationFilter.LINEAR_MIPMAP_LINEAR + ); + expect(imagery.texture.sampler.magnificationFilter).toEqual( + TextureMinificationFilter.LINEAR + ); + expect(textureBeforeReprojection).not.toEqual(imagery.texture); + imagery.releaseReference(); }); }); }); }); - it("does not reproject web mercator images when not necessary", function () { - const provider = createWebMercatorProvider(); + it("does not reproject web mercator images when not necessary", async function () { + const provider = await createWebMercatorProvider(); const layer = new ImageryLayer(provider); + const imagery = new Imagery(layer, 0, 1, 3); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 1, 3); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); + layer._createTexture(scene.context, imagery); return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; + return imagery.state === ImageryState.TEXTURE_LOADED; }).then(function () { - layer._createTexture(scene.context, imagery); + expect(imagery.textureWebMercator).toBeDefined(); + layer._reprojectTexture(scene.frameState, imagery, false); + layer.queueReprojectionCommands(scene.frameState); + expect(scene.frameState.commandList.length).toBe(0); return pollToPromise(function () { - return imagery.state === ImageryState.TEXTURE_LOADED; + return imagery.state === ImageryState.READY; }).then(function () { - expect(imagery.textureWebMercator).toBeDefined(); - layer._reprojectTexture(scene.frameState, imagery, false); - layer.queueReprojectionCommands(scene.frameState); - expect(scene.frameState.commandList.length).toBe(0); - - return pollToPromise(function () { - return imagery.state === ImageryState.READY; - }).then(function () { - expect(imagery.texture).not.toBeDefined(); - imagery.releaseReference(); - }); + expect(imagery.texture).not.toBeDefined(); + imagery.releaseReference(); }); }); }); }); - it("reprojects web mercator images later if it becomes necessary later", function () { - const provider = createWebMercatorProvider(); + it("reprojects web mercator images later if it becomes necessary later", async function () { + const provider = await createWebMercatorProvider(); const layer = new ImageryLayer(provider); + const imagery = new Imagery(layer, 0, 1, 3); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 1, 3); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); + layer._createTexture(scene.context, imagery); return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; + return imagery.state === ImageryState.TEXTURE_LOADED; }).then(function () { - layer._createTexture(scene.context, imagery); + const textureBeforeReprojection = imagery.textureWebMercator; + layer._reprojectTexture(scene.frameState, imagery, false); + layer.queueReprojectionCommands(scene.frameState); + expect(scene.frameState.commandList.length).toBe(0); return pollToPromise(function () { - return imagery.state === ImageryState.TEXTURE_LOADED; + return imagery.state === ImageryState.READY; }).then(function () { - const textureBeforeReprojection = imagery.textureWebMercator; - layer._reprojectTexture(scene.frameState, imagery, false); + expect(imagery.texture).not.toBeDefined(); + + layer._reprojectTexture(scene.frameState, imagery, true); layer.queueReprojectionCommands(scene.frameState); - expect(scene.frameState.commandList.length).toBe(0); + scene.frameState.commandList[0].execute(computeEngine); return pollToPromise(function () { return imagery.state === ImageryState.READY; }).then(function () { - expect(imagery.texture).not.toBeDefined(); - - layer._reprojectTexture(scene.frameState, imagery, true); - layer.queueReprojectionCommands(scene.frameState); - scene.frameState.commandList[0].execute(computeEngine); - - return pollToPromise(function () { - return imagery.state === ImageryState.READY; - }).then(function () { - expect(imagery.texture).toBeDefined(); - expect(imagery.texture.sampler).toBeDefined(); - expect(imagery.texture.sampler.minificationFilter).toEqual( - TextureMinificationFilter.LINEAR_MIPMAP_LINEAR - ); - expect(imagery.texture.sampler.magnificationFilter).toEqual( - TextureMinificationFilter.LINEAR - ); - expect(textureBeforeReprojection).not.toEqual(imagery.texture); - imagery.releaseReference(); - }); + expect(imagery.texture).toBeDefined(); + expect(imagery.texture.sampler).toBeDefined(); + expect(imagery.texture.sampler.minificationFilter).toEqual( + TextureMinificationFilter.LINEAR_MIPMAP_LINEAR + ); + expect(imagery.texture.sampler.magnificationFilter).toEqual( + TextureMinificationFilter.LINEAR + ); + expect(textureBeforeReprojection).not.toEqual(imagery.texture); + imagery.releaseReference(); }); }); }); @@ -362,78 +345,70 @@ describe( }); const layer = new ImageryLayer(provider); + const imagery = new Imagery(layer, 4400, 2686, 13); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 4400, 2686, 13); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); + layer._createTexture(scene.context, imagery); return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; + return imagery.state === ImageryState.TEXTURE_LOADED; }).then(function () { - layer._createTexture(scene.context, imagery); + layer._reprojectTexture(scene.frameState, imagery, true); + layer.queueReprojectionCommands(scene.frameState); + expect(scene.frameState.commandList.length).toBe(0); return pollToPromise(function () { - return imagery.state === ImageryState.TEXTURE_LOADED; + return imagery.state === ImageryState.READY; }).then(function () { - layer._reprojectTexture(scene.frameState, imagery, true); - layer.queueReprojectionCommands(scene.frameState); - expect(scene.frameState.commandList.length).toBe(0); - - return pollToPromise(function () { - return imagery.state === ImageryState.READY; - }).then(function () { - expect(imagery.texture).toBeDefined(); - expect(imagery.texture.sampler).toBeDefined(); - expect(imagery.texture.sampler.minificationFilter).toEqual( - TextureMinificationFilter.LINEAR_MIPMAP_LINEAR - ); - expect(imagery.texture.sampler.magnificationFilter).toEqual( - TextureMinificationFilter.LINEAR - ); - expect(imagery.texture).toBe(imagery.textureWebMercator); - imagery.releaseReference(); - }); + expect(imagery.texture).toBeDefined(); + expect(imagery.texture.sampler).toBeDefined(); + expect(imagery.texture.sampler.minificationFilter).toEqual( + TextureMinificationFilter.LINEAR_MIPMAP_LINEAR + ); + expect(imagery.texture.sampler.magnificationFilter).toEqual( + TextureMinificationFilter.LINEAR + ); + expect(imagery.texture).toBe(imagery.textureWebMercator); + imagery.releaseReference(); }); }); }); }); - it("cancels reprojection", function () { - const provider = createWebMercatorProvider(); + it("cancels reprojection", async function () { + const provider = await createWebMercatorProvider(); const layer = new ImageryLayer(provider); + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); + layer._createTexture(scene.context, imagery); return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; + return imagery.state === ImageryState.TEXTURE_LOADED; }).then(function () { - layer._createTexture(scene.context, imagery); - - return pollToPromise(function () { - return imagery.state === ImageryState.TEXTURE_LOADED; - }).then(function () { - layer._reprojectTexture(scene.frameState, imagery); - layer.cancelReprojections(); - layer.queueReprojectionCommands(scene.frameState); - expect(scene.frameState.commandList.length).toEqual(0); - }); + layer._reprojectTexture(scene.frameState, imagery); + layer.cancelReprojections(); + layer.queueReprojectionCommands(scene.frameState); + expect(scene.frameState.commandList.length).toEqual(0); }); }); }); - it("basic properties work as expected", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + it("basic properties work as expected", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); const rectangle = new Rectangle(0.1, 0.2, 0.3, 0.4); const layer = new ImageryLayer(provider, { @@ -445,10 +420,10 @@ describe( expect(layer.isDestroyed()).toEqual(true); }); - it("allows setting texture filter properties", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + it("allows setting texture filter properties", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); // expect default LINEAR let layer = new ImageryLayer(provider); @@ -472,35 +447,31 @@ describe( TextureMagnificationFilter.NEAREST ); + const imagery = new Imagery(layer, 0, 0, 0); + imagery.addReference(); + layer._requestImagery(imagery); + RequestScheduler.update(); + return pollToPromise(function () { - return provider.ready; + return imagery.state === ImageryState.RECEIVED; }).then(function () { - const imagery = new Imagery(layer, 0, 0, 0); - imagery.addReference(); - layer._requestImagery(imagery); - RequestScheduler.update(); - - return pollToPromise(function () { - return imagery.state === ImageryState.RECEIVED; - }).then(function () { - layer._createTexture(scene.context, imagery); - const sampler = imagery.texture.sampler; - expect(sampler.minificationFilter).toEqual( - TextureMinificationFilter.NEAREST - ); - expect(sampler.magnificationFilter).toEqual( - TextureMinificationFilter.NEAREST - ); - imagery.releaseReference(); - layer.destroy(); - }); + layer._createTexture(scene.context, imagery); + const sampler = imagery.texture.sampler; + expect(sampler.minificationFilter).toEqual( + TextureMinificationFilter.NEAREST + ); + expect(sampler.magnificationFilter).toEqual( + TextureMinificationFilter.NEAREST + ); + imagery.releaseReference(); + layer.destroy(); }); }); - it("uses default texture filter properties of ImageryProvider", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }); + it("uses default texture filter properties of ImageryProvider", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); provider.defaultMinificationFilter = TextureMinificationFilter.NEAREST; provider.defaultMagnificationFilter = TextureMinificationFilter.NEAREST; @@ -515,17 +486,19 @@ describe( layer.destroy(); }); - it("returns HTTP status code information in TileProviderError", function () { + it("returns HTTP status code information in TileProviderError", async function () { // Web browsers unfortunately provide very little information about what went wrong when an Image fails // to load. But when an imagery provider is configured to use a TileDiscardPolicy, Cesium downloads the image // using XHR and then creates a blob URL to pass to an actual Image. This allows access to much more detailed // information, including the status code. - const provider = new ArcGisMapServerImageryProvider({ - url: "File/That/Does/Not/Exist", - usePreCachedTilesIfAvailable: false, - tileDiscardPolicy: new NeverTileDiscardPolicy(), - }); + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "File/That/Does/Not/Exist", + { + usePreCachedTilesIfAvailable: false, + tileDiscardPolicy: new NeverTileDiscardPolicy(), + } + ); let errorRaised = false; provider.errorEvent.addEventListener(function (tileProviderError) { @@ -536,25 +509,22 @@ describe( }); const imageryLayer = new ImageryLayer(provider); + imageryLayer._requestImagery(new Imagery(imageryLayer, 0, 0, 0)); + RequestScheduler.update(); return pollToPromise(function () { - return provider.ready; - }).then(function () { - imageryLayer._requestImagery(new Imagery(imageryLayer, 0, 0, 0)); - RequestScheduler.update(); - - return pollToPromise(function () { - return errorRaised; - }); + return errorRaised; }); }); - it("getViewableRectangle works", function () { + it("getViewableRectangle works", async function () { const providerRectangle = Rectangle.fromDegrees(8.2, 61.09, 8.5, 61.7); - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - rectangle: providerRectangle, - }); + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png", + { + rectangle: providerRectangle, + } + ); const layerRectangle = Rectangle.fromDegrees(7.2, 60.9, 9.0, 61.7); const layer = new ImageryLayer(provider, { @@ -588,237 +558,173 @@ describe( }); describe("createTileImagerySkeletons", function () { - it("handles a base layer that does not cover the entire globe", function () { - const provider = new TileMapServiceImageryProvider({ - url: "Data/TMS/SmallArea", - }); + it("handles a base layer that does not cover the entire globe", async function () { + const provider = await TileMapServiceImageryProvider.fromUrl( + "Data/TMS/SmallArea" + ); const layers = new ImageryLayerCollection(); const layer = layers.addImageryProvider(provider); const terrainProvider = new EllipsoidTerrainProvider(); - return pollToPromise(function () { - return provider.ready && terrainProvider.ready; - }).then(function () { - const tiles = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - tiles[0].data = new GlobeSurfaceTile(); - tiles[1].data = new GlobeSurfaceTile(); - - layer._createTileImagerySkeletons(tiles[0], terrainProvider); - layer._createTileImagerySkeletons(tiles[1], terrainProvider); - - // Both tiles should have imagery from this layer completely covering them. - expect(tiles[0].data.imagery.length).toBe(4); - expect(tiles[0].data.imagery[0].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[0].data.imagery[0].textureCoordinateRectangle.w).toBe( - 1.0 - ); - expect(tiles[0].data.imagery[1].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[0].data.imagery[1].textureCoordinateRectangle.y).toBe( - 0.0 - ); - expect(tiles[0].data.imagery[2].textureCoordinateRectangle.z).toBe( - 1.0 - ); - expect(tiles[0].data.imagery[2].textureCoordinateRectangle.w).toBe( - 1.0 - ); - expect(tiles[0].data.imagery[3].textureCoordinateRectangle.y).toBe( - 0.0 - ); - expect(tiles[0].data.imagery[3].textureCoordinateRectangle.z).toBe( - 1.0 - ); - - expect(tiles[1].data.imagery.length).toBe(2); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.w).toBe( - 1.0 - ); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.z).toBe( - 1.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.y).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.z).toBe( - 1.0 - ); - }); + const tiles = QuadtreeTile.createLevelZeroTiles( + terrainProvider.tilingScheme + ); + tiles[0].data = new GlobeSurfaceTile(); + tiles[1].data = new GlobeSurfaceTile(); + + layer._createTileImagerySkeletons(tiles[0], terrainProvider); + layer._createTileImagerySkeletons(tiles[1], terrainProvider); + + // Both tiles should have imagery from this layer completely covering them. + expect(tiles[0].data.imagery.length).toBe(4); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.w).toBe(1.0); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.y).toBe(0.0); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.z).toBe(1.0); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.w).toBe(1.0); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.y).toBe(0.0); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.z).toBe(1.0); + + expect(tiles[1].data.imagery.length).toBe(2); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.w).toBe(1.0); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.z).toBe(1.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.y).toBe(0.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.z).toBe(1.0); }); - it("does not get confused when base layer imagery overlaps in one direction but not the other", function () { + it("does not get confused when base layer imagery overlaps in one direction but not the other", async function () { // This is a pretty specific test targeted at https://github.com/CesiumGS/cesium/issues/2815 // It arranges for tileImageryBoundsScratch to be a rectangle that is invalid in the WebMercator projection. // Then, it triggers issue #2815 where that stale data is used in a later call. Prior to the fix this // triggers an exception (use of an undefined reference). - const wholeWorldProvider = new SingleTileImageryProvider({ - url: "Data/Images/Blue.png", - }); - - const provider = new TileMapServiceImageryProvider({ - url: "Data/TMS/SmallArea", - }); + const wholeWorldProvider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Blue.png" + ); + const provider = await TileMapServiceImageryProvider.fromUrl( + "Data/TMS/SmallArea" + ); const layers = new ImageryLayerCollection(); const wholeWorldLayer = layers.addImageryProvider(wholeWorldProvider); const terrainProvider = new EllipsoidTerrainProvider(); - return pollToPromise(function () { - return ( - wholeWorldProvider.ready && provider.ready && terrainProvider.ready - ); - }).then(function () { - let tiles = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - tiles[0].data = new GlobeSurfaceTile(); - tiles[1].data = new GlobeSurfaceTile(); - - wholeWorldLayer._createTileImagerySkeletons( - tiles[0], - terrainProvider - ); - wholeWorldLayer._createTileImagerySkeletons( - tiles[1], - terrainProvider - ); - - layers.removeAll(); - const layer = layers.addImageryProvider(provider); - - // Use separate tiles for the small area provider. - tiles = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - tiles[0].data = new GlobeSurfaceTile(); - tiles[1].data = new GlobeSurfaceTile(); - - // The stale data was used in this call prior to the fix. - layer._createTileImagerySkeletons(tiles[1], terrainProvider); - - // Same assertions as above as in 'handles a base layer that does not cover the entire globe' - // as a sanity check. Really we're just testing that the call above doesn't throw. - expect(tiles[1].data.imagery.length).toBe(2); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.w).toBe( - 1.0 - ); - expect(tiles[1].data.imagery[0].textureCoordinateRectangle.z).toBe( - 1.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.x).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.y).toBe( - 0.0 - ); - expect(tiles[1].data.imagery[1].textureCoordinateRectangle.z).toBe( - 1.0 - ); - }); - }); + let tiles = QuadtreeTile.createLevelZeroTiles( + terrainProvider.tilingScheme + ); + tiles[0].data = new GlobeSurfaceTile(); + tiles[1].data = new GlobeSurfaceTile(); - it("handles a non-base layer that does not cover the entire globe", function () { - const baseProvider = new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }); + wholeWorldLayer._createTileImagerySkeletons(tiles[0], terrainProvider); + wholeWorldLayer._createTileImagerySkeletons(tiles[1], terrainProvider); - const provider = new TileMapServiceImageryProvider({ - url: "Data/TMS/SmallArea", - }); + layers.removeAll(); + const layer = layers.addImageryProvider(provider); + + // Use separate tiles for the small area provider. + tiles = QuadtreeTile.createLevelZeroTiles(terrainProvider.tilingScheme); + tiles[0].data = new GlobeSurfaceTile(); + tiles[1].data = new GlobeSurfaceTile(); + + // The stale data was used in this call prior to the fix. + layer._createTileImagerySkeletons(tiles[1], terrainProvider); + + // Same assertions as above as in 'handles a base layer that does not cover the entire globe' + // as a sanity check. Really we're just testing that the call above doesn't throw. + expect(tiles[1].data.imagery.length).toBe(2); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.w).toBe(1.0); + expect(tiles[1].data.imagery[0].textureCoordinateRectangle.z).toBe(1.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.x).toBe(0.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.y).toBe(0.0); + expect(tiles[1].data.imagery[1].textureCoordinateRectangle.z).toBe(1.0); + }); + + it("handles a non-base layer that does not cover the entire globe", async function () { + const baseProvider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" + ); + const provider = await TileMapServiceImageryProvider.fromUrl( + "Data/TMS/SmallArea" + ); const layers = new ImageryLayerCollection(); layers.addImageryProvider(baseProvider); const layer = layers.addImageryProvider(provider); const terrainProvider = new EllipsoidTerrainProvider(); - return pollToPromise(function () { - return provider.ready && terrainProvider.ready; - }).then(function () { - const tiles = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - tiles[0].data = new GlobeSurfaceTile(); - tiles[1].data = new GlobeSurfaceTile(); - - layer._createTileImagerySkeletons(tiles[0], terrainProvider); - layer._createTileImagerySkeletons(tiles[1], terrainProvider); - - // Only the western tile should have imagery from this layer. - // And the imagery should not cover it completely. - expect(tiles[0].data.imagery.length).toBe(4); - expect( - tiles[0].data.imagery[0].textureCoordinateRectangle.x - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[0].textureCoordinateRectangle.y - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[0].textureCoordinateRectangle.z - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[0].textureCoordinateRectangle.w - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[1].textureCoordinateRectangle.x - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[1].textureCoordinateRectangle.y - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[1].textureCoordinateRectangle.z - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[1].textureCoordinateRectangle.w - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[2].textureCoordinateRectangle.x - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[2].textureCoordinateRectangle.y - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[2].textureCoordinateRectangle.z - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[2].textureCoordinateRectangle.w - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[3].textureCoordinateRectangle.x - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[3].textureCoordinateRectangle.y - ).not.toBe(0.0); - expect( - tiles[0].data.imagery[3].textureCoordinateRectangle.z - ).not.toBe(1.0); - expect( - tiles[0].data.imagery[3].textureCoordinateRectangle.w - ).not.toBe(1.0); - - expect(tiles[1].data.imagery.length).toBe(0); - }); + const tiles = QuadtreeTile.createLevelZeroTiles( + terrainProvider.tilingScheme + ); + tiles[0].data = new GlobeSurfaceTile(); + tiles[1].data = new GlobeSurfaceTile(); + + layer._createTileImagerySkeletons(tiles[0], terrainProvider); + layer._createTileImagerySkeletons(tiles[1], terrainProvider); + + // Only the western tile should have imagery from this layer. + // And the imagery should not cover it completely. + expect(tiles[0].data.imagery.length).toBe(4); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.x).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.y).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.z).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[0].textureCoordinateRectangle.w).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.x).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.y).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.z).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[1].textureCoordinateRectangle.w).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.x).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.y).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.z).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[2].textureCoordinateRectangle.w).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.x).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.y).not.toBe( + 0.0 + ); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.z).not.toBe( + 1.0 + ); + expect(tiles[0].data.imagery[3].textureCoordinateRectangle.w).not.toBe( + 1.0 + ); + + expect(tiles[1].data.imagery.length).toBe(0); }); - it("honors the minimumTerrainLevel and maximumTerrainLevel properties", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }); + it("honors the minimumTerrainLevel and maximumTerrainLevel properties", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" + ); const layer = new ImageryLayer(provider, { minimumTerrainLevel: 2, @@ -830,89 +736,80 @@ describe( const terrainProvider = new EllipsoidTerrainProvider(); - return pollToPromise(function () { - return provider.ready && terrainProvider.ready; - }).then(function () { - const level0 = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - const level1 = level0[0].children; - const level2 = level1[0].children; - const level3 = level2[0].children; - const level4 = level3[0].children; - const level5 = level4[0].children; - - level0[0].data = new GlobeSurfaceTile(); - level1[0].data = new GlobeSurfaceTile(); - level2[0].data = new GlobeSurfaceTile(); - level3[0].data = new GlobeSurfaceTile(); - level4[0].data = new GlobeSurfaceTile(); - level5[0].data = new GlobeSurfaceTile(); - - layer._createTileImagerySkeletons(level0[0], terrainProvider); - expect(level0[0].data.imagery.length).toBe(0); - - layer._createTileImagerySkeletons(level1[0], terrainProvider); - expect(level1[0].data.imagery.length).toBe(0); - - layer._createTileImagerySkeletons(level2[0], terrainProvider); - expect(level2[0].data.imagery.length).toBe(1); - - layer._createTileImagerySkeletons(level3[0], terrainProvider); - expect(level3[0].data.imagery.length).toBe(1); - - layer._createTileImagerySkeletons(level4[0], terrainProvider); - expect(level4[0].data.imagery.length).toBe(1); - - layer._createTileImagerySkeletons(level5[0], terrainProvider); - expect(level5[0].data.imagery.length).toBe(0); - }); + const level0 = QuadtreeTile.createLevelZeroTiles( + terrainProvider.tilingScheme + ); + const level1 = level0[0].children; + const level2 = level1[0].children; + const level3 = level2[0].children; + const level4 = level3[0].children; + const level5 = level4[0].children; + + level0[0].data = new GlobeSurfaceTile(); + level1[0].data = new GlobeSurfaceTile(); + level2[0].data = new GlobeSurfaceTile(); + level3[0].data = new GlobeSurfaceTile(); + level4[0].data = new GlobeSurfaceTile(); + level5[0].data = new GlobeSurfaceTile(); + + layer._createTileImagerySkeletons(level0[0], terrainProvider); + expect(level0[0].data.imagery.length).toBe(0); + + layer._createTileImagerySkeletons(level1[0], terrainProvider); + expect(level1[0].data.imagery.length).toBe(0); + + layer._createTileImagerySkeletons(level2[0], terrainProvider); + expect(level2[0].data.imagery.length).toBe(1); + + layer._createTileImagerySkeletons(level3[0], terrainProvider); + expect(level3[0].data.imagery.length).toBe(1); + + layer._createTileImagerySkeletons(level4[0], terrainProvider); + expect(level4[0].data.imagery.length).toBe(1); + + layer._createTileImagerySkeletons(level5[0], terrainProvider); + expect(level5[0].data.imagery.length).toBe(0); }); - it("honors limited extent of non-base ImageryLayer", function () { - const provider = new SingleTileImageryProvider({ - url: "Data/Images/Green4x4.png", - }); + it("honors limited extent of non-base ImageryLayer", async function () { + const provider = await SingleTileImageryProvider.fromUrl( + "Data/Images/Green4x4.png" + ); const layer = new ImageryLayer(provider, { rectangle: Rectangle.fromDegrees(7.2, 60.9, 9.0, 61.7), }); const layers = new ImageryLayerCollection(); - layers.addImageryProvider( - new SingleTileImageryProvider({ - url: "Data/Images/Red16x16.png", - }) + const provider2 = await SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" ); + layers.addImageryProvider(provider2); layers.add(layer); const terrainProvider = new EllipsoidTerrainProvider(); - return pollToPromise(function () { - return provider.ready && terrainProvider.ready; - }).then(function () { - const tiles = QuadtreeTile.createLevelZeroTiles( - terrainProvider.tilingScheme - ); - tiles[0].data = new GlobeSurfaceTile(); - tiles[1].data = new GlobeSurfaceTile(); - - layer._createTileImagerySkeletons(tiles[0], terrainProvider); - layer._createTileImagerySkeletons(tiles[1], terrainProvider); - - // The western hemisphere should not have any imagery tiles mapped to it. - expect(tiles[0].data.imagery.length).toBe(0); - - // The eastern hemisphere should have one tile with limited extent. - expect(tiles[1].data.imagery.length).toBe(1); - - const textureCoordinates = - tiles[1].data.imagery[0].textureCoordinateRectangle; - expect(textureCoordinates.x).toBeGreaterThan(0.0); - expect(textureCoordinates.y).toBeGreaterThan(0.0); - expect(textureCoordinates.z).toBeLessThan(1.0); - expect(textureCoordinates.w).toBeLessThan(1.0); - }); + const tiles = QuadtreeTile.createLevelZeroTiles( + terrainProvider.tilingScheme + ); + tiles[0].data = new GlobeSurfaceTile(); + tiles[1].data = new GlobeSurfaceTile(); + + layer._createTileImagerySkeletons(tiles[0], terrainProvider); + layer._createTileImagerySkeletons(tiles[1], terrainProvider); + + // The western hemisphere should not have any imagery tiles mapped to it. + expect(tiles[0].data.imagery.length).toBe(0); + + // The eastern hemisphere should have one tile with limited extent. + expect(tiles[1].data.imagery.length).toBe(1); + + const textureCoordinates = + tiles[1].data.imagery[0].textureCoordinateRectangle; + expect(textureCoordinates.x).toBeGreaterThan(0.0); + expect(textureCoordinates.y).toBeGreaterThan(0.0); + expect(textureCoordinates.z).toBeLessThan(1.0); + expect(textureCoordinates.w).toBeLessThan(1.0); }); }); }, diff --git a/packages/engine/Specs/Scene/MapboxImageryProviderSpec.js b/packages/engine/Specs/Scene/MapboxImageryProviderSpec.js index eafca87a047..4024502d3e2 100644 --- a/packages/engine/Specs/Scene/MapboxImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/MapboxImageryProviderSpec.js @@ -234,9 +234,7 @@ describe("Scene/MapboxImageryProvider", function () { mapId: "test-id", maximumLevel: 5, }); - return provider.readyPromise.then(function () { - expect(provider.maximumLevel).toEqual(5); - }); + expect(provider.maximumLevel).toEqual(5); }); it("uses minimumLevel passed to constructor", function () { @@ -246,9 +244,7 @@ describe("Scene/MapboxImageryProvider", function () { mapId: "test-id", minimumLevel: 1, }); - return provider.readyPromise.then(function () { - expect(provider.minimumLevel).toEqual(1); - }); + expect(provider.minimumLevel).toEqual(1); }); it("when no credit is supplied, the provider adds a default credit", function () { @@ -257,9 +253,7 @@ describe("Scene/MapboxImageryProvider", function () { url: "made/up/mapbox/server/", mapId: "test-id", }); - return provider.readyPromise.then(function () { - expect(provider.credit).toBe(MapboxImageryProvider._defaultCredit); - }); + expect(provider.credit).toBe(MapboxImageryProvider._defaultCredit); }); it("turns the supplied credit into a logo", function () { @@ -270,9 +264,7 @@ describe("Scene/MapboxImageryProvider", function () { mapId: "test-id", credit: creditText, }); - return providerWithCredit.readyPromise.then(function () { - expect(providerWithCredit.credit.html).toEqual(creditText); - }); + expect(providerWithCredit.credit.html).toEqual(creditText); }); it("raises error event when image cannot be loaded", function () { diff --git a/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js b/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js index 319cdae0ec3..50f3d6a81ad 100644 --- a/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/MapboxStyleImageryProviderSpec.js @@ -234,9 +234,7 @@ describe("Scene/MapboxStyleImageryProvider", function () { styleId: "test-id", maximumLevel: 5, }); - return provider.readyPromise.then(function () { - expect(provider.maximumLevel).toEqual(5); - }); + expect(provider.maximumLevel).toEqual(5); }); it("uses minimumLevel passed to constructor", function () { @@ -246,9 +244,7 @@ describe("Scene/MapboxStyleImageryProvider", function () { styleId: "test-id", minimumLevel: 1, }); - return provider.readyPromise.then(function () { - expect(provider.minimumLevel).toEqual(1); - }); + expect(provider.minimumLevel).toEqual(1); }); it("when no credit is supplied, the provider adds a default credit", function () { @@ -257,9 +253,7 @@ describe("Scene/MapboxStyleImageryProvider", function () { url: "made/up/mapbox/server/", styleId: "test-id", }); - return provider.readyPromise.then(function () { - expect(provider.credit).toBe(MapboxStyleImageryProvider._defaultCredit); - }); + expect(provider.credit).toBe(MapboxStyleImageryProvider._defaultCredit); }); it("turns the supplied credit into a logo", function () { @@ -270,9 +264,7 @@ describe("Scene/MapboxStyleImageryProvider", function () { styleId: "test-id", credit: creditText, }); - return providerWithCredit.readyPromise.then(function () { - expect(providerWithCredit.credit.html).toEqual(creditText); - }); + expect(providerWithCredit.credit.html).toEqual(creditText); }); it("raises error event when image cannot be loaded", function () { diff --git a/packages/engine/Specs/Scene/SceneSpec.js b/packages/engine/Specs/Scene/SceneSpec.js index ac03d760e8a..ccf3492a7cb 100644 --- a/packages/engine/Specs/Scene/SceneSpec.js +++ b/packages/engine/Specs/Scene/SceneSpec.js @@ -1495,33 +1495,26 @@ describe( scene.destroyForSpecs(); }); - it("Sets terrainProvider", function () { + it("Sets terrainProvider", async function () { returnQuantizedMeshTileJson(); const scene = createScene(); const globe = (scene.globe = new Globe(Ellipsoid.UNIT_SPHERE)); - scene.terrainProvider = new CesiumTerrainProvider({ - url: "//terrain/tiles", - }); + scene.terrainProvider = await CesiumTerrainProvider.fromUrl( + "//terrain/tiles" + ); - return scene.terrainProvider.readyPromise - .then(() => { - expect(scene.terrainProvider).toBe(globe.terrainProvider); - scene.globe = undefined; - const newProvider = new CesiumTerrainProvider({ - url: "//newTerrain/tiles", - }); - return newProvider.readyPromise.then(() => { - expect(function () { - scene.terrainProvider = newProvider; - }).not.toThrow(); - }); - }) - .finally(() => { - scene.destroyForSpecs(); - Resource._Implementations.loadWithXhr = - Resource._DefaultImplementations.loadWithXhr; - }); + expect(scene.terrainProvider).toBe(globe.terrainProvider); + scene.globe = undefined; + const newProvider = await CesiumTerrainProvider.fromUrl( + "//newTerrain/tiles" + ); + expect(function () { + scene.terrainProvider = newProvider; + }).not.toThrow(); + scene.destroyForSpecs(); + Resource._Implementations.loadWithXhr = + Resource._DefaultImplementations.loadWithXhr; }); it("Gets terrainProviderChanged", function () { From 011ffe03ed1dbe016e483a1d6036400102349b3d Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Feb 2023 22:02:09 -0500 Subject: [PATCH 437/679] voxels: add setIntersection methods for RayShapeIntersection structs --- .../engine/Source/Shaders/Voxels/IntersectBox.glsl | 14 +++++++------- .../Source/Shaders/Voxels/IntersectionUtils.glsl | 8 ++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl index c56a7d4cf50..efb0f3a3073 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectBox.glsl @@ -30,11 +30,11 @@ Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv) return Box(p0, p1); } -vec3 getBoxNormal(in Box box, in Ray ray, in float entryT) +vec3 getBoxNormal(in Box box, in Ray ray, in float t) { - vec3 entryPoint = ray.pos + (entryT - RAY_SHIFT) * ray.dir; - vec3 lower = step(entryPoint, box.p0); - vec3 upper = step(box.p1, entryPoint); + vec3 hitPoint = ray.pos + t * ray.dir; + vec3 lower = step(hitPoint, box.p0); + vec3 upper = step(box.p1, hitPoint); return normalize(upper - lower); } @@ -55,8 +55,8 @@ RayShapeIntersection intersectBox(in Ray ray, in Box box) float entryT = max(max(entries.x, entries.y), entries.z); float exitT = min(min(exits.x, exits.y), exits.z); - vec3 entryNormal = getBoxNormal(box, ray, entryT); - vec3 exitNormal = getBoxNormal(box, ray, exitT); + vec3 entryNormal = getBoxNormal(box, ray, entryT - RAY_SHIFT); + vec3 exitNormal = getBoxNormal(box, ray, exitT + RAY_SHIFT); if (entryT > exitT) { entryT = NO_HIT; @@ -69,5 +69,5 @@ RayShapeIntersection intersectBox(in Ray ray, in Box box) void intersectShape(in Ray ray, inout Intersections ix) { RayShapeIntersection intersection = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds)); - setIntersectionPair(ix, BOX_INTERSECTION_INDEX, vec2(intersection.entry.w, intersection.exit.w)); + setShapeIntersection(ix, BOX_INTERSECTION_INDEX, intersection); } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index a595a51c171..c38100e311e 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -47,9 +47,17 @@ RayShapeIntersection getFirstIntersection(in Intersections ix) return RayShapeIntersection(ix.intersections[0], ix.intersections[1]); } +vec4 encodeIntersectionType(vec4 intersection, int index, bool entry) +{ + float scale = float(index > 0) * 2.0 + float(!entry) + 1.0; + return vec4(intersection.xyz * scale, intersection.w); +} + // Use defines instead of real functions because WebGL1 cannot access array with non-constant index. #define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*bool*/ enter) (ix).intersections[(index)] = vec4(0.0, float(!positive) * 2.0 + float(!enter) + 1.0, 0.0, (t)) #define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec4(0.0, float((index) > 0) * 2.0 + 1.0, 0.0, (entryExit).x); (ix).intersections[(index) * 2 + 1] = vec4(0.0, float((index) > 0) * 2.0 + 2.0, 0.0, (entryExit).y) +#define setSurfaceIntersection(/*inout Intersections*/ ix, /*int*/ index, /*vec4*/ intersection) (ix).intersections[(index)] = intersection; +#define setShapeIntersection(/*inout Intersections*/ ix, /*int*/ index, /*RayShapeIntersection*/ intersection) (ix).intersections[(index) * 2 + 0] = encodeIntersectionType((intersection).entry, (index), true); (ix).intersections[(index) * 2 + 1] = encodeIntersectionType((intersection).exit, (index), false) #if (INTERSECTION_COUNT > 1) void initializeIntersections(inout Intersections ix) { From 8d311efa45b9961f3f153e0a6b66a7cd0c64a6fd Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Feb 2023 23:27:42 -0500 Subject: [PATCH 438/679] voxels: use clipping plane normals --- .../Voxels/IntersectClippingPlanes.glsl | 45 ++++++++++++------- .../Shaders/Voxels/IntersectionUtils.glsl | 8 ++-- .../engine/Source/Shaders/Voxels/VoxelFS.glsl | 4 +- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl index a1609d0c79c..956c596d02c 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectClippingPlanes.glsl @@ -23,45 +23,56 @@ vec4 intersectPlane(in Ray ray, in vec4 plane) { } void intersectClippingPlanes(in Ray ray, inout Intersections ix) { + vec4 backSide = vec4(-ray.dir, -INF_HIT); + vec4 farSide = vec4(ray.dir, +INF_HIT); + RayShapeIntersection clippingVolume; + #if (CLIPPING_PLANES_COUNT == 1) // Union and intersection are the same when there's one clipping plane, and the code // is more simplified. vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix); vec4 intersection = intersectPlane(ray, planeUv); - vec2 entryExitT = dot(ray.dir, planeUv.xyz) > 0.0 - ? vec2(intersection.w, +INF_HIT) - : vec2(-INF_HIT, intersection.w); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, entryExitT); + bool reflects = dot(ray.dir, intersection.xyz) < 0.0; + clippingVolume.entry = reflects ? backSide : intersection; + clippingVolume.exit = reflects ? intersection : farSide; + setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume); #elif defined(CLIPPING_PLANES_UNION) - float minPositiveT = +INF_HIT; - float maxNegativeT = -INF_HIT; + vec4 firstTransmission = vec4(ray.dir, +INF_HIT); + vec4 lastReflection = vec4(-ray.dir, -INF_HIT); for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); vec4 intersection = intersectPlane(ray, planeUv); if (dot(ray.dir, planeUv.xyz) > 0.0) { - minPositiveT = min(minPositiveT, intersection.w); + firstTransmission = intersection.w <= firstTransmission.w ? intersection : firstTransmission; } else { - maxNegativeT = max(maxNegativeT, intersection.w); + lastReflection = intersection.w >= lastReflection.w ? intersection : lastReflection; } } - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, vec2(-INF_HIT, maxNegativeT)); - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, vec2(minPositiveT, +INF_HIT)); + clippingVolume.entry = backSide; + clippingVolume.exit = lastReflection; + setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, clippingVolume); + clippingVolume.entry = firstTransmission; + clippingVolume.exit = farSide; + setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, clippingVolume); #else // intersection - float maxPositiveT = -INF_HIT; - float minNegativeT = +INF_HIT; + vec4 lastTransmission = vec4(ray.dir, -INF_HIT); + vec4 firstReflection = vec4(-ray.dir, +INF_HIT); for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) { vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix); vec4 intersection = intersectPlane(ray, planeUv); if (dot(ray.dir, planeUv.xyz) > 0.0) { - maxPositiveT = max(maxPositiveT, intersection.w); + lastTransmission = intersection.w > lastTransmission.w ? intersection : lastTransmission; } else { - minNegativeT = min(minNegativeT, intersection.w); + firstReflection = intersection.w < firstReflection.w ? intersection: firstReflection; } } - if (maxPositiveT < minNegativeT) { - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(maxPositiveT, minNegativeT)); + if (lastTransmission.w < firstReflection.w) { + clippingVolume.entry = lastTransmission; + clippingVolume.exit = firstReflection; } else { - setIntersectionPair(ix, CLIPPING_PLANES_INTERSECTION_INDEX, vec2(NO_HIT)); + clippingVolume.entry = vec4(-ray.dir, NO_HIT); + clippingVolume.exit = vec4(ray.dir, NO_HIT); } + setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume); #endif } diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index c38100e311e..d16f8586658 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -109,10 +109,10 @@ RayShapeIntersection nextIntersection(inout Intersections ix) { ix.index = i + 1; surfaceIntersection = ix.intersections[i]; - float t = surfaceIntersection.w; - float intersectionType = length(surfaceIntersection.xyz) - 1.0; - bool currShapeIsPositive = intersectionType < 2.0; - bool enter = mod(intersectionType, 2.0) == 0.0; + int intersectionType = int(length(surfaceIntersection.xyz) - 0.5); + bool currShapeIsPositive = intersectionType < 2; + // TODO: use intMod for WebGL1 compatibility + bool enter = intersectionType % 2 == 0; ix.surroundCount += enter ? +1 : -1; ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 88120c660fe..10c172dbfd9 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -32,9 +32,9 @@ vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersecti #if defined(SHAPE_BOX) Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv); RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); - float entry = max(voxelIntersection.entry.w, shapeIntersection.entry.w); + vec4 entry = shapeIntersection.entry.w >= voxelIntersection.entry.w ? shapeIntersection.entry : voxelIntersection.entry; float exit = min(voxelIntersection.exit.w, shapeIntersection.exit.w); - return vec4(voxelIntersection.entry.xyz, exit - entry); + return vec4(normalize(entry.xyz), exit - entry.w); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); return vec4(viewRay.dir, u_stepSize / dimAtLevel); From ced19581407a95eb7f2a840f4e9c3fb200b614be Mon Sep 17 00:00:00 2001 From: Zhouhai <850168627@qq.com> Date: Tue, 7 Feb 2023 15:41:18 +0800 Subject: [PATCH 439/679] Update CHANGES.md --- CHANGES.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c02cf295458..80339c4d288 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,17 @@ # Change Log +### 1.103 - 2023-03-01 + +#### @cesium/engine + +#### Major Announcements :loudspeaker: + +##### Additions :tada: + +##### Fixes :wrench: + +- Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) + ### 1.102 - 2023-02-01 #### @cesium/engine From 5ca80c77f2824d8159ca275b49fdd2a4c55862b2 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 7 Feb 2023 09:30:39 -0500 Subject: [PATCH 440/679] voxels: use WebGL1 fallback for integer mod --- packages/engine/Source/Scene/VoxelRenderResources.js | 2 +- packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/VoxelRenderResources.js b/packages/engine/Source/Scene/VoxelRenderResources.js index 27119de61fc..77ec4da6ad4 100644 --- a/packages/engine/Source/Scene/VoxelRenderResources.js +++ b/packages/engine/Source/Scene/VoxelRenderResources.js @@ -87,8 +87,8 @@ function VoxelRenderResources(primitive) { shaderBuilder.addFragmentLines([ customShader.fragmentShaderText, "#line 0", - IntersectionUtils, Octree, + IntersectionUtils, Megatexture, ]); diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index d16f8586658..66ae307dce1 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -111,8 +111,7 @@ RayShapeIntersection nextIntersection(inout Intersections ix) { surfaceIntersection = ix.intersections[i]; int intersectionType = int(length(surfaceIntersection.xyz) - 0.5); bool currShapeIsPositive = intersectionType < 2; - // TODO: use intMod for WebGL1 compatibility - bool enter = intersectionType % 2 == 0; + bool enter = intMod(intersectionType, 2) == 0; ix.surroundCount += enter ? +1 : -1; ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive; From 0d9566e913486f12b6f25e09dc894a2ddf646bf8 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 6 Feb 2023 17:15:15 -0500 Subject: [PATCH 441/679] Cleanup --- .../Source/Scene/GridImageryProvider.js | 3 ++- packages/engine/Source/Scene/Imagery.js | 2 +- .../engine/Source/Scene/IonImageryProvider.js | 20 +++++++++---------- .../Scene/TileCoordinatesImageryProvider.js | 1 + .../Scene/TileMapServiceImageryProvider.js | 2 -- packages/widgets/Specs/Viewer/ViewerSpec.js | 11 ++++++++++ 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/engine/Source/Scene/GridImageryProvider.js b/packages/engine/Source/Scene/GridImageryProvider.js index 112d6b65bf0..2daca9a188d 100644 --- a/packages/engine/Source/Scene/GridImageryProvider.js +++ b/packages/engine/Source/Scene/GridImageryProvider.js @@ -149,6 +149,7 @@ function GridImageryProvider(options) { // We only need a single canvas since all tiles will be the same this._canvas = this._createGridCanvas(); + this._ready = true; this._readyPromise = Promise.resolve(true); } @@ -270,7 +271,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * @memberof GridImageryProvider.prototype * @type {Boolean} * @readonly - * @deprected + * @deprecated */ ready: { get: function () { diff --git a/packages/engine/Source/Scene/Imagery.js b/packages/engine/Source/Scene/Imagery.js index f6eba2f5ad7..4b23f7a83a2 100644 --- a/packages/engine/Source/Scene/Imagery.js +++ b/packages/engine/Source/Scene/Imagery.js @@ -34,7 +34,7 @@ function Imagery(imageryLayer, x, y, level, rectangle) { this.credits = undefined; this.referenceCount = 0; - if (!defined(rectangle) && imageryLayer.imageryProvider.ready) { + if (!defined(rectangle) && imageryLayer.imageryProvider._ready) { const tilingScheme = imageryLayer.imageryProvider.tilingScheme; rectangle = tilingScheme.tileXYToRectangle(x, y, level); } diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 63b173dd9b8..042926db84d 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -38,10 +38,14 @@ const ImageryProviderMapping = { const ImageryProviderAsyncMapping = { ARCGIS_MAPSERVER: ArcGisMapServerImageryProvider.fromUrl, - BING: BingMapsImageryProvider.fromUrl, + BING: async (url, options) => { + const key = options.key; + delete options.key; + return BingMapsImageryProvider.fromUrl(url, key, options); + }, GOOGLE_EARTH: async (url, options) => { const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); - GoogleEarthEnterpriseMapsProvider.fromMetadata(metadata, options); + return GoogleEarthEnterpriseMapsProvider.fromMetadata(metadata, options); }, MAPBOX: (url, options) => { return new MapboxImageryProvider({ @@ -49,12 +53,7 @@ const ImageryProviderAsyncMapping = { ...options, }); }, - SINGLE_TILE: (url, options) => { - return new SingleTileImageryProvider({ - url: url, - ...options, - }); - }, + SINGLE_TILE: SingleTileImageryProvider.fromUrl, TMS: TileMapServiceImageryProvider.fromUrl, URL_TEMPLATE: (url, options) => { return new UrlTemplateImageryProvider({ @@ -401,8 +400,7 @@ IonImageryProvider._initialize = function (provider, assetId, options) { // already retrieved. This exists mainly to support Bing caching to reduce // world imagery sessions, but provides a small boost of performance in general // if constantly reloading assets - const cacheKey = - options.assetId.toString() + options.accessToken + options.server; + const cacheKey = assetId.toString() + options.accessToken + options.server; let promise = IonImageryProvider._endpointCache[cacheKey]; if (!defined(promise)) { promise = endpointResource.fetchJson(); @@ -449,7 +447,7 @@ IonImageryProvider._initialize = function (provider, assetId, options) { provider._imageryProvider = imageryProvider; // readyPromise is deprecated. This is here for backwards compatibility - return imageryProvider._readyPromise.then(function () { + return Promise.resolve(imageryProvider._readyPromise).then(function () { provider._ready = true; return true; }); diff --git a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js index 757e30aefda..94ea6f034f8 100644 --- a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js +++ b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js @@ -39,6 +39,7 @@ function TileCoordinatesImageryProvider(options) { this._errorEvent = new Event(); this._tileWidth = defaultValue(options.tileWidth, 256); this._tileHeight = defaultValue(options.tileHeight, 256); + this._ready = true; this._readyPromise = Promise.resolve(true); /** diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index 93abda78c04..25a84981323 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -269,8 +269,6 @@ TileMapServiceImageryProvider._metadataSuccess = function ( let format, bbox, tilesets; const tilesetsList = []; //list of TileSets - // TODO: Check for error? https://github.com/CesiumGS/cesium/issues/6242 - // Allowing options properties (already copied to that) to override XML values // Iterate XML Document nodes for properties diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index 9a2a3701b46..e5964bcb42e 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -12,6 +12,7 @@ import { HeadingPitchRange, JulianDate, Matrix4, + Rectangle, TimeIntervalCollection, WebMercatorProjection, ConstantPositionProperty, @@ -53,10 +54,20 @@ import pollToPromise from "../../../../Specs/pollToPromise.js"; describe( "Widgets/Viewer/Viewer", function () { + const readyPromise = Promise.resolve(true); const testProvider = { isReady: function () { return false; }, + _ready: true, + ready: true, + _readyPromise: readyPromise, + readyPromise: readyPromise, + tilingScheme: { + tileXYToRectangle: function () { + return new Rectangle(); + }, + }, }; const testProviderViewModel = new ProviderViewModel({ From ca38b2c36c21879ccb3e65415d1ae4c503a485d8 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 7 Feb 2023 10:43:51 -0500 Subject: [PATCH 442/679] Update processVoxelPropertiesSpec --- packages/engine/Specs/Scene/processVoxelPropertiesSpec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js b/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js index a4ce9c9a2a1..808586fe14e 100644 --- a/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js +++ b/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js @@ -90,6 +90,7 @@ describe("Scene/processVoxelProperties", function () { " vec3 positionUv;", " vec3 positionShapeUv;", " vec3 positionUvLocal;", + " vec3 surfaceNormal;", " vec3 viewDirUv;", " vec3 viewDirWorld;", " float travelDistance;", From e17a30833e39906b38ca8f78c4fedb50a30abc97 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Wed, 8 Feb 2023 08:49:11 +0800 Subject: [PATCH 443/679] halfing arcLength from delta --- packages/engine/Source/Scene/CameraEventAggregator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 99aaa0da8c1..823060d711e 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -160,7 +160,7 @@ function listenToWheel(aggregator, modifier) { aggregator._eventHandler.setInputAction( function (delta) { // TODO: magic numbers - const arcLength = 15.0 * CesiumMath.toRadians(delta); + const arcLength = 7.5 * CesiumMath.toRadians(delta); pressTime[key] = releaseTime[key] = new Date(); movement.endPosition.x = 0.0; movement.endPosition.y = arcLength; From 5064d9c2e5e1a0d5a6f4727eabeff05da5bad886 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Feb 2023 11:38:23 -0500 Subject: [PATCH 444/679] Allow lazy-loading for SingleTileImageryProvider --- CHANGES.md | 4 +- .../Source/Scene/SingleTileImageryProvider.js | 91 +++++++++++-------- .../Source/Scene/createWorldImageryAsync.js | 2 +- .../Scene/SingleTileImageryProviderSpec.js | 52 +++++++++++ 4 files changed, 111 insertions(+), 38 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e64c819b31e..49c38ae4ccc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - Fixed a bug decoding glTF Draco attributes with quantization bits above 16. [#7471](https://github.com/CesiumGS/cesium/issues/7471) - Fixed an edge case in `viewer.flyTo` when flying to a imagery layer with certain terrain providers. [#10937](https://github.com/CesiumGS/cesium/issues/10937) +- Fixed `SingleTileImageryProvider` fetching image when `show` is `false` by allowing lazy-loading for `SingleTileImageryProvider` if `tileWidth` and `tileHeight` are provided to the constructor. [#9529](https://github.com/CesiumGS/cesium/issues/9529) ##### Additions :tada: @@ -24,7 +25,8 @@ - `MapboxImageryProvider.ready` and `MapboxImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `MapboxStyleImageryProvider.ready` and `MapboxStyleImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `OpenStreetMapImageryProvider.ready` and `OpenStreetMapImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `SingleTileImageryProvider` constructor parameter `options.url`, `SingleTileImageryProvider.ready`, and `SingleTileImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `SingleTileImageryProvider.fromUrl` instead. +- `SingleTileImageryProvider` constructor parameter `options.url` was deprecated in Cesium 1.102 and will be removed in 1.104. Provide `options.tileHeight` and `options.tileWidth`, or use `SingleTileImageryProvider.fromUrl` instead. +- `SingleTileImageryProvider.ready` and `SingleTileImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `SingleTileImageryProvider.fromUrl` instead. - `TileCoordinatesImageryProvider.ready` and `TileCoordinatesImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `TileMapServiceImageryProvider` constructor parameter `options.url`, `TileMapServiceImageryProvider.ready`, and `TileMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `TileMapServiceImageryProvider.fromUrl` instead. - `UrlTemplateImageryProvider.reinitialize`, `UrlTemplateImageryProvider.ready`, and `UrlTemplateImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index 3db8c4c40d4..2b5452f4680 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -16,17 +16,15 @@ import ImageryProvider from "./ImageryProvider.js"; * * Initialization options for the SingleTileImageryProvider constructor * - * @property {Resource|String} [url] The url for the tile. Deprecated. + * @property {Resource|String} url The url for the tile. + * @property {Number} tileWidth The width of the tile, in pixels. + * @property {Number} tileHeight The height of the tile, in pixels. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. */ /** - * <div class="notice"> - * To construct a SingleTileImageryProvider, call {@link SingleTileImageryProvider.fromUrl}. Do not call the constructor directly. - * </div> - * * Provides a single, top-level imagery tile. The single image is assumed to use a * {@link GeographicTilingScheme}. * @@ -142,9 +140,8 @@ function SingleTileImageryProvider(options) { this._tilingScheme = tilingScheme; this._image = undefined; this._texture = undefined; - this._tileWidth = 0; - this._tileHeight = 0; + this._hasError = false; this._errorEvent = new Event(); this._ready = false; @@ -155,23 +152,41 @@ function SingleTileImageryProvider(options) { } this._credit = credit; - if (defined(options.url)) { - deprecationWarning( - "SingleTileImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use SingleTileImageryProvider.fromUrl instead." - ); - - const resource = Resource.createIfNeeded(options.url); - this._resource = resource; - this._readyPromise = doRequest(resource, this).then((image) => { - TileProviderError.reportSuccess(this._errorEvent); - this._image = image; - this._tileWidth = image.width; - this._tileHeight = image.height; - this._ready = true; - return true; - }); + //>>includeStart('debug', pragmas.debug); + Check.defined("options.url", options.url); + //>>includeEnd('debug'); + + const resource = Resource.createIfNeeded(options.url); + this._resource = resource; + + if (defined(options.tileWidth) || defined(options.tileHeight)) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.number("options.tileWidth", options.tileWidth); + Check.typeOf.number("options.tileHeight", options.tileHeight); + //>>includeEnd('debug'); + + this._tileWidth = options.tileWidth; + this._tileHeight = options.tileHeight; + this._ready = true; + this._readyPromise = Promise.resolve(true); + return; } + + deprecationWarning( + "SingleTileImageryProvider options.url", + "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Provide options.tileHeight and options.tileWidth, or use SingleTileImageryProvider.fromUrl instead." + ); + + this._tileWidth = 0; + this._tileHeight = 0; + this._readyPromise = doRequest(resource, this).then((image) => { + TileProviderError.reportSuccess(this._errorEvent); + this._image = image; + this._tileWidth = image.width; + this._tileHeight = image.height; + this._ready = true; + return true; + }); } Object.defineProperties(SingleTileImageryProvider.prototype, { @@ -369,8 +384,6 @@ function failure(resource, error, provider, previousError) { message += `: ${error.message}`; } - // When readyPromise is deprecated, TileProviderError.reportError, - // retry attempts, and related parameters can be removed const reportedError = TileProviderError.reportError( previousError, provider, @@ -385,6 +398,9 @@ function failure(resource, error, provider, previousError) { return doRequest(resource, provider, reportedError); } + if (defined(provider)) { + provider._hasError = true; + } throw new RuntimeError(message); } @@ -413,14 +429,14 @@ SingleTileImageryProvider.fromUrl = async function (url, options) { const resource = Resource.createIfNeeded(url); const image = await doRequest(resource); - const provider = new SingleTileImageryProvider(options); - provider._resource = resource; + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + const provider = new SingleTileImageryProvider({ + ...options, + url: url, + tileWidth: image.width, + tileHeight: image.height, + }); provider._image = image; - provider._tileWidth = image.width; - provider._tileHeight = image.height; - provider._ready = true; - provider._readyPromise = Promise.resolve(true); - return provider; }; @@ -445,17 +461,20 @@ SingleTileImageryProvider.prototype.getTileCredits = function (x, y, level) { * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.<ImageryTypes>|undefined} The resolved image */ -SingleTileImageryProvider.prototype.requestImage = function ( +SingleTileImageryProvider.prototype.requestImage = async function ( x, y, level, request ) { - if (!defined(this._image)) { - return; + if (!this._hasError && !defined(this._image)) { + const image = await doRequest(this._resource, this); + this._image = image; + TileProviderError.reportSuccess(this._errorEvent); + return image; } - return Promise.resolve(this._image); + return this._image; }; /** diff --git a/packages/engine/Source/Scene/createWorldImageryAsync.js b/packages/engine/Source/Scene/createWorldImageryAsync.js index 9b2f0b26b5b..edcb82e8d89 100644 --- a/packages/engine/Source/Scene/createWorldImageryAsync.js +++ b/packages/engine/Source/Scene/createWorldImageryAsync.js @@ -9,7 +9,7 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * * @param {Object} [options] Object with the following properties: * @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. - * @returns {Promise<IonImageryProvide>} + * @returns {Promise<IonImageryProvider>} * * @see Ion * diff --git a/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js b/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js index 4cb6cdcb111..cf8ec6698bf 100644 --- a/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/SingleTileImageryProviderSpec.js @@ -65,6 +65,28 @@ describe("Scene/SingleTileImageryProvider", function () { }); }); + it("constructor throws without url", async function () { + expect(() => new SingleTileImageryProvider()).toThrowDeveloperError(); + }); + + it("constructor throws without tile height and tile width", async function () { + expect( + () => + new SingleTileImageryProvider({ + url: "Data/Images/Red16x16.png", + tileWidth: 16, + }) + ).toThrowDeveloperError(); + + expect( + () => + new SingleTileImageryProvider({ + url: "Data/Images/Red16x16.png", + tileHeight: 16, + }) + ).toThrowDeveloperError(); + }); + it("fromUrl throws without url", async function () { await expectAsync( SingleTileImageryProvider.fromUrl() @@ -162,6 +184,36 @@ describe("Scene/SingleTileImageryProvider", function () { expect(image).toBeImageOrImageBitmap(); }); + it("lazy loads image when constructed with tile height and tile width", async function () { + const imageUrl = "Data/Images/Red16x16.png"; + + spyOn(Resource._Implementations, "createImage").and.callFake(function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + expect(url).toEqual(imageUrl); + Resource._DefaultImplementations.createImage( + request, + crossOrigin, + deferred + ); + }); + + const provider = new SingleTileImageryProvider({ + url: imageUrl, + tileHeight: 16, + tileWidth: 16, + }); + + expect(Resource._Implementations.createImage).not.toHaveBeenCalled(); + + const image = await Promise.resolve(provider.requestImage(0, 0, 0)); + expect(image).toBeImageOrImageBitmap(); + expect(Resource._Implementations.createImage).toHaveBeenCalled(); + }); + it("turns the supplied credit into a logo", async function () { const provider = await SingleTileImageryProvider.fromUrl( "Data/Images/Red16x16.png" From 592872ee9f797ee045230012bc38a19b936ca413 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Feb 2023 13:54:09 -0500 Subject: [PATCH 445/679] Update GoogleEarthEnterpriseMapsProvider.js --- CHANGES.md | 3 +- .../GoogleEarthEnterpriseMapsProvider.js | 491 +++++++++--------- .../engine/Source/Scene/IonImageryProvider.js | 6 +- .../GoogleEarthEnterpriseMapsProviderSpec.js | 182 +++++++ .../createFakeBingMapsMetadataResponse.js | 2 +- 5 files changed, 433 insertions(+), 251 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 49c38ae4ccc..2e7ce9c1d99 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,7 +12,7 @@ ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. ##### Deprecated :hourglass_flowing_sand: @@ -20,6 +20,7 @@ - `ArcGisMapServerImageryProvider` constructor parameter `url`,`ArcGisMapServerImageryProvider.ready`, and `ArcGisMapServerImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGisMapServerImageryProvider.fromUrl` instead. - `BingMapsImageryProvider` constructor parameter `url`,`BingMapsImageryProvider.ready`, and `BingMapsImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `BingMapsImageryProvider.fromUrl` instead. - `GoogleEarthEnterpriseImageryProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseImageryProvider.ready`, and `GoogleEarthEnterpriseImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseImageryProvider.fromMetadata` instead. +- `GoogleEarthEnterpriseMapsProvider` constructor parameters `options.url` and `options.channel`, `GoogleEarthEnterpriseMapsProvider.ready`, and `GoogleEarthEnterpriseMapsProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseMapsProvider.fromUrl` instead. - `GridImageryProvider.ready` and `GridImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `IonImageryProvider` constructor parameter `assetId`,`BIonImageryProvider.ready`, and `IonImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `IonImageryProvider.fromAssetId` instead. - `MapboxImageryProvider.ready` and `MapboxImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js index 7e500951581..4dd0c17d8f2 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js @@ -3,6 +3,7 @@ import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; @@ -18,7 +19,7 @@ import ImageryProvider from "./ImageryProvider.js"; * * Initialization options for the GoogleEarthEnterpriseMapsProvider constructor * - * @property {Resource|String} url The url of the Google Earth server hosting the imagery. + * @property {Resource|String} [url] The url of the Google Earth server hosting the imagery. Deprecated. * @property {Number} channel The channel (id) to be used when requesting data from the server. * The channel number can be found by looking at the json file located at: * earth.localdomain/default_map/query?request=Json&vars=geeServerDefs The /default_map path may @@ -47,6 +48,123 @@ import ImageryProvider from "./ImageryProvider.js"; */ /** + * Used to track creation details while fetching initial metadata + * + * @constructor + * @private + * + * @param {GoogleEarthEnterpriseMapsProvider.ConstructorOptions} options An object describing initialization options + */ +function ImageryProviderBuilder(options) { + this.channel = options.channel; + this.ellipsoid = options.ellipsoid; + this.tilingScheme = undefined; + this.version = undefined; +} + +/** + * Complete GoogleEarthEnterpriseMapsProvider creation based on builder values. + * + * @private + * + * @param {GoogleEarthEnterpriseMapsProvider} provider + */ +ImageryProviderBuilder.prototype.build = function (provider) { + provider._channel = this.channel; + provider._version = this.version; + provider._tilingScheme = this.tilingScheme; +}; + +function metadataSuccess(text, imageryProviderBuilder) { + let data; + + // The Google Earth server sends malformed JSON data currently... + try { + // First, try parsing it like normal in case a future version sends correctly formatted JSON + data = JSON.parse(text); + } catch (e) { + // Quote object strings manually, then try parsing again + data = JSON.parse( + text.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g, '$1"$2":') + ); + } + + let layer; + for (let i = 0; i < data.layers.length; i++) { + if (data.layers[i].id === imageryProviderBuilder.channel) { + layer = data.layers[i]; + break; + } + } + + if (!defined(layer)) { + const message = `Could not find layer with channel (id) of ${imageryProviderBuilder.channel}.`; + throw new RuntimeError(message); + } + + if (!defined(layer.version)) { + const message = `Could not find a version in channel (id) ${imageryProviderBuilder.channel}.`; + throw new RuntimeError(message); + } + + imageryProviderBuilder.version = layer.version; + + if (defined(data.projection) && data.projection === "flat") { + imageryProviderBuilder.tilingScheme = new GeographicTilingScheme({ + numberOfLevelZeroTilesX: 2, + numberOfLevelZeroTilesY: 2, + rectangle: new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI), + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + // Default to mercator projection when projection is undefined + } else if (!defined(data.projection) || data.projection === "mercator") { + imageryProviderBuilder.tilingScheme = new WebMercatorTilingScheme({ + numberOfLevelZeroTilesX: 2, + numberOfLevelZeroTilesY: 2, + ellipsoid: imageryProviderBuilder.ellipsoid, + }); + } else { + const message = `Unsupported projection ${data.projection}.`; + throw new RuntimeError(message); + } + + return true; +} + +function metadataFailure(error, metadataResource, provider) { + let message = `An error occurred while accessing ${metadataResource.url}.`; + if (defined(error) && defined(error.message)) { + message += `: ${error.message}`; + } + + TileProviderError.reportError( + undefined, + provider, + defined(provider) ? provider._errorEvent : undefined, + message + ); + + throw new RuntimeError(message); +} + +async function requestMetadata( + metadataResource, + imageryProviderBuilder, + provider +) { + try { + const text = await metadataResource.fetchText(); + metadataSuccess(text, imageryProviderBuilder); + } catch (error) { + metadataFailure(error, metadataResource, provider); + } +} + +/** + * <div class="notice"> + * To construct a GoogleEarthEnterpriseMapsProvider, call {@link GoogleEarthEnterpriseImageryProvider.fromUrl}. Do not call the constructor directly. + * </div> + * * Provides tiled imagery using the Google Earth Imagery API. * * Notes: This imagery provider does not work with the public Google Earth servers. It works with the @@ -81,25 +199,13 @@ import ImageryProvider from "./ImageryProvider.js"; * * * @example - * const google = new Cesium.GoogleEarthEnterpriseMapsProvider({ - * url : 'https://earth.localdomain', - * channel : 1008 - * }); + * const google = await Cesium.GoogleEarthEnterpriseMapsProvider.fromUrl("https://earth.localdomain", 1008); * * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} */ function GoogleEarthEnterpriseMapsProvider(options) { options = defaultValue(options, {}); - //>>includeStart('debug', pragmas.debug); - if (!defined(options.url)) { - throw new DeveloperError("options.url is required."); - } - if (!defined(options.channel)) { - throw new DeveloperError("options.channel is required."); - } - //>>includeEnd('debug'); - /** * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. @@ -186,19 +292,6 @@ function GoogleEarthEnterpriseMapsProvider(options) { */ this.defaultMagnificationFilter = undefined; - const url = options.url; - const path = defaultValue(options.path, "/default_map"); - - const resource = Resource.createIfNeeded(url).getDerivedResource({ - // We used to just append path to url, so now that we do proper URI resolution, removed the / - url: path[0] === "/" ? path.substring(1) : path, - }); - - resource.appendForwardSlash(); - - this._resource = resource; - this._url = url; - this._path = path; this._tileDiscardPolicy = options.tileDiscardPolicy; this._channel = options.channel; this._requestType = "ImageryMaps"; @@ -216,126 +309,56 @@ function GoogleEarthEnterpriseMapsProvider(options) { this._errorEvent = new Event(); - this._ready = false; - const metadataResource = resource.getDerivedResource({ - url: "query", - queryParameters: { - request: "Json", - vars: "geeServerDefs", - is2d: "t", - }, - }); - const that = this; - let metadataError; - - function metadataSuccess(text) { - let data; - - // The Google Earth server sends malformed JSON data currently... - try { - // First, try parsing it like normal in case a future version sends correctly formatted JSON - data = JSON.parse(text); - } catch (e) { - // Quote object strings manually, then try parsing again - data = JSON.parse( - text.replace(/([\[\{,])[\n\r ]*([A-Za-z0-9]+)[\n\r ]*:/g, '$1"$2":') - ); + if (defined(options.url) || defined(options.channel)) { + //>>includeStart('debug', pragmas.debug); + if (!defined(options.url)) { + throw new DeveloperError("options.url is required."); } - - let layer; - for (let i = 0; i < data.layers.length; i++) { - if (data.layers[i].id === that._channel) { - layer = data.layers[i]; - break; - } + if (!defined(options.channel)) { + throw new DeveloperError("options.channel is required."); } + //>>includeEnd('debug'); - let message; - - if (!defined(layer)) { - message = `Could not find layer with channel (id) of ${that._channel}.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(message)); - } - - if (!defined(layer.version)) { - message = `Could not find a version in channel (id) ${that._channel}.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(message)); - } - that._version = layer.version; - - if (defined(data.projection) && data.projection === "flat") { - that._tilingScheme = new GeographicTilingScheme({ - numberOfLevelZeroTilesX: 2, - numberOfLevelZeroTilesY: 2, - rectangle: new Rectangle(-Math.PI, -Math.PI, Math.PI, Math.PI), - ellipsoid: options.ellipsoid, - }); - // Default to mercator projection when projection is undefined - } else if (!defined(data.projection) || data.projection === "mercator") { - that._tilingScheme = new WebMercatorTilingScheme({ - numberOfLevelZeroTilesX: 2, - numberOfLevelZeroTilesY: 2, - ellipsoid: options.ellipsoid, - }); - } else { - message = `Unsupported projection ${data.projection}.`; - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message - ); - if (metadataError.retry) { - return requestMetadata(); - } - return Promise.reject(new RuntimeError(message)); - } - - that._ready = true; - TileProviderError.reportSuccess(metadataError); - return Promise.resolve(true); - } - - function metadataFailure(e) { - const message = defaultValue( - e.message, - `An error occurred while accessing ${metadataResource.url}.` + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.url", + "GoogleEarthEnterpriseMapsProvider.url and GoogleEarthEnterpriseMapsProvider.channel were deprecated in CesiumJS 1.102. They will be removed in 1.104. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." ); - metadataError = TileProviderError.reportError( - metadataError, - that, - that._errorEvent, - message - ); - return Promise.reject(new RuntimeError(message)); - } - function requestMetadata() { - return metadataResource - .fetchText() - .then(metadataSuccess) - .catch(metadataFailure); + const url = options.url; + const path = defaultValue(options.path, "/default_map"); + + const resource = Resource.createIfNeeded(url).getDerivedResource({ + // We used to just append path to url, so now that we do proper URI resolution, removed the / + url: path[0] === "/" ? path.substring(1) : path, + }); + + resource.appendForwardSlash(); + + this._resource = resource; + this._url = url; + this._path = path; + + this._ready = false; + const metadataResource = resource.getDerivedResource({ + url: "query", + queryParameters: { + request: "Json", + vars: "geeServerDefs", + is2d: "t", + }, + }); + + const imageryProviderBuilder = new ImageryProviderBuilder(options); + this._readyPromise = requestMetadata( + metadataResource, + imageryProviderBuilder, + this + ).then(() => { + imageryProviderBuilder.build(this); + this._ready = true; + return true; + }); } - - this._readyPromise = requestMetadata(); } Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { @@ -388,168 +411,96 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { }, /** - * Gets the width of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the width of each tile, in pixels. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Number} * @readonly */ tileWidth: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileWidth must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileWidth; }, }, /** - * Gets the height of each tile, in pixels. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the height of each tile, in pixels. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Number} * @readonly */ tileHeight: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileHeight must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileHeight; }, }, /** - * Gets the maximum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the maximum level-of-detail that can be requested. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Number|undefined} * @readonly */ maximumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._maximumLevel; }, }, /** - * Gets the minimum level-of-detail that can be requested. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the minimum level-of-detail that can be requested. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Number} * @readonly */ minimumLevel: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumLevel must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return 0; }, }, /** - * Gets the tiling scheme used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the tiling scheme used by this provider. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {TilingScheme} * @readonly */ tilingScheme: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tilingScheme must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme; }, }, /** - * Gets the version of the data used by this provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the version of the data used by this provider. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Number} * @readonly */ version: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "version must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._version; }, }, /** - * Gets the type of data that is being requested from the provider. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the type of data that is being requested from the provider. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {String} * @readonly */ requestType: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestType must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._requestType; }, }, /** - * Gets the rectangle, in radians, of the imagery provided by this instance. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Gets the rectangle, in radians, of the imagery provided by this instance. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Rectangle} * @readonly */ rectangle: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "rectangle must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tilingScheme.rectangle; }, }, @@ -557,22 +508,13 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets the tile discard policy. If not undefined, the discard policy is responsible * for filtering out "missing" tiles via its shouldDiscardImage function. If this function - * returns undefined, no tiles are filtered. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * returns undefined, no tiles are filtered. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {TileDiscardPolicy} * @readonly */ tileDiscardPolicy: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "tileDiscardPolicy must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - return this._tileDiscardPolicy; }, }, @@ -596,9 +538,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.ready", + "GoogleEarthEnterpriseMapsProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." + ); return this._ready; }, }, @@ -608,16 +555,21 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Promise.<Boolean>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.readyPromise", + "GoogleEarthEnterpriseMapsProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." + ); return this._readyPromise; }, }, /** * Gets the credit to display when this imagery provider is active. Typically this is used to credit - * the source of the imagery. This function should not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * the source of the imagery. * @memberof GoogleEarthEnterpriseMapsProvider.prototype * @type {Credit} * @readonly @@ -645,6 +597,66 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { }, }); +/** + * Creates a tiled imagery provider using the Google Earth Imagery API. + * + * @param {Resource|String} url The url of the Google Earth server hosting the imagery. + * @param {GoogleEarthEnterpriseMapsProvider.ConstructorOptions} [options] Object describing initialization options + * @returns {Promise<GoogleEarthEnterpriseMapsProvider>} The created GoogleEarthEnterpriseMapsProvider. + * + * @exception {RuntimeError} Could not find layer with channel (id) of <code>options.channel</code>. + * @exception {RuntimeError} Could not find a version in channel (id) <code>options.channel</code>. + * @exception {RuntimeError} Unsupported projection <code>data.projection</code>. + * + * @example + * const google = await Cesium.GoogleEarthEnterpriseMapsProvider.fromUrl("https://earth.localdomain", 1008); + */ +GoogleEarthEnterpriseMapsProvider.fromUrl = async function ( + url, + channel, + options +) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + Check.defined("channel", channel); + //>>includeEnd('debug'); + + options = defaultValue(options, {}); + + const path = defaultValue(options.path, "/default_map"); + + const resource = Resource.createIfNeeded(url).getDerivedResource({ + // We used to just append path to url, so now that we do proper URI resolution, removed the / + url: path[0] === "/" ? path.substring(1) : path, + }); + + resource.appendForwardSlash(); + + const metadataResource = resource.getDerivedResource({ + url: "query", + queryParameters: { + request: "Json", + vars: "geeServerDefs", + is2d: "t", + }, + }); + + const imageryProviderBuilder = new ImageryProviderBuilder(options); + imageryProviderBuilder.channel = channel; + await requestMetadata(metadataResource, imageryProviderBuilder); + + const provider = new GoogleEarthEnterpriseMapsProvider(options); + imageryProviderBuilder.build(provider); + + provider._readyPromise = Promise.resolve(true); + provider._ready = true; + provider._resource = resource; + provider._url = url; + provider._path = path; + + return provider; +}; + /** * Gets the credits to be displayed when a given tile is displayed. * @@ -652,8 +664,6 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * @param {Number} y The tile Y coordinate. * @param {Number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. - * - * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. */ GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function ( x, @@ -664,8 +674,7 @@ GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function ( }; /** - * Requests the image for a given tile. This function should - * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. + * Requests the image for a given tile. * * @param {Number} x The tile X coordinate. * @param {Number} y The tile Y coordinate. @@ -673,8 +682,6 @@ GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function ( * @param {Request} [request] The request object. Intended for internal use only. * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. - * - * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ GoogleEarthEnterpriseMapsProvider.prototype.requestImage = function ( x, @@ -682,14 +689,6 @@ GoogleEarthEnterpriseMapsProvider.prototype.requestImage = function ( level, request ) { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "requestImage must not be called before the imagery provider is ready." - ); - } - //>>includeEnd('debug'); - const resource = this._resource.getDerivedResource({ url: "query", request: request, diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 042926db84d..4473550bbf1 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -3,7 +3,6 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; -import GoogleEarthEnterpriseMetadata from "../Core/GoogleEarthEnterpriseMetadata.js"; import IonResource from "../Core/IonResource.js"; import RuntimeError from "../Core/RuntimeError.js"; import ArcGisMapServerImageryProvider from "./ArcGisMapServerImageryProvider.js"; @@ -44,8 +43,9 @@ const ImageryProviderAsyncMapping = { return BingMapsImageryProvider.fromUrl(url, key, options); }, GOOGLE_EARTH: async (url, options) => { - const metadata = await GoogleEarthEnterpriseMetadata.fromUrl(url); - return GoogleEarthEnterpriseMapsProvider.fromMetadata(metadata, options); + const channel = options.channel; + delete options.channel; + return GoogleEarthEnterpriseMapsProvider.fromUrl(url, channel, options); }, MAPBOX: (url, options) => { return new MapboxImageryProvider({ diff --git a/packages/engine/Specs/Scene/GoogleEarthEnterpriseMapsProviderSpec.js b/packages/engine/Specs/Scene/GoogleEarthEnterpriseMapsProviderSpec.js index 0a1014405f4..e35b280e799 100644 --- a/packages/engine/Specs/Scene/GoogleEarthEnterpriseMapsProviderSpec.js +++ b/packages/engine/Specs/Scene/GoogleEarthEnterpriseMapsProviderSpec.js @@ -4,6 +4,7 @@ import { Request, RequestScheduler, Resource, + RuntimeError, WebMercatorTilingScheme, GoogleEarthEnterpriseMapsProvider, Imagery, @@ -150,6 +151,187 @@ describe("Scene/GoogleEarthEnterpriseMapsProvider", function () { }); }); + it("fromUrl throws without url", async function () { + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl(undefined, 1234) + ).toBeRejectedWithDeveloperError(); + }); + + it("fromUrl throws without channel", async function () { + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl("url", undefined) + ).toBeRejectedWithDeveloperError(); + }); + + it("fromUrl resolves to imagery provider", async function () { + const path = ""; + const url = "http://example.invalid"; + const channel = 1234; + + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterpriseMapsProvider/good.json", + responseType, + method, + data, + headers, + deferred + ); + }; + + const provider = await GoogleEarthEnterpriseMapsProvider.fromUrl( + url, + channel, + { + path: path, + } + ); + + expect(provider).toBeInstanceOf(GoogleEarthEnterpriseMapsProvider); + }); + + it("fromUrl with Resource resolves to imagery provider", async function () { + const path = ""; + const url = "http://example.invalid"; + const channel = 1234; + + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterpriseMapsProvider/good.json", + responseType, + method, + data, + headers, + deferred + ); + }; + + const resource = new Resource({ + url: url, + }); + + const provider = await GoogleEarthEnterpriseMapsProvider.fromUrl( + resource, + channel, + { path: path } + ); + + expect(provider).toBeInstanceOf(GoogleEarthEnterpriseMapsProvider); + }); + + it("fromUrl throws with invalid url", async function () { + const url = "http://invalid.localhost"; + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl(url, 1234) + ).toBeRejectedWithError( + RuntimeError, + new RegExp("An error occurred while accessing") + ); + }); + + it("fromUrl throws when channel cannot be found", async function () { + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterpriseMapsProvider/bad_channel.json", + responseType, + method, + data, + headers, + deferred + ); + }; + + const url = "http://invalid.localhost"; + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl(url, 1235) + ).toBeRejectedWithError( + RuntimeError, + new RegExp("Could not find layer with channel \\(id\\) of 1235") + ); + }); + + it("fromUrl throws when channel version cannot be found", async function () { + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterpriseMapsProvider/bad_version.json", + responseType, + method, + data, + headers, + deferred + ); + }; + + const url = "http://invalid.localhost"; + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl(url, 1234) + ).toBeRejectedWithError( + RuntimeError, + new RegExp("Could not find a version in channel \\(id\\) 1234") + ); + }); + + it("fromUrl throws when unsupported projection is specified", async function () { + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/GoogleEarthEnterpriseMapsProvider/bad_projection.json", + responseType, + method, + data, + headers, + deferred + ); + }; + + const url = "http://invalid.localhost"; + await expectAsync( + GoogleEarthEnterpriseMapsProvider.fromUrl(url, 1234) + ).toBeRejectedWithError( + RuntimeError, + new RegExp("Unsupported projection asdf") + ); + }); + it("returns valid value for hasAlphaChannel", function () { const path = ""; const url = "http://example.invalid"; diff --git a/packages/engine/Specs/createFakeBingMapsMetadataResponse.js b/packages/engine/Specs/createFakeBingMapsMetadataResponse.js index a1d6c1f0ff3..dd03d226f84 100644 --- a/packages/engine/Specs/createFakeBingMapsMetadataResponse.js +++ b/packages/engine/Specs/createFakeBingMapsMetadataResponse.js @@ -1,4 +1,4 @@ -import { BingMapsStyle } from "@cesium/engine"; +import { BingMapsStyle } from "../index.js"; export default function (mapStyle) { let stylePrefix = "a"; From b6b0663e491a87fe1249b1f3d309dd6613a3907e Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Feb 2023 15:40:57 -0500 Subject: [PATCH 446/679] Async event handler for terrain providers --- Apps/CesiumViewer/CesiumViewer.js | 18 +- Apps/Sandcastle/gallery/Terrain.html | 83 ++++---- packages/engine/Source/Scene/Globe.js | 1 + .../Source/Scene/GlobeSurfaceTileProvider.js | 13 +- packages/engine/Source/Scene/ImageryLayer.js | 7 +- packages/engine/Source/Scene/Scene.js | 59 ++++++ packages/engine/Source/Scene/Terrain.js | 180 ++++++++++++++++++ packages/engine/Source/Widget/CesiumWidget.js | 15 +- packages/engine/Specs/Scene/SceneSpec.js | 81 ++++++-- packages/engine/Specs/Scene/TerrainSpec.js | 57 ++++++ .../BaseLayerPickerViewModel.js | 44 ++--- packages/widgets/Source/Viewer/Viewer.js | 19 +- 12 files changed, 469 insertions(+), 108 deletions(-) create mode 100644 packages/engine/Source/Scene/Terrain.js create mode 100644 packages/engine/Specs/Scene/TerrainSpec.js diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 3592c9000ad..5a7bb85825f 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -4,7 +4,6 @@ if (window.CESIUM_BASE_URL === undefined) { import { Cartesian3, - createWorldTerrainAsync, defined, formatError, Math as CesiumMath, @@ -14,6 +13,7 @@ import { GeoJsonDataSource, KmlDataSource, GpxDataSource, + Terrain, TileMapServiceImageryProvider, Viewer, viewerCesiumInspectorMixin, @@ -50,21 +50,21 @@ async function main() { } const loadingIndicator = document.getElementById("loadingIndicator"); - let viewer; - try { - const hasBaseLayerPicker = !defined(imageryProvider); + const hasBaseLayerPicker = !defined(imageryProvider); - const terrainProvider = await createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); + const terrain = Terrain.fromWorldTerrain({ + requestWaterMask: true, + requestVertexNormals: true, + }); + let viewer; + try { viewer = new Viewer("cesiumContainer", { imageryProvider: imageryProvider, baseLayerPicker: hasBaseLayerPicker, scene3DOnly: endUserOptions.scene3DOnly, requestRenderMode: true, - terrainProvider: terrainProvider, + terrain: terrain, }); if (hasBaseLayerPicker) { diff --git a/Apps/Sandcastle/gallery/Terrain.html b/Apps/Sandcastle/gallery/Terrain.html index f1e50500145..7053b56c68d 100644 --- a/Apps/Sandcastle/gallery/Terrain.html +++ b/Apps/Sandcastle/gallery/Terrain.html @@ -39,18 +39,12 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer"); - - (async () => { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - } catch (error) { - console.log(error); - } - })(); + const viewer = new Cesium.Viewer("cesiumContainer", { + terrain: Cesium.Terrain.fromWorldTerrain({ + requestWaterMask: true, + requestVertexNormals: true, + }), + }); // set lighting to true viewer.scene.globe.enableLighting = true; @@ -91,36 +85,41 @@ [ { text: "CesiumTerrainProvider - Cesium World Terrain", - onselect: async function () { - const provider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - requestVertexNormals: true, - }); - viewer.terrainProvider = provider; + onselect: function () { + viewer.scene.setTerrain( + Cesium.Terrain.fromWorldTerrain({ + requestWaterMask: true, + requestVertexNormals: true, + }) + ); viewer.scene.globe.enableLighting = true; }, }, { text: "CesiumTerrainProvider - Cesium World Terrain - no effects", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + onselect: function () { + viewer.scene.setTerrain(Cesium.Terrain.fromWorldTerrain()); }, }, { text: "CesiumTerrainProvider - Cesium World Terrain w/ Lighting", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestVertexNormals: true, - }); + onselect: function () { + viewer.scene.setTerrain( + Cesium.Terrain.fromWorldTerrain({ + requestVertexNormals: true, + }) + ); viewer.scene.globe.enableLighting = true; }, }, { text: "CesiumTerrainProvider - Cesium World Terrain w/ Water", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync({ - requestWaterMask: true, - }); + onselect: function () { + viewer.scene.setTerrain( + Cesium.Terrain.fromWorldTerrain({ + requestWaterMask: true, + }) + ); }, }, { @@ -137,23 +136,29 @@ }, { text: "VRTheWorldTerrainProvider", - onselect: async function () { - const provider = await Cesium.VRTheWorldTerrainProvider.fromUrl( - "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", - { - credit: "Terrain data courtesy VT MÄK", - } + onselect: function () { + viewer.scene.setTerrain( + new Cesium.Terrain( + Cesium.VRTheWorldTerrainProvider.fromUrl( + "http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/", + { + credit: "Terrain data courtesy VT MÄK", + } + ) + ) ); - viewer.terrainProvider = provider; }, }, { text: "ArcGISTerrainProvider", - onselect: async function () { - const provider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + onselect: function () { + viewer.scene.setTerrain( + new Cesium.Terrain( + Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" + ) + ) ); - viewer.terrainProvider = provider; }, }, ], diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index c6876f2195b..5e157374ad8 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -984,6 +984,7 @@ Globe.prototype.beginFrame = function (frameState) { const terrainProvider = this.terrainProvider; const hasWaterMask = this.showWaterEffect && + defined(terrainProvider) && terrainProvider.hasWaterMask && // ready is deprecated; This is here for backwards compatibility terrainProvider._ready; diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 42a96649b47..3cfb07d0014 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -237,6 +237,7 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { ready: { get: function () { return ( + defined(this._terrainProvider) && // ready is deprecated; This is here for backwards compatibility this._terrainProvider._ready && (this._imageryLayers.length === 0 || @@ -295,12 +296,6 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { return; } - //>>includeStart('debug', pragmas.debug); - if (!defined(terrainProvider)) { - throw new DeveloperError("terrainProvider is required."); - } - //>>includeEnd('debug'); - this._terrainProvider = terrainProvider; if (defined(this._quadtree)) { @@ -350,6 +345,7 @@ GlobeSurfaceTileProvider.prototype.update = function (frameState) { function updateCredits(surface, frameState) { const creditDisplay = frameState.creditDisplay; if ( + defined(surface._terrainProvider) && // ready is deprecated; This is here for backwards compatibility surface._terrainProvider._ready && defined(surface._terrainProvider.credit) @@ -573,6 +569,10 @@ GlobeSurfaceTileProvider.prototype.cancelReprojections = function () { GlobeSurfaceTileProvider.prototype.getLevelMaximumGeometricError = function ( level ) { + if (!defined(this._terrainProvider)) { + return 0; + } + return this._terrainProvider.getLevelMaximumGeometricError(level); }; @@ -2126,6 +2126,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { const oceanNormalMap = tileProvider.oceanNormalMap; const showOceanWaves = showReflectiveOcean && defined(oceanNormalMap); const hasVertexNormals = + defined(tileProvider.terrainProvider) && // ready is deprecated; This is here for backwards compatibility tileProvider.terrainProvider._ready && tileProvider.terrainProvider.hasVertexNormals; diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 497e80cba98..851967cd62f 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -511,7 +511,7 @@ ImageryLayer.prototype.getViewableRectangle = function () { * @private * * @param {Tile} tile The terrain tile. - * @param {TerrainProvider} terrainProvider The terrain provider associated with the terrain tile. + * @param {TerrainProvider|undefined} terrainProvider The terrain provider associated with the terrain tile. * @param {Number} insertionPoint The position to insert new skeletons before in the tile's imagery list. * @returns {Boolean} true if this layer overlaps any portion of the terrain tile; otherwise, false. */ @@ -523,8 +523,9 @@ ImageryLayer.prototype._createTileImagerySkeletons = function ( const surfaceTile = tile.data; if ( - defined(this._minimumTerrainLevel) && - tile.level < this._minimumTerrainLevel + !defined(terrainProvider) || + (defined(this._minimumTerrainLevel) && + tile.level < this._minimumTerrainLevel) ) { return false; } diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index 40d9c4f8e3b..6e21011661e 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -3,6 +3,7 @@ import BoundingSphere from "../Core/BoundingSphere.js"; import BoxGeometry from "../Core/BoxGeometry.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartographic from "../Core/Cartographic.js"; +import Check from "../Core/Check.js"; import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js"; @@ -638,6 +639,7 @@ function Scene(options) { requestRenderAfterFrame(this) ); this._removeGlobeCallbacks = []; + this._removeTerrainProviderReadyListener = undefined; const viewport = new BoundingRectangle( 0, @@ -1104,6 +1106,11 @@ Object.defineProperties(Scene.prototype, { return this.globe.terrainProvider; }, set: function (terrainProvider) { + // Cancel any in-progress terrain update + this._removeTerrainProviderReadyListener = + this._removeTerrainProviderReadyListener && + this._removeTerrainProviderReadyListener(); + if (defined(this.globe)) { this.globe.terrainProvider = terrainProvider; } @@ -4377,6 +4384,55 @@ Scene.prototype.morphTo3D = function (duration) { this._transitioner.morphTo3D(duration, ellipsoid); }; +function setTerrain(scene, terrain) { + // Cancel any in-progress terrain update + scene._removeTerrainProviderReadyListener = + scene._removeTerrainProviderReadyListener && + scene._removeTerrainProviderReadyListener(); + + // Set a placeholder + scene.globe.terrainProvider = undefined; + + scene._removeTerrainProviderReadyListener = terrain.readyEvent.addEventListener( + (provider) => { + if (defined(scene) && defined(scene.globe)) { + scene.globe.terrainProvider = provider; + } + + scene._removeTerrainProviderReadyListener(); + } + ); +} + +/** + * Update the terrain providing surface geometry for the globe. + * + * @param {Terrain} terrain The terrain provider async helper + * @returns {Terrain} terrain The terrain provider async helper + * + * @example + * // Use Cesium World Terrain + * scene.setTerrain(Cesium.Terrain.fromWorldTerrain()); + * + * @example + * // Use a custom terrain provider + * const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); + * scene.setTerrain(terrain); + * + * terrain.errorEvent.addEventListener(error => { + * alert(`Encountered an error while creating terrain! ${error}`); + * }); + */ +Scene.prototype.setTerrain = function (terrain) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("terrain", terrain); + //>>includeEnd('debug'); + + setTerrain(this, terrain); + + return terrain; +}; + /** * Returns true if this object was destroyed; otherwise, false. * <br /><br /> @@ -4421,6 +4477,9 @@ Scene.prototype.destroy = function () { this._groundPrimitives = this._groundPrimitives && this._groundPrimitives.destroy(); this._globe = this._globe && this._globe.destroy(); + this._removeTerrainProviderReadyListener = + this._removeTerrainProviderReadyListener && + this._removeTerrainProviderReadyListener(); this.skyBox = this.skyBox && this.skyBox.destroy(); this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy(); this._debugSphere = this._debugSphere && this._debugSphere.destroy(); diff --git a/packages/engine/Source/Scene/Terrain.js b/packages/engine/Source/Scene/Terrain.js new file mode 100644 index 00000000000..3dfdf84f706 --- /dev/null +++ b/packages/engine/Source/Scene/Terrain.js @@ -0,0 +1,180 @@ +import Check from "../Core/Check.js"; +import Event from "../Core/Event.js"; +import createWorldTerrainAsync from "../Core/createWorldTerrainAsync.js"; + +function handleError(errorEvent, error) { + if (errorEvent.numberOfListeners > 0) { + errorEvent.raiseEvent(error); + } else { + // Default handler is to log to the console + console.error(error); + } +} + +async function handlePromise(instance, promise) { + let provider; + try { + provider = await Promise.resolve(promise); + } catch (error) { + handleError(instance._errorEvent, error); + } + + instance._provider = provider; + instance._readyEvent.raiseEvent(provider); +} + +/** + * A helper to manage async operations of a terrain provider. + * + * @alias Terrain + * @constructor + * + * @see Terrain.fromWorldTerrain + * @see CesiumTerrainProvider + * @see VRTheWorldTerrainProvider + * @see GoogleEarthEnterpriseTerrainProvider + * + * @example + * // Create + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); + * }); + * + * @example + * // Handle loading events + * const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); + * + * terrain.readyEvent.addEventListener(provider => { + * scene.terrainProvider = provider; + * scene.globe.enableLighting = true; + * + * terrain.provider.errorEvent.addEventListener(error => { + * alert(`Encountered an error while loading terrain tiles! ${error}`); + * }); + * }); + * + * terrain.errorEvent.addEventListener(error => { + * alert(`Encountered an error while creating terrain! ${error}`); + * }); + * + * @param {Promise<TerrainProvider>} A promise which resolves to a terrain provider + */ +function Terrain(providerPromise) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("providerPromise", providerPromise); + //>>includeEnd('debug'); + + this._provider = undefined; + this._errorEvent = new Event(); + this._readyEvent = new Event(); + + handlePromise(this, providerPromise); +} + +Object.defineProperties(Terrain.prototype, { + /** + * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link TileProviderError}. + * @memberof TerrainProvider.prototype + * @type {Event<TerrainProvider.ErrorEvent>} + * @readonly + */ + errorEvent: { + get: function () { + return this._errorEvent; + }, + }, + + /** + * Gets an event that is raised when the terrain provider has been successfully created. Event listeners + * are passed the created instance of {@link TerrainProvider}. + * @memberof TerrainProvider.prototype + * @type {Event<TerrainProvider.ReadyEvent>} + * @readonly + */ + readyEvent: { + get: function () { + return this._readyEvent; + }, + }, + + /** + * The terrain provider providing surface geometry to a globe. Do not use until {@link Terrain.readyEvent} is raised. + * @memberof Viewer.prototype + * + * @type {TerrainProvider} + * @readonly + */ + provider: { + get: function () { + return this._provider; + }, + }, +}); +/** + * Creates a {@link Terrain} instance for {@link https://cesium.com/content/#cesium-world-terrain|Cesium World Terrain}. + * + * @function + * + * @param {Object} [options] Object with the following properties: + * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. + * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server if available. + * @returns {<Terrain>} A promise that resolves to the created CesiumTerrainProvider + * + * @see Ion + * @see createWorldTerrainAsync + * + * @example + * // Create Cesium World Terrain with default settings + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: Cesium.Terrain.fromWorldTerrain() + * }); + * + * @example + * // Create Cesium World Terrain with water and normals. + * const viewer1 = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: Cesium.Terrain.fromWorldTerrain({ + * requestWaterMask: true, + * requestVertexNormals: true + * }); + * }); + * + * @example + * // Handle loading events + * const providerManager = Cesium.Terrain.fromWorldTerrain(); + * + * providerManager.readyEvent.addEventListener(provider => { + * viewer.terrainProvider = provider; + * viewer.scene.globe.enableLighting = true; + * + * providerManager.provider.errorEvent.addEventListener(error => { + * alert(`Encountered an error while loading terrain tiles! ${error}`); + * }); + * }); + * + * providerManager.errorEvent.addEventListener(error => { + * alert(`Encountered an error while creating terrain! ${error}`); + * }); + */ +Terrain.fromWorldTerrain = function (options) { + return new Terrain(createWorldTerrainAsync(options)); +}; + +/** + * A function that is called when an error occurs. + * @callback Terrain.ErrorEvent + * + * @this Terrain + * @param {Error} err An object holding details about the error that occurred. + */ + +/** + * A function that is called when the provider has been created + * @callback Terrain.ReadyEvent + * + * @this Terrain + * @param {TerrainProvider} provider The created terrain provider. + */ + +export default Terrain; diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index fbe6ebba276..8565cbfaa26 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -125,6 +125,7 @@ function configureCameraFrustum(widget) { * @param {Clock} [options.clock=new Clock()] The clock to use to control current time. * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to <code>false</code>, no imagery provider will be added. * @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. + * @param {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. * @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @param {SkyAtmosphere | false} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. * @param {SceneMode} [options.sceneMode=SceneMode.SCENE3D] The initial scene mode. @@ -163,7 +164,7 @@ function configureCameraFrustum(widget) { * try { * const widget2 = new Cesium.CesiumWidget("cesiumContainer", { * imageryProvider: Cesium.createWorldImagery(), - * terrainProvider: await Cesium.createWorldTerrainAsync(), + * terrain: Cesium.Terrain.fromWorldTerrain() * skyBox: new Cesium.SkyBox({ * sources: { * positiveX: "stars/TychoSkymapII.t3_08192x04096_80_px.jpg", @@ -360,6 +361,18 @@ function CesiumWidget(container, options) { scene.terrainProvider = options.terrainProvider; } + if (defined(options.terrain) && options.globe !== false) { + //>>includeStart('debug', pragmas.debug); + if (defined(options.terrainProvider)) { + throw new DeveloperError( + "Specify either options.terrainProvider or options.terrain." + ); + } + //>>includeEnd('debug') + + scene.setTerrain(options.terrain); + } + this._screenSpaceEventHandler = new ScreenSpaceEventHandler(canvas); if (defined(options.sceneMode)) { diff --git a/packages/engine/Specs/Scene/SceneSpec.js b/packages/engine/Specs/Scene/SceneSpec.js index ac03d760e8a..cd477e0cf65 100644 --- a/packages/engine/Specs/Scene/SceneSpec.js +++ b/packages/engine/Specs/Scene/SceneSpec.js @@ -41,6 +41,7 @@ import { SunLight, TweenCollection, Sun, + Terrain, GroundPrimitive, PerInstanceColorAppearance, ColorGeometryInstanceAttribute, @@ -1495,33 +1496,71 @@ describe( scene.destroyForSpecs(); }); - it("Sets terrainProvider", function () { + it("Sets terrainProvider", async function () { returnQuantizedMeshTileJson(); const scene = createScene(); const globe = (scene.globe = new Globe(Ellipsoid.UNIT_SPHERE)); - scene.terrainProvider = new CesiumTerrainProvider({ - url: "//terrain/tiles", + scene.terrainProvider = await CesiumTerrainProvider.fromUrl( + "//terrain/tiles" + ); + + expect(scene.terrainProvider).toBe(globe.terrainProvider); + scene.globe = undefined; + + const newProvider = await CesiumTerrainProvider.fromUrl( + "//newTerrain/tiles" + ); + expect(function () { + scene.terrainProvider = newProvider; + }).not.toThrow(); + + scene.destroyForSpecs(); + Resource._Implementations.loadWithXhr = + Resource._DefaultImplementations.loadWithXhr; + }); + + it("setTerrain updates terrain provider", async function () { + returnQuantizedMeshTileJson(); + + const scene = createScene(); + const globe = (scene.globe = new Globe(Ellipsoid.UNIT_SPHERE)); + const promise = CesiumTerrainProvider.fromUrl("//terrain/tiles"); + scene.setTerrain(new Terrain(promise)); + + const originalProvider = scene.terrainProvider; + let terrainWasChanged = false; + scene.terrainProviderChanged.addEventListener((terrainProvider) => { + expect(terrainProvider).not.toBe(originalProvider); + expect(scene.terrainProvider).toBe(terrainProvider); + expect(scene.terrainProvider).toBe(globe.terrainProvider); + terrainWasChanged = true; }); - return scene.terrainProvider.readyPromise - .then(() => { - expect(scene.terrainProvider).toBe(globe.terrainProvider); - scene.globe = undefined; - const newProvider = new CesiumTerrainProvider({ - url: "//newTerrain/tiles", - }); - return newProvider.readyPromise.then(() => { - expect(function () { - scene.terrainProvider = newProvider; - }).not.toThrow(); - }); - }) - .finally(() => { - scene.destroyForSpecs(); - Resource._Implementations.loadWithXhr = - Resource._DefaultImplementations.loadWithXhr; - }); + await promise; + + expect(terrainWasChanged).toBeTrue(); + + scene.destroyForSpecs(); + Resource._Implementations.loadWithXhr = + Resource._DefaultImplementations.loadWithXhr; + }); + + it("setTerrain handles destroy", async function () { + returnQuantizedMeshTileJson(); + + const scene = createScene(); + scene.globe = new Globe(Ellipsoid.UNIT_SPHERE); + + const promise = CesiumTerrainProvider.fromUrl("//newTerrain/tiles"); + scene.setTerrain(new Terrain(promise)); + scene.destroyForSpecs(); + + await expectAsync(promise).toBeResolved(); + expect(scene.isDestroyed()).toBeTrue(); + + Resource._Implementations.loadWithXhr = + Resource._DefaultImplementations.loadWithXhr; }); it("Gets terrainProviderChanged", function () { diff --git a/packages/engine/Specs/Scene/TerrainSpec.js b/packages/engine/Specs/Scene/TerrainSpec.js new file mode 100644 index 00000000000..35dfa3a690d --- /dev/null +++ b/packages/engine/Specs/Scene/TerrainSpec.js @@ -0,0 +1,57 @@ +import { Terrain, EllipsoidTerrainProvider } from "../../index.js"; + +describe("Scene/Terrain", function () { + it("constructor throws without terrain promise", function () { + expect(() => new Terrain()).toThrowDeveloperError(); + }); + + it("does not throw on error", function () { + expect(() => { + // eslint-disable-next-line no-unused-vars + const terrain = new Terrain(Promise.reject(new Error("Fail"))); + }).not.toThrow(); + }); + + it("readyEvent handles terrain promise success", async function () { + let resolve; + const promise = new Promise((r) => { + resolve = r; + }); + + const terrain = new Terrain(promise); + const terrainProvider = new EllipsoidTerrainProvider(); + + let wasCalled = false; + terrain.readyEvent.addEventListener((provider) => { + expect(provider).toBe(terrainProvider); + wasCalled = true; + }); + + resolve(terrainProvider); + + await promise; + expect(wasCalled).toBeTrue(); + expect(terrain.provider).toBe(terrainProvider); + }); + + it("errorEvent handles terrain promise failure", async function () { + let reject; + const promise = new Promise((resolve, r) => { + reject = r; + }); + + const terrain = new Terrain(promise); + const error = new Error("Fail"); + + let wasCalled = false; + terrain.errorEvent.addEventListener((e) => { + expect(e).toBe(error); + wasCalled = true; + }); + + reject(error); + + await expectAsync(promise).toBeRejected(); + expect(wasCalled).toBeTrue(); + }); +}); diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js index 191b07f5abc..78c964be115 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -3,6 +3,7 @@ import { defined, DeveloperError, EllipsoidTerrainProvider, + Terrain, } from "@cesium/engine"; import knockout from "../ThirdParty/knockout.js"; import createCommand from "../createCommand.js"; @@ -181,7 +182,7 @@ function BaseLayerPickerViewModel(options) { get: function () { return selectedImageryViewModel(); }, - set: async function (value) { + set: function (value) { if (selectedImageryViewModel() === value) { this.dropDownVisible = false; return; @@ -253,31 +254,19 @@ function BaseLayerPickerViewModel(options) { newProvider = value.creationCommand(); } - selectedTerrainViewModel(value); - - const updateTerrainProvider = async () => { - try { - const provider = await Promise.resolve(newProvider); - - if (!defined(provider) || this._globe.isDestroyed()) { - this.dropDownVisible = false; - return; - } - + const terrain = new Terrain(Promise.resolve(newProvider)); + const removeEventListener = terrain.readyEvent.addEventListener( + (terrainProvider) => { this._globe.depthTestAgainstTerrain = !( - provider instanceof EllipsoidTerrainProvider - ); - this._globe.terrainProvider = provider; - } catch (error) { - console.log( - `An error occurred while creating the terrain provider: ${error}` + terrainProvider instanceof EllipsoidTerrainProvider ); + this._globe.terrainProvider = terrainProvider; + removeEventListener(); } + ); - this.dropDownVisible = false; - }; - - updateTerrainProvider(); + selectedTerrainViewModel(value); + this.dropDownVisible = false; }, }); @@ -290,12 +279,9 @@ function BaseLayerPickerViewModel(options) { options.selectedImageryProviderViewModel, imageryProviderViewModels[0] ); - - selectedTerrainViewModel( - defaultValue( - options.selectedTerrainProviderViewModel, - terrainProviderViewModels[0] - ) + this.selectedTerrain = defaultValue( + options.selectedTerrainProviderViewModel, + terrainProviderViewModels[0] ); } @@ -303,6 +289,7 @@ Object.defineProperties(BaseLayerPickerViewModel.prototype, { /** * Gets the command to toggle the visibility of the drop down. * @memberof BaseLayerPickerViewModel.prototype + * * @type {Command} */ toggleDropDown: { @@ -314,6 +301,7 @@ Object.defineProperties(BaseLayerPickerViewModel.prototype, { /** * Gets the globe. * @memberof BaseLayerPickerViewModel.prototype + * * @type {Globe} */ globe: { diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 2cdde7b667e..d5a902be89f 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -315,6 +315,7 @@ function enableVRUI(viewer, enabled) { * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use + * @param {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. @@ -375,7 +376,7 @@ function enableVRUI(viewer, enabled) { * // Start in Columbus Viewer * sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, * // Use Cesium World Terrain - * terrainProvider: await Cesium.createWorldTerrainAsync(), + * terrain: Cesium.Terrain.fromWorldTerrain(), * // Hide the base layer picker * baseLayerPicker: false, * // Use OpenStreetMaps @@ -690,6 +691,22 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to scene.terrainProvider = options.terrainProvider; } + if (defined(options.terrain)) { + //>>includeStart('debug', pragmas.debug); + if (defined(options.terrainProvider)) { + throw new DeveloperError( + "Specify either options.terrainProvider or options.terrain." + ); + } + //>>includeEnd('debug') + + if (createBaseLayerPicker) { + baseLayerPicker.viewModel.selectedTerrain = undefined; + } + + scene.setTerrain(options.terrain); + } + // Navigation Help Button let navigationHelpButton; if ( From c95cbc6b8061ce35acb530f6abd969c49d668567 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Feb 2023 16:03:05 -0500 Subject: [PATCH 447/679] Cleanup doc --- packages/engine/Source/Scene/Terrain.js | 50 +++++++++++++------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/engine/Source/Scene/Terrain.js b/packages/engine/Source/Scene/Terrain.js index 3dfdf84f706..1ed77b5a7e7 100644 --- a/packages/engine/Source/Scene/Terrain.js +++ b/packages/engine/Source/Scene/Terrain.js @@ -37,15 +37,16 @@ async function handlePromise(instance, promise) { * @example * // Create * const viewer = new Cesium.Viewer("cesiumContainer", { - * terrainProvider: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); + * terrain: new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); * }); * * @example * // Handle loading events * const terrain = new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl("https://myTestTerrain.com")); * + * scene.setTerrain(terrain); + * * terrain.readyEvent.addEventListener(provider => { - * scene.terrainProvider = provider; * scene.globe.enableLighting = true; * * terrain.provider.errorEvent.addEventListener(error => { @@ -57,27 +58,27 @@ async function handlePromise(instance, promise) { * alert(`Encountered an error while creating terrain! ${error}`); * }); * - * @param {Promise<TerrainProvider>} A promise which resolves to a terrain provider + * @param {Promise<TerrainProvider>} terrainProviderPromise A promise which resolves to a terrain provider */ -function Terrain(providerPromise) { +function Terrain(terrainProviderPromise) { //>>includeStart('debug', pragmas.debug); - Check.typeOf.object("providerPromise", providerPromise); + Check.typeOf.object("terrainProviderPromise", terrainProviderPromise); //>>includeEnd('debug'); this._provider = undefined; this._errorEvent = new Event(); this._readyEvent = new Event(); - handlePromise(this, providerPromise); + handlePromise(this, terrainProviderPromise); } Object.defineProperties(Terrain.prototype, { /** * Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing * to the event, you will be notified of the error and can potentially recover from it. Event listeners - * are passed an instance of {@link TileProviderError}. - * @memberof TerrainProvider.prototype - * @type {Event<TerrainProvider.ErrorEvent>} + * are passed an instance of the thrown error. + * @memberof Terrain.prototype + * @type {Event<Terrain.ErrorEventCallback>} * @readonly */ errorEvent: { @@ -89,8 +90,8 @@ Object.defineProperties(Terrain.prototype, { /** * Gets an event that is raised when the terrain provider has been successfully created. Event listeners * are passed the created instance of {@link TerrainProvider}. - * @memberof TerrainProvider.prototype - * @type {Event<TerrainProvider.ReadyEvent>} + * @memberof Terrain.prototype + * @type {Event<Terrain.ReadyEventCallback>} * @readonly */ readyEvent: { @@ -120,7 +121,7 @@ Object.defineProperties(Terrain.prototype, { * @param {Object} [options] Object with the following properties: * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server if available. - * @returns {<Terrain>} A promise that resolves to the created CesiumTerrainProvider + * @returns {Terrain} An asynchronous helper object for a CesiumTerrainProvider * * @see Ion * @see createWorldTerrainAsync @@ -128,13 +129,13 @@ Object.defineProperties(Terrain.prototype, { * @example * // Create Cesium World Terrain with default settings * const viewer = new Cesium.Viewer("cesiumContainer", { - * terrainProvider: Cesium.Terrain.fromWorldTerrain() + * terrain: Cesium.Terrain.fromWorldTerrain() * }); * * @example * // Create Cesium World Terrain with water and normals. * const viewer1 = new Cesium.Viewer("cesiumContainer", { - * terrainProvider: Cesium.Terrain.fromWorldTerrain({ + * terrain: Cesium.Terrain.fromWorldTerrain({ * requestWaterMask: true, * requestVertexNormals: true * }); @@ -142,18 +143,19 @@ Object.defineProperties(Terrain.prototype, { * * @example * // Handle loading events - * const providerManager = Cesium.Terrain.fromWorldTerrain(); + * const terrain = Cesium.Terrain.fromWorldTerrain(); * - * providerManager.readyEvent.addEventListener(provider => { - * viewer.terrainProvider = provider; - * viewer.scene.globe.enableLighting = true; + * scene.setTerrain(terrain); * - * providerManager.provider.errorEvent.addEventListener(error => { + * terrain.readyEvent.addEventListener(provider => { + * scene.globe.enableLighting = true; + * + * terrain.provider.errorEvent.addEventListener(error => { * alert(`Encountered an error while loading terrain tiles! ${error}`); * }); * }); * - * providerManager.errorEvent.addEventListener(error => { + * terrain.errorEvent.addEventListener(error => { * alert(`Encountered an error while creating terrain! ${error}`); * }); */ @@ -161,9 +163,11 @@ Terrain.fromWorldTerrain = function (options) { return new Terrain(createWorldTerrainAsync(options)); }; +export default Terrain; + /** * A function that is called when an error occurs. - * @callback Terrain.ErrorEvent + * @callback Terrain.ErrorEventCallback * * @this Terrain * @param {Error} err An object holding details about the error that occurred. @@ -171,10 +175,8 @@ Terrain.fromWorldTerrain = function (options) { /** * A function that is called when the provider has been created - * @callback Terrain.ReadyEvent + * @callback Terrain.ReadyEventCallback * * @this Terrain * @param {TerrainProvider} provider The created terrain provider. */ - -export default Terrain; From 263340f8675398f776bab85e90adabbdf612525f Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Feb 2023 17:19:04 -0500 Subject: [PATCH 448/679] Fix remaining sandcastles --- Apps/Sandcastle/gallery/3D Tiles Inspector.html | 9 ++++----- Apps/Sandcastle/gallery/3D Tiles Interior.html | 9 ++++----- ...Tiles Next Photogrammetry Classification.html | 9 ++++----- .../3D Tiles Photogrammetry Classification.html | 9 ++++----- .../gallery/3D Tiles Point Cloud Shading.html | 9 ++++----- .../Sandcastle/gallery/3D Tiles Point Cloud.html | 9 ++++----- Apps/Sandcastle/gallery/Ambient Occlusion.html | 9 ++++----- .../gallery/ArcGIS Tiled Elevation Terrain.html | 9 ++++----- Apps/Sandcastle/gallery/CZML Box.html | 9 ++++----- Apps/Sandcastle/gallery/CZML Colors.html | 9 ++++----- .../gallery/CZML Custom Properties.html | 9 ++++----- Apps/Sandcastle/gallery/CZML Model Data URL.html | 9 ++++----- .../gallery/CZML Point - Time Dynamic.html | 9 ++++----- .../gallery/CZML Position Definitions.html | 9 ++++----- Apps/Sandcastle/gallery/CZML ZIndex.html | 9 ++++----- Apps/Sandcastle/gallery/Callback Property.html | 9 ++++----- Apps/Sandcastle/gallery/Camera.html | 9 ++++----- .../gallery/Cartographic Limit Rectangle.html | 9 ++++----- .../Sandcastle/gallery/Cesium World Terrain.html | 9 ++++----- Apps/Sandcastle/gallery/Clamp to 3D Tiles.html | 9 ++++----- Apps/Sandcastle/gallery/Clock.html | 8 +++----- Apps/Sandcastle/gallery/Clouds.html | 9 ++++----- Apps/Sandcastle/gallery/Custom Geocoder.html | 9 ++++----- Apps/Sandcastle/gallery/Custom Post Process.html | 9 ++++----- .../gallery/Geometry Height Reference.html | 9 ++++----- Apps/Sandcastle/gallery/I3S 3D Object Layer.html | 16 ++++++++-------- Apps/Sandcastle/gallery/I3S Feature Picking.html | 16 ++++++++-------- .../gallery/I3S IntegratedMesh Layer.html | 16 ++++++++-------- Apps/Sandcastle/gallery/Labels.html | 9 ++++----- .../gallery/development/Corridor Outline.html | 9 ++++----- 30 files changed, 131 insertions(+), 159 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index d07f605b952..b0439fe0852 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -62,15 +62,14 @@ tileset.boundingSphere.radius / 4.0 ) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Interior.html b/Apps/Sandcastle/gallery/3D Tiles Interior.html index 2a95807f28b..3fc2975278f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interior.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interior.html @@ -60,15 +60,14 @@ endTransform: Cesium.Matrix4.IDENTITY, }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 6ed0f78f7c8..07074ed6b1d 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -352,15 +352,14 @@ ]; Sandcastle.addToolbarMenu(demos); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 233b9d36d80..0d96bfd5ade 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -76,15 +76,14 @@ classificationTileset.show = checked; nonClassificationTileset.show = !checked; }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index cbbb50ece83..c4a5e7ea38b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -372,15 +372,14 @@ viewModelTileset.pointCloudShading.eyeDomeLighting = checked; } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index 8779b985f8e..0432f4efa17 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -58,15 +58,14 @@ 6.281110875400085 ), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Ambient Occlusion.html b/Apps/Sandcastle/gallery/Ambient Occlusion.html index 5575c9ebe55..93d0363738f 100644 --- a/Apps/Sandcastle/gallery/Ambient Occlusion.html +++ b/Apps/Sandcastle/gallery/Ambient Occlusion.html @@ -203,15 +203,14 @@ ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index e16d10af0b5..00296dec2b5 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -37,15 +37,14 @@ "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" ), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Box.html b/Apps/Sandcastle/gallery/CZML Box.html index 411335c7978..e698bb0e70d 100644 --- a/Apps/Sandcastle/gallery/CZML Box.html +++ b/Apps/Sandcastle/gallery/CZML Box.html @@ -105,15 +105,14 @@ viewer.dataSources.add(dataSourcePromise); viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Colors.html b/Apps/Sandcastle/gallery/CZML Colors.html index 3ab17adf809..0ab646b53eb 100644 --- a/Apps/Sandcastle/gallery/CZML Colors.html +++ b/Apps/Sandcastle/gallery/CZML Colors.html @@ -87,15 +87,14 @@ const dataSourcePromise = Cesium.CzmlDataSource.load(czml); viewer.dataSources.add(dataSourcePromise); viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Custom Properties.html b/Apps/Sandcastle/gallery/CZML Custom Properties.html index 7217a1083e6..08668919f59 100644 --- a/Apps/Sandcastle/gallery/CZML Custom Properties.html +++ b/Apps/Sandcastle/gallery/CZML Custom Properties.html @@ -172,15 +172,14 @@ viewer.dataSources.add(dataSource); viewer.zoomTo(dataSource); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Model Data URL.html b/Apps/Sandcastle/gallery/CZML Model Data URL.html index b0561778dcd..e7862e2915a 100644 --- a/Apps/Sandcastle/gallery/CZML Model Data URL.html +++ b/Apps/Sandcastle/gallery/CZML Model Data URL.html @@ -172,15 +172,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html index 3ca62d6746d..211171f84cb 100644 --- a/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html +++ b/Apps/Sandcastle/gallery/CZML Point - Time Dynamic.html @@ -83,15 +83,14 @@ viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML Position Definitions.html b/Apps/Sandcastle/gallery/CZML Position Definitions.html index 6520d1bd165..0d15bfe6e50 100644 --- a/Apps/Sandcastle/gallery/CZML Position Definitions.html +++ b/Apps/Sandcastle/gallery/CZML Position Definitions.html @@ -103,15 +103,14 @@ viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/CZML ZIndex.html b/Apps/Sandcastle/gallery/CZML ZIndex.html index 492f9ba8868..60528c8e308 100644 --- a/Apps/Sandcastle/gallery/CZML ZIndex.html +++ b/Apps/Sandcastle/gallery/CZML ZIndex.html @@ -146,15 +146,14 @@ viewer.zoomTo(dataSourcePromise); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Callback Property.html b/Apps/Sandcastle/gallery/Callback Property.html index 8747ff39473..65e589a54f8 100644 --- a/Apps/Sandcastle/gallery/Callback Property.html +++ b/Apps/Sandcastle/gallery/Callback Property.html @@ -118,15 +118,14 @@ // Keep the view centered. viewer.trackedEntity = label; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Camera.html b/Apps/Sandcastle/gallery/Camera.html index 340b5f18bf6..69710e5112f 100644 --- a/Apps/Sandcastle/gallery/Camera.html +++ b/Apps/Sandcastle/gallery/Camera.html @@ -485,15 +485,14 @@ reset(); }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 043814d13fe..5f23f3ba7a4 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -89,15 +89,14 @@ rectangleEntity.show = checked; } }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 0e4162731d7..2a878d49bf7 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -39,15 +39,14 @@ const viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: await Cesium.createWorldTerrainAsync(), }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index 048b34bad1b..afcb097af0a 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -85,15 +85,14 @@ entity.position = scene.clampToHeight(position, objectsToExclude); }); } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clock.html b/Apps/Sandcastle/gallery/Clock.html index aedacb0ce17..631860739e7 100644 --- a/Apps/Sandcastle/gallery/Clock.html +++ b/Apps/Sandcastle/gallery/Clock.html @@ -62,15 +62,13 @@ Sandcastle.addToolbarButton("Speed Up Clock", function () { viewer.clockViewModel.multiplier *= 2; }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index f275991e71a..2e1a9fc85ca 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -267,15 +267,14 @@ }); scene.fog.density = 1.15e-4; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Geocoder.html b/Apps/Sandcastle/gallery/Custom Geocoder.html index 5e6c82b4ebf..de0aff61340 100644 --- a/Apps/Sandcastle/gallery/Custom Geocoder.html +++ b/Apps/Sandcastle/gallery/Custom Geocoder.html @@ -90,15 +90,14 @@ }); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Custom Post Process.html b/Apps/Sandcastle/gallery/Custom Post Process.html index 2e5b56fa077..52e493bf4aa 100644 --- a/Apps/Sandcastle/gallery/Custom Post Process.html +++ b/Apps/Sandcastle/gallery/Custom Post Process.html @@ -78,15 +78,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index 1ac2145e111..58c0b761150 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -174,15 +174,14 @@ viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); } //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 52d15402f4a..232a99021d9 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -150,15 +150,15 @@ <h1>Loading...</h1> } return false; } //Sandcastle_End - if (typeof Cesium !== "undefined") { - window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } - } }; + if (typeof Cesium !== "undefined") { + window.startupCalled = true; + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); + } </script> </body> </html> diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index 10052a04dbf..5678e7aed10 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -150,15 +150,15 @@ <h1>Loading...</h1> } return false; } //Sandcastle_End - if (typeof Cesium !== "undefined") { - window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } - } }; + if (typeof Cesium !== "undefined") { + window.startupCalled = true; + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); + } </script> </body> </html> diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 305d18ae14a..03bb0cefccd 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -85,15 +85,15 @@ <h1>Loading...</h1> viewer.camera.setView({ destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), }); //Sandcastle_End - if (typeof Cesium !== "undefined") { - window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { - console.error(error); - } - } }; + if (typeof Cesium !== "undefined") { + window.startupCalled = true; + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); + } </script> </body> </html> diff --git a/Apps/Sandcastle/gallery/Labels.html b/Apps/Sandcastle/gallery/Labels.html index dc6f65433af..4de6651f0c2 100644 --- a/Apps/Sandcastle/gallery/Labels.html +++ b/Apps/Sandcastle/gallery/Labels.html @@ -268,15 +268,14 @@ } }; //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/development/Corridor Outline.html b/Apps/Sandcastle/gallery/development/Corridor Outline.html index 750f89e3502..349c05fc9d8 100644 --- a/Apps/Sandcastle/gallery/development/Corridor Outline.html +++ b/Apps/Sandcastle/gallery/development/Corridor Outline.html @@ -98,15 +98,14 @@ }) ); //Sandcastle_End - Sandcastle.finishedLoading(); }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - try { - window.startup(Cesium); - } catch (error) { + window.startup(Cesium).catch((error) => { + "use strict"; console.error(error); - } + }); + Sandcastle.finishedLoading(); } </script> </body> From 40597989c281b5cb37ecaf9919b2287edb49681e Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 9 Feb 2023 13:10:08 +0800 Subject: [PATCH 449/679] Implement types - init --- Tools/jsdoc/conf.json | 1 + Tools/jsdoc/ts-conf.json | 1 + packages/engine/Source/Scene/Material.js | 118 ++++++++++++++++------- packages/engine/tsd-conf.json | 1 + packages/widgets/tsd-conf.json | 1 + 5 files changed, 86 insertions(+), 36 deletions(-) diff --git a/Tools/jsdoc/conf.json b/Tools/jsdoc/conf.json index 840e70cb871..cae7f00f043 100644 --- a/Tools/jsdoc/conf.json +++ b/Tools/jsdoc/conf.json @@ -16,6 +16,7 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ + "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags" ], "templates": { diff --git a/Tools/jsdoc/ts-conf.json b/Tools/jsdoc/ts-conf.json index 14b6d7bdf07..871593ad322 100644 --- a/Tools/jsdoc/ts-conf.json +++ b/Tools/jsdoc/ts-conf.json @@ -16,6 +16,7 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ + "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index a2380e9481e..42625259e77 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -36,6 +36,48 @@ import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.j import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; import WaterMaterial from "../Shaders/Materials/Water.js"; +/** + * @typedef {{}} GeneralValue Use for general uniform value, may be a struct in GLSL. + * @typedef { Color | + * String | + * Cartesian2 | + * import('../Core/Cartesian3').default | + * import('../Core/Cartesian4').default | + * Matrix2 | + * Matrix3 | + * Matrix4 | + * GeneralValue + * } FabricUniformValue + */ + +/** + * @typedef {Object.<string, FabricUniformValue>} FabricUniforms An object contain all uniforms that fabric material will use. + */ + +/** + * @typedef {Object} FabricComponents An object define all components will apply to fabric material. + * @property {String} [diffuse='vec3(0.0)'] Diffuse expression. + * @property {Number | String} [specular=0.0] Specular Expression. + * @property {Number | String} [shininess=1.0] Shininess Expression. + * @property {String} [normal] Normal Expression. + * @property {String} [emission='vec3(0.0)'] Emission Expression. + * @property {Number | String} [alpha=1] Alpha Expression. + */ + +/** + * @typedef {Object} Fabric The fabric definition to a material template object. + * @property {String} type The material type. + * @property {FabricUniforms} uniforms The uniforms that will use during shadering. + * @property {FabricComponents} components + */ + +/** + * @typedef {Object} MaterialTemplate A material template object. + * @property {Boolean} strict + * @property {Fabric} fabric + * @property {Boolean | (material: Material) => Boolean} translucent + */ + /** * A Material defines surface appearance through a combination of diffuse, specular, * normal, emission, and alpha components. These values are specified using a @@ -227,13 +269,12 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * * @param {Object} [options] Object with the following properties: * @param {Boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. - * @param {Boolean|Function} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry + * @param {Boolean|(material: Material) => Boolean} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry * with this material is expected to appear translucent. * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The {@link TextureMinificationFilter} to apply to this material's textures. * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The {@link TextureMagnificationFilter} to apply to this material's textures. - * @param {Object} options.fabric The fabric JSON used to generate the material. - * - * @constructor + * @param {Fabric} options.fabric The fabric JSON used to generate the material. + *ructor * * @exception {DeveloperError} fabric: uniform has invalid type. * @exception {DeveloperError} fabric: uniforms and materials cannot share the same property. @@ -258,12 +299,12 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * * // Create a color material with full Fabric notation: * polygon.material = new Cesium.Material({ - * fabric : { - * type : 'Color', - * uniforms : { - * color : new Cesium.Color(1.0, 1.0, 0.0, 1.0) - * } + * fabric: { + * type: 'Color', + * uniforms: { + * color: new Cesium.Color(1.0, 1.0, 0.0, 1.0) * } + * } * }); */ function Material(options) { @@ -350,7 +391,7 @@ Material._uniformList = {}; * Shorthand for: new Material({fabric : {type : type}}); * * @param {String} type The base material type. - * @param {Object} [uniforms] Overrides for the default uniforms. + * @param {FabricUniforms} [uniforms] Overrides for the default uniforms. * @returns {Material} New material object. * * @exception {DeveloperError} material with that type does not exist. @@ -1206,6 +1247,11 @@ function getNumberOfTokens(material, token, excludePeriod) { Material._materialCache = { _materials: {}, + /** + * Add a fabric material to + * @param {String} type The material type. + * @param {MaterialTemplate} materialTemplate An object represent a fabric material. + */ addMaterial: function (type, materialTemplate) { this._materials[type] = materialTemplate; }, @@ -1216,19 +1262,19 @@ Material._materialCache = { /** * Gets or sets the default texture uniform value. - * @type {String} + * @type {"czm_defaultImage"} */ Material.DefaultImageId = "czm_defaultImage"; /** * Gets or sets the default cube map texture uniform value. - * @type {String} + * @type {"czm_defaultCubeMap"} */ Material.DefaultCubeMapId = "czm_defaultCubeMap"; /** * Gets the name of the color material. - * @type {String} + * @type {"Color"} * @readonly */ Material.ColorType = "Color"; @@ -1250,7 +1296,7 @@ Material._materialCache.addMaterial(Material.ColorType, { /** * Gets the name of the image material. - * @type {String} + * @type {"Image"} * @readonly */ Material.ImageType = "Image"; @@ -1275,7 +1321,7 @@ Material._materialCache.addMaterial(Material.ImageType, { /** * Gets the name of the diffuce map material. - * @type {String} + * @type {"DiffuseMap"} * @readonly */ Material.DiffuseMapType = "DiffuseMap"; @@ -1296,7 +1342,7 @@ Material._materialCache.addMaterial(Material.DiffuseMapType, { /** * Gets the name of the alpha map material. - * @type {String} + * @type {"AlphaMap"} * @readonly */ Material.AlphaMapType = "AlphaMap"; @@ -1317,7 +1363,7 @@ Material._materialCache.addMaterial(Material.AlphaMapType, { /** * Gets the name of the specular map material. - * @type {String} + * @type {"SpecularMap"} * @readonly */ Material.SpecularMapType = "SpecularMap"; @@ -1338,7 +1384,7 @@ Material._materialCache.addMaterial(Material.SpecularMapType, { /** * Gets the name of the emmision map material. - * @type {String} + * @type {"EmissionMap"} * @readonly */ Material.EmissionMapType = "EmissionMap"; @@ -1359,7 +1405,7 @@ Material._materialCache.addMaterial(Material.EmissionMapType, { /** * Gets the name of the bump map material. - * @type {String} + * @type {"BumpMap"} * @readonly */ Material.BumpMapType = "BumpMap"; @@ -1379,7 +1425,7 @@ Material._materialCache.addMaterial(Material.BumpMapType, { /** * Gets the name of the normal map material. - * @type {String} + * @type {"NormalMap"} * @readonly */ Material.NormalMapType = "NormalMap"; @@ -1399,7 +1445,7 @@ Material._materialCache.addMaterial(Material.NormalMapType, { /** * Gets the name of the grid material. - * @type {String} + * @type {"Grid"} * @readonly */ Material.GridType = "Grid"; @@ -1423,7 +1469,7 @@ Material._materialCache.addMaterial(Material.GridType, { /** * Gets the name of the stripe material. - * @type {String} + * @type {"Stripe"} * @readonly */ Material.StripeType = "Stripe"; @@ -1447,7 +1493,7 @@ Material._materialCache.addMaterial(Material.StripeType, { /** * Gets the name of the checkerboard material. - * @type {String} + * @type {"Checkerboard"} * @readonly */ Material.CheckerboardType = "Checkerboard"; @@ -1469,7 +1515,7 @@ Material._materialCache.addMaterial(Material.CheckerboardType, { /** * Gets the name of the dot material. - * @type {String} + * @type {"Dot"} * @readonly */ Material.DotType = "Dot"; @@ -1491,7 +1537,7 @@ Material._materialCache.addMaterial(Material.DotType, { /** * Gets the name of the water material. - * @type {String} + * @type {"Water"} * @readonly */ Material.WaterType = "Water"; @@ -1521,7 +1567,7 @@ Material._materialCache.addMaterial(Material.WaterType, { /** * Gets the name of the rim lighting material. - * @type {String} + * @type {"RimLighting"} * @readonly */ Material.RimLightingType = "RimLighting"; @@ -1543,7 +1589,7 @@ Material._materialCache.addMaterial(Material.RimLightingType, { /** * Gets the name of the fade material. - * @type {String} + * @type {"Fade"} * @readonly */ Material.FadeType = "Fade"; @@ -1573,7 +1619,7 @@ Material._materialCache.addMaterial(Material.FadeType, { /** * Gets the name of the polyline arrow material. - * @type {String} + * @type {"PolylineArrow"} * @readonly */ Material.PolylineArrowType = "PolylineArrow"; @@ -1590,7 +1636,7 @@ Material._materialCache.addMaterial(Material.PolylineArrowType, { /** * Gets the name of the polyline glow material. - * @type {String} + * @type {"PolylineDash"} * @readonly */ Material.PolylineDashType = "PolylineDash"; @@ -1610,7 +1656,7 @@ Material._materialCache.addMaterial(Material.PolylineDashType, { /** * Gets the name of the polyline glow material. - * @type {String} + * @type {"PolylineGlow"} * @readonly */ Material.PolylineGlowType = "PolylineGlow"; @@ -1629,7 +1675,7 @@ Material._materialCache.addMaterial(Material.PolylineGlowType, { /** * Gets the name of the polyline outline material. - * @type {String} + * @type {"PolylineOutline"} * @readonly */ Material.PolylineOutlineType = "PolylineOutline"; @@ -1651,7 +1697,7 @@ Material._materialCache.addMaterial(Material.PolylineOutlineType, { /** * Gets the name of the elevation contour material. - * @type {String} + * @type {"ElevationContour"} * @readonly */ Material.ElevationContourType = "ElevationContour"; @@ -1670,7 +1716,7 @@ Material._materialCache.addMaterial(Material.ElevationContourType, { /** * Gets the name of the elevation contour material. - * @type {String} + * @type {"ElevationRamp"} * @readonly */ Material.ElevationRampType = "ElevationRamp"; @@ -1689,7 +1735,7 @@ Material._materialCache.addMaterial(Material.ElevationRampType, { /** * Gets the name of the slope ramp material. - * @type {String} + * @type {"SlopeRamp"} * @readonly */ Material.SlopeRampMaterialType = "SlopeRamp"; @@ -1706,7 +1752,7 @@ Material._materialCache.addMaterial(Material.SlopeRampMaterialType, { /** * Gets the name of the aspect ramp material. - * @type {String} + * @type {"AspectRamp"} * @readonly */ Material.AspectRampMaterialType = "AspectRamp"; @@ -1723,7 +1769,7 @@ Material._materialCache.addMaterial(Material.AspectRampMaterialType, { /** * Gets the name of the elevation band material. - * @type {String} + * @type {"ElevationBand"} * @readonly */ Material.ElevationBandType = "ElevationBand"; diff --git a/packages/engine/tsd-conf.json b/packages/engine/tsd-conf.json index 43cc31afea8..98807f59ae6 100644 --- a/packages/engine/tsd-conf.json +++ b/packages/engine/tsd-conf.json @@ -14,6 +14,7 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ + "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], diff --git a/packages/widgets/tsd-conf.json b/packages/widgets/tsd-conf.json index 135bf4d652b..5ee384a2e0a 100644 --- a/packages/widgets/tsd-conf.json +++ b/packages/widgets/tsd-conf.json @@ -13,6 +13,7 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ + "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], From 863d53d27fcc1845777a5e5033296878c18da217 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 9 Feb 2023 13:55:56 +0800 Subject: [PATCH 450/679] Fix build-ts & build-docs error. --- package.json | 1 + packages/engine/Source/Scene/Material.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ecf93bcc4bf..a875185ce0e 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "istanbul-lib-instrument": "^5.2.0", "jasmine-core": "^4.0.1", "jsdoc": "^3.6.7", + "jsdoc-tsimport-plugin": "^1.0.5", "karma": "^6.3.20", "karma-chrome-launcher": "^3.1.0", "karma-coverage": "^2.0.3", diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index 42625259e77..c0e10f7464c 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -71,11 +71,15 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * @property {FabricComponents} components */ +/** + * @typedef {Function} TranslucentFunction + */ + /** * @typedef {Object} MaterialTemplate A material template object. * @property {Boolean} strict * @property {Fabric} fabric - * @property {Boolean | (material: Material) => Boolean} translucent + * @property {Boolean | TranslucentFunction} translucent */ /** @@ -269,7 +273,7 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * * @param {Object} [options] Object with the following properties: * @param {Boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. - * @param {Boolean|(material: Material) => Boolean} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry + * @param {Boolean | TranslucentFunction} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry * with this material is expected to appear translucent. * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The {@link TextureMinificationFilter} to apply to this material's textures. * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The {@link TextureMagnificationFilter} to apply to this material's textures. @@ -306,6 +310,8 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * } * } * }); + * + * @constructor */ function Material(options) { /** From 9ea3c9ac09f9f70b4129831e9661dbbbbe1035f8 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 9 Feb 2023 14:38:05 +0800 Subject: [PATCH 451/679] Add function types for callback function. --- packages/engine/Source/Scene/Material.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index c0e10f7464c..ae68ed4467b 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -37,7 +37,7 @@ import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js" import WaterMaterial from "../Shaders/Materials/Water.js"; /** - * @typedef {{}} GeneralValue Use for general uniform value, may be a struct in GLSL. + * @typedef {Object.<string, any>} GeneralValue Use for general uniform value, may be a struct in GLSL. * @typedef { Color | * String | * Cartesian2 | @@ -47,7 +47,7 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * Matrix3 | * Matrix4 | * GeneralValue - * } FabricUniformValue + * } FabricUniformValue Fabric material uniform value types. */ /** @@ -72,7 +72,9 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; */ /** - * @typedef {Function} TranslucentFunction + * @callback TranslucentFunction A function determine material is translucent or not. + * @param {Material} material + * @returns {Boolean} */ /** @@ -346,7 +348,7 @@ function Material(options) { /** * When <code>true</code> or a function that returns <code>true</code>, * the geometry is expected to appear translucent. - * @type {Boolean|Function} + * @type {Boolean | TranslucentFunction} * @default undefined */ this.translucent = undefined; @@ -404,7 +406,7 @@ Material._uniformList = {}; * * @example * const material = Cesium.Material.fromType('Color', { - * color : new Cesium.Color(1.0, 0.0, 0.0, 1.0) + * color: new Cesium.Color(1.0, 0.0, 0.0, 1.0) * }); */ Material.fromType = function (type, uniforms) { From 637df4b7c7ba3b7f805f4484e8ddb8a31a79692b Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Thu, 9 Feb 2023 15:30:29 +0800 Subject: [PATCH 452/679] Fixed requestWebgl1 hint error in context --- CHANGES.md | 1 + packages/engine/Source/Renderer/Context.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 80339c4d288..38aab2d19c4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ ##### Fixes :wrench: - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) +- Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) ### 1.102 - 2023-02-01 diff --git a/packages/engine/Source/Renderer/Context.js b/packages/engine/Source/Renderer/Context.js index b346e5fd652..fea81d75c60 100644 --- a/packages/engine/Source/Renderer/Context.js +++ b/packages/engine/Source/Renderer/Context.js @@ -397,7 +397,7 @@ function Context(canvas, options) { * especially for horizon views. * </p> * - * @property {Boolean} [requestWebGl1=false] If true and the browser supports it, use a WebGL 1 rendering context + * @property {Boolean} [requestWebgl1=false] If true and the browser supports it, use a WebGL 1 rendering context * @property {Boolean} [allowTextureFilterAnisotropic=true] If true, use anisotropic filtering during texture sampling * @property {WebGLOptions} [webgl] WebGL options to be passed on to canvas.getContext * @property {Function} [getWebGLStub] A function to create a WebGL stub for testing From 3d8f53819fcf942f2bfbebaedfa65cae45365e2a Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Fri, 10 Feb 2023 16:35:41 +0800 Subject: [PATCH 453/679] Change constructor type to primitive type for: Object, Number, String, Boolean; and standardize the generic syntax of Array and Promise --- .../Sandcastle/gallery/Custom DataSource.html | 4 +- Apps/Sandcastle/gallery/Custom Geocoder.html | 2 +- build.js | 146 +++--- gulpfile.js | 34 +- .../Source/Core/ApproximateTerrainHeights.js | 6 +- .../ArcGISTiledElevationTerrainProvider.js | 40 +- packages/engine/Source/Core/ArcType.js | 8 +- .../Source/Core/ArticulationStageType.js | 2 +- .../engine/Source/Core/AssociativeArray.js | 14 +- .../Source/Core/AttributeCompression.js | 24 +- .../Source/Core/AxisAlignedBoundingBox.js | 4 +- .../Source/Core/BingMapsGeocoderService.js | 12 +- .../engine/Source/Core/BoundingRectangle.js | 34 +- packages/engine/Source/Core/BoundingSphere.js | 50 +- packages/engine/Source/Core/BoxGeometry.js | 16 +- .../engine/Source/Core/BoxOutlineGeometry.js | 16 +- packages/engine/Source/Core/Cartesian2.js | 76 +-- packages/engine/Source/Core/Cartesian3.js | 100 ++-- packages/engine/Source/Core/Cartesian4.js | 88 ++-- packages/engine/Source/Core/Cartographic.js | 38 +- .../Core/CartographicGeocoderService.js | 2 +- .../engine/Source/Core/CatmullRomSpline.js | 20 +- .../Source/Core/CesiumTerrainProvider.js | 66 +-- packages/engine/Source/Core/Check.js | 34 +- packages/engine/Source/Core/CircleGeometry.js | 24 +- .../Source/Core/CircleOutlineGeometry.js | 24 +- packages/engine/Source/Core/Clock.js | 14 +- packages/engine/Source/Core/ClockRange.js | 8 +- packages/engine/Source/Core/ClockStep.js | 8 +- packages/engine/Source/Core/Color.js | 116 ++--- .../Core/ColorGeometryInstanceAttribute.js | 14 +- .../engine/Source/Core/ComponentDatatype.js | 30 +- .../Source/Core/CompressedTextureBuffer.js | 4 +- packages/engine/Source/Core/ConstantSpline.js | 18 +- .../Source/Core/CoplanarPolygonGeometry.js | 20 +- .../Core/CoplanarPolygonOutlineGeometry.js | 16 +- packages/engine/Source/Core/CornerType.js | 8 +- .../engine/Source/Core/CorridorGeometry.js | 26 +- .../Source/Core/CorridorOutlineGeometry.js | 22 +- packages/engine/Source/Core/Credit.js | 14 +- .../engine/Source/Core/CubicRealPolynomial.js | 20 +- packages/engine/Source/Core/CullingVolume.js | 14 +- .../Core/CustomHeightmapTerrainProvider.js | 56 +-- .../engine/Source/Core/CylinderGeometry.js | 22 +- .../Source/Core/CylinderOutlineGeometry.js | 24 +- packages/engine/Source/Core/DefaultProxy.js | 6 +- packages/engine/Source/Core/DeveloperError.js | 8 +- .../Source/Core/DistanceDisplayCondition.js | 24 +- ...splayConditionGeometryInstanceAttribute.js | 8 +- .../Source/Core/DoubleEndedPriorityQueue.js | 10 +- .../Source/Core/EarthOrientationParameters.js | 12 +- .../Core/EarthOrientationParametersSample.js | 20 +- packages/engine/Source/Core/EasingFunction.js | 4 +- .../engine/Source/Core/EllipseGeometry.js | 38 +- .../Source/Core/EllipseOutlineGeometry.js | 28 +- packages/engine/Source/Core/Ellipsoid.js | 40 +- .../engine/Source/Core/EllipsoidGeodesic.js | 10 +- .../engine/Source/Core/EllipsoidGeometry.js | 26 +- .../Source/Core/EllipsoidOutlineGeometry.js | 28 +- .../engine/Source/Core/EllipsoidRhumbLine.js | 16 +- .../Source/Core/EllipsoidTerrainProvider.js | 36 +- .../engine/Source/Core/EllipsoidalOccluder.js | 18 +- .../engine/Source/Core/EncodedCartesian3.js | 10 +- packages/engine/Source/Core/Event.js | 8 +- packages/engine/Source/Core/EventHelper.js | 2 +- .../engine/Source/Core/ExtrapolationType.js | 8 +- .../engine/Source/Core/FeatureDetection.js | 18 +- .../engine/Source/Core/FrustumGeometry.js | 14 +- .../Source/Core/FrustumOutlineGeometry.js | 14 +- packages/engine/Source/Core/Fullscreen.js | 16 +- packages/engine/Source/Core/GeocodeType.js | 6 +- .../engine/Source/Core/GeocoderService.js | 6 +- .../Source/Core/GeographicTilingScheme.js | 32 +- packages/engine/Source/Core/Geometry.js | 8 +- .../engine/Source/Core/GeometryAttribute.js | 6 +- .../engine/Source/Core/GeometryInstance.js | 6 +- .../Source/Core/GeometryInstanceAttribute.js | 10 +- .../engine/Source/Core/GeometryPipeline.js | 22 +- .../Core/GoogleEarthEnterpriseMetadata.js | 44 +- .../Core/GoogleEarthEnterpriseTerrainData.js | 58 +-- .../GoogleEarthEnterpriseTerrainProvider.js | 42 +- .../GoogleEarthEnterpriseTileInformation.js | 28 +- packages/engine/Source/Core/GregorianDate.js | 32 +- .../Source/Core/GroundPolylineGeometry.js | 26 +- .../engine/Source/Core/HeadingPitchRange.js | 12 +- .../engine/Source/Core/HeadingPitchRoll.js | 36 +- packages/engine/Source/Core/Heap.js | 14 +- .../engine/Source/Core/HeightmapEncoding.js | 6 +- .../Source/Core/HeightmapTerrainData.js | 88 ++-- .../Source/Core/HeightmapTessellator.js | 32 +- .../Core/HermitePolynomialApproximation.js | 34 +- packages/engine/Source/Core/HermiteSpline.js | 34 +- packages/engine/Source/Core/HilbertOrder.js | 14 +- packages/engine/Source/Core/Iau2006XysData.js | 26 +- .../engine/Source/Core/Iau2006XysSample.js | 12 +- .../Source/Core/IauOrientationParameters.js | 8 +- packages/engine/Source/Core/IndexDatatype.js | 24 +- .../Source/Core/InterpolationAlgorithm.js | 34 +- .../engine/Source/Core/InterpolationType.js | 2 +- packages/engine/Source/Core/Intersect.js | 8 +- .../engine/Source/Core/IntersectionTests.js | 10 +- .../engine/Source/Core/Intersections2D.js | 46 +- packages/engine/Source/Core/Interval.js | 8 +- packages/engine/Source/Core/Ion.js | 4 +- .../engine/Source/Core/IonGeocoderService.js | 8 +- packages/engine/Source/Core/IonResource.js | 12 +- packages/engine/Source/Core/JulianDate.js | 54 +-- .../Source/Core/KeyboardEventModifier.js | 8 +- .../Core/LagrangePolynomialApproximation.js | 16 +- packages/engine/Source/Core/LeapSecond.js | 4 +- .../engine/Source/Core/LinearApproximation.js | 16 +- packages/engine/Source/Core/LinearSpline.js | 26 +- packages/engine/Source/Core/ManagedArray.js | 12 +- packages/engine/Source/Core/Math.js | 272 +++++------ packages/engine/Source/Core/Matrix2.js | 88 ++-- packages/engine/Source/Core/Matrix3.js | 118 ++--- packages/engine/Source/Core/Matrix4.js | 182 +++---- .../engine/Source/Core/MorphWeightSpline.js | 28 +- packages/engine/Source/Core/MortonOrder.js | 42 +- packages/engine/Source/Core/NearFarScalar.js | 32 +- packages/engine/Source/Core/Occluder.js | 10 +- .../Core/OffsetGeometryInstanceAttribute.js | 10 +- .../Source/Core/OpenCageGeocoderService.js | 36 +- .../engine/Source/Core/OrientedBoundingBox.js | 28 +- .../engine/Source/Core/OrthographicFrustum.js | 46 +- .../Core/OrthographicOffCenterFrustum.js | 42 +- packages/engine/Source/Core/Packable.js | 14 +- .../Source/Core/PackableForInterpolation.js | 22 +- .../Source/Core/PeliasGeocoderService.js | 4 +- .../engine/Source/Core/PerspectiveFrustum.js | 56 +-- .../Core/PerspectiveOffCenterFrustum.js | 42 +- packages/engine/Source/Core/PinBuilder.js | 18 +- packages/engine/Source/Core/PixelFormat.js | 46 +- packages/engine/Source/Core/Plane.js | 8 +- packages/engine/Source/Core/PlaneGeometry.js | 14 +- .../Source/Core/PlaneOutlineGeometry.js | 10 +- .../engine/Source/Core/PolygonGeometry.js | 48 +- .../Source/Core/PolygonGeometryLibrary.js | 8 +- .../Source/Core/PolygonOutlineGeometry.js | 32 +- .../engine/Source/Core/PolygonPipeline.js | 20 +- .../engine/Source/Core/PolylineGeometry.js | 20 +- .../engine/Source/Core/PolylinePipeline.js | 30 +- .../Source/Core/PolylineVolumeGeometry.js | 16 +- .../Core/PolylineVolumeOutlineGeometry.js | 16 +- packages/engine/Source/Core/PrimitiveType.js | 16 +- packages/engine/Source/Core/Proxy.js | 4 +- .../Source/Core/QuadraticRealPolynomial.js | 16 +- .../Source/Core/QuantizedMeshTerrainData.js | 74 +-- .../Source/Core/QuarticRealPolynomial.js | 24 +- packages/engine/Source/Core/Quaternion.js | 84 ++-- .../engine/Source/Core/QuaternionSpline.js | 20 +- packages/engine/Source/Core/Queue.js | 4 +- packages/engine/Source/Core/Ray.js | 2 +- packages/engine/Source/Core/Rectangle.js | 76 +-- .../Source/Core/RectangleCollisionChecker.js | 6 +- .../engine/Source/Core/RectangleGeometry.js | 30 +- .../Source/Core/RectangleOutlineGeometry.js | 22 +- packages/engine/Source/Core/ReferenceFrame.js | 6 +- packages/engine/Source/Core/Request.js | 26 +- .../engine/Source/Core/RequestErrorEvent.js | 14 +- .../engine/Source/Core/RequestScheduler.js | 26 +- packages/engine/Source/Core/RequestState.js | 2 +- packages/engine/Source/Core/RequestType.js | 2 +- packages/engine/Source/Core/Resource.js | 446 +++++++++--------- packages/engine/Source/Core/RuntimeError.js | 8 +- packages/engine/Source/Core/S2Cell.js | 30 +- .../Source/Core/ScreenSpaceEventHandler.js | 14 +- .../Source/Core/ScreenSpaceEventType.js | 32 +- .../Core/ShowGeometryInstanceAttribute.js | 8 +- .../Source/Core/SimplePolylineGeometry.js | 18 +- packages/engine/Source/Core/SphereGeometry.js | 20 +- .../Source/Core/SphereOutlineGeometry.js | 22 +- packages/engine/Source/Core/Spherical.js | 26 +- packages/engine/Source/Core/Spline.js | 24 +- packages/engine/Source/Core/SteppedSpline.js | 28 +- packages/engine/Source/Core/TaskProcessor.js | 20 +- packages/engine/Source/Core/TerrainData.js | 50 +- .../engine/Source/Core/TerrainEncoding.js | 28 +- .../engine/Source/Core/TerrainExaggeration.js | 6 +- packages/engine/Source/Core/TerrainMesh.js | 36 +- .../engine/Source/Core/TerrainProvider.js | 46 +- .../engine/Source/Core/TerrainQuantization.js | 6 +- .../engine/Source/Core/TileAvailability.js | 32 +- .../engine/Source/Core/TileProviderError.js | 30 +- packages/engine/Source/Core/TilingScheme.js | 26 +- packages/engine/Source/Core/TimeConstants.js | 20 +- packages/engine/Source/Core/TimeInterval.js | 46 +- .../Source/Core/TimeIntervalCollection.js | 78 +-- packages/engine/Source/Core/TimeStandard.js | 6 +- packages/engine/Source/Core/Tipsify.js | 20 +- packages/engine/Source/Core/Transforms.js | 4 +- .../Source/Core/TranslationRotationScale.js | 2 +- .../Source/Core/TridiagonalSystemSolver.js | 6 +- packages/engine/Source/Core/TrustedServers.js | 10 +- .../Source/Core/VRTheWorldTerrainProvider.js | 40 +- packages/engine/Source/Core/VertexFormat.js | 14 +- .../engine/Source/Core/VideoSynchronizer.js | 8 +- packages/engine/Source/Core/Visibility.js | 8 +- .../engine/Source/Core/VulkanConstants.js | 2 +- packages/engine/Source/Core/WallGeometry.js | 26 +- .../engine/Source/Core/WallOutlineGeometry.js | 26 +- packages/engine/Source/Core/WebGLConstants.js | 2 +- .../Source/Core/WebMercatorProjection.js | 10 +- .../Source/Core/WebMercatorTilingScheme.js | 32 +- packages/engine/Source/Core/WindingOrder.js | 6 +- .../Source/Core/WireframeIndexGenerator.js | 6 +- .../Source/Core/arrayRemoveDuplicates.js | 8 +- packages/engine/Source/Core/binarySearch.js | 4 +- packages/engine/Source/Core/buildModuleUrl.js | 8 +- .../Source/Core/cancelAnimationFrame.js | 2 +- packages/engine/Source/Core/clone.js | 6 +- packages/engine/Source/Core/combine.js | 8 +- packages/engine/Source/Core/createGuid.js | 2 +- .../engine/Source/Core/createWorldTerrain.js | 6 +- packages/engine/Source/Core/defaultValue.js | 2 +- packages/engine/Source/Core/defer.js | 2 +- packages/engine/Source/Core/defined.js | 2 +- .../engine/Source/Core/deprecationWarning.js | 4 +- packages/engine/Source/Core/destroyObject.js | 4 +- packages/engine/Source/Core/formatError.js | 2 +- packages/engine/Source/Core/getAbsoluteUri.js | 6 +- packages/engine/Source/Core/getBaseUri.js | 6 +- .../engine/Source/Core/getExtensionFromUri.js | 4 +- .../engine/Source/Core/getFilenameFromUri.js | 4 +- .../Source/Core/getImageFromTypedArray.js | 4 +- packages/engine/Source/Core/getImagePixels.js | 4 +- .../Source/Core/getJsonFromTypedArray.js | 6 +- .../Source/Core/getStringFromTypedArray.js | 6 +- packages/engine/Source/Core/getTimestamp.js | 2 +- packages/engine/Source/Core/isBlobUri.js | 4 +- packages/engine/Source/Core/isDataUri.js | 4 +- packages/engine/Source/Core/isLeapYear.js | 4 +- packages/engine/Source/Core/loadKTX2.js | 16 +- packages/engine/Source/Core/mergeSort.js | 2 +- packages/engine/Source/Core/objectToQuery.js | 4 +- packages/engine/Source/Core/oneTimeWarning.js | 4 +- .../Source/Core/parseResponseHeaders.js | 4 +- .../engine/Source/Core/pointInsideTriangle.js | 2 +- packages/engine/Source/Core/queryToObject.js | 4 +- .../Source/Core/requestAnimationFrame.js | 4 +- packages/engine/Source/Core/sampleTerrain.js | 14 +- .../Source/Core/sampleTerrainMostDetailed.js | 2 +- .../Source/Core/scaleToGeodeticSurface.js | 2 +- packages/engine/Source/Core/subdivideArray.js | 2 +- .../engine/Source/Core/writeTextToCanvas.js | 16 +- .../Source/DataSources/BillboardGraphics.js | 2 +- .../Source/DataSources/BillboardVisualizer.js | 4 +- .../Source/DataSources/BoundingSphereState.js | 2 +- .../engine/Source/DataSources/BoxGraphics.js | 2 +- .../Source/DataSources/CallbackProperty.js | 16 +- .../DataSources/Cesium3DTilesetGraphics.js | 2 +- .../DataSources/Cesium3DTilesetVisualizer.js | 4 +- .../CheckerboardMaterialProperty.js | 12 +- .../DataSources/ColorMaterialProperty.js | 10 +- .../DataSources/CompositeEntityCollection.js | 16 +- .../DataSources/CompositeMaterialProperty.js | 10 +- .../DataSources/CompositePositionProperty.js | 4 +- .../Source/DataSources/CompositeProperty.js | 8 +- .../DataSources/ConstantPositionProperty.js | 8 +- .../Source/DataSources/ConstantProperty.js | 10 +- .../Source/DataSources/CorridorGraphics.js | 2 +- .../Source/DataSources/CustomDataSource.js | 10 +- .../Source/DataSources/CylinderGraphics.js | 2 +- .../Source/DataSources/CzmlDataSource.js | 52 +- .../engine/Source/DataSources/DataSource.js | 8 +- .../Source/DataSources/DataSourceClock.js | 4 +- .../DataSources/DataSourceCollection.js | 22 +- .../Source/DataSources/DataSourceDisplay.js | 10 +- .../DataSources/DynamicGeometryUpdater.js | 2 +- .../Source/DataSources/EllipseGraphics.js | 2 +- .../DataSources/EllipsoidGeometryUpdater.js | 4 +- .../Source/DataSources/EllipsoidGraphics.js | 2 +- packages/engine/Source/DataSources/Entity.js | 26 +- .../Source/DataSources/EntityCluster.js | 32 +- .../Source/DataSources/EntityCollection.js | 16 +- .../Source/DataSources/GeoJsonDataSource.js | 54 +-- .../Source/DataSources/GeometryUpdater.js | 44 +- .../Source/DataSources/GeometryVisualizer.js | 4 +- .../Source/DataSources/GpxDataSource.js | 46 +- .../DataSources/GridMaterialProperty.js | 14 +- .../DataSources/GroundGeometryUpdater.js | 10 +- .../DataSources/ImageMaterialProperty.js | 16 +- .../Source/DataSources/KmlDataSource.js | 64 +-- packages/engine/Source/DataSources/KmlTour.js | 6 +- .../engine/Source/DataSources/KmlTourFlyTo.js | 12 +- .../engine/Source/DataSources/KmlTourWait.js | 4 +- .../Source/DataSources/LabelGraphics.js | 2 +- .../Source/DataSources/LabelVisualizer.js | 4 +- .../Source/DataSources/MaterialProperty.js | 10 +- .../Source/DataSources/ModelGraphics.js | 2 +- .../Source/DataSources/ModelVisualizer.js | 4 +- .../DataSources/NodeTransformationProperty.js | 6 +- .../engine/Source/DataSources/PathGraphics.js | 2 +- .../Source/DataSources/PathVisualizer.js | 4 +- .../Source/DataSources/PlaneGraphics.js | 2 +- .../Source/DataSources/PointGraphics.js | 2 +- .../Source/DataSources/PointVisualizer.js | 4 +- .../Source/DataSources/PolygonGraphics.js | 6 +- .../PolylineArrowMaterialProperty.js | 10 +- .../PolylineDashMaterialProperty.js | 16 +- .../DataSources/PolylineGeometryUpdater.js | 26 +- .../PolylineGlowMaterialProperty.js | 16 +- .../Source/DataSources/PolylineGraphics.js | 4 +- .../PolylineOutlineMaterialProperty.js | 14 +- .../Source/DataSources/PolylineVisualizer.js | 4 +- .../DataSources/PolylineVolumeGraphics.js | 6 +- .../Source/DataSources/PositionProperty.js | 4 +- .../DataSources/PositionPropertyArray.js | 4 +- .../engine/Source/DataSources/Property.js | 8 +- .../Source/DataSources/PropertyArray.js | 4 +- .../engine/Source/DataSources/PropertyBag.js | 20 +- .../Source/DataSources/RectangleGraphics.js | 2 +- .../Source/DataSources/ReferenceProperty.js | 20 +- .../engine/Source/DataSources/Rotation.js | 28 +- .../DataSources/SampledPositionProperty.js | 22 +- .../Source/DataSources/SampledProperty.js | 24 +- .../DataSources/StripeMaterialProperty.js | 16 +- .../Source/DataSources/StripeOrientation.js | 6 +- .../DataSources/TerrainOffsetProperty.js | 2 +- .../TimeIntervalCollectionPositionProperty.js | 6 +- .../TimeIntervalCollectionProperty.js | 8 +- .../VelocityOrientationProperty.js | 4 +- .../DataSources/VelocityVectorProperty.js | 8 +- .../engine/Source/DataSources/Visualizer.js | 4 +- .../engine/Source/DataSources/WallGraphics.js | 8 +- .../engine/Source/DataSources/exportKml.js | 16 +- packages/engine/Source/Renderer/Buffer.js | 8 +- .../engine/Source/Renderer/ClearCommand.js | 6 +- .../engine/Source/Renderer/ComputeCommand.js | 6 +- packages/engine/Source/Renderer/Context.js | 92 ++-- .../engine/Source/Renderer/ContextLimits.js | 44 +- .../engine/Source/Renderer/CubeMapFace.js | 22 +- .../engine/Source/Renderer/DrawCommand.js | 30 +- .../engine/Source/Renderer/Framebuffer.js | 8 +- .../Source/Renderer/FramebufferManager.js | 18 +- .../Source/Renderer/MultisampleFramebuffer.js | 2 +- packages/engine/Source/Renderer/PassState.js | 4 +- .../engine/Source/Renderer/PixelDatatype.js | 2 +- .../engine/Source/Renderer/RenderState.js | 2 +- .../engine/Source/Renderer/ShaderBuilder.js | 48 +- .../engine/Source/Renderer/ShaderCache.js | 16 +- .../Source/Renderer/ShaderDestination.js | 4 +- .../engine/Source/Renderer/ShaderFunction.js | 6 +- .../engine/Source/Renderer/ShaderSource.js | 16 +- .../engine/Source/Renderer/ShaderStruct.js | 8 +- packages/engine/Source/Renderer/Texture.js | 36 +- .../Renderer/TextureMagnificationFilter.js | 8 +- .../Renderer/TextureMinificationFilter.js | 16 +- .../engine/Source/Renderer/UniformState.js | 28 +- .../engine/Source/Renderer/VertexArray.js | 4 +- .../engine/Source/Renderer/createUniform.js | 24 +- .../Source/Renderer/createUniformArray.js | 24 +- .../Source/Renderer/freezeRenderState.js | 4 +- .../engine/Source/Renderer/loadCubeMap.js | 6 +- packages/engine/Source/Scene/AlphaMode.js | 8 +- packages/engine/Source/Scene/Appearance.js | 28 +- .../Scene/ArcGisMapServerImageryProvider.js | 86 ++-- packages/engine/Source/Scene/AttributeType.js | 22 +- packages/engine/Source/Scene/AutoExposure.js | 12 +- packages/engine/Source/Scene/Axis.js | 12 +- packages/engine/Source/Scene/B3dmParser.js | 4 +- packages/engine/Source/Scene/BatchTable.js | 26 +- .../Source/Scene/BatchTableHierarchy.js | 44 +- packages/engine/Source/Scene/BatchTexture.js | 28 +- packages/engine/Source/Scene/Billboard.js | 34 +- .../Source/Scene/BillboardCollection.js | 26 +- .../Source/Scene/BingMapsImageryProvider.js | 80 ++-- packages/engine/Source/Scene/BingMapsStyle.js | 22 +- packages/engine/Source/Scene/BlendEquation.js | 12 +- packages/engine/Source/Scene/BlendFunction.js | 32 +- packages/engine/Source/Scene/BlendOption.js | 8 +- packages/engine/Source/Scene/BlendingState.js | 8 +- packages/engine/Source/Scene/BufferLoader.js | 10 +- packages/engine/Source/Scene/Camera.js | 112 ++--- .../Source/Scene/CameraEventAggregator.js | 37 +- .../engine/Source/Scene/CameraEventType.js | 12 +- .../Source/Scene/Cesium3DContentGroup.js | 2 +- packages/engine/Source/Scene/Cesium3DTile.js | 48 +- .../Source/Scene/Cesium3DTileBatchTable.js | 2 +- .../Scene/Cesium3DTileColorBlendMode.js | 8 +- .../Source/Scene/Cesium3DTileContent.js | 30 +- .../Source/Scene/Cesium3DTileContentType.js | 34 +- .../Source/Scene/Cesium3DTileFeature.js | 32 +- .../Scene/Cesium3DTileOptimizationHint.js | 2 +- .../Source/Scene/Cesium3DTileOptimizations.js | 2 +- .../Source/Scene/Cesium3DTilePassState.js | 2 +- .../Source/Scene/Cesium3DTilePointFeature.js | 46 +- .../engine/Source/Scene/Cesium3DTileRefine.js | 6 +- .../engine/Source/Scene/Cesium3DTileStyle.js | 34 +- .../Scene/Cesium3DTilesVoxelProvider.js | 4 +- .../engine/Source/Scene/Cesium3DTileset.js | 222 ++++----- .../Source/Scene/Cesium3DTilesetHeatmap.js | 8 +- .../Source/Scene/Cesium3DTilesetMetadata.js | 10 +- packages/engine/Source/Scene/CircleEmitter.js | 4 +- .../Source/Scene/ClassificationPrimitive.js | 50 +- .../engine/Source/Scene/ClassificationType.js | 8 +- packages/engine/Source/Scene/ClippingPlane.js | 4 +- .../Source/Scene/ClippingPlaneCollection.js | 34 +- .../engine/Source/Scene/CloudCollection.js | 32 +- packages/engine/Source/Scene/CloudType.js | 6 +- .../engine/Source/Scene/ColorBlendMode.js | 2 +- .../Source/Scene/ConditionsExpression.js | 22 +- packages/engine/Source/Scene/ConeEmitter.js | 4 +- .../engine/Source/Scene/ContentMetadata.js | 32 +- packages/engine/Source/Scene/CreditDisplay.js | 4 +- packages/engine/Source/Scene/CullFace.js | 8 +- packages/engine/Source/Scene/CumulusCloud.js | 6 +- .../engine/Source/Scene/DebugAppearance.js | 34 +- .../Source/Scene/DebugCameraPrimitive.js | 12 +- .../Source/Scene/DebugModelMatrixPrimitive.js | 16 +- packages/engine/Source/Scene/DepthFunction.js | 18 +- .../DeviceOrientationCameraController.js | 2 +- .../engine/Source/Scene/DirectionalLight.js | 6 +- .../Scene/DiscardEmptyTileImagePolicy.js | 4 +- .../Scene/DiscardMissingTileImagePolicy.js | 10 +- packages/engine/Source/Scene/DracoLoader.js | 8 +- .../engine/Source/Scene/EllipsoidPrimitive.js | 14 +- .../Scene/EllipsoidSurfaceAppearance.js | 38 +- packages/engine/Source/Scene/Expression.js | 28 +- packages/engine/Source/Scene/Fog.js | 10 +- .../engine/Source/Scene/FrameRateMonitor.js | 28 +- packages/engine/Source/Scene/FrameState.js | 72 +-- .../engine/Source/Scene/FrustumCommands.js | 4 +- .../Source/Scene/GetFeatureInfoFormat.js | 4 +- packages/engine/Source/Scene/Globe.js | 68 +-- .../engine/Source/Scene/GlobeSurfaceTile.js | 2 +- .../Source/Scene/GlobeSurfaceTileProvider.js | 12 +- .../engine/Source/Scene/GlobeTranslucency.js | 6 +- .../Source/Scene/GltfBufferViewLoader.js | 14 +- .../engine/Source/Scene/GltfDracoLoader.js | 16 +- .../engine/Source/Scene/GltfImageLoader.js | 14 +- .../Source/Scene/GltfIndexBufferLoader.js | 22 +- .../engine/Source/Scene/GltfJsonLoader.js | 14 +- packages/engine/Source/Scene/GltfLoader.js | 48 +- .../engine/Source/Scene/GltfLoaderUtil.js | 22 +- .../Source/Scene/GltfPipeline/addBuffer.js | 4 +- .../Source/Scene/GltfPipeline/addDefaults.js | 4 +- .../GltfPipeline/addExtensionsRequired.js | 4 +- .../Scene/GltfPipeline/addExtensionsUsed.js | 4 +- .../Scene/GltfPipeline/addPipelineExtras.js | 4 +- .../Source/Scene/GltfPipeline/addToArray.js | 4 +- .../Scene/GltfPipeline/findAccessorMinMax.js | 4 +- .../GltfPipeline/forEachTextureInMaterial.js | 6 +- .../GltfPipeline/getAccessorByteStride.js | 6 +- .../Scene/GltfPipeline/getComponentReader.js | 10 +- .../GltfPipeline/moveTechniqueRenderStates.js | 4 +- .../GltfPipeline/moveTechniquesToExtension.js | 4 +- .../GltfPipeline/numberOfComponentsForType.js | 4 +- .../Source/Scene/GltfPipeline/parseGlb.js | 2 +- .../Scene/GltfPipeline/readAccessorPacked.js | 4 +- .../Scene/GltfPipeline/removeExtension.js | 4 +- .../GltfPipeline/removeExtensionsRequired.js | 4 +- .../GltfPipeline/removeExtensionsUsed.js | 4 +- .../GltfPipeline/removePipelineExtras.js | 4 +- .../GltfPipeline/removeUnusedElements.js | 4 +- .../updateAccessorComponentTypes.js | 4 +- .../Scene/GltfPipeline/updateVersion.js | 8 +- .../Scene/GltfPipeline/usesExtension.js | 6 +- .../Scene/GltfStructuralMetadataLoader.js | 18 +- .../engine/Source/Scene/GltfTextureLoader.js | 16 +- .../Source/Scene/GltfVertexBufferLoader.js | 26 +- .../GoogleEarthEnterpriseImageryProvider.js | 66 +-- .../GoogleEarthEnterpriseMapsProvider.js | 76 +-- .../Source/Scene/GridImageryProvider.js | 66 +-- .../Source/Scene/GroundPolylinePrimitive.js | 40 +- .../engine/Source/Scene/GroundPrimitive.js | 52 +- packages/engine/Source/Scene/GroupMetadata.js | 34 +- .../engine/Source/Scene/HeightReference.js | 8 +- .../engine/Source/Scene/HorizontalOrigin.js | 8 +- .../engine/Source/Scene/I3SDataProvider.js | 26 +- packages/engine/Source/Scene/I3SFeature.js | 2 +- packages/engine/Source/Scene/I3SField.js | 10 +- packages/engine/Source/Scene/I3SGeometry.js | 16 +- packages/engine/Source/Scene/I3SLayer.js | 14 +- packages/engine/Source/Scene/I3SNode.js | 12 +- packages/engine/Source/Scene/I3dmParser.js | 4 +- .../engine/Source/Scene/ImageBasedLighting.js | 22 +- packages/engine/Source/Scene/ImageryLayer.js | 78 +-- .../Source/Scene/ImageryLayerCollection.js | 22 +- .../Source/Scene/ImageryLayerFeatureInfo.js | 8 +- .../engine/Source/Scene/ImageryProvider.js | 60 +-- .../Source/Scene/Implicit3DTileContent.js | 110 ++--- .../Scene/ImplicitAvailabilityBitstream.js | 20 +- .../Source/Scene/ImplicitMetadataView.js | 32 +- .../Source/Scene/ImplicitSubdivisionScheme.js | 8 +- .../engine/Source/Scene/ImplicitSubtree.js | 96 ++-- .../Source/Scene/ImplicitSubtreeCache.js | 12 +- .../Source/Scene/ImplicitSubtreeMetadata.js | 32 +- .../Source/Scene/ImplicitTileCoordinates.js | 54 +-- .../engine/Source/Scene/ImplicitTileset.js | 20 +- .../Source/Scene/InstanceAttributeSemantic.js | 10 +- .../engine/Source/Scene/IonImageryProvider.js | 64 +-- .../Source/Scene/IonWorldImageryStyle.js | 8 +- .../engine/Source/Scene/JsonMetadataTable.js | 22 +- packages/engine/Source/Scene/KeyframeNode.js | 2 +- packages/engine/Source/Scene/Label.js | 28 +- .../engine/Source/Scene/LabelCollection.js | 22 +- packages/engine/Source/Scene/LabelStyle.js | 8 +- packages/engine/Source/Scene/Light.js | 2 +- packages/engine/Source/Scene/MapMode2D.js | 6 +- .../Source/Scene/MapboxImageryProvider.js | 74 +-- .../Scene/MapboxStyleImageryProvider.js | 78 +-- packages/engine/Source/Scene/Material.js | 54 +-- .../engine/Source/Scene/MaterialAppearance.js | 42 +- packages/engine/Source/Scene/Megatexture.js | 30 +- packages/engine/Source/Scene/MetadataClass.js | 32 +- .../Source/Scene/MetadataClassProperty.js | 82 ++-- .../Source/Scene/MetadataComponentType.js | 42 +- .../engine/Source/Scene/MetadataEntity.js | 62 +-- packages/engine/Source/Scene/MetadataEnum.js | 26 +- .../engine/Source/Scene/MetadataEnumValue.js | 20 +- .../engine/Source/Scene/MetadataSchema.js | 32 +- .../Source/Scene/MetadataSchemaLoader.js | 12 +- .../engine/Source/Scene/MetadataSemantic.js | 34 +- packages/engine/Source/Scene/MetadataTable.js | 48 +- .../Source/Scene/MetadataTableProperty.js | 18 +- packages/engine/Source/Scene/MetadataType.js | 30 +- .../engine/Source/Scene/Model/B3dmLoader.js | 26 +- .../Model/ClassificationModelDrawCommand.js | 6 +- .../engine/Source/Scene/Model/CustomShader.js | 36 +- .../Source/Scene/Model/CustomShaderMode.js | 8 +- .../Model/CustomShaderTranslucencyMode.js | 8 +- .../Source/Scene/Model/GeoJsonLoader.js | 10 +- .../engine/Source/Scene/Model/I3dmLoader.js | 22 +- .../Source/Scene/Model/LightingModel.js | 6 +- .../Scene/Model/MaterialPipelineStage.js | 12 +- .../Scene/Model/MetadataPipelineStage.js | 51 +- packages/engine/Source/Scene/Model/Model.js | 170 +++---- .../Source/Scene/Model/ModelAlphaOptions.js | 2 +- .../Source/Scene/Model/ModelAnimation.js | 22 +- .../Scene/Model/ModelAnimationChannel.js | 4 +- .../Scene/Model/ModelAnimationCollection.js | 36 +- .../Source/Scene/Model/ModelArticulation.js | 8 +- .../Scene/Model/ModelArticulationStage.js | 10 +- .../Source/Scene/Model/ModelDrawCommand.js | 6 +- .../engine/Source/Scene/Model/ModelFeature.js | 24 +- .../Source/Scene/Model/ModelFeatureTable.js | 10 +- .../Scene/Model/ModelLightingOptions.js | 2 +- .../engine/Source/Scene/Model/ModelNode.js | 6 +- .../Scene/Model/ModelRenderResources.js | 8 +- .../Source/Scene/Model/ModelRuntimeNode.js | 14 +- .../Scene/Model/ModelRuntimePrimitive.js | 6 +- .../Source/Scene/Model/ModelSceneGraph.js | 22 +- .../Model/ModelSilhouettePipelineStage.js | 2 +- .../engine/Source/Scene/Model/ModelSkin.js | 2 +- .../Source/Scene/Model/ModelStatistics.js | 14 +- .../engine/Source/Scene/Model/ModelType.js | 16 +- .../engine/Source/Scene/Model/ModelUtility.js | 20 +- .../Source/Scene/Model/NodeRenderResources.js | 14 +- .../engine/Source/Scene/Model/PntsLoader.js | 12 +- .../Model/PointCloudStylingPipelineStage.js | 2 +- .../Scene/Model/PrimitiveOutlineGenerator.js | 56 +-- .../Scene/Model/PrimitiveRenderResources.js | 20 +- .../Source/Scene/Model/StyleCommandsNeeded.js | 2 +- .../Source/Scene/Model/TextureManager.js | 6 +- .../Source/Scene/Model/TextureUniform.js | 12 +- .../engine/Source/Scene/Model/UniformType.js | 34 +- .../engine/Source/Scene/Model/VaryingType.js | 16 +- .../engine/Source/Scene/ModelAnimationLoop.js | 8 +- .../engine/Source/Scene/ModelComponents.js | 122 ++--- packages/engine/Source/Scene/Moon.js | 16 +- .../Source/Scene/Multiple3DTileContent.js | 28 +- .../Source/Scene/NeverTileDiscardPolicy.js | 4 +- packages/engine/Source/Scene/OIT.js | 18 +- .../Scene/OctahedralProjectedCubeMap.js | 8 +- .../Scene/OpenStreetMapImageryProvider.js | 12 +- .../Scene/OrderedGroundPrimitiveCollection.js | 18 +- packages/engine/Source/Scene/Particle.js | 26 +- packages/engine/Source/Scene/ParticleBurst.js | 16 +- .../engine/Source/Scene/ParticleSystem.js | 72 +-- .../Scene/PerInstanceColorAppearance.js | 36 +- .../engine/Source/Scene/PerformanceDisplay.js | 4 +- packages/engine/Source/Scene/PntsParser.js | 2 +- .../Source/Scene/PointCloudEyeDomeLighting.js | 2 +- .../engine/Source/Scene/PointCloudShading.js | 40 +- .../engine/Source/Scene/PointPrimitive.js | 12 +- .../Source/Scene/PointPrimitiveCollection.js | 22 +- packages/engine/Source/Scene/Polyline.js | 18 +- .../engine/Source/Scene/PolylineCollection.js | 22 +- .../Source/Scene/PolylineColorAppearance.js | 26 +- .../Scene/PolylineMaterialAppearance.js | 26 +- .../engine/Source/Scene/PostProcessStage.js | 30 +- .../Scene/PostProcessStageCollection.js | 20 +- .../Source/Scene/PostProcessStageComposite.js | 26 +- .../Source/Scene/PostProcessStageLibrary.js | 16 +- .../Scene/PostProcessStageSampleMode.js | 6 +- .../Scene/PostProcessStageTextureCache.js | 8 +- packages/engine/Source/Scene/Primitive.js | 44 +- .../Source/Scene/PrimitiveCollection.js | 40 +- .../engine/Source/Scene/PrimitiveLoadPlan.js | 12 +- .../engine/Source/Scene/PropertyAttribute.js | 18 +- .../Source/Scene/PropertyAttributeProperty.js | 12 +- packages/engine/Source/Scene/PropertyTable.js | 68 +-- .../engine/Source/Scene/PropertyTexture.js | 18 +- .../Source/Scene/PropertyTextureProperty.js | 14 +- .../engine/Source/Scene/QuadtreePrimitive.js | 18 +- packages/engine/Source/Scene/QuadtreeTile.js | 22 +- .../Source/Scene/QuadtreeTileLoadState.js | 2 +- .../Source/Scene/QuadtreeTileProvider.js | 12 +- packages/engine/Source/Scene/ResourceCache.js | 78 +-- .../engine/Source/Scene/ResourceCacheKey.js | 84 ++-- .../Source/Scene/ResourceCacheStatistics.js | 4 +- .../engine/Source/Scene/ResourceLoader.js | 10 +- .../Source/Scene/ResourceLoaderState.js | 10 +- packages/engine/Source/Scene/SDFSettings.js | 8 +- packages/engine/Source/Scene/Scene.js | 152 +++--- packages/engine/Source/Scene/SceneMode.js | 12 +- .../engine/Source/Scene/SceneTransitioner.js | 2 +- .../Scene/ScreenSpaceCameraController.js | 45 +- packages/engine/Source/Scene/ShadowMap.js | 44 +- packages/engine/Source/Scene/ShadowMode.js | 10 +- .../Source/Scene/ShadowVolumeAppearance.js | 34 +- .../Source/Scene/SingleTileImageryProvider.js | 62 +-- packages/engine/Source/Scene/SkyAtmosphere.js | 20 +- packages/engine/Source/Scene/SkyBox.js | 10 +- packages/engine/Source/Scene/SpatialNode.js | 30 +- packages/engine/Source/Scene/SphereEmitter.js | 4 +- .../engine/Source/Scene/SplitDirection.js | 8 +- packages/engine/Source/Scene/Splitter.js | 4 +- .../engine/Source/Scene/StencilFunction.js | 18 +- .../engine/Source/Scene/StencilOperation.js | 18 +- .../engine/Source/Scene/StructuralMetadata.js | 22 +- .../engine/Source/Scene/StyleExpression.js | 16 +- packages/engine/Source/Scene/Sun.js | 6 +- packages/engine/Source/Scene/SunLight.js | 6 +- .../Source/Scene/SupportedImageFormats.js | 6 +- packages/engine/Source/Scene/TextureAtlas.js | 32 +- .../engine/Source/Scene/TileBoundingRegion.js | 12 +- .../engine/Source/Scene/TileBoundingS2Cell.js | 12 +- .../engine/Source/Scene/TileBoundingSphere.js | 10 +- .../engine/Source/Scene/TileBoundingVolume.js | 4 +- .../Scene/TileCoordinatesImageryProvider.js | 60 +-- .../engine/Source/Scene/TileDiscardPolicy.js | 4 +- packages/engine/Source/Scene/TileImagery.js | 6 +- .../Scene/TileMapServiceImageryProvider.js | 18 +- packages/engine/Source/Scene/TileMetadata.js | 32 +- .../Source/Scene/TileOrientedBoundingBox.js | 4 +- .../Source/Scene/TileReplacementQueue.js | 2 +- .../Source/Scene/TileSelectionResult.js | 2 +- .../engine/Source/Scene/TilesetMetadata.js | 30 +- .../engine/Source/Scene/TimeDynamicImagery.js | 16 +- .../Source/Scene/TimeDynamicPointCloud.js | 18 +- packages/engine/Source/Scene/Tonemapper.js | 10 +- .../Scene/TranslucentTileClassification.js | 2 +- .../engine/Source/Scene/TweenCollection.js | 62 +-- .../Scene/UrlTemplateImageryProvider.js | 94 ++-- .../engine/Source/Scene/Vector3DTileBatch.js | 14 +- .../Scene/Vector3DTileClampedPolylines.js | 18 +- .../Source/Scene/Vector3DTileGeometry.js | 16 +- .../engine/Source/Scene/Vector3DTilePoints.js | 14 +- .../Source/Scene/Vector3DTilePolygons.js | 20 +- .../Source/Scene/Vector3DTilePolylines.js | 18 +- .../Source/Scene/Vector3DTilePrimitive.js | 16 +- .../Source/Scene/VertexAttributeSemantic.js | 30 +- .../engine/Source/Scene/VerticalOrigin.js | 10 +- packages/engine/Source/Scene/ViewportQuad.js | 4 +- packages/engine/Source/Scene/VoxelBoxShape.js | 14 +- packages/engine/Source/Scene/VoxelContent.js | 6 +- .../engine/Source/Scene/VoxelCylinderShape.js | 38 +- .../Source/Scene/VoxelEllipsoidShape.js | 22 +- .../engine/Source/Scene/VoxelPrimitive.js | 82 ++-- packages/engine/Source/Scene/VoxelProvider.js | 26 +- .../Source/Scene/VoxelRenderResources.js | 2 +- packages/engine/Source/Scene/VoxelShape.js | 14 +- .../engine/Source/Scene/VoxelShapeType.js | 8 +- .../engine/Source/Scene/VoxelTraversal.js | 70 +-- .../Scene/WebMapServiceImageryProvider.js | 98 ++-- .../Scene/WebMapTileServiceImageryProvider.js | 86 ++-- .../Scene/createBillboardPointCallback.js | 10 +- .../Scene/createElevationBandMaterial.js | 10 +- .../engine/Source/Scene/createOsmBuildings.js | 6 +- .../Scene/createTangentSpaceDebugPrimitive.js | 4 +- .../engine/Source/Scene/createWorldImagery.js | 2 +- .../Source/Scene/findContentMetadata.js | 2 +- .../engine/Source/Scene/findGroupMetadata.js | 2 +- .../engine/Source/Scene/findTileMetadata.js | 2 +- .../Source/Scene/getClipAndStyleCode.js | 8 +- .../Source/Scene/getClippingFunction.js | 2 +- packages/engine/Source/Scene/hasExtension.js | 6 +- .../engine/Source/Scene/parseBatchTable.js | 28 +- .../Scene/parseBoundingVolumeSemantics.js | 14 +- .../Scene/parseFeatureMetadataLegacy.js | 8 +- .../Source/Scene/parseStructuralMetadata.js | 8 +- .../Source/Scene/preprocess3DTileContent.js | 4 +- .../Source/Scene/processVoxelProperties.js | 14 +- packages/engine/Source/Widget/CesiumWidget.js | 46 +- .../Workers/cesiumWorkerBootstrapper.js | 36 +- .../WorkersES6/createTaskProcessorWorker.js | 6 +- .../Specs/Scene/ImageryLayerCollectionSpec.js | 2 +- .../Scene/ImplicitTileCoordinatesSpec.js | 18 +- .../widgets/Source/Animation/Animation.js | 4 +- .../Source/Animation/AnimationViewModel.js | 22 +- .../Source/BaseLayerPicker/BaseLayerPicker.js | 6 +- .../BaseLayerPickerViewModel.js | 8 +- .../BaseLayerPicker/ProviderViewModel.js | 18 +- .../Cesium3DTilesInspector.js | 4 +- .../Cesium3DTilesInspectorViewModel.js | 106 ++--- .../Source/CesiumInspector/CesiumInspector.js | 4 +- .../CesiumInspectorViewModel.js | 50 +- packages/widgets/Source/ClockViewModel.js | 8 +- packages/widgets/Source/Command.js | 2 +- .../FullscreenButton/FullscreenButton.js | 6 +- .../FullscreenButtonViewModel.js | 12 +- packages/widgets/Source/Geocoder/Geocoder.js | 10 +- .../Source/Geocoder/GeocoderViewModel.js | 16 +- .../widgets/Source/HomeButton/HomeButton.js | 6 +- .../Source/HomeButton/HomeButtonViewModel.js | 6 +- packages/widgets/Source/InfoBox/InfoBox.js | 4 +- .../Source/InfoBox/InfoBoxViewModel.js | 18 +- packages/widgets/Source/InspectorShared.js | 30 +- .../NavigationHelpButton.js | 8 +- .../NavigationHelpButtonViewModel.js | 4 +- .../PerformanceWatchdog.js | 8 +- .../PerformanceWatchdogViewModel.js | 10 +- .../ProjectionPicker/ProjectionPicker.js | 4 +- .../ProjectionPickerViewModel.js | 10 +- .../Source/SceneModePicker/SceneModePicker.js | 6 +- .../SceneModePickerViewModel.js | 16 +- .../SelectionIndicator/SelectionIndicator.js | 4 +- .../SelectionIndicatorViewModel.js | 4 +- packages/widgets/Source/Timeline/Timeline.js | 2 +- .../widgets/Source/ToggleButtonViewModel.js | 10 +- packages/widgets/Source/VRButton/VRButton.js | 6 +- .../Source/VRButton/VRButtonViewModel.js | 10 +- packages/widgets/Source/Viewer/Viewer.js | 96 ++-- .../Source/Viewer/viewerDragDropMixin.js | 16 +- .../Viewer/viewerPerformanceWatchdogMixin.js | 4 +- .../Source/VoxelInspector/VoxelInspector.js | 4 +- .../VoxelInspector/VoxelInspectorViewModel.js | 2 +- packages/widgets/Source/createCommand.js | 2 +- .../widgets/Source/subscribeAndEvaluate.js | 8 +- 731 files changed, 7870 insertions(+), 7859 deletions(-) diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 991d384e2c3..c4badac1fb3 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -41,7 +41,7 @@ * @alias WebGLGlobeDataSource * @constructor * - * @param {String} [name] The name of this data source. If undefined, a name + * @param {string} [name] The name of this data source. If undefined, a name * will be derived from the url. * * @example @@ -144,7 +144,7 @@ /** * Gets the array of series names. * @memberof WebGLGlobeDataSource.prototype - * @type {String[]} + * @type {} */ seriesNames: { get: function () { diff --git a/Apps/Sandcastle/gallery/Custom Geocoder.html b/Apps/Sandcastle/gallery/Custom Geocoder.html index 2804297cf80..11a11fd4844 100644 --- a/Apps/Sandcastle/gallery/Custom Geocoder.html +++ b/Apps/Sandcastle/gallery/Custom Geocoder.html @@ -55,7 +55,7 @@ /** * The function called to geocode using this geocoder service. * - * @param {String} input The query to be sent to the geocoder service + * @param {string} input The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ OpenStreetMapNominatimGeocoder.prototype.geocode = function (input) { diff --git a/build.js b/build.js index f14aed2b94b..7201aac66fd 100644 --- a/build.js +++ b/build.js @@ -144,24 +144,24 @@ export async function getFilesFromWorkspaceGlobs(workspaceGlobs) { } /** - * @typedef {Object} CesiumBundles - * @property {Object} esmBundle The ESM bundle. - * @property {Object} iifeBundle The IIFE bundle, for use in browsers. - * @property {Object} nodeBundle The CommonJS bundle, for use in NodeJS. + * @typedef {object} CesiumBundles + * @property {object} esmBundle The ESM bundle. + * @property {object} iifeBundle The IIFE bundle, for use in browsers. + * @property {object} nodeBundle The CommonJS bundle, for use in NodeJS. */ /** * Bundles all individual modules, optionally minifying and stripping out debug pragmas. - * @param {Object} options - * @param {String} options.path Directory where build artifacts are output - * @param {Boolean} [options.minify=false] true if the output should be minified - * @param {Boolean} [options.removePragmas=false] true if the output should have debug pragmas stripped out - * @param {Boolean} [options.sourcemap=false] true if an external sourcemap should be generated - * @param {Boolean} [options.iife=false] true if an IIFE style module should be built - * @param {Boolean} [options.node=false] true if a CJS style node module should be built - * @param {Boolean} [options.incremental=false] true if build output should be cached for repeated builds - * @param {Boolean} [options.write=true] true if build output should be written to disk. If false, the files that would have been written as in-memory buffers - * @returns {Promise.<CesiumBundles>} + * @param {object} options + * @param {string} options.path Directory where build artifacts are output + * @param {boolean} [options.minify=false] true if the output should be minified + * @param {boolean} [options.removePragmas=false] true if the output should have debug pragmas stripped out + * @param {boolean} [options.sourcemap=false] true if an external sourcemap should be generated + * @param {boolean} [options.iife=false] true if an IIFE style module should be built + * @param {boolean} [options.node=false] true if a CJS style node module should be built + * @param {boolean} [options.incremental=false] true if build output should be cached for repeated builds + * @param {boolean} [options.write=true] true if build output should be written to disk. If false, the files that would have been written as in-memory buffers + * @returns {Promise<CesiumBundles>} */ export async function bundleCesiumJs(options) { const buildConfig = defaultESBuildOptions(); @@ -245,9 +245,9 @@ const workspaceSourceFiles = { /** * Generates export declaration from a file from a workspace. * - * @param {String} workspace The workspace the file belongs to. - * @param {String} file The file. - * @returns {String} The export declaration. + * @param {string} workspace The workspace the file belongs to. + * @param {string} file The file. + * @returns {string} The export declaration. */ function generateDeclaration(workspace, file) { let assignmentName = path.basename(file, path.extname(file)); @@ -319,11 +319,11 @@ function rollupWarning(message) { } /** - * @param {Object} options + * @param {object} options * @param {boolean} [options.minify=false] true if the worker output should be minified * @param {boolean} [options.removePragmas=false] true if debug pragma should be removed * @param {boolean} [options.sourcemap=false] true if an external sourcemap should be generated - * @param {String} options.path output directory + * @param {string} options.path output directory */ export async function bundleCombinedWorkers(options) { // Bundle non ES6 workers. @@ -386,15 +386,15 @@ export async function bundleCombinedWorkers(options) { /** * Bundles the workers and outputs the result to the specified directory - * @param {Object} options + * @param {object} options * @param {boolean} [options.minify=false] true if the worker output should be minified * @param {boolean} [options.removePragmas=false] true if debug pragma should be removed * @param {boolean} [options.sourcemap=false] true if an external sourcemap should be generated - * @param {Array.<String>} options.input The worker globs. - * @param {Array.<String>} options.inputES6 The ES6 worker globs. - * @param {String} options.path output directory - * @param {String} options.copyrightHeader The copyright header to add to worker bundles - * @returns {Promise.<*>} + * @param {string[]} options.input The worker globs. + * @param {string[]} options.inputES6 The ES6 worker globs. + * @param {string} options.path output directory + * @param {string} options.copyrightHeader The copyright header to add to worker bundles + * @returns {Promise<any>} */ export async function bundleWorkers(options) { // Copy existing workers @@ -621,8 +621,8 @@ const externalResolvePlugin = { /** * Creates a template html file in the Sandcastle app listing the gallery of demos - * @param {Boolean} [noDevelopmentGallery=false] true if the development gallery should not be included in the list - * @returns {Promise.<*>} + * @param {boolean} [noDevelopmentGallery=false] true if the development gallery should not be included in the list + * @returns {Promise<any>} */ export async function createGalleryList(noDevelopmentGallery) { const demoObjects = []; @@ -721,10 +721,10 @@ const has_new_gallery_demos = ${newDemos.length > 0 ? "true;" : "false;"}\n`; /** * Helper function to copy files. * - * @param {Array.<String>} globs The file globs to be copied. - * @param {String} destination The path to copy the files to. - * @param {String} base The base path to omit from the globs when files are copied. Defaults to "". - * @returns {Promise.<Buffer>} A promise containing the stream output as a buffer. + * @param {Array.>} globs The file globs to be copied. + * @param {string} destination The path to copy the files to. + * @param {string} base The base path to omit from the globs when files are copied. Defaults to "". + * @returns {Promise<Buffer>} A promise containing the stream output as a buffer. */ export async function copyFiles(globs, destination, base) { const stream = gulp @@ -737,8 +737,8 @@ export async function copyFiles(globs, destination, base) { /** * Copy assets from engine. * - * @param {String} destination The path to copy files to. - * @returns {Promise.<>} A promise that completes when all assets are copied to the destination. + * @param {string} destination The path to copy files to. + * @returns {Promise<void>} A promise that completes when all assets are copied to the destination. */ export async function copyEngineAssets(destination) { const engineStaticAssets = [ @@ -765,8 +765,8 @@ export async function copyEngineAssets(destination) { /** * Copy assets from widgets. * - * @param {String} destination The path to copy files to. - * @returns {Promise.<>} A promise that completes when all assets are copied to the destination. + * @param {string} destination The path to copy files to. + * @returns {Promise<void>} A promise that completes when all assets are copied to the destination. */ export async function copyWidgetsAssets(destination) { const widgetsStaticAssets = [ @@ -805,10 +805,10 @@ export async function createJsHintOptions() { /** * Bundles spec files for testing in the browser and on the command line with karma. - * @param {Object} options - * @param {Boolean} [options.incremental=false] true if the build should be cached for repeated rebuilds - * @param {Boolean} [options.write=false] true if build output should be written to disk. If false, the files that would have been written as in-memory buffers - * @returns {Promise.<*>} + * @param {object} options + * @param {boolean} [options.incremental=false] true if the build should be cached for repeated rebuilds + * @param {boolean} [options.write=false] true if build output should be written to disk. If false, the files that would have been written as in-memory buffers + * @returns {Promise<any>} */ export function bundleCombinedSpecs(options) { options = options || {}; @@ -834,7 +834,7 @@ export function bundleCombinedSpecs(options) { /** * Creates the index.js for a package. * - * @param {String} workspace The workspace to create the index.js for. + * @param {string} workspace The workspace to create the index.js for. * @returns */ async function createIndexJs(workspace) { @@ -873,9 +873,9 @@ async function createIndexJs(workspace) { /** * Creates a single entry point file by importing all individual spec files. - * @param {Array.<String>} files The individual spec files. - * @param {String} workspace The workspace. - * @param {String} outputPath The path the file is written to. + * @param {Array.>} files The individual spec files. + * @param {string} workspace The workspace. + * @param {string} outputPath The path the file is written to. */ async function createSpecListForWorkspace(files, workspace, outputPath) { let contents = ""; @@ -896,12 +896,12 @@ async function createSpecListForWorkspace(files, workspace, outputPath) { /** * Bundles CSS files. * - * @param {Object} options - * @param {Array.<String>} options.filePaths The file paths to bundle. - * @param {Boolean} options.sourcemap - * @param {Boolean} options.minify - * @param {String} options.outdir The output directory. - * @param {String} options.outbase The + * @param {object} options + * @param {Array.>} options.filePaths The file paths to bundle. + * @param {boolean} options.sourcemap + * @param {boolean} options.minify + * @param {string} options.outdir The output directory. + * @param {string} options.outbase The */ async function bundleCSS(options) { // Configure options for esbuild. @@ -927,13 +927,13 @@ const workspaceCssFiles = { /** * Bundles spec files for testing in the browser. * - * @param {Object} options - * @param {Boolean} [options.incremental=false] True if builds should be generated incrementally. - * @param {String} options.outbase The base path the output files are relative to. - * @param {String} options.outdir The directory to place the output in. - * @param {String} options.specListFile The path to the SpecList.js file - * @param {Boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. - * @returns {Object} The bundle generated from Specs. + * @param {object} options + * @param {boolean} [options.incremental=false] True if builds should be generated incrementally. + * @param {string} options.outbase The base path the output files are relative to. + * @param {string} options.outdir The directory to place the output in. + * @param {string} options.specListFile The path to the SpecList.js file + * @param {boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. + * @returns {object} The bundle generated from Specs. */ async function bundleSpecs(options) { const incremental = options.incremental ?? true; @@ -967,10 +967,10 @@ async function bundleSpecs(options) { /** * Builds the engine workspace. * - * @param {Object} options - * @param {Boolean} [options.incremental=false] True if builds should be generated incrementally. - * @param {Boolean} [options.minify=false] True if bundles should be minified. - * @param {Boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. + * @param {object} options + * @param {boolean} [options.incremental=false] True if builds should be generated incrementally. + * @param {boolean} [options.minify=false] True if bundles should be minified. + * @param {boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. */ export const buildEngine = async (options) => { options = options || {}; @@ -1018,9 +1018,9 @@ export const buildEngine = async (options) => { /** * Builds the widgets workspace. * - * @param {Object} options - * @param {Boolean} [options.incremental=false] True if builds should be generated incrementally. - * @param {Boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. + * @param {object} options + * @param {boolean} [options.incremental=false] True if builds should be generated incrementally. + * @param {boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. */ export const buildWidgets = async (options) => { options = options || {}; @@ -1052,16 +1052,16 @@ export const buildWidgets = async (options) => { /** * Build CesiumJS. * - * @param {Object} options - * @param {Boolean} [options.development=true] True if build is targeted for development. - * @param {Boolean} [options.iife=true] True if IIFE bundle should be generated. - * @param {Boolean} [options.incremental=true] True if builds should be generated incrementally. - * @param {Boolean} [options.minify=false] True if bundles should be minified. - * @param {Boolean} [options.node=true] True if CommonJS bundle should be generated. - * @param {Boolean} options.outputDirectory The directory where the output should go. - * @param {Boolean} [options.removePragmas=false] True if debug pragmas should be removed. - * @param {Boolean} [options.sourcemap=true] True if sourcemap should be included in the generated bundles. - * @param {Boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. + * @param {object} options + * @param {boolean} [options.development=true] True if build is targeted for development. + * @param {boolean} [options.iife=true] True if IIFE bundle should be generated. + * @param {boolean} [options.incremental=true] True if builds should be generated incrementally. + * @param {boolean} [options.minify=false] True if bundles should be minified. + * @param {boolean} [options.node=true] True if CommonJS bundle should be generated. + * @param {boolean} options.outputDirectory The directory where the output should go. + * @param {boolean} [options.removePragmas=false] True if debug pragmas should be removed. + * @param {boolean} [options.sourcemap=true] True if sourcemap should be included in the generated bundles. + * @param {boolean} [options.write=true] True if bundles generated are written to files instead of in-memory buffers. */ export async function buildCesium(options) { const development = options.development ?? true; diff --git a/gulpfile.js b/gulpfile.js index a31f29bfc60..f877b500801 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -499,7 +499,7 @@ export const release = gulp.series( * Removes scripts from package.json files to ensure that * they still work when run from within the ZIP file. * - * @param {String} packageJsonPath The path to the package.json. + * @param {string} packageJsonPath The path to the package.json. * @returns {WritableStream} A stream that writes to the updated package.json file. */ async function pruneScriptsForZip(packageJsonPath) { @@ -1250,15 +1250,15 @@ async function setStatus(state, targetUrl, description, context) { /** * Generates coverage report. * - * @param {Object} options An object with the following properties: - * @param {String} options.outputDirectory The output directory for the generated build artifacts. - * @param {String} options.coverageDirectory The path where the coverage reports should be saved to. - * @param {String} options.specList The path to the spec list for the package. + * @param {object} options An object with the following properties: + * @param {string} options.outputDirectory The output directory for the generated build artifacts. + * @param {string} options.coverageDirectory The path where the coverage reports should be saved to. + * @param {string} options.specList The path to the spec list for the package. * @param {RegExp} options.filter The filter for finding which files should be instrumented. - * @param {Boolean} [options.webglStub=false] True if WebGL stub should be used when running tests. - * @param {Boolean} [options.suppressPassed=false] True if output should be suppressed for tests that pass. - * @param {Boolean} [options.failTaskOnError=false] True if the gulp task should fail on errors in the tests. - * @param {String} options.workspace The name of the workspace, if any. + * @param {boolean} [options.webglStub=false] True if WebGL stub should be used when running tests. + * @param {boolean} [options.suppressPassed=false] True if output should be suppressed for tests that pass. + * @param {boolean} [options.failTaskOnError=false] True if the gulp task should fail on errors in the tests. + * @param {string} options.workspace The name of the workspace, if any. */ export async function runCoverage(options) { const webglStub = options.webglStub ?? false; @@ -1635,7 +1635,7 @@ export async function test() { * Generates TypeScript definition file (.d.ts) for a package. * * @param {*} workspaceName - * @param {String} definitionsPath The path of the .d.ts file to generate. + * @param {string} definitionsPath The path of the .d.ts file to generate. * @param {*} configurationPath * @param {*} processSourceFunc * @param {*} processModulesFunc @@ -1920,9 +1920,9 @@ ${source} /** * Reads `ThirdParty.extra.json` file - * @param path {string} Path to `ThirdParty.extra.json` - * @param discoveredDependencies {Array<string>} List of previously discovered modules - * @returns {Promise<Array<Object>>} A promise to an array of objects with 'name`, `license`, and `url` strings + * @param {string} path Path to `ThirdParty.extra.json` + * @param {string[]} discoveredDependencies List of previously discovered modules + * @returns {Promise<object[]>} A promise to an array of objects with 'name`, `license`, and `url` strings */ async function getLicenseDataFromThirdPartyExtra(path, discoveredDependencies) { if (!existsSync(path)) { @@ -1973,10 +1973,10 @@ async function getLicenseDataFromThirdPartyExtra(path, discoveredDependencies) { /** * Extracts name, license, and url from `package.json` file. * - * @param packageName {string} Name of package - * @param discoveredDependencies {Array<string>} List of previously discovered modules - * @param licenseOverride {Array<string>} If specified, override info fetched from package.json. Useful in the case where there are multiple licenses and we might chose a single one. - * @returns {Promise<Object>} A promise to an object with 'name`, `license`, and `url` strings + * @param {string} packageName Name of package + * @param {string[]} discoveredDependencies List of previously discovered modules + * @param {string[]} licenseOverride If specified, override info fetched from package.json. Useful in the case where there are multiple licenses and we might chose a single one. + * @returns {Promise<object>} A promise to an object with 'name`, `license`, and `url` strings */ async function getLicenseDataFromPackage( packageJson, diff --git a/packages/engine/Source/Core/ApproximateTerrainHeights.js b/packages/engine/Source/Core/ApproximateTerrainHeights.js index 007fe0501e7..6b1891ddc82 100644 --- a/packages/engine/Source/Core/ApproximateTerrainHeights.js +++ b/packages/engine/Source/Core/ApproximateTerrainHeights.js @@ -36,7 +36,7 @@ const ApproximateTerrainHeights = {}; /** * Initializes the minimum and maximum terrain heights - * @return {Promise.<void>} + * @return {Promise<void>} */ ApproximateTerrainHeights.initialize = function () { let initPromise = ApproximateTerrainHeights._initPromise; @@ -57,7 +57,7 @@ ApproximateTerrainHeights.initialize = function () { * Computes the minimum and maximum terrain heights for a given rectangle * @param {Rectangle} rectangle The bounding rectangle * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid - * @return {{minimumTerrainHeight: Number, maximumTerrainHeight: Number}} + * @return {{minimumTerrainHeight: number, maximumTerrainHeight: number}} */ ApproximateTerrainHeights.getMinimumMaximumHeights = function ( rectangle, @@ -243,7 +243,7 @@ Object.defineProperties(ApproximateTerrainHeights, { /** * Determines if the terrain heights are initialized and ready to use. To initialize the terrain heights, * call {@link ApproximateTerrainHeights#initialize} and wait for the returned promise to resolve. - * @type {Boolean} + * @type {boolean} * @readonly * @memberof ApproximateTerrainHeights */ diff --git a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js index 5d20a5b5eb2..df8ea1dfbe1 100644 --- a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js +++ b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js @@ -28,9 +28,9 @@ const ALL_CHILDREN = 15; * @alias ArcGISTiledElevationTerrainProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String|Promise<Resource>|Promise<String>} options.url The URL of the ArcGIS ImageServer service. - * @param {String} [options.token] The authorization token to use to connect to the service. + * @param {object} options Object with the following properties: + * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The URL of the ArcGIS ImageServer service. + * @param {string} [options.token] The authorization token to use to connect to the service. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. * If neither parameter is specified, the WGS84 ellipsoid is used. @@ -271,7 +271,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof ArcGISTiledElevationTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -283,7 +283,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof ArcGISTiledElevationTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -298,7 +298,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link ArcGISTiledElevationTerrainProvider#ready} returns true. * @memberof ArcGISTiledElevationTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -311,7 +311,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link ArcGISTiledElevationTerrainProvider#ready} returns true. * @memberof ArcGISTiledElevationTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -347,11 +347,11 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { * {@link ArcGISTiledElevationTerrainProvider#ready} returns true. The result includes terrain * data and indicates that all child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. */ @@ -459,8 +459,8 @@ function isTileAvailable(that, level, x, y) { /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ ArcGISTiledElevationTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -479,10 +479,10 @@ ArcGISTiledElevationTerrainProvider.prototype.getLevelMaximumGeometricError = fu /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported, otherwise true or false. */ ArcGISTiledElevationTerrainProvider.prototype.getTileDataAvailable = function ( x, @@ -506,9 +506,9 @@ ArcGISTiledElevationTerrainProvider.prototype.getTileDataAvailable = function ( /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined} This provider does not support loading availability. */ ArcGISTiledElevationTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/ArcType.js b/packages/engine/Source/Core/ArcType.js index dd2e9007ccc..a1b9f80a803 100644 --- a/packages/engine/Source/Core/ArcType.js +++ b/packages/engine/Source/Core/ArcType.js @@ -1,13 +1,13 @@ /** * ArcType defines the path that should be taken connecting vertices. * - * @enum {Number} + * @enum {number} */ const ArcType = { /** * Straight line that does not conform to the surface of the ellipsoid. * - * @type {Number} + * @type {number} * @constant */ NONE: 0, @@ -15,7 +15,7 @@ const ArcType = { /** * Follow geodesic path. * - * @type {Number} + * @type {number} * @constant */ GEODESIC: 1, @@ -23,7 +23,7 @@ const ArcType = { /** * Follow rhumb or loxodrome path. * - * @type {Number} + * @type {number} * @constant */ RHUMB: 2, diff --git a/packages/engine/Source/Core/ArticulationStageType.js b/packages/engine/Source/Core/ArticulationStageType.js index 890b6419bb6..7c4c64c303e 100644 --- a/packages/engine/Source/Core/ArticulationStageType.js +++ b/packages/engine/Source/Core/ArticulationStageType.js @@ -3,7 +3,7 @@ * in the AGI_articulations extension. * * @alias {ArticulationStageType} - * @enum {String} + * @enum {string} * * @private */ diff --git a/packages/engine/Source/Core/AssociativeArray.js b/packages/engine/Source/Core/AssociativeArray.js index 05ae7741474..1012807e8c0 100644 --- a/packages/engine/Source/Core/AssociativeArray.js +++ b/packages/engine/Source/Core/AssociativeArray.js @@ -17,7 +17,7 @@ Object.defineProperties(AssociativeArray.prototype, { * Gets the number of items in the collection. * @memberof AssociativeArray.prototype * - * @type {Number} + * @type {number} */ length: { get: function () { @@ -42,8 +42,8 @@ Object.defineProperties(AssociativeArray.prototype, { /** * Determines if the provided key is in the array. * - * @param {String|Number} key The key to check. - * @returns {Boolean} <code>true</code> if the key is in the array, <code>false</code> otherwise. + * @param {string|number} key The key to check. + * @returns {boolean} <code>true</code> if the key is in the array, <code>false</code> otherwise. */ AssociativeArray.prototype.contains = function (key) { //>>includeStart('debug', pragmas.debug); @@ -58,7 +58,7 @@ AssociativeArray.prototype.contains = function (key) { * Associates the provided key with the provided value. If the key already * exists, it is overwritten with the new value. * - * @param {String|Number} key A unique identifier. + * @param {string|number} key A unique identifier. * @param {*} value The value to associate with the provided key. */ AssociativeArray.prototype.set = function (key, value) { @@ -79,7 +79,7 @@ AssociativeArray.prototype.set = function (key, value) { /** * Retrieves the value associated with the provided key. * - * @param {String|Number} key The key whose value is to be retrieved. + * @param {string|number} key The key whose value is to be retrieved. * @returns {*} The associated value, or undefined if the key does not exist in the collection. */ AssociativeArray.prototype.get = function (key) { @@ -94,8 +94,8 @@ AssociativeArray.prototype.get = function (key) { /** * Removes a key-value pair from the collection. * - * @param {String|Number} key The key to be removed. - * @returns {Boolean} True if it was removed, false if the key was not in the collection. + * @param {string|number} key The key to be removed. + * @returns {boolean} True if it was removed, false if the key was not in the collection. */ AssociativeArray.prototype.remove = function (key) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/AttributeCompression.js b/packages/engine/Source/Core/AttributeCompression.js index b53fc598b38..b6b521cc009 100644 --- a/packages/engine/Source/Core/AttributeCompression.js +++ b/packages/engine/Source/Core/AttributeCompression.js @@ -28,7 +28,7 @@ const AttributeCompression = {}; * * @param {Cartesian3} vector The normalized vector to be compressed into 2 component 'oct' encoding. * @param {Cartesian2} result The 2 component oct-encoded unit length vector. - * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits. + * @param {number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits. * @returns {Cartesian2} The 2 component oct-encoded unit length vector. * * @exception {DeveloperError} vector must be normalized. @@ -106,9 +106,9 @@ AttributeCompression.octEncodeToCartesian4 = function (vector, result) { /** * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component vector. * - * @param {Number} x The x component of the oct-encoded unit length vector. - * @param {Number} y The y component of the oct-encoded unit length vector. - * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits. + * @param {number} x The x component of the oct-encoded unit length vector. + * @param {number} y The y component of the oct-encoded unit length vector. + * @param {number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits. * @param {Cartesian3} result The decoded and normalized vector * @returns {Cartesian3} The decoded and normalized vector. * @@ -142,8 +142,8 @@ AttributeCompression.octDecodeInRange = function (x, y, rangeMax, result) { /** * Decodes a unit-length vector in 2 byte 'oct' encoding to a normalized 3-component vector. * - * @param {Number} x The x component of the oct-encoded unit length vector. - * @param {Number} y The y component of the oct-encoded unit length vector. + * @param {number} x The x component of the oct-encoded unit length vector. + * @param {number} y The y component of the oct-encoded unit length vector. * @param {Cartesian3} result The decoded and normalized vector. * @returns {Cartesian3} The decoded and normalized vector. * @@ -202,7 +202,7 @@ AttributeCompression.octDecodeFromCartesian4 = function (encoded, result) { * Packs an oct encoded vector into a single floating-point number. * * @param {Cartesian2} encoded The oct encoded vector. - * @returns {Number} The oct encoded vector packed into a single float. + * @returns {number} The oct encoded vector packed into a single float. * */ AttributeCompression.octPackFloat = function (encoded) { @@ -219,7 +219,7 @@ const scratchEncodeCart2 = new Cartesian2(); * stores those values in a single float-point number. * * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding. - * @returns {Number} The 2 byte oct-encoded unit length vector. + * @returns {number} The 2 byte oct-encoded unit length vector. * * @exception {DeveloperError} vector must be normalized. */ @@ -231,7 +231,7 @@ AttributeCompression.octEncodeFloat = function (vector) { /** * Decodes a unit-length vector in 'oct' encoding packed in a floating-point number to a normalized 3-component vector. * - * @param {Number} value The oct-encoded unit length vector stored as a single floating-point number. + * @param {number} value The oct-encoded unit length vector stored as a single floating-point number. * @param {Cartesian3} result The decoded and normalized vector * @returns {Cartesian3} The decoded and normalized vector. * @@ -309,7 +309,7 @@ AttributeCompression.octUnpack = function (packed, v1, v2, v3) { * Pack texture coordinates into a single float. The texture coordinates will only preserve 12 bits of precision. * * @param {Cartesian2} textureCoordinates The texture coordinates to compress. Both coordinates must be in the range 0.0-1.0. - * @returns {Number} The packed texture coordinates. + * @returns {number} The packed texture coordinates. * */ AttributeCompression.compressTextureCoordinates = function ( @@ -328,7 +328,7 @@ AttributeCompression.compressTextureCoordinates = function ( /** * Decompresses texture coordinates that were packed into a single float. * - * @param {Number} compressed The compressed texture coordinates. + * @param {number} compressed The compressed texture coordinates. * @param {Cartesian2} result The decompressed texture coordinates. * @returns {Cartesian2} The modified result parameter. * @@ -414,7 +414,7 @@ AttributeCompression.zigZagDeltaDecode = function ( * @param {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array} typedArray The typed array for the quantized data. * @param {ComponentDatatype} componentDatatype The component datatype of the quantized data. * @param {AttributeType} type The attribute type of the quantized data. - * @param {Number} count The number of attributes referenced in the dequantized array. + * @param {number} count The number of attributes referenced in the dequantized array. * * @returns {Float32Array} The dequantized array. */ diff --git a/packages/engine/Source/Core/AxisAlignedBoundingBox.js b/packages/engine/Source/Core/AxisAlignedBoundingBox.js index cb8441938b5..41af002cd3c 100644 --- a/packages/engine/Source/Core/AxisAlignedBoundingBox.js +++ b/packages/engine/Source/Core/AxisAlignedBoundingBox.js @@ -164,7 +164,7 @@ AxisAlignedBoundingBox.clone = function (box, result) { * * @param {AxisAlignedBoundingBox} [left] The first AxisAlignedBoundingBox. * @param {AxisAlignedBoundingBox} [right] The second AxisAlignedBoundingBox. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ AxisAlignedBoundingBox.equals = function (left, right) { return ( @@ -251,7 +251,7 @@ AxisAlignedBoundingBox.prototype.intersectPlane = function (plane) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {AxisAlignedBoundingBox} [right] The right hand side AxisAlignedBoundingBox. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ AxisAlignedBoundingBox.prototype.equals = function (right) { return AxisAlignedBoundingBox.equals(this, right); diff --git a/packages/engine/Source/Core/BingMapsGeocoderService.js b/packages/engine/Source/Core/BingMapsGeocoderService.js index a1026f61d70..9be3c977180 100644 --- a/packages/engine/Source/Core/BingMapsGeocoderService.js +++ b/packages/engine/Source/Core/BingMapsGeocoderService.js @@ -12,9 +12,9 @@ const url = "https://dev.virtualearth.net/REST/v1/Locations"; * @alias BingMapsGeocoderService * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.key A key to use with the Bing Maps geocoding service - * @param {String} [options.culture] A Bing Maps {@link https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes|Culture Code} to return results in a specific culture and language. + * @param {object} options Object with the following properties: + * @param {string} options.key A key to use with the Bing Maps geocoding service + * @param {string} [options.culture] A Bing Maps {@link https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes|Culture Code} to return results in a specific culture and language. */ function BingMapsGeocoderService(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -44,7 +44,7 @@ function BingMapsGeocoderService(options) { Object.defineProperties(BingMapsGeocoderService.prototype, { /** * The URL endpoint for the Bing geocoder service - * @type {String} + * @type {string} * @memberof BingMapsGeocoderService.prototype * @readonly */ @@ -56,7 +56,7 @@ Object.defineProperties(BingMapsGeocoderService.prototype, { /** * The key for the Bing geocoder service - * @type {String} + * @type {string} * @memberof BingMapsGeocoderService.prototype * @readonly */ @@ -70,7 +70,7 @@ Object.defineProperties(BingMapsGeocoderService.prototype, { /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ BingMapsGeocoderService.prototype.geocode = function (query) { diff --git a/packages/engine/Source/Core/BoundingRectangle.js b/packages/engine/Source/Core/BoundingRectangle.js index 4c858c1f418..f0a1881613e 100644 --- a/packages/engine/Source/Core/BoundingRectangle.js +++ b/packages/engine/Source/Core/BoundingRectangle.js @@ -12,10 +12,10 @@ import Rectangle from "./Rectangle.js"; * @alias BoundingRectangle * @constructor * - * @param {Number} [x=0.0] The x coordinate of the rectangle. - * @param {Number} [y=0.0] The y coordinate of the rectangle. - * @param {Number} [width=0.0] The width of the rectangle. - * @param {Number} [height=0.0] The height of the rectangle. + * @param {number} [x=0.0] The x coordinate of the rectangle. + * @param {number} [y=0.0] The y coordinate of the rectangle. + * @param {number} [width=0.0] The width of the rectangle. + * @param {number} [height=0.0] The height of the rectangle. * * @see BoundingSphere * @see Packable @@ -23,28 +23,28 @@ import Rectangle from "./Rectangle.js"; function BoundingRectangle(x, y, width, height) { /** * The x coordinate of the rectangle. - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** * The y coordinate of the rectangle. - * @type {Number} + * @type {number} * @default 0.0 */ this.y = defaultValue(y, 0.0); /** * The width of the rectangle. - * @type {Number} + * @type {number} * @default 0.0 */ this.width = defaultValue(width, 0.0); /** * The height of the rectangle. - * @type {Number} + * @type {number} * @default 0.0 */ this.height = defaultValue(height, 0.0); @@ -52,7 +52,7 @@ function BoundingRectangle(x, y, width, height) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ BoundingRectangle.packedLength = 4; @@ -60,10 +60,10 @@ BoundingRectangle.packedLength = 4; * Stores the provided instance into the provided array. * * @param {BoundingRectangle} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ BoundingRectangle.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -84,8 +84,8 @@ BoundingRectangle.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {BoundingRectangle} [result] The object into which to store the result. * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ @@ -160,7 +160,7 @@ const fromRectangleUpperRight = new Cartographic(); * Computes a bounding rectangle from a rectangle. * * @param {Rectangle} rectangle The valid rectangle used to create a bounding rectangle. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. * @param {BoundingRectangle} [result] The object onto which to store the result. * @returns {BoundingRectangle} The modified result parameter or a new BoundingRectangle instance if one was not provided. */ @@ -326,7 +326,7 @@ BoundingRectangle.intersect = function (left, right) { * * @param {BoundingRectangle} [left] The first BoundingRectangle. * @param {BoundingRectangle} [right] The second BoundingRectangle. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ BoundingRectangle.equals = function (left, right) { return ( @@ -365,7 +365,7 @@ BoundingRectangle.prototype.intersect = function (right) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {BoundingRectangle} [right] The right hand side BoundingRectangle. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ BoundingRectangle.prototype.equals = function (right) { return BoundingRectangle.equals(this, right); diff --git a/packages/engine/Source/Core/BoundingSphere.js b/packages/engine/Source/Core/BoundingSphere.js index 58c9f54e85d..3da2d739f67 100644 --- a/packages/engine/Source/Core/BoundingSphere.js +++ b/packages/engine/Source/Core/BoundingSphere.js @@ -18,7 +18,7 @@ import Rectangle from "./Rectangle.js"; * @constructor * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. - * @param {Number} [radius=0.0] The radius of the bounding sphere. + * @param {number} [radius=0.0] The radius of the bounding sphere. * * @see AxisAlignedBoundingBox * @see BoundingRectangle @@ -34,7 +34,7 @@ function BoundingSphere(center, radius) { /** * The radius of the sphere. - * @type {Number} + * @type {number} * @default 0.0 */ this.radius = defaultValue(radius, 0.0); @@ -233,7 +233,7 @@ const fromRectangle2DNortheast = new Cartographic(); * Computes a bounding sphere from a rectangle projected in 2D. * * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. * @param {BoundingSphere} [result] The object onto which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ @@ -252,9 +252,9 @@ BoundingSphere.fromRectangle2D = function (rectangle, projection, result) { * object's minimum and maximum heights over the rectangle. * * @param {Rectangle} [rectangle] The rectangle around which to create a bounding sphere. - * @param {Object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. - * @param {Number} [minimumHeight=0.0] The minimum height over the rectangle. - * @param {Number} [maximumHeight=0.0] The maximum height over the rectangle. + * @param {object} [projection=GeographicProjection] The projection used to project the rectangle into 2D. + * @param {number} [minimumHeight=0.0] The minimum height over the rectangle. + * @param {number} [maximumHeight=0.0] The maximum height over the rectangle. * @param {BoundingSphere} [result] The object onto which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ @@ -312,7 +312,7 @@ const fromRectangle3DScratch = []; * * @param {Rectangle} [rectangle] The valid rectangle used to create a bounding sphere. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. - * @param {Number} [surfaceHeight=0.0] The height above the surface of the ellipsoid. + * @param {number} [surfaceHeight=0.0] The height above the surface of the ellipsoid. * @param {BoundingSphere} [result] The object onto which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ @@ -350,12 +350,12 @@ BoundingSphere.fromRectangle3D = function ( * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to * ensure a tight fit. * - * @param {Number[]} [positions] An array of points that the bounding sphere will enclose. Each point + * @param {number[]} [positions] An array of points that the bounding sphere will enclose. Each point * is formed from three elements in the array in the order X, Y, Z. * @param {Cartesian3} [center=Cartesian3.ZERO] The position to which the positions are relative, which need not be the * origin of the coordinate system. This is useful when the positions are to be used for * relative-to-center (RTC) rendering. - * @param {Number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may + * @param {number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may * be higher. Regardless of the value of this parameter, the X coordinate of the first position * is at array index 0, the Y coordinate is at array index 1, and the Z coordinate is at array index * 2. When stride is 3, the X coordinate of the next position then begins at array index 3. If @@ -555,9 +555,9 @@ BoundingSphere.fromVertices = function (positions, center, stride, result) { * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to * ensure a tight fit. * - * @param {Number[]} [positionsHigh] An array of high bits of the encoded cartesians that the bounding sphere will enclose. Each point + * @param {number[]} [positionsHigh] An array of high bits of the encoded cartesians that the bounding sphere will enclose. Each point * is formed from three elements in the array in the order X, Y, Z. - * @param {Number[]} [positionsLow] An array of low bits of the encoded cartesians that the bounding sphere will enclose. Each point + * @param {number[]} [positionsLow] An array of low bits of the encoded cartesians that the bounding sphere will enclose. Each point * is formed from three elements in the array in the order X, Y, Z. * @param {BoundingSphere} [result] The object onto which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. @@ -936,7 +936,7 @@ BoundingSphere.clone = function (sphere, result) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ BoundingSphere.packedLength = 4; @@ -944,10 +944,10 @@ BoundingSphere.packedLength = 4; * Stores the provided instance into the provided array. * * @param {BoundingSphere} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ BoundingSphere.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -969,8 +969,8 @@ BoundingSphere.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {BoundingSphere} [result] The object into which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. */ @@ -1147,7 +1147,7 @@ const distanceSquaredToScratch = new Cartesian3(); * * @param {BoundingSphere} sphere The sphere. * @param {Cartesian3} cartesian The point - * @returns {Number} The distance squared from the bounding sphere to the point. Returns 0 if the point is inside the sphere. + * @returns {number} The distance squared from the bounding sphere to the point. Returns 0 if the point is inside the sphere. * * @example * // Sort bounding spheres from back to front @@ -1268,7 +1268,7 @@ const projectTo2DProjection = new GeographicProjection(); * Creates a bounding sphere in 2D from a bounding sphere in 3D world coordinates. * * @param {BoundingSphere} sphere The bounding sphere to transform to 2D. - * @param {Object} [projection=GeographicProjection] The projection to 2D. + * @param {object} [projection=GeographicProjection] The projection to 2D. * @param {BoundingSphere} [result] The object onto which to store the result. * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if none was provided. */ @@ -1381,7 +1381,7 @@ BoundingSphere.projectTo2D = function (sphere, projection, result) { * * @param {BoundingSphere} sphere The bounding sphere surrounding the occludee object. * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. */ BoundingSphere.isOccluded = function (sphere, occluder) { //>>includeStart('debug', pragmas.debug); @@ -1397,7 +1397,7 @@ BoundingSphere.isOccluded = function (sphere, occluder) { * * @param {BoundingSphere} [left] The first BoundingSphere. * @param {BoundingSphere} [right] The second BoundingSphere. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ BoundingSphere.equals = function (left, right) { return ( @@ -1426,7 +1426,7 @@ BoundingSphere.prototype.intersectPlane = function (plane) { * Computes the estimated distance squared from the closest point on a bounding sphere to a point. * * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * @returns {number} The estimated distance squared from the bounding sphere to the point. * * @example * // Sort bounding spheres from back to front @@ -1467,7 +1467,7 @@ BoundingSphere.prototype.computePlaneDistances = function ( * Determines whether or not a sphere is hidden from view by the occluder. * * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. */ BoundingSphere.prototype.isOccluded = function (occluder) { return BoundingSphere.isOccluded(this, occluder); @@ -1478,7 +1478,7 @@ BoundingSphere.prototype.isOccluded = function (occluder) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {BoundingSphere} [right] The right hand side BoundingSphere. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ BoundingSphere.prototype.equals = function (right) { return BoundingSphere.equals(this, right); @@ -1496,7 +1496,7 @@ BoundingSphere.prototype.clone = function (result) { /** * Computes the radius of the BoundingSphere. - * @returns {Number} The radius of the BoundingSphere. + * @returns {number} The radius of the BoundingSphere. */ BoundingSphere.prototype.volume = function () { const radius = this.radius; diff --git a/packages/engine/Source/Core/BoxGeometry.js b/packages/engine/Source/Core/BoxGeometry.js index 32f9aba4560..405107e0afd 100644 --- a/packages/engine/Source/Core/BoxGeometry.js +++ b/packages/engine/Source/Core/BoxGeometry.js @@ -20,7 +20,7 @@ const diffScratch = new Cartesian3(); * @alias BoxGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. @@ -70,7 +70,7 @@ function BoxGeometry(options) { /** * Creates a cube centered at the origin given its dimensions. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @returns {BoxGeometry} @@ -141,7 +141,7 @@ BoxGeometry.fromAxisAlignedBoundingBox = function (boundingBox) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ BoxGeometry.packedLength = 2 * Cartesian3.packedLength + VertexFormat.packedLength + 1; @@ -150,10 +150,10 @@ BoxGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {BoxGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ BoxGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -194,8 +194,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {BoxGeometry} [result] The object into which to store the result. * @returns {BoxGeometry} The modified result parameter or a new BoxGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/BoxOutlineGeometry.js b/packages/engine/Source/Core/BoxOutlineGeometry.js index a76b4b6be5b..5e18ee05e9b 100644 --- a/packages/engine/Source/Core/BoxOutlineGeometry.js +++ b/packages/engine/Source/Core/BoxOutlineGeometry.js @@ -19,7 +19,7 @@ const diffScratch = new Cartesian3(); * @alias BoxOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.minimum The minimum x, y, and z coordinates of the box. * @param {Cartesian3} options.maximum The maximum x, y, and z coordinates of the box. * @@ -62,7 +62,7 @@ function BoxOutlineGeometry(options) { /** * Creates an outline of a cube centered at the origin given its dimensions. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.dimensions The width, depth, and height of the box stored in the x, y, and z coordinates of the <code>Cartesian3</code>, respectively. * @returns {BoxOutlineGeometry} * @@ -130,7 +130,7 @@ BoxOutlineGeometry.fromAxisAlignedBoundingBox = function (boundingBox) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ BoxOutlineGeometry.packedLength = 2 * Cartesian3.packedLength + 1; @@ -138,10 +138,10 @@ BoxOutlineGeometry.packedLength = 2 * Cartesian3.packedLength + 1; * Stores the provided instance into the provided array. * * @param {BoxOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ BoxOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -172,8 +172,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {BoxOutlineGeometry} [result] The object into which to store the result. * @returns {BoxOutlineGeometry} The modified result parameter or a new BoxOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/Cartesian2.js b/packages/engine/Source/Core/Cartesian2.js index b06e8f55a80..9d7d8137359 100644 --- a/packages/engine/Source/Core/Cartesian2.js +++ b/packages/engine/Source/Core/Cartesian2.js @@ -9,8 +9,8 @@ import CesiumMath from "./Math.js"; * @alias Cartesian2 * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. + * @param {number} [x=0.0] The X component. + * @param {number} [y=0.0] The Y component. * * @see Cartesian3 * @see Cartesian4 @@ -19,14 +19,14 @@ import CesiumMath from "./Math.js"; function Cartesian2(x, y) { /** * The X component. - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** * The Y component. - * @type {Number} + * @type {number} * @default 0.0 */ this.y = defaultValue(y, 0.0); @@ -35,8 +35,8 @@ function Cartesian2(x, y) { /** * Creates a Cartesian2 instance from x and y coordinates. * - * @param {Number} x The x coordinate. - * @param {Number} y The y coordinate. + * @param {number} x The x coordinate. + * @param {number} y The y coordinate. * @param {Cartesian2} [result] The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. */ @@ -94,7 +94,7 @@ Cartesian2.fromCartesian4 = Cartesian2.clone; /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Cartesian2.packedLength = 2; @@ -102,10 +102,10 @@ Cartesian2.packedLength = 2; * Stores the provided instance into the provided array. * * @param {Cartesian2} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Cartesian2.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -124,8 +124,8 @@ Cartesian2.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Cartesian2} [result] The object into which to store the result. * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. */ @@ -148,8 +148,8 @@ Cartesian2.unpack = function (array, startingIndex, result) { * Flattens an array of Cartesian2s into an array of components. * * @param {Cartesian2[]} array The array of cartesians to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 2 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 2) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 2 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 2) elements. + * @returns {number[]} The packed array. */ Cartesian2.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -179,7 +179,7 @@ Cartesian2.packArray = function (array, result) { /** * Unpacks an array of cartesian components into an array of Cartesian2s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Cartesian2[]} [result] The array onto which to store the result. * @returns {Cartesian2[]} The unpacked array. */ @@ -210,8 +210,8 @@ Cartesian2.unpackArray = function (array, result) { * Creates a Cartesian2 from two consecutive elements in an array. * @function * - * @param {Number[]} array The array whose two consecutive elements correspond to the x and y components, respectively. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. + * @param {number[]} array The array whose two consecutive elements correspond to the x and y components, respectively. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. * @param {Cartesian2} [result] The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. * @@ -230,7 +230,7 @@ Cartesian2.fromArray = Cartesian2.unpack; * Computes the value of the maximum component for the supplied Cartesian. * * @param {Cartesian2} cartesian The cartesian to use. - * @returns {Number} The value of the maximum component. + * @returns {number} The value of the maximum component. */ Cartesian2.maximumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -244,7 +244,7 @@ Cartesian2.maximumComponent = function (cartesian) { * Computes the value of the minimum component for the supplied Cartesian. * * @param {Cartesian2} cartesian The cartesian to use. - * @returns {Number} The value of the minimum component. + * @returns {number} The value of the minimum component. */ Cartesian2.minimumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -325,7 +325,7 @@ Cartesian2.clamp = function (value, min, max, result) { * Computes the provided Cartesian's squared magnitude. * * @param {Cartesian2} cartesian The Cartesian instance whose squared magnitude is to be computed. - * @returns {Number} The squared magnitude. + * @returns {number} The squared magnitude. */ Cartesian2.magnitudeSquared = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -339,7 +339,7 @@ Cartesian2.magnitudeSquared = function (cartesian) { * Computes the Cartesian's magnitude (length). * * @param {Cartesian2} cartesian The Cartesian instance whose magnitude is to be computed. - * @returns {Number} The magnitude. + * @returns {number} The magnitude. */ Cartesian2.magnitude = function (cartesian) { return Math.sqrt(Cartesian2.magnitudeSquared(cartesian)); @@ -352,7 +352,7 @@ const distanceScratch = new Cartesian2(); * * @param {Cartesian2} left The first point to compute the distance from. * @param {Cartesian2} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 1.0 @@ -374,7 +374,7 @@ Cartesian2.distance = function (left, right) { * * @param {Cartesian2} left The first point to compute the distance from. * @param {Cartesian2} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 4.0, not 2.0 @@ -422,7 +422,7 @@ Cartesian2.normalize = function (cartesian, result) { * * @param {Cartesian2} left The first Cartesian. * @param {Cartesian2} right The second Cartesian. - * @returns {Number} The dot product. + * @returns {number} The dot product. */ Cartesian2.dot = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -438,7 +438,7 @@ Cartesian2.dot = function (left, right) { * * @param {Cartesian2} left The first Cartesian. * @param {Cartesian2} right The second Cartesian. - * @returns {Number} The cross product. + * @returns {number} The cross product. */ Cartesian2.cross = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -533,7 +533,7 @@ Cartesian2.subtract = function (left, right, result) { * Multiplies the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian2} cartesian The Cartesian to be scaled. - * @param {Number} scalar The scalar to multiply with. + * @param {number} scalar The scalar to multiply with. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter. */ @@ -553,7 +553,7 @@ Cartesian2.multiplyByScalar = function (cartesian, scalar, result) { * Divides the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian2} cartesian The Cartesian to be divided. - * @param {Number} scalar The scalar to divide by. + * @param {number} scalar The scalar to divide by. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter. */ @@ -611,7 +611,7 @@ const lerpScratch = new Cartesian2(); * * @param {Cartesian2} start The value corresponding to t at 0.0. * @param {Cartesian2} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter. */ @@ -635,7 +635,7 @@ const angleBetweenScratch2 = new Cartesian2(); * * @param {Cartesian2} left The first Cartesian. * @param {Cartesian2} right The second Cartesian. - * @returns {Number} The angle between the Cartesians. + * @returns {number} The angle between the Cartesians. */ Cartesian2.angleBetween = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -682,7 +682,7 @@ Cartesian2.mostOrthogonalAxis = function (cartesian, result) { * * @param {Cartesian2} [left] The first Cartesian. * @param {Cartesian2} [right] The second Cartesian. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Cartesian2.equals = function (left, right) { return ( @@ -708,9 +708,9 @@ Cartesian2.equalsArray = function (cartesian, array, offset) { * * @param {Cartesian2} [left] The first Cartesian. * @param {Cartesian2} [right] The second Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Cartesian2.equalsEpsilon = function ( left, @@ -784,7 +784,7 @@ Cartesian2.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Cartesian2} [right] The right hand side Cartesian. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Cartesian2.prototype.equals = function (right) { return Cartesian2.equals(this, right); @@ -796,9 +796,9 @@ Cartesian2.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Cartesian2} [right] The right hand side Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Cartesian2.prototype.equalsEpsilon = function ( right, @@ -816,7 +816,7 @@ Cartesian2.prototype.equalsEpsilon = function ( /** * Creates a string representing this Cartesian in the format '(x, y)'. * - * @returns {String} A string representing the provided Cartesian in the format '(x, y)'. + * @returns {string} A string representing the provided Cartesian in the format '(x, y)'. */ Cartesian2.prototype.toString = function () { return `(${this.x}, ${this.y})`; diff --git a/packages/engine/Source/Core/Cartesian3.js b/packages/engine/Source/Core/Cartesian3.js index 35c5cd20ff3..934917052da 100644 --- a/packages/engine/Source/Core/Cartesian3.js +++ b/packages/engine/Source/Core/Cartesian3.js @@ -9,9 +9,9 @@ import CesiumMath from "./Math.js"; * @alias Cartesian3 * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. - * @param {Number} [z=0.0] The Z component. + * @param {number} [x=0.0] The X component. + * @param {number} [y=0.0] The Y component. + * @param {number} [z=0.0] The Z component. * * @see Cartesian2 * @see Cartesian4 @@ -20,21 +20,21 @@ import CesiumMath from "./Math.js"; function Cartesian3(x, y, z) { /** * The X component. - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** * The Y component. - * @type {Number} + * @type {number} * @default 0.0 */ this.y = defaultValue(y, 0.0); /** * The Z component. - * @type {Number} + * @type {number} * @default 0.0 */ this.z = defaultValue(z, 0.0); @@ -69,9 +69,9 @@ Cartesian3.fromSpherical = function (spherical, result) { /** * Creates a Cartesian3 instance from x, y and z coordinates. * - * @param {Number} x The x coordinate. - * @param {Number} y The y coordinate. - * @param {Number} z The z coordinate. + * @param {number} x The x coordinate. + * @param {number} y The y coordinate. + * @param {number} z The z coordinate. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. */ @@ -120,7 +120,7 @@ Cartesian3.fromCartesian4 = Cartesian3.clone; /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Cartesian3.packedLength = 3; @@ -128,10 +128,10 @@ Cartesian3.packedLength = 3; * Stores the provided instance into the provided array. * * @param {Cartesian3} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Cartesian3.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -151,8 +151,8 @@ Cartesian3.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Cartesian3} [result] The object into which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. */ @@ -176,8 +176,8 @@ Cartesian3.unpack = function (array, startingIndex, result) { * Flattens an array of Cartesian3s into an array of components. * * @param {Cartesian3[]} array The array of cartesians to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 3 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 3) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 3 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 3) elements. + * @returns {number[]} The packed array. */ Cartesian3.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -207,7 +207,7 @@ Cartesian3.packArray = function (array, result) { /** * Unpacks an array of cartesian components into an array of Cartesian3s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Cartesian3[]} [result] The array onto which to store the result. * @returns {Cartesian3[]} The unpacked array. */ @@ -238,8 +238,8 @@ Cartesian3.unpackArray = function (array, result) { * Creates a Cartesian3 from three consecutive elements in an array. * @function * - * @param {Number[]} array The array whose three consecutive elements correspond to the x, y, and z components, respectively. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. + * @param {number[]} array The array whose three consecutive elements correspond to the x, y, and z components, respectively. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. * @@ -258,7 +258,7 @@ Cartesian3.fromArray = Cartesian3.unpack; * Computes the value of the maximum component for the supplied Cartesian. * * @param {Cartesian3} cartesian The cartesian to use. - * @returns {Number} The value of the maximum component. + * @returns {number} The value of the maximum component. */ Cartesian3.maximumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -272,7 +272,7 @@ Cartesian3.maximumComponent = function (cartesian) { * Computes the value of the minimum component for the supplied Cartesian. * * @param {Cartesian3} cartesian The cartesian to use. - * @returns {Number} The value of the minimum component. + * @returns {number} The value of the minimum component. */ Cartesian3.minimumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -357,7 +357,7 @@ Cartesian3.clamp = function (value, min, max, result) { * Computes the provided Cartesian's squared magnitude. * * @param {Cartesian3} cartesian The Cartesian instance whose squared magnitude is to be computed. - * @returns {Number} The squared magnitude. + * @returns {number} The squared magnitude. */ Cartesian3.magnitudeSquared = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -375,7 +375,7 @@ Cartesian3.magnitudeSquared = function (cartesian) { * Computes the Cartesian's magnitude (length). * * @param {Cartesian3} cartesian The Cartesian instance whose magnitude is to be computed. - * @returns {Number} The magnitude. + * @returns {number} The magnitude. */ Cartesian3.magnitude = function (cartesian) { return Math.sqrt(Cartesian3.magnitudeSquared(cartesian)); @@ -388,7 +388,7 @@ const distanceScratch = new Cartesian3(); * * @param {Cartesian3} left The first point to compute the distance from. * @param {Cartesian3} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 1.0 @@ -410,7 +410,7 @@ Cartesian3.distance = function (left, right) { * * @param {Cartesian3} left The first point to compute the distance from. * @param {Cartesian3} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 4.0, not 2.0 @@ -459,7 +459,7 @@ Cartesian3.normalize = function (cartesian, result) { * * @param {Cartesian3} left The first Cartesian. * @param {Cartesian3} right The second Cartesian. - * @returns {Number} The dot product. + * @returns {number} The dot product. */ Cartesian3.dot = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -558,7 +558,7 @@ Cartesian3.subtract = function (left, right, result) { * Multiplies the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian3} cartesian The Cartesian to be scaled. - * @param {Number} scalar The scalar to multiply with. + * @param {number} scalar The scalar to multiply with. * @param {Cartesian3} result The object onto which to store the result. * @returns {Cartesian3} The modified result parameter. */ @@ -579,7 +579,7 @@ Cartesian3.multiplyByScalar = function (cartesian, scalar, result) { * Divides the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian3} cartesian The Cartesian to be divided. - * @param {Number} scalar The scalar to divide by. + * @param {number} scalar The scalar to divide by. * @param {Cartesian3} result The object onto which to store the result. * @returns {Cartesian3} The modified result parameter. */ @@ -640,7 +640,7 @@ const lerpScratch = new Cartesian3(); * * @param {Cartesian3} start The value corresponding to t at 0.0. * @param {Cartesian3} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Cartesian3} result The object onto which to store the result. * @returns {Cartesian3} The modified result parameter. */ @@ -664,7 +664,7 @@ const angleBetweenScratch2 = new Cartesian3(); * * @param {Cartesian3} left The first Cartesian. * @param {Cartesian3} right The second Cartesian. - * @returns {Number} The angle between the Cartesians. + * @returns {number} The angle between the Cartesians. */ Cartesian3.angleBetween = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -741,7 +741,7 @@ Cartesian3.projectVector = function (a, b, result) { * * @param {Cartesian3} [left] The first Cartesian. * @param {Cartesian3} [right] The second Cartesian. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Cartesian3.equals = function (left, right) { return ( @@ -772,9 +772,9 @@ Cartesian3.equalsArray = function (cartesian, array, offset) { * * @param {Cartesian3} [left] The first Cartesian. * @param {Cartesian3} [right] The second Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Cartesian3.equalsEpsilon = function ( left, @@ -863,9 +863,9 @@ Cartesian3.midpoint = function (left, right, result) { /** * Returns a Cartesian3 position from longitude and latitude values given in degrees. * - * @param {Number} longitude The longitude, in degrees - * @param {Number} latitude The latitude, in degrees - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {number} longitude The longitude, in degrees + * @param {number} latitude The latitude, in degrees + * @param {number} [height=0.0] The height, in meters, above the ellipsoid. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The position @@ -901,9 +901,9 @@ const wgs84RadiiSquared = new Cartesian3( /** * Returns a Cartesian3 position from longitude and latitude values given in radians. * - * @param {Number} longitude The longitude, in radians - * @param {Number} latitude The latitude, in radians - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {number} longitude The longitude, in radians + * @param {number} latitude The latitude, in radians + * @param {number} [height=0.0] The height, in meters, above the ellipsoid. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The position @@ -948,7 +948,7 @@ Cartesian3.fromRadians = function ( /** * Returns an array of Cartesian3 positions given an array of longitude and latitude values given in degrees. * - * @param {Number[]} coordinates A list of longitude and latitude values. Values alternate [longitude, latitude, longitude, latitude...]. + * @param {number[]} coordinates A list of longitude and latitude values. Values alternate [longitude, latitude, longitude, latitude...]. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the coordinates lie. * @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result. * @returns {Cartesian3[]} The array of positions. @@ -992,7 +992,7 @@ Cartesian3.fromDegreesArray = function (coordinates, ellipsoid, result) { /** * Returns an array of Cartesian3 positions given an array of longitude and latitude values given in radians. * - * @param {Number[]} coordinates A list of longitude and latitude values. Values alternate [longitude, latitude, longitude, latitude...]. + * @param {number[]} coordinates A list of longitude and latitude values. Values alternate [longitude, latitude, longitude, latitude...]. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the coordinates lie. * @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result. * @returns {Cartesian3[]} The array of positions. @@ -1036,7 +1036,7 @@ Cartesian3.fromRadiansArray = function (coordinates, ellipsoid, result) { /** * Returns an array of Cartesian3 positions given an array of longitude, latitude and height values where longitude and latitude are given in degrees. * - * @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...]. + * @param {number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...]. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. * @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result. * @returns {Cartesian3[]} The array of positions. @@ -1081,7 +1081,7 @@ Cartesian3.fromDegreesArrayHeights = function (coordinates, ellipsoid, result) { /** * Returns an array of Cartesian3 positions given an array of longitude, latitude and height values where longitude and latitude are given in radians. * - * @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...]. + * @param {number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...]. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies. * @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result. * @returns {Cartesian3[]} The array of positions. @@ -1178,7 +1178,7 @@ Cartesian3.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Cartesian3} [right] The right hand side Cartesian. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Cartesian3.prototype.equals = function (right) { return Cartesian3.equals(this, right); @@ -1190,9 +1190,9 @@ Cartesian3.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Cartesian3} [right] The right hand side Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Cartesian3.prototype.equalsEpsilon = function ( right, @@ -1210,7 +1210,7 @@ Cartesian3.prototype.equalsEpsilon = function ( /** * Creates a string representing this Cartesian in the format '(x, y, z)'. * - * @returns {String} A string representing this Cartesian in the format '(x, y, z)'. + * @returns {string} A string representing this Cartesian in the format '(x, y, z)'. */ Cartesian3.prototype.toString = function () { return `(${this.x}, ${this.y}, ${this.z})`; diff --git a/packages/engine/Source/Core/Cartesian4.js b/packages/engine/Source/Core/Cartesian4.js index 923dae49a95..fa841cc9b2a 100644 --- a/packages/engine/Source/Core/Cartesian4.js +++ b/packages/engine/Source/Core/Cartesian4.js @@ -9,10 +9,10 @@ import CesiumMath from "./Math.js"; * @alias Cartesian4 * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. - * @param {Number} [z=0.0] The Z component. - * @param {Number} [w=0.0] The W component. + * @param {number} [x=0.0] The X component. + * @param {number} [y=0.0] The Y component. + * @param {number} [z=0.0] The Z component. + * @param {number} [w=0.0] The W component. * * @see Cartesian2 * @see Cartesian3 @@ -21,28 +21,28 @@ import CesiumMath from "./Math.js"; function Cartesian4(x, y, z, w) { /** * The X component. - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** * The Y component. - * @type {Number} + * @type {number} * @default 0.0 */ this.y = defaultValue(y, 0.0); /** * The Z component. - * @type {Number} + * @type {number} * @default 0.0 */ this.z = defaultValue(z, 0.0); /** * The W component. - * @type {Number} + * @type {number} * @default 0.0 */ this.w = defaultValue(w, 0.0); @@ -51,10 +51,10 @@ function Cartesian4(x, y, z, w) { /** * Creates a Cartesian4 instance from x, y, z and w coordinates. * - * @param {Number} x The x coordinate. - * @param {Number} y The y coordinate. - * @param {Number} z The z coordinate. - * @param {Number} w The w coordinate. + * @param {number} x The x coordinate. + * @param {number} y The y coordinate. + * @param {number} z The z coordinate. + * @param {number} w The w coordinate. * @param {Cartesian4} [result] The object onto which to store the result. * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. */ @@ -118,7 +118,7 @@ Cartesian4.clone = function (cartesian, result) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Cartesian4.packedLength = 4; @@ -126,10 +126,10 @@ Cartesian4.packedLength = 4; * Stores the provided instance into the provided array. * * @param {Cartesian4} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Cartesian4.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -150,8 +150,8 @@ Cartesian4.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Cartesian4} [result] The object into which to store the result. * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. */ @@ -176,8 +176,8 @@ Cartesian4.unpack = function (array, startingIndex, result) { * Flattens an array of Cartesian4s into an array of components. * * @param {Cartesian4[]} array The array of cartesians to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 4 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 4) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 4 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 4) elements. + * @returns {number[]} The packed array. */ Cartesian4.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -207,7 +207,7 @@ Cartesian4.packArray = function (array, result) { /** * Unpacks an array of cartesian components into an array of Cartesian4s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Cartesian4[]} [result] The array onto which to store the result. * @returns {Cartesian4[]} The unpacked array. */ @@ -238,8 +238,8 @@ Cartesian4.unpackArray = function (array, result) { * Creates a Cartesian4 from four consecutive elements in an array. * @function * - * @param {Number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. + * @param {number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. * @param {Cartesian4} [result] The object onto which to store the result. * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. * @@ -258,7 +258,7 @@ Cartesian4.fromArray = Cartesian4.unpack; * Computes the value of the maximum component for the supplied Cartesian. * * @param {Cartesian4} cartesian The cartesian to use. - * @returns {Number} The value of the maximum component. + * @returns {number} The value of the maximum component. */ Cartesian4.maximumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -272,7 +272,7 @@ Cartesian4.maximumComponent = function (cartesian) { * Computes the value of the minimum component for the supplied Cartesian. * * @param {Cartesian4} cartesian The cartesian to use. - * @returns {Number} The value of the minimum component. + * @returns {number} The value of the minimum component. */ Cartesian4.minimumComponent = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -362,7 +362,7 @@ Cartesian4.clamp = function (value, min, max, result) { * Computes the provided Cartesian's squared magnitude. * * @param {Cartesian4} cartesian The Cartesian instance whose squared magnitude is to be computed. - * @returns {Number} The squared magnitude. + * @returns {number} The squared magnitude. */ Cartesian4.magnitudeSquared = function (cartesian) { //>>includeStart('debug', pragmas.debug); @@ -381,7 +381,7 @@ Cartesian4.magnitudeSquared = function (cartesian) { * Computes the Cartesian's magnitude (length). * * @param {Cartesian4} cartesian The Cartesian instance whose magnitude is to be computed. - * @returns {Number} The magnitude. + * @returns {number} The magnitude. */ Cartesian4.magnitude = function (cartesian) { return Math.sqrt(Cartesian4.magnitudeSquared(cartesian)); @@ -394,7 +394,7 @@ const distanceScratch = new Cartesian4(); * * @param {Cartesian4} left The first point to compute the distance from. * @param {Cartesian4} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 1.0 @@ -418,7 +418,7 @@ Cartesian4.distance = function (left, right) { * * @param {Cartesian4} left The first point to compute the distance from. * @param {Cartesian4} right The second point to compute the distance to. - * @returns {Number} The distance between two points. + * @returns {number} The distance between two points. * * @example * // Returns 4.0, not 2.0 @@ -475,7 +475,7 @@ Cartesian4.normalize = function (cartesian, result) { * * @param {Cartesian4} left The first Cartesian. * @param {Cartesian4} right The second Cartesian. - * @returns {Number} The dot product. + * @returns {number} The dot product. */ Cartesian4.dot = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -580,7 +580,7 @@ Cartesian4.subtract = function (left, right, result) { * Multiplies the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian4} cartesian The Cartesian to be scaled. - * @param {Number} scalar The scalar to multiply with. + * @param {number} scalar The scalar to multiply with. * @param {Cartesian4} result The object onto which to store the result. * @returns {Cartesian4} The modified result parameter. */ @@ -602,7 +602,7 @@ Cartesian4.multiplyByScalar = function (cartesian, scalar, result) { * Divides the provided Cartesian componentwise by the provided scalar. * * @param {Cartesian4} cartesian The Cartesian to be divided. - * @param {Number} scalar The scalar to divide by. + * @param {number} scalar The scalar to divide by. * @param {Cartesian4} result The object onto which to store the result. * @returns {Cartesian4} The modified result parameter. */ @@ -666,7 +666,7 @@ const lerpScratch = new Cartesian4(); * * @param {Cartesian4} start The value corresponding to t at 0.0. * @param {Cartesian4}end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Cartesian4} result The object onto which to store the result. * @returns {Cartesian4} The modified result parameter. */ @@ -733,7 +733,7 @@ Cartesian4.mostOrthogonalAxis = function (cartesian, result) { * * @param {Cartesian4} [left] The first Cartesian. * @param {Cartesian4} [right] The second Cartesian. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Cartesian4.equals = function (left, right) { return ( @@ -766,9 +766,9 @@ Cartesian4.equalsArray = function (cartesian, array, offset) { * * @param {Cartesian4} [left] The first Cartesian. * @param {Cartesian4} [right] The second Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Cartesian4.equalsEpsilon = function ( left, @@ -870,7 +870,7 @@ Cartesian4.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Cartesian4} [right] The right hand side Cartesian. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Cartesian4.prototype.equals = function (right) { return Cartesian4.equals(this, right); @@ -882,9 +882,9 @@ Cartesian4.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Cartesian4} [right] The right hand side Cartesian. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Cartesian4.prototype.equalsEpsilon = function ( right, @@ -902,7 +902,7 @@ Cartesian4.prototype.equalsEpsilon = function ( /** * Creates a string representing this Cartesian in the format '(x, y, z, w)'. * - * @returns {String} A string representing the provided Cartesian in the format '(x, y, z, w)'. + * @returns {string} A string representing the provided Cartesian in the format '(x, y, z, w)'. */ Cartesian4.prototype.toString = function () { return `(${this.x}, ${this.y}, ${this.z}, ${this.w})`; @@ -919,7 +919,7 @@ const littleEndian = testU8[0] === 0x44; /** * Packs an arbitrary floating point value to 4 values representable using uint8. * - * @param {Number} value A floating point number. + * @param {number} value A floating point number. * @param {Cartesian4} [result] The Cartesian4 that will contain the packed float. * @returns {Cartesian4} A Cartesian4 representing the float packed to values in x, y, z, and w. */ @@ -954,7 +954,7 @@ Cartesian4.packFloat = function (value, result) { * Unpacks a float packed using Cartesian4.packFloat. * * @param {Cartesian4} packedFloat A Cartesian4 containing a float packed to 4 values representable using uint8. - * @returns {Number} The unpacked float. + * @returns {number} The unpacked float. * @private */ Cartesian4.unpackFloat = function (packedFloat) { diff --git a/packages/engine/Source/Core/Cartographic.js b/packages/engine/Source/Core/Cartographic.js index e08b82e817f..87957c75bdc 100644 --- a/packages/engine/Source/Core/Cartographic.js +++ b/packages/engine/Source/Core/Cartographic.js @@ -10,30 +10,30 @@ import scaleToGeodeticSurface from "./scaleToGeodeticSurface.js"; * @alias Cartographic * @constructor * - * @param {Number} [longitude=0.0] The longitude, in radians. - * @param {Number} [latitude=0.0] The latitude, in radians. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {number} [longitude=0.0] The longitude, in radians. + * @param {number} [latitude=0.0] The latitude, in radians. + * @param {number} [height=0.0] The height, in meters, above the ellipsoid. * * @see Ellipsoid */ function Cartographic(longitude, latitude, height) { /** * The longitude, in radians. - * @type {Number} + * @type {number} * @default 0.0 */ this.longitude = defaultValue(longitude, 0.0); /** * The latitude, in radians. - * @type {Number} + * @type {number} * @default 0.0 */ this.latitude = defaultValue(latitude, 0.0); /** * The height, in meters, above the ellipsoid. - * @type {Number} + * @type {number} * @default 0.0 */ this.height = defaultValue(height, 0.0); @@ -43,9 +43,9 @@ function Cartographic(longitude, latitude, height) { * Creates a new Cartographic instance from longitude and latitude * specified in radians. * - * @param {Number} longitude The longitude, in radians. - * @param {Number} latitude The latitude, in radians. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {number} longitude The longitude, in radians. + * @param {number} latitude The latitude, in radians. + * @param {number} [height=0.0] The height, in meters, above the ellipsoid. * @param {Cartographic} [result] The object onto which to store the result. * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. */ @@ -72,9 +72,9 @@ Cartographic.fromRadians = function (longitude, latitude, height, result) { * specified in degrees. The values in the resulting object will * be in radians. * - * @param {Number} longitude The longitude, in degrees. - * @param {Number} latitude The latitude, in degrees. - * @param {Number} [height=0.0] The height, in meters, above the ellipsoid. + * @param {number} longitude The longitude, in degrees. + * @param {number} latitude The latitude, in degrees. + * @param {number} [height=0.0] The height, in meters, above the ellipsoid. * @param {Cartographic} [result] The object onto which to store the result. * @returns {Cartographic} The modified result parameter or a new Cartographic instance if one was not provided. */ @@ -213,7 +213,7 @@ Cartographic.clone = function (cartographic, result) { * * @param {Cartographic} [left] The first cartographic. * @param {Cartographic} [right] The second cartographic. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Cartographic.equals = function (left, right) { return ( @@ -233,8 +233,8 @@ Cartographic.equals = function (left, right) { * * @param {Cartographic} [left] The first cartographic. * @param {Cartographic} [right] The second cartographic. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Cartographic.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0); @@ -272,7 +272,7 @@ Cartographic.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Cartographic} [right] The second cartographic. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Cartographic.prototype.equals = function (right) { return Cartographic.equals(this, right); @@ -284,8 +284,8 @@ Cartographic.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Cartographic} [right] The second cartographic. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Cartographic.prototype.equalsEpsilon = function (right, epsilon) { return Cartographic.equalsEpsilon(this, right, epsilon); @@ -294,7 +294,7 @@ Cartographic.prototype.equalsEpsilon = function (right, epsilon) { /** * Creates a string representing this cartographic in the format '(longitude, latitude, height)'. * - * @returns {String} A string representing the provided cartographic in the format '(longitude, latitude, height)'. + * @returns {string} A string representing the provided cartographic in the format '(longitude, latitude, height)'. */ Cartographic.prototype.toString = function () { return `(${this.longitude}, ${this.latitude}, ${this.height})`; diff --git a/packages/engine/Source/Core/CartographicGeocoderService.js b/packages/engine/Source/Core/CartographicGeocoderService.js index 89f698c36fc..35a6ebd0b10 100644 --- a/packages/engine/Source/Core/CartographicGeocoderService.js +++ b/packages/engine/Source/Core/CartographicGeocoderService.js @@ -13,7 +13,7 @@ function CartographicGeocoderService() {} /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ CartographicGeocoderService.prototype.geocode = function (query) { diff --git a/packages/engine/Source/Core/CatmullRomSpline.js b/packages/engine/Source/Core/CatmullRomSpline.js index 9ecbdba88d4..8f7c4ea6d9f 100644 --- a/packages/engine/Source/Core/CatmullRomSpline.js +++ b/packages/engine/Source/Core/CatmullRomSpline.js @@ -111,8 +111,8 @@ const lastTangentScratch = new Cartesian3(); * @alias CatmullRomSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. * The values are in no way connected to the clock time. They are the parameterization for the curve. * @param {Cartesian3[]} options.points The array of {@link Cartesian3} control points. * @param {Cartesian3} [options.firstTangent] The tangent of the curve at the first control point. @@ -201,7 +201,7 @@ Object.defineProperties(CatmullRomSpline.prototype, { * * @memberof CatmullRomSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -280,8 +280,8 @@ CatmullRomSpline.catmullRomCoefficientMatrix = new Matrix4( * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -293,8 +293,8 @@ CatmullRomSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ CatmullRomSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -302,15 +302,15 @@ CatmullRomSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ CatmullRomSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. * diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index 34077f60da3..e97d448994d 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -47,13 +47,13 @@ function LayerInformation(layer) { * @alias CesiumTerrainProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String|Promise<Resource>|Promise<String>} options.url The URL of the Cesium terrain server. - * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available. - * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server, if available. - * @param {Boolean} [options.requestMetadata=true] Flag that indicates if the client should request per tile metadata from the server, if available. + * @param {object} options Object with the following properties: + * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The URL of the Cesium terrain server. + * @param {boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available. + * @param {boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server, if available. + * @param {boolean} [options.requestMetadata=true] Flag that indicates if the client should request per tile metadata from the server, if available. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. * * * @example @@ -83,7 +83,7 @@ function CesiumTerrainProvider(options) { /** * Boolean flag that indicates if the client should request vertex normals from the server. - * @type {Boolean} + * @type {boolean} * @default false * @private */ @@ -94,7 +94,7 @@ function CesiumTerrainProvider(options) { /** * Boolean flag that indicates if the client should request tile watermasks from the server. - * @type {Boolean} + * @type {boolean} * @default false * @private */ @@ -102,7 +102,7 @@ function CesiumTerrainProvider(options) { /** * Boolean flag that indicates if the client should request tile metadata from the server. - * @type {Boolean} + * @type {boolean} * @default true * @private */ @@ -483,7 +483,7 @@ const QuantizedMeshExtensionIds = { /** * Oct-Encoded Per-Vertex Normals are included as an extension to the tile mesh * - * @type {Number} + * @type {number} * @constant * @default 1 */ @@ -491,7 +491,7 @@ const QuantizedMeshExtensionIds = { /** * A watermask is included as an extension to the tile mesh * - * @type {Number} + * @type {number} * @constant * @default 2 */ @@ -499,7 +499,7 @@ const QuantizedMeshExtensionIds = { /** * A json object contain metadata about the tile * - * @type {Number} + * @type {number} * @constant * @default 4 */ @@ -787,12 +787,12 @@ function createQuantizedMeshTerrainData(provider, buffer, level, x, y, layer) { * {@link CesiumTerrainProvider#ready} returns true. The result must include terrain data and * may optionally include a water mask and an indication of which child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. * @@ -986,7 +986,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -998,7 +998,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof CesiumTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -1013,7 +1013,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link CesiumTerrainProvider#ready} returns true. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} */ @@ -1035,7 +1035,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link CesiumTerrainProvider#ready} returns true. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} */ @@ -1058,7 +1058,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include metadata. * This function should not be called before {@link CesiumTerrainProvider#ready} returns true. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} */ @@ -1082,7 +1082,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * Vertex normals data is appended to the standard tile mesh data only if the client requests the vertex normals and * if the server provides vertex normals. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ requestVertexNormals: { @@ -1096,7 +1096,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * Watermask data is appended to the standard tile mesh data only if the client requests the watermask and * if the server provides a watermask. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ requestWaterMask: { @@ -1110,7 +1110,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { * Metadata is appended to the standard tile mesh data only if the client requests the metadata and * if the server provides a metadata. * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ requestMetadata: { @@ -1148,8 +1148,8 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -1160,10 +1160,10 @@ CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function ( /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported or availability is unknown, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported or availability is unknown, otherwise true or false. */ CesiumTerrainProvider.prototype.getTileDataAvailable = function (x, y, level) { if (!defined(this._availability)) { @@ -1198,9 +1198,9 @@ CesiumTerrainProvider.prototype.getTileDataAvailable = function (x, y, level) { /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined|Promise<void>} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded */ CesiumTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/Check.js b/packages/engine/Source/Core/Check.js index 1cb5ddf6ee7..543eda9ca0e 100644 --- a/packages/engine/Source/Core/Check.js +++ b/packages/engine/Source/Core/Check.js @@ -24,7 +24,7 @@ function getFailedTypeErrorMessage(actual, expected, name) { /** * Throws if test is not defined * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value that is to be checked * @exception {DeveloperError} test must be defined */ @@ -37,7 +37,7 @@ Check.defined = function (name, test) { /** * Throws if test is not typeof 'function' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'function' */ @@ -52,7 +52,7 @@ Check.typeOf.func = function (name, test) { /** * Throws if test is not typeof 'string' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'string' */ @@ -67,7 +67,7 @@ Check.typeOf.string = function (name, test) { /** * Throws if test is not typeof 'number' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'number' */ @@ -82,9 +82,9 @@ Check.typeOf.number = function (name, test) { /** * Throws if test is not typeof 'number' and less than limit * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test - * @param {Number} limit The limit value to compare against + * @param {number} limit The limit value to compare against * @exception {DeveloperError} test must be typeof 'number' and less than limit */ Check.typeOf.number.lessThan = function (name, test, limit) { @@ -99,9 +99,9 @@ Check.typeOf.number.lessThan = function (name, test, limit) { /** * Throws if test is not typeof 'number' and less than or equal to limit * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test - * @param {Number} limit The limit value to compare against + * @param {number} limit The limit value to compare against * @exception {DeveloperError} test must be typeof 'number' and less than or equal to limit */ Check.typeOf.number.lessThanOrEquals = function (name, test, limit) { @@ -116,9 +116,9 @@ Check.typeOf.number.lessThanOrEquals = function (name, test, limit) { /** * Throws if test is not typeof 'number' and greater than limit * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test - * @param {Number} limit The limit value to compare against + * @param {number} limit The limit value to compare against * @exception {DeveloperError} test must be typeof 'number' and greater than limit */ Check.typeOf.number.greaterThan = function (name, test, limit) { @@ -133,9 +133,9 @@ Check.typeOf.number.greaterThan = function (name, test, limit) { /** * Throws if test is not typeof 'number' and greater than or equal to limit * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test - * @param {Number} limit The limit value to compare against + * @param {number} limit The limit value to compare against * @exception {DeveloperError} test must be typeof 'number' and greater than or equal to limit */ Check.typeOf.number.greaterThanOrEquals = function (name, test, limit) { @@ -150,7 +150,7 @@ Check.typeOf.number.greaterThanOrEquals = function (name, test, limit) { /** * Throws if test is not typeof 'object' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'object' */ @@ -165,7 +165,7 @@ Check.typeOf.object = function (name, test) { /** * Throws if test is not typeof 'boolean' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'boolean' */ @@ -180,7 +180,7 @@ Check.typeOf.bool = function (name, test) { /** * Throws if test is not typeof 'bigint' * - * @param {String} name The name of the variable being tested + * @param {string} name The name of the variable being tested * @param {*} test The value to test * @exception {DeveloperError} test must be typeof 'bigint' */ @@ -195,8 +195,8 @@ Check.typeOf.bigint = function (name, test) { /** * Throws if test1 and test2 is not typeof 'number' and not equal in value * - * @param {String} name1 The name of the first variable being tested - * @param {String} name2 The name of the second variable being tested against + * @param {string} name1 The name of the first variable being tested + * @param {string} name2 The name of the second variable being tested against * @param {*} test1 The value to test * @param {*} test2 The value to test against * @exception {DeveloperError} test1 and test2 should be type of 'number' and be equal in value diff --git a/packages/engine/Source/Core/CircleGeometry.js b/packages/engine/Source/Core/CircleGeometry.js index 684db45f74c..78e6387c15a 100644 --- a/packages/engine/Source/Core/CircleGeometry.js +++ b/packages/engine/Source/Core/CircleGeometry.js @@ -12,15 +12,15 @@ import VertexFormat from "./VertexFormat.js"; * @alias CircleGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.center The circle's center point in the fixed frame. - * @param {Number} options.radius The radius in meters. + * @param {number} options.radius The radius in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. - * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. - * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. + * @param {number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. + * @param {number} [options.granularity=0.02] The angular distance between points on the circle in radians. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. * * @exception {DeveloperError} radius must be greater than zero. * @exception {DeveloperError} granularity must be greater than zero. @@ -62,7 +62,7 @@ function CircleGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ CircleGeometry.packedLength = EllipseGeometry.packedLength; @@ -70,10 +70,10 @@ CircleGeometry.packedLength = EllipseGeometry.packedLength; * Stores the provided instance into the provided array. * * @param {CircleGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CircleGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -104,8 +104,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CircleGeometry} [result] The object into which to store the result. * @returns {CircleGeometry} The modified result parameter or a new CircleGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/CircleOutlineGeometry.js b/packages/engine/Source/Core/CircleOutlineGeometry.js index e0ce1d197d8..80e40987de1 100644 --- a/packages/engine/Source/Core/CircleOutlineGeometry.js +++ b/packages/engine/Source/Core/CircleOutlineGeometry.js @@ -11,14 +11,14 @@ import Ellipsoid from "./Ellipsoid.js"; * @alias CircleOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.center The circle's center point in the fixed frame. - * @param {Number} options.radius The radius in meters. + * @param {number} options.radius The radius in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the circle will be on. - * @param {Number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. - * @param {Number} [options.granularity=0.02] The angular distance between points on the circle in radians. - * @param {Number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom of an extruded circle. + * @param {number} [options.height=0.0] The distance in meters between the circle and the ellipsoid surface. + * @param {number} [options.granularity=0.02] The angular distance between points on the circle in radians. + * @param {number} [options.extrudedHeight=0.0] The distance in meters between the circle's extruded face and the ellipsoid surface. + * @param {number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom of an extruded circle. * * @exception {DeveloperError} radius must be greater than zero. * @exception {DeveloperError} granularity must be greater than zero. @@ -58,7 +58,7 @@ function CircleOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ CircleOutlineGeometry.packedLength = EllipseOutlineGeometry.packedLength; @@ -66,10 +66,10 @@ CircleOutlineGeometry.packedLength = EllipseOutlineGeometry.packedLength; * Stores the provided instance into the provided array. * * @param {CircleOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CircleOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -102,8 +102,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CircleOutlineGeometry} [result] The object into which to store the result. * @returns {CircleOutlineGeometry} The modified result parameter or a new CircleOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/Clock.js b/packages/engine/Source/Core/Clock.js index a39346baa9d..8bdea4fbf34 100644 --- a/packages/engine/Source/Core/Clock.js +++ b/packages/engine/Source/Core/Clock.js @@ -13,15 +13,15 @@ import JulianDate from "./JulianDate.js"; * @alias Clock * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {JulianDate} [options.startTime] The start time of the clock. * @param {JulianDate} [options.stopTime] The stop time of the clock. * @param {JulianDate} [options.currentTime] The current time. - * @param {Number} [options.multiplier=1.0] Determines how much time advances when {@link Clock#tick} is called, negative values allow for advancing backwards. + * @param {number} [options.multiplier=1.0] Determines how much time advances when {@link Clock#tick} is called, negative values allow for advancing backwards. * @param {ClockStep} [options.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER] Determines if calls to {@link Clock#tick} are frame dependent or system clock dependent. * @param {ClockRange} [options.clockRange=ClockRange.UNBOUNDED] Determines how the clock should behave when {@link Clock#startTime} or {@link Clock#stopTime} is reached. - * @param {Boolean} [options.canAnimate=true] Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, for example. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * @param {Boolean} [options.shouldAnimate=false] Indicates whether {@link Clock#tick} should attempt to advance time. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * @param {boolean} [options.canAnimate=true] Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, for example. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. + * @param {boolean} [options.shouldAnimate=false] Indicates whether {@link Clock#tick} should attempt to advance time. The clock will only tick when both {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. * * @exception {DeveloperError} startTime must come before stopTime. * @@ -109,7 +109,7 @@ function Clock(options) { * Indicates whether {@link Clock#tick} can advance time. This could be false if data is being buffered, * for example. The clock will only advance time when both * {@link Clock#canAnimate} and {@link Clock#shouldAnimate} are true. - * @type {Boolean} + * @type {boolean} * @default true */ this.canAnimate = defaultValue(options.canAnimate, true); @@ -178,7 +178,7 @@ Object.defineProperties(Clock.prototype, { * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. * @memberof Clock.prototype - * @type {Number} + * @type {number} * @default 1.0 */ multiplier: { @@ -230,7 +230,7 @@ Object.defineProperties(Clock.prototype, { * {@link Clock#clockStep} from {@link ClockStep.SYSTEM_CLOCK} to * {@link ClockStep.SYSTEM_CLOCK_MULTIPLIER}. * @memberof Clock.prototype - * @type {Boolean} + * @type {boolean} * @default false */ shouldAnimate: { diff --git a/packages/engine/Source/Core/ClockRange.js b/packages/engine/Source/Core/ClockRange.js index 694179fcf18..8a8e83f7657 100644 --- a/packages/engine/Source/Core/ClockRange.js +++ b/packages/engine/Source/Core/ClockRange.js @@ -2,7 +2,7 @@ * Constants used by {@link Clock#tick} to determine behavior * when {@link Clock#startTime} or {@link Clock#stopTime} is reached. * - * @enum {Number} + * @enum {number} * * @see Clock * @see ClockStep @@ -11,7 +11,7 @@ const ClockRange = { /** * {@link Clock#tick} will always advances the clock in its current direction. * - * @type {Number} + * @type {number} * @constant */ UNBOUNDED: 0, @@ -20,7 +20,7 @@ const ClockRange = { * When {@link Clock#startTime} or {@link Clock#stopTime} is reached, * {@link Clock#tick} will not advance {@link Clock#currentTime} any further. * - * @type {Number} + * @type {number} * @constant */ CLAMPED: 1, @@ -31,7 +31,7 @@ const ClockRange = { * time is moving backwards, {@link Clock#tick} will not advance past * {@link Clock#startTime} * - * @type {Number} + * @type {number} * @constant */ LOOP_STOP: 2, diff --git a/packages/engine/Source/Core/ClockStep.js b/packages/engine/Source/Core/ClockStep.js index 60ae312d131..0494677f9d0 100644 --- a/packages/engine/Source/Core/ClockStep.js +++ b/packages/engine/Source/Core/ClockStep.js @@ -2,7 +2,7 @@ * Constants to determine how much time advances with each call * to {@link Clock#tick}. * - * @enum {Number} + * @enum {number} * * @see Clock * @see ClockRange @@ -12,7 +12,7 @@ const ClockStep = { * {@link Clock#tick} advances the current time by a fixed step, * which is the number of seconds specified by {@link Clock#multiplier}. * - * @type {Number} + * @type {number} * @constant */ TICK_DEPENDENT: 0, @@ -21,7 +21,7 @@ const ClockStep = { * {@link Clock#tick} advances the current time by the amount of system * time elapsed since the previous call multiplied by {@link Clock#multiplier}. * - * @type {Number} + * @type {number} * @constant */ SYSTEM_CLOCK_MULTIPLIER: 1, @@ -30,7 +30,7 @@ const ClockStep = { * {@link Clock#tick} sets the clock to the current system time; * ignoring all other settings. * - * @type {Number} + * @type {number} * @constant */ SYSTEM_CLOCK: 2, diff --git a/packages/engine/Source/Core/Color.js b/packages/engine/Source/Core/Color.js index f8b2c180156..9dfa7b959fd 100644 --- a/packages/engine/Source/Core/Color.js +++ b/packages/engine/Source/Core/Color.js @@ -26,10 +26,10 @@ function hue2rgb(m1, m2, h) { /** * A color, specified using red, green, blue, and alpha values, * which range from <code>0</code> (no intensity) to <code>1.0</code> (full intensity). - * @param {Number} [red=1.0] The red component. - * @param {Number} [green=1.0] The green component. - * @param {Number} [blue=1.0] The blue component. - * @param {Number} [alpha=1.0] The alpha component. + * @param {number} [red=1.0] The red component. + * @param {number} [green=1.0] The green component. + * @param {number} [blue=1.0] The blue component. + * @param {number} [alpha=1.0] The alpha component. * * @constructor * @alias Color @@ -39,25 +39,25 @@ function hue2rgb(m1, m2, h) { function Color(red, green, blue, alpha) { /** * The red component. - * @type {Number} + * @type {number} * @default 1.0 */ this.red = defaultValue(red, 1.0); /** * The green component. - * @type {Number} + * @type {number} * @default 1.0 */ this.green = defaultValue(green, 1.0); /** * The blue component. - * @type {Number} + * @type {number} * @default 1.0 */ this.blue = defaultValue(blue, 1.0); /** * The alpha component. - * @type {Number} + * @type {number} * @default 1.0 */ this.alpha = defaultValue(alpha, 1.0); @@ -91,10 +91,10 @@ Color.fromCartesian4 = function (cartesian, result) { * Creates a new Color specified using red, green, blue, and alpha values * that are in the range of 0 to 255, converting them internally to a range of 0.0 to 1.0. * - * @param {Number} [red=255] The red component. - * @param {Number} [green=255] The green component. - * @param {Number} [blue=255] The blue component. - * @param {Number} [alpha=255] The alpha component. + * @param {number} [red=255] The red component. + * @param {number} [green=255] The green component. + * @param {number} [blue=255] The blue component. + * @param {number} [alpha=255] The alpha component. * @param {Color} [result] The object onto which to store the result. * @returns {Color} The modified result parameter or a new Color instance if one was not provided. */ @@ -120,7 +120,7 @@ Color.fromBytes = function (red, green, blue, alpha, result) { * of the specified color, but with the specified alpha value. * * @param {Color} color The base color - * @param {Number} alpha The new alpha component. + * @param {number} alpha The new alpha component. * @param {Color} [result] The object onto which to store the result. * @returns {Color} The modified result parameter or a new Color instance if one was not provided. * @@ -156,7 +156,7 @@ if (FeatureDetection.supportsTypedArrays()) { * Creates a new Color from a single numeric unsigned 32-bit RGBA value, using the endianness * of the system. * - * @param {Number} rgba A single numeric unsigned 32-bit RGBA value. + * @param {number} rgba A single numeric unsigned 32-bit RGBA value. * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. * @returns {Color} The color object. * @@ -180,10 +180,10 @@ Color.fromRgba = function (rgba, result) { /** * Creates a Color instance from hue, saturation, and lightness. * - * @param {Number} [hue=0] The hue angle 0...1 - * @param {Number} [saturation=0] The saturation value 0...1 - * @param {Number} [lightness=0] The lightness value 0...1 - * @param {Number} [alpha=1.0] The alpha component 0...1 + * @param {number} [hue=0] The hue angle 0...1 + * @param {number} [saturation=0] The saturation value 0...1 + * @param {number} [lightness=0] The lightness value 0...1 + * @param {number} [alpha=1.0] The alpha component 0...1 * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. * @returns {Color} The color object. * @@ -228,19 +228,19 @@ Color.fromHsl = function (hue, saturation, lightness, alpha, result) { * Creates a random color using the provided options. For reproducible random colors, you should * call {@link CesiumMath#setRandomNumberSeed} once at the beginning of your application. * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.red] If specified, the red component to use instead of a randomized value. - * @param {Number} [options.minimumRed=0.0] The maximum red value to generate if none was specified. - * @param {Number} [options.maximumRed=1.0] The minimum red value to generate if none was specified. - * @param {Number} [options.green] If specified, the green component to use instead of a randomized value. - * @param {Number} [options.minimumGreen=0.0] The maximum green value to generate if none was specified. - * @param {Number} [options.maximumGreen=1.0] The minimum green value to generate if none was specified. - * @param {Number} [options.blue] If specified, the blue component to use instead of a randomized value. - * @param {Number} [options.minimumBlue=0.0] The maximum blue value to generate if none was specified. - * @param {Number} [options.maximumBlue=1.0] The minimum blue value to generate if none was specified. - * @param {Number} [options.alpha] If specified, the alpha component to use instead of a randomized value. - * @param {Number} [options.minimumAlpha=0.0] The maximum alpha value to generate if none was specified. - * @param {Number} [options.maximumAlpha=1.0] The minimum alpha value to generate if none was specified. + * @param {object} [options] Object with the following properties: + * @param {number} [options.red] If specified, the red component to use instead of a randomized value. + * @param {number} [options.minimumRed=0.0] The maximum red value to generate if none was specified. + * @param {number} [options.maximumRed=1.0] The minimum red value to generate if none was specified. + * @param {number} [options.green] If specified, the green component to use instead of a randomized value. + * @param {number} [options.minimumGreen=0.0] The maximum green value to generate if none was specified. + * @param {number} [options.maximumGreen=1.0] The minimum green value to generate if none was specified. + * @param {number} [options.blue] If specified, the blue component to use instead of a randomized value. + * @param {number} [options.minimumBlue=0.0] The maximum blue value to generate if none was specified. + * @param {number} [options.maximumBlue=1.0] The minimum blue value to generate if none was specified. + * @param {number} [options.alpha] If specified, the alpha component to use instead of a randomized value. + * @param {number} [options.minimumAlpha=0.0] The maximum alpha value to generate if none was specified. + * @param {number} [options.maximumAlpha=1.0] The minimum alpha value to generate if none was specified. * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. * @returns {Color} The modified result parameter or a new instance if result was undefined. * @@ -359,7 +359,7 @@ const hslParenthesesMatcher = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9 /** * Creates a Color instance from a CSS color value. * - * @param {String} color The CSS color value in #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(), rgba(), hsl(), or hsla() format. + * @param {string} color The CSS color value in #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(), rgba(), hsl(), or hsla() format. * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. * @returns {Color} The color object, or undefined if the string was not a valid CSS color. * @@ -435,7 +435,7 @@ Color.fromCssColorString = function (color, result) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Color.packedLength = 4; @@ -443,10 +443,10 @@ Color.packedLength = 4; * Stores the provided instance into the provided array. * * @param {Color} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Color.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -466,8 +466,8 @@ Color.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Color} [result] The object into which to store the result. * @returns {Color} The modified result parameter or a new Color instance if one was not provided. */ @@ -491,8 +491,8 @@ Color.unpack = function (array, startingIndex, result) { * Converts a 'byte' color component in the range of 0 to 255 into * a 'float' color component in the range of 0 to 1.0. * - * @param {Number} number The number to be converted. - * @returns {Number} The converted number. + * @param {number} number The number to be converted. + * @returns {number} The converted number. */ Color.byteToFloat = function (number) { return number / 255.0; @@ -502,8 +502,8 @@ Color.byteToFloat = function (number) { * Converts a 'float' color component in the range of 0 to 1.0 into * a 'byte' color component in the range of 0 to 255. * - * @param {Number} number The number to be converted. - * @returns {Number} The converted number. + * @param {number} number The number to be converted. + * @returns {number} The converted number. */ Color.floatToByte = function (number) { return number === 1.0 ? 255.0 : (number * 256.0) | 0; @@ -535,7 +535,7 @@ Color.clone = function (color, result) { * * @param {Color} left The first Color to compare for equality. * @param {Color} right The second Color to compare for equality. - * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. */ Color.equals = function (left, right) { return ( @@ -575,7 +575,7 @@ Color.prototype.clone = function (result) { * Returns true if this Color equals other. * * @param {Color} other The Color to compare for equality. - * @returns {Boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the Colors are equal; otherwise, <code>false</code>. */ Color.prototype.equals = function (other) { return Color.equals(this, other); @@ -585,8 +585,8 @@ Color.prototype.equals = function (other) { * Returns <code>true</code> if this Color equals other componentwise within the specified epsilon. * * @param {Color} other The Color to compare for equality. - * @param {Number} [epsilon=0.0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if the Colors are equal within the specified epsilon; otherwise, <code>false</code>. + * @param {number} [epsilon=0.0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if the Colors are equal within the specified epsilon; otherwise, <code>false</code>. */ Color.prototype.equalsEpsilon = function (other, epsilon) { return ( @@ -602,7 +602,7 @@ Color.prototype.equalsEpsilon = function (other, epsilon) { /** * Creates a string representing this Color in the format '(red, green, blue, alpha)'. * - * @returns {String} A string representing this Color in the format '(red, green, blue, alpha)'. + * @returns {string} A string representing this Color in the format '(red, green, blue, alpha)'. */ Color.prototype.toString = function () { return `(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`; @@ -611,7 +611,7 @@ Color.prototype.toString = function () { /** * Creates a string containing the CSS color value for this color. * - * @returns {String} The CSS equivalent of this color. + * @returns {string} The CSS equivalent of this color. * * @see {@link http://www.w3.org/TR/css3-color/#rgba-color|CSS RGB or RGBA color values} */ @@ -628,7 +628,7 @@ Color.prototype.toCssColorString = function () { /** * Creates a string containing CSS hex string color value for this color. * - * @returns {String} The CSS hex string equivalent of this color. + * @returns {string} The CSS hex string equivalent of this color. */ Color.prototype.toCssHexString = function () { let r = Color.floatToByte(this.red).toString(16); @@ -657,8 +657,8 @@ Color.prototype.toCssHexString = function () { * Converts this color to an array of red, green, blue, and alpha values * that are in the range of 0 to 255. * - * @param {Number[]} [result] The array to store the result in, if undefined a new instance will be created. - * @returns {Number[]} The modified result parameter or a new instance if result was undefined. + * @param {number[]} [result] The array to store the result in, if undefined a new instance will be created. + * @returns {number[]} The modified result parameter or a new instance if result was undefined. */ Color.prototype.toBytes = function (result) { const red = Color.floatToByte(this.red); @@ -680,7 +680,7 @@ Color.prototype.toBytes = function (result) { * Converts this color to a single numeric unsigned 32-bit RGBA value, using the endianness * of the system. * - * @returns {Number} A single numeric unsigned 32-bit RGBA value. + * @returns {number} A single numeric unsigned 32-bit RGBA value. * * * @example @@ -700,7 +700,7 @@ Color.prototype.toRgba = function () { /** * Brightens this color by the provided magnitude. * - * @param {Number} magnitude A positive number indicating the amount to brighten. + * @param {number} magnitude A positive number indicating the amount to brighten. * @param {Color} result The object onto which to store the result. * @returns {Color} The modified result parameter. * @@ -725,7 +725,7 @@ Color.prototype.brighten = function (magnitude, result) { /** * Darkens this color by the provided magnitude. * - * @param {Number} magnitude A positive number indicating the amount to darken. + * @param {number} magnitude A positive number indicating the amount to darken. * @param {Color} result The object onto which to store the result. * @returns {Color} The modified result parameter. * @@ -751,7 +751,7 @@ Color.prototype.darken = function (magnitude, result) { * Creates a new Color that has the same red, green, and blue components * as this Color, but with the specified alpha value. * - * @param {Number} alpha The new alpha component. + * @param {number} alpha The new alpha component. * @param {Color} [result] The object onto which to store the result. * @returns {Color} The modified result parameter or a new Color instance if one was not provided. * @@ -876,7 +876,7 @@ Color.mod = function (left, right, result) { * * @param {Color} start The color corresponding to t at 0.0. * @param {Color} end The color corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Color} result The object onto which to store the result. * @returns {Color} The modified result parameter. */ @@ -899,7 +899,7 @@ Color.lerp = function (start, end, t, result) { * Multiplies the provided Color componentwise by the provided scalar. * * @param {Color} color The Color to be scaled. - * @param {Number} scalar The scalar to multiply with. + * @param {number} scalar The scalar to multiply with. * @param {Color} result The object onto which to store the result. * @returns {Color} The modified result parameter. */ @@ -921,7 +921,7 @@ Color.multiplyByScalar = function (color, scalar, result) { * Divides the provided Color componentwise by the provided scalar. * * @param {Color} color The Color to be divided. - * @param {Number} scalar The scalar to divide with. + * @param {number} scalar The scalar to divide with. * @param {Color} result The object onto which to store the result. * @returns {Color} The modified result parameter. */ diff --git a/packages/engine/Source/Core/ColorGeometryInstanceAttribute.js b/packages/engine/Source/Core/ColorGeometryInstanceAttribute.js index 298bdf5da8f..1b409b4255b 100644 --- a/packages/engine/Source/Core/ColorGeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/ColorGeometryInstanceAttribute.js @@ -10,10 +10,10 @@ import DeveloperError from "./DeveloperError.js"; * @alias ColorGeometryInstanceAttribute * @constructor * - * @param {Number} [red=1.0] The red component. - * @param {Number} [green=1.0] The green component. - * @param {Number} [blue=1.0] The blue component. - * @param {Number} [alpha=1.0] The alpha component. + * @param {number} [red=1.0] The red component. + * @param {number} [green=1.0] The green component. + * @param {number} [blue=1.0] The blue component. + * @param {number} [alpha=1.0] The alpha component. * * * @example @@ -76,7 +76,7 @@ Object.defineProperties(ColorGeometryInstanceAttribute.prototype, { * * @memberof ColorGeometryInstanceAttribute.prototype * - * @type {Number} + * @type {number} * @readonly * * @default 4 @@ -94,7 +94,7 @@ Object.defineProperties(ColorGeometryInstanceAttribute.prototype, { * * @memberof ColorGeometryInstanceAttribute.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -166,7 +166,7 @@ ColorGeometryInstanceAttribute.toValue = function (color, result) { * * @param {ColorGeometryInstanceAttribute} [left] The first ColorGeometryInstanceAttribute. * @param {ColorGeometryInstanceAttribute} [right] The second ColorGeometryInstanceAttribute. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ColorGeometryInstanceAttribute.equals = function (left, right) { return ( diff --git a/packages/engine/Source/Core/ComponentDatatype.js b/packages/engine/Source/Core/ComponentDatatype.js index b7c8d3439fc..9e92afe2696 100644 --- a/packages/engine/Source/Core/ComponentDatatype.js +++ b/packages/engine/Source/Core/ComponentDatatype.js @@ -7,14 +7,14 @@ import WebGLConstants from "./WebGLConstants.js"; * WebGL component datatypes. Components are intrinsics, * which form attributes, which form vertices. * - * @enum {Number} + * @enum {number} */ const ComponentDatatype = { /** * 8-bit signed byte corresponding to <code>gl.BYTE</code> and the type * of an element in <code>Int8Array</code>. * - * @type {Number} + * @type {number} * @constant */ BYTE: WebGLConstants.BYTE, @@ -23,7 +23,7 @@ const ComponentDatatype = { * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type * of an element in <code>Uint8Array</code>. * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_BYTE: WebGLConstants.UNSIGNED_BYTE, @@ -32,7 +32,7 @@ const ComponentDatatype = { * 16-bit signed short corresponding to <code>SHORT</code> and the type * of an element in <code>Int16Array</code>. * - * @type {Number} + * @type {number} * @constant */ SHORT: WebGLConstants.SHORT, @@ -41,7 +41,7 @@ const ComponentDatatype = { * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type * of an element in <code>Uint16Array</code>. * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_SHORT: WebGLConstants.UNSIGNED_SHORT, @@ -52,7 +52,7 @@ const ComponentDatatype = { * * @memberOf ComponentDatatype * - * @type {Number} + * @type {number} * @constant */ INT: WebGLConstants.INT, @@ -63,7 +63,7 @@ const ComponentDatatype = { * * @memberOf ComponentDatatype * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_INT: WebGLConstants.UNSIGNED_INT, @@ -72,7 +72,7 @@ const ComponentDatatype = { * 32-bit floating-point corresponding to <code>FLOAT</code> and the type * of an element in <code>Float32Array</code>. * - * @type {Number} + * @type {number} * @constant */ FLOAT: WebGLConstants.FLOAT, @@ -84,7 +84,7 @@ const ComponentDatatype = { * * @memberOf ComponentDatatype * - * @type {Number} + * @type {number} * @constant * @default 0x140A */ @@ -95,7 +95,7 @@ const ComponentDatatype = { * Returns the size, in bytes, of the corresponding datatype. * * @param {ComponentDatatype} componentDatatype The component datatype to get the size of. - * @returns {Number} The size in bytes. + * @returns {number} The size in bytes. * * @exception {DeveloperError} componentDatatype is not a valid value. * @@ -177,7 +177,7 @@ ComponentDatatype.fromTypedArray = function (array) { * Validates that the provided component datatype is a valid {@link ComponentDatatype} * * @param {ComponentDatatype} componentDatatype The component datatype to validate. - * @returns {Boolean} <code>true</code> if the provided component datatype is a valid value; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the provided component datatype is a valid value; otherwise, <code>false</code>. * * @example * if (!Cesium.ComponentDatatype.validate(componentDatatype)) { @@ -202,7 +202,7 @@ ComponentDatatype.validate = function (componentDatatype) { * Creates a typed array corresponding to component data type. * * @param {ComponentDatatype} componentDatatype The component data type. - * @param {Number|Array} valuesOrLength The length of the array to create or an array. + * @param {number|Array} valuesOrLength The length of the array to create or an array. * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array. * * @exception {DeveloperError} componentDatatype is not a valid value. @@ -253,8 +253,8 @@ ComponentDatatype.createTypedArray = function ( * * @param {ComponentDatatype} componentDatatype The type of the view to create. * @param {ArrayBuffer} buffer The buffer storage to use for the view. - * @param {Number} [byteOffset] The offset, in bytes, to the first element in the view. - * @param {Number} [length] The number of elements in the view. + * @param {number} [byteOffset] The offset, in bytes, to the first element in the view. + * @param {number} [length] The number of elements in the view. * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array view of the buffer. * * @exception {DeveloperError} componentDatatype is not a valid value. @@ -308,7 +308,7 @@ ComponentDatatype.createArrayBufferView = function ( /** * Get the ComponentDatatype from its name. * - * @param {String} name The name of the ComponentDatatype. + * @param {string} name The name of the ComponentDatatype. * @returns {ComponentDatatype} The ComponentDatatype. * * @exception {DeveloperError} name is not a valid value. diff --git a/packages/engine/Source/Core/CompressedTextureBuffer.js b/packages/engine/Source/Core/CompressedTextureBuffer.js index be19eb34677..062d2fe4f1f 100644 --- a/packages/engine/Source/Core/CompressedTextureBuffer.js +++ b/packages/engine/Source/Core/CompressedTextureBuffer.js @@ -7,8 +7,8 @@ import defined from "./defined.js"; * * @param {PixelFormat} internalFormat The pixel format of the compressed texture. * @param {PixelDatatype} pixelDatatype The pixel datatype of the compressed texture. - * @param {Number} width The width of the texture. - * @param {Number} height The height of the texture. + * @param {number} width The width of the texture. + * @param {number} height The height of the texture. * @param {Uint8Array} buffer The compressed texture buffer. */ function CompressedTextureBuffer( diff --git a/packages/engine/Source/Core/ConstantSpline.js b/packages/engine/Source/Core/ConstantSpline.js index d6c476131a3..032003de3a3 100644 --- a/packages/engine/Source/Core/ConstantSpline.js +++ b/packages/engine/Source/Core/ConstantSpline.js @@ -9,7 +9,7 @@ import Spline from "./Spline.js"; * @alias ConstantSpline * @constructor * - * @param {Number|Cartesian3|Quaternion} value The constant value that the spline evaluates to. + * @param {number|Cartesian3|Quaternion} value The constant value that the spline evaluates to. * * @example * const position = new Cesium.Cartesian3(1.0, 2.0, 3.0); @@ -34,7 +34,7 @@ Object.defineProperties(ConstantSpline.prototype, { * * @memberof ConstantSpline.prototype * - * @type {Number|Cartesian3|Quaternion} + * @type {number|Cartesian3|Quaternion} * @readonly */ value: { @@ -51,7 +51,7 @@ Object.defineProperties(ConstantSpline.prototype, { * Since a constant spline has no internal times array, this will throw an error. * @function * - * @param {Number} time The time. + * @param {number} time The time. * * @exception {DeveloperError} findTimeInterval cannot be called on a ConstantSpline. */ @@ -67,8 +67,8 @@ ConstantSpline.prototype.findTimeInterval = function (time) { * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ ConstantSpline.prototype.wrapTime = function (time) { //>>includeStart('debug', pragmas.debug); @@ -82,8 +82,8 @@ ConstantSpline.prototype.wrapTime = function (time) { * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ ConstantSpline.prototype.clampTime = function (time) { //>>includeStart('debug', pragmas.debug); @@ -97,9 +97,9 @@ ConstantSpline.prototype.clampTime = function (time) { * Evaluates the curve at a given time. * @function * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Cartesian3|Quaternion} [result] The object onto which to store the result. - * @returns {Number|Cartesian3|Quaternion} The modified result parameter or the value that the constant spline represents. + * @returns {number|Cartesian3|Quaternion} The modified result parameter or the value that the constant spline represents. */ ConstantSpline.prototype.evaluate = function (time, result) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/CoplanarPolygonGeometry.js b/packages/engine/Source/Core/CoplanarPolygonGeometry.js index 90b17ceb0a1..208a1059e05 100644 --- a/packages/engine/Source/Core/CoplanarPolygonGeometry.js +++ b/packages/engine/Source/Core/CoplanarPolygonGeometry.js @@ -227,9 +227,9 @@ function createGeometryFromPolygon( * @alias CoplanarPolygonGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @param {PolygonHierarchy} [options.textureCoordinates] Texture coordinates as a {@link PolygonHierarchy} of {@link Cartesian2} points. @@ -266,7 +266,7 @@ function CoplanarPolygonGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength( @@ -287,10 +287,10 @@ function CoplanarPolygonGeometry(options) { /** * A description of a coplanar polygon from an array of positions. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @param {PolygonHierarchy} [options.textureCoordinates] Texture coordinates as a {@link PolygonHierarchy} of {@link Cartesian2} points. * @returns {CoplanarPolygonGeometry} @@ -333,10 +333,10 @@ CoplanarPolygonGeometry.fromPositions = function (options) { * Stores the provided instance into the provided array. * * @param {CoplanarPolygonGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CoplanarPolygonGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -383,8 +383,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CoplanarPolygonGeometry} [result] The object into which to store the result. * @returns {CoplanarPolygonGeometry} The modified result parameter or a new CoplanarPolygonGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/CoplanarPolygonOutlineGeometry.js b/packages/engine/Source/Core/CoplanarPolygonOutlineGeometry.js index a027cf03a5a..0f900967670 100644 --- a/packages/engine/Source/Core/CoplanarPolygonOutlineGeometry.js +++ b/packages/engine/Source/Core/CoplanarPolygonOutlineGeometry.js @@ -54,7 +54,7 @@ function createGeometryFromPositions(positions) { * @alias CoplanarPolygonOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. * * @see CoplanarPolygonOutlineGeometry.createGeometry @@ -82,7 +82,7 @@ function CoplanarPolygonOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength( @@ -94,7 +94,7 @@ function CoplanarPolygonOutlineGeometry(options) { /** * A description of a coplanar polygon outline from an array of positions. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. * @returns {CoplanarPolygonOutlineGeometry} */ @@ -117,10 +117,10 @@ CoplanarPolygonOutlineGeometry.fromPositions = function (options) { * Stores the provided instance into the provided array. * * @param {CoplanarPolygonOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CoplanarPolygonOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -148,8 +148,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CoplanarPolygonOutlineGeometry} [result] The object into which to store the result. * @returns {CoplanarPolygonOutlineGeometry} The modified result parameter or a new CoplanarPolygonOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/CornerType.js b/packages/engine/Source/Core/CornerType.js index 9f0f72600cf..c2c4ed23e41 100644 --- a/packages/engine/Source/Core/CornerType.js +++ b/packages/engine/Source/Core/CornerType.js @@ -4,14 +4,14 @@ * @demo The {@link https://sandcastle.cesium.com/index.html?src=Corridor.html&label=Geometries|Corridor Demo} * demonstrates the three corner types, as used by {@link CorridorGraphics}. * - * @enum {Number} + * @enum {number} */ const CornerType = { /** * <img src="Images/CornerTypeRounded.png" style="vertical-align: middle;" width="186" height="189" /> * * Corner has a smooth edge. - * @type {Number} + * @type {number} * @constant */ ROUNDED: 0, @@ -20,7 +20,7 @@ const CornerType = { * <img src="Images/CornerTypeMitered.png" style="vertical-align: middle;" width="186" height="189" /> * * Corner point is the intersection of adjacent edges. - * @type {Number} + * @type {number} * @constant */ MITERED: 1, @@ -29,7 +29,7 @@ const CornerType = { * <img src="Images/CornerTypeBeveled.png" style="vertical-align: middle;" width="186" height="189" /> * * Corner is clipped. - * @type {Number} + * @type {number} * @constant */ BEVELED: 2, diff --git a/packages/engine/Source/Core/CorridorGeometry.js b/packages/engine/Source/Core/CorridorGeometry.js index a2df6ce5111..e5dd6af5ab5 100644 --- a/packages/engine/Source/Core/CorridorGeometry.js +++ b/packages/engine/Source/Core/CorridorGeometry.js @@ -1047,13 +1047,13 @@ function computeRectangle(positions, ellipsoid, width, cornerType, result) { * @alias CorridorGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor. - * @param {Number} options.width The distance between the edges of the corridor in meters. + * @param {number} options.width The distance between the edges of the corridor in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0] The distance in meters between the ellipsoid surface and the positions. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipsoid surface and the extruded face. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.height=0] The distance in meters between the ellipsoid surface and the positions. + * @param {number} [options.extrudedHeight] The distance in meters between the ellipsoid surface and the extruded face. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * @@ -1104,7 +1104,7 @@ function CorridorGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = 1 + @@ -1118,10 +1118,10 @@ function CorridorGeometry(options) { * Stores the provided instance into the provided array. * * @param {CorridorGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CorridorGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -1174,8 +1174,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CorridorGeometry} [result] The object into which to store the result. * @returns {CorridorGeometry} The modified result parameter or a new CorridorGeometry instance if one was not provided. */ @@ -1243,9 +1243,9 @@ CorridorGeometry.unpack = function (array, startingIndex, result) { /** * Computes the bounding rectangle given the provided options * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor. - * @param {Number} options.width The distance between the edges of the corridor in meters. + * @param {number} options.width The distance between the edges of the corridor in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * @param {Rectangle} [result] An object in which to store the result. diff --git a/packages/engine/Source/Core/CorridorOutlineGeometry.js b/packages/engine/Source/Core/CorridorOutlineGeometry.js index c8e9c6130fc..66a39d04bd3 100644 --- a/packages/engine/Source/Core/CorridorOutlineGeometry.js +++ b/packages/engine/Source/Core/CorridorOutlineGeometry.js @@ -358,13 +358,13 @@ function computePositionsExtruded(params) { * @alias CorridorOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor outline. - * @param {Number} options.width The distance between the edges of the corridor outline. + * @param {number} options.width The distance between the edges of the corridor outline. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0] The distance in meters between the positions and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the extruded face and the ellipsoid surface. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.height=0] The distance in meters between the positions and the ellipsoid surface. + * @param {number} [options.extrudedHeight] The distance in meters between the extruded face and the ellipsoid surface. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * * @see CorridorOutlineGeometry.createGeometry @@ -405,7 +405,7 @@ function CorridorOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = 1 + positions.length * Cartesian3.packedLength + Ellipsoid.packedLength + 6; @@ -415,10 +415,10 @@ function CorridorOutlineGeometry(options) { * Stores the provided instance into the provided array. * * @param {CorridorOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CorridorOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -464,8 +464,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CorridorOutlineGeometry} [result] The object into which to store the result. * @returns {CorridorOutlineGeometry} The modified result parameter or a new CorridorOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/Credit.js b/packages/engine/Source/Core/Credit.js index 456d34768dd..807a79ff1c0 100644 --- a/packages/engine/Source/Core/Credit.js +++ b/packages/engine/Source/Core/Credit.js @@ -8,8 +8,8 @@ const creditToId = {}; /** * A credit contains data pertaining to how to display attributions/credits for certain content on the screen. - * @param {String} html An string representing an html code snippet - * @param {Boolean} [showOnScreen=false] If true, the credit will be visible in the main credit container. Otherwise, it will appear in a popover + * @param {string} html An string representing an html code snippet + * @param {boolean} [showOnScreen=false] If true, the credit will be visible in the main credit container. Otherwise, it will appear in a popover * * @alias Credit * @constructor @@ -47,7 +47,7 @@ Object.defineProperties(Credit.prototype, { /** * The credit content * @memberof Credit.prototype - * @type {String} + * @type {string} * @readonly */ html: { @@ -58,7 +58,7 @@ Object.defineProperties(Credit.prototype, { /** * @memberof Credit.prototype - * @type {Number} + * @type {number} * @readonly * * @private @@ -72,7 +72,7 @@ Object.defineProperties(Credit.prototype, { /** * Whether the credit should be displayed on screen or in a lightbox * @memberof Credit.prototype - * @type {Boolean} + * @type {boolean} */ showOnScreen: { get: function () { @@ -116,7 +116,7 @@ Object.defineProperties(Credit.prototype, { * * @param {Credit} left The first credit * @param {Credit} right The second credit - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Credit.equals = function (left, right) { return ( @@ -132,7 +132,7 @@ Credit.equals = function (left, right) { * Returns true if the credits are equal * * @param {Credit} credit The credit to compare to. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Credit.prototype.equals = function (credit) { return Credit.equals(this, credit); diff --git a/packages/engine/Source/Core/CubicRealPolynomial.js b/packages/engine/Source/Core/CubicRealPolynomial.js index 767cadb2802..b199a322dcb 100644 --- a/packages/engine/Source/Core/CubicRealPolynomial.js +++ b/packages/engine/Source/Core/CubicRealPolynomial.js @@ -11,11 +11,11 @@ const CubicRealPolynomial = {}; /** * Provides the discriminant of the cubic equation from the supplied coefficients. * - * @param {Number} a The coefficient of the 3rd order monomial. - * @param {Number} b The coefficient of the 2nd order monomial. - * @param {Number} c The coefficient of the 1st order monomial. - * @param {Number} d The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. + * @param {number} a The coefficient of the 3rd order monomial. + * @param {number} b The coefficient of the 2nd order monomial. + * @param {number} c The coefficient of the 1st order monomial. + * @param {number} d The coefficient of the 0th order monomial. + * @returns {number} The value of the discriminant. */ CubicRealPolynomial.computeDiscriminant = function (a, b, c, d) { //>>includeStart('debug', pragmas.debug); @@ -155,11 +155,11 @@ function computeRealRoots(a, b, c, d) { /** * Provides the real valued roots of the cubic polynomial with the provided coefficients. * - * @param {Number} a The coefficient of the 3rd order monomial. - * @param {Number} b The coefficient of the 2nd order monomial. - * @param {Number} c The coefficient of the 1st order monomial. - * @param {Number} d The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @param {number} a The coefficient of the 3rd order monomial. + * @param {number} b The coefficient of the 2nd order monomial. + * @param {number} c The coefficient of the 1st order monomial. + * @param {number} d The coefficient of the 0th order monomial. + * @returns {number[]} The real valued roots. */ CubicRealPolynomial.computeRealRoots = function (a, b, c, d) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/CullingVolume.js b/packages/engine/Source/Core/CullingVolume.js index fca05af24f0..080d4a0a768 100644 --- a/packages/engine/Source/Core/CullingVolume.js +++ b/packages/engine/Source/Core/CullingVolume.js @@ -103,7 +103,7 @@ CullingVolume.fromBoundingSphere = function (boundingSphere, result) { /** * Determines whether a bounding volume intersects the culling volume. * - * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. + * @param {object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. * @returns {Intersect} Intersect.OUTSIDE, Intersect.INTERSECTING, or Intersect.INSIDE. */ CullingVolume.prototype.computeVisibility = function (boundingVolume) { @@ -132,12 +132,12 @@ CullingVolume.prototype.computeVisibility = function (boundingVolume) { /** * Determines whether a bounding volume intersects the culling volume. * - * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. - * @param {Number} parentPlaneMask A bit mask from the boundingVolume's parent's check against the same culling + * @param {object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. + * @param {number} parentPlaneMask A bit mask from the boundingVolume's parent's check against the same culling * volume, such that if (planeMask & (1 << planeIndex) === 0), for k < 31, then * the parent (and therefore this) volume is completely inside plane[planeIndex] * and that plane check can be skipped. - * @returns {Number} A plane mask as described above (which can be applied to this boundingVolume's children). + * @returns {number} A plane mask as described above (which can be applied to this boundingVolume's children). * * @private */ @@ -192,7 +192,7 @@ CullingVolume.prototype.computeVisibilityWithPlaneMask = function ( * For plane masks (as used in {@link CullingVolume#computeVisibilityWithPlaneMask}), this special value * represents the case where the object bounding volume is entirely outside the culling volume. * - * @type {Number} + * @type {number} * @private */ CullingVolume.MASK_OUTSIDE = 0xffffffff; @@ -201,7 +201,7 @@ CullingVolume.MASK_OUTSIDE = 0xffffffff; * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value * represents the case where the object bounding volume is entirely inside the culling volume. * - * @type {Number} + * @type {number} * @private */ CullingVolume.MASK_INSIDE = 0x00000000; @@ -210,7 +210,7 @@ CullingVolume.MASK_INSIDE = 0x00000000; * For plane masks (as used in {@link CullingVolume.prototype.computeVisibilityWithPlaneMask}), this value * represents the case where the object bounding volume (may) intersect all planes of the culling volume. * - * @type {Number} + * @type {number} * @private */ CullingVolume.MASK_INDETERMINATE = 0x7fffffff; diff --git a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js index adfeaa4f0eb..d4328b00882 100644 --- a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js +++ b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js @@ -10,10 +10,10 @@ import TerrainProvider from "./TerrainProvider.js"; /** * @callback CustomHeightmapTerrainProvider.GeometryCallback - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Number[]|Promise.<Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|Number[]>|undefined} An array or a promise to an array of heights in row-major order. If undefined, the globe will render the parent tile. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|number[]|Promise<Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array|number[]>|undefined} An array or a promise to an array of heights in row-major order. If undefined, the globe will render the parent tile. */ /** @@ -28,17 +28,17 @@ import TerrainProvider from "./TerrainProvider.js"; * @alias CustomHeightmapTerrainProvider * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {CustomHeightmapTerrainProvider.GeometryCallback} options.callback The callback function for requesting tile geometry. - * @param {Number} options.width The number of columns per heightmap tile. - * @param {Number} options.height The number of rows per heightmap tile. + * @param {number} options.width The number of columns per heightmap tile. + * @param {number} options.height The number of rows per heightmap tile. * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal * surface is broken into tiles. If this parameter is not provided, a {@link GeographicTilingScheme} * is used. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. * * @example * const viewer = new Cesium.Viewer("cesiumContainer", { @@ -135,7 +135,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -147,7 +147,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -163,7 +163,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { * Water mask is not supported by {@link CustomHeightmapTerrainProvider}, so the return * value will always be false. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -177,7 +177,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { * Vertex normals are not supported by {@link CustomHeightmapTerrainProvider}, so the return * value will always be false. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -189,7 +189,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { /** * Gets the number of columns per heightmap tile. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ width: { @@ -201,7 +201,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { /** * Gets the number of rows per heightmap tile. * @memberof CustomHeightmapTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ height: { @@ -215,12 +215,12 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { * Requests the geometry for a given tile. The result includes terrain * data and indicates that all child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. */ @@ -241,7 +241,7 @@ CustomHeightmapTerrainProvider.prototype.requestTileGeometry = function ( return Promise.resolve(promise).then(function (heightmapData) { let buffer = heightmapData; if (Array.isArray(buffer)) { - // HeightmapTerrainData expects a TypedArray, so convert from Number[] to Float64Array + // HeightmapTerrainData expects a TypedArray, so convert from number[] to Float64Array buffer = new Float64Array(buffer); } @@ -256,8 +256,8 @@ CustomHeightmapTerrainProvider.prototype.requestTileGeometry = function ( /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ CustomHeightmapTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -268,10 +268,10 @@ CustomHeightmapTerrainProvider.prototype.getLevelMaximumGeometricError = functio /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported, otherwise true or false. */ CustomHeightmapTerrainProvider.prototype.getTileDataAvailable = function ( x, @@ -284,9 +284,9 @@ CustomHeightmapTerrainProvider.prototype.getTileDataAvailable = function ( /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined|Promise<void>} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded */ CustomHeightmapTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/CylinderGeometry.js b/packages/engine/Source/Core/CylinderGeometry.js index bfaf8e06a85..a2b620c57a7 100644 --- a/packages/engine/Source/Core/CylinderGeometry.js +++ b/packages/engine/Source/Core/CylinderGeometry.js @@ -27,11 +27,11 @@ const positionScratch = new Cartesian3(); * @alias CylinderGeometry * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number} options.length The length of the cylinder. - * @param {Number} options.topRadius The radius of the top of the cylinder. - * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. - * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. + * @param {object} options Object with the following properties: + * @param {number} options.length The length of the cylinder. + * @param {number} options.topRadius The radius of the top of the cylinder. + * @param {number} options.bottomRadius The radius of the bottom of the cylinder. + * @param {number} [options.slices=128] The number of edges around the perimeter of the cylinder. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * * @exception {DeveloperError} options.slices must be greater than or equal to 3. @@ -92,7 +92,7 @@ function CylinderGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ CylinderGeometry.packedLength = VertexFormat.packedLength + 5; @@ -100,10 +100,10 @@ CylinderGeometry.packedLength = VertexFormat.packedLength + 5; * Stores the provided instance into the provided array. * * @param {CylinderGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CylinderGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -142,8 +142,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CylinderGeometry} [result] The object into which to store the result. * @returns {CylinderGeometry} The modified result parameter or a new CylinderGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/CylinderOutlineGeometry.js b/packages/engine/Source/Core/CylinderOutlineGeometry.js index b639e07cbcf..bd587dcb408 100644 --- a/packages/engine/Source/Core/CylinderOutlineGeometry.js +++ b/packages/engine/Source/Core/CylinderOutlineGeometry.js @@ -22,12 +22,12 @@ const radiusScratch = new Cartesian2(); * @alias CylinderOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number} options.length The length of the cylinder. - * @param {Number} options.topRadius The radius of the top of the cylinder. - * @param {Number} options.bottomRadius The radius of the bottom of the cylinder. - * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder. + * @param {object} options Object with the following properties: + * @param {number} options.length The length of the cylinder. + * @param {number} options.topRadius The radius of the top of the cylinder. + * @param {number} options.bottomRadius The radius of the bottom of the cylinder. + * @param {number} [options.slices=128] The number of edges around the perimeter of the cylinder. + * @param {number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder. * * @exception {DeveloperError} options.length must be greater than 0. * @exception {DeveloperError} options.topRadius must be greater than 0. @@ -84,7 +84,7 @@ function CylinderOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ CylinderOutlineGeometry.packedLength = 6; @@ -92,10 +92,10 @@ CylinderOutlineGeometry.packedLength = 6; * Stores the provided instance into the provided array. * * @param {CylinderOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ CylinderOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -127,8 +127,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {CylinderOutlineGeometry} [result] The object into which to store the result. * @returns {CylinderOutlineGeometry} The modified result parameter or a new CylinderOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/DefaultProxy.js b/packages/engine/Source/Core/DefaultProxy.js index 17b3badb71b..8000b305da2 100644 --- a/packages/engine/Source/Core/DefaultProxy.js +++ b/packages/engine/Source/Core/DefaultProxy.js @@ -6,7 +6,7 @@ * @constructor * @extends {Proxy} * - * @param {String} proxy The proxy URL that will be used to requests all resources. + * @param {string} proxy The proxy URL that will be used to requests all resources. */ function DefaultProxy(proxy) { this.proxy = proxy; @@ -15,8 +15,8 @@ function DefaultProxy(proxy) { /** * Get the final URL to use to request a given resource. * - * @param {String} resource The resource to request. - * @returns {String} proxied resource + * @param {string} resource The resource to request. + * @returns {string} proxied resource */ DefaultProxy.prototype.getURL = function (resource) { const prefix = this.proxy.indexOf("?") === -1 ? "?" : ""; diff --git a/packages/engine/Source/Core/DeveloperError.js b/packages/engine/Source/Core/DeveloperError.js index 142af569e4d..a330471eef2 100644 --- a/packages/engine/Source/Core/DeveloperError.js +++ b/packages/engine/Source/Core/DeveloperError.js @@ -14,21 +14,21 @@ import defined from "./defined.js"; * @constructor * @extends Error * - * @param {String} [message] The error message for this exception. + * @param {string} [message] The error message for this exception. * * @see RuntimeError */ function DeveloperError(message) { /** * 'DeveloperError' indicating that this exception was thrown due to a developer error. - * @type {String} + * @type {string} * @readonly */ this.name = "DeveloperError"; /** * The explanation for why this exception was thrown. - * @type {String} + * @type {string} * @readonly */ this.message = message; @@ -43,7 +43,7 @@ function DeveloperError(message) { /** * The stack trace of this exception, if available. - * @type {String} + * @type {string} * @readonly */ this.stack = stack; diff --git a/packages/engine/Source/Core/DistanceDisplayCondition.js b/packages/engine/Source/Core/DistanceDisplayCondition.js index 31c3a26a04e..e00e08aec34 100644 --- a/packages/engine/Source/Core/DistanceDisplayCondition.js +++ b/packages/engine/Source/Core/DistanceDisplayCondition.js @@ -8,8 +8,8 @@ import DeveloperError from "./DeveloperError.js"; * @alias DistanceDisplayCondition * @constructor * - * @param {Number} [near=0.0] The smallest distance in the interval where the object is visible. - * @param {Number} [far=Number.MAX_VALUE] The largest distance in the interval where the object is visible. + * @param {number} [near=0.0] The smallest distance in the interval where the object is visible. + * @param {number} [far=Number.MAX_VALUE] The largest distance in the interval where the object is visible. * * @example * // Make a billboard that is only visible when the distance to the camera is between 10 and 20 meters. @@ -27,7 +27,7 @@ Object.defineProperties(DistanceDisplayCondition.prototype, { /** * The smallest distance in the interval where the object is visible. * @memberof DistanceDisplayCondition.prototype - * @type {Number} + * @type {number} * @default 0.0 */ near: { @@ -41,7 +41,7 @@ Object.defineProperties(DistanceDisplayCondition.prototype, { /** * The largest distance in the interval where the object is visible. * @memberof DistanceDisplayCondition.prototype - * @type {Number} + * @type {number} * @default Number.MAX_VALUE */ far: { @@ -56,7 +56,7 @@ Object.defineProperties(DistanceDisplayCondition.prototype, { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ DistanceDisplayCondition.packedLength = 2; @@ -64,10 +64,10 @@ DistanceDisplayCondition.packedLength = 2; * Stores the provided instance into the provided array. * * @param {DistanceDisplayCondition} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ DistanceDisplayCondition.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -90,8 +90,8 @@ DistanceDisplayCondition.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {DistanceDisplayCondition} [result] The object into which to store the result. * @returns {DistanceDisplayCondition} The modified result parameter or a new DistanceDisplayCondition instance if one was not provided. */ @@ -117,7 +117,7 @@ DistanceDisplayCondition.unpack = function (array, startingIndex, result) { * * @param {DistanceDisplayCondition} left A distance display condition. * @param {DistanceDisplayCondition} right Another distance display condition. - * @return {Boolean} Whether the two distance display conditions are equal. + * @return {boolean} Whether the two distance display conditions are equal. */ DistanceDisplayCondition.equals = function (left, right) { return ( @@ -164,7 +164,7 @@ DistanceDisplayCondition.prototype.clone = function (result) { * Determines if this distance display condition is equal to another. * * @param {DistanceDisplayCondition} other Another distance display condition. - * @return {Boolean} Whether this distance display condition is equal to the other. + * @return {boolean} Whether this distance display condition is equal to the other. */ DistanceDisplayCondition.prototype.equals = function (other) { return DistanceDisplayCondition.equals(this, other); diff --git a/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js b/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js index b6a35ca8c9d..e962c9b0a2c 100644 --- a/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js @@ -9,8 +9,8 @@ import DeveloperError from "./DeveloperError.js"; * @alias DistanceDisplayConditionGeometryInstanceAttribute * @constructor * - * @param {Number} [near=0.0] The near distance. - * @param {Number} [far=Number.MAX_VALUE] The far distance. + * @param {number} [near=0.0] The near distance. + * @param {number} [far=Number.MAX_VALUE] The far distance. * * @exception {DeveloperError} far must be greater than near. * @@ -79,7 +79,7 @@ Object.defineProperties( * * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype * - * @type {Number} + * @type {number} * @readonly * * @default 3 @@ -97,7 +97,7 @@ Object.defineProperties( * * @memberof DistanceDisplayConditionGeometryInstanceAttribute.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false diff --git a/packages/engine/Source/Core/DoubleEndedPriorityQueue.js b/packages/engine/Source/Core/DoubleEndedPriorityQueue.js index 85725846311..e0abcf5f6e0 100644 --- a/packages/engine/Source/Core/DoubleEndedPriorityQueue.js +++ b/packages/engine/Source/Core/DoubleEndedPriorityQueue.js @@ -10,9 +10,9 @@ import defined from "./defined.js"; * @constructor * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {DoubleEndedPriorityQueue.ComparatorCallback} options.comparator The comparator to use for the queue. If comparator(a, b) is less than 0, a is lower priority than b. - * @param {Number} [options.maximumLength] The maximum length of the queue. If an element is inserted when the queue is at full capacity, the minimum element is removed. By default, the size of the queue is unlimited. + * @param {number} [options.maximumLength] The maximum length of the queue. If an element is inserted when the queue is at full capacity, the minimum element is removed. By default, the size of the queue is unlimited. */ function DoubleEndedPriorityQueue(options) { //>>includeStart('debug', pragmas.debug); @@ -41,7 +41,7 @@ Object.defineProperties(DoubleEndedPriorityQueue.prototype, { * * @memberof DoubleEndedPriorityQueue.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -58,7 +58,7 @@ Object.defineProperties(DoubleEndedPriorityQueue.prototype, { * * @memberof DoubleEndedPriorityQueue.prototype * - * @type {Number} + * @type {number} * @readonly */ maximumLength: { @@ -400,6 +400,6 @@ function pushDown(that, index) { * @callback DoubleEndedPriorityQueue.ComparatorCallback * @param {*} a An element in the queue. * @param {*} b An element in the queue. - * @returns {Number} If the result of the comparison is less than 0, a is lower priority than b. + * @returns {number} If the result of the comparison is less than 0, a is lower priority than b. */ export default DoubleEndedPriorityQueue; diff --git a/packages/engine/Source/Core/EarthOrientationParameters.js b/packages/engine/Source/Core/EarthOrientationParameters.js index 7dcec084254..514d9284a58 100644 --- a/packages/engine/Source/Core/EarthOrientationParameters.js +++ b/packages/engine/Source/Core/EarthOrientationParameters.js @@ -20,11 +20,11 @@ import TimeStandard from "./TimeStandard.js"; * @alias EarthOrientationParameters * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Object} [options.data] The actual EOP data. If neither this + * @param {object} [options] Object with the following properties: + * @param {object} [options.data] The actual EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. - * @param {Boolean} [options.addNewLeapSeconds=true] True if leap seconds that + * @param {boolean} [options.addNewLeapSeconds=true] True if leap seconds that * are specified in the EOP data but not in {@link JulianDate.leapSeconds} * should be added to {@link JulianDate.leapSeconds}. False if * new leap seconds should be handled correctly in the context @@ -75,12 +75,12 @@ function EarthOrientationParameters(options) { /** * - * @param {Resource|String} [url] The URL from which to obtain EOP data. If neither this + * @param {Resource|string} [url] The URL from which to obtain EOP data. If neither this * parameter nor options.data is specified, all EOP values are assumed * to be 0.0. If options.data is specified, this parameter is * ignored. - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.addNewLeapSeconds=true] True if leap seconds that + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.addNewLeapSeconds=true] True if leap seconds that * are specified in the EOP data but not in {@link JulianDate.leapSeconds} * should be added to {@link JulianDate.leapSeconds}. False if * new leap seconds should be handled correctly in the context diff --git a/packages/engine/Source/Core/EarthOrientationParametersSample.js b/packages/engine/Source/Core/EarthOrientationParametersSample.js index 2dbc856954d..336e564da4b 100644 --- a/packages/engine/Source/Core/EarthOrientationParametersSample.js +++ b/packages/engine/Source/Core/EarthOrientationParametersSample.js @@ -4,11 +4,11 @@ * @alias EarthOrientationParametersSample * @constructor * - * @param {Number} xPoleWander The pole wander about the X axis, in radians. - * @param {Number} yPoleWander The pole wander about the Y axis, in radians. - * @param {Number} xPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. - * @param {Number} yPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. - * @param {Number} ut1MinusUtc The difference in time standards, UT1 - UTC, in seconds. + * @param {number} xPoleWander The pole wander about the X axis, in radians. + * @param {number} yPoleWander The pole wander about the Y axis, in radians. + * @param {number} xPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. + * @param {number} yPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. + * @param {number} ut1MinusUtc The difference in time standards, UT1 - UTC, in seconds. * * @private */ @@ -21,31 +21,31 @@ function EarthOrientationParametersSample( ) { /** * The pole wander about the X axis, in radians. - * @type {Number} + * @type {number} */ this.xPoleWander = xPoleWander; /** * The pole wander about the Y axis, in radians. - * @type {Number} + * @type {number} */ this.yPoleWander = yPoleWander; /** * The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. - * @type {Number} + * @type {number} */ this.xPoleOffset = xPoleOffset; /** * The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. - * @type {Number} + * @type {number} */ this.yPoleOffset = yPoleOffset; /** * The difference in time standards, UT1 - UTC, in seconds. - * @type {Number} + * @type {number} */ this.ut1MinusUtc = ut1MinusUtc; } diff --git a/packages/engine/Source/Core/EasingFunction.js b/packages/engine/Source/Core/EasingFunction.js index 8baaf38d28e..0b8cc00c2e8 100644 --- a/packages/engine/Source/Core/EasingFunction.js +++ b/packages/engine/Source/Core/EasingFunction.js @@ -240,8 +240,8 @@ const EasingFunction = { /** * Function interface for implementing a custom easing function. * @callback EasingFunction.Callback - * @param {Number} time The time in the range <code>[0, 1]</code>. - * @returns {Number} The value of the function at the given time. + * @param {number} time The time in the range <code>[0, 1]</code>. + * @returns {number} The value of the function at the given time. * * @example * function quadraticIn(time) { diff --git a/packages/engine/Source/Core/EllipseGeometry.js b/packages/engine/Source/Core/EllipseGeometry.js index b7ecda453b1..483ec135780 100644 --- a/packages/engine/Source/Core/EllipseGeometry.js +++ b/packages/engine/Source/Core/EllipseGeometry.js @@ -888,16 +888,16 @@ function computeRectangle( * @alias EllipseGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. - * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. - * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. + * @param {number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. + * @param {number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. - * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates counter-clockwise from north. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. + * @param {number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. + * @param {number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. + * @param {number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates counter-clockwise from north. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. @@ -967,7 +967,7 @@ function EllipseGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ EllipseGeometry.packedLength = Cartesian3.packedLength + @@ -979,10 +979,10 @@ EllipseGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {EllipseGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ EllipseGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -1035,8 +1035,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {EllipseGeometry} [result] The object into which to store the result. * @returns {EllipseGeometry} The modified result parameter or a new EllipseGeometry instance if one was not provided. */ @@ -1105,13 +1105,13 @@ EllipseGeometry.unpack = function (array, startingIndex, result) { /** * Computes the bounding rectangle based on the provided options * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. - * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. - * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. + * @param {number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. + * @param {number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. - * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. + * @param {number} [options.rotation=0.0] The angle of rotation counter-clockwise from north. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians. * @param {Rectangle} [result] An object in which to store the result * * @returns {Rectangle} The result rectangle diff --git a/packages/engine/Source/Core/EllipseOutlineGeometry.js b/packages/engine/Source/Core/EllipseOutlineGeometry.js index 5a18e4f7e31..3593c2db0b9 100644 --- a/packages/engine/Source/Core/EllipseOutlineGeometry.js +++ b/packages/engine/Source/Core/EllipseOutlineGeometry.js @@ -184,16 +184,16 @@ function computeExtrudedEllipse(options) { * @alias EllipseOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.center The ellipse's center point in the fixed frame. - * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. - * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. + * @param {number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters. + * @param {number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on. - * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians. - * @param {Number} [options.granularity=0.02] The angular distance between points on the ellipse in radians. - * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse. + * @param {number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface. + * @param {number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface. + * @param {number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians. + * @param {number} [options.granularity=0.02] The angular distance between points on the ellipse in radians. + * @param {number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse. * * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero. * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis. @@ -263,7 +263,7 @@ function EllipseOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ EllipseOutlineGeometry.packedLength = Cartesian3.packedLength + Ellipsoid.packedLength + 8; @@ -272,10 +272,10 @@ EllipseOutlineGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {EllipseOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ EllipseOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -325,8 +325,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {EllipseOutlineGeometry} [result] The object into which to store the result. * @returns {EllipseOutlineGeometry} The modified result parameter or a new EllipseOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/Ellipsoid.js b/packages/engine/Source/Core/Ellipsoid.js index 184dec48833..88e7937e622 100644 --- a/packages/engine/Source/Core/Ellipsoid.js +++ b/packages/engine/Source/Core/Ellipsoid.js @@ -62,9 +62,9 @@ function initialize(ellipsoid, x, y, z) { * @alias Ellipsoid * @constructor * - * @param {Number} [x=0] The radius in the x direction. - * @param {Number} [y=0] The radius in the y direction. - * @param {Number} [z=0] The radius in the z direction. + * @param {number} [x=0] The radius in the x direction. + * @param {number} [y=0] The radius in the y direction. + * @param {number} [z=0] The radius in the z direction. * * @exception {DeveloperError} All radii components must be greater than or equal to zero. * @@ -145,7 +145,7 @@ Object.defineProperties(Ellipsoid.prototype, { /** * Gets the minimum radius of the ellipsoid. * @memberof Ellipsoid.prototype - * @type {Number} + * @type {number} * @readonly */ minimumRadius: { @@ -156,7 +156,7 @@ Object.defineProperties(Ellipsoid.prototype, { /** * Gets the maximum radius of the ellipsoid. * @memberof Ellipsoid.prototype - * @type {Number} + * @type {number} * @readonly */ maximumRadius: { @@ -267,7 +267,7 @@ Ellipsoid.prototype.clone = function (result) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Ellipsoid.packedLength = Cartesian3.packedLength; @@ -275,10 +275,10 @@ Ellipsoid.packedLength = Cartesian3.packedLength; * Stores the provided instance into the provided array. * * @param {Ellipsoid} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Ellipsoid.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -296,8 +296,8 @@ Ellipsoid.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Ellipsoid} [result] The object into which to store the result. * @returns {Ellipsoid} The modified result parameter or a new Ellipsoid instance if one was not provided. */ @@ -618,7 +618,7 @@ Ellipsoid.prototype.transformPositionFromScaledSpace = function ( * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Ellipsoid} [right] The other Ellipsoid. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Ellipsoid.prototype.equals = function (right) { return ( @@ -630,7 +630,7 @@ Ellipsoid.prototype.equals = function (right) { /** * Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'. * - * @returns {String} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'. + * @returns {string} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'. */ Ellipsoid.prototype.toString = function () { return this._radii.toString(); @@ -640,7 +640,7 @@ Ellipsoid.prototype.toString = function () { * Computes a point which is the intersection of the surface normal with the z-axis. * * @param {Cartesian3} position the position. must be on the surface of the ellipsoid. - * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. + * @param {number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid. * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center. * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis). * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2 @@ -714,10 +714,10 @@ const weights = [ /** * Compute the 10th order Gauss-Legendre Quadrature of the given definite integral. * - * @param {Number} a The lower bound for the integration. - * @param {Number} b The upper bound for the integration. + * @param {number} a The lower bound for the integration. + * @param {number} b The upper bound for the integration. * @param {Ellipsoid~RealValuedScalarFunction} func The function to integrate. - * @returns {Number} The value of the integral of the given function over the given domain. + * @returns {number} The value of the integral of the given function over the given domain. * * @private */ @@ -748,8 +748,8 @@ function gaussLegendreQuadrature(a, b, func) { * A real valued scalar function. * @callback Ellipsoid~RealValuedScalarFunction * - * @param {Number} x The value used to evaluate the function. - * @returns {Number} The value of the function at x. + * @param {number} x The value used to evaluate the function. + * @returns {number} The value of the function at x. * * @private */ @@ -759,7 +759,7 @@ function gaussLegendreQuadrature(a, b, func) { * Gauss-Legendre 10th order quadrature. * * @param {Rectangle} rectangle The rectangle used for computing the surface area. - * @returns {Number} The approximate area of the rectangle on the surface of this ellipsoid. + * @returns {number} The approximate area of the rectangle on the surface of this ellipsoid. */ Ellipsoid.prototype.surfaceArea = function (rectangle) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/EllipsoidGeodesic.js b/packages/engine/Source/Core/EllipsoidGeodesic.js index 99256cfeaeb..6416b824114 100644 --- a/packages/engine/Source/Core/EllipsoidGeodesic.js +++ b/packages/engine/Source/Core/EllipsoidGeodesic.js @@ -315,7 +315,7 @@ Object.defineProperties(EllipsoidGeodesic.prototype, { /** * Gets the surface distance between the start and end point * @memberof EllipsoidGeodesic.prototype - * @type {Number} + * @type {number} * @readonly */ surfaceDistance: { @@ -355,7 +355,7 @@ Object.defineProperties(EllipsoidGeodesic.prototype, { /** * Gets the heading at the initial point. * @memberof EllipsoidGeodesic.prototype - * @type {Number} + * @type {number} * @readonly */ startHeading: { @@ -371,7 +371,7 @@ Object.defineProperties(EllipsoidGeodesic.prototype, { /** * Gets the heading at the final point. * @memberof EllipsoidGeodesic.prototype - * @type {Number} + * @type {number} * @readonly */ endHeading: { @@ -403,7 +403,7 @@ EllipsoidGeodesic.prototype.setEndPoints = function (start, end) { /** * Provides the location of a point at the indicated portion along the geodesic. * - * @param {Number} fraction The portion of the distance between the initial and final points. + * @param {number} fraction The portion of the distance between the initial and final points. * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the point along the geodesic. */ @@ -420,7 +420,7 @@ EllipsoidGeodesic.prototype.interpolateUsingFraction = function ( /** * Provides the location of a point at the indicated distance along the geodesic. * - * @param {Number} distance The distance from the inital point to the point of interest along the geodesic + * @param {number} distance The distance from the inital point to the point of interest along the geodesic * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the point along the geodesic. * diff --git a/packages/engine/Source/Core/EllipsoidGeometry.js b/packages/engine/Source/Core/EllipsoidGeometry.js index e7ea3db9020..e6a8409dc78 100644 --- a/packages/engine/Source/Core/EllipsoidGeometry.js +++ b/packages/engine/Source/Core/EllipsoidGeometry.js @@ -31,15 +31,15 @@ const sin = Math.sin; * @alias EllipsoidGeometry * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. * @param {Cartesian3} [options.innerRadii=options.radii] The inner radii of the ellipsoid in the x, y, and z directions. - * @param {Number} [options.minimumClock=0.0] The minimum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [options.maximumClock=2*PI] The maximum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [options.minimumCone=0.0] The minimum angle measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [options.maximumCone=PI] The maximum angle measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. - * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. + * @param {number} [options.minimumClock=0.0] The minimum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {number} [options.maximumClock=2*PI] The maximum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {number} [options.minimumCone=0.0] The minimum angle measured from the positive z-axis and toward the negative z-axis. + * @param {number} [options.maximumCone=PI] The maximum angle measured from the positive z-axis and toward the negative z-axis. + * @param {number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. + * @param {number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * * @exception {DeveloperError} options.slicePartitions cannot be less than three. @@ -95,7 +95,7 @@ function EllipsoidGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ EllipsoidGeometry.packedLength = 2 * Cartesian3.packedLength + VertexFormat.packedLength + 7; @@ -104,10 +104,10 @@ EllipsoidGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {EllipsoidGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ EllipsoidGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -160,8 +160,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {EllipsoidGeometry} [result] The object into which to store the result. * @returns {EllipsoidGeometry} The modified result parameter or a new EllipsoidGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/EllipsoidOutlineGeometry.js b/packages/engine/Source/Core/EllipsoidOutlineGeometry.js index 7b24cb420f4..53b1fd403a9 100644 --- a/packages/engine/Source/Core/EllipsoidOutlineGeometry.js +++ b/packages/engine/Source/Core/EllipsoidOutlineGeometry.js @@ -23,16 +23,16 @@ const sin = Math.sin; * @alias EllipsoidOutlineGeometry * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions. * @param {Cartesian3} [options.innerRadii=options.radii] The inner radii of the ellipsoid in the x, y, and z directions. - * @param {Number} [options.minimumClock=0.0] The minimum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [options.maximumClock=2*PI] The maximum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [options.minimumCone=0.0] The minimum angle measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [options.maximumCone=PI] The maximum angle measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines). - * @param {Number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines). - * @param {Number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature. + * @param {number} [options.minimumClock=0.0] The minimum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {number} [options.maximumClock=2*PI] The maximum angle lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {number} [options.minimumCone=0.0] The minimum angle measured from the positive z-axis and toward the negative z-axis. + * @param {number} [options.maximumCone=PI] The maximum angle measured from the positive z-axis and toward the negative z-axis. + * @param {number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines). + * @param {number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines). + * @param {number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature. * * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. @@ -96,7 +96,7 @@ function EllipsoidOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ EllipsoidOutlineGeometry.packedLength = 2 * Cartesian3.packedLength + 8; @@ -104,10 +104,10 @@ EllipsoidOutlineGeometry.packedLength = 2 * Cartesian3.packedLength + 8; * Stores the provided instance into the provided array. * * @param {EllipsoidOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ EllipsoidOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -157,8 +157,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {EllipsoidOutlineGeometry} [result] The object into which to store the result. * @returns {EllipsoidOutlineGeometry} The modified result parameter or a new EllipsoidOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/EllipsoidRhumbLine.js b/packages/engine/Source/Core/EllipsoidRhumbLine.js index adfa9089f29..047d48e8796 100644 --- a/packages/engine/Source/Core/EllipsoidRhumbLine.js +++ b/packages/engine/Source/Core/EllipsoidRhumbLine.js @@ -415,7 +415,7 @@ Object.defineProperties(EllipsoidRhumbLine.prototype, { /** * Gets the surface distance between the start and end point * @memberof EllipsoidRhumbLine.prototype - * @type {Number} + * @type {number} * @readonly */ surfaceDistance: { @@ -455,7 +455,7 @@ Object.defineProperties(EllipsoidRhumbLine.prototype, { /** * Gets the heading from the start point to the end point. * @memberof EllipsoidRhumbLine.prototype - * @type {Number} + * @type {number} * @readonly */ heading: { @@ -473,8 +473,8 @@ Object.defineProperties(EllipsoidRhumbLine.prototype, { * Create a rhumb line using an initial position with a heading and distance. * * @param {Cartographic} start The initial planetodetic point on the path. - * @param {Number} heading The heading in radians. - * @param {Number} distance The rhumb line distance between the start and end point. + * @param {number} heading The heading in radians. + * @param {number} distance The rhumb line distance between the start and end point. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rhumb line lies. * @param {EllipsoidRhumbLine} [result] The object in which to store the result. * @returns {EllipsoidRhumbLine} The EllipsoidRhumbLine object. @@ -538,7 +538,7 @@ EllipsoidRhumbLine.prototype.setEndPoints = function (start, end) { /** * Provides the location of a point at the indicated portion along the rhumb line. * - * @param {Number} fraction The portion of the distance between the initial and final points. + * @param {number} fraction The portion of the distance between the initial and final points. * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the point along the rhumb line. */ @@ -555,7 +555,7 @@ EllipsoidRhumbLine.prototype.interpolateUsingFraction = function ( /** * Provides the location of a point at the indicated distance along the rhumb line. * - * @param {Number} distance The distance from the inital point to the point of interest along the rhumbLine. + * @param {number} distance The distance from the inital point to the point of interest along the rhumbLine. * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the point along the rhumb line. * @@ -588,7 +588,7 @@ EllipsoidRhumbLine.prototype.interpolateUsingSurfaceDistance = function ( * Provides the location of a point at the indicated longitude along the rhumb line. * If the longitude is outside the range of start and end points, the first intersection with the longitude from the start point in the direction of the heading is returned. This follows the spiral property of a rhumb line. * - * @param {Number} intersectionLongitude The longitude, in radians, at which to find the intersection point from the starting point using the heading. + * @param {number} intersectionLongitude The longitude, in radians, at which to find the intersection point from the starting point using the heading. * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the intersection point along the rhumb line, undefined if there is no intersection or infinite intersections. * @@ -692,7 +692,7 @@ EllipsoidRhumbLine.prototype.findIntersectionWithLongitude = function ( * Provides the location of a point at the indicated latitude along the rhumb line. * If the latitude is outside the range of start and end points, the first intersection with the latitude from that start point in the direction of the heading is returned. This follows the spiral property of a rhumb line. * - * @param {Number} intersectionLatitude The latitude, in radians, at which to find the intersection point from the starting point using the heading. + * @param {number} intersectionLatitude The latitude, in radians, at which to find the intersection point from the starting point using the heading. * @param {Cartographic} [result] The object in which to store the result. * @returns {Cartographic} The location of the intersection point along the rhumb line, undefined if there is no intersection or infinite intersections. * diff --git a/packages/engine/Source/Core/EllipsoidTerrainProvider.js b/packages/engine/Source/Core/EllipsoidTerrainProvider.js index 29857362fbf..7ef3f155401 100644 --- a/packages/engine/Source/Core/EllipsoidTerrainProvider.js +++ b/packages/engine/Source/Core/EllipsoidTerrainProvider.js @@ -13,7 +13,7 @@ import TerrainProvider from "./TerrainProvider.js"; * @alias EllipsoidTerrainProvider * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal * surface is broken into tiles. If this parameter is not provided, a {@link GeographicTilingScheme} * is used. @@ -89,7 +89,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -101,7 +101,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof EllipsoidTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -116,7 +116,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link EllipsoidTerrainProvider#ready} returns true. * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -129,7 +129,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. * @memberof EllipsoidTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -158,12 +158,12 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { * {@link TerrainProvider#ready} returns true. The result includes terrain * data and indicates that all child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. */ @@ -187,8 +187,8 @@ EllipsoidTerrainProvider.prototype.requestTileGeometry = function ( /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ EllipsoidTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -199,10 +199,10 @@ EllipsoidTerrainProvider.prototype.getLevelMaximumGeometricError = function ( /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported, otherwise true or false. */ EllipsoidTerrainProvider.prototype.getTileDataAvailable = function ( x, @@ -215,9 +215,9 @@ EllipsoidTerrainProvider.prototype.getTileDataAvailable = function ( /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined} This provider does not support loading availability. */ EllipsoidTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/EllipsoidalOccluder.js b/packages/engine/Source/Core/EllipsoidalOccluder.js index 02ae7e6f730..e94d8bbcbf3 100644 --- a/packages/engine/Source/Core/EllipsoidalOccluder.js +++ b/packages/engine/Source/Core/EllipsoidalOccluder.js @@ -87,7 +87,7 @@ const scratchCartesian = new Cartesian3(); * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. * * @param {Cartesian3} occludee The point to test for visibility. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. * * @example * const cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); @@ -115,7 +115,7 @@ EllipsoidalOccluder.prototype.isPointVisible = function (occludee) { * into the scaled space, call {@link Ellipsoid#transformPositionToScaledSpace}. * * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. * * @example * const cameraPosition = new Cesium.Cartesian3(0, 0, 2.5); @@ -145,7 +145,7 @@ const scratchCameraPositionInScaledSpaceShrunk = new Cartesian3(); * {@link EllipsoidalOccluder#computeHorizonCullingPointFromVerticesPossiblyUnderEllipsoid}. * * @param {Cartesian3} occludeeScaledSpacePosition The point to test for visibility, represented in the scaled space of the possibly-shrunk ellipsoid. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. */ EllipsoidalOccluder.prototype.isScaledSpacePointVisiblePossiblyUnderEllipsoid = function ( occludeeScaledSpacePosition, @@ -222,7 +222,7 @@ const scratchEllipsoidShrunk = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE); * @param {Cartesian3[]} positions The positions from which to compute the horizon culling point. The positions * must be expressed in a reference frame centered at the ellipsoid and aligned with the * ellipsoid's axes. - * @param {Number} [minimumHeight] The minimum height of all positions. If this value is undefined, all positions are assumed to be above the ellipsoid. + * @param {number} [minimumHeight] The minimum height of all positions. If this value is undefined, all positions are assumed to be above the ellipsoid. * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. * @returns {Cartesian3} The computed horizon culling point, expressed in the possibly-shrunk ellipsoid-scaled space. */ @@ -254,10 +254,10 @@ EllipsoidalOccluder.prototype.computeHorizonCullingPointPossiblyUnderEllipsoid = * A reasonable direction to use is the direction from the center of the ellipsoid to * the center of the bounding sphere computed from the positions. The direction need not * be normalized. - * @param {Number[]} vertices The vertices from which to compute the horizon culling point. The positions + * @param {number[]} vertices The vertices from which to compute the horizon culling point. The positions * must be expressed in a reference frame centered at the ellipsoid and aligned with the * ellipsoid's axes. - * @param {Number} [stride=3] + * @param {number} [stride=3] * @param {Cartesian3} [center=Cartesian3.ZERO] * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. * @returns {Cartesian3} The computed horizon culling point, expressed in the ellipsoid-scaled space. @@ -289,12 +289,12 @@ EllipsoidalOccluder.prototype.computeHorizonCullingPointFromVertices = function * A reasonable direction to use is the direction from the center of the ellipsoid to * the center of the bounding sphere computed from the positions. The direction need not * be normalized. - * @param {Number[]} vertices The vertices from which to compute the horizon culling point. The positions + * @param {number[]} vertices The vertices from which to compute the horizon culling point. The positions * must be expressed in a reference frame centered at the ellipsoid and aligned with the * ellipsoid's axes. - * @param {Number} [stride=3] + * @param {number} [stride=3] * @param {Cartesian3} [center=Cartesian3.ZERO] - * @param {Number} [minimumHeight] The minimum height of all vertices. If this value is undefined, all vertices are assumed to be above the ellipsoid. + * @param {number} [minimumHeight] The minimum height of all vertices. If this value is undefined, all vertices are assumed to be above the ellipsoid. * @param {Cartesian3} [result] The instance on which to store the result instead of allocating a new instance. * @returns {Cartesian3} The computed horizon culling point, expressed in the possibly-shrunk ellipsoid-scaled space. */ diff --git a/packages/engine/Source/Core/EncodedCartesian3.js b/packages/engine/Source/Core/EncodedCartesian3.js index 45bac72ee95..b6df42a5ffd 100644 --- a/packages/engine/Source/Core/EncodedCartesian3.js +++ b/packages/engine/Source/Core/EncodedCartesian3.js @@ -41,9 +41,9 @@ function EncodedCartesian3() { * The fixed-point encoding follows {@link http://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}. * </p> * - * @param {Number} value The floating-point value to encode. - * @param {Object} [result] The object onto which to store the result. - * @returns {Object} The modified result parameter or a new instance if one was not provided. + * @param {number} value The floating-point value to encode. + * @param {object} [result] The object onto which to store the result. + * @returns {object} The modified result parameter or a new instance if one was not provided. * * @example * const value = 1234567.1234567; @@ -132,8 +132,8 @@ const encodedP = new EncodedCartesian3(); * </p> * * @param {Cartesian3} cartesian The cartesian to encode. - * @param {Number[]} cartesianArray The array to write to. - * @param {Number} index The index into the array to start writing. Six elements will be written. + * @param {number[]} cartesianArray The array to write to. + * @param {number} index The index into the array to start writing. Six elements will be written. * * @exception {DeveloperError} index must be a number greater than or equal to 0. * diff --git a/packages/engine/Source/Core/Event.js b/packages/engine/Source/Core/Event.js index a6c0000da71..cf53ef96605 100644 --- a/packages/engine/Source/Core/Event.js +++ b/packages/engine/Source/Core/Event.js @@ -32,7 +32,7 @@ Object.defineProperties(Event.prototype, { /** * The number of listeners currently subscribed to the event. * @memberof Event.prototype - * @type {Number} + * @type {number} * @readonly */ numberOfListeners: { @@ -48,7 +48,7 @@ Object.defineProperties(Event.prototype, { * in which the function will execute. * * @param {Listener} listener The function to be executed when the event is raised. - * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * @param {object} [scope] An optional object scope to serve as the <code>this</code> * pointer in which the listener function will execute. * @returns {Event.RemoveCallback} A function that will remove this event listener when invoked. * @@ -73,8 +73,8 @@ Event.prototype.addEventListener = function (listener, scope) { * Unregisters a previously registered callback. * * @param {Listener} listener The function to be unregistered. - * @param {Object} [scope] The scope that was originally passed to addEventListener. - * @returns {Boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. + * @param {object} [scope] The scope that was originally passed to addEventListener. + * @returns {boolean} <code>true</code> if the listener was removed; <code>false</code> if the listener and scope are not registered with the event. * * @see Event#addEventListener * @see Event#raiseEvent diff --git a/packages/engine/Source/Core/EventHelper.js b/packages/engine/Source/Core/EventHelper.js index 4ae3a4a0904..e9a024c6459 100644 --- a/packages/engine/Source/Core/EventHelper.js +++ b/packages/engine/Source/Core/EventHelper.js @@ -30,7 +30,7 @@ function EventHelper() { * * @param {Event} event The event to attach to. * @param {Function} listener The function to be executed when the event is raised. - * @param {Object} [scope] An optional object scope to serve as the <code>this</code> + * @param {object} [scope] An optional object scope to serve as the <code>this</code> * pointer in which the listener function will execute. * @returns {EventHelper.RemoveCallback} A function that will remove this event listener when invoked. * diff --git a/packages/engine/Source/Core/ExtrapolationType.js b/packages/engine/Source/Core/ExtrapolationType.js index 0480f15596b..a62b453818a 100644 --- a/packages/engine/Source/Core/ExtrapolationType.js +++ b/packages/engine/Source/Core/ExtrapolationType.js @@ -2,7 +2,7 @@ * Constants to determine how an interpolated value is extrapolated * when querying outside the bounds of available data. * - * @enum {Number} + * @enum {number} * * @see SampledProperty */ @@ -10,7 +10,7 @@ const ExtrapolationType = { /** * No extrapolation occurs. * - * @type {Number} + * @type {number} * @constant */ NONE: 0, @@ -18,7 +18,7 @@ const ExtrapolationType = { /** * The first or last value is used when outside the range of sample data. * - * @type {Number} + * @type {number} * @constant */ HOLD: 1, @@ -26,7 +26,7 @@ const ExtrapolationType = { /** * The value is extrapolated. * - * @type {Number} + * @type {number} * @constant */ EXTRAPOLATE: 2, diff --git a/packages/engine/Source/Core/FeatureDetection.js b/packages/engine/Source/Core/FeatureDetection.js index 410311b8970..e7f41884fe4 100644 --- a/packages/engine/Source/Core/FeatureDetection.js +++ b/packages/engine/Source/Core/FeatureDetection.js @@ -326,7 +326,7 @@ const FeatureDetection = { * Detects whether the current browser supports Basis Universal textures and the web assembly modules needed to transcode them. * * @param {Scene} scene - * @returns {Boolean} true if the browser supports web assembly modules and the scene supports Basis Universal textures, false if not. + * @returns {boolean} true if the browser supports web assembly modules and the scene supports Basis Universal textures, false if not. */ FeatureDetection.supportsBasis = function (scene) { return FeatureDetection.supportsWebAssembly() && scene.context.supportsBasis; @@ -335,7 +335,7 @@ FeatureDetection.supportsBasis = function (scene) { /** * Detects whether the current browser supports the full screen standard. * - * @returns {Boolean} true if the browser supports the full screen standard, false if not. + * @returns {boolean} true if the browser supports the full screen standard, false if not. * * @see Fullscreen * @see {@link http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html|W3C Fullscreen Living Specification} @@ -347,7 +347,7 @@ FeatureDetection.supportsFullscreen = function () { /** * Detects whether the current browser supports typed arrays. * - * @returns {Boolean} true if the browser supports typed arrays, false if not. + * @returns {boolean} true if the browser supports typed arrays, false if not. * * @see {@link https://tc39.es/ecma262/#sec-typedarray-objects|Typed Array Specification} */ @@ -358,7 +358,7 @@ FeatureDetection.supportsTypedArrays = function () { /** * Detects whether the current browser supports BigInt64Array typed arrays. * - * @returns {Boolean} true if the browser supports BigInt64Array typed arrays, false if not. + * @returns {boolean} true if the browser supports BigInt64Array typed arrays, false if not. * * @see {@link https://tc39.es/ecma262/#sec-typedarray-objects|Typed Array Specification} */ @@ -369,7 +369,7 @@ FeatureDetection.supportsBigInt64Array = function () { /** * Detects whether the current browser supports BigUint64Array typed arrays. * - * @returns {Boolean} true if the browser supports BigUint64Array typed arrays, false if not. + * @returns {boolean} true if the browser supports BigUint64Array typed arrays, false if not. * * @see {@link https://tc39.es/ecma262/#sec-typedarray-objects|Typed Array Specification} */ @@ -380,7 +380,7 @@ FeatureDetection.supportsBigUint64Array = function () { /** * Detects whether the current browser supports BigInt. * - * @returns {Boolean} true if the browser supports BigInt, false if not. + * @returns {boolean} true if the browser supports BigInt, false if not. * * @see {@link https://tc39.es/ecma262/#sec-bigint-objects|BigInt Specification} */ @@ -391,7 +391,7 @@ FeatureDetection.supportsBigInt = function () { /** * Detects whether the current browser supports Web Workers. * - * @returns {Boolean} true if the browsers supports Web Workers, false if not. + * @returns {boolean} true if the browsers supports Web Workers, false if not. * * @see {@link http://www.w3.org/TR/workers/} */ @@ -402,7 +402,7 @@ FeatureDetection.supportsWebWorkers = function () { /** * Detects whether the current browser supports Web Assembly. * - * @returns {Boolean} true if the browsers supports Web Assembly, false if not. + * @returns {boolean} true if the browsers supports Web Assembly, false if not. * * @see {@link https://developer.mozilla.org/en-US/docs/WebAssembly} */ @@ -414,7 +414,7 @@ FeatureDetection.supportsWebAssembly = function () { * Detects whether the current browser supports a WebGL2 rendering context for the specified scene. * * @param {Scene} scene the Cesium scene specifying the rendering context - * @returns {Boolean} true if the browser supports a WebGL2 rendering context, false if not. + * @returns {boolean} true if the browser supports a WebGL2 rendering context, false if not. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext|WebGL2RenderingContext} */ diff --git a/packages/engine/Source/Core/FrustumGeometry.js b/packages/engine/Source/Core/FrustumGeometry.js index f19fb633e25..bece354b733 100644 --- a/packages/engine/Source/Core/FrustumGeometry.js +++ b/packages/engine/Source/Core/FrustumGeometry.js @@ -25,7 +25,7 @@ const ORTHOGRAPHIC = 1; * @alias FrustumGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. * @param {Cartesian3} options.origin The origin of the frustum. * @param {Quaternion} options.orientation The orientation of the frustum. @@ -69,7 +69,7 @@ function FrustumGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = 2 + @@ -83,10 +83,10 @@ function FrustumGeometry(options) { * Stores the provided instance into the provided array. * * @param {FrustumGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ FrustumGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -129,8 +129,8 @@ const scratchVertexFormat = new VertexFormat(); /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {FrustumGeometry} [result] The object into which to store the result. */ FrustumGeometry.unpack = function (array, startingIndex, result) { diff --git a/packages/engine/Source/Core/FrustumOutlineGeometry.js b/packages/engine/Source/Core/FrustumOutlineGeometry.js index 73aeb81817a..e49aea1bd14 100644 --- a/packages/engine/Source/Core/FrustumOutlineGeometry.js +++ b/packages/engine/Source/Core/FrustumOutlineGeometry.js @@ -22,7 +22,7 @@ const ORTHOGRAPHIC = 1; * @alias FrustumOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. * @param {Cartesian3} options.origin The origin of the frustum. * @param {Quaternion} options.orientation The orientation of the frustum. @@ -63,7 +63,7 @@ function FrustumOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; @@ -73,10 +73,10 @@ function FrustumOutlineGeometry(options) { * Stores the provided instance into the provided array. * * @param {FrustumOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ FrustumOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -116,8 +116,8 @@ const scratchPackorigin = new Cartesian3(); /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {FrustumOutlineGeometry} [result] The object into which to store the result. */ FrustumOutlineGeometry.unpack = function (array, startingIndex, result) { diff --git a/packages/engine/Source/Core/Fullscreen.js b/packages/engine/Source/Core/Fullscreen.js index b63a51fe5fe..3b18de25a21 100644 --- a/packages/engine/Source/Core/Fullscreen.js +++ b/packages/engine/Source/Core/Fullscreen.js @@ -24,7 +24,7 @@ Object.defineProperties(Fullscreen, { * The element that is currently fullscreen, if any. To simply check if the * browser is in fullscreen mode or not, use {@link Fullscreen#fullscreen}. * @memberof Fullscreen - * @type {Object} + * @type {object} * @readonly */ element: { @@ -43,7 +43,7 @@ Object.defineProperties(Fullscreen, { * In your event handler, to determine if the browser is in fullscreen mode or not, * use {@link Fullscreen#fullscreen}. * @memberof Fullscreen - * @type {String} + * @type {string} * @readonly */ changeEventName: { @@ -60,7 +60,7 @@ Object.defineProperties(Fullscreen, { * The name of the event that is fired when a fullscreen error * occurs. This event name is intended for use with addEventListener. * @memberof Fullscreen - * @type {String} + * @type {string} * @readonly */ errorEventName: { @@ -78,7 +78,7 @@ Object.defineProperties(Fullscreen, { * For example, by default, iframes cannot go fullscreen unless the containing page * adds an "allowfullscreen" attribute (or prefixed equivalent). * @memberof Fullscreen - * @type {Boolean} + * @type {boolean} * @readonly */ enabled: { @@ -94,7 +94,7 @@ Object.defineProperties(Fullscreen, { /** * Determines if the browser is currently in fullscreen mode. * @memberof Fullscreen - * @type {Boolean} + * @type {boolean} * @readonly */ fullscreen: { @@ -111,7 +111,7 @@ Object.defineProperties(Fullscreen, { /** * Detects whether the browser supports the standard fullscreen API. * - * @returns {Boolean} <code>true</code> if the browser supports the standard fullscreen API, + * @returns {boolean} <code>true</code> if the browser supports the standard fullscreen API, * <code>false</code> otherwise. */ Fullscreen.supportsFullscreen = function () { @@ -214,8 +214,8 @@ Fullscreen.supportsFullscreen = function () { * Asynchronously requests the browser to enter fullscreen mode on the given element. * If fullscreen mode is not supported by the browser, does nothing. * - * @param {Object} element The HTML element which will be placed into fullscreen mode. - * @param {Object} [vrDevice] The HMDVRDevice device. + * @param {object} element The HTML element which will be placed into fullscreen mode. + * @param {object} [vrDevice] The HMDVRDevice device. * * @example * // Put the entire page into fullscreen. diff --git a/packages/engine/Source/Core/GeocodeType.js b/packages/engine/Source/Core/GeocodeType.js index f224ab9e406..3348b6d5ffb 100644 --- a/packages/engine/Source/Core/GeocodeType.js +++ b/packages/engine/Source/Core/GeocodeType.js @@ -1,13 +1,13 @@ /** * The type of geocoding to be performed by a {@link GeocoderService}. - * @enum {Number} + * @enum {number} * @see Geocoder */ const GeocodeType = { /** * Perform a search where the input is considered complete. * - * @type {Number} + * @type {number} * @constant */ SEARCH: 0, @@ -16,7 +16,7 @@ const GeocodeType = { * Perform an auto-complete using partial input, typically * reserved for providing possible results as a user is typing. * - * @type {Number} + * @type {number} * @constant */ AUTOCOMPLETE: 1, diff --git a/packages/engine/Source/Core/GeocoderService.js b/packages/engine/Source/Core/GeocoderService.js index 5162da37835..9d5f026c37c 100644 --- a/packages/engine/Source/Core/GeocoderService.js +++ b/packages/engine/Source/Core/GeocoderService.js @@ -1,8 +1,8 @@ import DeveloperError from "./DeveloperError.js"; /** - * @typedef {Object} GeocoderService.Result - * @property {String} displayName The display name for a location + * @typedef {object} GeocoderService.Result + * @property {string} displayName The display name for a location * @property {Rectangle|Cartesian3} destination The bounding box for a location */ @@ -21,7 +21,7 @@ function GeocoderService() {} /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. * @returns {Promise<GeocoderService.Result[]>} */ diff --git a/packages/engine/Source/Core/GeographicTilingScheme.js b/packages/engine/Source/Core/GeographicTilingScheme.js index e03fbfcad8a..0b2ce78a357 100644 --- a/packages/engine/Source/Core/GeographicTilingScheme.js +++ b/packages/engine/Source/Core/GeographicTilingScheme.js @@ -15,13 +15,13 @@ import Rectangle from "./Rectangle.js"; * @alias GeographicTilingScheme * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to * the WGS84 ellipsoid. * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the tiling scheme. - * @param {Number} [options.numberOfLevelZeroTilesX=2] The number of tiles in the X direction at level zero of + * @param {number} [options.numberOfLevelZeroTilesX=2] The number of tiles in the X direction at level zero of * the tile tree. - * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of + * @param {number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of * the tile tree. */ function GeographicTilingScheme(options) { @@ -78,8 +78,8 @@ Object.defineProperties(GeographicTilingScheme.prototype, { /** * Gets the total number of tiles in the X direction at a specified level-of-detail. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the X direction at the given level. */ GeographicTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) { return this._numberOfLevelZeroTilesX << level; @@ -88,8 +88,8 @@ GeographicTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) { /** * Gets the total number of tiles in the Y direction at a specified level-of-detail. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the Y direction at the given level. */ GeographicTilingScheme.prototype.getNumberOfYTilesAtLevel = function (level) { return this._numberOfLevelZeroTilesY << level; @@ -133,10 +133,10 @@ GeographicTilingScheme.prototype.rectangleToNativeRectangle = function ( * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates * of the tiling scheme. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -158,10 +158,10 @@ GeographicTilingScheme.prototype.tileXYToNativeRectangle = function ( /** * Converts tile x, y coordinates and level to a cartographic rectangle in radians. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -201,7 +201,7 @@ GeographicTilingScheme.prototype.tileXYToRectangle = function ( * a given cartographic position. * * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {number} level The tile level-of-detail. Zero is the least detailed. * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates diff --git a/packages/engine/Source/Core/Geometry.js b/packages/engine/Source/Core/Geometry.js index 9be59cba994..5fde5b98626 100644 --- a/packages/engine/Source/Core/Geometry.js +++ b/packages/engine/Source/Core/Geometry.js @@ -26,7 +26,7 @@ import Transforms from "./Transforms.js"; * @alias Geometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {GeometryAttributes} options.attributes Attributes, which make up the geometry's vertices. * @param {PrimitiveType} [options.primitiveType=PrimitiveType.TRIANGLES] The type of primitives in the geometry. * @param {Uint16Array|Uint32Array} [options.indices] Optional index data that determines the primitives in the geometry. @@ -174,7 +174,7 @@ function Geometry(options) { * respect to the number of attributes in a vertex, not the number of vertices. * * @param {Geometry} geometry The geometry. - * @returns {Number} The number of vertices in the geometry. + * @returns {number} The number of vertices in the geometry. * * @example * const numVertices = Cesium.Geometry.computeNumberOfVertices(geometry); @@ -244,10 +244,10 @@ const rotation2DScratch = new Matrix2(); * as an intermediary instead of local ENU, which is more accurate for large-area rectangles. * * @param {Cartesian3[]} positions Array of positions outlining the geometry - * @param {Number} stRotation Texture coordinate rotation. + * @param {number} stRotation Texture coordinate rotation. * @param {Ellipsoid} ellipsoid Ellipsoid for projecting and generating local vectors. * @param {Rectangle} boundingRectangle Bounding rectangle around the positions. - * @returns {Number[]} An array of 6 numbers specifying [minimum point, u extent, v extent] as points in the "cartographic" system. + * @returns {number[]} An array of 6 numbers specifying [minimum point, u extent, v extent] as points in the "cartographic" system. * @private */ Geometry._textureCoordinateRotationPoints = function ( diff --git a/packages/engine/Source/Core/GeometryAttribute.js b/packages/engine/Source/Core/GeometryAttribute.js index 9b1e35b6dbc..972a48e22df 100644 --- a/packages/engine/Source/Core/GeometryAttribute.js +++ b/packages/engine/Source/Core/GeometryAttribute.js @@ -10,10 +10,10 @@ import DeveloperError from "./DeveloperError.js"; * @alias GeometryAttribute * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {ComponentDatatype} [options.componentDatatype] The datatype of each component in the attribute, e.g., individual elements in values. - * @param {Number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. - * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * @param {number} [options.componentsPerAttribute] A number between 1 and 4 that defines the number of components in an attributes. + * @param {boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. * @param {number[]|Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} [options.values] The values for the attributes stored in a typed array. * * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. diff --git a/packages/engine/Source/Core/GeometryInstance.js b/packages/engine/Source/Core/GeometryInstance.js index 1eedb7341f3..61e71b8ac53 100644 --- a/packages/engine/Source/Core/GeometryInstance.js +++ b/packages/engine/Source/Core/GeometryInstance.js @@ -12,11 +12,11 @@ import Matrix4 from "./Matrix4.js"; * @alias GeometryInstance * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Geometry|GeometryFactory} options.geometry The geometry to instance. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix that transforms to transform the geometry from model to world coordinates. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} or get/set per-instance attributes with {@link Primitive#getGeometryInstanceAttributes}. - * @param {Object} [options.attributes] Per-instance attributes like a show or color attribute shown in the example below. + * @param {object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} or get/set per-instance attributes with {@link Primitive#getGeometryInstanceAttributes}. + * @param {object} [options.attributes] Per-instance attributes like a show or color attribute shown in the example below. * * * @example diff --git a/packages/engine/Source/Core/GeometryInstanceAttribute.js b/packages/engine/Source/Core/GeometryInstanceAttribute.js index aabb2df4188..5b7f4ff658d 100644 --- a/packages/engine/Source/Core/GeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/GeometryInstanceAttribute.js @@ -8,11 +8,11 @@ import DeveloperError from "./DeveloperError.js"; * @alias GeometryInstanceAttribute * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ComponentDatatype} options.componentDatatype The datatype of each component in the attribute, e.g., individual elements in values. - * @param {Number} options.componentsPerAttribute A number between 1 and 4 that defines the number of components in an attributes. - * @param {Boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. - * @param {Number[]} options.value The value for the attribute. + * @param {number} options.componentsPerAttribute A number between 1 and 4 that defines the number of components in an attributes. + * @param {boolean} [options.normalize=false] When <code>true</code> and <code>componentDatatype</code> is an integer format, indicate that the components should be mapped to the range [0, 1] (unsigned) or [-1, 1] (signed) when they are accessed as floating-point for rendering. + * @param {number[]} options.value The value for the attribute. * * @exception {DeveloperError} options.componentsPerAttribute must be between 1 and 4. * @@ -121,7 +121,7 @@ function GeometryInstanceAttribute(options) { * every three elements in <code>values</code> defines one attributes since * <code>componentsPerAttribute</code> is 3. * - * @type {Number[]} + * @type {number[]} * * @default undefined * diff --git a/packages/engine/Source/Core/GeometryPipeline.js b/packages/engine/Source/Core/GeometryPipeline.js index c62466052fc..37e56ec2a16 100644 --- a/packages/engine/Source/Core/GeometryPipeline.js +++ b/packages/engine/Source/Core/GeometryPipeline.js @@ -155,8 +155,8 @@ GeometryPipeline.toWireframe = function (geometry) { * visualize vector attributes like normals, tangents, and bitangents. * * @param {Geometry} geometry The <code>Geometry</code> instance with the attribute. - * @param {String} [attributeName='normal'] The name of the attribute. - * @param {Number} [length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. + * @param {string} [attributeName='normal'] The name of the attribute. + * @param {number} [length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. * @returns {Geometry} A new <code>Geometry</code> instance with line segments for the vector. * * @exception {DeveloperError} geometry.attributes must have an attribute with the same name as the attributeName parameter. @@ -228,7 +228,7 @@ GeometryPipeline.createLineSegmentsForVectors = function ( * for matching vertex attributes and shader programs. * * @param {Geometry} geometry The geometry, which is not modified, to create the object for. - * @returns {Object} An object with attribute name / index pairs. + * @returns {object} An object with attribute name / index pairs. * * @example * const attributeLocations = Cesium.GeometryPipeline.createAttributeLocations(geometry); @@ -394,7 +394,7 @@ GeometryPipeline.reorderForPreVertexCache = function (geometry) { * is not <code>TRIANGLES</code> or the geometry does not have an <code>indices</code>, this function has no effect. * * @param {Geometry} geometry The geometry to modify. - * @param {Number} [cacheCapacity=24] The number of vertices that can be held in the GPU's vertex cache. + * @param {number} [cacheCapacity=24] The number of vertices that can be held in the GPU's vertex cache. * @returns {Geometry} The modified <code>geometry</code> argument, with its indices reordered for the post-vertex-shader cache. * * @exception {DeveloperError} cacheCapacity must be greater than two. @@ -601,10 +601,10 @@ const scratchProjectTo2DCartographic = new Cartographic(); * </p> * * @param {Geometry} geometry The geometry to modify. - * @param {String} attributeName The name of the attribute. - * @param {String} attributeName3D The name of the attribute in 3D. - * @param {String} attributeName2D The name of the attribute in 2D. - * @param {Object} [projection=new GeographicProjection()] The projection to use. + * @param {string} attributeName The name of the attribute. + * @param {string} attributeName3D The name of the attribute in 3D. + * @param {string} attributeName2D The name of the attribute in 2D. + * @param {object} [projection=new GeographicProjection()] The projection to use. * @returns {Geometry} The modified <code>geometry</code> argument with <code>position3D</code> and <code>position2D</code> attributes. * * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. @@ -714,9 +714,9 @@ const encodedResult = { * </p> * * @param {Geometry} geometry The geometry to modify. - * @param {String} attributeName The name of the attribute. - * @param {String} attributeHighName The name of the attribute for the encoded high bits. - * @param {String} attributeLowName The name of the attribute for the encoded low bits. + * @param {string} attributeName The name of the attribute. + * @param {string} attributeHighName The name of the attribute for the encoded high bits. + * @param {string} attributeLowName The name of the attribute for the encoded low bits. * @returns {Geometry} The modified <code>geometry</code> argument, with its encoded attribute. * * @exception {DeveloperError} geometry must have attribute matching the attributeName argument. diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js index 39f10b66f5f..54825fed1d4 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js @@ -36,7 +36,7 @@ const defaultKey = stringToBuffer( * @alias GoogleEarthEnterpriseMetadata * @constructor * - * @param {Resource|String} resourceOrUrl The url of the Google Earth Enterprise server hosting the imagery + * @param {Resource|string} resourceOrUrl The url of the Google Earth Enterprise server hosting the imagery * * @see GoogleEarthEnterpriseImageryProvider * @see GoogleEarthEnterpriseTerrainProvider @@ -63,42 +63,42 @@ function GoogleEarthEnterpriseMetadata(resourceOrUrl) { /** * True if imagery is available. - * @type {Boolean} + * @type {boolean} * @default true */ this.imageryPresent = true; /** * True if imagery is sent as a protocol buffer, false if sent as plain images. If undefined we will try both. - * @type {Boolean} + * @type {boolean} * @default undefined */ this.protoImagery = undefined; /** * True if terrain is available. - * @type {Boolean} + * @type {boolean} * @default true */ this.terrainPresent = true; /** * Exponent used to compute constant to calculate negative height values. - * @type {Number} + * @type {number} * @default 32 */ this.negativeAltitudeExponentBias = 32; /** * Threshold where any numbers smaller are actually negative values. They are multiplied by -2^negativeAltitudeExponentBias. - * @type {Number} + * @type {number} * @default EPSILON12 */ this.negativeAltitudeThreshold = CesiumMath.EPSILON12; /** * Dictionary of provider id to copyright strings. - * @type {Object} + * @type {object} * @default {} */ this.providers = {}; @@ -134,7 +134,7 @@ Object.defineProperties(GoogleEarthEnterpriseMetadata.prototype, { /** * Gets the name of the Google Earth Enterprise server. * @memberof GoogleEarthEnterpriseMetadata.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -170,7 +170,7 @@ Object.defineProperties(GoogleEarthEnterpriseMetadata.prototype, { /** * Gets a promise that resolves to true when the metadata is ready for use. * @memberof GoogleEarthEnterpriseMetadata.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -184,9 +184,9 @@ Object.defineProperties(GoogleEarthEnterpriseMetadata.prototype, { * Converts a tiles (x, y, level) position into a quadkey used to request an image * from a Google Earth Enterprise server. * - * @param {Number} x The tile's x coordinate. - * @param {Number} y The tile's y coordinate. - * @param {Number} level The tile's zoom level. + * @param {number} x The tile's x coordinate. + * @param {number} y The tile's y coordinate. + * @param {number} level The tile's zoom level. * * @see GoogleEarthEnterpriseMetadata#quadKeyToTileXY */ @@ -226,7 +226,7 @@ GoogleEarthEnterpriseMetadata.tileXYToQuadKey = function (x, y, level) { * Converts a tile's quadkey used to request an image from a Google Earth Enterprise server into the * (x, y, level) position. * - * @param {String} quadkey The tile's quad key + * @param {string} quadkey The tile's quad key * * @see GoogleEarthEnterpriseMetadata#tileXYToQuadKey */ @@ -294,8 +294,8 @@ const taskProcessor = new TaskProcessor("decodeGoogleEarthEnterprisePacket"); /** * Retrieves a Google Earth Enterprise quadtree packet. * - * @param {String} [quadKey=''] The quadkey to retrieve the packet for. - * @param {Number} [version=1] The cnode version to be used in the request. + * @param {string} [quadKey=''] The quadkey to retrieve the packet for. + * @param {number} [version=1] The cnode version to be used in the request. * @param {Request} [request] The request object. Intended for internal use only. * * @private @@ -373,9 +373,9 @@ GoogleEarthEnterpriseMetadata.prototype.getQuadTreePacket = function ( /** * Populates the metadata subtree down to the specified tile. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. * * @returns {Promise<GoogleEarthEnterpriseTileInformation>} A promise that resolves to the tile info for the requested quad key @@ -460,9 +460,9 @@ function populateSubtree(that, quadKey, request) { /** * Gets information about a tile * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. * * @private @@ -479,7 +479,7 @@ GoogleEarthEnterpriseMetadata.prototype.getTileInformation = function ( /** * Gets information about a tile from a quadKey * - * @param {String} quadkey The quadkey for the tile + * @param {string} quadkey The quadkey for the tile * @returns {GoogleEarthEnterpriseTileInformation|undefined} Information about the tile or undefined if it isn't loaded. * * @private diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainData.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainData.js index cead7ff94de..f343aff9957 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainData.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainData.js @@ -22,11 +22,11 @@ import TerrainMesh from "./TerrainMesh.js"; * @alias GoogleEarthEnterpriseTerrainData * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ArrayBuffer} options.buffer The buffer containing terrain data. - * @param {Number} options.negativeAltitudeExponentBias Multiplier for negative terrain heights that are encoded as very small positive values. - * @param {Number} options.negativeElevationThreshold Threshold for negative values - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * @param {number} options.negativeAltitudeExponentBias Multiplier for negative terrain heights that are encoded as very small positive values. + * @param {number} options.negativeElevationThreshold Threshold for negative values + * @param {number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. * If a child's bit is set, geometry will be requested for that tile as well when it * is needed. If the bit is cleared, the child tile is not requested and geometry is * instead upsampled from the parent. The bit values are as follows: @@ -37,7 +37,7 @@ import TerrainMesh from "./TerrainMesh.js"; * <tr><td>2</td><td>4</td><td>Northeast</td></tr> * <tr><td>3</td><td>8</td><td>Northwest</td></tr> * </table> - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * @param {boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; * otherwise, false. * @param {Credit[]} [options.credits] Array of credits for this tile. * @@ -132,15 +132,15 @@ const rectangleScratch = new Rectangle(); * * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. - * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} options.level The level of the tile for which to create the terrain data. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height from which terrain is exaggerated. - * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * @param {number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {number} options.level The level of the tile for which to create the terrain data. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height from which terrain is exaggerated. + * @param {boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. + * @returns {Promise<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ @@ -237,9 +237,9 @@ GoogleEarthEnterpriseTerrainData.prototype.createMesh = function (options) { * Computes the terrain height at a specified longitude and latitude. * * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position + * @param {number} longitude The longitude in radians. + * @param {number} latitude The latitude in radians. + * @returns {number} The terrain height at the specified position. If the position * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly * incorrect for positions far outside the rectangle. */ @@ -276,13 +276,13 @@ const upsampleTaskProcessor = new TaskProcessor( * height samples in this instance, interpolated if necessary. * * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * @param {number} thisX The X coordinate of this tile in the tiling scheme. + * @param {number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {number} thisLevel The level of this tile in the tiling scheme. + * @param {number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, * or undefined if too many asynchronous upsample operations are in progress and the request has been * deferred. */ @@ -387,11 +387,11 @@ GoogleEarthEnterpriseTerrainData.prototype.upsample = function ( * to be one of the four children of this tile. If non-child tile coordinates are * given, the availability of the southeast child tile is returned. * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. + * @param {number} thisX The tile X coordinate of this (the parent) tile. + * @param {number} thisY The tile Y coordinate of this (the parent) tile. + * @param {number} childX The tile X coordinate of the child tile to check for availability. + * @param {number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {boolean} True if the child tile is available; otherwise, false. */ GoogleEarthEnterpriseTerrainData.prototype.isChildAvailable = function ( thisX, @@ -423,7 +423,7 @@ GoogleEarthEnterpriseTerrainData.prototype.isChildAvailable = function ( * as by downloading it from a remote server. This method should return true for instances * returned from a call to {@link HeightmapTerrainData#upsample}. * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @returns {boolean} True if this instance was created by upsampling; otherwise, false. */ GoogleEarthEnterpriseTerrainData.prototype.wasCreatedByUpsampling = function () { return this._createdByUpsampling; diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index 74c89b8d532..5b8c1d1207e 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -72,11 +72,11 @@ TerrainCache.prototype.tidy = function () { * @alias GoogleEarthEnterpriseTerrainProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String} options.url The url of the Google Earth Enterprise server hosting the imagery. + * @param {object} options Object with the following properties: + * @param {Resource|string} options.url The url of the Google Earth Enterprise server hosting the imagery. * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseImageryProvider. * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. * * @see GoogleEarthEnterpriseImageryProvider * @see CesiumTerrainProvider @@ -179,7 +179,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { /** * Gets the name of the Google Earth Enterprise server url hosting the imagery. * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -238,7 +238,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -250,7 +250,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -278,7 +278,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -291,7 +291,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. * @memberof GoogleEarthEnterpriseTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -342,11 +342,11 @@ function computeChildMask(quadKey, info, metadata) { * {@link GoogleEarthEnterpriseTerrainProvider#ready} returns true. The result must include terrain data and * may optionally include a water mask and an indication of which child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. * @@ -546,8 +546,8 @@ GoogleEarthEnterpriseTerrainProvider.prototype.requestTileGeometry = function ( /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ GoogleEarthEnterpriseTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -558,10 +558,10 @@ GoogleEarthEnterpriseTerrainProvider.prototype.getLevelMaximumGeometricError = f /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported, otherwise true or false. */ GoogleEarthEnterpriseTerrainProvider.prototype.getTileDataAvailable = function ( x, @@ -615,9 +615,9 @@ GoogleEarthEnterpriseTerrainProvider.prototype.getTileDataAvailable = function ( /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined} */ GoogleEarthEnterpriseTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTileInformation.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTileInformation.js index 88f6bee95dc..e1caecb56ae 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTileInformation.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTileInformation.js @@ -11,12 +11,12 @@ const terrainBitmask = 0x80; /** * Contains information about each tile from a Google Earth Enterprise server * - * @param {Number} bits Bitmask that contains the type of data and available children for each tile. - * @param {Number} cnodeVersion Version of the request for subtree metadata. - * @param {Number} imageryVersion Version of the request for imagery tile. - * @param {Number} terrainVersion Version of the request for terrain tile. - * @param {Number} imageryProvider Id of imagery provider. - * @param {Number} terrainProvider Id of terrain provider. + * @param {number} bits Bitmask that contains the type of data and available children for each tile. + * @param {number} cnodeVersion Version of the request for subtree metadata. + * @param {number} imageryVersion Version of the request for imagery tile. + * @param {number} terrainVersion Version of the request for terrain tile. + * @param {number} imageryProvider Id of imagery provider. + * @param {number} terrainProvider Id of terrain provider. * * @private */ @@ -41,7 +41,7 @@ function GoogleEarthEnterpriseTileInformation( /** * Creates GoogleEarthEnterpriseTileInformation from an object * - * @param {Object} info Object to be cloned + * @param {object} info Object to be cloned * @param {GoogleEarthEnterpriseTileInformation} [result] The object onto which to store the result. * @returns {GoogleEarthEnterpriseTileInformation} The modified result parameter or a new GoogleEarthEnterpriseTileInformation instance if none was provided. */ @@ -81,7 +81,7 @@ GoogleEarthEnterpriseTileInformation.prototype.setParent = function (parent) { /** * Gets whether a subtree is available * - * @returns {Boolean} true if subtree is available, false otherwise. + * @returns {boolean} true if subtree is available, false otherwise. */ GoogleEarthEnterpriseTileInformation.prototype.hasSubtree = function () { return isBitSet(this._bits, cacheFlagBitmask); @@ -90,7 +90,7 @@ GoogleEarthEnterpriseTileInformation.prototype.hasSubtree = function () { /** * Gets whether imagery is available * - * @returns {Boolean} true if imagery is available, false otherwise. + * @returns {boolean} true if imagery is available, false otherwise. */ GoogleEarthEnterpriseTileInformation.prototype.hasImagery = function () { return isBitSet(this._bits, imageBitmask); @@ -99,7 +99,7 @@ GoogleEarthEnterpriseTileInformation.prototype.hasImagery = function () { /** * Gets whether terrain is available * - * @returns {Boolean} true if terrain is available, false otherwise. + * @returns {boolean} true if terrain is available, false otherwise. */ GoogleEarthEnterpriseTileInformation.prototype.hasTerrain = function () { return isBitSet(this._bits, terrainBitmask); @@ -108,7 +108,7 @@ GoogleEarthEnterpriseTileInformation.prototype.hasTerrain = function () { /** * Gets whether any children are present * - * @returns {Boolean} true if any children are available, false otherwise. + * @returns {boolean} true if any children are available, false otherwise. */ GoogleEarthEnterpriseTileInformation.prototype.hasChildren = function () { return isBitSet(this._bits, anyChildBitmask); @@ -117,9 +117,9 @@ GoogleEarthEnterpriseTileInformation.prototype.hasChildren = function () { /** * Gets whether a specified child is available * - * @param {Number} index Index of child tile + * @param {number} index Index of child tile * - * @returns {Boolean} true if child is available, false otherwise + * @returns {boolean} true if child is available, false otherwise */ GoogleEarthEnterpriseTileInformation.prototype.hasChild = function (index) { return isBitSet(this._bits, childrenBitmasks[index]); @@ -128,7 +128,7 @@ GoogleEarthEnterpriseTileInformation.prototype.hasChild = function (index) { /** * Gets bitmask containing children * - * @returns {Number} Children bitmask + * @returns {number} Children bitmask */ GoogleEarthEnterpriseTileInformation.prototype.getChildBitmask = function () { return this._bits & anyChildBitmask; diff --git a/packages/engine/Source/Core/GregorianDate.js b/packages/engine/Source/Core/GregorianDate.js index cd4c53c1d1a..14973a978ec 100644 --- a/packages/engine/Source/Core/GregorianDate.js +++ b/packages/engine/Source/Core/GregorianDate.js @@ -4,14 +4,14 @@ * @alias GregorianDate * @constructor * - * @param {Number} [year] The year as a whole number. - * @param {Number} [month] The month as a whole number with range [1, 12]. - * @param {Number} [day] The day of the month as a whole number starting at 1. - * @param {Number} [hour] The hour as a whole number with range [0, 23]. - * @param {Number} [minute] The minute of the hour as a whole number with range [0, 59]. - * @param {Number} [second] The second of the minute as a whole number with range [0, 60], with 60 representing a leap second. - * @param {Number} [millisecond] The millisecond of the second as a floating point number with range [0.0, 1000.0). - * @param {Boolean} [isLeapSecond] Whether this time is during a leap second. + * @param {number} [year] The year as a whole number. + * @param {number} [month] The month as a whole number with range [1, 12]. + * @param {number} [day] The day of the month as a whole number starting at 1. + * @param {number} [hour] The hour as a whole number with range [0, 23]. + * @param {number} [minute] The minute of the hour as a whole number with range [0, 59]. + * @param {number} [second] The second of the minute as a whole number with range [0, 60], with 60 representing a leap second. + * @param {number} [millisecond] The millisecond of the second as a floating point number with range [0.0, 1000.0). + * @param {boolean} [isLeapSecond] Whether this time is during a leap second. * * @see JulianDate#toGregorianDate */ @@ -27,42 +27,42 @@ function GregorianDate( ) { /** * Gets or sets the year as a whole number. - * @type {Number} + * @type {number} */ this.year = year; /** * Gets or sets the month as a whole number with range [1, 12]. - * @type {Number} + * @type {number} */ this.month = month; /** * Gets or sets the day of the month as a whole number starting at 1. - * @type {Number} + * @type {number} */ this.day = day; /** * Gets or sets the hour as a whole number with range [0, 23]. - * @type {Number} + * @type {number} */ this.hour = hour; /** * Gets or sets the minute of the hour as a whole number with range [0, 59]. - * @type {Number} + * @type {number} */ this.minute = minute; /** * Gets or sets the second of the minute as a whole number with range [0, 60], with 60 representing a leap second. - * @type {Number} + * @type {number} */ this.second = second; /** * Gets or sets the millisecond of the second as a floating point number with range [0.0, 1000.0). - * @type {Number} + * @type {number} */ this.millisecond = millisecond; /** * Gets or sets whether this time is during a leap second. - * @type {Boolean} + * @type {boolean} */ this.isLeapSecond = isLeapSecond; } diff --git a/packages/engine/Source/Core/GroundPolylineGeometry.js b/packages/engine/Source/Core/GroundPolylineGeometry.js index 8422a587d0f..877874c2f5a 100644 --- a/packages/engine/Source/Core/GroundPolylineGeometry.js +++ b/packages/engine/Source/Core/GroundPolylineGeometry.js @@ -49,11 +49,11 @@ const WALL_INITIAL_MAX_HEIGHT = 1000.0; * @alias GroundPolylineGeometry * @constructor * - * @param {Object} options Options with the following properties: + * @param {object} options Options with the following properties: * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the polyline's points. Heights above the ellipsoid will be ignored. - * @param {Number} [options.width=1.0] The screen space width in pixels. - * @param {Number} [options.granularity=9999.0] The distance interval in meters used for interpolating options.points. Defaults to 9999.0 meters. Zero indicates no interpolation. - * @param {Boolean} [options.loop=false] Whether during geometry creation a line segment will be added between the last and first line positions to make this Polyline a loop. + * @param {number} [options.width=1.0] The screen space width in pixels. + * @param {number} [options.granularity=9999.0] The distance interval in meters used for interpolating options.points. Defaults to 9999.0 meters. Zero indicates no interpolation. + * @param {boolean} [options.loop=false] Whether during geometry creation a line segment will be added between the last and first line positions to make this Polyline a loop. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polyline segments must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}. * * @exception {DeveloperError} At least two positions are required. @@ -92,7 +92,7 @@ function GroundPolylineGeometry(options) { /** * The screen space width in pixels. - * @type {Number} + * @type {number} */ this.width = defaultValue(options.width, 1.0); // Doesn't get packed, not necessary for computing geometry. @@ -101,7 +101,7 @@ function GroundPolylineGeometry(options) { /** * The distance interval used for interpolating options.points. Zero indicates no interpolation. * Default of 9999.0 allows centimeter accuracy with 32 bit floating point. - * @type {Boolean} + * @type {boolean} * @default 9999.0 */ this.granularity = defaultValue(options.granularity, 9999.0); @@ -109,7 +109,7 @@ function GroundPolylineGeometry(options) { /** * Whether during geometry creation a line segment will be added between the last and first line positions to make this Polyline a loop. * If the geometry has two positions this parameter will be ignored. - * @type {Boolean} + * @type {boolean} * @default false */ this.loop = defaultValue(options.loop, false); @@ -135,7 +135,7 @@ Object.defineProperties(GroundPolylineGeometry.prototype, { /** * The number of elements used to pack the object into an array. * @memberof GroundPolylineGeometry.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -285,10 +285,10 @@ function getPosition(ellipsoid, cartographic, height, result) { * Stores the provided instance into the provided array. * * @param {PolygonGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ GroundPolylineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -325,8 +325,8 @@ GroundPolylineGeometry.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolygonGeometry} [result] The object into which to store the result. */ GroundPolylineGeometry.unpack = function (array, startingIndex, result) { diff --git a/packages/engine/Source/Core/HeadingPitchRange.js b/packages/engine/Source/Core/HeadingPitchRange.js index 15741102e77..355f03c816f 100644 --- a/packages/engine/Source/Core/HeadingPitchRange.js +++ b/packages/engine/Source/Core/HeadingPitchRange.js @@ -9,14 +9,14 @@ import defined from "./defined.js"; * @alias HeadingPitchRange * @constructor * - * @param {Number} [heading=0.0] The heading angle in radians. - * @param {Number} [pitch=0.0] The pitch angle in radians. - * @param {Number} [range=0.0] The distance from the center in meters. + * @param {number} [heading=0.0] The heading angle in radians. + * @param {number} [pitch=0.0] The pitch angle in radians. + * @param {number} [range=0.0] The distance from the center in meters. */ function HeadingPitchRange(heading, pitch, range) { /** * Heading is the rotation from the local north direction where a positive angle is increasing eastward. - * @type {Number} + * @type {number} * @default 0.0 */ this.heading = defaultValue(heading, 0.0); @@ -24,14 +24,14 @@ function HeadingPitchRange(heading, pitch, range) { /** * Pitch is the rotation from the local xy-plane. Positive pitch angles * are above the plane. Negative pitch angles are below the plane. - * @type {Number} + * @type {number} * @default 0.0 */ this.pitch = defaultValue(pitch, 0.0); /** * Range is the distance from the center of the local frame. - * @type {Number} + * @type {number} * @default 0.0 */ this.range = defaultValue(range, 0.0); diff --git a/packages/engine/Source/Core/HeadingPitchRoll.js b/packages/engine/Source/Core/HeadingPitchRoll.js index dfa22c92fc3..92a3dadfefc 100644 --- a/packages/engine/Source/Core/HeadingPitchRoll.js +++ b/packages/engine/Source/Core/HeadingPitchRoll.js @@ -10,26 +10,26 @@ import CesiumMath from "./Math.js"; * @alias HeadingPitchRoll * @constructor * - * @param {Number} [heading=0.0] The heading component in radians. - * @param {Number} [pitch=0.0] The pitch component in radians. - * @param {Number} [roll=0.0] The roll component in radians. + * @param {number} [heading=0.0] The heading component in radians. + * @param {number} [pitch=0.0] The pitch component in radians. + * @param {number} [roll=0.0] The roll component in radians. */ function HeadingPitchRoll(heading, pitch, roll) { /** * Gets or sets the heading. - * @type {Number} + * @type {number} * @default 0.0 */ this.heading = defaultValue(heading, 0.0); /** * Gets or sets the pitch. - * @type {Number} + * @type {number} * @default 0.0 */ this.pitch = defaultValue(pitch, 0.0); /** * Gets or sets the roll. - * @type {Number} + * @type {number} * @default 0.0 */ this.roll = defaultValue(roll, 0.0); @@ -69,9 +69,9 @@ HeadingPitchRoll.fromQuaternion = function (quaternion, result) { /** * Returns a new HeadingPitchRoll instance from angles given in degrees. * - * @param {Number} heading the heading in degrees - * @param {Number} pitch the pitch in degrees - * @param {Number} roll the heading in degrees + * @param {number} heading the heading in degrees + * @param {number} pitch the pitch in degrees + * @param {number} roll the heading in degrees * @param {HeadingPitchRoll} [result] The object in which to store the result. If not provided, a new instance is created and returned. * @returns {HeadingPitchRoll} A new HeadingPitchRoll instance */ @@ -126,7 +126,7 @@ HeadingPitchRoll.clone = function (headingPitchRoll, result) { * * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ HeadingPitchRoll.equals = function (left, right) { return ( @@ -146,9 +146,9 @@ HeadingPitchRoll.equals = function (left, right) { * * @param {HeadingPitchRoll} [left] The first HeadingPitchRoll. * @param {HeadingPitchRoll} [right] The second HeadingPitchRoll. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ HeadingPitchRoll.equalsEpsilon = function ( left, @@ -196,7 +196,7 @@ HeadingPitchRoll.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ HeadingPitchRoll.prototype.equals = function (right) { return HeadingPitchRoll.equals(this, right); @@ -208,9 +208,9 @@ HeadingPitchRoll.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {HeadingPitchRoll} [right] The right hand side HeadingPitchRoll. - * @param {Number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [relativeEpsilon=0] The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ HeadingPitchRoll.prototype.equalsEpsilon = function ( right, @@ -228,7 +228,7 @@ HeadingPitchRoll.prototype.equalsEpsilon = function ( /** * Creates a string representing this HeadingPitchRoll in the format '(heading, pitch, roll)' in radians. * - * @returns {String} A string representing the provided HeadingPitchRoll in the format '(heading, pitch, roll)'. + * @returns {string} A string representing the provided HeadingPitchRoll in the format '(heading, pitch, roll)'. */ HeadingPitchRoll.prototype.toString = function () { return `(${this.heading}, ${this.pitch}, ${this.roll})`; diff --git a/packages/engine/Source/Core/Heap.js b/packages/engine/Source/Core/Heap.js index 47816444f82..700475cedc5 100644 --- a/packages/engine/Source/Core/Heap.js +++ b/packages/engine/Source/Core/Heap.js @@ -9,7 +9,7 @@ import defined from "./defined.js"; * @constructor * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Heap.ComparatorCallback} options.comparator The comparator to use for the heap. If comparator(a, b) is less than 0, sort a to a lower index than b, otherwise sort to a higher index. */ function Heap(options) { @@ -30,7 +30,7 @@ Object.defineProperties(Heap.prototype, { * * @memberof Heap.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -58,7 +58,7 @@ Object.defineProperties(Heap.prototype, { * * @memberof Heap.prototype * - * @type {Number} + * @type {number} */ maximumLength: { get: function () { @@ -105,7 +105,7 @@ function swap(array, a, b) { /** * Resizes the internal array of the heap. * - * @param {Number} [length] The length to resize internal array to. Defaults to the current length of the heap. + * @param {number} [length] The length to resize internal array to. Defaults to the current length of the heap. */ Heap.prototype.reserve = function (length) { length = defaultValue(length, this._length); @@ -115,7 +115,7 @@ Heap.prototype.reserve = function (length) { /** * Update the heap so that index and all descendants satisfy the heap property. * - * @param {Number} [index=0] The starting index to heapify from. + * @param {number} [index=0] The starting index to heapify from. */ Heap.prototype.heapify = function (index) { index = defaultValue(index, 0); @@ -204,7 +204,7 @@ Heap.prototype.insert = function (element) { /** * Remove the element specified by index from the heap and return it. * - * @param {Number} [index=0] The index to remove. + * @param {number} [index=0] The index to remove. * @returns {*} The specified element of the heap. */ Heap.prototype.pop = function (index) { @@ -229,6 +229,6 @@ Heap.prototype.pop = function (index) { * @callback Heap.ComparatorCallback * @param {*} a An element in the heap. * @param {*} b An element in the heap. - * @returns {Number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. + * @returns {number} If the result of the comparison is less than 0, sort a to a lower index than b, otherwise sort to a higher index. */ export default Heap; diff --git a/packages/engine/Source/Core/HeightmapEncoding.js b/packages/engine/Source/Core/HeightmapEncoding.js index a7f02a09d60..ba66c785b83 100644 --- a/packages/engine/Source/Core/HeightmapEncoding.js +++ b/packages/engine/Source/Core/HeightmapEncoding.js @@ -1,13 +1,13 @@ /** * The encoding that is used for a heightmap * - * @enum {Number} + * @enum {number} */ const HeightmapEncoding = { /** * No encoding * - * @type {Number} + * @type {number} * @constant */ NONE: 0, @@ -15,7 +15,7 @@ const HeightmapEncoding = { /** * LERC encoding * - * @type {Number} + * @type {number} * @constant * * @see {@link https://github.com/Esri/lerc|The LERC specification} diff --git a/packages/engine/Source/Core/HeightmapTerrainData.js b/packages/engine/Source/Core/HeightmapTerrainData.js index 4d797eddbbb..fab32e682b8 100644 --- a/packages/engine/Source/Core/HeightmapTerrainData.js +++ b/packages/engine/Source/Core/HeightmapTerrainData.js @@ -23,11 +23,11 @@ import TerrainProvider from "./TerrainProvider.js"; * @alias HeightmapTerrainData * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} options.buffer The buffer containing height data. - * @param {Number} options.width The width (longitude direction) of the heightmap, in samples. - * @param {Number} options.height The height (latitude direction) of the heightmap, in samples. - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * @param {number} options.width The width (longitude direction) of the heightmap, in samples. + * @param {number} options.height The height (latitude direction) of the heightmap, in samples. + * @param {number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. * If a child's bit is set, geometry will be requested for that tile as well when it * is needed. If the bit is cleared, the child tile is not requested and geometry is * instead upsampled from the parent. The bit values are as follows: @@ -41,38 +41,38 @@ import TerrainProvider from "./TerrainProvider.js"; * @param {Uint8Array} [options.waterMask] The water mask included in this terrain data, if any. A water mask is a square * Uint8Array or image where a value of 255 indicates water and a value of 0 indicates land. * Values in between 0 and 255 are allowed as well to smoothly blend between land and water. - * @param {Object} [options.structure] An object describing the structure of the height data. - * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain + * @param {object} [options.structure] An object describing the structure of the height data. + * @param {number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain * the height above the heightOffset, in meters. The heightOffset is added to the resulting * height after multiplying by the scale. - * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final + * @param {number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final * height in meters. The offset is added after the height sample is multiplied by the * heightScale. - * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height + * @param {number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height * sample. This is usually 1, indicating that each element is a separate height sample. If * it is greater than 1, that number of elements together form the height sample, which is * computed according to the structure.elementMultiplier and structure.isBigEndian properties. - * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of + * @param {number} [options.structure.stride=1] The number of elements to skip to get from the first element of * one height to the first element of the next height. - * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the + * @param {number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier * is 256, the height is computed as follows: * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` * This is assuming that the isBigEndian property is false. If it is true, the order of the * elements is reversed. - * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the + * @param {boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the * stride property is greater than 1. If this property is false, the first element is the * low-order element. If it is true, the first element is the high-order element. - * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower + * @param {number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is * not specified, no minimum value is enforced. - * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher + * @param {number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger * than 65535. If this parameter is not specified, no maximum value is enforced. * @param {HeightmapEncoding} [options.encoding=HeightmapEncoding.NONE] The encoding that is used on the buffer. - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * @param {boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; * otherwise, false. * * @@ -195,15 +195,15 @@ const createMeshTaskProcessorThrottle = new TaskProcessor( * * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. - * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} options.level The level of the tile for which to create the terrain data. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. - * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * @param {number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {number} options.level The level of the tile for which to create the terrain data. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. + * @param {boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. + * @returns {Promise<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ @@ -316,13 +316,13 @@ HeightmapTerrainData.prototype.createMesh = function (options) { }; /** - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. - * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} options.level The level of the tile for which to create the terrain data. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. + * @param {number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {number} options.level The level of the tile for which to create the terrain data. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. * * @private */ @@ -423,9 +423,9 @@ HeightmapTerrainData.prototype._createMeshSync = function (options) { * Computes the terrain height at a specified longitude and latitude. * * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position + * @param {number} longitude The longitude in radians. + * @param {number} latitude The latitude in radians. + * @returns {number} The terrain height at the specified position. If the position * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly * incorrect for positions far outside the rectangle. */ @@ -494,13 +494,13 @@ HeightmapTerrainData.prototype.interpolateHeight = function ( * height samples in this instance, interpolated if necessary. * * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * @param {number} thisX The X coordinate of this tile in the tiling scheme. + * @param {number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {number} thisLevel The level of this tile in the tiling scheme. + * @param {number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise<HeightmapTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, * or undefined if the mesh is unavailable. */ HeightmapTerrainData.prototype.upsample = function ( @@ -644,11 +644,11 @@ HeightmapTerrainData.prototype.upsample = function ( * to be one of the four children of this tile. If non-child tile coordinates are * given, the availability of the southeast child tile is returned. * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. + * @param {number} thisX The tile X coordinate of this (the parent) tile. + * @param {number} thisY The tile Y coordinate of this (the parent) tile. + * @param {number} childX The tile X coordinate of the child tile to check for availability. + * @param {number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {boolean} True if the child tile is available; otherwise, false. */ HeightmapTerrainData.prototype.isChildAvailable = function ( thisX, @@ -688,7 +688,7 @@ HeightmapTerrainData.prototype.isChildAvailable = function ( * as by downloading it from a remote server. This method should return true for instances * returned from a call to {@link HeightmapTerrainData#upsample}. * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @returns {boolean} True if this instance was created by upsampling; otherwise, false. */ HeightmapTerrainData.prototype.wasCreatedByUpsampling = function () { return this._createdByUpsampling; diff --git a/packages/engine/Source/Core/HeightmapTessellator.js b/packages/engine/Source/Core/HeightmapTessellator.js index a1b2c48072e..be566f845e3 100644 --- a/packages/engine/Source/Core/HeightmapTessellator.js +++ b/packages/engine/Source/Core/HeightmapTessellator.js @@ -46,51 +46,51 @@ const maximumScratch = new Cartesian3(); /** * Fills an array of vertices from a heightmap image. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} options.heightmap The heightmap to tessellate. - * @param {Number} options.width The width of the heightmap, in height samples. - * @param {Number} options.height The height of the heightmap, in height samples. - * @param {Number} options.skirtHeight The height of skirts to drape at the edges of the heightmap. + * @param {number} options.width The width of the heightmap, in height samples. + * @param {number} options.height The height of the heightmap, in height samples. + * @param {number} options.skirtHeight The height of skirts to drape at the edges of the heightmap. * @param {Rectangle} options.nativeRectangle A rectangle in the native coordinates of the heightmap's projection. For * a heightmap with a geographic projection, this is degrees. For the web mercator * projection, this is meters. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height from which terrain is exaggerated. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height from which terrain is exaggerated. * @param {Rectangle} [options.rectangle] The rectangle covered by the heightmap, in geodetic coordinates with north, south, east and * west properties in radians. Either rectangle or nativeRectangle must be provided. If both * are provided, they're assumed to be consistent. - * @param {Boolean} [options.isGeographic=true] True if the heightmap uses a {@link GeographicProjection}, or false if it uses + * @param {boolean} [options.isGeographic=true] True if the heightmap uses a {@link GeographicProjection}, or false if it uses * a {@link WebMercatorProjection}. * @param {Cartesian3} [options.relativeToCenter=Cartesian3.ZERO] The positions will be computed as <code>Cartesian3.subtract(worldPosition, relativeToCenter)</code>. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to which the heightmap applies. - * @param {Object} [options.structure] An object describing the structure of the height data. - * @param {Number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain + * @param {object} [options.structure] An object describing the structure of the height data. + * @param {number} [options.structure.heightScale=1.0] The factor by which to multiply height samples in order to obtain * the height above the heightOffset, in meters. The heightOffset is added to the resulting * height after multiplying by the scale. - * @param {Number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final + * @param {number} [options.structure.heightOffset=0.0] The offset to add to the scaled height to obtain the final * height in meters. The offset is added after the height sample is multiplied by the * heightScale. - * @param {Number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height + * @param {number} [options.structure.elementsPerHeight=1] The number of elements in the buffer that make up a single height * sample. This is usually 1, indicating that each element is a separate height sample. If * it is greater than 1, that number of elements together form the height sample, which is * computed according to the structure.elementMultiplier and structure.isBigEndian properties. - * @param {Number} [options.structure.stride=1] The number of elements to skip to get from the first element of + * @param {number} [options.structure.stride=1] The number of elements to skip to get from the first element of * one height to the first element of the next height. - * @param {Number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the + * @param {number} [options.structure.elementMultiplier=256.0] The multiplier used to compute the height value when the * stride property is greater than 1. For example, if the stride is 4 and the strideMultiplier * is 256, the height is computed as follows: * `height = buffer[index] + buffer[index + 1] * 256 + buffer[index + 2] * 256 * 256 + buffer[index + 3] * 256 * 256 * 256` * This is assuming that the isBigEndian property is false. If it is true, the order of the * elements is reversed. - * @param {Number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower + * @param {number} [options.structure.lowestEncodedHeight] The lowest value that can be stored in the height buffer. Any heights that are lower * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height * buffer is a `Uint16Array`, this value should be 0 because a `Uint16Array` cannot store negative numbers. If this parameter is * not specified, no minimum value is enforced. - * @param {Number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher + * @param {number} [options.structure.highestEncodedHeight] The highest value that can be stored in the height buffer. Any heights that are higher * than this value after encoding with the `heightScale` and `heightOffset` are clamped to this value. For example, if the height * buffer is a `Uint16Array`, this value should be `256 * 256 - 1` or 65535 because a `Uint16Array` cannot store numbers larger * than 65535. If this parameter is not specified, no maximum value is enforced. - * @param {Boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the + * @param {boolean} [options.structure.isBigEndian=false] Indicates endianness of the elements in the buffer when the * stride property is greater than 1. If this property is false, the first element is the * low-order element. If it is true, the first element is the high-order element. * diff --git a/packages/engine/Source/Core/HermitePolynomialApproximation.js b/packages/engine/Source/Core/HermitePolynomialApproximation.js index 4e7cae0549c..c2737cd26d2 100644 --- a/packages/engine/Source/Core/HermitePolynomialApproximation.js +++ b/packages/engine/Source/Core/HermitePolynomialApproximation.js @@ -73,9 +73,9 @@ const HermitePolynomialApproximation = { /** * Given the desired degree, returns the number of data points required for interpolation. * - * @param {Number} degree The desired degree of interpolation. - * @param {Number} [inputOrder=0] The order of the inputs (0 means just the data, 1 means the data and its derivative, etc). - * @returns {Number} The number of required data points needed for the desired degree of interpolation. + * @param {number} degree The desired degree of interpolation. + * @param {number} [inputOrder=0] The order of the inputs (0 means just the data, 1 means the data and its derivative, etc). + * @returns {number} The number of required data points needed for the desired degree of interpolation. * @exception {DeveloperError} degree must be 0 or greater. * @exception {DeveloperError} inputOrder must be 0 or greater. */ @@ -103,15 +103,15 @@ HermitePolynomialApproximation.getRequiredDataPoints = function ( /** * Interpolates values using Hermite Polynomial Approximation. * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @param {number[]} [result] An existing array into which to store the result. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ HermitePolynomialApproximation.interpolateOrderZero = function ( x, @@ -199,18 +199,18 @@ const arrayScratch = []; /** * Interpolates values using Hermite Polynomial Approximation. * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number} inputOrder The number of derivatives supplied for input. - * @param {Number} outputOrder The number of derivatives desired for output. - * @param {Number[]} [result] An existing array into which to store the result. + * @param {number} inputOrder The number of derivatives supplied for input. + * @param {number} outputOrder The number of derivatives desired for output. + * @param {number[]} [result] An existing array into which to store the result. * - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ HermitePolynomialApproximation.interpolate = function ( x, diff --git a/packages/engine/Source/Core/HermiteSpline.js b/packages/engine/Source/Core/HermiteSpline.js index a89719c47a9..629e81e7687 100644 --- a/packages/engine/Source/Core/HermiteSpline.js +++ b/packages/engine/Source/Core/HermiteSpline.js @@ -119,8 +119,8 @@ function generateNatural(points) { * @alias HermiteSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. * The values are in no way connected to the clock time. They are the parameterization for the curve. * @param {Cartesian3[]} options.points The array of control points. * @param {Cartesian3[]} options.inTangents The array of incoming tangents at each control point. @@ -229,7 +229,7 @@ Object.defineProperties(HermiteSpline.prototype, { * * @memberof HermiteSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -285,8 +285,8 @@ Object.defineProperties(HermiteSpline.prototype, { * Creates a spline where the tangents at each control point are the same. * The curves are guaranteed to be at least in the class C<sup>1</sup>. * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. + * @param {object} options Object with the following properties: + * @param {number[]} options.times The array of control point times. * @param {Cartesian3[]} options.points The array of control points. * @param {Cartesian3[]} options.tangents The array of tangents at the control points. * @returns {HermiteSpline} A hermite spline. @@ -357,8 +357,8 @@ HermiteSpline.createC1 = function (options) { * Creates a natural cubic spline. The tangents at the control points are generated * to create a curve in the class C<sup>2</sup>. * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. + * @param {object} options Object with the following properties: + * @param {number[]} options.times The array of control point times. * @param {Cartesian3[]} options.points The array of control points. * @returns {HermiteSpline|LinearSpline} A hermite spline, or a linear spline if less than 3 control points were given. * @@ -422,9 +422,9 @@ HermiteSpline.createNaturalCubic = function (options) { * Creates a clamped cubic spline. The tangents at the interior control points are generated * to create a curve in the class C<sup>2</sup>. * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times The array of control point times. - * @param {Number[]|Cartesian3[]} options.points The array of control points. + * @param {object} options Object with the following properties: + * @param {number[]} options.times The array of control point times. + * @param {number[]|Cartesian3[]} options.points The array of control points. * @param {Cartesian3} options.firstTangent The outgoing tangent of the first control point. * @param {Cartesian3} options.lastTangent The incoming tangent of the last control point. * @returns {HermiteSpline|LinearSpline} A hermite spline, or a linear spline if less than 3 control points were given. @@ -523,8 +523,8 @@ HermiteSpline.hermiteCoefficientMatrix = new Matrix4( * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -539,8 +539,8 @@ const scratchTemp = new Cartesian3(); * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ HermiteSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -548,15 +548,15 @@ HermiteSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ HermiteSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. * diff --git a/packages/engine/Source/Core/HilbertOrder.js b/packages/engine/Source/Core/HilbertOrder.js index 8bfdde6cb55..540a1ea493b 100644 --- a/packages/engine/Source/Core/HilbertOrder.js +++ b/packages/engine/Source/Core/HilbertOrder.js @@ -11,10 +11,10 @@ const HilbertOrder = {}; /** * Computes the Hilbert index at the given level from 2D coordinates. * - * @param {Number} level The level of the curve - * @param {Number} x The X coordinate - * @param {Number} y The Y coordinate - * @returns {Number} The Hilbert index. + * @param {number} level The level of the curve + * @param {number} x The X coordinate + * @param {number} y The Y coordinate + * @returns {number} The Hilbert index. * @private */ HilbertOrder.encode2D = function (level, x, y) { @@ -55,9 +55,9 @@ HilbertOrder.encode2D = function (level, x, y) { /** * Computes the 2D coordinates from the Hilbert index at the given level. * - * @param {Number} level The level of the curve - * @param {BigInt} index The Hilbert index - * @returns {Number[]} An array containing the 2D coordinates ([x, y]) corresponding to the Morton index. + * @param {number} level The level of the curve + * @param {bigint} index The Hilbert index + * @returns {number[]} An array containing the 2D coordinates ([x, y]) corresponding to the Morton index. * @private */ HilbertOrder.decode2D = function (level, index) { diff --git a/packages/engine/Source/Core/Iau2006XysData.js b/packages/engine/Source/Core/Iau2006XysData.js index 27c9d3d7683..c09aec64a55 100644 --- a/packages/engine/Source/Core/Iau2006XysData.js +++ b/packages/engine/Source/Core/Iau2006XysData.js @@ -13,15 +13,15 @@ import TimeStandard from "./TimeStandard.js"; * @alias Iau2006XysData * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Resource|String} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, + * @param {object} [options] Object with the following properties: + * @param {Resource|string} [options.xysFileUrlTemplate='Assets/IAU2006_XYS/IAU2006_XYS_{0}.json'] A template URL for obtaining the XYS data. In the template, * `{0}` will be replaced with the file index. - * @param {Number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. - * @param {Number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the + * @param {number} [options.interpolationOrder=9] The order of interpolation to perform on the XYS data. + * @param {number} [options.sampleZeroJulianEphemerisDate=2442396.5] The Julian ephemeris date (JED) of the * first XYS sample. - * @param {Number} [options.stepSizeDays=1.0] The step size, in days, between successive XYS samples. - * @param {Number} [options.samplesPerXysFile=1000] The number of samples in each XYS file. - * @param {Number} [options.totalSamples=27426] The total number of samples in all XYS files. + * @param {number} [options.stepSizeDays=1.0] The step size, in days, between successive XYS samples. + * @param {number} [options.samplesPerXysFile=1000] The number of samples in each XYS file. + * @param {number} [options.totalSamples=27426] The total number of samples in all XYS files. * * @private */ @@ -85,13 +85,13 @@ function getDaysSinceEpoch(xys, dayTT, secondTT) { /** * Preloads XYS data for a specified date range. * - * @param {Number} startDayTT The Julian day number of the beginning of the interval to preload, expressed in + * @param {number} startDayTT The Julian day number of the beginning of the interval to preload, expressed in * the Terrestrial Time (TT) time standard. - * @param {Number} startSecondTT The seconds past noon of the beginning of the interval to preload, expressed in + * @param {number} startSecondTT The seconds past noon of the beginning of the interval to preload, expressed in * the Terrestrial Time (TT) time standard. - * @param {Number} stopDayTT The Julian day number of the end of the interval to preload, expressed in + * @param {number} stopDayTT The Julian day number of the end of the interval to preload, expressed in * the Terrestrial Time (TT) time standard. - * @param {Number} stopSecondTT The seconds past noon of the end of the interval to preload, expressed in + * @param {number} stopSecondTT The seconds past noon of the end of the interval to preload, expressed in * the Terrestrial Time (TT) time standard. * @returns {Promise<void>} A promise that, when resolved, indicates that the requested interval has been * preloaded. @@ -138,9 +138,9 @@ Iau2006XysData.prototype.preload = function ( * Computes the XYS values for a given date by interpolating. If the required data is not yet downloaded, * this method will return undefined. * - * @param {Number} dayTT The Julian day number for which to compute the XYS value, expressed in + * @param {number} dayTT The Julian day number for which to compute the XYS value, expressed in * the Terrestrial Time (TT) time standard. - * @param {Number} secondTT The seconds past noon of the date for which to compute the XYS value, expressed in + * @param {number} secondTT The seconds past noon of the date for which to compute the XYS value, expressed in * the Terrestrial Time (TT) time standard. * @param {Iau2006XysSample} [result] The instance to which to copy the interpolated result. If this parameter * is undefined, a new instance is allocated and returned. diff --git a/packages/engine/Source/Core/Iau2006XysSample.js b/packages/engine/Source/Core/Iau2006XysSample.js index 2e712b59226..e0a83e0c325 100644 --- a/packages/engine/Source/Core/Iau2006XysSample.js +++ b/packages/engine/Source/Core/Iau2006XysSample.js @@ -4,28 +4,28 @@ * @alias Iau2006XysSample * @constructor * - * @param {Number} x The X value. - * @param {Number} y The Y value. - * @param {Number} s The S value. + * @param {number} x The X value. + * @param {number} y The Y value. + * @param {number} s The S value. * * @private */ function Iau2006XysSample(x, y, s) { /** * The X value. - * @type {Number} + * @type {number} */ this.x = x; /** * The Y value. - * @type {Number} + * @type {number} */ this.y = y; /** * The S value. - * @type {Number} + * @type {number} */ this.s = s; } diff --git a/packages/engine/Source/Core/IauOrientationParameters.js b/packages/engine/Source/Core/IauOrientationParameters.js index 361aa7725fd..ba72c47384e 100644 --- a/packages/engine/Source/Core/IauOrientationParameters.js +++ b/packages/engine/Source/Core/IauOrientationParameters.js @@ -19,7 +19,7 @@ function IauOrientationParameters( /** * The right ascension of the north pole of the body with respect to * the International Celestial Reference Frame, in radians. - * @type {Number} + * @type {number} * * @private */ @@ -28,7 +28,7 @@ function IauOrientationParameters( /** * The declination of the north pole of the body with respect to * the International Celestial Reference Frame, in radians. - * @type {Number} + * @type {number} * * @private */ @@ -37,7 +37,7 @@ function IauOrientationParameters( /** * The rotation about the north pole used to align a set of axes with * the meridian defined by the IAU report, in radians. - * @type {Number} + * @type {number} * * @private */ @@ -45,7 +45,7 @@ function IauOrientationParameters( /** * The instantaneous rotation rate about the north pole, in radians per second. - * @type {Number} + * @type {number} * * @private */ diff --git a/packages/engine/Source/Core/IndexDatatype.js b/packages/engine/Source/Core/IndexDatatype.js index 70f4457a897..6a31e2ce942 100644 --- a/packages/engine/Source/Core/IndexDatatype.js +++ b/packages/engine/Source/Core/IndexDatatype.js @@ -7,14 +7,14 @@ import WebGLConstants from "./WebGLConstants.js"; * Constants for WebGL index datatypes. These corresponds to the * <code>type</code> parameter of {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml|drawElements}. * - * @enum {Number} + * @enum {number} */ const IndexDatatype = { /** * 8-bit unsigned byte corresponding to <code>UNSIGNED_BYTE</code> and the type * of an element in <code>Uint8Array</code>. * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_BYTE: WebGLConstants.UNSIGNED_BYTE, @@ -23,7 +23,7 @@ const IndexDatatype = { * 16-bit unsigned short corresponding to <code>UNSIGNED_SHORT</code> and the type * of an element in <code>Uint16Array</code>. * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_SHORT: WebGLConstants.UNSIGNED_SHORT, @@ -32,7 +32,7 @@ const IndexDatatype = { * 32-bit unsigned int corresponding to <code>UNSIGNED_INT</code> and the type * of an element in <code>Uint32Array</code>. * - * @type {Number} + * @type {number} * @constant */ UNSIGNED_INT: WebGLConstants.UNSIGNED_INT, @@ -42,7 +42,7 @@ const IndexDatatype = { * Returns the size, in bytes, of the corresponding datatype. * * @param {IndexDatatype} indexDatatype The index datatype to get the size of. - * @returns {Number} The size in bytes. + * @returns {number} The size in bytes. * * @example * // Returns 2 @@ -68,7 +68,7 @@ IndexDatatype.getSizeInBytes = function (indexDatatype) { /** * Gets the datatype with a given size in bytes. * - * @param {Number} sizeInBytes The size of a single index in bytes. + * @param {number} sizeInBytes The size of a single index in bytes. * @returns {IndexDatatype} The index datatype with the given size. */ IndexDatatype.fromSizeInBytes = function (sizeInBytes) { @@ -92,7 +92,7 @@ IndexDatatype.fromSizeInBytes = function (sizeInBytes) { * Validates that the provided index datatype is a valid {@link IndexDatatype}. * * @param {IndexDatatype} indexDatatype The index datatype to validate. - * @returns {Boolean} <code>true</code> if the provided index datatype is a valid value; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the provided index datatype is a valid value; otherwise, <code>false</code>. * * @example * if (!Cesium.IndexDatatype.validate(indexDatatype)) { @@ -112,8 +112,8 @@ IndexDatatype.validate = function (indexDatatype) { * Creates a typed array that will store indices, using either <code><Uint16Array</code> * or <code>Uint32Array</code> depending on the number of vertices. * - * @param {Number} numberOfVertices Number of vertices that the indices will reference. - * @param {Number|Array} indicesLengthOrArray Passed through to the typed array constructor. + * @param {number} numberOfVertices Number of vertices that the indices will reference. + * @param {number|Array} indicesLengthOrArray Passed through to the typed array constructor. * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>indicesLengthOrArray</code>. * * @example @@ -140,10 +140,10 @@ IndexDatatype.createTypedArray = function ( * Creates a typed array from a source array buffer. The resulting typed array will store indices, using either <code><Uint16Array</code> * or <code>Uint32Array</code> depending on the number of vertices. * - * @param {Number} numberOfVertices Number of vertices that the indices will reference. + * @param {number} numberOfVertices Number of vertices that the indices will reference. * @param {ArrayBuffer} sourceArray Passed through to the typed array constructor. - * @param {Number} byteOffset Passed through to the typed array constructor. - * @param {Number} length Passed through to the typed array constructor. + * @param {number} byteOffset Passed through to the typed array constructor. + * @param {number} length Passed through to the typed array constructor. * @returns {Uint16Array|Uint32Array} A <code>Uint16Array</code> or <code>Uint32Array</code> constructed with <code>sourceArray</code>, <code>byteOffset</code>, and <code>length</code>. * */ diff --git a/packages/engine/Source/Core/InterpolationAlgorithm.js b/packages/engine/Source/Core/InterpolationAlgorithm.js index f11caeba82e..b050eda4ddb 100644 --- a/packages/engine/Source/Core/InterpolationAlgorithm.js +++ b/packages/engine/Source/Core/InterpolationAlgorithm.js @@ -13,7 +13,7 @@ const InterpolationAlgorithm = {}; /** * Gets the name of this interpolation algorithm. - * @type {String} + * @type {string} */ InterpolationAlgorithm.type = undefined; @@ -21,8 +21,8 @@ InterpolationAlgorithm.type = undefined; * Given the desired degree, returns the number of data points required for interpolation. * @function * - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} The number of required data points needed for the desired degree of interpolation. + * @param {number} degree The desired degree of interpolation. + * @returns {number} The number of required data points needed for the desired degree of interpolation. */ InterpolationAlgorithm.getRequiredDataPoints = DeveloperError.throwInstantiationError; @@ -31,16 +31,16 @@ InterpolationAlgorithm.getRequiredDataPoints = * Performs zero order interpolation. * @function * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. + * @param {number[]} [result] An existing array into which to store the result. * - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ InterpolationAlgorithm.interpolateOrderZero = DeveloperError.throwInstantiationError; @@ -49,17 +49,17 @@ InterpolationAlgorithm.interpolateOrderZero = * Performs higher order interpolation. Not all interpolators need to support high-order interpolation, * if this function remains undefined on implementing objects, interpolateOrderZero will be used instead. * @function - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number} inputOrder The number of derivatives supplied for input. - * @param {Number} outputOrder The number of derivatives desired for output. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @param {number} inputOrder The number of derivatives supplied for input. + * @param {number} outputOrder The number of derivatives desired for output. + * @param {number[]} [result] An existing array into which to store the result. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ InterpolationAlgorithm.interpolate = DeveloperError.throwInstantiationError; export default InterpolationAlgorithm; diff --git a/packages/engine/Source/Core/InterpolationType.js b/packages/engine/Source/Core/InterpolationType.js index 2cfa604d2a9..50b6e4b3fc8 100644 --- a/packages/engine/Source/Core/InterpolationType.js +++ b/packages/engine/Source/Core/InterpolationType.js @@ -1,7 +1,7 @@ /** * An enum describing the type of interpolation used in a glTF animation. * - * @enum {Number} + * @enum {number} * * @private */ diff --git a/packages/engine/Source/Core/Intersect.js b/packages/engine/Source/Core/Intersect.js index 526bb9e2427..dada0889bd4 100644 --- a/packages/engine/Source/Core/Intersect.js +++ b/packages/engine/Source/Core/Intersect.js @@ -4,13 +4,13 @@ * partially inside the frustum and partially outside (INTERSECTING), or somewhere entirely * outside of the frustum's 6 planes (OUTSIDE). * - * @enum {Number} + * @enum {number} */ const Intersect = { /** * Represents that an object is not contained within the frustum. * - * @type {Number} + * @type {number} * @constant */ OUTSIDE: -1, @@ -18,7 +18,7 @@ const Intersect = { /** * Represents that an object intersects one of the frustum's planes. * - * @type {Number} + * @type {number} * @constant */ INTERSECTING: 0, @@ -26,7 +26,7 @@ const Intersect = { /** * Represents that an object is fully within the frustum. * - * @type {Number} + * @type {number} * @constant */ INSIDE: 1, diff --git a/packages/engine/Source/Core/IntersectionTests.js b/packages/engine/Source/Core/IntersectionTests.js index 92e3f861391..c8cbcbddebe 100644 --- a/packages/engine/Source/Core/IntersectionTests.js +++ b/packages/engine/Source/Core/IntersectionTests.js @@ -77,9 +77,9 @@ const scratchQVec = new Cartesian3(); * @param {Cartesian3} p0 The first vertex of the triangle. * @param {Cartesian3} p1 The second vertex of the triangle. * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * @param {boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle * and return undefined for intersections with the back face. - * @returns {Number} The intersection as a parametric distance along the ray, or undefined if there is no intersection. + * @returns {number} The intersection as a parametric distance along the ray, or undefined if there is no intersection. */ IntersectionTests.rayTriangleParametric = function ( ray, @@ -177,7 +177,7 @@ IntersectionTests.rayTriangleParametric = function ( * @param {Cartesian3} p0 The first vertex of the triangle. * @param {Cartesian3} p1 The second vertex of the triangle. * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * @param {boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle * and return undefined for intersections with the back face. * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. * @returns {Cartesian3} The intersection point or undefined if there is no intersections. @@ -220,7 +220,7 @@ const scratchLineSegmentTriangleRay = new Ray(); * @param {Cartesian3} p0 The first vertex of the triangle. * @param {Cartesian3} p1 The second vertex of the triangle. * @param {Cartesian3} p2 The third vertex of the triangle. - * @param {Boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle + * @param {boolean} [cullBackFaces=false] If <code>true</code>, will only compute an intersection with the front face of the triangle * and return undefined for intersections with the back face. * @param {Cartesian3} [result] The <code>Cartesian3</code> onto which to store the result. * @returns {Cartesian3} The intersection point or undefined if there is no intersections. @@ -868,7 +868,7 @@ IntersectionTests.lineSegmentPlane = function ( * @param {Cartesian3} p1 Second point of the triangle * @param {Cartesian3} p2 Third point of the triangle * @param {Plane} plane Intersection plane - * @returns {Object} An object with properties <code>positions</code> and <code>indices</code>, which are arrays that represent three triangles that do not cross the plane. (Undefined if no intersection exists) + * @returns {object} An object with properties <code>positions</code> and <code>indices</code>, which are arrays that represent three triangles that do not cross the plane. (Undefined if no intersection exists) * * @example * const origin = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); diff --git a/packages/engine/Source/Core/Intersections2D.js b/packages/engine/Source/Core/Intersections2D.js index dcf8db9955c..df98e06093d 100644 --- a/packages/engine/Source/Core/Intersections2D.js +++ b/packages/engine/Source/Core/Intersections2D.js @@ -16,15 +16,15 @@ const Intersections2D = {}; * polygon on a given side of the threshold. The resulting polygon may have 0, 1, 2, * 3, or 4 vertices. * - * @param {Number} threshold The threshold coordinate value at which to clip the triangle. - * @param {Boolean} keepAbove true to keep the portion of the triangle above the threshold, or false + * @param {number} threshold The threshold coordinate value at which to clip the triangle. + * @param {boolean} keepAbove true to keep the portion of the triangle above the threshold, or false * to keep the portion below. - * @param {Number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order. - * @param {Number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order. - * @param {Number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order. - * @param {Number[]} [result] The array into which to copy the result. If this parameter is not supplied, + * @param {number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order. + * @param {number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order. + * @param {number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order. + * @param {number[]} [result] The array into which to copy the result. If this parameter is not supplied, * a new array is constructed and returned. - * @returns {Number[]} The polygon that results after the clip, specified as a list of + * @returns {number[]} The polygon that results after the clip, specified as a list of * vertices. The vertices are specified in counter-clockwise order. * Each vertex is either an index from the existing list (identified as * a 0, 1, or 2) or -1 indicating a new vertex not in the original triangle. @@ -217,14 +217,14 @@ Intersections2D.clipTriangleAtAxisAlignedThreshold = function ( /** * Compute the barycentric coordinates of a 2D position within a 2D triangle. * - * @param {Number} x The x coordinate of the position for which to find the barycentric coordinates. - * @param {Number} y The y coordinate of the position for which to find the barycentric coordinates. - * @param {Number} x1 The x coordinate of the triangle's first vertex. - * @param {Number} y1 The y coordinate of the triangle's first vertex. - * @param {Number} x2 The x coordinate of the triangle's second vertex. - * @param {Number} y2 The y coordinate of the triangle's second vertex. - * @param {Number} x3 The x coordinate of the triangle's third vertex. - * @param {Number} y3 The y coordinate of the triangle's third vertex. + * @param {number} x The x coordinate of the position for which to find the barycentric coordinates. + * @param {number} y The y coordinate of the position for which to find the barycentric coordinates. + * @param {number} x1 The x coordinate of the triangle's first vertex. + * @param {number} y1 The y coordinate of the triangle's first vertex. + * @param {number} x2 The x coordinate of the triangle's second vertex. + * @param {number} y2 The y coordinate of the triangle's second vertex. + * @param {number} x3 The x coordinate of the triangle's third vertex. + * @param {number} y3 The y coordinate of the triangle's third vertex. * @param {Cartesian3} [result] The instance into to which to copy the result. If this parameter * is undefined, a new instance is created and returned. * @returns {Cartesian3} The barycentric coordinates of the position within the triangle. @@ -294,14 +294,14 @@ Intersections2D.computeBarycentricCoordinates = function ( /** * Compute the intersection between 2 line segments * - * @param {Number} x00 The x coordinate of the first line's first vertex. - * @param {Number} y00 The y coordinate of the first line's first vertex. - * @param {Number} x01 The x coordinate of the first line's second vertex. - * @param {Number} y01 The y coordinate of the first line's second vertex. - * @param {Number} x10 The x coordinate of the second line's first vertex. - * @param {Number} y10 The y coordinate of the second line's first vertex. - * @param {Number} x11 The x coordinate of the second line's second vertex. - * @param {Number} y11 The y coordinate of the second line's second vertex. + * @param {number} x00 The x coordinate of the first line's first vertex. + * @param {number} y00 The y coordinate of the first line's first vertex. + * @param {number} x01 The x coordinate of the first line's second vertex. + * @param {number} y01 The y coordinate of the first line's second vertex. + * @param {number} x10 The x coordinate of the second line's first vertex. + * @param {number} y10 The y coordinate of the second line's first vertex. + * @param {number} x11 The x coordinate of the second line's second vertex. + * @param {number} y11 The y coordinate of the second line's second vertex. * @param {Cartesian2} [result] The instance into to which to copy the result. If this parameter * is undefined, a new instance is created and returned. * @returns {Cartesian2} The intersection point, undefined if there is no intersection point or lines are coincident. diff --git a/packages/engine/Source/Core/Interval.js b/packages/engine/Source/Core/Interval.js index b09a5024ffc..4f8f99c8b96 100644 --- a/packages/engine/Source/Core/Interval.js +++ b/packages/engine/Source/Core/Interval.js @@ -5,19 +5,19 @@ import defaultValue from "./defaultValue.js"; * @alias Interval * @constructor * - * @param {Number} [start=0.0] The beginning of the interval. - * @param {Number} [stop=0.0] The end of the interval. + * @param {number} [start=0.0] The beginning of the interval. + * @param {number} [stop=0.0] The end of the interval. */ function Interval(start, stop) { /** * The beginning of the interval. - * @type {Number} + * @type {number} * @default 0.0 */ this.start = defaultValue(start, 0.0); /** * The end of the interval. - * @type {Number} + * @type {number} * @default 0.0 */ this.stop = defaultValue(stop, 0.0); diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index a1daf6ecd06..f566d49ac37 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -24,14 +24,14 @@ const Ion = {}; /** * Gets or sets the default Cesium ion access token. * - * @type {String} + * @type {string} */ Ion.defaultAccessToken = defaultAccessToken; /** * Gets or sets the default Cesium ion server. * - * @type {String|Resource} + * @type {string|Resource} * @default https://api.cesium.com */ Ion.defaultServer = new Resource({ url: "https://api.cesium.com/" }); diff --git a/packages/engine/Source/Core/IonGeocoderService.js b/packages/engine/Source/Core/IonGeocoderService.js index 534e7c5e9c7..8d73ff089cf 100644 --- a/packages/engine/Source/Core/IonGeocoderService.js +++ b/packages/engine/Source/Core/IonGeocoderService.js @@ -11,10 +11,10 @@ import Resource from "./Resource.js"; * @alias IonGeocoderService * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Scene} options.scene The scene - * @param {String} [options.accessToken=Ion.defaultAccessToken] The access token to use. - * @param {String|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server. + * @param {string} [options.accessToken=Ion.defaultAccessToken] The access token to use. + * @param {string|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server. * * @see Ion */ @@ -54,7 +54,7 @@ function IonGeocoderService(options) { /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. * @returns {Promise<GeocoderService.Result[]>} */ diff --git a/packages/engine/Source/Core/IonResource.js b/packages/engine/Source/Core/IonResource.js index ca3f0f36041..137be3899ee 100644 --- a/packages/engine/Source/Core/IonResource.js +++ b/packages/engine/Source/Core/IonResource.js @@ -15,7 +15,7 @@ import RuntimeError from "./RuntimeError.js"; * @constructor * @augments Resource * - * @param {Object} endpoint The result of the Cesium ion asset endpoint service. + * @param {object} endpoint The result of the Cesium ion asset endpoint service. * @param {Resource} endpointResource The resource used to retreive the endpoint. * * @see Ion @@ -80,11 +80,11 @@ if (defined(Object.create)) { /** * Asynchronously creates an instance. * - * @param {Number} assetId The Cesium ion asset id. - * @param {Object} [options] An object with the following properties: - * @param {String} [options.accessToken=Ion.defaultAccessToken] The access token to use. - * @param {String|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server. - * @returns {Promise.<IonResource>} A Promise to am instance representing the Cesium ion Asset. + * @param {number} assetId The Cesium ion asset id. + * @param {object} [options] An object with the following properties: + * @param {string} [options.accessToken=Ion.defaultAccessToken] The access token to use. + * @param {string|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server. + * @returns {Promise<IonResource>} A Promise to am instance representing the Cesium ion Asset. * * @example * //Load a Cesium3DTileset with asset ID of 124624234 diff --git a/packages/engine/Source/Core/JulianDate.js b/packages/engine/Source/Core/JulianDate.js index 363736b83cc..3e8a6ec24d5 100644 --- a/packages/engine/Source/Core/JulianDate.js +++ b/packages/engine/Source/Core/JulianDate.js @@ -199,20 +199,20 @@ const iso8601ErrorMessage = "Invalid ISO 8601 date."; * @alias JulianDate * @constructor * - * @param {Number} [julianDayNumber=0.0] The Julian Day Number representing the number of whole days. Fractional days will also be handled correctly. - * @param {Number} [secondsOfDay=0.0] The number of seconds into the current Julian Day Number. Fractional seconds, negative seconds and seconds greater than a day will be handled correctly. + * @param {number} [julianDayNumber=0.0] The Julian Day Number representing the number of whole days. Fractional days will also be handled correctly. + * @param {number} [secondsOfDay=0.0] The number of seconds into the current Julian Day Number. Fractional seconds, negative seconds and seconds greater than a day will be handled correctly. * @param {TimeStandard} [timeStandard=TimeStandard.UTC] The time standard in which the first two parameters are defined. */ function JulianDate(julianDayNumber, secondsOfDay, timeStandard) { /** * Gets or sets the number of whole days. - * @type {Number} + * @type {number} */ this.dayNumber = undefined; /** * Gets or sets the number of seconds into the current day. - * @type {Number} + * @type {number} */ this.secondsOfDay = undefined; @@ -304,7 +304,7 @@ JulianDate.fromDate = function (date, result) { * This method is superior to <code>Date.parse</code> because it will handle all valid formats defined by the ISO 8601 * specification, including leap seconds and sub-millisecond times, which discarded by most JavaScript implementations. * - * @param {String} iso8601String An ISO 8601 date. + * @param {string} iso8601String An ISO 8601 date. * @param {JulianDate} [result] An existing instance to use for the result. * @returns {JulianDate} The modified result parameter or a new instance if none was provided. * @@ -745,8 +745,8 @@ JulianDate.toDate = function (julianDate) { * Creates an ISO8601 representation of the provided date. * * @param {JulianDate} julianDate The date to be converted. - * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. - * @returns {String} The ISO8601 representation of the provided date. + * @param {number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. + * @returns {string} The ISO8601 representation of the provided date. */ JulianDate.toIso8601 = function (julianDate, precision) { //>>includeStart('debug', pragmas.debug); @@ -858,7 +858,7 @@ JulianDate.clone = function (julianDate, result) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Number} A negative value if left is less than right, a positive value if left is greater than right, or zero if left and right are equal. + * @returns {number} A negative value if left is less than right, a positive value if left is greater than right, or zero if left and right are equal. */ JulianDate.compare = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -882,7 +882,7 @@ JulianDate.compare = function (left, right) { * * @param {JulianDate} [left] The first instance. * @param {JulianDate} [right] The second instance. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. */ JulianDate.equals = function (left, right) { return ( @@ -902,8 +902,8 @@ JulianDate.equals = function (left, right) { * * @param {JulianDate} [left] The first instance. * @param {JulianDate} [right] The second instance. - * @param {Number} [epsilon=0] The maximum number of seconds that should separate the two instances. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + * @param {number} [epsilon=0] The maximum number of seconds that should separate the two instances. + * @returns {boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. */ JulianDate.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0); @@ -920,7 +920,7 @@ JulianDate.equalsEpsilon = function (left, right, epsilon) { * Computes the total number of whole and fractional days represented by the provided instance. * * @param {JulianDate} julianDate The date. - * @returns {Number} The Julian date as single floating point number. + * @returns {number} The Julian date as single floating point number. */ JulianDate.totalDays = function (julianDate) { //>>includeStart('debug', pragmas.debug); @@ -939,7 +939,7 @@ JulianDate.totalDays = function (julianDate) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Number} The difference, in seconds, when subtracting <code>right</code> from <code>left</code>. + * @returns {number} The difference, in seconds, when subtracting <code>right</code> from <code>left</code>. */ JulianDate.secondsDifference = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -961,7 +961,7 @@ JulianDate.secondsDifference = function (left, right) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Number} The difference, in days, when subtracting <code>right</code> from <code>left</code>. + * @returns {number} The difference, in days, when subtracting <code>right</code> from <code>left</code>. */ JulianDate.daysDifference = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -983,7 +983,7 @@ JulianDate.daysDifference = function (left, right) { * Computes the number of seconds the provided instance is ahead of UTC. * * @param {JulianDate} julianDate The date. - * @returns {Number} The number of seconds the provided instance is ahead of UTC + * @returns {number} The number of seconds the provided instance is ahead of UTC */ JulianDate.computeTaiMinusUtc = function (julianDate) { binarySearchScratchLeapSecond.julianDate = julianDate; @@ -1007,7 +1007,7 @@ JulianDate.computeTaiMinusUtc = function (julianDate) { * Adds the provided number of seconds to the provided date instance. * * @param {JulianDate} julianDate The date. - * @param {Number} seconds The number of seconds to add or subtract. + * @param {number} seconds The number of seconds to add or subtract. * @param {JulianDate} result An existing instance to use for the result. * @returns {JulianDate} The modified result parameter. */ @@ -1035,7 +1035,7 @@ JulianDate.addSeconds = function (julianDate, seconds, result) { * Adds the provided number of minutes to the provided date instance. * * @param {JulianDate} julianDate The date. - * @param {Number} minutes The number of minutes to add or subtract. + * @param {number} minutes The number of minutes to add or subtract. * @param {JulianDate} result An existing instance to use for the result. * @returns {JulianDate} The modified result parameter. */ @@ -1061,7 +1061,7 @@ JulianDate.addMinutes = function (julianDate, minutes, result) { * Adds the provided number of hours to the provided date instance. * * @param {JulianDate} julianDate The date. - * @param {Number} hours The number of hours to add or subtract. + * @param {number} hours The number of hours to add or subtract. * @param {JulianDate} result An existing instance to use for the result. * @returns {JulianDate} The modified result parameter. */ @@ -1087,7 +1087,7 @@ JulianDate.addHours = function (julianDate, hours, result) { * Adds the provided number of days to the provided date instance. * * @param {JulianDate} julianDate The date. - * @param {Number} days The number of days to add or subtract. + * @param {number} days The number of days to add or subtract. * @param {JulianDate} result An existing instance to use for the result. * @returns {JulianDate} The modified result parameter. */ @@ -1113,7 +1113,7 @@ JulianDate.addDays = function (julianDate, days, result) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if <code>left</code> is earlier than <code>right</code>, <code>false</code> otherwise. */ JulianDate.lessThan = function (left, right) { return JulianDate.compare(left, right) < 0; @@ -1124,7 +1124,7 @@ JulianDate.lessThan = function (left, right) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if <code>left</code> is earlier than or equal to <code>right</code>, <code>false</code> otherwise. */ JulianDate.lessThanOrEquals = function (left, right) { return JulianDate.compare(left, right) <= 0; @@ -1135,7 +1135,7 @@ JulianDate.lessThanOrEquals = function (left, right) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if <code>left</code> is later than <code>right</code>, <code>false</code> otherwise. */ JulianDate.greaterThan = function (left, right) { return JulianDate.compare(left, right) > 0; @@ -1146,7 +1146,7 @@ JulianDate.greaterThan = function (left, right) { * * @param {JulianDate} left The first instance. * @param {JulianDate} right The second instance. - * @returns {Boolean} <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if <code>left</code> is later than or equal to <code>right</code>, <code>false</code> otherwise. */ JulianDate.greaterThanOrEquals = function (left, right) { return JulianDate.compare(left, right) >= 0; @@ -1166,7 +1166,7 @@ JulianDate.prototype.clone = function (result) { * Compares this and the provided instance and returns <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {JulianDate} [right] The second instance. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. */ JulianDate.prototype.equals = function (right) { return JulianDate.equals(this, right); @@ -1179,8 +1179,8 @@ JulianDate.prototype.equals = function (right) { * seconds, must be less than <code>epsilon</code>. * * @param {JulianDate} [right] The second instance. - * @param {Number} [epsilon=0] The maximum number of seconds that should separate the two instances. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + * @param {number} [epsilon=0] The maximum number of seconds that should separate the two instances. + * @returns {boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. */ JulianDate.prototype.equalsEpsilon = function (right, epsilon) { return JulianDate.equalsEpsilon(this, right, epsilon); @@ -1189,7 +1189,7 @@ JulianDate.prototype.equalsEpsilon = function (right, epsilon) { /** * Creates a string representing this date in ISO8601 format. * - * @returns {String} A string representing this date in ISO8601 format. + * @returns {string} A string representing this date in ISO8601 format. */ JulianDate.prototype.toString = function () { return JulianDate.toIso8601(this); diff --git a/packages/engine/Source/Core/KeyboardEventModifier.js b/packages/engine/Source/Core/KeyboardEventModifier.js index 687783fdf74..ede05482c42 100644 --- a/packages/engine/Source/Core/KeyboardEventModifier.js +++ b/packages/engine/Source/Core/KeyboardEventModifier.js @@ -2,13 +2,13 @@ * This enumerated type is for representing keyboard modifiers. These are keys * that are held down in addition to other event types. * - * @enum {Number} + * @enum {number} */ const KeyboardEventModifier = { /** * Represents the shift key being held down. * - * @type {Number} + * @type {number} * @constant */ SHIFT: 0, @@ -16,7 +16,7 @@ const KeyboardEventModifier = { /** * Represents the control key being held down. * - * @type {Number} + * @type {number} * @constant */ CTRL: 1, @@ -24,7 +24,7 @@ const KeyboardEventModifier = { /** * Represents the alt key being held down. * - * @type {Number} + * @type {number} * @constant */ ALT: 2, diff --git a/packages/engine/Source/Core/LagrangePolynomialApproximation.js b/packages/engine/Source/Core/LagrangePolynomialApproximation.js index e5f91d7bebb..67c15aa28fb 100644 --- a/packages/engine/Source/Core/LagrangePolynomialApproximation.js +++ b/packages/engine/Source/Core/LagrangePolynomialApproximation.js @@ -12,8 +12,8 @@ const LagrangePolynomialApproximation = { /** * Given the desired degree, returns the number of data points required for interpolation. * - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} The number of required data points needed for the desired degree of interpolation. + * @param {number} degree The desired degree of interpolation. + * @returns {number} The number of required data points needed for the desired degree of interpolation. */ LagrangePolynomialApproximation.getRequiredDataPoints = function (degree) { return Math.max(degree + 1.0, 2); @@ -22,15 +22,15 @@ LagrangePolynomialApproximation.getRequiredDataPoints = function (degree) { /** * Interpolates values using Lagrange Polynomial Approximation. * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @param {number[]} [result] An existing array into which to store the result. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ LagrangePolynomialApproximation.interpolateOrderZero = function ( x, diff --git a/packages/engine/Source/Core/LeapSecond.js b/packages/engine/Source/Core/LeapSecond.js index 920fa66c33c..dbcf62cd453 100644 --- a/packages/engine/Source/Core/LeapSecond.js +++ b/packages/engine/Source/Core/LeapSecond.js @@ -5,7 +5,7 @@ * @constructor * * @param {JulianDate} [date] A Julian date representing the time of the leap second. - * @param {Number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. + * @param {number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. */ function LeapSecond(date, offset) { /** @@ -17,7 +17,7 @@ function LeapSecond(date, offset) { /** * Gets or sets the cumulative number of seconds between the UTC and TAI time standards at the time * of this leap second. - * @type {Number} + * @type {number} */ this.offset = offset; } diff --git a/packages/engine/Source/Core/LinearApproximation.js b/packages/engine/Source/Core/LinearApproximation.js index 3137ffc896e..c605a7f4fb3 100644 --- a/packages/engine/Source/Core/LinearApproximation.js +++ b/packages/engine/Source/Core/LinearApproximation.js @@ -14,8 +14,8 @@ const LinearApproximation = { * Given the desired degree, returns the number of data points required for interpolation. * Since linear interpolation can only generate a first degree polynomial, this function * always returns 2. - * @param {Number} degree The desired degree of interpolation. - * @returns {Number} This function always returns 2. + * @param {number} degree The desired degree of interpolation. + * @returns {number} This function always returns 2. * */ LinearApproximation.getRequiredDataPoints = function (degree) { @@ -25,15 +25,15 @@ LinearApproximation.getRequiredDataPoints = function (degree) { /** * Interpolates values using linear approximation. * - * @param {Number} x The independent variable for which the dependent variables will be interpolated. - * @param {Number[]} xTable The array of independent variables to use to interpolate. The values + * @param {number} x The independent variable for which the dependent variables will be interpolated. + * @param {number[]} xTable The array of independent variables to use to interpolate. The values * in this array must be in increasing order and the same value must not occur twice in the array. - * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three + * @param {number[]} yTable The array of dependent variables to use to interpolate. For a set of three * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. - * @param {Number} yStride The number of dependent variable values in yTable corresponding to + * @param {number} yStride The number of dependent variable values in yTable corresponding to * each independent variable value in xTable. - * @param {Number[]} [result] An existing array into which to store the result. - * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. + * @param {number[]} [result] An existing array into which to store the result. + * @returns {number[]} The array of interpolated values, or the result parameter if one was provided. */ LinearApproximation.interpolateOrderZero = function ( x, diff --git a/packages/engine/Source/Core/LinearSpline.js b/packages/engine/Source/Core/LinearSpline.js index 3e327440dbe..d067d318cc2 100644 --- a/packages/engine/Source/Core/LinearSpline.js +++ b/packages/engine/Source/Core/LinearSpline.js @@ -10,10 +10,10 @@ import Spline from "./Spline.js"; * @alias LinearSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Number[]|Cartesian3[]} options.points The array of control points. + * @param {number[]|Cartesian3[]} options.points The array of control points. * * @exception {DeveloperError} points.length must be greater than or equal to 2. * @exception {DeveloperError} times.length must be equal to points.length. @@ -74,7 +74,7 @@ Object.defineProperties(LinearSpline.prototype, { * * @memberof LinearSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -88,7 +88,7 @@ Object.defineProperties(LinearSpline.prototype, { * * @memberof LinearSpline.prototype * - * @type {Number[]|Cartesian3[]} + * @type {number[]|Cartesian3[]} * @readonly */ points: { @@ -103,8 +103,8 @@ Object.defineProperties(LinearSpline.prototype, { * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -116,8 +116,8 @@ LinearSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ LinearSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -125,17 +125,17 @@ LinearSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ LinearSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Number|Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. + * @returns {number|Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element diff --git a/packages/engine/Source/Core/ManagedArray.js b/packages/engine/Source/Core/ManagedArray.js index 180143d222f..7b010687fda 100644 --- a/packages/engine/Source/Core/ManagedArray.js +++ b/packages/engine/Source/Core/ManagedArray.js @@ -8,7 +8,7 @@ import defaultValue from "./defaultValue.js"; * @constructor * @private * - * @param {Number} [length=0] The initial length of the array. + * @param {number} [length=0] The initial length of the array. */ function ManagedArray(length) { length = defaultValue(length, 0); @@ -63,7 +63,7 @@ Object.defineProperties(ManagedArray.prototype, { /** * Gets the element at an index. * - * @param {Number} index The index to get. + * @param {number} index The index to get. */ ManagedArray.prototype.get = function (index) { //>>includeStart('debug', pragmas.debug); @@ -76,7 +76,7 @@ ManagedArray.prototype.get = function (index) { /** * Sets the element at an index. Resizes the array if index is greater than the length of the array. * - * @param {Number} index The index to set. + * @param {number} index The index to set. * @param {*} element The element to set at index. */ ManagedArray.prototype.set = function (index, element) { @@ -126,7 +126,7 @@ ManagedArray.prototype.pop = function () { /** * Resize the internal array if length > _array.length. * - * @param {Number} length The length. + * @param {number} length The length. */ ManagedArray.prototype.reserve = function (length) { //>>includeStart('debug', pragmas.debug); @@ -141,7 +141,7 @@ ManagedArray.prototype.reserve = function (length) { /** * Resize the array. * - * @param {Number} length The length. + * @param {number} length The length. */ ManagedArray.prototype.resize = function (length) { //>>includeStart('debug', pragmas.debug); @@ -154,7 +154,7 @@ ManagedArray.prototype.resize = function (length) { /** * Trim the internal array to the specified length. Defaults to the current length. * - * @param {Number} [length] The length. + * @param {number} [length] The length. */ ManagedArray.prototype.trim = function (length) { length = defaultValue(length, this._length); diff --git a/packages/engine/Source/Core/Math.js b/packages/engine/Source/Core/Math.js index c61d9917441..a8f5e57d681 100644 --- a/packages/engine/Source/Core/Math.js +++ b/packages/engine/Source/Core/Math.js @@ -14,147 +14,147 @@ const CesiumMath = {}; /** * 0.1 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON1 = 0.1; /** * 0.01 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON2 = 0.01; /** * 0.001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON3 = 0.001; /** * 0.0001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON4 = 0.0001; /** * 0.00001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON5 = 0.00001; /** * 0.000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON6 = 0.000001; /** * 0.0000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON7 = 0.0000001; /** * 0.00000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON8 = 0.00000001; /** * 0.000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON9 = 0.000000001; /** * 0.0000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON10 = 0.0000000001; /** * 0.00000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON11 = 0.00000000001; /** * 0.000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON12 = 0.000000000001; /** * 0.0000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON13 = 0.0000000000001; /** * 0.00000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON14 = 0.00000000000001; /** * 0.000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON15 = 0.000000000000001; /** * 0.0000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON16 = 0.0000000000000001; /** * 0.00000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON17 = 0.00000000000000001; /** * 0.000000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON18 = 0.000000000000000001; /** * 0.0000000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON19 = 0.0000000000000000001; /** * 0.00000000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON20 = 0.00000000000000000001; /** * 0.000000000000000000001 - * @type {Number} + * @type {number} * @constant */ CesiumMath.EPSILON21 = 0.000000000000000000001; @@ -162,14 +162,14 @@ CesiumMath.EPSILON21 = 0.000000000000000000001; /** * The gravitational parameter of the Earth in meters cubed * per second squared as defined by the WGS84 model: 3.986004418e14 - * @type {Number} + * @type {number} * @constant */ CesiumMath.GRAVITATIONALPARAMETER = 3.986004418e14; /** * Radius of the sun in meters: 6.955e8 - * @type {Number} + * @type {number} * @constant */ CesiumMath.SOLAR_RADIUS = 6.955e8; @@ -178,21 +178,21 @@ CesiumMath.SOLAR_RADIUS = 6.955e8; * The mean radius of the moon, according to the "Report of the IAU/IAG Working Group on * Cartographic Coordinates and Rotational Elements of the Planets and satellites: 2000", * Celestial Mechanics 82: 83-110, 2002. - * @type {Number} + * @type {number} * @constant */ CesiumMath.LUNAR_RADIUS = 1737400.0; /** * 64 * 1024 - * @type {Number} + * @type {number} * @constant */ CesiumMath.SIXTY_FOUR_KILOBYTES = 64 * 1024; /** * 4 * 1024 * 1024 * 1024 - * @type {Number} + * @type {number} * @constant */ CesiumMath.FOUR_GIGABYTES = 4 * 1024 * 1024 * 1024; @@ -202,8 +202,8 @@ CesiumMath.FOUR_GIGABYTES = 4 * 1024 * 1024 * 1024; * negative, or 0 if the value is 0. * * @function - * @param {Number} value The value to return the sign of. - * @returns {Number} The sign of value. + * @param {number} value The value to return the sign of. + * @returns {number} The sign of value. */ // eslint-disable-next-line es/no-math-sign CesiumMath.sign = defaultValue(Math.sign, function sign(value) { @@ -219,8 +219,8 @@ CesiumMath.sign = defaultValue(Math.sign, function sign(value) { * Returns 1.0 if the given value is positive or zero, and -1.0 if it is negative. * This is similar to {@link CesiumMath#sign} except that returns 1.0 instead of * 0.0 when the input value is 0.0. - * @param {Number} value The value to return the sign of. - * @returns {Number} The sign of value. + * @param {number} value The value to return the sign of. + * @returns {number} The sign of value. */ CesiumMath.signNotZero = function (value) { return value < 0.0 ? -1.0 : 1.0; @@ -228,9 +228,9 @@ CesiumMath.signNotZero = function (value) { /** * Converts a scalar value in the range [-1.0, 1.0] to a SNORM in the range [0, rangeMaximum] - * @param {Number} value The scalar value in the range [-1.0, 1.0] - * @param {Number} [rangeMaximum=255] The maximum value in the mapped range, 255 by default. - * @returns {Number} A SNORM value, where 0 maps to -1.0 and rangeMaximum maps to 1.0. + * @param {number} value The scalar value in the range [-1.0, 1.0] + * @param {number} [rangeMaximum=255] The maximum value in the mapped range, 255 by default. + * @returns {number} A SNORM value, where 0 maps to -1.0 and rangeMaximum maps to 1.0. * * @see CesiumMath.fromSNorm */ @@ -243,9 +243,9 @@ CesiumMath.toSNorm = function (value, rangeMaximum) { /** * Converts a SNORM value in the range [0, rangeMaximum] to a scalar in the range [-1.0, 1.0]. - * @param {Number} value SNORM value in the range [0, rangeMaximum] - * @param {Number} [rangeMaximum=255] The maximum value in the SNORM range, 255 by default. - * @returns {Number} Scalar in the range [-1.0, 1.0]. + * @param {number} value SNORM value in the range [0, rangeMaximum] + * @param {number} [rangeMaximum=255] The maximum value in the SNORM range, 255 by default. + * @returns {number} Scalar in the range [-1.0, 1.0]. * * @see CesiumMath.toSNorm */ @@ -258,10 +258,10 @@ CesiumMath.fromSNorm = function (value, rangeMaximum) { /** * Converts a scalar value in the range [rangeMinimum, rangeMaximum] to a scalar in the range [0.0, 1.0] - * @param {Number} value The scalar value in the range [rangeMinimum, rangeMaximum] - * @param {Number} rangeMinimum The minimum value in the mapped range. - * @param {Number} rangeMaximum The maximum value in the mapped range. - * @returns {Number} A scalar value, where rangeMinimum maps to 0.0 and rangeMaximum maps to 1.0. + * @param {number} value The scalar value in the range [rangeMinimum, rangeMaximum] + * @param {number} rangeMinimum The minimum value in the mapped range. + * @param {number} rangeMaximum The maximum value in the mapped range. + * @returns {number} A scalar value, where rangeMinimum maps to 0.0 and rangeMaximum maps to 1.0. */ CesiumMath.normalize = function (value, rangeMinimum, rangeMaximum) { rangeMaximum = Math.max(rangeMaximum - rangeMinimum, 0.0); @@ -289,8 +289,8 @@ CesiumMath.normalize = function (value, rangeMinimum, rangeMaximum) { *</p> * * @function - * @param {Number} value The number whose hyperbolic sine is to be returned. - * @returns {Number} The hyperbolic sine of <code>value</code>. + * @param {number} value The number whose hyperbolic sine is to be returned. + * @returns {number} The hyperbolic sine of <code>value</code>. */ // eslint-disable-next-line es/no-math-sinh CesiumMath.sinh = defaultValue(Math.sinh, function sinh(value) { @@ -314,8 +314,8 @@ CesiumMath.sinh = defaultValue(Math.sinh, function sinh(value) { *</p> * * @function - * @param {Number} value The number whose hyperbolic cosine is to be returned. - * @returns {Number} The hyperbolic cosine of <code>value</code>. + * @param {number} value The number whose hyperbolic cosine is to be returned. + * @returns {number} The hyperbolic cosine of <code>value</code>. */ // eslint-disable-next-line es/no-math-cosh CesiumMath.cosh = defaultValue(Math.cosh, function cosh(value) { @@ -325,10 +325,10 @@ CesiumMath.cosh = defaultValue(Math.cosh, function cosh(value) { /** * Computes the linear interpolation of two values. * - * @param {Number} p The start value to interpolate. - * @param {Number} q The end value to interpolate. - * @param {Number} time The time of interpolation generally in the range <code>[0.0, 1.0]</code>. - * @returns {Number} The linearly interpolated value. + * @param {number} p The start value to interpolate. + * @param {number} q The end value to interpolate. + * @param {number} time The time of interpolation generally in the range <code>[0.0, 1.0]</code>. + * @returns {number} The linearly interpolated value. * * @example * const n = Cesium.Math.lerp(0.0, 2.0, 0.5); // returns 1.0 @@ -340,7 +340,7 @@ CesiumMath.lerp = function (p, q, time) { /** * pi * - * @type {Number} + * @type {number} * @constant */ CesiumMath.PI = Math.PI; @@ -348,7 +348,7 @@ CesiumMath.PI = Math.PI; /** * 1/pi * - * @type {Number} + * @type {number} * @constant */ CesiumMath.ONE_OVER_PI = 1.0 / Math.PI; @@ -356,7 +356,7 @@ CesiumMath.ONE_OVER_PI = 1.0 / Math.PI; /** * pi/2 * - * @type {Number} + * @type {number} * @constant */ CesiumMath.PI_OVER_TWO = Math.PI / 2.0; @@ -364,7 +364,7 @@ CesiumMath.PI_OVER_TWO = Math.PI / 2.0; /** * pi/3 * - * @type {Number} + * @type {number} * @constant */ CesiumMath.PI_OVER_THREE = Math.PI / 3.0; @@ -372,7 +372,7 @@ CesiumMath.PI_OVER_THREE = Math.PI / 3.0; /** * pi/4 * - * @type {Number} + * @type {number} * @constant */ CesiumMath.PI_OVER_FOUR = Math.PI / 4.0; @@ -380,7 +380,7 @@ CesiumMath.PI_OVER_FOUR = Math.PI / 4.0; /** * pi/6 * - * @type {Number} + * @type {number} * @constant */ CesiumMath.PI_OVER_SIX = Math.PI / 6.0; @@ -388,7 +388,7 @@ CesiumMath.PI_OVER_SIX = Math.PI / 6.0; /** * 3pi/2 * - * @type {Number} + * @type {number} * @constant */ CesiumMath.THREE_PI_OVER_TWO = (3.0 * Math.PI) / 2.0; @@ -396,7 +396,7 @@ CesiumMath.THREE_PI_OVER_TWO = (3.0 * Math.PI) / 2.0; /** * 2pi * - * @type {Number} + * @type {number} * @constant */ CesiumMath.TWO_PI = 2.0 * Math.PI; @@ -404,7 +404,7 @@ CesiumMath.TWO_PI = 2.0 * Math.PI; /** * 1/2pi * - * @type {Number} + * @type {number} * @constant */ CesiumMath.ONE_OVER_TWO_PI = 1.0 / (2.0 * Math.PI); @@ -412,7 +412,7 @@ CesiumMath.ONE_OVER_TWO_PI = 1.0 / (2.0 * Math.PI); /** * The number of radians in a degree. * - * @type {Number} + * @type {number} * @constant */ CesiumMath.RADIANS_PER_DEGREE = Math.PI / 180.0; @@ -420,7 +420,7 @@ CesiumMath.RADIANS_PER_DEGREE = Math.PI / 180.0; /** * The number of degrees in a radian. * - * @type {Number} + * @type {number} * @constant */ CesiumMath.DEGREES_PER_RADIAN = 180.0 / Math.PI; @@ -428,15 +428,15 @@ CesiumMath.DEGREES_PER_RADIAN = 180.0 / Math.PI; /** * The number of radians in an arc second. * - * @type {Number} + * @type {number} * @constant */ CesiumMath.RADIANS_PER_ARCSECOND = CesiumMath.RADIANS_PER_DEGREE / 3600.0; /** * Converts degrees to radians. - * @param {Number} degrees The angle to convert in degrees. - * @returns {Number} The corresponding angle in radians. + * @param {number} degrees The angle to convert in degrees. + * @returns {number} The corresponding angle in radians. */ CesiumMath.toRadians = function (degrees) { //>>includeStart('debug', pragmas.debug); @@ -449,8 +449,8 @@ CesiumMath.toRadians = function (degrees) { /** * Converts radians to degrees. - * @param {Number} radians The angle to convert in radians. - * @returns {Number} The corresponding angle in degrees. + * @param {number} radians The angle to convert in radians. + * @returns {number} The corresponding angle in degrees. */ CesiumMath.toDegrees = function (radians) { //>>includeStart('debug', pragmas.debug); @@ -464,8 +464,8 @@ CesiumMath.toDegrees = function (radians) { /** * Converts a longitude value, in radians, to the range [<code>-Math.PI</code>, <code>Math.PI</code>). * - * @param {Number} angle The longitude value, in radians, to convert to the range [<code>-Math.PI</code>, <code>Math.PI</code>). - * @returns {Number} The equivalent longitude value in the range [<code>-Math.PI</code>, <code>Math.PI</code>). + * @param {number} angle The longitude value, in radians, to convert to the range [<code>-Math.PI</code>, <code>Math.PI</code>). + * @returns {number} The equivalent longitude value in the range [<code>-Math.PI</code>, <code>Math.PI</code>). * * @example * // Convert 270 degrees to -90 degrees longitude @@ -495,8 +495,8 @@ CesiumMath.convertLongitudeRange = function (angle) { * Convenience function that clamps a latitude value, in radians, to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>). * Useful for sanitizing data before use in objects requiring correct range. * - * @param {Number} angle The latitude value, in radians, to clamp to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>). - * @returns {Number} The latitude value clamped to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>). + * @param {number} angle The latitude value, in radians, to clamp to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>). + * @returns {number} The latitude value clamped to the range [<code>-Math.PI/2</code>, <code>Math.PI/2</code>). * * @example * // Clamp 108 degrees latitude to 90 degrees latitude @@ -519,8 +519,8 @@ CesiumMath.clampToLatitudeRange = function (angle) { /** * Produces an angle in the range -Pi <= angle <= Pi which is equivalent to the provided angle. * - * @param {Number} angle in radians - * @returns {Number} The angle in the range [<code>-CesiumMath.PI</code>, <code>CesiumMath.PI</code>]. + * @param {number} angle in radians + * @returns {number} The angle in the range [<code>-CesiumMath.PI</code>, <code>CesiumMath.PI</code>]. */ CesiumMath.negativePiToPi = function (angle) { //>>includeStart('debug', pragmas.debug); @@ -539,8 +539,8 @@ CesiumMath.negativePiToPi = function (angle) { /** * Produces an angle in the range 0 <= angle <= 2Pi which is equivalent to the provided angle. * - * @param {Number} angle in radians - * @returns {Number} The angle in the range [0, <code>CesiumMath.TWO_PI</code>]. + * @param {number} angle in radians + * @returns {number} The angle in the range [0, <code>CesiumMath.TWO_PI</code>]. */ CesiumMath.zeroToTwoPi = function (angle) { //>>includeStart('debug', pragmas.debug); @@ -566,9 +566,9 @@ CesiumMath.zeroToTwoPi = function (angle) { /** * The modulo operation that also works for negative dividends. * - * @param {Number} m The dividend. - * @param {Number} n The divisor. - * @returns {Number} The remainder. + * @param {number} m The dividend. + * @param {number} n The divisor. + * @returns {number} The remainder. */ CesiumMath.mod = function (m, n) { //>>includeStart('debug', pragmas.debug); @@ -597,11 +597,11 @@ CesiumMath.mod = function (m, n) { * first compared using an absolute tolerance test. If that fails, a relative tolerance test is performed. * Use this test if you are unsure of the magnitudes of left and right. * - * @param {Number} left The first value to compare. - * @param {Number} right The other value to compare. - * @param {Number} [relativeEpsilon=0] The maximum inclusive delta between <code>left</code> and <code>right</code> for the relative tolerance test. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The maximum inclusive delta between <code>left</code> and <code>right</code> for the absolute tolerance test. - * @returns {Boolean} <code>true</code> if the values are equal within the epsilon; otherwise, <code>false</code>. + * @param {number} left The first value to compare. + * @param {number} right The other value to compare. + * @param {number} [relativeEpsilon=0] The maximum inclusive delta between <code>left</code> and <code>right</code> for the relative tolerance test. + * @param {number} [absoluteEpsilon=relativeEpsilon] The maximum inclusive delta between <code>left</code> and <code>right</code> for the absolute tolerance test. + * @returns {boolean} <code>true</code> if the values are equal within the epsilon; otherwise, <code>false</code>. * * @example * const a = Cesium.Math.equalsEpsilon(0.0, 0.01, Cesium.Math.EPSILON2); // true @@ -637,10 +637,10 @@ CesiumMath.equalsEpsilon = function ( * Determines if the left value is less than the right value. If the two values are within * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns false. * - * @param {Number} left The first number to compare. - * @param {Number} right The second number to compare. - * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison. - * @returns {Boolean} <code>true</code> if <code>left</code> is less than <code>right</code> by more than + * @param {number} left The first number to compare. + * @param {number} right The second number to compare. + * @param {number} absoluteEpsilon The absolute epsilon to use in comparison. + * @returns {boolean} <code>true</code> if <code>left</code> is less than <code>right</code> by more than * <code>absoluteEpsilon<code>. <code>false</code> if <code>left</code> is greater or if the two * values are nearly equal. */ @@ -663,10 +663,10 @@ CesiumMath.lessThan = function (left, right, absoluteEpsilon) { * Determines if the left value is less than or equal to the right value. If the two values are within * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns true. * - * @param {Number} left The first number to compare. - * @param {Number} right The second number to compare. - * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison. - * @returns {Boolean} <code>true</code> if <code>left</code> is less than <code>right</code> or if the + * @param {number} left The first number to compare. + * @param {number} right The second number to compare. + * @param {number} absoluteEpsilon The absolute epsilon to use in comparison. + * @returns {boolean} <code>true</code> if <code>left</code> is less than <code>right</code> or if the * the values are nearly equal. */ CesiumMath.lessThanOrEquals = function (left, right, absoluteEpsilon) { @@ -688,10 +688,10 @@ CesiumMath.lessThanOrEquals = function (left, right, absoluteEpsilon) { * Determines if the left value is greater the right value. If the two values are within * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns false. * - * @param {Number} left The first number to compare. - * @param {Number} right The second number to compare. - * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison. - * @returns {Boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> by more than + * @param {number} left The first number to compare. + * @param {number} right The second number to compare. + * @param {number} absoluteEpsilon The absolute epsilon to use in comparison. + * @returns {boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> by more than * <code>absoluteEpsilon<code>. <code>false</code> if <code>left</code> is less or if the two * values are nearly equal. */ @@ -714,10 +714,10 @@ CesiumMath.greaterThan = function (left, right, absoluteEpsilon) { * Determines if the left value is greater than or equal to the right value. If the two values are within * <code>absoluteEpsilon</code> of each other, they are considered equal and this function returns true. * - * @param {Number} left The first number to compare. - * @param {Number} right The second number to compare. - * @param {Number} absoluteEpsilon The absolute epsilon to use in comparison. - * @returns {Boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> or if the + * @param {number} left The first number to compare. + * @param {number} right The second number to compare. + * @param {number} absoluteEpsilon The absolute epsilon to use in comparison. + * @returns {boolean} <code>true</code> if <code>left</code> is greater than <code>right</code> or if the * the values are nearly equal. */ CesiumMath.greaterThanOrEquals = function (left, right, absoluteEpsilon) { @@ -740,8 +740,8 @@ const factorials = [1]; /** * Computes the factorial of the provided number. * - * @param {Number} n The number whose factorial is to be computed. - * @returns {Number} The factorial of the provided number or undefined if the number is less than 0. + * @param {number} n The number whose factorial is to be computed. + * @returns {number} The factorial of the provided number or undefined if the number is less than 0. * * @exception {DeveloperError} A number greater than or equal to 0 is required. * @@ -776,10 +776,10 @@ CesiumMath.factorial = function (n) { /** * Increments a number with a wrapping to a minimum value if the number exceeds the maximum value. * - * @param {Number} [n] The number to be incremented. - * @param {Number} [maximumValue] The maximum incremented value before rolling over to the minimum value. - * @param {Number} [minimumValue=0.0] The number reset to after the maximum value has been exceeded. - * @returns {Number} The incremented number. + * @param {number} [n] The number to be incremented. + * @param {number} [maximumValue] The maximum incremented value before rolling over to the minimum value. + * @param {number} [minimumValue=0.0] The number reset to after the maximum value has been exceeded. + * @returns {number} The incremented number. * * @exception {DeveloperError} Maximum value must be greater than minimum value. * @@ -810,8 +810,8 @@ CesiumMath.incrementWrap = function (n, maximumValue, minimumValue) { * Determines if a non-negative integer is a power of two. * The maximum allowed input is (2^32)-1 due to 32-bit bitwise operator limitation in Javascript. * - * @param {Number} n The integer to test in the range [0, (2^32)-1]. - * @returns {Boolean} <code>true</code> if the number if a power of two; otherwise, <code>false</code>. + * @param {number} n The integer to test in the range [0, (2^32)-1]. + * @returns {boolean} <code>true</code> if the number if a power of two; otherwise, <code>false</code>. * * @exception {DeveloperError} A number between 0 and (2^32)-1 is required. * @@ -833,8 +833,8 @@ CesiumMath.isPowerOfTwo = function (n) { * Computes the next power-of-two integer greater than or equal to the provided non-negative integer. * The maximum allowed input is 2^31 due to 32-bit bitwise operator limitation in Javascript. * - * @param {Number} n The integer to test in the range [0, 2^31]. - * @returns {Number} The next power-of-two integer. + * @param {number} n The integer to test in the range [0, 2^31]. + * @returns {number} The next power-of-two integer. * * @exception {DeveloperError} A number between 0 and 2^31 is required. * @@ -865,8 +865,8 @@ CesiumMath.nextPowerOfTwo = function (n) { * Computes the previous power-of-two integer less than or equal to the provided non-negative integer. * The maximum allowed input is (2^32)-1 due to 32-bit bitwise operator limitation in Javascript. * - * @param {Number} n The integer to test in the range [0, (2^32)-1]. - * @returns {Number} The previous power-of-two integer. + * @param {number} n The integer to test in the range [0, (2^32)-1]. + * @returns {number} The previous power-of-two integer. * * @exception {DeveloperError} A number between 0 and (2^32)-1 is required. * @@ -897,10 +897,10 @@ CesiumMath.previousPowerOfTwo = function (n) { /** * Constraint a value to lie between two values. * - * @param {Number} value The value to clamp. - * @param {Number} min The minimum value. - * @param {Number} max The maximum value. - * @returns {Number} The clamped value such that min <= result <= max. + * @param {number} value The value to clamp. + * @param {number} min The minimum value. + * @param {number} max The maximum value. + * @returns {number} The clamped value such that min <= result <= max. */ CesiumMath.clamp = function (value, min, max) { //>>includeStart('debug', pragmas.debug); @@ -918,7 +918,7 @@ let randomNumberGenerator = new MersenneTwister(); * Sets the seed used by the random number generator * in {@link CesiumMath#nextRandomNumber}. * - * @param {Number} seed An integer used as the seed. + * @param {number} seed An integer used as the seed. */ CesiumMath.setRandomNumberSeed = function (seed) { //>>includeStart('debug', pragmas.debug); @@ -934,7 +934,7 @@ CesiumMath.setRandomNumberSeed = function (seed) { * Generates a random floating point number in the range of [0.0, 1.0) * using a Mersenne twister. * - * @returns {Number} A random number in the range of [0.0, 1.0). + * @returns {number} A random number in the range of [0.0, 1.0). * * @see CesiumMath.setRandomNumberSeed * @see {@link http://en.wikipedia.org/wiki/Mersenne_twister|Mersenne twister on Wikipedia} @@ -946,9 +946,9 @@ CesiumMath.nextRandomNumber = function () { /** * Generates a random number between two numbers. * - * @param {Number} min The minimum value. - * @param {Number} max The maximum value. - * @returns {Number} A random number between the min and max. + * @param {number} min The minimum value. + * @param {number} max The maximum value. + * @returns {number} A random number between the min and max. */ CesiumMath.randomBetween = function (min, max) { return CesiumMath.nextRandomNumber() * (max - min) + min; @@ -958,8 +958,8 @@ CesiumMath.randomBetween = function (min, max) { * Computes <code>Math.acos(value)</code>, but first clamps <code>value</code> to the range [-1.0, 1.0] * so that the function will never return NaN. * - * @param {Number} value The value for which to compute acos. - * @returns {Number} The acos of the value if the value is in the range [-1.0, 1.0], or the acos of -1.0 or 1.0, + * @param {number} value The value for which to compute acos. + * @returns {number} The acos of the value if the value is in the range [-1.0, 1.0], or the acos of -1.0 or 1.0, * whichever is closer, if the value is outside the range. */ CesiumMath.acosClamped = function (value) { @@ -975,8 +975,8 @@ CesiumMath.acosClamped = function (value) { * Computes <code>Math.asin(value)</code>, but first clamps <code>value</code> to the range [-1.0, 1.0] * so that the function will never return NaN. * - * @param {Number} value The value for which to compute asin. - * @returns {Number} The asin of the value if the value is in the range [-1.0, 1.0], or the asin of -1.0 or 1.0, + * @param {number} value The value for which to compute asin. + * @returns {number} The asin of the value if the value is in the range [-1.0, 1.0], or the asin of -1.0 or 1.0, * whichever is closer, if the value is outside the range. */ CesiumMath.asinClamped = function (value) { @@ -991,9 +991,9 @@ CesiumMath.asinClamped = function (value) { /** * Finds the chord length between two points given the circle's radius and the angle between the points. * - * @param {Number} angle The angle between the two points. - * @param {Number} radius The radius of the circle. - * @returns {Number} The chord length. + * @param {number} angle The angle between the two points. + * @param {number} radius The radius of the circle. + * @returns {number} The chord length. */ CesiumMath.chordLength = function (angle, radius) { //>>includeStart('debug', pragmas.debug); @@ -1010,9 +1010,9 @@ CesiumMath.chordLength = function (angle, radius) { /** * Finds the logarithm of a number to a base. * - * @param {Number} number The number. - * @param {Number} base The base. - * @returns {Number} The result. + * @param {number} number The number. + * @param {number} base The base. + * @returns {number} The result. */ CesiumMath.logBase = function (number, base) { //>>includeStart('debug', pragmas.debug); @@ -1031,8 +1031,8 @@ CesiumMath.logBase = function (number, base) { * Returns NaN if <code>number</code> is not provided. * * @function - * @param {Number} [number] The number. - * @returns {Number} The result. + * @param {number} [number] The number. + * @returns {number} The result. */ // eslint-disable-next-line es/no-math-cbrt CesiumMath.cbrt = defaultValue(Math.cbrt, function cbrt(number) { @@ -1044,8 +1044,8 @@ CesiumMath.cbrt = defaultValue(Math.cbrt, function cbrt(number) { * Finds the base 2 logarithm of a number. * * @function - * @param {Number} number The number. - * @returns {Number} The result. + * @param {number} number The number. + * @returns {number} The result. */ // eslint-disable-next-line es/no-math-log2 CesiumMath.log2 = defaultValue(Math.log2, function log2(number) { @@ -1068,8 +1068,8 @@ CesiumMath.fog = function (distanceToCamera, density) { * Rajan, S. Sichun Wang Inkol, R. Joyal, A., May 2006. * Adapted from ShaderFastLibs under MIT License. * - * @param {Number} x An input number in the range [-1, 1] - * @returns {Number} An approximation of atan(x) + * @param {number} x An input number in the range [-1, 1] + * @returns {number} An approximation of atan(x) */ CesiumMath.fastApproximateAtan = function (x) { //>>includeStart('debug', pragmas.debug); @@ -1084,9 +1084,9 @@ CesiumMath.fastApproximateAtan = function (x) { * * Range reduction math based on nvidia's cg reference implementation: http://developer.download.nvidia.com/cg/atan2.html * - * @param {Number} x An input number that isn't zero if y is zero. - * @param {Number} y An input number that isn't zero if x is zero. - * @returns {Number} An approximation of atan2(x, y) + * @param {number} x An input number that isn't zero if y is zero. + * @param {number} y An input number that isn't zero if x is zero. + * @returns {number} An approximation of atan2(x, y) */ CesiumMath.fastApproximateAtan2 = function (x, y) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/Matrix2.js b/packages/engine/Source/Core/Matrix2.js index 266cc4c3f29..7f0cba621c0 100644 --- a/packages/engine/Source/Core/Matrix2.js +++ b/packages/engine/Source/Core/Matrix2.js @@ -11,10 +11,10 @@ import DeveloperError from "./DeveloperError.js"; * @constructor * @implements {ArrayLike<number>} * - * @param {Number} [column0Row0=0.0] The value for column 0, row 0. - * @param {Number} [column1Row0=0.0] The value for column 1, row 0. - * @param {Number} [column0Row1=0.0] The value for column 0, row 1. - * @param {Number} [column1Row1=0.0] The value for column 1, row 1. + * @param {number} [column0Row0=0.0] The value for column 0, row 0. + * @param {number} [column1Row0=0.0] The value for column 1, row 0. + * @param {number} [column0Row1=0.0] The value for column 0, row 1. + * @param {number} [column1Row1=0.0] The value for column 1, row 1. * * @see Matrix2.fromArray * @see Matrix2.fromColumnMajorArray @@ -34,7 +34,7 @@ function Matrix2(column0Row0, column1Row0, column0Row1, column1Row1) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Matrix2.packedLength = 4; @@ -42,10 +42,10 @@ Matrix2.packedLength = 4; * Stores the provided instance into the provided array. * * @param {Matrix2} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Matrix2.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -66,8 +66,8 @@ Matrix2.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Matrix2} [result] The object into which to store the result. * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. */ @@ -94,8 +94,8 @@ Matrix2.unpack = function (array, startingIndex, result) { * are stored in column-major order. * * @param {Matrix2[]} array The array of matrices to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 4 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 4) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 4 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 4) elements. + * @returns {number[]} The packed array. */ Matrix2.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -125,7 +125,7 @@ Matrix2.packArray = function (array, result) { /** * Unpacks an array of column-major matrix components into an array of Matrix2s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Matrix2[]} [result] The array onto which to store the result. * @returns {Matrix2[]} The unpacked array. */ @@ -177,8 +177,8 @@ Matrix2.clone = function (matrix, result) { * Creates a Matrix2 from 4 consecutive elements in an array. * * @function - * @param {Number[]} array The array whose 4 consecutive elements correspond to the positions of the matrix. Assumes column-major order. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. + * @param {number[]} array The array whose 4 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. * @param {Matrix2} [result] The object onto which to store the result. * @returns {Matrix2} The modified result parameter or a new Matrix2 instance if one was not provided. * @@ -198,7 +198,7 @@ Matrix2.fromArray = Matrix2.unpack; /** * Creates a Matrix2 instance from a column-major order array. * - * @param {Number[]} values The column-major order array. + * @param {number[]} values The column-major order array. * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. */ @@ -214,7 +214,7 @@ Matrix2.fromColumnMajorArray = function (values, result) { * Creates a Matrix2 instance from a row-major order array. * The resulting matrix will be in column-major order. * - * @param {Number[]} values The row-major order array. + * @param {number[]} values The row-major order array. * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. */ @@ -265,7 +265,7 @@ Matrix2.fromScale = function (scale, result) { /** * Computes a Matrix2 instance representing a uniform scale. * - * @param {Number} scale The uniform scale factor. + * @param {number} scale The uniform scale factor. * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. * @@ -294,7 +294,7 @@ Matrix2.fromUniformScale = function (scale, result) { /** * Creates a rotation matrix. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. * @param {Matrix2} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix2} The modified result parameter, or a new Matrix2 instance if one was not provided. * @@ -327,8 +327,8 @@ Matrix2.fromRotation = function (angle, result) { * The array will be in column-major order. * * @param {Matrix2} matrix The matrix to use.. - * @param {Number[]} [result] The Array onto which to store the result. - * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + * @param {number[]} [result] The Array onto which to store the result. + * @returns {number[]} The modified Array parameter or a new Array instance if one was not provided. */ Matrix2.toArray = function (matrix, result) { //>>includeStart('debug', pragmas.debug); @@ -348,9 +348,9 @@ Matrix2.toArray = function (matrix, result) { /** * Computes the array index of the element at the provided row and column. * - * @param {Number} row The zero-based index of the row. - * @param {Number} column The zero-based index of the column. - * @returns {Number} The index of the element at the provided row and column. + * @param {number} row The zero-based index of the row. + * @param {number} column The zero-based index of the column. + * @returns {number} The index of the element at the provided row and column. * * @exception {DeveloperError} row must be 0 or 1. * @exception {DeveloperError} column must be 0 or 1. @@ -377,7 +377,7 @@ Matrix2.getElementIndex = function (column, row) { * Retrieves a copy of the matrix column at the provided index as a Cartesian2 instance. * * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to retrieve. + * @param {number} index The zero-based index of the column to retrieve. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter. * @@ -406,7 +406,7 @@ Matrix2.getColumn = function (matrix, index, result) { * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian2 instance. * * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to set. + * @param {number} index The zero-based index of the column to set. * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified column. * @param {Cartesian2} result The object onto which to store the result. * @returns {Matrix2} The modified result parameter. @@ -435,7 +435,7 @@ Matrix2.setColumn = function (matrix, index, cartesian, result) { * Retrieves a copy of the matrix row at the provided index as a Cartesian2 instance. * * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to retrieve. + * @param {number} index The zero-based index of the row to retrieve. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter. * @@ -463,7 +463,7 @@ Matrix2.getRow = function (matrix, index, result) { * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian2 instance. * * @param {Matrix2} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to set. + * @param {number} index The zero-based index of the row to set. * @param {Cartesian2} cartesian The Cartesian whose values will be assigned to the specified row. * @param {Matrix2} result The object onto which to store the result. * @returns {Matrix2} The modified result parameter. @@ -531,7 +531,7 @@ const scaleScratch2 = new Cartesian2(); * This assumes the matrix is an affine transformation. * * @param {Matrix2} matrix The matrix to use. - * @param {Number} scale The uniform scale that replaces the scale of the provided matrix. + * @param {number} scale The uniform scale that replaces the scale of the provided matrix. * @param {Matrix2} result The object onto which to store the result. * @returns {Matrix2} The modified result parameter. * @@ -599,7 +599,7 @@ const scaleScratch3 = new Cartesian2(); * The maximum scale is the maximum length of the column vectors. * * @param {Matrix2} matrix The matrix. - * @returns {Number} The maximum scale. + * @returns {number} The maximum scale. */ Matrix2.getMaximumScale = function (matrix) { Matrix2.getScale(matrix, scaleScratch3); @@ -761,7 +761,7 @@ Matrix2.multiplyByVector = function (matrix, cartesian, result) { * Computes the product of a matrix and a scalar. * * @param {Matrix2} matrix The matrix. - * @param {Number} scalar The number to multiply by. + * @param {number} scalar The number to multiply by. * @param {Matrix2} result The object onto which to store the result. * @returns {Matrix2} The modified result parameter. */ @@ -818,7 +818,7 @@ Matrix2.multiplyByScale = function (matrix, scale, result) { * Computes the product of a matrix times a uniform scale, as if the scale were a scale matrix. * * @param {Matrix2} matrix The matrix on the left-hand side. - * @param {Number} scale The uniform scale on the right-hand side. + * @param {number} scale The uniform scale on the right-hand side. * @param {Matrix2} result The object onto which to store the result. * @returns {Matrix2} The modified result parameter. * @@ -920,7 +920,7 @@ Matrix2.abs = function (matrix, result) { * * @param {Matrix2} [left] The first matrix. * @param {Matrix2} [right] The second matrix. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Matrix2.equals = function (left, right) { return ( @@ -953,8 +953,8 @@ Matrix2.equalsArray = function (matrix, array, offset) { * * @param {Matrix2} [left] The first matrix. * @param {Matrix2} [right] The second matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Matrix2.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0); @@ -988,7 +988,7 @@ Matrix2.ZERO = Object.freeze(new Matrix2(0.0, 0.0, 0.0, 0.0)); /** * The index into Matrix2 for column 0, row 0. * - * @type {Number} + * @type {number} * @constant * * @example @@ -1000,7 +1000,7 @@ Matrix2.COLUMN0ROW0 = 0; /** * The index into Matrix2 for column 0, row 1. * - * @type {Number} + * @type {number} * @constant * * @example @@ -1012,7 +1012,7 @@ Matrix2.COLUMN0ROW1 = 1; /** * The index into Matrix2 for column 1, row 0. * - * @type {Number} + * @type {number} * @constant * * @example @@ -1024,7 +1024,7 @@ Matrix2.COLUMN1ROW0 = 2; /** * The index into Matrix2 for column 1, row 1. * - * @type {Number} + * @type {number} * @constant * * @example @@ -1038,7 +1038,7 @@ Object.defineProperties(Matrix2.prototype, { * Gets the number of items in the collection. * @memberof Matrix2.prototype * - * @type {Number} + * @type {number} */ length: { get: function () { @@ -1062,7 +1062,7 @@ Matrix2.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Matrix2} [right] The right hand side matrix. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Matrix2.prototype.equals = function (right) { return Matrix2.equals(this, right); @@ -1074,8 +1074,8 @@ Matrix2.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Matrix2} [right] The right hand side matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Matrix2.prototype.equalsEpsilon = function (right, epsilon) { return Matrix2.equalsEpsilon(this, right, epsilon); @@ -1085,7 +1085,7 @@ Matrix2.prototype.equalsEpsilon = function (right, epsilon) { * Creates a string representing this Matrix with each row being * on a separate line and in the format '(column0, column1)'. * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1)'. + * @returns {string} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1)'. */ Matrix2.prototype.toString = function () { return `(${this[0]}, ${this[2]})\n` + `(${this[1]}, ${this[3]})`; diff --git a/packages/engine/Source/Core/Matrix3.js b/packages/engine/Source/Core/Matrix3.js index 04b1cbeb232..80b4a5185c2 100644 --- a/packages/engine/Source/Core/Matrix3.js +++ b/packages/engine/Source/Core/Matrix3.js @@ -12,15 +12,15 @@ import CesiumMath from "./Math.js"; * @constructor * @implements {ArrayLike<number>} * - * @param {Number} [column0Row0=0.0] The value for column 0, row 0. - * @param {Number} [column1Row0=0.0] The value for column 1, row 0. - * @param {Number} [column2Row0=0.0] The value for column 2, row 0. - * @param {Number} [column0Row1=0.0] The value for column 0, row 1. - * @param {Number} [column1Row1=0.0] The value for column 1, row 1. - * @param {Number} [column2Row1=0.0] The value for column 2, row 1. - * @param {Number} [column0Row2=0.0] The value for column 0, row 2. - * @param {Number} [column1Row2=0.0] The value for column 1, row 2. - * @param {Number} [column2Row2=0.0] The value for column 2, row 2. + * @param {number} [column0Row0=0.0] The value for column 0, row 0. + * @param {number} [column1Row0=0.0] The value for column 1, row 0. + * @param {number} [column2Row0=0.0] The value for column 2, row 0. + * @param {number} [column0Row1=0.0] The value for column 0, row 1. + * @param {number} [column1Row1=0.0] The value for column 1, row 1. + * @param {number} [column2Row1=0.0] The value for column 2, row 1. + * @param {number} [column0Row2=0.0] The value for column 0, row 2. + * @param {number} [column1Row2=0.0] The value for column 1, row 2. + * @param {number} [column2Row2=0.0] The value for column 2, row 2. * * @see Matrix3.fromArray * @see Matrix3.fromColumnMajorArray @@ -60,7 +60,7 @@ function Matrix3( /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Matrix3.packedLength = 9; @@ -68,10 +68,10 @@ Matrix3.packedLength = 9; * Stores the provided instance into the provided array. * * @param {Matrix3} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Matrix3.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -97,8 +97,8 @@ Matrix3.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Matrix3} [result] The object into which to store the result. * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. */ @@ -130,8 +130,8 @@ Matrix3.unpack = function (array, startingIndex, result) { * are stored in column-major order. * * @param {Matrix3[]} array The array of matrices to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 9 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 9) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 9 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 9) elements. + * @returns {number[]} The packed array. */ Matrix3.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -161,7 +161,7 @@ Matrix3.packArray = function (array, result) { /** * Unpacks an array of column-major matrix components into an array of Matrix3s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Matrix3[]} [result] The array onto which to store the result. * @returns {Matrix3[]} The unpacked array. */ @@ -228,8 +228,8 @@ Matrix3.clone = function (matrix, result) { * Creates a Matrix3 from 9 consecutive elements in an array. * * @function - * @param {Number[]} array The array whose 9 consecutive elements correspond to the positions of the matrix. Assumes column-major order. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. + * @param {number[]} array The array whose 9 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. * @param {Matrix3} [result] The object onto which to store the result. * @returns {Matrix3} The modified result parameter or a new Matrix3 instance if one was not provided. * @@ -251,7 +251,7 @@ Matrix3.fromArray = Matrix3.unpack; /** * Creates a Matrix3 instance from a column-major order array. * - * @param {Number[]} values The column-major order array. + * @param {number[]} values The column-major order array. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. */ @@ -267,7 +267,7 @@ Matrix3.fromColumnMajorArray = function (values, result) { * Creates a Matrix3 instance from a row-major order array. * The resulting matrix will be in column-major order. * - * @param {Number[]} values The row-major order array. + * @param {number[]} values The row-major order array. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. */ @@ -435,7 +435,7 @@ Matrix3.fromScale = function (scale, result) { /** * Computes a Matrix3 instance representing a uniform scale. * - * @param {Number} scale The uniform scale factor. + * @param {number} scale The uniform scale factor. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * @@ -515,7 +515,7 @@ Matrix3.fromCrossProduct = function (vector, result) { /** * Creates a rotation matrix around the x-axis. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * @@ -563,7 +563,7 @@ Matrix3.fromRotationX = function (angle, result) { /** * Creates a rotation matrix around the y-axis. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * @@ -611,7 +611,7 @@ Matrix3.fromRotationY = function (angle, result) { /** * Creates a rotation matrix around the z-axis. * - * @param {Number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. + * @param {number} angle The angle, in radians, of the rotation. Positive angles are counterclockwise. * @param {Matrix3} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix3} The modified result parameter, or a new Matrix3 instance if one was not provided. * @@ -661,8 +661,8 @@ Matrix3.fromRotationZ = function (angle, result) { * The array will be in column-major order. * * @param {Matrix3} matrix The matrix to use.. - * @param {Number[]} [result] The Array onto which to store the result. - * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + * @param {number[]} [result] The Array onto which to store the result. + * @returns {number[]} The modified Array parameter or a new Array instance if one was not provided. */ Matrix3.toArray = function (matrix, result) { //>>includeStart('debug', pragmas.debug); @@ -697,9 +697,9 @@ Matrix3.toArray = function (matrix, result) { /** * Computes the array index of the element at the provided row and column. * - * @param {Number} column The zero-based index of the column. - * @param {Number} row The zero-based index of the row. - * @returns {Number} The index of the element at the provided row and column. + * @param {number} column The zero-based index of the column. + * @param {number} row The zero-based index of the row. + * @returns {number} The index of the element at the provided row and column. * * @exception {DeveloperError} row must be 0, 1, or 2. * @exception {DeveloperError} column must be 0, 1, or 2. @@ -725,7 +725,7 @@ Matrix3.getElementIndex = function (column, row) { * Retrieves a copy of the matrix column at the provided index as a Cartesian3 instance. * * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to retrieve. + * @param {number} index The zero-based index of the column to retrieve. * @param {Cartesian3} result The object onto which to store the result. * @returns {Cartesian3} The modified result parameter. * @@ -754,7 +754,7 @@ Matrix3.getColumn = function (matrix, index, result) { * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian3 instance. * * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to set. + * @param {number} index The zero-based index of the column to set. * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified column. * @param {Matrix3} result The object onto which to store the result. * @returns {Matrix3} The modified result parameter. @@ -782,7 +782,7 @@ Matrix3.setColumn = function (matrix, index, cartesian, result) { * Retrieves a copy of the matrix row at the provided index as a Cartesian3 instance. * * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to retrieve. + * @param {number} index The zero-based index of the row to retrieve. * @param {Cartesian3} result The object onto which to store the result. * @returns {Cartesian3} The modified result parameter. * @@ -810,7 +810,7 @@ Matrix3.getRow = function (matrix, index, result) { * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian3 instance. * * @param {Matrix3} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to set. + * @param {number} index The zero-based index of the row to set. * @param {Cartesian3} cartesian The Cartesian whose values will be assigned to the specified row. * @param {Matrix3} result The object onto which to store the result. * @returns {Matrix3} The modified result parameter. @@ -883,7 +883,7 @@ const scaleScratch2 = new Cartesian3(); * This assumes the matrix is an affine transformation. * * @param {Matrix3} matrix The matrix to use. - * @param {Number} scale The uniform scale that replaces the scale of the provided matrix. + * @param {number} scale The uniform scale that replaces the scale of the provided matrix. * @param {Matrix3} result The object onto which to store the result. * @returns {Matrix3} The modified result parameter. * @@ -960,7 +960,7 @@ const scaleScratch3 = new Cartesian3(); * The maximum scale is the maximum length of the column vectors. * * @param {Matrix3} matrix The matrix. - * @returns {Number} The maximum scale. + * @returns {number} The maximum scale. */ Matrix3.getMaximumScale = function (matrix) { Matrix3.getScale(matrix, scaleScratch3); @@ -1167,7 +1167,7 @@ Matrix3.multiplyByVector = function (matrix, cartesian, result) { * Computes the product of a matrix and a scalar. * * @param {Matrix3} matrix The matrix. - * @param {Number} scalar The number to multiply by. + * @param {number} scalar The number to multiply by. * @param {Matrix3} result The object onto which to store the result. * @returns {Matrix3} The modified result parameter. */ @@ -1234,7 +1234,7 @@ Matrix3.multiplyByScale = function (matrix, scale, result) { * Computes the product of a matrix times a uniform scale, as if the scale were a scale matrix. * * @param {Matrix3} matrix The matrix on the left-hand side. - * @param {Number} scale The uniform scale on the right-hand side. + * @param {number} scale The uniform scale on the right-hand side. * @param {Matrix3} result The object onto which to store the result. * @returns {Matrix3} The modified result parameter. * @@ -1429,8 +1429,8 @@ const jMatrixTranspose = new Matrix3(); * </p> * * @param {Matrix3} matrix The matrix to decompose into diagonal and unitary matrix. Expected to be symmetric. - * @param {Object} [result] An object with unitary and diagonal properties which are matrices onto which to store the result. - * @returns {Object} An object with unitary and diagonal properties which are the unitary and diagonal matrices, respectively. + * @param {object} [result] An object with unitary and diagonal properties which are matrices onto which to store the result. + * @returns {object} An object with unitary and diagonal properties which are the unitary and diagonal matrices, respectively. * * @example * const a = //... symetric matrix @@ -1520,7 +1520,7 @@ Matrix3.abs = function (matrix, result) { * Computes the determinant of the provided matrix. * * @param {Matrix3} matrix The matrix to use. - * @returns {Number} The value of the determinant of the matrix. + * @returns {number} The value of the determinant of the matrix. */ Matrix3.determinant = function (matrix) { //>>includeStart('debug', pragmas.debug); @@ -1618,7 +1618,7 @@ Matrix3.inverseTranspose = function (matrix, result) { * * @param {Matrix3} [left] The first matrix. * @param {Matrix3} [right] The second matrix. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Matrix3.equals = function (left, right) { return ( @@ -1644,8 +1644,8 @@ Matrix3.equals = function (left, right) { * * @param {Matrix3} [left] The first matrix. * @param {Matrix3} [right] The second matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Matrix3.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0); @@ -1689,7 +1689,7 @@ Matrix3.ZERO = Object.freeze( /** * The index into Matrix3 for column 0, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN0ROW0 = 0; @@ -1697,7 +1697,7 @@ Matrix3.COLUMN0ROW0 = 0; /** * The index into Matrix3 for column 0, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN0ROW1 = 1; @@ -1705,7 +1705,7 @@ Matrix3.COLUMN0ROW1 = 1; /** * The index into Matrix3 for column 0, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN0ROW2 = 2; @@ -1713,7 +1713,7 @@ Matrix3.COLUMN0ROW2 = 2; /** * The index into Matrix3 for column 1, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN1ROW0 = 3; @@ -1721,7 +1721,7 @@ Matrix3.COLUMN1ROW0 = 3; /** * The index into Matrix3 for column 1, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN1ROW1 = 4; @@ -1729,7 +1729,7 @@ Matrix3.COLUMN1ROW1 = 4; /** * The index into Matrix3 for column 1, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN1ROW2 = 5; @@ -1737,7 +1737,7 @@ Matrix3.COLUMN1ROW2 = 5; /** * The index into Matrix3 for column 2, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN2ROW0 = 6; @@ -1745,7 +1745,7 @@ Matrix3.COLUMN2ROW0 = 6; /** * The index into Matrix3 for column 2, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN2ROW1 = 7; @@ -1753,7 +1753,7 @@ Matrix3.COLUMN2ROW1 = 7; /** * The index into Matrix3 for column 2, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix3.COLUMN2ROW2 = 8; @@ -1763,7 +1763,7 @@ Object.defineProperties(Matrix3.prototype, { * Gets the number of items in the collection. * @memberof Matrix3.prototype * - * @type {Number} + * @type {number} */ length: { get: function () { @@ -1787,7 +1787,7 @@ Matrix3.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Matrix3} [right] The right hand side matrix. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Matrix3.prototype.equals = function (right) { return Matrix3.equals(this, right); @@ -1816,8 +1816,8 @@ Matrix3.equalsArray = function (matrix, array, offset) { * <code>false</code> otherwise. * * @param {Matrix3} [right] The right hand side matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Matrix3.prototype.equalsEpsilon = function (right, epsilon) { return Matrix3.equalsEpsilon(this, right, epsilon); @@ -1827,7 +1827,7 @@ Matrix3.prototype.equalsEpsilon = function (right, epsilon) { * Creates a string representing this Matrix with each row being * on a separate line and in the format '(column0, column1, column2)'. * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2)'. + * @returns {string} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2)'. */ Matrix3.prototype.toString = function () { return ( diff --git a/packages/engine/Source/Core/Matrix4.js b/packages/engine/Source/Core/Matrix4.js index 6b6aa3047cb..ecdaa3c0d00 100644 --- a/packages/engine/Source/Core/Matrix4.js +++ b/packages/engine/Source/Core/Matrix4.js @@ -15,22 +15,22 @@ import RuntimeError from "./RuntimeError.js"; * @constructor * @implements {ArrayLike<number>} * - * @param {Number} [column0Row0=0.0] The value for column 0, row 0. - * @param {Number} [column1Row0=0.0] The value for column 1, row 0. - * @param {Number} [column2Row0=0.0] The value for column 2, row 0. - * @param {Number} [column3Row0=0.0] The value for column 3, row 0. - * @param {Number} [column0Row1=0.0] The value for column 0, row 1. - * @param {Number} [column1Row1=0.0] The value for column 1, row 1. - * @param {Number} [column2Row1=0.0] The value for column 2, row 1. - * @param {Number} [column3Row1=0.0] The value for column 3, row 1. - * @param {Number} [column0Row2=0.0] The value for column 0, row 2. - * @param {Number} [column1Row2=0.0] The value for column 1, row 2. - * @param {Number} [column2Row2=0.0] The value for column 2, row 2. - * @param {Number} [column3Row2=0.0] The value for column 3, row 2. - * @param {Number} [column0Row3=0.0] The value for column 0, row 3. - * @param {Number} [column1Row3=0.0] The value for column 1, row 3. - * @param {Number} [column2Row3=0.0] The value for column 2, row 3. - * @param {Number} [column3Row3=0.0] The value for column 3, row 3. + * @param {number} [column0Row0=0.0] The value for column 0, row 0. + * @param {number} [column1Row0=0.0] The value for column 1, row 0. + * @param {number} [column2Row0=0.0] The value for column 2, row 0. + * @param {number} [column3Row0=0.0] The value for column 3, row 0. + * @param {number} [column0Row1=0.0] The value for column 0, row 1. + * @param {number} [column1Row1=0.0] The value for column 1, row 1. + * @param {number} [column2Row1=0.0] The value for column 2, row 1. + * @param {number} [column3Row1=0.0] The value for column 3, row 1. + * @param {number} [column0Row2=0.0] The value for column 0, row 2. + * @param {number} [column1Row2=0.0] The value for column 1, row 2. + * @param {number} [column2Row2=0.0] The value for column 2, row 2. + * @param {number} [column3Row2=0.0] The value for column 3, row 2. + * @param {number} [column0Row3=0.0] The value for column 0, row 3. + * @param {number} [column1Row3=0.0] The value for column 1, row 3. + * @param {number} [column2Row3=0.0] The value for column 2, row 3. + * @param {number} [column3Row3=0.0] The value for column 3, row 3. * * @see Matrix4.fromArray * @see Matrix4.fromColumnMajorArray @@ -91,7 +91,7 @@ function Matrix4( /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Matrix4.packedLength = 16; @@ -99,10 +99,10 @@ Matrix4.packedLength = 16; * Stores the provided instance into the provided array. * * @param {Matrix4} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Matrix4.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -135,8 +135,8 @@ Matrix4.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Matrix4} [result] The object into which to store the result. * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. */ @@ -175,8 +175,8 @@ Matrix4.unpack = function (array, startingIndex, result) { * are stored in column-major order. * * @param {Matrix4[]} array The array of matrices to pack. - * @param {Number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 16 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 16) elements. - * @returns {Number[]} The packed array. + * @param {number[]} [result] The array onto which to store the result. If this is a typed array, it must have array.length * 16 components, else a {@link DeveloperError} will be thrown. If it is a regular array, it will be resized to have (array.length * 16) elements. + * @returns {number[]} The packed array. */ Matrix4.packArray = function (array, result) { //>>includeStart('debug', pragmas.debug); @@ -206,7 +206,7 @@ Matrix4.packArray = function (array, result) { /** * Unpacks an array of column-major matrix components into an array of Matrix4s. * - * @param {Number[]} array The array of components to unpack. + * @param {number[]} array The array of components to unpack. * @param {Matrix4[]} [result] The array onto which to store the result. * @returns {Matrix4[]} The unpacked array. */ @@ -287,8 +287,8 @@ Matrix4.clone = function (matrix, result) { * Creates a Matrix4 from 16 consecutive elements in an array. * @function * - * @param {Number[]} array The array whose 16 consecutive elements correspond to the positions of the matrix. Assumes column-major order. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. + * @param {number[]} array The array whose 16 consecutive elements correspond to the positions of the matrix. Assumes column-major order. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to first column first row position in the matrix. * @param {Matrix4} [result] The object onto which to store the result. * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. * @@ -311,7 +311,7 @@ Matrix4.fromArray = Matrix4.unpack; /** * Computes a Matrix4 instance from a column-major order array. * - * @param {Number[]} values The column-major order array. + * @param {number[]} values The column-major order array. * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. */ @@ -327,7 +327,7 @@ Matrix4.fromColumnMajorArray = function (values, result) { * Computes a Matrix4 instance from a row-major order array. * The resulting matrix will be in column-major order. * - * @param {Number[]} values The row-major order array. + * @param {number[]} values The row-major order array. * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. */ @@ -614,7 +614,7 @@ Matrix4.fromScale = function (scale, result) { /** * Computes a Matrix4 instance representing a uniform scale. * - * @param {Number} scale The uniform scale factor. + * @param {number} scale The uniform scale factor. * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created. * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. * @@ -818,10 +818,10 @@ Matrix4.fromCamera = function (camera, result) { /** * Computes a Matrix4 instance representing a perspective transformation matrix. * - * @param {Number} fovY The field of view along the Y axis in radians. - * @param {Number} aspectRatio The aspect ratio. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. + * @param {number} fovY The field of view along the Y axis in radians. + * @param {number} aspectRatio The aspect ratio. + * @param {number} near The distance to the near plane in meters. + * @param {number} far The distance to the far plane in meters. * @param {Matrix4} result The object in which the result will be stored. * @returns {Matrix4} The modified result parameter. * @@ -874,12 +874,12 @@ Matrix4.computePerspectiveFieldOfView = function ( /** * Computes a Matrix4 instance representing an orthographic transformation matrix. * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. + * @param {number} left The number of meters to the left of the camera that will be in view. + * @param {number} right The number of meters to the right of the camera that will be in view. + * @param {number} bottom The number of meters below of the camera that will be in view. + * @param {number} top The number of meters above of the camera that will be in view. + * @param {number} near The distance to the near plane in meters. + * @param {number} far The distance to the far plane in meters. * @param {Matrix4} result The object in which the result will be stored. * @returns {Matrix4} The modified result parameter. */ @@ -935,12 +935,12 @@ Matrix4.computeOrthographicOffCenter = function ( /** * Computes a Matrix4 instance representing an off center perspective transformation. * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. - * @param {Number} far The distance to the far plane in meters. + * @param {number} left The number of meters to the left of the camera that will be in view. + * @param {number} right The number of meters to the right of the camera that will be in view. + * @param {number} bottom The number of meters below of the camera that will be in view. + * @param {number} top The number of meters above of the camera that will be in view. + * @param {number} near The distance to the near plane in meters. + * @param {number} far The distance to the far plane in meters. * @param {Matrix4} result The object in which the result will be stored. * @returns {Matrix4} The modified result parameter. */ @@ -993,11 +993,11 @@ Matrix4.computePerspectiveOffCenter = function ( /** * Computes a Matrix4 instance representing an infinite off center perspective transformation. * - * @param {Number} left The number of meters to the left of the camera that will be in view. - * @param {Number} right The number of meters to the right of the camera that will be in view. - * @param {Number} bottom The number of meters below of the camera that will be in view. - * @param {Number} top The number of meters above of the camera that will be in view. - * @param {Number} near The distance to the near plane in meters. + * @param {number} left The number of meters to the left of the camera that will be in view. + * @param {number} right The number of meters to the right of the camera that will be in view. + * @param {number} bottom The number of meters below of the camera that will be in view. + * @param {number} top The number of meters above of the camera that will be in view. + * @param {number} near The distance to the near plane in meters. * @param {Matrix4} result The object in which the result will be stored. * @returns {Matrix4} The modified result parameter. */ @@ -1048,9 +1048,9 @@ Matrix4.computeInfinitePerspectiveOffCenter = function ( /** * Computes a Matrix4 instance that transforms from normalized device coordinates to window coordinates. * - * @param {Object} [viewport = { x : 0.0, y : 0.0, width : 0.0, height : 0.0 }] The viewport's corners as shown in Example 1. - * @param {Number} [nearDepthRange=0.0] The near plane distance in window coordinates. - * @param {Number} [farDepthRange=1.0] The far plane distance in window coordinates. + * @param {object} [viewport = { x : 0.0, y : 0.0, width : 0.0, height : 0.0 }] The viewport's corners as shown in Example 1. + * @param {number} [nearDepthRange=0.0] The near plane distance in window coordinates. + * @param {number} [farDepthRange=1.0] The far plane distance in window coordinates. * @param {Matrix4} [result] The object in which the result will be stored. * @returns {Matrix4} The modified result parameter. * @@ -1156,8 +1156,8 @@ Matrix4.computeView = function (position, direction, up, right, result) { * The array will be in column-major order. * * @param {Matrix4} matrix The matrix to use.. - * @param {Number[]} [result] The Array onto which to store the result. - * @returns {Number[]} The modified Array parameter or a new Array instance if one was not provided. + * @param {number[]} [result] The Array onto which to store the result. + * @returns {number[]} The modified Array parameter or a new Array instance if one was not provided. * * @example * //create an array from an instance of Matrix4 @@ -1217,9 +1217,9 @@ Matrix4.toArray = function (matrix, result) { /** * Computes the array index of the element at the provided row and column. * - * @param {Number} row The zero-based index of the row. - * @param {Number} column The zero-based index of the column. - * @returns {Number} The index of the element at the provided row and column. + * @param {number} row The zero-based index of the row. + * @param {number} column The zero-based index of the column. + * @returns {number} The index of the element at the provided row and column. * * @exception {DeveloperError} row must be 0, 1, 2, or 3. * @exception {DeveloperError} column must be 0, 1, 2, or 3. @@ -1246,7 +1246,7 @@ Matrix4.getElementIndex = function (column, row) { * Retrieves a copy of the matrix column at the provided index as a Cartesian4 instance. * * @param {Matrix4} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to retrieve. + * @param {number} index The zero-based index of the column to retrieve. * @param {Cartesian4} result The object onto which to store the result. * @returns {Cartesian4} The modified result parameter. * @@ -1296,7 +1296,7 @@ Matrix4.getColumn = function (matrix, index, result) { * Computes a new matrix that replaces the specified column in the provided matrix with the provided Cartesian4 instance. * * @param {Matrix4} matrix The matrix to use. - * @param {Number} index The zero-based index of the column to set. + * @param {number} index The zero-based index of the column to set. * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified column. * @param {Matrix4} result The object onto which to store the result. * @returns {Matrix4} The modified result parameter. @@ -1342,7 +1342,7 @@ Matrix4.setColumn = function (matrix, index, cartesian, result) { * Retrieves a copy of the matrix row at the provided index as a Cartesian4 instance. * * @param {Matrix4} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to retrieve. + * @param {number} index The zero-based index of the row to retrieve. * @param {Cartesian4} result The object onto which to store the result. * @returns {Cartesian4} The modified result parameter. * @@ -1391,7 +1391,7 @@ Matrix4.getRow = function (matrix, index, result) { * Computes a new matrix that replaces the specified row in the provided matrix with the provided Cartesian4 instance. * * @param {Matrix4} matrix The matrix to use. - * @param {Number} index The zero-based index of the row to set. + * @param {number} index The zero-based index of the row to set. * @param {Cartesian4} cartesian The Cartesian whose values will be assigned to the specified row. * @param {Matrix4} result The object onto which to store the result. * @returns {Matrix4} The modified result parameter. @@ -1531,7 +1531,7 @@ const scaleScratch2 = new Cartesian3(); * This assumes the matrix is an affine transformation. * * @param {Matrix4} matrix The matrix to use. - * @param {Number} scale The uniform scale that replaces the scale of the provided matrix. + * @param {number} scale The uniform scale that replaces the scale of the provided matrix. * @param {Matrix4} result The object onto which to store the result. * @returns {Matrix4} The modified result parameter. * @@ -1619,7 +1619,7 @@ const scaleScratch3 = new Cartesian3(); * 3x3 matrix. * * @param {Matrix4} matrix The matrix. - * @returns {Number} The maximum scale. + * @returns {number} The maximum scale. */ Matrix4.getMaximumScale = function (matrix) { Matrix4.getScale(matrix, scaleScratch3); @@ -2154,7 +2154,7 @@ Matrix4.multiplyByScale = function (matrix, scale, result) { * Computes the product of a matrix times a uniform scale, as if the scale were a scale matrix. * * @param {Matrix4} matrix The matrix on the left-hand side. - * @param {Number} scale The uniform scale on the right-hand side. + * @param {number} scale The uniform scale on the right-hand side. * @param {Matrix4} result The object onto which to store the result. * @returns {Matrix4} The modified result parameter. * @@ -2306,7 +2306,7 @@ Matrix4.multiplyByPoint = function (matrix, cartesian, result) { * Computes the product of a matrix and a scalar. * * @param {Matrix4} matrix The matrix. - * @param {Number} scalar The number to multiply by. + * @param {number} scalar The number to multiply by. * @param {Matrix4} result The object onto which to store the result. * @returns {Matrix4} The modified result parameter. * @@ -2491,7 +2491,7 @@ Matrix4.abs = function (matrix, result) { * * @param {Matrix4} [left] The first matrix. * @param {Matrix4} [right] The second matrix. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. * * @example * //compares two Matrix4 instances @@ -2552,8 +2552,8 @@ Matrix4.equals = function (left, right) { * * @param {Matrix4} [left] The first matrix. * @param {Matrix4} [right] The second matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. * * @example * //compares two Matrix4 instances @@ -3019,7 +3019,7 @@ Matrix4.ZERO = Object.freeze( /** * The index into Matrix4 for column 0, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN0ROW0 = 0; @@ -3027,7 +3027,7 @@ Matrix4.COLUMN0ROW0 = 0; /** * The index into Matrix4 for column 0, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN0ROW1 = 1; @@ -3035,7 +3035,7 @@ Matrix4.COLUMN0ROW1 = 1; /** * The index into Matrix4 for column 0, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN0ROW2 = 2; @@ -3043,7 +3043,7 @@ Matrix4.COLUMN0ROW2 = 2; /** * The index into Matrix4 for column 0, row 3. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN0ROW3 = 3; @@ -3051,7 +3051,7 @@ Matrix4.COLUMN0ROW3 = 3; /** * The index into Matrix4 for column 1, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN1ROW0 = 4; @@ -3059,7 +3059,7 @@ Matrix4.COLUMN1ROW0 = 4; /** * The index into Matrix4 for column 1, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN1ROW1 = 5; @@ -3067,7 +3067,7 @@ Matrix4.COLUMN1ROW1 = 5; /** * The index into Matrix4 for column 1, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN1ROW2 = 6; @@ -3075,7 +3075,7 @@ Matrix4.COLUMN1ROW2 = 6; /** * The index into Matrix4 for column 1, row 3. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN1ROW3 = 7; @@ -3083,7 +3083,7 @@ Matrix4.COLUMN1ROW3 = 7; /** * The index into Matrix4 for column 2, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN2ROW0 = 8; @@ -3091,7 +3091,7 @@ Matrix4.COLUMN2ROW0 = 8; /** * The index into Matrix4 for column 2, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN2ROW1 = 9; @@ -3099,7 +3099,7 @@ Matrix4.COLUMN2ROW1 = 9; /** * The index into Matrix4 for column 2, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN2ROW2 = 10; @@ -3107,7 +3107,7 @@ Matrix4.COLUMN2ROW2 = 10; /** * The index into Matrix4 for column 2, row 3. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN2ROW3 = 11; @@ -3115,7 +3115,7 @@ Matrix4.COLUMN2ROW3 = 11; /** * The index into Matrix4 for column 3, row 0. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN3ROW0 = 12; @@ -3123,7 +3123,7 @@ Matrix4.COLUMN3ROW0 = 12; /** * The index into Matrix4 for column 3, row 1. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN3ROW1 = 13; @@ -3131,7 +3131,7 @@ Matrix4.COLUMN3ROW1 = 13; /** * The index into Matrix4 for column 3, row 2. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN3ROW2 = 14; @@ -3139,7 +3139,7 @@ Matrix4.COLUMN3ROW2 = 14; /** * The index into Matrix4 for column 3, row 3. * - * @type {Number} + * @type {number} * @constant */ Matrix4.COLUMN3ROW3 = 15; @@ -3149,7 +3149,7 @@ Object.defineProperties(Matrix4.prototype, { * Gets the number of items in the collection. * @memberof Matrix4.prototype * - * @type {Number} + * @type {number} */ length: { get: function () { @@ -3173,7 +3173,7 @@ Matrix4.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Matrix4} [right] The right hand side matrix. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ Matrix4.prototype.equals = function (right) { return Matrix4.equals(this, right); @@ -3209,8 +3209,8 @@ Matrix4.equalsArray = function (matrix, array, offset) { * <code>false</code> otherwise. * * @param {Matrix4} [right] The right hand side matrix. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ Matrix4.prototype.equalsEpsilon = function (right, epsilon) { return Matrix4.equalsEpsilon(this, right, epsilon); @@ -3220,7 +3220,7 @@ Matrix4.prototype.equalsEpsilon = function (right, epsilon) { * Computes a string representing this Matrix with each row being * on a separate line and in the format '(column0, column1, column2, column3)'. * - * @returns {String} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2, column3)'. + * @returns {string} A string representing the provided Matrix with each row being on a separate line and in the format '(column0, column1, column2, column3)'. */ Matrix4.prototype.toString = function () { return ( diff --git a/packages/engine/Source/Core/MorphWeightSpline.js b/packages/engine/Source/Core/MorphWeightSpline.js index 76e2d211b38..d566c1e604f 100644 --- a/packages/engine/Source/Core/MorphWeightSpline.js +++ b/packages/engine/Source/Core/MorphWeightSpline.js @@ -10,10 +10,10 @@ import Spline from "./Spline.js"; * @alias MorphWeightSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. * The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Number[]} options.weights The array of floating-point control weights given. The weights are ordered such + * @param {number[]} options.weights The array of floating-point control weights given. The weights are ordered such * that all weights for the targets are given in chronological order and order in which they appear in * the glTF from which the morph targets come. This means for 2 targets, weights = [w(0,0), w(0,1), w(1,0), w(1,1) ...] * where i and j in w(i,j) are the time indices and target indices, respectively. @@ -69,7 +69,7 @@ Object.defineProperties(MorphWeightSpline.prototype, { * * @memberof WeightSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -83,7 +83,7 @@ Object.defineProperties(MorphWeightSpline.prototype, { * * @memberof WeightSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ weights: { @@ -98,8 +98,8 @@ Object.defineProperties(MorphWeightSpline.prototype, { * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -112,8 +112,8 @@ MorphWeightSpline.prototype.findTimeInterval = * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ MorphWeightSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -121,17 +121,17 @@ MorphWeightSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ MorphWeightSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. - * @param {Number[]} [result] The object onto which to store the result. - * @returns {Number[]} The modified result parameter or a new instance of the point on the curve at the given time. + * @param {number} time The time at which to evaluate the curve. + * @param {number[]} [result] The object onto which to store the result. + * @returns {number[]} The modified result parameter or a new instance of the point on the curve at the given time. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element diff --git a/packages/engine/Source/Core/MortonOrder.js b/packages/engine/Source/Core/MortonOrder.js index 9f3cb94ef3c..390abf91395 100644 --- a/packages/engine/Source/Core/MortonOrder.js +++ b/packages/engine/Source/Core/MortonOrder.js @@ -22,8 +22,8 @@ const MortonOrder = {}; * output: 20 * * @private - * @param {Number} v A 16-bit unsigned integer. - * @returns {Number} A 32-bit unsigned integer. + * @param {number} v A 16-bit unsigned integer. + * @returns {number} A 32-bit unsigned integer. * @see {@link https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/} * @private */ @@ -46,8 +46,8 @@ function insertOneSpacing(v) { * output: 72 * * @private - * @param {Number} v A 10-bit unsigned integer. - * @returns {Number} A 30-bit unsigned integer. + * @param {number} v A 10-bit unsigned integer. + * @returns {number} A 30-bit unsigned integer. * @see {@link https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/} */ function insertTwoSpacing(v) { @@ -69,8 +69,8 @@ function insertTwoSpacing(v) { * output: 6 * * @private - * @param {Number} v A 32-bit unsigned integer. - * @returns {Number} A 16-bit unsigned integer. + * @param {number} v A 32-bit unsigned integer. + * @returns {number} A 16-bit unsigned integer. * @see {@link https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/} */ function removeOneSpacing(v) { @@ -93,8 +93,8 @@ function removeOneSpacing(v) { * output: 6 * * @private - * @param {Number} v A 30-bit unsigned integer. - * @returns {Number} A 10-bit unsigned integer. + * @param {number} v A 30-bit unsigned integer. + * @returns {number} A 10-bit unsigned integer. * @see {@link https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/} */ function removeTwoSpacing(v) { @@ -110,9 +110,9 @@ function removeTwoSpacing(v) { * Computes the Morton index from 2D coordinates. This is equivalent to interleaving their bits. * The inputs must be 16-bit unsigned integers (resulting in 32-bit Morton index) due to 32-bit bitwise operator limitation in JavaScript. * - * @param {Number} x The X coordinate in the range [0, (2^16)-1]. - * @param {Number} y The Y coordinate in the range [0, (2^16)-1]. - * @returns {Number} The Morton index. + * @param {number} x The X coordinate in the range [0, (2^16)-1]. + * @param {number} y The Y coordinate in the range [0, (2^16)-1]. + * @returns {number} The Morton index. * @private */ MortonOrder.encode2D = function (x, y) { @@ -135,9 +135,9 @@ MortonOrder.encode2D = function (x, y) { * Computes the 2D coordinates from a Morton index. This is equivalent to deinterleaving their bits. * The input must be a 32-bit unsigned integer (resulting in 16 bits per coordinate) due to 32-bit bitwise operator limitation in JavaScript. * - * @param {Number} mortonIndex The Morton index in the range [0, (2^32)-1]. - * @param {Number[]} [result] The array onto which to store the result. - * @returns {Number[]} An array containing the 2D coordinates correspoding to the Morton index. + * @param {number} mortonIndex The Morton index in the range [0, (2^32)-1]. + * @param {number[]} [result] The array onto which to store the result. + * @returns {number[]} An array containing the 2D coordinates correspoding to the Morton index. * @private */ MortonOrder.decode2D = function (mortonIndex, result) { @@ -161,10 +161,10 @@ MortonOrder.decode2D = function (mortonIndex, result) { * Computes the Morton index from 3D coordinates. This is equivalent to interleaving their bits. * The inputs must be 10-bit unsigned integers (resulting in 30-bit Morton index) due to 32-bit bitwise operator limitation in JavaScript. * - * @param {Number} x The X coordinate in the range [0, (2^10)-1]. - * @param {Number} y The Y coordinate in the range [0, (2^10)-1]. - * @param {Number} z The Z coordinate in the range [0, (2^10)-1]. - * @returns {Number} The Morton index. + * @param {number} x The X coordinate in the range [0, (2^10)-1]. + * @param {number} y The Y coordinate in the range [0, (2^10)-1]. + * @param {number} z The Z coordinate in the range [0, (2^10)-1]. + * @returns {number} The Morton index. * @private */ MortonOrder.encode3D = function (x, y, z) { @@ -188,9 +188,9 @@ MortonOrder.encode3D = function (x, y, z) { * Computes the 3D coordinates from a Morton index. This is equivalent to deinterleaving their bits. * The input must be a 30-bit unsigned integer (resulting in 10 bits per coordinate) due to 32-bit bitwise operator limitation in JavaScript. * - * @param {Number} mortonIndex The Morton index in the range [0, (2^30)-1]. - * @param {Number[]} [result] The array onto which to store the result. - * @returns {Number[]} An array containing the 3D coordinates corresponding to the Morton index. + * @param {number} mortonIndex The Morton index in the range [0, (2^30)-1]. + * @param {number[]} [result] The array onto which to store the result. + * @returns {number[]} An array containing the 3D coordinates corresponding to the Morton index. * @private */ MortonOrder.decode3D = function (mortonIndex, result) { diff --git a/packages/engine/Source/Core/NearFarScalar.js b/packages/engine/Source/Core/NearFarScalar.js index 61eb59a0dd0..9b693fcc638 100644 --- a/packages/engine/Source/Core/NearFarScalar.js +++ b/packages/engine/Source/Core/NearFarScalar.js @@ -7,35 +7,35 @@ import DeveloperError from "./DeveloperError.js"; * @alias NearFarScalar * @constructor * - * @param {Number} [near=0.0] The lower bound of the camera range. - * @param {Number} [nearValue=0.0] The value at the lower bound of the camera range. - * @param {Number} [far=1.0] The upper bound of the camera range. - * @param {Number} [farValue=0.0] The value at the upper bound of the camera range. + * @param {number} [near=0.0] The lower bound of the camera range. + * @param {number} [nearValue=0.0] The value at the lower bound of the camera range. + * @param {number} [far=1.0] The upper bound of the camera range. + * @param {number} [farValue=0.0] The value at the upper bound of the camera range. * * @see Packable */ function NearFarScalar(near, nearValue, far, farValue) { /** * The lower bound of the camera range. - * @type {Number} + * @type {number} * @default 0.0 */ this.near = defaultValue(near, 0.0); /** * The value at the lower bound of the camera range. - * @type {Number} + * @type {number} * @default 0.0 */ this.nearValue = defaultValue(nearValue, 0.0); /** * The upper bound of the camera range. - * @type {Number} + * @type {number} * @default 1.0 */ this.far = defaultValue(far, 1.0); /** * The value at the upper bound of the camera range. - * @type {Number} + * @type {number} * @default 0.0 */ this.farValue = defaultValue(farValue, 0.0); @@ -71,7 +71,7 @@ NearFarScalar.clone = function (nearFarScalar, result) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ NearFarScalar.packedLength = 4; @@ -79,10 +79,10 @@ NearFarScalar.packedLength = 4; * Stores the provided instance into the provided array. * * @param {NearFarScalar} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ NearFarScalar.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -107,8 +107,8 @@ NearFarScalar.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {NearFarScalar} [result] The object into which to store the result. * @returns {NearFarScalar} The modified result parameter or a new NearFarScalar instance if one was not provided. */ @@ -137,7 +137,7 @@ NearFarScalar.unpack = function (array, startingIndex, result) { * * @param {NearFarScalar} [left] The first NearFarScalar. * @param {NearFarScalar} [right] The second NearFarScalar. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. */ NearFarScalar.equals = function (left, right) { return ( @@ -166,7 +166,7 @@ NearFarScalar.prototype.clone = function (result) { * <code>false</code> otherwise. * * @param {NearFarScalar} [right] The right hand side NearFarScalar. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. */ NearFarScalar.prototype.equals = function (right) { return NearFarScalar.equals(this, right); diff --git a/packages/engine/Source/Core/Occluder.js b/packages/engine/Source/Core/Occluder.js index 9f7b69899e4..cf247a0c360 100644 --- a/packages/engine/Source/Core/Occluder.js +++ b/packages/engine/Source/Core/Occluder.js @@ -65,7 +65,7 @@ Object.defineProperties(Occluder.prototype, { /** * The radius of the occluder. * @memberof Occluder.prototype - * @type {Number} + * @type {number} */ radius: { get: function () { @@ -175,7 +175,7 @@ const tempVecScratch = new Cartesian3(); * Determines whether or not a point, the <code>occludee</code>, is hidden from view by the occluder. * * @param {Cartesian3} occludee The point surrounding the occludee object. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. * * * @example @@ -211,7 +211,7 @@ const occludeePositionScratch = new Cartesian3(); * Determines whether or not a sphere, the <code>occludee</code>, is hidden from view by the occluder. * * @param {BoundingSphere} occludee The bounding sphere surrounding the occludee object. - * @returns {Boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the occludee is visible; otherwise <code>false</code>. * * * @example @@ -389,7 +389,7 @@ const occludeePointScratch = new Cartesian3(); * @param {BoundingSphere} occluderBoundingSphere The bounding sphere surrounding the occluder. * @param {Cartesian3} occludeePosition The point where the occludee (bounding sphere of radius 0) is located. * @param {Cartesian3[]} positions List of altitude points on the horizon near the surface of the occluder. - * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> + * @returns {object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> * which is a boolean value. * * @exception {DeveloperError} <code>positions</code> must contain at least one element. @@ -500,7 +500,7 @@ const computeOccludeePointFromRectangleScratch = []; * * @param {Rectangle} rectangle The rectangle used to create a bounding sphere. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine positions of the rectangle. - * @returns {Object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> + * @returns {object} An object containing two attributes: <code>occludeePoint</code> and <code>valid</code> * which is a boolean value. */ Occluder.computeOccludeePointFromRectangle = function (rectangle, ellipsoid) { diff --git a/packages/engine/Source/Core/OffsetGeometryInstanceAttribute.js b/packages/engine/Source/Core/OffsetGeometryInstanceAttribute.js index ca643f2e110..039d0b2136a 100644 --- a/packages/engine/Source/Core/OffsetGeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/OffsetGeometryInstanceAttribute.js @@ -9,9 +9,9 @@ import defined from "./defined.js"; * @alias OffsetGeometryInstanceAttribute * @constructor * - * @param {Number} [x=0] The x translation - * @param {Number} [y=0] The y translation - * @param {Number} [z=0] The z translation + * @param {number} [x=0] The x translation + * @param {number} [y=0] The y translation + * @param {number} [z=0] The z translation * * @private * @@ -54,7 +54,7 @@ Object.defineProperties(OffsetGeometryInstanceAttribute.prototype, { * * @memberof OffsetGeometryInstanceAttribute.prototype * - * @type {Number} + * @type {number} * @readonly * * @default 3 @@ -72,7 +72,7 @@ Object.defineProperties(OffsetGeometryInstanceAttribute.prototype, { * * @memberof OffsetGeometryInstanceAttribute.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false diff --git a/packages/engine/Source/Core/OpenCageGeocoderService.js b/packages/engine/Source/Core/OpenCageGeocoderService.js index ca575c97d54..f49342b73f2 100644 --- a/packages/engine/Source/Core/OpenCageGeocoderService.js +++ b/packages/engine/Source/Core/OpenCageGeocoderService.js @@ -11,22 +11,22 @@ import Resource from "./Resource.js"; * @alias OpenCageGeocoderService * @constructor * - * @param {Resource|String} url The endpoint to the OpenCage server. - * @param {String} apiKey The OpenCage API Key. - * @param {Object} [params] An object with the following properties (See https://opencagedata.com/api#forward-opt): - * @param {Number} [params.abbrv] When set to 1 we attempt to abbreviate and shorten the formatted string we return. - * @param {Number} [options.add_request] When set to 1 the various request parameters are added to the response for ease of debugging. - * @param {String} [options.bounds] Provides the geocoder with a hint to the region that the query resides in. - * @param {String} [options.countrycode] Restricts the results to the specified country or countries (as defined by the ISO 3166-1 Alpha 2 standard). - * @param {String} [options.jsonp] Wraps the returned JSON with a function name. - * @param {String} [options.language] An IETF format language code. - * @param {Number} [options.limit] The maximum number of results we should return. - * @param {Number} [options.min_confidence] An integer from 1-10. Only results with at least this confidence will be returned. - * @param {Number} [options.no_annotations] When set to 1 results will not contain annotations. - * @param {Number} [options.no_dedupe] When set to 1 results will not be deduplicated. - * @param {Number} [options.no_record] When set to 1 the query contents are not logged. - * @param {Number} [options.pretty] When set to 1 results are 'pretty' printed for easier reading. Useful for debugging. - * @param {String} [options.proximity] Provides the geocoder with a hint to bias results in favour of those closer to the specified location (For example: 41.40139,2.12870). + * @param {Resource|string} url The endpoint to the OpenCage server. + * @param {string} apiKey The OpenCage API Key. + * @param {object} [params] An object with the following properties (See https://opencagedata.com/api#forward-opt): + * @param {number} [params.abbrv] When set to 1 we attempt to abbreviate and shorten the formatted string we return. + * @param {number} [options.add_request] When set to 1 the various request parameters are added to the response for ease of debugging. + * @param {string} [options.bounds] Provides the geocoder with a hint to the region that the query resides in. + * @param {string} [options.countrycode] Restricts the results to the specified country or countries (as defined by the ISO 3166-1 Alpha 2 standard). + * @param {string} [options.jsonp] Wraps the returned JSON with a function name. + * @param {string} [options.language] An IETF format language code. + * @param {number} [options.limit] The maximum number of results we should return. + * @param {number} [options.min_confidence] An integer from 1-10. Only results with at least this confidence will be returned. + * @param {number} [options.no_annotations] When set to 1 results will not contain annotations. + * @param {number} [options.no_dedupe] When set to 1 results will not be deduplicated. + * @param {number} [options.no_record] When set to 1 the query contents are not logged. + * @param {number} [options.pretty] When set to 1 results are 'pretty' printed for easier reading. Useful for debugging. + * @param {string} [options.proximity] Provides the geocoder with a hint to bias results in favour of those closer to the specified location (For example: 41.40139,2.12870). * * @example * // Configure a Viewer to use the OpenCage Geocoder @@ -64,7 +64,7 @@ Object.defineProperties(OpenCageGeocoderService.prototype, { }, /** * Optional params passed to OpenCage in order to customize geocoding - * @type {Object} + * @type {object} * @memberof OpenCageGeocoderService.prototype * @readonly */ @@ -78,7 +78,7 @@ Object.defineProperties(OpenCageGeocoderService.prototype, { /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ OpenCageGeocoderService.prototype.geocode = function (query) { diff --git a/packages/engine/Source/Core/OrientedBoundingBox.js b/packages/engine/Source/Core/OrientedBoundingBox.js index f18ebabd3d9..59fe1d019ae 100644 --- a/packages/engine/Source/Core/OrientedBoundingBox.js +++ b/packages/engine/Source/Core/OrientedBoundingBox.js @@ -55,7 +55,7 @@ function OrientedBoundingBox(center, halfAxes) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ OrientedBoundingBox.packedLength = Cartesian3.packedLength + Matrix3.packedLength; @@ -64,10 +64,10 @@ OrientedBoundingBox.packedLength = * Stores the provided instance into the provided array. * * @param {OrientedBoundingBox} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ OrientedBoundingBox.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -86,8 +86,8 @@ OrientedBoundingBox.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {OrientedBoundingBox} [result] The object into which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if one was not provided. */ @@ -328,8 +328,8 @@ const scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); * There are no guarantees about the orientation of the bounding box. * * @param {Rectangle} rectangle The cartographic rectangle on the surface of the ellipsoid. - * @param {Number} [minimumHeight=0.0] The minimum height (elevation) within the tile. - * @param {Number} [maximumHeight=0.0] The maximum height (elevation) within the tile. + * @param {number} [minimumHeight=0.0] The minimum height (elevation) within the tile. + * @param {number} [maximumHeight=0.0] The maximum height (elevation) within the tile. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle is defined. * @param {OrientedBoundingBox} [result] The object onto which to store the result. * @returns {OrientedBoundingBox} The modified result parameter or a new OrientedBoundingBox instance if none was provided. @@ -724,7 +724,7 @@ const scratchPPrime = new Cartesian3(); * * @param {OrientedBoundingBox} box The box. * @param {Cartesian3} cartesian The point - * @returns {Number} The distance squared from the oriented bounding box to the point. Returns 0 if the point is inside the box. + * @returns {number} The distance squared from the oriented bounding box to the point. Returns 0 if the point is inside the box. * * @example * // Sort bounding boxes from back to front @@ -1126,7 +1126,7 @@ const scratchBoundingSphere = new BoundingSphere(); * * @param {OrientedBoundingBox} box The bounding box surrounding the occludee object. * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the box is not visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the box is not visible; otherwise <code>false</code>. */ OrientedBoundingBox.isOccluded = function (box, occluder) { //>>includeStart('debug', pragmas.debug); @@ -1163,7 +1163,7 @@ OrientedBoundingBox.prototype.intersectPlane = function (plane) { * Computes the estimated distance squared from the closest point on a bounding box to a point. * * @param {Cartesian3} cartesian The point - * @returns {Number} The estimated distance squared from the bounding sphere to the point. + * @returns {number} The estimated distance squared from the bounding sphere to the point. * * @example * // Sort bounding boxes from back to front @@ -1223,7 +1223,7 @@ OrientedBoundingBox.prototype.computeTransformation = function (result) { * Determines whether or not a bounding box is hidden from view by the occluder. * * @param {Occluder} occluder The occluder. - * @returns {Boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the sphere is not visible; otherwise <code>false</code>. */ OrientedBoundingBox.prototype.isOccluded = function (occluder) { return OrientedBoundingBox.isOccluded(this, occluder); @@ -1235,7 +1235,7 @@ OrientedBoundingBox.prototype.isOccluded = function (occluder) { * * @param {OrientedBoundingBox} left The first OrientedBoundingBox. * @param {OrientedBoundingBox} right The second OrientedBoundingBox. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ OrientedBoundingBox.equals = function (left, right) { return ( @@ -1262,7 +1262,7 @@ OrientedBoundingBox.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {OrientedBoundingBox} [right] The right hand side OrientedBoundingBox. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ OrientedBoundingBox.prototype.equals = function (right) { return OrientedBoundingBox.equals(this, right); diff --git a/packages/engine/Source/Core/OrthographicFrustum.js b/packages/engine/Source/Core/OrthographicFrustum.js index c1a5e797413..6e45f6b1b19 100644 --- a/packages/engine/Source/Core/OrthographicFrustum.js +++ b/packages/engine/Source/Core/OrthographicFrustum.js @@ -14,11 +14,11 @@ import OrthographicOffCenterFrustum from "./OrthographicOffCenterFrustum.js"; * @alias OrthographicFrustum * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.width] The width of the frustum in meters. - * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. - * @param {Number} [options.near=1.0] The distance of the near plane. - * @param {Number} [options.far=500000000.0] The distance of the far plane. + * @param {object} [options] An object with the following properties: + * @param {number} [options.width] The width of the frustum in meters. + * @param {number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {number} [options.near=1.0] The distance of the near plane. + * @param {number} [options.far=500000000.0] The distance of the far plane. * * @example * const maxRadii = ellipsoid.maximumRadius; @@ -34,7 +34,7 @@ function OrthographicFrustum(options) { /** * The horizontal width of the frustum in meters. - * @type {Number} + * @type {number} * @default undefined */ this.width = options.width; @@ -42,7 +42,7 @@ function OrthographicFrustum(options) { /** * The aspect ratio of the frustum's width to it's height. - * @type {Number} + * @type {number} * @default undefined */ this.aspectRatio = options.aspectRatio; @@ -50,7 +50,7 @@ function OrthographicFrustum(options) { /** * The distance of the near plane. - * @type {Number} + * @type {number} * @default 1.0 */ this.near = defaultValue(options.near, 1.0); @@ -58,7 +58,7 @@ function OrthographicFrustum(options) { /** * The distance of the far plane. - * @type {Number} + * @type {number} * @default 500000000.0; */ this.far = defaultValue(options.far, 500000000.0); @@ -67,7 +67,7 @@ function OrthographicFrustum(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ OrthographicFrustum.packedLength = 4; @@ -75,10 +75,10 @@ OrthographicFrustum.packedLength = 4; * Stores the provided instance into the provided array. * * @param {OrthographicFrustum} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ OrthographicFrustum.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -99,8 +99,8 @@ OrthographicFrustum.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {OrthographicFrustum} [result] The object into which to store the result. * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. */ @@ -211,10 +211,10 @@ OrthographicFrustum.prototype.computeCullingVolume = function ( /** * Returns the pixel's width and height in meters. * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Number} pixelRatio The scaling factor from pixel space to coordinate space. + * @param {number} drawingBufferWidth The width of the drawing buffer. + * @param {number} drawingBufferHeight The height of the drawing buffer. + * @param {number} distance The distance to the near plane in meters. + * @param {number} pixelRatio The scaling factor from pixel space to coordinate space. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. * @@ -276,7 +276,7 @@ OrthographicFrustum.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {OrthographicFrustum} [other] The right hand side OrthographicFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ OrthographicFrustum.prototype.equals = function (other) { if (!defined(other) || !(other instanceof OrthographicFrustum)) { @@ -299,9 +299,9 @@ OrthographicFrustum.prototype.equals = function (other) { * <code>false</code> otherwise. * * @param {OrthographicFrustum} other The right hand side OrthographicFrustum. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. + * @param {number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. */ OrthographicFrustum.prototype.equalsEpsilon = function ( other, diff --git a/packages/engine/Source/Core/OrthographicOffCenterFrustum.js b/packages/engine/Source/Core/OrthographicOffCenterFrustum.js index fafef3377a9..b99d0c5065b 100644 --- a/packages/engine/Source/Core/OrthographicOffCenterFrustum.js +++ b/packages/engine/Source/Core/OrthographicOffCenterFrustum.js @@ -16,13 +16,13 @@ import Matrix4 from "./Matrix4.js"; * @alias OrthographicOffCenterFrustum * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.left] The left clipping plane distance. - * @param {Number} [options.right] The right clipping plane distance. - * @param {Number} [options.top] The top clipping plane distance. - * @param {Number} [options.bottom] The bottom clipping plane distance. - * @param {Number} [options.near=1.0] The near clipping plane distance. - * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * @param {object} [options] An object with the following properties: + * @param {number} [options.left] The left clipping plane distance. + * @param {number} [options.right] The right clipping plane distance. + * @param {number} [options.top] The top clipping plane distance. + * @param {number} [options.bottom] The bottom clipping plane distance. + * @param {number} [options.near=1.0] The near clipping plane distance. + * @param {number} [options.far=500000000.0] The far clipping plane distance. * * @example * const maxRadii = ellipsoid.maximumRadius; @@ -40,7 +40,7 @@ function OrthographicOffCenterFrustum(options) { /** * The left clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.left = options.left; @@ -48,7 +48,7 @@ function OrthographicOffCenterFrustum(options) { /** * The right clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.right = options.right; @@ -56,7 +56,7 @@ function OrthographicOffCenterFrustum(options) { /** * The top clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.top = options.top; @@ -64,7 +64,7 @@ function OrthographicOffCenterFrustum(options) { /** * The bottom clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.bottom = options.bottom; @@ -72,7 +72,7 @@ function OrthographicOffCenterFrustum(options) { /** * The distance of the near plane. - * @type {Number} + * @type {number} * @default 1.0 */ this.near = defaultValue(options.near, 1.0); @@ -80,7 +80,7 @@ function OrthographicOffCenterFrustum(options) { /** * The distance of the far plane. - * @type {Number} + * @type {number} * @default 500000000.0; */ this.far = defaultValue(options.far, 500000000.0); @@ -293,10 +293,10 @@ OrthographicOffCenterFrustum.prototype.computeCullingVolume = function ( /** * Returns the pixel's width and height in meters. * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Number} pixelRatio The scaling factor from pixel space to coordinate space. + * @param {number} drawingBufferWidth The width of the drawing buffer. + * @param {number} drawingBufferHeight The height of the drawing buffer. + * @param {number} distance The distance to the near plane in meters. + * @param {number} pixelRatio The scaling factor from pixel space to coordinate space. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. * @@ -388,7 +388,7 @@ OrthographicOffCenterFrustum.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {OrthographicOffCenterFrustum} [other] The right hand side OrthographicOffCenterFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ OrthographicOffCenterFrustum.prototype.equals = function (other) { return ( @@ -409,9 +409,9 @@ OrthographicOffCenterFrustum.prototype.equals = function (other) { * <code>false</code> otherwise. * * @param {OrthographicOffCenterFrustum} other The right hand side OrthographicOffCenterFrustum. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. + * @param {number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. */ OrthographicOffCenterFrustum.prototype.equalsEpsilon = function ( other, diff --git a/packages/engine/Source/Core/Packable.js b/packages/engine/Source/Core/Packable.js index b27ecf00e15..ef167bed20d 100644 --- a/packages/engine/Source/Core/Packable.js +++ b/packages/engine/Source/Core/Packable.js @@ -12,7 +12,7 @@ import DeveloperError from "./DeveloperError.js"; const Packable = { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ packedLength: undefined, @@ -21,8 +21,8 @@ const Packable = { * @function * * @param {*} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. */ pack: DeveloperError.throwInstantiationError, @@ -30,10 +30,10 @@ const Packable = { * Retrieves an instance from a packed array. * @function * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. - * @param {Object} [result] The object into which to store the result. - * @returns {Object} The modified result parameter or a new Object instance if one was not provided. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {object} [result] The object into which to store the result. + * @returns {object} The modified result parameter or a new Object instance if one was not provided. */ unpack: DeveloperError.throwInstantiationError, }; diff --git a/packages/engine/Source/Core/PackableForInterpolation.js b/packages/engine/Source/Core/PackableForInterpolation.js index caf6f1d1f99..11e4a388588 100644 --- a/packages/engine/Source/Core/PackableForInterpolation.js +++ b/packages/engine/Source/Core/PackableForInterpolation.js @@ -12,7 +12,7 @@ import DeveloperError from "./DeveloperError.js"; const PackableForInterpolation = { /** * The number of elements used to store the object into an array in its interpolatable form. - * @type {Number} + * @type {number} */ packedInterpolationLength: undefined, @@ -20,10 +20,10 @@ const PackableForInterpolation = { * Converts a packed array into a form suitable for interpolation. * @function * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} [result] The object into which to store the result. + * @param {number[]} packedArray The packed array. + * @param {number} [startingIndex=0] The index of the first element to be converted. + * @param {number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {number[]} [result] The object into which to store the result. */ convertPackedArrayForInterpolation: DeveloperError.throwInstantiationError, @@ -31,12 +31,12 @@ const PackableForInterpolation = { * Retrieves an instance from a packed array converted with {@link PackableForInterpolation.convertPackedArrayForInterpolation}. * @function * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [startingIndex=0] The startingIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. - * @param {Object} [result] The object into which to store the result. - * @returns {Object} The modified result parameter or a new Object instance if one was not provided. + * @param {number[]} array The array previously packed for interpolation. + * @param {number[]} sourceArray The original packed array. + * @param {number} [startingIndex=0] The startingIndex used to convert the array. + * @param {number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {object} [result] The object into which to store the result. + * @returns {object} The modified result parameter or a new Object instance if one was not provided. */ unpackInterpolationResult: DeveloperError.throwInstantiationError, }; diff --git a/packages/engine/Source/Core/PeliasGeocoderService.js b/packages/engine/Source/Core/PeliasGeocoderService.js index 42d9cc26b2b..f859d8c0723 100644 --- a/packages/engine/Source/Core/PeliasGeocoderService.js +++ b/packages/engine/Source/Core/PeliasGeocoderService.js @@ -10,7 +10,7 @@ import Resource from "./Resource.js"; * @alias PeliasGeocoderService * @constructor * - * @param {Resource|String} url The endpoint to the Pelias server. + * @param {Resource|string} url The endpoint to the Pelias server. * * @example * // Configure a Viewer to use the Pelias server hosted by https://geocode.earth/ @@ -49,7 +49,7 @@ Object.defineProperties(PeliasGeocoderService.prototype, { /** * @function * - * @param {String} query The query to be sent to the geocoder service + * @param {string} query The query to be sent to the geocoder service * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. * @returns {Promise<GeocoderService.Result[]>} */ diff --git a/packages/engine/Source/Core/PerspectiveFrustum.js b/packages/engine/Source/Core/PerspectiveFrustum.js index 0663a6ab374..2290af9c9c0 100644 --- a/packages/engine/Source/Core/PerspectiveFrustum.js +++ b/packages/engine/Source/Core/PerspectiveFrustum.js @@ -14,13 +14,13 @@ import PerspectiveOffCenterFrustum from "./PerspectiveOffCenterFrustum.js"; * @alias PerspectiveFrustum * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.fov] The angle of the field of view (FOV), in radians. - * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. - * @param {Number} [options.near=1.0] The distance of the near plane. - * @param {Number} [options.far=500000000.0] The distance of the far plane. - * @param {Number} [options.xOffset=0.0] The offset in the x direction. - * @param {Number} [options.yOffset=0.0] The offset in the y direction. + * @param {object} [options] An object with the following properties: + * @param {number} [options.fov] The angle of the field of view (FOV), in radians. + * @param {number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {number} [options.near=1.0] The distance of the near plane. + * @param {number} [options.far=500000000.0] The distance of the far plane. + * @param {number} [options.xOffset=0.0] The offset in the x direction. + * @param {number} [options.yOffset=0.0] The offset in the y direction. * * @example * const frustum = new Cesium.PerspectiveFrustum({ @@ -41,7 +41,7 @@ function PerspectiveFrustum(options) { * The angle of the field of view (FOV), in radians. This angle will be used * as the horizontal FOV if the width is greater than the height, otherwise * it will be the vertical FOV. - * @type {Number} + * @type {number} * @default undefined */ this.fov = options.fov; @@ -52,7 +52,7 @@ function PerspectiveFrustum(options) { /** * The aspect ratio of the frustum's width to it's height. - * @type {Number} + * @type {number} * @default undefined */ this.aspectRatio = options.aspectRatio; @@ -60,7 +60,7 @@ function PerspectiveFrustum(options) { /** * The distance of the near plane. - * @type {Number} + * @type {number} * @default 1.0 */ this.near = defaultValue(options.near, 1.0); @@ -68,7 +68,7 @@ function PerspectiveFrustum(options) { /** * The distance of the far plane. - * @type {Number} + * @type {number} * @default 500000000.0 */ this.far = defaultValue(options.far, 500000000.0); @@ -76,7 +76,7 @@ function PerspectiveFrustum(options) { /** * Offsets the frustum in the x direction. - * @type {Number} + * @type {number} * @default 0.0 */ this.xOffset = defaultValue(options.xOffset, 0.0); @@ -84,7 +84,7 @@ function PerspectiveFrustum(options) { /** * Offsets the frustum in the y direction. - * @type {Number} + * @type {number} * @default 0.0 */ this.yOffset = defaultValue(options.yOffset, 0.0); @@ -93,7 +93,7 @@ function PerspectiveFrustum(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ PerspectiveFrustum.packedLength = 6; @@ -101,10 +101,10 @@ PerspectiveFrustum.packedLength = 6; * Stores the provided instance into the provided array. * * @param {PerspectiveFrustum} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PerspectiveFrustum.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -127,8 +127,8 @@ PerspectiveFrustum.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PerspectiveFrustum} [result] The object into which to store the result. * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. */ @@ -253,7 +253,7 @@ Object.defineProperties(PerspectiveFrustum.prototype, { /** * Gets the angle of the vertical field of view, in radians. * @memberof PerspectiveFrustum.prototype - * @type {Number} + * @type {number} * @readonly * @default undefined */ @@ -301,10 +301,10 @@ PerspectiveFrustum.prototype.computeCullingVolume = function ( /** * Returns the pixel's width and height in meters. * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Number} pixelRatio The scaling factor from pixel space to coordinate space. + * @param {number} drawingBufferWidth The width of the drawing buffer. + * @param {number} drawingBufferHeight The height of the drawing buffer. + * @param {number} distance The distance to the near plane in meters. + * @param {number} pixelRatio The scaling factor from pixel space to coordinate space. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. * @@ -377,7 +377,7 @@ PerspectiveFrustum.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {PerspectiveFrustum} [other] The right hand side PerspectiveFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ PerspectiveFrustum.prototype.equals = function (other) { if (!defined(other) || !(other instanceof PerspectiveFrustum)) { @@ -400,9 +400,9 @@ PerspectiveFrustum.prototype.equals = function (other) { * <code>false</code> otherwise. * * @param {PerspectiveFrustum} other The right hand side PerspectiveFrustum. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. + * @param {number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. */ PerspectiveFrustum.prototype.equalsEpsilon = function ( other, diff --git a/packages/engine/Source/Core/PerspectiveOffCenterFrustum.js b/packages/engine/Source/Core/PerspectiveOffCenterFrustum.js index 1cbd78bee16..00339b199d6 100644 --- a/packages/engine/Source/Core/PerspectiveOffCenterFrustum.js +++ b/packages/engine/Source/Core/PerspectiveOffCenterFrustum.js @@ -16,13 +16,13 @@ import Matrix4 from "./Matrix4.js"; * @alias PerspectiveOffCenterFrustum * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.left] The left clipping plane distance. - * @param {Number} [options.right] The right clipping plane distance. - * @param {Number} [options.top] The top clipping plane distance. - * @param {Number} [options.bottom] The bottom clipping plane distance. - * @param {Number} [options.near=1.0] The near clipping plane distance. - * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * @param {object} [options] An object with the following properties: + * @param {number} [options.left] The left clipping plane distance. + * @param {number} [options.right] The right clipping plane distance. + * @param {number} [options.top] The top clipping plane distance. + * @param {number} [options.bottom] The bottom clipping plane distance. + * @param {number} [options.near=1.0] The near clipping plane distance. + * @param {number} [options.far=500000000.0] The far clipping plane distance. * * @example * const frustum = new Cesium.PerspectiveOffCenterFrustum({ @@ -41,7 +41,7 @@ function PerspectiveOffCenterFrustum(options) { /** * Defines the left clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.left = options.left; @@ -49,7 +49,7 @@ function PerspectiveOffCenterFrustum(options) { /** * Defines the right clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.right = options.right; @@ -57,7 +57,7 @@ function PerspectiveOffCenterFrustum(options) { /** * Defines the top clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.top = options.top; @@ -65,7 +65,7 @@ function PerspectiveOffCenterFrustum(options) { /** * Defines the bottom clipping plane. - * @type {Number} + * @type {number} * @default undefined */ this.bottom = options.bottom; @@ -73,7 +73,7 @@ function PerspectiveOffCenterFrustum(options) { /** * The distance of the near plane. - * @type {Number} + * @type {number} * @default 1.0 */ this.near = defaultValue(options.near, 1.0); @@ -81,7 +81,7 @@ function PerspectiveOffCenterFrustum(options) { /** * The distance of the far plane. - * @type {Number} + * @type {number} * @default 500000000.0 */ this.far = defaultValue(options.far, 500000000.0); @@ -339,10 +339,10 @@ PerspectiveOffCenterFrustum.prototype.computeCullingVolume = function ( /** * Returns the pixel's width and height in meters. * - * @param {Number} drawingBufferWidth The width of the drawing buffer. - * @param {Number} drawingBufferHeight The height of the drawing buffer. - * @param {Number} distance The distance to the near plane in meters. - * @param {Number} pixelRatio The scaling factor from pixel space to coordinate space. + * @param {number} drawingBufferWidth The width of the drawing buffer. + * @param {number} drawingBufferHeight The height of the drawing buffer. + * @param {number} distance The distance to the near plane in meters. + * @param {number} pixelRatio The scaling factor from pixel space to coordinate space. * @param {Cartesian2} result The object onto which to store the result. * @returns {Cartesian2} The modified result parameter or a new instance of {@link Cartesian2} with the pixel's width and height in the x and y properties, respectively. * @@ -448,7 +448,7 @@ PerspectiveOffCenterFrustum.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {PerspectiveOffCenterFrustum} [other] The right hand side PerspectiveOffCenterFrustum. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ PerspectiveOffCenterFrustum.prototype.equals = function (other) { return ( @@ -469,9 +469,9 @@ PerspectiveOffCenterFrustum.prototype.equals = function (other) { * <code>false</code> otherwise. * * @param {PerspectiveOffCenterFrustum} other The right hand side PerspectiveOffCenterFrustum. - * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. - * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. + * @param {number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if this and other are within the provided epsilon, <code>false</code> otherwise. */ PerspectiveOffCenterFrustum.prototype.equalsEpsilon = function ( other, diff --git a/packages/engine/Source/Core/PinBuilder.js b/packages/engine/Source/Core/PinBuilder.js index 10953db75c2..143477b41c9 100644 --- a/packages/engine/Source/Core/PinBuilder.js +++ b/packages/engine/Source/Core/PinBuilder.js @@ -26,7 +26,7 @@ function PinBuilder() { * Creates an empty pin of the specified color and size. * * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. + * @param {number} size The size of the pin, in pixels. * @returns {HTMLCanvasElement} The canvas element that represents the generated pin. */ PinBuilder.prototype.fromColor = function (color, size) { @@ -44,10 +44,10 @@ PinBuilder.prototype.fromColor = function (color, size) { /** * Creates a pin with the specified icon, color, and size. * - * @param {Resource|String} url The url of the image to be stamped onto the pin. + * @param {Resource|string} url The url of the image to be stamped onto the pin. * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {HTMLCanvasElement|Promise.<HTMLCanvasElement>} The canvas element or a Promise to the canvas element that represents the generated pin. + * @param {number} size The size of the pin, in pixels. + * @returns {HTMLCanvasElement|Promise<HTMLCanvasElement>} The canvas element or a Promise to the canvas element that represents the generated pin. */ PinBuilder.prototype.fromUrl = function (url, color, size) { //>>includeStart('debug', pragmas.debug); @@ -67,10 +67,10 @@ PinBuilder.prototype.fromUrl = function (url, color, size) { /** * Creates a pin with the specified {@link https://www.mapbox.com/maki/|maki} icon identifier, color, and size. * - * @param {String} id The id of the maki icon to be stamped onto the pin. + * @param {string} id The id of the maki icon to be stamped onto the pin. * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. - * @returns {HTMLCanvasElement|Promise.<HTMLCanvasElement>} The canvas element or a Promise to the canvas element that represents the generated pin. + * @param {number} size The size of the pin, in pixels. + * @returns {HTMLCanvasElement|Promise<HTMLCanvasElement>} The canvas element or a Promise to the canvas element that represents the generated pin. */ PinBuilder.prototype.fromMakiIconId = function (id, color, size) { //>>includeStart('debug', pragmas.debug); @@ -97,9 +97,9 @@ PinBuilder.prototype.fromMakiIconId = function (id, color, size) { * Creates a pin with the specified text, color, and size. The text will be sized to be as large as possible * while still being contained completely within the pin. * - * @param {String} text The text to be stamped onto the pin. + * @param {string} text The text to be stamped onto the pin. * @param {Color} color The color of the pin. - * @param {Number} size The size of the pin, in pixels. + * @param {number} size The size of the pin, in pixels. * @returns {HTMLCanvasElement} The canvas element that represents the generated pin. */ PinBuilder.prototype.fromText = function (text, color, size) { diff --git a/packages/engine/Source/Core/PixelFormat.js b/packages/engine/Source/Core/PixelFormat.js index 15c8f9bca39..f95c7a53dc9 100644 --- a/packages/engine/Source/Core/PixelFormat.js +++ b/packages/engine/Source/Core/PixelFormat.js @@ -4,13 +4,13 @@ import WebGLConstants from "./WebGLConstants.js"; /** * The format of a pixel, i.e., the number of components it has and what they represent. * - * @enum {Number} + * @enum {number} */ const PixelFormat = { /** * A pixel format containing a depth value. * - * @type {Number} + * @type {number} * @constant */ DEPTH_COMPONENT: WebGLConstants.DEPTH_COMPONENT, @@ -18,7 +18,7 @@ const PixelFormat = { /** * A pixel format containing a depth and stencil value, most often used with {@link PixelDatatype.UNSIGNED_INT_24_8}. * - * @type {Number} + * @type {number} * @constant */ DEPTH_STENCIL: WebGLConstants.DEPTH_STENCIL, @@ -26,7 +26,7 @@ const PixelFormat = { /** * A pixel format containing an alpha channel. * - * @type {Number} + * @type {number} * @constant */ ALPHA: WebGLConstants.ALPHA, @@ -34,7 +34,7 @@ const PixelFormat = { /** * A pixel format containing a red channel * - * @type {Number} + * @type {number} * @constant */ RED: WebGLConstants.RED, @@ -42,7 +42,7 @@ const PixelFormat = { /** * A pixel format containing red and green channels. * - * @type {Number} + * @type {number} * @constant */ RG: WebGLConstants.RG, @@ -50,7 +50,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels. * - * @type {Number} + * @type {number} * @constant */ RGB: WebGLConstants.RGB, @@ -58,7 +58,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels. * - * @type {Number} + * @type {number} * @constant */ RGBA: WebGLConstants.RGBA, @@ -66,7 +66,7 @@ const PixelFormat = { /** * A pixel format containing a luminance (intensity) channel. * - * @type {Number} + * @type {number} * @constant */ LUMINANCE: WebGLConstants.LUMINANCE, @@ -74,7 +74,7 @@ const PixelFormat = { /** * A pixel format containing luminance (intensity) and alpha channels. * - * @type {Number} + * @type {number} * @constant */ LUMINANCE_ALPHA: WebGLConstants.LUMINANCE_ALPHA, @@ -82,7 +82,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels that is DXT1 compressed. * - * @type {Number} + * @type {number} * @constant */ RGB_DXT1: WebGLConstants.COMPRESSED_RGB_S3TC_DXT1_EXT, @@ -90,7 +90,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is DXT1 compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_DXT1: WebGLConstants.COMPRESSED_RGBA_S3TC_DXT1_EXT, @@ -98,7 +98,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is DXT3 compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_DXT3: WebGLConstants.COMPRESSED_RGBA_S3TC_DXT3_EXT, @@ -106,7 +106,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is DXT5 compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_DXT5: WebGLConstants.COMPRESSED_RGBA_S3TC_DXT5_EXT, @@ -114,7 +114,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels that is PVR 4bpp compressed. * - * @type {Number} + * @type {number} * @constant */ RGB_PVRTC_4BPPV1: WebGLConstants.COMPRESSED_RGB_PVRTC_4BPPV1_IMG, @@ -122,7 +122,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels that is PVR 2bpp compressed. * - * @type {Number} + * @type {number} * @constant */ RGB_PVRTC_2BPPV1: WebGLConstants.COMPRESSED_RGB_PVRTC_2BPPV1_IMG, @@ -130,7 +130,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is PVR 4bpp compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_PVRTC_4BPPV1: WebGLConstants.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, @@ -138,7 +138,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is PVR 2bpp compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_PVRTC_2BPPV1: WebGLConstants.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, @@ -146,7 +146,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is ASTC compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_ASTC: WebGLConstants.COMPRESSED_RGBA_ASTC_4x4_WEBGL, @@ -154,7 +154,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels that is ETC1 compressed. * - * @type {Number} + * @type {number} * @constant */ RGB_ETC1: WebGLConstants.COMPRESSED_RGB_ETC1_WEBGL, @@ -162,7 +162,7 @@ const PixelFormat = { /** * A pixel format containing red, green, and blue channels that is ETC2 compressed. * - * @type {Number} + * @type {number} * @constant */ RGB8_ETC2: WebGLConstants.COMPRESSED_RGB8_ETC2, @@ -170,7 +170,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is ETC2 compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA8_ETC2_EAC: WebGLConstants.COMPRESSED_RGBA8_ETC2_EAC, @@ -178,7 +178,7 @@ const PixelFormat = { /** * A pixel format containing red, green, blue, and alpha channels that is BC7 compressed. * - * @type {Number} + * @type {number} * @constant */ RGBA_BC7: WebGLConstants.COMPRESSED_RGBA_BPTC_UNORM, diff --git a/packages/engine/Source/Core/Plane.js b/packages/engine/Source/Core/Plane.js index a602c725fab..ab9ee77567c 100644 --- a/packages/engine/Source/Core/Plane.js +++ b/packages/engine/Source/Core/Plane.js @@ -19,7 +19,7 @@ import Matrix4 from "./Matrix4.js"; * @constructor * * @param {Cartesian3} normal The plane's normal (normalized). - * @param {Number} distance The shortest distance from the origin to the plane. The sign of + * @param {number} distance The shortest distance from the origin to the plane. The sign of * <code>distance</code> determines which side of the plane the origin * is on. If <code>distance</code> is positive, the origin is in the half-space * in the direction of the normal; if negative, the origin is in the half-space @@ -60,7 +60,7 @@ function Plane(normal, distance) { * in the direction of the normal; if negative, the origin is in the half-space * opposite to the normal; if zero, the plane passes through the origin. * - * @type {Number} + * @type {number} */ this.distance = distance; } @@ -153,7 +153,7 @@ Plane.fromCartesian4 = function (coefficients, result) { * * @param {Plane} plane The plane. * @param {Cartesian3} point The point. - * @returns {Number} The signed shortest distance of the point to the plane. + * @returns {number} The signed shortest distance of the point to the plane. */ Plane.getPointDistance = function (plane, point) { //>>includeStart('debug', pragmas.debug); @@ -272,7 +272,7 @@ Plane.clone = function (plane, result) { * * @param {Plane} left The first plane. * @param {Plane} right The second plane. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Plane.equals = function (left, right) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/PlaneGeometry.js b/packages/engine/Source/Core/PlaneGeometry.js index 7665cdaf052..8bc861fd149 100644 --- a/packages/engine/Source/Core/PlaneGeometry.js +++ b/packages/engine/Source/Core/PlaneGeometry.js @@ -16,7 +16,7 @@ import VertexFormat from "./VertexFormat.js"; * @alias PlaneGeometry * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * * @example @@ -35,7 +35,7 @@ function PlaneGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ PlaneGeometry.packedLength = VertexFormat.packedLength; @@ -43,10 +43,10 @@ PlaneGeometry.packedLength = VertexFormat.packedLength; * Stores the provided instance into the provided array. * * @param {PlaneGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PlaneGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -69,8 +69,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PlaneGeometry} [result] The object into which to store the result. * @returns {PlaneGeometry} The modified result parameter or a new PlaneGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/PlaneOutlineGeometry.js b/packages/engine/Source/Core/PlaneOutlineGeometry.js index 511a7f5e7be..e116db3d6fe 100644 --- a/packages/engine/Source/Core/PlaneOutlineGeometry.js +++ b/packages/engine/Source/Core/PlaneOutlineGeometry.js @@ -21,7 +21,7 @@ function PlaneOutlineGeometry() { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ PlaneOutlineGeometry.packedLength = 0; @@ -29,9 +29,9 @@ PlaneOutlineGeometry.packedLength = 0; * Stores the provided instance into the provided array. * * @param {PlaneOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. + * @param {number[]} array The array to pack into. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PlaneOutlineGeometry.pack = function (value, array) { //>>includeStart('debug', pragmas.debug); @@ -45,8 +45,8 @@ PlaneOutlineGeometry.pack = function (value, array) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PlaneOutlineGeometry} [result] The object into which to store the result. * @returns {PlaneOutlineGeometry} The modified result parameter or a new PlaneOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/PolygonGeometry.js b/packages/engine/Source/Core/PolygonGeometry.js index dcfe3c5c2a0..069c92707a5 100644 --- a/packages/engine/Source/Core/PolygonGeometry.js +++ b/packages/engine/Source/Core/PolygonGeometry.js @@ -700,17 +700,17 @@ function createGeometryFromPositionsExtruded( * @alias PolygonGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. + * @param {number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. + * @param {number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. - * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. + * @param {boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}. * @param {PolygonHierarchy} [options.textureCoordinates] Texture coordinates as a {@link PolygonHierarchy} of {@link Cartesian2} points. Has no effect for ground primitives. * @@ -853,7 +853,7 @@ function PolygonGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength( @@ -874,17 +874,17 @@ function PolygonGeometry(options) { /** * A description of a polygon from an array of positions. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. - * @param {Number} [options.height=0.0] The height of the polygon. - * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. + * @param {number} [options.height=0.0] The height of the polygon. + * @param {number} [options.extrudedHeight] The height of the polygon extrusion. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. - * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. - * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open. + * @param {boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}. * @param {PolygonHierarchy} [options.textureCoordinates] Texture coordinates as a {@link PolygonHierarchy} of {@link Cartesian2} points. Has no effect for ground primitives. * @returns {PolygonGeometry} @@ -935,10 +935,10 @@ PolygonGeometry.fromPositions = function (options) { * Stores the provided instance into the provided array. * * @param {PolygonGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PolygonGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -997,8 +997,8 @@ const dummyOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolygonGeometry} [result] The object into which to store the result. */ PolygonGeometry.unpack = function (array, startingIndex, result) { @@ -1081,9 +1081,9 @@ PolygonGeometry.unpack = function (array, startingIndex, result) { /** * Returns the bounding rectangle given the provided options * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions sampled. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions sampled. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @param {Rectangle} [result] An object in which to store the result. diff --git a/packages/engine/Source/Core/PolygonGeometryLibrary.js b/packages/engine/Source/Core/PolygonGeometryLibrary.js index c97adec4358..b24e1ae9aaa 100644 --- a/packages/engine/Source/Core/PolygonGeometryLibrary.js +++ b/packages/engine/Source/Core/PolygonGeometryLibrary.js @@ -192,8 +192,8 @@ PolygonGeometryLibrary.subdivideRhumbLineCount = function ( * @param {Cartesian2} t1 Second texture coordinate. * @param {Cartesian3} p0 First world position. * @param {Cartesian3} p1 Second world position. - * @param {Number} minDistance Minimum distance for a segment. - * @param {Array<Cartesian2>} result The subdivided texture coordinates. + * @param {number} minDistance Minimum distance for a segment. + * @param {Cartesian2[]} result The subdivided texture coordinates. * * @private */ @@ -266,8 +266,8 @@ PolygonGeometryLibrary.subdivideLine = function (p0, p1, minDistance, result) { * @param {Ellipsoid} ellipsoid The ellipsoid. * @param {Cartesian3} p0 First world position. * @param {Cartesian3} p1 Second world position. - * @param {Number} minDistance Minimum distance for a segment. - * @param {Array<Cartesian2>} result The subdivided texture coordinates. + * @param {number} minDistance Minimum distance for a segment. + * @param {Cartesian2[]} result The subdivided texture coordinates. * * @private */ diff --git a/packages/engine/Source/Core/PolygonOutlineGeometry.js b/packages/engine/Source/Core/PolygonOutlineGeometry.js index 652357e702c..14c235d55c4 100644 --- a/packages/engine/Source/Core/PolygonOutlineGeometry.js +++ b/packages/engine/Source/Core/PolygonOutlineGeometry.js @@ -268,14 +268,14 @@ function createGeometryFromPositionsExtruded( * @alias PolygonOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes. - * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. - * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. + * @param {number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface. + * @param {number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}. * * @see PolygonOutlineGeometry#createGeometry @@ -402,7 +402,7 @@ function PolygonOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength( @@ -417,10 +417,10 @@ function PolygonOutlineGeometry(options) { * Stores the provided instance into the provided array. * * @param {PolygonOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PolygonOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -460,8 +460,8 @@ const dummyOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolygonOutlineGeometry} [result] The object into which to store the result. * @returns {PolygonOutlineGeometry} The modified result parameter or a new PolygonOutlineGeometry instance if one was not provided. */ @@ -514,13 +514,13 @@ PolygonOutlineGeometry.unpack = function (array, startingIndex, result) { /** * A description of a polygon outline from an array of positions. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon. - * @param {Number} [options.height=0.0] The height of the polygon. - * @param {Number} [options.extrudedHeight] The height of the polygon extrusion. + * @param {number} [options.height=0.0] The height of the polygon. + * @param {number} [options.extrudedHeight] The height of the polygon extrusion. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link LinkType.GEODESIC} and {@link ArcType.RHUMB}. * @returns {PolygonOutlineGeometry} * diff --git a/packages/engine/Source/Core/PolygonPipeline.js b/packages/engine/Source/Core/PolygonPipeline.js index 19a3f194861..539c656f8d2 100644 --- a/packages/engine/Source/Core/PolygonPipeline.js +++ b/packages/engine/Source/Core/PolygonPipeline.js @@ -62,8 +62,8 @@ PolygonPipeline.computeWindingOrder2D = function (positions) { * Triangulate a polygon. * * @param {Cartesian2[]} positions Cartesian2 array containing the vertices of the polygon - * @param {Number[]} [holes] An array of the staring indices of the holes. - * @returns {Number[]} Index array representing triangles that fill the polygon + * @param {number[]} [holes] An array of the staring indices of the holes. + * @returns {number[]} Index array representing triangles that fill the polygon */ PolygonPipeline.triangulate = function (positions, holes) { //>>includeStart('debug', pragmas.debug); @@ -91,9 +91,9 @@ const subdivisionTexcoordMidScratch = new Cartesian2(); * * @param {Ellipsoid} ellipsoid The ellipsoid the polygon in on. * @param {Cartesian3[]} positions An array of {@link Cartesian3} positions of the polygon. - * @param {Number[]} indices An array of indices that determines the triangles in the polygon. + * @param {number[]} indices An array of indices that determines the triangles in the polygon. * @param {Cartesian2[]} texcoords An optional array of {@link Cartesian2} texture coordinates of the polygon. - * @param {Number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * * @exception {DeveloperError} At least three indices are required. * @exception {DeveloperError} The number of indices must be divisable by three. @@ -326,9 +326,9 @@ const subdivisionCartographicScratch = new Cartographic(); * * @param {Ellipsoid} ellipsoid The ellipsoid the polygon in on. * @param {Cartesian3[]} positions An array of {@link Cartesian3} positions of the polygon. - * @param {Number[]} indices An array of indices that determines the triangles in the polygon. + * @param {number[]} indices An array of indices that determines the triangles in the polygon. * @param {Cartesian2[]} texcoords An optional array of {@link Cartesian2} texture coordinates of the polygon. - * @param {Number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * * @exception {DeveloperError} At least three indices are required. * @exception {DeveloperError} The number of indices must be divisable by three. @@ -585,11 +585,11 @@ PolygonPipeline.computeRhumbLineSubdivision = function ( /** * Scales each position of a geometry's position attribute to a height, in place. * - * @param {Number[]} positions The array of numbers representing the positions to be scaled - * @param {Number} [height=0.0] The desired height to add to the positions + * @param {number[]} positions The array of numbers representing the positions to be scaled + * @param {number} [height=0.0] The desired height to add to the positions * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @param {Boolean} [scaleToSurface=true] <code>true</code> if the positions need to be scaled to the surface before the height is added. - * @returns {Number[]} The input array of positions, scaled to height + * @param {boolean} [scaleToSurface=true] <code>true</code> if the positions need to be scaled to the surface before the height is added. + * @returns {number[]} The input array of positions, scaled to height */ PolygonPipeline.scaleToGeodeticHeight = function ( positions, diff --git a/packages/engine/Source/Core/PolylineGeometry.js b/packages/engine/Source/Core/PolylineGeometry.js index f1625e42aea..a5f50ef1680 100644 --- a/packages/engine/Source/Core/PolylineGeometry.js +++ b/packages/engine/Source/Core/PolylineGeometry.js @@ -67,13 +67,13 @@ function interpolateColors(p0, p1, color0, color1, numPoints) { * @alias PolylineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the positions in the polyline as a line strip. - * @param {Number} [options.width=1.0] The width in pixels. + * @param {number} [options.width=1.0] The width in pixels. * @param {Color[]} [options.colors] An Array of {@link Color} defining the per vertex or per segment colors. - * @param {Boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. + * @param {boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polyline segments must follow. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.arcType is not ArcType.NONE. Determines the number of positions in the buffer. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.arcType is not ArcType.NONE. Determines the number of positions in the buffer. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @@ -143,7 +143,7 @@ function PolylineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 4; @@ -153,10 +153,10 @@ function PolylineGeometry(options) { * Stores the provided instance into the provided array. * * @param {PolylineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PolylineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -218,8 +218,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolylineGeometry} [result] The object into which to store the result. * @returns {PolylineGeometry} The modified result parameter or a new PolylineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/PolylinePipeline.js b/packages/engine/Source/Core/PolylinePipeline.js index 04b0e2fa7bf..dccbae1ec08 100644 --- a/packages/engine/Source/Core/PolylinePipeline.js +++ b/packages/engine/Source/Core/PolylinePipeline.js @@ -188,7 +188,7 @@ function generateCartesianRhumbArc( * transformation matrix, where the upper left 3x3 elements are a rotation matrix, and * the upper three elements in the fourth column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. * The matrix is not verified to be in the proper form. - * @returns {Object} An object with a <code>positions</code> property that is an array of positions and a + * @returns {object} An object with a <code>positions</code> property that is an array of positions and a * <code>segments</code> property. * * @@ -307,12 +307,12 @@ PolylinePipeline.wrapLongitude = function (positions, modelMatrix) { /** * Subdivides polyline and raises all points to the specified height. Returns an array of numbers to represent the positions. - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number|number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid. + * @returns {number[]} A new array of positions of type {number} that have been subdivided and raised to the surface of the ellipsoid. * * @example * const positions = Cesium.Cartesian3.fromDegreesArray([ @@ -414,12 +414,12 @@ const scratchCartographic1 = new Cartographic(); /** * Subdivides polyline and raises all points to the specified height using Rhumb lines. Returns an array of numbers to represent the positions. - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number|number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. - * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid. + * @returns {number[]} A new array of positions of type {number} that have been subdivided and raised to the surface of the ellipsoid. * * @example * const positions = Cesium.Cartesian3.fromDegreesArray([ @@ -520,10 +520,10 @@ PolylinePipeline.generateRhumbArc = function (options) { /** * Subdivides polyline and raises all points to the specified height. Returns an array of new {Cartesian3} positions. - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number|number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid. * @@ -550,10 +550,10 @@ PolylinePipeline.generateCartesianArc = function (options) { /** * Subdivides polyline and raises all points to the specified height using Rhumb Lines. Returns an array of new {Cartesian3} positions. - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions. - * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. - * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number|number[]} [options.height=0.0] A number or array of numbers representing the heights of each position. + * @param {number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie. * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid. * diff --git a/packages/engine/Source/Core/PolylineVolumeGeometry.js b/packages/engine/Source/Core/PolylineVolumeGeometry.js index e7b9d4e391e..fe5aa704bbf 100644 --- a/packages/engine/Source/Core/PolylineVolumeGeometry.js +++ b/packages/engine/Source/Core/PolylineVolumeGeometry.js @@ -175,11 +175,11 @@ function computeAttributes( * @alias PolylineVolumeGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.polylinePositions An array of {@link Cartesian3} positions that define the center of the polyline volume. * @param {Cartesian2[]} options.shapePositions An array of {@link Cartesian2} positions that define the shape to be extruded along the polyline * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * @@ -240,7 +240,7 @@ function PolylineVolumeGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 2; @@ -250,10 +250,10 @@ function PolylineVolumeGeometry(options) { * Stores the provided instance into the provided array. * * @param {PolylineVolumeGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PolylineVolumeGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -311,8 +311,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolylineVolumeGeometry} [result] The object into which to store the result. * @returns {PolylineVolumeGeometry} The modified result parameter or a new PolylineVolumeGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/PolylineVolumeOutlineGeometry.js b/packages/engine/Source/Core/PolylineVolumeOutlineGeometry.js index 09328f83d98..facd80c11df 100644 --- a/packages/engine/Source/Core/PolylineVolumeOutlineGeometry.js +++ b/packages/engine/Source/Core/PolylineVolumeOutlineGeometry.js @@ -80,11 +80,11 @@ function computeAttributes(positions, shape) { * @alias PolylineVolumeOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.polylinePositions An array of positions that define the center of the polyline volume. * @param {Cartesian2[]} options.shapePositions An array of positions that define the shape to be extruded along the polyline * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners. * * @see PolylineVolumeOutlineGeometry#createGeometry @@ -138,7 +138,7 @@ function PolylineVolumeOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + 2; } @@ -147,10 +147,10 @@ function PolylineVolumeOutlineGeometry(options) { * Stores the provided instance into the provided array. * * @param {PolylineVolumeOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ PolylineVolumeOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -204,8 +204,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {PolylineVolumeOutlineGeometry} [result] The object into which to store the result. * @returns {PolylineVolumeOutlineGeometry} The modified result parameter or a new PolylineVolumeOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/PrimitiveType.js b/packages/engine/Source/Core/PrimitiveType.js index 19a0887d9f2..9be8354aa0b 100644 --- a/packages/engine/Source/Core/PrimitiveType.js +++ b/packages/engine/Source/Core/PrimitiveType.js @@ -3,13 +3,13 @@ import WebGLConstants from "./WebGLConstants.js"; /** * The type of a geometric primitive, i.e., points, lines, and triangles. * - * @enum {Number} + * @enum {number} */ const PrimitiveType = { /** * Points primitive where each vertex (or index) is a separate point. * - * @type {Number} + * @type {number} * @constant */ POINTS: WebGLConstants.POINTS, @@ -17,7 +17,7 @@ const PrimitiveType = { /** * Lines primitive where each two vertices (or indices) is a line segment. Line segments are not necessarily connected. * - * @type {Number} + * @type {number} * @constant */ LINES: WebGLConstants.LINES, @@ -26,7 +26,7 @@ const PrimitiveType = { * Line loop primitive where each vertex (or index) after the first connects a line to * the previous vertex, and the last vertex implicitly connects to the first. * - * @type {Number} + * @type {number} * @constant */ LINE_LOOP: WebGLConstants.LINE_LOOP, @@ -34,7 +34,7 @@ const PrimitiveType = { /** * Line strip primitive where each vertex (or index) after the first connects a line to the previous vertex. * - * @type {Number} + * @type {number} * @constant */ LINE_STRIP: WebGLConstants.LINE_STRIP, @@ -42,7 +42,7 @@ const PrimitiveType = { /** * Triangles primitive where each three vertices (or indices) is a triangle. Triangles do not necessarily share edges. * - * @type {Number} + * @type {number} * @constant */ TRIANGLES: WebGLConstants.TRIANGLES, @@ -51,7 +51,7 @@ const PrimitiveType = { * Triangle strip primitive where each vertex (or index) after the first two connect to * the previous two vertices forming a triangle. For example, this can be used to model a wall. * - * @type {Number} + * @type {number} * @constant */ TRIANGLE_STRIP: WebGLConstants.TRIANGLE_STRIP, @@ -61,7 +61,7 @@ const PrimitiveType = { * the previous vertex and the first vertex forming a triangle. For example, this can be used * to model a cone or circle. * - * @type {Number} + * @type {number} * @constant */ TRIANGLE_FAN: WebGLConstants.TRIANGLE_FAN, diff --git a/packages/engine/Source/Core/Proxy.js b/packages/engine/Source/Core/Proxy.js index 43af4dbabc3..c16a27f1ad1 100644 --- a/packages/engine/Source/Core/Proxy.js +++ b/packages/engine/Source/Core/Proxy.js @@ -15,8 +15,8 @@ function Proxy() { /** * Get the final URL to use to request a given resource. * - * @param {String} resource The resource to request. - * @returns {String} proxied resource + * @param {string} resource The resource to request. + * @returns {string} proxied resource * @function */ Proxy.prototype.getURL = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/Core/QuadraticRealPolynomial.js b/packages/engine/Source/Core/QuadraticRealPolynomial.js index 7df6640c548..17a0fe1031f 100644 --- a/packages/engine/Source/Core/QuadraticRealPolynomial.js +++ b/packages/engine/Source/Core/QuadraticRealPolynomial.js @@ -11,10 +11,10 @@ const QuadraticRealPolynomial = {}; /** * Provides the discriminant of the quadratic equation from the supplied coefficients. * - * @param {Number} a The coefficient of the 2nd order monomial. - * @param {Number} b The coefficient of the 1st order monomial. - * @param {Number} c The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. + * @param {number} a The coefficient of the 2nd order monomial. + * @param {number} b The coefficient of the 1st order monomial. + * @param {number} c The coefficient of the 0th order monomial. + * @returns {number} The value of the discriminant. */ QuadraticRealPolynomial.computeDiscriminant = function (a, b, c) { //>>includeStart('debug', pragmas.debug); @@ -48,10 +48,10 @@ function addWithCancellationCheck(left, right, tolerance) { /** * Provides the real valued roots of the quadratic polynomial with the provided coefficients. * - * @param {Number} a The coefficient of the 2nd order monomial. - * @param {Number} b The coefficient of the 1st order monomial. - * @param {Number} c The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @param {number} a The coefficient of the 2nd order monomial. + * @param {number} b The coefficient of the 1st order monomial. + * @param {number} c The coefficient of the 0th order monomial. + * @returns {number[]} The real valued roots. */ QuadraticRealPolynomial.computeRealRoots = function (a, b, c) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/QuantizedMeshTerrainData.js b/packages/engine/Source/Core/QuantizedMeshTerrainData.js index 0a88ed831ce..f3c8d45d7ca 100644 --- a/packages/engine/Source/Core/QuantizedMeshTerrainData.js +++ b/packages/engine/Source/Core/QuantizedMeshTerrainData.js @@ -24,26 +24,26 @@ import TerrainMesh from "./TerrainMesh.js"; * @alias QuantizedMeshTerrainData * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh. * @param {Uint16Array|Uint32Array} options.indices The indices specifying how the quantized vertices are linked * together into triangles. Each three indices specifies one triangle. - * @param {Number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. - * @param {Number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. + * @param {number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. + * @param {number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. * @param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh. * @param {OrientedBoundingBox} [options.orientedBoundingBox] An OrientedBoundingBox bounding all of the vertices in the mesh. * @param {Cartesian3} options.horizonOcclusionPoint The horizon occlusion point of the mesh. If this point * is below the horizon, the entire tile is assumed to be below the horizon as well. * The point is expressed in ellipsoid-scaled coordinates. - * @param {Number[]} options.westIndices The indices of the vertices on the western edge of the tile. - * @param {Number[]} options.southIndices The indices of the vertices on the southern edge of the tile. - * @param {Number[]} options.eastIndices The indices of the vertices on the eastern edge of the tile. - * @param {Number[]} options.northIndices The indices of the vertices on the northern edge of the tile. - * @param {Number} options.westSkirtHeight The height of the skirt to add on the western edge of the tile. - * @param {Number} options.southSkirtHeight The height of the skirt to add on the southern edge of the tile. - * @param {Number} options.eastSkirtHeight The height of the skirt to add on the eastern edge of the tile. - * @param {Number} options.northSkirtHeight The height of the skirt to add on the northern edge of the tile. - * @param {Number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. + * @param {number[]} options.westIndices The indices of the vertices on the western edge of the tile. + * @param {number[]} options.southIndices The indices of the vertices on the southern edge of the tile. + * @param {number[]} options.eastIndices The indices of the vertices on the eastern edge of the tile. + * @param {number[]} options.northIndices The indices of the vertices on the northern edge of the tile. + * @param {number} options.westSkirtHeight The height of the skirt to add on the western edge of the tile. + * @param {number} options.southSkirtHeight The height of the skirt to add on the southern edge of the tile. + * @param {number} options.eastSkirtHeight The height of the skirt to add on the eastern edge of the tile. + * @param {number} options.northSkirtHeight The height of the skirt to add on the northern edge of the tile. + * @param {number} [options.childTileMask=15] A bit mask indicating which of this tile's four children exist. * If a child's bit is set, geometry will be requested for that tile as well when it * is needed. If the bit is cleared, the child tile is not requested and geometry is * instead upsampled from the parent. The bit values are as follows: @@ -54,7 +54,7 @@ import TerrainMesh from "./TerrainMesh.js"; * <tr><td>2</td><td>4</td><td>Northwest</td></tr> * <tr><td>3</td><td>8</td><td>Northeast</td></tr> * </table> - * @param {Boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; + * @param {boolean} [options.createdByUpsampling=false] True if this instance was created by upsampling another instance; * otherwise, false. * @param {Uint8Array} [options.encodedNormals] The buffer containing per vertex normals, encoded using 'oct' encoding * @param {Uint8Array} [options.waterMask] The buffer containing the watermask. @@ -275,15 +275,15 @@ const createMeshTaskProcessorThrottle = new TaskProcessor( * * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. - * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} options.level The level of the tile for which to create the terrain data. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. - * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * @param {number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {number} options.level The level of the tile for which to create the terrain data. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. + * @param {boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. + * @returns {Promise<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ @@ -418,13 +418,13 @@ const upsampleTaskProcessor = new TaskProcessor( * vertices in this instance, interpolated if necessary. * * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<QuantizedMeshTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, + * @param {number} thisX The X coordinate of this tile in the tiling scheme. + * @param {number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {number} thisLevel The level of this tile in the tiling scheme. + * @param {number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise<QuantizedMeshTerrainData>|undefined} A promise for upsampled heightmap terrain data for the descendant tile, * or undefined if too many asynchronous upsample operations are in progress and the request has been * deferred. */ @@ -563,9 +563,9 @@ const barycentricCoordinateScratch = new Cartesian3(); * Computes the terrain height at a specified longitude and latitude. * * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. The position is clamped to + * @param {number} longitude The longitude in radians. + * @param {number} latitude The latitude in radians. + * @returns {number} The terrain height at the specified position. The position is clamped to * the rectangle, so expect incorrect results for positions far outside the rectangle. */ QuantizedMeshTerrainData.prototype.interpolateHeight = function ( @@ -720,11 +720,11 @@ function interpolateHeight(terrainData, u, v) { * to be one of the four children of this tile. If non-child tile coordinates are * given, the availability of the southeast child tile is returned. * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. + * @param {number} thisX The tile X coordinate of this (the parent) tile. + * @param {number} thisY The tile Y coordinate of this (the parent) tile. + * @param {number} childX The tile X coordinate of the child tile to check for availability. + * @param {number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {boolean} True if the child tile is available; otherwise, false. */ QuantizedMeshTerrainData.prototype.isChildAvailable = function ( thisX, @@ -764,7 +764,7 @@ QuantizedMeshTerrainData.prototype.isChildAvailable = function ( * as by downloading it from a remote server. This method should return true for instances * returned from a call to {@link HeightmapTerrainData#upsample}. * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @returns {boolean} True if this instance was created by upsampling; otherwise, false. */ QuantizedMeshTerrainData.prototype.wasCreatedByUpsampling = function () { return this._createdByUpsampling; diff --git a/packages/engine/Source/Core/QuarticRealPolynomial.js b/packages/engine/Source/Core/QuarticRealPolynomial.js index baa589c0558..c71888ad4fa 100644 --- a/packages/engine/Source/Core/QuarticRealPolynomial.js +++ b/packages/engine/Source/Core/QuarticRealPolynomial.js @@ -13,12 +13,12 @@ const QuarticRealPolynomial = {}; /** * Provides the discriminant of the quartic equation from the supplied coefficients. * - * @param {Number} a The coefficient of the 4th order monomial. - * @param {Number} b The coefficient of the 3rd order monomial. - * @param {Number} c The coefficient of the 2nd order monomial. - * @param {Number} d The coefficient of the 1st order monomial. - * @param {Number} e The coefficient of the 0th order monomial. - * @returns {Number} The value of the discriminant. + * @param {number} a The coefficient of the 4th order monomial. + * @param {number} b The coefficient of the 3rd order monomial. + * @param {number} c The coefficient of the 2nd order monomial. + * @param {number} d The coefficient of the 1st order monomial. + * @param {number} e The coefficient of the 0th order monomial. + * @returns {number} The value of the discriminant. */ QuarticRealPolynomial.computeDiscriminant = function (a, b, c, d, e) { //>>includeStart('debug', pragmas.debug); @@ -263,12 +263,12 @@ function neumark(a3, a2, a1, a0) { /** * Provides the real valued roots of the quartic polynomial with the provided coefficients. * - * @param {Number} a The coefficient of the 4th order monomial. - * @param {Number} b The coefficient of the 3rd order monomial. - * @param {Number} c The coefficient of the 2nd order monomial. - * @param {Number} d The coefficient of the 1st order monomial. - * @param {Number} e The coefficient of the 0th order monomial. - * @returns {Number[]} The real valued roots. + * @param {number} a The coefficient of the 4th order monomial. + * @param {number} b The coefficient of the 3rd order monomial. + * @param {number} c The coefficient of the 2nd order monomial. + * @param {number} d The coefficient of the 1st order monomial. + * @param {number} e The coefficient of the 0th order monomial. + * @returns {number[]} The real valued roots. */ QuarticRealPolynomial.computeRealRoots = function (a, b, c, d, e) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/Quaternion.js b/packages/engine/Source/Core/Quaternion.js index 962b9cac0ac..b77cb770e1d 100644 --- a/packages/engine/Source/Core/Quaternion.js +++ b/packages/engine/Source/Core/Quaternion.js @@ -11,38 +11,38 @@ import Matrix3 from "./Matrix3.js"; * @alias Quaternion * @constructor * - * @param {Number} [x=0.0] The X component. - * @param {Number} [y=0.0] The Y component. - * @param {Number} [z=0.0] The Z component. - * @param {Number} [w=0.0] The W component. + * @param {number} [x=0.0] The X component. + * @param {number} [y=0.0] The Y component. + * @param {number} [z=0.0] The Z component. + * @param {number} [w=0.0] The W component. * * @see PackableForInterpolation */ function Quaternion(x, y, z, w) { /** * The X component. - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); /** * The Y component. - * @type {Number} + * @type {number} * @default 0.0 */ this.y = defaultValue(y, 0.0); /** * The Z component. - * @type {Number} + * @type {number} * @default 0.0 */ this.z = defaultValue(z, 0.0); /** * The W component. - * @type {Number} + * @type {number} * @default 0.0 */ this.w = defaultValue(w, 0.0); @@ -54,7 +54,7 @@ let fromAxisAngleScratch = new Cartesian3(); * Computes a quaternion representing a rotation around an axis. * * @param {Cartesian3} axis The axis of rotation. - * @param {Number} angle The angle in radians to rotate around the axis. + * @param {number} angle The angle in radians to rotate around the axis. * @param {Quaternion} [result] The object onto which to store the result. * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. */ @@ -220,7 +220,7 @@ const sampledQuaternionQuaternion0Conjugate = new Quaternion(); /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Quaternion.packedLength = 4; @@ -228,10 +228,10 @@ Quaternion.packedLength = 4; * Stores the provided instance into the provided array. * * @param {Quaternion} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Quaternion.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -252,8 +252,8 @@ Quaternion.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Quaternion} [result] The object into which to store the result. * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. */ @@ -276,17 +276,17 @@ Quaternion.unpack = function (array, startingIndex, result) { /** * The number of elements used to store the object into an array in its interpolatable form. - * @type {Number} + * @type {number} */ Quaternion.packedInterpolationLength = 3; /** * Converts a packed array into a form suitable for interpolation. * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} [result] The object into which to store the result. + * @param {number[]} packedArray The packed array. + * @param {number} [startingIndex=0] The index of the first element to be converted. + * @param {number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {number[]} [result] The object into which to store the result. */ Quaternion.convertPackedArrayForInterpolation = function ( packedArray, @@ -342,10 +342,10 @@ Quaternion.convertPackedArrayForInterpolation = function ( /** * Retrieves an instance from a packed array converted with {@link convertPackedArrayForInterpolation}. * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [firstIndex=0] The firstIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {number[]} array The array previously packed for interpolation. + * @param {number[]} sourceArray The original packed array. + * @param {number} [firstIndex=0] The firstIndex used to convert the array. + * @param {number} [lastIndex=packedArray.length] The lastIndex used to convert the array. * @param {Quaternion} [result] The object into which to store the result. * @returns {Quaternion} The modified result parameter or a new Quaternion instance if one was not provided. */ @@ -433,7 +433,7 @@ Quaternion.conjugate = function (quaternion, result) { * Computes magnitude squared for the provided quaternion. * * @param {Quaternion} quaternion The quaternion to conjugate. - * @returns {Number} The magnitude squared. + * @returns {number} The magnitude squared. */ Quaternion.magnitudeSquared = function (quaternion) { //>>includeStart('debug', pragmas.debug); @@ -452,7 +452,7 @@ Quaternion.magnitudeSquared = function (quaternion) { * Computes magnitude for the provided quaternion. * * @param {Quaternion} quaternion The quaternion to conjugate. - * @returns {Number} The magnitude. + * @returns {number} The magnitude. */ Quaternion.magnitude = function (quaternion) { return Math.sqrt(Quaternion.magnitudeSquared(quaternion)); @@ -569,7 +569,7 @@ Quaternion.negate = function (quaternion, result) { * * @param {Quaternion} left The first quaternion. * @param {Quaternion} right The second quaternion. - * @returns {Number} The dot product. + * @returns {number} The dot product. */ Quaternion.dot = function (left, right) { //>>includeStart('debug', pragmas.debug); @@ -623,7 +623,7 @@ Quaternion.multiply = function (left, right, result) { * Multiplies the provided quaternion componentwise by the provided scalar. * * @param {Quaternion} quaternion The quaternion to be scaled. - * @param {Number} scalar The scalar to multiply with. + * @param {number} scalar The scalar to multiply with. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. */ @@ -645,7 +645,7 @@ Quaternion.multiplyByScalar = function (quaternion, scalar, result) { * Divides the provided quaternion componentwise by the provided scalar. * * @param {Quaternion} quaternion The quaternion to be divided. - * @param {Number} scalar The scalar to divide by. + * @param {number} scalar The scalar to divide by. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. */ @@ -694,7 +694,7 @@ Quaternion.computeAxis = function (quaternion, result) { * Computes the angle of rotation of the provided quaternion. * * @param {Quaternion} quaternion The quaternion to use. - * @returns {Number} The angle of rotation. + * @returns {number} The angle of rotation. */ Quaternion.computeAngle = function (quaternion) { //>>includeStart('debug', pragmas.debug); @@ -713,7 +713,7 @@ let lerpScratch = new Quaternion(); * * @param {Quaternion} start The value corresponding to t at 0.0. * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. */ @@ -738,7 +738,7 @@ let slerpScaledR = new Quaternion(); * * @param {Quaternion} start The value corresponding to t at 0.0. * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. * @@ -881,7 +881,7 @@ Quaternion.computeInnerQuadrangle = function (q0, q1, q2, result) { * @param {Quaternion} q1 The second quaternion. * @param {Quaternion} s0 The first inner quadrangle. * @param {Quaternion} s1 The second inner quadrangle. - * @param {Number} t The time in [0,1] used to interpolate. + * @param {number} t The time in [0,1] used to interpolate. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. * @@ -937,7 +937,7 @@ v[7] = (opmu * 8.0) / 17.0; * * @param {Quaternion} start The value corresponding to t at 0.0. * @param {Quaternion} end The value corresponding to t at 1.0. - * @param {Number} t The point along t at which to interpolate. + * @param {number} t The point along t at which to interpolate. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter. * @@ -1016,7 +1016,7 @@ Quaternion.fastSlerp = function (start, end, t, result) { * @param {Quaternion} q1 The second quaternion. * @param {Quaternion} s0 The first inner quadrangle. * @param {Quaternion} s1 The second inner quadrangle. - * @param {Number} t The time in [0,1] used to interpolate. + * @param {number} t The time in [0,1] used to interpolate. * @param {Quaternion} result The object onto which to store the result. * @returns {Quaternion} The modified result parameter or a new instance if none was provided. * @@ -1043,7 +1043,7 @@ Quaternion.fastSquad = function (q0, q1, s0, s1, t, result) { * * @param {Quaternion} [left] The first quaternion. * @param {Quaternion} [right] The second quaternion. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Quaternion.equals = function (left, right) { return ( @@ -1064,8 +1064,8 @@ Quaternion.equals = function (left, right) { * * @param {Quaternion} [left] The first quaternion. * @param {Quaternion} [right] The second quaternion. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Quaternion.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0); @@ -1112,7 +1112,7 @@ Quaternion.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Quaternion} [right] The right hand side quaternion. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Quaternion.prototype.equals = function (right) { return Quaternion.equals(this, right); @@ -1124,8 +1124,8 @@ Quaternion.prototype.equals = function (right) { * <code>false</code> otherwise. * * @param {Quaternion} [right] The right hand side quaternion. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Quaternion.prototype.equalsEpsilon = function (right, epsilon) { return Quaternion.equalsEpsilon(this, right, epsilon); @@ -1134,7 +1134,7 @@ Quaternion.prototype.equalsEpsilon = function (right, epsilon) { /** * Returns a string representing this quaternion in the format (x, y, z, w). * - * @returns {String} A string representing this Quaternion. + * @returns {string} A string representing this Quaternion. */ Quaternion.prototype.toString = function () { return `(${this.x}, ${this.y}, ${this.z}, ${this.w})`; diff --git a/packages/engine/Source/Core/QuaternionSpline.js b/packages/engine/Source/Core/QuaternionSpline.js index 295626cf241..a469c068c92 100644 --- a/packages/engine/Source/Core/QuaternionSpline.js +++ b/packages/engine/Source/Core/QuaternionSpline.js @@ -33,8 +33,8 @@ function createEvaluateFunction(spline) { * @alias QuaternionSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. * The values are in no way connected to the clock time. They are the parameterization for the curve. * @param {Quaternion[]} options.points The array of {@link Quaternion} control points. * @@ -82,7 +82,7 @@ Object.defineProperties(QuaternionSpline.prototype, { * * @memberof QuaternionSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -111,8 +111,8 @@ Object.defineProperties(QuaternionSpline.prototype, { * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -124,8 +124,8 @@ QuaternionSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ QuaternionSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -133,15 +133,15 @@ QuaternionSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ QuaternionSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Quaternion} [result] The object onto which to store the result. * @returns {Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. * diff --git a/packages/engine/Source/Core/Queue.js b/packages/engine/Source/Core/Queue.js index f26b1df586d..b21cff76d1a 100644 --- a/packages/engine/Source/Core/Queue.js +++ b/packages/engine/Source/Core/Queue.js @@ -16,7 +16,7 @@ Object.defineProperties(Queue.prototype, { * * @memberof Queue.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -114,7 +114,7 @@ Queue.prototype.sort = function (compareFunction) { * * @param {*} a An item in the array. * @param {*} b An item in the array. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * @returns {number} Returns a negative value if <code>a</code> is less than <code>b</code>, * a positive value if <code>a</code> is greater than <code>b</code>, or * 0 if <code>a</code> is equal to <code>b</code>. * diff --git a/packages/engine/Source/Core/Ray.js b/packages/engine/Source/Core/Ray.js index ab2dd79e3fe..6b63229d65b 100644 --- a/packages/engine/Source/Core/Ray.js +++ b/packages/engine/Source/Core/Ray.js @@ -55,7 +55,7 @@ Ray.clone = function (ray, result) { * where o is the origin of the ray and d is the direction. * * @param {Ray} ray The ray. - * @param {Number} t A scalar value. + * @param {number} t A scalar value. * @param {Cartesian3} [result] The object in which the result will be stored. * @returns {Cartesian3} The modified result parameter, or a new instance if none was provided. * diff --git a/packages/engine/Source/Core/Rectangle.js b/packages/engine/Source/Core/Rectangle.js index 18035003952..36ca6fab850 100644 --- a/packages/engine/Source/Core/Rectangle.js +++ b/packages/engine/Source/Core/Rectangle.js @@ -11,10 +11,10 @@ import CesiumMath from "./Math.js"; * @alias Rectangle * @constructor * - * @param {Number} [west=0.0] The westernmost longitude, in radians, in the range [-Pi, Pi]. - * @param {Number} [south=0.0] The southernmost latitude, in radians, in the range [-Pi/2, Pi/2]. - * @param {Number} [east=0.0] The easternmost longitude, in radians, in the range [-Pi, Pi]. - * @param {Number} [north=0.0] The northernmost latitude, in radians, in the range [-Pi/2, Pi/2]. + * @param {number} [west=0.0] The westernmost longitude, in radians, in the range [-Pi, Pi]. + * @param {number} [south=0.0] The southernmost latitude, in radians, in the range [-Pi/2, Pi/2]. + * @param {number} [east=0.0] The easternmost longitude, in radians, in the range [-Pi, Pi]. + * @param {number} [north=0.0] The northernmost latitude, in radians, in the range [-Pi/2, Pi/2]. * * @see Packable */ @@ -22,7 +22,7 @@ function Rectangle(west, south, east, north) { /** * The westernmost longitude in radians in the range [-Pi, Pi]. * - * @type {Number} + * @type {number} * @default 0.0 */ this.west = defaultValue(west, 0.0); @@ -30,7 +30,7 @@ function Rectangle(west, south, east, north) { /** * The southernmost latitude in radians in the range [-Pi/2, Pi/2]. * - * @type {Number} + * @type {number} * @default 0.0 */ this.south = defaultValue(south, 0.0); @@ -38,7 +38,7 @@ function Rectangle(west, south, east, north) { /** * The easternmost longitude in radians in the range [-Pi, Pi]. * - * @type {Number} + * @type {number} * @default 0.0 */ this.east = defaultValue(east, 0.0); @@ -46,7 +46,7 @@ function Rectangle(west, south, east, north) { /** * The northernmost latitude in radians in the range [-Pi/2, Pi/2]. * - * @type {Number} + * @type {number} * @default 0.0 */ this.north = defaultValue(north, 0.0); @@ -56,7 +56,7 @@ Object.defineProperties(Rectangle.prototype, { /** * Gets the width of the rectangle in radians. * @memberof Rectangle.prototype - * @type {Number} + * @type {number} * @readonly */ width: { @@ -68,7 +68,7 @@ Object.defineProperties(Rectangle.prototype, { /** * Gets the height of the rectangle in radians. * @memberof Rectangle.prototype - * @type {Number} + * @type {number} * @readonly */ height: { @@ -80,7 +80,7 @@ Object.defineProperties(Rectangle.prototype, { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ Rectangle.packedLength = 4; @@ -88,10 +88,10 @@ Rectangle.packedLength = 4; * Stores the provided instance into the provided array. * * @param {Rectangle} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ Rectangle.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -112,8 +112,8 @@ Rectangle.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Rectangle} [result] The object into which to store the result. * @returns {Rectangle} The modified result parameter or a new Rectangle instance if one was not provided. */ @@ -138,7 +138,7 @@ Rectangle.unpack = function (array, startingIndex, result) { /** * Computes the width of a rectangle in radians. * @param {Rectangle} rectangle The rectangle to compute the width of. - * @returns {Number} The width. + * @returns {number} The width. */ Rectangle.computeWidth = function (rectangle) { //>>includeStart('debug', pragmas.debug); @@ -155,7 +155,7 @@ Rectangle.computeWidth = function (rectangle) { /** * Computes the height of a rectangle in radians. * @param {Rectangle} rectangle The rectangle to compute the height of. - * @returns {Number} The height. + * @returns {number} The height. */ Rectangle.computeHeight = function (rectangle) { //>>includeStart('debug', pragmas.debug); @@ -167,10 +167,10 @@ Rectangle.computeHeight = function (rectangle) { /** * Creates a rectangle given the boundary longitude and latitude in degrees. * - * @param {Number} [west=0.0] The westernmost longitude in degrees in the range [-180.0, 180.0]. - * @param {Number} [south=0.0] The southernmost latitude in degrees in the range [-90.0, 90.0]. - * @param {Number} [east=0.0] The easternmost longitude in degrees in the range [-180.0, 180.0]. - * @param {Number} [north=0.0] The northernmost latitude in degrees in the range [-90.0, 90.0]. + * @param {number} [west=0.0] The westernmost longitude in degrees in the range [-180.0, 180.0]. + * @param {number} [south=0.0] The southernmost latitude in degrees in the range [-90.0, 90.0]. + * @param {number} [east=0.0] The easternmost longitude in degrees in the range [-180.0, 180.0]. + * @param {number} [north=0.0] The northernmost latitude in degrees in the range [-90.0, 90.0]. * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. * @@ -198,10 +198,10 @@ Rectangle.fromDegrees = function (west, south, east, north, result) { /** * Creates a rectangle given the boundary longitude and latitude in radians. * - * @param {Number} [west=0.0] The westernmost longitude in radians in the range [-Math.PI, Math.PI]. - * @param {Number} [south=0.0] The southernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. - * @param {Number} [east=0.0] The easternmost longitude in radians in the range [-Math.PI, Math.PI]. - * @param {Number} [north=0.0] The northernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. + * @param {number} [west=0.0] The westernmost longitude in radians in the range [-Math.PI, Math.PI]. + * @param {number} [south=0.0] The southernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. + * @param {number} [east=0.0] The easternmost longitude in radians in the range [-Math.PI, Math.PI]. + * @param {number} [north=0.0] The northernmost latitude in radians in the range [-Math.PI/2, Math.PI/2]. * @param {Rectangle} [result] The object onto which to store the result, or undefined if a new instance should be created. * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. * @@ -372,8 +372,8 @@ Rectangle.clone = function (rectangle, result) { * * @param {Rectangle} [left] The first Rectangle. * @param {Rectangle} [right] The second Rectangle. - * @param {Number} [absoluteEpsilon=0] The absolute epsilon tolerance to use for equality testing. - * @returns {Boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [absoluteEpsilon=0] The absolute epsilon tolerance to use for equality testing. + * @returns {boolean} <code>true</code> if left and right are within the provided epsilon, <code>false</code> otherwise. */ Rectangle.equalsEpsilon = function (left, right, absoluteEpsilon) { absoluteEpsilon = defaultValue(absoluteEpsilon, 0); @@ -404,7 +404,7 @@ Rectangle.prototype.clone = function (result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Rectangle} [other] The Rectangle to compare. - * @returns {Boolean} <code>true</code> if the Rectangles are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the Rectangles are equal, <code>false</code> otherwise. */ Rectangle.prototype.equals = function (other) { return Rectangle.equals(this, other); @@ -416,7 +416,7 @@ Rectangle.prototype.equals = function (other) { * * @param {Rectangle} [left] The first Rectangle. * @param {Rectangle} [right] The second Rectangle. - * @returns {Boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if left and right are equal; otherwise <code>false</code>. */ Rectangle.equals = function (left, right) { return ( @@ -436,8 +436,8 @@ Rectangle.equals = function (left, right) { * <code>false</code> otherwise. * * @param {Rectangle} [other] The Rectangle to compare. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. - * @returns {Boolean} <code>true</code> if the Rectangles are within the provided epsilon, <code>false</code> otherwise. + * @param {number} [epsilon=0] The epsilon to use for equality testing. + * @returns {boolean} <code>true</code> if the Rectangles are within the provided epsilon, <code>false</code> otherwise. */ Rectangle.prototype.equalsEpsilon = function (other, epsilon) { return Rectangle.equalsEpsilon(this, other, epsilon); @@ -786,7 +786,7 @@ Rectangle.expand = function (rectangle, cartographic, result) { * * @param {Rectangle} rectangle The rectangle * @param {Cartographic} cartographic The cartographic to test. - * @returns {Boolean} true if the provided cartographic is inside the rectangle, false otherwise. + * @returns {boolean} true if the provided cartographic is inside the rectangle, false otherwise. */ Rectangle.contains = function (rectangle, cartographic) { //>>includeStart('debug', pragmas.debug); @@ -824,7 +824,7 @@ const subsampleLlaScratch = new Cartographic(); * * @param {Rectangle} rectangle The rectangle to subsample. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use. - * @param {Number} [surfaceHeight=0.0] The height of the rectangle above the ellipsoid. + * @param {number} [surfaceHeight=0.0] The height of the rectangle above the ellipsoid. * @param {Cartesian3[]} [result] The array of Cartesians onto which to store the result. * @returns {Cartesian3[]} The modified result parameter or a new Array of Cartesians instances if none was provided. */ @@ -898,10 +898,10 @@ Rectangle.subsample = function (rectangle, ellipsoid, surfaceHeight, result) { * Computes a subsection of a rectangle from normalized coordinates in the range [0.0, 1.0]. * * @param {Rectangle} rectangle The rectangle to subsection. - * @param {Number} westLerp The west interpolation factor in the range [0.0, 1.0]. Must be less than or equal to eastLerp. - * @param {Number} southLerp The south interpolation factor in the range [0.0, 1.0]. Must be less than or equal to northLerp. - * @param {Number} eastLerp The east interpolation factor in the range [0.0, 1.0]. Must be greater than or equal to westLerp. - * @param {Number} northLerp The north interpolation factor in the range [0.0, 1.0]. Must be greater than or equal to southLerp. + * @param {number} westLerp The west interpolation factor in the range [0.0, 1.0]. Must be less than or equal to eastLerp. + * @param {number} southLerp The south interpolation factor in the range [0.0, 1.0]. Must be less than or equal to northLerp. + * @param {number} eastLerp The east interpolation factor in the range [0.0, 1.0]. Must be greater than or equal to westLerp. + * @param {number} northLerp The north interpolation factor in the range [0.0, 1.0]. Must be greater than or equal to southLerp. * @param {Rectangle} [result] The object onto which to store the result. * @returns {Rectangle} The modified result parameter or a new Rectangle instance if none was provided. */ diff --git a/packages/engine/Source/Core/RectangleCollisionChecker.js b/packages/engine/Source/Core/RectangleCollisionChecker.js index b5801d9c982..bb8cdb51684 100644 --- a/packages/engine/Source/Core/RectangleCollisionChecker.js +++ b/packages/engine/Source/Core/RectangleCollisionChecker.js @@ -29,7 +29,7 @@ RectangleWithId.fromRectangleAndId = function (id, rectangle, result) { /** * Insert a rectangle into the collision checker. * - * @param {String} id Unique string ID for the rectangle being inserted. + * @param {string} id Unique string ID for the rectangle being inserted. * @param {Rectangle} rectangle A Rectangle * @private */ @@ -55,7 +55,7 @@ const removalScratch = new RectangleWithId(); /** * Remove a rectangle from the collision checker. * - * @param {String} id Unique string ID for the rectangle being removed. + * @param {string} id Unique string ID for the rectangle being removed. * @param {Rectangle} rectangle A Rectangle * @private */ @@ -78,7 +78,7 @@ const collisionScratch = new RectangleWithId(); * Checks if a given rectangle collides with any of the rectangles in the collection. * * @param {Rectangle} rectangle A Rectangle that should be checked against the rectangles in the collision checker. - * @returns {Boolean} Whether the rectangle collides with any of the rectangles in the collision checker. + * @returns {boolean} Whether the rectangle collides with any of the rectangles in the collision checker. */ RectangleCollisionChecker.prototype.collides = function (rectangle) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/RectangleGeometry.js b/packages/engine/Source/Core/RectangleGeometry.js index ab1b4a4a4ab..7e0b8d5ae7d 100644 --- a/packages/engine/Source/Core/RectangleGeometry.js +++ b/packages/engine/Source/Core/RectangleGeometry.js @@ -975,15 +975,15 @@ function computeRectangle(rectangle, granularity, rotation, ellipsoid, result) { * @alias RectangleGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. + * @param {number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. * * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. @@ -1056,7 +1056,7 @@ function RectangleGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ RectangleGeometry.packedLength = Rectangle.packedLength + @@ -1068,10 +1068,10 @@ RectangleGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {RectangleGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ RectangleGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -1119,8 +1119,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {RectangleGeometry} [result] The object into which to store the result. * @returns {RectangleGeometry} The modified result parameter or a new RectangleGeometry instance if one was not provided. */ @@ -1183,11 +1183,11 @@ RectangleGeometry.unpack = function (array, startingIndex, result) { /** * Computes the bounding rectangle based on the provided options * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. * @param {Rectangle} [result] An object in which to store the result. * * @returns {Rectangle} The result rectangle diff --git a/packages/engine/Source/Core/RectangleOutlineGeometry.js b/packages/engine/Source/Core/RectangleOutlineGeometry.js index 5a8432d98b5..03d7cd32d21 100644 --- a/packages/engine/Source/Core/RectangleOutlineGeometry.js +++ b/packages/engine/Source/Core/RectangleOutlineGeometry.js @@ -247,13 +247,13 @@ function constructExtrudedRectangle(rectangleGeometry, computedOptions) { * @alias RectangleOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Rectangle} options.rectangle A cartographic rectangle with north, south, east and west properties in radians. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the rectangle lies. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. - * @param {Number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. - * @param {Number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number} [options.height=0.0] The distance in meters between the rectangle and the ellipsoid surface. + * @param {number} [options.rotation=0.0] The rotation of the rectangle, in radians. A positive rotation is counter-clockwise. + * @param {number} [options.extrudedHeight] The distance in meters between the rectangle's extruded face and the ellipsoid surface. * * @exception {DeveloperError} <code>options.rectangle.north</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. * @exception {DeveloperError} <code>options.rectangle.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>]. @@ -309,7 +309,7 @@ function RectangleOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ RectangleOutlineGeometry.packedLength = Rectangle.packedLength + Ellipsoid.packedLength + 5; @@ -318,10 +318,10 @@ RectangleOutlineGeometry.packedLength = * Stores the provided instance into the provided array. * * @param {RectangleOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ RectangleOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -366,8 +366,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {RectangleOutlineGeometry} [result] The object into which to store the result. * @returns {RectangleOutlineGeometry} The modified result parameter or a new Quaternion instance if one was not provided. */ diff --git a/packages/engine/Source/Core/ReferenceFrame.js b/packages/engine/Source/Core/ReferenceFrame.js index c4a15b4c454..fdc89904035 100644 --- a/packages/engine/Source/Core/ReferenceFrame.js +++ b/packages/engine/Source/Core/ReferenceFrame.js @@ -1,13 +1,13 @@ /** * Constants for identifying well-known reference frames. * - * @enum {Number} + * @enum {number} */ const ReferenceFrame = { /** * The fixed frame. * - * @type {Number} + * @type {number} * @constant */ FIXED: 0, @@ -15,7 +15,7 @@ const ReferenceFrame = { /** * The inertial frame. * - * @type {Number} + * @type {number} * @constant */ INERTIAL: 1, diff --git a/packages/engine/Source/Core/Request.js b/packages/engine/Source/Core/Request.js index f37b1321873..9988f54c6cc 100644 --- a/packages/engine/Source/Core/Request.js +++ b/packages/engine/Source/Core/Request.js @@ -9,14 +9,14 @@ import RequestType from "./RequestType.js"; * @alias Request * @constructor - * @param {Object} [options] An object with the following properties: - * @param {String} [options.url] The url to request. + * @param {object} [options] An object with the following properties: + * @param {string} [options.url] The url to request. * @param {Request.RequestCallback} [options.requestFunction] The function that makes the actual data request. * @param {Request.CancelCallback} [options.cancelFunction] The function that is called when the request is cancelled. * @param {Request.PriorityCallback} [options.priorityFunction] The function that is called to update the request's priority, which occurs once per frame. - * @param {Number} [options.priority=0.0] The initial priority of the request. - * @param {Boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. - * @param {Boolean} [options.throttleByServer=false] Whether to throttle the request by server. + * @param {number} [options.priority=0.0] The initial priority of the request. + * @param {boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. + * @param {boolean} [options.throttleByServer=false] Whether to throttle the request by server. * @param {RequestType} [options.type=RequestType.OTHER] The type of request. */ function Request(options) { @@ -28,7 +28,7 @@ function Request(options) { /** * The URL to request. * - * @type {String} + * @type {string} */ this.url = options.url; @@ -60,7 +60,7 @@ function Request(options) { * * If priorityFunction is defined, this value is updated every frame with the result of that call. * - * @type {Number} + * @type {number} * @default 0.0 */ this.priority = defaultValue(options.priority, 0.0); @@ -69,7 +69,7 @@ function Request(options) { * Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the * request will be throttled and sent based on priority. * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -81,7 +81,7 @@ function Request(options) { * for HTTP/1 servers, and an unlimited amount of connections for HTTP/2 servers. Setting this value * to <code>true</code> is preferable for requests going through HTTP/1 servers. * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -101,7 +101,7 @@ function Request(options) { /** * A key used to identify the server that a request is going to. It is derived from the url's authority and scheme. * - * @type {String} + * @type {string} * * @private */ @@ -118,7 +118,7 @@ function Request(options) { /** * The requests's deferred promise. * - * @type {Object} + * @type {object} * * @private */ @@ -127,7 +127,7 @@ function Request(options) { /** * Whether the request was explicitly cancelled. * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -187,6 +187,6 @@ Request.prototype.clone = function (result) { /** * The function that is called to update the request's priority, which occurs once per frame. * @callback Request.PriorityCallback - * @returns {Number} The updated priority value. + * @returns {number} The updated priority value. */ export default Request; diff --git a/packages/engine/Source/Core/RequestErrorEvent.js b/packages/engine/Source/Core/RequestErrorEvent.js index eb4e9789673..ba9d4b9fe1f 100644 --- a/packages/engine/Source/Core/RequestErrorEvent.js +++ b/packages/engine/Source/Core/RequestErrorEvent.js @@ -7,9 +7,9 @@ import parseResponseHeaders from "./parseResponseHeaders.js"; * @constructor * @alias RequestErrorEvent * - * @param {Number} [statusCode] The HTTP error status code, such as 404. - * @param {Object} [response] The response included along with the error. - * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * @param {number} [statusCode] The HTTP error status code, such as 404. + * @param {object} [response] The response included along with the error. + * @param {string|Object} [responseHeaders] The response headers, represented either as an object literal or as a * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. */ function RequestErrorEvent(statusCode, response, responseHeaders) { @@ -17,7 +17,7 @@ function RequestErrorEvent(statusCode, response, responseHeaders) { * The HTTP error status code, such as 404. If the error does not have a particular * HTTP code, this property will be undefined. * - * @type {Number} + * @type {number} */ this.statusCode = statusCode; @@ -25,7 +25,7 @@ function RequestErrorEvent(statusCode, response, responseHeaders) { * The response included along with the error. If the error does not include a response, * this property will be undefined. * - * @type {Object} + * @type {object} */ this.response = response; @@ -33,7 +33,7 @@ function RequestErrorEvent(statusCode, response, responseHeaders) { * The headers included in the response, represented as an object literal of key/value pairs. * If the error does not include any headers, this property will be undefined. * - * @type {Object} + * @type {object} */ this.responseHeaders = responseHeaders; @@ -46,7 +46,7 @@ function RequestErrorEvent(statusCode, response, responseHeaders) { * Creates a string representing this RequestErrorEvent. * @memberof RequestErrorEvent * - * @returns {String} A string representing the provided RequestErrorEvent. + * @returns {string} A string representing the provided RequestErrorEvent. */ RequestErrorEvent.prototype.toString = function () { let str = "Request has failed."; diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index 8a1a7145b5c..59cf7bdb372 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -51,7 +51,7 @@ function RequestScheduler() {} /** * The maximum number of simultaneous active requests. Un-throttled requests do not observe this limit. - * @type {Number} + * @type {number} * @default 50 */ RequestScheduler.maximumRequests = 50; @@ -59,14 +59,14 @@ RequestScheduler.maximumRequests = 50; /** * The maximum number of simultaneous active requests per server. Un-throttled requests or servers specifically * listed in {@link requestsByServer} do not observe this limit. - * @type {Number} + * @type {number} * @default 6 */ RequestScheduler.maximumRequestsPerServer = 6; /** * A per server key list of overrides to use for throttling instead of <code>maximumRequestsPerServer</code> - * @type {Object} + * @type {object} * * @example * RequestScheduler.requestsByServer = { @@ -81,14 +81,14 @@ RequestScheduler.requestsByServer = { /** * Specifies if the request scheduler should throttle incoming requests, or let the browser queue requests under its control. - * @type {Boolean} + * @type {boolean} * @default true */ RequestScheduler.throttleRequests = true; /** * When true, log statistics to the console every frame - * @type {Boolean} + * @type {boolean} * @default false * @private */ @@ -125,7 +125,7 @@ Object.defineProperties(RequestScheduler, { * * @memberof RequestScheduler * - * @type {Number} + * @type {number} * @default 20 * @private */ @@ -157,9 +157,9 @@ function updatePriority(request) { /** * Check if there are open slots for a particular server key. If desiredRequests is greater than 1, this checks if the queue has room for scheduling multiple requests. - * @param {String} serverKey The server key returned by {@link RequestScheduler.getServerKey}. - * @param {Number} [desiredRequests=1] How many requests the caller plans to request - * @return {Boolean} True if there are enough open slots for <code>desiredRequests</code> more requests. + * @param {string} serverKey The server key returned by {@link RequestScheduler.getServerKey}. + * @param {number} [desiredRequests=1] How many requests the caller plans to request + * @return {boolean} True if there are enough open slots for <code>desiredRequests</code> more requests. * @private */ RequestScheduler.serverHasOpenSlots = function (serverKey, desiredRequests) { @@ -179,8 +179,8 @@ RequestScheduler.serverHasOpenSlots = function (serverKey, desiredRequests) { * Check if the priority heap has open slots, regardless of which server they * are from. This is used in {@link Multiple3DTileContent} for determining when * all requests can be scheduled - * @param {Number} desiredRequests The number of requests the caller intends to make - * @return {Boolean} <code>true</code> if the heap has enough available slots to meet the desiredRequests. <code>false</code> otherwise. + * @param {number} desiredRequests The number of requests the caller intends to make + * @return {boolean} <code>true</code> if the heap has enough available slots to meet the desiredRequests. <code>false</code> otherwise. * * @private */ @@ -341,8 +341,8 @@ RequestScheduler.update = function () { /** * Get the server key from a given url. * - * @param {String} url The url. - * @returns {String} The server key. + * @param {string} url The url. + * @returns {string} The server key. * @private */ RequestScheduler.getServerKey = function (url) { diff --git a/packages/engine/Source/Core/RequestState.js b/packages/engine/Source/Core/RequestState.js index a117d9e2b0b..2ef0134824a 100644 --- a/packages/engine/Source/Core/RequestState.js +++ b/packages/engine/Source/Core/RequestState.js @@ -1,7 +1,7 @@ /** * State of the request. * - * @enum {Number} + * @enum {number} */ const RequestState = { /** diff --git a/packages/engine/Source/Core/RequestType.js b/packages/engine/Source/Core/RequestType.js index 5cb89c0e44e..0c5358eb603 100644 --- a/packages/engine/Source/Core/RequestType.js +++ b/packages/engine/Source/Core/RequestType.js @@ -1,7 +1,7 @@ /** * An enum identifying the type of request. Used for finer grained logging and priority sorting. * - * @enum {Number} + * @enum {number} */ const RequestType = { /** diff --git a/packages/engine/Source/Core/Resource.js b/packages/engine/Source/Core/Resource.js index a02c303f4b3..c4292ebad06 100644 --- a/packages/engine/Source/Core/Resource.js +++ b/packages/engine/Source/Core/Resource.js @@ -41,8 +41,8 @@ const xhrBlobSupported = (function () { * * @param {Uri} uri The Uri with a query object. * @param {Resource} resource The Resource that will be assigned queryParameters. - * @param {Boolean} merge If true, we'll merge with the resource's existing queryParameters. Otherwise they will be replaced. - * @param {Boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in uri will take precedence. + * @param {boolean} merge If true, we'll merge with the resource's existing queryParameters. Otherwise they will be replaced. + * @param {boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in uri will take precedence. * * @private */ @@ -135,11 +135,11 @@ function checkAndResetRequest(request) { /** * This combines a map of query parameters. * - * @param {Object} q1 The first map of query parameters. Values in this map will take precedence if preserveQueryParameters is false. - * @param {Object} q2 The second map of query parameters. - * @param {Boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in q1 will take precedence. + * @param {object} q1 The first map of query parameters. Values in this map will take precedence if preserveQueryParameters is false. + * @param {object} q2 The second map of query parameters. + * @param {boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in q1 will take precedence. * - * @returns {Object} The combined map of query parameters. + * @returns {object} The combined map of query parameters. * * @example * const q1 = { @@ -215,17 +215,17 @@ function combineQueryParameters(q1, q2, preserveQueryParameters) { } /** - * @typedef {Object} Resource.ConstructorOptions + * @typedef {object} Resource.ConstructorOptions * * Initialization options for the Resource constructor * - * @property {String} url The url of the resource. - * @property {Object} [queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @property {Object} [templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @property {Object} [headers={}] Additional HTTP headers that will be sent. + * @property {string} url The url of the resource. + * @property {object} [queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @property {object} [templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @property {object} [headers={}] Additional HTTP headers that will be sent. * @property {Proxy} [proxy] A proxy to be used when loading the resource. * @property {Resource.RetryCallback} [retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @property {Number} [retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @property {number} [retryAttempts=0] The number of times the retryCallback should be called before giving up. * @property {Request} [request] A Request object that will be used. Intended for internal use only. */ @@ -235,7 +235,7 @@ function combineQueryParameters(q1, q2, preserveQueryParameters) { * @alias Resource * @constructor * - * @param {String|Resource.ConstructorOptions} options A url or an object describing initialization options + * @param {string|Resource.ConstructorOptions} options A url or an object describing initialization options * * @example * function refreshTokenRetryCallback(resource, error) { @@ -286,7 +286,7 @@ function Resource(options) { /** * Additional HTTP headers that will be sent with the request. * - * @type {Object} + * @type {object} */ this.headers = defaultClone(options.headers, {}); @@ -314,7 +314,7 @@ function Resource(options) { /** * The number of times the retryCallback should be called before giving up. * - * @type {Number} + * @type {number} */ this.retryAttempts = defaultValue(options.retryAttempts, 0); this._retryCount = 0; @@ -331,7 +331,7 @@ function Resource(options) { /** * A helper function to create a resource depending on whether we have a String or a Resource * - * @param {Resource|String} resource A Resource or a String to use when creating a new Resource. + * @param {Resource|string} resource A Resource or a String to use when creating a new Resource. * * @returns {Resource} If resource is a String, a Resource constructed with the url and options. Otherwise the resource parameter is returned. * @@ -361,7 +361,7 @@ let supportsImageBitmapOptionsPromise; /** * A helper function to check whether createImageBitmap supports passing ImageBitmapOptions. * - * @returns {Promise<Boolean>} A promise that resolves to true if this browser supports creating an ImageBitmap with options. + * @returns {Promise<boolean>} A promise that resolves to true if this browser supports creating an ImageBitmap with options. * * @private */ @@ -420,7 +420,7 @@ Object.defineProperties(Resource, { * Returns true if blobs are supported. * * @memberof Resource - * @type {Boolean} + * @type {boolean} * * @readonly */ @@ -436,7 +436,7 @@ Object.defineProperties(Resource.prototype, { * Query parameters appended to the url. * * @memberof Resource.prototype - * @type {Object} + * @type {object} * * @readonly */ @@ -450,7 +450,7 @@ Object.defineProperties(Resource.prototype, { * The key/value pairs used to replace template parameters in the url. * * @memberof Resource.prototype - * @type {Object} + * @type {object} * * @readonly */ @@ -464,7 +464,7 @@ Object.defineProperties(Resource.prototype, { * The url to the resource with template values replaced, query string appended and encoded by proxy if one was set. * * @memberof Resource.prototype - * @type {String} + * @type {string} */ url: { get: function () { @@ -486,7 +486,7 @@ Object.defineProperties(Resource.prototype, { * The file extension of the resource. * * @memberof Resource.prototype - * @type {String} + * @type {string} * * @readonly */ @@ -500,7 +500,7 @@ Object.defineProperties(Resource.prototype, { * True if the Resource refers to a data URI. * * @memberof Resource.prototype - * @type {Boolean} + * @type {boolean} */ isDataUri: { get: function () { @@ -512,7 +512,7 @@ Object.defineProperties(Resource.prototype, { * True if the Resource refers to a blob URI. * * @memberof Resource.prototype - * @type {Boolean} + * @type {boolean} */ isBlobUri: { get: function () { @@ -524,7 +524,7 @@ Object.defineProperties(Resource.prototype, { * True if the Resource refers to a cross origin URL. * * @memberof Resource.prototype - * @type {Boolean} + * @type {boolean} */ isCrossOriginUrl: { get: function () { @@ -536,7 +536,7 @@ Object.defineProperties(Resource.prototype, { * True if the Resource has request headers. This is equivalent to checking if the headers property has any keys. * * @memberof Resource.prototype - * @type {Boolean} + * @type {boolean} */ hasHeaders: { get: function () { @@ -549,7 +549,7 @@ Object.defineProperties(Resource.prototype, { * Override Object#toString so that implicit string conversion gives the * complete URL represented by this Resource. * - * @returns {String} The URL represented by this Resource + * @returns {string} The URL represented by this Resource */ Resource.prototype.toString = function () { return this.getUrlComponent(true, true); @@ -558,10 +558,10 @@ Resource.prototype.toString = function () { /** * Returns the url, optional with the query string and processed by a proxy. * - * @param {Boolean} [query=false] If true, the query string is included. - * @param {Boolean} [proxy=false] If true, the url is processed by the proxy object, if defined. + * @param {boolean} [query=false] If true, the query string is included. + * @param {boolean} [proxy=false] If true, the url is processed by the proxy object, if defined. * - * @returns {String} The url with all the requested components. + * @returns {string} The url with all the requested components. */ Resource.prototype.getUrlComponent = function (query, proxy) { if (this.isDataUri) { @@ -598,8 +598,8 @@ Resource.prototype.getUrlComponent = function (query, proxy) { * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, * as opposed to adding them one at a time to the queryParameters property. If a value is already set, it will be replaced with the new value. * - * @param {Object} params The query parameters - * @param {Boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. + * @param {object} params The query parameters + * @param {boolean} [useAsDefault=false] If true the params will be used as the default values, so they will only be set if they are undefined. */ Resource.prototype.setQueryParameters = function (params, useAsDefault) { if (useAsDefault) { @@ -621,7 +621,7 @@ Resource.prototype.setQueryParameters = function (params, useAsDefault) { * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, * as opposed to adding them one at a time to the queryParameters property. * - * @param {Object} params The query parameters + * @param {object} params The query parameters */ Resource.prototype.appendQueryParameters = function (params) { this._queryParameters = combineQueryParameters( @@ -635,8 +635,8 @@ Resource.prototype.appendQueryParameters = function (params) { * Combines the specified object and the existing template values. This allows you to add many values at once, * as opposed to adding them one at a time to the templateValues property. If a value is already set, it will become an array and the new value will be appended. * - * @param {Object} template The template values - * @param {Boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. + * @param {object} template The template values + * @param {boolean} [useAsDefault=false] If true the values will be used as the default values, so they will only be set if they are undefined. */ Resource.prototype.setTemplateValues = function (template, useAsDefault) { if (useAsDefault) { @@ -649,16 +649,16 @@ Resource.prototype.setTemplateValues = function (template, useAsDefault) { /** * Returns a resource relative to the current instance. All properties remain the same as the current instance unless overridden in options. * - * @param {Object} options An object with the following properties - * @param {String} [options.url] The url that will be resolved relative to the url of the current instance. - * @param {Object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {object} options An object with the following properties + * @param {string} [options.url] The url that will be resolved relative to the url of the current instance. + * @param {object} [options.queryParameters] An object containing query parameters that will be combined with those of the current instance. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). These will be combined with those of the current instance. + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The function to call when loading the resource fails. - * @param {Number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {Boolean} [options.preserveQueryParameters=false] If true, this will keep all query parameters from the current resource and derived resource. If false, derived parameters will replace those of the current resource. + * @param {boolean} [options.preserveQueryParameters=false] If true, this will keep all query parameters from the current resource and derived resource. If false, derived parameters will replace those of the current resource. * * @returns {Resource} The resource derived from the current one. */ @@ -723,7 +723,7 @@ Resource.prototype.getDerivedResource = function (options) { * * @param {Error} [error] The error that was encountered. * - * @returns {Promise<Boolean>} A promise to a boolean, that if true will cause the resource request to be retried. + * @returns {Promise<boolean>} A promise to a boolean, that if true will cause the resource request to be retried. * * @private */ @@ -774,9 +774,9 @@ Resource.prototype.clone = function (result) { /** * Returns the base path of the Resource. * - * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @param {boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri * - * @returns {String} The base URI of the resource + * @returns {string} The base URI of the resource */ Resource.prototype.getBaseUri = function (includeQuery) { return getBaseUri(this.getUrlComponent(includeQuery), includeQuery); @@ -795,7 +795,7 @@ Resource.prototype.appendForwardSlash = function () { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * @example * // load a single URL asynchronously @@ -817,16 +817,16 @@ Resource.prototype.fetchArrayBuffer = function () { /** * Creates a Resource and calls fetchArrayBuffer() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @returns {Promise.<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchArrayBuffer = function (options) { const resource = new Resource(options); @@ -839,7 +839,7 @@ Resource.fetchArrayBuffer = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * @example * // load a single URL asynchronously @@ -861,16 +861,16 @@ Resource.prototype.fetchBlob = function () { /** * Creates a Resource and calls fetchBlob() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @returns {Promise.<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<Blob>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchBlob = function (options) { const resource = new Resource(options); @@ -882,12 +882,12 @@ Resource.fetchBlob = function (options) { * an {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap|ImageBitmap} if <code>preferImageBitmap</code> is true and the browser supports <code>createImageBitmap</code> or otherwise an * {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement|Image} once loaded, or reject if the image failed to load. * - * @param {Object} [options] An object with the following properties. - * @param {Boolean} [options.preferBlob=false] If true, we will load the image via a blob. - * @param {Boolean} [options.preferImageBitmap=false] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. - * @param {Boolean} [options.flipY=false] If true, image will be vertically flipped during decode. Only applies if the browser supports <code>createImageBitmap</code>. - * @param {Boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies if the browser supports <code>createImageBitmap</code>. - * @returns {Promise.<ImageBitmap|HTMLImageElement>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} [options] An object with the following properties. + * @param {boolean} [options.preferBlob=false] If true, we will load the image via a blob. + * @param {boolean} [options.preferImageBitmap=false] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. + * @param {boolean} [options.flipY=false] If true, image will be vertically flipped during decode. Only applies if the browser supports <code>createImageBitmap</code>. + * @param {boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies if the browser supports <code>createImageBitmap</code>. + * @returns {Promise<ImageBitmap|HTMLImageElement>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1009,11 +1009,11 @@ Resource.prototype.fetchImage = function (options) { /** * Fetches an image and returns a promise to it. * - * @param {Object} [options] An object with the following properties. + * @param {object} [options] An object with the following properties. * @param {Resource} [options.resource] Resource object that points to an image to fetch. - * @param {Boolean} [options.preferImageBitmap] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. - * @param {Boolean} [options.flipY] If true, image will be vertically flipped during decode. Only applies if the browser supports <code>createImageBitmap</code>. - * @param {Boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies if the browser supports <code>createImageBitmap</code>. + * @param {boolean} [options.preferImageBitmap] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. + * @param {boolean} [options.flipY] If true, image will be vertically flipped during decode. Only applies if the browser supports <code>createImageBitmap</code>. + * @param {boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies if the browser supports <code>createImageBitmap</code>. * @private */ function fetchImage(options) { @@ -1076,20 +1076,20 @@ function fetchImage(options) { /** * Creates a Resource and calls fetchImage() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. - * @param {Boolean} [options.flipY=false] Whether to vertically flip the image during fetch and decode. Only applies when requesting an image and the browser supports <code>createImageBitmap</code>. + * @param {boolean} [options.flipY=false] Whether to vertically flip the image during fetch and decode. Only applies when requesting an image and the browser supports <code>createImageBitmap</code>. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {Boolean} [options.preferBlob=false] If true, we will load the image via a blob. - * @param {Boolean} [options.preferImageBitmap=false] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. - * @param {Boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies when requesting an image and the browser supports <code>createImageBitmap</code>. - * @returns {Promise.<ImageBitmap|HTMLImageElement>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {boolean} [options.preferBlob=false] If true, we will load the image via a blob. + * @param {boolean} [options.preferImageBitmap=false] If true, image will be decoded during fetch and an <code>ImageBitmap</code> is returned. + * @param {boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the image will be ignored. Only applies when requesting an image and the browser supports <code>createImageBitmap</code>. + * @returns {Promise<ImageBitmap|HTMLImageElement>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchImage = function (options) { const resource = new Resource(options); @@ -1107,7 +1107,7 @@ Resource.fetchImage = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<string>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * @example * // load text from a URL, setting a custom header @@ -1136,16 +1136,16 @@ Resource.prototype.fetchText = function () { /** * Creates a Resource and calls fetchText() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @returns {Promise.<String>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<string>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchText = function (options) { const resource = new Resource(options); @@ -1161,7 +1161,7 @@ Resource.fetchText = function (options) { * adds 'Accept: application/json,*/*;q=0.01' to the request headers, if not * already specified. * - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1197,16 +1197,16 @@ Resource.prototype.fetchJson = function () { /** * Creates a Resource and calls fetchJson() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchJson = function (options) { const resource = new Resource(options); @@ -1219,7 +1219,7 @@ Resource.fetchJson = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1246,16 +1246,16 @@ Resource.prototype.fetchXML = function () { /** * Creates a Resource and calls fetchXML() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @returns {Promise.<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @returns {Promise<XMLDocument>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchXML = function (options) { const resource = new Resource(options); @@ -1265,8 +1265,8 @@ Resource.fetchXML = function (options) { /** * Requests a resource using JSONP. * - * @param {String} [callbackParameterName='callback'] The callback parameter name that the server expects. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1351,17 +1351,17 @@ function fetchJsonp(resource, callbackParameterName, functionName) { /** * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.callbackParameterName='callback'] The callback parameter name that the server expects. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.callbackParameterName='callback'] The callback parameter name that the server expects. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetchJsonp = function (options) { const resource = new Resource(options); @@ -1494,11 +1494,11 @@ function decodeDataUri(dataUriRegexResult, responseType) { * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. It's recommended that you use * the more specific functions eg. fetchJson, fetchBlob, etc. * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1522,18 +1522,18 @@ Resource.prototype.fetch = function (options) { /** * Creates a Resource from a URL and calls fetch() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.fetch = function (options) { const resource = new Resource(options); @@ -1550,11 +1550,11 @@ Resource.fetch = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1578,19 +1578,19 @@ Resource.prototype.delete = function (options) { /** * Creates a Resource from a URL and calls delete() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.data] Data that is posted with the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.data] Data that is posted with the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.delete = function (options) { const resource = new Resource(options); @@ -1608,11 +1608,11 @@ Resource.delete = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1636,18 +1636,18 @@ Resource.prototype.head = function (options) { /** * Creates a Resource from a URL and calls head() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.head = function (options) { const resource = new Resource(options); @@ -1664,11 +1664,11 @@ Resource.head = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1692,18 +1692,18 @@ Resource.prototype.options = function (options) { /** * Creates a Resource from a URL and calls options() on it. * - * @param {String|Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {string|Object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.options = function (options) { const resource = new Resource(options); @@ -1720,13 +1720,13 @@ Resource.options = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} data Data that is posted with the resource. - * @param {Object} [options] Object with the following properties: - * @param {Object} [options.data] Data that is posted with the resource. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} data Data that is posted with the resource. + * @param {object} [options] Object with the following properties: + * @param {object} [options.data] Data that is posted with the resource. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1753,19 +1753,19 @@ Resource.prototype.post = function (data, options) { /** * Creates a Resource from a URL and calls post() on it. * - * @param {Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} options.data Data that is posted with the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} options.data Data that is posted with the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.post = function (options) { const resource = new Resource(options); @@ -1782,12 +1782,12 @@ Resource.post = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} data Data that is posted with the resource. - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} data Data that is posted with the resource. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1814,19 +1814,19 @@ Resource.prototype.put = function (data, options) { /** * Creates a Resource from a URL and calls put() on it. * - * @param {Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} options.data Data that is posted with the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} options.data Data that is posted with the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.put = function (options) { const resource = new Resource(options); @@ -1843,12 +1843,12 @@ Resource.put = function (options) { * using XMLHttpRequest, which means that in order to make requests to another origin, * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. * - * @param {Object} data Data that is posted with the resource. - * @param {Object} [options] Object with the following properties: - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {Object} [options.headers] Additional HTTP headers to send with the request, if any. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {object} data Data that is posted with the resource. + * @param {object} [options] Object with the following properties: + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {object} [options.headers] Additional HTTP headers to send with the request, if any. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * * @example @@ -1875,19 +1875,19 @@ Resource.prototype.patch = function (data, options) { /** * Creates a Resource from a URL and calls patch() on it. * - * @param {Object} options A url or an object with the following properties - * @param {String} options.url The url of the resource. - * @param {Object} options.data Data that is posted with the resource. - * @param {Object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. - * @param {Object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). - * @param {Object} [options.headers={}] Additional HTTP headers that will be sent. + * @param {object} options A url or an object with the following properties + * @param {string} options.url The url of the resource. + * @param {object} options.data Data that is posted with the resource. + * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. + * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). + * @param {object} [options.headers={}] Additional HTTP headers that will be sent. * @param {Proxy} [options.proxy] A proxy to be used when loading the resource. * @param {Resource.RetryCallback} [options.retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. - * @param {Number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. + * @param {number} [options.retryAttempts=0] The number of times the retryCallback should be called before giving up. * @param {Request} [options.request] A Request object that will be used. Intended for internal use only. - * @param {String} [options.responseType] The type of response. This controls the type of item returned. - * @param {String} [options.overrideMimeType] Overrides the MIME type returned by the server. - * @returns {Promise.<*>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {string} [options.responseType] The type of response. This controls the type of item returned. + * @param {string} [options.overrideMimeType] Overrides the MIME type returned by the server. + * @returns {Promise<any>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. */ Resource.patch = function (options) { const resource = new Resource(options); @@ -2302,6 +2302,6 @@ Resource.DEFAULT = Object.freeze( * * @param {Resource} [resource] The resource that failed to load. * @param {Error} [error] The error that occurred during the loading of the resource. - * @returns {Boolean|Promise<Boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. + * @returns {boolean|Promise<boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. */ export default Resource; diff --git a/packages/engine/Source/Core/RuntimeError.js b/packages/engine/Source/Core/RuntimeError.js index 3a8f2a557dd..8bbd56d74ef 100644 --- a/packages/engine/Source/Core/RuntimeError.js +++ b/packages/engine/Source/Core/RuntimeError.js @@ -13,21 +13,21 @@ import defined from "./defined.js"; * @constructor * @extends Error * - * @param {String} [message] The error message for this exception. + * @param {string} [message] The error message for this exception. * * @see DeveloperError */ function RuntimeError(message) { /** * 'RuntimeError' indicating that this exception was thrown due to a runtime error. - * @type {String} + * @type {string} * @readonly */ this.name = "RuntimeError"; /** * The explanation for why this exception was thrown. - * @type {String} + * @type {string} * @readonly */ this.message = message; @@ -42,7 +42,7 @@ function RuntimeError(message) { /** * The stack trace of this exception, if available. - * @type {String} + * @type {string} * @readonly */ this.stack = stack; diff --git a/packages/engine/Source/Core/S2Cell.js b/packages/engine/Source/Core/S2Cell.js index 495c97c86b8..67a05266fce 100644 --- a/packages/engine/Source/Core/S2Cell.js +++ b/packages/engine/Source/Core/S2Cell.js @@ -154,7 +154,7 @@ const S2_POSITION_TO_ORIENTATION_MASK = [ * @alias S2Cell * @constructor * - * @param {BigInt} [cellId] The 64-bit S2CellId. + * @param {bigint} [cellId] The 64-bit S2CellId. * @private */ function S2Cell(cellId) { @@ -177,7 +177,7 @@ function S2Cell(cellId) { /** * Creates a new S2Cell from a token. A token is a hexadecimal representation of the 64-bit S2CellId. * - * @param {String} token The token for the S2 Cell. + * @param {string} token The token for the S2 Cell. * @returns {S2Cell} Returns a new S2Cell. * @private */ @@ -195,8 +195,8 @@ S2Cell.fromToken = function (token) { /** * Validates an S2 cell ID. * - * @param {BigInt} [cellId] The S2CellId. - * @returns {Boolean} Returns true if the cell ID is valid, returns false otherwise. + * @param {bigint} [cellId] The S2CellId. + * @returns {boolean} Returns true if the cell ID is valid, returns false otherwise. * @private */ S2Cell.isValidId = function (cellId) { @@ -229,8 +229,8 @@ S2Cell.isValidId = function (cellId) { /** * Validates an S2 cell token. * - * @param {String} [token] The hexadecimal representation of an S2CellId. - * @returns {Boolean} Returns true if the token is valid, returns false otherwise. + * @param {string} [token] The hexadecimal representation of an S2CellId. + * @returns {boolean} Returns true if the token is valid, returns false otherwise. * @private */ S2Cell.isValidToken = function (token) { @@ -248,8 +248,8 @@ S2Cell.isValidToken = function (token) { /** * Converts an S2 cell token to a 64-bit S2 cell ID. * - * @param {String} [token] The hexadecimal representation of an S2CellId. Expected to be a valid S2 token. - * @returns {BigInt} Returns the S2 cell ID. + * @param {string} [token] The hexadecimal representation of an S2CellId. Expected to be a valid S2 token. + * @returns {bigint} Returns the S2 cell ID. * @private */ S2Cell.getIdFromToken = function (token) { @@ -263,7 +263,7 @@ S2Cell.getIdFromToken = function (token) { /** * Converts a 64-bit S2 cell ID to an S2 cell token. * - * @param {BigInt} [cellId] The S2 cell ID. + * @param {bigint} [cellId] The S2 cell ID. * @returns {string} Returns hexadecimal representation of an S2CellId. * @private */ @@ -284,7 +284,7 @@ S2Cell.getTokenFromId = function (cellId) { /** * Gets the level of the cell from the cell ID. * - * @param {BigInt} [cellId] The S2 cell ID. + * @param {bigint} [cellId] The S2 cell ID. * @returns {number} Returns the level of the cell. * @private */ @@ -314,7 +314,7 @@ S2Cell.getLevel = function (cellId) { /** * Gets the child cell of the cell at the given index. * - * @param {Number} index An integer index of the child. + * @param {number} index An integer index of the child. * @returns {S2Cell} The child of the S2Cell. * @private */ @@ -398,7 +398,7 @@ S2Cell.prototype.getCenter = function (ellipsoid) { /** * Get vertex of the S2 cell. Vertices are indexed in CCW order. * - * @param {Number} index An integer index of the vertex. Must be in the range [0-3]. + * @param {number} index An integer index of the vertex. Must be in the range [0-3]. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. * @returns {Cartesian3} The position of the vertex of the S2 cell. * @private @@ -427,9 +427,9 @@ S2Cell.prototype.getVertex = function (index, ellipsoid) { /** * Creates an S2Cell from its face, position along the Hilbert curve for a given level. * - * @param {Number} face The root face of S2 this cell is on. Must be in the range [0-5]. - * @param {BigInt} position The position along the Hilbert curve. Must be in the range [0-4**level). - * @param {Number} level The level of the S2 curve. Must be in the range [0-30]. + * @param {number} face The root face of S2 this cell is on. Must be in the range [0-5]. + * @param {bigint} position The position along the Hilbert curve. Must be in the range [0-4**level). + * @param {number} level The level of the S2 curve. Must be in the range [0-30]. * @returns {S2Cell} A new S2Cell from the given parameters. * @private */ diff --git a/packages/engine/Source/Core/ScreenSpaceEventHandler.js b/packages/engine/Source/Core/ScreenSpaceEventHandler.js index bac2b72e2ad..0c2fb86c607 100644 --- a/packages/engine/Source/Core/ScreenSpaceEventHandler.js +++ b/packages/engine/Source/Core/ScreenSpaceEventHandler.js @@ -893,7 +893,7 @@ function handlePointerMove(screenSpaceEventHandler, event) { } /** - * @typedef {Object} ScreenSpaceEventHandler.PositionedEvent + * @typedef {object} ScreenSpaceEventHandler.PositionedEvent * * An Event that occurs at a single position on screen. * @@ -909,7 +909,7 @@ function handlePointerMove(screenSpaceEventHandler, event) { */ /** - * @typedef {Object} ScreenSpaceEventHandler.MotionEvent + * @typedef {object} ScreenSpaceEventHandler.MotionEvent * * An Event that starts at one position and ends at another. * @@ -926,7 +926,7 @@ function handlePointerMove(screenSpaceEventHandler, event) { */ /** - * @typedef {Object} ScreenSpaceEventHandler.TwoPointEvent + * @typedef {object} ScreenSpaceEventHandler.TwoPointEvent * * An Event that occurs at a two positions on screen. * @@ -943,7 +943,7 @@ function handlePointerMove(screenSpaceEventHandler, event) { */ /** - * @typedef {Object} ScreenSpaceEventHandler.TwoPointMotionEvent + * @typedef {object} ScreenSpaceEventHandler.TwoPointMotionEvent * * An Event that starts at a two positions on screen and moves to two other positions. * @@ -1093,7 +1093,7 @@ ScreenSpaceEventHandler.prototype.removeInputAction = function ( * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ScreenSpaceEventHandler#destroy */ @@ -1125,7 +1125,7 @@ ScreenSpaceEventHandler.prototype.destroy = function () { /** * The amount of time, in milliseconds, that mouse events will be disabled after * receiving any touch events, such that any emulated mouse events will be ignored. - * @type {Number} + * @type {number} * @default 800 */ ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds = 800; @@ -1133,7 +1133,7 @@ ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds = 800; /** * The amount of time, in milliseconds, before a touch on the screen becomes a * touch and hold. - * @type {Number} + * @type {number} * @default 1500 */ ScreenSpaceEventHandler.touchHoldDelayMilliseconds = 1500; diff --git a/packages/engine/Source/Core/ScreenSpaceEventType.js b/packages/engine/Source/Core/ScreenSpaceEventType.js index ca9af078e34..cb5f633f39b 100644 --- a/packages/engine/Source/Core/ScreenSpaceEventType.js +++ b/packages/engine/Source/Core/ScreenSpaceEventType.js @@ -1,13 +1,13 @@ /** * This enumerated type is for classifying mouse events: down, up, click, double click, move and move while a button is held down. * - * @enum {Number} + * @enum {number} */ const ScreenSpaceEventType = { /** * Represents a mouse left button down event. * - * @type {Number} + * @type {number} * @constant */ LEFT_DOWN: 0, @@ -15,7 +15,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse left button up event. * - * @type {Number} + * @type {number} * @constant */ LEFT_UP: 1, @@ -23,7 +23,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse left click event. * - * @type {Number} + * @type {number} * @constant */ LEFT_CLICK: 2, @@ -31,7 +31,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse left double click event. * - * @type {Number} + * @type {number} * @constant */ LEFT_DOUBLE_CLICK: 3, @@ -39,7 +39,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse left button down event. * - * @type {Number} + * @type {number} * @constant */ RIGHT_DOWN: 5, @@ -47,7 +47,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse right button up event. * - * @type {Number} + * @type {number} * @constant */ RIGHT_UP: 6, @@ -55,7 +55,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse right click event. * - * @type {Number} + * @type {number} * @constant */ RIGHT_CLICK: 7, @@ -63,7 +63,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse middle button down event. * - * @type {Number} + * @type {number} * @constant */ MIDDLE_DOWN: 10, @@ -71,7 +71,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse middle button up event. * - * @type {Number} + * @type {number} * @constant */ MIDDLE_UP: 11, @@ -79,7 +79,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse middle click event. * - * @type {Number} + * @type {number} * @constant */ MIDDLE_CLICK: 12, @@ -87,7 +87,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse move event. * - * @type {Number} + * @type {number} * @constant */ MOUSE_MOVE: 15, @@ -95,7 +95,7 @@ const ScreenSpaceEventType = { /** * Represents a mouse wheel event. * - * @type {Number} + * @type {number} * @constant */ WHEEL: 16, @@ -103,7 +103,7 @@ const ScreenSpaceEventType = { /** * Represents the start of a two-finger event on a touch surface. * - * @type {Number} + * @type {number} * @constant */ PINCH_START: 17, @@ -111,7 +111,7 @@ const ScreenSpaceEventType = { /** * Represents the end of a two-finger event on a touch surface. * - * @type {Number} + * @type {number} * @constant */ PINCH_END: 18, @@ -119,7 +119,7 @@ const ScreenSpaceEventType = { /** * Represents a change of a two-finger event on a touch surface. * - * @type {Number} + * @type {number} * @constant */ PINCH_MOVE: 19, diff --git a/packages/engine/Source/Core/ShowGeometryInstanceAttribute.js b/packages/engine/Source/Core/ShowGeometryInstanceAttribute.js index 18e224151e4..ddef78ca7af 100644 --- a/packages/engine/Source/Core/ShowGeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/ShowGeometryInstanceAttribute.js @@ -9,7 +9,7 @@ import DeveloperError from "./DeveloperError.js"; * @alias ShowGeometryInstanceAttribute * @constructor * - * @param {Boolean} [show=true] Determines if the geometry instance will be shown. + * @param {boolean} [show=true] Determines if the geometry instance will be shown. * * * @example @@ -66,7 +66,7 @@ Object.defineProperties(ShowGeometryInstanceAttribute.prototype, { * * @memberof ShowGeometryInstanceAttribute.prototype * - * @type {Number} + * @type {number} * @readonly * * @default 1 @@ -84,7 +84,7 @@ Object.defineProperties(ShowGeometryInstanceAttribute.prototype, { * * @memberof ShowGeometryInstanceAttribute.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -99,7 +99,7 @@ Object.defineProperties(ShowGeometryInstanceAttribute.prototype, { /** * Converts a boolean show to a typed array that can be used to assign a show attribute. * - * @param {Boolean} show The show value. + * @param {boolean} show The show value. * @param {Uint8Array} [result] The array to store the result in, if undefined a new instance will be created. * @returns {Uint8Array} The modified result parameter or a new instance if result was undefined. * diff --git a/packages/engine/Source/Core/SimplePolylineGeometry.js b/packages/engine/Source/Core/SimplePolylineGeometry.js index de72f8b0b60..cabcb2312d4 100644 --- a/packages/engine/Source/Core/SimplePolylineGeometry.js +++ b/packages/engine/Source/Core/SimplePolylineGeometry.js @@ -62,12 +62,12 @@ function interpolateColors(p0, p1, color0, color1, minDistance, array, offset) { * @alias SimplePolylineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of {@link Cartesian3} defining the positions in the polyline as a line strip. * @param {Color[]} [options.colors] An Array of {@link Color} defining the per vertex or per segment colors. - * @param {Boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. + * @param {boolean} [options.colorsPerVertex=false] A boolean that determines whether the colors will be flat across each segment of the line or interpolated across the vertices. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polyline segments must follow. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.arcType is not ArcType.NONE. Determines the number of positions in the buffer. + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude if options.arcType is not ArcType.NONE. Determines the number of positions in the buffer. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * * @exception {DeveloperError} At least two positions are required. @@ -122,7 +122,7 @@ function SimplePolylineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + 3; } @@ -131,10 +131,10 @@ function SimplePolylineGeometry(options) { * Stores the provided instance into the provided array. * * @param {SimplePolylineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ SimplePolylineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -179,8 +179,8 @@ SimplePolylineGeometry.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {SimplePolylineGeometry} [result] The object into which to store the result. * @returns {SimplePolylineGeometry} The modified result parameter or a new SimplePolylineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/SphereGeometry.js b/packages/engine/Source/Core/SphereGeometry.js index 3e9b5ebf512..14246063e2f 100644 --- a/packages/engine/Source/Core/SphereGeometry.js +++ b/packages/engine/Source/Core/SphereGeometry.js @@ -11,10 +11,10 @@ import VertexFormat from "./VertexFormat.js"; * @alias SphereGeometry * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.radius=1.0] The radius of the sphere. - * @param {Number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. - * @param {Number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. + * @param {object} [options] Object with the following properties: + * @param {number} [options.radius=1.0] The radius of the sphere. + * @param {number} [options.stackPartitions=64] The number of times to partition the ellipsoid into stacks. + * @param {number} [options.slicePartitions=64] The number of times to partition the ellipsoid into radial slices. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * * @exception {DeveloperError} options.slicePartitions cannot be less than three. @@ -45,7 +45,7 @@ function SphereGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ SphereGeometry.packedLength = EllipsoidGeometry.packedLength; @@ -53,10 +53,10 @@ SphereGeometry.packedLength = EllipsoidGeometry.packedLength; * Stores the provided instance into the provided array. * * @param {SphereGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ SphereGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -78,8 +78,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {SphereGeometry} [result] The object into which to store the result. * @returns {SphereGeometry} The modified result parameter or a new SphereGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/SphereOutlineGeometry.js b/packages/engine/Source/Core/SphereOutlineGeometry.js index 7a86fadf0e6..f8a182129a0 100644 --- a/packages/engine/Source/Core/SphereOutlineGeometry.js +++ b/packages/engine/Source/Core/SphereOutlineGeometry.js @@ -10,11 +10,11 @@ import EllipsoidOutlineGeometry from "./EllipsoidOutlineGeometry.js"; * @alias SphereOutlineGeometry * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.radius=1.0] The radius of the sphere. - * @param {Number} [options.stackPartitions=10] The count of stacks for the sphere (1 greater than the number of parallel lines). - * @param {Number} [options.slicePartitions=8] The count of slices for the sphere (Equal to the number of radial lines). - * @param {Number} [options.subdivisions=200] The number of points per line, determining the granularity of the curvature . + * @param {object} [options] Object with the following properties: + * @param {number} [options.radius=1.0] The radius of the sphere. + * @param {number} [options.stackPartitions=10] The count of stacks for the sphere (1 greater than the number of parallel lines). + * @param {number} [options.slicePartitions=8] The count of slices for the sphere (Equal to the number of radial lines). + * @param {number} [options.subdivisions=200] The number of points per line, determining the granularity of the curvature . * * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one. * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero. @@ -44,7 +44,7 @@ function SphereOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ SphereOutlineGeometry.packedLength = EllipsoidOutlineGeometry.packedLength; @@ -52,10 +52,10 @@ SphereOutlineGeometry.packedLength = EllipsoidOutlineGeometry.packedLength; * Stores the provided instance into the provided array. * * @param {SphereOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ SphereOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -81,8 +81,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {SphereOutlineGeometry} [result] The object into which to store the result. * @returns {SphereOutlineGeometry} The modified result parameter or a new SphereOutlineGeometry instance if one was not provided. */ diff --git a/packages/engine/Source/Core/Spherical.js b/packages/engine/Source/Core/Spherical.js index 67c10b544bc..57dca19407f 100644 --- a/packages/engine/Source/Core/Spherical.js +++ b/packages/engine/Source/Core/Spherical.js @@ -8,26 +8,26 @@ import defined from "./defined.js"; * @alias Spherical * @constructor * - * @param {Number} [clock=0.0] The angular coordinate lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. - * @param {Number} [cone=0.0] The angular coordinate measured from the positive z-axis and toward the negative z-axis. - * @param {Number} [magnitude=1.0] The linear coordinate measured from the origin. + * @param {number} [clock=0.0] The angular coordinate lying in the xy-plane measured from the positive x-axis and toward the positive y-axis. + * @param {number} [cone=0.0] The angular coordinate measured from the positive z-axis and toward the negative z-axis. + * @param {number} [magnitude=1.0] The linear coordinate measured from the origin. */ function Spherical(clock, cone, magnitude) { /** * The clock component. - * @type {Number} + * @type {number} * @default 0.0 */ this.clock = defaultValue(clock, 0.0); /** * The cone component. - * @type {Number} + * @type {number} * @default 0.0 */ this.cone = defaultValue(cone, 0.0); /** * The magnitude component. - * @type {Number} + * @type {number} * @default 1.0 */ this.magnitude = defaultValue(magnitude, 1.0); @@ -109,7 +109,7 @@ Spherical.normalize = function (spherical, result) { * * @param {Spherical} left The first Spherical to be compared. * @param {Spherical} right The second Spherical to be compared. - * @returns {Boolean} true if the first spherical is equal to the second spherical, false otherwise. + * @returns {boolean} true if the first spherical is equal to the second spherical, false otherwise. */ Spherical.equals = function (left, right) { return ( @@ -127,8 +127,8 @@ Spherical.equals = function (left, right) { * * @param {Spherical} left The first Spherical to be compared. * @param {Spherical} right The second Spherical to be compared. - * @param {Number} [epsilon=0.0] The epsilon to compare against. - * @returns {Boolean} true if the first spherical is within the provided epsilon of the second spherical, false otherwise. + * @param {number} [epsilon=0.0] The epsilon to compare against. + * @returns {boolean} true if the first spherical is within the provided epsilon of the second spherical, false otherwise. */ Spherical.equalsEpsilon = function (left, right, epsilon) { epsilon = defaultValue(epsilon, 0.0); @@ -146,7 +146,7 @@ Spherical.equalsEpsilon = function (left, right, epsilon) { * Returns true if this spherical is equal to the provided spherical, false otherwise. * * @param {Spherical} other The Spherical to be compared. - * @returns {Boolean} true if this spherical is equal to the provided spherical, false otherwise. + * @returns {boolean} true if this spherical is equal to the provided spherical, false otherwise. */ Spherical.prototype.equals = function (other) { return Spherical.equals(this, other); @@ -166,8 +166,8 @@ Spherical.prototype.clone = function (result) { * Returns true if this spherical is within the provided epsilon of the provided spherical, false otherwise. * * @param {Spherical} other The Spherical to be compared. - * @param {Number} epsilon The epsilon to compare against. - * @returns {Boolean} true if this spherical is within the provided epsilon of the provided spherical, false otherwise. + * @param {number} epsilon The epsilon to compare against. + * @returns {boolean} true if this spherical is within the provided epsilon of the provided spherical, false otherwise. */ Spherical.prototype.equalsEpsilon = function (other, epsilon) { return Spherical.equalsEpsilon(this, other, epsilon); @@ -176,7 +176,7 @@ Spherical.prototype.equalsEpsilon = function (other, epsilon) { /** * Returns a string representing this instance in the format (clock, cone, magnitude). * - * @returns {String} A string representing this instance. + * @returns {string} A string representing this instance. */ Spherical.prototype.toString = function () { return `(${this.clock}, ${this.cone}, ${this.magnitude})`; diff --git a/packages/engine/Source/Core/Spline.js b/packages/engine/Source/Core/Spline.js index 9c28766f10a..036c0af77d6 100644 --- a/packages/engine/Source/Core/Spline.js +++ b/packages/engine/Source/Core/Spline.js @@ -21,7 +21,7 @@ import Quaternion from "./Quaternion.js"; function Spline() { /** * An array of times for the control points. - * @type {Number[]} + * @type {number[]} * @default undefined */ this.times = undefined; @@ -40,7 +40,7 @@ function Spline() { * Gets the type of the point. This helps a spline determine how to interpolate * and return its values. * - * @param {Number|Cartesian3|Quaternion} point + * @param {number|Cartesian3|Quaternion} point * @returns {*} The type of the point. * * @exception {DeveloperError} value must be a Cartesian3, Quaternion, or Number. @@ -69,9 +69,9 @@ Spline.getPointType = function (point) { * Evaluates the curve at a given time. * @function * - * @param {Number} time The time at which to evaluate the curve. - * @param {Cartesian3|Quaternion|Number[]} [result] The object onto which to store the result. - * @returns {Cartesian3|Quaternion|Number[]} The modified result parameter or a new instance of the point on the curve at the given time. + * @param {number} time The time at which to evaluate the curve. + * @param {Cartesian3|Quaternion|number[]} [result] The object onto which to store the result. + * @returns {Cartesian3|Quaternion|number[]} The modified result parameter or a new instance of the point on the curve at the given time. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -83,9 +83,9 @@ Spline.prototype.evaluate = DeveloperError.throwInstantiationError; * Finds an index <code>i</code> in <code>times</code> such that the parameter * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * - * @param {Number} time The time. - * @param {Number} startIndex The index from which to start the search. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @param {number} startIndex The index from which to start the search. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -146,8 +146,8 @@ Spline.prototype.findTimeInterval = function (time, startIndex) { * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around the animation period. + * @param {number} time The time. + * @return {number} The time, wrapped around the animation period. */ Spline.prototype.wrapTime = function (time) { //>>includeStart('debug', pragmas.debug); @@ -174,8 +174,8 @@ Spline.prototype.wrapTime = function (time) { * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ Spline.prototype.clampTime = function (time) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Core/SteppedSpline.js b/packages/engine/Source/Core/SteppedSpline.js index f861184be86..4f3242a2f0d 100644 --- a/packages/engine/Source/Core/SteppedSpline.js +++ b/packages/engine/Source/Core/SteppedSpline.js @@ -9,9 +9,9 @@ import Spline from "./Spline.js"; * @alias SteppedSpline * @constructor * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. The values are in no way connected to the clock time. They are the parameterization for the curve. - * @param {Number[]|Cartesian3[]|Quaternion[]} options.points The array of control points. + * @param {object} options Object with the following properties: + * @param {number[]} options.times An array of strictly increasing, unit-less, floating-point times at each point. The values are in no way connected to the clock time. They are the parameterization for the curve. + * @param {number[]|Cartesian3[]|Quaternion[]} options.points The array of control points. * * @exception {DeveloperError} points.length must be greater than or equal to 2. * @exception {DeveloperError} times.length must be equal to points.length. @@ -71,7 +71,7 @@ Object.defineProperties(SteppedSpline.prototype, { * * @memberof SteppedSpline.prototype * - * @type {Number[]} + * @type {number[]} * @readonly */ times: { @@ -85,7 +85,7 @@ Object.defineProperties(SteppedSpline.prototype, { * * @memberof SteppedSpline.prototype * - * @type {Number[]|Cartesian3[]|Quaternion[]} + * @type {number[]|Cartesian3[]|Quaternion[]} * @readonly */ points: { @@ -100,9 +100,9 @@ Object.defineProperties(SteppedSpline.prototype, { * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>. * @function * - * @param {Number} time The time. - * @param {Number} startIndex The index from which to start the search. - * @returns {Number} The index for the element at the start of the interval. + * @param {number} time The time. + * @param {number} startIndex The index from which to start the search. + * @returns {number} The index for the element at the start of the interval. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element @@ -114,8 +114,8 @@ SteppedSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval; * Wraps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, wrapped around to the updated animation. + * @param {number} time The time. + * @return {number} The time, wrapped around to the updated animation. */ SteppedSpline.prototype.wrapTime = Spline.prototype.wrapTime; @@ -123,17 +123,17 @@ SteppedSpline.prototype.wrapTime = Spline.prototype.wrapTime; * Clamps the given time to the period covered by the spline. * @function * - * @param {Number} time The time. - * @return {Number} The time, clamped to the animation period. + * @param {number} time The time. + * @return {number} The time, clamped to the animation period. */ SteppedSpline.prototype.clampTime = Spline.prototype.clampTime; /** * Evaluates the curve at a given time. * - * @param {Number} time The time at which to evaluate the curve. + * @param {number} time The time at which to evaluate the curve. * @param {Cartesian3|Quaternion} [result] The object onto which to store the result. - * @returns {Number|Cartesian3|Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. + * @returns {number|Cartesian3|Quaternion} The modified result parameter or a new instance of the point on the curve at the given time. * * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code> * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element diff --git a/packages/engine/Source/Core/TaskProcessor.js b/packages/engine/Source/Core/TaskProcessor.js index 0414c34fa46..699aaa13653 100644 --- a/packages/engine/Source/Core/TaskProcessor.js +++ b/packages/engine/Source/Core/TaskProcessor.js @@ -195,8 +195,8 @@ function getWebAssemblyLoaderConfig(processor, wasmOptions) { * @alias TaskProcessor * @constructor * - * @param {String} workerPath The Url to the worker. This can either be an absolute path or relative to the Cesium Workers folder. - * @param {Number} [maximumActiveTasks=Number.POSITIVE_INFINITY] The maximum number of active tasks. Once exceeded, + * @param {string} workerPath The Url to the worker. This can either be an absolute path or relative to the Cesium Workers folder. + * @param {number} [maximumActiveTasks=Number.POSITIVE_INFINITY] The maximum number of active tasks. Once exceeded, * scheduleTask will not queue any more tasks, allowing * work to be rescheduled in future frames. */ @@ -223,10 +223,10 @@ const emptyTransferableObjectArray = []; * Otherwise, returns a promise that will resolve to the result posted back by the worker when * finished. * - * @param {Object} parameters Any input data that will be posted to the worker. + * @param {object} parameters Any input data that will be posted to the worker. * @param {Object[]} [transferableObjects] An array of objects contained in parameters that should be * transferred to the worker instead of copied. - * @returns {Promise.<Object>|undefined} Either a promise that will resolve to the result when available, or undefined + * @returns {Promise<object>|undefined} Either a promise that will resolve to the result when available, or undefined * if there are too many active tasks, * * @example @@ -289,11 +289,11 @@ TaskProcessor.prototype.scheduleTask = function ( * and compiling a web assembly module asychronously, as well as an optional * fallback JavaScript module to use if Web Assembly is not supported. * - * @param {Object} [webAssemblyOptions] An object with the following properties: - * @param {String} [webAssemblyOptions.modulePath] The path of the web assembly JavaScript wrapper module. - * @param {String} [webAssemblyOptions.wasmBinaryFile] The path of the web assembly binary file. - * @param {String} [webAssemblyOptions.fallbackModulePath] The path of the fallback JavaScript module to use if web assembly is not supported. - * @returns {Promise.<Object>} A promise that resolves to the result when the web worker has loaded and compiled the web assembly module and is ready to process tasks. + * @param {object} [webAssemblyOptions] An object with the following properties: + * @param {string} [webAssemblyOptions.modulePath] The path of the web assembly JavaScript wrapper module. + * @param {string} [webAssemblyOptions.wasmBinaryFile] The path of the web assembly binary file. + * @param {string} [webAssemblyOptions.fallbackModulePath] The path of the fallback JavaScript module to use if web assembly is not supported. + * @returns {Promise<object>} A promise that resolves to the result when the web worker has loaded and compiled the web assembly module and is ready to process tasks. */ TaskProcessor.prototype.initWebAssemblyModule = function (webAssemblyOptions) { if (!defined(this._worker)) { @@ -339,7 +339,7 @@ TaskProcessor.prototype.initWebAssemblyModule = function (webAssemblyOptions) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see TaskProcessor#destroy */ diff --git a/packages/engine/Source/Core/TerrainData.js b/packages/engine/Source/Core/TerrainData.js index 13e8430e03e..029c30687e1 100644 --- a/packages/engine/Source/Core/TerrainData.js +++ b/packages/engine/Source/Core/TerrainData.js @@ -41,9 +41,9 @@ Object.defineProperties(TerrainData.prototype, { * @function * * @param {Rectangle} rectangle The rectangle covered by this terrain data. - * @param {Number} longitude The longitude in radians. - * @param {Number} latitude The latitude in radians. - * @returns {Number} The terrain height at the specified position. If the position + * @param {number} longitude The longitude in radians. + * @param {number} latitude The latitude in radians. + * @returns {number} The terrain height at the specified position. If the position * is outside the rectangle, this method will extrapolate the height, which is likely to be wildly * incorrect for positions far outside the rectangle. */ @@ -57,11 +57,11 @@ TerrainData.prototype.interpolateHeight = * given, the availability of the southeast child tile is returned. * @function * - * @param {Number} thisX The tile X coordinate of this (the parent) tile. - * @param {Number} thisY The tile Y coordinate of this (the parent) tile. - * @param {Number} childX The tile X coordinate of the child tile to check for availability. - * @param {Number} childY The tile Y coordinate of the child tile to check for availability. - * @returns {Boolean} True if the child tile is available; otherwise, false. + * @param {number} thisX The tile X coordinate of this (the parent) tile. + * @param {number} thisY The tile Y coordinate of this (the parent) tile. + * @param {number} childX The tile X coordinate of the child tile to check for availability. + * @param {number} childY The tile Y coordinate of the child tile to check for availability. + * @returns {boolean} True if the child tile is available; otherwise, false. */ TerrainData.prototype.isChildAvailable = DeveloperError.throwInstantiationError; @@ -71,15 +71,15 @@ TerrainData.prototype.isChildAvailable = DeveloperError.throwInstantiationError; * * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {TilingScheme} options.tilingScheme The tiling scheme to which this tile belongs. - * @param {Number} options.x The X coordinate of the tile for which to create the terrain data. - * @param {Number} options.y The Y coordinate of the tile for which to create the terrain data. - * @param {Number} options.level The level of the tile for which to create the terrain data. - * @param {Number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. - * @param {Number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. - * @param {Boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. - * @returns {Promise.<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many + * @param {number} options.x The X coordinate of the tile for which to create the terrain data. + * @param {number} options.y The Y coordinate of the tile for which to create the terrain data. + * @param {number} options.level The level of the tile for which to create the terrain data. + * @param {number} [options.exaggeration=1.0] The scale used to exaggerate the terrain. + * @param {number} [options.exaggerationRelativeHeight=0.0] The height relative to which terrain is exaggerated. + * @param {boolean} [options.throttle=true] If true, indicates that this operation will need to be retried if too many asynchronous mesh creations are already in progress. + * @returns {Promise<TerrainMesh>|undefined} A promise for the terrain mesh, or undefined if too many * asynchronous mesh creations are already in progress and the operation should * be retried later. */ @@ -90,13 +90,13 @@ TerrainData.prototype.createMesh = DeveloperError.throwInstantiationError; * @function * * @param {TilingScheme} tilingScheme The tiling scheme of this terrain data. - * @param {Number} thisX The X coordinate of this tile in the tiling scheme. - * @param {Number} thisY The Y coordinate of this tile in the tiling scheme. - * @param {Number} thisLevel The level of this tile in the tiling scheme. - * @param {Number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. - * @param {Number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. - * @returns {Promise.<TerrainData>|undefined} A promise for upsampled terrain data for the descendant tile, + * @param {number} thisX The X coordinate of this tile in the tiling scheme. + * @param {number} thisY The Y coordinate of this tile in the tiling scheme. + * @param {number} thisLevel The level of this tile in the tiling scheme. + * @param {number} descendantX The X coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantY The Y coordinate within the tiling scheme of the descendant tile for which we are upsampling. + * @param {number} descendantLevel The level within the tiling scheme of the descendant tile for which we are upsampling. + * @returns {Promise<TerrainData>|undefined} A promise for upsampled terrain data for the descendant tile, * or undefined if too many asynchronous upsample operations are in progress and the request has been * deferred. */ @@ -109,7 +109,7 @@ TerrainData.prototype.upsample = DeveloperError.throwInstantiationError; * returned from a call to {@link TerrainData#upsample}. * @function * - * @returns {Boolean} True if this instance was created by upsampling; otherwise, false. + * @returns {boolean} True if this instance was created by upsampling; otherwise, false. */ TerrainData.prototype.wasCreatedByUpsampling = DeveloperError.throwInstantiationError; @@ -117,7 +117,7 @@ TerrainData.prototype.wasCreatedByUpsampling = /** * The maximum number of asynchronous tasks used for terrain processing. * - * @type {Number} + * @type {number} * @private */ TerrainData.maximumAsynchronousTasks = 5; diff --git a/packages/engine/Source/Core/TerrainEncoding.js b/packages/engine/Source/Core/TerrainEncoding.js index a6faa36c07b..f6a6702babd 100644 --- a/packages/engine/Source/Core/TerrainEncoding.js +++ b/packages/engine/Source/Core/TerrainEncoding.js @@ -26,14 +26,14 @@ const SHIFT_LEFT_12 = Math.pow(2.0, 12.0); * * @param {Cartesian3} center The center point of the vertices. * @param {AxisAlignedBoundingBox} axisAlignedBoundingBox The bounds of the tile in the east-north-up coordinates at the tiles center. - * @param {Number} minimumHeight The minimum height. - * @param {Number} maximumHeight The maximum height. + * @param {number} minimumHeight The minimum height. + * @param {number} maximumHeight The maximum height. * @param {Matrix4} fromENU The east-north-up to fixed frame matrix at the center of the terrain mesh. - * @param {Boolean} hasVertexNormals If the mesh has vertex normals. - * @param {Boolean} [hasWebMercatorT=false] true if the terrain data includes a Web Mercator texture coordinate; otherwise, false. - * @param {Boolean} [hasGeodeticSurfaceNormals=false] true if the terrain data includes geodetic surface normals; otherwise, false. - * @param {Number} [exaggeration=1.0] A scalar used to exaggerate terrain. - * @param {Number} [exaggerationRelativeHeight=0.0] The relative height from which terrain is exaggerated. + * @param {boolean} hasVertexNormals If the mesh has vertex normals. + * @param {boolean} [hasWebMercatorT=false] true if the terrain data includes a Web Mercator texture coordinate; otherwise, false. + * @param {boolean} [hasGeodeticSurfaceNormals=false] true if the terrain data includes geodetic surface normals; otherwise, false. + * @param {number} [exaggeration=1.0] A scalar used to exaggerate terrain. + * @param {number} [exaggerationRelativeHeight=0.0] The relative height from which terrain is exaggerated. * * @private */ @@ -112,13 +112,13 @@ function TerrainEncoding( /** * The minimum height of the tile including the skirts. - * @type {Number} + * @type {number} */ this.minimumHeight = minimumHeight; /** * The maximum height of the tile. - * @type {Number} + * @type {number} */ this.maximumHeight = maximumHeight; @@ -149,19 +149,19 @@ function TerrainEncoding( /** * The terrain mesh contains normals. - * @type {Boolean} + * @type {boolean} */ this.hasVertexNormals = hasVertexNormals; /** * The terrain mesh contains a vertical texture coordinate following the Web Mercator projection. - * @type {Boolean} + * @type {boolean} */ this.hasWebMercatorT = defaultValue(hasWebMercatorT, false); /** * The terrain mesh contains geodetic surface normals, used for terrain exaggeration. - * @type {Boolean} + * @type {boolean} */ this.hasGeodeticSurfaceNormals = defaultValue( hasGeodeticSurfaceNormals, @@ -170,7 +170,7 @@ function TerrainEncoding( /** * A scalar used to exaggerate terrain. - * @type {Number} + * @type {number} */ this.exaggeration = defaultValue(exaggeration, 1.0); @@ -184,7 +184,7 @@ function TerrainEncoding( /** * The number of components in each vertex. This value can differ with different quantizations. - * @type {Number} + * @type {number} */ this.stride = 0; diff --git a/packages/engine/Source/Core/TerrainExaggeration.js b/packages/engine/Source/Core/TerrainExaggeration.js index 7773584c741..fa5e68377f8 100644 --- a/packages/engine/Source/Core/TerrainExaggeration.js +++ b/packages/engine/Source/Core/TerrainExaggeration.js @@ -8,9 +8,9 @@ const TerrainExaggeration = {}; /** * Scales a height relative to an offset. * - * @param {Number} height The height. - * @param {Number} scale A scalar used to exaggerate the terrain. If the value is 1.0 there will be no effect. - * @param {Number} relativeHeight The height relative to which terrain is exaggerated. If the value is 0.0 terrain will be exaggerated relative to the ellipsoid surface. + * @param {number} height The height. + * @param {number} scale A scalar used to exaggerate the terrain. If the value is 1.0 there will be no effect. + * @param {number} relativeHeight The height relative to which terrain is exaggerated. If the value is 0.0 terrain will be exaggerated relative to the ellipsoid surface. */ TerrainExaggeration.getHeight = function (height, scale, relativeHeight) { return (height - relativeHeight) * scale + relativeHeight; diff --git a/packages/engine/Source/Core/TerrainMesh.js b/packages/engine/Source/Core/TerrainMesh.js index 6ea2c33e118..60a939b5404 100644 --- a/packages/engine/Source/Core/TerrainMesh.js +++ b/packages/engine/Source/Core/TerrainMesh.js @@ -13,21 +13,21 @@ import defaultValue from "./defaultValue.js"; * the Cartesian position of the vertex, H is the height above the ellipsoid, and * U and V are the texture coordinates. * @param {Uint8Array|Uint16Array|Uint32Array} indices The indices describing how the vertices are connected to form triangles. - * @param {Number} indexCountWithoutSkirts The index count of the mesh not including skirts. - * @param {Number} vertexCountWithoutSkirts The vertex count of the mesh not including skirts. - * @param {Number} minimumHeight The lowest height in the tile, in meters above the ellipsoid. - * @param {Number} maximumHeight The highest height in the tile, in meters above the ellipsoid. + * @param {number} indexCountWithoutSkirts The index count of the mesh not including skirts. + * @param {number} vertexCountWithoutSkirts The vertex count of the mesh not including skirts. + * @param {number} minimumHeight The lowest height in the tile, in meters above the ellipsoid. + * @param {number} maximumHeight The highest height in the tile, in meters above the ellipsoid. * @param {BoundingSphere} boundingSphere3D A bounding sphere that completely contains the tile. * @param {Cartesian3} occludeePointInScaledSpace The occludee point of the tile, represented in ellipsoid- * scaled space, and used for horizon culling. If this point is below the horizon, * the tile is considered to be entirely below the horizon. - * @param {Number} [vertexStride=6] The number of components in each vertex. + * @param {number} [vertexStride=6] The number of components in each vertex. * @param {OrientedBoundingBox} [orientedBoundingBox] A bounding box that completely contains the tile. * @param {TerrainEncoding} encoding Information used to decode the mesh. - * @param {Number[]} westIndicesSouthToNorth The indices of the vertices on the Western edge of the tile, ordered from South to North (clockwise). - * @param {Number[]} southIndicesEastToWest The indices of the vertices on the Southern edge of the tile, ordered from East to West (clockwise). - * @param {Number[]} eastIndicesNorthToSouth The indices of the vertices on the Eastern edge of the tile, ordered from North to South (clockwise). - * @param {Number[]} northIndicesWestToEast The indices of the vertices on the Northern edge of the tile, ordered from West to East (clockwise). + * @param {number[]} westIndicesSouthToNorth The indices of the vertices on the Western edge of the tile, ordered from South to North (clockwise). + * @param {number[]} southIndicesEastToWest The indices of the vertices on the Southern edge of the tile, ordered from East to West (clockwise). + * @param {number[]} eastIndicesNorthToSouth The indices of the vertices on the Eastern edge of the tile, ordered from North to South (clockwise). + * @param {number[]} northIndicesWestToEast The indices of the vertices on the Northern edge of the tile, ordered from West to East (clockwise). * * @private */ @@ -69,7 +69,7 @@ function TerrainMesh( * The number of components in each vertex. Typically this is 6 for the 6 components * [X, Y, Z, H, U, V], but if each vertex has additional data (such as a vertex normal), this value * may be higher. - * @type {Number} + * @type {number} */ this.stride = defaultValue(vertexStride, 6); @@ -81,25 +81,25 @@ function TerrainMesh( /** * The index count of the mesh not including skirts. - * @type {Number} + * @type {number} */ this.indexCountWithoutSkirts = indexCountWithoutSkirts; /** * The vertex count of the mesh not including skirts. - * @type {Number} + * @type {number} */ this.vertexCountWithoutSkirts = vertexCountWithoutSkirts; /** * The lowest height in the tile, in meters above the ellipsoid. - * @type {Number} + * @type {number} */ this.minimumHeight = minimumHeight; /** * The highest height in the tile, in meters above the ellipsoid. - * @type {Number} + * @type {number} */ this.maximumHeight = maximumHeight; @@ -131,25 +131,25 @@ function TerrainMesh( /** * The indices of the vertices on the Western edge of the tile, ordered from South to North (clockwise). - * @type {Number[]} + * @type {number[]} */ this.westIndicesSouthToNorth = westIndicesSouthToNorth; /** * The indices of the vertices on the Southern edge of the tile, ordered from East to West (clockwise). - * @type {Number[]} + * @type {number[]} */ this.southIndicesEastToWest = southIndicesEastToWest; /** * The indices of the vertices on the Eastern edge of the tile, ordered from North to South (clockwise). - * @type {Number[]} + * @type {number[]} */ this.eastIndicesNorthToSouth = eastIndicesNorthToSouth; /** * The indices of the vertices on the Northern edge of the tile, ordered from West to East (clockwise). - * @type {Number[]} + * @type {number[]} */ this.northIndicesWestToEast = northIndicesWestToEast; } diff --git a/packages/engine/Source/Core/TerrainProvider.js b/packages/engine/Source/Core/TerrainProvider.js index e7f5d035bf2..e1ad2c17069 100644 --- a/packages/engine/Source/Core/TerrainProvider.js +++ b/packages/engine/Source/Core/TerrainProvider.js @@ -59,7 +59,7 @@ Object.defineProperties(TerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof TerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -69,7 +69,7 @@ Object.defineProperties(TerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof TerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -82,7 +82,7 @@ Object.defineProperties(TerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link TerrainProvider#ready} returns true. * @memberof TerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -93,7 +93,7 @@ Object.defineProperties(TerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link TerrainProvider#ready} returns true. * @memberof TerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -122,8 +122,8 @@ const regularGridIndicesCache = []; * same list of indices. The total number of vertices must be less than or equal * to 65536. * - * @param {Number} width The number of vertices in the regular grid in the horizontal direction. - * @param {Number} height The number of vertices in the regular grid in the vertical direction. + * @param {number} width The number of vertices in the regular grid in the horizontal direction. + * @param {number} height The number of vertices in the regular grid in the vertical direction. * @returns {Uint16Array|Uint32Array} The list of indices. Uint16Array gets returned for 64KB or less and Uint32Array for 4GB or less. */ TerrainProvider.getRegularGridIndices = function (width, height) { @@ -372,7 +372,7 @@ function addSkirtIndices(edgeIndices, vertexIndex, indices, offset) { * {@link Globe.maximumScreenSpaceError} screen pixels and will probably go very slowly. * A value of 0.5 will cut the estimated level zero geometric error in half, allowing twice the * screen pixels between adjacent heightmap vertices and thus rendering more quickly. - * @type {Number} + * @type {number} */ TerrainProvider.heightmapTerrainQuality = 0.25; @@ -380,9 +380,9 @@ TerrainProvider.heightmapTerrainQuality = 0.25; * Determines an appropriate geometric error estimate when the geometry comes from a heightmap. * * @param {Ellipsoid} ellipsoid The ellipsoid to which the terrain is attached. - * @param {Number} tileImageWidth The width, in pixels, of the heightmap associated with a single tile. - * @param {Number} numberOfTilesAtLevelZero The number of tiles in the horizontal direction at tile level zero. - * @returns {Number} An estimated geometric error. + * @param {number} tileImageWidth The width, in pixels, of the heightmap associated with a single tile. + * @param {number} numberOfTilesAtLevelZero The number of tiles in the horizontal direction at tile level zero. + * @returns {number} An estimated geometric error. */ TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap = function ( ellipsoid, @@ -404,12 +404,12 @@ TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap = function ( * may optionally include a water mask and an indication of which child tiles are available. * @function * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. * - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. */ @@ -421,8 +421,8 @@ TerrainProvider.prototype.requestTileGeometry = * called before {@link TerrainProvider#ready} returns true. * @function * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ TerrainProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; @@ -431,10 +431,10 @@ TerrainProvider.prototype.getLevelMaximumGeometricError = * Determines whether data for a tile is available to be loaded. * @function * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported by the terrain provider, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported by the terrain provider, otherwise true or false. */ TerrainProvider.prototype.getTileDataAvailable = DeveloperError.throwInstantiationError; @@ -443,9 +443,9 @@ TerrainProvider.prototype.getTileDataAvailable = * Makes sure we load availability data for a tile * @function * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined|Promise<void>} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded */ TerrainProvider.prototype.loadTileDataAvailability = diff --git a/packages/engine/Source/Core/TerrainQuantization.js b/packages/engine/Source/Core/TerrainQuantization.js index 2d0dcb984cb..8e623e6ca98 100644 --- a/packages/engine/Source/Core/TerrainQuantization.js +++ b/packages/engine/Source/Core/TerrainQuantization.js @@ -1,7 +1,7 @@ /** * This enumerated type is used to determine how the vertices of the terrain mesh are compressed. * - * @enum {Number} + * @enum {number} * * @private */ @@ -9,7 +9,7 @@ const TerrainQuantization = { /** * The vertices are not compressed. * - * @type {Number} + * @type {number} * @constant */ NONE: 0, @@ -17,7 +17,7 @@ const TerrainQuantization = { /** * The vertices are compressed to 12 bits. * - * @type {Number} + * @type {number} * @constant */ BITS12: 1, diff --git a/packages/engine/Source/Core/TileAvailability.js b/packages/engine/Source/Core/TileAvailability.js index 2ff06c9c0e2..0a6a74a3eed 100644 --- a/packages/engine/Source/Core/TileAvailability.js +++ b/packages/engine/Source/Core/TileAvailability.js @@ -10,7 +10,7 @@ import Rectangle from "./Rectangle.js"; * @constructor * * @param {TilingScheme} tilingScheme The tiling scheme in which to report availability. - * @param {Number} maximumLevel The maximum tile level that is potentially available. + * @param {number} maximumLevel The maximum tile level that is potentially available. */ function TileAvailability(tilingScheme, maximumLevel) { this._tilingScheme = tilingScheme; @@ -37,11 +37,11 @@ function findNode(level, x, y, nodes) { * Marks a rectangular range of tiles in a particular level as being available. For best performance, * add your ranges in order of increasing level. * - * @param {Number} level The level. - * @param {Number} startX The X coordinate of the first available tiles at the level. - * @param {Number} startY The Y coordinate of the first available tiles at the level. - * @param {Number} endX The X coordinate of the last available tiles at the level. - * @param {Number} endY The Y coordinate of the last available tiles at the level. + * @param {number} level The level. + * @param {number} startX The X coordinate of the first available tiles at the level. + * @param {number} startY The Y coordinate of the first available tiles at the level. + * @param {number} endX The X coordinate of the last available tiles at the level. + * @param {number} endY The Y coordinate of the last available tiles at the level. */ TileAvailability.prototype.addAvailableTileRange = function ( level, @@ -93,7 +93,7 @@ TileAvailability.prototype.addAvailableTileRange = function ( * {@link TileAvailability#addAvailableTileRange}. * * @param {Cartographic} position The position for which to determine the maximum available level. The height component is ignored. - * @return {Number} The level of the most detailed tile covering the position. + * @return {number} The level of the most detailed tile covering the position. * @throws {DeveloperError} If position is outside any tile according to the tiling scheme. */ TileAvailability.prototype.computeMaximumLevelAtPosition = function (position) { @@ -127,7 +127,7 @@ const eastScratch = new Rectangle(); * {@link TileAvailability#addAvailableTileRange}. * * @param {Rectangle} rectangle The rectangle. - * @return {Number} The best available level for the entire rectangle. + * @return {number} The best available level for the entire rectangle. */ TileAvailability.prototype.computeBestAvailableLevelOverRectangle = function ( rectangle @@ -187,10 +187,10 @@ const cartographicScratch = new Cartographic(); /** * Determines if a particular tile is available. - * @param {Number} level The tile level to check. - * @param {Number} x The X coordinate of the tile to check. - * @param {Number} y The Y coordinate of the tile to check. - * @return {Boolean} True if the tile is available; otherwise, false. + * @param {number} level The tile level to check. + * @param {number} x The X coordinate of the tile to check. + * @param {number} y The Y coordinate of the tile to check. + * @return {boolean} True if the tile is available; otherwise, false. */ TileAvailability.prototype.isTileAvailable = function (level, x, y) { // Get the center of the tile and find the maximum level at that position. @@ -220,10 +220,10 @@ TileAvailability.prototype.isTileAvailable = function (level, x, y) { * <tr><td>3</td><td>8</td><td>Northeast</td></tr> * </table> * - * @param {Number} level The level of the parent tile. - * @param {Number} x The X coordinate of the parent tile. - * @param {Number} y The Y coordinate of the parent tile. - * @return {Number} The bit mask indicating child availability. + * @param {number} level The level of the parent tile. + * @param {number} x The X coordinate of the parent tile. + * @param {number} y The Y coordinate of the parent tile. + * @return {number} The bit mask indicating child availability. */ TileAvailability.prototype.computeChildMaskForTile = function (level, x, y) { const childLevel = level + 1; diff --git a/packages/engine/Source/Core/TileProviderError.js b/packages/engine/Source/Core/TileProviderError.js index cf02dd30a06..4e006ef0744 100644 --- a/packages/engine/Source/Core/TileProviderError.js +++ b/packages/engine/Source/Core/TileProviderError.js @@ -9,14 +9,14 @@ import formatError from "./formatError.js"; * @constructor * * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that experienced the error. - * @param {String} message A message describing the error. - * @param {Number} [x] The X coordinate of the tile that experienced the error, or undefined if the error + * @param {string} message A message describing the error. + * @param {number} [x] The X coordinate of the tile that experienced the error, or undefined if the error * is not specific to a particular tile. - * @param {Number} [y] The Y coordinate of the tile that experienced the error, or undefined if the error + * @param {number} [y] The Y coordinate of the tile that experienced the error, or undefined if the error * is not specific to a particular tile. - * @param {Number} [level] The level of the tile that experienced the error, or undefined if the error + * @param {number} [level] The level of the tile that experienced the error, or undefined if the error * is not specific to a particular tile. - * @param {Number} [timesRetried=0] The number of times this operation has been retried. + * @param {number} [timesRetried=0] The number of times this operation has been retried. * @param {Error} [error] The error or exception that occurred, if any. */ function TileProviderError( @@ -36,34 +36,34 @@ function TileProviderError( /** * The message describing the error. - * @type {String} + * @type {string} */ this.message = message; /** * The X coordinate of the tile that experienced the error. If the error is not specific * to a particular tile, this property will be undefined. - * @type {Number} + * @type {number} */ this.x = x; /** * The Y coordinate of the tile that experienced the error. If the error is not specific * to a particular tile, this property will be undefined. - * @type {Number} + * @type {number} */ this.y = y; /** * The level-of-detail of the tile that experienced the error. If the error is not specific * to a particular tile, this property will be undefined. - * @type {Number} + * @type {number} */ this.level = level; /** * The number of times this operation has been retried. - * @type {Number} + * @type {number} * @default 0 */ this.timesRetried = defaultValue(timesRetried, 0); @@ -72,7 +72,7 @@ function TileProviderError( * True if the failed operation should be retried; otherwise, false. The imagery or terrain provider * will set the initial value of this property before raising the event, but any listeners * can change it. The value after the last listener is invoked will be acted upon. - * @type {Boolean} + * @type {boolean} * @default false */ this.retry = false; @@ -94,12 +94,12 @@ function TileProviderError( * occurred. * @param {ImageryProvider|TerrainProvider} provider The imagery or terrain provider that encountered the error. * @param {Event} event The event to raise to inform listeners of the error. - * @param {String} message The message describing the error. - * @param {Number} x The X coordinate of the tile that experienced the error, or undefined if the + * @param {string} message The message describing the error. + * @param {number} x The X coordinate of the tile that experienced the error, or undefined if the * error is not specific to a particular tile. - * @param {Number} y The Y coordinate of the tile that experienced the error, or undefined if the + * @param {number} y The Y coordinate of the tile that experienced the error, or undefined if the * error is not specific to a particular tile. - * @param {Number} level The level-of-detail of the tile that experienced the error, or undefined if the + * @param {number} level The level-of-detail of the tile that experienced the error, or undefined if the * error is not specific to a particular tile. * @param {Error} [errorDetails] The error or exception that occurred, if any. * @returns {TileProviderError} The error instance that was passed to the event listeners and that diff --git a/packages/engine/Source/Core/TilingScheme.js b/packages/engine/Source/Core/TilingScheme.js index a76fad8adca..7429de380a9 100644 --- a/packages/engine/Source/Core/TilingScheme.js +++ b/packages/engine/Source/Core/TilingScheme.js @@ -54,8 +54,8 @@ Object.defineProperties(TilingScheme.prototype, { * Gets the total number of tiles in the X direction at a specified level-of-detail. * @function * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the X direction at the given level. */ TilingScheme.prototype.getNumberOfXTilesAtLevel = DeveloperError.throwInstantiationError; @@ -64,8 +64,8 @@ TilingScheme.prototype.getNumberOfXTilesAtLevel = * Gets the total number of tiles in the Y direction at a specified level-of-detail. * @function * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the Y direction at the given level. */ TilingScheme.prototype.getNumberOfYTilesAtLevel = DeveloperError.throwInstantiationError; @@ -89,10 +89,10 @@ TilingScheme.prototype.rectangleToNativeRectangle = * of the tiling scheme. * @function * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -104,10 +104,10 @@ TilingScheme.prototype.tileXYToNativeRectangle = * Converts tile x, y coordinates and level to a cartographic rectangle in radians. * @function * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -121,7 +121,7 @@ TilingScheme.prototype.tileXYToRectangle = * @function * * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {number} level The tile level-of-detail. Zero is the least detailed. * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates diff --git a/packages/engine/Source/Core/TimeConstants.js b/packages/engine/Source/Core/TimeConstants.js index a65133d175b..72ae3cad38d 100644 --- a/packages/engine/Source/Core/TimeConstants.js +++ b/packages/engine/Source/Core/TimeConstants.js @@ -10,63 +10,63 @@ const TimeConstants = { /** * The number of seconds in one millisecond: <code>0.001</code> - * @type {Number} + * @type {number} * @constant */ SECONDS_PER_MILLISECOND: 0.001, /** * The number of seconds in one minute: <code>60</code>. - * @type {Number} + * @type {number} * @constant */ SECONDS_PER_MINUTE: 60.0, /** * The number of minutes in one hour: <code>60</code>. - * @type {Number} + * @type {number} * @constant */ MINUTES_PER_HOUR: 60.0, /** * The number of hours in one day: <code>24</code>. - * @type {Number} + * @type {number} * @constant */ HOURS_PER_DAY: 24.0, /** * The number of seconds in one hour: <code>3600</code>. - * @type {Number} + * @type {number} * @constant */ SECONDS_PER_HOUR: 3600.0, /** * The number of minutes in one day: <code>1440</code>. - * @type {Number} + * @type {number} * @constant */ MINUTES_PER_DAY: 1440.0, /** * The number of seconds in one day, ignoring leap seconds: <code>86400</code>. - * @type {Number} + * @type {number} * @constant */ SECONDS_PER_DAY: 86400.0, /** * The number of days in one Julian century: <code>36525</code>. - * @type {Number} + * @type {number} * @constant */ DAYS_PER_JULIAN_CENTURY: 36525.0, /** * One trillionth of a second. - * @type {Number} + * @type {number} * @constant */ PICOSECOND: 0.000000001, @@ -75,7 +75,7 @@ const TimeConstants = { * The number of days to subtract from a Julian date to determine the * modified Julian date, which gives the number of days since midnight * on November 17, 1858. - * @type {Number} + * @type {number} * @constant */ MODIFIED_JULIAN_DATE_DIFFERENCE: 2400000.5, diff --git a/packages/engine/Source/Core/TimeInterval.js b/packages/engine/Source/Core/TimeInterval.js index 497483ef5db..6350ce23ca3 100644 --- a/packages/engine/Source/Core/TimeInterval.js +++ b/packages/engine/Source/Core/TimeInterval.js @@ -11,12 +11,12 @@ import JulianDate from "./JulianDate.js"; * @alias TimeInterval * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {JulianDate} [options.start=new JulianDate()] The start time of the interval. * @param {JulianDate} [options.stop=new JulianDate()] The stop time of the interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. - * @param {Object} [options.data] Arbitrary data associated with this interval. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @param {object} [options.data] Arbitrary data associated with this interval. * * @example * // Create an instance that spans August 1st, 1980 and is associated @@ -83,14 +83,14 @@ function TimeInterval(options) { /** * Gets or sets whether or not the start time is included in this interval. - * @type {Boolean} + * @type {boolean} * @default true */ this.isStartIncluded = defaultValue(options.isStartIncluded, true); /** * Gets or sets whether or not the stop time is included in this interval. - * @type {Boolean} + * @type {boolean} * @default true */ this.isStopIncluded = defaultValue(options.isStopIncluded, true); @@ -100,7 +100,7 @@ Object.defineProperties(TimeInterval.prototype, { /** * Gets whether or not this interval is empty. * @memberof TimeInterval.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isEmpty: { @@ -128,11 +128,11 @@ const scratchInterval = { * * @throws DeveloperError if options.iso8601 does not match proper formatting. * - * @param {Object} options Object with the following properties: - * @param {String} options.iso8601 An ISO 8601 interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. - * @param {Object} [options.data] Arbitrary data associated with this interval. + * @param {object} options Object with the following properties: + * @param {string} options.iso8601 An ISO 8601 interval. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @param {object} [options.data] Arbitrary data associated with this interval. * @param {TimeInterval} [result] An existing instance to use for the result. * @returns {TimeInterval} The modified result parameter or a new instance if none was provided. */ @@ -175,8 +175,8 @@ TimeInterval.fromIso8601 = function (options, result) { * Creates an ISO8601 representation of the provided interval. * * @param {TimeInterval} timeInterval The interval to be converted. - * @param {Number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. - * @returns {String} The ISO8601 representation of the provided interval. + * @param {number} [precision] The number of fractional digits used to represent the seconds component. By default, the most precise representation is used. + * @returns {string} The ISO8601 representation of the provided interval. */ TimeInterval.toIso8601 = function (timeInterval, precision) { //>>includeStart('debug', pragmas.debug); @@ -217,7 +217,7 @@ TimeInterval.clone = function (timeInterval, result) { * @param {TimeInterval} [left] The first instance. * @param {TimeInterval} [right] The second instance. * @param {TimeInterval.DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the dates are equal; otherwise, <code>false</code>. */ TimeInterval.equals = function (left, right, dataComparer) { return ( @@ -242,9 +242,9 @@ TimeInterval.equals = function (left, right, dataComparer) { * * @param {TimeInterval} [left] The first instance. * @param {TimeInterval} [right] The second instance. - * @param {Number} [epsilon=0] The maximum number of seconds that should separate the two instances. + * @param {number} [epsilon=0] The maximum number of seconds that should separate the two instances. * @param {TimeInterval.DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the two dates are within <code>epsilon</code> seconds of each other; otherwise <code>false</code>. */ TimeInterval.equalsEpsilon = function (left, right, epsilon, dataComparer) { epsilon = defaultValue(epsilon, 0); @@ -331,7 +331,7 @@ TimeInterval.intersect = function (left, right, result, mergeCallback) { * * @param {TimeInterval} timeInterval The interval. * @param {JulianDate} julianDate The date to check. - * @returns {Boolean} <code>true</code> if the interval contains the specified date, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the interval contains the specified date, <code>false</code> otherwise. */ TimeInterval.contains = function (timeInterval, julianDate) { //>>includeStart('debug', pragmas.debug); @@ -375,7 +375,7 @@ TimeInterval.prototype.clone = function (result) { * * @param {TimeInterval} [right] The right hand side interval. * @param {TimeInterval.DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ TimeInterval.prototype.equals = function (right, dataComparer) { return TimeInterval.equals(this, right, dataComparer); @@ -387,9 +387,9 @@ TimeInterval.prototype.equals = function (right, dataComparer) { * <code>false</code> otherwise. * * @param {TimeInterval} [right] The right hand side interval. - * @param {Number} [epsilon=0] The epsilon to use for equality testing. + * @param {number} [epsilon=0] The epsilon to use for equality testing. * @param {TimeInterval.DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are within the provided epsilon, <code>false</code> otherwise. */ TimeInterval.prototype.equalsEpsilon = function (right, epsilon, dataComparer) { return TimeInterval.equalsEpsilon(this, right, epsilon, dataComparer); @@ -398,7 +398,7 @@ TimeInterval.prototype.equalsEpsilon = function (right, epsilon, dataComparer) { /** * Creates a string representing this TimeInterval in ISO8601 format. * - * @returns {String} A string representing this TimeInterval in ISO8601 format. + * @returns {string} A string representing this TimeInterval in ISO8601 format. */ TimeInterval.prototype.toString = function () { return TimeInterval.toIso8601(this); @@ -433,6 +433,6 @@ TimeInterval.EMPTY = Object.freeze( * @callback TimeInterval.DataComparer * @param {*} leftData The first data instance. * @param {*} rightData The second data instance. - * @returns {Boolean} <code>true</code> if the provided instances are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the provided instances are equal, <code>false</code> otherwise. */ export default TimeInterval; diff --git a/packages/engine/Source/Core/TimeIntervalCollection.js b/packages/engine/Source/Core/TimeIntervalCollection.js index 804fd6398a9..0d17ace0721 100644 --- a/packages/engine/Source/Core/TimeIntervalCollection.js +++ b/packages/engine/Source/Core/TimeIntervalCollection.js @@ -61,7 +61,7 @@ Object.defineProperties(TimeIntervalCollection.prototype, { /** * Gets whether or not the start time is included in the collection. * @memberof TimeIntervalCollection.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isStartIncluded: { @@ -88,7 +88,7 @@ Object.defineProperties(TimeIntervalCollection.prototype, { /** * Gets whether or not the stop time is included in the collection. * @memberof TimeIntervalCollection.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isStopIncluded: { @@ -102,7 +102,7 @@ Object.defineProperties(TimeIntervalCollection.prototype, { /** * Gets the number of intervals in the collection. * @memberof TimeIntervalCollection.prototype - * @type {Number} + * @type {number} * @readonly */ length: { @@ -114,7 +114,7 @@ Object.defineProperties(TimeIntervalCollection.prototype, { /** * Gets whether or not the collection is empty. * @memberof TimeIntervalCollection.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isEmpty: { @@ -130,7 +130,7 @@ Object.defineProperties(TimeIntervalCollection.prototype, { * * @param {TimeIntervalCollection} [right] The right hand side collection. * @param {TimeInterval.DataComparer} [dataComparer] A function which compares the data of the two intervals. If omitted, reference equality is used. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ TimeIntervalCollection.prototype.equals = function (right, dataComparer) { if (this === right) { @@ -156,7 +156,7 @@ TimeIntervalCollection.prototype.equals = function (right, dataComparer) { /** * Gets the interval at the specified index. * - * @param {Number} index The index of the interval to retrieve. + * @param {number} index The index of the interval to retrieve. * @returns {TimeInterval|undefined} The interval at the specified index, or <code>undefined</code> if no interval exists as that index. */ TimeIntervalCollection.prototype.get = function (index) { @@ -194,7 +194,7 @@ TimeIntervalCollection.prototype.findIntervalContainingDate = function (date) { * Finds and returns the data for the interval that contains the specified date. * * @param {JulianDate} date The date to search for. - * @returns {Object} The data for the interval containing the specified date, or <code>undefined</code> if no such interval exists. + * @returns {object} The data for the interval containing the specified date, or <code>undefined</code> if no such interval exists. */ TimeIntervalCollection.prototype.findDataForIntervalContainingDate = function ( date @@ -207,7 +207,7 @@ TimeIntervalCollection.prototype.findDataForIntervalContainingDate = function ( * Checks if the specified date is inside this collection. * * @param {JulianDate} julianDate The date to check. - * @returns {Boolean} <code>true</code> if the collection contains the specified date, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the collection contains the specified date, <code>false</code> otherwise. */ TimeIntervalCollection.prototype.contains = function (julianDate) { return this.indexOf(julianDate) >= 0; @@ -219,7 +219,7 @@ const indexOfScratch = new TimeInterval(); * Finds and returns the index of the interval in the collection that contains the specified date. * * @param {JulianDate} date The date to search for. - * @returns {Number} The index of the interval that contains the specified date, if no such interval exists, + * @returns {number} The index of the interval that contains the specified date, if no such interval exists, * it returns a negative number which is the bitwise complement of the index of the next interval that * starts after the date, or if no interval starts after the specified date, the bitwise complement of * the length of the collection. @@ -269,11 +269,11 @@ TimeIntervalCollection.prototype.indexOf = function (date) { * Returns the first interval in the collection that matches the specified parameters. * All parameters are optional and <code>undefined</code> parameters are treated as a don't care condition. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {JulianDate} [options.start] The start time of the interval. * @param {JulianDate} [options.stop] The stop time of the interval. - * @param {Boolean} [options.isStartIncluded] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStartIncluded] <code>true</code> if <code>options.start</code> is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded] <code>true</code> if <code>options.stop</code> is included in the interval, <code>false</code> otherwise. * @returns {TimeInterval|undefined} The first interval in the collection that matches the specified parameters. */ TimeIntervalCollection.prototype.findInterval = function (options) { @@ -505,7 +505,7 @@ TimeIntervalCollection.prototype.addInterval = function ( * The data property of the input interval is ignored. * * @param {TimeInterval} interval The interval to remove. - * @returns {Boolean} <code>true</code> if the interval was removed, <code>false</code> if no part of the interval was in the collection. + * @returns {boolean} <code>true</code> if the interval was removed, <code>false</code> if no part of the interval was in the collection. */ TimeIntervalCollection.prototype.removeInterval = function (interval) { //>>includeStart('debug', pragmas.debug); @@ -731,12 +731,12 @@ TimeIntervalCollection.prototype.intersect = function ( /** * Creates a new instance from a JulianDate array. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {JulianDate[]} options.julianDates An array of ISO 8601 dates. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. * @param {TimeIntervalCollection} [result] An existing instance to use for the result. * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. @@ -898,9 +898,9 @@ const durationRegex = /P(?:([\d.,]+)Y)?(?:([\d.,]+)M)?(?:([\d.,]+)W)?(?:([\d.,]+ /** * Parses ISO8601 duration string * - * @param {String} iso8601 An ISO 8601 duration. + * @param {string} iso8601 An ISO 8601 duration. * @param {GregorianDate} result An existing instance to use for the result. - * @returns {Boolean} True is parsing succeeded, false otherwise + * @returns {boolean} True is parsing succeeded, false otherwise * * @private */ @@ -981,12 +981,12 @@ const scratchDuration = new GregorianDate(); /** * Creates a new instance from an {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} time interval (start/end/duration). * - * @param {Object} options Object with the following properties: - * @param {String} options.iso8601 An ISO 8601 interval. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {object} options Object with the following properties: + * @param {string} options.iso8601 An ISO 8601 interval. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. * @param {TimeIntervalCollection} [result] An existing instance to use for the result. * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. @@ -1038,12 +1038,12 @@ TimeIntervalCollection.fromIso8601 = function (options, result) { /** * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} date array. * - * @param {Object} options Object with the following properties: - * @param {String[]} options.iso8601Dates An array of ISO 8601 dates. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {object} options Object with the following properties: + * @param {string[]} options.iso8601Dates An array of ISO 8601 dates. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. * @param {TimeIntervalCollection} [result] An existing instance to use for the result. * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. @@ -1076,14 +1076,14 @@ TimeIntervalCollection.fromIso8601DateArray = function (options, result) { /** * Creates a new instance from a {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601} duration array. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {JulianDate} options.epoch An date that the durations are relative to. - * @param {String} options.iso8601Durations An array of ISO 8601 durations. - * @param {Boolean} [options.relativeToPrevious=false] <code>true</code> if durations are relative to previous date, <code>false</code> if always relative to the epoch. - * @param {Boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. - * @param {Boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. - * @param {Boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. + * @param {string} options.iso8601Durations An array of ISO 8601 durations. + * @param {boolean} [options.relativeToPrevious=false] <code>true</code> if durations are relative to previous date, <code>false</code> if always relative to the epoch. + * @param {boolean} [options.isStartIncluded=true] <code>true</code> if start time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.isStopIncluded=true] <code>true</code> if stop time is included in the interval, <code>false</code> otherwise. + * @param {boolean} [options.leadingInterval=false] <code>true</code> if you want to add a interval from Iso8601.MINIMUM_VALUE to start time, <code>false</code> otherwise. + * @param {boolean} [options.trailingInterval=false] <code>true</code> if you want to add a interval from stop time to Iso8601.MAXIMUM_VALUE, <code>false</code> otherwise. * @param {Function} [options.dataCallback] A function that will be return the data that is called with each interval before it is added to the collection. If unspecified, the data will be the index in the collection. * @param {TimeIntervalCollection} [result] An existing instance to use for the result. * @returns {TimeIntervalCollection} The modified result parameter or a new instance if none was provided. diff --git a/packages/engine/Source/Core/TimeStandard.js b/packages/engine/Source/Core/TimeStandard.js index cd1bc3b1941..022772f8f3e 100644 --- a/packages/engine/Source/Core/TimeStandard.js +++ b/packages/engine/Source/Core/TimeStandard.js @@ -1,7 +1,7 @@ /** * Provides the type of time standards which JulianDate can take as input. * - * @enum {Number} + * @enum {number} * * @see JulianDate */ @@ -13,7 +13,7 @@ const TimeStandard = { * <code>UTC = TAI - deltaT</code> where <code>deltaT</code> is the number of leap * seconds which have been introduced as of the time in TAI. * - * @type {Number} + * @type {number} * @constant */ UTC: 0, @@ -22,7 +22,7 @@ const TimeStandard = { * Represents the International Atomic Time (TAI) time standard. * TAI is the principal time standard to which the other time standards are related. * - * @type {Number} + * @type {number} * @constant */ TAI: 1, diff --git a/packages/engine/Source/Core/Tipsify.js b/packages/engine/Source/Core/Tipsify.js index 87d89ef2d00..d40e9ac5cfa 100644 --- a/packages/engine/Source/Core/Tipsify.js +++ b/packages/engine/Source/Core/Tipsify.js @@ -21,13 +21,13 @@ const Tipsify = {}; /** * Calculates the average cache miss ratio (ACMR) for a given set of indices. * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices + * @param {object} options Object with the following properties: + * @param {number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices * in the vertex buffer that define the geometry's triangles. - * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. + * @param {number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. * If not supplied, this value will be computed. - * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. - * @returns {Number} The average cache miss ratio (ACMR). + * @param {number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. + * @returns {number} The average cache miss ratio (ACMR). * * @exception {DeveloperError} indices length must be a multiple of three. * @exception {DeveloperError} cacheSize must be greater than two. @@ -99,13 +99,13 @@ Tipsify.calculateACMR = function (options) { /** * Optimizes triangles for the post-vertex shader cache. * - * @param {Object} options Object with the following properties: - * @param {Number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices + * @param {object} options Object with the following properties: + * @param {number[]} options.indices Lists triads of numbers corresponding to the indices of the vertices * in the vertex buffer that define the geometry's triangles. - * @param {Number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. + * @param {number} [options.maximumIndex] The maximum value of the elements in <code>args.indices</code>. * If not supplied, this value will be computed. - * @param {Number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. - * @returns {Number[]} A list of the input indices in an optimized order. + * @param {number} [options.cacheSize=24] The number of vertices that can be stored in the cache at any one time. + * @returns {number[]} A list of the input indices in an optimized order. * * @exception {DeveloperError} indices length must be a multiple of three. * @exception {DeveloperError} cacheSize must be greater than two. diff --git a/packages/engine/Source/Core/Transforms.js b/packages/engine/Source/Core/Transforms.js index 1642351d138..a643478bb43 100644 --- a/packages/engine/Source/Core/Transforms.js +++ b/packages/engine/Source/Core/Transforms.js @@ -90,9 +90,9 @@ let scratchThirdCartesian = new Cartesian3(); /** * Generates a function that computes a 4x4 transformation matrix from a reference frame * centered at the provided origin to the provided ellipsoid's fixed reference frame. - * @param {String} firstAxis name of the first axis of the local reference frame. Must be + * @param {string} firstAxis name of the first axis of the local reference frame. Must be * 'east', 'north', 'up', 'west', 'south' or 'down'. - * @param {String} secondAxis name of the second axis of the local reference frame. Must be + * @param {string} secondAxis name of the second axis of the local reference frame. Must be * 'east', 'north', 'up', 'west', 'south' or 'down'. * @return {Transforms.LocalFrameToFixedFrame} The function that will computes a * 4x4 transformation matrix from a reference frame, with first axis and second axis compliant with the parameters, diff --git a/packages/engine/Source/Core/TranslationRotationScale.js b/packages/engine/Source/Core/TranslationRotationScale.js index 12ad6844404..f3ce144596a 100644 --- a/packages/engine/Source/Core/TranslationRotationScale.js +++ b/packages/engine/Source/Core/TranslationRotationScale.js @@ -46,7 +46,7 @@ function TranslationRotationScale(translation, rotation, scale) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {TranslationRotationScale} [right] The right hand side TranslationRotationScale. - * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if they are equal, <code>false</code> otherwise. */ TranslationRotationScale.prototype.equals = function (right) { return ( diff --git a/packages/engine/Source/Core/TridiagonalSystemSolver.js b/packages/engine/Source/Core/TridiagonalSystemSolver.js index 817881a03c3..b53dabc7e3e 100644 --- a/packages/engine/Source/Core/TridiagonalSystemSolver.js +++ b/packages/engine/Source/Core/TridiagonalSystemSolver.js @@ -13,9 +13,9 @@ const TridiagonalSystemSolver = {}; /** * Solves a tridiagonal system of linear equations. * - * @param {Number[]} diagonal An array with length <code>n</code> that contains the diagonal of the coefficient matrix. - * @param {Number[]} lower An array with length <code>n - 1</code> that contains the lower diagonal of the coefficient matrix. - * @param {Number[]} upper An array with length <code>n - 1</code> that contains the upper diagonal of the coefficient matrix. + * @param {number[]} diagonal An array with length <code>n</code> that contains the diagonal of the coefficient matrix. + * @param {number[]} lower An array with length <code>n - 1</code> that contains the lower diagonal of the coefficient matrix. + * @param {number[]} upper An array with length <code>n - 1</code> that contains the upper diagonal of the coefficient matrix. * @param {Cartesian3[]} right An array of Cartesians with length <code>n</code> that is the right side of the system of equations. * * @exception {DeveloperError} diagonal and right must have the same lengths. diff --git a/packages/engine/Source/Core/TrustedServers.js b/packages/engine/Source/Core/TrustedServers.js index 933cf90ffc1..92b24ae7cef 100644 --- a/packages/engine/Source/Core/TrustedServers.js +++ b/packages/engine/Source/Core/TrustedServers.js @@ -16,8 +16,8 @@ let _servers = {}; /** * Adds a trusted server to the registry * - * @param {String} host The host to be added. - * @param {Number} port The port used to access the host. + * @param {string} host The host to be added. + * @param {number} port The port used to access the host. * * @example * // Add a trusted server @@ -42,8 +42,8 @@ TrustedServers.add = function (host, port) { /** * Removes a trusted server from the registry * - * @param {String} host The host to be removed. - * @param {Number} port The port used to access the host. + * @param {string} host The host to be removed. + * @param {number} port The port used to access the host. * * @example * // Remove a trusted server @@ -103,7 +103,7 @@ function getAuthority(url) { /** * Tests whether a server is trusted or not. The server must have been added with the port if it is included in the url. * - * @param {String} url The url to be tested against the trusted list + * @param {string} url The url to be tested against the trusted list * * @returns {boolean} Returns true if url is trusted, false otherwise. * diff --git a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js index fae254756aa..dda00d9a795 100644 --- a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js +++ b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js @@ -26,11 +26,11 @@ function DataRectangle(rectangle, maxLevel) { * @alias VRTheWorldTerrainProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String} options.url The URL of the VR-TheWorld TileMap. + * @param {object} options Object with the following properties: + * @param {Resource|string} options.url The URL of the VR-TheWorld TileMap. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. If this parameter is not * specified, the WGS84 ellipsoid is used. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. * * * @example @@ -204,7 +204,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -216,7 +216,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof VRTheWorldTerrainProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -231,7 +231,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { * as a reflective surface with animated waves. This function should not be * called before {@link VRTheWorldTerrainProvider#ready} returns true. * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasWaterMask: { @@ -244,7 +244,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { * Gets a value indicating whether or not the requested tiles include vertex normals. * This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. * @memberof VRTheWorldTerrainProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasVertexNormals: { @@ -273,11 +273,11 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { * {@link VRTheWorldTerrainProvider#ready} returns true. The result includes terrain * data and indicates that all child tiles are available. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<TerrainData>|undefined} A promise for the requested geometry. If this method + * @returns {Promise<TerrainData>|undefined} A promise for the requested geometry. If this method * returns undefined instead of a promise, it is an indication that too many requests are already * pending and the request will be retried later. */ @@ -325,8 +325,8 @@ VRTheWorldTerrainProvider.prototype.requestTileGeometry = function ( /** * Gets the maximum geometric error allowed in a tile at a given level. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error. */ VRTheWorldTerrainProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -419,10 +419,10 @@ function isTileInRectangle(tilingScheme, rectangle, x, y, level) { /** * Determines whether data for a tile is available to be loaded. * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. - * @returns {Boolean|undefined} Undefined if not supported, otherwise true or false. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. + * @returns {boolean|undefined} Undefined if not supported, otherwise true or false. */ VRTheWorldTerrainProvider.prototype.getTileDataAvailable = function ( x, @@ -435,9 +435,9 @@ VRTheWorldTerrainProvider.prototype.getTileDataAvailable = function ( /** * Makes sure we load availability data for a tile * - * @param {Number} x The X coordinate of the tile for which to request geometry. - * @param {Number} y The Y coordinate of the tile for which to request geometry. - * @param {Number} level The level of the tile for which to request geometry. + * @param {number} x The X coordinate of the tile for which to request geometry. + * @param {number} y The Y coordinate of the tile for which to request geometry. + * @param {number} level The level of the tile for which to request geometry. * @returns {undefined|Promise<void>} Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded */ VRTheWorldTerrainProvider.prototype.loadTileDataAvailability = function ( diff --git a/packages/engine/Source/Core/VertexFormat.js b/packages/engine/Source/Core/VertexFormat.js index 5baf95dcbca..11055426225 100644 --- a/packages/engine/Source/Core/VertexFormat.js +++ b/packages/engine/Source/Core/VertexFormat.js @@ -7,7 +7,7 @@ import DeveloperError from "./DeveloperError.js"; * to a {@link Geometry} to request that certain properties be computed, e.g., just position, * position and normal, etc. * - * @param {Object} [options] An object with boolean properties corresponding to VertexFormat properties as shown in the code example. + * @param {object} [options] An object with boolean properties corresponding to VertexFormat properties as shown in the code example. * * @alias VertexFormat * @constructor @@ -220,7 +220,7 @@ VertexFormat.DEFAULT = VertexFormat.POSITION_NORMAL_AND_ST; /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ VertexFormat.packedLength = 6; @@ -228,10 +228,10 @@ VertexFormat.packedLength = 6; * Stores the provided instance into the provided array. * * @param {VertexFormat} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ VertexFormat.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -258,8 +258,8 @@ VertexFormat.pack = function (value, array, startingIndex) { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {VertexFormat} [result] The object into which to store the result. * @returns {VertexFormat} The modified result parameter or a new VertexFormat instance if one was not provided. */ diff --git a/packages/engine/Source/Core/VideoSynchronizer.js b/packages/engine/Source/Core/VideoSynchronizer.js index cd4e3b7af44..5599dcae75c 100644 --- a/packages/engine/Source/Core/VideoSynchronizer.js +++ b/packages/engine/Source/Core/VideoSynchronizer.js @@ -10,11 +10,11 @@ import JulianDate from "./JulianDate.js"; * @alias VideoSynchronizer * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Clock} [options.clock] The clock instance used to drive the video. * @param {HTMLVideoElement} [options.element] The video element to be synchronized. * @param {JulianDate} [options.epoch=Iso8601.MINIMUM_VALUE] The simulation time that marks the start of the video. - * @param {Number} [options.tolerance=1.0] The maximum amount of time, in seconds, that the clock and video can diverge. + * @param {number} [options.tolerance=1.0] The maximum amount of time, in seconds, that the clock and video can diverge. * * @demo {@link https://sandcastle.cesium.com/index.html?src=Video.html|Video Material Demo} */ @@ -43,7 +43,7 @@ function VideoSynchronizer(options) { * Lower values make the synchronization more accurate but video * performance might suffer. Higher values provide better performance * but at the cost of accuracy. - * @type {Number} + * @type {number} * @default 1.0 */ this.tolerance = defaultValue(options.tolerance, 1.0); @@ -134,7 +134,7 @@ VideoSynchronizer.prototype.destroy = function () { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ VideoSynchronizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Core/Visibility.js b/packages/engine/Source/Core/Visibility.js index 60f5758d7c9..21c80db3db8 100644 --- a/packages/engine/Source/Core/Visibility.js +++ b/packages/engine/Source/Core/Visibility.js @@ -4,13 +4,13 @@ * it has no visibility, may partially block an occludee from view, or may not block it at all, * leading to full visibility. * - * @enum {Number} + * @enum {number} */ const Visibility = { /** * Represents that no part of an object is visible. * - * @type {Number} + * @type {number} * @constant */ NONE: -1, @@ -18,7 +18,7 @@ const Visibility = { /** * Represents that part, but not all, of an object is visible * - * @type {Number} + * @type {number} * @constant */ PARTIAL: 0, @@ -26,7 +26,7 @@ const Visibility = { /** * Represents that an object is visible in its entirety. * - * @type {Number} + * @type {number} * @constant */ FULL: 1, diff --git a/packages/engine/Source/Core/VulkanConstants.js b/packages/engine/Source/Core/VulkanConstants.js index 5a8205c33db..5252ff1df36 100644 --- a/packages/engine/Source/Core/VulkanConstants.js +++ b/packages/engine/Source/Core/VulkanConstants.js @@ -3,7 +3,7 @@ * * These match the constants from the {@link https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#formats-definition|Vulkan 1.2 specification}. * - * @enum {Number} + * @enum {number} * @private */ const VulkanConstants = { diff --git a/packages/engine/Source/Core/WallGeometry.js b/packages/engine/Source/Core/WallGeometry.js index 2c086757b18..a67e0a88226 100644 --- a/packages/engine/Source/Core/WallGeometry.js +++ b/packages/engine/Source/Core/WallGeometry.js @@ -29,12 +29,12 @@ const scratchNormal = new Cartesian3(); * @alias WallGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the + * @param {number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the * wall at <code>positions</code>. If undefined, the height at each position is 0.0. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. @@ -115,7 +115,7 @@ function WallGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + VertexFormat.packedLength + 1; @@ -125,10 +125,10 @@ function WallGeometry(options) { * Stores the provided instance into the provided array. * * @param {WallGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ WallGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -197,8 +197,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {WallGeometry} [result] The object into which to store the result. * @returns {WallGeometry} The modified result parameter or a new WallGeometry instance if one was not provided. */ @@ -274,11 +274,11 @@ WallGeometry.unpack = function (array, startingIndex, result) { * A description of a wall, which is similar to a KML line string. A wall is defined by a series of points, * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the + * @param {number} [options.maximumHeight] A constant that defines the maximum height of the * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the + * @param {number} [options.minimumHeight] A constant that defines the minimum height of the * wall at <code>positions</code>. If undefined, the height at each position is 0.0. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. diff --git a/packages/engine/Source/Core/WallOutlineGeometry.js b/packages/engine/Source/Core/WallOutlineGeometry.js index 842541376db..e68299c1414 100644 --- a/packages/engine/Source/Core/WallOutlineGeometry.js +++ b/packages/engine/Source/Core/WallOutlineGeometry.js @@ -23,12 +23,12 @@ const scratchCartesian3Position2 = new Cartesian3(); * @alias WallOutlineGeometry * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. - * @param {Number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the + * @param {number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {number[]} [options.maximumHeights] An array parallel to <code>positions</code> that give the maximum height of the * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the + * @param {number[]} [options.minimumHeights] An array parallel to <code>positions</code> that give the minimum height of the * wall at <code>positions</code>. If undefined, the height at each position is 0.0. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * @@ -104,7 +104,7 @@ function WallOutlineGeometry(options) { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ this.packedLength = numComponents + Ellipsoid.packedLength + 1; } @@ -113,10 +113,10 @@ function WallOutlineGeometry(options) { * Stores the provided instance into the provided array. * * @param {WallOutlineGeometry} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ WallOutlineGeometry.pack = function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -180,8 +180,8 @@ const scratchOptions = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {WallOutlineGeometry} [result] The object into which to store the result. * @returns {WallOutlineGeometry} The modified result parameter or a new WallOutlineGeometry instance if one was not provided. */ @@ -249,11 +249,11 @@ WallOutlineGeometry.unpack = function (array, startingIndex, result) { * A description of a walloutline. A wall is defined by a series of points, * which extrude down to the ground. Optionally, they can extrude downwards to a specified height. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3[]} options.positions An array of Cartesian objects, which are the points of the wall. - * @param {Number} [options.maximumHeight] A constant that defines the maximum height of the + * @param {number} [options.maximumHeight] A constant that defines the maximum height of the * wall at <code>positions</code>. If undefined, the height of each position in used. - * @param {Number} [options.minimumHeight] A constant that defines the minimum height of the + * @param {number} [options.minimumHeight] A constant that defines the minimum height of the * wall at <code>positions</code>. If undefined, the height at each position is 0.0. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * @returns {WallOutlineGeometry} diff --git a/packages/engine/Source/Core/WebGLConstants.js b/packages/engine/Source/Core/WebGLConstants.js index 7ff6a671062..8e99cd67b54 100644 --- a/packages/engine/Source/Core/WebGLConstants.js +++ b/packages/engine/Source/Core/WebGLConstants.js @@ -7,7 +7,7 @@ * and [WebGL 2.0]{@link https://www.khronos.org/registry/webgl/specs/latest/2.0/} * specifications. * - * @enum {Number} + * @enum {number} */ const WebGLConstants = { DEPTH_BUFFER_BIT: 0x00000100, diff --git a/packages/engine/Source/Core/WebMercatorProjection.js b/packages/engine/Source/Core/WebMercatorProjection.js index 82e269ef95c..79a7cb309ec 100644 --- a/packages/engine/Source/Core/WebMercatorProjection.js +++ b/packages/engine/Source/Core/WebMercatorProjection.js @@ -44,8 +44,8 @@ Object.defineProperties(WebMercatorProjection.prototype, { * Converts a Mercator angle, in the range -PI to PI, to a geodetic latitude * in the range -PI/2 to PI/2. * - * @param {Number} mercatorAngle The angle to convert. - * @returns {Number} The geodetic latitude in radians. + * @param {number} mercatorAngle The angle to convert. + * @returns {number} The geodetic latitude in radians. */ WebMercatorProjection.mercatorAngleToGeodeticLatitude = function ( mercatorAngle @@ -57,8 +57,8 @@ WebMercatorProjection.mercatorAngleToGeodeticLatitude = function ( * Converts a geodetic latitude in radians, in the range -PI/2 to PI/2, to a Mercator * angle in the range -PI to PI. * - * @param {Number} latitude The geodetic latitude in radians. - * @returns {Number} The Mercator angle. + * @param {number} latitude The geodetic latitude in radians. + * @returns {number} The Mercator angle. */ WebMercatorProjection.geodeticLatitudeToMercatorAngle = function (latitude) { // Clamp the latitude coordinate to the valid Mercator bounds. @@ -83,7 +83,7 @@ WebMercatorProjection.geodeticLatitudeToMercatorAngle = function (latitude) { * The constant value is computed by calling: * WebMercatorProjection.mercatorAngleToGeodeticLatitude(Math.PI) * - * @type {Number} + * @type {number} */ WebMercatorProjection.MaximumLatitude = WebMercatorProjection.mercatorAngleToGeodeticLatitude( Math.PI diff --git a/packages/engine/Source/Core/WebMercatorTilingScheme.js b/packages/engine/Source/Core/WebMercatorTilingScheme.js index c835a8f246c..2266870b131 100644 --- a/packages/engine/Source/Core/WebMercatorTilingScheme.js +++ b/packages/engine/Source/Core/WebMercatorTilingScheme.js @@ -12,12 +12,12 @@ import WebMercatorProjection from "./WebMercatorProjection.js"; * @alias WebMercatorTilingScheme * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid whose surface is being tiled. Defaults to * the WGS84 ellipsoid. - * @param {Number} [options.numberOfLevelZeroTilesX=1] The number of tiles in the X direction at level zero of + * @param {number} [options.numberOfLevelZeroTilesX=1] The number of tiles in the X direction at level zero of * the tile tree. - * @param {Number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of + * @param {number} [options.numberOfLevelZeroTilesY=1] The number of tiles in the Y direction at level zero of * the tile tree. * @param {Cartesian2} [options.rectangleSouthwestInMeters] The southwest corner of the rectangle covered by the * tiling scheme, in meters. If this parameter or rectangleNortheastInMeters is not specified, the entire @@ -113,8 +113,8 @@ Object.defineProperties(WebMercatorTilingScheme.prototype, { /** * Gets the total number of tiles in the X direction at a specified level-of-detail. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the X direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the X direction at the given level. */ WebMercatorTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) { return this._numberOfLevelZeroTilesX << level; @@ -123,8 +123,8 @@ WebMercatorTilingScheme.prototype.getNumberOfXTilesAtLevel = function (level) { /** * Gets the total number of tiles in the Y direction at a specified level-of-detail. * - * @param {Number} level The level-of-detail. - * @returns {Number} The number of tiles in the Y direction at the given level. + * @param {number} level The level-of-detail. + * @returns {number} The number of tiles in the Y direction at the given level. */ WebMercatorTilingScheme.prototype.getNumberOfYTilesAtLevel = function (level) { return this._numberOfLevelZeroTilesY << level; @@ -163,10 +163,10 @@ WebMercatorTilingScheme.prototype.rectangleToNativeRectangle = function ( * Converts tile x, y coordinates and level to a rectangle expressed in the native coordinates * of the tiling scheme. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -206,10 +206,10 @@ WebMercatorTilingScheme.prototype.tileXYToNativeRectangle = function ( /** * Converts tile x, y coordinates and level to a cartographic rectangle in radians. * - * @param {Number} x The integer x coordinate of the tile. - * @param {Number} y The integer y coordinate of the tile. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. - * @param {Object} [result] The instance to which to copy the result, or undefined if a new instance + * @param {number} x The integer x coordinate of the tile. + * @param {number} y The integer y coordinate of the tile. + * @param {number} level The tile level-of-detail. Zero is the least detailed. + * @param {object} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Rectangle} The specified 'result', or a new object containing the rectangle * if 'result' is undefined. @@ -242,7 +242,7 @@ WebMercatorTilingScheme.prototype.tileXYToRectangle = function ( * a given cartographic position. * * @param {Cartographic} position The position. - * @param {Number} level The tile level-of-detail. Zero is the least detailed. + * @param {number} level The tile level-of-detail. Zero is the least detailed. * @param {Cartesian2} [result] The instance to which to copy the result, or undefined if a new instance * should be created. * @returns {Cartesian2} The specified 'result', or a new object containing the tile x, y coordinates diff --git a/packages/engine/Source/Core/WindingOrder.js b/packages/engine/Source/Core/WindingOrder.js index 7be369dc995..e9696c5ebb5 100644 --- a/packages/engine/Source/Core/WindingOrder.js +++ b/packages/engine/Source/Core/WindingOrder.js @@ -3,13 +3,13 @@ import WebGLConstants from "./WebGLConstants.js"; /** * Winding order defines the order of vertices for a triangle to be considered front-facing. * - * @enum {Number} + * @enum {number} */ const WindingOrder = { /** * Vertices are in clockwise order. * - * @type {Number} + * @type {number} * @constant */ CLOCKWISE: WebGLConstants.CW, @@ -17,7 +17,7 @@ const WindingOrder = { /** * Vertices are in counter-clockwise order. * - * @type {Number} + * @type {number} * @constant */ COUNTER_CLOCKWISE: WebGLConstants.CCW, diff --git a/packages/engine/Source/Core/WireframeIndexGenerator.js b/packages/engine/Source/Core/WireframeIndexGenerator.js index cdb3cbc72f6..6100dad6eff 100644 --- a/packages/engine/Source/Core/WireframeIndexGenerator.js +++ b/packages/engine/Source/Core/WireframeIndexGenerator.js @@ -164,7 +164,7 @@ function createWireframeFromTriangleFanIndices(vertexCount, originalIndices) { * or creating them from scratch if the model had none. * * @param {PrimitiveType} primitiveType The primitive type. - * @param {Number} vertexCount The number of vertices in the primitive. + * @param {number} vertexCount The number of vertices in the primitive. * @param {Uint8Array|Uint16Array|Uint32Array} [originalIndices] A typed array containing the original indices of the primitive. * * @return {Uint16Array|Uint32Array} A typed array with the wireframe indices, or undefined if the primitive type does not use triangles. @@ -202,8 +202,8 @@ WireframeIndexGenerator.createWireframeIndices = function ( * Gets the number of indices in the wireframe index buffer of a primitive type. * * @param {PrimitiveType} primitiveType The primitive type. - * @param {Number} originalCount The original number of vertices or indices in the primitive. - * @return {Number} The number of indices in the primitive's wireframe. + * @param {number} originalCount The original number of vertices or indices in the primitive. + * @return {number} The number of indices in the primitive's wireframe. * * @private */ diff --git a/packages/engine/Source/Core/arrayRemoveDuplicates.js b/packages/engine/Source/Core/arrayRemoveDuplicates.js index 0f1a08844cb..c001def6300 100644 --- a/packages/engine/Source/Core/arrayRemoveDuplicates.js +++ b/packages/engine/Source/Core/arrayRemoveDuplicates.js @@ -8,11 +8,11 @@ const removeDuplicatesEpsilon = CesiumMath.EPSILON10; /** * Removes adjacent duplicate values in an array of values. * - * @param {Array.<*>} [values] The array of values. + * @param {any[]} [values] The array of values. * @param {Function} equalsEpsilon Function to compare values with an epsilon. Boolean equalsEpsilon(left, right, epsilon). - * @param {Boolean} [wrapAround=false] Compare the last value in the array against the first value. If they are equal, the last value is removed. - * @param {Array.<Number>} [removedIndices=undefined] Store the indices that correspond to the duplicate items removed from the array, if there were any. - * @returns {Array.<*>|undefined} A new array of values with no adjacent duplicate values or the input array if no duplicates were found. + * @param {boolean} [wrapAround=false] Compare the last value in the array against the first value. If they are equal, the last value is removed. + * @param {number[]} [removedIndices=undefined] Store the indices that correspond to the duplicate items removed from the array, if there were any. + * @returns {any[]|undefined} A new array of values with no adjacent duplicate values or the input array if no duplicates were found. * * @example * // Returns [(1.0, 1.0, 1.0), (2.0, 2.0, 2.0), (3.0, 3.0, 3.0), (1.0, 1.0, 1.0)] diff --git a/packages/engine/Source/Core/binarySearch.js b/packages/engine/Source/Core/binarySearch.js index c14b7631c64..5cbb2890b96 100644 --- a/packages/engine/Source/Core/binarySearch.js +++ b/packages/engine/Source/Core/binarySearch.js @@ -8,7 +8,7 @@ import Check from "./Check.js"; * @param {*} itemToFind The item to find in the array. * @param {binarySearchComparator} comparator The function to use to compare the item to * elements in the array. - * @returns {Number} The index of <code>itemToFind</code> in the array, if it exists. If <code>itemToFind</code> + * @returns {number} The index of <code>itemToFind</code> in the array, if it exists. If <code>itemToFind</code> * does not exist, the return value is a negative number which is the bitwise complement (~) * of the index before which the itemToFind should be inserted in order to maintain the * sorted order of the array. @@ -55,7 +55,7 @@ function binarySearch(array, itemToFind, comparator) { * * @param {*} a An item in the array. * @param {*} b The item being searched for. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * @returns {number} Returns a negative value if <code>a</code> is less than <code>b</code>, * a positive value if <code>a</code> is greater than <code>b</code>, or * 0 if <code>a</code> is equal to <code>b</code>. * diff --git a/packages/engine/Source/Core/buildModuleUrl.js b/packages/engine/Source/Core/buildModuleUrl.js index 44b878a3c9b..026faec9f04 100644 --- a/packages/engine/Source/Core/buildModuleUrl.js +++ b/packages/engine/Source/Core/buildModuleUrl.js @@ -93,8 +93,8 @@ let implementation; * Given a relative URL under the Cesium base URL, returns an absolute URL. * @function * - * @param {String} relativeUrl The relative path. - * @returns {String} The absolutely URL representation of the provided path. + * @param {string} relativeUrl The relative path. + * @returns {string} The absolutely URL representation of the provided path. * * @example * const viewer = new Cesium.Viewer("cesiumContainer", { @@ -132,7 +132,7 @@ buildModuleUrl._clearBaseResource = function () { /** * Sets the base URL for resolving modules. - * @param {String} value The new base URL. + * @param {string} value The new base URL. */ buildModuleUrl.setBaseUrl = function (value) { baseResource = Resource.DEFAULT.getDerivedResource({ @@ -144,7 +144,7 @@ buildModuleUrl.setBaseUrl = function (value) { * Gets the base URL for resolving modules. * * @function - * @returns {String} The configured base URL + * @returns {string} The configured base URL */ buildModuleUrl.getCesiumBaseUrl = getCesiumBaseUrl; diff --git a/packages/engine/Source/Core/cancelAnimationFrame.js b/packages/engine/Source/Core/cancelAnimationFrame.js index d86c38ef1cb..dd07ecf5bb5 100644 --- a/packages/engine/Source/Core/cancelAnimationFrame.js +++ b/packages/engine/Source/Core/cancelAnimationFrame.js @@ -32,7 +32,7 @@ if (typeof cancelAnimationFrame !== "undefined") { * * @function cancelAnimationFrame * - * @param {Number} requestID The value returned by {@link requestAnimationFrame}. + * @param {number} requestID The value returned by {@link requestAnimationFrame}. * * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} * diff --git a/packages/engine/Source/Core/clone.js b/packages/engine/Source/Core/clone.js index 2532c8853d1..f366c04b182 100644 --- a/packages/engine/Source/Core/clone.js +++ b/packages/engine/Source/Core/clone.js @@ -5,9 +5,9 @@ import defaultValue from "./defaultValue.js"; * * @function * - * @param {Object} object The object to clone. - * @param {Boolean} [deep=false] If true, all properties will be deep cloned recursively. - * @returns {Object} The cloned object. + * @param {object} object The object to clone. + * @param {boolean} [deep=false] If true, all properties will be deep cloned recursively. + * @returns {object} The cloned object. */ function clone(object, deep) { if (object === null || typeof object !== "object") { diff --git a/packages/engine/Source/Core/combine.js b/packages/engine/Source/Core/combine.js index f166b9f00c7..98d5cf74c6d 100644 --- a/packages/engine/Source/Core/combine.js +++ b/packages/engine/Source/Core/combine.js @@ -25,10 +25,10 @@ import defined from "./defined.js"; * // } * // } * - * @param {Object} [object1] The first object to merge. - * @param {Object} [object2] The second object to merge. - * @param {Boolean} [deep=false] Perform a recursive merge. - * @returns {Object} The combined object containing all properties from both objects. + * @param {object} [object1] The first object to merge. + * @param {object} [object2] The second object to merge. + * @param {boolean} [deep=false] Perform a recursive merge. + * @returns {object} The combined object containing all properties from both objects. * * @function */ diff --git a/packages/engine/Source/Core/createGuid.js b/packages/engine/Source/Core/createGuid.js index 783eccebe75..f11200d302a 100644 --- a/packages/engine/Source/Core/createGuid.js +++ b/packages/engine/Source/Core/createGuid.js @@ -3,7 +3,7 @@ * * @function * - * @returns {String} + * @returns {string} * * * @example diff --git a/packages/engine/Source/Core/createWorldTerrain.js b/packages/engine/Source/Core/createWorldTerrain.js index 0fcc7c9c0cb..3a0406b982a 100644 --- a/packages/engine/Source/Core/createWorldTerrain.js +++ b/packages/engine/Source/Core/createWorldTerrain.js @@ -7,9 +7,9 @@ import IonResource from "./IonResource.js"; * * @function * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. - * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server if available. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. + * @param {boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server if available. * @returns {CesiumTerrainProvider} * * @see Ion diff --git a/packages/engine/Source/Core/defaultValue.js b/packages/engine/Source/Core/defaultValue.js index 9a52e51ecfb..50c20d55498 100644 --- a/packages/engine/Source/Core/defaultValue.js +++ b/packages/engine/Source/Core/defaultValue.js @@ -21,7 +21,7 @@ function defaultValue(a, b) { /** * A frozen empty object that can be used as the default value for options passed as * an object literal. - * @type {Object} + * @type {object} * @memberof defaultValue */ defaultValue.EMPTY_OBJECT = Object.freeze({}); diff --git a/packages/engine/Source/Core/defer.js b/packages/engine/Source/Core/defer.js index 8ea507f022b..2e6c510fc22 100644 --- a/packages/engine/Source/Core/defer.js +++ b/packages/engine/Source/Core/defer.js @@ -15,7 +15,7 @@ /** * An object which contains a promise object, and functions to resolve or reject the promise. * - * @typedef {Object} defer.deferred + * @typedef {object} defer.deferred * @property {defer.resolve} resolve Resolves the promise when called. * @property {defer.reject} reject Rejects the promise when called. * @property {Promise} promise Promise object. diff --git a/packages/engine/Source/Core/defined.js b/packages/engine/Source/Core/defined.js index d9125ecd06b..5040c613e7c 100644 --- a/packages/engine/Source/Core/defined.js +++ b/packages/engine/Source/Core/defined.js @@ -2,7 +2,7 @@ * @function * * @param {*} value The object. - * @returns {Boolean} Returns true if the object is defined, returns false otherwise. + * @returns {boolean} Returns true if the object is defined, returns false otherwise. * * @example * if (Cesium.defined(positions)) { diff --git a/packages/engine/Source/Core/deprecationWarning.js b/packages/engine/Source/Core/deprecationWarning.js index 6e762389326..0b9c727b829 100644 --- a/packages/engine/Source/Core/deprecationWarning.js +++ b/packages/engine/Source/Core/deprecationWarning.js @@ -9,8 +9,8 @@ import oneTimeWarning from "./oneTimeWarning.js"; * * @function deprecationWarning * - * @param {String} identifier The unique identifier for this deprecated API. - * @param {String} message The message to log to the console. + * @param {string} identifier The unique identifier for this deprecated API. + * @param {string} message The message to log to the console. * * @example * // Deprecated function or class diff --git a/packages/engine/Source/Core/destroyObject.js b/packages/engine/Source/Core/destroyObject.js index bbec29ffa31..40093a8ba36 100644 --- a/packages/engine/Source/Core/destroyObject.js +++ b/packages/engine/Source/Core/destroyObject.js @@ -18,8 +18,8 @@ function returnTrue() { * * @function * - * @param {Object} object The object to destroy. - * @param {String} [message] The message to include in the exception that is thrown if + * @param {object} object The object to destroy. + * @param {string} [message] The message to include in the exception that is thrown if * a destroyed object's function is called. * * diff --git a/packages/engine/Source/Core/formatError.js b/packages/engine/Source/Core/formatError.js index 83256927296..3ef17614f97 100644 --- a/packages/engine/Source/Core/formatError.js +++ b/packages/engine/Source/Core/formatError.js @@ -7,7 +7,7 @@ import defined from "./defined.js"; * @function * * @param {*} object The item to find in the array. - * @returns {String} A string containing the formatted error. + * @returns {string} A string containing the formatted error. */ function formatError(object) { let result; diff --git a/packages/engine/Source/Core/getAbsoluteUri.js b/packages/engine/Source/Core/getAbsoluteUri.js index b80320cac15..63f5e7cb9d9 100644 --- a/packages/engine/Source/Core/getAbsoluteUri.js +++ b/packages/engine/Source/Core/getAbsoluteUri.js @@ -7,9 +7,9 @@ import DeveloperError from "./DeveloperError.js"; * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. * @function * - * @param {String} relative The relative Uri. - * @param {String} [base] The base Uri. - * @returns {String} The absolute Uri of the given relative Uri. + * @param {string} relative The relative Uri. + * @param {string} [base] The base Uri. + * @returns {string} The absolute Uri of the given relative Uri. * * @example * //absolute Uri will be "https://test.com/awesome.png"; diff --git a/packages/engine/Source/Core/getBaseUri.js b/packages/engine/Source/Core/getBaseUri.js index 96c36b599c3..78c600cafbc 100644 --- a/packages/engine/Source/Core/getBaseUri.js +++ b/packages/engine/Source/Core/getBaseUri.js @@ -6,9 +6,9 @@ import DeveloperError from "./DeveloperError.js"; * Given a URI, returns the base path of the URI. * @function * - * @param {String} uri The Uri. - * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri - * @returns {String} The base path of the Uri. + * @param {string} uri The Uri. + * @param {boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri + * @returns {string} The base path of the Uri. * * @example * // basePath will be "/Gallery/"; diff --git a/packages/engine/Source/Core/getExtensionFromUri.js b/packages/engine/Source/Core/getExtensionFromUri.js index 05fda9b6818..f51ea912d35 100644 --- a/packages/engine/Source/Core/getExtensionFromUri.js +++ b/packages/engine/Source/Core/getExtensionFromUri.js @@ -6,8 +6,8 @@ import DeveloperError from "./DeveloperError.js"; * Given a URI, returns the extension of the URI. * @function getExtensionFromUri * - * @param {String} uri The Uri. - * @returns {String} The extension of the Uri. + * @param {string} uri The Uri. + * @returns {string} The extension of the Uri. * * @example * //extension will be "czml"; diff --git a/packages/engine/Source/Core/getFilenameFromUri.js b/packages/engine/Source/Core/getFilenameFromUri.js index 54a1fbbfba1..ee250c0173e 100644 --- a/packages/engine/Source/Core/getFilenameFromUri.js +++ b/packages/engine/Source/Core/getFilenameFromUri.js @@ -6,8 +6,8 @@ import DeveloperError from "./DeveloperError.js"; * Given a URI, returns the last segment of the URI, removing any path or query information. * @function getFilenameFromUri * - * @param {String} uri The Uri. - * @returns {String} The last segment of the Uri. + * @param {string} uri The Uri. + * @returns {string} The last segment of the Uri. * * @example * //fileName will be"simple.czml"; diff --git a/packages/engine/Source/Core/getImageFromTypedArray.js b/packages/engine/Source/Core/getImageFromTypedArray.js index 75204caea80..43d32b93d78 100644 --- a/packages/engine/Source/Core/getImageFromTypedArray.js +++ b/packages/engine/Source/Core/getImageFromTypedArray.js @@ -2,8 +2,8 @@ * Constructs an image from a TypedArray of pixel values * * @param {Uint8Array} typedArray The array of pixel values - * @param {Number} width The width of the image to create - * @param {Number} height The height of the image to create + * @param {number} width The width of the image to create + * @param {number} height The height of the image to create * @returns {HTMLCanvasElement} A new canvas containing the constructed image * * @private diff --git a/packages/engine/Source/Core/getImagePixels.js b/packages/engine/Source/Core/getImagePixels.js index 7c46c8e54c0..b027c3d6a3b 100644 --- a/packages/engine/Source/Core/getImagePixels.js +++ b/packages/engine/Source/Core/getImagePixels.js @@ -9,8 +9,8 @@ const context2DsByWidthAndHeight = {}; * @function getImagePixels * * @param {HTMLImageElement|ImageBitmap} image The image to extract pixels from. - * @param {Number} width The width of the image. If not defined, then image.width is assigned. - * @param {Number} height The height of the image. If not defined, then image.height is assigned. + * @param {number} width The width of the image. If not defined, then image.width is assigned. + * @param {number} height The height of the image. If not defined, then image.height is assigned. * @returns {ImageData} The pixels of the image. */ function getImagePixels(image, width, height) { diff --git a/packages/engine/Source/Core/getJsonFromTypedArray.js b/packages/engine/Source/Core/getJsonFromTypedArray.js index 02db059e05d..ff5e2f4c51f 100644 --- a/packages/engine/Source/Core/getJsonFromTypedArray.js +++ b/packages/engine/Source/Core/getJsonFromTypedArray.js @@ -6,9 +6,9 @@ import getStringFromTypedArray from "./getStringFromTypedArray.js"; * @function * * @param {Uint8Array} uint8Array The Uint8Array to read from. - * @param {Number} [byteOffset=0] The byte offset to start reading from. - * @param {Number} [byteLength] The byte length to read. If byteLength is omitted the remainder of the buffer is read. - * @returns {Object} An object containing the parsed JSON. + * @param {number} [byteOffset=0] The byte offset to start reading from. + * @param {number} [byteLength] The byte length to read. If byteLength is omitted the remainder of the buffer is read. + * @returns {object} An object containing the parsed JSON. * * @private */ diff --git a/packages/engine/Source/Core/getStringFromTypedArray.js b/packages/engine/Source/Core/getStringFromTypedArray.js index 8fb220a9de4..2b3c04fe394 100644 --- a/packages/engine/Source/Core/getStringFromTypedArray.js +++ b/packages/engine/Source/Core/getStringFromTypedArray.js @@ -9,9 +9,9 @@ import RuntimeError from "./RuntimeError.js"; * @function * * @param {Uint8Array} uint8Array The Uint8Array to read from. - * @param {Number} [byteOffset=0] The byte offset to start reading from. - * @param {Number} [byteLength] The byte length to read. If byteLength is omitted the remainder of the buffer is read. - * @returns {String} The string. + * @param {number} [byteOffset=0] The byte offset to start reading from. + * @param {number} [byteLength] The byte length to read. If byteLength is omitted the remainder of the buffer is read. + * @returns {string} The string. * * @private */ diff --git a/packages/engine/Source/Core/getTimestamp.js b/packages/engine/Source/Core/getTimestamp.js index 6eafcdcaff9..6c1ce26a187 100644 --- a/packages/engine/Source/Core/getTimestamp.js +++ b/packages/engine/Source/Core/getTimestamp.js @@ -6,7 +6,7 @@ * * @function getTimestamp * - * @returns {Number} The timestamp in milliseconds since some unspecified reference time. + * @returns {number} The timestamp in milliseconds since some unspecified reference time. */ let getTimestamp; diff --git a/packages/engine/Source/Core/isBlobUri.js b/packages/engine/Source/Core/isBlobUri.js index c29b33cb761..9e3f6c38459 100644 --- a/packages/engine/Source/Core/isBlobUri.js +++ b/packages/engine/Source/Core/isBlobUri.js @@ -7,8 +7,8 @@ const blobUriRegex = /^blob:/i; * * @function isBlobUri * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a blob uri; otherwise, false. + * @param {string} uri The uri to test. + * @returns {boolean} true when the uri is a blob uri; otherwise, false. * * @private */ diff --git a/packages/engine/Source/Core/isDataUri.js b/packages/engine/Source/Core/isDataUri.js index 73fd785828b..bb5ef14bef0 100644 --- a/packages/engine/Source/Core/isDataUri.js +++ b/packages/engine/Source/Core/isDataUri.js @@ -7,8 +7,8 @@ const dataUriRegex = /^data:/i; * * @function isDataUri * - * @param {String} uri The uri to test. - * @returns {Boolean} true when the uri is a data uri; otherwise, false. + * @param {string} uri The uri to test. + * @returns {boolean} true when the uri is a data uri; otherwise, false. * * @private */ diff --git a/packages/engine/Source/Core/isLeapYear.js b/packages/engine/Source/Core/isLeapYear.js index 6de7117cdd8..404b3725b9e 100644 --- a/packages/engine/Source/Core/isLeapYear.js +++ b/packages/engine/Source/Core/isLeapYear.js @@ -5,8 +5,8 @@ import DeveloperError from "./DeveloperError.js"; * * @function isLeapYear * - * @param {Number} year The year to be tested. - * @returns {Boolean} True if <code>year</code> is a leap year. + * @param {number} year The year to be tested. + * @returns {boolean} True if <code>year</code> is a leap year. * * @example * const leapYear = Cesium.isLeapYear(2000); // true diff --git a/packages/engine/Source/Core/loadKTX2.js b/packages/engine/Source/Core/loadKTX2.js index f73207439e5..8359640fc85 100644 --- a/packages/engine/Source/Core/loadKTX2.js +++ b/packages/engine/Source/Core/loadKTX2.js @@ -5,12 +5,12 @@ import KTX2Transcoder from "./KTX2Transcoder.js"; /** * Stores the supported formats that KTX2 can transcode to. Called during context creation. * - * @param {Boolean} s3tc Whether or not S3TC is supported - * @param {Boolean} pvrtc Whether or not PVRTC is supported - * @param {Boolean} astc Whether or not ASTC is supported - * @param {Boolean} etc Whether or not ETC is supported - * @param {Boolean} etc1 Whether or not ETC1 is supported - * @param {Boolean} bc7 Whether or not BC7 is supported + * @param {boolean} s3tc Whether or not S3TC is supported + * @param {boolean} pvrtc Whether or not PVRTC is supported + * @param {boolean} astc Whether or not ASTC is supported + * @param {boolean} etc Whether or not ETC is supported + * @param {boolean} etc1 Whether or not ETC1 is supported + * @param {boolean} bc7 Whether or not BC7 is supported * @private */ let supportedTranscoderFormats; @@ -51,8 +51,8 @@ loadKTX2.setKTX2SupportedFormats = function ( * * @function loadKTX2 * - * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. - * @returns {Promise.<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. + * @param {Resource|string|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. + * @returns {Promise<CompressedTextureBuffer>|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority. * * @exception {RuntimeError} Invalid KTX2 file. * @exception {RuntimeError} KTX2 texture arrays are not supported. diff --git a/packages/engine/Source/Core/mergeSort.js b/packages/engine/Source/Core/mergeSort.js index a5250b12b80..ea60bd76381 100644 --- a/packages/engine/Source/Core/mergeSort.js +++ b/packages/engine/Source/Core/mergeSort.js @@ -99,7 +99,7 @@ function mergeSort(array, comparator, userDefinedObject) { * @param {*} a An item in the array. * @param {*} b An item in the array. * @param {*} [userDefinedObject] An object that was passed to {@link mergeSort}. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * @returns {number} Returns a negative value if <code>a</code> is less than <code>b</code>, * a positive value if <code>a</code> is greater than <code>b</code>, or * 0 if <code>a</code> is equal to <code>b</code>. * diff --git a/packages/engine/Source/Core/objectToQuery.js b/packages/engine/Source/Core/objectToQuery.js index b0b5f6c8615..c9a6e960f33 100644 --- a/packages/engine/Source/Core/objectToQuery.js +++ b/packages/engine/Source/Core/objectToQuery.js @@ -7,8 +7,8 @@ import DeveloperError from "./DeveloperError.js"; * will produce multiple values with the same name. * @function objectToQuery * - * @param {Object} obj The object containing data to encode. - * @returns {String} An encoded query string. + * @param {object} obj The object containing data to encode. + * @returns {string} An encoded query string. * * * @example diff --git a/packages/engine/Source/Core/oneTimeWarning.js b/packages/engine/Source/Core/oneTimeWarning.js index cd26c4450d0..4231bd3eae4 100644 --- a/packages/engine/Source/Core/oneTimeWarning.js +++ b/packages/engine/Source/Core/oneTimeWarning.js @@ -11,8 +11,8 @@ const warnings = {}; * * @function oneTimeWarning * - * @param {String} identifier The unique identifier for this warning. - * @param {String} [message=identifier] The message to log to the console. + * @param {string} identifier The unique identifier for this warning. + * @param {string} [message=identifier] The message to log to the console. * * @example * for(let i=0;i<foo.length;++i) { diff --git a/packages/engine/Source/Core/parseResponseHeaders.js b/packages/engine/Source/Core/parseResponseHeaders.js index 69bf7143638..b151c962ecb 100644 --- a/packages/engine/Source/Core/parseResponseHeaders.js +++ b/packages/engine/Source/Core/parseResponseHeaders.js @@ -4,9 +4,9 @@ * * @function parseResponseHeaders * - * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is + * @param {string} headerString The header string returned by getAllResponseHeaders(). The format is * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value + * @returns {object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value * is that header's value. * * @private diff --git a/packages/engine/Source/Core/pointInsideTriangle.js b/packages/engine/Source/Core/pointInsideTriangle.js index 2613fd0b5eb..c6f2c0b07e3 100644 --- a/packages/engine/Source/Core/pointInsideTriangle.js +++ b/packages/engine/Source/Core/pointInsideTriangle.js @@ -13,7 +13,7 @@ const scratchBarycentricCoords = new Cartesian3(); * @param {Cartesian2|Cartesian3} p0 The first point of the triangle. * @param {Cartesian2|Cartesian3} p1 The second point of the triangle. * @param {Cartesian2|Cartesian3} p2 The third point of the triangle. - * @returns {Boolean} <code>true</code> if the point is inside the triangle; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the point is inside the triangle; otherwise, <code>false</code>. * * @example * // Returns true diff --git a/packages/engine/Source/Core/queryToObject.js b/packages/engine/Source/Core/queryToObject.js index 9a0c80b62b5..0aa374bab87 100644 --- a/packages/engine/Source/Core/queryToObject.js +++ b/packages/engine/Source/Core/queryToObject.js @@ -7,8 +7,8 @@ import DeveloperError from "./DeveloperError.js"; * the value in the object will be an array of values. * @function queryToObject * - * @param {String} queryString The query string. - * @returns {Object} An object containing the parameters parsed from the query string. + * @param {string} queryString The query string. + * @returns {object} An object containing the parameters parsed from the query string. * * * @example diff --git a/packages/engine/Source/Core/requestAnimationFrame.js b/packages/engine/Source/Core/requestAnimationFrame.js index bd873996ee2..c94919f6e79 100644 --- a/packages/engine/Source/Core/requestAnimationFrame.js +++ b/packages/engine/Source/Core/requestAnimationFrame.js @@ -45,7 +45,7 @@ if (typeof requestAnimationFrame !== "undefined") { * @function requestAnimationFrame * * @param {requestAnimationFrameCallback} callback The function to call when the next frame should be drawn. - * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. + * @returns {number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. * * * @example @@ -78,6 +78,6 @@ function requestAnimationFramePolyFill(callback) { * A function that will be called when the next frame should be drawn. * @callback requestAnimationFrameCallback * - * @param {Number} timestamp A timestamp for the frame, in milliseconds. + * @param {number} timestamp A timestamp for the frame, in milliseconds. */ export default requestAnimationFramePolyFill; diff --git a/packages/engine/Source/Core/sampleTerrain.js b/packages/engine/Source/Core/sampleTerrain.js index f23a2f55be6..f8fd9ea76ff 100644 --- a/packages/engine/Source/Core/sampleTerrain.js +++ b/packages/engine/Source/Core/sampleTerrain.js @@ -18,9 +18,9 @@ import defined from "./defined.js"; * @function sampleTerrain * * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. - * @param {Number} level The terrain level-of-detail from which to query terrain heights. + * @param {number} level The terrain level-of-detail from which to query terrain heights. * @param {Cartographic[]} positions The positions to update with terrain heights. - * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. + * @returns {Promise<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. * * @see sampleTerrainMostDetailed * @@ -50,8 +50,8 @@ function sampleTerrain(terrainProvider, level, positions) { } /** - * @param {Array.<Object>} tileRequests The mutated list of requests, the first one will be attempted - * @param {Array.<Promise<void>>} results The list to put the result promises into + * @param {object[]} tileRequests The mutated list of requests, the first one will be attempted + * @param {Array<Promise<void>>} results The list to put the result promises into * @returns {boolean} true if the request was made, and we are okay to attempt the next item immediately, * or false if we were throttled and should wait awhile before retrying. * @@ -97,8 +97,8 @@ function delay(ms) { /** * Recursively consumes all the tileRequests until the list has been emptied * and a Promise of each result has been put into the results list - * @param {Array.<Object>} tileRequests The list of requests desired to be made - * @param {Array.<Promise<void>>} results The list to put all the result promises into + * @param {object[]} tileRequests The list of requests desired to be made + * @param {Array<Promise<void>>} results The list to put all the result promises into * @returns {Promise<void>} A promise which resolves once all requests have been started * * @private @@ -176,7 +176,7 @@ function doSampling(terrainProvider, level, positions) { * @param {Cartographic} position The position to interpolate for and assign the height value to * @param {TerrainData} terrainData * @param {Rectangle} rectangle - * @returns {Boolean} If the height was actually interpolated and assigned + * @returns {boolean} If the height was actually interpolated and assigned * @private */ function interpolateAndAssignHeight(position, terrainData, rectangle) { diff --git a/packages/engine/Source/Core/sampleTerrainMostDetailed.js b/packages/engine/Source/Core/sampleTerrainMostDetailed.js index 621bba06c5d..54160a04f6c 100644 --- a/packages/engine/Source/Core/sampleTerrainMostDetailed.js +++ b/packages/engine/Source/Core/sampleTerrainMostDetailed.js @@ -12,7 +12,7 @@ const scratchCartesian2 = new Cartesian2(); * * @param {TerrainProvider} terrainProvider The terrain provider from which to query heights. * @param {Cartographic[]} positions The positions to update with terrain heights. - * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. This + * @returns {Promise<Cartographic[]>} A promise that resolves to the provided list of positions when terrain the query has completed. This * promise will reject if the terrain provider's `availability` property is undefined. * * @example diff --git a/packages/engine/Source/Core/scaleToGeodeticSurface.js b/packages/engine/Source/Core/scaleToGeodeticSurface.js index 968c7271ab6..99b2a8b75b6 100644 --- a/packages/engine/Source/Core/scaleToGeodeticSurface.js +++ b/packages/engine/Source/Core/scaleToGeodeticSurface.js @@ -14,7 +14,7 @@ const scaleToGeodeticSurfaceGradient = new Cartesian3(); * @param {Cartesian3} cartesian The Cartesian position to scale. * @param {Cartesian3} oneOverRadii One over radii of the ellipsoid. * @param {Cartesian3} oneOverRadiiSquared One over radii squared of the ellipsoid. - * @param {Number} centerToleranceSquared Tolerance for closeness to the center. + * @param {number} centerToleranceSquared Tolerance for closeness to the center. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center. * diff --git a/packages/engine/Source/Core/subdivideArray.js b/packages/engine/Source/Core/subdivideArray.js index d7003ee1173..9404c76f43c 100644 --- a/packages/engine/Source/Core/subdivideArray.js +++ b/packages/engine/Source/Core/subdivideArray.js @@ -7,7 +7,7 @@ import DeveloperError from "./DeveloperError.js"; * @function subdivideArray * * @param {Array} array The array to divide. - * @param {Number} numberOfArrays The number of arrays to divide the provided array into. + * @param {number} numberOfArrays The number of arrays to divide the provided array into. * * @exception {DeveloperError} numberOfArrays must be greater than 0. */ diff --git a/packages/engine/Source/Core/writeTextToCanvas.js b/packages/engine/Source/Core/writeTextToCanvas.js index eeb4a4141ca..599ced41b78 100644 --- a/packages/engine/Source/Core/writeTextToCanvas.js +++ b/packages/engine/Source/Core/writeTextToCanvas.js @@ -101,17 +101,17 @@ let imageSmoothingEnabledName; * Writes the given text into a new canvas. The canvas will be sized to fit the text. * If text is blank, returns undefined. * - * @param {String} text The text to write. - * @param {Object} [options] Object with the following properties: - * @param {String} [options.font='10px sans-serif'] The CSS font to use. - * @param {String} [options.textBaseline='bottom'] The baseline of the text. - * @param {Boolean} [options.fill=true] Whether to fill the text. - * @param {Boolean} [options.stroke=false] Whether to stroke the text. + * @param {string} text The text to write. + * @param {object} [options] Object with the following properties: + * @param {string} [options.font='10px sans-serif'] The CSS font to use. + * @param {string} [options.textBaseline='bottom'] The baseline of the text. + * @param {boolean} [options.fill=true] Whether to fill the text. + * @param {boolean} [options.stroke=false] Whether to stroke the text. * @param {Color} [options.fillColor=Color.WHITE] The fill color. * @param {Color} [options.strokeColor=Color.BLACK] The stroke color. - * @param {Number} [options.strokeWidth=1] The stroke width. + * @param {number} [options.strokeWidth=1] The stroke width. * @param {Color} [options.backgroundColor=Color.TRANSPARENT] The background color of the canvas. - * @param {Number} [options.padding=0] The pixel size of the padding to add around the text. + * @param {number} [options.padding=0] The pixel size of the padding to add around the text. * @returns {HTMLCanvasElement|undefined} A new canvas with the given text drawn into it. The dimensions object * from measureText will also be added to the returned canvas. If text is * blank, returns undefined. diff --git a/packages/engine/Source/DataSources/BillboardGraphics.js b/packages/engine/Source/DataSources/BillboardGraphics.js index fe5144eb494..e6686ecaf4f 100644 --- a/packages/engine/Source/DataSources/BillboardGraphics.js +++ b/packages/engine/Source/DataSources/BillboardGraphics.js @@ -5,7 +5,7 @@ import Event from "../Core/Event.js"; import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} BillboardGraphics.ConstructorOptions + * @typedef {object} BillboardGraphics.ConstructorOptions * * Initialization options for the BillboardGraphics constructor * diff --git a/packages/engine/Source/DataSources/BillboardVisualizer.js b/packages/engine/Source/DataSources/BillboardVisualizer.js index c9128722494..954e72047a6 100644 --- a/packages/engine/Source/DataSources/BillboardVisualizer.js +++ b/packages/engine/Source/DataSources/BillboardVisualizer.js @@ -75,7 +75,7 @@ function BillboardVisualizer(entityCluster, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ BillboardVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -274,7 +274,7 @@ BillboardVisualizer.prototype.getBoundingSphere = function (entity, result) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ BillboardVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/BoundingSphereState.js b/packages/engine/Source/DataSources/BoundingSphereState.js index c7027f5924c..a317884f522 100644 --- a/packages/engine/Source/DataSources/BoundingSphereState.js +++ b/packages/engine/Source/DataSources/BoundingSphereState.js @@ -1,6 +1,6 @@ /** * The state of a BoundingSphere computation being performed by a {@link Visualizer}. - * @enum {Number} + * @enum {number} * @private */ const BoundingSphereState = { diff --git a/packages/engine/Source/DataSources/BoxGraphics.js b/packages/engine/Source/DataSources/BoxGraphics.js index 9be7f8a0d06..d922d102285 100644 --- a/packages/engine/Source/DataSources/BoxGraphics.js +++ b/packages/engine/Source/DataSources/BoxGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} BoxGraphics.ConstructorOptions + * @typedef {object} BoxGraphics.ConstructorOptions * * Initialization options for the BoxGraphics constructor * diff --git a/packages/engine/Source/DataSources/CallbackProperty.js b/packages/engine/Source/DataSources/CallbackProperty.js index d264814cdf8..c3609030cd9 100644 --- a/packages/engine/Source/DataSources/CallbackProperty.js +++ b/packages/engine/Source/DataSources/CallbackProperty.js @@ -9,7 +9,7 @@ import Event from "../Core/Event.js"; * @constructor * * @param {CallbackProperty.Callback} callback The function to be called when the property is evaluated. - * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. + * @param {boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. */ function CallbackProperty(callback, isConstant) { this._callback = undefined; @@ -23,7 +23,7 @@ Object.defineProperties(CallbackProperty.prototype, { * Gets a value indicating if this property is constant. * @memberof CallbackProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -50,8 +50,8 @@ Object.defineProperties(CallbackProperty.prototype, { * Gets the value of the property. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied or is unsupported. */ CallbackProperty.prototype.getValue = function (time, result) { return this._callback(time, result); @@ -61,7 +61,7 @@ CallbackProperty.prototype.getValue = function (time, result) { * Sets the callback to be used. * * @param {CallbackProperty.Callback} callback The function to be called when the property is evaluated. - * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. + * @param {boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change. */ CallbackProperty.prototype.setCallback = function (callback, isConstant) { //>>includeStart('debug', pragmas.debug); @@ -89,7 +89,7 @@ CallbackProperty.prototype.setCallback = function (callback, isConstant) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ CallbackProperty.prototype.equals = function (other) { return ( @@ -105,7 +105,7 @@ CallbackProperty.prototype.equals = function (other) { * @callback CallbackProperty.Callback * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into. If omitted, the function must create and return a new instance. - * @returns {Object} The modified result parameter, or a new instance if the result parameter was not supplied or is unsupported. + * @param {object} [result] The object to store the value into. If omitted, the function must create and return a new instance. + * @returns {object} The modified result parameter, or a new instance if the result parameter was not supplied or is unsupported. */ export default CallbackProperty; diff --git a/packages/engine/Source/DataSources/Cesium3DTilesetGraphics.js b/packages/engine/Source/DataSources/Cesium3DTilesetGraphics.js index 3caf31975b3..6eb239dd7e6 100644 --- a/packages/engine/Source/DataSources/Cesium3DTilesetGraphics.js +++ b/packages/engine/Source/DataSources/Cesium3DTilesetGraphics.js @@ -5,7 +5,7 @@ import Event from "../Core/Event.js"; import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} Cesium3DTilesetGraphics.ConstructorOptions + * @typedef {object} Cesium3DTilesetGraphics.ConstructorOptions * * Initialization options for the Cesium3DTilesetGraphics constructor * diff --git a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js index 36b6487505b..f0c5a9f794d 100644 --- a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js +++ b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js @@ -47,7 +47,7 @@ function Cesium3DTilesetVisualizer(scene, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ Cesium3DTilesetVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -127,7 +127,7 @@ Cesium3DTilesetVisualizer.prototype.update = function (time) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ Cesium3DTilesetVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/CheckerboardMaterialProperty.js b/packages/engine/Source/DataSources/CheckerboardMaterialProperty.js index c60116fb162..547e29eafba 100644 --- a/packages/engine/Source/DataSources/CheckerboardMaterialProperty.js +++ b/packages/engine/Source/DataSources/CheckerboardMaterialProperty.js @@ -15,7 +15,7 @@ const defaultRepeat = new Cartesian2(2.0, 2.0); * @alias CheckerboardMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Color} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. * @param {Property|Color} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. * @param {Property|Cartesian2} [options.repeat=new Cartesian2(2.0, 2.0)] A {@link Cartesian2} Property specifying how many times the tiles repeat in each direction. @@ -42,7 +42,7 @@ Object.defineProperties(CheckerboardMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof CheckerboardMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -99,7 +99,7 @@ Object.defineProperties(CheckerboardMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ CheckerboardMaterialProperty.prototype.getType = function (time) { return "Checkerboard"; @@ -109,8 +109,8 @@ CheckerboardMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ CheckerboardMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -137,7 +137,7 @@ CheckerboardMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ CheckerboardMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/ColorMaterialProperty.js b/packages/engine/Source/DataSources/ColorMaterialProperty.js index f5e60c7dd5f..c6abf36e56d 100644 --- a/packages/engine/Source/DataSources/ColorMaterialProperty.js +++ b/packages/engine/Source/DataSources/ColorMaterialProperty.js @@ -26,7 +26,7 @@ Object.defineProperties(ColorMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof ColorMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -63,7 +63,7 @@ Object.defineProperties(ColorMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ ColorMaterialProperty.prototype.getType = function (time) { return "Color"; @@ -73,8 +73,8 @@ ColorMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ ColorMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -94,7 +94,7 @@ ColorMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ColorMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/CompositeEntityCollection.js b/packages/engine/Source/DataSources/CompositeEntityCollection.js index ff0cf4d86b5..56dcf75fc3c 100644 --- a/packages/engine/Source/DataSources/CompositeEntityCollection.js +++ b/packages/engine/Source/DataSources/CompositeEntityCollection.js @@ -157,7 +157,7 @@ Object.defineProperties(CompositeEntityCollection.prototype, { * Gets a globally unique identifier for this collection. * @memberof CompositeEntityCollection.prototype * @readonly - * @type {String} + * @type {string} */ id: { get: function () { @@ -193,7 +193,7 @@ Object.defineProperties(CompositeEntityCollection.prototype, { * Adds a collection to the composite. * * @param {EntityCollection} collection the collection to add. - * @param {Number} [index] the index to add the collection at. If omitted, the collection will + * @param {number} [index] the index to add the collection at. If omitted, the collection will * added on top of all existing collections. * * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of collections. @@ -232,7 +232,7 @@ CompositeEntityCollection.prototype.addCollection = function ( * Removes a collection from this composite, if present. * * @param {EntityCollection} collection The collection to remove. - * @returns {Boolean} true if the collection was in the composite and was removed, + * @returns {boolean} true if the collection was in the composite and was removed, * false if the collection was not in the composite. */ CompositeEntityCollection.prototype.removeCollection = function (collection) { @@ -257,7 +257,7 @@ CompositeEntityCollection.prototype.removeAllCollections = function () { * Checks to see if the composite contains a given collection. * * @param {EntityCollection} collection the collection to check for. - * @returns {Boolean} true if the composite contains the collection, false otherwise. + * @returns {boolean} true if the composite contains the collection, false otherwise. */ CompositeEntityCollection.prototype.containsCollection = function (collection) { return this._collections.indexOf(collection) !== -1; @@ -267,7 +267,7 @@ CompositeEntityCollection.prototype.containsCollection = function (collection) { * Returns true if the provided entity is in this collection, false otherwise. * * @param {Entity} entity The entity. - * @returns {Boolean} true if the provided entity is in this collection, false otherwise. + * @returns {boolean} true if the provided entity is in this collection, false otherwise. */ CompositeEntityCollection.prototype.contains = function (entity) { return this._composite.contains(entity); @@ -277,7 +277,7 @@ CompositeEntityCollection.prototype.contains = function (entity) { * Determines the index of a given collection in the composite. * * @param {EntityCollection} collection The collection to find the index of. - * @returns {Number} The index of the collection in the composite, or -1 if the collection does not exist in the composite. + * @returns {number} The index of the collection in the composite, or -1 if the collection does not exist in the composite. */ CompositeEntityCollection.prototype.indexOfCollection = function (collection) { return this._collections.indexOf(collection); @@ -286,7 +286,7 @@ CompositeEntityCollection.prototype.indexOfCollection = function (collection) { /** * Gets a collection by index from the composite. * - * @param {Number} index the index to retrieve. + * @param {number} index the index to retrieve. */ CompositeEntityCollection.prototype.getCollection = function (index) { //>>includeStart('debug', pragmas.debug); @@ -462,7 +462,7 @@ CompositeEntityCollection.prototype.computeAvailability = function () { /** * Gets an entity with the specified id. * - * @param {String} id The id of the entity to retrieve. + * @param {string} id The id of the entity to retrieve. * @returns {Entity|undefined} The entity with the provided id or undefined if the id did not exist in the collection. */ CompositeEntityCollection.prototype.getById = function (id) { diff --git a/packages/engine/Source/DataSources/CompositeMaterialProperty.js b/packages/engine/Source/DataSources/CompositeMaterialProperty.js index 00528197d20..7827c7ad61f 100644 --- a/packages/engine/Source/DataSources/CompositeMaterialProperty.js +++ b/packages/engine/Source/DataSources/CompositeMaterialProperty.js @@ -25,7 +25,7 @@ Object.defineProperties(CompositeMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof CompositeMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -64,7 +64,7 @@ Object.defineProperties(CompositeMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ CompositeMaterialProperty.prototype.getType = function (time) { //>>includeStart('debug', pragmas.debug); @@ -86,8 +86,8 @@ CompositeMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ CompositeMaterialProperty.prototype.getValue = function (time, result) { //>>includeStart('debug', pragmas.debug); @@ -110,7 +110,7 @@ CompositeMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ CompositeMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/CompositePositionProperty.js b/packages/engine/Source/DataSources/CompositePositionProperty.js index d8f5c9bd49c..e5e74a7951e 100644 --- a/packages/engine/Source/DataSources/CompositePositionProperty.js +++ b/packages/engine/Source/DataSources/CompositePositionProperty.js @@ -30,7 +30,7 @@ Object.defineProperties(CompositePositionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof CompositePositionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -129,7 +129,7 @@ CompositePositionProperty.prototype.getValueInReferenceFrame = function ( * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ CompositePositionProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/CompositeProperty.js b/packages/engine/Source/DataSources/CompositeProperty.js index 16033145b4a..703d7d5df47 100644 --- a/packages/engine/Source/DataSources/CompositeProperty.js +++ b/packages/engine/Source/DataSources/CompositeProperty.js @@ -68,7 +68,7 @@ Object.defineProperties(CompositeProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof CompositeProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -107,8 +107,8 @@ Object.defineProperties(CompositeProperty.prototype, { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ CompositeProperty.prototype.getValue = function (time, result) { //>>includeStart('debug', pragmas.debug); @@ -129,7 +129,7 @@ CompositeProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ CompositeProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/ConstantPositionProperty.js b/packages/engine/Source/DataSources/ConstantPositionProperty.js index 461591cdd82..7fe47c720e8 100644 --- a/packages/engine/Source/DataSources/ConstantPositionProperty.js +++ b/packages/engine/Source/DataSources/ConstantPositionProperty.js @@ -28,7 +28,7 @@ Object.defineProperties(ConstantPositionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof ConstantPositionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -69,8 +69,8 @@ Object.defineProperties(ConstantPositionProperty.prototype, { * Gets the value of the property at the provided time in the fixed frame. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ ConstantPositionProperty.prototype.getValue = function (time, result) { return this.getValueInReferenceFrame(time, ReferenceFrame.FIXED, result); @@ -133,7 +133,7 @@ ConstantPositionProperty.prototype.getValueInReferenceFrame = function ( * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ConstantPositionProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/ConstantProperty.js b/packages/engine/Source/DataSources/ConstantProperty.js index 77370306541..79cbec143a3 100644 --- a/packages/engine/Source/DataSources/ConstantProperty.js +++ b/packages/engine/Source/DataSources/ConstantProperty.js @@ -25,7 +25,7 @@ Object.defineProperties(ConstantProperty.prototype, { * This property always returns <code>true</code>. * @memberof ConstantProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -51,8 +51,8 @@ Object.defineProperties(ConstantProperty.prototype, { * Gets the value of the property. * * @param {JulianDate} [time] The time for which to retrieve the value. This parameter is unused since the value does not change with respect to time. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ ConstantProperty.prototype.getValue = function (time, result) { return this._hasClone ? this._value.clone(result) : this._value; @@ -85,7 +85,7 @@ ConstantProperty.prototype.setValue = function (value) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ConstantProperty.prototype.equals = function (other) { return ( @@ -108,7 +108,7 @@ ConstantProperty.prototype.valueOf = function () { /** * Creates a string representing this property's value. * - * @returns {String} A string representing the property's value. + * @returns {string} A string representing the property's value. */ ConstantProperty.prototype.toString = function () { return String(this._value); diff --git a/packages/engine/Source/DataSources/CorridorGraphics.js b/packages/engine/Source/DataSources/CorridorGraphics.js index 9858c8c8e72..b33c6ee21cd 100644 --- a/packages/engine/Source/DataSources/CorridorGraphics.js +++ b/packages/engine/Source/DataSources/CorridorGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} CorridorGraphics.ConstructorOptions + * @typedef {object} CorridorGraphics.ConstructorOptions * * Initialization options for the CorridorGraphics constructor * diff --git a/packages/engine/Source/DataSources/CustomDataSource.js b/packages/engine/Source/DataSources/CustomDataSource.js index 94a896ab742..a853be4c438 100644 --- a/packages/engine/Source/DataSources/CustomDataSource.js +++ b/packages/engine/Source/DataSources/CustomDataSource.js @@ -11,7 +11,7 @@ import EntityCollection from "./EntityCollection.js"; * @alias CustomDataSource * @constructor * - * @param {String} [name] A human-readable name for this instance. + * @param {string} [name] A human-readable name for this instance. * * @example * const dataSource = new Cesium.CustomDataSource('myData'); @@ -40,7 +40,7 @@ Object.defineProperties(CustomDataSource.prototype, { /** * Gets or sets a human-readable name for this instance. * @memberof CustomDataSource.prototype - * @type {String} + * @type {string} */ name: { get: function () { @@ -82,7 +82,7 @@ Object.defineProperties(CustomDataSource.prototype, { /** * Gets or sets whether the data source is currently loading data. * @memberof CustomDataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: function () { @@ -125,7 +125,7 @@ Object.defineProperties(CustomDataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof CustomDataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -164,7 +164,7 @@ Object.defineProperties(CustomDataSource.prototype, { * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ CustomDataSource.prototype.update = function (time) { return true; diff --git a/packages/engine/Source/DataSources/CylinderGraphics.js b/packages/engine/Source/DataSources/CylinderGraphics.js index fd9935367d9..9f25286c042 100644 --- a/packages/engine/Source/DataSources/CylinderGraphics.js +++ b/packages/engine/Source/DataSources/CylinderGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} CylinderGraphics.ConstructorOptions + * @typedef {object} CylinderGraphics.ConstructorOptions * * Initialization options for the CylinderGraphics constructor * diff --git a/packages/engine/Source/DataSources/CzmlDataSource.js b/packages/engine/Source/DataSources/CzmlDataSource.js index 5d38d99591f..3c3e6dab676 100644 --- a/packages/engine/Source/DataSources/CzmlDataSource.js +++ b/packages/engine/Source/DataSources/CzmlDataSource.js @@ -4824,7 +4824,7 @@ function DocumentPacket() { } /** - * @typedef {Object} CzmlDataSource.LoadOptions + * @typedef {object} CzmlDataSource.LoadOptions * * Initialization options for the <code>load</code> method. * @@ -4837,7 +4837,7 @@ function DocumentPacket() { * @alias CzmlDataSource * @constructor * - * @param {String} [name] An optional name for the data source. This value will be overwritten if a loaded document contains a name. + * @param {string} [name] An optional name for the data source. This value will be overwritten if a loaded document contains a name. * * @demo {@link https://sandcastle.cesium.com/index.html?src=CZML.html|Cesium Sandcastle CZML Demo} */ @@ -4859,10 +4859,10 @@ function CzmlDataSource(name) { /** * Creates a Promise to a new instance loaded with the provided CZML data. * - * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Resource|string|Object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<CzmlDataSource>} A promise that resolves to the new instance once the data is processed. + * @returns {Promise<CzmlDataSource>} A promise that resolves to the new instance once the data is processed. */ CzmlDataSource.load = function (czml, options) { return new CzmlDataSource().load(czml, options); @@ -4872,7 +4872,7 @@ Object.defineProperties(CzmlDataSource.prototype, { /** * Gets a human-readable name for this instance. * @memberof CzmlDataSource.prototype - * @type {String} + * @type {string} */ name: { get: function () { @@ -4904,7 +4904,7 @@ Object.defineProperties(CzmlDataSource.prototype, { /** * Gets a value indicating if the data source is currently loading data. * @memberof CzmlDataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: function () { @@ -4944,7 +4944,7 @@ Object.defineProperties(CzmlDataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof CzmlDataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -4993,7 +4993,7 @@ Object.defineProperties(CzmlDataSource.prototype, { * collection based on the provided CZML packet. * * @param {Entity} entity - * @param {Object} packet + * @param {object} packet * @param {EntityCollection} entityCollection * @param {string} sourceUri */ @@ -5001,7 +5001,7 @@ Object.defineProperties(CzmlDataSource.prototype, { /** * Gets the array of CZML processing functions. * @memberof CzmlDataSource - * @type {Array.<CzmlDataSource.UpdaterFunction>} + * @type {CzmlDataSource.UpdaterFunction[]} */ CzmlDataSource.updaters = [ processBillboard, // @@ -5032,10 +5032,10 @@ CzmlDataSource.updaters = [ /** * Processes the provided url or CZML object without clearing any existing data. * - * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Resource|string|Object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. + * @returns {Promise<CzmlDataSource>} A promise that resolves to this instances once the data is processed. */ CzmlDataSource.prototype.process = function (czml, options) { return load(this, czml, options, false); @@ -5044,10 +5044,10 @@ CzmlDataSource.prototype.process = function (czml, options) { /** * Loads the provided url or CZML object, replacing any existing data. * - * @param {Resource|String|Object} czml A url or CZML object to be processed. + * @param {Resource|string|Object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<CzmlDataSource>} A promise that resolves to this instances once the data is processed. + * @returns {Promise<CzmlDataSource>} A promise that resolves to this instances once the data is processed. */ CzmlDataSource.prototype.load = function (czml, options) { return load(this, czml, options, true); @@ -5060,7 +5060,7 @@ CzmlDataSource.prototype.load = function (czml, options) { * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ CzmlDataSource.prototype.update = function (time) { return true; @@ -5072,11 +5072,11 @@ CzmlDataSource.prototype.update = function (time) { * @function * * @param {Function} type The constructor function for the property being processed. - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. + * @param {object} object The object on which the property will be added or updated. + * @param {string} propertyName The name of the property on the object. + * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. + * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processPacketData = processPacketData; @@ -5086,11 +5086,11 @@ CzmlDataSource.processPacketData = processPacketData; * which creates or updates a {@link PositionProperty} from a CZML packet. * @function * - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. + * @param {object} object The object on which the property will be added or updated. + * @param {string} propertyName The name of the property on the object. + * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. + * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processPositionPacketData = processPositionPacketData; @@ -5100,11 +5100,11 @@ CzmlDataSource.processPositionPacketData = processPositionPacketData; * which creates or updates a {@link MaterialProperty} from a CZML packet. * @function * - * @param {Object} object The object on which the property will be added or updated. - * @param {String} propertyName The name of the property on the object. - * @param {Object} packetData The CZML packet being processed. + * @param {object} object The object on which the property will be added or updated. + * @param {string} propertyName The name of the property on the object. + * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. - * @param {String} sourceUri The originating uri of the data being processed. + * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processMaterialPacketData = processMaterialPacketData; diff --git a/packages/engine/Source/DataSources/DataSource.js b/packages/engine/Source/DataSources/DataSource.js index 4ac76037172..8f72f258ae5 100644 --- a/packages/engine/Source/DataSources/DataSource.js +++ b/packages/engine/Source/DataSources/DataSource.js @@ -18,7 +18,7 @@ Object.defineProperties(DataSource.prototype, { /** * Gets a human-readable name for this instance. * @memberof DataSource.prototype - * @type {String} + * @type {string} */ name: { get: DeveloperError.throwInstantiationError, @@ -42,7 +42,7 @@ Object.defineProperties(DataSource.prototype, { /** * Gets a value indicating if the data source is currently loading data. * @memberof DataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: DeveloperError.throwInstantiationError, @@ -74,7 +74,7 @@ Object.defineProperties(DataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof DataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: DeveloperError.throwInstantiationError, @@ -98,7 +98,7 @@ Object.defineProperties(DataSource.prototype, { * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ DataSource.prototype.update = function (time) { DeveloperError.throwInstantiationError(); diff --git a/packages/engine/Source/DataSources/DataSourceClock.js b/packages/engine/Source/DataSources/DataSourceClock.js index f267a4bafa6..58d55e2a3f0 100644 --- a/packages/engine/Source/DataSources/DataSourceClock.js +++ b/packages/engine/Source/DataSources/DataSourceClock.js @@ -81,7 +81,7 @@ Object.defineProperties(DataSourceClock.prototype, { * Gets or sets the desired clock multiplier. * See {@link Clock#multiplier}. * @memberof DataSourceClock.prototype - * @type {Number} + * @type {number} */ multiplier: createRawPropertyDescriptor("multiplier"), }); @@ -109,7 +109,7 @@ DataSourceClock.prototype.clone = function (result) { * Returns true if this DataSourceClock is equivalent to the other * * @param {DataSourceClock} other The other DataSourceClock to compare to. - * @returns {Boolean} <code>true</code> if the DataSourceClocks are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the DataSourceClocks are equal; otherwise, <code>false</code>. */ DataSourceClock.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/DataSourceCollection.js b/packages/engine/Source/DataSources/DataSourceCollection.js index 46ca82cba16..17e33f50b45 100644 --- a/packages/engine/Source/DataSources/DataSourceCollection.js +++ b/packages/engine/Source/DataSources/DataSourceCollection.js @@ -21,7 +21,7 @@ Object.defineProperties(DataSourceCollection.prototype, { /** * Gets the number of data sources in this collection. * @memberof DataSourceCollection.prototype - * @type {Number} + * @type {number} * @readonly */ length: { @@ -73,10 +73,10 @@ Object.defineProperties(DataSourceCollection.prototype, { /** * Adds a data source to the collection. * - * @param {DataSource|Promise.<DataSource>} dataSource A data source or a promise to a data source to add to the collection. + * @param {DataSource|Promise<DataSource>} dataSource A data source or a promise to a data source to add to the collection. * When passing a promise, the data source will not actually be added * to the collection until the promise resolves successfully. - * @returns {Promise.<DataSource>} A Promise that resolves once the data source has been added to the collection. + * @returns {Promise<DataSource>} A Promise that resolves once the data source has been added to the collection. */ DataSourceCollection.prototype.add = function (dataSource) { //>>includeStart('debug', pragmas.debug); @@ -102,8 +102,8 @@ DataSourceCollection.prototype.add = function (dataSource) { * Removes a data source from this collection, if present. * * @param {DataSource} dataSource The data source to remove. - * @param {Boolean} [destroy=false] Whether to destroy the data source in addition to removing it. - * @returns {Boolean} true if the data source was in the collection and was removed, + * @param {boolean} [destroy=false] Whether to destroy the data source in addition to removing it. + * @returns {boolean} true if the data source was in the collection and was removed, * false if the data source was not in the collection. */ DataSourceCollection.prototype.remove = function (dataSource, destroy) { @@ -127,7 +127,7 @@ DataSourceCollection.prototype.remove = function (dataSource, destroy) { /** * Removes all data sources from this collection. * - * @param {Boolean} [destroy=false] whether to destroy the data sources in addition to removing them. + * @param {boolean} [destroy=false] whether to destroy the data sources in addition to removing them. */ DataSourceCollection.prototype.removeAll = function (destroy) { destroy = defaultValue(destroy, false); @@ -148,7 +148,7 @@ DataSourceCollection.prototype.removeAll = function (destroy) { * Checks to see if the collection contains a given data source. * * @param {DataSource} dataSource The data source to check for. - * @returns {Boolean} true if the collection contains the data source, false otherwise. + * @returns {boolean} true if the collection contains the data source, false otherwise. */ DataSourceCollection.prototype.contains = function (dataSource) { return this.indexOf(dataSource) !== -1; @@ -158,7 +158,7 @@ DataSourceCollection.prototype.contains = function (dataSource) { * Determines the index of a given data source in the collection. * * @param {DataSource} dataSource The data source to find the index of. - * @returns {Number} The index of the data source in the collection, or -1 if the data source does not exist in the collection. + * @returns {number} The index of the data source in the collection, or -1 if the data source does not exist in the collection. */ DataSourceCollection.prototype.indexOf = function (dataSource) { return this._dataSources.indexOf(dataSource); @@ -167,7 +167,7 @@ DataSourceCollection.prototype.indexOf = function (dataSource) { /** * Gets a data source by index from the collection. * - * @param {Number} index the index to retrieve. + * @param {number} index the index to retrieve. * @returns {DataSource} The data source at the specified index. */ DataSourceCollection.prototype.get = function (index) { @@ -183,7 +183,7 @@ DataSourceCollection.prototype.get = function (index) { /** * Gets a data source by name from the collection. * - * @param {String} name The name to retrieve. + * @param {string} name The name to retrieve. * @returns {DataSource[]} A list of all data sources matching the provided name. */ DataSourceCollection.prototype.getByName = function (name) { @@ -306,7 +306,7 @@ DataSourceCollection.prototype.lowerToBottom = function (dataSource) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} true if this object was destroyed; otherwise, false. + * @returns {boolean} true if this object was destroyed; otherwise, false. * * @see DataSourceCollection#destroy */ diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index ccf908f322b..691855fff52 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -25,7 +25,7 @@ import PolylineVisualizer from "./PolylineVisualizer.js"; * @alias DataSourceDisplay * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Scene} options.scene The scene in which to display the data. * @param {DataSourceCollection} options.dataSourceCollection The data sources to display. * @param {DataSourceDisplay.VisualizersCallback} [options.visualizersCallback=DataSourceDisplay.defaultVisualizersCallback] @@ -192,7 +192,7 @@ Object.defineProperties(DataSourceDisplay.prototype, { /** * Gets a value indicating whether or not all entities in the data source are ready * @memberof DataSourceDisplay.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -208,7 +208,7 @@ Object.defineProperties(DataSourceDisplay.prototype, { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see DataSourceDisplay#destroy */ @@ -259,7 +259,7 @@ DataSourceDisplay.prototype.destroy = function () { * Updates the display to the provided time. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if all data sources are ready to be displayed, false otherwise. + * @returns {boolean} True if all data sources are ready to be displayed, false otherwise. */ DataSourceDisplay.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -335,7 +335,7 @@ const getBoundingSphereBoundingSphereScratch = new BoundingSphere(); * The bounding sphere is in the fixed frame of the scene's globe. * * @param {Entity} entity The entity whose bounding sphere to compute. - * @param {Boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. + * @param {boolean} allowPartial If true, pending bounding spheres are ignored and an answer will be returned from the currently available data. * If false, the the function will halt and return pending if any of the bounding spheres are pending. * @param {BoundingSphere} result The bounding sphere onto which to store the result. * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere, diff --git a/packages/engine/Source/DataSources/DynamicGeometryUpdater.js b/packages/engine/Source/DataSources/DynamicGeometryUpdater.js index caa202a93a8..23963ef14fa 100644 --- a/packages/engine/Source/DataSources/DynamicGeometryUpdater.js +++ b/packages/engine/Source/DataSources/DynamicGeometryUpdater.js @@ -247,7 +247,7 @@ DynamicGeometryUpdater.prototype.getBoundingSphere = function (result) { * @memberof DynamicGeometryUpdater * @function * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ DynamicGeometryUpdater.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/EllipseGraphics.js b/packages/engine/Source/DataSources/EllipseGraphics.js index 86a2adfab7b..4c85aee9acf 100644 --- a/packages/engine/Source/DataSources/EllipseGraphics.js +++ b/packages/engine/Source/DataSources/EllipseGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} EllipseGraphics.ConstructorOptions + * @typedef {object} EllipseGraphics.ConstructorOptions * * Initialization options for the EllipseGraphics constructor * diff --git a/packages/engine/Source/DataSources/EllipsoidGeometryUpdater.js b/packages/engine/Source/DataSources/EllipsoidGeometryUpdater.js index f67ef84aa8d..8984d6ea1d3 100644 --- a/packages/engine/Source/DataSources/EllipsoidGeometryUpdater.js +++ b/packages/engine/Source/DataSources/EllipsoidGeometryUpdater.js @@ -105,7 +105,7 @@ Object.defineProperties(EllipsoidGeometryUpdater.prototype, { * Creates the geometry instance which represents the fill of the geometry. * * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @param {Boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance + * @param {boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance * @param {Matrix4} [modelMatrixResult] Used to store the result of the model matrix calculation * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry. * @@ -189,7 +189,7 @@ EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function ( * Creates the geometry instance which represents the outline of the geometry. * * @param {JulianDate} time The time to use when retrieving initial attribute values. - * @param {Boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance + * @param {boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance * @param {Matrix4} [modelMatrixResult] Used to store the result of the model matrix calculation * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry. * diff --git a/packages/engine/Source/DataSources/EllipsoidGraphics.js b/packages/engine/Source/DataSources/EllipsoidGraphics.js index 23d2fd970af..ea68b330a75 100644 --- a/packages/engine/Source/DataSources/EllipsoidGraphics.js +++ b/packages/engine/Source/DataSources/EllipsoidGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} EllipsoidGraphics.ConstructorOptions + * @typedef {object} EllipsoidGraphics.ConstructorOptions * * Initialization options for the EllipsoidGraphics constructor * diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index ab803c910ca..a781ce8503d 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -61,14 +61,14 @@ function createPropertyTypeDescriptor(name, Type) { } /** - * @typedef {Object} Entity.ConstructorOptions + * @typedef {object} Entity.ConstructorOptions * * Initialization options for the Entity constructor * - * @property {String} [id] A unique identifier for this object. If none is provided, a GUID is generated. - * @property {String} [name] A human readable name to display to users. It does not have to be unique. + * @property {string} [id] A unique identifier for this object. If none is provided, a GUID is generated. + * @property {string} [name] A human readable name to display to users. It does not have to be unique. * @property {TimeIntervalCollection} [availability] The availability, if any, associated with this object. - * @property {Boolean} [show] A boolean value indicating if the entity and its children are displayed. + * @property {boolean} [show] A boolean value indicating if the entity and its children are displayed. * @property {Property | string} [description] A string Property specifying an HTML description for this entity. * @property {PositionProperty | Cartesian3} [position] A Property specifying the entity position. * @property {Property} [orientation] A Property specifying the entity orientation. @@ -233,7 +233,7 @@ Object.defineProperties(Entity.prototype, { /** * Gets the unique ID associated with this object. * @memberof Entity.prototype - * @type {String} + * @type {string} */ id: { get: function () { @@ -256,14 +256,14 @@ Object.defineProperties(Entity.prototype, { * Gets or sets the name of the object. The name is intended for end-user * consumption and does not need to be unique. * @memberof Entity.prototype - * @type {String|undefined} + * @type {string|undefined} */ name: createRawPropertyDescriptor("name"), /** * Gets or sets whether this entity should be displayed. When set to true, * the entity is only displayed if the parent entity's show property is also true. * @memberof Entity.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -295,7 +295,7 @@ Object.defineProperties(Entity.prototype, { * Gets whether this entity is being displayed, taking into account * the visibility of any ancestor entities. * @memberof Entity.prototype - * @type {Boolean} + * @type {boolean} */ isShowing: { get: function () { @@ -495,7 +495,7 @@ Object.defineProperties(Entity.prototype, { * Given a time, returns true if this object should have data during that time. * * @param {JulianDate} time The time to check availability for. - * @returns {Boolean} true if the object should have data during the provided time, false otherwise. + * @returns {boolean} true if the object should have data during the provided time, false otherwise. */ Entity.prototype.isAvailable = function (time) { //>>includeStart('debug', pragmas.debug); @@ -513,7 +513,7 @@ Entity.prototype.isAvailable = function (time) { * observed with {@link Entity#definitionChanged} and composited * with {@link CompositeEntityCollection} * - * @param {String} propertyName The name of the property to add. + * @param {string} propertyName The name of the property to add. * * @exception {DeveloperError} "propertyName" is a reserved property name. * @exception {DeveloperError} "propertyName" is already a registered property. @@ -546,7 +546,7 @@ Entity.prototype.addProperty = function (propertyName) { /** * Removed a property previously added with addProperty. * - * @param {String} propertyName The name of the property to remove. + * @param {string} propertyName The name of the property to remove. * * @exception {DeveloperError} "propertyName" is a reserved property name. * @exception {DeveloperError} "propertyName" is not a registered property. @@ -732,7 +732,7 @@ Entity.prototype.computeModelMatrixForHeightReference = function ( * instead be rendered as if height is 0. * * @param {Scene} scene The current scene. - * @returns {Boolean} Whether or not the current scene supports materials for entities on terrain. + * @returns {boolean} Whether or not the current scene supports materials for entities on terrain. */ Entity.supportsMaterialsforEntitiesOnTerrain = function (scene) { return GroundPrimitive.supportsMaterials(scene); @@ -744,7 +744,7 @@ Entity.supportsMaterialsforEntitiesOnTerrain = function (scene) { * the provided heights and using the `arcType` parameter instead of clamped to the ground. * * @param {Scene} scene The current scene. - * @returns {Boolean} Whether or not the current scene supports polylines on terrain or 3D TIles. + * @returns {boolean} Whether or not the current scene supports polylines on terrain or 3D TIles. */ Entity.supportsPolylinesOnTerrain = function (scene) { return GroundPolylinePrimitive.isSupported(scene); diff --git a/packages/engine/Source/DataSources/EntityCluster.js b/packages/engine/Source/DataSources/EntityCluster.js index 444eaa0e7ce..164aa48ca8e 100644 --- a/packages/engine/Source/DataSources/EntityCluster.js +++ b/packages/engine/Source/DataSources/EntityCluster.js @@ -18,14 +18,14 @@ import KDBush from "kdbush"; /** * Defines how screen space objects (billboards, points, labels) are clustered. * - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.enabled=false] Whether or not to enable clustering. - * @param {Number} [options.pixelRange=80] The pixel range to extend the screen space bounding box. - * @param {Number} [options.minimumClusterSize=2] The minimum number of screen space objects that can be clustered. - * @param {Boolean} [options.clusterBillboards=true] Whether or not to cluster the billboards of an entity. - * @param {Boolean} [options.clusterLabels=true] Whether or not to cluster the labels of an entity. - * @param {Boolean} [options.clusterPoints=true] Whether or not to cluster the points of an entity. - * @param {Boolean} [options.show=true] Determines if the entities in the cluster will be shown. + * @param {object} [options] An object with the following properties: + * @param {boolean} [options.enabled=false] Whether or not to enable clustering. + * @param {number} [options.pixelRange=80] The pixel range to extend the screen space bounding box. + * @param {number} [options.minimumClusterSize=2] The minimum number of screen space objects that can be clustered. + * @param {boolean} [options.clusterBillboards=true] Whether or not to cluster the billboards of an entity. + * @param {boolean} [options.clusterLabels=true] Whether or not to cluster the labels of an entity. + * @param {boolean} [options.clusterPoints=true] Whether or not to cluster the points of an entity. + * @param {boolean} [options.show=true] Determines if the entities in the cluster will be shown. * * @alias EntityCluster * @constructor @@ -70,7 +70,7 @@ function EntityCluster(options) { /** * Determines if entities in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -517,7 +517,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets whether clustering is enabled. * @memberof EntityCluster.prototype - * @type {Boolean} + * @type {boolean} */ enabled: { get: function () { @@ -531,7 +531,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets the pixel range to extend the screen space bounding box. * @memberof EntityCluster.prototype - * @type {Number} + * @type {number} */ pixelRange: { get: function () { @@ -545,7 +545,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets the minimum number of screen space objects that can be clustered. * @memberof EntityCluster.prototype - * @type {Number} + * @type {number} */ minimumClusterSize: { get: function () { @@ -570,7 +570,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets whether clustering billboard entities is enabled. * @memberof EntityCluster.prototype - * @type {Boolean} + * @type {boolean} */ clusterBillboards: { get: function () { @@ -585,7 +585,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets whether clustering labels entities is enabled. * @memberof EntityCluster.prototype - * @type {Boolean} + * @type {boolean} */ clusterLabels: { get: function () { @@ -599,7 +599,7 @@ Object.defineProperties(EntityCluster.prototype, { /** * Gets or sets whether clustering point entities is enabled. * @memberof EntityCluster.prototype - * @type {Boolean} + * @type {boolean} */ clusterPoints: { get: function () { @@ -981,7 +981,7 @@ EntityCluster.prototype.destroy = function () { * @callback EntityCluster.newClusterCallback * * @param {Entity[]} clusteredEntities An array of the entities contained in the cluster. - * @param {Object} cluster An object containing the Billboard, Label, and Point + * @param {object} cluster An object containing the Billboard, Label, and Point * primitives that represent this cluster of entities. * @param {Billboard} cluster.billboard * @param {Label} cluster.label diff --git a/packages/engine/Source/DataSources/EntityCollection.js b/packages/engine/Source/DataSources/EntityCollection.js index f780851c6b9..5a3a3c1d670 100644 --- a/packages/engine/Source/DataSources/EntityCollection.js +++ b/packages/engine/Source/DataSources/EntityCollection.js @@ -128,7 +128,7 @@ Object.defineProperties(EntityCollection.prototype, { * Gets a globally unique identifier for this collection. * @memberof EntityCollection.prototype * @readonly - * @type {String} + * @type {string} */ id: { get: function () { @@ -152,7 +152,7 @@ Object.defineProperties(EntityCollection.prototype, { * displayed. When true, each entity is only displayed if * its own show property is also true. * @memberof EntityCollection.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -305,7 +305,7 @@ EntityCollection.prototype.add = function (entity) { * Removes an entity from the collection. * * @param {Entity} entity The entity to be removed. - * @returns {Boolean} true if the item was removed, false if it did not exist in the collection. + * @returns {boolean} true if the item was removed, false if it did not exist in the collection. */ EntityCollection.prototype.remove = function (entity) { if (!defined(entity)) { @@ -318,7 +318,7 @@ EntityCollection.prototype.remove = function (entity) { * Returns true if the provided entity is in this collection, false otherwise. * * @param {Entity} entity The entity. - * @returns {Boolean} true if the provided entity is in this collection, false otherwise. + * @returns {boolean} true if the provided entity is in this collection, false otherwise. */ EntityCollection.prototype.contains = function (entity) { //>>includeStart('debug', pragmas.debug); @@ -332,8 +332,8 @@ EntityCollection.prototype.contains = function (entity) { /** * Removes an entity with the provided id from the collection. * - * @param {String} id The id of the entity to remove. - * @returns {Boolean} true if the item was removed, false if no item with the provided id existed in the collection. + * @param {string} id The id of the entity to remove. + * @returns {boolean} true if the item was removed, false if no item with the provided id existed in the collection. */ EntityCollection.prototype.removeById = function (id) { if (!defined(id)) { @@ -395,7 +395,7 @@ EntityCollection.prototype.removeAll = function () { /** * Gets an entity with the specified id. * - * @param {String} id The id of the entity to retrieve. + * @param {string} id The id of the entity to retrieve. * @returns {Entity|undefined} The entity with the provided id or undefined if the id did not exist in the collection. */ EntityCollection.prototype.getById = function (id) { @@ -411,7 +411,7 @@ EntityCollection.prototype.getById = function (id) { /** * Gets an entity with the specified id or creates it and adds it to the collection if it does not exist. * - * @param {String} id The id of the entity to retrieve or create. + * @param {string} id The id of the entity to retrieve or create. * @returns {Entity} The new or existing object. */ EntityCollection.prototype.getOrCreateEntity = function (id) { diff --git a/packages/engine/Source/DataSources/GeoJsonDataSource.js b/packages/engine/Source/DataSources/GeoJsonDataSource.js index 4c465f677cb..c7670c904b8 100644 --- a/packages/engine/Source/DataSources/GeoJsonDataSource.js +++ b/packages/engine/Source/DataSources/GeoJsonDataSource.js @@ -550,20 +550,20 @@ function processTopology(dataSource, geoJson, geometry, crsFunction, options) { } /** - * @typedef {Object} GeoJsonDataSource.LoadOptions + * @typedef {object} GeoJsonDataSource.LoadOptions * * Initialization options for the <code>load</code> method. * - * @property {String} [sourceUri] Overrides the url to use for resolving relative links. + * @property {string} [sourceUri] Overrides the url to use for resolving relative links. * @property {GeoJsonDataSource.describe} [describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string). - * @property {Number} [markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. - * @property {String} [markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. + * @property {number} [markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels. + * @property {string} [markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point. * @property {Color} [markerColor=GeoJsonDataSource.markerColor] The default color of the map pin created for each point. * @property {Color} [stroke=GeoJsonDataSource.stroke] The default color of polylines and polygon outlines. - * @property {Number} [strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. + * @property {number} [strokeWidth=GeoJsonDataSource.strokeWidth] The default width of polylines and polygon outlines. * @property {Color} [fill=GeoJsonDataSource.fill] The default color for polygon interiors. - * @property {Boolean} [clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {boolean} [clampToGround=GeoJsonDataSource.clampToGround] true if we want the geometry features (polygons or linestrings) clamped to the ground. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. */ /** @@ -575,7 +575,7 @@ function processTopology(dataSource, geoJson, geometry, crsFunction, options) { * @alias GeoJsonDataSource * @constructor * - * @param {String} [name] The name of this data source. If undefined, a name will be taken from + * @param {string} [name] The name of this data source. If undefined, a name will be taken from * the name of the GeoJSON file. * * @demo {@link https://sandcastle.cesium.com/index.html?src=GeoJSON%20and%20TopoJSON.html|Cesium Sandcastle GeoJSON and TopoJSON Demo} @@ -607,10 +607,10 @@ function GeoJsonDataSource(name) { /** * Creates a Promise to a new instance loaded with the provided GeoJSON or TopoJSON data. * - * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<GeoJsonDataSource>} A promise that will resolve when the data is loaded. + * @returns {Promise<GeoJsonDataSource>} A promise that will resolve when the data is loaded. */ GeoJsonDataSource.load = function (data, options) { return new GeoJsonDataSource().load(data, options); @@ -620,7 +620,7 @@ Object.defineProperties(GeoJsonDataSource, { /** * Gets or sets the default size of the map pin created for each point, in pixels. * @memberof GeoJsonDataSource - * @type {Number} + * @type {number} * @default 48 */ markerSize: { @@ -636,7 +636,7 @@ Object.defineProperties(GeoJsonDataSource, { * This can be any valid {@link http://mapbox.com/maki/|Maki} identifier, any single character, * or blank if no symbol is to be used. * @memberof GeoJsonDataSource - * @type {String} + * @type {string} */ markerSymbol: { get: function () { @@ -677,7 +677,7 @@ Object.defineProperties(GeoJsonDataSource, { /** * Gets or sets the default width of polylines and polygon outlines. * @memberof GeoJsonDataSource - * @type {Number} + * @type {number} * @default 2.0 */ strokeWidth: { @@ -705,7 +705,7 @@ Object.defineProperties(GeoJsonDataSource, { /** * Gets or sets default of whether to clamp to the ground. * @memberof GeoJsonDataSource - * @type {Boolean} + * @type {boolean} * @default false */ clampToGround: { @@ -723,7 +723,7 @@ Object.defineProperties(GeoJsonDataSource, { * supported the EPSG type can be added to this list as well, by specifying the complete EPSG name, * for example 'EPSG:4326'. * @memberof GeoJsonDataSource - * @type {Object} + * @type {object} */ crsNames: { get: function () { @@ -738,7 +738,7 @@ Object.defineProperties(GeoJsonDataSource, { * Items in this object take precedence over those defined in <code>crsLinkHrefs</code>, assuming * the link has a type specified. * @memberof GeoJsonDataSource - * @type {Object} + * @type {object} */ crsLinkHrefs: { get: function () { @@ -752,7 +752,7 @@ Object.defineProperties(GeoJsonDataSource, { * to a function that takes a GeoJSON coordinate and transforms it into a WGS84 Earth-fixed Cartesian. * Items in <code>crsLinkHrefs</code> take precedence over this object. * @memberof GeoJsonDataSource - * @type {Object} + * @type {object} */ crsLinkTypes: { get: function () { @@ -765,7 +765,7 @@ Object.defineProperties(GeoJsonDataSource.prototype, { /** * Gets or sets a human-readable name for this instance. * @memberof GeoJsonDataSource.prototype - * @type {String} + * @type {string} */ name: { get: function () { @@ -800,7 +800,7 @@ Object.defineProperties(GeoJsonDataSource.prototype, { /** * Gets a value indicating if the data source is currently loading data. * @memberof GeoJsonDataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: function () { @@ -840,7 +840,7 @@ Object.defineProperties(GeoJsonDataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof GeoJsonDataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -885,10 +885,10 @@ Object.defineProperties(GeoJsonDataSource.prototype, { /** * Asynchronously loads the provided GeoJSON or TopoJSON data, replacing any existing data. * - * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. + * @returns {Promise<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. */ GeoJsonDataSource.prototype.load = function (data, options) { return preload(this, data, options, true); @@ -897,10 +897,10 @@ GeoJsonDataSource.prototype.load = function (data, options) { /** * Asynchronously loads the provided GeoJSON or TopoJSON data, without replacing any existing data. * - * @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. + * @returns {Promise<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. */ GeoJsonDataSource.prototype.process = function (data, options) { return preload(this, data, options, false); @@ -976,7 +976,7 @@ function preload(that, data, options, clear) { * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ GeoJsonDataSource.prototype.update = function (time) { return true; @@ -1058,7 +1058,7 @@ function load(that, geoJson, options, sourceUri, clear) { /** * This callback is displayed as part of the GeoJsonDataSource class. * @callback GeoJsonDataSource.describe - * @param {Object} properties The properties of the feature. - * @param {String} nameProperty The property key that Cesium estimates to have the name of the feature. + * @param {object} properties The properties of the feature. + * @param {string} nameProperty The property key that Cesium estimates to have the name of the feature. */ export default GeoJsonDataSource; diff --git a/packages/engine/Source/DataSources/GeometryUpdater.js b/packages/engine/Source/DataSources/GeometryUpdater.js index 85d5b5d6659..982f2c7fe48 100644 --- a/packages/engine/Source/DataSources/GeometryUpdater.js +++ b/packages/engine/Source/DataSources/GeometryUpdater.js @@ -31,12 +31,12 @@ const defaultClassificationType = new ConstantProperty(ClassificationType.BOTH); * @alias GeometryUpdater * @constructor * - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {Entity} options.entity The entity containing the geometry to be visualized. * @param {Scene} options.scene The scene where visualization is taking place. - * @param {Object} options.geometryOptions Options for the geometry - * @param {String} options.geometryPropertyName The geometry property name - * @param {String[]} options.observedPropertyNames The entity properties this geometry cares about + * @param {object} options.geometryOptions Options for the geometry + * @param {string} options.geometryPropertyName The geometry property name + * @param {string[]} options.observedPropertyNames The entity properties this geometry cares about */ function GeometryUpdater(options) { //>>includeStart('debug', pragmas.debug); @@ -79,7 +79,7 @@ Object.defineProperties(GeometryUpdater.prototype, { /** * Gets the unique ID associated with this updater * @memberof GeometryUpdater.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -103,7 +103,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Gets a value indicating if the geometry has a fill component. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ fillEnabled: { @@ -115,7 +115,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Gets a value indicating if fill visibility varies with simulation time. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ hasConstantFill: { @@ -144,7 +144,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Gets a value indicating if the geometry has an outline component. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ outlineEnabled: { @@ -156,7 +156,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Gets a value indicating if the geometry has an outline component. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ hasConstantOutline: { @@ -186,7 +186,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * This value is only valid if isDynamic is false. * @memberof GeometryUpdater.prototype * - * @type {Number} + * @type {number} * @readonly */ outlineWidth: { @@ -237,7 +237,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * returned by GeometryUpdater#createDynamicUpdater. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isDynamic: { @@ -250,7 +250,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * This property is only valid for static geometry. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isClosed: { @@ -262,7 +262,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Gets a value indicating if the geometry should be drawn on terrain. * @memberof EllipseGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ onTerrain: { @@ -275,7 +275,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * of this updater change. * @memberof GeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ geometryChanged: { @@ -289,7 +289,7 @@ Object.defineProperties(GeometryUpdater.prototype, { * Checks if the geometry is outlined at the provided time. * * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + * @returns {boolean} true if geometry is outlined at the provided time, false otherwise. */ GeometryUpdater.prototype.isOutlineVisible = function (time) { const entity = this._entity; @@ -305,7 +305,7 @@ GeometryUpdater.prototype.isOutlineVisible = function (time) { * Checks if the geometry is filled at the provided time. * * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + * @returns {boolean} true if geometry is filled at the provided time, false otherwise. */ GeometryUpdater.prototype.isFilled = function (time) { const entity = this._entity; @@ -344,7 +344,7 @@ GeometryUpdater.prototype.createOutlineGeometryInstance = /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ GeometryUpdater.prototype.isDestroyed = function () { return false; @@ -360,7 +360,7 @@ GeometryUpdater.prototype.destroy = function () { }; /** * @param {Entity} entity - * @param {Object} geometry + * @param {object} geometry * @private */ GeometryUpdater.prototype._isHidden = function (entity, geometry) { @@ -372,7 +372,7 @@ GeometryUpdater.prototype._isHidden = function (entity, geometry) { /** * @param {Entity} entity - * @param {Object} geometry + * @param {object} geometry * @private */ GeometryUpdater.prototype._isOnTerrain = function (entity, geometry) { @@ -389,14 +389,14 @@ GeometryUpdater.prototype._getIsClosed = function (options) { /** * @param {Entity} entity - * @param {Object} geometry + * @param {object} geometry * @private */ GeometryUpdater.prototype._isDynamic = DeveloperError.throwInstantiationError; /** * @param {Entity} entity - * @param {Object} geometry + * @param {object} geometry * @private */ GeometryUpdater.prototype._setStaticOptions = @@ -404,7 +404,7 @@ GeometryUpdater.prototype._setStaticOptions = /** * @param {Entity} entity - * @param {String} propertyName + * @param {string} propertyName * @param {*} newValue * @param {*} oldValue * @private diff --git a/packages/engine/Source/DataSources/GeometryVisualizer.js b/packages/engine/Source/DataSources/GeometryVisualizer.js index 63a65b327ec..71047894437 100644 --- a/packages/engine/Source/DataSources/GeometryVisualizer.js +++ b/packages/engine/Source/DataSources/GeometryVisualizer.js @@ -298,7 +298,7 @@ function GeometryVisualizer( * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} True if the visualizer successfully updated to the provided time, + * @returns {boolean} True if the visualizer successfully updated to the provided time, * false if the visualizer is waiting for asynchronous primitives to be created. */ GeometryVisualizer.prototype.update = function (time) { @@ -441,7 +441,7 @@ GeometryVisualizer.prototype.getBoundingSphere = function (entity, result) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ GeometryVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/GpxDataSource.js b/packages/engine/Source/DataSources/GpxDataSource.js index cd3b78cab7e..887af0f2c47 100644 --- a/packages/engine/Source/DataSources/GpxDataSource.js +++ b/packages/engine/Source/DataSources/GpxDataSource.js @@ -765,14 +765,14 @@ function GpxDataSource() { /** * Creates a Promise to a new instance loaded with the provided GPX data. * - * @param {String|Document|Blob} data A url, parsed GPX document, or Blob containing binary GPX data. - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.clampToGround] True if the symbols should be rendered at the same height as the terrain - * @param {String} [options.waypointImage] Image to use for waypoint billboards. - * @param {String} [options.trackImage] Image to use for track billboards. - * @param {String} [options.trackColor] Color to use for track lines. - * @param {String} [options.routeColor] Color to use for route lines. - * @returns {Promise.<GpxDataSource>} A promise that will resolve to a new GpxDataSource instance once the gpx is loaded. + * @param {string|Document|Blob} data A url, parsed GPX document, or Blob containing binary GPX data. + * @param {object} [options] An object with the following properties: + * @param {boolean} [options.clampToGround] True if the symbols should be rendered at the same height as the terrain + * @param {string} [options.waypointImage] Image to use for waypoint billboards. + * @param {string} [options.trackImage] Image to use for track billboards. + * @param {string} [options.trackColor] Color to use for track lines. + * @param {string} [options.routeColor] Color to use for route lines. + * @returns {Promise<GpxDataSource>} A promise that will resolve to a new GpxDataSource instance once the gpx is loaded. */ GpxDataSource.load = function (data, options) { return new GpxDataSource().load(data, options); @@ -783,7 +783,7 @@ Object.defineProperties(GpxDataSource.prototype, { * Gets a human-readable name for this instance. * This will be automatically be set to the GPX document name on load. * @memberof GpxDataSource.prototype - * @type {String} + * @type {string} */ name: { get: function () { @@ -793,7 +793,7 @@ Object.defineProperties(GpxDataSource.prototype, { /** * Gets the version of the GPX Schema in use. * @memberof GpxDataSource.prototype - * @type {String} + * @type {string} */ version: { get: function () { @@ -803,7 +803,7 @@ Object.defineProperties(GpxDataSource.prototype, { /** * Gets the creator of the GPX document. * @memberof GpxDataSource.prototype - * @type {String} + * @type {string} */ creator: { get: function () { @@ -813,7 +813,7 @@ Object.defineProperties(GpxDataSource.prototype, { /** * Gets an object containing metadata about the GPX file. * @memberof GpxDataSource.prototype - * @type {Object} + * @type {object} */ metadata: { get: function () { @@ -845,7 +845,7 @@ Object.defineProperties(GpxDataSource.prototype, { /** * Gets a value indicating if the data source is currently loading data. * @memberof GpxDataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: function () { @@ -885,7 +885,7 @@ Object.defineProperties(GpxDataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof GpxDataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -924,7 +924,7 @@ Object.defineProperties(GpxDataSource.prototype, { * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ GpxDataSource.prototype.update = function (time) { return true; @@ -933,14 +933,14 @@ GpxDataSource.prototype.update = function (time) { /** * Asynchronously loads the provided GPX data, replacing any existing data. * - * @param {String|Document|Blob} data A url, parsed GPX document, or Blob containing binary GPX data or a parsed GPX document. - * @param {Object} [options] An object with the following properties: - * @param {Boolean} [options.clampToGround] True if the symbols should be rendered at the same height as the terrain - * @param {String} [options.waypointImage] Image to use for waypoint billboards. - * @param {String} [options.trackImage] Image to use for track billboards. - * @param {String} [options.trackColor] Color to use for track lines. - * @param {String} [options.routeColor] Color to use for route lines. - * @returns {Promise.<GpxDataSource>} A promise that will resolve to this instances once the GPX is loaded. + * @param {string|Document|Blob} data A url, parsed GPX document, or Blob containing binary GPX data or a parsed GPX document. + * @param {object} [options] An object with the following properties: + * @param {boolean} [options.clampToGround] True if the symbols should be rendered at the same height as the terrain + * @param {string} [options.waypointImage] Image to use for waypoint billboards. + * @param {string} [options.trackImage] Image to use for track billboards. + * @param {string} [options.trackColor] Color to use for track lines. + * @param {string} [options.routeColor] Color to use for route lines. + * @returns {Promise<GpxDataSource>} A promise that will resolve to this instances once the GPX is loaded. */ GpxDataSource.prototype.load = function (data, options) { if (!defined(data)) { diff --git a/packages/engine/Source/DataSources/GridMaterialProperty.js b/packages/engine/Source/DataSources/GridMaterialProperty.js index 133b55ffa35..1304ddd745e 100644 --- a/packages/engine/Source/DataSources/GridMaterialProperty.js +++ b/packages/engine/Source/DataSources/GridMaterialProperty.js @@ -16,9 +16,9 @@ const defaultLineThickness = new Cartesian2(1, 1); * A {@link MaterialProperty} that maps to grid {@link Material} uniforms. * @alias GridMaterialProperty * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the grid {@link Color}. - * @param {Property|Number} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values. + * @param {Property|number} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values. * @param {Property|Cartesian2} [options.lineCount=new Cartesian2(8, 8)] A {@link Cartesian2} Property specifying the number of grid lines along each axis. * @param {Property|Cartesian2} [options.lineThickness=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the thickness of grid lines along each axis. * @param {Property|Cartesian2} [options.lineOffset=new Cartesian2(0.0, 0.0)] A {@link Cartesian2} Property specifying starting offset of grid lines along each axis. @@ -53,7 +53,7 @@ Object.defineProperties(GridMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof GridMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -128,7 +128,7 @@ Object.defineProperties(GridMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ GridMaterialProperty.prototype.getType = function (time) { return "Grid"; @@ -138,8 +138,8 @@ GridMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ GridMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -182,7 +182,7 @@ GridMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ GridMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/GroundGeometryUpdater.js b/packages/engine/Source/DataSources/GroundGeometryUpdater.js index 47d8fd26750..5373bb70d37 100644 --- a/packages/engine/Source/DataSources/GroundGeometryUpdater.js +++ b/packages/engine/Source/DataSources/GroundGeometryUpdater.js @@ -17,12 +17,12 @@ const defaultZIndex = new ConstantProperty(0); * An abstract class for updating ground geometry entities. * @constructor * @alias GroundGeometryUpdater - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {Entity} options.entity The entity containing the geometry to be visualized. * @param {Scene} options.scene The scene where visualization is taking place. - * @param {Object} options.geometryOptions Options for the geometry - * @param {String} options.geometryPropertyName The geometry property name - * @param {String[]} options.observedPropertyNames The entity properties this geometry cares about + * @param {object} options.geometryOptions Options for the geometry + * @param {string} options.geometryPropertyName The geometry property name + * @param {string[]} options.observedPropertyNames The entity properties this geometry cares about */ function GroundGeometryUpdater(options) { GeometryUpdater.call(this, options); @@ -39,7 +39,7 @@ if (defined(Object.create)) { Object.defineProperties(GroundGeometryUpdater.prototype, { /** * Gets the zindex - * @type {Number} + * @type {number} * @memberof GroundGeometryUpdater.prototype * @readonly */ diff --git a/packages/engine/Source/DataSources/ImageMaterialProperty.js b/packages/engine/Source/DataSources/ImageMaterialProperty.js index 0c7a377275d..5aa8c5b713f 100644 --- a/packages/engine/Source/DataSources/ImageMaterialProperty.js +++ b/packages/engine/Source/DataSources/ImageMaterialProperty.js @@ -15,11 +15,11 @@ const defaultColor = Color.WHITE; * @alias ImageMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Property|String|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.image] A Property specifying the Image, URL, Canvas, or Video. + * @param {object} [options] Object with the following properties: + * @param {Property|string|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.image] A Property specifying the Image, URL, Canvas, or Video. * @param {Property|Cartesian2} [options.repeat=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the number of times the image repeats in each direction. * @param {Property|Color} [options.color=Color.WHITE] The color applied to the image - * @param {Property|Boolean} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections) + * @param {Property|boolean} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections) */ function ImageMaterialProperty(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -46,7 +46,7 @@ Object.defineProperties(ImageMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof ImageMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -108,7 +108,7 @@ Object.defineProperties(ImageMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ ImageMaterialProperty.prototype.getType = function (time) { return "Image"; @@ -118,8 +118,8 @@ ImageMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ ImageMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -151,7 +151,7 @@ ImageMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ImageMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/KmlDataSource.js b/packages/engine/Source/DataSources/KmlDataSource.js index a1ba044f608..474f252406b 100644 --- a/packages/engine/Source/DataSources/KmlDataSource.js +++ b/packages/engine/Source/DataSources/KmlDataSource.js @@ -3539,29 +3539,29 @@ function load(dataSource, entityCollection, data, options) { // https://github.com/microsoft/TypeScript/issues/20077 and/or // https://github.com/jsdoc/jsdoc/issues/1199 actually get resolved /** - * @typedef {Object} KmlDataSource.LoadOptions + * @typedef {object} KmlDataSource.LoadOptions * * Initialization options for the `load` method. * - * @property {String} [sourceUri] Overrides the url to use for resolving relative links and other KML network features. - * @property {Boolean} [clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. + * @property {string} [sourceUri] Overrides the url to use for resolving relative links and other KML network features. + * @property {boolean} [clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. * @property {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The global ellipsoid used for geographical calculations. - * @property {Element|String} [screenOverlayContainer] A container for ScreenOverlay images. + * @property {Element|string} [screenOverlayContainer] A container for ScreenOverlay images. */ /** - * @typedef {Object} KmlDataSource.ConstructorOptions + * @typedef {object} KmlDataSource.ConstructorOptions * * Options for constructing a new KmlDataSource, or calling the static `load` method. * * @property {Camera} [camera] The camera that is used for viewRefreshModes and sending camera properties to network links. * @property {HTMLCanvasElement} [canvas] The canvas that is used for sending viewer properties to network links. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. * - * @property {String} [sourceUri] Overrides the url to use for resolving relative links and other KML network features. - * @property {Boolean} [clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. + * @property {string} [sourceUri] Overrides the url to use for resolving relative links and other KML network features. + * @property {boolean} [clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground. * @property {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The global ellipsoid used for geographical calculations. - * @property {Element|String} [screenOverlayContainer] A container for ScreenOverlay images. + * @property {Element|string} [screenOverlayContainer] A container for ScreenOverlay images. */ @@ -3667,10 +3667,10 @@ function KmlDataSource(options) { /** * Creates a Promise to a new instance loaded with the provided KML data. * - * @param {Resource|String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. + * @param {Resource|string|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. * @param {KmlDataSource.ConstructorOptions} [options] An object specifying configuration options * - * @returns {Promise.<KmlDataSource>} A promise that will resolve to a new KmlDataSource instance once the KML is loaded. + * @returns {Promise<KmlDataSource>} A promise that will resolve to a new KmlDataSource instance once the KML is loaded. */ KmlDataSource.load = function (data, options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -3683,7 +3683,7 @@ Object.defineProperties(KmlDataSource.prototype, { * Gets or sets a human-readable name for this instance. * This will be automatically be set to the KML document name on load. * @memberof KmlDataSource.prototype - * @type {String} + * @type {string} */ name: { get: function () { @@ -3721,7 +3721,7 @@ Object.defineProperties(KmlDataSource.prototype, { /** * Gets a value indicating if the data source is currently loading data. * @memberof KmlDataSource.prototype - * @type {Boolean} + * @type {boolean} */ isLoading: { get: function () { @@ -3781,7 +3781,7 @@ Object.defineProperties(KmlDataSource.prototype, { /** * Gets whether or not this data source should be displayed. * @memberof KmlDataSource.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -3836,10 +3836,10 @@ Object.defineProperties(KmlDataSource.prototype, { /** * Asynchronously loads the provided KML data, replacing any existing data. * - * @param {Resource|String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. + * @param {Resource|string|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document. * @param {KmlDataSource.LoadOptions} [options] An object specifying configuration options * - * @returns {Promise.<KmlDataSource>} A promise that will resolve to this instances once the KML is loaded. + * @returns {Promise<KmlDataSource>} A promise that will resolve to this instances once the KML is loaded. */ KmlDataSource.prototype.load = function (data, options) { //>>includeStart('debug', pragmas.debug); @@ -4113,7 +4113,7 @@ const entitiesToIgnore = new AssociativeArray(); * Updates any NetworkLink that require updating. * * @param {JulianDate} time The simulation time. - * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise. + * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ KmlDataSource.prototype.update = function (time) { const networkLinks = this._networkLinks; @@ -4253,10 +4253,10 @@ KmlDataSource.prototype.update = function (time) { function KmlFeatureData() { /** * @typedef KmlFeatureData.Author - * @type {Object} - * @property {String} name Gets the name. - * @property {String} uri Gets the URI. - * @property {Number} age Gets the email. + * @type {object} + * @property {string} name Gets the name. + * @property {string} uri Gets the URI. + * @property {number} age Gets the email. */ /** @@ -4271,13 +4271,13 @@ function KmlFeatureData() { /** * @typedef KmlFeatureData.Link - * @type {Object} - * @property {String} href Gets the href. - * @property {String} hreflang Gets the language of the linked resource. - * @property {String} rel Gets the link relation. - * @property {String} type Gets the link type. - * @property {String} title Gets the link title. - * @property {String} length Gets the link length. + * @type {object} + * @property {string} href Gets the href. + * @property {string} hreflang Gets the language of the linked resource. + * @property {string} rel Gets the link relation. + * @property {string} type Gets the link type. + * @property {string} title Gets the link title. + * @property {string} length Gets the link length. */ /** @@ -4295,24 +4295,24 @@ function KmlFeatureData() { /** * Gets the unstructured address field. - * @type {String} + * @type {string} */ this.address = undefined; /** * Gets the phone number. - * @type {String} + * @type {string} */ this.phoneNumber = undefined; /** * Gets the snippet. - * @type {String} + * @type {string} */ this.snippet = undefined; /** * Gets the extended data, parsed into a JSON object. * Currently only the <code>Data</code> property is supported. * <code>SchemaData</code> and custom data are ignored. - * @type {String} + * @type {string} */ this.extendedData = undefined; } diff --git a/packages/engine/Source/DataSources/KmlTour.js b/packages/engine/Source/DataSources/KmlTour.js index 637a6a7968a..dd60e28a105 100644 --- a/packages/engine/Source/DataSources/KmlTour.js +++ b/packages/engine/Source/DataSources/KmlTour.js @@ -8,8 +8,8 @@ import Event from "../Core/Event.js"; * @alias KmlTour * @constructor * - * @param {String} name name parsed from KML - * @param {String} id id parsed from KML + * @param {string} name name parsed from KML + * @param {string} id id parsed from KML * @param {Array} playlist array with KmlTourFlyTos and KmlTourWaits * * @see KmlTourFlyTo @@ -86,7 +86,7 @@ KmlTour.prototype.addPlaylistEntry = function (entry) { * Play this tour. * * @param {Viewer|CesiumWidget} widget The widget. - * @param {Object} [cameraOptions] these options will be merged with {@link Camera#flyTo} + * @param {object} [cameraOptions] these options will be merged with {@link Camera#flyTo} * options for FlyTo playlist entries. */ KmlTour.prototype.play = function (widget, cameraOptions) { diff --git a/packages/engine/Source/DataSources/KmlTourFlyTo.js b/packages/engine/Source/DataSources/KmlTourFlyTo.js index dedba2cab68..405279eb566 100644 --- a/packages/engine/Source/DataSources/KmlTourFlyTo.js +++ b/packages/engine/Source/DataSources/KmlTourFlyTo.js @@ -9,8 +9,8 @@ import EasingFunction from "../Core/EasingFunction.js"; * @alias KmlTourFlyTo * @constructor * - * @param {Number} duration entry duration - * @param {String} flyToMode KML fly to mode: bounce, smooth, etc + * @param {number} duration entry duration + * @param {string} flyToMode KML fly to mode: bounce, smooth, etc * @param {KmlCamera|KmlLookAt} view KmlCamera or KmlLookAt * * @see KmlTour @@ -32,7 +32,7 @@ function KmlTourFlyTo(duration, flyToMode, view) { * * @param {KmlTourFlyTo.DoneCallback} done function which will be called when playback ends * @param {Camera} camera Cesium camera - * @param {Object} [cameraOptions] which will be merged with camera flyTo options. See {@link Camera#flyTo} + * @param {object} [cameraOptions] which will be merged with camera flyTo options. See {@link Camera#flyTo} */ KmlTourFlyTo.prototype.play = function (done, camera, cameraOptions) { this.activeCamera = camera; @@ -70,8 +70,8 @@ KmlTourFlyTo.prototype.stop = function () { * Returns options for {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} * depends on this.view type. * - * @param {Object} cameraOptions options to merge with generated. See {@link Camera#flyTo} - * @returns {Object} {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} options + * @param {object} cameraOptions options to merge with generated. See {@link Camera#flyTo} + * @returns {object} {@link Camera#flyTo} or {@link Camera#flyToBoundingSphere} options */ KmlTourFlyTo.prototype.getCameraOptions = function (cameraOptions) { let options = { @@ -103,7 +103,7 @@ KmlTourFlyTo.prototype.getCameraOptions = function (cameraOptions) { * A function that will be executed when the flight completes. * @callback KmlTourFlyTo.DoneCallback * - * @param {Boolean} terminated true if {@link KmlTourFlyTo#stop} was + * @param {boolean} terminated true if {@link KmlTourFlyTo#stop} was * called before entry done playback. */ export default KmlTourFlyTo; diff --git a/packages/engine/Source/DataSources/KmlTourWait.js b/packages/engine/Source/DataSources/KmlTourWait.js index 0be6e7403dc..d59da1e5055 100644 --- a/packages/engine/Source/DataSources/KmlTourWait.js +++ b/packages/engine/Source/DataSources/KmlTourWait.js @@ -5,7 +5,7 @@ import defined from "../Core/defined.js"; * @alias KmlTourWait * @constructor * - * @param {Number} duration entry duration + * @param {number} duration entry duration * * @see KmlTour * @see KmlTourFlyTo @@ -46,7 +46,7 @@ KmlTourWait.prototype.stop = function () { * A function which will be called when playback ends. * * @callback KmlTourWait.DoneCallback - * @param {Boolean} terminated true if {@link KmlTourWait#stop} was + * @param {boolean} terminated true if {@link KmlTourWait#stop} was * called before entry done playback. */ export default KmlTourWait; diff --git a/packages/engine/Source/DataSources/LabelGraphics.js b/packages/engine/Source/DataSources/LabelGraphics.js index 3495a7e88e0..0622b72bb66 100644 --- a/packages/engine/Source/DataSources/LabelGraphics.js +++ b/packages/engine/Source/DataSources/LabelGraphics.js @@ -5,7 +5,7 @@ import Event from "../Core/Event.js"; import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} LabelGraphics.ConstructorOptions + * @typedef {object} LabelGraphics.ConstructorOptions * * Initialization options for the LabelGraphics constructor * diff --git a/packages/engine/Source/DataSources/LabelVisualizer.js b/packages/engine/Source/DataSources/LabelVisualizer.js index 94392355dda..e88281164f2 100644 --- a/packages/engine/Source/DataSources/LabelVisualizer.js +++ b/packages/engine/Source/DataSources/LabelVisualizer.js @@ -84,7 +84,7 @@ function LabelVisualizer(entityCluster, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ LabelVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -293,7 +293,7 @@ LabelVisualizer.prototype.getBoundingSphere = function (entity, result) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ LabelVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/MaterialProperty.js b/packages/engine/Source/DataSources/MaterialProperty.js index c6aec1da45b..c6a957f79e7 100644 --- a/packages/engine/Source/DataSources/MaterialProperty.js +++ b/packages/engine/Source/DataSources/MaterialProperty.js @@ -29,7 +29,7 @@ Object.defineProperties(MaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof MaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -54,7 +54,7 @@ Object.defineProperties(MaterialProperty.prototype, { * @function * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; @@ -63,8 +63,8 @@ MaterialProperty.prototype.getType = DeveloperError.throwInstantiationError; * @function * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; @@ -74,7 +74,7 @@ MaterialProperty.prototype.getValue = DeveloperError.throwInstantiationError; * @function * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ MaterialProperty.prototype.equals = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/DataSources/ModelGraphics.js b/packages/engine/Source/DataSources/ModelGraphics.js index 42ee8fea00b..d80f77132ea 100644 --- a/packages/engine/Source/DataSources/ModelGraphics.js +++ b/packages/engine/Source/DataSources/ModelGraphics.js @@ -19,7 +19,7 @@ function createArticulationStagePropertyBag(value) { } /** - * @typedef {Object} ModelGraphics.ConstructorOptions + * @typedef {object} ModelGraphics.ConstructorOptions * * Initialization options for the ModelGraphics constructor * diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index b86c061ffc5..f70b8d382fc 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -68,7 +68,7 @@ function ModelVisualizer(scene, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ ModelVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -315,7 +315,7 @@ ModelVisualizer.prototype.update = function (time) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ ModelVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/NodeTransformationProperty.js b/packages/engine/Source/DataSources/NodeTransformationProperty.js index 516b3c41217..f6513cd0597 100644 --- a/packages/engine/Source/DataSources/NodeTransformationProperty.js +++ b/packages/engine/Source/DataSources/NodeTransformationProperty.js @@ -12,7 +12,7 @@ const defaultNodeTransformation = new TranslationRotationScale(); * @alias NodeTransformationProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Cartesian3} [options.translation=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node. * @param {Property|Quaternion} [options.rotation=Quaternion.IDENTITY] A {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node. * @param {Property|Cartesian3} [options.scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node. @@ -39,7 +39,7 @@ Object.defineProperties(NodeTransformationProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof NodeTransformationProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -130,7 +130,7 @@ NodeTransformationProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ NodeTransformationProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PathGraphics.js b/packages/engine/Source/DataSources/PathGraphics.js index 4e95e18792d..d914bb4424e 100644 --- a/packages/engine/Source/DataSources/PathGraphics.js +++ b/packages/engine/Source/DataSources/PathGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} PathGraphics.ConstructorOptions + * @typedef {object} PathGraphics.ConstructorOptions * * Initialization options for the PathGraphics constructor * diff --git a/packages/engine/Source/DataSources/PathVisualizer.js b/packages/engine/Source/DataSources/PathVisualizer.js index 9394f485801..47aac602625 100644 --- a/packages/engine/Source/DataSources/PathVisualizer.js +++ b/packages/engine/Source/DataSources/PathVisualizer.js @@ -612,7 +612,7 @@ function PathVisualizer(scene, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ PathVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -682,7 +682,7 @@ PathVisualizer.prototype.update = function (time) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ PathVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/PlaneGraphics.js b/packages/engine/Source/DataSources/PlaneGraphics.js index 01169fadeec..519ff7d449f 100644 --- a/packages/engine/Source/DataSources/PlaneGraphics.js +++ b/packages/engine/Source/DataSources/PlaneGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} PlaneGraphics.ConstructorOptions + * @typedef {object} PlaneGraphics.ConstructorOptions * * Initialization options for the PlaneGraphics constructor * diff --git a/packages/engine/Source/DataSources/PointGraphics.js b/packages/engine/Source/DataSources/PointGraphics.js index 982d86906ff..6f1cbba104e 100644 --- a/packages/engine/Source/DataSources/PointGraphics.js +++ b/packages/engine/Source/DataSources/PointGraphics.js @@ -5,7 +5,7 @@ import Event from "../Core/Event.js"; import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} PointGraphics.ConstructorOptions + * @typedef {object} PointGraphics.ConstructorOptions * * Initialization options for the PointGraphics constructor * diff --git a/packages/engine/Source/DataSources/PointVisualizer.js b/packages/engine/Source/DataSources/PointVisualizer.js index 798bb03cd9c..2210646daa9 100644 --- a/packages/engine/Source/DataSources/PointVisualizer.js +++ b/packages/engine/Source/DataSources/PointVisualizer.js @@ -68,7 +68,7 @@ function PointVisualizer(entityCluster, entityCollection) { * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} This function always returns true. + * @returns {boolean} This function always returns true. */ PointVisualizer.prototype.update = function (time) { //>>includeStart('debug', pragmas.debug); @@ -350,7 +350,7 @@ PointVisualizer.prototype.getBoundingSphere = function (entity, result) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ PointVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/PolygonGraphics.js b/packages/engine/Source/DataSources/PolygonGraphics.js index 29db7184144..d0339c682fd 100644 --- a/packages/engine/Source/DataSources/PolygonGraphics.js +++ b/packages/engine/Source/DataSources/PolygonGraphics.js @@ -16,7 +16,7 @@ function createPolygonHierarchyProperty(value) { } /** - * @typedef {Object} PolygonGraphics.ConstructorOptions + * @typedef {object} PolygonGraphics.ConstructorOptions * * Initialization options for the PolygonGraphics constructor * @@ -34,8 +34,8 @@ function createPolygonHierarchyProperty(value) { * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline. * @property {Property | boolean} [perPositionHeight=false] A boolean specifying whether or not the height of each position is used. - * @property {Boolean | boolean} [closeTop=true] When false, leaves off the top of an extruded polygon open. - * @property {Boolean | boolean} [closeBottom=true] When false, leaves off the bottom of an extruded polygon open. + * @property {boolean | boolean} [closeTop=true] When false, leaves off the top of an extruded polygon open. + * @property {boolean | boolean} [closeBottom=true] When false, leaves off the bottom of an extruded polygon open. * @property {Property | ArcType} [arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from light sources. * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed. diff --git a/packages/engine/Source/DataSources/PolylineArrowMaterialProperty.js b/packages/engine/Source/DataSources/PolylineArrowMaterialProperty.js index cd413dce829..78ad0b87c94 100644 --- a/packages/engine/Source/DataSources/PolylineArrowMaterialProperty.js +++ b/packages/engine/Source/DataSources/PolylineArrowMaterialProperty.js @@ -26,7 +26,7 @@ Object.defineProperties(PolylineArrowMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof PolylineArrowMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -61,7 +61,7 @@ Object.defineProperties(PolylineArrowMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ PolylineArrowMaterialProperty.prototype.getType = function (time) { return "PolylineArrow"; @@ -71,8 +71,8 @@ PolylineArrowMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ PolylineArrowMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -92,7 +92,7 @@ PolylineArrowMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PolylineArrowMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PolylineDashMaterialProperty.js b/packages/engine/Source/DataSources/PolylineDashMaterialProperty.js index 7240e1caf20..1ff9c6675f9 100644 --- a/packages/engine/Source/DataSources/PolylineDashMaterialProperty.js +++ b/packages/engine/Source/DataSources/PolylineDashMaterialProperty.js @@ -15,11 +15,11 @@ const defaultDashPattern = 255.0; * @alias PolylineDashMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. * @param {Property|Color} [options.gapColor=Color.TRANSPARENT] A Property specifying the {@link Color} of the gaps in the line. - * @param {Property|Number} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixels. - * @param {Property|Number} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash + * @param {Property|number} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixels. + * @param {Property|number} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash */ function PolylineDashMaterialProperty(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -45,7 +45,7 @@ Object.defineProperties(PolylineDashMaterialProperty.prototype, { * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof PolylineDashMaterialProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -104,7 +104,7 @@ Object.defineProperties(PolylineDashMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ PolylineDashMaterialProperty.prototype.getType = function (time) { return "PolylineDash"; @@ -114,8 +114,8 @@ PolylineDashMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ PolylineDashMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -153,7 +153,7 @@ PolylineDashMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PolylineDashMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PolylineGeometryUpdater.js b/packages/engine/Source/DataSources/PolylineGeometryUpdater.js index 924efbf2a0b..6ad349c9d86 100644 --- a/packages/engine/Source/DataSources/PolylineGeometryUpdater.js +++ b/packages/engine/Source/DataSources/PolylineGeometryUpdater.js @@ -108,7 +108,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { /** * Gets the unique ID associated with this updater * @memberof PolylineGeometryUpdater.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -132,7 +132,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Gets a value indicating if the geometry has a fill component. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ fillEnabled: { @@ -144,7 +144,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Gets a value indicating if fill visibility varies with simulation time. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ hasConstantFill: { @@ -184,7 +184,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Gets a value indicating if the geometry has an outline component. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ outlineEnabled: { @@ -194,7 +194,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Gets a value indicating if outline visibility varies with simulation time. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ hasConstantOutline: { @@ -253,7 +253,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * returned by GeometryUpdater#createDynamicUpdater. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isDynamic: { @@ -266,7 +266,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * This property is only valid for static geometry. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isClosed: { @@ -277,7 +277,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * of this updater change. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ geometryChanged: { @@ -304,7 +304,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Returns false if polylines on terrain is not supported. * @memberof PolylineGeometryUpdater.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ clampToGround: { @@ -315,7 +315,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { /** * Gets the zindex - * @type {Number} + * @type {number} * @memberof PolylineGeometryUpdater.prototype * @readonly */ @@ -330,7 +330,7 @@ Object.defineProperties(PolylineGeometryUpdater.prototype, { * Checks if the geometry is outlined at the provided time. * * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise. + * @returns {boolean} true if geometry is outlined at the provided time, false otherwise. */ PolylineGeometryUpdater.prototype.isOutlineVisible = function (time) { return false; @@ -340,7 +340,7 @@ PolylineGeometryUpdater.prototype.isOutlineVisible = function (time) { * Checks if the geometry is filled at the provided time. * * @param {JulianDate} time The time for which to retrieve visibility. - * @returns {Boolean} true if geometry is filled at the provided time, false otherwise. + * @returns {boolean} true if geometry is filled at the provided time, false otherwise. */ PolylineGeometryUpdater.prototype.isFilled = function (time) { const entity = this._entity; @@ -460,7 +460,7 @@ PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function ( /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ PolylineGeometryUpdater.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/PolylineGlowMaterialProperty.js b/packages/engine/Source/DataSources/PolylineGlowMaterialProperty.js index 4bfde8b82e5..11ac0f10a9e 100644 --- a/packages/engine/Source/DataSources/PolylineGlowMaterialProperty.js +++ b/packages/engine/Source/DataSources/PolylineGlowMaterialProperty.js @@ -14,10 +14,10 @@ const defaultTaperPower = 1.0; * @alias PolylineGlowMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. - * @param {Property|Number} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width. - * @param {Property|Number} [options.taperPower=1.0] A numeric Property specifying the strength of the tapering effect, as a percentage of the total line length. If 1.0 or higher, no taper effect is used. + * @param {Property|number} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width. + * @param {Property|number} [options.taperPower=1.0] A numeric Property specifying the strength of the tapering effect, as a percentage of the total line length. If 1.0 or higher, no taper effect is used. */ function PolylineGlowMaterialProperty(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -40,7 +40,7 @@ Object.defineProperties(PolylineGlowMaterialProperty.prototype, { * Gets a value indicating if this property is constant. A property is considered * constant if getValue always returns the same result for the current definition. * @memberof PolylineGlowMaterialProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -89,7 +89,7 @@ Object.defineProperties(PolylineGlowMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ PolylineGlowMaterialProperty.prototype.getType = function (time) { return "PolylineGlow"; @@ -99,8 +99,8 @@ PolylineGlowMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ PolylineGlowMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -132,7 +132,7 @@ PolylineGlowMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PolylineGlowMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PolylineGraphics.js b/packages/engine/Source/DataSources/PolylineGraphics.js index 90566a52334..68c00789e03 100644 --- a/packages/engine/Source/DataSources/PolylineGraphics.js +++ b/packages/engine/Source/DataSources/PolylineGraphics.js @@ -6,12 +6,12 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} PolylineGraphics.ConstructorOptions + * @typedef {object} PolylineGraphics.ConstructorOptions * * Initialization options for the PolylineGraphics constructor * * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the polyline. - * @property {Property | Array<Cartesian3>} [positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip. + * @property {Property | Cartesian3[]} [positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip. * @property {Property | number} [width=1.0] A numeric Property specifying the width in pixels. * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if arcType is not ArcType.NONE. * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to draw the polyline. diff --git a/packages/engine/Source/DataSources/PolylineOutlineMaterialProperty.js b/packages/engine/Source/DataSources/PolylineOutlineMaterialProperty.js index 69334d6f358..27851e59ba7 100644 --- a/packages/engine/Source/DataSources/PolylineOutlineMaterialProperty.js +++ b/packages/engine/Source/DataSources/PolylineOutlineMaterialProperty.js @@ -14,10 +14,10 @@ const defaultOutlineWidth = 1.0; * @alias PolylineOutlineMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line. * @param {Property|Color} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline. - * @param {Property|Number} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels. + * @param {Property|number} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels. */ function PolylineOutlineMaterialProperty(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -41,7 +41,7 @@ Object.defineProperties(PolylineOutlineMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof PolylineOutlineMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -96,7 +96,7 @@ Object.defineProperties(PolylineOutlineMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ PolylineOutlineMaterialProperty.prototype.getType = function (time) { return "PolylineOutline"; @@ -106,8 +106,8 @@ PolylineOutlineMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ PolylineOutlineMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -138,7 +138,7 @@ PolylineOutlineMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PolylineOutlineMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PolylineVisualizer.js b/packages/engine/Source/DataSources/PolylineVisualizer.js index f3d969009b7..a30fb2fad7b 100644 --- a/packages/engine/Source/DataSources/PolylineVisualizer.js +++ b/packages/engine/Source/DataSources/PolylineVisualizer.js @@ -197,7 +197,7 @@ function PolylineVisualizer( * Entity counterpart at the given time. * * @param {JulianDate} time The time to update to. - * @returns {Boolean} True if the visualizer successfully updated to the provided time, + * @returns {boolean} True if the visualizer successfully updated to the provided time, * false if the visualizer is waiting for asynchronous primitives to be created. */ PolylineVisualizer.prototype.update = function (time) { @@ -329,7 +329,7 @@ PolylineVisualizer.prototype.getBoundingSphere = function (entity, result) { /** * Returns true if this object was destroyed; otherwise, false. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ PolylineVisualizer.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/DataSources/PolylineVolumeGraphics.js b/packages/engine/Source/DataSources/PolylineVolumeGraphics.js index 6bd22468dca..19ff7e271c9 100644 --- a/packages/engine/Source/DataSources/PolylineVolumeGraphics.js +++ b/packages/engine/Source/DataSources/PolylineVolumeGraphics.js @@ -6,13 +6,13 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} PolylineVolumeGraphics.ConstructorOptions + * @typedef {object} PolylineVolumeGraphics.ConstructorOptions * * Initialization options for the PolylineVolumeGraphics constructor * * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the volume. - * @property {Property | Array<Cartesian3>} [positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip. - * @property {Property | Array<Cartesian2>} [shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. + * @property {Property | Cartesian3[]} [positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip. + * @property {Property | Cartesian2[]} [shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded. * @property {Property | CornerType} [cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners. * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. * @property {Property | boolean} [fill=true] A boolean Property specifying whether the volume is filled with the provided material. diff --git a/packages/engine/Source/DataSources/PositionProperty.js b/packages/engine/Source/DataSources/PositionProperty.js index 93f28de8b6b..88b0e2371a6 100644 --- a/packages/engine/Source/DataSources/PositionProperty.js +++ b/packages/engine/Source/DataSources/PositionProperty.js @@ -29,7 +29,7 @@ Object.defineProperties(PositionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof PositionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -85,7 +85,7 @@ PositionProperty.prototype.getValueInReferenceFrame = * @function * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PositionProperty.prototype.equals = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/DataSources/PositionPropertyArray.js b/packages/engine/Source/DataSources/PositionPropertyArray.js index fb58d11d357..ac8853533a6 100644 --- a/packages/engine/Source/DataSources/PositionPropertyArray.js +++ b/packages/engine/Source/DataSources/PositionPropertyArray.js @@ -30,7 +30,7 @@ Object.defineProperties(PositionPropertyArray.prototype, { * is considered constant if all property items in the array are constant. * @memberof PositionPropertyArray.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -170,7 +170,7 @@ PositionPropertyArray.prototype.setValue = function (value) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PositionPropertyArray.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/Property.js b/packages/engine/Source/DataSources/Property.js index facdbf6957b..5bb13ab71b4 100644 --- a/packages/engine/Source/DataSources/Property.js +++ b/packages/engine/Source/DataSources/Property.js @@ -28,7 +28,7 @@ Object.defineProperties(Property.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof Property.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -53,8 +53,8 @@ Object.defineProperties(Property.prototype, { * @function * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ Property.prototype.getValue = DeveloperError.throwInstantiationError; @@ -64,7 +64,7 @@ Property.prototype.getValue = DeveloperError.throwInstantiationError; * @function * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ Property.prototype.equals = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/DataSources/PropertyArray.js b/packages/engine/Source/DataSources/PropertyArray.js index 0e083bf0a18..305e3c0c940 100644 --- a/packages/engine/Source/DataSources/PropertyArray.js +++ b/packages/engine/Source/DataSources/PropertyArray.js @@ -26,7 +26,7 @@ Object.defineProperties(PropertyArray.prototype, { * is considered constant if all property items in the array are constant. * @memberof PropertyArray.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -131,7 +131,7 @@ PropertyArray.prototype.setValue = function (value) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PropertyArray.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/PropertyBag.js b/packages/engine/Source/DataSources/PropertyBag.js index b6e27371551..a5b0220f400 100644 --- a/packages/engine/Source/DataSources/PropertyBag.js +++ b/packages/engine/Source/DataSources/PropertyBag.js @@ -13,7 +13,7 @@ import Property from "./Property.js"; * @implements Record<string, any> * @constructor * - * @param {Object} [value] An object, containing key-value mapping of property names to properties. + * @param {object} [value] An object, containing key-value mapping of property names to properties. * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. */ function PropertyBag(value, createPropertyCallback) { @@ -41,7 +41,7 @@ Object.defineProperties(PropertyBag.prototype, { * is considered constant if all property items in this object are constant. * @memberof PropertyBag.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -74,9 +74,9 @@ Object.defineProperties(PropertyBag.prototype, { /** * Determines if this object has defined a property with the given name. * - * @param {String} propertyName The name of the property to check for. + * @param {string} propertyName The name of the property to check for. * - * @returns {Boolean} True if this object has defined a property with the given name, false otherwise. + * @returns {boolean} True if this object has defined a property with the given name, false otherwise. */ PropertyBag.prototype.hasProperty = function (propertyName) { return this._propertyNames.indexOf(propertyName) !== -1; @@ -89,7 +89,7 @@ function createConstantProperty(value) { /** * Adds a property to this object. * - * @param {String} propertyName The name of the property to add. + * @param {string} propertyName The name of the property to add. * @param {*} [value] The value of the new property, if provided. * @param {Function} [createPropertyCallback] A function that will be called when the value of this new property is set to a value that is not a Property. * @@ -134,7 +134,7 @@ PropertyBag.prototype.addProperty = function ( /** * Removed a property previously added with addProperty. * - * @param {String} propertyName The name of the property to remove. + * @param {string} propertyName The name of the property to remove. * * @exception {DeveloperError} "propertyName" is not a registered property. */ @@ -162,9 +162,9 @@ PropertyBag.prototype.removeProperty = function (propertyName) { * result will be an object, mapping property names to those values. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. * Note that any properties in result which are not part of this PropertyBag will be left as-is. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ PropertyBag.prototype.getValue = function (time, result) { //>>includeStart('debug', pragmas.debug); @@ -193,7 +193,7 @@ PropertyBag.prototype.getValue = function (time, result) { * Assigns each unassigned property on this object to the value * of the same property on the provided source object. * - * @param {Object} source The object to be merged into this object. + * @param {object} source The object to be merged into this object. * @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. */ PropertyBag.prototype.merge = function (source, createPropertyCallback) { @@ -263,7 +263,7 @@ function propertiesEqual(a, b) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ PropertyBag.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/RectangleGraphics.js b/packages/engine/Source/DataSources/RectangleGraphics.js index 4c8f30aa5b1..020f96e56d1 100644 --- a/packages/engine/Source/DataSources/RectangleGraphics.js +++ b/packages/engine/Source/DataSources/RectangleGraphics.js @@ -6,7 +6,7 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} RectangleGraphics.ConstructorOptions + * @typedef {object} RectangleGraphics.ConstructorOptions * * Initialization options for the RectangleGraphics constructor * diff --git a/packages/engine/Source/DataSources/ReferenceProperty.js b/packages/engine/Source/DataSources/ReferenceProperty.js index 6d427d786f3..88218e81d0d 100644 --- a/packages/engine/Source/DataSources/ReferenceProperty.js +++ b/packages/engine/Source/DataSources/ReferenceProperty.js @@ -51,8 +51,8 @@ function resolve(that) { * @constructor * * @param {EntityCollection} targetCollection The entity collection which will be used to resolve the reference. - * @param {String} targetId The id of the entity which is being referenced. - * @param {String[]} targetPropertyNames The names of the property on the target entity which we will use. + * @param {string} targetId The id of the entity which is being referenced. + * @param {string[]} targetPropertyNames The names of the property on the target entity which we will use. * * @example * const collection = new Cesium.EntityCollection(); @@ -122,7 +122,7 @@ Object.defineProperties(ReferenceProperty.prototype, { /** * Gets a value indicating if this property is constant. * @memberof ReferenceProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -158,7 +158,7 @@ Object.defineProperties(ReferenceProperty.prototype, { /** * Gets the id of the entity being referenced. * @memberof ReferenceProperty.prototype - * @type {String} + * @type {string} * @readonly */ targetId: { @@ -180,7 +180,7 @@ Object.defineProperties(ReferenceProperty.prototype, { /** * Gets the array of property names used to retrieve the referenced property. * @memberof ReferenceProperty.prototype - * @type {String[]} + * @type {} * @readonly */ targetPropertyNames: { @@ -209,7 +209,7 @@ Object.defineProperties(ReferenceProperty.prototype, { * or any sub-properties contains a # . or \ they must be escaped. * * @param {EntityCollection} targetCollection - * @param {String} referenceString + * @param {string} referenceString * @returns {ReferenceProperty} A new instance of ReferenceProperty. * * @exception {DeveloperError} invalid referenceString. @@ -258,8 +258,8 @@ ReferenceProperty.fromString = function (targetCollection, referenceString) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ ReferenceProperty.prototype.getValue = function (time, result) { const target = resolve(this); @@ -291,7 +291,7 @@ ReferenceProperty.prototype.getValueInReferenceFrame = function ( * This method is only valid if the property being referenced is a {@link MaterialProperty}. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ ReferenceProperty.prototype.getType = function (time) { const target = resolve(this); @@ -303,7 +303,7 @@ ReferenceProperty.prototype.getType = function (time) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ ReferenceProperty.prototype.equals = function (other) { if (this === other) { diff --git a/packages/engine/Source/DataSources/Rotation.js b/packages/engine/Source/DataSources/Rotation.js index 6ed6a6a19bd..5f60a4a92fe 100644 --- a/packages/engine/Source/DataSources/Rotation.js +++ b/packages/engine/Source/DataSources/Rotation.js @@ -32,7 +32,7 @@ import CesiumMath from "../Core/Math.js"; const Rotation = { /** * The number of elements used to pack the object into an array. - * @type {Number} + * @type {number} */ packedLength: 1, @@ -40,10 +40,10 @@ const Rotation = { * Stores the provided instance into the provided array. * * @param {Rotation} value The value to pack. - * @param {Number[]} array The array to pack into. - * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * @param {number[]} array The array to pack into. + * @param {number} [startingIndex=0] The index into the array at which to start packing the elements. * - * @returns {Number[]} The array that was packed into + * @returns {number[]} The array that was packed into */ pack: function (value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); @@ -65,8 +65,8 @@ const Rotation = { /** * Retrieves an instance from a packed array. * - * @param {Number[]} array The packed array. - * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {number[]} array The packed array. + * @param {number} [startingIndex=0] The starting index of the element to be unpacked. * @param {Rotation} [result] The object into which to store the result. * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. */ @@ -84,10 +84,10 @@ const Rotation = { /** * Converts a packed array into a form suitable for interpolation. * - * @param {Number[]} packedArray The packed array. - * @param {Number} [startingIndex=0] The index of the first element to be converted. - * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. - * @param {Number[]} [result] The object into which to store the result. + * @param {number[]} packedArray The packed array. + * @param {number} [startingIndex=0] The index of the first element to be converted. + * @param {number} [lastIndex=packedArray.length] The index of the last element to be converted. + * @param {number[]} [result] The object into which to store the result. */ convertPackedArrayForInterpolation: function ( packedArray, @@ -123,10 +123,10 @@ const Rotation = { /** * Retrieves an instance from a packed array converted with {@link Rotation.convertPackedArrayForInterpolation}. * - * @param {Number[]} array The array previously packed for interpolation. - * @param {Number[]} sourceArray The original packed array. - * @param {Number} [firstIndex=0] The firstIndex used to convert the array. - * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. + * @param {number[]} array The array previously packed for interpolation. + * @param {number[]} sourceArray The original packed array. + * @param {number} [firstIndex=0] The firstIndex used to convert the array. + * @param {number} [lastIndex=packedArray.length] The lastIndex used to convert the array. * @param {Rotation} [result] The object into which to store the result. * @returns {Rotation} The modified result parameter or a new Rotation instance if one was not provided. */ diff --git a/packages/engine/Source/DataSources/SampledPositionProperty.js b/packages/engine/Source/DataSources/SampledPositionProperty.js index 58e9e48a49b..001fba3465b 100644 --- a/packages/engine/Source/DataSources/SampledPositionProperty.js +++ b/packages/engine/Source/DataSources/SampledPositionProperty.js @@ -16,7 +16,7 @@ import SampledProperty from "./SampledProperty.js"; * @constructor * * @param {ReferenceFrame} [referenceFrame=ReferenceFrame.FIXED] The reference frame in which the position is defined. - * @param {Number} [numberOfDerivatives=0] The number of derivatives that accompany each position; i.e. velocity, acceleration, etc... + * @param {number} [numberOfDerivatives=0] The number of derivatives that accompany each position; i.e. velocity, acceleration, etc... */ function SampledPositionProperty(referenceFrame, numberOfDerivatives) { numberOfDerivatives = defaultValue(numberOfDerivatives, 0); @@ -45,7 +45,7 @@ Object.defineProperties(SampledPositionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof SampledPositionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -82,7 +82,7 @@ Object.defineProperties(SampledPositionProperty.prototype, { * Gets the degree of interpolation to perform when retrieving a value. Call <code>setInterpolationOptions</code> to set this. * @memberof SampledPositionProperty.prototype * - * @type {Number} + * @type {number} * @default 1 * @readonly */ @@ -108,7 +108,7 @@ Object.defineProperties(SampledPositionProperty.prototype, { * The number of derivatives contained by this property; i.e. 0 for just position, 1 for velocity, etc. * @memberof SampledPositionProperty.prototype * - * @type {Number} + * @type {number} * @default 0 */ numberOfDerivatives: { @@ -135,7 +135,7 @@ Object.defineProperties(SampledPositionProperty.prototype, { * Gets or sets the amount of time to extrapolate forward before * the property becomes undefined. A value of 0 will extrapolate forever. * @memberof SampledPositionProperty.prototype - * @type {Number} + * @type {number} * @default 0 */ forwardExtrapolationDuration: { @@ -165,7 +165,7 @@ Object.defineProperties(SampledPositionProperty.prototype, { * Gets or sets the amount of time to extrapolate backward * before the property becomes undefined. A value of 0 will extrapolate forever. * @memberof SampledPositionProperty.prototype - * @type {Number} + * @type {number} * @default 0 */ backwardExtrapolationDuration: { @@ -223,9 +223,9 @@ SampledPositionProperty.prototype.getValueInReferenceFrame = function ( /** * Sets the algorithm and degree to use when interpolating a position. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * @param {number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. */ SampledPositionProperty.prototype.setInterpolationOptions = function (options) { this._property.setInterpolationOptions(options); @@ -278,7 +278,7 @@ SampledPositionProperty.prototype.addSamples = function ( * Adds samples as a single packed array where each new sample is represented as a date, * followed by the packed representation of the corresponding value and derivatives. * - * @param {Number[]} packedSamples The array of packed samples. + * @param {number[]} packedSamples The array of packed samples. * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. */ SampledPositionProperty.prototype.addSamplesPackedArray = function ( @@ -292,7 +292,7 @@ SampledPositionProperty.prototype.addSamplesPackedArray = function ( * Removes a sample at the given time, if present. * * @param {JulianDate} time The sample time. - * @returns {Boolean} <code>true</code> if a sample at time was removed, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if a sample at time was removed, <code>false</code> otherwise. */ SampledPositionProperty.prototype.removeSample = function (time) { return this._property.removeSample(time); @@ -312,7 +312,7 @@ SampledPositionProperty.prototype.removeSamples = function (timeInterval) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ SampledPositionProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/SampledProperty.js b/packages/engine/Source/DataSources/SampledProperty.js index 1f2604348c7..39248a3a39e 100644 --- a/packages/engine/Source/DataSources/SampledProperty.js +++ b/packages/engine/Source/DataSources/SampledProperty.js @@ -118,7 +118,7 @@ function mergeNewSamples(epoch, times, values, newData, packedLength) { * @alias SampledProperty * @constructor * - * @param {Number|Packable} type The type of property. + * @param {number|Packable} type The type of property. * @param {Packable[]} [derivativeTypes] When supplied, indicates that samples will contain derivative information of the specified types. * * @@ -221,7 +221,7 @@ Object.defineProperties(SampledProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof SampledProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -266,7 +266,7 @@ Object.defineProperties(SampledProperty.prototype, { /** * Gets the degree of interpolation to perform when retrieving a value. * @memberof SampledProperty.prototype - * @type {Number} + * @type {number} * @default 1 */ interpolationDegree: { @@ -307,7 +307,7 @@ Object.defineProperties(SampledProperty.prototype, { * Gets or sets the amount of time to extrapolate forward before * the property becomes undefined. A value of 0 will extrapolate forever. * @memberof SampledProperty.prototype - * @type {Number} + * @type {number} * @default 0 */ forwardExtrapolationDuration: { @@ -343,7 +343,7 @@ Object.defineProperties(SampledProperty.prototype, { * Gets or sets the amount of time to extrapolate backward * before the property becomes undefined. A value of 0 will extrapolate forever. * @memberof SampledProperty.prototype - * @type {Number} + * @type {number} * @default 0 */ backwardExtrapolationDuration: { @@ -363,8 +363,8 @@ Object.defineProperties(SampledProperty.prototype, { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ SampledProperty.prototype.getValue = function (time, result) { //>>includeStart('debug', pragmas.debug); @@ -535,9 +535,9 @@ SampledProperty.prototype.getValue = function (time, result) { /** * Sets the algorithm and degree to use when interpolating a value. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm. If undefined, the existing property will be unchanged. - * @param {Number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. + * @param {number} [options.interpolationDegree] The new interpolation degree. If undefined, the existing property will be unchanged. */ SampledProperty.prototype.setInterpolationOptions = function (options) { if (!defined(options)) { @@ -676,7 +676,7 @@ SampledProperty.prototype.addSamples = function ( * Adds samples as a single packed array where each new sample is represented as a date, * followed by the packed representation of the corresponding value and derivatives. * - * @param {Number[]} packedSamples The array of packed samples. + * @param {number[]} packedSamples The array of packed samples. * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds. */ SampledProperty.prototype.addSamplesPackedArray = function ( @@ -702,7 +702,7 @@ SampledProperty.prototype.addSamplesPackedArray = function ( * Removes a sample at the given time, if present. * * @param {JulianDate} time The sample time. - * @returns {Boolean} <code>true</code> if a sample at time was removed, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if a sample at time was removed, <code>false</code> otherwise. */ SampledProperty.prototype.removeSample = function (time) { //>>includeStart('debug', pragmas.debug); @@ -760,7 +760,7 @@ SampledProperty.prototype.removeSamples = function (timeInterval) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ SampledProperty.prototype.equals = function (other) { if (this === other) { diff --git a/packages/engine/Source/DataSources/StripeMaterialProperty.js b/packages/engine/Source/DataSources/StripeMaterialProperty.js index 54d29125de1..c778483802a 100644 --- a/packages/engine/Source/DataSources/StripeMaterialProperty.js +++ b/packages/engine/Source/DataSources/StripeMaterialProperty.js @@ -17,12 +17,12 @@ const defaultRepeat = 1; * @alias StripeMaterialProperty * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Property|StripeOrientation} [options.orientation=StripeOrientation.HORIZONTAL] A Property specifying the {@link StripeOrientation}. * @param {Property|Color} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}. * @param {Property|Color} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}. - * @param {Property|Number} [options.offset=0] A numeric Property specifying how far into the pattern to start the material. - * @param {Property|Number} [options.repeat=1] A numeric Property specifying how many times the stripes repeat. + * @param {Property|number} [options.offset=0] A numeric Property specifying how far into the pattern to start the material. + * @param {Property|number} [options.repeat=1] A numeric Property specifying how many times the stripes repeat. */ function StripeMaterialProperty(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -52,7 +52,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof StripeMaterialProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -129,7 +129,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, { * Gets the {@link Material} type at the provided time. * * @param {JulianDate} time The time for which to retrieve the type. - * @returns {String} The type of material. + * @returns {string} The type of material. */ StripeMaterialProperty.prototype.getType = function (time) { return "Stripe"; @@ -139,8 +139,8 @@ StripeMaterialProperty.prototype.getType = function (time) { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ StripeMaterialProperty.prototype.getValue = function (time, result) { if (!defined(result)) { @@ -171,7 +171,7 @@ StripeMaterialProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ StripeMaterialProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/StripeOrientation.js b/packages/engine/Source/DataSources/StripeOrientation.js index 8b0588f4dae..5ad1b636992 100644 --- a/packages/engine/Source/DataSources/StripeOrientation.js +++ b/packages/engine/Source/DataSources/StripeOrientation.js @@ -1,18 +1,18 @@ /** * Defined the orientation of stripes in {@link StripeMaterialProperty}. * - * @enum {Number} + * @enum {number} */ const StripeOrientation = { /** * Horizontal orientation. - * @type {Number} + * @type {number} */ HORIZONTAL: 0, /** * Vertical orientation. - * @type {Number} + * @type {number} */ VERTICAL: 1, }; diff --git a/packages/engine/Source/DataSources/TerrainOffsetProperty.js b/packages/engine/Source/DataSources/TerrainOffsetProperty.js index 85c10720779..17eab9c2640 100644 --- a/packages/engine/Source/DataSources/TerrainOffsetProperty.js +++ b/packages/engine/Source/DataSources/TerrainOffsetProperty.js @@ -84,7 +84,7 @@ Object.defineProperties(TerrainOffsetProperty.prototype, { * Gets a value indicating if this property is constant. * @memberof TerrainOffsetProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { diff --git a/packages/engine/Source/DataSources/TimeIntervalCollectionPositionProperty.js b/packages/engine/Source/DataSources/TimeIntervalCollectionPositionProperty.js index 1f41507af83..9fd6a16a7a4 100644 --- a/packages/engine/Source/DataSources/TimeIntervalCollectionPositionProperty.js +++ b/packages/engine/Source/DataSources/TimeIntervalCollectionPositionProperty.js @@ -31,7 +31,7 @@ Object.defineProperties(TimeIntervalCollectionPositionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof TimeIntervalCollectionPositionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -82,7 +82,7 @@ Object.defineProperties(TimeIntervalCollectionPositionProperty.prototype, { * Gets the value of the property at the provided time in the fixed frame. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. * @returns {Cartesian3 | undefined} The modified result parameter or a new instance if the result parameter was not supplied. */ TimeIntervalCollectionPositionProperty.prototype.getValue = function ( @@ -132,7 +132,7 @@ TimeIntervalCollectionPositionProperty.prototype.getValueInReferenceFrame = func * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ TimeIntervalCollectionPositionProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/TimeIntervalCollectionProperty.js b/packages/engine/Source/DataSources/TimeIntervalCollectionProperty.js index 06851a541d0..3c7f5a4b8f8 100644 --- a/packages/engine/Source/DataSources/TimeIntervalCollectionProperty.js +++ b/packages/engine/Source/DataSources/TimeIntervalCollectionProperty.js @@ -55,7 +55,7 @@ Object.defineProperties(TimeIntervalCollectionProperty.prototype, { * constant if getValue always returns the same result for the current definition. * @memberof TimeIntervalCollectionProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -95,8 +95,8 @@ Object.defineProperties(TimeIntervalCollectionProperty.prototype, { * Gets the value of the property at the provided time. * * @param {JulianDate} time The time for which to retrieve the value. - * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned. - * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied. + * @param {object} [result] The object to store the value into, if omitted, a new instance is created and returned. + * @returns {object} The modified result parameter or a new instance if the result parameter was not supplied. */ TimeIntervalCollectionProperty.prototype.getValue = function (time, result) { //>>includeStart('debug', pragmas.debug); @@ -117,7 +117,7 @@ TimeIntervalCollectionProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ TimeIntervalCollectionProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/VelocityOrientationProperty.js b/packages/engine/Source/DataSources/VelocityOrientationProperty.js index 1486c214c96..f6b2788542b 100644 --- a/packages/engine/Source/DataSources/VelocityOrientationProperty.js +++ b/packages/engine/Source/DataSources/VelocityOrientationProperty.js @@ -47,7 +47,7 @@ Object.defineProperties(VelocityOrientationProperty.prototype, { * Gets a value indicating if this property is constant. * @memberof VelocityOrientationProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -137,7 +137,7 @@ VelocityOrientationProperty.prototype.getValue = function (time, result) { * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ VelocityOrientationProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/VelocityVectorProperty.js b/packages/engine/Source/DataSources/VelocityVectorProperty.js index ea547f9a2ef..0184422ffd0 100644 --- a/packages/engine/Source/DataSources/VelocityVectorProperty.js +++ b/packages/engine/Source/DataSources/VelocityVectorProperty.js @@ -14,7 +14,7 @@ import Property from "./Property.js"; * @constructor * * @param {PositionProperty} [position] The position property used to compute the velocity. - * @param {Boolean} [normalize=true] Whether to normalize the computed velocity vector. + * @param {boolean} [normalize=true] Whether to normalize the computed velocity vector. * * @example * //Create an entity with a billboard rotated to match its velocity. @@ -42,7 +42,7 @@ Object.defineProperties(VelocityVectorProperty.prototype, { * Gets a value indicating if this property is constant. * @memberof VelocityVectorProperty.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ isConstant: { @@ -99,7 +99,7 @@ Object.defineProperties(VelocityVectorProperty.prototype, { * will be normalized or not. * @memberof VelocityVectorProperty.prototype * - * @type {Boolean} + * @type {boolean} */ normalize: { get: function () { @@ -204,7 +204,7 @@ VelocityVectorProperty.prototype._getValue = function ( * <code>true</code> if they are equal, <code>false</code> otherwise. * * @param {Property} [other] The other property. - * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise. */ VelocityVectorProperty.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/DataSources/Visualizer.js b/packages/engine/Source/DataSources/Visualizer.js index 5a64cf18c85..fc9331513f9 100644 --- a/packages/engine/Source/DataSources/Visualizer.js +++ b/packages/engine/Source/DataSources/Visualizer.js @@ -26,7 +26,7 @@ function Visualizer() { * * @param {JulianDate} time The time. * - * @returns {Boolean} True if the display was updated to the provided time, + * @returns {boolean} True if the display was updated to the provided time, * false if the visualizer is waiting for an asynchronous operation to * complete before data can be updated. */ @@ -49,7 +49,7 @@ Visualizer.prototype.getBoundingSphere = DeveloperError.throwInstantiationError; * Returns true if this object was destroyed; otherwise, false. * @function * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ Visualizer.prototype.isDestroyed = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/DataSources/WallGraphics.js b/packages/engine/Source/DataSources/WallGraphics.js index 6e94982e4c7..05653c9225b 100644 --- a/packages/engine/Source/DataSources/WallGraphics.js +++ b/packages/engine/Source/DataSources/WallGraphics.js @@ -6,14 +6,14 @@ import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor import createPropertyDescriptor from "./createPropertyDescriptor.js"; /** - * @typedef {Object} WallGraphics.ConstructorOptions + * @typedef {object} WallGraphics.ConstructorOptions * * Initialization options for the WallGraphics constructor * * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the wall. - * @property {Property | Array<Cartesian3>} [positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall. - * @property {Property | Array<number>} [minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface. - * @property {Property | Array<number>} [maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position. + * @property {Property | Cartesian3[]} [positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall. + * @property {Property | number[]} [minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface. + * @property {Property | number[]} [maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position. * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point. * @property {Property | boolean} [fill=true] A boolean Property specifying whether the wall is filled with the provided material. * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the wall. diff --git a/packages/engine/Source/DataSources/exportKml.js b/packages/engine/Source/DataSources/exportKml.js index 2484f0c7dd4..1715dc9d021 100644 --- a/packages/engine/Source/DataSources/exportKml.js +++ b/packages/engine/Source/DataSources/exportKml.js @@ -224,14 +224,14 @@ IdManager.prototype.get = function (id) { /** * @typedef exportKmlResultKml - * @type {Object} - * @property {String} kml The generated KML. + * @type {object} + * @property {string} kml The generated KML. * @property {Object.<string, Blob>} externalFiles An object dictionary of external files */ /** * @typedef exportKmlResultKmz - * @type {Object} + * @type {object} * @property {Blob} kmz The generated kmz file. */ @@ -247,14 +247,14 @@ IdManager.prototype.get = function (id) { * * @function exportKml * - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {EntityCollection} options.entities The EntityCollection to export as KML. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for the output file. * @param {exportKmlModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection. * @param {JulianDate} [options.time=entities.computeAvailability().start] The time value to use to get properties that are not time varying in KML. * @param {TimeInterval} [options.defaultAvailability=entities.computeAvailability()] The interval that will be sampled if an entity doesn't have an availability. - * @param {Number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML. - * @param {Boolean} [options.kmz=false] If true KML and external files will be compressed into a kmz file. + * @param {number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML. + * @param {boolean} [options.kmz=false] If true KML and external files will be compressed into a kmz file. * * @returns {Promise<exportKmlResultKml|exportKmlResultKmz>} A promise that resolved to an object containing the KML string and a dictionary of external file blobs, or a kmz file as a blob if options.kmz is true. * @demo {@link https://sandcastle.cesium.com/index.html?src=Export%20KML.html|Cesium Sandcastle KML Export Demo} @@ -1513,7 +1513,7 @@ function colorToString(color) { * * @param {ModelGraphics} model The ModelGraphics instance for an Entity. * @param {JulianDate} time The time that any properties should use to get the value. - * @param {Object} externalFiles An object that maps a filename to a Blob or a Promise that resolves to a Blob. - * @returns {String} The URL to use for the href in the KML document. + * @param {object} externalFiles An object that maps a filename to a Blob or a Promise that resolves to a Blob. + * @returns {string} The URL to use for the href in the KML document. */ export default exportKml; diff --git a/packages/engine/Source/Renderer/Buffer.js b/packages/engine/Source/Renderer/Buffer.js index 8b323f3fb5f..641e8cc5c96 100644 --- a/packages/engine/Source/Renderer/Buffer.js +++ b/packages/engine/Source/Renderer/Buffer.js @@ -78,10 +78,10 @@ function Buffer(options) { * A vertex array defines the actual makeup of a vertex, e.g., positions, normals, texture coordinates, * etc., by interpreting the raw data in one or more vertex buffers. * - * @param {Object} options An object containing the following properties: + * @param {object} options An object containing the following properties: * @param {Context} options.context The context in which to create the buffer * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. - * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. + * @param {number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. * @returns {VertexBuffer} The vertex buffer, ready to be attached to a vertex array. * @@ -133,10 +133,10 @@ Buffer.createVertexBuffer = function (options) { * <code>Context.draw</code> can render using the entire index buffer or a subset * of the index buffer defined by an offset and count. * - * @param {Object} options An object containing the following properties: + * @param {object} options An object containing the following properties: * @param {Context} options.context The context in which to create the buffer * @param {ArrayBufferView} [options.typedArray] A typed array containing the data to copy to the buffer. - * @param {Number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. + * @param {number} [options.sizeInBytes] A <code>Number</code> defining the size of the buffer in bytes. Required if options.typedArray is not given. * @param {BufferUsage} options.usage Specifies the expected usage pattern of the buffer. On some GL implementations, this can significantly affect performance. See {@link BufferUsage}. * @param {IndexDatatype} options.indexDatatype The datatype of indices in the buffer. * @returns {IndexBuffer} The index buffer, ready to be attached to a vertex array. diff --git a/packages/engine/Source/Renderer/ClearCommand.js b/packages/engine/Source/Renderer/ClearCommand.js index b2b23f86c90..696db4f2934 100644 --- a/packages/engine/Source/Renderer/ClearCommand.js +++ b/packages/engine/Source/Renderer/ClearCommand.js @@ -22,7 +22,7 @@ function ClearCommand(options) { /** * The value to clear the depth buffer to. When <code>undefined</code>, the depth buffer is not cleared. * - * @type {Number} + * @type {number} * * @default undefined */ @@ -31,7 +31,7 @@ function ClearCommand(options) { /** * The value to clear the stencil buffer to. When <code>undefined</code>, the stencil buffer is not cleared. * - * @type {Number} + * @type {number} * * @default undefined */ @@ -63,7 +63,7 @@ function ClearCommand(options) { * reference to the command, and can be used to selectively execute commands * with {@link Scene#debugCommandFilter}. * - * @type {Object} + * @type {object} * * @default undefined * diff --git a/packages/engine/Source/Renderer/ComputeCommand.js b/packages/engine/Source/Renderer/ComputeCommand.js index abb9c71a9a5..0979b648c90 100644 --- a/packages/engine/Source/Renderer/ComputeCommand.js +++ b/packages/engine/Source/Renderer/ComputeCommand.js @@ -38,7 +38,7 @@ function ComputeCommand(options) { * An object with functions whose names match the uniforms in the shader program * and return values to set those uniforms. * - * @type {Object} + * @type {object} * @default undefined */ this.uniformMap = options.uniformMap; @@ -81,7 +81,7 @@ function ComputeCommand(options) { * Whether the renderer resources will persist beyond this call. If not, they * will be destroyed after completion. * - * @type {Boolean} + * @type {boolean} * @default false */ this.persists = defaultValue(options.persists, false); @@ -100,7 +100,7 @@ function ComputeCommand(options) { * reference to the command, and can be used to selectively execute commands * with {@link Scene#debugCommandFilter}. * - * @type {Object} + * @type {object} * @default undefined * * @see Scene#debugCommandFilter diff --git a/packages/engine/Source/Renderer/Context.js b/packages/engine/Source/Renderer/Context.js index b346e5fd652..2e51bd4fe7a 100644 --- a/packages/engine/Source/Renderer/Context.js +++ b/packages/engine/Source/Renderer/Context.js @@ -379,7 +379,7 @@ function Context(canvas, options) { * be stored globally, except they're tied to a particular context, and to manage * their lifetime. * - * @type {Object} + * @type {object} */ this.cache = {}; @@ -387,7 +387,7 @@ function Context(canvas, options) { } /** - * @typedef {Object} ContextOptions + * @typedef {object} ContextOptions * * Options to control the setting up of a WebGL Context. * <p> @@ -397,8 +397,8 @@ function Context(canvas, options) { * especially for horizon views. * </p> * - * @property {Boolean} [requestWebGl1=false] If true and the browser supports it, use a WebGL 1 rendering context - * @property {Boolean} [allowTextureFilterAnisotropic=true] If true, use anisotropic filtering during texture sampling + * @property {boolean} [requestWebGl1=false] If true and the browser supports it, use a WebGL 1 rendering context + * @property {boolean} [allowTextureFilterAnisotropic=true] If true, use anisotropic filtering during texture sampling * @property {WebGLOptions} [webgl] WebGL options to be passed on to canvas.getContext * @property {Function} [getWebGLStub] A function to create a WebGL stub for testing */ @@ -407,7 +407,7 @@ function Context(canvas, options) { * @private * @param {HTMLCanvasElement} canvas The canvas element to which the context will be associated * @param {WebGLOptions} webglOptions WebGL options to be passed on to HTMLCanvasElement.getContext() - * @param {Boolean} requestWebgl1 Whether to request a WebGLRenderingContext or a WebGL2RenderingContext. + * @param {boolean} requestWebgl1 Whether to request a WebGLRenderingContext or a WebGL2RenderingContext. * @returns {WebGLRenderingContext|WebGL2RenderingContext} */ function getWebGLContext(canvas, webglOptions, requestWebgl1) { @@ -436,7 +436,7 @@ function getWebGLContext(canvas, webglOptions, requestWebgl1) { } /** - * @typedef {Object} WebGLOptions + * @typedef {object} WebGLOptions * * WebGL options to be passed on to HTMLCanvasElement.getContext(). * See {@link https://registry.khronos.org/webgl/specs/latest/1.0/#5.2|WebGLContextAttributes} @@ -449,14 +449,14 @@ function getWebGLContext(canvas, webglOptions, requestWebgl1) { * <code>alpha</code> to true. * </p> * - * @property {Boolean} [alpha=false] - * @property {Boolean} [depth=true] - * @property {Boolean} [stencil=false] - * @property {Boolean} [antialias=true] - * @property {Boolean} [premultipliedAlpha=true] - * @property {Boolean} [preserveDrawingBuffer=false] + * @property {boolean} [alpha=false] + * @property {boolean} [depth=true] + * @property {boolean} [stencil=false] + * @property {boolean} [antialias=true] + * @property {boolean} [premultipliedAlpha=true] + * @property {boolean} [preserveDrawingBuffer=false] * @property {("default"|"low-power"|"high-performance")} [powerPreference="high-performance"] - * @property {Boolean} [failIfMajorPerformanceCaveat=false] + * @property {boolean} [failIfMajorPerformanceCaveat=false] */ function errorToString(gl, error) { @@ -608,7 +608,7 @@ Object.defineProperties(Context.prototype, { /** * The number of stencil bits per pixel in the default bound framebuffer. The minimum is eight bits. * @memberof Context.prototype - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>STENCIL_BITS</code>. */ stencilBits: { @@ -621,7 +621,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the WebGL context supports stencil buffers. * Stencil buffers are not supported by all systems. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} */ stencilBuffer: { get: function () { @@ -633,7 +633,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the WebGL context supports antialiasing. By default * antialiasing is requested, but it is not supported by all systems. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} */ antialias: { get: function () { @@ -645,7 +645,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the WebGL context supports multisample antialiasing. Requires * WebGL2. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} */ msaa: { get: function () { @@ -659,7 +659,7 @@ Object.defineProperties(Context.prototype, { * functions from GLSL. A shader using these functions still needs to explicitly enable the * extension with <code>#extension GL_OES_standard_derivatives : enable</code>. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/gles/extensions/OES/OES_standard_derivatives.txt|OES_standard_derivatives} */ standardDerivatives: { @@ -672,7 +672,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the EXT_float_blend extension is supported. This * extension enables blending with 32-bit float values. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_float_blend/} */ floatBlend: { @@ -686,7 +686,7 @@ Object.defineProperties(Context.prototype, { * extension extends blending capabilities by adding two new blend equations: * the minimum or maximum color components of the source and destination colors. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/} */ blendMinmax: { @@ -700,7 +700,7 @@ Object.defineProperties(Context.prototype, { * extension allows the use of unsigned int indices, which can improve performance by * eliminating batch breaking caused by unsigned short indices. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/|OES_element_index_uint} */ elementIndexUint: { @@ -713,7 +713,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_depth_texture is supported. This extension provides * access to depth textures that, for example, can be attached to framebuffers for shadow mapping. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} */ depthTexture: { @@ -726,7 +726,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if OES_texture_float is supported. This extension provides * access to floating point textures that, for example, can be attached to framebuffers for high dynamic range. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_float/} */ floatingPointTexture: { @@ -739,7 +739,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if OES_texture_half_float is supported. This extension provides * access to floating point textures that, for example, can be attached to framebuffers for high dynamic range. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/} */ halfFloatingPointTexture: { @@ -752,7 +752,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if OES_texture_float_linear is supported. This extension provides * access to linear sampling methods for minification and magnification filters of floating-point textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/} */ textureFloatLinear: { @@ -765,7 +765,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if OES_texture_half_float_linear is supported. This extension provides * access to linear sampling methods for minification and magnification filters of half floating-point textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float_linear/} */ textureHalfFloatLinear: { @@ -781,7 +781,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if EXT_texture_filter_anisotropic is supported. This extension provides * access to anisotropic filtering for textured surfaces at an oblique angle from the viewer. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/} */ textureFilterAnisotropic: { @@ -794,7 +794,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_compressed_texture_s3tc is supported. This extension provides * access to DXT compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/} */ s3tc: { @@ -807,7 +807,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_compressed_texture_pvrtc is supported. This extension provides * access to PVR compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/} */ pvrtc: { @@ -820,7 +820,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_compressed_texture_astc is supported. This extension provides * access to ASTC compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/} */ astc: { @@ -833,7 +833,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_compressed_texture_etc is supported. This extension provides * access to ETC compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/} */ etc: { @@ -846,7 +846,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if WEBGL_compressed_texture_etc1 is supported. This extension provides * access to ETC1 compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/} */ etc1: { @@ -859,7 +859,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if EXT_texture_compression_bptc is supported. This extension provides * access to BC7 compressed textures. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/} */ bc7: { @@ -871,7 +871,7 @@ Object.defineProperties(Context.prototype, { /** * <code>true</code> if S3TC, PVRTC, ASTC, ETC, ETC1, or BC7 compression is supported. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} */ supportsBasis: { get: function () { @@ -891,7 +891,7 @@ Object.defineProperties(Context.prototype, { * extension can improve performance by reducing the overhead of switching vertex arrays. * When enabled, this extension is automatically used by {@link VertexArray}. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/|OES_vertex_array_object} */ vertexArrayObject: { @@ -906,7 +906,7 @@ Object.defineProperties(Context.prototype, { * from GLSL fragment shaders. A shader using these functions still needs to explicitly enable the * extension with <code>#extension GL_EXT_frag_depth : enable</code>. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/|EXT_frag_depth} */ fragmentDepth: { @@ -919,7 +919,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the ANGLE_instanced_arrays extension is supported. This * extension provides access to instanced rendering. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays} */ instancedArrays: { @@ -932,7 +932,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the EXT_color_buffer_float extension is supported. This * extension makes the gl.RGBA32F format color renderable. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_color_buffer_float/} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/} */ @@ -946,7 +946,7 @@ Object.defineProperties(Context.prototype, { * <code>true</code> if the EXT_color_buffer_half_float extension is supported. This * extension makes the format gl.RGBA16F format color renderable. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_half_float/} * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/} */ @@ -966,7 +966,7 @@ Object.defineProperties(Context.prototype, { * A shader using this feature needs to explicitly enable the extension with * <code>#extension GL_EXT_draw_buffers : enable</code>. * @memberof Context.prototype - * @type {Boolean} + * @type {boolean} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_draw_buffers/|WEBGL_draw_buffers} */ drawBuffers: { @@ -1106,7 +1106,7 @@ Object.defineProperties(Context.prototype, { /** * The drawingBufferHeight of the underlying GL context. * @memberof Context.prototype - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} */ drawingBufferHeight: { @@ -1118,7 +1118,7 @@ Object.defineProperties(Context.prototype, { /** * The drawingBufferWidth of the underlying GL context. * @memberof Context.prototype - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} */ drawingBufferWidth: { @@ -1132,7 +1132,7 @@ Object.defineProperties(Context.prototype, { * {@link Framebuffer}, it is used to represent the default framebuffer in calls to * {@link Texture.fromFramebuffer}. * @memberof Context.prototype - * @type {Object} + * @type {object} */ defaultFramebuffer: { get: function () { @@ -1536,7 +1536,7 @@ Context.prototype.createViewportQuadCommand = function ( * Gets the object associated with a pick color. * * @param {Color} pickColor The pick color. - * @returns {Object} The object associated with the pick color, or undefined if no object is associated with that color. + * @returns {object} The object associated with the pick color, or undefined if no object is associated with that color. * * @example * const object = context.getObjectByPickColor(pickColor); @@ -1578,8 +1578,8 @@ PickId.prototype.destroy = function () { * The ID has an RGBA color value unique to this context. You must call destroy() * on the pick ID when destroying the input object. * - * @param {Object} object The object to associate with the pick ID. - * @returns {Object} A PickId object with a <code>color</code> property. + * @param {object} object The object to associate with the pick ID. + * @returns {object} A PickId object with a <code>color</code> property. * * @exception {RuntimeError} Out of unique Pick IDs. * diff --git a/packages/engine/Source/Renderer/ContextLimits.js b/packages/engine/Source/Renderer/ContextLimits.js index 287f44e494b..6bdb837cf60 100644 --- a/packages/engine/Source/Renderer/ContextLimits.js +++ b/packages/engine/Source/Renderer/ContextLimits.js @@ -32,7 +32,7 @@ Object.defineProperties(ContextLimits, { * shader with this WebGL implementation. The minimum is eight. If both shaders access the * same texture unit, this counts as two texture units. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_COMBINED_TEXTURE_IMAGE_UNITS</code>. */ maximumCombinedTextureImageUnits: { @@ -45,7 +45,7 @@ Object.defineProperties(ContextLimits, { * The approximate maximum cube mape width and height supported by this WebGL implementation. * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_CUBE_MAP_TEXTURE_SIZE</code>. */ maximumCubeMapSize: { @@ -58,7 +58,7 @@ Object.defineProperties(ContextLimits, { * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> * uniforms that can be used by a fragment shader with this WebGL implementation. The minimum is 16. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_FRAGMENT_UNIFORM_VECTORS</code>. */ maximumFragmentUniformVectors: { @@ -70,7 +70,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum number of texture units that can be used from the fragment shader with this WebGL implementation. The minimum is eight. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_IMAGE_UNITS</code>. */ maximumTextureImageUnits: { @@ -83,7 +83,7 @@ Object.defineProperties(ContextLimits, { * The maximum renderbuffer width and height supported by this WebGL implementation. * The minimum is 16, but most desktop and laptop implementations will support much larger sizes like 8,192. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_RENDERBUFFER_SIZE</code>. */ maximumRenderbufferSize: { @@ -96,7 +96,7 @@ Object.defineProperties(ContextLimits, { * The approximate maximum texture width and height supported by this WebGL implementation. * The minimum is 64, but most desktop and laptop implementations will support much larger sizes like 8,192. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_TEXTURE_SIZE</code>. */ maximumTextureSize: { @@ -109,7 +109,7 @@ Object.defineProperties(ContextLimits, { * The maximum number of <code>vec4</code> varying variables supported by this WebGL implementation. * The minimum is eight. Matrices and arrays count as multiple <code>vec4</code>s. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VARYING_VECTORS</code>. */ maximumVaryingVectors: { @@ -121,7 +121,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum number of <code>vec4</code> vertex attributes supported by this WebGL implementation. The minimum is eight. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_ATTRIBS</code>. */ maximumVertexAttributes: { @@ -134,7 +134,7 @@ Object.defineProperties(ContextLimits, { * The maximum number of texture units that can be used from the vertex shader with this WebGL implementation. * The minimum is zero, which means the GL does not support vertex texture fetch. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_TEXTURE_IMAGE_UNITS</code>. */ maximumVertexTextureImageUnits: { @@ -147,7 +147,7 @@ Object.defineProperties(ContextLimits, { * The maximum number of <code>vec4</code>, <code>ivec4</code>, and <code>bvec4</code> * uniforms that can be used by a vertex shader with this WebGL implementation. The minimum is 16. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VERTEX_UNIFORM_VECTORS</code>. */ maximumVertexUniformVectors: { @@ -159,7 +159,7 @@ Object.defineProperties(ContextLimits, { /** * The minimum aliased line width, in pixels, supported by this WebGL implementation. It will be at most one. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. */ minimumAliasedLineWidth: { @@ -171,7 +171,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. */ maximumAliasedLineWidth: { @@ -183,7 +183,7 @@ Object.defineProperties(ContextLimits, { /** * The minimum aliased point size, in pixels, supported by this WebGL implementation. It will be at most one. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. */ minimumAliasedPointSize: { @@ -195,7 +195,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum aliased point size, in pixels, supported by this WebGL implementation. It will be at least one. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_POINT_SIZE_RANGE</code>. */ maximumAliasedPointSize: { @@ -207,7 +207,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum supported width of the viewport. It will be at least as large as the visible width of the associated canvas. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. */ maximumViewportWidth: { @@ -219,7 +219,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum supported height of the viewport. It will be at least as large as the visible height of the associated canvas. * @memberof ContextLimits - * @type {Number} + * @type {number} * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>MAX_VIEWPORT_DIMS</code>. */ maximumViewportHeight: { @@ -231,7 +231,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum degree of anisotropy for texture filtering * @memberof ContextLimits - * @type {Number} + * @type {number} */ maximumTextureFilterAnisotropy: { get: function () { @@ -242,7 +242,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum number of simultaneous outputs that may be written in a fragment shader. * @memberof ContextLimits - * @type {Number} + * @type {number} */ maximumDrawBuffers: { get: function () { @@ -253,7 +253,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum number of color attachments supported. * @memberof ContextLimits - * @type {Number} + * @type {number} */ maximumColorAttachments: { get: function () { @@ -264,7 +264,7 @@ Object.defineProperties(ContextLimits, { /** * The maximum number of samples supported for multisampling. * @memberof ContextLimits - * @type {Number} + * @type {number} */ maximumSamples: { get: function () { @@ -275,7 +275,7 @@ Object.defineProperties(ContextLimits, { /** * High precision float supported (<code>highp</code>) in fragment shaders. * @memberof ContextLimits - * @type {Boolean} + * @type {boolean} */ highpFloatSupported: { get: function () { @@ -286,7 +286,7 @@ Object.defineProperties(ContextLimits, { /** * High precision int supported (<code>highp</code>) in fragment shaders. * @memberof ContextLimits - * @type {Boolean} + * @type {boolean} */ highpIntSupported: { get: function () { diff --git a/packages/engine/Source/Renderer/CubeMapFace.js b/packages/engine/Source/Renderer/CubeMapFace.js index c3730d5bc23..9f161b84876 100644 --- a/packages/engine/Source/Renderer/CubeMapFace.js +++ b/packages/engine/Source/Renderer/CubeMapFace.js @@ -54,12 +54,12 @@ Object.defineProperties(CubeMapFace.prototype, { /** * Copies texels from the source to the cubemap's face. - * @param {Object} options Object with the following properties: - * @param {Object} options.source The source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, {@link HTMLVideoElement}, + * @param {object} options Object with the following properties: + * @param {object} options.source The source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, {@link HTMLVideoElement}, * or an object with a width, height, and arrayBufferView properties. - * @param {Number} [options.xOffset=0] An offset in the x direction in the cubemap where copying begins. - * @param {Number} [options.yOffset=0] An offset in the y direction in the cubemap where copying begins. - * @param {Boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the texture will be ignored. + * @param {number} [options.xOffset=0] An offset in the x direction in the cubemap where copying begins. + * @param {number} [options.yOffset=0] An offset in the y direction in the cubemap where copying begins. + * @param {boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the texture will be ignored. * @exception {DeveloperError} xOffset must be greater than or equal to zero. * @exception {DeveloperError} yOffset must be greater than or equal to zero. * @exception {DeveloperError} xOffset + source.width must be less than or equal to width. @@ -268,12 +268,12 @@ CubeMapFace.prototype.copyFrom = function (options) { /** * Copies texels from the framebuffer to the cubemap's face. * - * @param {Number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. - * @param {Number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. - * @param {Number} [framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. - * @param {Number} [framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. - * @param {Number} [width=CubeMap's width] The width of the subimage to copy. - * @param {Number} [height=CubeMap's height] The height of the subimage to copy. + * @param {number} [xOffset=0] An offset in the x direction in the cubemap where copying begins. + * @param {number} [yOffset=0] An offset in the y direction in the cubemap where copying begins. + * @param {number} [framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. + * @param {number} [framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. + * @param {number} [width=CubeMap's width] The width of the subimage to copy. + * @param {number} [height=CubeMap's height] The height of the subimage to copy. * * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is HALF_FLOAT. diff --git a/packages/engine/Source/Renderer/DrawCommand.js b/packages/engine/Source/Renderer/DrawCommand.js index 0ecb8b3b583..14d75d5c7ee 100644 --- a/packages/engine/Source/Renderer/DrawCommand.js +++ b/packages/engine/Source/Renderer/DrawCommand.js @@ -93,7 +93,7 @@ Object.defineProperties(DrawCommand.prototype, { * </p> * * @memberof DrawCommand.prototype - * @type {Object} + * @type {object} * @default undefined * * @see DrawCommand#debugShowBoundingVolume @@ -137,7 +137,7 @@ Object.defineProperties(DrawCommand.prototype, { * If the command was already culled, set this to <code>false</code> for a performance improvement. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default true */ cull: { @@ -157,7 +157,7 @@ Object.defineProperties(DrawCommand.prototype, { * {@link DrawCommand#cull} must also be <code>true</code> in order for the command to be culled. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default true */ occlude: { @@ -236,7 +236,7 @@ Object.defineProperties(DrawCommand.prototype, { * The number of vertices to draw in the vertex array. * * @memberof DrawCommand.prototype - * @type {Number} + * @type {number} * @default undefined */ count: { @@ -255,7 +255,7 @@ Object.defineProperties(DrawCommand.prototype, { * The offset to start drawing in the vertex array. * * @memberof DrawCommand.prototype - * @type {Number} + * @type {number} * @default 0 */ offset: { @@ -274,7 +274,7 @@ Object.defineProperties(DrawCommand.prototype, { * The number of instances to draw. * * @memberof DrawCommand.prototype - * @type {Number} + * @type {number} * @default 0 */ instanceCount: { @@ -312,7 +312,7 @@ Object.defineProperties(DrawCommand.prototype, { * Whether this command should cast shadows when shadowing is enabled. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false */ castShadows: { @@ -331,7 +331,7 @@ Object.defineProperties(DrawCommand.prototype, { * Whether this command should receive shadows when shadowing is enabled. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false */ receiveShadows: { @@ -351,7 +351,7 @@ Object.defineProperties(DrawCommand.prototype, { * and return values to set those uniforms. * * @memberof DrawCommand.prototype - * @type {Object} + * @type {object} * @default undefined */ uniformMap: { @@ -428,7 +428,7 @@ Object.defineProperties(DrawCommand.prototype, { * to the eye containing the bounding volume. Defaults to <code>false</code>. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false */ executeInClosestFrustum: { @@ -450,7 +450,7 @@ Object.defineProperties(DrawCommand.prototype, { * with {@link Scene#debugCommandFilter}. * * @memberof DrawCommand.prototype - * @type {Object} + * @type {object} * @default undefined * * @see Scene#debugCommandFilter @@ -474,7 +474,7 @@ Object.defineProperties(DrawCommand.prototype, { * </p> * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false * * @see DrawCommand#boundingVolume @@ -511,7 +511,7 @@ Object.defineProperties(DrawCommand.prototype, { * during the pick pass. * * @memberof DrawCommand.prototype - * @type {String} + * @type {string} * @default undefined */ pickId: { @@ -529,7 +529,7 @@ Object.defineProperties(DrawCommand.prototype, { * Whether this command should be executed in the pick pass only. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false */ pickOnly: { @@ -547,7 +547,7 @@ Object.defineProperties(DrawCommand.prototype, { * Whether this command should be derived to draw depth for classification of translucent primitives. * * @memberof DrawCommand.prototype - * @type {Boolean} + * @type {boolean} * @default false */ depthForTranslucentClassification: { diff --git a/packages/engine/Source/Renderer/Framebuffer.js b/packages/engine/Source/Renderer/Framebuffer.js index 61a1ef71fcf..ad0caf4688b 100644 --- a/packages/engine/Source/Renderer/Framebuffer.js +++ b/packages/engine/Source/Renderer/Framebuffer.js @@ -33,7 +33,7 @@ function attachRenderbuffer(framebuffer, attachment, renderbuffer) { * Framebuffers are used for render-to-texture effects; they allow us to render to * textures in one pass, and read from it in a later pass. * - * @param {Object} options The initial framebuffer attachments as shown in the example below. <code>context</code> is required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthTexture</code>, <code>depthRenderbuffer</code>, <code>stencilRenderbuffer</code>, <code>depthStencilTexture</code>, <code>depthStencilRenderbuffer</code>, and <code>destroyAttachments</code>. + * @param {object} options The initial framebuffer attachments as shown in the example below. <code>context</code> is required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthTexture</code>, <code>depthRenderbuffer</code>, <code>stencilRenderbuffer</code>, <code>depthStencilTexture</code>, <code>depthStencilRenderbuffer</code>, and <code>destroyAttachments</code>. * * @exception {DeveloperError} Cannot have both color texture and color renderbuffer attachments. * @exception {DeveloperError} Cannot have both a depth texture and depth renderbuffer attachment. @@ -101,7 +101,7 @@ function Framebuffer(options) { * {@link Framebuffer#destroy} is called or when a new attachment is assigned * to an attachment point. * - * @type {Boolean} + * @type {boolean} * @default true * * @see Framebuffer#destroy @@ -292,7 +292,7 @@ Object.defineProperties(Framebuffer.prototype, { * The status of the framebuffer. If the status is not WebGLConstants.FRAMEBUFFER_COMPLETE, * a {@link DeveloperError} will be thrown when attempting to render to the framebuffer. * @memberof Framebuffer.prototype - * @type {Number} + * @type {number} */ status: { get: function () { @@ -338,7 +338,7 @@ Object.defineProperties(Framebuffer.prototype, { * depth and depth-stencil textures, and depth and depth-stencil renderbuffers. When * rendering to a framebuffer, a depth attachment is required for the depth test to have effect. * @memberof Framebuffer.prototype - * @type {Boolean} + * @type {boolean} */ hasDepthAttachment: { get: function () { diff --git a/packages/engine/Source/Renderer/FramebufferManager.js b/packages/engine/Source/Renderer/FramebufferManager.js index 83d4a5d2b48..5594895fa3d 100644 --- a/packages/engine/Source/Renderer/FramebufferManager.js +++ b/packages/engine/Source/Renderer/FramebufferManager.js @@ -13,15 +13,15 @@ import PixelFormat from "../Core/PixelFormat.js"; /** * Creates a wrapper object around a framebuffer and its resources. * - * @param {Object} options Object with the following properties: - * @param {Number} [options.numSamples=1] The multisampling rate of the render targets. Requires a WebGL2 context. - * @param {Number} [options.colorAttachmentsLength=1] The number of color attachments this FramebufferManager will create. - * @param {Boolean} [options.color=true] Whether the FramebufferManager will use color attachments. - * @param {Boolean} [options.depth=false] Whether the FramebufferManager will use depth attachments. - * @param {Boolean} [options.depthStencil=false] Whether the FramebufferManager will use depth-stencil attachments. - * @param {Boolean} [options.supportsDepthTexture=false] Whether the FramebufferManager will create a depth texture when the extension is supported. - * @param {Boolean} [options.createColorAttachments=true] Whether the FramebufferManager will construct its own color attachments. - * @param {Boolean} [options.createDepthAttachments=true] Whether the FramebufferManager will construct its own depth attachments. + * @param {object} options Object with the following properties: + * @param {number} [options.numSamples=1] The multisampling rate of the render targets. Requires a WebGL2 context. + * @param {number} [options.colorAttachmentsLength=1] The number of color attachments this FramebufferManager will create. + * @param {boolean} [options.color=true] Whether the FramebufferManager will use color attachments. + * @param {boolean} [options.depth=false] Whether the FramebufferManager will use depth attachments. + * @param {boolean} [options.depthStencil=false] Whether the FramebufferManager will use depth-stencil attachments. + * @param {boolean} [options.supportsDepthTexture=false] Whether the FramebufferManager will create a depth texture when the extension is supported. + * @param {boolean} [options.createColorAttachments=true] Whether the FramebufferManager will construct its own color attachments. + * @param {boolean} [options.createDepthAttachments=true] Whether the FramebufferManager will construct its own depth attachments. * @param {PixelDatatype} [options.pixelDatatype=undefined] The default pixel datatype to use when creating color attachments. * @param {PixelFormat} [options.pixelFormat=undefined] The default pixel format to use when creating color attachments. * diff --git a/packages/engine/Source/Renderer/MultisampleFramebuffer.js b/packages/engine/Source/Renderer/MultisampleFramebuffer.js index 9327cc49cc5..183e1bf20a7 100644 --- a/packages/engine/Source/Renderer/MultisampleFramebuffer.js +++ b/packages/engine/Source/Renderer/MultisampleFramebuffer.js @@ -12,7 +12,7 @@ import Framebuffer from "./Framebuffer.js"; * second is bound to DRAW_FRAMEBUFFER during the blit, and has texture attachments * to store the copied pixels. * - * @param {Object} options The initial framebuffer attachments. <code>context</code>, <code>width</code>, and <code>height</code> are required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthStencilTexture</code>, <code>depthStencilRenderbuffer</code>, and <code>destroyAttachments</code>. + * @param {object} options The initial framebuffer attachments. <code>context</code>, <code>width</code>, and <code>height</code> are required. The possible properties are <code>colorTextures</code>, <code>colorRenderbuffers</code>, <code>depthStencilTexture</code>, <code>depthStencilRenderbuffer</code>, and <code>destroyAttachments</code>. * * @exception {DeveloperError} Both color renderbuffer and texture attachments must be provided. * @exception {DeveloperError} Both depth-stencil renderbuffer and texture attachments must be provided. diff --git a/packages/engine/Source/Renderer/PassState.js b/packages/engine/Source/Renderer/PassState.js index f634256ce14..a0ec7e60341 100644 --- a/packages/engine/Source/Renderer/PassState.js +++ b/packages/engine/Source/Renderer/PassState.js @@ -30,7 +30,7 @@ function PassState(context) { * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. * </p> * - * @type {Boolean} + * @type {boolean} * @default undefined */ this.blendingEnabled = undefined; @@ -42,7 +42,7 @@ function PassState(context) { * When this is <code>undefined</code>, the {@link DrawCommand}'s property is used. * </p> * - * @type {Object} + * @type {object} * @default undefined */ this.scissorTest = undefined; diff --git a/packages/engine/Source/Renderer/PixelDatatype.js b/packages/engine/Source/Renderer/PixelDatatype.js index 4452a63fc8f..e04330d36f9 100644 --- a/packages/engine/Source/Renderer/PixelDatatype.js +++ b/packages/engine/Source/Renderer/PixelDatatype.js @@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * The data type of a pixel. * - * @enum {Number} + * @enum {number} * @see PostProcessStage */ const PixelDatatype = { diff --git a/packages/engine/Source/Renderer/RenderState.js b/packages/engine/Source/Renderer/RenderState.js index eabd07fa393..e83838745c3 100644 --- a/packages/engine/Source/Renderer/RenderState.js +++ b/packages/engine/Source/Renderer/RenderState.js @@ -372,7 +372,7 @@ let renderStateCache = {}; * state for a {@link DrawCommand} or {@link ClearCommand}. All inputs states are optional. Omitted states * use the defaults shown in the example below. * - * @param {Object} [renderState] The states defining the render state as shown in the example below. + * @param {object} [renderState] The states defining the render state as shown in the example below. * * @exception {RuntimeError} renderState.lineWidth is out of range. * @exception {DeveloperError} Invalid renderState.frontFace. diff --git a/packages/engine/Source/Renderer/ShaderBuilder.js b/packages/engine/Source/Renderer/ShaderBuilder.js index ddf650988a7..cf2756c28bb 100644 --- a/packages/engine/Source/Renderer/ShaderBuilder.js +++ b/packages/engine/Source/Renderer/ShaderBuilder.js @@ -92,7 +92,7 @@ Object.defineProperties(ShaderBuilder.prototype, { * the vertex shader. * * @memberof ShaderBuilder.prototype - * @type {Object.<String, Number>} + * @type {Object.<string, Number>} * @readonly * @private */ @@ -107,8 +107,8 @@ Object.defineProperties(ShaderBuilder.prototype, { * Add a <code>#define</code> macro to one or both of the shaders. These lines * will appear at the top of the final shader source. * - * @param {String} identifier An identifier for the macro. Identifiers must use uppercase letters with underscores to be consistent with Cesium's style guide. - * @param {String} [value] The value of the macro. If undefined, the define will not include a value. The value will be converted to GLSL code via <code>toString()</code> + * @param {string} identifier An identifier for the macro. Identifiers must use uppercase letters with underscores to be consistent with Cesium's style guide. + * @param {string} [value] The value of the macro. If undefined, the define will not include a value. The value will be converted to GLSL code via <code>toString()</code> * @param {ShaderDestination} [destination=ShaderDestination.BOTH] Whether the define appears in the vertex shader, the fragment shader, or both. * * @example @@ -141,8 +141,8 @@ ShaderBuilder.prototype.addDefine = function (identifier, value, destination) { /** * Add a new dynamically-generated struct to the shader - * @param {String} structId A unique ID to identify this struct in {@link ShaderBuilder#addStructField} - * @param {String} structName The name of the struct as it will appear in the shader. + * @param {string} structId A unique ID to identify this struct in {@link ShaderBuilder#addStructField} + * @param {string} structName The name of the struct as it will appear in the shader. * @param {ShaderDestination} destination Whether the struct will appear in the vertex shader, the fragment shader, or both. * * @example @@ -174,9 +174,9 @@ ShaderBuilder.prototype.addStruct = function ( /** * Add a field to a dynamically-generated struct. - * @param {String} structId The ID of the struct. This must be created first with {@link ShaderBuilder#addStruct} - * @param {String} type The GLSL type of the field - * @param {String} identifier The identifier of the field. + * @param {string} structId The ID of the struct. This must be created first with {@link ShaderBuilder#addStruct} + * @param {string} type The GLSL type of the field + * @param {string} identifier The identifier of the field. * * @example * // generates the following struct in the fragment shader @@ -200,8 +200,8 @@ ShaderBuilder.prototype.addStructField = function (structId, type, identifier) { /** * Add a new dynamically-generated function to the shader. - * @param {String} functionName The name of the function. This will be used to identify the function in {@link ShaderBuilder#addFunctionLines}. - * @param {String} signature The full signature of the function as it will appear in the shader. Do not include the curly braces. + * @param {string} functionName The name of the function. This will be used to identify the function in {@link ShaderBuilder#addFunctionLines}. + * @param {string} signature The full signature of the function as it will appear in the shader. Do not include the curly braces. * @param {ShaderDestination} destination Whether the struct will appear in the vertex shader, the fragment shader, or both. * @example * // generates the following function in the vertex shader @@ -233,8 +233,8 @@ ShaderBuilder.prototype.addFunction = function ( /** * Add lines to a dynamically-generated function - * @param {String} functionName The name of the function. This must be created beforehand using {@link ShaderBuilder#addFunction} - * @param {String|String[]} lines One or more lines of GLSL code to add to the function body. Do not include any preceding or ending whitespace, but do include the semicolon for each line. + * @param {string} functionName The name of the function. This must be created beforehand using {@link ShaderBuilder#addFunction} + * @param {string|string[]} lines One or more lines of GLSL code to add to the function body. Do not include any preceding or ending whitespace, but do include the semicolon for each line. * * @example * // generates the following function in the vertex shader @@ -265,8 +265,8 @@ ShaderBuilder.prototype.addFunctionLines = function (functionName, lines) { * Add a uniform declaration to one or both of the shaders. These lines * will appear grouped near the top of the final shader source. * - * @param {String} type The GLSL type of the uniform. - * @param {String} identifier An identifier for the uniform. Identifiers must begin with <code>u_</code> to be consistent with Cesium's style guide. + * @param {string} type The GLSL type of the uniform. + * @param {string} identifier An identifier for the uniform. Identifiers must begin with <code>u_</code> to be consistent with Cesium's style guide. * @param {ShaderDestination} [destination=ShaderDestination.BOTH] Whether the uniform appears in the vertex shader, the fragment shader, or both. * * @example @@ -302,9 +302,9 @@ ShaderBuilder.prototype.addUniform = function (type, identifier, destination) { * {@link ShaderBuilder#addAttribute} * </p> * - * @param {String} type The GLSL type of the attribute - * @param {String} identifier An identifier for the attribute. Identifiers must begin with <code>a_</code> to be consistent with Cesium's style guide. - * @return {Number} The integer location of the attribute. This location can be used when creating attributes for a {@link VertexArray}. This will always be 0. + * @param {string} type The GLSL type of the attribute + * @param {string} identifier An identifier for the attribute. Identifiers must begin with <code>a_</code> to be consistent with Cesium's style guide. + * @return {number} The integer location of the attribute. This location can be used when creating attributes for a {@link VertexArray}. This will always be 0. * * @example * // creates the line "in vec3 a_position;" @@ -338,9 +338,9 @@ ShaderBuilder.prototype.setPositionAttribute = function (type, identifier) { * reserved for the position attribute. See {@link ShaderBuilder#setPositionAttribute} * </p> * - * @param {String} type The GLSL type of the attribute - * @param {String} identifier An identifier for the attribute. Identifiers must begin with <code>a_</code> to be consistent with Cesium's style guide. - * @return {Number} The integer location of the attribute. This location can be used when creating attributes for a {@link VertexArray} + * @param {string} type The GLSL type of the attribute + * @param {string} identifier An identifier for the attribute. Identifiers must begin with <code>a_</code> to be consistent with Cesium's style guide. + * @return {number} The integer location of the attribute. This location can be used when creating attributes for a {@link VertexArray} * * @example * // creates the line "in vec2 a_texCoord0;" in the vertex shader @@ -367,8 +367,8 @@ ShaderBuilder.prototype.addAttribute = function (type, identifier) { /** * Add a varying declaration to both the vertex and fragment shaders. * - * @param {String} type The GLSL type of the varying - * @param {String} identifier An identifier for the varying. Identifiers must begin with <code>v_</code> to be consistent with Cesium's style guide. + * @param {string} type The GLSL type of the varying + * @param {string} identifier An identifier for the varying. Identifiers must begin with <code>v_</code> to be consistent with Cesium's style guide. * * @example * // creates the line "in vec3 v_color;" in the vertex shader @@ -389,7 +389,7 @@ ShaderBuilder.prototype.addVarying = function (type, identifier) { /** * Appends lines of GLSL code to the vertex shader * - * @param {String|String[]} lines One or more lines to add to the end of the vertex shader source + * @param {string|string[]} lines One or more lines to add to the end of the vertex shader source * * @example * shaderBuilder.addVertexLines([ @@ -421,7 +421,7 @@ ShaderBuilder.prototype.addVertexLines = function (lines) { /** * Appends lines of GLSL code to the fragment shader * - * @param {String[]} lines The lines to add to the end of the fragment shader source + * @param {string[]} lines The lines to add to the end of the fragment shader source * * @example * shaderBuilder.addFragmentLines([ diff --git a/packages/engine/Source/Renderer/ShaderCache.js b/packages/engine/Source/Renderer/ShaderCache.js index b7addaf09d6..95268dd6b8b 100644 --- a/packages/engine/Source/Renderer/ShaderCache.js +++ b/packages/engine/Source/Renderer/ShaderCache.js @@ -29,11 +29,11 @@ Object.defineProperties(ShaderCache.prototype, { * replace an existing reference to a shader program, which is passed as the first argument. * </p> * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ShaderProgram} [options.shaderProgram] The shader program that is being reassigned. - * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. - * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. - * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. + * @param {string|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. + * @param {string|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. + * @param {object} options.attributeLocations Indices for the attribute inputs to the vertex shader. * @returns {ShaderProgram} The cached or newly created shader program. * @@ -65,10 +65,10 @@ function toSortedJson(dictionary) { * Returns a shader program from the cache, or creates and caches a new shader program, * given the GLSL vertex and fragment shader source and attribute locations. * - * @param {Object} options Object with the following properties: - * @param {String|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. - * @param {String|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. - * @param {Object} options.attributeLocations Indices for the attribute inputs to the vertex shader. + * @param {object} options Object with the following properties: + * @param {string|ShaderSource} options.vertexShaderSource The GLSL source for the vertex shader. + * @param {string|ShaderSource} options.fragmentShaderSource The GLSL source for the fragment shader. + * @param {object} options.attributeLocations Indices for the attribute inputs to the vertex shader. * * @returns {ShaderProgram} The cached or newly created shader program. */ diff --git a/packages/engine/Source/Renderer/ShaderDestination.js b/packages/engine/Source/Renderer/ShaderDestination.js index bcc4b238579..eb3a9af3c31 100644 --- a/packages/engine/Source/Renderer/ShaderDestination.js +++ b/packages/engine/Source/Renderer/ShaderDestination.js @@ -16,7 +16,7 @@ const ShaderDestination = { * Check if a variable should be included in the vertex shader. * * @param {ShaderDestination} destination The ShaderDestination to check - * @return {Boolean} <code>true</code> if the variable appears in the vertex shader, or <code>false</code> otherwise + * @return {boolean} <code>true</code> if the variable appears in the vertex shader, or <code>false</code> otherwise * @private */ ShaderDestination.includesVertexShader = function (destination) { @@ -34,7 +34,7 @@ ShaderDestination.includesVertexShader = function (destination) { * Check if a variable should be included in the vertex shader. * * @param {ShaderDestination} destination The ShaderDestination to check - * @return {Boolean} <code>true</code> if the variable appears in the vertex shader, or <code>false</code> otherwise + * @return {boolean} <code>true</code> if the variable appears in the vertex shader, or <code>false</code> otherwise * @private */ ShaderDestination.includesFragmentShader = function (destination) { diff --git a/packages/engine/Source/Renderer/ShaderFunction.js b/packages/engine/Source/Renderer/ShaderFunction.js index 4f84cf51388..3da6656486e 100644 --- a/packages/engine/Source/Renderer/ShaderFunction.js +++ b/packages/engine/Source/Renderer/ShaderFunction.js @@ -7,7 +7,7 @@ import DeveloperError from "../Core/DeveloperError.js"; * @constructor * * @see {@link ShaderBuilder} - * @param {String} signature The full signature of the function as it will appear in the shader. Do not include the curly braces. + * @param {string} signature The full signature of the function as it will appear in the shader. Do not include the curly braces. * @example * // generate the following function * // @@ -31,7 +31,7 @@ function ShaderFunction(signature) { /** * Adds one or more lines to the body of the function - * @param {String|String[]} lines One or more lines of GLSL code to add to the function body. Do not include any preceding or ending whitespace, but do include the semicolon for each line. + * @param {string|string[]} lines One or more lines of GLSL code to add to the function body. Do not include any preceding or ending whitespace, but do include the semicolon for each line. */ ShaderFunction.prototype.addLines = function (lines) { //>>includeStart('debug', pragmas.debug); @@ -57,7 +57,7 @@ ShaderFunction.prototype.addLines = function (lines) { /** * Generate lines of GLSL code for use with {@link ShaderBuilder} - * @return {String[]} + * @return {string[]} */ ShaderFunction.prototype.generateGlslLines = function () { return [].concat(this.signature, "{", this.body, "}"); diff --git a/packages/engine/Source/Renderer/ShaderSource.js b/packages/engine/Source/Renderer/ShaderSource.js index 493aa622920..66d253e19ef 100644 --- a/packages/engine/Source/Renderer/ShaderSource.js +++ b/packages/engine/Source/Renderer/ShaderSource.js @@ -304,11 +304,11 @@ function combineShader(shaderSource, isFragmentShader, context) { /** * An object containing various inputs that will be combined to form a final GLSL shader string. * - * @param {Object} [options] Object with the following properties: - * @param {String[]} [options.sources] An array of strings to combine containing GLSL code for the shader. - * @param {String[]} [options.defines] An array of strings containing GLSL identifiers to <code>#define</code>. - * @param {String} [options.pickColorQualifier] The GLSL qualifier, <code>uniform</code> or <code>in</code>, for the input <code>czm_pickColor</code>. When defined, a pick fragment shader is generated. - * @param {Boolean} [options.includeBuiltIns=true] If true, referenced built-in functions will be included with the combined shader. Set to false if this shader will become a source in another shader, to avoid duplicating functions. + * @param {object} [options] Object with the following properties: + * @param {string[]} [options.sources] An array of strings to combine containing GLSL code for the shader. + * @param {string[]} [options.defines] An array of strings containing GLSL identifiers to <code>#define</code>. + * @param {string} [options.pickColorQualifier] The GLSL qualifier, <code>uniform</code> or <code>in</code>, for the input <code>czm_pickColor</code>. When defined, a pick fragment shader is generated. + * @param {boolean} [options.includeBuiltIns=true] If true, referenced built-in functions will be included with the combined shader. Set to false if this shader will become a source in another shader, to avoid duplicating functions. * * @exception {DeveloperError} options.pickColorQualifier must be 'uniform' or 'in'. * @@ -368,7 +368,7 @@ ShaderSource.replaceMain = function (source, renamedMain) { * {@link ShaderSource#createCombinedFragmentShader} are both expensive to * compute, create a simpler string key for lookups in the {@link ShaderCache}. * - * @returns {String} A key for identifying this shader + * @returns {string} A key for identifying this shader * * @private */ @@ -388,7 +388,7 @@ ShaderSource.prototype.getCacheKey = function () { * * @param {Context} context The current rendering context * - * @returns {String} The combined shader string. + * @returns {string} The combined shader string. */ ShaderSource.prototype.createCombinedVertexShader = function (context) { return combineShader(this, false, context); @@ -399,7 +399,7 @@ ShaderSource.prototype.createCombinedVertexShader = function (context) { * * @param {Context} context The current rendering context * - * @returns {String} The combined shader string. + * @returns {string} The combined shader string. */ ShaderSource.prototype.createCombinedFragmentShader = function (context) { return combineShader(this, true, context); diff --git a/packages/engine/Source/Renderer/ShaderStruct.js b/packages/engine/Source/Renderer/ShaderStruct.js index 9b2a2c7c1fa..c65c4983cd2 100644 --- a/packages/engine/Source/Renderer/ShaderStruct.js +++ b/packages/engine/Source/Renderer/ShaderStruct.js @@ -5,7 +5,7 @@ * @constructor * * @see {@link ShaderBuilder} - * @param {String} name The name of the struct as it will appear in the shader. + * @param {string} name The name of the struct as it will appear in the shader. * @example * // Generate the struct: * // @@ -30,8 +30,8 @@ function ShaderStruct(name) { /** * Add a field to the struct - * @param {String} type The type of the struct field - * @param {String} identifier The identifier of the struct field + * @param {string} type The type of the struct field + * @param {string} identifier The identifier of the struct field */ ShaderStruct.prototype.addField = function (type, identifier) { const field = ` ${type} ${identifier};`; @@ -40,7 +40,7 @@ ShaderStruct.prototype.addField = function (type, identifier) { /** * Generate a list of lines of GLSL code for use with {@link ShaderBuilder} - * @return {String[]} The generated GLSL code. + * @return {string[]} The generated GLSL code. */ ShaderStruct.prototype.generateGlslLines = function () { let fields = this.fields; diff --git a/packages/engine/Source/Renderer/Texture.js b/packages/engine/Source/Renderer/Texture.js index e75a25274ca..1f157e74ce1 100644 --- a/packages/engine/Source/Renderer/Texture.js +++ b/packages/engine/Source/Renderer/Texture.js @@ -411,13 +411,13 @@ Texture.create = function (options) { * Creates a texture, and copies a subimage of the framebuffer to it. When called without arguments, * the texture is the same width and height as the framebuffer and contains its contents. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Context} options.context The context in which the Texture gets created. * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGB] The texture's internal pixel format. - * @param {Number} [options.framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. - * @param {Number} [options.framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. - * @param {Number} [options.width=canvas.clientWidth] The width of the texture in texels. - * @param {Number} [options.height=canvas.clientHeight] The height of the texture in texels. + * @param {number} [options.framebufferXOffset=0] An offset in the x direction in the framebuffer where copying begins from. + * @param {number} [options.framebufferYOffset=0] An offset in the y direction in the framebuffer where copying begins from. + * @param {number} [options.width=canvas.clientWidth] The width of the texture in texels. + * @param {number} [options.height=canvas.clientHeight] The height of the texture in texels. * @param {Framebuffer} [options.framebuffer=defaultFramebuffer] The framebuffer from which to create the texture. If this * parameter is not specified, the default framebuffer is used. * @returns {Texture} A texture with contents from the framebuffer. @@ -515,7 +515,7 @@ Object.defineProperties(Texture.prototype, { /** * A unique id for the texture * @memberof Texture.prototype - * @type {String} + * @type {string} * @readonly * @private */ @@ -531,7 +531,7 @@ Object.defineProperties(Texture.prototype, { * coordinates in both directions, uses linear filtering for both magnification and minification, * and uses a maximum anisotropy of 1.0. * @memberof Texture.prototype - * @type {Object} + * @type {object} */ sampler: { get: function () { @@ -648,12 +648,12 @@ Object.defineProperties(Texture.prototype, { /** * Copy new image data into this texture, from a source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, or {@link HTMLVideoElement}. * or an object with width, height, and arrayBufferView properties. - * @param {Object} options Object with the following properties: - * @param {Object} options.source The source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, or {@link HTMLVideoElement}, + * @param {object} options Object with the following properties: + * @param {object} options.source The source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, or {@link HTMLVideoElement}, * or an object with width, height, and arrayBufferView properties. - * @param {Number} [options.xOffset=0] The offset in the x direction within the texture to copy into. - * @param {Number} [options.yOffset=0] The offset in the y direction within the texture to copy into. - * @param {Boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the texture will be ignored. + * @param {number} [options.xOffset=0] The offset in the x direction within the texture to copy into. + * @param {number} [options.yOffset=0] The offset in the y direction within the texture to copy into. + * @param {boolean} [options.skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the texture will be ignored. * * @exception {DeveloperError} Cannot call copyFrom when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. * @exception {DeveloperError} Cannot call copyFrom with a compressed texture pixel format. @@ -872,12 +872,12 @@ Texture.prototype.copyFrom = function (options) { }; /** - * @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into. - * @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into. - * @param {Number} [framebufferXOffset=0] optional - * @param {Number} [framebufferYOffset=0] optional - * @param {Number} [width=width] optional - * @param {Number} [height=height] optional + * @param {number} [xOffset=0] The offset in the x direction within the texture to copy into. + * @param {number} [yOffset=0] The offset in the y direction within the texture to copy into. + * @param {number} [framebufferXOffset=0] optional + * @param {number} [framebufferYOffset=0] optional + * @param {number} [width=width] optional + * @param {number} [height=height] optional * * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel format is DEPTH_COMPONENT or DEPTH_STENCIL. * @exception {DeveloperError} Cannot call copyFromFramebuffer when the texture pixel data type is FLOAT. diff --git a/packages/engine/Source/Renderer/TextureMagnificationFilter.js b/packages/engine/Source/Renderer/TextureMagnificationFilter.js index d432fe40570..3dfc3589def 100644 --- a/packages/engine/Source/Renderer/TextureMagnificationFilter.js +++ b/packages/engine/Source/Renderer/TextureMagnificationFilter.js @@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Enumerates all possible filters used when magnifying WebGL textures. * - * @enum {Number} + * @enum {number} * * @see TextureMinificationFilter */ @@ -11,14 +11,14 @@ const TextureMagnificationFilter = { /** * Samples the texture by returning the closest pixel. * - * @type {Number} + * @type {number} * @constant */ NEAREST: WebGLConstants.NEAREST, /** * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. * - * @type {Number} + * @type {number} * @constant */ LINEAR: WebGLConstants.LINEAR, @@ -27,7 +27,7 @@ const TextureMagnificationFilter = { /** * Validates the given <code>textureMinificationFilter</code> with respect to the possible enum values. * @param textureMagnificationFilter - * @returns {Boolean} <code>true</code> if <code>textureMagnificationFilter</code> is valid. + * @returns {boolean} <code>true</code> if <code>textureMagnificationFilter</code> is valid. * * @private */ diff --git a/packages/engine/Source/Renderer/TextureMinificationFilter.js b/packages/engine/Source/Renderer/TextureMinificationFilter.js index ddab3b091f1..9c881d20666 100644 --- a/packages/engine/Source/Renderer/TextureMinificationFilter.js +++ b/packages/engine/Source/Renderer/TextureMinificationFilter.js @@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Enumerates all possible filters used when minifying WebGL textures. * - * @enum {Number} + * @enum {number} * * @see TextureMagnificationFilter */ @@ -11,14 +11,14 @@ const TextureMinificationFilter = { /** * Samples the texture by returning the closest pixel. * - * @type {Number} + * @type {number} * @constant */ NEAREST: WebGLConstants.NEAREST, /** * Samples the texture through bi-linear interpolation of the four nearest pixels. This produces smoother results than <code>NEAREST</code> filtering. * - * @type {Number} + * @type {number} * @constant */ LINEAR: WebGLConstants.LINEAR, @@ -28,7 +28,7 @@ const TextureMinificationFilter = { * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. * </p> * - * @type {Number} + * @type {number} * @constant */ NEAREST_MIPMAP_NEAREST: WebGLConstants.NEAREST_MIPMAP_NEAREST, @@ -38,7 +38,7 @@ const TextureMinificationFilter = { * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. * </p> * - * @type {Number} + * @type {number} * @constant */ LINEAR_MIPMAP_NEAREST: WebGLConstants.LINEAR_MIPMAP_NEAREST, @@ -51,7 +51,7 @@ const TextureMinificationFilter = { * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. * </p> * - * @type {Number} + * @type {number} * @constant */ NEAREST_MIPMAP_LINEAR: WebGLConstants.NEAREST_MIPMAP_LINEAR, @@ -63,7 +63,7 @@ const TextureMinificationFilter = { * <p> * Requires that the texture has a mipmap. The mip level is chosen by the view angle and screen-space size of the texture. * </p> - * @type {Number} + * @type {number} * @constant */ LINEAR_MIPMAP_LINEAR: WebGLConstants.LINEAR_MIPMAP_LINEAR, @@ -75,7 +75,7 @@ const TextureMinificationFilter = { * @private * * @param textureMinificationFilter - * @returns {Boolean} <code>true</code> if <code>textureMinificationFilter</code> is valid. + * @returns {boolean} <code>true</code> if <code>textureMinificationFilter</code> is valid. */ TextureMinificationFilter.validate = function (textureMinificationFilter) { return ( diff --git a/packages/engine/Source/Renderer/UniformState.js b/packages/engine/Source/Renderer/UniformState.js index ea292e6cece..75e55c25da0 100644 --- a/packages/engine/Source/Renderer/UniformState.js +++ b/packages/engine/Source/Renderer/UniformState.js @@ -27,7 +27,7 @@ function UniformState() { */ this.globeDepthTexture = undefined; /** - * @type {Number} + * @type {number} */ this.gamma = undefined; @@ -640,7 +640,7 @@ Object.defineProperties(UniformState.prototype, { * The far plane's distance from the near plane, plus 1.0. * * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ farDepthFromNearPlusOne: { get: function () { @@ -652,7 +652,7 @@ Object.defineProperties(UniformState.prototype, { * The log2 of {@link UniformState#farDepthFromNearPlusOne}. * * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ log2FarDepthFromNearPlusOne: { get: function () { @@ -664,7 +664,7 @@ Object.defineProperties(UniformState.prototype, { * 1.0 divided by {@link UniformState#log2FarDepthFromNearPlusOne}. * * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ oneOverLog2FarDepthFromNearPlusOne: { get: function () { @@ -675,7 +675,7 @@ Object.defineProperties(UniformState.prototype, { /** * The height in meters of the eye (camera) above or below the ellipsoid. * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ eyeHeight: { get: function () { @@ -846,7 +846,7 @@ Object.defineProperties(UniformState.prototype, { * Gets the scaling factor for transforming from the canvas * pixel space to canvas coordinate space. * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ pixelRatio: { get: function () { @@ -857,7 +857,7 @@ Object.defineProperties(UniformState.prototype, { /** * A scalar used to mix a color with the fog color based on the distance to the camera. * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ fogDensity: { get: function () { @@ -868,7 +868,7 @@ Object.defineProperties(UniformState.prototype, { /** * A scalar that represents the geometric tolerance per meter * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ geometricToleranceOverMeter: { get: function () { @@ -955,7 +955,7 @@ Object.defineProperties(UniformState.prototype, { /** * The maximum level-of-detail of the specular environment map atlas of the scene. * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ specularEnvironmentMapsMaximumLOD: { get: function () { @@ -966,7 +966,7 @@ Object.defineProperties(UniformState.prototype, { /** * The splitter position to use when rendering with a splitter. This will be in pixel coordinates relative to the canvas. * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ splitPosition: { get: function () { @@ -980,7 +980,7 @@ Object.defineProperties(UniformState.prototype, { * be applied. When less than zero, the depth test should never be applied. * * @memberof UniformState.prototype - * @type {Number} + * @type {number} */ minimumDisableDepthTestDistance: { get: function () { @@ -1004,7 +1004,7 @@ Object.defineProperties(UniformState.prototype, { * Whether or not the current projection is orthographic in 3D. * * @memberOf UniformState.prototype - * @type {Boolean} + * @type {boolean} */ orthographicIn3D: { get: function () { @@ -1135,7 +1135,7 @@ function setSunAndMoonDirections(uniformState, frameState) { * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms * are set to the right value. * - * @param {Object} camera The camera to synchronize with. + * @param {object} camera The camera to synchronize with. */ UniformState.prototype.updateCamera = function (camera) { setView(this, camera.viewMatrix); @@ -1156,7 +1156,7 @@ UniformState.prototype.updateCamera = function (camera) { * by the {@link Scene} when rendering to ensure that automatic GLSL uniforms * are set to the right value. * - * @param {Object} frustum The frustum to synchronize with. + * @param {object} frustum The frustum to synchronize with. */ UniformState.prototype.updateFrustum = function (frustum) { setProjection(this, frustum.projectionMatrix); diff --git a/packages/engine/Source/Renderer/VertexArray.js b/packages/engine/Source/Renderer/VertexArray.js index 3241144a490..ed35bd1b76c 100644 --- a/packages/engine/Source/Renderer/VertexArray.js +++ b/packages/engine/Source/Renderer/VertexArray.js @@ -178,7 +178,7 @@ function bind(gl, attributes, indexBuffer) { * Creates a vertex array, which defines the attributes making up a vertex, and contains an optional index buffer * to select vertices for rendering. Attributes are defined using object literals as shown in Example 1 below. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Context} options.context The context in which the VertexArray gets created. * @param {Object[]} options.attributes An array of attributes. * @param {IndexBuffer} [options.indexBuffer] An optional index buffer. @@ -531,7 +531,7 @@ function interleaveAttributes(attributes) { * <br /> * If <code>options</code> is not specified or the <code>geometry</code> contains no data, the returned vertex array is empty. * - * @param {Object} options An object defining the geometry, attribute indices, buffer usage, and vertex layout used to create the vertex array. + * @param {object} options An object defining the geometry, attribute indices, buffer usage, and vertex layout used to create the vertex array. * * @exception {RuntimeError} Each attribute list must have the same number of vertices. * @exception {DeveloperError} The geometry must have zero or one index lists. diff --git a/packages/engine/Source/Renderer/createUniform.js b/packages/engine/Source/Renderer/createUniform.js index 55f43cd1ff1..ccf68c1981f 100644 --- a/packages/engine/Source/Renderer/createUniform.js +++ b/packages/engine/Source/Renderer/createUniform.js @@ -57,7 +57,7 @@ function createUniform(gl, activeUniform, uniformName, location) { */ function UniformFloat(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -84,7 +84,7 @@ UniformFloat.prototype.set = function () { */ function UniformFloatVec2(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -112,7 +112,7 @@ UniformFloatVec2.prototype.set = function () { */ function UniformFloatVec3(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -152,7 +152,7 @@ UniformFloatVec3.prototype.set = function () { */ function UniformFloatVec4(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -192,7 +192,7 @@ UniformFloatVec4.prototype.set = function () { */ function UniformSampler(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -227,7 +227,7 @@ UniformSampler.prototype._setSampler = function (textureUnitIndex) { */ function UniformInt(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -253,7 +253,7 @@ UniformInt.prototype.set = function () { */ function UniformIntVec2(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -280,7 +280,7 @@ UniformIntVec2.prototype.set = function () { */ function UniformIntVec3(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -307,7 +307,7 @@ UniformIntVec3.prototype.set = function () { */ function UniformIntVec4(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -336,7 +336,7 @@ const scratchUniformArray = new Float32Array(4); */ function UniformMat2(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -366,7 +366,7 @@ const scratchMat3Array = new Float32Array(9); */ function UniformMat3(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -396,7 +396,7 @@ const scratchMat4Array = new Float32Array(16); */ function UniformMat4(gl, activeUniform, uniformName, location) { /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; diff --git a/packages/engine/Source/Renderer/createUniformArray.js b/packages/engine/Source/Renderer/createUniformArray.js index 8028c837089..0c9268a1d7b 100644 --- a/packages/engine/Source/Renderer/createUniformArray.js +++ b/packages/engine/Source/Renderer/createUniformArray.js @@ -74,7 +74,7 @@ function UniformArrayFloat(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -116,7 +116,7 @@ function UniformArrayFloatVec2(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -160,7 +160,7 @@ function UniformArrayFloatVec3(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -222,7 +222,7 @@ function UniformArrayFloatVec4(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -289,7 +289,7 @@ function UniformArraySampler(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -339,7 +339,7 @@ function UniformArrayInt(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -381,7 +381,7 @@ function UniformArrayIntVec2(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -425,7 +425,7 @@ function UniformArrayIntVec3(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -469,7 +469,7 @@ function UniformArrayIntVec4(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -513,7 +513,7 @@ function UniformArrayMat2(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -557,7 +557,7 @@ function UniformArrayMat3(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; @@ -601,7 +601,7 @@ function UniformArrayMat4(gl, activeUniform, uniformName, locations) { const length = locations.length; /** - * @type {String} + * @type {string} * @readonly */ this.name = uniformName; diff --git a/packages/engine/Source/Renderer/freezeRenderState.js b/packages/engine/Source/Renderer/freezeRenderState.js index 02c31607405..253be6539ff 100644 --- a/packages/engine/Source/Renderer/freezeRenderState.js +++ b/packages/engine/Source/Renderer/freezeRenderState.js @@ -4,8 +4,8 @@ * * @private * - * @param {Object} renderState - * @returns {Object} Returns frozen renderState. + * @param {object} renderState + * @returns {object} Returns frozen renderState. * */ function freezeRenderState(renderState) { diff --git a/packages/engine/Source/Renderer/loadCubeMap.js b/packages/engine/Source/Renderer/loadCubeMap.js index 018bf9c9627..992d4fc8097 100644 --- a/packages/engine/Source/Renderer/loadCubeMap.js +++ b/packages/engine/Source/Renderer/loadCubeMap.js @@ -11,9 +11,9 @@ import CubeMap from "./CubeMap.js"; * @function loadCubeMap * * @param {Context} context The context to use to create the cube map. - * @param {Object} urls The source URL of each image. See the example below. - * @param {Boolean} [skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the images will be ignored. - * @returns {Promise.<CubeMap>} a promise that will resolve to the requested {@link CubeMap} when loaded. + * @param {object} urls The source URL of each image. See the example below. + * @param {boolean} [skipColorSpaceConversion=false] If true, any custom gamma or color profiles in the images will be ignored. + * @returns {Promise<CubeMap>} a promise that will resolve to the requested {@link CubeMap} when loaded. * * @exception {DeveloperError} context is required. * @exception {DeveloperError} urls is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. diff --git a/packages/engine/Source/Scene/AlphaMode.js b/packages/engine/Source/Scene/AlphaMode.js index 959ab42abd9..56f3bce645d 100644 --- a/packages/engine/Source/Scene/AlphaMode.js +++ b/packages/engine/Source/Scene/AlphaMode.js @@ -1,14 +1,14 @@ /** * The alpha rendering mode of the material. * - * @enum {String} + * @enum {string} * @private */ const AlphaMode = { /** * The alpha value is ignored and the rendered output is fully opaque. * - * @type {String} + * @type {string} * @constant */ OPAQUE: "OPAQUE", @@ -16,7 +16,7 @@ const AlphaMode = { /** * The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value. * - * @type {String} + * @type {string} * @constant */ MASK: "MASK", @@ -24,7 +24,7 @@ const AlphaMode = { /** * The rendered output is composited onto the destination with alpha blending. * - * @type {String} + * @type {string} * @constant */ BLEND: "BLEND", diff --git a/packages/engine/Source/Scene/Appearance.js b/packages/engine/Source/Scene/Appearance.js index 07f4aa3680e..597e89308fd 100644 --- a/packages/engine/Source/Scene/Appearance.js +++ b/packages/engine/Source/Scene/Appearance.js @@ -13,13 +13,13 @@ import CullFace from "./CullFace.js"; * @alias Appearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link Appearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link Appearance#renderState} has backface culling enabled. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link Appearance#renderState} has alpha blending enabled. + * @param {boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link Appearance#renderState} has backface culling enabled. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @see MaterialAppearance * @see EllipsoidSurfaceAppearance @@ -46,7 +46,7 @@ function Appearance(options) { /** * When <code>true</code>, the geometry is expected to appear translucent. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -64,7 +64,7 @@ Object.defineProperties(Appearance.prototype, { * * @memberof Appearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -80,7 +80,7 @@ Object.defineProperties(Appearance.prototype, { * * @memberof Appearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -94,7 +94,7 @@ Object.defineProperties(Appearance.prototype, { * * @memberof Appearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -108,7 +108,7 @@ Object.defineProperties(Appearance.prototype, { * * @memberof Appearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -124,7 +124,7 @@ Object.defineProperties(Appearance.prototype, { * Procedurally creates the full GLSL fragment shader source for this appearance * taking into account {@link Appearance#fragmentShaderSource} and {@link Appearance#material}. * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ Appearance.prototype.getFragmentShaderSource = function () { const parts = []; @@ -145,7 +145,7 @@ Appearance.prototype.getFragmentShaderSource = function () { /** * Determines if the geometry is translucent based on {@link Appearance#translucent} and {@link Material#isTranslucent}. * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ Appearance.prototype.isTranslucent = function () { return ( @@ -159,7 +159,7 @@ Appearance.prototype.isTranslucent = function () { * it can contain a subset of render state properties identical to the render state * created in the context. * - * @returns {Object} The render state. + * @returns {object} The render state. */ Appearance.prototype.getRenderState = function () { const translucent = this.isTranslucent(); diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index 3c9af4d7afc..8646d48e7a4 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -20,12 +20,12 @@ import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js"; import ImageryProvider from "./ImageryProvider.js"; /** - * @typedef {Object} ArcGisMapServerImageryProvider.ConstructorOptions + * @typedef {object} ArcGisMapServerImageryProvider.ConstructorOptions * * Initialization options for the ArcGisMapServerImageryProvider constructor * - * @property {Resource|String} url The URL of the ArcGIS MapServer service. - * @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. + * @property {Resource|string} url The URL of the ArcGIS MapServer service. + * @property {string} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. If this value is not specified, a default * {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a @@ -37,11 +37,11 @@ import ImageryProvider from "./ImageryProvider.js"; * these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this * parameter. - * @property {Boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached + * @property {boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached * tiles are used if they are available. If false, any pre-cached tiles are ignored and the * 'export' service is used. - * @property {String} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. - * @property {Boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke + * @property {string} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. + * @property {boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke * the Identify service on the MapServer and return the features included in the response. If false, * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) * without communicating with the server. Set this property to false if you don't want this provider's features to @@ -53,10 +53,10 @@ import ImageryProvider from "./ImageryProvider.js"; * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified and used, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server. - * @property {Number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server. - * @property {Number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. - * @property {Number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server. + * @property {number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server. + * @property {number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. + * @property {number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing * a tiled server. */ @@ -100,7 +100,7 @@ function ArcGisMapServerImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -109,7 +109,7 @@ function ArcGisMapServerImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -118,7 +118,7 @@ function ArcGisMapServerImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -127,7 +127,7 @@ function ArcGisMapServerImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -136,7 +136,7 @@ function ArcGisMapServerImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -144,7 +144,7 @@ function ArcGisMapServerImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -153,7 +153,7 @@ function ArcGisMapServerImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -161,7 +161,7 @@ function ArcGisMapServerImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -219,7 +219,7 @@ function ArcGisMapServerImageryProvider(options) { * invoke the "identify" operation on the ArcGIS server and return the features included in the response. If false, * {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) * without communicating with the server. - * @type {Boolean} + * @type {boolean} * @default true */ this.enablePickFeatures = defaultValue(options.enablePickFeatures, true); @@ -448,7 +448,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets the URL of the ArcGIS MapServer. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -460,7 +460,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets the ArcGIS token used to authenticate with the ArcGis MapServer service. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ token: { @@ -485,7 +485,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -506,7 +506,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -527,7 +527,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -548,7 +548,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -647,7 +647,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -659,7 +659,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof ArcGisMapServerImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -688,7 +688,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * not have pre-cached tiles. * @memberof ArcGisMapServerImageryProvider.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * @default true */ @@ -706,7 +706,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * and texture upload time are reduced. * @memberof ArcGisMapServerImageryProvider.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * @default true */ @@ -720,7 +720,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { * Gets the comma-separated list of layer IDs to show. * @memberof ArcGisMapServerImageryProvider.prototype * - * @type {String} + * @type {string} */ layers: { get: function () { @@ -732,9 +732,9 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -751,11 +751,11 @@ ArcGisMapServerImageryProvider.prototype.getTileCredits = function ( * Requests the image for a given tile. This function should * not be called before {@link ArcGisMapServerImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -785,12 +785,12 @@ ArcGisMapServerImageryProvider.prototype.requestImage = function ( * Asynchronously determines what features, if any, are located at a given longitude and latitude within * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * diff --git a/packages/engine/Source/Scene/AttributeType.js b/packages/engine/Source/Scene/AttributeType.js index 0cb63d6f8c9..5ba4d4f2e5c 100644 --- a/packages/engine/Source/Scene/AttributeType.js +++ b/packages/engine/Source/Scene/AttributeType.js @@ -10,7 +10,7 @@ import Matrix4 from "../Core/Matrix4.js"; /** * An enum describing the attribute type for glTF and 3D Tiles. * - * @enum {String} + * @enum {string} * * @private */ @@ -18,7 +18,7 @@ const AttributeType = { /** * The attribute is a single component. * - * @type {String} + * @type {string} * @constant */ SCALAR: "SCALAR", @@ -26,7 +26,7 @@ const AttributeType = { /** * The attribute is a two-component vector. * - * @type {String} + * @type {string} * @constant */ VEC2: "VEC2", @@ -34,7 +34,7 @@ const AttributeType = { /** * The attribute is a three-component vector. * - * @type {String} + * @type {string} * @constant */ VEC3: "VEC3", @@ -42,7 +42,7 @@ const AttributeType = { /** * The attribute is a four-component vector. * - * @type {String} + * @type {string} * @constant */ VEC4: "VEC4", @@ -50,7 +50,7 @@ const AttributeType = { /** * The attribute is a 2x2 matrix. * - * @type {String} + * @type {string} * @constant */ MAT2: "MAT2", @@ -58,7 +58,7 @@ const AttributeType = { /** * The attribute is a 3x3 matrix. * - * @type {String} + * @type {string} * @constant */ MAT3: "MAT3", @@ -66,7 +66,7 @@ const AttributeType = { /** * The attribute is a 4x4 matrix. * - * @type {String} + * @type {string} * @constant */ MAT4: "MAT4", @@ -107,7 +107,7 @@ AttributeType.getMathType = function (attributeType) { * Gets the number of components per attribute. * * @param {AttributeType} attributeType The attribute type. - * @returns {Number} The number of components. + * @returns {number} The number of components. * * @private */ @@ -138,7 +138,7 @@ AttributeType.getNumberOfComponents = function (attributeType) { * types require one, but matrices require multiple attribute locations. * * @param {AttributeType} attributeType The attribute type. - * @returns {Number} The number of attribute locations needed in the shader + * @returns {number} The number of attribute locations needed in the shader * * @private */ @@ -166,7 +166,7 @@ AttributeType.getAttributeLocationCount = function (attributeType) { * Gets the GLSL type for the attribute type. * * @param {AttributeType} attributeType The attribute type. - * @returns {String} The GLSL type for the attribute type. + * @returns {string} The GLSL type for the attribute type. * * @private */ diff --git a/packages/engine/Source/Scene/AutoExposure.js b/packages/engine/Source/Scene/AutoExposure.js index 7c0968b99e2..7d7e08f3d60 100644 --- a/packages/engine/Source/Scene/AutoExposure.js +++ b/packages/engine/Source/Scene/AutoExposure.js @@ -39,7 +39,7 @@ function AutoExposure() { /** * Whether or not to execute this post-process stage when ready. * - * @type {Boolean} + * @type {boolean} */ this.enabled = true; this._enabled = true; @@ -47,7 +47,7 @@ function AutoExposure() { /** * The minimum value used to clamp the luminance. * - * @type {Number} + * @type {number} * @default 0.1 */ this.minimumLuminance = 0.1; @@ -55,7 +55,7 @@ function AutoExposure() { /** * The maximum value used to clamp the luminance. * - * @type {Number} + * @type {number} * @default 10.0 */ this.maximumLuminance = 10.0; @@ -68,7 +68,7 @@ Object.defineProperties(AutoExposure.prototype, { * to load. * * @memberof AutoExposure.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -80,7 +80,7 @@ Object.defineProperties(AutoExposure.prototype, { * The unique name of this post-process stage for reference by other stages. * * @memberof AutoExposure.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -358,7 +358,7 @@ AutoExposure.prototype.execute = function (context, colorTexture) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see AutoExposure#destroy */ diff --git a/packages/engine/Source/Scene/Axis.js b/packages/engine/Source/Scene/Axis.js index 2ea92c1bd99..04b763122af 100644 --- a/packages/engine/Source/Scene/Axis.js +++ b/packages/engine/Source/Scene/Axis.js @@ -6,13 +6,13 @@ import Matrix4 from "../Core/Matrix4.js"; /** * An enum describing the x, y, and z axes and helper conversion functions. * - * @enum {Number} + * @enum {number} */ const Axis = { /** * Denotes the x-axis. * - * @type {Number} + * @type {number} * @constant */ X: 0, @@ -20,7 +20,7 @@ const Axis = { /** * Denotes the y-axis. * - * @type {Number} + * @type {number} * @constant */ Y: 1, @@ -28,7 +28,7 @@ const Axis = { /** * Denotes the z-axis. * - * @type {Number} + * @type {number} * @constant */ Z: 2, @@ -97,8 +97,8 @@ Axis.Y_UP_TO_X_UP = Matrix4.fromRotationTranslation( /** * Gets the axis by name * - * @param {String} name The name of the axis. - * @returns {Number} The axis enum. + * @param {string} name The name of the axis. + * @returns {number} The axis enum. */ Axis.fromName = function (name) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/B3dmParser.js b/packages/engine/Source/Scene/B3dmParser.js index 84cde3f39c5..6d06e616153 100644 --- a/packages/engine/Source/Scene/B3dmParser.js +++ b/packages/engine/Source/Scene/B3dmParser.js @@ -21,8 +21,8 @@ const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; * @private * * @param {ArrayBuffer} arrayBuffer The array buffer containing the b3dm. - * @param {Number} [byteOffset=0] The byte offset of the beginning of the b3dm in the array buffer. - * @returns {Object} Returns an object with the batch length, feature table (binary and json), batch table (binary and json) and glTF parts of the b3dm. + * @param {number} [byteOffset=0] The byte offset of the beginning of the b3dm in the array buffer. + * @returns {object} Returns an object with the batch length, feature table (binary and json), batch table (binary and json) and glTF parts of the b3dm. */ B3dmParser.parse = function (arrayBuffer, byteOffset) { const byteStart = defaultValue(byteOffset, 0); diff --git a/packages/engine/Source/Scene/BatchTable.js b/packages/engine/Source/Scene/BatchTable.js index 3efa78ae3c1..a24e541c86e 100644 --- a/packages/engine/Source/Scene/BatchTable.js +++ b/packages/engine/Source/Scene/BatchTable.js @@ -22,7 +22,7 @@ import Texture from "../Renderer/Texture.js"; * @param {Context} context The context in which the batch table is created. * @param {Object[]} attributes An array of objects describing a per instance attribute. Each object contains a datatype, components per attributes, whether it is normalized and a function name * to retrieve the value in the vertex shader. - * @param {Number} numberOfInstances The number of instances in a batch table. + * @param {number} numberOfInstances The number of instances in a batch table. * * @example * // create the batch table @@ -142,7 +142,7 @@ Object.defineProperties(BatchTable.prototype, { /** * The number of instances. * @memberOf BatchTable.prototype - * @type {Number} + * @type {number} * @readonly */ numberOfInstances: { @@ -247,10 +247,10 @@ const scratchGetAttributeCartesian4 = new Cartesian4(); /** * Gets the value of an attribute in the table. * - * @param {Number} instanceIndex The index of the instance. - * @param {Number} attributeIndex The index of the attribute. + * @param {number} instanceIndex The index of the instance. + * @param {number} attributeIndex The index of the attribute. * @param {undefined|Cartesian2|Cartesian3|Cartesian4} [result] The object onto which to store the result. The type is dependent on the attribute's number of components. - * @returns {Number|Cartesian2|Cartesian3|Cartesian4} The attribute value stored for the instance. + * @returns {number|Cartesian2|Cartesian3|Cartesian4} The attribute value stored for the instance. * * @exception {DeveloperError} instanceIndex is out of range. * @exception {DeveloperError} attributeIndex is out of range. @@ -315,9 +315,9 @@ const setAttributeScratchCartesian4 = new Cartesian4(); /** * Sets the value of an attribute in the table. * - * @param {Number} instanceIndex The index of the instance. - * @param {Number} attributeIndex The index of the attribute. - * @param {Number|Cartesian2|Cartesian3|Cartesian4} value The value to be stored in the table. The type of value will depend on the number of components of the attribute. + * @param {number} instanceIndex The index of the instance. + * @param {number} attributeIndex The index of the attribute. + * @param {number|Cartesian2|Cartesian3|Cartesian4} value The value to be stored in the table. The type of value will depend on the number of components of the attribute. * * @exception {DeveloperError} instanceIndex is out of range. * @exception {DeveloperError} attributeIndex is out of range. @@ -593,7 +593,7 @@ BatchTable.prototype.getVertexShaderCallback = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see BatchTable#destroy */ @@ -622,15 +622,15 @@ BatchTable.prototype.destroy = function () { * A callback for updating uniform maps. * @callback BatchTable.updateUniformMapCallback * - * @param {Object} uniformMap The uniform map. - * @returns {Object} The new uniform map with properties for retrieving values from the batch table. + * @param {object} uniformMap The uniform map. + * @returns {object} The new uniform map with properties for retrieving values from the batch table. */ /** * A callback for updating a vertex shader source. * @callback BatchTable.updateVertexShaderSourceCallback * - * @param {String} vertexShaderSource The vertex shader source. - * @returns {String} The new vertex shader source with the functions for retrieving batch table values injected. + * @param {string} vertexShaderSource The vertex shader source. + * @returns {string} The new vertex shader source with the functions for retrieving batch table values injected. */ export default BatchTable; diff --git a/packages/engine/Source/Scene/BatchTableHierarchy.js b/packages/engine/Source/Scene/BatchTableHierarchy.js index 802ee6b5a95..8d8cfd41113 100644 --- a/packages/engine/Source/Scene/BatchTableHierarchy.js +++ b/packages/engine/Source/Scene/BatchTableHierarchy.js @@ -12,8 +12,8 @@ import RuntimeError from "../Core/RuntimeError.js"; /** * Object for handling the <code>3DTILES_batch_table_hierarchy</code> extension * - * @param {Object} options Object with the following properties: - * @param {Object} options.extension The <code>3DTILES_batch_table_hierarchy</code> extension object. + * @param {object} options Object with the following properties: + * @param {object} options.extension The <code>3DTILES_batch_table_hierarchy</code> extension object. * @param {Uint8Array} [options.binaryBody] The binary body of the batch table * * @alias BatchTableHierarchy @@ -56,7 +56,7 @@ Object.defineProperties(BatchTableHierarchy.prototype, { * <code>3DTILES_batch_table_hierarchy</code> extension. * * @param {BatchTableHierarchy} hierarchy The hierarchy instance - * @param {Object} hierarchyJson The JSON of the extension + * @param {object} hierarchyJson The JSON of the extension * @param {Uint8Array} [binaryBody] The binary body of the batch table for accessing binary properties * @private */ @@ -365,9 +365,9 @@ function traverseHierarchy(hierarchy, instanceIndex, endConditionCallback) { /** * Returns whether the feature has this property. * - * @param {Number} batchId the batch ID of the feature - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the feature has this property. + * @param {number} batchId the batch ID of the feature + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the feature has this property. * @private */ BatchTableHierarchy.prototype.hasProperty = function (batchId, propertyId) { @@ -387,8 +387,8 @@ BatchTableHierarchy.prototype.hasProperty = function (batchId, propertyId) { /** * Returns whether any feature has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether any feature has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether any feature has this property. * @private */ BatchTableHierarchy.prototype.propertyExists = function (propertyId) { @@ -406,10 +406,10 @@ BatchTableHierarchy.prototype.propertyExists = function (propertyId) { /** * Returns an array of property IDs. * - * @param {Number} batchId the batch ID of the feature - * @param {Number} index The index of the entity. - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {number} batchId the batch ID of the feature + * @param {number} index The index of the entity. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ BatchTableHierarchy.prototype.getPropertyIds = function (batchId, results) { @@ -434,8 +434,8 @@ BatchTableHierarchy.prototype.getPropertyIds = function (batchId, results) { /** * Returns a copy of the value of the property with the given ID. * - * @param {Number} batchId the batch ID of the feature - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} batchId the batch ID of the feature + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * @private */ @@ -467,10 +467,10 @@ function getBinaryProperty(binaryProperty, index) { * Sets the value of the property with the given ID. Only properties of the * instance may be set; parent properties may not be set. * - * @param {Number} batchId The batchId of the feature - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} batchId The batchId of the feature + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * * @exception {DeveloperError} when setting an inherited property * @private @@ -520,9 +520,9 @@ function setBinaryProperty(binaryProperty, index, value) { /** * Check if a feature belongs to a class with the given name * - * @param {Number} batchId The batch ID of the feature - * @param {String} className The name of the class - * @return {Boolean} <code>true</code> if the feature belongs to the class given by className, or <code>false</code> otherwise + * @param {number} batchId The batch ID of the feature + * @param {string} className The name of the class + * @return {boolean} <code>true</code> if the feature belongs to the class given by className, or <code>false</code> otherwise * @private */ BatchTableHierarchy.prototype.isClass = function (batchId, className) { @@ -544,8 +544,8 @@ BatchTableHierarchy.prototype.isClass = function (batchId, className) { /** * Get the name of the class a given feature belongs to * - * @param {Number} batchId The batch ID of the feature - * @return {String} The name of the class this feature belongs to + * @param {number} batchId The batch ID of the feature + * @return {string} The name of the class this feature belongs to */ BatchTableHierarchy.prototype.getClassName = function (batchId) { const classId = this._classIds[batchId]; diff --git a/packages/engine/Source/Scene/BatchTexture.js b/packages/engine/Source/Scene/BatchTexture.js index 4350c295137..7b43f8cee30 100644 --- a/packages/engine/Source/Scene/BatchTexture.js +++ b/packages/engine/Source/Scene/BatchTexture.js @@ -16,10 +16,10 @@ import Texture from "../Renderer/Texture.js"; * An object that manages color, show/hide and picking textures for a batch * table or feature table. * - * @param {Object} options Object with the following properties: - * @param {Number} featuresLength The number of features in the batch table or feature table + * @param {object} options Object with the following properties: + * @param {number} featuresLength The number of features in the batch table or feature table * @param {Cesium3DTileContent|ModelFeatureTable} owner The owner of this batch texture. For 3D Tiles, this will be a {@link Cesium3DTileContent}. For glTF models, this will be a {@link ModelFeatureTable}. - * @param {Object} [statistics] The statistics object to update with information about the batch texture. + * @param {object} [statistics] The statistics object to update with information about the batch texture. * @param {Function} [colorChangedCallback] A callback function that is called whenever the color of a feature changes. * * @alias BatchTexture @@ -81,7 +81,7 @@ Object.defineProperties(BatchTexture.prototype, { * Number of features that are translucent * * @memberof BatchTexture.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -95,7 +95,7 @@ Object.defineProperties(BatchTexture.prototype, { * Total size of all GPU resources used by this batch texture. * * @memberof BatchTexture.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -228,8 +228,8 @@ function checkBatchId(batchId, featuresLength) { /** * Set whether a feature is visible. * - * @param {Number} batchId the ID of the feature - * @param {Boolean} show <code>true</code> if the feature should be shown, <code>false</code> otherwise + * @param {number} batchId the ID of the feature + * @param {boolean} show <code>true</code> if the feature should be shown, <code>false</code> otherwise * @private */ BatchTexture.prototype.setShow = function (batchId, show) { @@ -263,7 +263,7 @@ BatchTexture.prototype.setShow = function (batchId, show) { /** * Set the show for all features at once. * - * @param {Boolean} show <code>true</code> if the feature should be shown, <code>false</code> otherwise + * @param {boolean} show <code>true</code> if the feature should be shown, <code>false</code> otherwise * @private */ BatchTexture.prototype.setAllShow = function (show) { @@ -280,8 +280,8 @@ BatchTexture.prototype.setAllShow = function (show) { /** * Check the current show value for a feature * - * @param {Number} batchId the ID of the feature - * @return {Boolean} <code>true</code> if the feature is shown, or <code>false</code> otherwise + * @param {number} batchId the ID of the feature + * @return {boolean} <code>true</code> if the feature is shown, or <code>false</code> otherwise * @private */ BatchTexture.prototype.getShow = function (batchId) { @@ -303,7 +303,7 @@ const scratchColorBytes = new Array(4); /** * Set the styling color of a feature * - * @param {Number} batchId the ID of the feature + * @param {number} batchId the ID of the feature * @param {Color} color the color to assign to this feature. * * @private @@ -386,7 +386,7 @@ BatchTexture.prototype.setAllColor = function (color) { /** * Get the current color of a feature * - * @param {Number} batchId The ID of the feature + * @param {number} batchId The ID of the feature * @param {Color} result A color object where the result will be stored. * @return {Color} The color assigned to the selected feature * @@ -421,7 +421,7 @@ BatchTexture.prototype.getColor = function (batchId, result) { * Get the pick color of a feature. This feature is an RGBA encoding of the * pick ID. * - * @param {Number} batchId The ID of the feature + * @param {number} batchId The ID of the feature * @return {PickId} The picking color assigned to this feature * * @private @@ -532,7 +532,7 @@ BatchTexture.prototype.update = function (tileset, frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see BatchTexture#destroy * @private diff --git a/packages/engine/Source/Scene/Billboard.js b/packages/engine/Source/Scene/Billboard.js index 3d330013936..4035cda8d00 100644 --- a/packages/engine/Source/Scene/Billboard.js +++ b/packages/engine/Source/Scene/Billboard.js @@ -250,7 +250,7 @@ Object.defineProperties(Billboard.prototype, { * Determines if this billboard will be shown. Use this to hide or show a billboard, instead * of removing it and re-adding it to the collection. * @memberof Billboard.prototype - * @type {Boolean} + * @type {boolean} * @default true */ show: { @@ -606,7 +606,7 @@ Object.defineProperties(Billboard.prototype, { * and <code>2.0</code>. * </div> * @memberof Billboard.prototype - * @type {Number} + * @type {number} */ scale: { get: function () { @@ -671,7 +671,7 @@ Object.defineProperties(Billboard.prototype, { /** * Gets or sets the rotation angle in radians. * @memberof Billboard.prototype - * @type {Number} + * @type {number} */ rotation: { get: function () { @@ -730,7 +730,7 @@ Object.defineProperties(Billboard.prototype, { /** * Gets or sets a width for the billboard. If undefined, the image width will be used. * @memberof Billboard.prototype - * @type {Number} + * @type {number} */ width: { get: function () { @@ -752,7 +752,7 @@ Object.defineProperties(Billboard.prototype, { /** * Gets or sets a height for the billboard. If undefined, the image height will be used. * @memberof Billboard.prototype - * @type {Number} + * @type {number} */ height: { get: function () { @@ -775,7 +775,7 @@ Object.defineProperties(Billboard.prototype, { * Gets or sets if the billboard size is in meters or pixels. <code>true</code> to size the billboard in meters; * otherwise, the size is in pixels. * @memberof Billboard.prototype - * @type {Boolean} + * @type {boolean} * @default false */ sizeInMeters: { @@ -830,7 +830,7 @@ Object.defineProperties(Billboard.prototype, { * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. * @memberof Billboard.prototype - * @type {Number} + * @type {number} */ disableDepthTestDistance: { get: function () { @@ -857,7 +857,7 @@ Object.defineProperties(Billboard.prototype, { /** * Gets or sets the user-defined object returned when the billboard is picked. * @memberof Billboard.prototype - * @type {Object} + * @type {object} */ id: { get: function () { @@ -908,7 +908,7 @@ Object.defineProperties(Billboard.prototype, { * </p> * * @memberof Billboard.prototype - * @type {String} + * @type {string} * @example * // load an image from a URL * b.image = 'some/image/url.png'; @@ -947,7 +947,7 @@ Object.defineProperties(Billboard.prototype, { * * @memberof Billboard.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -980,7 +980,7 @@ Object.defineProperties(Billboard.prototype, { /** * Determines whether or not this billboard will be shown or hidden because it was clustered. * @memberof Billboard.prototype - * @type {Boolean} + * @type {boolean} * @private */ clusterShow: { @@ -1023,7 +1023,7 @@ Object.defineProperties(Billboard.prototype, { /** * The outline width of this Billboard in pixels. Effective only for SDF billboards like Label glyphs. * @memberof Billboard.prototype - * @type {Number} + * @type {number} * @private */ outlineWidth: { @@ -1208,8 +1208,8 @@ Billboard.prototype._loadImage = function () { * To load an image from a URL, setting the {@link Billboard#image} property is more convenient. * </p> * - * @param {String} id The id of the image. This can be any string that uniquely identifies the image. - * @param {HTMLImageElement|HTMLCanvasElement|String|Resource|Billboard.CreateImageCallback} image The image to load. This parameter + * @param {string} id The id of the image. This can be any string that uniquely identifies the image. + * @param {HTMLImageElement|HTMLCanvasElement|string|Resource|Billboard.CreateImageCallback} image The image to load. This parameter * can either be a loaded Image or Canvas, a URL which will be loaded as an Image automatically, * or a function which will be called to create the image if it hasn't been loaded already. * @example @@ -1256,7 +1256,7 @@ Billboard.prototype.setImage = function (id, image) { * Uses a sub-region of the image with the given id as the image for this billboard, * measured in pixels from the bottom-left. * - * @param {String} id The id of the image to use. + * @param {string} id The id of the image to use. * @param {BoundingRectangle} subRegion The sub-region of the image. * * @exception {RuntimeError} image with id must be in the atlas @@ -1489,7 +1489,7 @@ Billboard.getScreenSpaceBoundingBox = function ( * are equal. Billboards in different collections can be equal. * * @param {Billboard} other The billboard to compare for equality. - * @returns {Boolean} <code>true</code> if the billboards are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the billboards are equal; otherwise, <code>false</code>. */ Billboard.prototype.equals = function (other) { return ( @@ -1546,7 +1546,7 @@ Billboard.prototype._destroy = function () { /** * A function that creates an image. * @callback Billboard.CreateImageCallback - * @param {String} id The identifier of the image to load. + * @param {string} id The identifier of the image to load. * @returns {HTMLImageElement|HTMLCanvasElement|Promise<HTMLImageElement|HTMLCanvasElement>} The image, or a promise that will resolve to an image. */ export default Billboard; diff --git a/packages/engine/Source/Scene/BillboardCollection.js b/packages/engine/Source/Scene/BillboardCollection.js index d5b2bf1b2e9..c0116eaabc6 100644 --- a/packages/engine/Source/Scene/BillboardCollection.js +++ b/packages/engine/Source/Scene/BillboardCollection.js @@ -105,14 +105,14 @@ const attributeLocationsInstanced = { * @alias BillboardCollection * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each billboard from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Scene} [options.scene] Must be passed in for billboards that use the height reference property or will be depth tested against the globe. * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The billboard blending option. The default * is used for rendering both opaque and translucent billboards. However, if either all of the billboards are completely opaque or all are completely translucent, * setting the technique to BlendOption.OPAQUE or BlendOption.TRANSLUCENT can improve performance by up to 2x. - * @param {Boolean} [options.show=true] Determines if the billboards in the collection will be shown. + * @param {boolean} [options.show=true] Determines if the billboards in the collection will be shown. * * @performance For best performance, prefer a few collections, each with many billboards, to * many collections with only a few billboards each. Organize collections so that billboards @@ -205,7 +205,7 @@ function BillboardCollection(options) { /** * Determines if billboards in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -253,7 +253,7 @@ function BillboardCollection(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -268,7 +268,7 @@ function BillboardCollection(options) { * Draws the texture atlas for this BillboardCollection as a fullscreen quad. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -348,7 +348,7 @@ Object.defineProperties(BillboardCollection.prototype, { * {@link BillboardCollection#get} to iterate over all the billboards * in the collection. * @memberof BillboardCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -387,7 +387,7 @@ Object.defineProperties(BillboardCollection.prototype, { * and explicitly destroy the atlas to avoid attempting to destroy it multiple times. * * @memberof BillboardCollection.prototype - * @type {Boolean} + * @type {boolean} * @private * * @example @@ -426,7 +426,7 @@ function destroyBillboards(billboards) { * Creates and adds a billboard with the specified initial properties to the collection. * The added billboard is returned so it can be modified or removed from the collection later. * - * @param {Object}[options] A template describing the billboard's properties as shown in Example 1. + * @param {object}[options] A template describing the billboard's properties as shown in Example 1. * @returns {Billboard} The billboard that was added to the collection. * * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer @@ -485,7 +485,7 @@ BillboardCollection.prototype.add = function (options) { * Removes a billboard from the collection. * * @param {Billboard} billboard The billboard to remove. - * @returns {Boolean} <code>true</code> if the billboard was removed; <code>false</code> if the billboard was not found in the collection. + * @returns {boolean} <code>true</code> if the billboard was removed; <code>false</code> if the billboard was not found in the collection. * * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For @@ -577,7 +577,7 @@ BillboardCollection.prototype._updateBillboard = function ( * Check whether this collection contains a given billboard. * * @param {Billboard} [billboard] The billboard to check for. - * @returns {Boolean} true if this collection contains the billboard, false otherwise. + * @returns {boolean} true if this collection contains the billboard, false otherwise. * * @see BillboardCollection#get */ @@ -592,7 +592,7 @@ BillboardCollection.prototype.contains = function (billboard) { * {@link BillboardCollection#length} to iterate over all the billboards * in the collection. * - * @param {Number} index The zero-based index of the billboard. + * @param {number} index The zero-based index of the billboard. * @returns {Billboard} The billboard at the specified index. * * @performance Expected constant time. If billboards were removed from the collection and @@ -2373,7 +2373,7 @@ BillboardCollection.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see BillboardCollection#destroy */ diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index 39870e4814f..4fa70ef672c 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -16,17 +16,17 @@ import DiscardEmptyTilePolicy from "./DiscardEmptyTileImagePolicy.js"; import ImageryProvider from "./ImageryProvider.js"; /** - * @typedef {Object} BingMapsImageryProvider.ConstructorOptions + * @typedef {object} BingMapsImageryProvider.ConstructorOptions * * Initialization options for the BingMapsImageryProvider constructor * - * @property {Resource|String} url The url of the Bing Maps server hosting the imagery. - * @property {String} key The Bing Maps key for your application, which can be + * @property {Resource|string} url The url of the Bing Maps server hosting the imagery. + * @property {string} key The Bing Maps key for your application, which can be * created at {@link https://www.bingmapsportal.com/}. - * @property {String} [tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'. + * @property {string} [tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'. * By default, tiles are loaded using the same protocol as the page. * @property {BingMapsStyle} [mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load. - * @property {String} [culture=''] The culture to use when requesting Bing Maps imagery. Not + * @property {string} [culture=''] The culture to use when requesting Bing Maps imagery. Not * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} * for information on the supported cultures. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. @@ -81,7 +81,7 @@ function BingMapsImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -90,7 +90,7 @@ function BingMapsImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -99,7 +99,7 @@ function BingMapsImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -108,7 +108,7 @@ function BingMapsImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -117,7 +117,7 @@ function BingMapsImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -125,7 +125,7 @@ function BingMapsImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -134,7 +134,7 @@ function BingMapsImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -142,7 +142,7 @@ function BingMapsImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default 1.0 */ this.defaultGamma = 1.0; @@ -315,7 +315,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { /** * Gets the name of the BingMaps server url hosting the imagery. * @memberof BingMapsImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -339,7 +339,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { /** * Gets the Bing Maps key. * @memberof BingMapsImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ key: { @@ -365,7 +365,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx} * for information on the supported cultures. * @memberof BingMapsImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ culture: { @@ -378,7 +378,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link BingMapsImageryProvider#ready} returns true. * @memberof BingMapsImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -399,7 +399,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link BingMapsImageryProvider#ready} returns true. * @memberof BingMapsImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -420,7 +420,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link BingMapsImageryProvider#ready} returns true. * @memberof BingMapsImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -441,7 +441,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link BingMapsImageryProvider#ready} returns true. * @memberof BingMapsImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -540,7 +540,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof BingMapsImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -552,7 +552,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof BingMapsImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -581,7 +581,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage * and texture upload time. * @memberof BingMapsImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -596,9 +596,9 @@ const rectangleScratch = new Rectangle(); /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -631,11 +631,11 @@ BingMapsImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link BingMapsImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -678,11 +678,11 @@ BingMapsImageryProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ BingMapsImageryProvider.prototype.pickFeatures = function ( @@ -699,9 +699,9 @@ BingMapsImageryProvider.prototype.pickFeatures = function ( * Converts a tiles (x, y, level) position into a quadkey used to request an image * from a Bing Maps server. * - * @param {Number} x The tile's x coordinate. - * @param {Number} y The tile's y coordinate. - * @param {Number} level The tile's zoom level. + * @param {number} x The tile's x coordinate. + * @param {number} y The tile's y coordinate. + * @param {number} level The tile's zoom level. * * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} * @see BingMapsImageryProvider#quadKeyToTileXY @@ -729,7 +729,7 @@ BingMapsImageryProvider.tileXYToQuadKey = function (x, y, level) { * Converts a tile's quadkey used to request an image from a Bing Maps server into the * (x, y, level) position. * - * @param {String} quadkey The tile's quad key + * @param {string} quadkey The tile's quad key * * @see {@link http://msdn.microsoft.com/en-us/library/bb259689.aspx|Bing Maps Tile System} * @see BingMapsImageryProvider#tileXYToQuadKey @@ -763,7 +763,7 @@ Object.defineProperties(BingMapsImageryProvider, { /** * Gets or sets the URL to the Bing logo for display in the credit. * @memberof BingMapsImageryProvider - * @type {String} + * @type {string} */ logoUrl: { get: function () { diff --git a/packages/engine/Source/Scene/BingMapsStyle.js b/packages/engine/Source/Scene/BingMapsStyle.js index ab9d5cd14ca..a41f5d8f8a2 100644 --- a/packages/engine/Source/Scene/BingMapsStyle.js +++ b/packages/engine/Source/Scene/BingMapsStyle.js @@ -1,7 +1,7 @@ /** * The types of imagery provided by Bing Maps. * - * @enum {Number} + * @enum {number} * * @see BingMapsImageryProvider */ @@ -9,7 +9,7 @@ const BingMapsStyle = { /** * Aerial imagery. * - * @type {String} + * @type {string} * @constant */ AERIAL: "Aerial", @@ -17,7 +17,7 @@ const BingMapsStyle = { /** * Aerial imagery with a road overlay. * - * @type {String} + * @type {string} * @constant * @deprecated See https://github.com/CesiumGS/cesium/issues/7128. * Use `BingMapsStyle.AERIAL_WITH_LABELS_ON_DEMAND` instead @@ -27,7 +27,7 @@ const BingMapsStyle = { /** * Aerial imagery with a road overlay. * - * @type {String} + * @type {string} * @constant */ AERIAL_WITH_LABELS_ON_DEMAND: "AerialWithLabelsOnDemand", @@ -35,7 +35,7 @@ const BingMapsStyle = { /** * Roads without additional imagery. * - * @type {String} + * @type {string} * @constant * @deprecated See https://github.com/CesiumGS/cesium/issues/7128. * Use `BingMapsStyle.ROAD_ON_DEMAND` instead @@ -45,7 +45,7 @@ const BingMapsStyle = { /** * Roads without additional imagery. * - * @type {String} + * @type {string} * @constant */ ROAD_ON_DEMAND: "RoadOnDemand", @@ -53,7 +53,7 @@ const BingMapsStyle = { /** * A dark version of the road maps. * - * @type {String} + * @type {string} * @constant */ CANVAS_DARK: "CanvasDark", @@ -61,7 +61,7 @@ const BingMapsStyle = { /** * A lighter version of the road maps. * - * @type {String} + * @type {string} * @constant */ CANVAS_LIGHT: "CanvasLight", @@ -69,7 +69,7 @@ const BingMapsStyle = { /** * A grayscale version of the road maps. * - * @type {String} + * @type {string} * @constant */ CANVAS_GRAY: "CanvasGray", @@ -77,7 +77,7 @@ const BingMapsStyle = { /** * Ordnance Survey imagery. This imagery is visible only for the London, UK area. * - * @type {String} + * @type {string} * @constant */ ORDNANCE_SURVEY: "OrdnanceSurvey", @@ -85,7 +85,7 @@ const BingMapsStyle = { /** * Collins Bart imagery. * - * @type {String} + * @type {string} * @constant */ COLLINS_BART: "CollinsBart", diff --git a/packages/engine/Source/Scene/BlendEquation.js b/packages/engine/Source/Scene/BlendEquation.js index d007e3433f4..c36e9653d6c 100644 --- a/packages/engine/Source/Scene/BlendEquation.js +++ b/packages/engine/Source/Scene/BlendEquation.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines how two pixels' values are combined. * - * @enum {Number} + * @enum {number} */ const BlendEquation = { /** * Pixel values are added componentwise. This is used in additive blending for translucency. * - * @type {Number} + * @type {number} * @constant */ ADD: WebGLConstants.FUNC_ADD, @@ -17,7 +17,7 @@ const BlendEquation = { /** * Pixel values are subtracted componentwise (source - destination). This is used in alpha blending for translucency. * - * @type {Number} + * @type {number} * @constant */ SUBTRACT: WebGLConstants.FUNC_SUBTRACT, @@ -25,7 +25,7 @@ const BlendEquation = { /** * Pixel values are subtracted componentwise (destination - source). * - * @type {Number} + * @type {number} * @constant */ REVERSE_SUBTRACT: WebGLConstants.FUNC_REVERSE_SUBTRACT, @@ -35,7 +35,7 @@ const BlendEquation = { * * This equation operates on each pixel color component. * - * @type {Number} + * @type {number} * @constant */ MIN: WebGLConstants.MIN, @@ -45,7 +45,7 @@ const BlendEquation = { * * This equation operates on each pixel color component. * - * @type {Number} + * @type {number} * @constant */ MAX: WebGLConstants.MAX, diff --git a/packages/engine/Source/Scene/BlendFunction.js b/packages/engine/Source/Scene/BlendFunction.js index 3c3a624fdfe..c8be135e246 100644 --- a/packages/engine/Source/Scene/BlendFunction.js +++ b/packages/engine/Source/Scene/BlendFunction.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines how blending factors are computed. * - * @enum {Number} + * @enum {number} */ const BlendFunction = { /** * The blend factor is zero. * - * @type {Number} + * @type {number} * @constant */ ZERO: WebGLConstants.ZERO, @@ -17,7 +17,7 @@ const BlendFunction = { /** * The blend factor is one. * - * @type {Number} + * @type {number} * @constant */ ONE: WebGLConstants.ONE, @@ -25,7 +25,7 @@ const BlendFunction = { /** * The blend factor is the source color. * - * @type {Number} + * @type {number} * @constant */ SOURCE_COLOR: WebGLConstants.SRC_COLOR, @@ -33,7 +33,7 @@ const BlendFunction = { /** * The blend factor is one minus the source color. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_SOURCE_COLOR: WebGLConstants.ONE_MINUS_SRC_COLOR, @@ -41,7 +41,7 @@ const BlendFunction = { /** * The blend factor is the destination color. * - * @type {Number} + * @type {number} * @constant */ DESTINATION_COLOR: WebGLConstants.DST_COLOR, @@ -49,7 +49,7 @@ const BlendFunction = { /** * The blend factor is one minus the destination color. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_DESTINATION_COLOR: WebGLConstants.ONE_MINUS_DST_COLOR, @@ -57,7 +57,7 @@ const BlendFunction = { /** * The blend factor is the source alpha. * - * @type {Number} + * @type {number} * @constant */ SOURCE_ALPHA: WebGLConstants.SRC_ALPHA, @@ -65,7 +65,7 @@ const BlendFunction = { /** * The blend factor is one minus the source alpha. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_SOURCE_ALPHA: WebGLConstants.ONE_MINUS_SRC_ALPHA, @@ -73,7 +73,7 @@ const BlendFunction = { /** * The blend factor is the destination alpha. * - * @type {Number} + * @type {number} * @constant */ DESTINATION_ALPHA: WebGLConstants.DST_ALPHA, @@ -81,7 +81,7 @@ const BlendFunction = { /** * The blend factor is one minus the destination alpha. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_DESTINATION_ALPHA: WebGLConstants.ONE_MINUS_DST_ALPHA, @@ -89,7 +89,7 @@ const BlendFunction = { /** * The blend factor is the constant color. * - * @type {Number} + * @type {number} * @constant */ CONSTANT_COLOR: WebGLConstants.CONSTANT_COLOR, @@ -97,7 +97,7 @@ const BlendFunction = { /** * The blend factor is one minus the constant color. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_CONSTANT_COLOR: WebGLConstants.ONE_MINUS_CONSTANT_COLOR, @@ -105,7 +105,7 @@ const BlendFunction = { /** * The blend factor is the constant alpha. * - * @type {Number} + * @type {number} * @constant */ CONSTANT_ALPHA: WebGLConstants.CONSTANT_ALPHA, @@ -113,7 +113,7 @@ const BlendFunction = { /** * The blend factor is one minus the constant alpha. * - * @type {Number} + * @type {number} * @constant */ ONE_MINUS_CONSTANT_ALPHA: WebGLConstants.ONE_MINUS_CONSTANT_ALPHA, @@ -121,7 +121,7 @@ const BlendFunction = { /** * The blend factor is the saturated source alpha. * - * @type {Number} + * @type {number} * @constant */ SOURCE_ALPHA_SATURATE: WebGLConstants.SRC_ALPHA_SATURATE, diff --git a/packages/engine/Source/Scene/BlendOption.js b/packages/engine/Source/Scene/BlendOption.js index 8228ed0c02a..bd40f1f0b54 100644 --- a/packages/engine/Source/Scene/BlendOption.js +++ b/packages/engine/Source/Scene/BlendOption.js @@ -1,26 +1,26 @@ /** * Determines how opaque and translucent parts of billboards, points, and labels are blended with the scene. * - * @enum {Number} + * @enum {number} */ const BlendOption = { /** * The billboards, points, or labels in the collection are completely opaque. - * @type {Number} + * @type {number} * @constant */ OPAQUE: 0, /** * The billboards, points, or labels in the collection are completely translucent. - * @type {Number} + * @type {number} * @constant */ TRANSLUCENT: 1, /** * The billboards, points, or labels in the collection are both opaque and translucent. - * @type {Number} + * @type {number} * @constant */ OPAQUE_AND_TRANSLUCENT: 2, diff --git a/packages/engine/Source/Scene/BlendingState.js b/packages/engine/Source/Scene/BlendingState.js index 82f0a228a13..856f4d497ff 100644 --- a/packages/engine/Source/Scene/BlendingState.js +++ b/packages/engine/Source/Scene/BlendingState.js @@ -15,7 +15,7 @@ const BlendingState = { /** * Blending is disabled. * - * @type {Object} + * @type {object} * @constant */ DISABLED: Object.freeze({ @@ -25,7 +25,7 @@ const BlendingState = { /** * Blending is enabled using alpha blending, <code>source(source.alpha) + destination(1 - source.alpha)</code>. * - * @type {Object} + * @type {object} * @constant */ ALPHA_BLEND: Object.freeze({ @@ -41,7 +41,7 @@ const BlendingState = { /** * Blending is enabled using alpha blending with premultiplied alpha, <code>source + destination(1 - source.alpha)</code>. * - * @type {Object} + * @type {object} * @constant */ PRE_MULTIPLIED_ALPHA_BLEND: Object.freeze({ @@ -57,7 +57,7 @@ const BlendingState = { /** * Blending is enabled using additive blending, <code>source(source.alpha) + destination</code>. * - * @type {Object} + * @type {object} * @constant */ ADDITIVE_BLEND: Object.freeze({ diff --git a/packages/engine/Source/Scene/BufferLoader.js b/packages/engine/Source/Scene/BufferLoader.js index f04cd75ad19..43562c0b93c 100644 --- a/packages/engine/Source/Scene/BufferLoader.js +++ b/packages/engine/Source/Scene/BufferLoader.js @@ -14,10 +14,10 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Uint8Array} [options.typedArray] The typed array containing the embedded buffer contents. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the external buffer. Mutually exclusive with options.typedArray. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {string} [options.cacheKey] The cache key of the resource. * * @exception {DeveloperError} One of options.typedArray and options.resource must be defined. * @@ -55,7 +55,7 @@ Object.defineProperties(BufferLoader.prototype, { * * @memberof BufferLoader.prototype * - * @type {Promise.<BufferLoader>|undefined} + * @type {Promise<BufferLoader>|undefined} * @readonly */ promise: { @@ -68,7 +68,7 @@ Object.defineProperties(BufferLoader.prototype, { * * @memberof BufferLoader.prototype * - * @type {String} + * @type {string} * @readonly */ cacheKey: { @@ -93,7 +93,7 @@ Object.defineProperties(BufferLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<BufferLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<BufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ BufferLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/Camera.js b/packages/engine/Source/Scene/Camera.js index c1765f2eb30..9c006a1020b 100644 --- a/packages/engine/Source/Scene/Camera.js +++ b/packages/engine/Source/Scene/Camera.js @@ -30,7 +30,7 @@ import MapMode2D from "./MapMode2D.js"; import SceneMode from "./SceneMode.js"; /** - * @typedef {Object} DirectionUp + * @typedef {object} DirectionUp * * An orientation given by a pair of unit vectors * @@ -38,7 +38,7 @@ import SceneMode from "./SceneMode.js"; * @property {Cartesian3} up The unit "up" vector **/ /** - * @typedef {Object} HeadingPitchRollValues + * @typedef {object} HeadingPitchRollValues * * An orientation given by numeric heading, pitch, and roll * @@ -170,28 +170,28 @@ function Camera(scene) { /** * The default amount to move the camera when an argument is not * provided to the move methods. - * @type {Number} + * @type {number} * @default 100000.0; */ this.defaultMoveAmount = 100000.0; /** * The default amount to rotate the camera when an argument is not * provided to the look methods. - * @type {Number} + * @type {number} * @default Math.PI / 60.0 */ this.defaultLookAmount = Math.PI / 60.0; /** * The default amount to rotate the camera when an argument is not * provided to the rotate methods. - * @type {Number} + * @type {number} * @default Math.PI / 3600.0 */ this.defaultRotateAmount = Math.PI / 3600.0; /** * The default amount to move the camera when an argument is not * provided to the zoom methods. - * @type {Number} + * @type {number} * @default 100000.0; */ this.defaultZoomAmount = 100000.0; @@ -204,7 +204,7 @@ function Camera(scene) { /** * The factor multiplied by the the map size used to determine where to clamp the camera position * when zooming out from the surface. The default is 1.5. Only valid for 2D and the map is rotatable. - * @type {Number} + * @type {number} * @default 1.5 */ this.maximumZoomFactor = 1.5; @@ -360,7 +360,7 @@ function updateCameraDeltas(camera) { /** * Checks if there's a camera flight with preload for this camera. * - * @returns {Boolean} Whether or not this camera has a current flight with a valid preloadFlightCamera in scene. + * @returns {boolean} Whether or not this camera has a current flight with a valid preloadFlightCamera in scene. * * @private * @@ -955,7 +955,7 @@ Object.defineProperties(Camera.prototype, { * Gets the camera heading in radians. * @memberof Camera.prototype * - * @type {Number} + * @type {number} * @readonly */ heading: { @@ -986,7 +986,7 @@ Object.defineProperties(Camera.prototype, { * Gets the camera pitch in radians. * @memberof Camera.prototype * - * @type {Number} + * @type {number} * @readonly */ pitch: { @@ -1017,7 +1017,7 @@ Object.defineProperties(Camera.prototype, { * Gets the camera roll in radians. * @memberof Camera.prototype * - * @type {Number} + * @type {number} * @readonly */ roll: { @@ -1399,13 +1399,13 @@ const scratchHpr = new HeadingPitchRoll(); /** * Sets the camera position, orientation and transform. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3|Rectangle} [options.destination] The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. * @param {HeadingPitchRollValues|DirectionUp} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame of the camera. - * @param {Boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to <code>true</code>. + * @param {boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to <code>true</code>. * * @example * // 1. Set position with a top-down view @@ -1504,7 +1504,7 @@ const pitchScratch = new Cartesian3(); * the default view for the 3D scene. The home view for 2D and columbus view shows the * entire map. * - * @param {Number} [duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. See {@link Camera#flyTo} + * @param {number} [duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. See {@link Camera#flyTo} */ Camera.prototype.flyHome = function (duration) { const mode = this._mode; @@ -1725,7 +1725,7 @@ const moveScratch = new Cartesian3(); * Translates the camera's position by <code>amount</code> along <code>direction</code>. * * @param {Cartesian3} direction The direction to move. - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveBackward * @see Camera#moveForward @@ -1755,7 +1755,7 @@ Camera.prototype.move = function (direction, amount) { * Translates the camera's position by <code>amount</code> along the camera's view vector. * When in 2D mode, this will zoom in the camera instead of translating the camera's position. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveBackward */ @@ -1776,7 +1776,7 @@ Camera.prototype.moveForward = function (amount) { * of the camera's view vector. * When in 2D mode, this will zoom out the camera instead of translating the camera's position. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveForward */ @@ -1795,7 +1795,7 @@ Camera.prototype.moveBackward = function (amount) { /** * Translates the camera's position by <code>amount</code> along the camera's up vector. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveDown */ @@ -1808,7 +1808,7 @@ Camera.prototype.moveUp = function (amount) { * Translates the camera's position by <code>amount</code> along the opposite direction * of the camera's up vector. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveUp */ @@ -1820,7 +1820,7 @@ Camera.prototype.moveDown = function (amount) { /** * Translates the camera's position by <code>amount</code> along the camera's right vector. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveLeft */ @@ -1833,7 +1833,7 @@ Camera.prototype.moveRight = function (amount) { * Translates the camera's position by <code>amount</code> along the opposite direction * of the camera's right vector. * - * @param {Number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. + * @param {number} [amount] The amount, in meters, to move. Defaults to <code>defaultMoveAmount</code>. * * @see Camera#moveRight */ @@ -1846,7 +1846,7 @@ Camera.prototype.moveLeft = function (amount) { * Rotates the camera around its up vector by amount, in radians, in the opposite direction * of its right vector if not in 2D mode. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#lookRight */ @@ -1863,7 +1863,7 @@ Camera.prototype.lookLeft = function (amount) { * Rotates the camera around its up vector by amount, in radians, in the direction * of its right vector if not in 2D mode. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#lookLeft */ @@ -1880,7 +1880,7 @@ Camera.prototype.lookRight = function (amount) { * Rotates the camera around its right vector by amount, in radians, in the direction * of its up vector if not in 2D mode. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#lookDown */ @@ -1897,7 +1897,7 @@ Camera.prototype.lookUp = function (amount) { * Rotates the camera around its right vector by amount, in radians, in the opposite direction * of its up vector if not in 2D mode. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#lookUp */ @@ -1916,7 +1916,7 @@ const lookScratchMatrix = new Matrix3(); * Rotate each of the camera's orientation vectors around <code>axis</code> by <code>angle</code> * * @param {Cartesian3} axis The axis to rotate around. - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#lookUp * @see Camera#lookDown @@ -1950,7 +1950,7 @@ Camera.prototype.look = function (axis, angle) { /** * Rotate the camera counter-clockwise around its direction vector by amount, in radians. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#twistRight */ @@ -1962,7 +1962,7 @@ Camera.prototype.twistLeft = function (amount) { /** * Rotate the camera clockwise around its direction vector by amount, in radians. * - * @param {Number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. + * @param {number} [amount] The amount, in radians, to rotate by. Defaults to <code>defaultLookAmount</code>. * * @see Camera#twistLeft */ @@ -1978,7 +1978,7 @@ const rotateScratchMatrix = new Matrix3(); * of the camera's position to the center of the camera's reference frame remains the same. * * @param {Cartesian3} axis The axis to rotate around given in world coordinates. - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. * * @see Camera#rotateUp * @see Camera#rotateDown @@ -2011,7 +2011,7 @@ Camera.prototype.rotate = function (axis, angle) { /** * Rotates the camera around the center of the camera's reference frame by angle downwards. * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. * * @see Camera#rotateUp * @see Camera#rotate @@ -2024,7 +2024,7 @@ Camera.prototype.rotateDown = function (angle) { /** * Rotates the camera around the center of the camera's reference frame by angle upwards. * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. * * @see Camera#rotateDown * @see Camera#rotate @@ -2097,7 +2097,7 @@ function rotateVertical(camera, angle) { /** * Rotates the camera around the center of the camera's reference frame by angle to the right. * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. * * @see Camera#rotateLeft * @see Camera#rotate @@ -2110,7 +2110,7 @@ Camera.prototype.rotateRight = function (angle) { /** * Rotates the camera around the center of the camera's reference frame by angle to the left. * - * @param {Number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. + * @param {number} [angle] The angle, in radians, to rotate by. Defaults to <code>defaultRotateAmount</code>. * * @see Camera#rotateRight * @see Camera#rotate @@ -2208,7 +2208,7 @@ function zoom3D(camera, amount) { /** * Zooms <code>amount</code> along the camera's view vector. * - * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. + * @param {number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. * * @see Camera#zoomOut */ @@ -2225,7 +2225,7 @@ Camera.prototype.zoomIn = function (amount) { * Zooms <code>amount</code> along the opposite direction of * the camera's view vector. * - * @param {Number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. + * @param {number} [amount] The amount to move. Defaults to <code>defaultZoomAmount</code>. * * @see Camera#zoomIn */ @@ -2242,7 +2242,7 @@ Camera.prototype.zoomOut = function (amount) { * Gets the magnitude of the camera position. In 3D, this is the vector magnitude. In 2D and * Columbus view, this is the distance to the map. * - * @returns {Number} The magnitude of the position. + * @returns {number} The magnitude of the position. */ Camera.prototype.getMagnitude = function () { if (this._mode === SceneMode.SCENE3D) { @@ -3026,7 +3026,7 @@ const scratchProj = new Cartesian3(); * Return the distance from the camera to the front of the bounding sphere. * * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. - * @returns {Number} The distance to the bounding sphere. + * @returns {number} The distance to the bounding sphere. */ Camera.prototype.distanceToBoundingSphere = function (boundingSphere) { //>>includeStart('debug', pragmas.debug); @@ -3054,9 +3054,9 @@ const scratchPixelSize = new Cartesian2(); * Return the pixel size in meters. * * @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. - * @param {Number} drawingBufferWidth The drawing buffer width. - * @param {Number} drawingBufferHeight The drawing buffer height. - * @returns {Number} The pixel size in meters. + * @param {number} drawingBufferWidth The drawing buffer width. + * @param {number} drawingBufferHeight The drawing buffer height. + * @returns {number} The pixel size in meters. */ Camera.prototype.getPixelSize = function ( boundingSphere, @@ -3194,8 +3194,8 @@ function createAnimationCV(camera, duration) { /** * Create an animation to move the map into view. This method is only valid for 2D and Columbus modes. * - * @param {Number} duration The duration, in seconds, of the animation. - * @returns {Object} The animation or undefined if the scene mode is 3D or the map is already ion view. + * @param {number} duration The duration, in seconds, of the animation. + * @returns {object} The animation or undefined if the scene mode is 3D or the map is already ion view. * * @private */ @@ -3273,20 +3273,20 @@ Camera.prototype.completeFlight = function () { /** * Flies the camera from its current position to a new position. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3|Rectangle} options.destination The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. - * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point + * @param {object} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. - * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. + * @param {number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. * @param {Camera.FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. * @param {Camera.FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. - * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. - * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. - * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. - * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. - * @param {Boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to <code>true</code>. + * @param {number} [options.maximumHeight] The maximum height at the peak of the flight. + * @param {number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. + * @param {number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. + * @param {number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. + * @param {boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to <code>true</code>. * @param {EasingFunction.Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. * * @exception {DeveloperError} If either direction or up is given, then both are required. @@ -3545,16 +3545,16 @@ const scratchFlyToBoundingSphereMatrix3 = new Matrix3(); * target will be the range. The heading will be aligned to local north.</p> * * @param {BoundingSphere} boundingSphere The bounding sphere to view, in world coordinates. - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. + * @param {object} [options] Object with the following properties: + * @param {number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target. * @param {Camera.FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. * @param {Camera.FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed. - * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. - * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. - * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. - * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. + * @param {number} [options.maximumHeight] The maximum height at the peak of the flight. + * @param {number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport. + * @param {number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude. + * @param {number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight. * @param {EasingFunction.Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight. */ Camera.prototype.flyToBoundingSphere = function (boundingSphere, options) { diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 19bff9d4e0b..7cf268e6b6a 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -133,6 +133,9 @@ function listenToPinch(aggregator, modifier, canvas) { function listenToWheel(aggregator, modifier) { const key = getKey(CameraEventType.WHEEL, modifier); + const pressTime = aggregator._pressTime; + const releaseTime = aggregator._releaseTime; + const update = aggregator._update; update[key] = true; @@ -141,21 +144,29 @@ function listenToWheel(aggregator, modifier) { movement = aggregator._movement[key] = {}; } + let lastMovement = aggregator._lastMovement[key]; + if (!defined(lastMovement)) { + lastMovement = aggregator._lastMovement[key] = { + startPosition: new Cartesian2(), + endPosition: new Cartesian2(), + valid: false, + }; + } + movement.startPosition = new Cartesian2(); + Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); movement.endPosition = new Cartesian2(); aggregator._eventHandler.setInputAction( function (delta) { // TODO: magic numbers const arcLength = 15.0 * CesiumMath.toRadians(delta); - if (!update[key]) { - movement.endPosition.y = movement.endPosition.y + arcLength; - } else { - Cartesian2.clone(Cartesian2.ZERO, movement.startPosition); - movement.endPosition.x = 0.0; - movement.endPosition.y = arcLength; - update[key] = false; - } + pressTime[key] = releaseTime[key] = new Date(); + movement.endPosition.x = 0.0; + movement.endPosition.y = arcLength; + Cartesian2.clone(movement.endPosition, lastMovement.endPosition); + lastMovement.valid = true; + update[key] = false; }, ScreenSpaceEventType.WHEEL, modifier @@ -358,7 +369,7 @@ Object.defineProperties(CameraEventAggregator.prototype, { /** * Gets whether any mouse button is down, a touch has started, or the wheel has been moved. * @memberof CameraEventAggregator.prototype - * @type {Boolean} + * @type {boolean} */ anyButtonDown: { get: function () { @@ -381,7 +392,7 @@ Object.defineProperties(CameraEventAggregator.prototype, { * * @param {CameraEventType} type The camera event type. * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Boolean} Returns <code>true</code> if a mouse button down or touch has started and has been moved; otherwise, <code>false</code> + * @returns {boolean} Returns <code>true</code> if a mouse button down or touch has started and has been moved; otherwise, <code>false</code> */ CameraEventAggregator.prototype.isMoving = function (type, modifier) { //>>includeStart('debug', pragmas.debug); @@ -399,7 +410,7 @@ CameraEventAggregator.prototype.isMoving = function (type, modifier) { * * @param {CameraEventType} type The camera event type. * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Object} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code>. + * @returns {object} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code>. */ CameraEventAggregator.prototype.getMovement = function (type, modifier) { //>>includeStart('debug', pragmas.debug); @@ -441,7 +452,7 @@ CameraEventAggregator.prototype.getLastMovement = function (type, modifier) { * * @param {CameraEventType} type The camera event type. * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Boolean} Whether the mouse button is down or a touch has started. + * @returns {boolean} Whether the mouse button is down or a touch has started. */ CameraEventAggregator.prototype.isButtonDown = function (type, modifier) { //>>includeStart('debug', pragmas.debug); @@ -535,7 +546,7 @@ CameraEventAggregator.prototype.reset = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see CameraEventAggregator#destroy */ diff --git a/packages/engine/Source/Scene/CameraEventType.js b/packages/engine/Source/Scene/CameraEventType.js index 8dcbe541fb5..73057554501 100644 --- a/packages/engine/Source/Scene/CameraEventType.js +++ b/packages/engine/Source/Scene/CameraEventType.js @@ -1,13 +1,13 @@ /** * Enumerates the available input for interacting with the camera. * - * @enum {Number} + * @enum {number} */ const CameraEventType = { /** * A left mouse button press followed by moving the mouse and releasing the button. * - * @type {Number} + * @type {number} * @constant */ LEFT_DRAG: 0, @@ -15,7 +15,7 @@ const CameraEventType = { /** * A right mouse button press followed by moving the mouse and releasing the button. * - * @type {Number} + * @type {number} * @constant */ RIGHT_DRAG: 1, @@ -23,7 +23,7 @@ const CameraEventType = { /** * A middle mouse button press followed by moving the mouse and releasing the button. * - * @type {Number} + * @type {number} * @constant */ MIDDLE_DRAG: 2, @@ -31,7 +31,7 @@ const CameraEventType = { /** * Scrolling the middle mouse button. * - * @type {Number} + * @type {number} * @constant */ WHEEL: 3, @@ -39,7 +39,7 @@ const CameraEventType = { /** * A two-finger touch on a touch surface. * - * @type {Number} + * @type {number} * @constant */ PINCH: 4, diff --git a/packages/engine/Source/Scene/Cesium3DContentGroup.js b/packages/engine/Source/Scene/Cesium3DContentGroup.js index 1694a948b7a..bacacd71862 100644 --- a/packages/engine/Source/Scene/Cesium3DContentGroup.js +++ b/packages/engine/Source/Scene/Cesium3DContentGroup.js @@ -7,7 +7,7 @@ import defaultValue from "../Core/defaultValue.js"; * <code>content.group.metadata</code> much like tile metadata is accessed as * <code>tile.metadata</code>. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {GroupMetadata} options.metadata The metadata associated with this group. * * @alias Cesium3DContentGroup diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 4495909c941..efc57429137 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -138,7 +138,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * The error, in meters, introduced if this tile is rendered and its children are not. * This is used to compute screen space error, i.e., the error measured in pixels. * - * @type {Number} + * @type {number} * @readonly */ this.geometricError = header.geometricError; @@ -264,7 +264,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { /** * When <code>true</code>, the tile has no content. * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -277,7 +277,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * This is <code>false</code> until the tile's content is loaded. * </p> * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -290,7 +290,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * This is <code>false</code> until the tile's implicit content is loaded. * </p> * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -305,7 +305,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * This is <code>false</code> until the tile's content is loaded. * </p> * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -319,7 +319,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_multiple_contents|3DTILES_multiple_contents extension} * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -362,7 +362,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { /** * The time in seconds after the tile's content is ready when the content expires and new content is requested. * - * @type {Number} + * @type {number} */ this.expireDuration = expireDuration; @@ -376,7 +376,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { /** * The time when a style was last applied to this tile. * - * @type {Number} + * @type {number} * * @private */ @@ -395,7 +395,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * Tracks if the tile's relationship with a ClippingPlaneCollection has changed with regards * to the ClippingPlaneCollection's state. * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -405,7 +405,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) { * Tracks if the tile's request should be deferred until all non-deferred * tiles load. * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -621,7 +621,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -644,7 +644,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -661,7 +661,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -678,7 +678,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -695,7 +695,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -714,7 +714,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * The promise remains <code>undefined</code> until the tile's content is requested. * </p> * - * @type {Promise.<Cesium3DTileContent>} + * @type {Promise<Cesium3DTileContent>} * @readonly * * @private @@ -731,7 +731,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * The promise remains <code>undefined</code> until the tile's content is requested. * </p> * - * @type {Promise.<Cesium3DTileContent>} + * @type {Promise<Cesium3DTileContent>} * @readonly * * @private @@ -1049,7 +1049,7 @@ function createPriorityFunction(tile) { * The request may not be made if the Cesium Request Scheduler can't prioritize it. * </p> * - * @return {Number} The number of requests that were attempted but not scheduled. + * @return {number} The number of requests that were attempted but not scheduled. * @private */ Cesium3DTile.prototype.requestContent = function () { @@ -1449,8 +1449,8 @@ function getContentBoundingVolume(tile, frameState) { * Determines whether the tile's bounding volume intersects the culling volume. * * @param {FrameState} frameState The frame state. - * @param {Number} parentVisibilityPlaneMask The parent's plane mask to speed up the visibility check. - * @returns {Number} A plane mask as described above in {@link CullingVolume#computeVisibilityWithPlaneMask}. + * @param {number} parentVisibilityPlaneMask The parent's plane mask to speed up the visibility check. + * @returns {number} A plane mask as described above in {@link CullingVolume#computeVisibilityWithPlaneMask}. * * @private */ @@ -1527,7 +1527,7 @@ Cesium3DTile.prototype.contentVisibility = function (frameState) { * Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera. * * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. + * @returns {number} The distance, in meters, or zero if the camera is inside the bounding volume. * * @private */ @@ -1542,7 +1542,7 @@ const scratchToTileCenter = new Cartesian3(); * Computes the distance from the center of the tile's bounding volume to the camera's plane defined by its position and view direction. * * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters. + * @returns {number} The distance, in meters. * * @private */ @@ -1561,7 +1561,7 @@ Cesium3DTile.prototype.distanceToTileCenter = function (frameState) { * Checks if the camera is inside the viewer request volume. * * @param {FrameState} frameState The frame state. - * @returns {Boolean} Whether the camera is inside the volume. + * @returns {boolean} Whether the camera is inside the volume. * * @private */ @@ -1687,7 +1687,7 @@ function createSphere(sphere, transform, result) { /** * Create a bounding volume from the tile's bounding volume header. * - * @param {Object} boundingVolumeHeader The tile's bounding volume header. + * @param {object} boundingVolumeHeader The tile's bounding volume header. * @param {Matrix4} transform The transform to apply to the bounding volume. * @param {TileBoundingVolume} [result] The object onto which to store the result. * diff --git a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js index 4430c4c0c35..a892b0f9494 100644 --- a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js +++ b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js @@ -88,7 +88,7 @@ Object.defineProperties(Cesium3DTileBatchTable.prototype, { * buffers and any binary properties. JSON data is not counted. * * @memberof Cesium3DTileBatchTable.prototype - * @type {Number} + * @type {number} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/Cesium3DTileColorBlendMode.js b/packages/engine/Source/Scene/Cesium3DTileColorBlendMode.js index 3970583d587..8ae81db8e3d 100644 --- a/packages/engine/Source/Scene/Cesium3DTileColorBlendMode.js +++ b/packages/engine/Source/Scene/Cesium3DTileColorBlendMode.js @@ -22,13 +22,13 @@ * } * </code></pre> * - * @enum {Number} + * @enum {number} */ const Cesium3DTileColorBlendMode = { /** * Multiplies the source color by the feature color. * - * @type {Number} + * @type {number} * @constant */ HIGHLIGHT: 0, @@ -36,7 +36,7 @@ const Cesium3DTileColorBlendMode = { /** * Replaces the source color with the feature color. * - * @type {Number} + * @type {number} * @constant */ REPLACE: 1, @@ -44,7 +44,7 @@ const Cesium3DTileColorBlendMode = { /** * Blends the source color and feature color together. * - * @type {Number} + * @type {number} * @constant */ MIX: 2, diff --git a/packages/engine/Source/Scene/Cesium3DTileContent.js b/packages/engine/Source/Scene/Cesium3DTileContent.js index 3ec029bfc8c..c5464c418e0 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContent.js +++ b/packages/engine/Source/Scene/Cesium3DTileContent.js @@ -22,7 +22,7 @@ function Cesium3DTileContent() { * not part of the public Cesium API. * </p> * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -35,7 +35,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ featuresLength: { @@ -56,7 +56,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ pointsLength: { @@ -71,7 +71,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -86,7 +86,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -101,7 +101,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ texturesByteLength: { @@ -118,7 +118,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly */ batchTableByteLength: { @@ -150,7 +150,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * * @memberof Cesium3DTileContent.prototype * - * @type {Promise.<Cesium3DTileContent>} + * @type {Promise<Cesium3DTileContent>} * @readonly */ readyPromise: { @@ -194,7 +194,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { * Gets the url of the tile's content. * @memberof Cesium3DTileContent.prototype * - * @type {String} + * @type {string} * @readonly */ url: { @@ -274,9 +274,9 @@ Object.defineProperties(Cesium3DTileContent.prototype, { /** * Returns whether the feature has this property. * - * @param {Number} batchId The batchId for the feature. - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} <code>true</code> if the feature has this property; otherwise, <code>false</code>. + * @param {number} batchId The batchId for the feature. + * @param {string} name The case-sensitive name of the property. + * @returns {boolean} <code>true</code> if the feature has this property; otherwise, <code>false</code>. */ Cesium3DTileContent.prototype.hasProperty = function (batchId, name) { DeveloperError.throwInstantiationError(); @@ -292,7 +292,7 @@ Cesium3DTileContent.prototype.hasProperty = function (batchId, name) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/TileFormats/BatchTable}. * - * @param {Number} batchId The batchId for the feature. + * @param {number} batchId The batchId for the feature. * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. * * @exception {DeveloperError} batchId must be between zero and {@link Cesium3DTileContent#featuresLength} - 1. @@ -308,7 +308,7 @@ Cesium3DTileContent.prototype.getFeature = function (batchId) { * not part of the public Cesium API. * </p> * - * @param {Boolean} enabled Whether to enable or disable debug settings. + * @param {boolean} enabled Whether to enable or disable debug settings. * @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object. * @private @@ -360,7 +360,7 @@ Cesium3DTileContent.prototype.update = function (tileset, frameState) { * not part of the public Cesium API. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Cesium3DTileContent#destroy * diff --git a/packages/engine/Source/Scene/Cesium3DTileContentType.js b/packages/engine/Source/Scene/Cesium3DTileContentType.js index 39caeef8579..8167d13e758 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContentType.js +++ b/packages/engine/Source/Scene/Cesium3DTileContentType.js @@ -4,7 +4,7 @@ * unless otherwise noted. For JSON files, the enum value is a unique name * for internal use. * - * @enum {String} + * @enum {string} * @see Cesium3DTileContent * * @private @@ -14,7 +14,7 @@ const Cesium3DTileContentType = { * A Batched 3D Model. This is a binary format with * magic number <code>b3dm</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -23,7 +23,7 @@ const Cesium3DTileContentType = { * An Instanced 3D Model. This is a binary format with magic number * <code>i3dm</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -32,7 +32,7 @@ const Cesium3DTileContentType = { * A Composite model. This is a binary format with magic number * <code>cmpt</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -41,7 +41,7 @@ const Cesium3DTileContentType = { * A Point Cloud model. This is a binary format with magic number * <code>pnts</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -50,7 +50,7 @@ const Cesium3DTileContentType = { * Vector tiles. This is a binary format with magic number * <code>vctr</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -59,7 +59,7 @@ const Cesium3DTileContentType = { * Geometry tiles. This is a binary format with magic number * <code>geom</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -68,7 +68,7 @@ const Cesium3DTileContentType = { * A glTF model in JSON + external BIN form. This is treated * as a JSON format. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -79,7 +79,7 @@ const Cesium3DTileContentType = { * changed from <code>glTF</code> to <code>glb</code> to distinguish it from * the JSON glTF format. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -89,7 +89,7 @@ const Cesium3DTileContentType = { * For implicit tiling, availability bitstreams are stored in binary subtree files. * The magic number is <code>subt</code> * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -98,7 +98,7 @@ const Cesium3DTileContentType = { /** * For implicit tiling. Subtrees can also be represented as JSON files. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -108,7 +108,7 @@ const Cesium3DTileContentType = { * Contents can reference another tileset.json to use * as an external tileset. This is a JSON-based format. * - * @type {String} + * @type {string} * @constant * @private */ @@ -117,7 +117,7 @@ const Cesium3DTileContentType = { * Multiple contents are handled separately from the other content types * due to differences in request scheduling. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -126,7 +126,7 @@ const Cesium3DTileContentType = { /** * GeoJSON content for <code>MAXAR_content_geojson</code> extension. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -135,7 +135,7 @@ const Cesium3DTileContentType = { /** * Binary voxel content for <code>3DTILES_content_voxels</code> extension. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -144,7 +144,7 @@ const Cesium3DTileContentType = { /** * Binary voxel content for <code>3DTILES_content_voxels</code> extension. * - * @type {String} + * @type {string} * @constant * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -156,7 +156,7 @@ const Cesium3DTileContentType = { * Check if a content is one of the supported binary formats. Otherwise, * the caller can assume a JSON format. * @param {Cesium3DTileContentType} contentType The content type of the content payload. - * @return {Boolean} <code>true</code> if the content type is a binary format, or <code>false</code> if the content type is a JSON format. + * @return {boolean} <code>true</code> if the content type is a binary format, or <code>false</code> if the content type is a JSON format. * @private */ Cesium3DTileContentType.isBinaryFormat = function (contentType) { diff --git a/packages/engine/Source/Scene/Cesium3DTileFeature.js b/packages/engine/Source/Scene/Cesium3DTileFeature.js index a19347705e3..5689f7e35ad 100644 --- a/packages/engine/Source/Scene/Cesium3DTileFeature.js +++ b/packages/engine/Source/Scene/Cesium3DTileFeature.js @@ -49,7 +49,7 @@ Object.defineProperties(Cesium3DTileFeature.prototype, { * * @memberof Cesium3DTileFeature.prototype * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -160,7 +160,7 @@ Object.defineProperties(Cesium3DTileFeature.prototype, { * * @memberof Cesium3DTileFeature.prototype * - * @type {Number} + * @type {number} * * @readonly * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -187,8 +187,8 @@ Object.defineProperties(Cesium3DTileFeature.prototype, { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} Whether the feature contains this property. + * @param {string} name The case-sensitive name of the property. + * @returns {boolean} Whether the feature contains this property. */ Cesium3DTileFeature.prototype.hasProperty = function (name) { return this._content.batchTable.hasProperty(this._batchId, name); @@ -200,8 +200,8 @@ Cesium3DTileFeature.prototype.hasProperty = function (name) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The IDs of the feature's properties. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The IDs of the feature's properties. */ Cesium3DTileFeature.prototype.getPropertyIds = function (results) { return this._content.batchTable.getPropertyIds(this._batchId, results); @@ -213,7 +213,7 @@ Cesium3DTileFeature.prototype.getPropertyIds = function (results) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * * @example @@ -259,8 +259,8 @@ Cesium3DTileFeature.prototype.getProperty = function (name) { * </p> * * @param {Cesium3DTileContent} content The content for accessing the metadata - * @param {Number} batchId The batch ID (or feature ID) of the feature to get a property for - * @param {String} name The semantic or property ID of the feature. Semantics are checked before property IDs in each granularity of metadata. + * @param {number} batchId The batch ID (or feature ID) of the feature to get a property for + * @param {string} name The semantic or property ID of the feature. Semantics are checked before property IDs in each granularity of metadata. * @return {*} The value of the property or <code>undefined</code> if the feature does not have this property. * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -353,7 +353,7 @@ Cesium3DTileFeature.getPropertyInherited = function (content, batchId, name) { * tileset. Within each granularity, semantics are resolved first, then other * properties. * </p> - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * @private */ @@ -371,7 +371,7 @@ Cesium3DTileFeature.prototype.getPropertyInherited = function (name) { * If a property with the given name doesn't exist, it is created. * </p> * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @param {*} value The value of the property that will be copied. * * @exception {DeveloperError} Inherited batch table hierarchy property is read only. @@ -404,8 +404,8 @@ Cesium3DTileFeature.prototype.setProperty = function (name, value) { * This function returns <code>false</code> if no batch table hierarchy is present. * </p> * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class name equals <code>className</code> + * @param {string} className The name to check against. + * @returns {boolean} Whether the feature's class name equals <code>className</code> * * @private */ @@ -419,8 +419,8 @@ Cesium3DTileFeature.prototype.isExactClass = function (className) { * This function returns <code>false</code> if no batch table hierarchy is present. * </p> * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class or inherited classes are named <code>className</code> + * @param {string} className The name to check against. + * @returns {boolean} Whether the feature's class or inherited classes are named <code>className</code> * * @private */ @@ -434,7 +434,7 @@ Cesium3DTileFeature.prototype.isClass = function (className) { * This function returns <code>undefined</code> if no batch table hierarchy is present. * </p> * - * @returns {String} The feature's class name. + * @returns {string} The feature's class name. * * @private */ diff --git a/packages/engine/Source/Scene/Cesium3DTileOptimizationHint.js b/packages/engine/Source/Scene/Cesium3DTileOptimizationHint.js index bef800f818c..11e484eefe2 100644 --- a/packages/engine/Source/Scene/Cesium3DTileOptimizationHint.js +++ b/packages/engine/Source/Scene/Cesium3DTileOptimizationHint.js @@ -1,7 +1,7 @@ /** * Hint defining optimization support for a 3D tile * - * @enum {Number} + * @enum {number} * * @private */ diff --git a/packages/engine/Source/Scene/Cesium3DTileOptimizations.js b/packages/engine/Source/Scene/Cesium3DTileOptimizations.js index 79281e3788c..9e836942f74 100644 --- a/packages/engine/Source/Scene/Cesium3DTileOptimizations.js +++ b/packages/engine/Source/Scene/Cesium3DTileOptimizations.js @@ -25,7 +25,7 @@ const scratchAxis = new Cartesian3(); * partially outside of the parent bounds. * * @param {Cesium3DTile} tile The tile to check. - * @returns {Boolean} Whether the childrenWithinParent optimization is supported. + * @returns {boolean} Whether the childrenWithinParent optimization is supported. */ Cesium3DTileOptimizations.checkChildrenWithinParent = function (tile) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/Cesium3DTilePassState.js b/packages/engine/Source/Scene/Cesium3DTilePassState.js index ac53e44fad4..d86c774faf5 100644 --- a/packages/engine/Source/Scene/Cesium3DTilePassState.js +++ b/packages/engine/Source/Scene/Cesium3DTilePassState.js @@ -43,7 +43,7 @@ function Cesium3DTilePassState(options) { /** * A read-only property that indicates whether the pass is ready, i.e. all tiles needed by the pass are loaded. * - * @type {Boolean} + * @type {boolean} * @readonly * @default false */ diff --git a/packages/engine/Source/Scene/Cesium3DTilePointFeature.js b/packages/engine/Source/Scene/Cesium3DTilePointFeature.js index 77028911b3c..63f30af2557 100644 --- a/packages/engine/Source/Scene/Cesium3DTilePointFeature.js +++ b/packages/engine/Source/Scene/Cesium3DTilePointFeature.js @@ -80,7 +80,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -123,7 +123,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Number} + * @type {number} */ pointSize: { get: function () { @@ -163,7 +163,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Number} + * @type {number} */ pointOutlineWidth: { get: function () { @@ -222,7 +222,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Number} + * @type {number} */ labelOutlineWidth: { get: function () { @@ -241,7 +241,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {String} + * @type {string} */ font: { get: function () { @@ -276,7 +276,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {String} + * @type {string} */ labelText: { get: function () { @@ -336,7 +336,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Boolean} + * @type {boolean} */ backgroundEnabled: { get: function () { @@ -404,7 +404,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Number} + * @type {number} */ heightOffset: { get: function () { @@ -437,7 +437,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Boolean} + * @type {boolean} */ anchorLineEnabled: { get: function () { @@ -475,7 +475,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {String} + * @type {string} */ image: { get: function () { @@ -495,7 +495,7 @@ Object.defineProperties(Cesium3DTilePointFeature.prototype, { * * @memberof Cesium3DTilePointFeature.prototype * - * @type {Number} + * @type {number} */ disableDepthTestDistance: { get: function () { @@ -719,8 +719,8 @@ function setBillboardImage(feature) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} Whether the feature contains this property. + * @param {string} name The case-sensitive name of the property. + * @returns {boolean} Whether the feature contains this property. */ Cesium3DTilePointFeature.prototype.hasProperty = function (name) { return this._content.batchTable.hasProperty(this._batchId, name); @@ -732,8 +732,8 @@ Cesium3DTilePointFeature.prototype.hasProperty = function (name) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The IDs of the feature's properties. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The IDs of the feature's properties. */ Cesium3DTilePointFeature.prototype.getPropertyIds = function (results) { return this._content.batchTable.getPropertyIds(this._batchId, results); @@ -745,7 +745,7 @@ Cesium3DTilePointFeature.prototype.getPropertyIds = function (results) { * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * * @example @@ -772,7 +772,7 @@ Cesium3DTilePointFeature.prototype.getProperty = function (name) { * tileset. Within each granularity, semantics are resolved first, then other * properties. * </p> - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -791,7 +791,7 @@ Cesium3DTilePointFeature.prototype.getPropertyInherited = function (name) { * If a property with the given name doesn't exist, it is created. * </p> * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @param {*} value The value of the property that will be copied. * * @exception {DeveloperError} Inherited batch table hierarchy property is read only. @@ -824,8 +824,8 @@ Cesium3DTilePointFeature.prototype.setProperty = function (name, value) { * This function returns <code>false</code> if no batch table hierarchy is present. * </p> * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class name equals <code>className</code> + * @param {string} className The name to check against. + * @returns {boolean} Whether the feature's class name equals <code>className</code> * * @private */ @@ -839,8 +839,8 @@ Cesium3DTilePointFeature.prototype.isExactClass = function (className) { * This function returns <code>false</code> if no batch table hierarchy is present. * </p> * - * @param {String} className The name to check against. - * @returns {Boolean} Whether the feature's class or inherited classes are named <code>className</code> + * @param {string} className The name to check against. + * @returns {boolean} Whether the feature's class or inherited classes are named <code>className</code> * * @private */ @@ -854,7 +854,7 @@ Cesium3DTilePointFeature.prototype.isClass = function (className) { * This function returns <code>undefined</code> if no batch table hierarchy is present. * </p> * - * @returns {String} The feature's class name. + * @returns {string} The feature's class name. * * @private */ diff --git a/packages/engine/Source/Scene/Cesium3DTileRefine.js b/packages/engine/Source/Scene/Cesium3DTileRefine.js index 01d0e8d2c25..4b998df48e6 100644 --- a/packages/engine/Source/Scene/Cesium3DTileRefine.js +++ b/packages/engine/Source/Scene/Cesium3DTileRefine.js @@ -5,7 +5,7 @@ * in the 3D Tiles spec. * </p> * - * @enum {Number} + * @enum {number} * * @private */ @@ -13,7 +13,7 @@ const Cesium3DTileRefine = { /** * Render this tile and, if it doesn't meet the screen space error, also refine to its children. * - * @type {Number} + * @type {number} * @constant */ ADD: 0, @@ -21,7 +21,7 @@ const Cesium3DTileRefine = { /** * Render this tile or, if it doesn't meet the screen space error, refine to its descendants instead. * - * @type {Number} + * @type {number} * @constant */ REPLACE: 1, diff --git a/packages/engine/Source/Scene/Cesium3DTileStyle.js b/packages/engine/Source/Scene/Cesium3DTileStyle.js index e4b73ca6f97..adea8e62bd1 100644 --- a/packages/engine/Source/Scene/Cesium3DTileStyle.js +++ b/packages/engine/Source/Scene/Cesium3DTileStyle.js @@ -16,7 +16,7 @@ import Expression from "./Expression.js"; * @alias Cesium3DTileStyle * @constructor * - * @param {Object} [style] An object defining a style. + * @param {object} [style] An object defining a style. * * @example * tileset.style = new Cesium.Cesium3DTileStyle({ @@ -166,7 +166,7 @@ Object.defineProperties(Cesium3DTileStyle.prototype, { * * @memberof Cesium3DTileStyle.prototype * - * @type {Object} + * @type {object} * @readonly * * @default {} @@ -1313,9 +1313,9 @@ Object.defineProperties(Cesium3DTileStyle.prototype, { /** * Asynchronously creates a Cesium3DTileStyle from a url. * - * @param {Resource|String} url The url of the style to be loaded. + * @param {Resource|string} url The url of the style to be loaded. * - * @returns {Promise.<Cesium3DTileStyle>} A promise which resolves to the created style + * @returns {Promise<Cesium3DTileStyle>} A promise which resolves to the created style * * @private */ @@ -1335,11 +1335,11 @@ Cesium3DTileStyle.fromUrl = function (url) { /** * Gets the color shader function for this style. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -1373,11 +1373,11 @@ Cesium3DTileStyle.prototype.getColorShaderFunction = function ( /** * Gets the show shader function for this style. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -1409,11 +1409,11 @@ Cesium3DTileStyle.prototype.getShowShaderFunction = function ( /** * Gets the pointSize shader function for this style. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -1445,7 +1445,7 @@ Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function ( /** * Gets the variables used by the style. * - * @returns {String[]} The variables used by the style. + * @returns {} The variables used by the style. * * @private */ diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 90477276db8..69a729ff49c 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -33,8 +33,8 @@ import VoxelShapeType from "./VoxelShapeType.js"; * @constructor * @augments VoxelProvider * - * @param {Object} options Object with the following properties: - * @param {Resource|String|Promise<Resource>|Promise<String>} options.url The URL to a tileset JSON file. + * @param {object} options Object with the following properties: + * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The URL to a tileset JSON file. * * @see VoxelProvider * @see VoxelPrimitive diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 1c2a9327103..c4b67cc0a68 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -60,66 +60,66 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * @alias Cesium3DTileset * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String|Promise<Resource>|Promise<String>} options.url The url to a tileset JSON file. - * @param {Boolean} [options.show=true] Determines if the tileset will be shown. + * @param {object} options Object with the following properties: + * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The url to a tileset JSON file. + * @param {boolean} [options.show=true] Determines if the tileset will be shown. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. * @param {Axis} [options.modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. * @param {Axis} [options.modelForwardAxis=Axis.X] Which axis is considered forward when loading models for tile contents. * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from light sources. - * @param {Number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. - * @param {Number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. - * @param {Boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. - * @param {Boolean} [options.cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. - * @param {Number} [options.cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. - * @param {Boolean} [options.preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. - * @param {Boolean} [options.preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. - * @param {Boolean} [options.preferLeaves=false] Optimization option. Prefer loading of leaves first. - * @param {Boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. - * @param {Number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. - * @param {Number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. - * @param {Number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. - * @param {Number} [options.progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. - * @param {Boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. - * @param {Number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. - * @param {Number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. + * @param {number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. + * @param {number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. + * @param {boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. + * @param {boolean} [options.cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. + * @param {number} [options.cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. + * @param {boolean} [options.preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. + * @param {boolean} [options.preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. + * @param {boolean} [options.preferLeaves=false] Optimization option. Prefer loading of leaves first. + * @param {boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. + * @param {number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. + * @param {number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. + * @param {number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. + * @param {number} [options.progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. + * @param {boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. + * @param {number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. + * @param {number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. * @param {Cesium3DTileset.foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError} - * @param {Number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. - * @param {Boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. - * @param {Number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. - * @param {Number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. - * @param {Number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. - * @param {Boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. - * @param {Boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. + * @param {number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. + * @param {boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. + * @param {number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. + * @param {number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. + * @param {number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. + * @param {boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. + * @param {boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. - * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * @param {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. * @param {Cartesian3} [options.lightColor] The light color when shading models. When <code>undefined</code> the scene's light color is used instead. * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting for this tileset. - * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. - * @param {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @param {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. + * @param {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @param {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. - * @param {Boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. - * @param {Boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. - * @param {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. + * @param {boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. + * @param {boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. + * @param {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset. - * @param {Boolean} [options.projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. - * @param {String} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. - * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. - * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. - * @param {Boolean} [options.enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. - * @param {Boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. - * @param {Boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. - * @param {Boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. - * @param {Boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. - * @param {Boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. - * @param {Boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. - * @param {Boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. + * @param {boolean} [options.projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. + * @param {string} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. + * @param {boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. + * @param {boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. + * @param {boolean} [options.enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. + * @param {boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. + * @param {boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. + * @param {boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. + * @param {boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. + * @param {boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. + * @param {boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. + * @param {boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. * @@ -242,7 +242,7 @@ function Cesium3DTileset(options) { /** * Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. * - * @type {Boolean} + * @type {boolean} * @default true */ this.cullRequestsWhileMoving = defaultValue( @@ -254,7 +254,7 @@ function Cesium3DTileset(options) { /** * Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. * - * @type {Number} + * @type {number} * @default 60.0 */ this.cullRequestsWhileMovingMultiplier = defaultValue( @@ -265,7 +265,7 @@ function Cesium3DTileset(options) { /** * Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. * - * @type {Number} + * @type {number} * @default 0.3 */ this.progressiveResolutionHeightFraction = CesiumMath.clamp( @@ -277,7 +277,7 @@ function Cesium3DTileset(options) { /** * Optimization option. Prefer loading of leaves first. * - * @type {Boolean} + * @type {boolean} * @default false */ this.preferLeaves = defaultValue(options.preferLeaves, false); @@ -308,7 +308,7 @@ function Cesium3DTileset(options) { /** * Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. * - * @type {Boolean} + * @type {boolean} * @default false */ this.preloadWhenHidden = defaultValue(options.preloadWhenHidden, false); @@ -316,7 +316,7 @@ function Cesium3DTileset(options) { /** * Optimization option. Fetch tiles at the camera's flight destination while the camera is in flight. * - * @type {Boolean} + * @type {boolean} * @default true */ this.preloadFlightDestinations = defaultValue( @@ -332,7 +332,7 @@ function Cesium3DTileset(options) { * The algorithm is biased towards "street views" where the camera is close to the ground plane of the tileset and looking * at the horizon. In addition results are more accurate for tightly fitting bounding volumes like box and region. * - * @type {Boolean} + * @type {boolean} * @default false */ this.dynamicScreenSpaceError = defaultValue( @@ -345,7 +345,7 @@ function Cesium3DTileset(options) { * screen space error for tiles around the edge of the screen. Screen space error returns to normal once all * the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. * - * @type {Boolean} + * @type {boolean} * @default true */ this.foveatedScreenSpaceError = defaultValue( @@ -375,7 +375,7 @@ function Cesium3DTileset(options) { * This time delay prevents requesting tiles around the edges of the screen when the camera is moving. * Setting this to 0.0 will immediately request all tiles in any given view. * - * @type {Number} + * @type {number} * @default 0.2 */ this.foveatedTimeDelay = defaultValue(options.foveatedTimeDelay, 0.2); @@ -395,7 +395,7 @@ function Cesium3DTileset(options) { * It is analogous to moving fog closer to the camera. * </p> * - * @type {Number} + * @type {number} * @default 0.00278 */ this.dynamicScreenSpaceErrorDensity = 0.00278; @@ -404,7 +404,7 @@ function Cesium3DTileset(options) { * A factor used to increase the screen space error of tiles for dynamic screen space error. As this value increases less tiles * are requested for rendering and tiles in the distance will have lower detail. If set to zero, the feature will be disabled. * - * @type {Number} + * @type {number} * @default 4.0 */ this.dynamicScreenSpaceErrorFactor = 4.0; @@ -417,7 +417,7 @@ function Cesium3DTileset(options) { * Valid values are between 0.0 and 1.0. * </p> * - * @type {Number} + * @type {number} * @default 0.25 */ this.dynamicScreenSpaceErrorHeightFalloff = 0.25; @@ -441,7 +441,7 @@ function Cesium3DTileset(options) { /** * Determines if the tileset will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -460,7 +460,7 @@ function Cesium3DTileset(options) { * A value of 0.0 results in the source color while a value of 1.0 results in the feature color, with any value in-between * resulting in a mix of the source color and feature color. * - * @type {Number} + * @type {number} * @default 0.5 */ this.colorBlendAmount = 0.5; @@ -650,7 +650,7 @@ function Cesium3DTileset(options) { * using this optimization. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.skipLevelOfDetail = defaultValue(options.skipLevelOfDetail, false); @@ -663,7 +663,7 @@ function Cesium3DTileset(options) { * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. * </p> * - * @type {Number} + * @type {number} * @default 1024 */ this.baseScreenSpaceError = defaultValue(options.baseScreenSpaceError, 1024); @@ -676,7 +676,7 @@ function Cesium3DTileset(options) { * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. * </p> * - * @type {Number} + * @type {number} * @default 16 */ this.skipScreenSpaceErrorFactor = defaultValue( @@ -691,7 +691,7 @@ function Cesium3DTileset(options) { * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. * </p> * - * @type {Number} + * @type {number} * @default 1 */ this.skipLevels = defaultValue(options.skipLevels, 1); @@ -703,7 +703,7 @@ function Cesium3DTileset(options) { * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.immediatelyLoadDesiredLevelOfDetail = defaultValue( @@ -718,7 +718,7 @@ function Cesium3DTileset(options) { * Only used when {@link Cesium3DTileset#skipLevelOfDetail} is <code>true</code>. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.loadSiblings = defaultValue(options.loadSiblings, false); @@ -751,7 +751,7 @@ function Cesium3DTileset(options) { * Whether to cull back-facing geometry. When true, back face culling is determined * by the glTF material's doubleSided property; when false, back face culling is disabled. * - * @type {Boolean} + * @type {boolean} * @default true */ this.backFaceCulling = defaultValue(options.backFaceCulling, true); @@ -763,7 +763,7 @@ function Cesium3DTileset(options) { * {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. * When true, outlines are displayed. When false, outlines are not displayed. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showOutline = defaultValue(options.showOutline, true); @@ -797,7 +797,7 @@ function Cesium3DTileset(options) { * out and see what was rendered. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugFreezeFrame = defaultValue(options.debugFreezeFrame, false); @@ -810,7 +810,7 @@ function Cesium3DTileset(options) { * from parent tiles may be interleaved with features from child tiles. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugColorizeTiles = defaultValue(options.debugColorizeTiles, false); @@ -826,7 +826,7 @@ function Cesium3DTileset(options) { * When true, renders each tile's content as a wireframe. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugWireframe = defaultValue(options.debugWireframe, false); @@ -847,7 +847,7 @@ function Cesium3DTileset(options) { * screen space error and are still refining to their descendants are yellow. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowBoundingVolume = defaultValue( @@ -862,7 +862,7 @@ function Cesium3DTileset(options) { * blue if the tile has a content bounding volume; otherwise it is red. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowContentBoundingVolume = defaultValue( @@ -876,7 +876,7 @@ function Cesium3DTileset(options) { * When true, renders the viewer request volume for each tile. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowViewerRequestVolume = defaultValue( @@ -895,7 +895,7 @@ function Cesium3DTileset(options) { * When true, draws labels to indicate the geometric error of each tile. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowGeometricError = defaultValue( @@ -909,7 +909,7 @@ function Cesium3DTileset(options) { * When true, draws labels to indicate the number of commands, points, triangles and features of each tile. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowRenderingStatistics = defaultValue( @@ -923,7 +923,7 @@ function Cesium3DTileset(options) { * When true, draws labels to indicate the geometry and texture memory usage of each tile. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowMemoryUsage = defaultValue(options.debugShowMemoryUsage, false); @@ -934,7 +934,7 @@ function Cesium3DTileset(options) { * When true, draws labels to indicate the url of each tile. * </p> * - * @type {Boolean} + * @type {boolean} * @default false */ this.debugShowUrl = defaultValue(options.debugShowUrl, false); @@ -1102,7 +1102,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Object} + * @type {object} * @readonly * * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. @@ -1126,7 +1126,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Object} + * @type {object} * @readonly * * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. @@ -1170,7 +1170,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Object} + * @type {object} * @readonly * * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. @@ -1202,7 +1202,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -1221,7 +1221,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Promise.<Cesium3DTileset>} + * @type {Promise<Cesium3DTileset>} * @readonly * * @example @@ -1247,7 +1247,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -1279,7 +1279,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {String} + * @type {string} * @readonly * @deprecated */ @@ -1445,7 +1445,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @default 16 * * @exception {DeveloperError} <code>maximumScreenSpaceError</code> must be greater than or equal to zero. @@ -1488,7 +1488,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @default 512 * * @exception {DeveloperError} <code>maximumMemoryUsage</code> must be greater than or equal to zero. @@ -1617,7 +1617,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @readonly */ timeSinceLoad: { @@ -1632,7 +1632,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @readonly * * @see Cesium3DTileset#maximumMemoryUsage @@ -1748,7 +1748,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @default 0.3 */ foveatedConeSize: { @@ -1771,7 +1771,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Number} + * @type {number} * @default 0.0 */ foveatedMinimumScreenSpaceErrorRelaxation: { @@ -1858,7 +1858,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * - * @type {Boolean} + * @type {boolean} * @default false */ vectorClassificationOnly: { @@ -1875,7 +1875,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. * - * @type {Boolean} + * @type {boolean} * @default false */ vectorKeepDecodedPositions: { @@ -1889,7 +1889,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {Boolean} + * @type {boolean} * @default false */ showCreditsOnScreen: { @@ -1920,7 +1920,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {String} + * @type {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ featureIdLabel: { @@ -1952,7 +1952,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @type {String} + * @type {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ instanceFeatureIdLabel: { @@ -1977,8 +1977,8 @@ Object.defineProperties(Cesium3DTileset.prototype, { /** * Provides a hook to override the method used to request the tileset json * useful when fetching tilesets from remote servers - * @param {Resource|String} tilesetUrl The url of the json file to be fetched - * @returns {Promise.<Object>} A promise that resolves with the fetched json data + * @param {Resource|string} tilesetUrl The url of the json file to be fetched + * @returns {Promise<object>} A promise that resolves with the fetched json data */ Cesium3DTileset.loadJson = function (tilesetUrl) { const resource = Resource.createIfNeeded(tilesetUrl); @@ -2077,7 +2077,7 @@ Cesium3DTileset.prototype.loadTileset = function ( * * @param {Cesium3DTileset} tileset The tileset * @param {Resource} baseResource The base resource for the tileset - * @param {Object} tileHeader The JSON header for the tile + * @param {object} tileHeader The JSON header for the tile * @param {Cesium3DTile} [parentTile] The parent tile of the new tile * @returns {Cesium3DTile} The newly created tile * @@ -2142,8 +2142,8 @@ function makeTile(tileset, baseResource, tileHeader, parentTile) { * instance. This is asynchronous since metadata schemas may be external. * * @param {Cesium3DTileset} tileset The tileset - * @param {Object} tilesetJson The tileset JSON - * @return {Promise<Object>} A promise that resolves to tilesetJson for chaining. + * @param {object} tilesetJson The tileset JSON + * @return {Promise<object>} A promise that resolves to tilesetJson for chaining. * @private */ function processMetadataExtension(tileset, tilesetJson) { @@ -3040,9 +3040,9 @@ Cesium3DTileset.prototype.updateForPass = function ( /** * <code>true</code> if the tileset JSON file lists the extension in extensionsUsed; otherwise, <code>false</code>. - * @param {String} extensionName The name of the extension to check. + * @param {string} extensionName The name of the extension to check. * - * @returns {Boolean} <code>true</code> if the tileset JSON file lists the extension in extensionsUsed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the tileset JSON file lists the extension in extensionsUsed; otherwise, <code>false</code>. */ Cesium3DTileset.prototype.hasExtension = function (extensionName) { if (!defined(this._extensionsUsed)) { @@ -3058,7 +3058,7 @@ Cesium3DTileset.prototype.hasExtension = function (extensionName) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Cesium3DTileset#destroy */ @@ -3134,7 +3134,7 @@ Cesium3DTileset.supportedExtensions = { * Checks to see if a given extension is supported by Cesium3DTileset. If * the extension is not supported by Cesium3DTileset, it throws a RuntimeError. * - * @param {Object} extensionsRequired The extensions we wish to check + * @param {object} extensionsRequired The extensions we wish to check * * @private */ @@ -3155,9 +3155,9 @@ Cesium3DTileset.checkSupportedExtensions = function (extensionsRequired) { * @callback Cesium3DTileset.foveatedInterpolationCallback * @default Math.lerp * - * @param {Number} p The start value to interpolate. - * @param {Number} q The end value to interpolate. - * @param {Number} time The time of interpolation generally in the range <code>[0.0, 1.0]</code>. - * @returns {Number} The interpolated value. + * @param {number} p The start value to interpolate. + * @param {number} q The end value to interpolate. + * @param {number} time The time of interpolation generally in the range <code>[0.0, 1.0]</code>. + * @returns {number} The interpolated value. */ export default Cesium3DTileset; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetHeatmap.js b/packages/engine/Source/Scene/Cesium3DTilesetHeatmap.js index 5d4f068e54f..ec01db34d54 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetHeatmap.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetHeatmap.js @@ -15,7 +15,7 @@ function Cesium3DTilesetHeatmap(tilePropertyName) { * The tile variable to track for heatmap colorization. * Tile's will be colorized relative to the other visible tile's values for this variable. * - * @type {String} + * @type {string} */ this.tilePropertyName = tilePropertyName; @@ -50,9 +50,9 @@ function getHeatmapValue(tileValue, tilePropertyName) { /** * Sets the reference minimum and maximum for the variable name. Converted to numbers before they are stored. * - * @param {Object} minimum The minimum reference value. - * @param {Object} maximum The maximum reference value. - * @param {String} tilePropertyName The tile variable that will use these reference values when it is colorized. + * @param {object} minimum The minimum reference value. + * @param {object} maximum The maximum reference value. + * @param {string} tilePropertyName The tile variable that will use these reference values when it is colorized. */ Cesium3DTilesetHeatmap.prototype.setReferenceMinimumMaximum = function ( minimum, diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMetadata.js b/packages/engine/Source/Scene/Cesium3DTilesetMetadata.js index 1b8dfd462b0..8c2df573bfb 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMetadata.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMetadata.js @@ -14,8 +14,8 @@ import TilesetMetadata from "./TilesetMetadata.js"; * the schema ({@link MetadataSchema}), tileset metadata ({@link TilesetMetadata}), group metadata (dictionary of {@link GroupMetadata}), and metadata statistics (dictionary) * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.metadataJson Either the tileset JSON (3D Tiles 1.1) or the <code>3DTILES_metadata</code> extension object that contains the tileset metadata. + * @param {object} options Object with the following properties: + * @param {object} options.metadataJson Either the tileset JSON (3D Tiles 1.1) or the <code>3DTILES_metadata</code> extension object that contains the tileset metadata. * @param {MetadataSchema} options.schema The parsed schema. * * @alias Cesium3DTilesetMetadata @@ -125,7 +125,7 @@ Object.defineProperties(Cesium3DTilesetMetadata.prototype, { * Only populated if using the legacy schema. * * @memberof Cesium3DTilesetMetadata.prototype - * @type {String[]} + * @type {} * @readonly * @private */ @@ -157,7 +157,7 @@ Object.defineProperties(Cesium3DTilesetMetadata.prototype, { * </p> * * @memberof Cesium3DTilesetMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -185,7 +185,7 @@ Object.defineProperties(Cesium3DTilesetMetadata.prototype, { * An object containing extensions. * * @memberof Cesium3DTilesetMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/CircleEmitter.js b/packages/engine/Source/Scene/CircleEmitter.js index a1e10a255d9..4fe04e5201b 100644 --- a/packages/engine/Source/Scene/CircleEmitter.js +++ b/packages/engine/Source/Scene/CircleEmitter.js @@ -10,7 +10,7 @@ import CesiumMath from "../Core/Math.js"; * @alias CircleEmitter * @constructor * - * @param {Number} [radius=1.0] The radius of the circle in meters. + * @param {number} [radius=1.0] The radius of the circle in meters. */ function CircleEmitter(radius) { radius = defaultValue(radius, 1.0); @@ -26,7 +26,7 @@ Object.defineProperties(CircleEmitter.prototype, { /** * The radius of the circle in meters. * @memberof CircleEmitter.prototype - * @type {Number} + * @type {number} * @default 1.0 */ radius: { diff --git a/packages/engine/Source/Scene/ClassificationPrimitive.js b/packages/engine/Source/Scene/ClassificationPrimitive.js index d0412080fab..b9d1c608bce 100644 --- a/packages/engine/Source/Scene/ClassificationPrimitive.js +++ b/packages/engine/Source/Scene/ClassificationPrimitive.js @@ -49,19 +49,19 @@ import StencilOperation from "./StencilOperation.js"; * @alias ClassificationPrimitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. This can either be a single instance or an array of length one. * @param {Appearance} [options.appearance] The appearance used to render the primitive. Defaults to PerInstanceColorAppearance when GeometryInstances have a color attribute. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. * * @see Primitive @@ -96,7 +96,7 @@ function ClassificationPrimitive(options) { * Determines if the primitive will be shown. This affects all geometry * instances in the primitive. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -118,7 +118,7 @@ function ClassificationPrimitive(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -132,7 +132,7 @@ function ClassificationPrimitive(options) { * Draws the shadow volume for each geometry in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -228,7 +228,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -244,7 +244,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -260,7 +260,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -276,7 +276,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -292,7 +292,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -308,7 +308,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -326,7 +326,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * * @memberof ClassificationPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -338,7 +338,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { /** * Gets a promise that resolves when the primitive is ready to render. * @memberof ClassificationPrimitive.prototype - * @type {Promise.<ClassificationPrimitive>} + * @type {Promise<ClassificationPrimitive>} * @readonly */ readyPromise: { @@ -352,7 +352,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * This is because texture coordinates on ClassificationPrimitives are computed differently, * and are used for culling when multiple GeometryInstances are batched in one ClassificationPrimitive. * @memberof ClassificationPrimitive.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -369,7 +369,7 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * Determines if ClassificationPrimitive rendering is supported. * * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if ClassificationPrimitives are supported; otherwise, returns <code>false</code> + * @returns {boolean} <code>true</code> if ClassificationPrimitives are supported; otherwise, returns <code>false</code> */ ClassificationPrimitive.isSupported = function (scene) { return scene.context.stencilBuffer; @@ -1361,7 +1361,7 @@ ClassificationPrimitive.prototype.update = function (frameState) { * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * * @param {*} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * @returns {object} The typed array in the attribute's format or undefined if the is no instance with id. * * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. * @@ -1390,7 +1390,7 @@ ClassificationPrimitive.prototype.getGeometryInstanceAttributes = function ( * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ClassificationPrimitive#destroy */ diff --git a/packages/engine/Source/Scene/ClassificationType.js b/packages/engine/Source/Scene/ClassificationType.js index 5992c7cb237..55fb1fe1820 100644 --- a/packages/engine/Source/Scene/ClassificationType.js +++ b/packages/engine/Source/Scene/ClassificationType.js @@ -1,27 +1,27 @@ /** * Whether a classification affects terrain, 3D Tiles or both. * - * @enum {Number} + * @enum {number} */ const ClassificationType = { /** * Only terrain will be classified. * - * @type {Number} + * @type {number} * @constant */ TERRAIN: 0, /** * Only 3D Tiles will be classified. * - * @type {Number} + * @type {number} * @constant */ CESIUM_3D_TILE: 1, /** * Both terrain and 3D Tiles will be classified. * - * @type {Number} + * @type {number} * @constant */ BOTH: 2, diff --git a/packages/engine/Source/Scene/ClippingPlane.js b/packages/engine/Source/Scene/ClippingPlane.js index d1e65e60cab..603ba0309a0 100644 --- a/packages/engine/Source/Scene/ClippingPlane.js +++ b/packages/engine/Source/Scene/ClippingPlane.js @@ -10,7 +10,7 @@ import defined from "../Core/defined.js"; * @constructor * * @param {Cartesian3} normal The plane's normal (normalized). - * @param {Number} distance The shortest distance from the origin to the plane. The sign of + * @param {number} distance The shortest distance from the origin to the plane. The sign of * <code>distance</code> determines which side of the plane the origin * is on. If <code>distance</code> is positive, the origin is in the half-space * in the direction of the normal; if negative, the origin is in the half-space @@ -36,7 +36,7 @@ Object.defineProperties(ClippingPlane.prototype, { * in the direction of the normal; if negative, the origin is in the half-space * opposite to the normal; if zero, the plane passes through the origin. * - * @type {Number} + * @type {number} * @memberof ClippingPlane.prototype */ distance: { diff --git a/packages/engine/Source/Scene/ClippingPlaneCollection.js b/packages/engine/Source/Scene/ClippingPlaneCollection.js index d16b971fb0a..c9c9d84a3cf 100644 --- a/packages/engine/Source/Scene/ClippingPlaneCollection.js +++ b/packages/engine/Source/Scene/ClippingPlaneCollection.js @@ -33,13 +33,13 @@ import ClippingPlane from "./ClippingPlane.js"; * @alias ClippingPlaneCollection * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {ClippingPlane[]} [options.planes=[]] An array of {@link ClippingPlane} objects used to selectively disable rendering on the outside of each plane. - * @param {Boolean} [options.enabled=true] Determines whether the clipping planes are active. + * @param {boolean} [options.enabled=true] Determines whether the clipping planes are active. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix specifying an additional transform relative to the clipping planes original coordinate system. - * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if it is on the outside of any plane in the collection. Otherwise, a region will only be clipped if it is on the outside of every plane. + * @param {boolean} [options.unionClippingRegions=false] If true, a region will be clipped if it is on the outside of any plane in the collection. Otherwise, a region will only be clipped if it is on the outside of every plane. * @param {Color} [options.edgeColor=Color.WHITE] The color applied to highlight the edge along which an object is clipped. - * @param {Number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. + * @param {number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. * * @demo {@link https://sandcastle.cesium.com/?src=3D%20Tiles%20Clipping%20Planes.html|Clipping 3D Tiles and glTF models.} * @demo {@link https://sandcastle.cesium.com/?src=Terrain%20Clipping%20Planes.html|Clipping the Globe.} @@ -99,7 +99,7 @@ function ClippingPlaneCollection(options) { /** * The width, in pixels, of the highlight applied to the edge along which an object is clipped. * - * @type {Number} + * @type {number} * @default 0.0 */ this.edgeWidth = defaultValue(options.edgeWidth, 0.0); @@ -163,7 +163,7 @@ Object.defineProperties(ClippingPlaneCollection.prototype, { * in the collection. * * @memberof ClippingPlaneCollection.prototype - * @type {Number} + * @type {number} * @readonly */ length: { @@ -178,7 +178,7 @@ Object.defineProperties(ClippingPlaneCollection.prototype, { * outside of every plane. * * @memberof ClippingPlaneCollection.prototype - * @type {Boolean} + * @type {boolean} * @default false */ unionClippingRegions: { @@ -200,7 +200,7 @@ Object.defineProperties(ClippingPlaneCollection.prototype, { * If true, clipping will be enabled. * * @memberof ClippingPlaneCollection.prototype - * @type {Boolean} + * @type {boolean} * @default true */ enabled: { @@ -249,7 +249,7 @@ Object.defineProperties(ClippingPlaneCollection.prototype, { * If this value changes, then shader regeneration is necessary. * * @memberof ClippingPlaneCollection.prototype - * @returns {Number} A Number that describes the ClippingPlaneCollection's state. + * @returns {number} A Number that describes the ClippingPlaneCollection's state. * @readonly * @private */ @@ -303,7 +303,7 @@ ClippingPlaneCollection.prototype.add = function (plane) { * {@link ClippingPlaneCollection#length} to iterate over all the planes * in the collection. * - * @param {Number} index The zero-based index of the plane. + * @param {number} index The zero-based index of the plane. * @returns {ClippingPlane} The ClippingPlane at the specified index. * * @see ClippingPlaneCollection#length @@ -331,7 +331,7 @@ function indexOf(planes, plane) { * Checks whether this collection contains a ClippingPlane equal to the given ClippingPlane. * * @param {ClippingPlane} [clippingPlane] The ClippingPlane to check for. - * @returns {Boolean} true if this collection contains the ClippingPlane, false otherwise. + * @returns {boolean} true if this collection contains the ClippingPlane, false otherwise. * * @see ClippingPlaneCollection#get */ @@ -343,7 +343,7 @@ ClippingPlaneCollection.prototype.contains = function (clippingPlane) { * Removes the first occurrence of the given ClippingPlane from the collection. * * @param {ClippingPlane} clippingPlane - * @returns {Boolean} <code>true</code> if the plane was removed; <code>false</code> if the plane was not found in the collection. + * @returns {boolean} <code>true</code> if the plane was removed; <code>false</code> if the plane was not found in the collection. * * @see ClippingPlaneCollection#add * @see ClippingPlaneCollection#contains @@ -612,7 +612,7 @@ const scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); * Determines the type intersection with the planes of this ClippingPlaneCollection instance and the specified {@link TileBoundingVolume}. * @private * - * @param {Object} tileBoundingVolume The volume to determine the intersection with the planes. + * @param {object} tileBoundingVolume The volume to determine the intersection with the planes. * @param {Matrix4} [transform] An optional, additional matrix to transform the plane to world coordinates. * @returns {Intersect} {@link Intersect.INSIDE} if the entire volume is on the side of the planes * the normal is pointing and should be entirely rendered, {@link Intersect.OUTSIDE} @@ -661,8 +661,8 @@ ClippingPlaneCollection.prototype.computeIntersectionWithBoundingVolume = functi * Destroys the owner's previous ClippingPlaneCollection if setting is successful. * * @param {ClippingPlaneCollection} [clippingPlaneCollection] A ClippingPlaneCollection (or undefined) being attached to an object - * @param {Object} owner An Object that should receive the new ClippingPlaneCollection - * @param {String} key The Key for the Object to reference the ClippingPlaneCollection + * @param {object} owner An Object that should receive the new ClippingPlaneCollection + * @param {string} key The Key for the Object to reference the ClippingPlaneCollection * @private */ ClippingPlaneCollection.setOwner = function ( @@ -693,7 +693,7 @@ ClippingPlaneCollection.setOwner = function ( * Function for checking if the context will allow clipping planes with floating point textures. * * @param {Context} context The Context that will contain clipped objects and clipping textures. - * @returns {Boolean} <code>true</code> if floating point textures can be used for clipping planes. + * @returns {boolean} <code>true</code> if floating point textures can be used for clipping planes. * @private */ ClippingPlaneCollection.useFloatTexture = function (context) { @@ -739,7 +739,7 @@ ClippingPlaneCollection.getTextureResolution = function ( * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ClippingPlaneCollection#destroy */ diff --git a/packages/engine/Source/Scene/CloudCollection.js b/packages/engine/Source/Scene/CloudCollection.js index 10b3b20e19e..43af3d6266a 100644 --- a/packages/engine/Source/Scene/CloudCollection.js +++ b/packages/engine/Source/Scene/CloudCollection.js @@ -76,12 +76,12 @@ const COLOR_INDEX = CumulusCloud.COLOR_INDEX; * @alias CloudCollection * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Whether to display the clouds. - * @param {Number} [options.noiseDetail=16.0] Desired amount of detail in the noise texture. - * @param {Number} [options.noiseOffset=Cartesian3.ZERO] Desired translation of data in noise texture. - * @param {Boolean} [options.debugBillboards=false] For debugging only. Determines if the billboards are rendered with an opaque color. - * @param {Boolean} [options.debugEllipsoids=false] For debugging only. Determines if the clouds will be rendered as opaque ellipsoids. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.show=true] Whether to display the clouds. + * @param {number} [options.noiseDetail=16.0] Desired amount of detail in the noise texture. + * @param {number} [options.noiseOffset=Cartesian3.ZERO] Desired translation of data in noise texture. + * @param {boolean} [options.debugBillboards=false] For debugging only. Determines if the billboards are rendered with an opaque color. + * @param {boolean} [options.debugEllipsoids=false] For debugging only. Determines if the clouds will be rendered as opaque ellipsoids. * @see CloudCollection#add * @see CloudCollection#remove * @see CumulusCloud @@ -139,7 +139,7 @@ function CloudCollection(options) { * </tr></table> * </div> * - * @type {Number} + * @type {number} * * @default 16.0 */ @@ -195,7 +195,7 @@ function CloudCollection(options) { /** * Determines if billboards in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -208,7 +208,7 @@ function CloudCollection(options) { * Renders the billboards with one opaque color for the sake of debugging. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -222,7 +222,7 @@ function CloudCollection(options) { * If <code>debugBillboards</code> is also true, then the ellipsoids will draw on top of the billboards. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -244,7 +244,7 @@ Object.defineProperties(CloudCollection.prototype, { /** * Returns the number of clouds in this collection. * @memberof CloudCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -267,7 +267,7 @@ function destroyClouds(clouds) { * Creates and adds a cloud with the specified initial properties to the collection. * The added cloud is returned so it can be modified or removed from the collection later. * - * @param {Object}[options] A template describing the cloud's properties as shown in Example 1. + * @param {object}[options] A template describing the cloud's properties as shown in Example 1. * @returns {CumulusCloud} The cloud that was added to the collection. * * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer @@ -321,7 +321,7 @@ CloudCollection.prototype.add = function (options) { * Removes a cloud from the collection. * * @param {CumulusCloud} cloud The cloud to remove. - * @returns {Boolean} <code>true</code> if the cloud was removed; <code>false</code> if the cloud was not found in the collection. + * @returns {boolean} <code>true</code> if the cloud was removed; <code>false</code> if the cloud was not found in the collection. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * @@ -403,7 +403,7 @@ CloudCollection.prototype._updateCloud = function (cloud, propertyChanged) { * Check whether this collection contains a given cloud. * * @param {CumulusCloud} [cloud] The cloud to check for. - * @returns {Boolean} true if this collection contains the cloud, false otherwise. + * @returns {boolean} true if this collection contains the cloud, false otherwise. * * @see CloudCollection#get */ @@ -417,7 +417,7 @@ CloudCollection.prototype.contains = function (cloud) { * it to the left, changing their indices. This function is commonly used with * {@link CloudCollection#length} to iterate over all the clouds in the collection. * - * @param {Number} index The zero-based index of the cloud. + * @param {number} index The zero-based index of the cloud. * @returns {CumulusCloud} The cloud at the specified index. * * @performance Expected constant time. If clouds were removed from the collection and @@ -1013,7 +1013,7 @@ CloudCollection.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see CloudCollection#destroy */ diff --git a/packages/engine/Source/Scene/CloudType.js b/packages/engine/Source/Scene/CloudType.js index 7f0664ff89e..bb7bbb741b9 100644 --- a/packages/engine/Source/Scene/CloudType.js +++ b/packages/engine/Source/Scene/CloudType.js @@ -1,14 +1,14 @@ /** * Specifies the type of the cloud that is added to a {@link CloudCollection} in {@link CloudCollection#add}. * - * @enum {Number} + * @enum {number} */ const CloudType = { /** * Cumulus cloud. * - * @type {Number} + * @type {number} * @constant */ CUMULUS: 0, @@ -18,7 +18,7 @@ const CloudType = { * Validates that the provided cloud type is a valid {@link CloudType} * * @param {CloudType} cloudType The cloud type to validate. - * @returns {Boolean} <code>true</code> if the provided cloud type is a valid value; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the provided cloud type is a valid value; otherwise, <code>false</code>. * * @example * if (!Cesium.CloudType.validate(cloudType)) { diff --git a/packages/engine/Source/Scene/ColorBlendMode.js b/packages/engine/Source/Scene/ColorBlendMode.js index 51b3ca1db48..b2f5194da14 100644 --- a/packages/engine/Source/Scene/ColorBlendMode.js +++ b/packages/engine/Source/Scene/ColorBlendMode.js @@ -7,7 +7,7 @@ import CesiumMath from "../Core/Math.js"; * REPLACE replaces the source color with the target color * MIX blends the source color and target color together * - * @enum {Number} + * @enum {number} * * @see Model.colorBlendMode */ diff --git a/packages/engine/Source/Scene/ConditionsExpression.js b/packages/engine/Source/Scene/ConditionsExpression.js index 2fb7ed5957c..ea1a355290e 100644 --- a/packages/engine/Source/Scene/ConditionsExpression.js +++ b/packages/engine/Source/Scene/ConditionsExpression.js @@ -15,8 +15,8 @@ import Expression from "./Expression.js"; * @alias ConditionsExpression * @constructor * - * @param {Object} [conditionsExpression] The conditions expression defined using the 3D Tiles Styling language. - * @param {Object} [defines] Defines in the style. + * @param {object} [conditionsExpression] The conditions expression defined using the 3D Tiles Styling language. + * @param {object} [defines] Defines in the style. * * @example * const expression = new Cesium.ConditionsExpression({ @@ -42,7 +42,7 @@ Object.defineProperties(ConditionsExpression.prototype, { * * @memberof ConditionsExpression.prototype * - * @type {Object} + * @type {object} * @readonly * * @default undefined @@ -91,8 +91,8 @@ function setRuntime(expression, defines) { * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. * * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + * @param {object} [result] The object onto which to store the result. + * @returns {boolean|number|string|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. */ ConditionsExpression.prototype.evaluate = function (feature, result) { const conditions = this._runtimeConditions; @@ -135,12 +135,12 @@ ConditionsExpression.prototype.evaluateColor = function (feature, result) { * Gets the shader function for this expression. * Returns undefined if the shader function can't be generated from this expression. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} returnType The return type of the generated function. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -188,7 +188,7 @@ ConditionsExpression.prototype.getShaderFunction = function ( /** * Gets the variables used by the expression. * - * @returns {String[]} The variables used by the expression. + * @returns {} The variables used by the expression. * * @private */ diff --git a/packages/engine/Source/Scene/ConeEmitter.js b/packages/engine/Source/Scene/ConeEmitter.js index 66a217f6df2..49371c5e6d6 100644 --- a/packages/engine/Source/Scene/ConeEmitter.js +++ b/packages/engine/Source/Scene/ConeEmitter.js @@ -12,7 +12,7 @@ const defaultAngle = CesiumMath.toRadians(30.0); * @alias ConeEmitter * @constructor * - * @param {Number} [angle=Cesium.Math.toRadians(30.0)] The angle of the cone in radians. + * @param {number} [angle=Cesium.Math.toRadians(30.0)] The angle of the cone in radians. */ function ConeEmitter(angle) { this._angle = defaultValue(angle, defaultAngle); @@ -22,7 +22,7 @@ Object.defineProperties(ConeEmitter.prototype, { /** * The angle of the cone in radians. * @memberof CircleEmitter.prototype - * @type {Number} + * @type {number} * @default Cesium.Math.toRadians(30.0) */ angle: { diff --git a/packages/engine/Source/Scene/ContentMetadata.js b/packages/engine/Source/Scene/ContentMetadata.js index 7bd110b6ff8..7a5c48d73f3 100644 --- a/packages/engine/Source/Scene/ContentMetadata.js +++ b/packages/engine/Source/Scene/ContentMetadata.js @@ -9,8 +9,8 @@ import MetadataEntity from "./MetadataEntity.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.content Either the content metadata JSON (3D Tiles 1.1) or the extension JSON attached to the content. + * @param {object} options Object with the following properties: + * @param {object} options.content Either the content metadata JSON (3D Tiles 1.1) or the extension JSON attached to the content. * @param {MetadataClass} options.class The class that the content metadata conforms to. * * @alias ContentMetadata @@ -53,7 +53,7 @@ Object.defineProperties(ContentMetadata.prototype, { * Extra user-defined properties. * * @memberof ContentMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -67,7 +67,7 @@ Object.defineProperties(ContentMetadata.prototype, { * An object containing extensions. * * @memberof ContentMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -81,8 +81,8 @@ Object.defineProperties(ContentMetadata.prototype, { /** * Returns whether the content has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the content has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the content has this property. * @private */ ContentMetadata.prototype.hasProperty = function (propertyId) { @@ -92,8 +92,8 @@ ContentMetadata.prototype.hasProperty = function (propertyId) { /** * Returns whether the content has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the content has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the content has a property with the given semantic. * @private */ ContentMetadata.prototype.hasPropertyBySemantic = function (semantic) { @@ -107,8 +107,8 @@ ContentMetadata.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ ContentMetadata.prototype.getPropertyIds = function (results) { @@ -121,7 +121,7 @@ ContentMetadata.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the content does not have this property. * @private */ @@ -135,9 +135,9 @@ ContentMetadata.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ ContentMetadata.prototype.setProperty = function (propertyId, value) { @@ -152,7 +152,7 @@ ContentMetadata.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the content does not have this semantic. * @private */ @@ -167,9 +167,9 @@ ContentMetadata.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ ContentMetadata.prototype.setPropertyBySemantic = function (semantic, value) { diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 5a7b6ec6350..0649d655236 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -280,7 +280,7 @@ function appendCss() { * The credit display is responsible for displaying credits on screen. * * @param {HTMLElement} container The HTML element where credits will be displayed - * @param {String} [delimiter= ' • '] The string to separate text credits + * @param {string} [delimiter= ' • '] The string to separate text credits * @param {HTMLElement} [viewport=document.body] The HTML element that will contain the credits popup * * @alias CreditDisplay @@ -550,7 +550,7 @@ CreditDisplay.prototype.destroy = function () { * Returns true if this object was destroyed; otherwise, false. * <br /><br /> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ CreditDisplay.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/CullFace.js b/packages/engine/Source/Scene/CullFace.js index 4503a136274..414ce811b22 100644 --- a/packages/engine/Source/Scene/CullFace.js +++ b/packages/engine/Source/Scene/CullFace.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines which triangles, if any, are culled. * - * @enum {Number} + * @enum {number} */ const CullFace = { /** * Front-facing triangles are culled. * - * @type {Number} + * @type {number} * @constant */ FRONT: WebGLConstants.FRONT, @@ -17,7 +17,7 @@ const CullFace = { /** * Back-facing triangles are culled. * - * @type {Number} + * @type {number} * @constant */ BACK: WebGLConstants.BACK, @@ -25,7 +25,7 @@ const CullFace = { /** * Both front-facing and back-facing triangles are culled. * - * @type {Number} + * @type {number} * @constant */ FRONT_AND_BACK: WebGLConstants.FRONT_AND_BACK, diff --git a/packages/engine/Source/Scene/CumulusCloud.js b/packages/engine/Source/Scene/CumulusCloud.js index 11d4cf60459..d66dd964813 100644 --- a/packages/engine/Source/Scene/CumulusCloud.js +++ b/packages/engine/Source/Scene/CumulusCloud.js @@ -88,7 +88,7 @@ Object.defineProperties(CumulusCloud.prototype, { * Determines if this cumulus cloud will be shown. Use this to hide or show a cloud, instead * of removing it and re-adding it to the collection. * @memberof CumulusCloud.prototype - * @type {Boolean} + * @type {boolean} * @default true */ show: { @@ -293,7 +293,7 @@ Object.defineProperties(CumulusCloud.prototype, { * </div> * * @memberof CumulusCloud.prototype - * @type {Number} + * @type {number} * @default -1.0 */ slice: { @@ -325,7 +325,7 @@ Object.defineProperties(CumulusCloud.prototype, { * </tr></table> * </div> * @memberof CumulusCloud.prototype - * @type {Number} + * @type {number} * @default 1.0 */ brightness: { diff --git a/packages/engine/Source/Scene/DebugAppearance.js b/packages/engine/Source/Scene/DebugAppearance.js index 1f2a8e2a978..098eea16a60 100644 --- a/packages/engine/Source/Scene/DebugAppearance.js +++ b/packages/engine/Source/Scene/DebugAppearance.js @@ -14,13 +14,13 @@ import Appearance from "./Appearance.js"; * @alias DebugAppearance * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.attributeName The name of the attribute to visualize. - * @param {Boolean} [options.perInstanceAttribute=false] Boolean that determines whether this attribute is a per-instance geometry attribute. - * @param {String} [options.glslDatatype='vec3'] The GLSL datatype of the attribute. Supported datatypes are <code>float</code>, <code>vec2</code>, <code>vec3</code>, and <code>vec4</code>. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {object} options Object with the following properties: + * @param {string} options.attributeName The name of the attribute to visualize. + * @param {boolean} [options.perInstanceAttribute=false] Boolean that determines whether this attribute is a per-instance geometry attribute. + * @param {string} [options.glslDatatype='vec3'] The GLSL datatype of the attribute. Supported datatypes are <code>float</code>, <code>vec2</code>, <code>vec3</code>, and <code>vec4</code>. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @exception {DeveloperError} options.glslDatatype must be float, vec2, vec3, or vec4. * @@ -122,7 +122,7 @@ function DebugAppearance(options) { /** * When <code>true</code>, the geometry is expected to appear translucent. * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -149,7 +149,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -165,7 +165,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -179,7 +179,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -193,7 +193,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -209,7 +209,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ attributeName: { @@ -223,7 +223,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @memberof DebugAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ glslDatatype: { @@ -239,7 +239,7 @@ Object.defineProperties(DebugAppearance.prototype, { * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ DebugAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -249,7 +249,7 @@ DebugAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ DebugAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -260,7 +260,7 @@ DebugAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ DebugAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; export default DebugAppearance; diff --git a/packages/engine/Source/Scene/DebugCameraPrimitive.js b/packages/engine/Source/Scene/DebugCameraPrimitive.js index b59abf5bd42..4b46ba57d05 100644 --- a/packages/engine/Source/Scene/DebugCameraPrimitive.js +++ b/packages/engine/Source/Scene/DebugCameraPrimitive.js @@ -23,13 +23,13 @@ import Primitive from "./Primitive.js"; * @alias DebugCameraPrimitive * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Camera} options.camera The camera. - * @param {Number[]} [options.frustumSplits] Distances to the near and far planes of the camera frustums. This overrides the camera's frustum near and far values. + * @param {number[]} [options.frustumSplits] Distances to the near and far planes of the camera frustums. This overrides the camera's frustum near and far values. * @param {Color} [options.color=Color.CYAN] The color of the debug outline. - * @param {Boolean} [options.updateOnChange=true] Whether the primitive updates when the underlying camera changes. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick}. + * @param {boolean} [options.updateOnChange=true] Whether the primitive updates when the underlying camera changes. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick}. * * @example * primitives.add(new Cesium.DebugCameraPrimitive({ @@ -220,7 +220,7 @@ DebugCameraPrimitive.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see DebugCameraPrimitive#destroy */ diff --git a/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js b/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js index 0a2f94e9e37..26d6857ab47 100644 --- a/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js +++ b/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js @@ -24,12 +24,12 @@ import Primitive from "./Primitive.js"; * @alias DebugModelMatrixPrimitive * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.length=10000000.0] The length of the axes in meters. - * @param {Number} [options.width=2.0] The width of the axes in pixels. + * @param {object} [options] Object with the following properties: + * @param {number} [options.length=10000000.0] The length of the axes in meters. + * @param {number} [options.width=2.0] The width of the axes in pixels. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 matrix that defines the reference frame, i.e., origin plus axes, to visualize. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} * * @example * primitives.add(new Cesium.DebugModelMatrixPrimitive({ @@ -44,7 +44,7 @@ function DebugModelMatrixPrimitive(options) { /** * The length of the axes in meters. * - * @type {Number} + * @type {number} * @default 10000000.0 */ this.length = defaultValue(options.length, 10000000.0); @@ -53,7 +53,7 @@ function DebugModelMatrixPrimitive(options) { /** * The width of the axes in pixels. * - * @type {Number} + * @type {number} * @default 2.0 */ this.width = defaultValue(options.width, 2.0); @@ -191,7 +191,7 @@ DebugModelMatrixPrimitive.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see DebugModelMatrixPrimitive#destroy */ diff --git a/packages/engine/Source/Scene/DepthFunction.js b/packages/engine/Source/Scene/DepthFunction.js index 0de918ea4fb..23598bd5587 100644 --- a/packages/engine/Source/Scene/DepthFunction.js +++ b/packages/engine/Source/Scene/DepthFunction.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines the function used to compare two depths for the depth test. * - * @enum {Number} + * @enum {number} */ const DepthFunction = { /** * The depth test never passes. * - * @type {Number} + * @type {number} * @constant */ NEVER: WebGLConstants.NEVER, @@ -17,7 +17,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is less than the stored depth. * - * @type {Number} + * @type {number} * @constant */ LESS: WebGLConstants.LESS, @@ -25,7 +25,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is equal to the stored depth. * - * @type {Number} + * @type {number} * @constant */ EQUAL: WebGLConstants.EQUAL, @@ -33,7 +33,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is less than or equal to the stored depth. * - * @type {Number} + * @type {number} * @constant */ LESS_OR_EQUAL: WebGLConstants.LEQUAL, @@ -41,7 +41,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is greater than the stored depth. * - * @type {Number} + * @type {number} * @constant */ GREATER: WebGLConstants.GREATER, @@ -49,7 +49,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is not equal to the stored depth. * - * @type {Number} + * @type {number} * @constant */ NOT_EQUAL: WebGLConstants.NOTEQUAL, @@ -57,7 +57,7 @@ const DepthFunction = { /** * The depth test passes if the incoming depth is greater than or equal to the stored depth. * - * @type {Number} + * @type {number} * @constant */ GREATER_OR_EQUAL: WebGLConstants.GEQUAL, @@ -65,7 +65,7 @@ const DepthFunction = { /** * The depth test always passes. * - * @type {Number} + * @type {number} * @constant */ ALWAYS: WebGLConstants.ALWAYS, diff --git a/packages/engine/Source/Scene/DeviceOrientationCameraController.js b/packages/engine/Source/Scene/DeviceOrientationCameraController.js index efcab6c37a3..986c524300b 100644 --- a/packages/engine/Source/Scene/DeviceOrientationCameraController.js +++ b/packages/engine/Source/Scene/DeviceOrientationCameraController.js @@ -97,7 +97,7 @@ DeviceOrientationCameraController.prototype.update = function () { * Returns true if this object was destroyed; otherwise, false. * <br /><br /> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ DeviceOrientationCameraController.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/DirectionalLight.js b/packages/engine/Source/Scene/DirectionalLight.js index 69b25125515..bdf90c8d883 100644 --- a/packages/engine/Source/Scene/DirectionalLight.js +++ b/packages/engine/Source/Scene/DirectionalLight.js @@ -7,10 +7,10 @@ import DeveloperError from "../Core/DeveloperError.js"; /** * A light that gets emitted in a single direction from infinitely far away. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Cartesian3} options.direction The direction in which light gets emitted. * @param {Color} [options.color=Color.WHITE] The color of the light. - * @param {Number} [options.intensity=1.0] The intensity of the light. + * @param {number} [options.intensity=1.0] The intensity of the light. * * @exception {DeveloperError} options.direction cannot be zero-length * @@ -41,7 +41,7 @@ function DirectionalLight(options) { /** * The intensity of the light. - * @type {Number} + * @type {number} * @default 1.0 */ this.intensity = defaultValue(options.intensity, 1.0); diff --git a/packages/engine/Source/Scene/DiscardEmptyTileImagePolicy.js b/packages/engine/Source/Scene/DiscardEmptyTileImagePolicy.js index a841ff51690..1a57765a3ac 100644 --- a/packages/engine/Source/Scene/DiscardEmptyTileImagePolicy.js +++ b/packages/engine/Source/Scene/DiscardEmptyTileImagePolicy.js @@ -14,7 +14,7 @@ function DiscardEmptyTileImagePolicy(options) {} /** * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {boolean} True if the discard policy is ready to process images; otherwise, false. */ DiscardEmptyTileImagePolicy.prototype.isReady = function () { return true; @@ -24,7 +24,7 @@ DiscardEmptyTileImagePolicy.prototype.isReady = function () { * Given a tile image, decide whether to discard that image. * * @param {HTMLImageElement} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {boolean} True if the image should be discarded; otherwise, false. */ DiscardEmptyTileImagePolicy.prototype.shouldDiscardImage = function (image) { return DiscardEmptyTileImagePolicy.EMPTY_IMAGE === image; diff --git a/packages/engine/Source/Scene/DiscardMissingTileImagePolicy.js b/packages/engine/Source/Scene/DiscardMissingTileImagePolicy.js index 4651ffb77a0..de950a3b0b1 100644 --- a/packages/engine/Source/Scene/DiscardMissingTileImagePolicy.js +++ b/packages/engine/Source/Scene/DiscardMissingTileImagePolicy.js @@ -11,11 +11,11 @@ import Resource from "../Core/Resource.js"; * @alias DiscardMissingTileImagePolicy * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String} options.missingImageUrl The URL of the known missing image. + * @param {object} options Object with the following properties: + * @param {Resource|string} options.missingImageUrl The URL of the known missing image. * @param {Cartesian2[]} options.pixelsToCheck An array of {@link Cartesian2} pixel positions to * compare against the missing image. - * @param {Boolean} [options.disableCheckIfAllPixelsAreTransparent=false] If true, the discard check will be disabled + * @param {boolean} [options.disableCheckIfAllPixelsAreTransparent=false] If true, the discard check will be disabled * if all of the pixelsToCheck in the missingImageUrl have an alpha value of 0. If false, the * discard check will proceed no matter the values of the pixelsToCheck. */ @@ -95,7 +95,7 @@ function DiscardMissingTileImagePolicy(options) { /** * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {boolean} True if the discard policy is ready to process images; otherwise, false. */ DiscardMissingTileImagePolicy.prototype.isReady = function () { return this._isReady; @@ -105,7 +105,7 @@ DiscardMissingTileImagePolicy.prototype.isReady = function () { * Given a tile image, decide whether to discard that image. * * @param {HTMLImageElement} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {boolean} True if the image should be discarded; otherwise, false. * * @exception {DeveloperError} <code>shouldDiscardImage</code> must not be called before the discard policy is ready. */ diff --git a/packages/engine/Source/Scene/DracoLoader.js b/packages/engine/Source/Scene/DracoLoader.js index 0508a1df235..af76477c17c 100644 --- a/packages/engine/Source/Scene/DracoLoader.js +++ b/packages/engine/Source/Scene/DracoLoader.js @@ -54,11 +54,11 @@ DracoLoader.decodePointCloud = function (parameters) { /** * Decodes a buffer view. Returns undefined if the task cannot be scheduled. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Uint8Array} options.array The typed array containing the buffer view data. - * @param {Object} options.bufferView The glTF buffer view object. - * @param {Object.<String, Number>} options.compressedAttributes The compressed attributes. - * @param {Boolean} options.dequantizeInShader Whether POSITION and NORMAL attributes should be dequantized on the GPU. + * @param {object} options.bufferView The glTF buffer view object. + * @param {Object.<string, Number>} options.compressedAttributes The compressed attributes. + * @param {boolean} options.dequantizeInShader Whether POSITION and NORMAL attributes should be dequantized on the GPU. * * @returns {Promise} A promise that resolves to the decoded indices and attributes. * @private diff --git a/packages/engine/Source/Scene/EllipsoidPrimitive.js b/packages/engine/Source/Scene/EllipsoidPrimitive.js index be29bae1821..deab0b747ac 100644 --- a/packages/engine/Source/Scene/EllipsoidPrimitive.js +++ b/packages/engine/Source/Scene/EllipsoidPrimitive.js @@ -35,14 +35,14 @@ const attributeLocations = { * @alias EllipsoidPrimitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Cartesian3} [options.center=Cartesian3.ZERO] The center of the ellipsoid in the ellipsoid's model coordinates. * @param {Cartesian3} [options.radii] The radius of the ellipsoid along the <code>x</code>, <code>y</code>, and <code>z</code> axes in the ellipsoid's model coordinates. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the ellipsoid from model to world coordinates. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. * @param {Material} [options.material=Material.ColorType] The surface appearance of the primitive. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * * @private */ @@ -108,7 +108,7 @@ function EllipsoidPrimitive(options) { /** * Determines if the ellipsoid primitive will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -158,7 +158,7 @@ function EllipsoidPrimitive(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -471,7 +471,7 @@ EllipsoidPrimitive.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see EllipsoidPrimitive#destroy */ diff --git a/packages/engine/Source/Scene/EllipsoidSurfaceAppearance.js b/packages/engine/Source/Scene/EllipsoidSurfaceAppearance.js index 48e7c4cdccb..30e4aaf91e3 100644 --- a/packages/engine/Source/Scene/EllipsoidSurfaceAppearance.js +++ b/packages/engine/Source/Scene/EllipsoidSurfaceAppearance.js @@ -16,15 +16,15 @@ import Material from "./Material.js"; * @alias EllipsoidSurfaceAppearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. - * @param {Boolean} [options.faceForward=options.aboveGround] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link EllipsoidSurfaceAppearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.aboveGround=false] When <code>true</code>, the geometry is expected to be on the ellipsoid's surface - not at a constant height above it - so {@link EllipsoidSurfaceAppearance#renderState} has backface culling enabled. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. + * @param {boolean} [options.faceForward=options.aboveGround] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link EllipsoidSurfaceAppearance#renderState} has alpha blending enabled. + * @param {boolean} [options.aboveGround=false] When <code>true</code>, the geometry is expected to be on the ellipsoid's surface - not at a constant height above it - so {@link EllipsoidSurfaceAppearance#renderState} has backface culling enabled. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric} * @@ -64,7 +64,7 @@ function EllipsoidSurfaceAppearance(options) { /** * When <code>true</code>, the geometry is expected to appear translucent. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -98,7 +98,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -115,7 +115,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -134,7 +134,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -150,7 +150,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -185,7 +185,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -204,7 +204,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -223,7 +223,7 @@ Object.defineProperties(EllipsoidSurfaceAppearance.prototype, { * * @memberof EllipsoidSurfaceAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -253,7 +253,7 @@ EllipsoidSurfaceAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_ST; * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ EllipsoidSurfaceAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -263,7 +263,7 @@ EllipsoidSurfaceAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ EllipsoidSurfaceAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -275,7 +275,7 @@ EllipsoidSurfaceAppearance.prototype.isTranslucent = * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ EllipsoidSurfaceAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; diff --git a/packages/engine/Source/Scene/Expression.js b/packages/engine/Source/Scene/Expression.js index 1ccd59e4504..094994e23c0 100644 --- a/packages/engine/Source/Scene/Expression.js +++ b/packages/engine/Source/Scene/Expression.js @@ -23,8 +23,8 @@ import ExpressionNodeType from "./ExpressionNodeType.js"; * @alias Expression * @constructor * - * @param {String} [expression] The expression defined using the 3D Tiles Styling language. - * @param {Object} [defines] Defines in the style. + * @param {string} [expression] The expression defined using the 3D Tiles Styling language. + * @param {object} [defines] Defines in the style. * * @example * const expression = new Cesium.Expression('(regExp("^Chest").test(${County})) && (${YearBuilt} >= 1970)'); @@ -63,7 +63,7 @@ Object.defineProperties(Expression.prototype, { * * @memberof Expression.prototype * - * @type {String} + * @type {string} * @readonly * * @default undefined @@ -131,8 +131,8 @@ const scratchStorage = { * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. * * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + * @param {object} [result] The object onto which to store the result. + * @returns {boolean|number|string|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. */ Expression.prototype.evaluate = function (feature, result) { scratchStorage.reset(); @@ -170,12 +170,12 @@ Expression.prototype.evaluateColor = function (feature, result) { * Gets the shader function for this expression. * Returns undefined if the shader function can't be generated from this expression. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} returnType The return type of the generated function. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -203,10 +203,10 @@ Expression.prototype.getShaderFunction = function ( * Gets the shader expression for this expression. * Returns undefined if the shader expression can't be generated from this expression. * - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. * - * @returns {String} The shader expression. + * @returns {string} The shader expression. * * @private */ @@ -223,7 +223,7 @@ Expression.prototype.getShaderExpression = function ( /** * Gets the variables used by the expression. * - * @returns {String[]} The variables used by the expression. + * @returns {} The variables used by the expression. * * @private */ diff --git a/packages/engine/Source/Scene/Fog.js b/packages/engine/Source/Scene/Fog.js index 5349f0dd9d7..217ef14afcb 100644 --- a/packages/engine/Source/Scene/Fog.js +++ b/packages/engine/Source/Scene/Fog.js @@ -13,14 +13,14 @@ import SceneMode from "./SceneMode.js"; function Fog() { /** * <code>true</code> if fog is enabled, <code>false</code> otherwise. - * @type {Boolean} + * @type {boolean} * @default true */ this.enabled = true; /** * <code>true</code> if fog is renderable in shaders, <code>false</code> otherwise. * This allows to benefits from optimized tile loading strategy based on fog density without the actual visual rendering. - * @type {Boolean} + * @type {boolean} * @default true */ this.renderable = true; @@ -30,7 +30,7 @@ function Fog() { * The more dense the fog is, the more aggressively the terrain is culled. For example, if the camera is a height of * 1000.0m above the ellipsoid, increasing the value to 3.0e-3 will cause many tiles close to the viewer be culled. * Decreasing the value will push the fog further from the viewer, but decrease performance as more of the terrain is rendered. - * @type {Number} + * @type {number} * @default 2.0e-4 */ this.density = 2.0e-4; @@ -39,14 +39,14 @@ function Fog() { * the number of terrain tiles requested for rendering. If set to zero, the feature will be disabled. If the value is increased * for mountainous regions, less tiles will need to be requested, but the terrain meshes near the horizon may be a noticeably * lower resolution. If the value is increased in a relatively flat area, there will be little noticeable change on the horizon. - * @type {Number} + * @type {number} * @default 2.0 */ this.screenSpaceErrorFactor = 2.0; /** * The minimum brightness of the fog color from lighting. A value of 0.0 can cause the fog to be completely black. A value of 1.0 will not affect * the brightness at all. - * @type {Number} + * @type {number} * @default 0.03 */ this.minimumBrightness = 0.03; diff --git a/packages/engine/Source/Scene/FrameRateMonitor.js b/packages/engine/Source/Scene/FrameRateMonitor.js index c448aee6436..68169a6c24f 100644 --- a/packages/engine/Source/Scene/FrameRateMonitor.js +++ b/packages/engine/Source/Scene/FrameRateMonitor.js @@ -15,17 +15,17 @@ import TimeConstants from "../Core/TimeConstants.js"; * @alias FrameRateMonitor * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Scene} options.scene The Scene instance for which to monitor performance. - * @param {Number} [options.samplingWindow=5.0] The length of the sliding window over which to compute the average frame rate, in seconds. - * @param {Number} [options.quietPeriod=2.0] The length of time to wait at startup and each time the page becomes visible (i.e. when the user + * @param {number} [options.samplingWindow=5.0] The length of the sliding window over which to compute the average frame rate, in seconds. + * @param {number} [options.quietPeriod=2.0] The length of time to wait at startup and each time the page becomes visible (i.e. when the user * switches back to the tab) before starting to measure performance, in seconds. - * @param {Number} [options.warmupPeriod=5.0] The length of the warmup period, in seconds. During the warmup period, a separate + * @param {number} [options.warmupPeriod=5.0] The length of the warmup period, in seconds. During the warmup period, a separate * (usually lower) frame rate is required. - * @param {Number} [options.minimumFrameRateDuringWarmup=4] The minimum frames-per-second that are required for acceptable performance during + * @param {number} [options.minimumFrameRateDuringWarmup=4] The minimum frames-per-second that are required for acceptable performance during * the warmup period. If the frame rate averages less than this during any samplingWindow during the warmupPeriod, the * lowFrameRate event will be raised and the page will redirect to the redirectOnLowFrameRateUrl, if any. - * @param {Number} [options.minimumFrameRateAfterWarmup=8] The minimum frames-per-second that are required for acceptable performance after + * @param {number} [options.minimumFrameRateAfterWarmup=8] The minimum frames-per-second that are required for acceptable performance after * the end of the warmup period. If the frame rate averages less than this during any samplingWindow after the warmupPeriod, the * lowFrameRate event will be raised and the page will redirect to the redirectOnLowFrameRateUrl, if any. */ @@ -40,7 +40,7 @@ function FrameRateMonitor(options) { /** * Gets or sets the length of the sliding window over which to compute the average frame rate, in seconds. - * @type {Number} + * @type {number} */ this.samplingWindow = defaultValue( options.samplingWindow, @@ -50,7 +50,7 @@ function FrameRateMonitor(options) { /** * Gets or sets the length of time to wait at startup and each time the page becomes visible (i.e. when the user * switches back to the tab) before starting to measure performance, in seconds. - * @type {Number} + * @type {number} */ this.quietPeriod = defaultValue( options.quietPeriod, @@ -60,7 +60,7 @@ function FrameRateMonitor(options) { /** * Gets or sets the length of the warmup period, in seconds. During the warmup period, a separate * (usually lower) frame rate is required. - * @type {Number} + * @type {number} */ this.warmupPeriod = defaultValue( options.warmupPeriod, @@ -71,7 +71,7 @@ function FrameRateMonitor(options) { * Gets or sets the minimum frames-per-second that are required for acceptable performance during * the warmup period. If the frame rate averages less than this during any <code>samplingWindow</code> during the <code>warmupPeriod</code>, the * <code>lowFrameRate</code> event will be raised and the page will redirect to the <code>redirectOnLowFrameRateUrl</code>, if any. - * @type {Number} + * @type {number} */ this.minimumFrameRateDuringWarmup = defaultValue( options.minimumFrameRateDuringWarmup, @@ -82,7 +82,7 @@ function FrameRateMonitor(options) { * Gets or sets the minimum frames-per-second that are required for acceptable performance after * the end of the warmup period. If the frame rate averages less than this during any <code>samplingWindow</code> after the <code>warmupPeriod</code>, the * <code>lowFrameRate</code> event will be raised and the page will redirect to the <code>redirectOnLowFrameRateUrl</code>, if any. - * @type {Number} + * @type {number} */ this.minimumFrameRateAfterWarmup = defaultValue( options.minimumFrameRateAfterWarmup, @@ -157,7 +157,7 @@ function FrameRateMonitor(options) { * {@link FrameRateMonitor} constructor. * * @memberof FrameRateMonitor - * @type {Object} + * @type {object} */ FrameRateMonitor.defaultSettings = { samplingWindow: 5.0, @@ -235,7 +235,7 @@ Object.defineProperties(FrameRateMonitor.prototype, { * Gets the most recently computed average frames-per-second over the last <code>samplingWindow</code>. * This property may be undefined if the frame rate has not been computed. * @memberof FrameRateMonitor.prototype - * @type {Number} + * @type {number} */ lastFramesPerSecond: { get: function () { @@ -279,7 +279,7 @@ FrameRateMonitor.prototype.unpause = function () { * * @memberof FrameRateMonitor * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see FrameRateMonitor#destroy */ diff --git a/packages/engine/Source/Scene/FrameState.js b/packages/engine/Source/Scene/FrameState.js index 4e6a6a0af10..14b50cefe1d 100644 --- a/packages/engine/Source/Scene/FrameState.js +++ b/packages/engine/Source/Scene/FrameState.js @@ -60,7 +60,7 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * The maximum level-of-detail of the specular environment atlas used for image-based lighting for PBR models. - * @type {Number} + * @type {number} */ this.specularEnvironmentMapsMaximumLOD = undefined; @@ -76,14 +76,14 @@ function FrameState(context, creditDisplay, jobScheduler) { * The current morph transition time between 2D/Columbus View and 3D, * with 0.0 being 2D or Columbus View and 1.0 being 3D. * - * @type {Number} + * @type {number} */ this.morphTime = SceneMode.getMorphTime(SceneMode.SCENE3D); /** * The current frame number. * - * @type {Number} + * @type {number} * @default 0 */ this.frameNumber = 0; @@ -91,7 +91,7 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * <code>true</code> if a new frame has been issued and the frame number has been updated. * - * @type {Boolean} + * @type {boolean} * @default false */ this.newFrame = false; @@ -130,7 +130,7 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * Whether the camera is underground. * - * @type {Boolean} + * @type {boolean} * @default false */ this.cameraUnderground = false; @@ -163,7 +163,7 @@ function FrameState(context, creditDisplay, jobScheduler) { * The maximum screen-space error used to drive level-of-detail refinement. Higher * values will provide better performance but lower visual quality. * - * @type {Number} + * @type {number} * @default 2 */ this.maximumScreenSpaceError = undefined; @@ -172,19 +172,19 @@ function FrameState(context, creditDisplay, jobScheduler) { * Ratio between a pixel and a density-independent pixel. Provides a standard unit of * measure for real pixel measurements appropriate to a particular device. * - * @type {Number} + * @type {number} * @default 1.0 */ this.pixelRatio = 1.0; /** * @typedef FrameState.Passes - * @type {Object} - * @property {Boolean} render <code>true</code> if the primitive should update for a render pass, <code>false</code> otherwise. - * @property {Boolean} pick <code>true</code> if the primitive should update for a picking pass, <code>false</code> otherwise. - * @property {Boolean} depth <code>true</code> if the primitive should update for a depth only pass, <code>false</code> otherwise. - * @property {Boolean} postProcess <code>true</code> if the primitive should update for a per-feature post-process pass, <code>false</code> otherwise. - * @property {Boolean} offscreen <code>true</code> if the primitive should update for an offscreen pass, <code>false</code> otherwise. + * @type {object} + * @property {boolean} render <code>true</code> if the primitive should update for a render pass, <code>false</code> otherwise. + * @property {boolean} pick <code>true</code> if the primitive should update for a picking pass, <code>false</code> otherwise. + * @property {boolean} depth <code>true</code> if the primitive should update for a depth only pass, <code>false</code> otherwise. + * @property {boolean} postProcess <code>true</code> if the primitive should update for a per-feature post-process pass, <code>false</code> otherwise. + * @property {boolean} offscreen <code>true</code> if the primitive should update for an offscreen pass, <code>false</code> otherwise. */ /** @@ -246,18 +246,18 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * Gets whether or not to optimize for 3D only. * - * @type {Boolean} + * @type {boolean} * @default false */ this.scene3DOnly = false; /** * @typedef FrameState.Fog - * @type {Object} - * @property {Boolean} enabled <code>true</code> if fog is enabled, <code>false</code> otherwise. - * @property {Number} density A positive number used to mix the color and fog color based on camera distance. - * @property {Number} sse A scalar used to modify the screen space error of geometry partially in fog. - * @property {Number} minimumBrightness The minimum brightness of terrain with fog applied. + * @type {object} + * @property {boolean} enabled <code>true</code> if fog is enabled, <code>false</code> otherwise. + * @property {number} density A positive number used to mix the color and fog color based on camera distance. + * @property {number} sse A scalar used to modify the screen space error of geometry partially in fog. + * @property {number} minimumBrightness The minimum brightness of terrain with fog applied. */ /** @@ -276,30 +276,30 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * A scalar used to exaggerate the terrain. - * @type {Number} + * @type {number} * @default 1.0 */ this.terrainExaggeration = 1.0; /** * The height relative to which terrain is exaggerated. - * @type {Number} + * @type {number} * @default 0.0 */ this.terrainExaggerationRelativeHeight = 0.0; /** * @typedef FrameState.ShadowState - * @type {Object} - * @property {Boolean} shadowsEnabled Whether there are any active shadow maps this frame. - * @property {Boolean} lightShadowsEnabled Whether there are any active shadow maps that originate from light sources. Does not include shadow maps that are used for analytical purposes. + * @type {object} + * @property {boolean} shadowsEnabled Whether there are any active shadow maps this frame. + * @property {boolean} lightShadowsEnabled Whether there are any active shadow maps that originate from light sources. Does not include shadow maps that are used for analytical purposes. * @property {ShadowMap[]} shadowMaps All shadow maps that are enabled this frame. * @property {ShadowMap[]} lightShadowMaps Shadow maps that originate from light sources. Does not include shadow maps that are used for analytical purposes. Only these shadow maps will be used to generate receive shadows shaders. - * @property {Number} nearPlane The near plane of the scene's frustum commands. Used for fitting cascaded shadow maps. - * @property {Number} farPlane The far plane of the scene's frustum commands. Used for fitting cascaded shadow maps. - * @property {Number} closestObjectSize The size of the bounding volume that is closest to the camera. This is used to place more shadow detail near the object. - * @property {Number} lastDirtyTime The time when a shadow map was last dirty - * @property {Boolean} outOfView Whether the shadows maps are out of view this frame + * @property {number} nearPlane The near plane of the scene's frustum commands. Used for fitting cascaded shadow maps. + * @property {number} farPlane The far plane of the scene's frustum commands. Used for fitting cascaded shadow maps. + * @property {number} closestObjectSize The size of the bounding volume that is closest to the camera. This is used to place more shadow detail near the object. + * @property {number} lastDirtyTime The time when a shadow map was last dirty + * @property {boolean} outOfView Whether the shadows maps are out of view this frame */ /** @@ -338,14 +338,14 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * The position of the splitter to use when rendering different things on either side of a splitter. * This value should be between 0.0 and 1.0 with 0 being the far left of the viewport and 1 being the far right of the viewport. - * @type {Number} + * @type {number} * @default 0.0 */ this.splitPosition = 0.0; /** * Distances to the near and far planes of the camera frustums - * @type {Number[]} + * @type {number[]} * @default [] */ this.frustumSplits = []; @@ -368,14 +368,14 @@ function FrameState(context, creditDisplay, jobScheduler) { * The distance from the camera at which to disable the depth test of billboards, labels and points * to, for example, prevent clipping against terrain. When set to zero, the depth test should always * be applied. When less than zero, the depth test should never be applied. - * @type {Number} + * @type {number} */ this.minimumDisableDepthTestDistance = undefined; /** * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and * unclassified 3D Tile geometry will render with the color multiplied with {@link FrameState#invertClassificationColor}. - * @type {Boolean} + * @type {boolean} * @default false */ this.invertClassification = false; @@ -389,7 +389,7 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * Whether or not the scene uses a logarithmic depth buffer. * - * @type {Boolean} + * @type {boolean} * @default false */ this.useLogDepth = false; @@ -404,7 +404,7 @@ function FrameState(context, creditDisplay, jobScheduler) { /** * The minimum terrain height out of all rendered terrain tiles. Used to improve culling for objects underneath the ellipsoid but above terrain. * - * @type {Number} + * @type {number} * @default 0.0 */ this.minimumTerrainHeight = 0.0; @@ -414,6 +414,6 @@ function FrameState(context, creditDisplay, jobScheduler) { * A function that will be called at the end of the frame. * * @callback FrameState.AfterRenderCallback - * @returns {Boolean} true if another render should be requested in request render mode + * @returns {boolean} true if another render should be requested in request render mode */ export default FrameState; diff --git a/packages/engine/Source/Scene/FrustumCommands.js b/packages/engine/Source/Scene/FrustumCommands.js index 783e468de0a..1e374378e22 100644 --- a/packages/engine/Source/Scene/FrustumCommands.js +++ b/packages/engine/Source/Scene/FrustumCommands.js @@ -6,8 +6,8 @@ import Pass from "../Renderer/Pass.js"; * @alias FrustumCommands * @constructor * - * @param {Number} [near=0.0] The lower bound or closest distance from the camera. - * @param {Number} [far=0.0] The upper bound or farthest distance from the camera. + * @param {number} [near=0.0] The lower bound or closest distance from the camera. + * @param {number} [far=0.0] The upper bound or farthest distance from the camera. * * @private */ diff --git a/packages/engine/Source/Scene/GetFeatureInfoFormat.js b/packages/engine/Source/Scene/GetFeatureInfoFormat.js index a390d16f490..6150c25d6cd 100644 --- a/packages/engine/Source/Scene/GetFeatureInfoFormat.js +++ b/packages/engine/Source/Scene/GetFeatureInfoFormat.js @@ -10,9 +10,9 @@ import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js"; * @alias GetFeatureInfoFormat * @constructor * - * @param {String} type The type of response to expect from a GetFeatureInfo request. Valid + * @param {string} type The type of response to expect from a GetFeatureInfo request. Valid * values are 'json', 'xml', 'html', or 'text'. - * @param {String} [format] The info format to request from the WMS server. This is usually a + * @param {string} [format] The info format to request from the WMS server. This is usually a * MIME type such as 'application/json' or text/xml'. If this parameter is not specified, the provider will request 'json' * using 'application/json', 'xml' using 'text/xml', 'html' using 'text/html', and 'text' using 'text/plain'. * @param {Function} [callback] A function to invoke with the GetFeatureInfo response from the WMS server diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index d8f91aae061..66d1767b17f 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -78,7 +78,7 @@ function Globe(ellipsoid) { /** * Determines if the globe will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = true; @@ -92,7 +92,7 @@ function Globe(ellipsoid) { * The maximum screen-space error used to drive level-of-detail refinement. Higher * values will provide better performance but lower visual quality. * - * @type {Number} + * @type {number} * @default 2 */ this.maximumScreenSpaceError = 2; @@ -103,7 +103,7 @@ function Globe(ellipsoid) { * this frame. A larger number will consume more memory but will show detail faster * when, for example, zooming out and then back in. * - * @type {Number} + * @type {number} * @default 100 */ this.tileCacheSize = 100; @@ -116,7 +116,7 @@ function Globe(ellipsoid) { * tile level to be loaded successively, significantly increasing load time. Setting it to a large * number (e.g. 1000) will minimize the number of tiles that are loaded but tend to make * detail appear all at once after a long wait. - * @type {Number} + * @type {number} * @default 20 */ this.loadingDescendantLimit = 20; @@ -125,7 +125,7 @@ function Globe(ellipsoid) { * Gets or sets a value indicating whether the ancestors of rendered tiles should be preloaded. * Setting this to true optimizes the zoom-out experience and provides more detail in * newly-exposed areas when panning. The down side is that it requires loading more tiles. - * @type {Boolean} + * @type {boolean} * @default true */ this.preloadAncestors = true; @@ -135,7 +135,7 @@ function Globe(ellipsoid) { * Setting this to true causes tiles with the same parent as a rendered tile to be loaded, even * if they are culled. Setting this to true may provide a better panning experience at the * cost of loading more tiles. - * @type {Boolean} + * @type {boolean} * @default false */ this.preloadSiblings = false; @@ -153,7 +153,7 @@ function Globe(ellipsoid) { /** * Enable lighting the globe with the scene's light source. * - * @type {Boolean} + * @type {boolean} * @default false */ this.enableLighting = false; @@ -163,7 +163,7 @@ function Globe(ellipsoid) { * This number is multiplied by the result of <code>czm_getLambertDiffuse</code> in GlobeFS.glsl. * This only takes effect when <code>enableLighting</code> is <code>true</code>. * - * @type {Number} + * @type {number} * @default 0.9 */ this.lambertDiffuseMultiplier = 0.9; @@ -172,7 +172,7 @@ function Globe(ellipsoid) { * Enable dynamic lighting effects on atmosphere and fog. This only takes effect * when <code>enableLighting</code> is <code>true</code>. * - * @type {Boolean} + * @type {boolean} * @default true */ this.dynamicAtmosphereLighting = true; @@ -182,7 +182,7 @@ function Globe(ellipsoid) { * light direction. This only takes effect when <code>enableLighting</code> and * <code>dynamicAtmosphereLighting</code> are <code>true</code>. * - * @type {Boolean} + * @type {boolean} * @default false */ this.dynamicAtmosphereLightingFromSun = false; @@ -190,7 +190,7 @@ function Globe(ellipsoid) { /** * Enable the ground atmosphere, which is drawn over the globe when viewed from a distance between <code>lightingFadeInDistance</code> and <code>lightingFadeOutDistance</code>. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showGroundAtmosphere = true; @@ -198,7 +198,7 @@ function Globe(ellipsoid) { /** * The intensity of the light that is used for computing the ground atmosphere color. * - * @type {Number} + * @type {number} * @default 10.0 */ this.atmosphereLightIntensity = 10.0; @@ -222,7 +222,7 @@ function Globe(ellipsoid) { /** * The Rayleigh scale height used in the atmospheric scattering equations for the ground atmosphere, in meters. * - * @type {Number} + * @type {number} * @default 10000.0 */ this.atmosphereRayleighScaleHeight = 10000.0; @@ -230,7 +230,7 @@ function Globe(ellipsoid) { /** * The Mie scale height used in the atmospheric scattering equations for the ground atmosphere, in meters. * - * @type {Number} + * @type {number} * @default 3200.0 */ this.atmosphereMieScaleHeight = 3200.0; @@ -240,7 +240,7 @@ function Globe(ellipsoid) { * <p> * Valid values are between -1.0 and 1.0. * </p> - * @type {Number} + * @type {number} * @default 0.9 */ this.atmosphereMieAnisotropy = 0.9; @@ -249,7 +249,7 @@ function Globe(ellipsoid) { * The distance where everything becomes lit. This only takes effect * when <code>enableLighting</code> or <code>showGroundAtmosphere</code> is <code>true</code>. * - * @type {Number} + * @type {number} * @default 10000000.0 */ this.lightingFadeOutDistance = 1.0e7; @@ -258,7 +258,7 @@ function Globe(ellipsoid) { * The distance where lighting resumes. This only takes effect * when <code>enableLighting</code> or <code>showGroundAtmosphere</code> is <code>true</code>. * - * @type {Number} + * @type {number} * @default 20000000.0 */ this.lightingFadeInDistance = 2.0e7; @@ -268,7 +268,7 @@ function Globe(ellipsoid) { * This only takes effect when <code>showGroundAtmosphere</code>, <code>enableLighting</code>, and * <code>dynamicAtmosphereLighting</code> are <code>true</code>. * - * @type {Number} + * @type {number} * @default 10000000.0 */ this.nightFadeOutDistance = 1.0e7; @@ -278,7 +278,7 @@ function Globe(ellipsoid) { * This only takes effect when <code>showGroundAtmosphere</code>, <code>enableLighting</code>, and * <code>dynamicAtmosphereLighting</code> are <code>true</code>. * - * @type {Number} + * @type {number} * @default 50000000.0 */ this.nightFadeInDistance = 5.0e7; @@ -288,7 +288,7 @@ function Globe(ellipsoid) { * covered by water; otherwise, false. This property is ignored if the * <code>terrainProvider</code> does not provide a water mask. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showWaterEffect = true; @@ -300,7 +300,7 @@ function Globe(ellipsoid) { * testing primitives against terrain is that slight numerical noise or terrain level-of-detail * switched can sometimes make a primitive that should be on the surface disappear underneath it. * - * @type {Boolean} + * @type {boolean} * @default false * */ @@ -319,7 +319,7 @@ function Globe(ellipsoid) { /** * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A hue shift of 1.0 indicates a complete rotation of the hues available. - * @type {Number} + * @type {number} * @default 0.0 */ this.atmosphereHueShift = 0.0; @@ -327,7 +327,7 @@ function Globe(ellipsoid) { /** * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A saturation shift of -1.0 is monochrome. - * @type {Number} + * @type {number} * @default 0.0 */ this.atmosphereSaturationShift = 0.0; @@ -335,7 +335,7 @@ function Globe(ellipsoid) { /** * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A brightness shift of -1.0 is complete darkness, which will let space show through. - * @type {Number} + * @type {number} * @default 0.0 */ this.atmosphereBrightnessShift = 0.0; @@ -345,7 +345,7 @@ function Globe(ellipsoid) { * A value of <code>2.0</code> scales the terrain by 2x. * A value of <code>0.0</code> makes the terrain completely flat. * Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. - * @type {Number} + * @type {number} * @default 1.0 */ this.terrainExaggeration = 1.0; @@ -355,7 +355,7 @@ function Globe(ellipsoid) { * Terrain that is above this height will scale upwards and terrain that is below this height will scale downwards. * Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. * If {@link Globe#terrainExaggeration} is <code>1.0</code> this value will have no effect. - * @type {Number} + * @type {number} * @default 0.0 */ this.terrainExaggerationRelativeHeight = 0.0; @@ -364,7 +364,7 @@ function Globe(ellipsoid) { * Whether to show terrain skirts. Terrain skirts are geometry extending downwards from a tile's edges used to hide seams between neighboring tiles. * Skirts are always hidden when the camera is underground or translucency is enabled. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showSkirts = true; @@ -372,7 +372,7 @@ function Globe(ellipsoid) { /** * Whether to cull back-facing terrain. Back faces are not culled when the camera is underground or translucency is enabled. * - * @type {Boolean} + * @type {boolean} * @default true */ this.backFaceCulling = true; @@ -384,7 +384,7 @@ function Globe(ellipsoid) { * Determines the darkness of the vertex shadow. * This only takes effect when <code>enableLighting</code> is <code>true</code>. * - * @type {Number} + * @type {number} * @default 0.3 */ this.vertexShadowDarkness = 0.3; @@ -427,7 +427,7 @@ Object.defineProperties(Globe.prototype, { * Returns <code>true</code> when the tile load queue is empty, <code>false</code> otherwise. When the load queue is empty, * all terrain and imagery for the current view have been loaded. * @memberof Globe.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ tilesLoaded: { @@ -493,7 +493,7 @@ Object.defineProperties(Globe.prototype, { * The normal map to use for rendering waves in the ocean. Setting this property will * only have an effect if the configured terrain provider includes a water mask. * @memberof Globe.prototype - * @type {String} + * @type {string} * @default buildModuleUrl('Assets/Textures/waterNormalsSmall.jpg') */ oceanNormalMapUrl: { @@ -699,7 +699,7 @@ const scratchSphereIntersectionResult = { * * @param {Ray} ray The ray to test for intersection. * @param {Scene} scene The scene. - * @param {Boolean} [cullBackFaces=true] Set to true to not pick back faces. + * @param {boolean} [cullBackFaces=true] Set to true to not pick back faces. * @param {Cartesian3} [result] The object onto which to store the result. * @returns {Cartesian3|undefined} The intersection or <code>undefined</code> if none was found. The returned position is in projected coordinates for 2D and Columbus View. * @@ -837,7 +837,7 @@ function tileIfContainsCartographic(tile, cartographic) { * Get the height of the surface at a given cartographic. * * @param {Cartographic} cartographic The cartographic for which to find the height. - * @returns {Number|undefined} The height of the cartographic or undefined if it could not be found. + * @returns {number|undefined} The height of the cartographic or undefined if it could not be found. */ Globe.prototype.getHeight = function (cartographic) { //>>includeStart('debug', pragmas.debug); @@ -1097,7 +1097,7 @@ Globe.prototype.endFrame = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see Globe#destroy */ diff --git a/packages/engine/Source/Scene/GlobeSurfaceTile.js b/packages/engine/Source/Scene/GlobeSurfaceTile.js index 0798fa1845f..409b44f82f5 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTile.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTile.js @@ -79,7 +79,7 @@ Object.defineProperties(GlobeSurfaceTile.prototype, { * unloaded while it is needed for rendering, regardless of the value of this * property. * @memberof GlobeSurfaceTile.prototype - * @type {Boolean} + * @type {boolean} */ eligibleForUnloading: { get: function () { diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 7a6ba4ec1a3..13f27f3ea9f 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -232,7 +232,7 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof GlobeSurfaceTileProvider.prototype - * @type {Boolean} + * @type {boolean} */ ready: { get: function () { @@ -565,8 +565,8 @@ GlobeSurfaceTileProvider.prototype.cancelReprojections = function () { * Gets the maximum geometric error allowed in a tile at a given level, in meters. This function should not be * called before {@link GlobeSurfaceTileProvider#ready} returns true. * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error in meters. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error in meters. */ GlobeSurfaceTileProvider.prototype.getLevelMaximumGeometricError = function ( level @@ -993,7 +993,7 @@ const tileDirectionScratch = new Cartesian3(); * Determines the priority for loading this tile. Lower priority values load sooner. * @param {QuadtreeTile} tile The tile. * @param {FrameState} frameState The frame state. - * @returns {Number} The load priority value. + * @returns {number} The load priority value. */ GlobeSurfaceTileProvider.prototype.computeTileLoadPriority = function ( tile, @@ -1142,7 +1142,7 @@ function computeOccludeePoint( * @param {QuadtreeTile} tile The tile instance. * @param {FrameState} frameState The state information of the current rendering frame. * - * @returns {Number} The distance from the camera to the closest point on the tile, in meters. + * @returns {number} The distance from the camera to the closest point on the tile, in meters. */ GlobeSurfaceTileProvider.prototype.computeDistanceToTile = function ( tile, @@ -1357,7 +1357,7 @@ function updateTileBoundingRegion(tile, tileProvider, frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see GlobeSurfaceTileProvider#destroy */ diff --git a/packages/engine/Source/Scene/GlobeTranslucency.js b/packages/engine/Source/Scene/GlobeTranslucency.js index 85a6db5bcbb..d81eca65182 100644 --- a/packages/engine/Source/Scene/GlobeTranslucency.js +++ b/packages/engine/Source/Scene/GlobeTranslucency.js @@ -34,7 +34,7 @@ Object.defineProperties(GlobeTranslucency.prototype, { * * @memberof GlobeTranslucency.prototype * - * @type {Boolean} + * @type {boolean} * @default false * * @see GlobeTranslucency#frontFaceAlpha @@ -61,7 +61,7 @@ Object.defineProperties(GlobeTranslucency.prototype, { * * @memberof GlobeTranslucency.prototype * - * @type {Number} + * @type {number} * @default 1.0 * * @see GlobeTranslucency#enabled @@ -141,7 +141,7 @@ Object.defineProperties(GlobeTranslucency.prototype, { * * @memberof GlobeTranslucency.prototype * - * @type {Number} + * @type {number} * @default 1.0 * * @see GlobeTranslucency#enabled diff --git a/packages/engine/Source/Scene/GltfBufferViewLoader.js b/packages/engine/Source/Scene/GltfBufferViewLoader.js index e43b2ace1b8..fcdb3894ecb 100644 --- a/packages/engine/Source/Scene/GltfBufferViewLoader.js +++ b/packages/engine/Source/Scene/GltfBufferViewLoader.js @@ -16,13 +16,13 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.bufferViewId The buffer view ID. + * @param {object} options.gltf The glTF JSON. + * @param {number} options.bufferViewId The buffer view ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {string} [options.cacheKey] The cache key of the resource. * * @private */ @@ -101,7 +101,7 @@ Object.defineProperties(GltfBufferViewLoader.prototype, { * * @memberof GltfBufferViewLoader.prototype * - * @type {Promise.<GltfBufferViewLoader>|undefined} + * @type {Promise<GltfBufferViewLoader>|undefined} * @readonly * @private */ @@ -115,7 +115,7 @@ Object.defineProperties(GltfBufferViewLoader.prototype, { * * @memberof GltfBufferViewLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -142,7 +142,7 @@ Object.defineProperties(GltfBufferViewLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfBufferViewLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfBufferViewLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfBufferViewLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfDracoLoader.js b/packages/engine/Source/Scene/GltfDracoLoader.js index 49481b13af0..289ab897d88 100644 --- a/packages/engine/Source/Scene/GltfDracoLoader.js +++ b/packages/engine/Source/Scene/GltfDracoLoader.js @@ -15,13 +15,13 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.draco The Draco extension object. + * @param {object} options.gltf The glTF JSON. + * @param {object} options.draco The Draco extension object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {string} [options.cacheKey] The cache key of the resource. * * @private */ @@ -68,7 +68,7 @@ Object.defineProperties(GltfDracoLoader.prototype, { * * @memberof GltfDracoLoader.prototype * - * @type {Promise.<GltfDracoLoader>} + * @type {Promise<GltfDracoLoader>} * @readonly * @private */ @@ -82,7 +82,7 @@ Object.defineProperties(GltfDracoLoader.prototype, { * * @memberof GltfDracoLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -96,7 +96,7 @@ Object.defineProperties(GltfDracoLoader.prototype, { * * @memberof GltfDracoLoader.prototype * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -109,7 +109,7 @@ Object.defineProperties(GltfDracoLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfDracoLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfImageLoader.js b/packages/engine/Source/Scene/GltfImageLoader.js index 53e42898325..fe9e946fae6 100644 --- a/packages/engine/Source/Scene/GltfImageLoader.js +++ b/packages/engine/Source/Scene/GltfImageLoader.js @@ -17,13 +17,13 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.imageId The image ID. + * @param {object} options.gltf The glTF JSON. + * @param {number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {string} [options.cacheKey] The cache key of the resource. * * @private */ @@ -73,7 +73,7 @@ Object.defineProperties(GltfImageLoader.prototype, { * * @memberof GltfImageLoader.prototype * - * @type {Promise.<GltfImageLoader>|undefined} + * @type {Promise<GltfImageLoader>|undefined} * @readonly * @private */ @@ -87,7 +87,7 @@ Object.defineProperties(GltfImageLoader.prototype, { * * @memberof GltfImageLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -128,7 +128,7 @@ Object.defineProperties(GltfImageLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfImageLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfImageLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfImageLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfIndexBufferLoader.js b/packages/engine/Source/Scene/GltfIndexBufferLoader.js index b5006e4cbef..1bcad69367a 100644 --- a/packages/engine/Source/Scene/GltfIndexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfIndexBufferLoader.js @@ -21,17 +21,17 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.accessorId The accessor ID corresponding to the index buffer. + * @param {object} options.gltf The glTF JSON. + * @param {number} options.accessorId The accessor ID corresponding to the index buffer. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {Object} [options.draco] The Draco extension object. - * @param {String} [options.cacheKey] The cache key of the resource. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.loadBuffer=false] Load the index buffer as a GPU index buffer. - * @param {Boolean} [options.loadTypedArray=false] Load the index buffer as a typed array. + * @param {object} [options.draco] The Draco extension object. + * @param {string} [options.cacheKey] The cache key of the resource. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.loadBuffer=false] Load the index buffer as a GPU index buffer. + * @param {boolean} [options.loadTypedArray=false] Load the index buffer as a typed array. * @private */ function GltfIndexBufferLoader(options) { @@ -93,7 +93,7 @@ Object.defineProperties(GltfIndexBufferLoader.prototype, { * * @memberof GltfIndexBufferLoader.prototype * - * @type {Promise.<GltfIndexBufferLoader>|undefined} + * @type {Promise<GltfIndexBufferLoader>|undefined} * @readonly * @private */ @@ -107,7 +107,7 @@ Object.defineProperties(GltfIndexBufferLoader.prototype, { * * @memberof GltfIndexBufferLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -165,7 +165,7 @@ const scratchIndexBufferJob = new CreateIndexBufferJob(); /** * Loads the resource. - * @returns {Promise.<GltfIndexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfIndexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfIndexBufferLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfJsonLoader.js b/packages/engine/Source/Scene/GltfJsonLoader.js index fdf7acb60ef..35a73a1f30b 100644 --- a/packages/engine/Source/Scene/GltfJsonLoader.js +++ b/packages/engine/Source/Scene/GltfJsonLoader.js @@ -25,13 +25,13 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {Uint8Array} [options.typedArray] The typed array containing the glTF contents. - * @param {Object} [options.gltfJson] The parsed glTF JSON contents. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {object} [options.gltfJson] The parsed glTF JSON contents. + * @param {string} [options.cacheKey] The cache key of the resource. * * @private */ @@ -73,7 +73,7 @@ Object.defineProperties(GltfJsonLoader.prototype, { * * @memberof GltfJsonLoader.prototype * - * @type {Promise.<GltfJsonLoader>|undefined} + * @type {Promise<GltfJsonLoader>|undefined} * @readonly * @private */ @@ -87,7 +87,7 @@ Object.defineProperties(GltfJsonLoader.prototype, { * * @memberof GltfJsonLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -101,7 +101,7 @@ Object.defineProperties(GltfJsonLoader.prototype, { * * @memberof GltfJsonLoader.prototype * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -114,7 +114,7 @@ Object.defineProperties(GltfJsonLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfJsonLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfJsonLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfJsonLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index 20655d764f4..4aaba7c27c1 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -59,7 +59,7 @@ const Material = ModelComponents.Material; * States of the glTF loading process. These states also apply to * asynchronous texture loading unless otherwise noted * - * @enum {Number} + * @enum {number} * * @private */ @@ -67,7 +67,7 @@ const GltfLoaderState = { /** * The initial state of the glTF loader before load() is called. * - * @type {Number} + * @type {number} * @constant * * @private @@ -77,7 +77,7 @@ const GltfLoaderState = { * The state of the loader while waiting for the glTF JSON loader promise * to resolve. * - * @type {Number} + * @type {number} * @constant * * @private @@ -87,7 +87,7 @@ const GltfLoaderState = { * The state of the loader once the glTF JSON is loaded but before * process() is called. * - * @type {Number} + * @type {number} * @constant */ LOADED: 2, @@ -95,7 +95,7 @@ const GltfLoaderState = { * The state of the loader while parsing the glTF and creating GPU resources * as needed. * - * @type {Number} + * @type {number} * @constant */ PROCESSING: 3, @@ -107,7 +107,7 @@ const GltfLoaderState = { * This state is not used for asynchronous texture loading. * </p> * - * @type {Number} + * @type {number} * @constant */ POST_PROCESSING: 4, @@ -116,7 +116,7 @@ const GltfLoaderState = { * enters the processed state (sometimes from a promise chain). The next * call to process() will advance to the ready state. * - * @type {Number} + * @type {number} * @constant */ PROCESSED: 5, @@ -124,21 +124,21 @@ const GltfLoaderState = { * When the loader reaches the ready state, the loaders' promise will be * resolved. * - * @type {Number} + * @type {number} * @constant */ READY: 6, /** * If an error occurs at any point, the loader switches to the failed state. * - * @type {Number} + * @type {number} * @constant */ FAILED: 7, /** * If unload() is called, the loader switches to the unloaded state. * - * @type {Number} + * @type {number} * @constant */ UNLOADED: 8, @@ -154,22 +154,22 @@ const GltfLoaderState = { * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. This is often the path of the .gltf or .glb file, but may also be the path of the .b3dm, .i3dm, or .cmpt file containing the embedded glb. .cmpt resources should have a URI fragment indicating the index of the inner content to which the glb belongs in order to individually identify the glb in the cache, e.g. http://example.com/tile.cmpt#index=2. * @param {Resource} [options.baseResource] The {@link Resource} that paths in the glTF JSON are relative to. * @param {Uint8Array} [options.typedArray] The typed array containing the glTF contents, e.g. from a .b3dm, .i3dm, or .cmpt file. - * @param {Object} [options.gltfJson] A parsed glTF JSON file instead of passing it in as a typed array. - * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. + * @param {object} [options.gltfJson] A parsed glTF JSON file instead of passing it in as a typed array. + * @param {boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. * @param {Axis} [options.forwardAxis=Axis.Z] The forward-axis of the glTF model. - * @param {Boolean} [options.loadAttributesAsTypedArray=false] Load all attributes and indices as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. - * @param {Boolean} [options.loadAttributesFor2D=false] If <code>true</code>, load the positions buffer and any instanced attribute buffers as typed arrays for accurately projecting models to 2D. - * @param {Boolean} [options.loadIndicesForWireframe=false] If <code>true</code>, load the index buffer as both a buffer and typed array. The latter is useful for creating wireframe indices in WebGL1. - * @param {Boolean} [options.loadPrimitiveOutline=true] If <code>true</code>, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. - * @param {Boolean} [options.loadForClassification=false] If <code>true</code> and if the model has feature IDs, load the feature IDs and indices as typed arrays. This is useful for batching features for classification. - * @param {Boolean} [options.renameBatchIdSemantic=false] If <code>true</code>, rename _BATCHID or BATCHID to _FEATURE_ID_0. This is used for .b3dm models + * @param {boolean} [options.loadAttributesAsTypedArray=false] Load all attributes and indices as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. + * @param {boolean} [options.loadAttributesFor2D=false] If <code>true</code>, load the positions buffer and any instanced attribute buffers as typed arrays for accurately projecting models to 2D. + * @param {boolean} [options.loadIndicesForWireframe=false] If <code>true</code>, load the index buffer as both a buffer and typed array. The latter is useful for creating wireframe indices in WebGL1. + * @param {boolean} [options.loadPrimitiveOutline=true] If <code>true</code>, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. + * @param {boolean} [options.loadForClassification=false] If <code>true</code> and if the model has feature IDs, load the feature IDs and indices as typed arrays. This is useful for batching features for classification. + * @param {boolean} [options.renameBatchIdSemantic=false] If <code>true</code>, rename _BATCHID or BATCHID to _FEATURE_ID_0. This is used for .b3dm models * @private */ function GltfLoader(options) { @@ -279,7 +279,7 @@ Object.defineProperties(GltfLoader.prototype, { * * @memberof GltfLoader.prototype * - * @type {Promise.<GltfLoader>|undefined} + * @type {Promise<GltfLoader>|undefined} * @readonly * @private */ @@ -293,7 +293,7 @@ Object.defineProperties(GltfLoader.prototype, { * * @memberof GltfLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -337,7 +337,7 @@ Object.defineProperties(GltfLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfLoaderUtil.js b/packages/engine/Source/Scene/GltfLoaderUtil.js index f07e398b758..1457ac6cd1a 100644 --- a/packages/engine/Source/Scene/GltfLoaderUtil.js +++ b/packages/engine/Source/Scene/GltfLoaderUtil.js @@ -25,12 +25,12 @@ const GltfLoaderUtil = {}; * WebP images the WebP image ID is returned. * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.textureId The texture ID. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.textureId The texture ID. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * - * @returns {Number} The image ID. + * @returns {number} The image ID. * @private */ GltfLoaderUtil.getImageIdFromTexture = function (options) { @@ -63,10 +63,10 @@ GltfLoaderUtil.getImageIdFromTexture = function (options) { /** * Create a sampler for a texture. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.textureInfo The texture info object. - * @param {Boolean} [options.compressedTextureNoMipmap=false] True when the texture is compressed and does not have an embedded mipmap. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {object} options.textureInfo The texture info object. + * @param {boolean} [options.compressedTextureNoMipmap=false] True when the texture is compressed and does not have an embedded mipmap. * * @returns {Sampler} The sampler. * @private @@ -137,9 +137,9 @@ const defaultScale = new Cartesian2(1.0, 1.0); /** * Create a model texture reader. * - * @param {Object} options Object with the following properties: - * @param {Object} options.textureInfo The texture info JSON. - * @param {String} [options.channels] The texture channels to read from. + * @param {object} options Object with the following properties: + * @param {object} options.textureInfo The texture info JSON. + * @param {string} [options.channels] The texture channels to read from. * @param {Texture} [options.texture] The texture object. * * @returns {ModelComponents.TextureReader} The texture reader for this model. diff --git a/packages/engine/Source/Scene/GltfPipeline/addBuffer.js b/packages/engine/Source/Scene/GltfPipeline/addBuffer.js index 291bdc0d1c0..b06b5a26705 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addBuffer.js +++ b/packages/engine/Source/Scene/GltfPipeline/addBuffer.js @@ -3,9 +3,9 @@ import addToArray from "./addToArray.js"; /** * Adds buffer to gltf. * - * @param {Object} gltf A javascript object containing a glTF asset. + * @param {object} gltf A javascript object containing a glTF asset. * @param {Buffer} buffer A Buffer object which will be added to gltf.buffers. - * @returns {Number} The bufferView id of the newly added bufferView. + * @returns {number} The bufferView id of the newly added bufferView. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/addDefaults.js b/packages/engine/Source/Scene/GltfPipeline/addDefaults.js index ab35038adfc..d67b10fd98b 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addDefaults.js +++ b/packages/engine/Source/Scene/GltfPipeline/addDefaults.js @@ -8,8 +8,8 @@ import WebGLConstants from "../../Core/WebGLConstants.js"; /** * Adds default glTF values if they don't exist. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The modified glTF. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} The modified glTF. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/addExtensionsRequired.js b/packages/engine/Source/Scene/GltfPipeline/addExtensionsRequired.js index c6b82ec7828..210de9cc9d9 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addExtensionsRequired.js +++ b/packages/engine/Source/Scene/GltfPipeline/addExtensionsRequired.js @@ -6,8 +6,8 @@ import defined from "../../Core/defined.js"; * Adds an extension to gltf.extensionsRequired if it does not already exist. * Initializes extensionsRequired if it is not defined. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The extension to add. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/addExtensionsUsed.js b/packages/engine/Source/Scene/GltfPipeline/addExtensionsUsed.js index 109065d6d5b..4975ed248bd 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addExtensionsUsed.js +++ b/packages/engine/Source/Scene/GltfPipeline/addExtensionsUsed.js @@ -5,8 +5,8 @@ import defined from "../../Core/defined.js"; * Adds an extension to gltf.extensionsUsed if it does not already exist. * Initializes extensionsUsed if it is not defined. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The extension to add. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/addPipelineExtras.js b/packages/engine/Source/Scene/GltfPipeline/addPipelineExtras.js index b4a81bb67ce..24242a8739b 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addPipelineExtras.js +++ b/packages/engine/Source/Scene/GltfPipeline/addPipelineExtras.js @@ -5,8 +5,8 @@ import defined from "../../Core/defined.js"; * Adds extras._pipeline to each object that can have extras in the glTF asset. * This stage runs before updateVersion and handles both glTF 1.0 and glTF 2.0 assets. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The glTF asset with the added pipeline extras. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} The glTF asset with the added pipeline extras. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/addToArray.js b/packages/engine/Source/Scene/GltfPipeline/addToArray.js index 35a105e92ca..a9d025a21d8 100644 --- a/packages/engine/Source/Scene/GltfPipeline/addToArray.js +++ b/packages/engine/Source/Scene/GltfPipeline/addToArray.js @@ -4,8 +4,8 @@ import defaultValue from "../../Core/defaultValue.js"; * Adds an element to an array and returns the element's index. * * @param {Array} array The array to add to. - * @param {Object} element The element to add. - * @param {Boolean} [checkDuplicates=false] When <code>true</code>, if a duplicate element is found its index is returned and <code>element</code> is not added to the array. + * @param {object} element The element to add. + * @param {boolean} [checkDuplicates=false] When <code>true</code>, if a duplicate element is found its index is returned and <code>element</code> is not added to the array. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/findAccessorMinMax.js b/packages/engine/Source/Scene/GltfPipeline/findAccessorMinMax.js index 54c602a47a7..0a276f4981b 100644 --- a/packages/engine/Source/Scene/GltfPipeline/findAccessorMinMax.js +++ b/packages/engine/Source/Scene/GltfPipeline/findAccessorMinMax.js @@ -7,8 +7,8 @@ import defined from "../../Core/defined.js"; /** * Finds the min and max values of the accessor. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor object from the glTF asset to read. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {object} accessor The accessor object from the glTF asset to read. * @returns {{min: Array, max: Array}} min holding the array of minimum values and max holding the array of maximum values. * * @private diff --git a/packages/engine/Source/Scene/GltfPipeline/forEachTextureInMaterial.js b/packages/engine/Source/Scene/GltfPipeline/forEachTextureInMaterial.js index bd168e7f284..047d4883de1 100644 --- a/packages/engine/Source/Scene/GltfPipeline/forEachTextureInMaterial.js +++ b/packages/engine/Source/Scene/GltfPipeline/forEachTextureInMaterial.js @@ -5,7 +5,7 @@ import defined from "../../Core/defined.js"; /** * Calls the provider handler function on each texture used by the material. * Mimics the behavior of functions in gltf-pipeline ForEach. - * @param {Object} material The glTF material. + * @param {object} material The glTF material. * @param {forEachTextureInMaterial~handler} handler Function that is called for each texture in the material. * * @private @@ -130,8 +130,8 @@ function forEachTextureInMaterial(material, handler) { /** * Function that is called for each texture in the material. If this function returns a value the for each stops and returns that value. * @callback forEachTextureInMaterial~handler - * @param {Number} The texture index. - * @param {Object} The texture info object. + * @param {number} The texture index. + * @param {object} The texture info object. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/getAccessorByteStride.js b/packages/engine/Source/Scene/GltfPipeline/getAccessorByteStride.js index d537bad96e6..f7239c93f6d 100644 --- a/packages/engine/Source/Scene/GltfPipeline/getAccessorByteStride.js +++ b/packages/engine/Source/Scene/GltfPipeline/getAccessorByteStride.js @@ -6,9 +6,9 @@ import defined from "../../Core/defined.js"; * Returns the byte stride of the provided accessor. * If the byteStride is 0, it is calculated based on type and componentType * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor. - * @returns {Number} The byte stride of the accessor. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {object} accessor The accessor. + * @returns {number} The byte stride of the accessor. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/getComponentReader.js b/packages/engine/Source/Scene/GltfPipeline/getComponentReader.js index 36253ea256e..5e44abfc086 100644 --- a/packages/engine/Source/Scene/GltfPipeline/getComponentReader.js +++ b/packages/engine/Source/Scene/GltfPipeline/getComponentReader.js @@ -3,7 +3,7 @@ import ComponentDatatype from "../../Core/ComponentDatatype.js"; /** * Returns a function to read and convert data from a DataView into an array. * - * @param {Number} componentType Type to convert the data to. + * @param {number} componentType Type to convert the data to. * @returns {ComponentReader} Function that reads and converts data. * * @private @@ -136,10 +136,10 @@ function getComponentReader(componentType) { * @callback ComponentReader * * @param {DataView} dataView The data view to read from. - * @param {Number} byteOffset The byte offset applied when reading from the data view. - * @param {Number} numberOfComponents The number of components to read. - * @param {Number} componentTypeByteLength The byte length of each component. - * @param {Number} result An array storing the components that are read. + * @param {number} byteOffset The byte offset applied when reading from the data view. + * @param {number} numberOfComponents The number of components to read. + * @param {number} componentTypeByteLength The byte length of each component. + * @param {number} result An array storing the components that are read. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/moveTechniqueRenderStates.js b/packages/engine/Source/Scene/GltfPipeline/moveTechniqueRenderStates.js index 882b5e1e205..9d2aa3b59bb 100644 --- a/packages/engine/Source/Scene/GltfPipeline/moveTechniqueRenderStates.js +++ b/packages/engine/Source/Scene/GltfPipeline/moveTechniqueRenderStates.js @@ -53,8 +53,8 @@ function getSupportedBlendFactors(value, defaultValue) { /** * Move glTF 1.0 technique render states to glTF 2.0 materials properties and KHR_blend extension. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The updated glTF asset. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} The updated glTF asset. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/moveTechniquesToExtension.js b/packages/engine/Source/Scene/GltfPipeline/moveTechniquesToExtension.js index 2c4a661907a..98c7a2938da 100644 --- a/packages/engine/Source/Scene/GltfPipeline/moveTechniquesToExtension.js +++ b/packages/engine/Source/Scene/GltfPipeline/moveTechniquesToExtension.js @@ -7,8 +7,8 @@ import defined from "../../Core/defined.js"; /** * Move glTF 1.0 material techniques to glTF 2.0 KHR_techniques_webgl extension. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The updated glTF asset. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} The updated glTF asset. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/numberOfComponentsForType.js b/packages/engine/Source/Scene/GltfPipeline/numberOfComponentsForType.js index 9a413a44d45..ef573b2918f 100644 --- a/packages/engine/Source/Scene/GltfPipeline/numberOfComponentsForType.js +++ b/packages/engine/Source/Scene/GltfPipeline/numberOfComponentsForType.js @@ -3,8 +3,8 @@ /** * Utility function for retrieving the number of components in a given type. * - * @param {String} type glTF type - * @returns {Number} The number of components in that type. + * @param {string} type glTF type + * @returns {number} The number of components in that type. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/parseGlb.js b/packages/engine/Source/Scene/GltfPipeline/parseGlb.js index 5c918e9f689..3ada028bc7d 100644 --- a/packages/engine/Source/Scene/GltfPipeline/parseGlb.js +++ b/packages/engine/Source/Scene/GltfPipeline/parseGlb.js @@ -14,7 +14,7 @@ const sizeOfUint32 = 4; * The returned glTF has pipeline extras included. The embedded binary data is stored in gltf.buffers[0].extras._pipeline.source. * * @param {Buffer} glb The glb data to parse. - * @returns {Object} A javascript object containing a glTF asset with pipeline extras included. + * @returns {object} A javascript object containing a glTF asset with pipeline extras included. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/readAccessorPacked.js b/packages/engine/Source/Scene/GltfPipeline/readAccessorPacked.js index be3aadd01f9..60b06b6ce13 100644 --- a/packages/engine/Source/Scene/GltfPipeline/readAccessorPacked.js +++ b/packages/engine/Source/Scene/GltfPipeline/readAccessorPacked.js @@ -7,8 +7,8 @@ import defined from "../../Core/defined.js"; /** * Returns the accessor data in a contiguous array. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {object} accessor The accessor. * @returns {Array} The accessor values in a contiguous array. * * @private diff --git a/packages/engine/Source/Scene/GltfPipeline/removeExtension.js b/packages/engine/Source/Scene/GltfPipeline/removeExtension.js index 49e0e1dda94..6622ea6ab13 100644 --- a/packages/engine/Source/Scene/GltfPipeline/removeExtension.js +++ b/packages/engine/Source/Scene/GltfPipeline/removeExtension.js @@ -5,8 +5,8 @@ import defined from "../../Core/defined.js"; /** * Removes an extension from gltf.extensions, gltf.extensionsUsed, gltf.extensionsRequired, and any other objects in the glTF if it is present. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The extension to remove. * * @returns {*} The extension data removed from gltf.extensions. */ diff --git a/packages/engine/Source/Scene/GltfPipeline/removeExtensionsRequired.js b/packages/engine/Source/Scene/GltfPipeline/removeExtensionsRequired.js index eac77f5e92a..6ca44926bad 100644 --- a/packages/engine/Source/Scene/GltfPipeline/removeExtensionsRequired.js +++ b/packages/engine/Source/Scene/GltfPipeline/removeExtensionsRequired.js @@ -3,8 +3,8 @@ import defined from "../../Core/defined.js"; /** * Removes an extension from gltf.extensionsRequired if it is present. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The extension to remove. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/removeExtensionsUsed.js b/packages/engine/Source/Scene/GltfPipeline/removeExtensionsUsed.js index 6bf41cf6a4e..dff9cf8985a 100644 --- a/packages/engine/Source/Scene/GltfPipeline/removeExtensionsUsed.js +++ b/packages/engine/Source/Scene/GltfPipeline/removeExtensionsUsed.js @@ -4,8 +4,8 @@ import defined from "../../Core/defined.js"; /** * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The extension to remove. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/removePipelineExtras.js b/packages/engine/Source/Scene/GltfPipeline/removePipelineExtras.js index 3dece5d8f70..e9162c6f517 100644 --- a/packages/engine/Source/Scene/GltfPipeline/removePipelineExtras.js +++ b/packages/engine/Source/Scene/GltfPipeline/removePipelineExtras.js @@ -4,8 +4,8 @@ import defined from "../../Core/defined.js"; /** * Iterate through the objects within the glTF and delete their pipeline extras object. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} glTF with no pipeline extras. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} glTF with no pipeline extras. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/removeUnusedElements.js b/packages/engine/Source/Scene/GltfPipeline/removeUnusedElements.js index 212e1c0d189..0ab354988a4 100644 --- a/packages/engine/Source/Scene/GltfPipeline/removeUnusedElements.js +++ b/packages/engine/Source/Scene/GltfPipeline/removeUnusedElements.js @@ -19,8 +19,8 @@ const allElementTypes = [ /** * Removes unused elements from gltf. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/updateAccessorComponentTypes.js b/packages/engine/Source/Scene/GltfPipeline/updateAccessorComponentTypes.js index 936a82e6386..1de3059dfd0 100644 --- a/packages/engine/Source/Scene/GltfPipeline/updateAccessorComponentTypes.js +++ b/packages/engine/Source/Scene/GltfPipeline/updateAccessorComponentTypes.js @@ -7,8 +7,8 @@ import WebGLConstants from "../../Core/WebGLConstants.js"; /** * Update accessors referenced by JOINTS_0 and WEIGHTS_0 attributes to use correct component types. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The glTF asset with compressed meshes. + * @param {object} gltf A javascript object containing a glTF asset. + * @returns {object} The glTF asset with compressed meshes. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/updateVersion.js b/packages/engine/Source/Scene/GltfPipeline/updateVersion.js index 9171bcffdd7..0eb8c0c1826 100644 --- a/packages/engine/Source/Scene/GltfPipeline/updateVersion.js +++ b/packages/engine/Source/Scene/GltfPipeline/updateVersion.js @@ -30,10 +30,10 @@ const updateFunctions = { * Applies changes made to the glTF spec between revisions so that the core library * only has to handle the latest version. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} [options] Options for updating the glTF. - * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version. - * @returns {Object} The updated glTF asset. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {object} [options] Options for updating the glTF. + * @param {string} [options.targetVersion] The glTF will be upgraded until it hits the specified version. + * @returns {object} The updated glTF asset. * * @private */ diff --git a/packages/engine/Source/Scene/GltfPipeline/usesExtension.js b/packages/engine/Source/Scene/GltfPipeline/usesExtension.js index 3fb17a4b678..10815912a82 100644 --- a/packages/engine/Source/Scene/GltfPipeline/usesExtension.js +++ b/packages/engine/Source/Scene/GltfPipeline/usesExtension.js @@ -3,9 +3,9 @@ import defined from "../../Core/defined.js"; /** * Checks whether the glTF uses the given extension. * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The name of the extension. - * @returns {Boolean} Whether the glTF uses the given extension. + * @param {object} gltf A javascript object containing a glTF asset. + * @param {string} extension The name of the extension. + * @returns {boolean} Whether the glTF uses the given extension. * * @private */ diff --git a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js index 032bcdf3f77..4af60922736 100644 --- a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js +++ b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js @@ -18,16 +18,16 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {String} [options.extension] The <code>EXT_structural_metadata</code> extension object. If this is undefined, then extensionLegacy must be defined. - * @param {String} [options.extensionLegacy] The legacy <code>EXT_feature_metadata</code> extension for backwards compatibility. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {string} [options.extension] The <code>EXT_structural_metadata</code> extension object. If this is undefined, then extensionLegacy must be defined. + * @param {string} [options.extensionLegacy] The legacy <code>EXT_feature_metadata</code> extension for backwards compatibility. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * @param {FrameState} options.frameState The frame state. - * @param {String} [options.cacheKey] The cache key of the resource. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {string} [options.cacheKey] The cache key of the resource. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -88,7 +88,7 @@ Object.defineProperties(GltfStructuralMetadataLoader.prototype, { * * @memberof GltfStructuralMetadataLoader.prototype * - * @type {Promise.<GltfStructuralMetadataLoader>|undefined} + * @type {Promise<GltfStructuralMetadataLoader>|undefined} * @readonly * @private */ @@ -102,7 +102,7 @@ Object.defineProperties(GltfStructuralMetadataLoader.prototype, { * * @memberof GltfStructuralMetadataLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -129,7 +129,7 @@ Object.defineProperties(GltfStructuralMetadataLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GltfStructuralMetadataLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfStructuralMetadataLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfStructuralMetadataLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfTextureLoader.js b/packages/engine/Source/Scene/GltfTextureLoader.js index 4c6139914c9..e99d0d21a9f 100644 --- a/packages/engine/Source/Scene/GltfTextureLoader.js +++ b/packages/engine/Source/Scene/GltfTextureLoader.js @@ -22,15 +22,15 @@ import resizeImageToNextPowerOfTwo from "../Core/resizeImageToNextPowerOfTwo.js" * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.textureInfo The texture info object. + * @param {object} options.gltf The glTF JSON. + * @param {object} options.textureInfo The texture info object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. - * @param {String} [options.cacheKey] The cache key of the resource. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {string} [options.cacheKey] The cache key of the resource. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * * @private */ @@ -92,7 +92,7 @@ Object.defineProperties(GltfTextureLoader.prototype, { * * @memberof GltfTextureLoader.prototype * - * @type {Promise.<GltfTextureLoader>|undefined} + * @type {Promise<GltfTextureLoader>|undefined} * @readonly * @private */ @@ -106,7 +106,7 @@ Object.defineProperties(GltfTextureLoader.prototype, { * * @memberof GltfTextureLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -135,7 +135,7 @@ const scratchTextureJob = new CreateTextureJob(); /** * Loads the resource. - * @returns {Promise.<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfTextureLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GltfVertexBufferLoader.js b/packages/engine/Source/Scene/GltfVertexBufferLoader.js index 425d3bad123..debd8fa50ae 100644 --- a/packages/engine/Source/Scene/GltfVertexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfVertexBufferLoader.js @@ -20,19 +20,19 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies). - * @param {Object} options.gltf The glTF JSON. + * @param {object} options.gltf The glTF JSON. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {Number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. - * @param {Object} [options.draco] The Draco extension object. - * @param {String} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. - * @param {Number} [options.accessorId] The accessor id. - * @param {String} [options.cacheKey] The cache key of the resource. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. - * @param {Boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. + * @param {number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. + * @param {object} [options.draco] The Draco extension object. + * @param {string} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. + * @param {number} [options.accessorId] The accessor id. + * @param {string} [options.cacheKey] The cache key of the resource. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. + * @param {boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. * * @exception {DeveloperError} One of options.bufferViewId and options.draco must be defined. * @exception {DeveloperError} When options.draco is defined options.attributeSemantic must also be defined. @@ -129,7 +129,7 @@ Object.defineProperties(GltfVertexBufferLoader.prototype, { * * @memberof GltfVertexBufferLoader.prototype * - * @type {Promise.<GltfVertexBufferLoader>|undefined} + * @type {Promise<GltfVertexBufferLoader>|undefined} * @readonly * @private */ @@ -143,7 +143,7 @@ Object.defineProperties(GltfVertexBufferLoader.prototype, { * * @memberof GltfVertexBufferLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -206,7 +206,7 @@ function hasDracoCompression(draco, semantic) { /** * Loads the resource. - * @returns {Promise.<GltfVertexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GltfVertexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GltfVertexBufferLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index 556b12bbbde..7f8ba0e311b 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -24,7 +24,7 @@ function GoogleEarthEnterpriseDiscardPolicy() { /** * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {boolean} True if the discard policy is ready to process images; otherwise, false. */ GoogleEarthEnterpriseDiscardPolicy.prototype.isReady = function () { return true; @@ -34,7 +34,7 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.isReady = function () { * Given a tile image, decide whether to discard that image. * * @param {HTMLImageElement} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {boolean} True if the image should be discarded; otherwise, false. */ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( image @@ -43,17 +43,17 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( }; /** - * @typedef {Object} GoogleEarthEnterpriseImageryProvider.ConstructorOptions + * @typedef {object} GoogleEarthEnterpriseImageryProvider.ConstructorOptions * * Initialization options for the GoogleEarthEnterpriseImageryProvider constructor * - * @property {Resource|String} url The url of the Google Earth Enterprise server hosting the imagery. + * @property {Resource|string} url The url of the Google Earth Enterprise server hosting the imagery. * @property {GoogleEarthEnterpriseMetadata} metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. If this value is not specified, a default * is to discard tiles that fail to download. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. */ /** @@ -99,7 +99,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -108,7 +108,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -117,7 +117,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -126,7 +126,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -135,7 +135,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -143,7 +143,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -152,7 +152,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -160,7 +160,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -265,7 +265,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** * Gets the name of the Google Earth Enterprise server url hosting the imagery. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -290,7 +290,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -311,7 +311,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -332,7 +332,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -353,7 +353,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -452,7 +452,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -464,7 +464,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -493,7 +493,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage * and texture upload time. * @memberof GoogleEarthEnterpriseImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -506,9 +506,9 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -542,11 +542,11 @@ GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function ( * Requests the image for a given tile. This function should * not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -631,11 +631,11 @@ GoogleEarthEnterpriseImageryProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ GoogleEarthEnterpriseImageryProvider.prototype.pickFeatures = function ( diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js index 7e500951581..ea93868135d 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js @@ -14,12 +14,12 @@ import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js"; import ImageryProvider from "./ImageryProvider.js"; /** - * @typedef {Object} GoogleEarthEnterpriseMapsProvider.ConstructorOptions + * @typedef {object} GoogleEarthEnterpriseMapsProvider.ConstructorOptions * * Initialization options for the GoogleEarthEnterpriseMapsProvider constructor * - * @property {Resource|String} url The url of the Google Earth server hosting the imagery. - * @property {Number} channel The channel (id) to be used when requesting data from the server. + * @property {Resource|string} url The url of the Google Earth server hosting the imagery. + * @property {number} channel The channel (id) to be used when requesting data from the server. * The channel number can be found by looking at the json file located at: * earth.localdomain/default_map/query?request=Json&vars=geeServerDefs The /default_map path may * differ depending on your Google Earth Enterprise server configuration. Look for the "id" that @@ -37,8 +37,8 @@ import ImageryProvider from "./ImageryProvider.js"; * } * ] * } - * @property {String} [path="/default_map"] The path of the Google Earth server hosting the imagery. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the Google Earth + * @property {string} [path="/default_map"] The path of the Google Earth server hosting the imagery. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the Google Earth * Enterprise server, or undefined if there is no limit. * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile * is invalid and should be discarded. To ensure that no tiles are discarded, construct and pass @@ -104,7 +104,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -113,7 +113,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -122,7 +122,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -131,7 +131,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -140,7 +140,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -148,7 +148,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -157,7 +157,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -165,7 +165,7 @@ function GoogleEarthEnterpriseMapsProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default 1.9 */ this.defaultGamma = 1.9; @@ -342,7 +342,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets the URL of the Google Earth MapServer. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -354,7 +354,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets the url path of the data on the Google Earth server. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} + * @type {string} * @readonly */ path: { @@ -378,7 +378,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets the imagery channel (id) currently being used. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} + * @type {number} * @readonly */ channel: { @@ -391,7 +391,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -412,7 +412,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -433,7 +433,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -454,7 +454,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -496,7 +496,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the version of the data used by this provider. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Number} + * @type {number} * @readonly */ version: { @@ -517,7 +517,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * Gets the type of data that is being requested from the provider. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {String} + * @type {string} * @readonly */ requestType: { @@ -594,7 +594,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -606,7 +606,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -635,7 +635,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof GoogleEarthEnterpriseMapsProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -648,9 +648,9 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -667,11 +667,11 @@ GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function ( * Requests the image for a given tile. This function should * not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -710,11 +710,11 @@ GoogleEarthEnterpriseMapsProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ GoogleEarthEnterpriseMapsProvider.prototype.pickFeatures = function ( @@ -733,7 +733,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider, { /** * Gets or sets the URL to the Google Earth logo for display in the credit. * @memberof GoogleEarthEnterpriseMapsProvider - * @type {String} + * @type {string} */ logoUrl: { get: function () { diff --git a/packages/engine/Source/Scene/GridImageryProvider.js b/packages/engine/Source/Scene/GridImageryProvider.js index ba0470f5019..6126d547b6e 100644 --- a/packages/engine/Source/Scene/GridImageryProvider.js +++ b/packages/engine/Source/Scene/GridImageryProvider.js @@ -9,7 +9,7 @@ const defaultGlowColor = new Color(0.0, 1.0, 0.0, 0.05); const defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2); /** - * @typedef {Object} GridImageryProvider.ConstructorOptions + * @typedef {object} GridImageryProvider.ConstructorOptions * * Initialization options for the GridImageryProvider constructor * @@ -17,14 +17,14 @@ const defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2); * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @property {Number} [cells=8] The number of grids cells. + * @property {number} [cells=8] The number of grids cells. * @property {Color} [color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines. * @property {Color} [glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines. - * @property {Number} [glowWidth=6] The width of lines used for rendering the line glow effect. + * @property {number} [glowWidth=6] The width of lines used for rendering the line glow effect. * @property {Color} [backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color. - * @property {Number} [tileWidth=256] The width of the tile for level-of-detail selection purposes. - * @property {Number} [tileHeight=256] The height of the tile for level-of-detail selection purposes. - * @property {Number} [canvasSize=256] The size of the canvas used for rendering. + * @property {number} [tileWidth=256] The width of the tile for level-of-detail selection purposes. + * @property {number} [tileHeight=256] The height of the tile for level-of-detail selection purposes. + * @property {number} [canvasSize=256] The size of the canvas used for rendering. */ /** @@ -43,7 +43,7 @@ function GridImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -52,7 +52,7 @@ function GridImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -61,7 +61,7 @@ function GridImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -70,7 +70,7 @@ function GridImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -79,7 +79,7 @@ function GridImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -87,7 +87,7 @@ function GridImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -96,7 +96,7 @@ function GridImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -104,7 +104,7 @@ function GridImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -168,7 +168,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link GridImageryProvider#ready} returns true. * @memberof GridImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -181,7 +181,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link GridImageryProvider#ready} returns true. * @memberof GridImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -194,7 +194,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link GridImageryProvider#ready} returns true. * @memberof GridImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -207,7 +207,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link GridImageryProvider#ready} returns true. * @memberof GridImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -274,7 +274,7 @@ Object.defineProperties(GridImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof GridImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -286,7 +286,7 @@ Object.defineProperties(GridImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof GridImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -315,7 +315,7 @@ Object.defineProperties(GridImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof GridImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -388,9 +388,9 @@ GridImageryProvider.prototype._createGridCanvas = function () { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -403,11 +403,11 @@ GridImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link GridImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<HTMLCanvasElement>} The resolved image as a Canvas DOM object. + * @returns {Promise<HTMLCanvasElement>} The resolved image as a Canvas DOM object. */ GridImageryProvider.prototype.requestImage = function (x, y, level, request) { return Promise.resolve(this._canvas); @@ -417,11 +417,11 @@ GridImageryProvider.prototype.requestImage = function (x, y, level, request) { * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ GridImageryProvider.prototype.pickFeatures = function ( diff --git a/packages/engine/Source/Scene/GroundPolylinePrimitive.js b/packages/engine/Source/Scene/GroundPolylinePrimitive.js index c33e6166617..77afcbe5b62 100644 --- a/packages/engine/Source/Scene/GroundPolylinePrimitive.js +++ b/packages/engine/Source/Scene/GroundPolylinePrimitive.js @@ -36,17 +36,17 @@ import StencilOperation from "./StencilOperation.js"; * @alias GroundPolylinePrimitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Array|GeometryInstance} [options.geometryInstances] GeometryInstances containing GroundPolylineGeometry * @param {Appearance} [options.appearance] The Appearance used to render the polyline. Defaults to a white color {@link Material} on a {@link PolylineMaterialAppearance}. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on creation to have effect. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on creation to have effect. * * @example * // 1. Draw a polyline on terrain with a basic color material @@ -132,7 +132,7 @@ function GroundPolylinePrimitive(options) { * Determines if the primitive will be shown. This affects all geometry * instances in the primitive. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -156,7 +156,7 @@ function GroundPolylinePrimitive(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -238,7 +238,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -254,7 +254,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -270,7 +270,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -286,7 +286,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -304,7 +304,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -316,7 +316,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { /** * Gets a promise that resolves when the primitive is ready to render. * @memberof GroundPolylinePrimitive.prototype - * @type {Promise.<GroundPolylinePrimitive>} + * @type {Promise<GroundPolylinePrimitive>} * @readonly */ readyPromise: { @@ -333,7 +333,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * * @memberof GroundPolylinePrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -847,7 +847,7 @@ GroundPolylinePrimitive.prototype.update = function (frameState) { * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * * @param {*} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * @returns {object} The typed array in the attribute's format or undefined if the is no instance with id. * * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. * @@ -874,7 +874,7 @@ GroundPolylinePrimitive.prototype.getGeometryInstanceAttributes = function ( * GroundPolylinePrimitives require support for the WEBGL_depth_texture extension. * * @param {Scene} scene The current scene. - * @returns {Boolean} Whether or not the current scene supports GroundPolylinePrimitives. + * @returns {boolean} Whether or not the current scene supports GroundPolylinePrimitives. */ GroundPolylinePrimitive.isSupported = function (scene) { return scene.frameState.context.depthTexture; @@ -887,7 +887,7 @@ GroundPolylinePrimitive.isSupported = function (scene) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see GroundPolylinePrimitive#destroy */ diff --git a/packages/engine/Source/Scene/GroundPrimitive.js b/packages/engine/Source/Scene/GroundPrimitive.js index 61446947227..861bd2b4435 100644 --- a/packages/engine/Source/Scene/GroundPrimitive.js +++ b/packages/engine/Source/Scene/GroundPrimitive.js @@ -50,19 +50,19 @@ const GroundPrimitiveUniformMap = { * @alias GroundPrimitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. * @param {Appearance} [options.appearance] The appearance used to render the primitive. Defaults to a flat PerInstanceColorAppearance when GeometryInstances have a color attribute. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be <code>true</code> on * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be <code>false</code>. * * @example @@ -161,7 +161,7 @@ function GroundPrimitive(options) { * Determines if the primitive will be shown. This affects all geometry * instances in the primitive. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -183,7 +183,7 @@ function GroundPrimitive(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -198,7 +198,7 @@ function GroundPrimitive(options) { * Draws the shadow volume for each geometry in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -276,7 +276,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -292,7 +292,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -308,7 +308,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -324,7 +324,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -340,7 +340,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -356,7 +356,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -374,7 +374,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @memberof GroundPrimitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -386,7 +386,7 @@ Object.defineProperties(GroundPrimitive.prototype, { /** * Gets a promise that resolves when the primitive is ready to render. * @memberof GroundPrimitive.prototype - * @type {Promise.<GroundPrimitive>} + * @type {Promise<GroundPrimitive>} * @readonly */ readyPromise: { @@ -401,7 +401,7 @@ Object.defineProperties(GroundPrimitive.prototype, { * * @function * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if GroundPrimitives are supported; otherwise, returns <code>false</code> + * @returns {boolean} <code>true</code> if GroundPrimitives are supported; otherwise, returns <code>false</code> */ GroundPrimitive.isSupported = ClassificationPrimitive.isSupported; @@ -956,7 +956,7 @@ GroundPrimitive.prototype.getBoundingSphere = function (id) { * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * * @param {*} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * @returns {object} The typed array in the attribute's format or undefined if the is no instance with id. * * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. * @@ -983,7 +983,7 @@ GroundPrimitive.prototype.getGeometryInstanceAttributes = function (id) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see GroundPrimitive#destroy */ @@ -1016,7 +1016,7 @@ GroundPrimitive.prototype.destroy = function () { * Exposed for testing. * * @param {Context} context Rendering context - * @returns {Boolean} Whether or not the current context supports materials on GroundPrimitives. + * @returns {boolean} Whether or not the current context supports materials on GroundPrimitives. * @private */ GroundPrimitive._supportsMaterials = function (context) { @@ -1028,7 +1028,7 @@ GroundPrimitive._supportsMaterials = function (context) { * Materials on GroundPrimitives require support for the WEBGL_depth_texture extension. * * @param {Scene} scene The current scene. - * @returns {Boolean} Whether or not the current scene supports materials on GroundPrimitives. + * @returns {boolean} Whether or not the current scene supports materials on GroundPrimitives. */ GroundPrimitive.supportsMaterials = function (scene) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/GroupMetadata.js b/packages/engine/Source/Scene/GroupMetadata.js index d910e919dda..54d8896a2e6 100644 --- a/packages/engine/Source/Scene/GroupMetadata.js +++ b/packages/engine/Source/Scene/GroupMetadata.js @@ -9,9 +9,9 @@ import MetadataEntity from "./MetadataEntity.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the group. - * @param {Object} options.group The group JSON object. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the group. + * @param {object} options.group The group JSON object. * @param {MetadataClass} options.class The class that group metadata conforms to. * * @alias GroupMetadata @@ -58,7 +58,7 @@ Object.defineProperties(GroupMetadata.prototype, { * The ID of the group. * * @memberof GroupMetadata.prototype - * @type {String} + * @type {string} * @readonly * @private */ @@ -86,7 +86,7 @@ Object.defineProperties(GroupMetadata.prototype, { * An object containing extensions. * * @memberof GroupMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -100,8 +100,8 @@ Object.defineProperties(GroupMetadata.prototype, { /** * Returns whether the group has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the group has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the group has this property. * @private */ GroupMetadata.prototype.hasProperty = function (propertyId) { @@ -111,8 +111,8 @@ GroupMetadata.prototype.hasProperty = function (propertyId) { /** * Returns whether the group has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the group has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the group has a property with the given semantic. * @private */ GroupMetadata.prototype.hasPropertyBySemantic = function (semantic) { @@ -126,8 +126,8 @@ GroupMetadata.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ GroupMetadata.prototype.getPropertyIds = function (results) { @@ -140,7 +140,7 @@ GroupMetadata.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the group does not have this property. * @private */ @@ -154,9 +154,9 @@ GroupMetadata.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ GroupMetadata.prototype.setProperty = function (propertyId, value) { @@ -171,7 +171,7 @@ GroupMetadata.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the group does not have this semantic. * @private */ @@ -186,9 +186,9 @@ GroupMetadata.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ GroupMetadata.prototype.setPropertyBySemantic = function (semantic, value) { diff --git a/packages/engine/Source/Scene/HeightReference.js b/packages/engine/Source/Scene/HeightReference.js index 45169f0c806..809fe4c0494 100644 --- a/packages/engine/Source/Scene/HeightReference.js +++ b/packages/engine/Source/Scene/HeightReference.js @@ -1,26 +1,26 @@ /** * Represents the position relative to the terrain. * - * @enum {Number} + * @enum {number} */ const HeightReference = { /** * The position is absolute. - * @type {Number} + * @type {number} * @constant */ NONE: 0, /** * The position is clamped to the terrain. - * @type {Number} + * @type {number} * @constant */ CLAMP_TO_GROUND: 1, /** * The position height is the height above the terrain. - * @type {Number} + * @type {number} * @constant */ RELATIVE_TO_GROUND: 2, diff --git a/packages/engine/Source/Scene/HorizontalOrigin.js b/packages/engine/Source/Scene/HorizontalOrigin.js index 3f775792655..61eaeb34029 100644 --- a/packages/engine/Source/Scene/HorizontalOrigin.js +++ b/packages/engine/Source/Scene/HorizontalOrigin.js @@ -8,7 +8,7 @@ * <img src='Images/Billboard.setHorizontalOrigin.png' width='648' height='196' /><br /> * </div> * - * @enum {Number} + * @enum {number} * * @see Billboard#horizontalOrigin * @see Label#horizontalOrigin @@ -17,7 +17,7 @@ const HorizontalOrigin = { /** * The origin is at the horizontal center of the object. * - * @type {Number} + * @type {number} * @constant */ CENTER: 0, @@ -25,7 +25,7 @@ const HorizontalOrigin = { /** * The origin is on the left side of the object. * - * @type {Number} + * @type {number} * @constant */ LEFT: 1, @@ -33,7 +33,7 @@ const HorizontalOrigin = { /** * The origin is on the right side of the object. * - * @type {Number} + * @type {number} * @constant */ RIGHT: -1, diff --git a/packages/engine/Source/Scene/I3SDataProvider.js b/packages/engine/Source/Scene/I3SDataProvider.js index ac0fe6cb36d..ea3cc327d41 100644 --- a/packages/engine/Source/Scene/I3SDataProvider.js +++ b/packages/engine/Source/Scene/I3SDataProvider.js @@ -70,13 +70,13 @@ import Rectangle from "../Core/Rectangle.js"; * @alias I3SDataProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|String} options.url The url of the I3S dataset. - * @param {String} [options.name] The name of the I3S dataset. - * @param {Boolean} [options.show=true] Determines if the dataset will be shown. + * @param {object} options Object with the following properties: + * @param {Resource|string} options.url The url of the I3S dataset. + * @param {string} [options.name] The name of the I3S dataset. + * @param {boolean} [options.show=true] Determines if the dataset will be shown. * @param {ArcGISTiledElevationTerrainProvider} [options.geoidTiledTerrainProvider] Tiled elevation provider describing an Earth Gravitational Model. If defined, geometry will be shifted based on the offsets given by this provider. Required to position I3S data sets with gravity-related height at the correct location. - * @param {Boolean} [options.traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. - * @param {Object} [options.cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. + * @param {boolean} [options.traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. + * @param {object} [options.cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. * * @example * const i3sData = new I3SDataProvider({ @@ -130,7 +130,7 @@ Object.defineProperties(I3SDataProvider.prototype, { /** * Gets a human-readable name for this dataset. * @memberof I3SDataProvider.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -142,7 +142,7 @@ Object.defineProperties(I3SDataProvider.prototype, { /** * Determines if the dataset will be shown. * @memberof I3SDataProvider.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -165,7 +165,7 @@ Object.defineProperties(I3SDataProvider.prototype, { /** * Gets or sets debugging and tracing of I3S fetches. * @memberof I3SDataProvider.prototype - * @type {Boolean} + * @type {boolean} */ traceFetches: { get: function () { @@ -215,7 +215,7 @@ Object.defineProperties(I3SDataProvider.prototype, { /** * Gets the I3S data for this object. * @memberof I3SDataProvider.prototype - * @type {Object} + * @type {object} * @readonly */ data: { @@ -255,7 +255,7 @@ Object.defineProperties(I3SDataProvider.prototype, { /** * Gets the promise that will be resolved when the I3S scene is loaded. * @memberof I3SDataProvider.prototype - * @type {Promise.<I3SDataProvider>} + * @type {Promise<I3SDataProvider>} * @readonly */ readyPromise: { @@ -268,7 +268,7 @@ Object.defineProperties(I3SDataProvider.prototype, { * When <code>true</code>, the I3S scene is loaded. * This is set to <code>true</code> right before {@link I3SDataProvider#readyPromise} is resolved. * @memberof I3SDataProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -320,7 +320,7 @@ I3SDataProvider.prototype.destroy = function () { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see I3SDataProvider#destroy */ diff --git a/packages/engine/Source/Scene/I3SFeature.js b/packages/engine/Source/Scene/I3SFeature.js index f2c5b9822a2..d911a75acaa 100644 --- a/packages/engine/Source/Scene/I3SFeature.js +++ b/packages/engine/Source/Scene/I3SFeature.js @@ -37,7 +37,7 @@ Object.defineProperties(I3SFeature.prototype, { /** * Gets the I3S data for this object. * @memberof I3SFeature.prototype - * @type {Object} + * @type {object} * @readonly */ data: { diff --git a/packages/engine/Source/Scene/I3SField.js b/packages/engine/Source/Scene/I3SField.js index 0123c73febc..381492a32e8 100644 --- a/packages/engine/Source/Scene/I3SField.js +++ b/packages/engine/Source/Scene/I3SField.js @@ -6,7 +6,7 @@ import defined from "../Core/defined.js"; * @alias I3SField * @internalConstructor * @privateParam {I3SNode} parent The parent of that geometry - * @privateParam {Object} storageInfo The structure containing the storage info of the field + * @privateParam {object} storageInfo The structure containing the storage info of the field */ function I3SField(parent, storageInfo) { this._storageInfo = storageInfo; @@ -38,7 +38,7 @@ Object.defineProperties(I3SField.prototype, { /** * Gets the header for this field. * @memberof I3SField.prototype - * @type {Object} + * @type {object} * @readonly */ header: { @@ -49,7 +49,7 @@ Object.defineProperties(I3SField.prototype, { /** * Gets the values for this field. * @memberof I3SField.prototype - * @type {Object} + * @type {object} * @readonly */ values: { @@ -62,7 +62,7 @@ Object.defineProperties(I3SField.prototype, { /** * Gets the name for the field. * @memberof I3SField.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -94,7 +94,7 @@ function getNumericTypeSize(type) { /** * Loads the content. - * @returns {Promise.<void>} A promise that is resolved when the field data is loaded + * @returns {Promise<void>} A promise that is resolved when the field data is loaded */ I3SField.prototype.load = function () { const that = this; diff --git a/packages/engine/Source/Scene/I3SGeometry.js b/packages/engine/Source/Scene/I3SGeometry.js index 7d97c5c46a6..406fe04ff48 100644 --- a/packages/engine/Source/Scene/I3SGeometry.js +++ b/packages/engine/Source/Scene/I3SGeometry.js @@ -11,7 +11,7 @@ import Matrix3 from "../Core/Matrix3.js"; * @alias I3SGeometry * @internalConstructor * @privateParam {I3SNode} parent The parent of that geometry - * @privateParam {String} uri The uri to load the data from + * @privateParam {string} uri The uri to load the data from */ function I3SGeometry(parent, uri) { const dataProvider = parent._dataProvider; @@ -51,7 +51,7 @@ Object.defineProperties(I3SGeometry.prototype, { /** * Gets the I3S data for this object. * @memberof I3SGeometry.prototype - * @type {Object} + * @type {object} * @readonly */ data: { @@ -62,7 +62,7 @@ Object.defineProperties(I3SGeometry.prototype, { /** * Gets the custom attributes of the geometry. * @memberof I3SGeometry.prototype - * @type {Object} + * @type {object} * @readonly */ customAttributes: { @@ -74,7 +74,7 @@ Object.defineProperties(I3SGeometry.prototype, { /** * Loads the content. - * @returns {Promise.<Object>} A promise that is resolved when the geometry data is loaded + * @returns {Promise<object>} A promise that is resolved when the geometry data is loaded * @private */ I3SGeometry.prototype.load = function () { @@ -121,10 +121,10 @@ const scratchV2p = new Cartesian3(); /** * Find a triangle touching the point [px, py, pz], then return the vertex closest to the search point - * @param {Number} px The x component of the point to query - * @param {Number} py The y component of the point to query - * @param {Number} pz The z component of the point to query - * @returns {Object} A structure containing the index of the closest point, + * @param {number} px The x component of the point to query + * @param {number} py The y component of the point to query + * @param {number} pz The z component of the point to query + * @returns {object} A structure containing the index of the closest point, * the squared distance from the queried point to the point that is found, * the distance from the queried point to the point that is found, * the queried position in local space, diff --git a/packages/engine/Source/Scene/I3SLayer.js b/packages/engine/Source/Scene/I3SLayer.js index e6b2f613125..a894236b8bf 100644 --- a/packages/engine/Source/Scene/I3SLayer.js +++ b/packages/engine/Source/Scene/I3SLayer.js @@ -12,8 +12,8 @@ import I3SNode from "./I3SNode.js"; * @alias I3SLayer * @internalConstructor * @privateParam {I3SDataProvider} dataProvider The i3s data provider - * @privateParam {Object} layerData The layer data that is loaded from the scene layer - * @privateParam {Number} index The index of the layer to be reflected + * @privateParam {object} layerData The layer data that is loaded from the scene layer + * @privateParam {number} index The index of the layer to be reflected */ function I3SLayer(dataProvider, layerData, index) { this._dataProvider = dataProvider; @@ -95,7 +95,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * Gets the I3S data for this object. * @memberof I3SLayer.prototype - * @type {Object} + * @type {object} * @readonly */ data: { @@ -107,7 +107,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * The version string of the loaded I3S dataset * @memberof I3SLayer.prototype - * @type {String} + * @type {string} * @readonly */ version: { @@ -119,7 +119,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * The major version number of the loaded I3S dataset * @memberof I3SLayer.prototype - * @type {Number} + * @type {number} * @readonly */ majorVersion: { @@ -131,7 +131,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * The minor version number of the loaded I3S dataset * @memberof I3SLayer.prototype - * @type {Number} + * @type {number} * @readonly */ minorVersion: { @@ -143,7 +143,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * When <code>true</code>, when the loaded I3S version is 1.6 or older * @memberof I3SLayer.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ legacyVersion16: { diff --git a/packages/engine/Source/Scene/I3SNode.js b/packages/engine/Source/Scene/I3SNode.js index 8b8536b9a8a..839b0517a68 100644 --- a/packages/engine/Source/Scene/I3SNode.js +++ b/packages/engine/Source/Scene/I3SNode.js @@ -157,7 +157,7 @@ Object.defineProperties(I3SNode.prototype, { /** * Gets the I3S data for this object. * @memberof I3SNode.prototype - * @type {Object} + * @type {object} * @readonly */ data: { @@ -217,7 +217,7 @@ I3SNode.prototype.load = function () { /** * Loads the node fields. - * @returns {Promise.<void>} A promise that is resolved when the I3S Node fields are loaded + * @returns {Promise<void>} A promise that is resolved when the I3S Node fields are loaded */ I3SNode.prototype.loadFields = function () { // Check if we must load fields @@ -243,7 +243,7 @@ I3SNode.prototype.loadFields = function () { /** * Returns the fields for a given picked position * @param {Cartesian3} pickedPosition The picked position - * @returns {Object} Object containing field names and their values + * @returns {object} Object containing field names and their values */ I3SNode.prototype.getFieldsForPickedPosition = function (pickedPosition) { const geometry = this.geometryData[0]; @@ -270,8 +270,8 @@ I3SNode.prototype.getFieldsForPickedPosition = function (pickedPosition) { /** * Returns the fields for a given feature - * @param {Number} featureIndex Index of the feature whose attributes we want to get - * @returns {Object} Object containing field names and their values + * @param {number} featureIndex Index of the feature whose attributes we want to get + * @returns {object} Object containing field names and their values */ I3SNode.prototype.getFieldsForFeature = function (featureIndex) { const featureFields = {}; @@ -848,7 +848,7 @@ Object.defineProperties(Cesium3DTile.prototype, { /** * Gets the I3S Node for the tile. * @memberof Cesium3DTile.prototype - * @type {String} + * @type {string} */ i3sNode: { get: function () { diff --git a/packages/engine/Source/Scene/I3dmParser.js b/packages/engine/Source/Scene/I3dmParser.js index 1ce4b993b19..90056bd425d 100644 --- a/packages/engine/Source/Scene/I3dmParser.js +++ b/packages/engine/Source/Scene/I3dmParser.js @@ -21,8 +21,8 @@ const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; * @private * * @param {ArrayBuffer} arrayBuffer The array buffer containing the i3dm. - * @param {Number} [byteOffset=0] The byte offset of the beginning of the i3dm in the array buffer. - * @returns {Object} Returns an object with the glTF format, feature table (binary and json), batch table (binary and json) and glTF parts of the i3dm. + * @param {number} [byteOffset=0] The byte offset of the beginning of the i3dm in the array buffer. + * @returns {object} Returns an object with the glTF format, feature table (binary and json), batch table (binary and json) and glTF parts of the i3dm. */ I3dmParser.parse = function (arrayBuffer, byteOffset) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/ImageBasedLighting.js b/packages/engine/Source/Scene/ImageBasedLighting.js index 632e1f9dc88..e5822bc5e57 100644 --- a/packages/engine/Source/Scene/ImageBasedLighting.js +++ b/packages/engine/Source/Scene/ImageBasedLighting.js @@ -20,9 +20,9 @@ import OctahedralProjectedCubeMap from "./OctahedralProjectedCubeMap.js"; * @constructor * * @param {Cartesian2} [options.imageBasedLightingFactor=Cartesian2(1.0, 1.0)] Scales diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox. - * @param {Number} [options.luminanceAtZenith=0.2] The sun's luminance at the zenith in kilo candela per meter squared to use for this model's procedural environment map. + * @param {number} [options.luminanceAtZenith=0.2] The sun's luminance at the zenith in kilo candela per meter squared to use for this model's procedural environment map. * @param {Cartesian3[]} [options.sphericalHarmonicCoefficients] The third order spherical harmonic coefficients used for the diffuse color of image-based lighting. - * @param {String} [options.specularEnvironmentMaps] A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. + * @param {string} [options.specularEnvironmentMaps] A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. */ function ImageBasedLighting(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -164,7 +164,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * * @memberof ImageBasedLighting.prototype * - * @type {Number} + * @type {number} * @default 0.2 */ luminanceAtZenith: { @@ -217,7 +217,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * * @memberof ImageBasedLighting.prototype * @demo {@link https://sandcastle.cesium.com/index.html?src=Image-Based Lighting.html|Sandcastle Image Based Lighting Demo} - * @type {String} + * @type {string} * @see ImageBasedLighting#sphericalHarmonicCoefficients */ specularEnvironmentMaps: { @@ -239,7 +239,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * Whether or not image-based lighting is enabled. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -257,7 +257,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * based on the properties and resources have changed. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -271,7 +271,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * Whether or not to use the default spherical harmonic coefficients. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -285,7 +285,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * Whether or not the image-based lighting settings use spherical harmonic coefficients. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -316,7 +316,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * Whether or not to use the default specular environment maps. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -330,7 +330,7 @@ Object.defineProperties(ImageBasedLighting.prototype, { * Whether or not the image-based lighting settings use specular environment maps. * * @memberof ImageBasedLighting.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -477,7 +477,7 @@ ImageBasedLighting.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see ImageBasedLighting#destroy * @private diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 497e80cba98..960c25de426 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -44,28 +44,28 @@ import TileImagery from "./TileImagery.js"; * @constructor * * @param {ImageryProvider} imageryProvider The imagery provider to use. - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Rectangle} [options.rectangle=imageryProvider.rectangle] The rectangle of the layer. This rectangle * can limit the visible portion of the imagery provider. - * @param {Number|Function} [options.alpha=1.0] The alpha blending value of this layer, from 0.0 to 1.0. + * @param {number|Function} [options.alpha=1.0] The alpha blending value of this layer, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. - * @param {Number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0. + * @param {number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>. - * @param {Number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0. + * @param {number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>. - * @param {Number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery + * @param {number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery * color. Less than 1.0 makes the imagery darker while greater than 1.0 makes it brighter. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -73,7 +73,7 @@ import TileImagery from "./TileImagery.js"; * imagery tile for which the brightness is required, and it is expected to return * the brightness value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.contrast=1.0] The contrast of this layer. 1.0 uses the unmodified imagery color. + * @param {number|Function} [options.contrast=1.0] The contrast of this layer. 1.0 uses the unmodified imagery color. * Less than 1.0 reduces the contrast while greater than 1.0 increases it. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -81,14 +81,14 @@ import TileImagery from "./TileImagery.js"; * imagery tile for which the contrast is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.hue=0.0] The hue of this layer. 0.0 uses the unmodified imagery color. + * @param {number|Function} [options.hue=0.0] The hue of this layer. 0.0 uses the unmodified imagery color. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates * of the imagery tile for which the hue is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.saturation=1.0] The saturation of this layer. 1.0 uses the unmodified imagery color. + * @param {number|Function} [options.saturation=1.0] The saturation of this layer. 1.0 uses the unmodified imagery color. * Less than 1.0 reduces the saturation while greater than 1.0 increases it. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -96,7 +96,7 @@ import TileImagery from "./TileImagery.js"; * of the imagery tile for which the saturation is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.gamma=1.0] The gamma correction to apply to this layer. 1.0 uses the unmodified imagery color. + * @param {number|Function} [options.gamma=1.0] The gamma correction to apply to this layer. 1.0 uses the unmodified imagery color. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the @@ -112,18 +112,18 @@ import TileImagery from "./TileImagery.js"; * texture minification filter to apply to this layer. Possible values * are <code>TextureMagnificationFilter.LINEAR</code> and * <code>TextureMagnificationFilter.NEAREST</code>. - * @param {Boolean} [options.show=true] True if the layer is shown; otherwise, false. - * @param {Number} [options.maximumAnisotropy=maximum supported] The maximum anisotropy level to use + * @param {boolean} [options.show=true] True if the layer is shown; otherwise, false. + * @param {number} [options.maximumAnisotropy=maximum supported] The maximum anisotropy level to use * for texture filtering. If this parameter is not specified, the maximum anisotropy supported * by the WebGL stack will be used. Larger values make the imagery look better in horizon * views. - * @param {Number} [options.minimumTerrainLevel] The minimum terrain level-of-detail at which to show this imagery layer, + * @param {number} [options.minimumTerrainLevel] The minimum terrain level-of-detail at which to show this imagery layer, * or undefined to show it at all levels. Level zero is the least-detailed level. - * @param {Number} [options.maximumTerrainLevel] The maximum terrain level-of-detail at which to show this imagery layer, + * @param {number} [options.maximumTerrainLevel] The maximum terrain level-of-detail at which to show this imagery layer, * or undefined to show it at all levels. Level zero is the least-detailed level. * @param {Rectangle} [options.cutoutRectangle] Cartographic rectangle for cutting out a portion of this ImageryLayer. * @param {Color} [options.colorToAlpha] Color to be used as alpha. - * @param {Number} [options.colorToAlphaThreshold=0.004] Threshold for color-to-alpha. + * @param {number} [options.colorToAlphaThreshold=0.004] Threshold for color-to-alpha. */ function ImageryLayer(imageryProvider, options) { this._imageryProvider = imageryProvider; @@ -134,7 +134,7 @@ function ImageryLayer(imageryProvider, options) { * The alpha blending value of this layer, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number} + * @type {number} * @default 1.0 */ this.alpha = defaultValue( @@ -146,7 +146,7 @@ function ImageryLayer(imageryProvider, options) { * The alpha blending value of this layer on the night side of the globe, with 0.0 representing fully transparent and * 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is <code>true</code>. * - * @type {Number} + * @type {number} * @default 1.0 */ this.nightAlpha = defaultValue( @@ -158,7 +158,7 @@ function ImageryLayer(imageryProvider, options) { * The alpha blending value of this layer on the day side of the globe, with 0.0 representing fully transparent and * 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is <code>true</code>. * - * @type {Number} + * @type {number} * @default 1.0 */ this.dayAlpha = defaultValue( @@ -170,7 +170,7 @@ function ImageryLayer(imageryProvider, options) { * The brightness of this layer. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number} + * @type {number} * @default {@link ImageryLayer.DEFAULT_BRIGHTNESS} */ this.brightness = defaultValue( @@ -185,7 +185,7 @@ function ImageryLayer(imageryProvider, options) { * The contrast of this layer. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number} + * @type {number} * @default {@link ImageryLayer.DEFAULT_CONTRAST} */ this.contrast = defaultValue( @@ -196,7 +196,7 @@ function ImageryLayer(imageryProvider, options) { /** * The hue of this layer in radians. 0.0 uses the unmodified imagery color. * - * @type {Number} + * @type {number} * @default {@link ImageryLayer.DEFAULT_HUE} */ this.hue = defaultValue( @@ -208,7 +208,7 @@ function ImageryLayer(imageryProvider, options) { * The saturation of this layer. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number} + * @type {number} * @default {@link ImageryLayer.DEFAULT_SATURATION} */ this.saturation = defaultValue( @@ -222,7 +222,7 @@ function ImageryLayer(imageryProvider, options) { /** * The gamma correction to apply to this layer. 1.0 uses the unmodified imagery color. * - * @type {Number} + * @type {number} * @default {@link ImageryLayer.DEFAULT_GAMMA} */ this.gamma = defaultValue( @@ -282,7 +282,7 @@ function ImageryLayer(imageryProvider, options) { /** * Determines if this layer is shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -327,7 +327,7 @@ function ImageryLayer(imageryProvider, options) { /** * Normalized (0-1) threshold for color-to-alpha. * - * @type {Number} + * @type {number} */ this.colorToAlphaThreshold = defaultValue( options.colorToAlphaThreshold, @@ -365,35 +365,35 @@ Object.defineProperties(ImageryLayer.prototype, { /** * This value is used as the default brightness for the imagery layer if one is not provided during construction * or by the imagery provider. This value does not modify the brightness of the imagery. - * @type {Number} + * @type {number} * @default 1.0 */ ImageryLayer.DEFAULT_BRIGHTNESS = 1.0; /** * This value is used as the default contrast for the imagery layer if one is not provided during construction * or by the imagery provider. This value does not modify the contrast of the imagery. - * @type {Number} + * @type {number} * @default 1.0 */ ImageryLayer.DEFAULT_CONTRAST = 1.0; /** * This value is used as the default hue for the imagery layer if one is not provided during construction * or by the imagery provider. This value does not modify the hue of the imagery. - * @type {Number} + * @type {number} * @default 0.0 */ ImageryLayer.DEFAULT_HUE = 0.0; /** * This value is used as the default saturation for the imagery layer if one is not provided during construction * or by the imagery provider. This value does not modify the saturation of the imagery. - * @type {Number} + * @type {number} * @default 1.0 */ ImageryLayer.DEFAULT_SATURATION = 1.0; /** * This value is used as the default gamma for the imagery layer if one is not provided during construction * or by the imagery provider. This value does not modify the gamma of the imagery. - * @type {Number} + * @type {number} * @default 1.0 */ ImageryLayer.DEFAULT_GAMMA = 1.0; @@ -425,7 +425,7 @@ ImageryLayer.DEFAULT_MAGNIFICATION_FILTER = TextureMagnificationFilter.LINEAR; /** * This value is used as the default threshold for color-to-alpha if one is not provided * during construction or by the imagery provider. - * @type {Number} + * @type {number} * @default 0.004 */ ImageryLayer.DEFAULT_APPLY_COLOR_TO_ALPHA_THRESHOLD = 0.004; @@ -437,7 +437,7 @@ ImageryLayer.DEFAULT_APPLY_COLOR_TO_ALPHA_THRESHOLD = 0.004; * it actually does not, by stretching the texels at the edges over the entire * globe. * - * @returns {Boolean} true if this is the base layer; otherwise, false. + * @returns {boolean} true if this is the base layer; otherwise, false. */ ImageryLayer.prototype.isBaseLayer = function () { return this._isBaseLayer; @@ -449,7 +449,7 @@ ImageryLayer.prototype.isBaseLayer = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see ImageryLayer#destroy */ @@ -486,7 +486,7 @@ const terrainRectangleScratch = new Rectangle(); * Computes the intersection of this layer's rectangle with the imagery provider's availability rectangle, * producing the overall bounds of imagery that can be produced by this layer. * - * @returns {Promise.<Rectangle>} A promise to a rectangle which defines the overall bounds of imagery that can be produced by this layer. + * @returns {Promise<Rectangle>} A promise to a rectangle which defines the overall bounds of imagery that can be produced by this layer. * * @example * // Zoom to an imagery layer. @@ -512,8 +512,8 @@ ImageryLayer.prototype.getViewableRectangle = function () { * * @param {Tile} tile The terrain tile. * @param {TerrainProvider} terrainProvider The terrain provider associated with the terrain tile. - * @param {Number} insertionPoint The position to insert new skeletons before in the tile's imagery list. - * @returns {Boolean} true if this layer overlaps any portion of the terrain tile; otherwise, false. + * @param {number} insertionPoint The position to insert new skeletons before in the tile's imagery list. + * @returns {boolean} true if this layer overlaps any portion of the terrain tile; otherwise, false. */ ImageryLayer.prototype._createTileImagerySkeletons = function ( tile, @@ -1192,7 +1192,7 @@ ImageryLayer.prototype._finalizeReprojectTexture = function (context, texture) { * * @param {FrameState} frameState The frameState. * @param {Imagery} imagery The imagery instance to reproject. - * @param {Boolean} [needGeographicProjection=true] True to reproject to geographic, or false if Web Mercator is fine. + * @param {boolean} [needGeographicProjection=true] True to reproject to geographic, or false if Web Mercator is fine. */ ImageryLayer.prototype._reprojectTexture = function ( frameState, @@ -1508,9 +1508,9 @@ function reprojectToGeographic(command, context, texture, rectangle) { * Gets the level with the specified world coordinate spacing between texels, or less. * * @param {ImageryLayer} layer The imagery layer to use. - * @param {Number} texelSpacing The texel spacing for which to find a corresponding level. - * @param {Number} latitudeClosestToEquator The latitude closest to the equator that we're concerned with. - * @returns {Number} The level with the specified texel spacing or less. + * @param {number} texelSpacing The texel spacing for which to find a corresponding level. + * @param {number} latitudeClosestToEquator The latitude closest to the equator that we're concerned with. + * @returns {number} The level with the specified texel spacing or less. * @private */ function getLevelWithMaximumTexelSpacing( diff --git a/packages/engine/Source/Scene/ImageryLayerCollection.js b/packages/engine/Source/Scene/ImageryLayerCollection.js index 81c22614c07..a1222d74496 100644 --- a/packages/engine/Source/Scene/ImageryLayerCollection.js +++ b/packages/engine/Source/Scene/ImageryLayerCollection.js @@ -59,7 +59,7 @@ Object.defineProperties(ImageryLayerCollection.prototype, { /** * Gets the number of layers in this collection. * @memberof ImageryLayerCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -72,7 +72,7 @@ Object.defineProperties(ImageryLayerCollection.prototype, { * Adds a layer to the collection. * * @param {ImageryLayer} layer the layer to add. - * @param {Number} [index] the index to add the layer at. If omitted, the layer will + * @param {number} [index] the index to add the layer at. If omitted, the layer will * be added on top of all existing layers. * * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of the layers. @@ -110,7 +110,7 @@ ImageryLayerCollection.prototype.add = function (layer, index) { * Creates a new layer using the given ImageryProvider and adds it to the collection. * * @param {ImageryProvider} imageryProvider the imagery provider to create a new layer for. - * @param {Number} [index] the index to add the layer at. If omitted, the layer will + * @param {number} [index] the index to add the layer at. If omitted, the layer will * added on top of all existing layers. * @returns {ImageryLayer} The newly created layer. */ @@ -133,8 +133,8 @@ ImageryLayerCollection.prototype.addImageryProvider = function ( * Removes a layer from this collection, if present. * * @param {ImageryLayer} layer The layer to remove. - * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. - * @returns {Boolean} true if the layer was in the collection and was removed, + * @param {boolean} [destroy=true] whether to destroy the layers in addition to removing them. + * @returns {boolean} true if the layer was in the collection and was removed, * false if the layer was not in the collection. */ ImageryLayerCollection.prototype.remove = function (layer, destroy) { @@ -161,7 +161,7 @@ ImageryLayerCollection.prototype.remove = function (layer, destroy) { /** * Removes all layers from this collection. * - * @param {Boolean} [destroy=true] whether to destroy the layers in addition to removing them. + * @param {boolean} [destroy=true] whether to destroy the layers in addition to removing them. */ ImageryLayerCollection.prototype.removeAll = function (destroy) { destroy = defaultValue(destroy, true); @@ -184,7 +184,7 @@ ImageryLayerCollection.prototype.removeAll = function (destroy) { * * @param {ImageryLayer} layer the layer to check for. * - * @returns {Boolean} true if the collection contains the layer, false otherwise. + * @returns {boolean} true if the collection contains the layer, false otherwise. */ ImageryLayerCollection.prototype.contains = function (layer) { return this.indexOf(layer) !== -1; @@ -195,7 +195,7 @@ ImageryLayerCollection.prototype.contains = function (layer) { * * @param {ImageryLayer} layer The layer to find the index of. * - * @returns {Number} The index of the layer in the collection, or -1 if the layer does not exist in the collection. + * @returns {number} The index of the layer in the collection, or -1 if the layer does not exist in the collection. */ ImageryLayerCollection.prototype.indexOf = function (layer) { return this._layers.indexOf(layer); @@ -204,7 +204,7 @@ ImageryLayerCollection.prototype.indexOf = function (layer) { /** * Gets a layer by index from the collection. * - * @param {Number} index the index to retrieve. + * @param {number} index the index to retrieve. * * @returns {ImageryLayer} The imagery layer at the given index. */ @@ -437,7 +437,7 @@ ImageryLayerCollection.prototype.pickImageryLayers = function (ray, scene) { * * @param {Ray} ray The ray to test for intersection. * @param {Scene} scene The scene. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise that resolves to an array of features intersected by the pick ray. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise that resolves to an array of features intersected by the pick ray. * If it can be quickly determined that no features are intersected (for example, * because no active imagery providers support {@link ImageryProvider#pickFeatures} * or because the pick ray does not intersect the surface), this function will @@ -552,7 +552,7 @@ ImageryLayerCollection.prototype.cancelReprojections = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} true if this object was destroyed; otherwise, false. + * @returns {boolean} true if this object was destroyed; otherwise, false. * * @see ImageryLayerCollection#destroy */ diff --git a/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js b/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js index 1156bf6df68..7c2654da2e9 100644 --- a/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js +++ b/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js @@ -9,14 +9,14 @@ import defined from "../Core/defined.js"; function ImageryLayerFeatureInfo() { /** * Gets or sets the name of the feature. - * @type {String|undefined} + * @type {string|undefined} */ this.name = undefined; /** * Gets or sets an HTML description of the feature. The HTML is not trusted and should * be sanitized before display to the user. - * @type {String|undefined} + * @type {string|undefined} */ this.description = undefined; @@ -47,7 +47,7 @@ function ImageryLayerFeatureInfo() { * 3) the first property containing the word 'name', 4) the first property containing the word 'title'. If * the name cannot be obtained from any of these sources, the existing name will be left unchanged. * - * @param {Object} properties An object literal containing the properties of the feature. + * @param {object} properties An object literal containing the properties of the feature. */ ImageryLayerFeatureInfo.prototype.configureNameFromProperties = function ( properties @@ -83,7 +83,7 @@ ImageryLayerFeatureInfo.prototype.configureNameFromProperties = function ( /** * Configures the description of this feature by creating an HTML table of properties and their values. * - * @param {Object} properties An object literal containing the properties of the feature. + * @param {object} properties An object literal containing the properties of the feature. */ ImageryLayerFeatureInfo.prototype.configureDescriptionFromProperties = function ( properties diff --git a/packages/engine/Source/Scene/ImageryProvider.js b/packages/engine/Source/Scene/ImageryProvider.js index 37a66f8df85..76d6ec9a4ba 100644 --- a/packages/engine/Source/Scene/ImageryProvider.js +++ b/packages/engine/Source/Scene/ImageryProvider.js @@ -47,7 +47,7 @@ function ImageryProvider() { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -56,7 +56,7 @@ function ImageryProvider() { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -65,7 +65,7 @@ function ImageryProvider() { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -74,7 +74,7 @@ function ImageryProvider() { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -83,7 +83,7 @@ function ImageryProvider() { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -91,7 +91,7 @@ function ImageryProvider() { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -100,7 +100,7 @@ function ImageryProvider() { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -108,7 +108,7 @@ function ImageryProvider() { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -136,7 +136,7 @@ Object.defineProperties(ImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof ImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -146,7 +146,7 @@ Object.defineProperties(ImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof ImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -168,7 +168,7 @@ Object.defineProperties(ImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link ImageryProvider#ready} returns true. * @memberof ImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -179,7 +179,7 @@ Object.defineProperties(ImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link ImageryProvider#ready} returns true. * @memberof ImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -190,7 +190,7 @@ Object.defineProperties(ImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link ImageryProvider#ready} returns true. * @memberof ImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -205,7 +205,7 @@ Object.defineProperties(ImageryProvider.prototype, { * provider with more than a few tiles at the minimum level will lead to * rendering problems. * @memberof ImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -277,7 +277,7 @@ Object.defineProperties(ImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof ImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -288,9 +288,9 @@ Object.defineProperties(ImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -303,11 +303,11 @@ ImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link ImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} Returns a promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} Returns a promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -323,12 +323,12 @@ ImageryProvider.prototype.requestImage = function (x, y, level, request) { * * @function * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. @@ -353,8 +353,8 @@ const ktx2Regex = /\.ktx2$/i; * that the request should be retried later. * * @param {ImageryProvider} imageryProvider The imagery provider for the URL. - * @param {Resource|String} url The URL of the image. - * @returns {Promise.<ImageryTypes|CompressedTextureBuffer>|undefined} A promise for the image that will resolve when the image is available, or + * @param {Resource|string} url The URL of the image. + * @returns {Promise<ImageryTypes|CompressedTextureBuffer>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. */ ImageryProvider.loadImage = function (imageryProvider, url) { diff --git a/packages/engine/Source/Scene/Implicit3DTileContent.js b/packages/engine/Source/Scene/Implicit3DTileContent.js index e8d922ac5b7..4e76d2b8d71 100644 --- a/packages/engine/Source/Scene/Implicit3DTileContent.js +++ b/packages/engine/Source/Scene/Implicit3DTileContent.js @@ -33,9 +33,9 @@ import parseBoundingVolumeSemantics from "./parseBoundingVolumeSemantics.js"; * @param {Cesium3DTileset} tileset The tileset this content belongs to * @param {Cesium3DTile} tile The tile this content belongs to. * @param {Resource} resource The resource for the tileset - * @param {Object} [json] The JSON object containing the subtree. Mutually exclusive with arrayBuffer. + * @param {object} [json] The JSON object containing the subtree. Mutually exclusive with arrayBuffer. * @param {ArrayBuffer} [arrayBuffer] The array buffer that stores the content payload. Mutually exclusive with json. - * @param {Number} [byteOffset=0] The offset into the array buffer, if one was provided + * @param {number} [byteOffset=0] The offset into the array buffer, if one was provided * * @exception {DeveloperError} One of json and arrayBuffer must be defined. * @@ -189,9 +189,9 @@ Object.defineProperties(Implicit3DTileContent.prototype, { * up a promise chain to expand the immediate subtree. * * @param {Implicit3DTileContent} content The implicit content - * @param {Object} [json] The JSON containing the subtree. Mutually exclusive with arrayBuffer. + * @param {object} [json] The JSON containing the subtree. Mutually exclusive with arrayBuffer. * @param {ArrayBuffer} [arrayBuffer] The ArrayBuffer containing a subtree binary. Mutually exclusive with json. - * @param {Number} [byteOffset=0] The byte offset into the arrayBuffer + * @param {number} [byteOffset=0] The byte offset into the arrayBuffer * @private */ function initialize(content, json, arrayBuffer, byteOffset) { @@ -262,9 +262,9 @@ function expandSubtree(content, subtree) { /** * A pair of (tile, childIndex) used for finding child subtrees. * - * @typedef {Object} ChildSubtreeLocator + * @typedef {object} ChildSubtreeLocator * @property {Cesium3DTile} tile One of the tiles in the bottommost row of the subtree. - * @property {Number} childIndex The morton index of the child tile relative to its parent + * @property {number} childIndex The morton index of the child tile relative to its parent * @private */ @@ -303,7 +303,7 @@ function listChildSubtrees(content, subtree, bottomRow) { * Results of transcodeSubtreeTiles, containing the root tile of the * subtree and the bottom row of nodes for further processing. * - * @typedef {Object} TranscodedSubtree + * @typedef {object} TranscodedSubtree * @property {Cesium3DTile} rootTile The transcoded root tile of the subtree * @property {Array<Cesium3DTile|undefined>} bottomRow The bottom row of transcoded tiles. This is helpful for processing child subtrees * @private @@ -317,7 +317,7 @@ function listChildSubtrees(content, subtree, bottomRow) { * @param {Implicit3DTileContent} content The implicit content * @param {ImplicitSubtree} subtree The subtree to get availability information * @param {Cesium3DTile} placeholderTile The placeholder tile, used for constructing the subtree root tile - * @param {Number} childIndex The Morton index of the root tile relative to parentOfRootTile + * @param {number} childIndex The Morton index of the root tile relative to parentOfRootTile * @returns {TranscodedSubtree} The newly created subtree of tiles * @private */ @@ -407,9 +407,9 @@ function getGeometricError(tileMetadata, implicitTileset, implicitCoordinates) { * @param {Implicit3DTileContent} implicitContent The implicit content * @param {ImplicitSubtree} subtree The subtree the child tile belongs to * @param {Cesium3DTile} parentTile The parent of the new child tile - * @param {Number} childIndex The morton index of the child tile relative to its parent - * @param {Number} childBitIndex The index of the child tile within the tile's availability information. - * @param {Boolean} [parentIsPlaceholderTile=false] True if parentTile is a placeholder tile. This is true for the root of each subtree. + * @param {number} childIndex The morton index of the child tile relative to its parent + * @param {number} childBitIndex The index of the child tile within the tile's availability information. + * @param {boolean} [parentIsPlaceholderTile=false] True if parentTile is a placeholder tile. This is true for the root of each subtree. * @returns {Cesium3DTile} The new child tile. * @private */ @@ -532,11 +532,11 @@ function deriveChildTile( * Returns true if the minimumHeight/maximumHeight parameter * is defined and the bounding volume is a region or S2 cell. * - * @param {Object} [boundingVolume] The bounding volume - * @param {Object} [tileBounds] The tile bounds - * @param {Number} [tileBounds.minimumHeight] The minimum height - * @param {Number} [tileBounds.maximumHeight] The maximum height - * @returns {Boolean} Whether the bounding volume's heights can be updated + * @param {object} [boundingVolume] The bounding volume + * @param {object} [tileBounds] The tile bounds + * @param {number} [tileBounds.minimumHeight] The minimum height + * @param {number} [tileBounds.maximumHeight] The maximum height + * @returns {boolean} Whether the bounding volume's heights can be updated * @private */ function canUpdateHeights(boundingVolume, tileBounds) { @@ -557,10 +557,10 @@ function canUpdateHeights(boundingVolume, tileBounds) { * minimumHeight/maximumHeight parameter is defined and the * bounding volume is a region or S2 cell. * - * @param {Object} boundingVolume The bounding volume - * @param {Object} [tileBounds] The tile bounds - * @param {Number} [tileBounds.minimumHeight] The new minimum height - * @param {Number} [tileBounds.maximumHeight] The new maximum height + * @param {object} boundingVolume The bounding volume + * @param {object} [tileBounds] The tile bounds + * @param {number} [tileBounds.minimumHeight] The new minimum height + * @param {number} [tileBounds.maximumHeight] The new maximum height * @private */ function updateHeights(boundingVolume, tileBounds) { @@ -591,8 +591,8 @@ function updateHeights(boundingVolume, tileBounds) { * minimumHeight/maximumHeight parameter is defined. * * @param {Array} region A 6-element array describing the bounding region - * @param {Number} [minimumHeight] The new minimum height - * @param {Number} [maximumHeight] The new maximum height + * @param {number} [minimumHeight] The new minimum height + * @param {number} [maximumHeight] The new maximum height * @private */ function updateRegionHeights(region, minimumHeight, maximumHeight) { @@ -612,9 +612,9 @@ function updateRegionHeights(region, minimumHeight, maximumHeight) { * semantics. Heights are only updated if the respective * minimumHeight/maximumHeight parameter is defined. * - * @param {Object} s2CellVolume An object describing the S2 cell - * @param {Number} [minimumHeight] The new minimum height - * @param {Number} [maximumHeight] The new maximum height + * @param {object} s2CellVolume An object describing the S2 cell + * @param {number} [minimumHeight] The new minimum height + * @param {number} [maximumHeight] The new maximum height * @private */ function updateS2CellHeights(s2CellVolume, minimumHeight, maximumHeight) { @@ -652,11 +652,11 @@ function updateS2CellHeights(s2CellVolume, minimumHeight, maximumHeight) { * * @param {ImplicitTileset} implicitTileset The implicit tileset struct which holds the root bounding volume * @param {ImplicitTileCoordinates} implicitCoordinates The coordinates of the child tile - * @param {Number} childIndex The morton index of the child tile relative to its parent - * @param {Boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. + * @param {number} childIndex The morton index of the child tile relative to its parent + * @param {boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. * @param {Cesium3DTile} parentTile The parent of the new child tile - * @param {Object} [tileBounds] The tile bounds - * @returns {Object} An object containing the JSON for a bounding volume + * @param {object} [tileBounds] The tile bounds + * @returns {object} An object containing the JSON for a bounding volume * @private */ function getTileBoundingVolume( @@ -712,8 +712,8 @@ function getTileBoundingVolume( * </ol> * </p> * - * @param {Object} tileBoundingVolume An object containing the JSON for the tile's bounding volume - * @param {Object} [contentBounds] The content bounds + * @param {object} tileBoundingVolume An object containing the JSON for the tile's bounding volume + * @param {object} [contentBounds] The content bounds * @returns {Object|undefined} An object containing the JSON for a bounding volume, or <code>undefined</code> if there is no bounding volume * @private */ @@ -742,10 +742,10 @@ function getContentBoundingVolume(tileBoundingVolume, contentBounds) { * * @param {ImplicitTileset} implicitTileset The implicit tileset struct which holds the root bounding volume * @param {ImplicitTileCoordinates} implicitCoordinates The coordinates of the child tile - * @param {Number} childIndex The morton index of the child tile relative to its parent - * @param {Boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. + * @param {number} childIndex The morton index of the child tile relative to its parent + * @param {boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. * @param {Cesium3DTile} parentTile The parent of the new child tile - * @returns {Object} An object containing the JSON for a bounding volume + * @returns {object} An object containing the JSON for a bounding volume * @private */ function deriveBoundingVolume( @@ -807,14 +807,14 @@ function deriveBoundingVolume( * dimensions, i.e. (x, y), leaving the z axis unchanged. * </p> * - * @param {Boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. + * @param {boolean} parentIsPlaceholderTile True if parentTile is a placeholder tile. This is true for the root of each subtree. * @param {Cesium3DTile} parentTile The parent of the new child tile - * @param {Number} childIndex The morton index of the child tile relative to its parent - * @param {Number} level The level of the descendant tile relative to the root implicit tile - * @param {Number} x The x coordinate of the descendant tile - * @param {Number} y The y coordinate of the descendant tile - * @param {Number} [z] The z coordinate of the descendant tile (octree only) - * @returns {Object} An object with the 3DTILES_bounding_volume_S2 extension. + * @param {number} childIndex The morton index of the child tile relative to its parent + * @param {number} level The level of the descendant tile relative to the root implicit tile + * @param {number} x The x coordinate of the descendant tile + * @param {number} y The y coordinate of the descendant tile + * @param {number} [z] The z coordinate of the descendant tile (octree only) + * @returns {object} An object with the 3DTILES_bounding_volume_S2 extension. * @private */ function deriveBoundingVolumeS2( @@ -908,12 +908,12 @@ const scratchHalfAxes = new Matrix3(); * than recursively subdividing to minimize floating point error. * </p> * - * @param {Number[]} rootBox An array of 12 numbers representing the bounding box of the root tile - * @param {Number} level The level of the descendant tile relative to the root implicit tile - * @param {Number} x The x coordinate of the descendant tile - * @param {Number} y The y coordinate of the descendant tile - * @param {Number} [z] The z coordinate of the descendant tile (octree only) - * @returns {Number[]} An array of 12 numbers representing the bounding box of the descendant tile. + * @param {number[]} rootBox An array of 12 numbers representing the bounding box of the root tile + * @param {number} level The level of the descendant tile relative to the root implicit tile + * @param {number} x The x coordinate of the descendant tile + * @param {number} y The y coordinate of the descendant tile + * @param {number} [z] The z coordinate of the descendant tile (octree only) + * @returns {number[]} An array of 12 numbers representing the bounding box of the descendant tile. * @private */ function deriveBoundingBox(rootBox, level, x, y, z) { @@ -985,12 +985,12 @@ const scratchRectangle = new Rectangle(); * This computes the child volume directly from the root bounding volume rather * than recursively subdividing to minimize floating point error. * </p> - * @param {Number[]} rootRegion An array of 6 numbers representing the root implicit tile - * @param {Number} level The level of the descendant tile relative to the root implicit tile - * @param {Number} x The x coordinate of the descendant tile - * @param {Number} y The x coordinate of the descendant tile - * @param {Number} [z] The z coordinate of the descendant tile (octree only) - * @returns {Number[]} An array of 6 numbers representing the bounding region of the descendant tile + * @param {number[]} rootRegion An array of 6 numbers representing the root implicit tile + * @param {number} level The level of the descendant tile relative to the root implicit tile + * @param {number} x The x coordinate of the descendant tile + * @param {number} y The x coordinate of the descendant tile + * @param {number} [z] The z coordinate of the descendant tile (octree only) + * @returns {number[]} An array of 6 numbers representing the bounding region of the descendant tile * @private */ function deriveBoundingRegion(rootRegion, level, x, y, z) { @@ -1039,7 +1039,7 @@ function deriveBoundingRegion(rootRegion, level, x, y, z) { * * @param {Implicit3DTileContent} content The content object. * @param {Cesium3DTile} parentTile The parent of the new child subtree. - * @param {Number} childIndex The morton index of the child tile relative to its parent + * @param {number} childIndex The morton index of the child tile relative to its parent * @returns {Cesium3DTile} The new placeholder tile * @private */ @@ -1099,7 +1099,7 @@ function makePlaceholderChildSubtree(content, parentTile, childIndex) { * this file and Cesium3DTile.js * @param {Implicit3DTileContent} content The implicit content * @param {Resource} baseResource The base resource for the tileset - * @param {Object} tileJson The JSON header for the tile + * @param {object} tileJson The JSON header for the tile * @param {Cesium3DTile} parentTile The parent of the new tile * @returns {Cesium3DTile} The newly created tile. * @private diff --git a/packages/engine/Source/Scene/ImplicitAvailabilityBitstream.js b/packages/engine/Source/Scene/ImplicitAvailabilityBitstream.js index bfb9b8524d6..9c664f9a525 100644 --- a/packages/engine/Source/Scene/ImplicitAvailabilityBitstream.js +++ b/packages/engine/Source/Scene/ImplicitAvailabilityBitstream.js @@ -11,12 +11,12 @@ import RuntimeError from "../Core/RuntimeError.js"; * @alias ImplicitAvailabilityBitstream * @constructor * - * @param {Object} options An object with the following properties: - * @param {Number} options.lengthBits The length of the bitstream in bits - * @param {Boolean} [options.constant] A single boolean value indicating the value of all the bits in the bitstream if they are all the same + * @param {object} options An object with the following properties: + * @param {number} options.lengthBits The length of the bitstream in bits + * @param {boolean} [options.constant] A single boolean value indicating the value of all the bits in the bitstream if they are all the same * @param {Uint8Array} [options.bitstream] An array of bytes storing the bitstream in binary - * @param {Number} [options.availableCount] A number indicating how many 1 bits are found in the bitstream - * @param {Boolean} [options.computeAvailableCountEnabled=false] If true, and options.availableCount is undefined, the availableCount will be computed from the bitstream. + * @param {number} [options.availableCount] A number indicating how many 1 bits are found in the bitstream + * @param {boolean} [options.computeAvailableCountEnabled=false] If true, and options.availableCount is undefined, the availableCount will be computed from the bitstream. * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -64,7 +64,7 @@ function ImplicitAvailabilityBitstream(options) { * computing availableCount if not precomputed * * @param {Uint8Array} bitstream The bitstream typed array - * @param {Number} lengthBits How many bits are in the bitstream + * @param {number} lengthBits How many bits are in the bitstream * @private */ function count1Bits(bitstream, lengthBits) { @@ -83,7 +83,7 @@ Object.defineProperties(ImplicitAvailabilityBitstream.prototype, { * * @memberof ImplicitAvailabilityBitstream.prototype * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -97,7 +97,7 @@ Object.defineProperties(ImplicitAvailabilityBitstream.prototype, { * * @memberof ImplicitAvailabilityBitstream.prototype * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -112,8 +112,8 @@ Object.defineProperties(ImplicitAvailabilityBitstream.prototype, { * Get a bit from the availability bitstream as a Boolean. If the bitstream * is a constant, the constant value is returned instead. * - * @param {Number} index The integer index of the bit. - * @returns {Boolean} The value of the bit + * @param {number} index The integer index of the bit. + * @returns {boolean} The value of the bit * @private */ ImplicitAvailabilityBitstream.prototype.getBit = function (index) { diff --git a/packages/engine/Source/Scene/ImplicitMetadataView.js b/packages/engine/Source/Scene/ImplicitMetadataView.js index 7856b29af0f..36292af6e96 100644 --- a/packages/engine/Source/Scene/ImplicitMetadataView.js +++ b/packages/engine/Source/Scene/ImplicitMetadataView.js @@ -9,8 +9,8 @@ import defaultValue from "../Core/defaultValue.js"; * * @param {MetadataTable} options.metadataTable The metadata table. * @param {MetadataClass} options.class The class that the metadata conforms to. - * @param {Number} options.entityId The ID of the entity the metadata belongs to. - * @param {Object} options.propertyTableJson The JSON that contains the property table of the entity. + * @param {number} options.entityId The ID of the entity the metadata belongs to. + * @param {object} options.propertyTableJson The JSON that contains the property table of the entity. * * @alias ImplicitMetadataView * @constructor @@ -59,7 +59,7 @@ Object.defineProperties(ImplicitMetadataView.prototype, { * Extra user-defined properties. * * @memberof ImplicitMetadataView.prototype - * @type {Object} + * @type {object} * @readonly */ extras: { @@ -72,7 +72,7 @@ Object.defineProperties(ImplicitMetadataView.prototype, { * An object containing extensions. * * @memberof ImplicitMetadataView.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { @@ -85,8 +85,8 @@ Object.defineProperties(ImplicitMetadataView.prototype, { /** * Returns whether the metadata contains this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the tile has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the tile has this property. * @private */ ImplicitMetadataView.prototype.hasProperty = function (propertyId) { @@ -96,8 +96,8 @@ ImplicitMetadataView.prototype.hasProperty = function (propertyId) { /** * Returns whether the metadata contains a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the tile has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the tile has a property with the given semantic. * @private */ ImplicitMetadataView.prototype.hasPropertyBySemantic = function (semantic) { @@ -107,8 +107,8 @@ ImplicitMetadataView.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs in the metadata table. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ ImplicitMetadataView.prototype.getPropertyIds = function (results) { @@ -121,7 +121,7 @@ ImplicitMetadataView.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the tile does not have this property. * @private */ @@ -135,9 +135,9 @@ ImplicitMetadataView.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ ImplicitMetadataView.prototype.setProperty = function (propertyId, value) { @@ -147,7 +147,7 @@ ImplicitMetadataView.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic in the metadata table. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the tile does not have this semantic. * @private */ @@ -158,9 +158,9 @@ ImplicitMetadataView.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic in the metadata table. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ diff --git a/packages/engine/Source/Scene/ImplicitSubdivisionScheme.js b/packages/engine/Source/Scene/ImplicitSubdivisionScheme.js index a9c22c1bb02..75f5ecde735 100644 --- a/packages/engine/Source/Scene/ImplicitSubdivisionScheme.js +++ b/packages/engine/Source/Scene/ImplicitSubdivisionScheme.js @@ -3,7 +3,7 @@ import DeveloperError from "../Core/DeveloperError.js"; /** * The subdivision scheme for an implicit tileset. * - * @enum {String} + * @enum {string} * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -11,7 +11,7 @@ const ImplicitSubdivisionScheme = { /** * A quadtree divides a parent tile into four children, split at the midpoint * of the x and y dimensions of the bounding box - * @type {String} + * @type {string} * @constant * @private */ @@ -19,7 +19,7 @@ const ImplicitSubdivisionScheme = { /** * An octree divides a parent tile into eight children, split at the midpoint * of the x, y, and z dimensions of the bounding box. - * @type {String} + * @type {string} * @constant * @private */ @@ -29,7 +29,7 @@ const ImplicitSubdivisionScheme = { /** * Get the branching factor for the given subdivision scheme * @param {ImplicitSubdivisionScheme} subdivisionScheme The subdivision scheme - * @returns {Number} The branching factor, either 4 for QUADTREE or 8 for OCTREE + * @returns {number} The branching factor, either 4 for QUADTREE or 8 for OCTREE * @private */ ImplicitSubdivisionScheme.getBranchingFactor = function (subdivisionScheme) { diff --git a/packages/engine/Source/Scene/ImplicitSubtree.js b/packages/engine/Source/Scene/ImplicitSubtree.js index 9f0ec3cc8ba..62ed8148b1b 100644 --- a/packages/engine/Source/Scene/ImplicitSubtree.js +++ b/packages/engine/Source/Scene/ImplicitSubtree.js @@ -28,7 +28,7 @@ import ResourceCache from "./ResourceCache.js"; * @constructor * * @param {Resource} resource The resource for this subtree. This is used for fetching external buffers as needed. - * @param {Object} [json] The JSON object for this subtree. Mutually exclusive with subtreeView. + * @param {object} [json] The JSON object for this subtree. Mutually exclusive with subtreeView. * @param {Uint8Array} [subtreeView] The contents of a subtree binary in a Uint8Array. Mutually exclusive with json. * @param {ImplicitTileset} implicitTileset The implicit tileset. This includes information about the size of subtrees * @param {ImplicitTileCoordinates} implicitCoordinates The coordinates of the subtree's root tile. @@ -127,7 +127,7 @@ Object.defineProperties(ImplicitSubtree.prototype, { * this property stores the JSON from the extension. This is used by {@link TileMetadata} * to get the extras and extensions for the tiles in the subtree. * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -183,8 +183,8 @@ Object.defineProperties(ImplicitSubtree.prototype, { /** * Check if a specific tile is available at an index of the tile availability bitstream * - * @param {Number} index The index of the desired tile - * @returns {Boolean} The value of the i-th bit + * @param {number} index The index of the desired tile + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.tileIsAvailableAtIndex = function (index) { @@ -195,7 +195,7 @@ ImplicitSubtree.prototype.tileIsAvailableAtIndex = function (index) { * Check if a specific tile is available at an implicit tile coordinate * * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a tile - * @returns {Boolean} The value of the i-th bit + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.tileIsAvailableAtCoordinates = function ( @@ -208,9 +208,9 @@ ImplicitSubtree.prototype.tileIsAvailableAtCoordinates = function ( /** * Check if a specific tile's content is available at an index of the content availability bitstream * - * @param {Number} index The index of the desired tile - * @param {Number} [contentIndex=0] The index of the desired content when multiple contents are used. - * @returns {Boolean} The value of the i-th bit + * @param {number} index The index of the desired tile + * @param {number} [contentIndex=0] The index of the desired content when multiple contents are used. + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.contentIsAvailableAtIndex = function ( @@ -234,8 +234,8 @@ ImplicitSubtree.prototype.contentIsAvailableAtIndex = function ( * Check if a specific tile's content is available at an implicit tile coordinate * * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a tile - * @param {Number} [contentIndex=0] The index of the desired content when the <code>3DTILES_multiple_contents</code> extension is used. - * @returns {Boolean} The value of the i-th bit + * @param {number} [contentIndex=0] The index of the desired content when the <code>3DTILES_multiple_contents</code> extension is used. + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.contentIsAvailableAtCoordinates = function ( @@ -249,8 +249,8 @@ ImplicitSubtree.prototype.contentIsAvailableAtCoordinates = function ( /** * Check if a child subtree is available at an index of the child subtree availability bitstream * - * @param {Number} index The index of the desired child subtree - * @returns {Boolean} The value of the i-th bit + * @param {number} index The index of the desired child subtree + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.childSubtreeIsAvailableAtIndex = function (index) { @@ -261,7 +261,7 @@ ImplicitSubtree.prototype.childSubtreeIsAvailableAtIndex = function (index) { * Check if a specific child subtree is available at an implicit tile coordinate * * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a child subtree - * @returns {Boolean} The value of the i-th bit + * @returns {boolean} The value of the i-th bit * @private */ ImplicitSubtree.prototype.childSubtreeIsAvailableAtCoordinates = function ( @@ -280,8 +280,8 @@ ImplicitSubtree.prototype.childSubtreeIsAvailableAtCoordinates = function ( * <li>Level 2 starts at index 5</li> * </ul> * - * @param {Number} level The 0-indexed level number relative to the root of the subtree - * @returns {Number} The first index at the desired level + * @param {number} level The 0-indexed level number relative to the root of the subtree + * @returns {number} The first index at the desired level * @private */ ImplicitSubtree.prototype.getLevelOffset = function (level) { @@ -294,8 +294,8 @@ ImplicitSubtree.prototype.getLevelOffset = function (level) { * chopping off the last 2 (quadtree) or 3 (octree) bits of the morton * index. * - * @param {Number} childIndex The morton index of the child tile relative to its parent - * @returns {Number} The index of the child's parent node + * @param {number} childIndex The morton index of the child tile relative to its parent + * @returns {number} The index of the child's parent node * @private */ ImplicitSubtree.prototype.getParentMortonIndex = function (mortonIndex) { @@ -313,7 +313,7 @@ ImplicitSubtree.prototype.getParentMortonIndex = function (mortonIndex) { * it resolves/rejects subtree.readyPromise. * * @param {ImplicitSubtree} subtree The subtree - * @param {Object} [json] The JSON object for this subtree. If parsing from a binary subtree file, this will be undefined. + * @param {object} [json] The JSON object for this subtree. If parsing from a binary subtree file, this will be undefined. * @param {Uint8Array} [subtreeView] The contents of the subtree binary * @param {ImplicitTileset} implicitTileset The implicit tileset this subtree belongs to. * @private @@ -433,8 +433,8 @@ function initialize(subtree, json, subtreeView, implicitTileset) { /** * A helper object for storing the two parts of the subtree binary * - * @typedef {Object} SubtreeChunks - * @property {Object} json The json chunk of the subtree + * @typedef {object} SubtreeChunks + * @property {object} json The json chunk of the subtree * @property {Uint8Array} binary The binary chunk of the subtree. This represents the internal buffer. * @private */ @@ -488,11 +488,11 @@ function parseSubtreeChunks(subtreeView) { * Buffers are assumed inactive until explicitly marked active. This is used * to avoid fetching unneeded buffers. * - * @typedef {Object} BufferHeader - * @property {Boolean} isExternal True if this is an external buffer - * @property {Boolean} isActive Whether this buffer is currently used. - * @property {String} [uri] The URI of the buffer (external buffers only) - * @property {Number} byteLength The byte length of the buffer, including any padding contained within. + * @typedef {object} BufferHeader + * @property {boolean} isExternal True if this is an external buffer + * @property {boolean} isActive Whether this buffer is currently used. + * @property {string} [uri] The URI of the buffer (external buffers only) + * @property {number} byteLength The byte length of the buffer, including any padding contained within. * @private */ @@ -520,12 +520,12 @@ function preprocessBuffers(bufferHeaders) { * A buffer header is the JSON header from the subtree JSON chunk plus * the isActive flag and a reference to the header for the underlying buffer * - * @typedef {Object} BufferViewHeader + * @typedef {object} BufferViewHeader * @property {BufferHeader} bufferHeader A reference to the header for the underlying buffer - * @property {Boolean} isActive Whether this bufferView is currently used. - * @property {Number} buffer The index of the underlying buffer. - * @property {Number} byteOffset The start byte of the bufferView within the buffer. - * @property {Number} byteLength The length of the bufferView. No padding is included in this length. + * @property {boolean} isActive Whether this bufferView is currently used. + * @property {number} buffer The index of the underlying buffer. + * @property {number} byteOffset The start byte of the bufferView within the buffer. + * @property {number} byteLength The length of the bufferView. No padding is included in this length. * @private */ @@ -619,7 +619,7 @@ function markActiveBufferViews(subtreeJson, bufferViewHeaders) { * allow filtering this to avoid downloading unneeded buffers. * </p> * - * @param {Object} propertyTableJson The property table JSON for either a tile or some content + * @param {object} propertyTableJson The property table JSON for either a tile or some content * @param {BufferViewHeader[]} bufferViewHeaders The preprocessed buffer view headers * @private */ @@ -680,7 +680,7 @@ function markActiveMetadataBufferViews(propertyTableJson, bufferViewHeaders) { * @param {ImplicitSubtree} subtree The subtree * @param {BufferHeader[]} bufferHeaders The preprocessed buffer headers * @param {Uint8Array} internalBuffer The binary chunk of the subtree file - * @returns {Promise<Object>} A promise resolving to the dictionary of active buffers + * @returns {Promise<object>} A promise resolving to the dictionary of active buffers * @private */ function requestActiveBuffers(subtree, bufferHeaders, internalBuffer) { @@ -729,8 +729,8 @@ function requestExternalBuffer(subtree, bufferHeader) { * extract a subarray from one of the active buffers. * * @param {BufferViewHeader[]} bufferViewHeaders - * @param {Object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents. - * @returns {Object} A dictionary of buffer view index to a Uint8Array of its contents. + * @param {object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents. + * @returns {object} A dictionary of buffer view index to a Uint8Array of its contents. * @private */ function parseActiveBufferViews(bufferViewHeaders, buffersU8) { @@ -755,9 +755,9 @@ function parseActiveBufferViews(bufferViewHeaders, buffersU8) { * Parse the three availability bitstreams and store them in the subtree * * @param {ImplicitSubtree} subtree The subtree to modify - * @param {Object} subtreeJson The subtree JSON + * @param {object} subtreeJson The subtree JSON * @param {ImplicitTileset} implicitTileset The implicit tileset this subtree belongs to - * @param {Object} bufferViewsU8 A dictionary of buffer view index to a Uint8Array of its contents. + * @param {object} bufferViewsU8 A dictionary of buffer view index to a Uint8Array of its contents. * @private */ function parseAvailability( @@ -812,10 +812,10 @@ function parseAvailability( * in-memory representation using an {@link ImplicitAvailabilityBitstream} * object. This handles both constants and bitstreams from a bufferView. * - * @param {Object} availabilityJson A JSON object representing the availability - * @param {Object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. - * @param {Number} lengthBits The length of the availability bitstream in bits - * @param {Boolean} [computeAvailableCountEnabled] If true and availabilityJson.availableCount is undefined, the availableCount will be computed. + * @param {object} availabilityJson A JSON object representing the availability + * @param {object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. + * @param {number} lengthBits The length of the availability bitstream in bits + * @param {boolean} [computeAvailableCountEnabled] If true and availabilityJson.availableCount is undefined, the availableCount will be computed. * @returns {ImplicitAvailabilityBitstream} The parsed bitstream object * @private */ @@ -857,7 +857,7 @@ function parseAvailabilityBitstream( * * @param {ImplicitSubtree} subtree The subtree * @param {ImplicitTileset} implicitTileset The implicit tileset this subtree belongs to. - * @param {Object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. + * @param {object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. * @private */ function parseTileMetadataTable(subtree, implicitTileset, bufferViewsU8) { @@ -882,7 +882,7 @@ function parseTileMetadataTable(subtree, implicitTileset, bufferViewsU8) { * * @param {ImplicitSubtree} subtree The subtree * @param {ImplicitTileset} implicitTileset The implicit tileset this subtree belongs to. - * @param {Object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. + * @param {object} bufferViewsU8 A dictionary of bufferView index to its Uint8Array contents. * @private */ function parseContentMetadataTables(subtree, implicitTileset, bufferViewsU8) { @@ -979,7 +979,7 @@ function makeContentJumpBuffers(subtree) { * Given the implicit tiling coordinates for a tile, get the index within the * subtree's tile availability bitstream. * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a tile - * @return {Number} The tile's index within the subtree. + * @return {number} The tile's index within the subtree. * @private */ ImplicitSubtree.prototype.getTileIndex = function (implicitCoordinates) { @@ -1001,7 +1001,7 @@ ImplicitSubtree.prototype.getTileIndex = function (implicitCoordinates) { * Given the implicit tiling coordinates for a child subtree, get the index within the * subtree's child subtree availability bitstream. * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a child subtree - * @return {Number} The child subtree's index within the subtree's child subtree availability bitstream. + * @return {number} The child subtree's index within the subtree's child subtree availability bitstream. * @private */ ImplicitSubtree.prototype.getChildSubtreeIndex = function ( @@ -1028,7 +1028,7 @@ ImplicitSubtree.prototype.getChildSubtreeIndex = function ( * Get the entity ID for a tile within this subtree. * @param {ImplicitSubtree} subtree The subtree * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a tile - * @return {Number} The entity ID for this tile for accessing tile metadata, or <code>undefined</code> if not applicable. + * @return {number} The entity ID for this tile for accessing tile metadata, or <code>undefined</code> if not applicable. * * @private */ @@ -1049,8 +1049,8 @@ function getTileEntityId(subtree, implicitCoordinates) { * Get the entity ID for a content within this subtree. * @param {ImplicitSubtree} subtree The subtree * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a content - * @param {Number} contentIndex The content index, for distinguishing between multiple contents. - * @return {Number} The entity ID for this content for accessing content metadata, or <code>undefined</code> if not applicable. + * @param {number} contentIndex The content index, for distinguishing between multiple contents. + * @return {number} The entity ID for this content for accessing content metadata, or <code>undefined</code> if not applicable. * * @private */ @@ -1100,7 +1100,7 @@ ImplicitSubtree.prototype.getTileMetadataView = function (implicitCoordinates) { /** * Create and return a metadata table view for a content within this subtree. * @param {ImplicitTileCoordinates} implicitCoordinates The global coordinates of a content - * @param {Number} contentIndex The index of the content used to distinguish between multiple contents + * @param {number} contentIndex The index of the content used to distinguish between multiple contents * @return {ImplicitMetadataView} The metadata view for this content, or <code>undefined</code> if not applicable. * * @private diff --git a/packages/engine/Source/Scene/ImplicitSubtreeCache.js b/packages/engine/Source/Scene/ImplicitSubtreeCache.js index b9bc554a764..252594d37bb 100644 --- a/packages/engine/Source/Scene/ImplicitSubtreeCache.js +++ b/packages/engine/Source/Scene/ImplicitSubtreeCache.js @@ -6,8 +6,8 @@ import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js"; * @alias ImplicitSubtreeCache * @constructor * - * @param {Object} [options] Object with the following properties - * @param {Number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. + * @param {object} [options] Object with the following properties + * @param {number} [options.maximumSubtreeCount=0] The total number of subtrees this cache can store. If adding a new subtree would exceed this limit, the lowest priority subtrees will be removed until there is room, unless the subtree that is going to be removed is the parent of the new subtree, in which case it will not be removed and the new subtree will still be added, exceeding the memory limit. * * @private */ @@ -15,14 +15,14 @@ function ImplicitSubtreeCache(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); /** - * @type {Number} + * @type {number} * @private */ this._maximumSubtreeCount = defaultValue(options.maximumSubtreeCount, 0); /** * A counter that goes up whenever a subtree is added. Used to sort subtrees by recency. - * @type {Number} + * @type {number} * @private */ this._subtreeRequestCounter = 0; @@ -96,7 +96,7 @@ ImplicitSubtreeCache.prototype.find = function (subtreeCoord) { /** * @param {ImplicitSubtreeCacheNode} a * @param {ImplicitSubtreeCacheNode} b - * @returns {Number} + * @returns {number} */ ImplicitSubtreeCache.comparator = function (a, b) { const aCoord = a.subtree.implicitCoordinates; @@ -115,7 +115,7 @@ ImplicitSubtreeCache.comparator = function (a, b) { * @constructor * * @param {ImplicitSubtree} subtree - * @param {Number} stamp + * @param {number} stamp * * @private */ diff --git a/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js b/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js index d4d05c20553..2fa2c797c62 100644 --- a/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js +++ b/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js @@ -9,8 +9,8 @@ import MetadataEntity from "./MetadataEntity.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.subtreeMetadata The subtree metadata JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.subtreeMetadata The subtree metadata JSON object. * @param {MetadataClass} options.class The class that subtree metadata conforms to. * * @alias ImplicitSubtreeMetadata @@ -57,7 +57,7 @@ Object.defineProperties(ImplicitSubtreeMetadata.prototype, { * Extra user-defined properties. * * @memberof ImplicitSubtreeMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -71,7 +71,7 @@ Object.defineProperties(ImplicitSubtreeMetadata.prototype, { * An object containing extensions. * * @memberof ImplicitSubtreeMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -85,8 +85,8 @@ Object.defineProperties(ImplicitSubtreeMetadata.prototype, { /** * Returns whether the subtree has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the subtree has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the subtree has this property. * @private */ ImplicitSubtreeMetadata.prototype.hasProperty = function (propertyId) { @@ -96,8 +96,8 @@ ImplicitSubtreeMetadata.prototype.hasProperty = function (propertyId) { /** * Returns whether the subtree has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the subtree has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the subtree has a property with the given semantic. * @private */ ImplicitSubtreeMetadata.prototype.hasPropertyBySemantic = function (semantic) { @@ -111,8 +111,8 @@ ImplicitSubtreeMetadata.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ ImplicitSubtreeMetadata.prototype.getPropertyIds = function (results) { @@ -125,7 +125,7 @@ ImplicitSubtreeMetadata.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the subtree does not have this property. * @private */ @@ -139,9 +139,9 @@ ImplicitSubtreeMetadata.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ ImplicitSubtreeMetadata.prototype.setProperty = function (propertyId, value) { @@ -156,7 +156,7 @@ ImplicitSubtreeMetadata.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the subtree does not have this semantic. * @private */ @@ -171,9 +171,9 @@ ImplicitSubtreeMetadata.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ ImplicitSubtreeMetadata.prototype.setPropertyBySemantic = function ( diff --git a/packages/engine/Source/Scene/ImplicitTileCoordinates.js b/packages/engine/Source/Scene/ImplicitTileCoordinates.js index 7ad18c68999..efcc652fe3d 100644 --- a/packages/engine/Source/Scene/ImplicitTileCoordinates.js +++ b/packages/engine/Source/Scene/ImplicitTileCoordinates.js @@ -38,13 +38,13 @@ import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js"; * @alias ImplicitTileCoordinates * @constructor * - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {ImplicitSubdivisionScheme} options.subdivisionScheme Whether the coordinates are for a quadtree or octree - * @param {Number} options.subtreeLevels The number of distinct levels within the coordinate's subtree - * @param {Number} options.level The level of a tile relative to the tile with the extension - * @param {Number} options.x The x coordinate of the tile - * @param {Number} options.y The y coordinate of the tile - * @param {Number} [options.z] The z coordinate of the tile. Only required when options.subdivisionScheme is ImplicitSubdivisionScheme.OCTREE + * @param {number} options.subtreeLevels The number of distinct levels within the coordinate's subtree + * @param {number} options.level The level of a tile relative to the tile with the extension + * @param {number} options.x The x coordinate of the tile + * @param {number} options.y The y coordinate of the tile + * @param {number} [options.z] The z coordinate of the tile. Only required when options.subdivisionScheme is ImplicitSubdivisionScheme.OCTREE * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -101,7 +101,7 @@ function ImplicitTileCoordinates(options) { /** * The number of distinct levels within the coordinate's subtree * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -112,7 +112,7 @@ function ImplicitTileCoordinates(options) { * (3D Tiles 1.1) or the <code>3DTILES_implicit_tiling</code> extension. * Level numbers start at 0. * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -121,7 +121,7 @@ function ImplicitTileCoordinates(options) { /** * X coordinate of this tile * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -130,7 +130,7 @@ function ImplicitTileCoordinates(options) { /** * Y coordinate of this tile * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -139,7 +139,7 @@ function ImplicitTileCoordinates(options) { /** * Z coordinate of this tile. Only defined for octrees. * - * @type {Number|undefined} + * @type {number|undefined} * @readonly * @private */ @@ -159,7 +159,7 @@ Object.defineProperties(ImplicitTileCoordinates.prototype, { * be computed more directly by concatenating the bits [z0] y0 x0 * </p> * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -180,7 +180,7 @@ Object.defineProperties(ImplicitTileCoordinates.prototype, { * Get the Morton index for this tile within the current level by interleaving * the bits of the x, y and z coordinates. * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -196,7 +196,7 @@ Object.defineProperties(ImplicitTileCoordinates.prototype, { /** * Get the tile index by adding the Morton index to the level offset * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -276,7 +276,7 @@ ImplicitTileCoordinates.prototype.getDescendantCoordinates = function ( /** * Compute the coordinates of a tile higher up in the tree by going up a number of levels. * - * @param {Number} offsetLevels The number of levels to go up in the tree + * @param {number} offsetLevels The number of levels to go up in the tree * @returns {ImplicitTileCoordinates} The coordinates of the ancestor * @private */ @@ -374,7 +374,7 @@ ImplicitTileCoordinates.prototype.getOffsetCoordinates = function ( * Given the morton index of the child, compute the coordinates of the child. * This is a special case of {@link ImplicitTileCoordinates#getDescendantCoordinates}. * - * @param {Number} childIndex The morton index of the child tile relative to its parent + * @param {number} childIndex The morton index of the child tile relative to its parent * @returns {ImplicitTileCoordinates} The tile coordinates of the child * @private */ @@ -444,7 +444,7 @@ ImplicitTileCoordinates.prototype.getParentSubtreeCoordinates = function () { * Returns whether this tile is an ancestor of another tile * * @param {ImplicitTileCoordinates} descendantCoordinates the descendant coordinates - * @returns {Boolean} <code>true</code> if this tile is an ancestor of the other tile + * @returns {boolean} <code>true</code> if this tile is an ancestor of the other tile * @private */ ImplicitTileCoordinates.prototype.isAncestor = function ( @@ -479,7 +479,7 @@ ImplicitTileCoordinates.prototype.isAncestor = function ( * Returns whether the provided coordinates are equal to this coordinate * * @param {ImplicitTileCoordinates} otherCoordinates the other coordinates - * @returns {Boolean} <code>true</code> if the coordinates are equal + * @returns {boolean} <code>true</code> if the coordinates are equal * @private */ ImplicitTileCoordinates.prototype.isEqual = function (otherCoordinates) { @@ -502,7 +502,7 @@ ImplicitTileCoordinates.prototype.isEqual = function (otherCoordinates) { /** * Returns whether this tile is the root of the implicit tileset * - * @returns {Boolean} <code>true</code> if this tile is the root + * @returns {boolean} <code>true</code> if this tile is the root * @private */ ImplicitTileCoordinates.prototype.isImplicitTilesetRoot = function () { @@ -512,7 +512,7 @@ ImplicitTileCoordinates.prototype.isImplicitTilesetRoot = function () { /** * Returns whether this tile is the root of the subtree * - * @returns {Boolean} <code>true</code> if this tile is the root of the subtree + * @returns {boolean} <code>true</code> if this tile is the root of the subtree * @private */ ImplicitTileCoordinates.prototype.isSubtreeRoot = function () { @@ -522,7 +522,7 @@ ImplicitTileCoordinates.prototype.isSubtreeRoot = function () { /** * Returns whether this tile is on the last row of tiles in the subtree * - * @returns {Boolean} <code>true</code> if this tile is on the last row of tiles in the subtree + * @returns {boolean} <code>true</code> if this tile is on the last row of tiles in the subtree * @private */ ImplicitTileCoordinates.prototype.isBottomOfSubtree = function () { @@ -532,7 +532,7 @@ ImplicitTileCoordinates.prototype.isBottomOfSubtree = function () { /** * Get a dictionary of values for templating into an implicit template URI. * - * @returns {Object} An object suitable for use with {@link Resource#getDerivedResource} + * @returns {object} An object suitable for use with {@link Resource#getDerivedResource} * @private */ ImplicitTileCoordinates.prototype.getTemplateValues = function () { @@ -555,9 +555,9 @@ const scratchCoordinatesArray = [0, 0, 0]; * octree/quadtree, compute the (level, x, y, [z]) coordinates * * @param {ImplicitSubdivisionScheme} subdivisionScheme Whether the coordinates are for a quadtree or octree - * @param {Number} subtreeLevels The number of distinct levels within the coordinate's subtree - * @param {Number} level The level of the tree - * @param {Number} mortonIndex The morton index of the tile. + * @param {number} subtreeLevels The number of distinct levels within the coordinate's subtree + * @param {number} level The level of the tree + * @param {number} mortonIndex The morton index of the tile. * @returns {ImplicitTileCoordinates} The coordinates of the tile with the given Morton index * @private */ @@ -598,8 +598,8 @@ ImplicitTileCoordinates.fromMortonIndex = function ( * the (level, x, y, [z]) coordinates * * @param {ImplicitSubdivisionScheme} subdivisionScheme Whether the coordinates are for a quadtree or octree - * @param {Number} subtreeLevels The number of distinct levels within the coordinate's subtree - * @param {Number} tileIndex The tile's index + * @param {number} subtreeLevels The number of distinct levels within the coordinate's subtree + * @param {number} tileIndex The tile's index * @returns {ImplicitTileCoordinates} The coordinates of the tile with the given tile index * @private */ diff --git a/packages/engine/Source/Scene/ImplicitTileset.js b/packages/engine/Source/Scene/ImplicitTileset.js index 45473db61de..7b114d6dcef 100644 --- a/packages/engine/Source/Scene/ImplicitTileset.js +++ b/packages/engine/Source/Scene/ImplicitTileset.js @@ -17,7 +17,7 @@ import ImplicitSubdivisionScheme from "./ImplicitSubdivisionScheme.js"; * @constructor * * @param {Resource} baseResource The base resource for the tileset - * @param {Object} tileJson The JSON header of the tile with either implicit tiling (3D Tiles 1.1) or the 3DTILES_implicit_tiling extension. + * @param {object} tileJson The JSON header of the tile with either implicit tiling (3D Tiles 1.1) or the 3DTILES_implicit_tiling extension. * @param {MetadataSchema} [metadataSchema] The metadata schema containing the implicit tile metadata class. * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -45,7 +45,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { /** * The geometric error of the root tile * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -76,7 +76,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * The JSON representation of a bounding volume. This is either a box or a * region. * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -85,7 +85,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { /** * The refine strategy as a string, either 'ADD' or 'REPLACE' * - * @type {String} + * @type {string} * @readonly * @private */ @@ -141,7 +141,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * The maximum number of contents as well as content availability bitstreams. * This is used for loop bounds when checking content availability. * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -160,7 +160,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * <li><code>tile.extensions["3DTILES_multiple_contents"]</code>, if used instead of tile.contents or tile.content</li> * </ul> * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -180,7 +180,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * The branching factor for this tileset. Either 4 for quadtrees or 8 for * octrees. * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -192,7 +192,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * How many distinct levels within each subtree. For example, a quadtree * with subtreeLevels = 2 will have 5 nodes per quadtree (1 root + 4 children) * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -201,7 +201,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { /** * The number of levels containing available tiles in the tileset. * - * @type {Number} + * @type {number} * @readonly * @private */ @@ -217,7 +217,7 @@ function ImplicitTileset(baseResource, tileJson, metadataSchema) { * This handles both regular tiles and tiles with multiple contents, either * in the contents array (3D Tiles 1.1) or the `3DTILES_multiple_contents` extension * - * @param {Object} tileJson The JSON header of the tile with either implicit tiling (3D Tiles 1.1) or the 3DTILES_implicit_tiling extension. + * @param {object} tileJson The JSON header of the tile with either implicit tiling (3D Tiles 1.1) or the 3DTILES_implicit_tiling extension. * @return {Object[]} An array of JSON headers for the contents of each tile * @private */ diff --git a/packages/engine/Source/Scene/InstanceAttributeSemantic.js b/packages/engine/Source/Scene/InstanceAttributeSemantic.js index d9e17b99e9d..09b4348ae52 100644 --- a/packages/engine/Source/Scene/InstanceAttributeSemantic.js +++ b/packages/engine/Source/Scene/InstanceAttributeSemantic.js @@ -3,7 +3,7 @@ import Check from "../Core/Check.js"; /** * An enum describing the built-in instance attribute semantics. * - * @enum {String} + * @enum {string} * * @private */ @@ -11,7 +11,7 @@ const InstanceAttributeSemantic = { /** * Per-instance translation. * - * @type {String} + * @type {string} * @constant */ TRANSLATION: "TRANSLATION", @@ -19,7 +19,7 @@ const InstanceAttributeSemantic = { /** * Per-instance rotation. * - * @type {String} + * @type {string} * @constant */ ROTATION: "ROTATION", @@ -27,7 +27,7 @@ const InstanceAttributeSemantic = { /** * Per-instance scale. * - * @type {String} + * @type {string} * @constant */ SCALE: "SCALE", @@ -35,7 +35,7 @@ const InstanceAttributeSemantic = { /** * Per-instance feature ID. * - * @type {String} + * @type {string} * @constant */ FEATURE_ID: "_FEATURE_ID", diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 99ee11783ec..16d4a83a91f 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -36,13 +36,13 @@ const ImageryProviderMapping = { }; /** - * @typedef {Object} IonImageryProvider.ConstructorOptions + * @typedef {object} IonImageryProvider.ConstructorOptions * * Initialization options for the TileMapServiceImageryProvider constructor * - * @property {Number} assetId An ion imagery asset ID - * @property {String} [accessToken=Ion.defaultAccessToken] The access token to use. - * @property {String|Resource} [server=Ion.defaultServer] The resource to the Cesium ion API server. + * @property {number} assetId An ion imagery asset ID + * @property {string} [accessToken=Ion.defaultAccessToken] The access token to use. + * @property {string|Resource} [server=Ion.defaultServer] The resource to the Cesium ion API server. */ /** @@ -68,7 +68,7 @@ function IonImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -77,7 +77,7 @@ function IonImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -86,7 +86,7 @@ function IonImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -95,7 +95,7 @@ function IonImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -104,7 +104,7 @@ function IonImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -112,7 +112,7 @@ function IonImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -121,7 +121,7 @@ function IonImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -129,7 +129,7 @@ function IonImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -222,7 +222,7 @@ Object.defineProperties(IonImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof IonImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -234,7 +234,7 @@ Object.defineProperties(IonImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof IonImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -267,7 +267,7 @@ Object.defineProperties(IonImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link IonImageryProvider#ready} returns true. * @memberof IonImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -287,7 +287,7 @@ Object.defineProperties(IonImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link IonImageryProvider#ready} returns true. * @memberof IonImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -307,7 +307,7 @@ Object.defineProperties(IonImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link IonImageryProvider#ready} returns true. * @memberof IonImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -331,7 +331,7 @@ Object.defineProperties(IonImageryProvider.prototype, { * provider with more than a few tiles at the minimum level will lead to * rendering problems. * @memberof IonImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -431,7 +431,7 @@ Object.defineProperties(IonImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof IonImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -465,9 +465,9 @@ Object.defineProperties(IonImageryProvider.prototype, { * Gets the credits to be displayed when a given tile is displayed. * @function * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -494,11 +494,11 @@ IonImageryProvider.prototype.getTileCredits = function (x, y, level) { * not be called before {@link IonImageryProvider#ready} returns true. * @function * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -521,12 +521,12 @@ IonImageryProvider.prototype.requestImage = function (x, y, level, request) { * * @function * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. diff --git a/packages/engine/Source/Scene/IonWorldImageryStyle.js b/packages/engine/Source/Scene/IonWorldImageryStyle.js index 68e4fc220af..a1a320492c6 100644 --- a/packages/engine/Source/Scene/IonWorldImageryStyle.js +++ b/packages/engine/Source/Scene/IonWorldImageryStyle.js @@ -3,13 +3,13 @@ /** * The types of imagery provided by {@link createWorldImagery}. * - * @enum {Number} + * @enum {number} */ const IonWorldImageryStyle = { /** * Aerial imagery. * - * @type {Number} + * @type {number} * @constant */ AERIAL: 2, @@ -17,7 +17,7 @@ const IonWorldImageryStyle = { /** * Aerial imagery with a road overlay. * - * @type {Number} + * @type {number} * @constant */ AERIAL_WITH_LABELS: 3, @@ -25,7 +25,7 @@ const IonWorldImageryStyle = { /** * Roads without additional imagery. * - * @type {Number} + * @type {number} * @constant */ ROAD: 4, diff --git a/packages/engine/Source/Scene/JsonMetadataTable.js b/packages/engine/Source/Scene/JsonMetadataTable.js index 2d43ecd740f..6d6f8a932e1 100644 --- a/packages/engine/Source/Scene/JsonMetadataTable.js +++ b/packages/engine/Source/Scene/JsonMetadataTable.js @@ -7,9 +7,9 @@ import MetadataEntity from "./MetadataEntity.js"; /** * A table for storing free-form JSON metadata, as in the 3D Tiles batch table. * - * @param {Object} options Object with the following properties: - * @param {Number} options.count The number of entities in the table. - * @param {Object.<String, Array>} options.properties The JSON representation of the metadata table. All the arrays must have exactly options.count elements. + * @param {object} options Object with the following properties: + * @param {number} options.count The number of entities in the table. + * @param {Object.<string, Array>} options.properties The JSON representation of the metadata table. All the arrays must have exactly options.count elements. * * @alias JsonMetadataTable * @constructor @@ -33,8 +33,8 @@ function JsonMetadataTable(options) { /** * Returns whether the table has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the table has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the table has this property. * @private */ JsonMetadataTable.prototype.hasProperty = function (propertyId) { @@ -44,8 +44,8 @@ JsonMetadataTable.prototype.hasProperty = function (propertyId) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ JsonMetadataTable.prototype.getPropertyIds = function (results) { @@ -55,8 +55,8 @@ JsonMetadataTable.prototype.getPropertyIds = function (results) { /** * Returns a copy of the value of the property with the given ID. * - * @param {Number} index The index of the entity. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the entity. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * * @exception {DeveloperError} index is out of bounds @@ -84,8 +84,8 @@ JsonMetadataTable.prototype.getProperty = function (index, propertyId) { * Sets the value of the property with the given ID. If the property did not * exist, it will be created. * - * @param {Number} index The index of the entity. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the entity. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. * * @exception {DeveloperError} index is out of bounds diff --git a/packages/engine/Source/Scene/KeyframeNode.js b/packages/engine/Source/Scene/KeyframeNode.js index 2ce89690525..56d3f8a69d3 100644 --- a/packages/engine/Source/Scene/KeyframeNode.js +++ b/packages/engine/Source/Scene/KeyframeNode.js @@ -12,7 +12,7 @@ const LoadState = Object.freeze({ * @constructor * * @param {SpatialNode} spatialNode - * @param {Number} keyframe + * @param {number} keyframe * * @private */ diff --git a/packages/engine/Source/Scene/Label.js b/packages/engine/Source/Scene/Label.js index ac8944de69a..22fe3501279 100644 --- a/packages/engine/Source/Scene/Label.js +++ b/packages/engine/Source/Scene/Label.js @@ -240,7 +240,7 @@ Object.defineProperties(Label.prototype, { * Determines if this label will be shown. Use this to hide or show a label, instead * of removing it and re-adding it to the collection. * @memberof Label.prototype - * @type {Boolean} + * @type {boolean} * @default true */ show: { @@ -351,7 +351,7 @@ Object.defineProperties(Label.prototype, { /** * Gets or sets the text of this label. * @memberof Label.prototype - * @type {String} + * @type {string} */ text: { get: function () { @@ -380,7 +380,7 @@ Object.defineProperties(Label.prototype, { /** * Gets or sets the font used to draw this label. Fonts are specified using the same syntax as the CSS 'font' property. * @memberof Label.prototype - * @type {String} + * @type {string} * @default '30px sans-serif' * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-styles|HTML canvas 2D context text styles} */ @@ -458,7 +458,7 @@ Object.defineProperties(Label.prototype, { /** * Gets or sets the outline width of this label. * @memberof Label.prototype - * @type {Number} + * @type {number} * @default 1.0 * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#fill-and-stroke-styles|HTML canvas 2D context fill and stroke styles} */ @@ -484,7 +484,7 @@ Object.defineProperties(Label.prototype, { * Determines if a background behind this label will be shown. * @memberof Label.prototype * @default false - * @type {Boolean} + * @type {boolean} */ showBackground: { get: function () { @@ -946,7 +946,7 @@ Object.defineProperties(Label.prototype, { * and <code>2.0</code>. * </div> * @memberof Label.prototype - * @type {Number} + * @type {number} * @default 1.0 */ scale: { @@ -984,7 +984,7 @@ Object.defineProperties(Label.prototype, { * Gets the total scale of the label, which is the label's scale multiplied by the computed relative size * of the desired font compared to the generated glyph size. * @memberof Label.prototype - * @type {Number} + * @type {number} * @default 1.0 */ totalScale: { @@ -1036,7 +1036,7 @@ Object.defineProperties(Label.prototype, { * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. * @memberof Label.prototype - * @type {Number} + * @type {number} */ disableDepthTestDistance: { get: function () { @@ -1143,7 +1143,7 @@ Object.defineProperties(Label.prototype, { /** * Determines whether or not this label will be shown or hidden because it was clustered. * @memberof Label.prototype - * @type {Boolean} + * @type {boolean} * @default true * @private */ @@ -1318,7 +1318,7 @@ Label.getScreenSpaceBoundingBox = function ( * are equal. Labels in different collections can be equal. * * @param {Label} other The label to compare for equality. - * @returns {Boolean} <code>true</code> if the labels are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the labels are equal; otherwise, <code>false</code>. */ Label.prototype.equals = function (other) { return ( @@ -1365,7 +1365,7 @@ Label.prototype.equals = function (other) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. */ Label.prototype.isDestroyed = function () { return false; @@ -1374,7 +1374,7 @@ Label.prototype.isDestroyed = function () { /** * Determines whether or not run the algorithm, that match the text of the label to right-to-left languages * @memberof Label - * @type {Boolean} + * @type {boolean} * @default false * * @example @@ -1476,8 +1476,8 @@ const rtlChars = new RegExp(`[${hebrew}${arabic}]`); /** * - * @param {String} value the text to parse and reorder - * @returns {String} the text as rightToLeft direction + * @param {string} value the text to parse and reorder + * @returns {string} the text as rightToLeft direction * @private */ function reverseRtl(value) { diff --git a/packages/engine/Source/Scene/LabelCollection.js b/packages/engine/Source/Scene/LabelCollection.js index 20940366cf5..87cdc39ae44 100644 --- a/packages/engine/Source/Scene/LabelCollection.js +++ b/packages/engine/Source/Scene/LabelCollection.js @@ -557,14 +557,14 @@ function destroyLabel(labelCollection, label) { * @alias LabelCollection * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each label from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Scene} [options.scene] Must be passed in for labels that use the height reference property or will be depth tested against the globe. * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The label blending option. The default * is used for rendering both opaque and translucent labels. However, if either all of the labels are completely opaque or all are completely translucent, * setting the technique to BlendOption.OPAQUE or BlendOption.TRANSLUCENT can improve performance by up to 2x. - * @param {Boolean} [options.show=true] Determines if the labels in the collection will be shown. + * @param {boolean} [options.show=true] Determines if the labels in the collection will be shown. * * @performance For best performance, prefer a few collections, each with many labels, to * many collections with only a few labels each. Avoid having collections where some @@ -622,7 +622,7 @@ function LabelCollection(options) { /** * Determines if labels in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -666,7 +666,7 @@ function LabelCollection(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -695,7 +695,7 @@ Object.defineProperties(LabelCollection.prototype, { * {@link LabelCollection#get} to iterate over all the labels * in the collection. * @memberof LabelCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -708,7 +708,7 @@ Object.defineProperties(LabelCollection.prototype, { * Creates and adds a label with the specified initial properties to the collection. * The added label is returned so it can be modified or removed from the collection later. * - * @param {Object} [options] A template describing the label's properties as shown in Example 1. + * @param {object} [options] A template describing the label's properties as shown in Example 1. * @returns {Label} The label that was added to the collection. * * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer @@ -769,7 +769,7 @@ LabelCollection.prototype.add = function (options) { * Removes a label from the collection. Once removed, a label is no longer usable. * * @param {Label} label The label to remove. - * @returns {Boolean} <code>true</code> if the label was removed; <code>false</code> if the label was not found in the collection. + * @returns {boolean} <code>true</code> if the label was removed; <code>false</code> if the label was not found in the collection. * * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For @@ -831,7 +831,7 @@ LabelCollection.prototype.removeAll = function () { * Check whether this collection contains a given label. * * @param {Label} label The label to check for. - * @returns {Boolean} true if this collection contains the label, false otherwise. + * @returns {boolean} true if this collection contains the label, false otherwise. * * @see LabelCollection#get * @@ -847,7 +847,7 @@ LabelCollection.prototype.contains = function (label) { * {@link LabelCollection#length} to iterate over all the labels * in the collection. * - * @param {Number} index The zero-based index of the billboard. + * @param {number} index The zero-based index of the billboard. * * @returns {Label} The label at the specified index. * @@ -957,7 +957,7 @@ LabelCollection.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see LabelCollection#destroy */ diff --git a/packages/engine/Source/Scene/LabelStyle.js b/packages/engine/Source/Scene/LabelStyle.js index bfae4664a02..2b318cd730b 100644 --- a/packages/engine/Source/Scene/LabelStyle.js +++ b/packages/engine/Source/Scene/LabelStyle.js @@ -1,7 +1,7 @@ /** * Describes how to draw a label. * - * @enum {Number} + * @enum {number} * * @see Label#style */ @@ -9,7 +9,7 @@ const LabelStyle = { /** * Fill the text of the label, but do not outline. * - * @type {Number} + * @type {number} * @constant */ FILL: 0, @@ -17,7 +17,7 @@ const LabelStyle = { /** * Outline the text of the label, but do not fill. * - * @type {Number} + * @type {number} * @constant */ OUTLINE: 1, @@ -25,7 +25,7 @@ const LabelStyle = { /** * Fill and outline the text of the label. * - * @type {Number} + * @type {number} * @constant */ FILL_AND_OUTLINE: 2, diff --git a/packages/engine/Source/Scene/Light.js b/packages/engine/Source/Scene/Light.js index 55da007fcfb..1fd3ac0616d 100644 --- a/packages/engine/Source/Scene/Light.js +++ b/packages/engine/Source/Scene/Light.js @@ -24,7 +24,7 @@ Object.defineProperties(Light.prototype, { /** * The intensity controls the strength of the light. <code>intensity</code> has a minimum value of 0.0 and no maximum value. * @memberof Light.prototype - * @type {Number} + * @type {number} */ intensity: { get: DeveloperError.throwInstantiationError, diff --git a/packages/engine/Source/Scene/MapMode2D.js b/packages/engine/Source/Scene/MapMode2D.js index 3a050da5bea..34830f23b83 100644 --- a/packages/engine/Source/Scene/MapMode2D.js +++ b/packages/engine/Source/Scene/MapMode2D.js @@ -1,13 +1,13 @@ /** * Describes how the map will operate in 2D. * - * @enum {Number} + * @enum {number} */ const MapMode2D = { /** * The 2D map can be rotated about the z axis. * - * @type {Number} + * @type {number} * @constant */ ROTATE: 0, @@ -15,7 +15,7 @@ const MapMode2D = { /** * The 2D map can be scrolled infinitely in the horizontal direction. * - * @type {Number} + * @type {number} * @constant */ INFINITE_SCROLL: 1, diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index baff4ff617f..0768b54ac8d 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -11,21 +11,21 @@ const defaultCredit = new Credit( ); /** - * @typedef {Object} MapboxImageryProvider.ConstructorOptions + * @typedef {object} MapboxImageryProvider.ConstructorOptions * * Initialization options for the MapboxImageryProvider constructor * - * @property {String} [url='https://api.mapbox.com/v4/'] The Mapbox server url. - * @property {String} mapId The Mapbox Map ID. - * @property {String} accessToken The public access token for the imagery. - * @property {String} [format='png'] The format of the image request. + * @property {string} [url='https://api.mapbox.com/v4/'] The Mapbox server url. + * @property {string} mapId The Mapbox Map ID. + * @property {string} accessToken The public access token for the imagery. + * @property {string} [format='png'] The format of the image request. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely * to result in rendering problems. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. */ /** @@ -66,7 +66,7 @@ function MapboxImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -75,7 +75,7 @@ function MapboxImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -84,7 +84,7 @@ function MapboxImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -93,7 +93,7 @@ function MapboxImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -102,7 +102,7 @@ function MapboxImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -110,7 +110,7 @@ function MapboxImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -119,7 +119,7 @@ function MapboxImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -127,7 +127,7 @@ function MapboxImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -197,7 +197,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets the URL of the Mapbox server. * @memberof MapboxImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -209,7 +209,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof MapboxImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -221,7 +221,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof MapboxImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -247,7 +247,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link MapboxImageryProvider#ready} returns true. * @memberof MapboxImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -260,7 +260,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link MapboxImageryProvider#ready} returns true. * @memberof MapboxImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -273,7 +273,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link MapboxImageryProvider#ready} returns true. * @memberof MapboxImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -290,7 +290,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * provider with more than a few tiles at the minimum level will lead to * rendering problems. * @memberof MapboxImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -374,7 +374,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof MapboxImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -387,9 +387,9 @@ Object.defineProperties(MapboxImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -402,11 +402,11 @@ MapboxImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link MapboxImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -421,12 +421,12 @@ MapboxImageryProvider.prototype.requestImage = function (x, y, level, request) { * This function is optional, so it may not exist on all ImageryProviders. * * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. diff --git a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js index 1382fdced6a..5ebdbf79c27 100644 --- a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js @@ -11,23 +11,23 @@ const defaultCredit = new Credit( ); /** - * @typedef {Object} MapboxStyleImageryProvider.ConstructorOptions + * @typedef {object} MapboxStyleImageryProvider.ConstructorOptions * * Initialization options for the MapboxStyleImageryProvider constructor * - * @property {Resource|String} [url='https://api.mapbox.com/styles/v1/'] The Mapbox server url. - * @property {String} [username='mapbox'] The username of the map account. - * @property {String} styleId The Mapbox Style ID. - * @property {String} accessToken The public access token for the imagery. - * @property {Number} [tilesize=512] The size of the image tiles. - * @property {Boolean} [scaleFactor] Determines if tiles are rendered at a @2x scale factor. + * @property {Resource|string} [url='https://api.mapbox.com/styles/v1/'] The Mapbox server url. + * @property {string} [username='mapbox'] The username of the map account. + * @property {string} styleId The Mapbox Style ID. + * @property {string} accessToken The public access token for the imagery. + * @property {number} [tilesize=512] The size of the image tiles. + * @property {boolean} [scaleFactor] Determines if tiles are rendered at a @2x scale factor. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely * to result in rendering problems. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. */ /** @@ -68,7 +68,7 @@ function MapboxStyleImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -77,7 +77,7 @@ function MapboxStyleImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -86,7 +86,7 @@ function MapboxStyleImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -95,7 +95,7 @@ function MapboxStyleImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -104,7 +104,7 @@ function MapboxStyleImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -112,7 +112,7 @@ function MapboxStyleImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -121,7 +121,7 @@ function MapboxStyleImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -129,7 +129,7 @@ function MapboxStyleImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -201,7 +201,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets the URL of the Mapbox server. * @memberof MapboxStyleImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -213,7 +213,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof MapboxStyleImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -225,7 +225,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof MapboxStyleImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -251,7 +251,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link MapboxStyleImageryProvider#ready} returns true. * @memberof MapboxStyleImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -264,7 +264,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link MapboxStyleImageryProvider#ready} returns true. * @memberof MapboxStyleImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -277,7 +277,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link MapboxStyleImageryProvider#ready} returns true. * @memberof MapboxStyleImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -294,7 +294,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * provider with more than a few tiles at the minimum level will lead to * rendering problems. * @memberof MapboxStyleImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -378,7 +378,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof MapboxStyleImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -391,9 +391,9 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -406,11 +406,11 @@ MapboxStyleImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link MapboxStyleImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -430,12 +430,12 @@ MapboxStyleImageryProvider.prototype.requestImage = function ( * This function is optional, so it may not exist on all ImageryProviders. * * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index ae68ed4467b..16c22d08ddc 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -55,33 +55,34 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; */ /** - * @typedef {Object} FabricComponents An object define all components will apply to fabric material. - * @property {String} [diffuse='vec3(0.0)'] Diffuse expression. - * @property {Number | String} [specular=0.0] Specular Expression. - * @property {Number | String} [shininess=1.0] Shininess Expression. - * @property {String} [normal] Normal Expression. - * @property {String} [emission='vec3(0.0)'] Emission Expression. - * @property {Number | String} [alpha=1] Alpha Expression. + * @typedef {object} FabricComponents An object define all components will apply to fabric material. + * @property {string} [diffuse='vec3(0.0)'] Diffuse expression. + * @property {number | String} [specular=0.0] Specular Expression. + * @property {number | String} [shininess=1.0] Shininess Expression. + * @property {string} [normal] Normal Expression. + * @property {string} [emission='vec3(0.0)'] Emission Expression. + * @property {number | String} [alpha=1] Alpha Expression. */ /** - * @typedef {Object} Fabric The fabric definition to a material template object. - * @property {String} type The material type. + * @typedef {object} Fabric The fabric definition to a material template object. + * @property {string} type The material type. * @property {FabricUniforms} uniforms The uniforms that will use during shadering. * @property {FabricComponents} components + * @property {string} source Shader code. */ /** * @callback TranslucentFunction A function determine material is translucent or not. * @param {Material} material - * @returns {Boolean} + * @returns {boolean} */ /** - * @typedef {Object} MaterialTemplate A material template object. - * @property {Boolean} strict + * @typedef {object} MaterialTemplate A material template object. + * @property {boolean} strict * @property {Fabric} fabric - * @property {Boolean | TranslucentFunction} translucent + * @property {boolean | TranslucentFunction} translucent */ /** @@ -272,10 +273,11 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * </div> * * @alias Material + * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. - * @param {Boolean | TranslucentFunction} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. + * @param {boolean | TranslucentFunction} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry * with this material is expected to appear translucent. * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The {@link TextureMinificationFilter} to apply to this material's textures. * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The {@link TextureMagnificationFilter} to apply to this material's textures. @@ -312,34 +314,32 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * } * } * }); - * - * @constructor */ function Material(options) { /** * The material type. Can be an existing type or a new type. If no type is specified in fabric, type is a GUID. - * @type {String} + * @type {string} * @default undefined */ this.type = undefined; /** * The glsl shader source for this material. - * @type {String} + * @type {string} * @default undefined */ this.shaderSource = undefined; /** * Maps sub-material names to Material objects. - * @type {Object} + * @type {object} * @default undefined */ this.materials = undefined; /** * Maps uniform names to their values. - * @type {Object} + * @type {object} * @default undefined */ this.uniforms = undefined; @@ -348,7 +348,7 @@ function Material(options) { /** * When <code>true</code> or a function that returns <code>true</code>, * the geometry is expected to appear translucent. - * @type {Boolean | TranslucentFunction} + * @type {boolean | TranslucentFunction} * @default undefined */ this.translucent = undefined; @@ -398,7 +398,7 @@ Material._uniformList = {}; * <br /><br /> * Shorthand for: new Material({fabric : {type : type}}); * - * @param {String} type The base material type. + * @param {string} type The base material type. * @param {FabricUniforms} [uniforms] Overrides for the default uniforms. * @returns {Material} New material object. * @@ -435,7 +435,7 @@ Material.fromType = function (type, uniforms) { /** * Gets whether or not this material is translucent. - * @returns {Boolean} <code>true</code> if this material is translucent, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if this material is translucent, <code>false</code> otherwise. */ Material.prototype.isTranslucent = function () { if (defined(this.translucent)) { @@ -586,7 +586,7 @@ Material.prototype.update = function (context) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see Material#destroy */ @@ -1257,7 +1257,7 @@ Material._materialCache = { _materials: {}, /** * Add a fabric material to - * @param {String} type The material type. + * @param {string} type The material type. * @param {MaterialTemplate} materialTemplate An object represent a fabric material. */ addMaterial: function (type, materialTemplate) { diff --git a/packages/engine/Source/Scene/MaterialAppearance.js b/packages/engine/Source/Scene/MaterialAppearance.js index be94c5d0032..06280407f4f 100644 --- a/packages/engine/Source/Scene/MaterialAppearance.js +++ b/packages/engine/Source/Scene/MaterialAppearance.js @@ -17,16 +17,16 @@ import Material from "./Material.js"; * @alias MaterialAppearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. - * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link MaterialAppearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link MaterialAppearance#renderState} has backface culling enabled. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. + * @param {boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link MaterialAppearance#renderState} has alpha blending enabled. + * @param {boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link MaterialAppearance#renderState} has backface culling enabled. * @param {MaterialAppearance.MaterialSupportType} [options.materialSupport=MaterialAppearance.MaterialSupport.TEXTURED] The type of materials that will be supported. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric} * @demo {@link https://sandcastle.cesium.com/index.html?src=Materials.html|Cesium Sandcastle Material Appearance Demo} @@ -73,7 +73,7 @@ function MaterialAppearance(options) { /** * When <code>true</code>, the geometry is expected to appear translucent. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -108,7 +108,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -125,7 +125,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -144,7 +144,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -160,7 +160,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -212,7 +212,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -231,7 +231,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @memberof MaterialAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -250,7 +250,7 @@ Object.defineProperties(MaterialAppearance.prototype, { * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ MaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -260,7 +260,7 @@ MaterialAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ MaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -271,17 +271,17 @@ MaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ MaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; /** * @typedef MaterialAppearance.MaterialSupportType - * @type {Object} + * @type {object} * @property {VertexFormat} vertexFormat - * @property {String} vertexShaderSource - * @property {String} fragmentShaderSource + * @property {string} vertexShaderSource + * @property {string} fragmentShaderSource */ /** diff --git a/packages/engine/Source/Scene/Megatexture.js b/packages/engine/Source/Scene/Megatexture.js index 5e9db2fc72a..759563bd9cf 100644 --- a/packages/engine/Source/Scene/Megatexture.js +++ b/packages/engine/Source/Scene/Megatexture.js @@ -23,9 +23,9 @@ import TextureWrap from "../Renderer/TextureWrap.js"; * * @param {Context} context * @param {Cartesian3} dimensions - * @param {Number} channelCount + * @param {number} channelCount * @param {MetadataComponentType} componentType - * @param {Number} [textureMemoryByteLength] + * @param {number} [textureMemoryByteLength] * * @private */ @@ -106,7 +106,7 @@ function Megatexture( } /** - * @type {Number} + * @type {number} * @readonly */ this.channelCount = channelCount; @@ -124,7 +124,7 @@ function Megatexture( this.voxelCountPerTile = Cartesian3.clone(dimensions, new Cartesian3()); /** - * @type {Number} + * @type {number} * @readonly */ this.maximumTileCount = @@ -245,7 +245,7 @@ function Megatexture( this.emptyList = this.nodes[0]; /** - * @type {Number} + * @type {number} * @readonly */ this.occupiedCount = 0; @@ -255,13 +255,13 @@ function Megatexture( * @alias MegatextureNode * @constructor * - * @param {Number} index + * @param {number} index * * @private */ function MegatextureNode(index) { /** - * @type {Number} + * @type {number} */ this.index = index; @@ -278,7 +278,7 @@ function MegatextureNode(index) { /** * @param {Array} data - * @returns {Number} + * @returns {number} */ Megatexture.prototype.add = function (data) { if (this.isFull()) { @@ -307,7 +307,7 @@ Megatexture.prototype.add = function (data) { }; /** - * @param {Number} index + * @param {number} index */ Megatexture.prototype.remove = function (index) { if (index < 0 || index >= this.maximumTileCount) { @@ -334,18 +334,18 @@ Megatexture.prototype.remove = function (index) { }; /** - * @returns {Boolean} + * @returns {boolean} */ Megatexture.prototype.isFull = function () { return this.emptyList === undefined; }; /** - * @param {Number} tileCount + * @param {number} tileCount * @param {Cartesian3} dimensions - * @param {Number} channelCount number of channels in the metadata. Must be 1 to 4. + * @param {number} channelCount number of channels in the metadata. Must be 1 to 4. * @param {MetadataComponentType} componentType - * @returns {Number} + * @returns {number} */ Megatexture.getApproximateTextureMemoryByteLength = function ( tileCount, @@ -393,7 +393,7 @@ Megatexture.getApproximateTextureMemoryByteLength = function ( }; /** - * @param {Number} index + * @param {number} index * @param {Float32Array|Uint16Array|Uint8Array} data */ Megatexture.prototype.writeDataToTexture = function (index, data) { @@ -459,7 +459,7 @@ Megatexture.prototype.writeDataToTexture = function (index, data) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Megatexture#destroy */ diff --git a/packages/engine/Source/Scene/MetadataClass.js b/packages/engine/Source/Scene/MetadataClass.js index 875c683e239..72d339e102a 100644 --- a/packages/engine/Source/Scene/MetadataClass.js +++ b/packages/engine/Source/Scene/MetadataClass.js @@ -11,13 +11,13 @@ import MetadataClassProperty from "./MetadataClassProperty.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata|3D Metadata Specification} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the class. - * @param {String} [options.name] The name of the class. - * @param {String} [options.description] The description of the class. - * @param {Object.<String, MetadataClassProperty>} [options.properties] The class properties, where each key is the property ID. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the class. + * @param {string} [options.name] The name of the class. + * @param {string} [options.description] The description of the class. + * @param {Object.<string, MetadataClassProperty>} [options.properties] The class properties, where each key is the property ID. * @param {*} [options.extras] Extra user-defined properties. - * @param {Object} [options.extensions] An object containing extensions. + * @param {object} [options.extensions] An object containing extensions. * * @alias MetadataClass * @constructor @@ -54,10 +54,10 @@ function MetadataClass(options) { /** * Creates a {@link MetadataClass} from either 3D Tiles 1.1, 3DTILES_metadata, EXT_structural_metadata, or EXT_feature_metadata. * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the class. - * @param {Object} options.class The class JSON object. - * @param {Object.<String, MetadataEnum>} [options.enums] A dictionary of enums. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the class. + * @param {object} options.class The class JSON object. + * @param {Object.<string, MetadataEnum>} [options.enums] A dictionary of enums. * * @returns {MetadataClass} The newly created metadata class. * @@ -101,7 +101,7 @@ Object.defineProperties(MetadataClass.prototype, { * The class properties. * * @memberof MetadataClass.prototype - * @type {Object.<String, MetadataClassProperty>} + * @type {Object.<string, MetadataClassProperty>} * @readonly */ properties: { @@ -114,7 +114,7 @@ Object.defineProperties(MetadataClass.prototype, { * A dictionary mapping semantics to class properties. * * @memberof MetadataClass.prototype - * @type {Object.<String, MetadataClassProperty>} + * @type {Object.<string, MetadataClassProperty>} * @readonly * * @private @@ -129,7 +129,7 @@ Object.defineProperties(MetadataClass.prototype, { * The ID of the class. * * @memberof MetadataClass.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -142,7 +142,7 @@ Object.defineProperties(MetadataClass.prototype, { * The name of the class. * * @memberof MetadataClass.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -155,7 +155,7 @@ Object.defineProperties(MetadataClass.prototype, { * The description of the class. * * @memberof MetadataClass.prototype - * @type {String} + * @type {string} * @readonly */ description: { @@ -181,7 +181,7 @@ Object.defineProperties(MetadataClass.prototype, { * An object containing extensions. * * @memberof MetadataClass.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { diff --git a/packages/engine/Source/Scene/MetadataClassProperty.js b/packages/engine/Source/Scene/MetadataClassProperty.js index f5dedda7a30..9d60464be83 100644 --- a/packages/engine/Source/Scene/MetadataClassProperty.js +++ b/packages/engine/Source/Scene/MetadataClassProperty.js @@ -18,27 +18,27 @@ import MetadataComponentType from "./MetadataComponentType.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata|3D Metadata Specification} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the property. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the property. * @param {MetadataType} options.type The type of the property such as SCALAR, VEC2, VEC3. * @param {MetadataComponentType} [options.componentType] The component type of the property. This includes integer (e.g. INT8 or UINT16), and floating point (FLOAT32 and FLOAT64) values. * @param {MetadataEnum} [options.enumType] The enum type of the property. Only defined when type is ENUM. - * @param {Boolean} [options.isArray=false] True if a property is an array (either fixed length or variable length), false otherwise. - * @param {Boolean} [options.isVariableLengthArray=false] True if a property is a variable length array, false otherwise. - * @param {Number} [options.arrayLength] The number of array elements. Only defined for fixed length arrays. - * @param {Boolean} [options.normalized=false] Whether the property is normalized. - * @param {Number|Number[]|Number[][]} [options.min] A number or an array of numbers storing the minimum allowable value of this property. Only defined when type is a numeric type. - * @param {Number|Number[]|Number[][]} [options.max] A number or an array of numbers storing the maximum allowable value of this property. Only defined when type is a numeric type. - * @param {Number|Number[]|Number[][]} [options.offset] The offset to be added to property values as part of the value transform. - * @param {Number|Number[]|Number[][]} [options.scale] The scale to be multiplied to property values as part of the value transform. - * @param {Boolean|Number|String|Array} [options.noData] The no-data sentinel value that represents null values. - * @param {Boolean|Number|String|Array} [options.default] A default value to use when an entity's property value is not defined. - * @param {Boolean} [options.required=false] Whether the property is required. - * @param {String} [options.name] The name of the property. - * @param {String} [options.description] The description of the property. - * @param {String} [options.semantic] An identifier that describes how this property should be interpreted. + * @param {boolean} [options.isArray=false] True if a property is an array (either fixed length or variable length), false otherwise. + * @param {boolean} [options.isVariableLengthArray=false] True if a property is a variable length array, false otherwise. + * @param {number} [options.arrayLength] The number of array elements. Only defined for fixed length arrays. + * @param {boolean} [options.normalized=false] Whether the property is normalized. + * @param {number|number[]|number[][]} [options.min] A number or an array of numbers storing the minimum allowable value of this property. Only defined when type is a numeric type. + * @param {number|number[]|number[][]} [options.max] A number or an array of numbers storing the maximum allowable value of this property. Only defined when type is a numeric type. + * @param {number|number[]|number[][]} [options.offset] The offset to be added to property values as part of the value transform. + * @param {number|number[]|number[][]} [options.scale] The scale to be multiplied to property values as part of the value transform. + * @param {boolean|number|string|Array} [options.noData] The no-data sentinel value that represents null values. + * @param {boolean|number|string|Array} [options.default] A default value to use when an entity's property value is not defined. + * @param {boolean} [options.required=false] Whether the property is required. + * @param {string} [options.name] The name of the property. + * @param {string} [options.description] The description of the property. + * @param {string} [options.semantic] An identifier that describes how this property should be interpreted. * @param {*} [options.extras] Extra user-defined properties. - * @param {Object} [options.extensions] An object containing extensions. + * @param {object} [options.extensions] An object containing extensions. * * @alias MetadataClassProperty * @constructor @@ -125,10 +125,10 @@ function MetadataClassProperty(options) { /** * Creates a {@link MetadataClassProperty} from either 3D Tiles 1.1, 3DTILES_metadata, EXT_structural_metadata, or EXT_feature_metadata. * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the property. - * @param {Object} options.property The property JSON object. - * @param {Object.<String, MetadataEnum>} [options.enums] A dictionary of enums. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the property. + * @param {object} options.property The property JSON object. + * @param {Object.<string, MetadataEnum>} [options.enums] A dictionary of enums. * * @returns {MetadataClassProperty} The newly created metadata class property. * @@ -197,7 +197,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The ID of the property. * * @memberof MetadataClassProperty.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -210,7 +210,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The name of the property. * * @memberof MetadataClassProperty.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -223,7 +223,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The description of the property. * * @memberof MetadataClassProperty.prototype - * @type {String} + * @type {string} * @readonly */ description: { @@ -293,7 +293,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * false otherwise. * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isArray: { @@ -306,7 +306,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * True if a property is a variable length array, false otherwise. * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ isVariableLengthArray: { @@ -320,7 +320,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * arrays. * * @memberof MetadataClassProperty.prototype - * @type {Number} + * @type {number} * @readonly */ arrayLength: { @@ -333,7 +333,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * Whether the property is normalized. * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ normalized: { @@ -346,7 +346,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * A number or an array of numbers storing the maximum allowable value of this property. Only defined when type is a numeric type. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly */ max: { @@ -359,7 +359,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * A number or an array of numbers storing the minimum allowable value of this property. Only defined when type is a numeric type. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly */ min: { @@ -372,7 +372,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The no-data sentinel value that represents null values * * @memberof MetadataClassProperty.prototype - * @type {Boolean|Number|String|Array} + * @type {boolean|number|string|Array} * @readonly */ noData: { @@ -385,7 +385,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * A default value to use when an entity's property value is not defined. * * @memberof MetadataClassProperty.prototype - * @type {Boolean|Number|String|Array} + * @type {boolean|number|string|Array} * @readonly */ default: { @@ -398,7 +398,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * Whether the property is required. * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ required: { @@ -411,7 +411,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * An identifier that describes how this property should be interpreted. * * @memberof MetadataClassProperty.prototype - * @type {String} + * @type {string} * @readonly */ semantic: { @@ -425,7 +425,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * undefined, they default to identity so this property is set false * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -439,7 +439,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The offset to be added to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly */ offset: { @@ -452,7 +452,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * The scale to be multiplied to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly */ scale: { @@ -478,7 +478,7 @@ Object.defineProperties(MetadataClassProperty.prototype, { * An object containing extensions. * * @memberof MetadataClassProperty.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { @@ -865,7 +865,7 @@ function arrayEquals(left, right) { * other sizes) are passed through unaltered. * * @param {*} value the original, normalized values. - * @param {Boolean} [enableNestedArrays=false] If true, arrays of vectors are represented as nested arrays. This is used for JSON encoding but not binary encoding + * @param {boolean} [enableNestedArrays=false] If true, arrays of vectors are represented as nested arrays. This is used for JSON encoding but not binary encoding * @returns {*} The appropriate vector or matrix type if the value is a vector or matrix type, respectively. If the property is an array of vectors or matrices, an array of the appropriate vector or matrix type is returned. Otherwise, the value is returned unaltered. * @private */ @@ -904,7 +904,7 @@ MetadataClassProperty.prototype.unpackVectorAndMatrixTypes = function ( * All other values (including arrays of other sizes) are passed through unaltered. * * @param {*} value The value of this property - * @param {Boolean} [enableNestedArrays=false] If true, arrays of vectors are represented as nested arrays. This is used for JSON encoding but not binary encoding + * @param {boolean} [enableNestedArrays=false] If true, arrays of vectors are represented as nested arrays. This is used for JSON encoding but not binary encoding * @returns {*} An array of the appropriate length if the property is a vector or matrix type. Otherwise, the value is returned unaltered. * @private */ @@ -939,7 +939,7 @@ MetadataClassProperty.prototype.packVectorAndMatrixTypes = function ( * Validates whether the given value conforms to the property. * * @param {*} value The value. - * @returns {String|undefined} An error message if the value does not conform to the property, otherwise undefined. + * @returns {string|undefined} An error message if the value does not conform to the property, otherwise undefined. * @private */ MetadataClassProperty.prototype.validate = function (value) { diff --git a/packages/engine/Source/Scene/MetadataComponentType.js b/packages/engine/Source/Scene/MetadataComponentType.js index 3093451e461..ad7ab3afdfc 100644 --- a/packages/engine/Source/Scene/MetadataComponentType.js +++ b/packages/engine/Source/Scene/MetadataComponentType.js @@ -7,49 +7,49 @@ import FeatureDetection from "../Core/FeatureDetection.js"; /** * An enum of metadata component types. * - * @enum {String} + * @enum {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ const MetadataComponentType = { /** * An 8-bit signed integer * - * @type {String} + * @type {string} * @constant */ INT8: "INT8", /** * An 8-bit unsigned integer * - * @type {String} + * @type {string} * @constant */ UINT8: "UINT8", /** * A 16-bit signed integer * - * @type {String} + * @type {string} * @constant */ INT16: "INT16", /** * A 16-bit unsigned integer * - * @type {String} + * @type {string} * @constant */ UINT16: "UINT16", /** * A 32-bit signed integer * - * @type {String} + * @type {string} * @constant */ INT32: "INT32", /** * A 32-bit unsigned integer * - * @type {String} + * @type {string} * @constant */ UINT32: "UINT32", @@ -58,7 +58,7 @@ const MetadataComponentType = { * * @see FeatureDetection.supportsBigInt * - * @type {String} + * @type {string} * @constant */ INT64: "INT64", @@ -67,21 +67,21 @@ const MetadataComponentType = { * * @see FeatureDetection.supportsBigInt * - * @type {String} + * @type {string} * @constant */ UINT64: "UINT64", /** * A 32-bit (single precision) floating point number * - * @type {String} + * @type {string} * @constant */ FLOAT32: "FLOAT32", /** * A 64-bit (double precision) floating point number * - * @type {String} + * @type {string} * @constant */ FLOAT64: "FLOAT64", @@ -95,7 +95,7 @@ const MetadataComponentType = { * </p> * * @param {MetadataComponentType} type The type. - * @returns {Number|BigInt} The minimum value. + * @returns {number|bigint} The minimum value. * * @private */ @@ -143,7 +143,7 @@ MetadataComponentType.getMinimum = function (type) { * </p> * * @param {MetadataComponentType} type The type. - * @returns {Number|BigInt} The maximum value. + * @returns {number|bigint} The maximum value. * * @private */ @@ -189,7 +189,7 @@ MetadataComponentType.getMaximum = function (type) { * Returns whether the type is an integer type. * * @param {MetadataComponentType} type The type. - * @returns {Boolean} Whether the type is an integer type. + * @returns {boolean} Whether the type is an integer type. * * @private */ @@ -217,7 +217,7 @@ MetadataComponentType.isIntegerType = function (type) { * Returns whether the type is an unsigned integer type. * * @param {MetadataComponentType} type The type. - * @returns {Boolean} Whether the type is an unsigned integer type. + * @returns {boolean} Whether the type is an unsigned integer type. * * @private */ @@ -242,7 +242,7 @@ MetadataComponentType.isUnsignedIntegerType = function (type) { * {@link Cartesian3}, or {@link Cartesian4} classes. This includes all numeric * types except for types requiring 64-bit integers * @param {MetadataComponentType} type The type to check - * @return {Boolean} <code>true</code> if the type can be encoded as a vector type, or <code>false</code> otherwise + * @return {boolean} <code>true</code> if the type can be encoded as a vector type, or <code>false</code> otherwise * @private */ MetadataComponentType.isVectorCompatible = function (type) { @@ -274,9 +274,9 @@ MetadataComponentType.isVectorCompatible = function (type) { * small precision differences. * </p> * - * @param {Number|BigInt} value The integer value. + * @param {number|bigint} value The integer value. * @param {MetadataComponentType} type The type. - * @returns {Number} The normalized value. + * @returns {number} The normalized value. * * @exception {DeveloperError} value must be a number or a BigInt * @exception {DeveloperError} type must be an integer type @@ -307,9 +307,9 @@ MetadataComponentType.normalize = function (value, type) { * Returns a BigInt for the INT64 and UINT64 types if BigInt is supported on this platform. * </p> * - * @param {Number} value The normalized value. + * @param {number} value The normalized value. * @param {MetadataComponentType} type The type. - * @returns {Number|BigInt} The integer value. + * @returns {number|bigint} The integer value. * * @exception {DeveloperError} type must be an integer type * @@ -371,7 +371,7 @@ MetadataComponentType.unapplyValueTransform = function (value, offset, scale) { * Gets the size in bytes for the numeric type. * * @param {MetadataComponentType} type The type. - * @returns {Number} The size in bytes. + * @returns {number} The size in bytes. * * @private */ diff --git a/packages/engine/Source/Scene/MetadataEntity.js b/packages/engine/Source/Scene/MetadataEntity.js index e6648aba79d..b33b6c78769 100644 --- a/packages/engine/Source/Scene/MetadataEntity.js +++ b/packages/engine/Source/Scene/MetadataEntity.js @@ -40,8 +40,8 @@ Object.defineProperties(MetadataEntity.prototype, { /** * Returns whether the entity has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the entity has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the entity has this property. * @private */ MetadataEntity.prototype.hasProperty = function (propertyId) { @@ -51,8 +51,8 @@ MetadataEntity.prototype.hasProperty = function (propertyId) { /** * Returns whether the entity has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the entity has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the entity has a property with the given semantic. * @private */ MetadataEntity.prototype.hasPropertyBySemantic = function (semantic) { @@ -62,8 +62,8 @@ MetadataEntity.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * @private */ MetadataEntity.prototype.getPropertyIds = function (results) { @@ -76,7 +76,7 @@ MetadataEntity.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * @private */ @@ -90,9 +90,9 @@ MetadataEntity.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ MetadataEntity.prototype.setProperty = function (propertyId, value) { @@ -102,7 +102,7 @@ MetadataEntity.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * @private */ @@ -113,9 +113,9 @@ MetadataEntity.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ MetadataEntity.prototype.setPropertyBySemantic = function (semantic, value) { @@ -125,10 +125,10 @@ MetadataEntity.prototype.setPropertyBySemantic = function (semantic, value) { /** * Returns whether the entity has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @param {Object} properties The dictionary containing properties. + * @param {string} propertyId The case-sensitive ID of the property. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. - * @returns {Boolean} Whether the entity has this property. + * @returns {boolean} Whether the entity has this property. * * @private */ @@ -163,10 +163,10 @@ MetadataEntity.hasProperty = function ( /** * Returns whether the entity has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @param {Object} properties The dictionary containing properties. + * @param {string} semantic The case-sensitive semantic of the property. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. - * @returns {Boolean} Whether the entity has a property with the given semantic. + * @returns {boolean} Whether the entity has a property with the given semantic. * * @private */ @@ -193,10 +193,10 @@ MetadataEntity.hasPropertyBySemantic = function ( /** * Returns an array of property IDs. * - * @param {Object} properties The dictionary containing properties. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {} The property IDs. * * @private */ @@ -246,8 +246,8 @@ MetadataEntity.getPropertyIds = function ( * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. - * @param {Object} properties The dictionary containing properties. + * @param {string} propertyId The case-sensitive ID of the property. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * @@ -301,11 +301,11 @@ MetadataEntity.getProperty = function ( * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @param {Object} properties The dictionary containing properties. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * * @private */ @@ -351,8 +351,8 @@ MetadataEntity.setProperty = function ( /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @param {Object} properties The dictionary containing properties. + * @param {string} semantic The case-sensitive semantic of the property. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * @@ -384,11 +384,11 @@ MetadataEntity.getPropertyBySemantic = function ( /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @param {Object} properties The dictionary containing properties. + * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ MetadataEntity.setPropertyBySemantic = function ( diff --git a/packages/engine/Source/Scene/MetadataEnum.js b/packages/engine/Source/Scene/MetadataEnum.js index d3f5cf671dd..913f6151d1f 100644 --- a/packages/engine/Source/Scene/MetadataEnum.js +++ b/packages/engine/Source/Scene/MetadataEnum.js @@ -10,14 +10,14 @@ import MetadataComponentType from "./MetadataComponentType.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata|3D Metadata Specification} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the enum. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the enum. * @param {MetadataEnumValue[]} options.values The enum values. * @param {MetadataComponentType} [options.valueType=MetadataComponentType.UINT16] The enum value type. - * @param {String} [options.name] The name of the enum. - * @param {String} [options.description] The description of the enum. + * @param {string} [options.name] The name of the enum. + * @param {string} [options.description] The description of the enum. * @param {*} [options.extras] Extra user-defined properties. - * @param {Object} [options.extensions] An object containing extensions. + * @param {object} [options.extensions] An object containing extensions. * * @alias MetadataEnum * @constructor @@ -62,9 +62,9 @@ function MetadataEnum(options) { /** * Creates a {@link MetadataEnum} from either 3D Tiles 1.1, 3DTILES_metadata, EXT_structural_metadata, or EXT_feature_metadata. * - * @param {Object} options Object with the following properties: - * @param {String} options.id The ID of the enum. - * @param {Object} options.enum The enum JSON object. + * @param {object} options Object with the following properties: + * @param {string} options.id The ID of the enum. + * @param {object} options.enum The enum JSON object. * * @returns {MetadataEnum} The newly created metadata enum. * @@ -129,7 +129,7 @@ Object.defineProperties(MetadataEnum.prototype, { * A dictionary mapping enum names to integer values. * * @memberof MetadataEnum.prototype - * @type {Object.<String, Number>} + * @type {Object.<string, Number>} * @readonly * * @private @@ -157,7 +157,7 @@ Object.defineProperties(MetadataEnum.prototype, { * The ID of the enum. * * @memberof MetadataEnum.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -170,7 +170,7 @@ Object.defineProperties(MetadataEnum.prototype, { * The name of the enum. * * @memberof MetadataEnum.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -183,7 +183,7 @@ Object.defineProperties(MetadataEnum.prototype, { * The description of the enum. * * @memberof MetadataEnum.prototype - * @type {String} + * @type {string} * @readonly */ description: { @@ -209,7 +209,7 @@ Object.defineProperties(MetadataEnum.prototype, { * An object containing extensions. * * @memberof MetadataEnum.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { diff --git a/packages/engine/Source/Scene/MetadataEnumValue.js b/packages/engine/Source/Scene/MetadataEnumValue.js index 5efec85e104..d08232daf26 100644 --- a/packages/engine/Source/Scene/MetadataEnumValue.js +++ b/packages/engine/Source/Scene/MetadataEnumValue.js @@ -8,12 +8,12 @@ import defaultValue from "../Core/defaultValue.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata|3D Metadata Specification} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {Number} options.value The integer value. - * @param {String} options.name The name of the enum value. - * @param {String} [options.description] The description of the enum value. + * @param {object} options Object with the following properties: + * @param {number} options.value The integer value. + * @param {string} options.name The name of the enum value. + * @param {string} [options.description] The description of the enum value. * @param {*} [options.extras] Extra user-defined properties. - * @param {Object} [options.extensions] An object containing extensions. + * @param {object} [options.extensions] An object containing extensions. * * @alias MetadataEnumValue * @constructor @@ -40,7 +40,7 @@ function MetadataEnumValue(options) { /** * Creates a {@link MetadataEnumValue} from either 3D Tiles 1.1, 3DTILES_metadata, EXT_structural_metadata, or EXT_feature_metadata. * - * @param {Object} value The enum value JSON object. + * @param {object} value The enum value JSON object. * * @returns {MetadataEnumValue} The newly created metadata enum value. * @@ -66,7 +66,7 @@ Object.defineProperties(MetadataEnumValue.prototype, { * The integer value. * * @memberof MetadataEnumValue.prototype - * @type {Number} + * @type {number} * @readonly */ value: { @@ -79,7 +79,7 @@ Object.defineProperties(MetadataEnumValue.prototype, { * The name of the enum value. * * @memberof MetadataEnumValue.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -92,7 +92,7 @@ Object.defineProperties(MetadataEnumValue.prototype, { * The description of the enum value. * * @memberof MetadataEnumValue.prototype - * @type {String} + * @type {string} * @readonly */ description: { @@ -118,7 +118,7 @@ Object.defineProperties(MetadataEnumValue.prototype, { * An object containing extensions. * * @memberof MetadataEnumValue.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { diff --git a/packages/engine/Source/Scene/MetadataSchema.js b/packages/engine/Source/Scene/MetadataSchema.js index e92677aca91..8aba71694df 100644 --- a/packages/engine/Source/Scene/MetadataSchema.js +++ b/packages/engine/Source/Scene/MetadataSchema.js @@ -11,15 +11,15 @@ import MetadataEnum from "./MetadataEnum.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata|3D Metadata Specification} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {String} [options.id] The ID of the schema - * @param {String} [options.name] The name of the schema. - * @param {String} [options.description] The description of the schema. - * @param {String} [options.version] The application-specific version of the schema. - * @param {Object.<String, MetadataClass>} [options.classes] Classes defined in the schema, where each key is the class ID. - * @param {Object.<String, MetadataEnum>} [options.enums] Enums defined in the schema, where each key is the enum ID. + * @param {object} options Object with the following properties: + * @param {string} [options.id] The ID of the schema + * @param {string} [options.name] The name of the schema. + * @param {string} [options.description] The description of the schema. + * @param {string} [options.version] The application-specific version of the schema. + * @param {Object.<string, MetadataClass>} [options.classes] Classes defined in the schema, where each key is the class ID. + * @param {Object.<string, MetadataEnum>} [options.enums] Enums defined in the schema, where each key is the enum ID. * @param {*} [options.extras] Extra user-defined properties. - * @param {Object} [options.extensions] An object containing extensions. + * @param {object} [options.extensions] An object containing extensions. * * @alias MetadataSchema * @constructor @@ -44,7 +44,7 @@ function MetadataSchema(options) { /** * Creates a {@link MetadataSchema} from either 3D Tiles 1.1, 3DTILES_metadata, EXT_structural_metadata, or EXT_feature_metadata. * - * @param {Object} schema The schema JSON object. + * @param {object} schema The schema JSON object. * * @returns {MetadataSchema} The newly created metadata schema * @@ -98,7 +98,7 @@ Object.defineProperties(MetadataSchema.prototype, { * Classes defined in the schema. * * @memberof MetadataSchema.prototype - * @type {Object.<String, MetadataClass>} + * @type {Object.<string, MetadataClass>} * @readonly */ classes: { @@ -111,7 +111,7 @@ Object.defineProperties(MetadataSchema.prototype, { * Enums defined in the schema. * * @memberof MetadataSchema.prototype - * @type {Object.<String, MetadataEnum>} + * @type {Object.<string, MetadataEnum>} * @readonly */ enums: { @@ -124,7 +124,7 @@ Object.defineProperties(MetadataSchema.prototype, { * The ID of the schema. * * @memberof MetadataSchema.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -137,7 +137,7 @@ Object.defineProperties(MetadataSchema.prototype, { * The name of the schema. * * @memberof MetadataSchema.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -150,7 +150,7 @@ Object.defineProperties(MetadataSchema.prototype, { * The description of the schema. * * @memberof MetadataSchema.prototype - * @type {String} + * @type {string} * @readonly */ description: { @@ -163,7 +163,7 @@ Object.defineProperties(MetadataSchema.prototype, { * The application-specific version of the schema. * * @memberof MetadataSchema.prototype - * @type {String} + * @type {string} * @readonly */ version: { @@ -189,7 +189,7 @@ Object.defineProperties(MetadataSchema.prototype, { * An object containing extensions. * * @memberof MetadataSchema.prototype - * @type {Object} + * @type {object} * @readonly */ extensions: { diff --git a/packages/engine/Source/Scene/MetadataSchemaLoader.js b/packages/engine/Source/Scene/MetadataSchemaLoader.js index be21b606d47..6fc9f0a05d5 100644 --- a/packages/engine/Source/Scene/MetadataSchemaLoader.js +++ b/packages/engine/Source/Scene/MetadataSchemaLoader.js @@ -15,10 +15,10 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @constructor * @augments ResourceLoader * - * @param {Object} options Object with the following properties: - * @param {Object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. + * @param {object} options Object with the following properties: + * @param {object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the schema JSON. Mutually exclusive with options.schema. - * @param {String} [options.cacheKey] The cache key of the resource. + * @param {string} [options.cacheKey] The cache key of the resource. * * @exception {DeveloperError} One of options.schema and options.resource must be defined. * @@ -57,7 +57,7 @@ Object.defineProperties(MetadataSchemaLoader.prototype, { * * @memberof MetadataSchemaLoader.prototype * - * @type {Promise.<MetadataSchemaLoader>|undefined} + * @type {Promise<MetadataSchemaLoader>|undefined} * @readonly * @private */ @@ -71,7 +71,7 @@ Object.defineProperties(MetadataSchemaLoader.prototype, { * * @memberof MetadataSchemaLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -98,7 +98,7 @@ Object.defineProperties(MetadataSchemaLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<MetadataSchemaLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<MetadataSchemaLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ MetadataSchemaLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/MetadataSemantic.js b/packages/engine/Source/Scene/MetadataSemantic.js index fbac2254754..867af8ac5fb 100644 --- a/packages/engine/Source/Scene/MetadataSemantic.js +++ b/packages/engine/Source/Scene/MetadataSemantic.js @@ -11,7 +11,7 @@ const MetadataSemantic = { /** * A unique identifier, stored as a <code>STRING</code>. * - * @type {String} + * @type {string} * @constant * @private */ @@ -19,7 +19,7 @@ const MetadataSemantic = { /** * A name, stored as a <code>STRING</code>. This does not have to be unique. * - * @type {String} + * @type {string} * @constant * @private */ @@ -27,7 +27,7 @@ const MetadataSemantic = { /** * A description, stored as a <code>STRING</code>. * - * @type {String} + * @type {string} * @constant * @private */ @@ -35,7 +35,7 @@ const MetadataSemantic = { /** * The number of tiles in a tileset, stored as a <code>UINT64</code>. * - * @type {String} + * @type {string} * @constant * @private */ @@ -43,7 +43,7 @@ const MetadataSemantic = { /** * A bounding box for a tile, stored as an array of 12 <code>FLOAT32</code> or <code>FLOAT64</code> components. The components are the same format as for <code>boundingVolume.box</code> in 3D Tiles 1.0. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -51,7 +51,7 @@ const MetadataSemantic = { /** * A bounding region for a tile, stored as an array of 6 <code>FLOAT64</code> components. The components are <code>[west, south, east, north, minimumHeight, maximumHeight]</code>. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -59,7 +59,7 @@ const MetadataSemantic = { /** * A bounding sphere for a tile, stored as an array of 4 <code>FLOAT32</code> or <code>FLOAT64</code> components. The components are <code>[centerX, centerY, centerZ, radius]</code>. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -67,7 +67,7 @@ const MetadataSemantic = { /** * The minimum height of a tile above (or below) the WGS84 ellipsoid, stored as a <code>FLOAT32</code> or a <code>FLOAT64</code>. This semantic is used to tighten bounding regions implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -75,7 +75,7 @@ const MetadataSemantic = { /** * The maximum height of a tile above (or below) the WGS84 ellipsoid, stored as a <code>FLOAT32</code> or a <code>FLOAT64</code>. This semantic is used to tighten bounding regions implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -85,7 +85,7 @@ const MetadataSemantic = { * * @see {@link https://cesium.com/blog/2013/04/25/horizon-culling/|Horizon Culling} * - * @type {String} + * @type {string} * @constant * @private */ @@ -93,7 +93,7 @@ const MetadataSemantic = { /** * The geometric error for a tile, stored as a <code>FLOAT32</code> or a <code>FLOAT64</code>. This semantic is used to override the geometric error implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -101,7 +101,7 @@ const MetadataSemantic = { /** * A bounding box for the content of a tile, stored as an array of 12 <code>FLOAT32</code> or <code>FLOAT64</code> components. The components are the same format as for <code>boundingVolume.box</code> in 3D Tiles 1.0. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -109,7 +109,7 @@ const MetadataSemantic = { /** * A bounding region for the content of a tile, stored as an array of 6 <code>FLOAT64</code> components. The components are <code>[west, south, east, north, minimumHeight, maximumHeight]</code>. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -117,7 +117,7 @@ const MetadataSemantic = { /** * A bounding sphere for the content of a tile, stored as an array of 4 <code>FLOAT32</code> or <code>FLOAT64</code> components. The components are <code>[centerX, centerY, centerZ, radius]</code>. This semantic is used to provide a tighter bounding volume than the one implicitly calculated in implicit tiling. * - * @type {String} + * @type {string} * @constant * @private */ @@ -125,7 +125,7 @@ const MetadataSemantic = { /** * The minimum height of the content of a tile above (or below) the WGS84 ellipsoid, stored as a <code>FLOAT32</code> or a <code>FLOAT64</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -133,7 +133,7 @@ const MetadataSemantic = { /** * The maximum height of the content of a tile above (or below) the WGS84 ellipsoid, stored as a <code>FLOAT32</code> or a <code>FLOAT64</code> * - * @type {String} + * @type {string} * @constant * @private */ @@ -143,7 +143,7 @@ const MetadataSemantic = { * * @see {@link https://cesium.com/blog/2013/04/25/horizon-culling/|Horizon Culling} * - * @type {String} + * @type {string} * @constant * @private */ diff --git a/packages/engine/Source/Scene/MetadataTable.js b/packages/engine/Source/Scene/MetadataTable.js index a660159ef4c..d1420080500 100644 --- a/packages/engine/Source/Scene/MetadataTable.js +++ b/packages/engine/Source/Scene/MetadataTable.js @@ -13,11 +13,11 @@ import MetadataTableProperty from "./MetadataTableProperty.js"; * For 3D Tiles Next details, see the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles, as well as the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: - * @param {Number} options.count The number of entities in the table. - * @param {Object} [options.properties] A dictionary containing properties. + * @param {object} options Object with the following properties: + * @param {number} options.count The number of entities in the table. + * @param {object} [options.properties] A dictionary containing properties. * @param {MetadataClass} options.class The class that properties conform to. - * @param {Object.<String, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. * * @alias MetadataTable * @constructor @@ -63,7 +63,7 @@ Object.defineProperties(MetadataTable.prototype, { * The number of entities in the table. * * @memberof MetadataTable.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -91,7 +91,7 @@ Object.defineProperties(MetadataTable.prototype, { * The size of all typed arrays used in this table. * * @memberof MetadataTable.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -105,8 +105,8 @@ Object.defineProperties(MetadataTable.prototype, { /** * Returns whether the table has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the table has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the table has this property. * @private */ MetadataTable.prototype.hasProperty = function (propertyId) { @@ -116,8 +116,8 @@ MetadataTable.prototype.hasProperty = function (propertyId) { /** * Returns whether the table has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the table has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the table has a property with the given semantic. * @private */ MetadataTable.prototype.hasPropertyBySemantic = function (semantic) { @@ -131,8 +131,8 @@ MetadataTable.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {string[]} The property IDs. * @private */ MetadataTable.prototype.getPropertyIds = function (results) { @@ -157,8 +157,8 @@ MetadataTable.prototype.getPropertyIds = function (results) { * may lose precision when read. * </p> * - * @param {Number} index The index of the entity. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the entity. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this property. * * @exception {DeveloperError} index is required and between zero and count - 1 @@ -200,10 +200,10 @@ MetadataTable.prototype.getProperty = function (index, propertyId) { * may lose precision when set." * </p> * - * @param {Number} index The index of the entity. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the entity. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * * @exception {DeveloperError} index is required and between zero and count - 1 * @exception {DeveloperError} value does not match type @@ -228,8 +228,8 @@ MetadataTable.prototype.setProperty = function (index, propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {Number} index The index of the entity. - * @param {String} semantic The case-sensitive semantic of the property. + * @param {number} index The index of the entity. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the entity does not have this semantic. * * @exception {DeveloperError} index is required and between zero and count - 1 @@ -256,10 +256,10 @@ MetadataTable.prototype.getPropertyBySemantic = function (index, semantic) { /** * Sets the value of the property with the given semantic. * - * @param {Number} index The index of the entity. - * @param {String} semantic The case-sensitive semantic of the property. + * @param {number} index The index of the entity. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * * @exception {DeveloperError} index is required and between zero and count - 1 * @exception {DeveloperError} value does not match type @@ -292,7 +292,7 @@ MetadataTable.prototype.setPropertyBySemantic = function ( /** * Returns a typed array containing the property values for a given propertyId. * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The typed array containing the property values or <code>undefined</code> if the property values are not stored in a typed array. * * @private @@ -314,7 +314,7 @@ MetadataTable.prototype.getPropertyTypedArray = function (propertyId) { /** * Returns a typed array containing the property values for the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The typed array containing the property values or <code>undefined</code> if the property values are not stored in a typed array. * * @private diff --git a/packages/engine/Source/Scene/MetadataTableProperty.js b/packages/engine/Source/Scene/MetadataTableProperty.js index 484eb713344..5d444dd5a2b 100644 --- a/packages/engine/Source/Scene/MetadataTableProperty.js +++ b/packages/engine/Source/Scene/MetadataTableProperty.js @@ -19,11 +19,11 @@ import MetadataType from "./MetadataType.js"; * for glTF. For the legacy glTF extension, see {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} * </p> * - * @param {Object} options Object with the following properties: - * @param {Number} options.count The number of elements in each property array. - * @param {Object} options.property The property JSON object. + * @param {object} options Object with the following properties: + * @param {number} options.count The number of elements in each property array. + * @param {object} options.property The property JSON object. * @param {MetadataClassProperty} options.classProperty The class property. - * @param {Object.<String, Uint8Array>} options.bufferViews An object mapping bufferView IDs to Uint8Array objects. + * @param {Object.<string, Uint8Array>} options.bufferViews An object mapping bufferView IDs to Uint8Array objects. * * @alias MetadataTableProperty * @constructor @@ -226,7 +226,7 @@ Object.defineProperties(MetadataTableProperty.prototype, { * undefined, they default to identity so this property is set false * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -240,7 +240,7 @@ Object.defineProperties(MetadataTableProperty.prototype, { * The offset to be added to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly * @private */ @@ -254,7 +254,7 @@ Object.defineProperties(MetadataTableProperty.prototype, { * The scale to be multiplied to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Number[]|Number[][]} + * @type {number|number[]|number[][]} * @readonly * @private */ @@ -310,7 +310,7 @@ Object.defineProperties(MetadataTableProperty.prototype, { /** * Returns a copy of the value at the given index. * - * @param {Number} index The index. + * @param {number} index The index. * @returns {*} The value of the property. * * @private @@ -337,7 +337,7 @@ MetadataTableProperty.prototype.get = function (index) { /** * Sets the value at the given index. * - * @param {Number} index The index. + * @param {number} index The index. * @param {*} value The value of the property. * * @private diff --git a/packages/engine/Source/Scene/MetadataType.js b/packages/engine/Source/Scene/MetadataType.js index e50d3d181cc..9bb0a2e8c7d 100644 --- a/packages/engine/Source/Scene/MetadataType.js +++ b/packages/engine/Source/Scene/MetadataType.js @@ -11,70 +11,70 @@ import Matrix4 from "../Core/Matrix4.js"; * An enum of metadata types. These metadata types are containers containing * one or more components of type {@link MetadataComponentType} * - * @enum {String} + * @enum {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ const MetadataType = { /** * A single component * - * @type {String} + * @type {string} * @constant */ SCALAR: "SCALAR", /** * A vector with two components * - * @type {String} + * @type {string} * @constant */ VEC2: "VEC2", /** * A vector with three components * - * @type {String} + * @type {string} * @constant */ VEC3: "VEC3", /** * A vector with four components * - * @type {String} + * @type {string} * @constant */ VEC4: "VEC4", /** * A 2x2 matrix, stored in column-major format. * - * @type {String} + * @type {string} * @constant */ MAT2: "MAT2", /** * A 3x3 matrix, stored in column-major format. * - * @type {String} + * @type {string} * @constant */ MAT3: "MAT3", /** * A 4x4 matrix, stored in column-major format. * - * @type {String} + * @type {string} * @constant */ MAT4: "MAT4", /** * A boolean (true/false) value * - * @type {String} + * @type {string} * @constant */ BOOLEAN: "BOOLEAN", /** * A UTF-8 encoded string value * - * @type {String} + * @type {string} * @constant */ STRING: "STRING", @@ -83,7 +83,7 @@ const MetadataType = { * * @see MetadataEnum * - * @type {String} + * @type {string} * @constant */ ENUM: "ENUM", @@ -93,7 +93,7 @@ const MetadataType = { * Check if a type is VEC2, VEC3 or VEC4 * * @param {MetadataType} type The type - * @return {Boolean} <code>true</code> if the type is a vector, <code>false</code> otherwise + * @return {boolean} <code>true</code> if the type is a vector, <code>false</code> otherwise * @private */ MetadataType.isVectorType = function (type) { @@ -115,7 +115,7 @@ MetadataType.isVectorType = function (type) { * Check if a type is MAT2, MAT3 or MAT4 * * @param {MetadataType} type The type - * @return {Boolean} <code>true</code> if the type is a matrix, <code>false</code> otherwise + * @return {boolean} <code>true</code> if the type is a matrix, <code>false</code> otherwise * @private */ MetadataType.isMatrixType = function (type) { @@ -138,7 +138,7 @@ MetadataType.isMatrixType = function (type) { * a VECN returns N, and a MATN returns N*N. All other types return 1. * * @param {MetadataType} type The type to get the component count for - * @return {Number} The number of components + * @return {number} The number of components * @private */ MetadataType.getComponentCount = function (type) { @@ -175,7 +175,7 @@ MetadataType.getComponentCount = function (type) { * Get the corresponding vector or matrix class. This is used to simplify * packing and unpacking code. * @param {MetadataType} type The metadata type - * @return {Object} The appropriate CartesianN class for vector types, MatrixN class for matrix types, or undefined otherwise. + * @return {object} The appropriate CartesianN class for vector types, MatrixN class for matrix types, or undefined otherwise. * @private */ MetadataType.getMathType = function (type) { diff --git a/packages/engine/Source/Scene/Model/B3dmLoader.js b/packages/engine/Source/Scene/Model/B3dmLoader.js index c033b7431eb..ebdb1bbf711 100644 --- a/packages/engine/Source/Scene/Model/B3dmLoader.js +++ b/packages/engine/Source/Scene/Model/B3dmLoader.js @@ -38,21 +38,21 @@ const FeatureIdAttribute = ModelComponents.FeatureIdAttribute; * @augments ResourceLoader * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.b3dmResource The {@link Resource} containing the b3dm. * @param {ArrayBuffer} options.arrayBuffer The array buffer of the b3dm contents. - * @param {Number} [options.byteOffset] The byte offset to the beginning of the b3dm contents in the array buffer. + * @param {number} [options.byteOffset] The byte offset to the beginning of the b3dm contents in the array buffer. * @param {Resource} [options.baseResource] The {@link Resource} that paths in the glTF JSON are relative to. - * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. + * @param {boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. * @param {Axis} [options.forwardAxis=Axis.X] The forward-axis of the glTF model. - * @param {Boolean} [options.loadAttributesAsTypedArray=false] If <code>true</code>, load all attributes as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. - * @param {Boolean} [options.loadAttributesFor2D=false] If <code>true</code>, load the positions buffer and any instanced attribute buffers as typed arrays for accurately projecting models to 2D. - * @param {Boolean} [options.loadIndicesForWireframe=false] If <code>true</code>, load the index buffer as a typed array. This is useful for creating wireframe indices in WebGL1. - * @param {Boolean} [options.loadPrimitiveOutline=true] If <code>true</code>, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. - * @param {Boolean} [options.loadForClassification=false] If <code>true</code> and if the model has feature IDs, load the feature IDs and indices as typed arrays. This is useful for batching features for classification. + * @param {boolean} [options.loadAttributesAsTypedArray=false] If <code>true</code>, load all attributes as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. + * @param {boolean} [options.loadAttributesFor2D=false] If <code>true</code>, load the positions buffer and any instanced attribute buffers as typed arrays for accurately projecting models to 2D. + * @param {boolean} [options.loadIndicesForWireframe=false] If <code>true</code>, load the index buffer as a typed array. This is useful for creating wireframe indices in WebGL1. + * @param {boolean} [options.loadPrimitiveOutline=true] If <code>true</code>, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. + * @param {boolean} [options.loadForClassification=false] If <code>true</code> and if the model has feature IDs, load the feature IDs and indices as typed arrays. This is useful for batching features for classification. * */ function B3dmLoader(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -133,7 +133,7 @@ Object.defineProperties(B3dmLoader.prototype, { * * @memberof B3dmLoader.prototype * - * @type {Promise.<B3dmLoader>|undefined} + * @type {Promise<B3dmLoader>|undefined} * @readonly * @private */ @@ -164,7 +164,7 @@ Object.defineProperties(B3dmLoader.prototype, { * * @memberof B3dmLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -192,7 +192,7 @@ Object.defineProperties(B3dmLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<B3dmLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<B3dmLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ B3dmLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/Model/ClassificationModelDrawCommand.js b/packages/engine/Source/Scene/Model/ClassificationModelDrawCommand.js index 90bc1507fec..4d23fa50ef7 100644 --- a/packages/engine/Source/Scene/Model/ClassificationModelDrawCommand.js +++ b/packages/engine/Source/Scene/Model/ClassificationModelDrawCommand.js @@ -18,7 +18,7 @@ import StencilOperation from "../StencilOperation.js"; * derived commands and returns only the necessary commands depending on the * given frame state. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {DrawCommand} options.command The draw command from which to derive other commands from. * @param {PrimitiveRenderResources} options.primitiveRenderResources The render resources of the primitive associated with the command. * @@ -348,7 +348,7 @@ Object.defineProperties(ClassificationModelDrawCommand.prototype, { * The batch lengths used to generate multiple draw commands. * * @memberof ClassificationModelDrawCommand.prototype - * @type {Number[]} + * @type {number[]} * * @readonly * @private @@ -363,7 +363,7 @@ Object.defineProperties(ClassificationModelDrawCommand.prototype, { * The batch offsets used to generate multiple draw commands. * * @memberof ClassificationModelDrawCommand.prototype - * @type {Number[]} + * @type {number[]} * * @readonly * @private diff --git a/packages/engine/Source/Scene/Model/CustomShader.js b/packages/engine/Source/Scene/Model/CustomShader.js index 463d277dcb7..c48311d030f 100644 --- a/packages/engine/Source/Scene/Model/CustomShader.js +++ b/packages/engine/Source/Scene/Model/CustomShader.js @@ -11,9 +11,9 @@ import CustomShaderTranslucencyMode from "./CustomShaderTranslucencyMode.js"; /** * An object describing a uniform, its type, and an initial value * - * @typedef {Object} UniformSpecifier + * @typedef {object} UniformSpecifier * @property {UniformType} type The Glsl type of the uniform. - * @property {Boolean|Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|TextureUniform} value The initial value of the uniform + * @property {boolean|number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|TextureUniform} value The initial value of the uniform * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -29,13 +29,13 @@ import CustomShaderTranslucencyMode from "./CustomShaderTranslucencyMode.js"; * <li>Using a dictionary automatically de-duplicates variable names</li> * <li>Queries such as <code>variableSet.hasOwnProperty("position")</code> are straightforward</li> * </ul> - * @typedef {Object<String, Boolean>} VariableSet + * @typedef {Object<string, boolean>} VariableSet * @private */ /** * Variable sets parsed from the user-defined vertex shader text. - * @typedef {Object} VertexVariableSets + * @typedef {object} VertexVariableSets * @property {VariableSet} attributeSet A set of all unique attributes used in the vertex shader via the <code>vsInput.attributes</code> struct. * @property {VariableSet} featureIdSet A set of all unique feature ID sets used in the vertex shader via the <code>vsInput.featureIds</code> struct. * @property {VariableSet} metadataSet A set of all unique metadata properties used in the vertex shader via the <code>vsInput.metadata</code> struct. @@ -44,7 +44,7 @@ import CustomShaderTranslucencyMode from "./CustomShaderTranslucencyMode.js"; /** * Variable sets parsed from the user-defined fragment shader text. - * @typedef {Object} FragmentVariableSets + * @typedef {object} FragmentVariableSets * @property {VariableSet} attributeSet A set of all unique attributes used in the fragment shader via the <code>fsInput.attributes</code> struct * @property {VariableSet} featureIdSet A set of all unique feature ID sets used in the fragment shader via the <code>fsInput.featureIds</code> struct. * @property {VariableSet} metadataSet A set of all unique metadata properties used in the fragment shader via the <code>fsInput.metadata</code> struct. @@ -74,14 +74,14 @@ import CustomShaderTranslucencyMode from "./CustomShaderTranslucencyMode.js"; * See the {@link https://github.com/CesiumGS/cesium/tree/main/Documentation/CustomShaderGuide|Custom Shader Guide} for more detailed documentation. * </p> * - * @param {Object} options An object with the following options + * @param {object} options An object with the following options * @param {CustomShaderMode} [options.mode=CustomShaderMode.MODIFY_MATERIAL] The custom shader mode, which determines how the custom shader code is inserted into the fragment shader. * @param {LightingModel} [options.lightingModel] The lighting model (e.g. PBR or unlit). If present, this overrides the default lighting for the model. * @param {CustomShaderTranslucencyMode} [options.translucencyMode=CustomShaderTranslucencyMode.INHERIT] The translucency mode, which determines how the custom shader will be applied. If the value is CustomShaderTransulcencyMode.OPAQUE or CustomShaderTransulcencyMode.TRANSLUCENT, the custom shader will override settings from the model's material. If the value is CustomShaderTransulcencyMode.INHERIT, the custom shader will render as either opaque or translucent depending on the primitive's material settings. - * @param {Object.<String, UniformSpecifier>} [options.uniforms] A dictionary for user-defined uniforms. The key is the uniform name that will appear in the GLSL code. The value is an object that describes the uniform type and initial value - * @param {Object.<String, VaryingType>} [options.varyings] A dictionary for declaring additional GLSL varyings used in the shader. The key is the varying name that will appear in the GLSL code. The value is the data type of the varying. For each varying, the declaration will be added to the top of the shader automatically. The caller is responsible for assigning a value in the vertex shader and using the value in the fragment shader. - * @param {String} [options.vertexShaderText] The custom vertex shader as a string of GLSL code. It must include a GLSL function called vertexMain. See the example for the expected signature. If not specified, the custom vertex shader step will be skipped in the computed vertex shader. - * @param {String} [options.fragmentShaderText] The custom fragment shader as a string of GLSL code. It must include a GLSL function called fragmentMain. See the example for the expected signature. If not specified, the custom fragment shader step will be skipped in the computed fragment shader. + * @param {Object.<string, UniformSpecifier>} [options.uniforms] A dictionary for user-defined uniforms. The key is the uniform name that will appear in the GLSL code. The value is an object that describes the uniform type and initial value + * @param {Object.<string, VaryingType>} [options.varyings] A dictionary for declaring additional GLSL varyings used in the shader. The key is the varying name that will appear in the GLSL code. The value is the data type of the varying. For each varying, the declaration will be added to the top of the shader automatically. The caller is responsible for assigning a value in the vertex shader and using the value in the fragment shader. + * @param {string} [options.vertexShaderText] The custom vertex shader as a string of GLSL code. It must include a GLSL function called vertexMain. See the example for the expected signature. If not specified, the custom vertex shader step will be skipped in the computed vertex shader. + * @param {string} [options.fragmentShaderText] The custom fragment shader as a string of GLSL code. It must include a GLSL function called fragmentMain. See the example for the expected signature. If not specified, the custom fragment shader step will be skipped in the computed fragment shader. * * @alias CustomShader * @constructor @@ -141,7 +141,7 @@ function CustomShader(options) { /** * Additional uniforms as declared by the user. * - * @type {Object.<String, UniformSpecifier>} + * @type {Object.<string, UniformSpecifier>} * @readonly */ this.uniforms = defaultValue(options.uniforms, defaultValue.EMPTY_OBJECT); @@ -149,21 +149,21 @@ function CustomShader(options) { * Additional varyings as declared by the user. * This is used by {@link CustomShaderPipelineStage} * - * @type {Object.<String, VaryingType>} + * @type {Object.<string, VaryingType>} * @readonly */ this.varyings = defaultValue(options.varyings, defaultValue.EMPTY_OBJECT); /** * The user-defined GLSL code for the vertex shader * - * @type {String} + * @type {string} * @readonly */ this.vertexShaderText = options.vertexShaderText; /** * The user-defined GLSL code for the fragment shader * - * @type {String} + * @type {string} * @readonly */ this.fragmentShaderText = options.fragmentShaderText; @@ -205,7 +205,7 @@ function CustomShader(options) { * The map of uniform names to a function that returns a value. This map * is combined with the overall uniform map used by the {@link DrawCommand} * - * @type {Object.<String, Function>} + * @type {Object.<string, Function>} * @readonly * @private */ @@ -404,8 +404,8 @@ function validateBuiltinVariables(customShader) { /** * Update the value of a uniform declared in the shader - * @param {String} uniformName The GLSL name of the uniform. This must match one of the uniforms declared in the constructor - * @param {Boolean|Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|String|Resource} value The new value of the uniform. + * @param {string} uniformName The GLSL name of the uniform. This must match one of the uniforms declared in the constructor + * @param {boolean|number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|string|Resource} value The new value of the uniform. */ CustomShader.prototype.setUniform = function (uniformName, value) { //>>includeStart('debug', pragmas.debug); @@ -440,7 +440,7 @@ CustomShader.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see CustomShader#destroy * @private diff --git a/packages/engine/Source/Scene/Model/CustomShaderMode.js b/packages/engine/Source/Scene/Model/CustomShaderMode.js index 06ce352d146..2ba1b8d59dc 100644 --- a/packages/engine/Source/Scene/Model/CustomShaderMode.js +++ b/packages/engine/Source/Scene/Model/CustomShaderMode.js @@ -2,7 +2,7 @@ * An enum describing how the {@link CustomShader} will be added to the * fragment shader. This determines how the shader interacts with the material. * - * @enum {String} + * @enum {string} * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -11,7 +11,7 @@ const CustomShaderMode = { * The custom shader will be used to modify the results of the material stage * before lighting is applied. * - * @type {String} + * @type {string} * @constant */ MODIFY_MATERIAL: "MODIFY_MATERIAL", @@ -19,7 +19,7 @@ const CustomShaderMode = { * The custom shader will be used instead of the material stage. This is a hint * to optimize out the material processing code. * - * @type {String} + * @type {string} * @constant */ REPLACE_MATERIAL: "REPLACE_MATERIAL", @@ -29,7 +29,7 @@ const CustomShaderMode = { * Convert the shader mode to an uppercase identifier for use in GLSL define * directives. For example: <code>#define CUSTOM_SHADER_MODIFY_MATERIAL</code> * @param {CustomShaderMode} customShaderMode The shader mode - * @return {String} The name of the GLSL macro to use + * @return {string} The name of the GLSL macro to use * * @private */ diff --git a/packages/engine/Source/Scene/Model/CustomShaderTranslucencyMode.js b/packages/engine/Source/Scene/Model/CustomShaderTranslucencyMode.js index 65c53408aeb..aa8d5803c7a 100644 --- a/packages/engine/Source/Scene/Model/CustomShaderTranslucencyMode.js +++ b/packages/engine/Source/Scene/Model/CustomShaderTranslucencyMode.js @@ -2,7 +2,7 @@ * An enum for controling how {@link CustomShader} handles translucency compared with the original * primitive. * - * @enum {Number} + * @enum {number} * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -12,21 +12,21 @@ const CustomShaderTranslucencyMode = { * translucent material, the custom shader will also be considered translucent. If the primitive * used an opaque material, the custom shader will be considered opaque. * - * @type {Number} + * @type {number} * @constant */ INHERIT: 0, /** * Force the primitive to render the primitive as opaque, ignoring any material settings. * - * @type {Number} + * @type {number} * @constant */ OPAQUE: 1, /** * Force the primitive to render the primitive as translucent, ignoring any material settings. * - * @type {Number} + * @type {number} * @constant */ TRANSLUCENT: 2, diff --git a/packages/engine/Source/Scene/Model/GeoJsonLoader.js b/packages/engine/Source/Scene/Model/GeoJsonLoader.js index 47b90ebda83..239edbb679c 100644 --- a/packages/engine/Source/Scene/Model/GeoJsonLoader.js +++ b/packages/engine/Source/Scene/Model/GeoJsonLoader.js @@ -37,8 +37,8 @@ import BufferUsage from "../../Renderer/BufferUsage.js"; * @augments ResourceLoader * @private * - * @param {Object} options Object with the following properties: - * @param {Object} options.geoJson The GeoJson object. + * @param {object} options Object with the following properties: + * @param {object} options.geoJson The GeoJson object. */ function GeoJsonLoader(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -64,7 +64,7 @@ Object.defineProperties(GeoJsonLoader.prototype, { * * @memberof GeoJsonLoader.prototype * - * @type {Promise.<GeoJsonLoader>|Undefined} + * @type {Promise<GeoJsonLoader>|Undefined} * @readonly * @private */ @@ -78,7 +78,7 @@ Object.defineProperties(GeoJsonLoader.prototype, { * * @memberof GeoJsonLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -105,7 +105,7 @@ Object.defineProperties(GeoJsonLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<GeoJsonLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<GeoJsonLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ GeoJsonLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/Model/I3dmLoader.js b/packages/engine/Source/Scene/Model/I3dmLoader.js index b94cbd79b10..0bb74d09981 100644 --- a/packages/engine/Source/Scene/Model/I3dmLoader.js +++ b/packages/engine/Source/Scene/Model/I3dmLoader.js @@ -53,19 +53,19 @@ const Instances = ModelComponents.Instances; * @augments ResourceLoader * @private * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.i3dmResource The {@link Resource} containing the i3dm. * @param {ArrayBuffer} options.arrayBuffer The array buffer of the i3dm contents. - * @param {Number} [options.byteOffset=0] The byte offset to the beginning of the i3dm contents in the array buffer. + * @param {number} [options.byteOffset=0] The byte offset to the beginning of the i3dm contents in the array buffer. * @param {Resource} [options.baseResource] The {@link Resource} that paths in the glTF JSON are relative to. - * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. + * @param {boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the glTF is loaded. * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. * @param {Axis} [options.forwardAxis=Axis.X] The forward-axis of the glTF model. - * @param {Boolean} [options.loadAttributesAsTypedArray=false] Load all attributes as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. - * @param {Boolean} [options.loadIndicesForWireframe=false] Load the index buffer as a typed array so wireframe indices can be created for WebGL1. - * @param {Boolean} [options.loadPrimitiveOutline=true] If true, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. + * @param {boolean} [options.loadAttributesAsTypedArray=false] Load all attributes as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array. + * @param {boolean} [options.loadIndicesForWireframe=false] Load the index buffer as a typed array so wireframe indices can be created for WebGL1. + * @param {boolean} [options.loadPrimitiveOutline=true] If true, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. */ function I3dmLoader(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -144,7 +144,7 @@ Object.defineProperties(I3dmLoader.prototype, { * * @memberof I3dmLoader.prototype * - * @type {Promise.<I3dmLoader>|undefined} + * @type {Promise<I3dmLoader>|undefined} * @readonly * @private */ @@ -175,7 +175,7 @@ Object.defineProperties(I3dmLoader.prototype, { * * @memberof I3dmLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -204,7 +204,7 @@ Object.defineProperties(I3dmLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<I3dmLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<I3dmLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ I3dmLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/Model/LightingModel.js b/packages/engine/Source/Scene/Model/LightingModel.js index f36715f3271..66d2f5795fe 100644 --- a/packages/engine/Source/Scene/Model/LightingModel.js +++ b/packages/engine/Source/Scene/Model/LightingModel.js @@ -1,7 +1,7 @@ /** * The lighting model to use for lighting a {@link Model}. * - * @enum {Number} + * @enum {number} * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -12,7 +12,7 @@ const LightingModel = { * when computing <code>out_FragColor</code>. The alpha mode is still * applied. * - * @type {Number} + * @type {number} * @constant */ UNLIT: 0, @@ -21,7 +21,7 @@ const LightingModel = { * both PBR metallic roughness and PBR specular glossiness. Image-based * lighting is also applied when possible. * - * @type {Number} + * @type {number} * @constant */ PBR: 1, diff --git a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js index 6d7167d1e91..35ff4dd6468 100644 --- a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js +++ b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js @@ -142,10 +142,10 @@ MaterialPipelineStage.process = function ( * Process a single texture transformation and add it to the shader and uniform map. * * @param {ShaderBuilder} shaderBuilder The shader builder to modify - * @param {Object.<String, Function>} uniformMap The uniform map to modify. + * @param {Object.<string, Function>} uniformMap The uniform map to modify. * @param {ModelComponents.TextureReader} textureReader The texture to add to the shader - * @param {String} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> - * @param {String} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" + * @param {string} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> + * @param {string} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" * * @private */ @@ -180,10 +180,10 @@ function processTextureTransform( * Process a single texture and add it to the shader and uniform map. * * @param {ShaderBuilder} shaderBuilder The shader builder to modify - * @param {Object.<String, Function>} uniformMap The uniform map to modify. + * @param {Object.<string, Function>} uniformMap The uniform map to modify. * @param {ModelComponents.TextureReader} textureReader The texture to add to the shader - * @param {String} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> - * @param {String} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" + * @param {string} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> + * @param {string} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" * * @private */ diff --git a/packages/engine/Source/Scene/Model/MetadataPipelineStage.js b/packages/engine/Source/Scene/Model/MetadataPipelineStage.js index df4ba81ceae..5bfd442ed65 100644 --- a/packages/engine/Source/Scene/Model/MetadataPipelineStage.js +++ b/packages/engine/Source/Scene/Model/MetadataPipelineStage.js @@ -120,7 +120,7 @@ MetadataPipelineStage.process = function ( * return as a flattened Array * @param {PropertyAttribute[]} propertyAttributes The PropertyAttributes with properties to be described * @param {ModelComponents.Primitive} primitive The primitive to be rendered - * @param {Object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) + * @param {object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) * @returns {Object[]} An array of objects containing information about each PropertyAttributeProperty * @private */ @@ -137,7 +137,7 @@ function getPropertyAttributesInfo(propertyAttributes, primitive, statistics) { * Collect info about the properties of a single PropertyAttribute * @param {PropertyAttribute} propertyAttribute The PropertyAttribute with properties to be described * @param {ModelComponents.Primitive} primitive The primitive to be rendered - * @param {Object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) + * @param {object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) * @returns {Object[]} An array of objects containing information about each PropertyAttributeProperty * @private */ @@ -177,7 +177,7 @@ function getPropertyAttributeInfo(propertyAttribute, primitive, statistics) { * Collect info about all properties of all propertyTextures, and * return as a flattened Array * @param {PropertyTexture[]} propertyTextures The PropertyTextures with properties to be described - * @param {Object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) + * @param {object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) * @returns {Object[]} An array of objects containing information about each PropertyTextureProperty * @private */ @@ -193,7 +193,7 @@ function getPropertyTexturesInfo(propertyTextures, statistics) { /** * Collect info about the properties of a single PropertyTexture * @param {PropertyTexture} propertyTexture The PropertyTexture with properties to be described - * @param {Object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) + * @param {object} [statistics] Statistics about the properties (if the model is from a 3DTiles tileset) * @returns {Object[]} An array of objects containing information about each PropertyTextureProperty * @private */ @@ -278,8 +278,8 @@ const floatConversions = { /** * For a type with integer components, find a corresponding float-component type - * @param {String} type The name of a GLSL type with integer components - * @returns {String} The name of a GLSL type of the same dimension with float components, if available; otherwise the input type + * @param {string} type The name of a GLSL type with integer components + * @returns {string} The name of a GLSL type of the same dimension with float components, if available; otherwise the input type * @private */ function convertToFloatComponents(type) { @@ -354,7 +354,7 @@ function declareStructsAndFunctions(shaderBuilder) { /** * Update the shader for a single PropertyAttributeProperty * @param {PrimitiveRenderResources} renderResources The render resources for the primitive - * @param {Object} propertyInfo Info about the PropertyAttributeProperty + * @param {object} propertyInfo Info about the PropertyAttributeProperty * @private */ function processPropertyAttributeProperty(renderResources, propertyInfo) { @@ -367,7 +367,7 @@ function processPropertyAttributeProperty(renderResources, propertyInfo) { * Add fields to the Metadata struct, and metadata value assignments to the * initializeMetadata function, for a PropertyAttributeProperty * @param {PrimitiveRenderResources} renderResources The render resources for the primitive - * @param {Object} propertyInfo Info about the PropertyAttributeProperty + * @param {object} propertyInfo Info about the PropertyAttributeProperty * @private */ function addPropertyAttributePropertyMetadata(renderResources, propertyInfo) { @@ -423,7 +423,7 @@ function processPropertyTextureProperty(renderResources, propertyInfo) { * Add fields to the Metadata struct, and metadata value expressions to the * initializeMetadata function, for a PropertyTextureProperty * @param {PrimitiveRenderResources} renderResources The render resources for the primitive - * @param {Object} propertyInfo Info about the PropertyTextureProperty + * @param {object} propertyInfo Info about the PropertyTextureProperty * @private */ function addPropertyTexturePropertyMetadata(renderResources, propertyInfo) { @@ -480,7 +480,7 @@ function addPropertyTexturePropertyMetadata(renderResources, propertyInfo) { * to the initializeMetadata function, for a PropertyAttributeProperty or * PropertyTextureProperty * @param {ShaderBuilder} shaderBuilder The shader builder for the primitive - * @param {Object} propertyInfo Info about the PropertyAttributeProperty or PropertyTextureProperty + * @param {object} propertyInfo Info about the PropertyAttributeProperty or PropertyTextureProperty * @private */ function addPropertyMetadataClass(shaderBuilder, propertyInfo) { @@ -525,7 +525,7 @@ function addPropertyMetadataClass(shaderBuilder, propertyInfo) { * expressions to the initializeMetadata function, for a * PropertyAttributeProperty or PropertyTextureProperty * @param {ShaderBuilder} shaderBuilder The shader builder for the primitive - * @param {Object} propertyInfo Info about the PropertyAttributeProperty or PropertyTextureProperty + * @param {object} propertyInfo Info about the PropertyAttributeProperty or PropertyTextureProperty * @private */ function addPropertyMetadataStatistics(shaderBuilder, propertyInfo) { @@ -577,39 +577,38 @@ function addPropertyMetadataStatistics(shaderBuilder, propertyInfo) { /** * Construct GLSL assignment statements to set metadata spec values in a struct * @param {Object[]} fieldNames An object with the following properties: - * @param {String} fieldNames[].specName The name of the property in the spec - * @param {String} fieldNames[].shaderName The name of the property in the shader - * @param {Object} values A source of property values, keyed on fieldNames[].specName - * @param {String} struct The name of the struct to which values will be assigned - * @param {String} type The type of the values to be assigned - * @returns {Array.<{name: String, value}>} Objects containing the property name (in the shader) and a GLSL assignment statement for the property value + * @param {string} fieldNames[].specName The name of the property in the spec + * @param {string} fieldNames[].shaderName The name of the property in the shader + * @param {object} values A source of property values, keyed on fieldNames[].specName + * @param {string} struct The name of the struct to which values will be assigned + * @param {string} type The type of the values to be assigned + * @returns {Array<{name: string, value: any}>} Objects containing the property name (in the shader) and a GLSL assignment statement for the property value * @private */ function getStructAssignments(fieldNames, values, struct, type) { - return defined(values) - ? fieldNames.map(constructAssignment).filter(defined) - : []; - function constructAssignment(field) { const value = values[field.specName]; if (defined(value)) { return `${struct}.${field.shaderName} = ${type}(${value});`; } } + return defined(values) + ? fieldNames.map(constructAssignment).filter(defined) + : []; } /** * Handle offset/scale transform for a property value * This wraps the GLSL value expression with a czm_valueTransform() call * - * @param {Object} options Object with the following properties: - * @param {String} options.valueExpression The GLSL value expression without the transform - * @param {String} options.metadataVariable The name of the GLSL variable that will contain the property value - * @param {String} options.glslType The GLSL type of the variable + * @param {object} options Object with the following properties: + * @param {string} options.valueExpression The GLSL value expression without the transform + * @param {string} options.metadataVariable The name of the GLSL variable that will contain the property value + * @param {string} options.glslType The GLSL type of the variable * @param {ShaderDestination} options.shaderDestination Which shader(s) use this variable * @param {PrimitiveRenderResources} options.renderResources The render resources for this primitive * @param {(PropertyAttributeProperty|PropertyTextureProperty)} options.property The property from which the value is derived - * @returns {String} A wrapped GLSL value expression + * @returns {string} A wrapped GLSL value expression * @private */ function addValueTransformUniforms(options) { diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index cc1888dc4e0..59980de218e 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -112,22 +112,22 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model. * @privateParam {ModelType} options.type Type of this model, to distinguish individual glTF files from 3D Tiles internally. - * @privateParam {Object} options Object with the following properties: + * @privateParam {object} options Object with the following properties: * @privateParam {Resource} options.resource The Resource to the 3D model. - * @privateParam {Boolean} [options.show=true] Whether or not to render the model. + * @privateParam {boolean} [options.show=true] Whether or not to render the model. * @privateParam {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. - * @privateParam {Number} [options.scale=1.0] A uniform scale applied to this model. - * @privateParam {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. - * @privateParam {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. - * @privateParam {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. - * @privateParam {Boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. - * @privateParam {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @privateParam {number} [options.scale=1.0] A uniform scale applied to this model. + * @privateParam {number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @privateParam {number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @privateParam {object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @privateParam {boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. + * @privateParam {boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. * @privateParam {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from light sources. - * @privateParam {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. - * @privateParam {Boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. - * @privateParam {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. - * @privateParam {Boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. - * @privateParam {Boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. + * @privateParam {boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @privateParam {boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. + * @privateParam {boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. + * @privateParam {boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. + * @privateParam {boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. * @privateParam {CustomShader} [options.customShader] A custom shader. This will add user-defined GLSL code to the vertex and fragment shaders. Using custom shaders with a {@link Cesium3DTileStyle} may lead to undefined behavior. * @privateParam {Cesium3DTileContent} [options.content] The tile content this model belongs to. This property will be undefined if model is not loaded as part of a tileset. * @privateParam {HeightReference} [options.heightReference=HeightReference.NONE] Determines how the model is drawn relative to terrain. @@ -135,23 +135,23 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * @privateParam {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. * @privateParam {Color} [options.color] A color that blends with the model's rendered color. * @privateParam {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. - * @privateParam {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @privateParam {number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @privateParam {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. - * @privateParam {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. - * @privateParam {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @privateParam {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @privateParam {number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @privateParam {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @privateParam {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. * @privateParam {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. * @privateParam {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @privateParam {Cartesian3} [options.lightColor] The light color when shading the model. When <code>undefined</code> the scene's light color is used instead. * @privateParam {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting on this model. - * @privateParam {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. - * @privateParam {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @privateParam {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. + * @privateParam {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. + * @privateParam {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. + * @privateParam {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. * @privateParam {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this model. - * @privateParam {Boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. - * @privateParam {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @privateParam {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @privateParam {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * @privateParam {boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. + * @privateParam {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @privateParam {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @privateParam {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. * @privateParam {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded. * @@ -214,7 +214,7 @@ function Model(options) { * The scale value after being clamped by the maximum scale parameter. * Used to adjust bounding spheres without repeated calculation. * - * @type {Number} + * @type {number} * @private */ this._clampedScale = defined(this._maximumScale) @@ -227,7 +227,7 @@ function Model(options) { * Whether or not the ModelSceneGraph should call updateModelMatrix. * This will be true if any of the model matrix, scale, minimum pixel size, or maximum scale are dirty. * - * @type {Number} + * @type {number} * @private */ this._updateModelMatrix = false; @@ -430,7 +430,7 @@ function Model(options) { * {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. * When true, outlines are displayed. When false, outlines are not displayed. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -659,7 +659,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -679,7 +679,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Promise.<Model>} + * @type {Promise<Model>} * @readonly */ readyPromise: { @@ -749,7 +749,7 @@ Object.defineProperties(Model.prototype, { * Determines if the model's animations should hold a pose over frames where no keyframes are specified. * * @memberof Model.prototype - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -768,7 +768,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -941,7 +941,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * * @private */ @@ -978,7 +978,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Object} + * @type {object} * * @default undefined * @@ -1002,7 +1002,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -1074,7 +1074,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * * @default 0.5 */ @@ -1115,7 +1115,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * * @default 0.0 */ @@ -1177,7 +1177,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -1201,7 +1201,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -1234,7 +1234,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -1266,7 +1266,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {String} + * @type {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ featureIdLabel: { @@ -1302,7 +1302,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {String} + * @type {string} * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ instanceFeatureIdLabel: { @@ -1411,7 +1411,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -1435,7 +1435,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * * @default 1.0 */ @@ -1457,7 +1457,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -1475,7 +1475,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} * * @default 0.0 */ @@ -1498,7 +1498,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Number} + * @type {number} */ maximumScale: { get: function () { @@ -1554,7 +1554,7 @@ Object.defineProperties(Model.prototype, { * * @memberof Model.prototype * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -1661,7 +1661,7 @@ Object.defineProperties(Model.prototype, { * Returns the node with the given <code>name</code> in the glTF. This is used to * modify a node's transform for user-defined animation. * - * @param {String} name The name of the node in the glTF. + * @param {string} name The name of the node in the glTF. * @returns {ModelNode} The node, or <code>undefined</code> if no node with the <code>name</code> exists. * * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. @@ -1689,8 +1689,8 @@ Model.prototype.getNode = function (name) { * multiple stage values, call Model.applyArticulations() to * cause the node matrices to be recalculated. * - * @param {String} articulationStageKey The name of the articulation, a space, and the name of the stage. - * @param {Number} value The numeric value of this stage of the articulation. + * @param {string} articulationStageKey The name of the articulation, a space, and the name of the stage. + * @param {number} value The numeric value of this stage of the articulation. * * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. * @@ -2386,7 +2386,7 @@ function addCreditsToCreditDisplay(model, frameState) { * If the model color's alpha is equal to zero, then it is considered invisible, * not translucent. * - * @returns {Boolean} <code>true</code> if the model is translucent, otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the model is translucent, otherwise <code>false</code>. * @private */ Model.prototype.isTranslucent = function () { @@ -2398,7 +2398,7 @@ Model.prototype.isTranslucent = function () { * Gets whether or not the model is invisible, i.e. if the model color's alpha * is equal to zero. * - * @returns {Boolean} <code>true</code> if the model is invisible, otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the model is invisible, otherwise <code>false</code>. * @private */ Model.prototype.isInvisible = function () { @@ -2418,7 +2418,7 @@ function supportsSilhouettes(frameState) { * </p> * * @param {FrameState} The frame state. - * @returns {Boolean} <code>true</code> if the model has silhouettes, otherwise <code>false</code>. + * @returns {boolean} <code>true</code> if the model has silhouettes, otherwise <code>false</code>. * @private */ Model.prototype.hasSilhouette = function (frameState) { @@ -2440,7 +2440,7 @@ function supportsSkipLevelOfDetail(frameState) { * is supported (i.e. the context supports stencil buffers). * * @param {FrameState} frameState The frame state. - * @returns {Boolean} <code>true</code> if the model is part of a tileset that uses the skipLevelOfDetail optimization, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the model is part of a tileset that uses the skipLevelOfDetail optimization, <code>false</code> otherwise. * @private */ Model.prototype.hasSkipLevelOfDetail = function (frameState) { @@ -2456,7 +2456,7 @@ Model.prototype.hasSkipLevelOfDetail = function (frameState) { /** * Gets whether or not clipping planes are enabled for this model. * - * @returns {Boolean} <code>true</code> if clipping planes are enabled for this model, <code>false</code>. + * @returns {boolean} <code>true</code> if clipping planes are enabled for this model, <code>false</code>. * @private */ Model.prototype.isClippingEnabled = function () { @@ -2474,7 +2474,7 @@ Model.prototype.isClippingEnabled = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Model#destroy */ @@ -2584,26 +2584,26 @@ Model.prototype.destroyModelResources = function () { * <p> * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the .glb extension. * - * @param {Object} options Object with the following properties: - * @param {String|Resource} options.url The url to the .gltf or .glb file. - * @param {String|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to. - * @param {Boolean} [options.show=true] Whether or not to render the model. + * @param {object} options Object with the following properties: + * @param {string|Resource} options.url The url to the .gltf or .glb file. + * @param {string|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {boolean} [options.show=true] Whether or not to render the model. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. - * @param {Number} [options.scale=1.0] A uniform scale applied to this model. - * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. - * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. - * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @param {number} [options.scale=1.0] A uniform scale applied to this model. + * @param {number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @param {number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @param {object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. + * @param {boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from light sources. - * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. - * @param {Boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. - * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. - * @param {Boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. - * @param {Boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. + * @param {boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @param {boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. + * @param {boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. + * @param {boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. + * @param {boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. * @param {Axis} [options.forwardAxis=Axis.Z] The forward-axis of the glTF model. * @param {CustomShader} [options.customShader] A custom shader. This will add user-defined GLSL code to the vertex and fragment shaders. Using custom shaders with a {@link Cesium3DTileStyle} may lead to undefined behavior. @@ -2613,23 +2613,23 @@ Model.prototype.destroyModelResources = function () { * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. * @param {Color} [options.color] A color that blends with the model's rendered color. * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. - * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. - * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. - * @param {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @param {number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @param {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @param {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Cartesian3} [options.lightColor] The light color when shading the model. When <code>undefined</code> the scene's light color is used instead. * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting on this model. - * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @param {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. + * @param {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this model. - * @param {Boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. - * @param {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting. + * @param {boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. + * @param {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting. * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded. * * @returns {Model} The newly created model. diff --git a/packages/engine/Source/Scene/Model/ModelAlphaOptions.js b/packages/engine/Source/Scene/Model/ModelAlphaOptions.js index 2393decfa50..050a88670f1 100644 --- a/packages/engine/Source/Scene/Model/ModelAlphaOptions.js +++ b/packages/engine/Source/Scene/Model/ModelAlphaOptions.js @@ -17,7 +17,7 @@ function ModelAlphaOptions() { /** * Determines the alpha threshold below which fragments are discarded * - * @type {Number} + * @type {number} * @private */ this.alphaCutoff = undefined; diff --git a/packages/engine/Source/Scene/Model/ModelAnimation.js b/packages/engine/Source/Scene/Model/ModelAnimation.js index 569cb013323..c78535b402a 100644 --- a/packages/engine/Source/Scene/Model/ModelAnimation.js +++ b/packages/engine/Source/Scene/Model/ModelAnimation.js @@ -37,7 +37,7 @@ function ModelAnimation(model, animation, options) { * This is slightly more efficient that not removing it, but if, for example, * time is reversed, the animation is not played again. * - * @type {Boolean} + * @type {boolean} * @default false */ this.removeOnStop = defaultValue(options.removeOnStop, false); @@ -149,7 +149,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {String} + * @type {string} * @readonly */ name: { @@ -196,7 +196,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -213,7 +213,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -246,7 +246,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {Number} + * @type {number} * @readonly * * @default undefined @@ -284,7 +284,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {Number} + * @type {number} * @readonly * * @default 1.0 @@ -300,7 +300,7 @@ Object.defineProperties(ModelAnimation.prototype, { * * @memberof ModelAnimation.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -387,7 +387,7 @@ function initialize(runtimeAnimation) { /** * Evaluate all animation channels to advance this animation. * - * @param {Number} time The local animation time. + * @param {number} time The local animation time. * * @private */ @@ -403,9 +403,9 @@ ModelAnimation.prototype.animate = function (time) { * A function used to compute the local animation time for a ModelAnimation. * @callback ModelAnimation.AnimationTimeCallback * - * @param {Number} duration The animation's original duration in seconds. - * @param {Number} seconds The seconds since the animation started, in scene time. - * @returns {Number} Returns the local animation time. + * @param {number} duration The animation's original duration in seconds. + * @param {number} seconds The seconds since the animation started, in scene time. + * @returns {number} Returns the local animation time. * * @example * // Use real time for model animation (assuming animateWhilePaused was set to true) diff --git a/packages/engine/Source/Scene/Model/ModelAnimationChannel.js b/packages/engine/Source/Scene/Model/ModelAnimationChannel.js index f0f7bed155b..a75db523484 100644 --- a/packages/engine/Source/Scene/Model/ModelAnimationChannel.js +++ b/packages/engine/Source/Scene/Model/ModelAnimationChannel.js @@ -18,7 +18,7 @@ const AnimatedPropertyType = ModelComponents.AnimatedPropertyType; * channel is responsible for interpolating between the keyframe values of an animated * property, then applying the change to the target node. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.AnimationChannel} options.channel The corresponding animation channel components from the 3D model. * @param {ModelAnimation} options.runtimeAnimation The runtime animation containing this channel. * @param {ModelRuntimeNode} options.runtimeNode The runtime node that this channel will animate. @@ -254,7 +254,7 @@ function initialize(runtimeChannel) { /** * Animates the target node property based on its spline. * - * @param {Number} time The local animation time. + * @param {number} time The local animation time. * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js index 8c1c0eb7697..0e8a93fe33d 100644 --- a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js +++ b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js @@ -56,7 +56,7 @@ function ModelAnimationCollection(model) { * to the model's animations. By default, this is based on scene time, so models using * the default will not animate regardless of this setting. * - * @type {Boolean} + * @type {boolean} * @default false */ this.animateWhilePaused = false; @@ -72,7 +72,7 @@ Object.defineProperties(ModelAnimationCollection.prototype, { * * @memberof ModelAnimationCollection.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -110,15 +110,15 @@ function addAnimation(collection, animation, options) { * This raises the {@link ModelAnimationCollection#animationAdded} event so, for example, a UI can stay in sync. * </p> * - * @param {Object} options Object with the following properties: - * @param {String} [options.name] The glTF animation name that identifies the animation. Must be defined if <code>options.index</code> is <code>undefined</code>. - * @param {Number} [options.index] The glTF animation index that identifies the animation. Must be defined if <code>options.name</code> is <code>undefined</code>. + * @param {object} options Object with the following properties: + * @param {string} [options.name] The glTF animation name that identifies the animation. Must be defined if <code>options.index</code> is <code>undefined</code>. + * @param {number} [options.index] The glTF animation index that identifies the animation. Must be defined if <code>options.name</code> is <code>undefined</code>. * @param {JulianDate} [options.startTime] The scene time to start playing the animation. When this is <code>undefined</code>, the animation starts at the next frame. - * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. + * @param {number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. * @param {JulianDate} [options.stopTime] The scene time to stop playing the animation. When this is <code>undefined</code>, the animation is played for its full duration. - * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animation is removed after it stops playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. - * @param {Number} [options.multiplier=1.0] Values greater than <code>1.0</code> increase the speed that the animation is played relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. - * @param {Boolean} [options.reverse=false] When <code>true</code>, the animation is played in reverse. + * @param {boolean} [options.removeOnStop=false] When <code>true</code>, the animation is removed after it stops playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. + * @param {number} [options.multiplier=1.0] Values greater than <code>1.0</code> increase the speed that the animation is played relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. + * @param {boolean} [options.reverse=false] When <code>true</code>, the animation is played in reverse. * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animation is looped. * @param {ModelAnimation.AnimationTimeCallback} [options.animationTime=undefined] If defined, computes the local animation time for this animation. * @returns {ModelAnimation} The animation that was added to the collection. @@ -230,13 +230,13 @@ ModelAnimationCollection.prototype.add = function (options) { * This raises the {@link ModelAnimationCollection#animationAdded} event for each model so, for example, a UI can stay in sync. * </p> * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {JulianDate} [options.startTime] The scene time to start playing the animations. When this is <code>undefined</code>, the animations starts at the next frame. - * @param {Number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. + * @param {number} [options.delay=0.0] The delay, in seconds, from <code>startTime</code> to start playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. * @param {JulianDate} [options.stopTime] The scene time to stop playing the animations. When this is <code>undefined</code>, the animations are played for its full duration. - * @param {Boolean} [options.removeOnStop=false] When <code>true</code>, the animations are removed after they stop playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. - * @param {Number} [options.multiplier=1.0] Values greater than <code>1.0</code> increase the speed that the animations play relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. - * @param {Boolean} [options.reverse=false] When <code>true</code>, the animations are played in reverse. + * @param {boolean} [options.removeOnStop=false] When <code>true</code>, the animations are removed after they stop playing. This will only affect the animation if <code>options.loop</code> is ModelAnimationLoop.NONE. + * @param {number} [options.multiplier=1.0] Values greater than <code>1.0</code> increase the speed that the animations play relative to the scene clock speed; values less than <code>1.0</code> decrease the speed. + * @param {boolean} [options.reverse=false] When <code>true</code>, the animations are played in reverse. * @param {ModelAnimationLoop} [options.loop=ModelAnimationLoop.NONE] Determines if and how the animations are looped. * @param {ModelAnimation.AnimationTimeCallback} [options.animationTime=undefined] If defined, computes the local animation time for all of the animations. * @returns {ModelAnimation[]} An array of {@link ModelAnimation} objects, one for each animation added to the collection. If there are no glTF animations, the array is empty. @@ -289,7 +289,7 @@ ModelAnimationCollection.prototype.addAll = function (options) { * </p> * * @param {ModelAnimation} runtimeAnimation The runtime animation to remove. - * @returns {Boolean} <code>true</code> if the animation was removed; <code>false</code> if the animation was not found in the collection. + * @returns {boolean} <code>true</code> if the animation was removed; <code>false</code> if the animation was not found in the collection. * * @example * const a = model.activeAnimations.add({ @@ -336,7 +336,7 @@ ModelAnimationCollection.prototype.removeAll = function () { * Determines whether this collection contains a given animation. * * @param {ModelAnimation} runtimeAnimation The runtime animation to check for. - * @returns {Boolean} <code>true</code> if this collection contains the animation, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if this collection contains the animation, <code>false</code> otherwise. */ ModelAnimationCollection.prototype.contains = function (runtimeAnimation) { if (defined(runtimeAnimation)) { @@ -352,7 +352,7 @@ ModelAnimationCollection.prototype.contains = function (runtimeAnimation) { * it to the left, changing their indices. This function is commonly used to iterate over * all the animations in the collection. * - * @param {Number} index The zero-based index of the animation. + * @param {number} index The zero-based index of the animation. * @returns {ModelAnimation} The runtime animation at the specified index. * * @example @@ -396,7 +396,7 @@ function createAnimationRemovedFunction( * that have stopped. * * @param {FrameState} frameState The current frame state. - * @returns {Boolean} <code>true</code> if an animation played during this update, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if an animation played during this update, <code>false</code> otherwise. * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelArticulation.js b/packages/engine/Source/Scene/Model/ModelArticulation.js index dfb743f30ac..401be000165 100644 --- a/packages/engine/Source/Scene/Model/ModelArticulation.js +++ b/packages/engine/Source/Scene/Model/ModelArticulation.js @@ -9,7 +9,7 @@ import ModelArticulationStage from "./ModelArticulationStage.js"; * {@link ModelSceneGraph}. This is defined in a model by the * <code>AGI_articulations</code> extension. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.Articulation} options.articulation The articulation components from the 3D model. * @param {ModelSceneGraph} options.sceneGraph The scene graph this articulation belongs to. * @@ -80,7 +80,7 @@ Object.defineProperties(ModelArticulation.prototype, { * The name of this articulation. * * @memberof ModelArticulation.prototype - * @type {String} + * @type {string} * @readonly * * @private @@ -150,8 +150,8 @@ function initialize(runtimeArticulation) { /** * Sets the current value of an articulation stage. * - * @param {String} stageName The name of the articulation stage. - * @param {Number} value The numeric value of this stage of the articulation. + * @param {string} stageName The name of the articulation stage. + * @param {number} value The numeric value of this stage of the articulation. * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelArticulationStage.js b/packages/engine/Source/Scene/Model/ModelArticulationStage.js index b8aa7d9b6c3..e0805f8aa65 100644 --- a/packages/engine/Source/Scene/Model/ModelArticulationStage.js +++ b/packages/engine/Source/Scene/Model/ModelArticulationStage.js @@ -12,7 +12,7 @@ const articulationEpsilon = CesiumMath.EPSILON16; * An in-memory representation of an articulation stage belonging to a * {@link ModelArticulation}. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.ArticulationStage} options.stage The articulation stage components from the 3D model. * @param {ModelArticulation} options.runtimeArticulation The runtime articulation that this stage belongs to. * @@ -76,7 +76,7 @@ Object.defineProperties(ModelArticulationStage.prototype, { * The name of this articulation stage. * * @memberof ModelArticulationStage.prototype - * @type {String} + * @type {string} * @readonly * * @private @@ -107,7 +107,7 @@ Object.defineProperties(ModelArticulationStage.prototype, { * The minimum value of this articulation stage. * * @memberof ModelArticulationStage.prototype - * @type {Number} + * @type {number} * @readonly * * @private @@ -122,7 +122,7 @@ Object.defineProperties(ModelArticulationStage.prototype, { * The maximum value of this articulation stage. * * @memberof ModelArticulationStage.prototype - * @type {Number} + * @type {number} * @readonly * * @private @@ -137,7 +137,7 @@ Object.defineProperties(ModelArticulationStage.prototype, { * The current value of this articulation stage. * * @memberof ModelArticulationStage.prototype - * @type {Number} + * @type {number} * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelDrawCommand.js b/packages/engine/Source/Scene/Model/ModelDrawCommand.js index db756cf0174..a82b75fc4b5 100644 --- a/packages/engine/Source/Scene/Model/ModelDrawCommand.js +++ b/packages/engine/Source/Scene/Model/ModelDrawCommand.js @@ -24,7 +24,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * This manages the derived commands and pushes only the necessary commands depending * on the given frame state. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {DrawCommand} options.command The draw command from which to derive other commands from. * @param {PrimitiveRenderResources} options.primitiveRenderResources The render resources of the primitive associated with the command. * @@ -346,7 +346,7 @@ Object.defineProperties(ModelDrawCommand.prototype, { * translucent. * * @memberof ModelDrawCommand.prototype - * @type {Boolean} + * @type {boolean} * * @private */ @@ -390,7 +390,7 @@ Object.defineProperties(ModelDrawCommand.prototype, { * Whether to draw the bounding sphere associated with this draw command. * * @memberof ModelDrawCommand.prototype - * @type {Boolean} + * @type {boolean} * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelFeature.js b/packages/engine/Source/Scene/Model/ModelFeature.js index 80672a0f225..7dba22eebb8 100644 --- a/packages/engine/Source/Scene/Model/ModelFeature.js +++ b/packages/engine/Source/Scene/Model/ModelFeature.js @@ -16,9 +16,9 @@ import defined from "../../Core/defined.js"; * @alias ModelFeature * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Model} options.model The model the feature belongs to. - * @param {Number} options.featureId The unique integral identifier for this feature. + * @param {number} options.featureId The unique integral identifier for this feature. * * @example * // On mouse over, display all the properties for a feature in the console log. @@ -48,7 +48,7 @@ Object.defineProperties(ModelFeature.prototype, { * * @memberof ModelFeature.prototype * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -123,7 +123,7 @@ Object.defineProperties(ModelFeature.prototype, { * * @memberof ModelFeature.prototype * - * @type {Number} + * @type {number} * * @readonly * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -138,8 +138,8 @@ Object.defineProperties(ModelFeature.prototype, { /** * Returns whether the feature contains this property. * - * @param {String} name The case-sensitive name of the property. - * @returns {Boolean} Whether the feature contains this property. + * @param {string} name The case-sensitive name of the property. + * @returns {boolean} Whether the feature contains this property. */ ModelFeature.prototype.hasProperty = function (name) { return this._featureTable.hasProperty(this._featureId, name); @@ -148,7 +148,7 @@ ModelFeature.prototype.hasProperty = function (name) { /** * Returns a copy of the value of the feature's property with the given name. * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * * @example @@ -178,7 +178,7 @@ ModelFeature.prototype.getProperty = function (name) { * previous {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {String} name The semantic or property ID of the feature. Semantics are checked before property IDs in each granularity of metadata. + * @param {string} name The semantic or property ID of the feature. Semantics are checked before property IDs in each granularity of metadata. * @return {*} The value of the property or <code>undefined</code> if the feature does not have this property. * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -194,8 +194,8 @@ ModelFeature.prototype.getPropertyInherited = function (name) { /** * Returns an array of property IDs for the feature. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The IDs of the feature's properties. + * @param {string[]} [results] An array into which to store the results. + * @returns {string[]} The IDs of the feature's properties. */ ModelFeature.prototype.getPropertyIds = function (results) { return this._featureTable.getPropertyIds(results); @@ -204,9 +204,9 @@ ModelFeature.prototype.getPropertyIds = function (results) { /** * Sets the value of the feature's property with the given name. * - * @param {String} name The case-sensitive name of the property. + * @param {string} name The case-sensitive name of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * * @exception {DeveloperError} Inherited batch table hierarchy property is read only. * diff --git a/packages/engine/Source/Scene/Model/ModelFeatureTable.js b/packages/engine/Source/Scene/Model/ModelFeatureTable.js index 9fc650f512d..1a18a39029d 100644 --- a/packages/engine/Source/Scene/Model/ModelFeatureTable.js +++ b/packages/engine/Source/Scene/Model/ModelFeatureTable.js @@ -13,7 +13,7 @@ import ModelType from "./ModelType.js"; * Manages the {@link ModelFeature}s in a {@link Model}. * Extracts the properties from a {@link PropertyTable}. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {Model} options.model The model that owns this feature table. * @param {PropertyTable} options.propertyTable The property table from the model used to initialize the model. * @@ -68,7 +68,7 @@ Object.defineProperties(ModelFeatureTable.prototype, { * * @memberof ModelFeatureTable.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -85,7 +85,7 @@ Object.defineProperties(ModelFeatureTable.prototype, { * * @memberof ModelFeatureTable.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -105,7 +105,7 @@ Object.defineProperties(ModelFeatureTable.prototype, { * * @memberof ModelFeatureTable.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -288,7 +288,7 @@ ModelFeatureTable.prototype.applyStyle = function (style) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ModelFeatureTable#destroy * @private diff --git a/packages/engine/Source/Scene/Model/ModelLightingOptions.js b/packages/engine/Source/Scene/Model/ModelLightingOptions.js index bc00a2b69e0..747034dbe46 100644 --- a/packages/engine/Source/Scene/Model/ModelLightingOptions.js +++ b/packages/engine/Source/Scene/Model/ModelLightingOptions.js @@ -4,7 +4,7 @@ import LightingModel from "./LightingModel.js"; /** * Options for configuring the {@link LightingPipelineStage} * - * @param {Object} options An object containing the following options + * @param {object} options An object containing the following options * @param {LightingModel} [options.lightingModel=LightingModel.UNLIT] The lighting model to use * * @alias ModelLightingOptions diff --git a/packages/engine/Source/Scene/Model/ModelNode.js b/packages/engine/Source/Scene/Model/ModelNode.js index e0877858924..2ddc3fb5420 100644 --- a/packages/engine/Source/Scene/Model/ModelNode.js +++ b/packages/engine/Source/Scene/Model/ModelNode.js @@ -38,7 +38,7 @@ Object.defineProperties(ModelNode.prototype, { * * @memberof ModelNode.prototype * - * @type {String} + * @type {string} * @readonly */ name: { @@ -52,7 +52,7 @@ Object.defineProperties(ModelNode.prototype, { * * @memberof ModelNode.prototype * - * @type {Number} + * @type {number} * @readonly */ id: { @@ -65,7 +65,7 @@ Object.defineProperties(ModelNode.prototype, { * Determines if this node and its children will be shown. * * @memberof ModelNode.prototype - * @type {Boolean} + * @type {boolean} * * @default true */ diff --git a/packages/engine/Source/Scene/Model/ModelRenderResources.js b/packages/engine/Source/Scene/Model/ModelRenderResources.js index d7de0ad2dd7..b423fc7e793 100644 --- a/packages/engine/Source/Scene/Model/ModelRenderResources.js +++ b/packages/engine/Source/Scene/Model/ModelRenderResources.js @@ -43,7 +43,7 @@ function ModelRenderResources(model) { * A dictionary mapping uniform name to functions that return the uniform * values. * - * @type {Object.<String, Function>} + * @type {Object.<string, Function>} * @readonly * * @private @@ -65,7 +65,7 @@ function ModelRenderResources(model) { * The pipeline stages simply set the options, the render state is created * when the {@link DrawCommand} is constructed. * - * @type {Object} + * @type {object} * @readonly * * @private @@ -83,7 +83,7 @@ function ModelRenderResources(model) { * Whether the model has a silhouette. This value indicates what draw commands * are needed and is set by ModelSilhouettePipelineStage. * - * @type {Boolean} + * @type {boolean} * @default false * * @private @@ -95,7 +95,7 @@ function ModelRenderResources(model) { * optimization. This value indicates what draw commands are needed and * is set by TilesetPipelineStage. * - * @type {Boolean} + * @type {boolean} * @default false * * @private diff --git a/packages/engine/Source/Scene/Model/ModelRuntimeNode.js b/packages/engine/Source/Scene/Model/ModelRuntimeNode.js index 41f6caccb59..ac1eba5e805 100644 --- a/packages/engine/Source/Scene/Model/ModelRuntimeNode.js +++ b/packages/engine/Source/Scene/Model/ModelRuntimeNode.js @@ -13,12 +13,12 @@ import NodeStatisticsPipelineStage from "./NodeStatisticsPipelineStage.js"; /** * An in-memory representation of a node as part of the {@link ModelSceneGraph}. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.Node} options.node The corresponding node components from the 3D model. * @param {Matrix4} options.transform The transform of this node, excluding transforms from the node's ancestors or children. * @param {Matrix4} options.transformToRoot The product of the transforms of all the node's ancestors, excluding the node's own transform. * @param {ModelSceneGraph} options.sceneGraph The scene graph this node belongs to. - * @param {Number[]} options.children The indices of the children of this node in the runtime nodes array of the scene graph. + * @param {number[]} options.children The indices of the children of this node in the runtime nodes array of the scene graph. * * @alias ModelRuntimeNode * @constructor @@ -67,7 +67,7 @@ function ModelRuntimeNode(options) { * Whether or not to show this node and its children. This can be toggled * by the user through {@link ModelNode}. * - * @type {Boolean} + * @type {boolean} * * @default true * @@ -81,7 +81,7 @@ function ModelRuntimeNode(options) { * own transform. If this is true, the node will ignore animations in the * model's asset. * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -222,7 +222,7 @@ Object.defineProperties(ModelRuntimeNode.prototype, { * The indices of the children of this node in the scene graph. * * @memberof ModelRuntimeNode.prototype - * @type {Number[]} + * @type {number[]} * @readonly * * @private @@ -438,7 +438,7 @@ Object.defineProperties(ModelRuntimeNode.prototype, { * in the model's asset to affect the node's properties. * * @memberof ModelRuntimeNode.prototype - * @type {Number[]} + * @type {number[]} * * @private */ @@ -541,7 +541,7 @@ function updateTransformFromParameters(runtimeNode, transformParameters) { /** * Returns the child with the given index. * - * @param {Number} index The index of the child. + * @param {number} index The index of the child. * * @returns {ModelRuntimeNode} * diff --git a/packages/engine/Source/Scene/Model/ModelRuntimePrimitive.js b/packages/engine/Source/Scene/Model/ModelRuntimePrimitive.js index 0fce1dd66d3..5593643409e 100644 --- a/packages/engine/Source/Scene/Model/ModelRuntimePrimitive.js +++ b/packages/engine/Source/Scene/Model/ModelRuntimePrimitive.js @@ -30,7 +30,7 @@ import WireframePipelineStage from "./WireframePipelineStage.js"; * In memory representation of a single primitive, that is, a primitive * and its corresponding mesh. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.Primitive} options.primitive The primitive component. * @param {ModelComponents.Node} options.node The node that this primitive belongs to. * @param {Model} options.model The {@link Model} this primitive belongs to. @@ -141,7 +141,7 @@ function ModelRuntimePrimitive(options) { * Model; this is just a reference. * </p> * - * @type {Number[]} + * @type {number[]} * * @private */ @@ -157,7 +157,7 @@ function ModelRuntimePrimitive(options) { * Model; this is just a reference. * </p> * - * @type {Number[]} + * @type {number[]} * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelSceneGraph.js b/packages/engine/Source/Scene/Model/ModelSceneGraph.js index d7f2d8f8bad..1ff305d3adc 100644 --- a/packages/engine/Source/Scene/Model/ModelSceneGraph.js +++ b/packages/engine/Source/Scene/Model/ModelSceneGraph.js @@ -28,7 +28,7 @@ import PrimitiveRenderResources from "./PrimitiveRenderResources.js"; /** * An in memory representation of the scene graph for a {@link Model} * - * @param {Object} options An object containing the following options + * @param {object} options An object containing the following options * @param {Model} options.model The model this scene graph belongs to * @param {ModelComponents} options.modelComponents The model components describing the model * @@ -99,7 +99,7 @@ function ModelSceneGraph(options) { /** * The indices of the root nodes in the runtime nodes array. * - * @type {Number[]} + * @type {number[]} * @readonly * * @private @@ -111,7 +111,7 @@ function ModelSceneGraph(options) { * to the nodes that will be manipulated by their skin, as opposed to the nodes * acting as joints for the skin. * - * @type {Number[]} + * @type {number[]} * @readonly * * @private @@ -375,7 +375,7 @@ function computeModelMatrix2D(sceneGraph, frameState) { * @param {ModelSceneGraph} sceneGraph The scene graph * @param {ModelComponents.Node} node The current node * @param {Matrix4} transformToRoot The transforms of this node's ancestors. - * @returns {Number} The index of this node in the runtimeNodes array. + * @returns {number} The index of this node in the runtimeNodes array. * * @private */ @@ -713,7 +713,7 @@ ModelSceneGraph.prototype.updateJointMatrices = function () { * @callback traverseSceneGraphCallback * * @param {ModelRuntimePrimitive} runtimePrimitive The runtime primitive for the current step of the traversal - * @param {Object} [options] A dictionary of additional options to be passed to the callback, or undefined if the callback does not need any additional information. + * @param {object} [options] A dictionary of additional options to be passed to the callback, or undefined if the callback does not need any additional information. * * @private */ @@ -725,9 +725,9 @@ ModelSceneGraph.prototype.updateJointMatrices = function () { * * @param {ModelSceneGraph} sceneGraph The scene graph. * @param {ModelRuntimeNode} runtimeNode The current runtime node. - * @param {Boolean} visibleNodesOnly Whether to only traverse nodes that are visible. + * @param {boolean} visibleNodesOnly Whether to only traverse nodes that are visible. * @param {traverseSceneGraphCallback} callback The callback to perform on the runtime primitives of the node. - * @param {Object} [callbackOptions] A dictionary of additional options to be passed to the callback, if needed. + * @param {object} [callbackOptions] A dictionary of additional options to be passed to the callback, if needed. * * @private */ @@ -790,7 +790,7 @@ const scratchBackFaceCullingOptions = { /** * Traverses through all draw commands and changes the back-face culling setting. * - * @param {Boolean} backFaceCulling The new value for the back-face culling setting. + * @param {boolean} backFaceCulling The new value for the back-face culling setting. * * @private */ @@ -841,7 +841,7 @@ const scratchShowBoundingVolumeOptions = { /** * Traverses through all draw commands and changes whether to show the debug bounding volume. * - * @param {Boolean} debugShowBoundingVolume The new value for showing the debug bounding volume. + * @param {boolean} debugShowBoundingVolume The new value for showing the debug bounding volume. * * @private */ @@ -926,8 +926,8 @@ function pushPrimitiveDrawCommands(runtimePrimitive, options) { /** * Sets the current value of an articulation stage. * - * @param {String} articulationStageKey The name of the articulation, a space, and the name of the stage. - * @param {Number} value The numeric value of this stage of the articulation. + * @param {string} articulationStageKey The name of the articulation, a space, and the name of the stage. + * @param {number} value The numeric value of this stage of the articulation. * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelSilhouettePipelineStage.js b/packages/engine/Source/Scene/Model/ModelSilhouettePipelineStage.js index d94a052299b..abcdee908fc 100644 --- a/packages/engine/Source/Scene/Model/ModelSilhouettePipelineStage.js +++ b/packages/engine/Source/Scene/Model/ModelSilhouettePipelineStage.js @@ -19,7 +19,7 @@ const ModelSilhouettePipelineStage = { * Tracks how many silhouettes have been created. This value is used to * assign a reference number to the stencil. * - * @type {Number} + * @type {number} * @private */ ModelSilhouettePipelineStage.silhouettesLength = 0; diff --git a/packages/engine/Source/Scene/Model/ModelSkin.js b/packages/engine/Source/Scene/Model/ModelSkin.js index 82b85c7e0d3..72f7dca5549 100644 --- a/packages/engine/Source/Scene/Model/ModelSkin.js +++ b/packages/engine/Source/Scene/Model/ModelSkin.js @@ -7,7 +7,7 @@ import defaultValue from "../../Core/defaultValue.js"; * Skins should only be initialized after all of the {@link ModelRuntimeNode}s have been instantiated * by the scene graph. * - * @param {Object} options An object containing the following options: + * @param {object} options An object containing the following options: * @param {ModelComponents.Skin} options.skin The corresponding skin components from the 3D model * @param {ModelSceneGraph} options.sceneGraph The scene graph this skin belongs to. * diff --git a/packages/engine/Source/Scene/Model/ModelStatistics.js b/packages/engine/Source/Scene/Model/ModelStatistics.js index 3b641cb0422..3188895efc5 100644 --- a/packages/engine/Source/Scene/Model/ModelStatistics.js +++ b/packages/engine/Source/Scene/Model/ModelStatistics.js @@ -15,7 +15,7 @@ function ModelStatistics() { /** * Total number of points across all POINTS primitives in this model. * - * @type {Number} + * @type {number} * @private */ this.pointsLength = 0; @@ -24,7 +24,7 @@ function ModelStatistics() { * Total number of triangles across all TRIANGLES, TRIANGLE_STRIP or * TRIANGLE_FAN primitives in this model. * - * @type {Number} + * @type {number} * @private */ this.trianglesLength = 0; @@ -35,7 +35,7 @@ function ModelStatistics() { * buffers of all the model's primitives. Any attributes generated by the * pipeline are included in this total. * - * @type {Number} + * @type {number} * @private */ this.geometryByteLength = 0; @@ -44,7 +44,7 @@ function ModelStatistics() { * Total size of all textures in bytes. This includes materials, * feature ID textures, and property textures. * - * @type {Number} + * @type {number} * @private */ this.texturesByteLength = 0; @@ -53,7 +53,7 @@ function ModelStatistics() { * Total size of property tables. This excludes the batch textures used for * picking and styling. * - * @type {Number} + * @type {number} * @private */ this.propertyTablesByteLength = 0; @@ -77,7 +77,7 @@ Object.defineProperties(ModelStatistics.prototype, { * * @memberof ModelStatistics.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -121,7 +121,7 @@ ModelStatistics.prototype.clear = function () { * counted again. * * @param {Buffer} buffer The GPU buffer associated with the model. - * @param {Boolean} hasCpuCopy Whether the buffer has a copy on the CPU via typed array. + * @param {boolean} hasCpuCopy Whether the buffer has a copy on the CPU via typed array. * * @private */ diff --git a/packages/engine/Source/Scene/Model/ModelType.js b/packages/engine/Source/Scene/Model/ModelType.js index afd78417b2c..56e39db6b38 100644 --- a/packages/engine/Source/Scene/Model/ModelType.js +++ b/packages/engine/Source/Scene/Model/ModelType.js @@ -6,7 +6,7 @@ import DeveloperError from "../../Core/DeveloperError.js"; * which include individual glTF models, and various 3D Tiles formats * (including glTF via <code>3DTILES_content_gltf</code>). * - * @enum {String} + * @enum {string} * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -18,7 +18,7 @@ const ModelType = { * which is for 3D Tiles * </p> * - * @type {String} + * @type {string} * @constant */ GLTF: "GLTF", @@ -30,28 +30,28 @@ const ModelType = { * which is for individual models * </p> * - * @type {String} + * @type {string} * @constant */ TILE_GLTF: "TILE_GLTF", /** * A 3D Tiles 1.0 Batched 3D Model * - * @type {String} + * @type {string} * @constant */ TILE_B3DM: "B3DM", /** * A 3D Tiles 1.0 Instanced 3D Model * - * @type {String} + * @type {string} * @constant */ TILE_I3DM: "I3DM", /** * A 3D Tiles 1.0 Point Cloud * - * @type {String} + * @type {string} * @constant */ TILE_PNTS: "PNTS", @@ -59,7 +59,7 @@ const ModelType = { /** * GeoJSON content for <code>MAXAR_content_geojson</code> extension * - * @type {String} + * @type {string} * @constant */ TILE_GEOJSON: "TILE_GEOJSON", @@ -68,7 +68,7 @@ const ModelType = { /** * Check if a model is used for 3D Tiles. * @param {ModelType} modelType The type of model - * @returns {Boolean} <code>true</code> if the model is a 3D Tiles format, <code>false</code> otherwise + * @returns {boolean} <code>true</code> if the model is a 3D Tiles format, <code>false</code> otherwise */ ModelType.is3DTiles = function (modelType) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/Model/ModelUtility.js b/packages/engine/Source/Scene/Model/ModelUtility.js index b99f9e8076b..20b06b70167 100644 --- a/packages/engine/Source/Scene/Model/ModelUtility.js +++ b/packages/engine/Source/Scene/Model/ModelUtility.js @@ -21,8 +21,8 @@ function ModelUtility() {} * Create a function for reporting when a model fails to load * * @param {Model} model The model to report about - * @param {String} type The type of object to report about - * @param {String} path The URI of the model file + * @param {string} type The type of object to report about + * @param {string} path The URI of the model file * @returns {Function} An error function that throws an error for the failed model * * @private @@ -70,7 +70,7 @@ ModelUtility.getNodeTransform = function (node) { * * @param {ModelComponents.Primitive|ModelComponents.Instances} object The primitive components or instances object * @param {VertexAttributeSemantic|InstanceAttributeSemantic} semantic The semantic to search for - * @param {Number} [setIndex] The set index of the semantic. May be undefined for some semantics (POSITION, NORMAL, TRANSLATION, ROTATION, for example) + * @param {number} [setIndex] The set index of the semantic. May be undefined for some semantics (POSITION, NORMAL, TRANSLATION, ROTATION, for example) * @return {ModelComponents.Attribute} The selected attribute, or undefined if not found. * * @private @@ -96,7 +96,7 @@ ModelUtility.getAttributeBySemantic = function (object, semantic, setIndex) { * as custom attributes do not have a semantic. * * @param {ModelComponents.Primitive|ModelComponents.Instances} object The primitive components or instances object - * @param {String} name The name of the attribute as it appears in the model file. + * @param {string} name The name of the attribute as it appears in the model file. * @return {ModelComponents.Attribute} The selected attribute, or undefined if not found. * * @private @@ -117,8 +117,8 @@ ModelUtility.getAttributeByName = function (object, name) { /** * Find a feature ID from an array with label or positionalLabel matching the * given label - * @param {Array.<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange|ModelComponents.FeatureIdTexture>} featureIds - * @param {String} label the label to search for + * @param {ModelComponents.FeatureIdAttribute[]|ModelComponents.FeatureIdImplicitRange[]|ModelComponents.FeatureIdTexture[]} featureIds + * @param {string} label the label to search for * @returns {ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange|ModelComponents.FeatureIdTexture} The feature ID set if found, otherwise <code>undefined</code> * * @private @@ -215,7 +215,7 @@ const cartesianMinScratch = new Cartesian3(); * @param {Cartesian3} [instancingTranslationMin] The component-wise minimum value of the instancing translation attribute. * @param {Cartesian3} [instancingTranslationMax] The component-wise maximum value of the instancing translation attribute. * - * @returns {Object} An object containing the minimum and maximum position values. + * @returns {object} An object containing the minimum and maximum position values. * * @private */ @@ -324,9 +324,9 @@ ModelUtility.getCullFace = function (modelMatrix, primitiveType) { * // Returns "_1234" * ModelUtility.sanitizeGlslIdentifier("1234"); * - * @param {String} identifier The original identifier. + * @param {string} identifier The original identifier. * - * @returns {String} The sanitized version of the identifier. + * @returns {string} The sanitized version of the identifier. */ ModelUtility.sanitizeGlslIdentifier = function (identifier) { // Remove non-alphanumeric characters and replace with a single underscore. @@ -371,7 +371,7 @@ ModelUtility.supportedExtensions = { * supported. If an unsupported extension is found, this throws * a {@link RuntimeError} with the extension name. * - * @param {Array<String>} extensionsRequired The extensionsRequired array in the glTF. + * @param {string[]} extensionsRequired The extensionsRequired array in the glTF. */ ModelUtility.checkSupportedExtensions = function (extensionsRequired) { const length = extensionsRequired.length; diff --git a/packages/engine/Source/Scene/Model/NodeRenderResources.js b/packages/engine/Source/Scene/Model/NodeRenderResources.js index d81c9600f5d..9cb251e6bfa 100644 --- a/packages/engine/Source/Scene/Model/NodeRenderResources.js +++ b/packages/engine/Source/Scene/Model/NodeRenderResources.js @@ -45,7 +45,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * A dictionary mapping uniform name to functions that return the uniform * values. Inherited from the model render resources. * - * @type {Object.<String, Function>} + * @type {Object.<string, Function>} * @readonly * * @private @@ -69,7 +69,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * when the {@link DrawCommand} is constructed. Inherited from the model * render resources. * - * @type {Object} + * @type {object} * @readonly * * @private @@ -83,7 +83,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * Whether the model has a silhouette. This value indicates what draw commands * are needed. Inherited from the model render resources. * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -95,7 +95,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * optimization. This value indicates what draw commands are needed. * Inherited from the model render resources. * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -129,7 +129,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * The index to give to the next vertex attribute added to the attributes array. * POSITION takes index 0. * - * @type {Number} + * @type {number} * * @private */ @@ -139,7 +139,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * The set index to assign to feature ID vertex attribute(s) created from the * offset/repeat in the feature ID attribute. * - * @type {Number} + * @type {number} * @default 0 * * @private @@ -149,7 +149,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { /** * The number of instances. This value is set by InstancingPipelineStage. * - * @type {Number} + * @type {number} * @default 0 * * @private diff --git a/packages/engine/Source/Scene/Model/PntsLoader.js b/packages/engine/Source/Scene/Model/PntsLoader.js index 58da7fe30ae..ac6013e1cd7 100644 --- a/packages/engine/Source/Scene/Model/PntsLoader.js +++ b/packages/engine/Source/Scene/Model/PntsLoader.js @@ -42,10 +42,10 @@ const MetallicRoughness = ModelComponents.MetallicRoughness; * @augments ResourceLoader * @private * - * @param {Object} options An object containing the following properties + * @param {object} options An object containing the following properties * @param {ArrayBuffer} options.arrayBuffer The array buffer of the pnts contents - * @param {Number} [options.byteOffset] The byte offset to the beginning of the pnts contents in the array buffer - * @param {Boolean} [options.loadAttributesFor2D=false] If true, load the positions buffer as a typed array for accurately projecting models to 2D. + * @param {number} [options.byteOffset] The byte offset to the beginning of the pnts contents in the array buffer + * @param {boolean} [options.loadAttributesFor2D=false] If true, load the positions buffer as a typed array for accurately projecting models to 2D. */ function PntsLoader(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -86,7 +86,7 @@ Object.defineProperties(PntsLoader.prototype, { * * @memberof PntsLoader.prototype * - * @type {Promise.<PntsLoader>|undefined} + * @type {Promise<PntsLoader>|undefined} * @readonly * @private */ @@ -100,7 +100,7 @@ Object.defineProperties(PntsLoader.prototype, { * * @memberof PntsLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -144,7 +144,7 @@ Object.defineProperties(PntsLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<PntsLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<PntsLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ PntsLoader.prototype.load = function () { diff --git a/packages/engine/Source/Scene/Model/PointCloudStylingPipelineStage.js b/packages/engine/Source/Scene/Model/PointCloudStylingPipelineStage.js index 369f5d42761..cb8e8af2cfd 100644 --- a/packages/engine/Source/Scene/Model/PointCloudStylingPipelineStage.js +++ b/packages/engine/Source/Scene/Model/PointCloudStylingPipelineStage.js @@ -355,7 +355,7 @@ function addShaderFunctionsAndDefines(shaderBuilder, shaderFunctionInfo) { * function. * * @param {Function} source The style function. - * @param {String[]} propertyNames The array of property names to add to. + * @param {string[]} propertyNames The array of property names to add to. * * @private */ diff --git a/packages/engine/Source/Scene/Model/PrimitiveOutlineGenerator.js b/packages/engine/Source/Scene/Model/PrimitiveOutlineGenerator.js index 06d2dcf8890..2e6e73a2cfe 100644 --- a/packages/engine/Source/Scene/Model/PrimitiveOutlineGenerator.js +++ b/packages/engine/Source/Scene/Model/PrimitiveOutlineGenerator.js @@ -32,10 +32,10 @@ const MAX_GLTF_UINT8_INDEX = 255; * @alias PrimitiveOutlineGenerator * @constructor * - * @param {Number} options Object with the following properties: + * @param {number} options Object with the following properties: * @param {Uint8Array|Uint16Array|Uint32Array} options.triangleIndices The original triangle indices of the primitive. The constructor takes ownership of this typed array as it will be modified internally. Use the updatedTriangleIndices getter to get the final result. - * @param {Number[]} options.outlineIndices The indices of edges in the triangle from the CESIUM_primitive_outline extension - * @param {Number} options.originalVertexCount The original number of vertices in the primitive + * @param {number[]} options.outlineIndices The indices of edges in the triangle from the CESIUM_primitive_outline extension + * @param {number} options.originalVertexCount The original number of vertices in the primitive * @example * // The constructor will compute the updated indices and generate outline * // coordinates. @@ -88,7 +88,7 @@ function PrimitiveOutlineGenerator(options) { /** * How many vertices were originally in the primitive * - * @type {Number} + * @type {number} * * @private */ @@ -120,7 +120,7 @@ function PrimitiveOutlineGenerator(options) { * Array containing the indices of any vertices that must be copied and * appended to the list. * - * @type {Number[]} + * @type {number[]} * * @private */ @@ -294,14 +294,14 @@ function initialize(outlineGenerator) { * and if found, computes outline coordinates for the three vertices. If not * possible, one of the vertices is returned so it can be copied. * - * @param {Number[]} outlineCoordinates An array to store the computed outline coordinates. There are 3 components per vertex. This will be modified in place. - * @param {Number} i0 The index of the first vertex of the triangle. - * @param {Number} i1 The index of the second vertex of the triangle. - * @param {Number} i2 The index of the third vertex of the triangle. - * @param {Boolean} hasEdge01 Whether there is an outline edge between vertices 0 and 1 of the triangle - * @param {Boolean} hasEdge12 Whether there is an outline edge between vertices 1 and 2 of the triangle - * @param {Boolean} hasEdge20 Whether there is an outline edge between vertices 2 and 0 of the triangle - * @returns {Number} If it's not possible to compute consistent outline coordinates for this triangle, the index of the most constrained vertex of i0, i1 and i2 is returned. Otherwise, this function returns undefined to indicate a successful match. + * @param {number[]} outlineCoordinates An array to store the computed outline coordinates. There are 3 components per vertex. This will be modified in place. + * @param {number} i0 The index of the first vertex of the triangle. + * @param {number} i1 The index of the second vertex of the triangle. + * @param {number} i2 The index of the third vertex of the triangle. + * @param {boolean} hasEdge01 Whether there is an outline edge between vertices 0 and 1 of the triangle + * @param {boolean} hasEdge12 Whether there is an outline edge between vertices 1 and 2 of the triangle + * @param {boolean} hasEdge20 Whether there is an outline edge between vertices 2 and 0 of the triangle + * @returns {number} If it's not possible to compute consistent outline coordinates for this triangle, the index of the most constrained vertex of i0, i1 and i2 is returned. Otherwise, this function returns undefined to indicate a successful match. * * @private */ @@ -448,12 +448,12 @@ function matchAndStoreCoordinates( * Then we can find an ordering that works for all three vertices with a * bitwise AND. * - * @param {Number[]} outlineCoordinates The array of outline coordinates - * @param {Number} vertexIndex The index of the vertex to compute the mask for - * @param {Number} a The outline coordinate for edge 2-0 - * @param {Number} b The outline coordinate for edge 0-1 - * @param {Number} c The outline coordinate for edge 1-2 - * @returns {Number} A bitmask with 6 bits where a 1 indicates the corresponding ordering is valid. + * @param {number[]} outlineCoordinates The array of outline coordinates + * @param {number} vertexIndex The index of the vertex to compute the mask for + * @param {number} a The outline coordinate for edge 2-0 + * @param {number} b The outline coordinate for edge 0-1 + * @param {number} c The outline coordinate for edge 1-2 + * @returns {number} A bitmask with 6 bits where a 1 indicates the corresponding ordering is valid. * * @private */ @@ -483,8 +483,8 @@ function computeOrderMask(outlineCoordinates, vertexIndex, a, b, c) { * Compute the popcount for 6-bit integers (values 0-63). This is the * number of 1s in the binary representation of the value. * - * @param {Number} value The value to compute the popcount for - * @returns {Number} The number of 1s in the binary representation of value + * @param {number} value The value to compute the popcount for + * @returns {number} The number of 1s in the binary representation of value * * @private */ @@ -601,7 +601,7 @@ PrimitiveOutlineGenerator.createTexture = function (context) { * mostly 0 values, except for the last value which is brighter to indicate * the outline. * - * @param {Number} size The width of the texture for this mip level + * @param {number} size The width of the texture for this mip level * @returns {Uint8Array} A typed array containing the texels of the mip level * * @private @@ -634,8 +634,8 @@ function createMipLevel(size) { * @alias EdgeSet * @constructor * - * @param {Number[]} edgeIndices An array of vertex indices with an even number of elements where each pair of indices defines an edge. - * @param {Number} originalVertexCount The original number of vertices. This is used for computing a hash function. + * @param {number[]} edgeIndices An array of vertex indices with an even number of elements where each pair of indices defines an edge. + * @param {number} originalVertexCount The original number of vertices. This is used for computing a hash function. * * @private */ @@ -644,7 +644,7 @@ function EdgeSet(edgeIndices, originalVertexCount) { * Original number of vertices in the primitive. This is used for computing * the hash key * - * @type {Number} + * @type {number} * * @private */ @@ -673,9 +673,9 @@ function EdgeSet(edgeIndices, originalVertexCount) { /** * Check if an edge exists in the set. The order of the input vertices does * not matter. - * @param {Number} a The first index - * @param {Number} b The second index - * @returns {Boolean} true if there is an edge between a and b + * @param {number} a The first index + * @param {number} b The second index + * @returns {boolean} true if there is an edge between a and b * * @private */ diff --git a/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js b/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js index 5a0d8d1cceb..3d9606bd937 100644 --- a/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js +++ b/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js @@ -57,7 +57,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * The index to give to the next vertex attribute added to the attributes * array. POSITION takes index 0. Inherited from the node render resources. * - * @type {Number} + * @type {number} * * @private */ @@ -68,7 +68,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * offset/repeat in the feature ID attribute. Inherited from the node render * resources. * - * @type {Number} + * @type {number} * * @private */ @@ -79,7 +79,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * A dictionary mapping uniform name to functions that return the uniform * values. Inherited from the node render resources. * - * @type {Object.<String, Function>} + * @type {Object.<string, Function>} * @readonly * * @private @@ -103,7 +103,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * is created when the {@link DrawCommand} is constructed. Inherited from * the node render resources. * - * @type {Object} + * @type {object} * @readonly * * @private @@ -114,7 +114,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * Whether the model has a silhouette. This value indicates what draw commands * are needed. Inherited from the node render resources. * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -126,7 +126,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * optimization. This value indicates what draw commands are needed. * Inherited from the node render resources. * - * @type {Boolean} + * @type {boolean} * @readonly * * @private @@ -148,7 +148,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * The number of instances. Default is 0, if instancing is not used. * Inherited from the node render resources. * - * @type {Number} + * @type {number} * @readonly * * @private @@ -180,7 +180,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * The number of indices in the primitive. The interpretation of this * depends on the primitive type. * - * @type {Number} + * @type {number} * @readonly * * @private @@ -194,7 +194,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * When present, picking and styling can use this. This value is set by * SelectedFeatureIdPipelineStage. * - * @type {Boolean} + * @type {boolean} * @default false * * @private @@ -287,7 +287,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * The shader variable to use for picking. If picking is enabled, this value * is set by PickingPipelineStage. * - * @type {String} + * @type {string} * * @private */ diff --git a/packages/engine/Source/Scene/Model/StyleCommandsNeeded.js b/packages/engine/Source/Scene/Model/StyleCommandsNeeded.js index fe6c1703f55..a673bbf3b1b 100644 --- a/packages/engine/Source/Scene/Model/StyleCommandsNeeded.js +++ b/packages/engine/Source/Scene/Model/StyleCommandsNeeded.js @@ -2,7 +2,7 @@ * An enum describing what commands (opaque or translucent) are required by * a {@link Cesium3DTileStyle}. * - * @enum {Number} + * @enum {number} * @private */ const StyleCommandsNeeded = { diff --git a/packages/engine/Source/Scene/Model/TextureManager.js b/packages/engine/Source/Scene/Model/TextureManager.js index daff9281819..fb13fda6291 100644 --- a/packages/engine/Source/Scene/Model/TextureManager.js +++ b/packages/engine/Source/Scene/Model/TextureManager.js @@ -29,7 +29,7 @@ function TextureManager() { /** * Get one of the loaded textures - * @param {String} textureId The unique ID of the texture loaded by {@link TextureManager#loadTexture2D} + * @param {string} textureId The unique ID of the texture loaded by {@link TextureManager#loadTexture2D} * @return {Texture} The texture or <code>undefined</code> if no texture exists */ TextureManager.prototype.getTexture = function (textureId) { @@ -60,7 +60,7 @@ function fetchTexture2D(textureManager, textureId, textureUniform) { * Load a texture 2D asynchronously. Note that {@link TextureManager#update} * must be called in the render loop to finish processing the textures. * - * @param {String} textureId A unique ID to identify this texture. + * @param {string} textureId A unique ID to identify this texture. * @param {TextureUniform} textureUniform A description of the texture * * @private @@ -203,7 +203,7 @@ TextureManager.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see TextureManager#destroy * @private diff --git a/packages/engine/Source/Scene/Model/TextureUniform.js b/packages/engine/Source/Scene/Model/TextureUniform.js index b74ddfef842..ef0b4b80980 100644 --- a/packages/engine/Source/Scene/Model/TextureUniform.js +++ b/packages/engine/Source/Scene/Model/TextureUniform.js @@ -11,17 +11,17 @@ import TextureWrap from "../../Renderer/TextureWrap.js"; * A simple struct that serves as a value of a <code>sampler2D</code>-valued * uniform. This is used with {@link CustomShader} and {@link TextureManager} * - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {Uint8Array} [options.typedArray] A typed array storing the contents of a texture. Values are stored in row-major order. Since WebGL uses a y-up convention for textures, rows are listed from bottom to top. - * @param {Number} [options.width] The width of the image. Required when options.typedArray is present - * @param {Number} [options.height] The height of the image. Required when options.typedArray is present. - * @param {String|Resource} [options.url] A URL string or resource pointing to a texture image. - * @param {Boolean} [options.repeat=true] When defined, the texture sampler will be set to wrap in both directions + * @param {number} [options.width] The width of the image. Required when options.typedArray is present + * @param {number} [options.height] The height of the image. Required when options.typedArray is present. + * @param {string|Resource} [options.url] A URL string or resource pointing to a texture image. + * @param {boolean} [options.repeat=true] When defined, the texture sampler will be set to wrap in both directions * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] When options.typedArray is defined, this is used to determine the pixel format of the texture * @param {PixelDatatype} [options.pixelDatatype=PixelDatatype.UNSIGNED_BYTE] When options.typedArray is defined, this is the data type of pixel values in the typed array. * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The minification filter of the texture sampler. * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The magnification filter of the texture sampler. - * @param {Number} [options.maximumAnisotropy=1.0] The maximum anisotropy of the texture sampler + * @param {number} [options.maximumAnisotropy=1.0] The maximum anisotropy of the texture sampler * * @alias TextureUniform * @constructor diff --git a/packages/engine/Source/Scene/Model/UniformType.js b/packages/engine/Source/Scene/Model/UniformType.js index 999d134042a..d8cd20aee2c 100644 --- a/packages/engine/Source/Scene/Model/UniformType.js +++ b/packages/engine/Source/Scene/Model/UniformType.js @@ -2,7 +2,7 @@ * An enum of the basic GLSL uniform types. These can be used with * {@link CustomShader} to declare user-defined uniforms. * - * @enum {String} + * @enum {string} * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -10,111 +10,111 @@ const UniformType = { /** * A single floating point value. * - * @type {String} + * @type {string} * @constant */ FLOAT: "float", /** * A vector of 2 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC2: "vec2", /** * A vector of 3 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC3: "vec3", /** * A vector of 4 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC4: "vec4", /** * A single integer value * - * @type {String} + * @type {string} * @constant */ INT: "int", /** * A vector of 2 integer values. * - * @type {String} + * @type {string} * @constant */ INT_VEC2: "ivec2", /** * A vector of 3 integer values. * - * @type {String} + * @type {string} * @constant */ INT_VEC3: "ivec3", /** * A vector of 4 integer values. * - * @type {String} + * @type {string} * @constant */ INT_VEC4: "ivec4", /** * A single boolean value. * - * @type {String} + * @type {string} * @constant */ BOOL: "bool", /** * A vector of 2 boolean values. * - * @type {String} + * @type {string} * @constant */ BOOL_VEC2: "bvec2", /** * A vector of 3 boolean values. * - * @type {String} + * @type {string} * @constant */ BOOL_VEC3: "bvec3", /** * A vector of 4 boolean values. * - * @type {String} + * @type {string} * @constant */ BOOL_VEC4: "bvec4", /** * A 2x2 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT2: "mat2", /** * A 3x3 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT3: "mat2", /** * A 3x3 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT4: "mat4", /** * A 2D sampled texture. - * @type {String} + * @type {string} * @constant */ SAMPLER_2D: "sampler2D", diff --git a/packages/engine/Source/Scene/Model/VaryingType.js b/packages/engine/Source/Scene/Model/VaryingType.js index 53bd15775f7..3b588dd175b 100644 --- a/packages/engine/Source/Scene/Model/VaryingType.js +++ b/packages/engine/Source/Scene/Model/VaryingType.js @@ -2,7 +2,7 @@ * An enum for the GLSL varying types. These can be used for declaring varyings * in {@link CustomShader} * - * @enum {String} + * @enum {string} * * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -10,49 +10,49 @@ const VaryingType = { /** * A single floating point value. * - * @type {String} + * @type {string} * @constant */ FLOAT: "float", /** * A vector of 2 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC2: "vec2", /** * A vector of 3 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC3: "vec3", /** * A vector of 4 floating point values. * - * @type {String} + * @type {string} * @constant */ VEC4: "vec4", /** * A 2x2 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT2: "mat2", /** * A 3x3 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT3: "mat2", /** * A 3x3 matrix of floating point values. * - * @type {String} + * @type {string} * @constant */ MAT4: "mat4", diff --git a/packages/engine/Source/Scene/ModelAnimationLoop.js b/packages/engine/Source/Scene/ModelAnimationLoop.js index d285da0ff02..9b661a0bab8 100644 --- a/packages/engine/Source/Scene/ModelAnimationLoop.js +++ b/packages/engine/Source/Scene/ModelAnimationLoop.js @@ -1,7 +1,7 @@ /** * Determines if and how a glTF animation is looped. * - * @enum {Number} + * @enum {number} * * @see ModelAnimationCollection#add */ @@ -9,7 +9,7 @@ const ModelAnimationLoop = { /** * Play the animation once; do not loop it. * - * @type {Number} + * @type {number} * @constant */ NONE: 0, @@ -17,7 +17,7 @@ const ModelAnimationLoop = { /** * Loop the animation playing it from the start immediately after it stops. * - * @type {Number} + * @type {number} * @constant */ REPEAT: 1, @@ -25,7 +25,7 @@ const ModelAnimationLoop = { /** * Loop the animation. First, playing it forward, then in reverse, then forward, and so on. * - * @type {Number} + * @type {number} * @constant */ MIRRORED_REPEAT: 2, diff --git a/packages/engine/Source/Scene/ModelComponents.js b/packages/engine/Source/Scene/ModelComponents.js index 06b3ac503c8..a2381934378 100644 --- a/packages/engine/Source/Scene/ModelComponents.js +++ b/packages/engine/Source/Scene/ModelComponents.js @@ -25,7 +25,7 @@ function Quantization() { /** * Whether the quantized attribute is oct-encoded. * - * @type {Boolean} + * @type {boolean} * @private */ this.octEncoded = false; @@ -33,7 +33,7 @@ function Quantization() { /** * Whether the oct-encoded values are stored as ZXY instead of XYZ. This is true when decoding from Draco. * - * @type {Boolean} + * @type {boolean} * @private */ this.octEncodedZXY = false; @@ -43,7 +43,7 @@ function Quantization() { * This is typically computed as (1 << quantizationBits) - 1. * For oct-encoded values this value is a single Number. * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.normalizationRange = undefined; @@ -53,7 +53,7 @@ function Quantization() { * The type should match the attribute type - e.g. if the attribute type * is AttributeType.VEC4 the offset should be a Cartesian4. * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.quantizedVolumeOffset = undefined; @@ -63,7 +63,7 @@ function Quantization() { * The type should match the attribute type - e.g. if the attribute type * is AttributeType.VEC4 the dimensions should be a Cartesian4. * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.quantizedVolumeDimensions = undefined; @@ -75,7 +75,7 @@ function Quantization() { * The type should match the attribute type - e.g. if the attribute type * is AttributeType.VEC4 the dimensions should be a Cartesian4. * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.quantizedVolumeStepSize = undefined; @@ -118,7 +118,7 @@ function Attribute() { /** * The attribute name. Must be unique within the attributes array. * - * @type {String} + * @type {string} * @private */ this.name = undefined; @@ -182,7 +182,7 @@ function Attribute() { /** * Whether the attribute is normalized. * - * @type {Boolean} + * @type {boolean} * @default false * @private */ @@ -191,7 +191,7 @@ function Attribute() { /** * The number of elements. * - * @type {Number} + * @type {number} * @private */ this.count = undefined; @@ -206,7 +206,7 @@ function Attribute() { * Must be defined for POSITION attributes. * </p> * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.min = undefined; @@ -221,7 +221,7 @@ function Attribute() { * Must be defined for POSITION attributes. * </p> * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.max = undefined; @@ -229,7 +229,7 @@ function Attribute() { /** * A constant value used for all elements when typed array and buffer are undefined. * - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @private */ this.constant = undefined; @@ -262,7 +262,7 @@ function Attribute() { /** * The byte offset of elements in the buffer. * - * @type {Number} + * @type {number} * @default 0 * @private */ @@ -271,7 +271,7 @@ function Attribute() { /** * The byte stride of elements in the buffer. When undefined the elements are tightly packed. * - * @type {Number} + * @type {number} * @private */ this.byteStride = undefined; @@ -297,7 +297,7 @@ function Indices() { /** * The number of indices. * - * @type {Number} + * @type {number} * @private */ this.count = undefined; @@ -332,7 +332,7 @@ function FeatureIdAttribute() { /** * How many unique features are defined in this set of feature IDs * - * @type {Number} + * @type {number} * @private */ this.featureCount = undefined; @@ -340,7 +340,7 @@ function FeatureIdAttribute() { /** * This value indicates that no feature is indicated with this vertex * - * @type {Number} + * @type {number} * @private */ this.nullFeatureId = undefined; @@ -350,7 +350,7 @@ function FeatureIdAttribute() { * feature IDs are used for classification, but no metadata is associated. * * - * @type {Number} + * @type {number} * @private */ this.propertyTableId = undefined; @@ -358,7 +358,7 @@ function FeatureIdAttribute() { /** * The set index of feature ID attribute containing feature IDs. * - * @type {Number} + * @type {number} * @private */ this.setIndex = undefined; @@ -367,7 +367,7 @@ function FeatureIdAttribute() { * The label to identify this set of feature IDs. This is used in picking, * styling and shaders. * - * @type {String} + * @type {string} * @private */ this.label = undefined; @@ -377,7 +377,7 @@ function FeatureIdAttribute() { * This will always be either "featureId_N" for primitives or * "instanceFeatureId_N" for instances. * - * @type {String} + * @type {string} * @private */ this.positionalLabel = undefined; @@ -397,7 +397,7 @@ function FeatureIdImplicitRange() { /** * How many unique features are defined in this set of feature IDs * - * @type {Number} + * @type {number} * @private */ this.featureCount = undefined; @@ -405,7 +405,7 @@ function FeatureIdImplicitRange() { /** * This value indicates that no feature is indicated with this vertex * - * @type {Number} + * @type {number} * @private */ this.nullFeatureId = undefined; @@ -414,7 +414,7 @@ function FeatureIdImplicitRange() { * The ID of the property table that feature IDs index into. If undefined, * feature IDs are used for classification, but no metadata is associated. * - * @type {Number} + * @type {number} * @private */ this.propertyTableId = undefined; @@ -422,7 +422,7 @@ function FeatureIdImplicitRange() { /** * The first feature ID to use when setIndex is undefined * - * @type {Number} + * @type {number} * @default 0 * @private */ @@ -431,7 +431,7 @@ function FeatureIdImplicitRange() { /** * Number of times each feature ID is repeated before being incremented. * - * @type {Number} + * @type {number} * @private */ this.repeat = undefined; @@ -440,7 +440,7 @@ function FeatureIdImplicitRange() { * The label to identify this set of feature IDs. This is used in picking, * styling and shaders. * - * @type {String} + * @type {string} * @private */ this.label = undefined; @@ -450,7 +450,7 @@ function FeatureIdImplicitRange() { * This will always be either "featureId_N" for primitives or * "instanceFeatureId_N" for instances. * - * @type {String} + * @type {string} * @private */ this.positionalLabel = undefined; @@ -468,7 +468,7 @@ function FeatureIdTexture() { /** * How many unique features are defined in this set of feature IDs * - * @type {Number} + * @type {number} * @private */ this.featureCount = undefined; @@ -476,7 +476,7 @@ function FeatureIdTexture() { /** * This value indicates that no feature is indicated with this texel * - * @type {Number} + * @type {number} * @private */ this.nullFeatureId = undefined; @@ -485,7 +485,7 @@ function FeatureIdTexture() { * The ID of the property table that feature IDs index into. If undefined, * feature IDs are used for classification, but no metadata is associated. * - * @type {String} + * @type {string} * @private */ this.propertyTableId = undefined; @@ -502,7 +502,7 @@ function FeatureIdTexture() { * The label to identify this set of feature IDs. This is used in picking, * styling and shaders. * - * @type {String} + * @type {string} * @private */ this.label = undefined; @@ -512,7 +512,7 @@ function FeatureIdTexture() { * This will always be either "featureId_N" for primitives or * "instanceFeatureId_N" for instances. * - * @type {String} + * @type {string} * @private */ this.positionalLabel = undefined; @@ -589,7 +589,7 @@ function Primitive() { * The feature IDs associated with this primitive. Feature ID types may * be interleaved * - * @type {Array.<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange|ModelComponents.FeatureIdTexture>} + * @type {ModelComponents.FeatureIdAttribute[]|ModelComponents.FeatureIdImplicitRange[]|ModelComponents.FeatureIdTexture[]} * @private */ this.featureIds = []; @@ -598,7 +598,7 @@ function Primitive() { * The property texture IDs. These indices correspond to the array of * property textures. * - * @type {Number[]} + * @type {number[]} * @private */ this.propertyTextureIds = []; @@ -607,7 +607,7 @@ function Primitive() { * The property attribute IDs. These indices correspond to the array of * property attributes in the EXT_structural_metadata extension. * - * @type {Number[]} + * @type {number[]} * @private */ this.propertyAttributeIds = []; @@ -643,7 +643,7 @@ function Instances() { * The feature ID attributes associated with this set of instances. * Feature ID attribute types may be interleaved. * - * @type {Array.<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange>} + * @type {ModelComponents.FeatureIdAttribute[]|ModelComponents.FeatureIdImplicitRange[]} * @private */ this.featureIds = []; @@ -653,7 +653,7 @@ function Instances() { * use EXT_mesh_gpu_instancing, the transform is applied in object space. For i3dm files, * the instance transform is in world space. * - * @type {Boolean} + * @type {boolean} * @private */ this.transformInWorldSpace = false; @@ -672,7 +672,7 @@ function Skin() { * The index of the skin in the glTF. This is useful for finding the skin * that applies to a node after the skin is instantiated at runtime. * - * @type {Number} + * @type {number} * @private */ this.index = undefined; @@ -706,7 +706,7 @@ function Node() { /** * The name of the node. * - * @type {String} + * @type {string} * @private */ this.name = undefined; @@ -715,7 +715,7 @@ function Node() { * The index of the node in the glTF. This is useful for finding the nodes * that belong to a skin after they have been instantiated at runtime. * - * @type {Number} + * @type {number} * @private */ this.index = undefined; @@ -790,7 +790,7 @@ function Node() { * An array of weights to be applied to the primitives' morph targets. * These are supplied by either the node or its mesh. * - * @type {Number[]} + * @type {number[]} * @private */ this.morphWeights = []; @@ -799,7 +799,7 @@ function Node() { * The name of the articulation affecting this node, as defined by the * AGI_articulations extension. * - * @type {String} + * @type {string} * @private */ this.articulationName = undefined; @@ -828,7 +828,7 @@ function Scene() { * this enum are used to look up the appropriate property on the runtime node. * * @alias {ModelComponents.AnimatedPropertyType} - * @enum {String} + * @enum {string} * * @private */ @@ -852,7 +852,7 @@ function AnimationSampler() { /** * The timesteps of the animation. * - * @type {Number[]} + * @type {number[]} * @private */ this.input = []; @@ -868,7 +868,7 @@ function AnimationSampler() { /** * The keyframe data of the animation. * - * @type {Number[]|Cartesian3[]|Quaternion[]} + * @type {number[]|Cartesian3[]|Quaternion[]} * @private */ this.output = []; @@ -938,7 +938,7 @@ function Animation() { /** * The name of the animation. * - * @type {String} + * @type {string} * @private */ this.name = undefined; @@ -973,7 +973,7 @@ function ArticulationStage() { /** * The name of the articulation stage. * - * @type {String} + * @type {string} * @private */ this.name = undefined; @@ -989,7 +989,7 @@ function ArticulationStage() { /** * The minimum value for the range of motion of this articulation stage. * - * @type {Number} + * @type {number} * @private */ this.minimumValue = undefined; @@ -997,7 +997,7 @@ function ArticulationStage() { /** * The maximum value for the range of motion of this articulation stage. * - * @type {Number} + * @type {number} * @private */ this.maximumValue = undefined; @@ -1005,7 +1005,7 @@ function ArticulationStage() { /** * The initial value for this articulation stage. * - * @type {Number} + * @type {number} * @private */ this.initialValue = undefined; @@ -1023,7 +1023,7 @@ function Articulation() { /** * The name of the articulation. * - * @type {String} + * @type {string} * @private */ this.name = undefined; @@ -1165,7 +1165,7 @@ function TextureReader() { * when textures are shared to avoid attaching a texture in multiple uniform * slots in the shader. * - * @type {Number} + * @type {number} * @private */ this.index = undefined; @@ -1173,7 +1173,7 @@ function TextureReader() { /** * The texture coordinate set. * - * @type {Number} + * @type {number} * @default 0 * @private */ @@ -1190,7 +1190,7 @@ function TextureReader() { /** * The texture channels to read from. When undefined all channels are read. * - * @type {String} + * @type {string} */ this.channels = undefined; } @@ -1234,7 +1234,7 @@ function MetallicRoughness() { /** * The metallic factor. * - * @type {Number} + * @type {number} * @default 1.0 * @private */ @@ -1243,7 +1243,7 @@ function MetallicRoughness() { /** * The roughness factor. * - * @type {Number} + * @type {number} * @default 1.0 * @private */ @@ -1315,7 +1315,7 @@ function SpecularGlossiness() { /** * The glossiness factor. * - * @type {Number} + * @type {number} * @default 1.0 * @private */ @@ -1407,7 +1407,7 @@ function Material() { /** * The alpha cutoff value of the material for the MASK alpha mode. * - * @type {Number} + * @type {number} * @default 0.5 * @private */ @@ -1416,7 +1416,7 @@ function Material() { /** * Specifies whether the material is double sided. * - * @type {Boolean} + * @type {boolean} * @default false * @private */ @@ -1425,7 +1425,7 @@ function Material() { /** * Specifies whether the material is unlit. * - * @type {Boolean} + * @type {boolean} * @default false * @private */ diff --git a/packages/engine/Source/Scene/Moon.js b/packages/engine/Source/Scene/Moon.js index e657320ef24..aef70fb880b 100644 --- a/packages/engine/Source/Scene/Moon.js +++ b/packages/engine/Source/Scene/Moon.js @@ -17,11 +17,11 @@ import Material from "./Material.js"; * @alias Moon * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Determines whether the moon will be rendered. - * @param {String} [options.textureUrl=buildModuleUrl('Assets/Textures/moonSmall.jpg')] The moon texture. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.show=true] Determines whether the moon will be rendered. + * @param {string} [options.textureUrl=buildModuleUrl('Assets/Textures/moonSmall.jpg')] The moon texture. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.MOON] The moon ellipsoid. - * @param {Boolean} [options.onlySunLighting=true] Use the sun as the only light source. + * @param {boolean} [options.onlySunLighting=true] Use the sun as the only light source. * * * @example @@ -40,14 +40,14 @@ function Moon(options) { /** * Determines if the moon will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); /** * The moon texture. - * @type {String} + * @type {string} * @default buildModuleUrl('Assets/Textures/moonSmall.jpg') */ this.textureUrl = url; @@ -56,7 +56,7 @@ function Moon(options) { /** * Use the sun as the only light source. - * @type {Boolean} + * @type {boolean} * @default true */ this.onlySunLighting = defaultValue(options.onlySunLighting, true); @@ -142,7 +142,7 @@ Moon.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Moon#destroy */ diff --git a/packages/engine/Source/Scene/Multiple3DTileContent.js b/packages/engine/Source/Scene/Multiple3DTileContent.js index b3c71194297..51b20bb93a4 100644 --- a/packages/engine/Source/Scene/Multiple3DTileContent.js +++ b/packages/engine/Source/Scene/Multiple3DTileContent.js @@ -27,7 +27,7 @@ import preprocess3DTileContent from "./preprocess3DTileContent.js"; * @param {Cesium3DTileset} tileset The tileset this content belongs to * @param {Cesium3DTile} tile The content this content belongs to * @param {Resource} tilesetResource The resource that points to the tileset. This will be used to derive each inner content's resource. - * @param {Object} contentsJson Either the tile JSON containing the contents array (3D Tiles 1.1), or <code>3DTILES_multiple_contents</code> extension JSON + * @param {object} contentsJson Either the tile JSON containing the contents array (3D Tiles 1.1), or <code>3DTILES_multiple_contents</code> extension JSON * * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -80,7 +80,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * Part of the {@link Cesium3DTileContent} interface. <code>Multiple3DTileContent</code> checks if any of the inner contents have dirty featurePropertiesDirty. * @memberof Multiple3DTileContent.prototype * - * @type {Boolean} + * @type {boolean} * * @private */ @@ -111,7 +111,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -128,7 +128,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -145,7 +145,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -162,7 +162,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -179,7 +179,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -196,7 +196,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Number} + * @type {number} * @readonly * * @private @@ -221,7 +221,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * * @memberof Multiple3DTileContent.prototype * - * @type {Promise.<Cesium3DTileContent>|undefined} + * @type {Promise<Cesium3DTileContent>|undefined} * @readonly * * @private @@ -263,7 +263,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * have a single URL, so this returns undefined. * @memberof Multiple3DTileContent.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -327,7 +327,7 @@ Object.defineProperties(Multiple3DTileContent.prototype, { * {@link Cesium3DTileset#debugShowUrl}. * @memberof Multiple3DTileContent.prototype * - * @type {String[]} + * @type {string[]} * @readonly * @private */ @@ -386,7 +386,7 @@ function cancelPendingRequests(multipleContents, originalContentState) { * requests are successfully scheduled. * </p> * - * @return {Number} The number of attempted requests that were unable to be scheduled. + * @return {number} The number of attempted requests that were unable to be scheduled. * @private */ Multiple3DTileContent.prototype.requestInnerContents = function () { @@ -419,8 +419,8 @@ Multiple3DTileContent.prototype.requestInnerContents = function () { /** * Check if all requests for inner contents can be scheduled at once. This is slower, but it avoids a potential memory leak. - * @param {String[]} serverKeys The server keys for all of the inner contents - * @return {Boolean} True if the request scheduler has enough open slots for all inner contents + * @param {string[]} serverKeys The server keys for all of the inner contents + * @return {boolean} True if the request scheduler has enough open slots for all inner contents * @private */ function canScheduleAllRequests(serverKeys) { diff --git a/packages/engine/Source/Scene/NeverTileDiscardPolicy.js b/packages/engine/Source/Scene/NeverTileDiscardPolicy.js index 77b6035d843..555eb450bde 100644 --- a/packages/engine/Source/Scene/NeverTileDiscardPolicy.js +++ b/packages/engine/Source/Scene/NeverTileDiscardPolicy.js @@ -10,7 +10,7 @@ function NeverTileDiscardPolicy(options) {} /** * Determines if the discard policy is ready to process images. - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {boolean} True if the discard policy is ready to process images; otherwise, false. */ NeverTileDiscardPolicy.prototype.isReady = function () { return true; @@ -20,7 +20,7 @@ NeverTileDiscardPolicy.prototype.isReady = function () { * Given a tile image, decide whether to discard that image. * * @param {HTMLImageElement} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {boolean} True if the image should be discarded; otherwise, false. */ NeverTileDiscardPolicy.prototype.shouldDiscardImage = function (image) { return false; diff --git a/packages/engine/Source/Scene/OIT.js b/packages/engine/Source/Scene/OIT.js index 8e3d4accaaf..4f479831b49 100644 --- a/packages/engine/Source/Scene/OIT.js +++ b/packages/engine/Source/Scene/OIT.js @@ -131,8 +131,8 @@ function destroyResources(oit) { * @private * @param {OIT} oit * @param {Context} context - * @param {Number} width - * @param {Number} height + * @param {number} width + * @param {number} height */ function updateTextures(oit, context, width, height) { destroyTextures(oit); @@ -165,7 +165,7 @@ function updateTextures(oit, context, width, height) { * @private * @param {OIT} oit * @param {Context} context - * @returns {Boolean} + * @returns {boolean} */ function updateFramebuffers(oit, context) { destroyFramebuffers(oit); @@ -236,8 +236,8 @@ function updateFramebuffers(oit, context) { * @param {Context} context * @param {PassState} passState * @param {Framebuffer} framebuffer - * @param {Boolean} useHDR - * @param {Number} numSamples + * @param {boolean} useHDR + * @param {number} numSamples */ OIT.prototype.update = function ( context, @@ -510,8 +510,8 @@ const alphaShaderSource = * @private * @param {Context} context * @param {ShaderProgram} shaderProgram - * @param {String} keyword - * @param {String} source + * @param {string} keyword + * @param {string} source * @returns {ShaderProgram} */ function getTranslucentShaderProgram(context, shaderProgram, keyword, source) { @@ -941,7 +941,7 @@ OIT.prototype.clear = function (context, passState, clearColor) { /** * @private - * @returns {Boolean} + * @returns {boolean} */ OIT.prototype.isSupported = function () { return this._translucentMRTSupport || this._translucentMultipassSupport; @@ -949,7 +949,7 @@ OIT.prototype.isSupported = function () { /** * @private - * @returns {Boolean} + * @returns {boolean} */ OIT.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js b/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js index ff54df0c5a0..8ba8225759d 100644 --- a/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js +++ b/packages/engine/Source/Scene/OctahedralProjectedCubeMap.js @@ -51,7 +51,7 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, { /** * The url to the KTX2 file containing the specular environment map and convoluted mipmaps. * @memberof OctahedralProjectedCubeMap.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -85,7 +85,7 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, { /** * The maximum number of mip levels. * @memberOf OctahedralProjectedCubeMap.prototype - * @type {Number} + * @type {number} * @readonly */ maximumMipmapLevel: { @@ -96,7 +96,7 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, { /** * Determines if the texture atlas is complete and ready to use. * @memberof OctahedralProjectedCubeMap.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -416,7 +416,7 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see OctahedralProjectedCubeMap#destroy */ diff --git a/packages/engine/Source/Scene/OpenStreetMapImageryProvider.js b/packages/engine/Source/Scene/OpenStreetMapImageryProvider.js index e45c8a44583..f3b9c42b147 100644 --- a/packages/engine/Source/Scene/OpenStreetMapImageryProvider.js +++ b/packages/engine/Source/Scene/OpenStreetMapImageryProvider.js @@ -12,17 +12,17 @@ const defaultCredit = new Credit( ); /** - * @typedef {Object} OpenStreetMapImageryProvider.ConstructorOptions + * @typedef {object} OpenStreetMapImageryProvider.ConstructorOptions * * Initialization options for the OpenStreetMapImageryProvider constructor * - * @property {String} [url='https://a.tile.openstreetmap.org'] The OpenStreetMap server url. - * @property {String} [fileExtension='png'] The file extension for images on the server. + * @property {string} [url='https://a.tile.openstreetmap.org'] The OpenStreetMap server url. + * @property {string} [fileExtension='png'] The file extension for images on the server. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @property {Credit|String} [credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas. */ /** diff --git a/packages/engine/Source/Scene/OrderedGroundPrimitiveCollection.js b/packages/engine/Source/Scene/OrderedGroundPrimitiveCollection.js index 5d682f3acc9..f52d0cb9530 100644 --- a/packages/engine/Source/Scene/OrderedGroundPrimitiveCollection.js +++ b/packages/engine/Source/Scene/OrderedGroundPrimitiveCollection.js @@ -23,7 +23,7 @@ Object.defineProperties(OrderedGroundPrimitiveCollection.prototype, { * * @memberof OrderedGroundPrimitiveCollection.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -37,7 +37,7 @@ Object.defineProperties(OrderedGroundPrimitiveCollection.prototype, { * Adds a primitive to the collection. * * @param {GroundPrimitive} primitive The primitive to add. - * @param {Number} [zIndex = 0] The index of the primitive + * @param {number} [zIndex = 0] The index of the primitive * @returns {GroundPrimitive} The primitive added to the collection. */ OrderedGroundPrimitiveCollection.prototype.add = function (primitive, zIndex) { @@ -72,7 +72,7 @@ OrderedGroundPrimitiveCollection.prototype.add = function (primitive, zIndex) { /** * Adjusts the z-index * @param {GroundPrimitive} primitive - * @param {Number} zIndex + * @param {number} zIndex */ OrderedGroundPrimitiveCollection.prototype.set = function (primitive, zIndex) { //>>includeStart('debug', pragmas.debug); @@ -93,9 +93,9 @@ OrderedGroundPrimitiveCollection.prototype.set = function (primitive, zIndex) { /** * Removes a primitive from the collection. * - * @param {Object} primitive The primitive to remove. - * @param {Boolean} [doNotDestroy = false] - * @returns {Boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. + * @param {object} primitive The primitive to remove. + * @param {boolean} [doNotDestroy = false] + * @returns {boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. */ OrderedGroundPrimitiveCollection.prototype.remove = function ( primitive, @@ -153,8 +153,8 @@ OrderedGroundPrimitiveCollection.prototype.removeAll = function () { /** * Determines if this collection contains a primitive. * - * @param {Object} primitive The primitive to check for. - * @returns {Boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. + * @param {object} primitive The primitive to check for. + * @returns {boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. */ OrderedGroundPrimitiveCollection.prototype.contains = function (primitive) { if (!defined(primitive)) { @@ -184,7 +184,7 @@ OrderedGroundPrimitiveCollection.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see OrderedGroundPrimitiveCollection#destroy */ diff --git a/packages/engine/Source/Scene/Particle.js b/packages/engine/Source/Scene/Particle.js index eac5a196e5e..a304f03475e 100644 --- a/packages/engine/Source/Scene/Particle.js +++ b/packages/engine/Source/Scene/Particle.js @@ -12,16 +12,16 @@ const defaultSize = new Cartesian2(1.0, 1.0); * @alias Particle * @constructor * - * @param {Object} options An object with the following properties: - * @param {Number} [options.mass=1.0] The mass of the particle in kilograms. + * @param {object} options An object with the following properties: + * @param {number} [options.mass=1.0] The mass of the particle in kilograms. * @param {Cartesian3} [options.position=Cartesian3.ZERO] The initial position of the particle in world coordinates. * @param {Cartesian3} [options.velocity=Cartesian3.ZERO] The velocity vector of the particle in world coordinates. - * @param {Number} [options.life=Number.MAX_VALUE] The life of the particle in seconds. - * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. + * @param {number} [options.life=Number.MAX_VALUE] The life of the particle in seconds. + * @param {object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. * @param {Color} [options.startColor=Color.WHITE] The color of a particle when it is born. * @param {Color} [options.endColor=Color.WHITE] The color of a particle when it dies. - * @param {Number} [options.startScale=1.0] The scale of the particle when it is born. - * @param {Number} [options.endScale=1.0] The scale of the particle when it dies. + * @param {number} [options.startScale=1.0] The scale of the particle when it is born. + * @param {number} [options.endScale=1.0] The scale of the particle when it dies. * @param {Cartesian2} [options.imageSize=new Cartesian2(1.0, 1.0)] The dimensions, width by height, to scale the particle image in pixels. */ function Particle(options) { @@ -29,7 +29,7 @@ function Particle(options) { /** * The mass of the particle in kilograms. - * @type {Number} + * @type {number} * @default 1.0 */ this.mass = defaultValue(options.mass, 1.0); @@ -51,13 +51,13 @@ function Particle(options) { ); /** * The life of the particle in seconds. - * @type {Number} + * @type {number} * @default Number.MAX_VALUE */ this.life = defaultValue(options.life, Number.MAX_VALUE); /** * The image to use for the particle. - * @type {Object} + * @type {object} * @default undefined */ this.image = options.image; @@ -75,13 +75,13 @@ function Particle(options) { this.endColor = Color.clone(defaultValue(options.endColor, Color.WHITE)); /** * the scale of the particle when it is born. - * @type {Number} + * @type {number} * @default 1.0 */ this.startScale = defaultValue(options.startScale, 1.0); /** * The scale of the particle when it dies. - * @type {Number} + * @type {number} * @default 1.0 */ this.endScale = defaultValue(options.endScale, 1.0); @@ -105,7 +105,7 @@ Object.defineProperties(Particle.prototype, { /** * Gets the age of the particle in seconds. * @memberof Particle.prototype - * @type {Number} + * @type {number} */ age: { get: function () { @@ -115,7 +115,7 @@ Object.defineProperties(Particle.prototype, { /** * Gets the age normalized to a value in the range [0.0, 1.0]. * @memberof Particle.prototype - * @type {Number} + * @type {number} */ normalizedAge: { get: function () { diff --git a/packages/engine/Source/Scene/ParticleBurst.js b/packages/engine/Source/Scene/ParticleBurst.js index ac486fb9f55..d1ef8b720c1 100644 --- a/packages/engine/Source/Scene/ParticleBurst.js +++ b/packages/engine/Source/Scene/ParticleBurst.js @@ -6,29 +6,29 @@ import defaultValue from "../Core/defaultValue.js"; * @alias ParticleBurst * @constructor * - * @param {Object} [options] An object with the following properties: - * @param {Number} [options.time=0.0] The time in seconds after the beginning of the particle system's lifetime that the burst will occur. - * @param {Number} [options.minimum=0.0] The minimum number of particles emmitted in the burst. - * @param {Number} [options.maximum=50.0] The maximum number of particles emitted in the burst. + * @param {object} [options] An object with the following properties: + * @param {number} [options.time=0.0] The time in seconds after the beginning of the particle system's lifetime that the burst will occur. + * @param {number} [options.minimum=0.0] The minimum number of particles emmitted in the burst. + * @param {number} [options.maximum=50.0] The maximum number of particles emitted in the burst. */ function ParticleBurst(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); /** * The time in seconds after the beginning of the particle system's lifetime that the burst will occur. - * @type {Number} + * @type {number} * @default 0.0 */ this.time = defaultValue(options.time, 0.0); /** * The minimum number of particles emitted. - * @type {Number} + * @type {number} * @default 0.0 */ this.minimum = defaultValue(options.minimum, 0.0); /** * The maximum number of particles emitted. - * @type {Number} + * @type {number} * @default 50.0 */ this.maximum = defaultValue(options.maximum, 50.0); @@ -40,7 +40,7 @@ Object.defineProperties(ParticleBurst.prototype, { /** * <code>true</code> if the burst has been completed; <code>false</code> otherwise. * @memberof ParticleBurst.prototype - * @type {Boolean} + * @type {boolean} */ complete: { get: function () { diff --git a/packages/engine/Source/Scene/ParticleSystem.js b/packages/engine/Source/Scene/ParticleSystem.js index d8ca0918a2e..acb93e90725 100644 --- a/packages/engine/Source/Scene/ParticleSystem.js +++ b/packages/engine/Source/Scene/ParticleSystem.js @@ -21,36 +21,36 @@ const defaultImageSize = new Cartesian2(1.0, 1.0); * @alias ParticleSystem * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Whether to display the particle system. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.show=true] Whether to display the particle system. * @param {ParticleSystem.updateCallback} [options.updateCallback] The callback function to be called each frame to update a particle. * @param {ParticleEmitter} [options.emitter=new CircleEmitter(0.5)] The particle emitter for this system. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system from model to world coordinates. * @param {Matrix4} [options.emitterModelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system. - * @param {Number} [options.emissionRate=5] The number of particles to emit per second. + * @param {number} [options.emissionRate=5] The number of particles to emit per second. * @param {ParticleBurst[]} [options.bursts] An array of {@link ParticleBurst}, emitting bursts of particles at periodic times. - * @param {Boolean} [options.loop=true] Whether the particle system should loop its bursts when it is complete. - * @param {Number} [options.scale=1.0] Sets the scale to apply to the image of the particle for the duration of its particleLife. - * @param {Number} [options.startScale] The initial scale to apply to the image of the particle at the beginning of its life. - * @param {Number} [options.endScale] The final scale to apply to the image of the particle at the end of its life. + * @param {boolean} [options.loop=true] Whether the particle system should loop its bursts when it is complete. + * @param {number} [options.scale=1.0] Sets the scale to apply to the image of the particle for the duration of its particleLife. + * @param {number} [options.startScale] The initial scale to apply to the image of the particle at the beginning of its life. + * @param {number} [options.endScale] The final scale to apply to the image of the particle at the end of its life. * @param {Color} [options.color=Color.WHITE] Sets the color of a particle for the duration of its particleLife. * @param {Color} [options.startColor] The color of the particle at the beginning of its life. * @param {Color} [options.endColor] The color of the particle at the end of its life. - * @param {Object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. + * @param {object} [options.image] The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. * @param {Cartesian2} [options.imageSize=new Cartesian2(1.0, 1.0)] If set, overrides the minimumImageSize and maximumImageSize inputs that scale the particle image's dimensions in pixels. * @param {Cartesian2} [options.minimumImageSize] Sets the minimum bound, width by height, above which to randomly scale the particle image's dimensions in pixels. * @param {Cartesian2} [options.maximumImageSize] Sets the maximum bound, width by height, below which to randomly scale the particle image's dimensions in pixels. - * @param {Boolean} [options.sizeInMeters] Sets if the size of particles is in meters or pixels. <code>true</code> to size the particles in meters; otherwise, the size is in pixels. - * @param {Number} [options.speed=1.0] If set, overrides the minimumSpeed and maximumSpeed inputs with this value. - * @param {Number} [options.minimumSpeed] Sets the minimum bound in meters per second above which a particle's actual speed will be randomly chosen. - * @param {Number} [options.maximumSpeed] Sets the maximum bound in meters per second below which a particle's actual speed will be randomly chosen. - * @param {Number} [options.lifetime=Number.MAX_VALUE] How long the particle system will emit particles, in seconds. - * @param {Number} [options.particleLife=5.0] If set, overrides the minimumParticleLife and maximumParticleLife inputs with this value. - * @param {Number} [options.minimumParticleLife] Sets the minimum bound in seconds for the possible duration of a particle's life above which a particle's actual life will be randomly chosen. - * @param {Number} [options.maximumParticleLife] Sets the maximum bound in seconds for the possible duration of a particle's life below which a particle's actual life will be randomly chosen. - * @param {Number} [options.mass=1.0] Sets the minimum and maximum mass of particles in kilograms. - * @param {Number} [options.minimumMass] Sets the minimum bound for the mass of a particle in kilograms. A particle's actual mass will be chosen as a random amount above this value. - * @param {Number} [options.maximumMass] Sets the maximum mass of particles in kilograms. A particle's actual mass will be chosen as a random amount below this value. + * @param {boolean} [options.sizeInMeters] Sets if the size of particles is in meters or pixels. <code>true</code> to size the particles in meters; otherwise, the size is in pixels. + * @param {number} [options.speed=1.0] If set, overrides the minimumSpeed and maximumSpeed inputs with this value. + * @param {number} [options.minimumSpeed] Sets the minimum bound in meters per second above which a particle's actual speed will be randomly chosen. + * @param {number} [options.maximumSpeed] Sets the maximum bound in meters per second below which a particle's actual speed will be randomly chosen. + * @param {number} [options.lifetime=Number.MAX_VALUE] How long the particle system will emit particles, in seconds. + * @param {number} [options.particleLife=5.0] If set, overrides the minimumParticleLife and maximumParticleLife inputs with this value. + * @param {number} [options.minimumParticleLife] Sets the minimum bound in seconds for the possible duration of a particle's life above which a particle's actual life will be randomly chosen. + * @param {number} [options.maximumParticleLife] Sets the maximum bound in seconds for the possible duration of a particle's life below which a particle's actual life will be randomly chosen. + * @param {number} [options.mass=1.0] Sets the minimum and maximum mass of particles in kilograms. + * @param {number} [options.minimumMass] Sets the minimum bound for the mass of a particle in kilograms. A particle's actual mass will be chosen as a random amount above this value. + * @param {number} [options.maximumMass] Sets the maximum mass of particles in kilograms. A particle's actual mass will be chosen as a random amount below this value. * @demo {@link https://cesium.com/learn/cesiumjs-learn/cesiumjs-particle-systems/|Particle Systems Tutorial} * @demo {@link https://sandcastle.cesium.com/?src=Particle%20System.html&label=Showcases|Particle Systems Tutorial Demo} * @demo {@link https://sandcastle.cesium.com/?src=Particle%20System%20Fireworks.html&label=Showcases|Particle Systems Fireworks Demo} @@ -60,7 +60,7 @@ function ParticleSystem(options) { /** * Whether to display the particle system. - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -74,14 +74,14 @@ function ParticleSystem(options) { /** * Whether the particle system should loop it's bursts when it is complete. - * @type {Boolean} + * @type {boolean} * @default true */ this.loop = defaultValue(options.loop, true); /** * The URI, HTMLImageElement, or HTMLCanvasElement to use for the billboard. - * @type {Object} + * @type {object} * @default undefined */ this.image = defaultValue(options.image, undefined); @@ -290,7 +290,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * The initial scale to apply to the image of the particle at the beginning of its life. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ startScale: { @@ -307,7 +307,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * The final scale to apply to the image of the particle at the end of its life. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ endScale: { @@ -324,7 +324,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * The number of particles to emit per second. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 5 */ emissionRate: { @@ -342,7 +342,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the minimum bound in meters per second above which a particle's actual speed will be randomly chosen. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ minimumSpeed: { @@ -359,7 +359,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the maximum bound in meters per second below which a particle's actual speed will be randomly chosen. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ maximumSpeed: { @@ -376,7 +376,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the minimum bound in seconds for the possible duration of a particle's life above which a particle's actual life will be randomly chosen. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 5.0 */ minimumParticleLife: { @@ -393,7 +393,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the maximum bound in seconds for the possible duration of a particle's life below which a particle's actual life will be randomly chosen. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 5.0 */ maximumParticleLife: { @@ -411,7 +411,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the minimum mass of particles in kilograms. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ minimumMass: { @@ -428,7 +428,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Sets the maximum mass of particles in kilograms. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default 1.0 */ maximumMass: { @@ -483,7 +483,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * Gets or sets if the particle size is in meters or pixels. <code>true</code> to size particles in meters; otherwise, the size is in pixels. * @memberof ParticleSystem.prototype - * @type {Boolean} + * @type {boolean} * @default false */ sizeInMeters: { @@ -500,7 +500,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * How long the particle system will emit particles, in seconds. * @memberof ParticleSystem.prototype - * @type {Number} + * @type {number} * @default Number.MAX_VALUE */ lifetime: { @@ -527,7 +527,7 @@ Object.defineProperties(ParticleSystem.prototype, { /** * When <code>true</code>, the particle system has reached the end of its lifetime; <code>false</code> otherwise. * @memberof ParticleSystem.prototype - * @type {Boolean} + * @type {boolean} */ isComplete: { get: function () { @@ -864,7 +864,7 @@ ParticleSystem.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ParticleSystem#destroy */ @@ -897,7 +897,7 @@ ParticleSystem.prototype.destroy = function () { * @callback ParticleSystem.updateCallback * * @param {Particle} particle The particle being updated. - * @param {Number} dt The time in seconds since the last update. + * @param {number} dt The time in seconds since the last update. * * @example * function applyGravity(particle, dt) { diff --git a/packages/engine/Source/Scene/PerInstanceColorAppearance.js b/packages/engine/Source/Scene/PerInstanceColorAppearance.js index dfc1a75c43a..a2a32ec136b 100644 --- a/packages/engine/Source/Scene/PerInstanceColorAppearance.js +++ b/packages/engine/Source/Scene/PerInstanceColorAppearance.js @@ -14,14 +14,14 @@ import Appearance from "./Appearance.js"; * @alias PerInstanceColorAppearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. - * @param {Boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. - * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link PerInstanceColorAppearance#renderState} has backface culling enabled. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.flat=false] When <code>true</code>, flat shading is used in the fragment shader, which means lighting is not taking into account. + * @param {boolean} [options.faceForward=!options.closed] When <code>true</code>, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}. + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. + * @param {boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link PerInstanceColorAppearance#renderState} has backface culling enabled. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @example * // A solid white line segment @@ -97,7 +97,7 @@ function PerInstanceColorAppearance(options) { * When <code>true</code>, the geometry is expected to appear translucent so * {@link PerInstanceColorAppearance#renderState} has alpha blending enabled. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -125,7 +125,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -139,7 +139,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -158,7 +158,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -174,7 +174,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -207,7 +207,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -226,7 +226,7 @@ Object.defineProperties(PerInstanceColorAppearance.prototype, { * * @memberof PerInstanceColorAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -267,7 +267,7 @@ PerInstanceColorAppearance.FLAT_VERTEX_FORMAT = VertexFormat.POSITION_ONLY; * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ PerInstanceColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -277,7 +277,7 @@ PerInstanceColorAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ PerInstanceColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -289,7 +289,7 @@ PerInstanceColorAppearance.prototype.isTranslucent = * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ PerInstanceColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; diff --git a/packages/engine/Source/Scene/PerformanceDisplay.js b/packages/engine/Source/Scene/PerformanceDisplay.js index e130db87eb6..d379843b32a 100644 --- a/packages/engine/Source/Scene/PerformanceDisplay.js +++ b/packages/engine/Source/Scene/PerformanceDisplay.js @@ -52,7 +52,7 @@ Object.defineProperties(PerformanceDisplay.prototype, { * The display should indicate the FPS is being throttled. * @memberof PerformanceDisplay.prototype * - * @type {Boolean} + * @type {boolean} */ throttled: { get: function () { @@ -78,7 +78,7 @@ Object.defineProperties(PerformanceDisplay.prototype, { * Update the display. This function should only be called once per frame, because * each call records a frame in the internal buffer and redraws the display. * - * @param {Boolean} [renderedThisFrame=true] If provided, the FPS count will only update and display if true. + * @param {boolean} [renderedThisFrame=true] If provided, the FPS count will only update and display if true. */ PerformanceDisplay.prototype.update = function (renderedThisFrame) { const time = getTimestamp(); diff --git a/packages/engine/Source/Scene/PntsParser.js b/packages/engine/Source/Scene/PntsParser.js index 8dde6b23ade..eb60db304b6 100644 --- a/packages/engine/Source/Scene/PntsParser.js +++ b/packages/engine/Source/Scene/PntsParser.js @@ -28,7 +28,7 @@ const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; * * @param {*} arrayBuffer The array buffer containing the pnts * @param {*} [byteOffset=0] The byte offset of the beginning of the pnts in the array buffer - * @returns {Object} An object containing a parsed representation of the point cloud + * @returns {object} An object containing a parsed representation of the point cloud */ PntsParser.parse = function (arrayBuffer, byteOffset) { byteOffset = defaultValue(byteOffset, 0); diff --git a/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js b/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js index e247beac473..a4ef56deca6 100644 --- a/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js +++ b/packages/engine/Source/Scene/PointCloudEyeDomeLighting.js @@ -254,7 +254,7 @@ PointCloudEyeDomeLighting.prototype.update = function ( * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PointCloudEyeDomeLighting#destroy */ diff --git a/packages/engine/Source/Scene/PointCloudShading.js b/packages/engine/Source/Scene/PointCloudShading.js index 658b534deca..2a46b8fc75c 100644 --- a/packages/engine/Source/Scene/PointCloudShading.js +++ b/packages/engine/Source/Scene/PointCloudShading.js @@ -5,16 +5,16 @@ import PointCloudEyeDomeLighting from "./PointCloudEyeDomeLighting.js"; * Options for performing point attenuation based on geometric error when rendering * point clouds using 3D Tiles. * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.attenuation=false] Perform point attenuation based on geometric error. - * @param {Number} [options.geometricErrorScale=1.0] Scale to be applied to each tile's geometric error. - * @param {Number} [options.maximumAttenuation] Maximum attenuation in pixels. Defaults to the Cesium3DTileset's maximumScreenSpaceError. - * @param {Number} [options.baseResolution] Average base resolution for the dataset in meters. Substitute for Geometric Error when not available. - * @param {Boolean} [options.eyeDomeLighting=true] When true, use eye dome lighting when drawing with point attenuation. - * @param {Number} [options.eyeDomeLightingStrength=1.0] Increasing this value increases contrast on slopes and edges. - * @param {Number} [options.eyeDomeLightingRadius=1.0] Increase the thickness of contours from eye dome lighting. - * @param {Boolean} [options.backFaceCulling=false] Determines whether back-facing points are hidden. This option works only if data has normals included. - * @param {Boolean} [options.normalShading=true] Determines whether a point cloud that contains normals is shaded by the scene's light source. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.attenuation=false] Perform point attenuation based on geometric error. + * @param {number} [options.geometricErrorScale=1.0] Scale to be applied to each tile's geometric error. + * @param {number} [options.maximumAttenuation] Maximum attenuation in pixels. Defaults to the Cesium3DTileset's maximumScreenSpaceError. + * @param {number} [options.baseResolution] Average base resolution for the dataset in meters. Substitute for Geometric Error when not available. + * @param {boolean} [options.eyeDomeLighting=true] When true, use eye dome lighting when drawing with point attenuation. + * @param {number} [options.eyeDomeLightingStrength=1.0] Increasing this value increases contrast on slopes and edges. + * @param {number} [options.eyeDomeLightingRadius=1.0] Increase the thickness of contours from eye dome lighting. + * @param {boolean} [options.backFaceCulling=false] Determines whether back-facing points are hidden. This option works only if data has normals included. + * @param {boolean} [options.normalShading=true] Determines whether a point cloud that contains normals is shaded by the scene's light source. * * @alias PointCloudShading * @constructor @@ -24,14 +24,14 @@ function PointCloudShading(options) { /** * Perform point attenuation based on geometric error. - * @type {Boolean} + * @type {boolean} * @default false */ this.attenuation = defaultValue(pointCloudShading.attenuation, false); /** * Scale to be applied to the geometric error before computing attenuation. - * @type {Number} + * @type {number} * @default 1.0 */ this.geometricErrorScale = defaultValue( @@ -41,7 +41,7 @@ function PointCloudShading(options) { /** * Maximum point attenuation in pixels. If undefined, the Cesium3DTileset's maximumScreenSpaceError will be used. - * @type {Number} + * @type {number} */ this.maximumAttenuation = pointCloudShading.maximumAttenuation; @@ -49,7 +49,7 @@ function PointCloudShading(options) { * Average base resolution for the dataset in meters. * Used in place of geometric error when geometric error is 0. * If undefined, an approximation will be computed for each tile that has geometric error of 0. - * @type {Number} + * @type {number} */ this.baseResolution = pointCloudShading.baseResolution; @@ -58,14 +58,14 @@ function PointCloudShading(options) { * Requires support for EXT_frag_depth, OES_texture_float, and WEBGL_draw_buffers extensions in WebGL 1.0, * otherwise eye dome lighting is ignored. * - * @type {Boolean} + * @type {boolean} * @default true */ this.eyeDomeLighting = defaultValue(pointCloudShading.eyeDomeLighting, true); /** * Eye dome lighting strength (apparent contrast) - * @type {Number} + * @type {number} * @default 1.0 */ this.eyeDomeLightingStrength = defaultValue( @@ -75,7 +75,7 @@ function PointCloudShading(options) { /** * Thickness of contours from eye dome lighting - * @type {Number} + * @type {number} * @default 1.0 */ this.eyeDomeLightingRadius = defaultValue( @@ -87,7 +87,7 @@ function PointCloudShading(options) { * Determines whether back-facing points are hidden. * This option works only if data has normals included. * - * @type {Boolean} + * @type {boolean} * @default false */ this.backFaceCulling = defaultValue(pointCloudShading.backFaceCulling, false); @@ -95,7 +95,7 @@ function PointCloudShading(options) { /** * Determines whether a point cloud that contains normals is shaded by the scene's light source. * - * @type {Boolean} + * @type {boolean} * @default true */ this.normalShading = defaultValue(pointCloudShading.normalShading, true); @@ -105,7 +105,7 @@ function PointCloudShading(options) { * Determines if point cloud shading is supported. * * @param {Scene} scene The scene. - * @returns {Boolean} <code>true</code> if point cloud shading is supported; otherwise, returns <code>false</code> + * @returns {boolean} <code>true</code> if point cloud shading is supported; otherwise, returns <code>false</code> */ PointCloudShading.isSupported = function (scene) { return PointCloudEyeDomeLighting.isSupported(scene.context); diff --git a/packages/engine/Source/Scene/PointPrimitive.js b/packages/engine/Source/Scene/PointPrimitive.js index 75ed8ca5e36..08307252f64 100644 --- a/packages/engine/Source/Scene/PointPrimitive.js +++ b/packages/engine/Source/Scene/PointPrimitive.js @@ -147,7 +147,7 @@ Object.defineProperties(PointPrimitive.prototype, { * Determines if this point will be shown. Use this to hide or show a point, instead * of removing it and re-adding it to the collection. * @memberof PointPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -286,7 +286,7 @@ Object.defineProperties(PointPrimitive.prototype, { /** * Gets or sets the inner size of the point in pixels. * @memberof PointPrimitive.prototype - * @type {Number} + * @type {number} */ pixelSize: { get: function () { @@ -369,7 +369,7 @@ Object.defineProperties(PointPrimitive.prototype, { * Gets or sets the outline width in pixels. This width adds to pixelSize, * increasing the total size of the point. * @memberof PointPrimitive.prototype - * @type {Number} + * @type {number} */ outlineWidth: { get: function () { @@ -421,7 +421,7 @@ Object.defineProperties(PointPrimitive.prototype, { * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. * @memberof PointPrimitive.prototype - * @type {Number} + * @type {number} * @default 0.0 */ disableDepthTestDistance: { @@ -472,7 +472,7 @@ Object.defineProperties(PointPrimitive.prototype, { /** * Determines whether or not this point will be shown or hidden because it was clustered. * @memberof PointPrimitive.prototype - * @type {Boolean} + * @type {boolean} * @private */ clusterShow: { @@ -635,7 +635,7 @@ PointPrimitive.getScreenSpaceBoundingBox = function ( * are equal. Points in different collections can be equal. * * @param {PointPrimitive} other The point to compare for equality. - * @returns {Boolean} <code>true</code> if the points are equal; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if the points are equal; otherwise, <code>false</code>. */ PointPrimitive.prototype.equals = function (other) { return ( diff --git a/packages/engine/Source/Scene/PointPrimitiveCollection.js b/packages/engine/Source/Scene/PointPrimitiveCollection.js index 5c06e1a7f95..ce42db08cf2 100644 --- a/packages/engine/Source/Scene/PointPrimitiveCollection.js +++ b/packages/engine/Source/Scene/PointPrimitiveCollection.js @@ -58,13 +58,13 @@ const attributeLocations = { * @alias PointPrimitiveCollection * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each point from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The point blending option. The default * is used for rendering both opaque and translucent points. However, if either all of the points are completely opaque or all are completely translucent, * setting the technique to BlendOption.OPAQUE or BlendOption.TRANSLUCENT can improve performance by up to 2x. - * @param {Boolean} [options.show=true] Determines if the primitives in the collection will be shown. + * @param {boolean} [options.show=true] Determines if the primitives in the collection will be shown. * * @performance For best performance, prefer a few collections, each with many points, to * many collections with only a few points each. Organize collections so that points @@ -131,7 +131,7 @@ function PointPrimitiveCollection(options) { /** * Determines if primitives in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -179,7 +179,7 @@ function PointPrimitiveCollection(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -232,7 +232,7 @@ Object.defineProperties(PointPrimitiveCollection.prototype, { * {@link PointPrimitiveCollection#get} to iterate over all the points * in the collection. * @memberof PointPrimitiveCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -255,7 +255,7 @@ function destroyPointPrimitives(pointPrimitives) { * Creates and adds a point with the specified initial properties to the collection. * The added point is returned so it can be modified or removed from the collection later. * - * @param {Object}[options] A template describing the point's properties as shown in Example 1. + * @param {object}[options] A template describing the point's properties as shown in Example 1. * @returns {PointPrimitive} The point that was added to the collection. * * @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer @@ -300,7 +300,7 @@ PointPrimitiveCollection.prototype.add = function (options) { * Removes a point from the collection. * * @param {PointPrimitive} pointPrimitive The point to remove. - * @returns {Boolean} <code>true</code> if the point was removed; <code>false</code> if the point was not found in the collection. + * @returns {boolean} <code>true</code> if the point was removed; <code>false</code> if the point was not found in the collection. * * @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer * is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For @@ -394,7 +394,7 @@ PointPrimitiveCollection.prototype._updatePointPrimitive = function ( * Check whether this collection contains a given point. * * @param {PointPrimitive} [pointPrimitive] The point to check for. - * @returns {Boolean} true if this collection contains the point, false otherwise. + * @returns {boolean} true if this collection contains the point, false otherwise. * * @see PointPrimitiveCollection#get */ @@ -411,7 +411,7 @@ PointPrimitiveCollection.prototype.contains = function (pointPrimitive) { * {@link PointPrimitiveCollection#length} to iterate over all the points * in the collection. * - * @param {Number} index The zero-based index of the point. + * @param {number} index The zero-based index of the point. * @returns {PointPrimitive} The point at the specified index. * * @performance Expected constant time. If points were removed from the collection and @@ -1181,7 +1181,7 @@ PointPrimitiveCollection.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PointPrimitiveCollection#destroy */ diff --git a/packages/engine/Source/Scene/Polyline.js b/packages/engine/Source/Scene/Polyline.js index 0590f6c92ed..b8eda50752e 100644 --- a/packages/engine/Source/Scene/Polyline.js +++ b/packages/engine/Source/Scene/Polyline.js @@ -21,13 +21,13 @@ import Material from "./Material.js"; * @internalConstructor * @class * - * @privateParam {Object} options Object with the following properties: - * @privateParam {Boolean} [options.show=true] <code>true</code> if this polyline will be shown; otherwise, <code>false</code>. - * @privateParam {Number} [options.width=1.0] The width of the polyline in pixels. - * @privateParam {Boolean} [options.loop=false] Whether a line segment will be added between the last and first line positions to make this line a loop. + * @privateParam {object} options Object with the following properties: + * @privateParam {boolean} [options.show=true] <code>true</code> if this polyline will be shown; otherwise, <code>false</code>. + * @privateParam {number} [options.width=1.0] The width of the polyline in pixels. + * @privateParam {boolean} [options.loop=false] Whether a line segment will be added between the last and first line positions to make this line a loop. * @privateParam {Material} [options.material=Material.ColorType] The material. * @privateParam {Cartesian3[]} [options.positions] The positions. - * @privateParam {Object} [options.id] The user-defined object to be returned when this polyline is picked. + * @privateParam {object} [options.id] The user-defined object to be returned when this polyline is picked. * @privateParam {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this polyline will be displayed. * @privateParam {PolylineCollection} polylineCollection The renderable polyline collection. * @@ -118,7 +118,7 @@ Object.defineProperties(Polyline.prototype, { * Determines if this polyline will be shown. Use this to hide or show a polyline, instead * of removing it and re-adding it to the collection. * @memberof Polyline.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -221,7 +221,7 @@ Object.defineProperties(Polyline.prototype, { /** * Gets or sets the width of the polyline. * @memberof Polyline.prototype - * @type {Number} + * @type {number} */ width: { get: function () { @@ -245,7 +245,7 @@ Object.defineProperties(Polyline.prototype, { /** * Gets or sets whether a line segment will be added between the first and last polyline positions. * @memberof Polyline.prototype - * @type {Boolean} + * @type {boolean} */ loop: { get: function () { @@ -316,7 +316,7 @@ Object.defineProperties(Polyline.prototype, { /** * Gets the destruction status of this polyline * @memberof Polyline.prototype - * @type {Boolean} + * @type {boolean} * @default false * @private */ diff --git a/packages/engine/Source/Scene/PolylineCollection.js b/packages/engine/Source/Scene/PolylineCollection.js index 3f9150479a0..81973318e16 100644 --- a/packages/engine/Source/Scene/PolylineCollection.js +++ b/packages/engine/Source/Scene/PolylineCollection.js @@ -77,10 +77,10 @@ const attributeLocations = { * @alias PolylineCollection * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each polyline from model to world coordinates. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.show=true] Determines if the polylines in the collection will be shown. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.show=true] Determines if the polylines in the collection will be shown. * * @performance For best performance, prefer a few collections, each with many polylines, to * many collections with only a few polylines each. Organize collections so that polylines @@ -120,7 +120,7 @@ function PolylineCollection(options) { /** * Determines if polylines in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -145,7 +145,7 @@ function PolylineCollection(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -200,7 +200,7 @@ Object.defineProperties(PolylineCollection.prototype, { * {@link PolylineCollection#get} to iterate over all the polylines * in the collection. * @memberof PolylineCollection.prototype - * @type {Number} + * @type {number} */ length: { get: function () { @@ -214,7 +214,7 @@ Object.defineProperties(PolylineCollection.prototype, { * Creates and adds a polyline with the specified initial properties to the collection. * The added polyline is returned so it can be modified or removed from the collection later. * - * @param {Object}[options] A template describing the polyline's properties as shown in Example 1. + * @param {object}[options] A template describing the polyline's properties as shown in Example 1. * @returns {Polyline} The polyline that was added to the collection. * * @performance After calling <code>add</code>, {@link PolylineCollection#update} is called and @@ -251,7 +251,7 @@ PolylineCollection.prototype.add = function (options) { * Removes a polyline from the collection. * * @param {Polyline} polyline The polyline to remove. - * @returns {Boolean} <code>true</code> if the polyline was removed; <code>false</code> if the polyline was not found in the collection. + * @returns {boolean} <code>true</code> if the polyline was removed; <code>false</code> if the polyline was not found in the collection. * * @performance After calling <code>remove</code>, {@link PolylineCollection#update} is called and * the collection's vertex buffer is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. @@ -320,7 +320,7 @@ PolylineCollection.prototype.removeAll = function () { * Determines if this collection contains the specified polyline. * * @param {Polyline} polyline The polyline to check for. - * @returns {Boolean} true if this collection contains the polyline, false otherwise. + * @returns {boolean} true if this collection contains the polyline, false otherwise. * * @see PolylineCollection#get */ @@ -335,7 +335,7 @@ PolylineCollection.prototype.contains = function (polyline) { * {@link PolylineCollection#length} to iterate over all the polylines * in the collection. * - * @param {Number} index The zero-based index of the polyline. + * @param {number} index The zero-based index of the polyline. * @returns {Polyline} The polyline at the specified index. * * @performance If polylines were removed from the collection and @@ -786,7 +786,7 @@ function createCommandLists( * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PolylineCollection#destroy */ diff --git a/packages/engine/Source/Scene/PolylineColorAppearance.js b/packages/engine/Source/Scene/PolylineColorAppearance.js index 89b14b04310..27c577fa1b7 100644 --- a/packages/engine/Source/Scene/PolylineColorAppearance.js +++ b/packages/engine/Source/Scene/PolylineColorAppearance.js @@ -22,11 +22,11 @@ if (!FeatureDetection.isInternetExplorer()) { * @alias PolylineColorAppearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineColorAppearance#renderState} has alpha blending enabled. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineColorAppearance#renderState} has alpha blending enabled. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @example * // A solid white line segment @@ -70,7 +70,7 @@ function PolylineColorAppearance(options) { * When <code>true</code>, the geometry is expected to appear translucent so * {@link PolylineColorAppearance#renderState} has alpha blending enabled. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -102,7 +102,7 @@ Object.defineProperties(PolylineColorAppearance.prototype, { * * @memberof PolylineColorAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -116,7 +116,7 @@ Object.defineProperties(PolylineColorAppearance.prototype, { * * @memberof PolylineColorAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -134,7 +134,7 @@ Object.defineProperties(PolylineColorAppearance.prototype, { * * @memberof PolylineColorAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -150,7 +150,7 @@ Object.defineProperties(PolylineColorAppearance.prototype, { * * @memberof PolylineColorAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -195,7 +195,7 @@ PolylineColorAppearance.VERTEX_FORMAT = VertexFormat.POSITION_ONLY; * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ PolylineColorAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -205,7 +205,7 @@ PolylineColorAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ PolylineColorAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -217,7 +217,7 @@ PolylineColorAppearance.prototype.isTranslucent = * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ PolylineColorAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; diff --git a/packages/engine/Source/Scene/PolylineMaterialAppearance.js b/packages/engine/Source/Scene/PolylineMaterialAppearance.js index 01f96114991..0f048aa81ea 100644 --- a/packages/engine/Source/Scene/PolylineMaterialAppearance.js +++ b/packages/engine/Source/Scene/PolylineMaterialAppearance.js @@ -21,12 +21,12 @@ if (!FeatureDetection.isInternetExplorer()) { * @alias PolylineMaterialAppearance * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color. - * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. - * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. - * @param {Object} [options.renderState] Optional render state to override the default render state. + * @param {string} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. + * @param {string} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. + * @param {object} [options.renderState] Optional render state to override the default render state. * * @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric} * @@ -72,7 +72,7 @@ function PolylineMaterialAppearance(options) { * When <code>true</code>, the geometry is expected to appear translucent so * {@link PolylineMaterialAppearance#renderState} has alpha blending enabled. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -104,7 +104,7 @@ Object.defineProperties(PolylineMaterialAppearance.prototype, { * * @memberof PolylineMaterialAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ vertexShaderSource: { @@ -125,7 +125,7 @@ Object.defineProperties(PolylineMaterialAppearance.prototype, { * * @memberof PolylineMaterialAppearance.prototype * - * @type {String} + * @type {string} * @readonly */ fragmentShaderSource: { @@ -144,7 +144,7 @@ Object.defineProperties(PolylineMaterialAppearance.prototype, { * * @memberof PolylineMaterialAppearance.prototype * - * @type {Object} + * @type {object} * @readonly */ renderState: { @@ -160,7 +160,7 @@ Object.defineProperties(PolylineMaterialAppearance.prototype, { * * @memberof PolylineMaterialAppearance.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -206,7 +206,7 @@ PolylineMaterialAppearance.VERTEX_FORMAT = VertexFormat.POSITION_AND_ST; * * @function * - * @returns {String} The full GLSL fragment shader source. + * @returns {string} The full GLSL fragment shader source. */ PolylineMaterialAppearance.prototype.getFragmentShaderSource = Appearance.prototype.getFragmentShaderSource; @@ -216,7 +216,7 @@ PolylineMaterialAppearance.prototype.getFragmentShaderSource = * * @function * - * @returns {Boolean} <code>true</code> if the appearance is translucent. + * @returns {boolean} <code>true</code> if the appearance is translucent. */ PolylineMaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent; @@ -228,7 +228,7 @@ PolylineMaterialAppearance.prototype.isTranslucent = * * @function * - * @returns {Object} The render state. + * @returns {object} The render state. */ PolylineMaterialAppearance.prototype.getRenderState = Appearance.prototype.getRenderState; diff --git a/packages/engine/Source/Scene/PostProcessStage.js b/packages/engine/Source/Scene/PostProcessStage.js index 1af387e0ae5..ab05093b5c6 100644 --- a/packages/engine/Source/Scene/PostProcessStage.js +++ b/packages/engine/Source/Scene/PostProcessStage.js @@ -26,17 +26,17 @@ import PostProcessStageSampleMode from "./PostProcessStageSampleMode.js"; * @alias PostProcessStage * @constructor * - * @param {Object} options An object with the following properties: - * @param {String} options.fragmentShader The fragment shader to use. The default <code>sampler2D</code> uniforms are <code>colorTexture</code> and <code>depthTexture</code>. The color texture is the output of rendering the scene or the previous stage. The depth texture is the output from rendering the scene. The shader should contain one or both uniforms. There is also a <code>vec2</code> varying named <code>v_textureCoordinates</code> that can be used to sample the textures. - * @param {Object} [options.uniforms] An object whose properties will be used to set the shaders uniforms. The properties can be constant values or a function. A constant value can also be a URI, data URI, or HTML element to use as a texture. - * @param {Number} [options.textureScale=1.0] A number in the range (0.0, 1.0] used to scale the texture dimensions. A scale of 1.0 will render this post-process stage to a texture the size of the viewport. - * @param {Boolean} [options.forcePowerOfTwo=false] Whether or not to force the texture dimensions to be both equal powers of two. The power of two will be the next power of two of the minimum of the dimensions. + * @param {object} options An object with the following properties: + * @param {string} options.fragmentShader The fragment shader to use. The default <code>sampler2D</code> uniforms are <code>colorTexture</code> and <code>depthTexture</code>. The color texture is the output of rendering the scene or the previous stage. The depth texture is the output from rendering the scene. The shader should contain one or both uniforms. There is also a <code>vec2</code> varying named <code>v_textureCoordinates</code> that can be used to sample the textures. + * @param {object} [options.uniforms] An object whose properties will be used to set the shaders uniforms. The properties can be constant values or a function. A constant value can also be a URI, data URI, or HTML element to use as a texture. + * @param {number} [options.textureScale=1.0] A number in the range (0.0, 1.0] used to scale the texture dimensions. A scale of 1.0 will render this post-process stage to a texture the size of the viewport. + * @param {boolean} [options.forcePowerOfTwo=false] Whether or not to force the texture dimensions to be both equal powers of two. The power of two will be the next power of two of the minimum of the dimensions. * @param {PostProcessStageSampleMode} [options.sampleMode=PostProcessStageSampleMode.NEAREST] How to sample the input color texture. * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] The color pixel format of the output texture. * @param {PixelDatatype} [options.pixelDatatype=PixelDatatype.UNSIGNED_BYTE] The pixel data type of the output texture. * @param {Color} [options.clearColor=Color.BLACK] The color to clear the output texture to. * @param {BoundingRectangle} [options.scissorRectangle] The rectangle to use for the scissor test. - * @param {String} [options.name=createGuid()] The unique name of this post-process stage for reference by other stages in a composite. If a name is not supplied, a GUID will be generated. + * @param {string} [options.name=createGuid()] The unique name of this post-process stage for reference by other stages in a composite. If a name is not supplied, a GUID will be generated. * * @exception {DeveloperError} options.textureScale must be greater than 0.0 and less than or equal to 1.0. * @exception {DeveloperError} options.pixelFormat must be a color format. @@ -176,7 +176,7 @@ function PostProcessStage(options) { /** * Whether or not to execute this post-process stage when ready. * - * @type {Boolean} + * @type {boolean} */ this.enabled = true; this._enabled = true; @@ -189,7 +189,7 @@ Object.defineProperties(PostProcessStage.prototype, { * to load. * * @memberof PostProcessStage.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -201,7 +201,7 @@ Object.defineProperties(PostProcessStage.prototype, { * The unique name of this post-process stage for reference by other stages in a {@link PostProcessStageComposite}. * * @memberof PostProcessStage.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -221,7 +221,7 @@ Object.defineProperties(PostProcessStage.prototype, { * </p> * * @memberof PostProcessStage.prototype - * @type {String} + * @type {string} * @readonly */ fragmentShader: { @@ -244,7 +244,7 @@ Object.defineProperties(PostProcessStage.prototype, { * </p> * * @memberof PostProcessStage.prototype - * @type {Object} + * @type {object} * @readonly */ uniforms: { @@ -256,7 +256,7 @@ Object.defineProperties(PostProcessStage.prototype, { * A number in the range (0.0, 1.0] used to scale the output texture dimensions. A scale of 1.0 will render this post-process stage to a texture the size of the viewport. * * @memberof PostProcessStage.prototype - * @type {Number} + * @type {number} * @readonly */ textureScale: { @@ -268,7 +268,7 @@ Object.defineProperties(PostProcessStage.prototype, { * Whether or not to force the output texture dimensions to be both equal powers of two. The power of two will be the next power of two of the minimum of the dimensions. * * @memberof PostProcessStage.prototype - * @type {Number} + * @type {number} * @readonly */ forcePowerOfTwo: { @@ -875,7 +875,7 @@ function createSelectedTexture(stage, context) { /** * A function that will be called before execute. Used to create WebGL resources and load any textures. * @param {Context} context The context. - * @param {Boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. + * @param {boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. * @private */ PostProcessStage.prototype.update = function (context, useLogDepth) { @@ -995,7 +995,7 @@ PostProcessStage.prototype.execute = function ( * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PostProcessStage#destroy */ diff --git a/packages/engine/Source/Scene/PostProcessStageCollection.js b/packages/engine/Source/Scene/PostProcessStageCollection.js index 6017377ca3b..1bdb38ca5e3 100644 --- a/packages/engine/Source/Scene/PostProcessStageCollection.js +++ b/packages/engine/Source/Scene/PostProcessStageCollection.js @@ -105,7 +105,7 @@ Object.defineProperties(PostProcessStageCollection.prototype, { * Determines if all of the post-process stages in the collection are ready to be executed. * * @memberof PostProcessStageCollection.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -231,7 +231,7 @@ Object.defineProperties(PostProcessStageCollection.prototype, { * The number of post-process stages in this collection. * * @memberof PostProcessStageCollection.prototype - * @type {Number} + * @type {number} * @readonly */ length: { @@ -286,7 +286,7 @@ Object.defineProperties(PostProcessStageCollection.prototype, { * Whether the collection has a stage that has selected features. * * @memberof PostProcessStageCollection.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -453,7 +453,7 @@ PostProcessStageCollection.prototype.add = function (stage) { * Removes a post-process stage from the collection and destroys it. * * @param {PostProcessStage|PostProcessStageComposite} stage The post-process stage to remove from the collection. - * @return {Boolean} Whether the post-process stage was removed. + * @return {boolean} Whether the post-process stage was removed. */ PostProcessStageCollection.prototype.remove = function (stage) { if (!this.contains(stage)) { @@ -489,7 +489,7 @@ PostProcessStageCollection.prototype.remove = function (stage) { * Returns whether the collection contains a post-process stage. * * @param {PostProcessStage|PostProcessStageComposite} stage The post-process stage. - * @return {Boolean} Whether the collection contains the post-process stage. + * @return {boolean} Whether the collection contains the post-process stage. */ PostProcessStageCollection.prototype.contains = function (stage) { return ( @@ -502,7 +502,7 @@ PostProcessStageCollection.prototype.contains = function (stage) { /** * Gets the post-process stage at <code>index</code>. * - * @param {Number} index The index of the post-process stage. + * @param {number} index The index of the post-process stage. * @return {PostProcessStage|PostProcessStageComposite} The post-process stage at index. */ PostProcessStageCollection.prototype.get = function (index) { @@ -532,7 +532,7 @@ PostProcessStageCollection.prototype.removeAll = function () { /** * Gets a post-process stage in the collection by its name. * - * @param {String} name The name of the post-process stage. + * @param {string} name The name of the post-process stage. * @return {PostProcessStage|PostProcessStageComposite} The post-process stage. * * @private @@ -545,7 +545,7 @@ PostProcessStageCollection.prototype.getStageByName = function (name) { * Called before the post-process stages in the collection are executed. Calls update for each stage and creates WebGL resources. * * @param {Context} context The context. - * @param {Boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. + * @param {boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. * * @private */ @@ -703,7 +703,7 @@ function getOutputTexture(stage) { /** * Gets the output texture of a stage with the given name. * - * @param {String} stageName The name of the stage. + * @param {string} stageName The name of the stage. * @return {Texture|undefined} The texture rendered to by the stage with the given name. * * @private @@ -854,7 +854,7 @@ PostProcessStageCollection.prototype.copy = function (context, framebuffer) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PostProcessStageCollection#destroy */ diff --git a/packages/engine/Source/Scene/PostProcessStageComposite.js b/packages/engine/Source/Scene/PostProcessStageComposite.js index cd6b5c89775..bcea9587afa 100644 --- a/packages/engine/Source/Scene/PostProcessStageComposite.js +++ b/packages/engine/Source/Scene/PostProcessStageComposite.js @@ -16,11 +16,11 @@ import destroyObject from "../Core/destroyObject.js"; * @alias PostProcessStageComposite * @constructor * - * @param {Object} options An object with the following properties: + * @param {object} options An object with the following properties: * @param {Array} options.stages An array of {@link PostProcessStage}s or composites to be executed in order. - * @param {Boolean} [options.inputPreviousStageTexture=true] Whether to execute each post-process stage where the input to one stage is the output of the previous. Otherwise, the input to each contained stage is the output of the stage that executed before the composite. - * @param {String} [options.name=createGuid()] The unique name of this post-process stage for reference by other composites. If a name is not supplied, a GUID will be generated. - * @param {Object} [options.uniforms] An alias to the uniforms of post-process stages. + * @param {boolean} [options.inputPreviousStageTexture=true] Whether to execute each post-process stage where the input to one stage is the output of the previous. Otherwise, the input to each contained stage is the output of the stage that executed before the composite. + * @param {string} [options.name=createGuid()] The unique name of this post-process stage for reference by other composites. If a name is not supplied, a GUID will be generated. + * @param {object} [options.uniforms] An alias to the uniforms of post-process stages. * * @exception {DeveloperError} options.stages.length must be greater than 0.0. * @@ -119,7 +119,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { * Determines if this post-process stage is ready to be executed. * * @memberof PostProcessStageComposite.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -138,7 +138,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { * The unique name of this post-process stage for reference by other stages in a PostProcessStageComposite. * * @memberof PostProcessStageComposite.prototype - * @type {String} + * @type {string} * @readonly */ name: { @@ -150,7 +150,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { * Whether or not to execute this post-process stage when ready. * * @memberof PostProcessStageComposite.prototype - * @type {Boolean} + * @type {boolean} */ enabled: { get: function () { @@ -167,7 +167,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { /** * An alias to the uniform values of the post-process stages. May be <code>undefined</code>; in which case, get each stage to set uniform values. * @memberof PostProcessStageComposite.prototype - * @type {Object} + * @type {object} */ uniforms: { get: function () { @@ -181,7 +181,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { * or the output texture of the previous stage. * * @memberof PostProcessStageComposite.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ inputPreviousStageTexture: { @@ -193,7 +193,7 @@ Object.defineProperties(PostProcessStageComposite.prototype, { * The number of post-process stages in this composite. * * @memberof PostProcessStageComposite.prototype - * @type {Number} + * @type {number} * @readonly */ length: { @@ -245,7 +245,7 @@ PostProcessStageComposite.prototype._isSupported = function (context) { /** * Gets the post-process stage at <code>index</code> * - * @param {Number} index The index of the post-process stage or composite. + * @param {number} index The index of the post-process stage or composite. * @return {PostProcessStage|PostProcessStageComposite} The post-process stage or composite at index. * * @exception {DeveloperError} index must be greater than or equal to 0. @@ -298,7 +298,7 @@ function isSelectedTextureDirty(stage) { /** * A function that will be called before execute. Updates each post-process stage in the composite. * @param {Context} context The context. - * @param {Boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. + * @param {boolean} useLogDepth Whether the scene uses a logarithmic depth buffer. * @private */ PostProcessStageComposite.prototype.update = function (context, useLogDepth) { @@ -330,7 +330,7 @@ PostProcessStageComposite.prototype.update = function (context, useLogDepth) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PostProcessStageComposite#destroy */ diff --git a/packages/engine/Source/Scene/PostProcessStageLibrary.js b/packages/engine/Source/Scene/PostProcessStageLibrary.js index 73db1b8adcf..b24dfab4538 100644 --- a/packages/engine/Source/Scene/PostProcessStageLibrary.js +++ b/packages/engine/Source/Scene/PostProcessStageLibrary.js @@ -198,7 +198,7 @@ PostProcessStageLibrary.createDepthOfFieldStage = function () { * </p> * * @param {Scene} scene The scene. - * @return {Boolean} Whether this post process stage is supported. + * @return {boolean} Whether this post process stage is supported. * * @see {Context#depthTexture} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} @@ -257,7 +257,7 @@ PostProcessStageLibrary.createEdgeDetectionStage = function () { * </p> * * @param {Scene} scene The scene. - * @return {Boolean} Whether this post process stage is supported. + * @return {boolean} Whether this post process stage is supported. * * @see {Context#depthTexture} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} @@ -352,7 +352,7 @@ PostProcessStageLibrary.createSilhouetteStage = function (edgeDetectionStages) { * </p> * * @param {Scene} scene The scene. - * @return {Boolean} Whether this post process stage is supported. + * @return {boolean} Whether this post process stage is supported. * * @see {Context#depthTexture} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} @@ -628,7 +628,7 @@ PostProcessStageLibrary.createAmbientOcclusionStage = function () { * </p> * * @param {Scene} scene The scene. - * @return {Boolean} Whether this post process stage is supported. + * @return {boolean} Whether this post process stage is supported. * * @see {Context#depthTexture} * @see {@link http://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/|WEBGL_depth_texture} @@ -655,7 +655,7 @@ PostProcessStageLibrary.createFXAAStage = function () { /** * Creates a post-process stage that applies ACES tonemapping operator. - * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @param {boolean} useAutoExposure Whether or not to use auto-exposure. * @return {PostProcessStage} A post-process stage that applies ACES tonemapping operator. * @private */ @@ -675,7 +675,7 @@ PostProcessStageLibrary.createAcesTonemappingStage = function ( /** * Creates a post-process stage that applies filmic tonemapping operator. - * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @param {boolean} useAutoExposure Whether or not to use auto-exposure. * @return {PostProcessStage} A post-process stage that applies filmic tonemapping operator. * @private */ @@ -695,7 +695,7 @@ PostProcessStageLibrary.createFilmicTonemappingStage = function ( /** * Creates a post-process stage that applies Reinhard tonemapping operator. - * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @param {boolean} useAutoExposure Whether or not to use auto-exposure. * @return {PostProcessStage} A post-process stage that applies Reinhard tonemapping operator. * @private */ @@ -715,7 +715,7 @@ PostProcessStageLibrary.createReinhardTonemappingStage = function ( /** * Creates a post-process stage that applies modified Reinhard tonemapping operator. - * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @param {boolean} useAutoExposure Whether or not to use auto-exposure. * @return {PostProcessStage} A post-process stage that applies modified Reinhard tonemapping operator. * @private */ diff --git a/packages/engine/Source/Scene/PostProcessStageSampleMode.js b/packages/engine/Source/Scene/PostProcessStageSampleMode.js index d011284ac3a..b078849fd0d 100644 --- a/packages/engine/Source/Scene/PostProcessStageSampleMode.js +++ b/packages/engine/Source/Scene/PostProcessStageSampleMode.js @@ -1,20 +1,20 @@ /** * Determines how input texture to a {@link PostProcessStage} is sampled. * - * @enum {Number} + * @enum {number} */ const PostProcessStageSampleMode = { /** * Samples the texture by returning the closest texel. * - * @type {Number} + * @type {number} * @constant */ NEAREST: 0, /** * Samples the texture through bi-linear interpolation of the four nearest texels. * - * @type {Number} + * @type {number} * @constant */ LINEAR: 1, diff --git a/packages/engine/Source/Scene/PostProcessStageTextureCache.js b/packages/engine/Source/Scene/PostProcessStageTextureCache.js index 27dae726510..cdc6e21a398 100644 --- a/packages/engine/Source/Scene/PostProcessStageTextureCache.js +++ b/packages/engine/Source/Scene/PostProcessStageTextureCache.js @@ -389,7 +389,7 @@ PostProcessStageTextureCache.prototype.clear = function (context) { /** * Gets the stage with the given name. - * @param {String} name The name of the stage. + * @param {string} name The name of the stage. * @return {PostProcessStage|PostProcessStageComposite} */ PostProcessStageTextureCache.prototype.getStageByName = function (name) { @@ -398,7 +398,7 @@ PostProcessStageTextureCache.prototype.getStageByName = function (name) { /** * Gets the output texture for a stage with the given name. - * @param {String} name The name of the stage. + * @param {string} name The name of the stage. * @return {Texture|undefined} The output texture of the stage with the given name. */ PostProcessStageTextureCache.prototype.getOutputTexture = function (name) { @@ -408,7 +408,7 @@ PostProcessStageTextureCache.prototype.getOutputTexture = function (name) { /** * Gets the framebuffer for a stage with the given name. * - * @param {String} name The name of the stage. + * @param {string} name The name of the stage. * @return {Framebuffer|undefined} The framebuffer for the stage with the given name. */ PostProcessStageTextureCache.prototype.getFramebuffer = function (name) { @@ -426,7 +426,7 @@ PostProcessStageTextureCache.prototype.getFramebuffer = function (name) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see PostProcessStageTextureCache#destroy */ diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index 1d9da3d018b..257f97b37ea 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -63,20 +63,20 @@ import ShadowMode from "./ShadowMode.js"; * @alias Primitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {GeometryInstance[]|GeometryInstance} [options.geometryInstances] The geometry instances - or a single geometry instance - to render. * @param {Appearance} [options.appearance] The appearance used to render the primitive. * @param {Appearance} [options.depthFailAppearance] The appearance used to shade this primitive when it fails the depth test. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. - * @param {Boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. - * @param {Boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. - * @param {Boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. - * @param {Boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. - * @param {Boolean} [options.cull=true] When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to <code>false</code> for a small performance gain if you are manually culling the primitive. - * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {boolean} [options.vertexCacheOptimize=false] When <code>true</code>, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {boolean} [options.interleave=false] When <code>true</code>, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {boolean} [options.compressVertices=true] When <code>true</code>, the geometry vertices are compressed, which will save memory. + * @param {boolean} [options.releaseGeometryInstances=true] When <code>true</code>, the primitive does not keep a reference to the input <code>geometryInstances</code> to save memory. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each geometry instance will only be pickable with {@link Scene#pick}. When <code>false</code>, GPU memory is saved. + * @param {boolean} [options.cull=true] When <code>true</code>, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to <code>false</code> for a small performance gain if you are manually culling the primitive. + * @param {boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {ShadowMode} [options.shadows=ShadowMode.DISABLED] Determines whether this primitive casts or receives shadows from light sources. * * @example @@ -254,7 +254,7 @@ function Primitive(options) { * based on their bounding volume. Set this to <code>false</code> for a small performance gain * if you are manually culling the primitive. * - * @type {Boolean} + * @type {boolean} * * @default true */ @@ -266,7 +266,7 @@ function Primitive(options) { * Draws the bounding sphere for each draw command in the primitive. * </p> * - * @type {Boolean} + * @type {boolean} * * @default false */ @@ -386,7 +386,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -402,7 +402,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default false @@ -418,7 +418,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -434,7 +434,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -450,7 +450,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -466,7 +466,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @default true @@ -484,7 +484,7 @@ Object.defineProperties(Primitive.prototype, { * * @memberof Primitive.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -496,7 +496,7 @@ Object.defineProperties(Primitive.prototype, { /** * Gets a promise that resolves when the primitive is ready to render. * @memberof Primitive.prototype - * @type {Promise.<Primitive>} + * @type {Promise<Primitive>} * @readonly */ readyPromise: { @@ -2388,7 +2388,7 @@ function createPickIdProperty(primitive, properties, index) { * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * * @param {*} id The id of the {@link GeometryInstance}. - * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * @returns {object} The typed array in the attribute's format or undefined if the is no instance with id. * * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. * @@ -2463,7 +2463,7 @@ Primitive.prototype.getGeometryInstanceAttributes = function (id) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Primitive#destroy */ diff --git a/packages/engine/Source/Scene/PrimitiveCollection.js b/packages/engine/Source/Scene/PrimitiveCollection.js index ec7ce6b65e4..89591993dfe 100644 --- a/packages/engine/Source/Scene/PrimitiveCollection.js +++ b/packages/engine/Source/Scene/PrimitiveCollection.js @@ -12,9 +12,9 @@ import DeveloperError from "../Core/DeveloperError.js"; * @alias PrimitiveCollection * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.show=true] Determines if the primitives in the collection will be shown. - * @param {Boolean} [options.destroyPrimitives=true] Determines if primitives in the collection are destroyed when they are removed. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.show=true] Determines if the primitives in the collection will be shown. + * @param {boolean} [options.destroyPrimitives=true] Determines if primitives in the collection are destroyed when they are removed. * * @example * const billboards = new Cesium.BillboardCollection(); @@ -38,7 +38,7 @@ function PrimitiveCollection(options) { /** * Determines if primitives in this collection will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -48,7 +48,7 @@ function PrimitiveCollection(options) { * {@link PrimitiveCollection#destroy} or {@link PrimitiveCollection#remove} or implicitly * by {@link PrimitiveCollection#removeAll}. * - * @type {Boolean} + * @type {boolean} * @default true * * @example @@ -76,7 +76,7 @@ Object.defineProperties(PrimitiveCollection.prototype, { * * @memberof PrimitiveCollection.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -89,9 +89,9 @@ Object.defineProperties(PrimitiveCollection.prototype, { /** * Adds a primitive to the collection. * - * @param {Object} primitive The primitive to add. - * @param {Number} [index] The index to add the layer at. If omitted, the primitive will be added at the bottom of all existing primitives. - * @returns {Object} The primitive added to the collection. + * @param {object} primitive The primitive to add. + * @param {number} [index] The index to add the layer at. If omitted, the primitive will be added at the bottom of all existing primitives. + * @returns {object} The primitive added to the collection. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * @@ -134,8 +134,8 @@ PrimitiveCollection.prototype.add = function (primitive, index) { /** * Removes a primitive from the collection. * - * @param {Object} [primitive] The primitive to remove. - * @returns {Boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. + * @param {object} [primitive] The primitive to remove. + * @returns {boolean} <code>true</code> if the primitive was removed; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * @@ -201,8 +201,8 @@ PrimitiveCollection.prototype.removeAll = function () { /** * Determines if this collection contains a primitive. * - * @param {Object} [primitive] The primitive to check for. - * @returns {Boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. + * @param {object} [primitive] The primitive to check for. + * @returns {boolean} <code>true</code> if the primitive is in the collection; <code>false</code> if the primitive is <code>undefined</code> or was not found in the collection. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * @@ -231,7 +231,7 @@ function getPrimitiveIndex(compositePrimitive, primitive) { * Raises a primitive "up one" in the collection. If all primitives in the collection are drawn * on the globe surface, this visually moves the primitive up one. * - * @param {Object} [primitive] The primitive to raise. + * @param {object} [primitive] The primitive to raise. * * @exception {DeveloperError} primitive is not in this collection. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. @@ -257,7 +257,7 @@ PrimitiveCollection.prototype.raise = function (primitive) { * Raises a primitive to the "top" of the collection. If all primitives in the collection are drawn * on the globe surface, this visually moves the primitive to the top. * - * @param {Object} [primitive] The primitive to raise the top. + * @param {object} [primitive] The primitive to raise the top. * * @exception {DeveloperError} primitive is not in this collection. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. @@ -283,7 +283,7 @@ PrimitiveCollection.prototype.raiseToTop = function (primitive) { * Lowers a primitive "down one" in the collection. If all primitives in the collection are drawn * on the globe surface, this visually moves the primitive down one. * - * @param {Object} [primitive] The primitive to lower. + * @param {object} [primitive] The primitive to lower. * * @exception {DeveloperError} primitive is not in this collection. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. @@ -309,7 +309,7 @@ PrimitiveCollection.prototype.lower = function (primitive) { * Lowers a primitive to the "bottom" of the collection. If all primitives in the collection are drawn * on the globe surface, this visually moves the primitive to the bottom. * - * @param {Object} [primitive] The primitive to lower to the bottom. + * @param {object} [primitive] The primitive to lower to the bottom. * * @exception {DeveloperError} primitive is not in this collection. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. @@ -334,8 +334,8 @@ PrimitiveCollection.prototype.lowerToBottom = function (primitive) { /** * Returns the primitive in the collection at the specified index. * - * @param {Number} index The zero-based index of the primitive to return. - * @returns {Object} The primitive at the <code>index</code>. + * @param {number} index The zero-based index of the primitive to return. + * @returns {object} The primitive at the <code>index</code>. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * @@ -432,7 +432,7 @@ PrimitiveCollection.prototype.postPassesUpdate = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see PrimitiveCollection#destroy */ diff --git a/packages/engine/Source/Scene/PrimitiveLoadPlan.js b/packages/engine/Source/Scene/PrimitiveLoadPlan.js index e58d972d060..31d1f5928f5 100644 --- a/packages/engine/Source/Scene/PrimitiveLoadPlan.js +++ b/packages/engine/Source/Scene/PrimitiveLoadPlan.js @@ -37,7 +37,7 @@ function AttributeLoadPlan(attribute) { * Whether the attribute will be loaded as a GPU buffer by the time * {@link PrimitiveLoadPlan#postProcess} is finished. * - * @type {Boolean} + * @type {boolean} * @private */ this.loadBuffer = false; @@ -46,7 +46,7 @@ function AttributeLoadPlan(attribute) { * Whether the attribute will be loaded as a packed typed array by the time * {@link PrimitiveLoadPlan#postProcess} is finished. * - * @type {Boolean} + * @type {boolean} * @private */ this.loadTypedArray = false; @@ -81,7 +81,7 @@ function IndicesLoadPlan(indices) { * Whether the indices will be loaded as a GPU buffer by the time * {@link PrimitiveLoadPlan#postProcess} is finished. * - * @type {Boolean} + * @type {boolean} * @private */ this.loadBuffer = false; @@ -90,7 +90,7 @@ function IndicesLoadPlan(indices) { * Whether the indices will be loaded as a typed array copy of the GPU * buffer by the time {@link PrimitiveLoadPlan#postProcess} is finished. * - * @type {Boolean} + * @type {boolean} * @private */ this.loadTypedArray = false; @@ -145,7 +145,7 @@ function PrimitiveLoadPlan(primitive) { * Set this true to indicate that the primitive has the * CESIUM_primitive_outline extension and needs to be post-processed * - * @type {Boolean} + * @type {boolean} * @private */ this.needsOutlines = false; @@ -153,7 +153,7 @@ function PrimitiveLoadPlan(primitive) { /** * The outline edge indices from the CESIUM_primitive_outline extension * - * @type {Number[]} + * @type {number[]} * @private */ this.outlineIndices = undefined; diff --git a/packages/engine/Source/Scene/PropertyAttribute.js b/packages/engine/Source/Scene/PropertyAttribute.js index 565e6bb1f91..86ce1a6c7cb 100644 --- a/packages/engine/Source/Scene/PropertyAttribute.js +++ b/packages/engine/Source/Scene/PropertyAttribute.js @@ -10,10 +10,10 @@ import PropertyAttributeProperty from "./PropertyAttributeProperty.js"; * See the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata|EXT_structural_metadata Extension} * </p> * - * @param {Object} options Object with the following properties: - * @param {String} [options.name] Optional human-readable name to describe the attribute - * @param {Number} [options.id] A unique id to identify the property attribute, useful for debugging. This is the array index in the property attributes array - * @param {Object} options.propertyAttribute The property attribute JSON, following the EXT_structural_metadata schema. + * @param {object} options Object with the following properties: + * @param {string} [options.name] Optional human-readable name to describe the attribute + * @param {number} [options.id] A unique id to identify the property attribute, useful for debugging. This is the array index in the property attributes array + * @param {object} options.propertyAttribute The property attribute JSON, following the EXT_structural_metadata schema. * @param {MetadataClass} options.class The class that properties conform to. * * @alias PropertyAttribute @@ -58,7 +58,7 @@ Object.defineProperties(PropertyAttribute.prototype, { * * @memberof PropertyAttribute.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -72,7 +72,7 @@ Object.defineProperties(PropertyAttribute.prototype, { * * @memberof PropertyAttribute.prototype * - * @type {String|Number} + * @type {string|number} * @readonly * @private */ @@ -101,7 +101,7 @@ Object.defineProperties(PropertyAttribute.prototype, { * * @memberof PropertyAttribute.prototype * - * @type {Object.<String, PropertyAttributeProperty>} + * @type {Object.<string, PropertyAttributeProperty>} * @readonly * @private */ @@ -131,7 +131,7 @@ Object.defineProperties(PropertyAttribute.prototype, { * * @memberof PropertyAttribute.prototype * - * @type {Object} + * @type {object} * @readonly * @private */ @@ -145,7 +145,7 @@ Object.defineProperties(PropertyAttribute.prototype, { /** * Gets the property with the given property ID. * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {PropertyAttributeProperty|undefined} The property, or <code>undefined</code> if the property does not exist. * @private */ diff --git a/packages/engine/Source/Scene/PropertyAttributeProperty.js b/packages/engine/Source/Scene/PropertyAttributeProperty.js index f7d515069cd..607fb861147 100644 --- a/packages/engine/Source/Scene/PropertyAttributeProperty.js +++ b/packages/engine/Source/Scene/PropertyAttributeProperty.js @@ -9,8 +9,8 @@ import defined from "../Core/defined.js"; * See the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata|EXT_structural_metadata Extension} * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.property The property JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.property The property JSON object. * @param {MetadataClassProperty} options.classProperty The class property. * * @alias PropertyAttributeProperty @@ -66,7 +66,7 @@ Object.defineProperties(PropertyAttributeProperty.prototype, { * The attribute semantic * * @memberof PropertyAttributeProperty.prototype - * @type {String} + * @type {string} * @readonly * @private */ @@ -81,7 +81,7 @@ Object.defineProperties(PropertyAttributeProperty.prototype, { * undefined, they default to identity so this property is set false * * @memberof MetadataClassProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -95,7 +95,7 @@ Object.defineProperties(PropertyAttributeProperty.prototype, { * The offset to be added to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @readonly * @private */ @@ -109,7 +109,7 @@ Object.defineProperties(PropertyAttributeProperty.prototype, { * The scale to be multiplied to property values as part of the value transform. * * @memberof MetadataClassProperty.prototype - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/PropertyTable.js b/packages/engine/Source/Scene/PropertyTable.js index 8271901b823..19860c82de1 100644 --- a/packages/engine/Source/Scene/PropertyTable.js +++ b/packages/engine/Source/Scene/PropertyTable.js @@ -21,15 +21,15 @@ import JsonMetadataTable from "./JsonMetadataTable.js"; * previous {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: - * @param {String} [options.name] Human-readable name to describe the table - * @param {String|Number} [options.id] A unique id to identify the property table, useful for debugging. For <code>EXT_structural_metadata</code>, this is the array index in the property tables array, for <code>EXT_feature_metadata</code> this is the dictionary key in the property tables dictionary. - * @param {Number} options.count The number of features in the table. + * @param {object} options Object with the following properties: + * @param {string} [options.name] Human-readable name to describe the table + * @param {string|number} [options.id] A unique id to identify the property table, useful for debugging. For <code>EXT_structural_metadata</code>, this is the array index in the property tables array, for <code>EXT_feature_metadata</code> this is the dictionary key in the property tables dictionary. + * @param {number} options.count The number of features in the table. * @param {MetadataTable} [options.metadataTable] A table of binary properties. * @param {JsonMetadataTable} [options.jsonMetadataTable] For compatibility with the old batch table, free-form JSON properties can be passed in. * @param {BatchTableHierarchy} [options.batchTableHierarchy] For compatibility with the <code>3DTILES_batch_table_hierarchy</code> extension, a hierarchy can be provided. - * @param {Object} [options.extras] Extra user-defined properties - * @param {Object} [options.extensions] An object containing extensions + * @param {object} [options.extras] Extra user-defined properties + * @param {object} [options.extensions] An object containing extensions * * @alias PropertyTable * @constructor @@ -59,7 +59,7 @@ Object.defineProperties(PropertyTable.prototype, { * A human-readable name for this table * * @memberof PropertyTable.prototype - * @type {String} + * @type {string} * @readonly * @private */ @@ -72,7 +72,7 @@ Object.defineProperties(PropertyTable.prototype, { * An identifier for this table. Useful for debugging. * * @memberof PropertyTable.prototype - * @type {String|Number} + * @type {string|number} * @readonly * @private */ @@ -85,7 +85,7 @@ Object.defineProperties(PropertyTable.prototype, { * The number of features in the table. * * @memberof PropertyTable.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -130,7 +130,7 @@ Object.defineProperties(PropertyTable.prototype, { * An object containing extensions. * * @memberof PropertyTable.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -145,7 +145,7 @@ Object.defineProperties(PropertyTable.prototype, { * not include JSON metadata * * @memberof PropertyTable.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -168,9 +168,9 @@ Object.defineProperties(PropertyTable.prototype, { /** * Returns whether the feature has this property. For compatibility with the <code>3DTILES_batch_table_hierarchy</code> extension, this is computed for a specific feature. * - * @param {Number} index The index of the feature. - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the feature has this property. + * @param {number} index The index of the feature. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the feature has this property. * @private */ PropertyTable.prototype.hasProperty = function (index, propertyId) { @@ -206,8 +206,8 @@ PropertyTable.prototype.hasProperty = function (index, propertyId) { /** * Returns whether the feature has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the feature has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the feature has a property with the given semantic. * @private */ PropertyTable.prototype.hasPropertyBySemantic = function (index, semantic) { @@ -228,8 +228,8 @@ PropertyTable.prototype.hasPropertyBySemantic = function (index, semantic) { * This is mainly useful for checking whether a property exists in the class * hierarchy when using the <code>3DTILES_batch_table_hierarchy</code> extension. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether any feature has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether any feature has this property. * @private */ PropertyTable.prototype.propertyExists = function (propertyId) { @@ -264,8 +264,8 @@ PropertyTable.prototype.propertyExists = function (propertyId) { /** * Returns whether any feature has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether any feature has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether any feature has a property with the given semantic. * @private */ PropertyTable.prototype.propertyExistsBySemantic = function (semantic) { @@ -285,9 +285,9 @@ const scratchResults = []; /** * Returns an array of property IDs. For compatibility with the <code>3DTILES_batch_table_hierarchy</code> extension, this is computed for a specific feature. * - * @param {Number} index The index of the feature. - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {number} index The index of the feature. + * @param {string[]} [results] An array into which to store the results. + * @returns {string[]} The property IDs. * @private */ PropertyTable.prototype.getPropertyIds = function (index, results) { @@ -325,8 +325,8 @@ PropertyTable.prototype.getPropertyIds = function (index, results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {Number} index The index of the feature. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the feature. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property. * @private */ @@ -364,8 +364,8 @@ PropertyTable.prototype.getProperty = function (index, propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {Number} index The index of the feature. - * @param {String} propertyId The case-sensitive ID of the property. + * @param {number} index The index of the feature. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. * @private */ @@ -404,8 +404,8 @@ PropertyTable.prototype.setProperty = function (index, propertyId, value) { * semantics. * </p> * - * @param {Number} index The index of the feature. - * @param {String} semantic The case-sensitive semantic of the property. + * @param {number} index The index of the feature. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this semantic. * @private */ @@ -425,10 +425,10 @@ PropertyTable.prototype.getPropertyBySemantic = function (index, semantic) { * semantics. * </p> * - * @param {Number} index The index of the feature. - * @param {String} semantic The case-sensitive semantic of the property. + * @param {number} index The index of the feature. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ PropertyTable.prototype.setPropertyBySemantic = function ( @@ -451,7 +451,7 @@ PropertyTable.prototype.setPropertyBySemantic = function ( * values in typed arrays. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The typed array containing the property values or <code>undefined</code> if the property values are not stored in a typed array. * * @private @@ -476,7 +476,7 @@ PropertyTable.prototype.getPropertyTypedArray = function (propertyId) { * semantics. * </p> * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The typed array containing the property values or <code>undefined</code> if the property values are not stored in a typed array. * * @private diff --git a/packages/engine/Source/Scene/PropertyTexture.js b/packages/engine/Source/Scene/PropertyTexture.js index 28d136766db..a6cd3a12fbe 100644 --- a/packages/engine/Source/Scene/PropertyTexture.js +++ b/packages/engine/Source/Scene/PropertyTexture.js @@ -10,12 +10,12 @@ import PropertyTextureProperty from "./PropertyTextureProperty.js"; * previous {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: - * @param {String} [options.name] Optional human-readable name to describe the texture - * @param {String|Number} [options.id] A unique id to identify the property texture, useful for debugging. For <code>EXT_structural_metadata</code>, this is the array index in the property textures array, for <code>EXT_feature_metadata</code> this is the dictionary key in the property textures dictionary. - * @param {Object} options.propertyTexture The property texture JSON, following the EXT_structural_metadata schema. + * @param {object} options Object with the following properties: + * @param {string} [options.name] Optional human-readable name to describe the texture + * @param {string|number} [options.id] A unique id to identify the property texture, useful for debugging. For <code>EXT_structural_metadata</code>, this is the array index in the property textures array, for <code>EXT_feature_metadata</code> this is the dictionary key in the property textures dictionary. + * @param {object} options.propertyTexture The property texture JSON, following the EXT_structural_metadata schema. * @param {MetadataClass} options.class The class that properties conform to. - * @param {Object.<String, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. + * @param {Object.<string, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. * * @alias PropertyTexture * @constructor @@ -64,7 +64,7 @@ Object.defineProperties(PropertyTexture.prototype, { * A human-readable name for this texture * * @memberof PropertyTexture.prototype - * @type {String} + * @type {string} * @readonly * @private */ @@ -77,7 +77,7 @@ Object.defineProperties(PropertyTexture.prototype, { * An identifier for this texture. Useful for debugging. * * @memberof PropertyTexture.prototype - * @type {String|Number} + * @type {string|number} * @readonly * @private */ @@ -133,7 +133,7 @@ Object.defineProperties(PropertyTexture.prototype, { * An object containing extensions. * * @memberof PropertyTexture.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -147,7 +147,7 @@ Object.defineProperties(PropertyTexture.prototype, { /** * Gets the property with the given property ID. * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {PropertyTextureProperty|undefined} The property, or <code>undefined</code> if the property does not exist. * @private */ diff --git a/packages/engine/Source/Scene/PropertyTextureProperty.js b/packages/engine/Source/Scene/PropertyTextureProperty.js index 6c4eace0a84..6bf3011f43e 100644 --- a/packages/engine/Source/Scene/PropertyTextureProperty.js +++ b/packages/engine/Source/Scene/PropertyTextureProperty.js @@ -13,8 +13,8 @@ import MetadataComponentType from "./MetadataComponentType.js"; * previous {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.property The property JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.property The property JSON object. * @param {MetadataClassProperty} options.classProperty The class property. * @param {Object.<Number, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. * @@ -97,7 +97,7 @@ Object.defineProperties(PropertyTextureProperty.prototype, { * undefined, they default to identity so this property is set false * * @memberof PropertyTextureProperty.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -111,7 +111,7 @@ Object.defineProperties(PropertyTextureProperty.prototype, { * The offset to be added to property values as part of the value transform. * * @memberof PropertyTextureProperty.prototype - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @readonly * @private */ @@ -125,7 +125,7 @@ Object.defineProperties(PropertyTextureProperty.prototype, { * The scale to be multiplied to property values as part of the value transform. * * @memberof PropertyTextureProperty.prototype - * @type {Number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} + * @type {number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4} * @readonly * @private */ @@ -248,8 +248,8 @@ PropertyTextureProperty.prototype.unpackInShader = function (packedValueGlsl) { * Reformat from an array of channel indices like <code>[0, 1]</code> to a * string of channels as would be used in GLSL swizzling (e.g. "rg") * - * @param {Number[]} channels the channel indices - * @return {String} The channels as a string of "r", "g", "b" or "a" characters. + * @param {number[]} channels the channel indices + * @return {string} The channels as a string of "r", "g", "b" or "a" characters. * @private */ function reformatChannels(channels) { diff --git a/packages/engine/Source/Scene/QuadtreePrimitive.js b/packages/engine/Source/Scene/QuadtreePrimitive.js index 795b71bf78e..8d042f40d23 100644 --- a/packages/engine/Source/Scene/QuadtreePrimitive.js +++ b/packages/engine/Source/Scene/QuadtreePrimitive.js @@ -32,10 +32,10 @@ import TileSelectionResult from "./TileSelectionResult.js"; * * @param {QuadtreeTileProvider} options.tileProvider The tile provider that loads, renders, and estimates * the distance to individual tiles. - * @param {Number} [options.maximumScreenSpaceError=2] The maximum screen-space error, in pixels, that is allowed. + * @param {number} [options.maximumScreenSpaceError=2] The maximum screen-space error, in pixels, that is allowed. * A higher maximum error will render fewer tiles and improve performance, while a lower * value will improve visual quality. - * @param {Number} [options.tileCacheSize=100] The maximum number of tiles that will be retained in the tile cache. + * @param {number} [options.tileCacheSize=100] The maximum number of tiles that will be retained in the tile cache. * Note that tiles will never be unloaded if they were used for rendering the last * frame, so the actual number of resident tiles may be higher. The value of * this property will not affect visual quality. @@ -105,7 +105,7 @@ function QuadtreePrimitive(options) { * Gets or sets the maximum screen-space error, in pixels, that is allowed. * A higher maximum error will render fewer tiles and improve performance, while a lower * value will improve visual quality. - * @type {Number} + * @type {number} * @default 2 */ this.maximumScreenSpaceError = defaultValue( @@ -118,7 +118,7 @@ function QuadtreePrimitive(options) { * Note that tiles will never be unloaded if they were used for rendering the last * frame, so the actual number of resident tiles may be higher. The value of * this property will not affect visual quality. - * @type {Number} + * @type {number} * @default 100 */ this.tileCacheSize = defaultValue(options.tileCacheSize, 100); @@ -131,7 +131,7 @@ function QuadtreePrimitive(options) { * tile level to be loaded successively, significantly increasing load time. Setting it to a large * number (e.g. 1000) will minimize the number of tiles that are loaded but tend to make * detail appear all at once after a long wait. - * @type {Number} + * @type {number} * @default 20 */ this.loadingDescendantLimit = 20; @@ -140,7 +140,7 @@ function QuadtreePrimitive(options) { * Gets or sets a value indicating whether the ancestors of rendered tiles should be preloaded. * Setting this to true optimizes the zoom-out experience and provides more detail in * newly-exposed areas when panning. The down side is that it requires loading more tiles. - * @type {Boolean} + * @type {boolean} * @default true */ this.preloadAncestors = true; @@ -150,7 +150,7 @@ function QuadtreePrimitive(options) { * Setting this to true causes tiles with the same parent as a rendered tile to be loaded, even * if they are culled. Setting this to true may provide a better panning experience at the * cost of loading more tiles. - * @type {Boolean} + * @type {boolean} * @default false */ this.preloadSiblings = false; @@ -459,7 +459,7 @@ QuadtreePrimitive.prototype.endFrame = function (frameState) { * * @memberof QuadtreePrimitive * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see QuadtreePrimitive#destroy */ @@ -704,7 +704,7 @@ for (let i = 0; i < traversalQuadsByLevel.length; ++i) { * @param {Primitive} primitive The QuadtreePrimitive. * @param {FrameState} frameState The frame state. * @param {QuadtreeTile} tile The tile to visit - * @param {Boolean} ancestorMeetsSse True if a tile higher in the tile tree already met the SSE and we're refining further only + * @param {boolean} ancestorMeetsSse True if a tile higher in the tile tree already met the SSE and we're refining further only * to maintain detail while that higher tile loads. * @param {TraversalDetails} traveralDetails On return, populated with details of how the traversal of this tile went. */ diff --git a/packages/engine/Source/Scene/QuadtreeTile.js b/packages/engine/Source/Scene/QuadtreeTile.js index 19f5b5abc48..601458acbbf 100644 --- a/packages/engine/Source/Scene/QuadtreeTile.js +++ b/packages/engine/Source/Scene/QuadtreeTile.js @@ -11,9 +11,9 @@ import TileSelectionResult from "./TileSelectionResult.js"; * @constructor * @private * - * @param {Number} options.level The level of the tile in the quadtree. - * @param {Number} options.x The X coordinate of the tile in the quadtree. 0 is the westernmost tile. - * @param {Number} options.y The Y coordinate of the tile in the quadtree. 0 is the northernmost tile. + * @param {number} options.level The level of the tile in the quadtree. + * @param {number} options.x The X coordinate of the tile in the quadtree. 0 is the westernmost tile. + * @param {number} options.y The Y coordinate of the tile in the quadtree. 0 is the northernmost tile. * @param {TilingScheme} options.tilingScheme The tiling scheme in which this tile exists. * @param {QuadtreeTile} [options.parent] This tile's parent, or undefined if this is a root tile. */ @@ -83,7 +83,7 @@ function QuadtreeTile(options) { /** * Gets or sets a value indicating whether or not the tile is currently renderable. - * @type {Boolean} + * @type {boolean} * @default false */ this.renderable = false; @@ -93,7 +93,7 @@ function QuadtreeTile(options) { * parent tile. If all four children of a parent tile were upsampled from the parent, * we will render the parent instead of the children even if the LOD indicates that * the children would be preferable. - * @type {Boolean} + * @type {boolean} * @default false */ this.upsampledFromParent = false; @@ -101,7 +101,7 @@ function QuadtreeTile(options) { /** * Gets or sets the additional data associated with this tile. The exact content is specific to the * {@link QuadtreeTileProvider}. - * @type {Object} + * @type {object} * @default undefined */ this.data = undefined; @@ -204,7 +204,7 @@ Object.defineProperties(QuadtreeTile.prototype, { /** * Gets the tile X coordinate. * @memberof QuadtreeTile.prototype - * @type {Number} + * @type {number} */ x: { get: function () { @@ -215,7 +215,7 @@ Object.defineProperties(QuadtreeTile.prototype, { /** * Gets the tile Y coordinate. * @memberof QuadtreeTile.prototype - * @type {Number} + * @type {number} */ y: { get: function () { @@ -226,7 +226,7 @@ Object.defineProperties(QuadtreeTile.prototype, { /** * Gets the level-of-detail, where zero is the coarsest, least-detailed. * @memberof QuadtreeTile.prototype - * @type {Number} + * @type {number} */ level: { get: function () { @@ -369,7 +369,7 @@ Object.defineProperties(QuadtreeTile.prototype, { * This property will return true if the {@link QuadtreeTile#state} is * <code>START</code> or <code>LOADING</code>. * @memberof QuadtreeTile.prototype - * @type {Boolean} + * @type {boolean} */ needsLoading: { get: function () { @@ -386,7 +386,7 @@ Object.defineProperties(QuadtreeTile.prototype, { * <code>eligibleForUnloading</code> property, the value of that property is returned. * Otherwise, this property returns true. * @memberof QuadtreeTile.prototype - * @type {Boolean} + * @type {boolean} */ eligibleForUnloading: { get: function () { diff --git a/packages/engine/Source/Scene/QuadtreeTileLoadState.js b/packages/engine/Source/Scene/QuadtreeTileLoadState.js index c76ebcea90c..5be7703b2bf 100644 --- a/packages/engine/Source/Scene/QuadtreeTileLoadState.js +++ b/packages/engine/Source/Scene/QuadtreeTileLoadState.js @@ -1,6 +1,6 @@ /** * The state of a {@link QuadtreeTile} in the tile load pipeline. - * @enum {Number} + * @enum {number} * @private */ const QuadtreeTileLoadState = { diff --git a/packages/engine/Source/Scene/QuadtreeTileProvider.js b/packages/engine/Source/Scene/QuadtreeTileProvider.js index 92c6a90a983..bb7f5fb73fb 100644 --- a/packages/engine/Source/Scene/QuadtreeTileProvider.js +++ b/packages/engine/Source/Scene/QuadtreeTileProvider.js @@ -19,7 +19,7 @@ function QuadtreeTileProvider() { * @memberof QuadtreeTileProvider * * @param {TilingScheme} tilingScheme The tiling scheme for which to compute the geometric error. - * @returns {Number} The maximum geometric error at level zero, in meters. + * @returns {number} The maximum geometric error at level zero, in meters. */ QuadtreeTileProvider.computeDefaultLevelZeroMaximumGeometricError = function ( tilingScheme @@ -45,7 +45,7 @@ Object.defineProperties(QuadtreeTileProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof QuadtreeTileProvider.prototype - * @type {Boolean} + * @type {boolean} */ ready: { get: DeveloperError.throwInstantiationError, @@ -120,8 +120,8 @@ QuadtreeTileProvider.prototype.endUpdate = * @memberof QuadtreeTileProvider * @function * - * @param {Number} level The tile level for which to get the maximum geometric error. - * @returns {Number} The maximum geometric error in meters. + * @param {number} level The tile level for which to get the maximum geometric error. + * @returns {number} The maximum geometric error in meters. */ QuadtreeTileProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; @@ -184,7 +184,7 @@ QuadtreeTileProvider.prototype.showTileThisFrame = * @param {QuadtreeTile} tile The tile instance. * @param {FrameState} frameState The state information of the current rendering frame. * - * @returns {Number} The distance from the camera to the closest point on the tile, in meters. + * @returns {number} The distance from the camera to the closest point on the tile, in meters. */ QuadtreeTileProvider.prototype.computeDistanceToTile = DeveloperError.throwInstantiationError; @@ -197,7 +197,7 @@ QuadtreeTileProvider.prototype.computeDistanceToTile = * * @memberof QuadtreeTileProvider * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see QuadtreeTileProvider#destroy */ diff --git a/packages/engine/Source/Scene/ResourceCache.js b/packages/engine/Source/Scene/ResourceCache.js index 862b39aeeaa..d80625bc6b5 100644 --- a/packages/engine/Source/Scene/ResourceCache.js +++ b/packages/engine/Source/Scene/ResourceCache.js @@ -50,7 +50,7 @@ function CacheEntry(resourceLoader) { * Gets a resource from the cache. If the resource exists its reference count is * incremented. Otherwise, if no resource loader exists, undefined is returned. * - * @param {String} cacheKey The cache key of the resource. + * @param {string} cacheKey The cache key of the resource. * * @returns {ResourceLoader|undefined} The resource. * @private @@ -71,7 +71,7 @@ ResourceCache.get = function (cacheKey) { /** * Loads a resource and adds it to the cache. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {ResourceLoader} options.resourceLoader The resource. * * @exception {DeveloperError} Resource with this cacheKey is already in the cach @@ -138,8 +138,8 @@ ResourceCache.unload = function (resourceLoader) { /** * Loads a schema from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. + * @param {object} options Object with the following properties: + * @param {object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the schema JSON. Mutually exclusive with options.schema. * * @returns {MetadataSchemaLoader} The schema resource. @@ -186,9 +186,9 @@ ResourceCache.loadSchema = function (options) { /** * Load an embedded buffer from the cache. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.parentResource The {@link Resource} containing the embedded buffer. - * @param {Number} options.bufferId A unique identifier of the embedded buffer within the parent resource. + * @param {number} options.bufferId A unique identifier of the embedded buffer within the parent resource. * @param {Uint8Array} [options.typedArray] The typed array containing the embedded buffer contents. * * @returns {BufferLoader} The buffer loader. @@ -234,7 +234,7 @@ ResourceCache.loadEmbeddedBuffer = function (options) { /** * Loads an external buffer from the cache. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.resource The {@link Resource} pointing to the external buffer. * * @returns {BufferLoader} The buffer loader. @@ -272,11 +272,11 @@ ResourceCache.loadExternalBuffer = function (options) { /** * Loads a glTF JSON from the cache. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {Uint8Array} [options.typedArray] The typed array containing the glTF contents. - * @param {Object} [options.gltfJson] The parsed glTF JSON contents. + * @param {object} [options.gltfJson] The parsed glTF JSON contents. * * @returns {GltfJsonLoader} The glTF JSON. * @private @@ -321,9 +321,9 @@ ResourceCache.loadGltfJson = function (options) { /** * Loads a glTF buffer view from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.bufferViewId The bufferView ID. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.bufferViewId The bufferView ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @@ -375,9 +375,9 @@ ResourceCache.loadBufferView = function (options) { /** * Loads Draco data from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.draco The Draco extension object. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {object} options.draco The Draco extension object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @@ -429,19 +429,19 @@ ResourceCache.loadDraco = function (options) { /** * Loads a glTF vertex buffer from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {FrameState} options.frameState The frame state. - * @param {Number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. - * @param {Object} [options.draco] The Draco extension object. - * @param {String} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. - * @param {Number} [options.accessorId] The accessor ID. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.dequantize=false] Determines whether or not the vertex buffer will be dequantized on the CPU. - * @param {Boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. - * @param {Boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. + * @param {number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. + * @param {object} [options.draco] The Draco extension object. + * @param {string} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. + * @param {number} [options.accessorId] The accessor ID. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.dequantize=false] Determines whether or not the vertex buffer will be dequantized on the CPU. + * @param {boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. + * @param {boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. * @exception {DeveloperError} One of options.bufferViewId and options.draco must be defined. * @exception {DeveloperError} When options.draco is defined options.attributeSemantic must also be defined. * @exception {DeveloperError} When options.draco is defined options.accessorId must also be defined. @@ -564,16 +564,16 @@ function hasDracoCompression(draco, semantic) { /** * Loads a glTF index buffer from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.accessorId The accessor ID corresponding to the index buffer. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.accessorId The accessor ID corresponding to the index buffer. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {FrameState} options.frameState The frame state. - * @param {Object} [options.draco] The Draco extension object. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. - * @param {Boolean} [options.loadTypedArray=false] Load index buffer as a typed array. + * @param {object} [options.draco] The Draco extension object. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. + * @param {boolean} [options.loadTypedArray=false] Load index buffer as a typed array. * @returns {GltfIndexBufferLoader} The index buffer loader. * @private */ @@ -645,9 +645,9 @@ ResourceCache.loadIndexBuffer = function (options) { /** * Loads a glTF image from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.imageId The image ID. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @@ -699,14 +699,14 @@ ResourceCache.loadImage = function (options) { /** * Loads a glTF texture from the cache. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.textureInfo The texture info object. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {object} options.textureInfo The texture info object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * @param {FrameState} options.frameState The frame state. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. + * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * * @returns {GltfTextureLoader} The texture loader. * @private diff --git a/packages/engine/Source/Scene/ResourceCacheKey.js b/packages/engine/Source/Scene/ResourceCacheKey.js index b8075efed85..71d983242d5 100644 --- a/packages/engine/Source/Scene/ResourceCacheKey.js +++ b/packages/engine/Source/Scene/ResourceCacheKey.js @@ -118,11 +118,11 @@ function getSamplerCacheKey(gltf, textureInfo) { /** * Gets the schema cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. + * @param {object} options Object with the following properties: + * @param {object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the schema JSON. Mutually exclusive with options.schema. * - * @returns {String} The schema cache key. + * @returns {string} The schema cache key. * * @exception {DeveloperError} One of options.schema and options.resource must be defined. * @private @@ -149,10 +149,10 @@ ResourceCacheKey.getSchemaCacheKey = function (options) { /** * Gets the external buffer cache key. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.resource The {@link Resource} pointing to the external buffer. * - * @returns {String} The external buffer cache key. + * @returns {string} The external buffer cache key. * @private */ ResourceCacheKey.getExternalBufferCacheKey = function (options) { @@ -169,11 +169,11 @@ ResourceCacheKey.getExternalBufferCacheKey = function (options) { /** * Gets the embedded buffer cache key. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.parentResource The {@link Resource} containing the embedded buffer. - * @param {Number} options.bufferId A unique identifier of the embedded buffer within the parent resource. + * @param {number} options.bufferId A unique identifier of the embedded buffer within the parent resource. * - * @returns {String} The embedded buffer cache key. + * @returns {string} The embedded buffer cache key. * @private */ ResourceCacheKey.getEmbeddedBufferCacheKey = function (options) { @@ -195,10 +195,10 @@ ResourceCacheKey.getEmbeddedBufferCacheKey = function (options) { /** * Gets the glTF cache key. * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * - * @returns {String} The glTF cache key. + * @returns {string} The glTF cache key. * @private */ ResourceCacheKey.getGltfCacheKey = function (options) { @@ -215,13 +215,13 @@ ResourceCacheKey.getGltfCacheKey = function (options) { /** * Gets the buffer view cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.bufferViewId The bufferView ID. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.bufferViewId The bufferView ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {String} The buffer view cache key. + * @returns {string} The buffer view cache key. * @private */ ResourceCacheKey.getBufferViewCacheKey = function (options) { @@ -261,13 +261,13 @@ ResourceCacheKey.getBufferViewCacheKey = function (options) { /** * Gets the Draco cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.draco The Draco extension object. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {object} options.draco The Draco extension object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {String} The Draco cache key. + * @returns {string} The Draco cache key. * @private */ ResourceCacheKey.getDracoCacheKey = function (options) { @@ -290,21 +290,21 @@ ResourceCacheKey.getDracoCacheKey = function (options) { /** * Gets the vertex buffer cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {FrameState} options.frameState The frame state. - * @param {Number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. - * @param {Object} [options.draco] The Draco extension object. - * @param {String} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. - * @param {Boolean} [options.dequantize=false] Determines whether or not the vertex buffer will be dequantized on the CPU. - * @param {Boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. - * @param {Boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. + * @param {number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer. + * @param {object} [options.draco] The Draco extension object. + * @param {string} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL. + * @param {boolean} [options.dequantize=false] Determines whether or not the vertex buffer will be dequantized on the CPU. + * @param {boolean} [options.loadBuffer=false] Load vertex buffer as a GPU vertex buffer. + * @param {boolean} [options.loadTypedArray=false] Load vertex buffer as a typed array. * @exception {DeveloperError} One of options.bufferViewId and options.draco must be defined. * @exception {DeveloperError} When options.draco is defined options.attributeSemantic must also be defined. * - * @returns {String} The vertex buffer cache key. + * @returns {string} The vertex buffer cache key. * @private */ ResourceCacheKey.getVertexBufferCacheKey = function (options) { @@ -405,17 +405,17 @@ function hasDracoCompression(draco, semantic) { /** * Gets the index buffer cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.accessorId The accessor ID corresponding to the index buffer. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.accessorId The accessor ID corresponding to the index buffer. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {FrameState} options.frameState The frame state. - * @param {Object} [options.draco] The Draco extension object. - * @param {Boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. - * @param {Boolean} [options.loadTypedArray=false] Load index buffer as a typed array. + * @param {object} [options.draco] The Draco extension object. + * @param {boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. + * @param {boolean} [options.loadTypedArray=false] Load index buffer as a typed array. * - * @returns {String} The index buffer cache key. + * @returns {string} The index buffer cache key. * @private */ ResourceCacheKey.getIndexBufferCacheKey = function (options) { @@ -484,13 +484,13 @@ ResourceCacheKey.getIndexBufferCacheKey = function (options) { /** * Gets the image cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.imageId The image ID. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {String} The image cache key. + * @returns {string} The image cache key. * @private */ ResourceCacheKey.getImageCacheKey = function (options) { @@ -520,15 +520,15 @@ ResourceCacheKey.getImageCacheKey = function (options) { /** * Gets the texture cache key. * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Object} options.textureInfo The texture info object. + * @param {object} options Object with the following properties: + * @param {object} options.gltf The glTF JSON. + * @param {object} options.textureInfo The texture info object. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * @param {FrameState} options.frameState The frame state. * - * @returns {String} The texture cache key. + * @returns {string} The texture cache key. * @private */ ResourceCacheKey.getTextureCacheKey = function (options) { diff --git a/packages/engine/Source/Scene/ResourceCacheStatistics.js b/packages/engine/Source/Scene/ResourceCacheStatistics.js index 70fef98fbc3..187f267bf36 100644 --- a/packages/engine/Source/Scene/ResourceCacheStatistics.js +++ b/packages/engine/Source/Scene/ResourceCacheStatistics.js @@ -14,7 +14,7 @@ function ResourceCacheStatistics() { /** * The size of vertex buffers and index buffers loaded in the cache in bytes. * - * @type {Number} + * @type {number} * @private */ this.geometryByteLength = 0; @@ -22,7 +22,7 @@ function ResourceCacheStatistics() { /** * The size of all textures loaded in the cache in bytes * - * @type {Number} + * @type {number} * @private */ this.texturesByteLength = 0; diff --git a/packages/engine/Source/Scene/ResourceLoader.js b/packages/engine/Source/Scene/ResourceLoader.js index aa5756207e6..03c1fde7851 100644 --- a/packages/engine/Source/Scene/ResourceLoader.js +++ b/packages/engine/Source/Scene/ResourceLoader.js @@ -25,7 +25,7 @@ Object.defineProperties(ResourceLoader.prototype, { * * @memberof ResourceLoader.prototype * - * @type {Promise.<ResourceLoader>|undefined} + * @type {Promise<ResourceLoader>|undefined} * @readonly * @private */ @@ -40,7 +40,7 @@ Object.defineProperties(ResourceLoader.prototype, { * * @memberof ResourceLoader.prototype * - * @type {String} + * @type {string} * @readonly * @private */ @@ -54,7 +54,7 @@ Object.defineProperties(ResourceLoader.prototype, { /** * Loads the resource. - * @returns {Promise.<ResourceLoader>} A promise which resolves to the loader when the resource loading is completed. + * @returns {Promise<ResourceLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ ResourceLoader.prototype.load = function () { @@ -78,7 +78,7 @@ ResourceLoader.prototype.process = function (frameState) {}; /** * Constructs a {@link RuntimeError} from an errorMessage and an error. * - * @param {String} errorMessage The error message. + * @param {string} errorMessage The error message. * @param {Error} [error] The error. * * @returns {RuntimeError} The runtime error. @@ -107,7 +107,7 @@ ResourceLoader.prototype.getError = function (errorMessage, error) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ResourceLoader#destroy * @private diff --git a/packages/engine/Source/Scene/ResourceLoaderState.js b/packages/engine/Source/Scene/ResourceLoaderState.js index df206e2943f..8e86d7621c9 100644 --- a/packages/engine/Source/Scene/ResourceLoaderState.js +++ b/packages/engine/Source/Scene/ResourceLoaderState.js @@ -7,7 +7,7 @@ const ResourceLoaderState = { /** * The resource has not yet been loaded. * - * @type {Number} + * @type {number} * @constant * @private */ @@ -15,7 +15,7 @@ const ResourceLoaderState = { /** * The resource is loading. In this state, external resources are fetched as needed. * - * @type {Number} + * @type {number} * @constant * @private */ @@ -23,7 +23,7 @@ const ResourceLoaderState = { /** * The resource has finished loading, but requires further processing. GPU resources are allocated in this state as needed. * - * @type {Number} + * @type {number} * @constant * @private */ @@ -31,7 +31,7 @@ const ResourceLoaderState = { /** * The resource has finished loading and processing; the results are ready to be used. * - * @type {Number} + * @type {number} * @constant * @private */ @@ -39,7 +39,7 @@ const ResourceLoaderState = { /** * The resource loading or processing has failed due to an error. * - * @type {Number} + * @type {number} * @constant * @private */ diff --git a/packages/engine/Source/Scene/SDFSettings.js b/packages/engine/Source/Scene/SDFSettings.js index 66748dde8d4..0ce45f7cc78 100644 --- a/packages/engine/Source/Scene/SDFSettings.js +++ b/packages/engine/Source/Scene/SDFSettings.js @@ -7,7 +7,7 @@ const SDFSettings = { /** * The font size in pixels * - * @type {Number} + * @type {number} * @constant */ FONT_SIZE: 48.0, @@ -15,7 +15,7 @@ const SDFSettings = { /** * Whitespace padding around glyphs. * - * @type {Number} + * @type {number} * @constant */ PADDING: 10.0, @@ -23,7 +23,7 @@ const SDFSettings = { /** * How many pixels around the glyph shape to use for encoding distance * - * @type {Number} + * @type {number} * @constant */ RADIUS: 8.0, @@ -31,7 +31,7 @@ const SDFSettings = { /** * How much of the radius (relative) is used for the inside part the glyph. * - * @type {Number} + * @type {number} * @constant */ CUTOFF: 0.25, diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index 40d9c4f8e3b..e1f1c31514b 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -85,20 +85,20 @@ const requestRenderAfterFrame = function (scene) { * @alias Scene * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {HTMLCanvasElement} options.canvas The HTML canvas element to create the scene for. * @param {ContextOptions} [options.contextOptions] Context and WebGL creation properties. * @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed. * @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas. * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. - * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. - * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. - * @param {Boolean} [options.shadows=false] Determines if shadows are cast by light sources. + * @param {boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. + * @param {boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. + * @param {boolean} [options.shadows=false] Determines if shadows are cast by light sources. * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. - * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @param {Number} [options.depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation. - * @param {Number} [options.msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. + * @param {boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {number} [options.depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation. + * @param {number} [options.msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. * * @see CesiumWidget * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} @@ -223,7 +223,7 @@ function Scene(options) { * after the event is raised. If this property is false, the <code>render</code> function * returns normally after raising the event. * - * @type {Boolean} + * @type {boolean} * @default false */ this.rethrowRenderErrors = false; @@ -232,7 +232,7 @@ function Scene(options) { * Determines whether or not to instantly complete the * scene transition animation on user input. * - * @type {Boolean} + * @type {boolean} * @default true */ this.completeMorphOnUserInput = true; @@ -280,7 +280,7 @@ function Scene(options) { /** * Uses a bloom filter on the sun when enabled. * - * @type {Boolean} + * @type {boolean} * @default true */ this.sunBloom = true; @@ -314,7 +314,7 @@ function Scene(options) { * The current morph transition time between 2D/Columbus View and 3D, * with 0.0 being 2D or Columbus View and 1.0 being 3D. * - * @type {Number} + * @type {number} * @default 1.0 */ this.morphTime = 1.0; @@ -327,7 +327,7 @@ function Scene(options) { * <code>true</code>, use {@link Scene#logarithmicDepthFarToNearRatio}. * </p> * - * @type {Number} + * @type {number} * @default 1000.0 */ this.farToNearRatio = 1000.0; @@ -340,7 +340,7 @@ function Scene(options) { * <code>false</code>, use {@link Scene#farToNearRatio}. * </p> * - * @type {Number} + * @type {number} * @default 1e9 */ this.logarithmicDepthFarToNearRatio = 1e9; @@ -350,7 +350,7 @@ function Scene(options) { * to the surface shows z-fighting, decreasing this will eliminate the artifact, but decrease performance. On the * other hand, increasing this will increase performance but may cause z-fighting among primitives close to the surface. * - * @type {Number} + * @type {number} * @default 1.75e6 */ this.nearToFarDistance2D = 1.75e6; @@ -480,14 +480,14 @@ function Scene(options) { * const worldPosition = viewer.scene.pickPosition(movement.position); * }, Cesium.ScreenSpaceEventType.LEFT_CLICK); * - * @type {Boolean} + * @type {boolean} * @default false */ this.pickTranslucentDepth = false; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. - * @type {Number} + * @type {number} * @default 500.0 * @private */ @@ -515,7 +515,7 @@ function Scene(options) { /** * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and * unclassified 3D Tile geometry will render with the color multiplied by {@link Scene#invertClassificationColor}. - * @type {Boolean} + * @type {boolean} * @default false */ this.invertClassification = false; @@ -536,13 +536,13 @@ function Scene(options) { /** * The focal length for use when with cardboard or WebVR. - * @type {Number} + * @type {number} */ this.focalLength = undefined; /** * The eye separation distance in meters for use with cardboard or WebVR. - * @type {Number} + * @type {number} */ this.eyeSeparation = undefined; @@ -604,7 +604,7 @@ function Scene(options) { * @see Scene#maximumRenderTimeChange * @see Scene#requestRender * - * @type {Boolean} + * @type {boolean} * @default false */ this.requestRenderMode = defaultValue(options.requestRenderMode, false); @@ -621,7 +621,7 @@ function Scene(options) { * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#requestRenderMode * - * @type {Number} + * @type {number} * @default 0.0 */ this.maximumRenderTimeChange = defaultValue( @@ -683,7 +683,7 @@ function Scene(options) { /** * The url to the KTX2 file containing the specular environment map and convoluted mipmaps for image-based lighting of PBR models. - * @type {String} + * @type {string} */ this.specularEnvironmentMaps = undefined; this._specularEnvironmentMapAtlas = undefined; @@ -740,7 +740,7 @@ Object.defineProperties(Scene.prototype, { * The drawingBufferHeight of the underlying GL context. * @memberof Scene.prototype * - * @type {Number} + * @type {number} * @readonly * * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} @@ -755,7 +755,7 @@ Object.defineProperties(Scene.prototype, { * The drawingBufferHeight of the underlying GL context. * @memberof Scene.prototype * - * @type {Number} + * @type {number} * @readonly * * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} @@ -770,7 +770,7 @@ Object.defineProperties(Scene.prototype, { * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. * @memberof Scene.prototype * - * @type {Number} + * @type {number} * @readonly * * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. @@ -785,7 +785,7 @@ Object.defineProperties(Scene.prototype, { * The maximum length in pixels of one edge of a cube map, supported by this WebGL implementation. It will be at least 16. * @memberof Scene.prototype * - * @type {Number} + * @type {number} * @readonly * * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>GL_MAX_CUBE_MAP_TEXTURE_SIZE</code>. @@ -800,7 +800,7 @@ Object.defineProperties(Scene.prototype, { * Returns <code>true</code> if the {@link Scene#pickPosition} function is supported. * @memberof Scene.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @see Scene#pickPosition @@ -815,7 +815,7 @@ Object.defineProperties(Scene.prototype, { * Returns <code>true</code> if the {@link Scene#sampleHeight} and {@link Scene#sampleHeightMostDetailed} functions are supported. * @memberof Scene.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @see Scene#sampleHeight @@ -831,7 +831,7 @@ Object.defineProperties(Scene.prototype, { * Returns <code>true</code> if the {@link Scene#clampToHeight} and {@link Scene#clampToHeightMostDetailed} functions are supported. * @memberof Scene.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @see Scene#clampToHeight @@ -847,7 +847,7 @@ Object.defineProperties(Scene.prototype, { * Returns <code>true</code> if the {@link Scene#invertClassification} is supported. * @memberof Scene.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @see Scene#invertClassification @@ -862,7 +862,7 @@ Object.defineProperties(Scene.prototype, { * Returns <code>true</code> if specular environment maps are supported. * @memberof Scene.prototype * - * @type {Boolean} + * @type {boolean} * @readonly * * @see Scene#specularEnvironmentMaps @@ -1259,7 +1259,7 @@ Object.defineProperties(Scene.prototype, { * * @memberof Scene.prototype * - * @type {Object} + * @type {object} * @readonly * * @default undefined @@ -1273,7 +1273,7 @@ Object.defineProperties(Scene.prototype, { /** * Gets whether or not the scene is optimized for 3D only viewing. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ scene3DOnly: { @@ -1287,7 +1287,7 @@ Object.defineProperties(Scene.prototype, { * Note that this only reflects the original construction option, and there are * other factors that could prevent OIT from functioning on a given system configuration. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ orderIndependentTranslucency: { @@ -1299,7 +1299,7 @@ Object.defineProperties(Scene.prototype, { /** * Gets the unique identifier for this scene. * @memberof Scene.prototype - * @type {String} + * @type {string} * @readonly */ id: { @@ -1359,7 +1359,7 @@ Object.defineProperties(Scene.prototype, { /** * Gets the number of frustums used in the last frame. * @memberof Scene.prototype - * @type {Number} + * @type {number} * * @private */ @@ -1373,7 +1373,7 @@ Object.defineProperties(Scene.prototype, { * When <code>true</code>, splits the scene into two viewports with steroscopic views for the left and right eyes. * Used for cardboard and WebVR. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @default false */ useWebVR: { @@ -1429,7 +1429,7 @@ Object.defineProperties(Scene.prototype, { * Gets or sets the position of the splitter within the viewport. Valid values are between 0.0 and 1.0. * @memberof Scene.prototype * - * @type {Number} + * @type {number} */ splitPosition: { get: function () { @@ -1446,7 +1446,7 @@ Object.defineProperties(Scene.prototype, { * be applied. When less than zero, the depth test should never be applied. Setting the disableDepthTestDistance * property of a billboard, label or point will override this value. * @memberof Scene.prototype - * @type {Number} + * @type {number} * @default 0.0 */ minimumDisableDepthTestDistance: { @@ -1469,7 +1469,7 @@ Object.defineProperties(Scene.prototype, { * Whether or not to use a logarithmic depth buffer. Enabling this option will allow for less frustums in the multi-frustum, * increasing performance. This property relies on fragmentDepth being supported. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} */ logarithmicDepthBuffer: { get: function () { @@ -1487,7 +1487,7 @@ Object.defineProperties(Scene.prototype, { /** * The value used for gamma correction. This is only used when rendering with high dynamic range. * @memberof Scene.prototype - * @type {Number} + * @type {number} * @default 2.2 */ gamma: { @@ -1502,7 +1502,7 @@ Object.defineProperties(Scene.prototype, { /** * Whether or not to use high dynamic range rendering. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @default false */ highDynamicRange: { @@ -1523,7 +1523,7 @@ Object.defineProperties(Scene.prototype, { /** * Whether or not high dynamic range rendering is supported. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @default true */ @@ -1540,7 +1540,7 @@ Object.defineProperties(Scene.prototype, { /** * Whether or not the camera is underneath the globe. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @default false */ @@ -1553,7 +1553,7 @@ Object.defineProperties(Scene.prototype, { /** * The sample rate of multisample antialiasing (values greater than 1 enable MSAA). * @memberof Scene.prototype - * @type {Number} + * @type {number} * @default 1 */ msaaSamples: { @@ -1569,7 +1569,7 @@ Object.defineProperties(Scene.prototype, { /** * Returns <code>true</code> if the Scene's context supports MSAA. * @memberof Scene.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ msaaSupported: { @@ -1583,7 +1583,7 @@ Object.defineProperties(Scene.prototype, { * measure for real pixel measurements appropriate to a particular device. * * @memberof Scene.prototype - * @type {Number} + * @type {number} * @default 1.0 * @private */ @@ -1617,7 +1617,7 @@ Object.defineProperties(Scene.prototype, { /** * Determines if a compressed texture format is supported. - * @param {String} format The texture format. May be the name of the format or the WebGL extension name, e.g. s3tc or WEBGL_compressed_texture_s3tc. + * @param {string} format The texture format. May be the name of the format or the WebGL extension name, e.g. s3tc or WEBGL_compressed_texture_s3tc. * @return {boolean} Whether or not the format is supported. */ Scene.prototype.getCompressedTextureFormatSupported = function (format) { @@ -3920,9 +3920,9 @@ Scene.prototype.clampLineWidth = function (width) { * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); * * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Number} [width=3] Width of the pick rectangle. - * @param {Number} [height=3] Height of the pick rectangle. - * @returns {Object} Object containing the picked primitive. + * @param {number} [width=3] Width of the pick rectangle. + * @param {number} [height=3] Height of the pick rectangle. + * @returns {object} Object containing the picked primitive. */ Scene.prototype.pick = function (windowPosition, width, height) { return this._picking.pick(this, windowPosition, width, height); @@ -3985,10 +3985,10 @@ Scene.prototype.pickPosition = function (windowPosition, result) { * the list are ordered by their visual order in the scene (front to back). * * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Number} [limit] If supplied, stop drilling after collecting this many picks. - * @param {Number} [width=3] Width of the pick rectangle. - * @param {Number} [height=3] Height of the pick rectangle. - * @returns {Array.<*>} Array of objects, each containing 1 picked primitives. + * @param {number} [limit] If supplied, stop drilling after collecting this many picks. + * @param {number} [width=3] Width of the pick rectangle. + * @param {number} [height=3] Height of the pick rectangle. + * @returns {any[]} Array of objects, each containing 1 picked primitives. * * @exception {DeveloperError} windowPosition is undefined. * @@ -4047,8 +4047,8 @@ function updateRequestRenderModeDeferCheckPass(scene) { * * @param {Ray} ray The ray. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Object} An object containing the object and position of the first intersection. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {object} An object containing the object and position of the first intersection. * * @exception {DeveloperError} Ray intersections are only supported in 3D mode. */ @@ -4070,9 +4070,9 @@ Scene.prototype.pickFromRay = function (ray, objectsToExclude, width) { * @private * * @param {Ray} ray The ray. - * @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections. + * @param {number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection. - * @param {Number} [width=0.1] Width of the intersection volume in meters. + * @param {number} [width=0.1] Width of the intersection volume in meters. * @returns {Object[]} List of objects containing the object and position of each intersection. * * @exception {DeveloperError} Ray intersections are only supported in 3D mode. @@ -4100,8 +4100,8 @@ Scene.prototype.drillPickFromRay = function ( * * @param {Ray} ray The ray. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Promise.<Object>} A promise that resolves to an object containing the object and position of the first intersection. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {Promise<object>} A promise that resolves to an object containing the object and position of the first intersection. * * @exception {DeveloperError} Ray intersections are only supported in 3D mode. */ @@ -4125,10 +4125,10 @@ Scene.prototype.pickFromRayMostDetailed = function ( * @private * * @param {Ray} ray The ray. - * @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections. + * @param {number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Promise.<Object[]>} A promise that resolves to a list of objects containing the object and position of each intersection. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {Promise<Object[]>} A promise that resolves to a list of objects containing the object and position of each intersection. * * @exception {DeveloperError} Ray intersections are only supported in 3D mode. */ @@ -4158,8 +4158,8 @@ Scene.prototype.drillPickFromRayMostDetailed = function ( * * @param {Cartographic} position The cartographic position to sample height from. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Number} The height. This may be <code>undefined</code> if there was no scene geometry to sample height from. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {number} The height. This may be <code>undefined</code> if there was no scene geometry to sample height from. * * @example * const position = new Cesium.Cartographic(-1.31968, 0.698874); @@ -4188,7 +4188,7 @@ Scene.prototype.sampleHeight = function (position, objectsToExclude, width) { * * @param {Cartesian3} cartesian The cartesian position. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to. - * @param {Number} [width=0.1] Width of the intersection volume in meters. + * @param {number} [width=0.1] Width of the intersection volume in meters. * @param {Cartesian3} [result] An optional object to return the clamped position. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. This may be <code>undefined</code> if there was no scene geometry to clamp to. * @@ -4228,8 +4228,8 @@ Scene.prototype.clampToHeight = function ( * * @param {Cartographic[]} positions The cartographic positions to update with sampled heights. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when the query has completed. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {Promise<Cartographic[]>} A promise that resolves to the provided list of positions when the query has completed. * * @example * const positions = [ @@ -4268,8 +4268,8 @@ Scene.prototype.sampleHeightMostDetailed = function ( * * @param {Cartesian3[]} cartesians The cartesian positions to update with clamped positions. * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to. - * @param {Number} [width=0.1] Width of the intersection volume in meters. - * @returns {Promise.<Cartesian3[]>} A promise that resolves to the provided list of positions when the query has completed. + * @param {number} [width=0.1] Width of the intersection volume in meters. + * @returns {Promise<Cartesian3[]>} A promise that resolves to the provided list of positions when the query has completed. * * @example * const cartesians = [ @@ -4331,7 +4331,7 @@ Scene.prototype.completeMorph = function () { /** * Asynchronously transitions the scene to 2D. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. + * @param {number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. */ Scene.prototype.morphTo2D = function (duration) { let ellipsoid; @@ -4347,7 +4347,7 @@ Scene.prototype.morphTo2D = function (duration) { /** * Asynchronously transitions the scene to Columbus View. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. + * @param {number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. */ Scene.prototype.morphToColumbusView = function (duration) { let ellipsoid; @@ -4363,7 +4363,7 @@ Scene.prototype.morphToColumbusView = function (duration) { /** * Asynchronously transitions the scene to 3D. - * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. + * @param {number} [duration=2.0] The amount of time, in seconds, for transition animations to complete. */ Scene.prototype.morphTo3D = function (duration) { let ellipsoid; @@ -4383,7 +4383,7 @@ Scene.prototype.morphTo3D = function (duration) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Scene#destroy */ diff --git a/packages/engine/Source/Scene/SceneMode.js b/packages/engine/Source/Scene/SceneMode.js index 006ed4ed704..2905c53cb82 100644 --- a/packages/engine/Source/Scene/SceneMode.js +++ b/packages/engine/Source/Scene/SceneMode.js @@ -1,14 +1,14 @@ /** * Indicates if the scene is viewed in 3D, 2D, or 2.5D Columbus view. * - * @enum {Number} + * @enum {number} * @see Scene#mode */ const SceneMode = { /** * Morphing between mode, e.g., 3D to 2D. * - * @type {Number} + * @type {number} * @constant */ MORPHING: 0, @@ -17,7 +17,7 @@ const SceneMode = { * Columbus View mode. A 2.5D perspective view where the map is laid out * flat and objects with non-zero height are drawn above it. * - * @type {Number} + * @type {number} * @constant */ COLUMBUS_VIEW: 1, @@ -25,7 +25,7 @@ const SceneMode = { /** * 2D mode. The map is viewed top-down with an orthographic projection. * - * @type {Number} + * @type {number} * @constant */ SCENE2D: 2, @@ -33,7 +33,7 @@ const SceneMode = { /** * 3D mode. A traditional 3D perspective view of the globe. * - * @type {Number} + * @type {number} * @constant */ SCENE3D: 3, @@ -43,7 +43,7 @@ const SceneMode = { * Returns the morph time for the given scene mode. * * @param {SceneMode} value The scene mode - * @returns {Number} The morph time + * @returns {number} The morph time */ SceneMode.getMorphTime = function (value) { if (value === SceneMode.SCENE3D) { diff --git a/packages/engine/Source/Scene/SceneTransitioner.js b/packages/engine/Source/Scene/SceneTransitioner.js index c10f8528fa9..c8f9e0f24c2 100644 --- a/packages/engine/Source/Scene/SceneTransitioner.js +++ b/packages/engine/Source/Scene/SceneTransitioner.js @@ -299,7 +299,7 @@ SceneTransitioner.prototype.morphTo3D = function (duration, ellipsoid) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ SceneTransitioner.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 0763865ddec..8d982335447 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -49,41 +49,41 @@ function ScreenSpaceCameraController(scene) { * start of such events, and set true on completion. To keep inputs disabled * past the end of camera flights, you must use the other booleans (enableTranslate, * enableZoom, enableRotate, enableTilt, and enableLook). - * @type {Boolean} + * @type {boolean} * @default true */ this.enableInputs = true; /** * If true, allows the user to pan around the map. If false, the camera stays locked at the current position. * This flag only applies in 2D and Columbus view modes. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableTranslate = true; /** * If true, allows the user to zoom in and out. If false, the camera is locked to the current distance from the ellipsoid. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableZoom = true; /** * If true, allows the user to rotate the world which translates the user's position. * This flag only applies in 2D and 3D. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableRotate = true; /** * If true, allows the user to tilt the camera. If false, the camera is locked to the current heading. * This flag only applies in 3D and Columbus view. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableTilt = true; /** * If true, allows the user to use free-look. If false, the camera view direction can only be changed through translating * or rotating. This flag only applies in 3D and Columbus view modes. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableLook = true; @@ -91,7 +91,7 @@ function ScreenSpaceCameraController(scene) { * A parameter in the range <code>[0, 1)</code> used to determine how long * the camera will continue to spin because of inertia. * With value of zero, the camera will have no inertia. - * @type {Number} + * @type {number} * @default 0.9 */ this.inertiaSpin = 0.9; @@ -99,7 +99,7 @@ function ScreenSpaceCameraController(scene) { * A parameter in the range <code>[0, 1)</code> used to determine how long * the camera will continue to translate because of inertia. * With value of zero, the camera will have no inertia. - * @type {Number} + * @type {number} * @default 0.9 */ this.inertiaTranslate = 0.9; @@ -107,7 +107,7 @@ function ScreenSpaceCameraController(scene) { * A parameter in the range <code>[0, 1)</code> used to determine how long * the camera will continue to zoom because of inertia. * With value of zero, the camera will have no inertia. - * @type {Number} + * @type {number} * @default 0.8 */ this.inertiaZoom = 0.8; @@ -115,25 +115,25 @@ function ScreenSpaceCameraController(scene) { * A parameter in the range <code>[0, 1)</code> used to limit the range * of various user inputs to a percentage of the window width/height per animation frame. * This helps keep the camera under control in low-frame-rate situations. - * @type {Number} + * @type {number} * @default 0.1 */ this.maximumMovementRatio = 0.1; /** * Sets the duration, in seconds, of the bounce back animations in 2D and Columbus view. - * @type {Number} + * @type {number} * @default 3.0 */ this.bounceAnimationTime = 3.0; /** * The minimum magnitude, in meters, of the camera position when zooming. Defaults to 1.0. - * @type {Number} + * @type {number} * @default 1.0 */ this.minimumZoomDistance = 1.0; /** * The maximum magnitude, in meters, of the camera position when zooming. Defaults to positive infinity. - * @type {Number} + * @type {number} * @default {@link Number.POSITIVE_INFINITY} */ this.maximumZoomDistance = Number.POSITIVE_INFINITY; @@ -218,14 +218,14 @@ function ScreenSpaceCameraController(scene) { }; /** * The minimum height the camera must be before picking the terrain instead of the ellipsoid. - * @type {Number} + * @type {number} * @default 150000.0 */ this.minimumPickingTerrainHeight = 150000.0; this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight; /** * The minimum height the camera must be before testing for collision with terrain. - * @type {Number} + * @type {number} * @default 15000.0 */ this.minimumCollisionTerrainHeight = 15000.0; @@ -233,14 +233,14 @@ function ScreenSpaceCameraController(scene) { /** * The minimum height the camera must be before switching from rotating a track ball to * free look when clicks originate on the sky or in space. - * @type {Number} + * @type {number} * @default 7500000.0 */ this.minimumTrackBallHeight = 7500000.0; this._minimumTrackBallHeight = this.minimumTrackBallHeight; /** * Enables or disables camera collision detection with terrain. - * @type {Boolean} + * @type {boolean} * @default true */ this.enableCollisionDetection = true; @@ -591,9 +591,9 @@ function handleZoom( return; } - const sameStartPosition = Cartesian2.equals( - startPosition, - object._zoomMouseStart + const sameStartPosition = defaultValue( + movement.inertiaEnabled, + Cartesian2.equals(startPosition, object._zoomMouseStart) ); let zoomingOnVector = object._zoomingOnVector; let rotatingZoom = object._rotatingZoom; @@ -2162,6 +2162,7 @@ function zoom3D(controller, startPosition, movement) { if (defined(movement.distance)) { movement = movement.distance; } + const inertiaMovement = movement.inertiaEnabled; const ellipsoid = controller._ellipsoid; const scene = controller._scene; @@ -2187,7 +2188,7 @@ function zoom3D(controller, startPosition, movement) { camera.position, zoom3DCartographic ).height; - if (height < controller._minimumPickingTerrainHeight) { + if (height < controller._minimumPickingTerrainHeight && !inertiaMovement) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); } @@ -2902,7 +2903,7 @@ ScreenSpaceCameraController.prototype.update = function () { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see ScreenSpaceCameraController#destroy */ diff --git a/packages/engine/Source/Scene/ShadowMap.js b/packages/engine/Source/Scene/ShadowMap.js index 966b274a896..3d8aaf1bd85 100644 --- a/packages/engine/Source/Scene/ShadowMap.js +++ b/packages/engine/Source/Scene/ShadowMap.js @@ -59,20 +59,20 @@ import ShadowMapShader from "./ShadowMapShader.js"; * @internalConstructor * @class * - * @privateParam {Object} options An object containing the following properties: + * @privateParam {object} options An object containing the following properties: * @privateParam {Context} options.context The context * @privateParam {Camera} options.lightCamera A camera representing the light source. - * @privateParam {Boolean} [options.enabled=true] Whether the shadow map is enabled. - * @privateParam {Boolean} [options.isPointLight=false] Whether the light source is a point light. Point light shadows do not use cascades. - * @privateParam {Number} [options.pointLightRadius=100.0] Radius of the point light. - * @privateParam {Boolean} [options.cascadesEnabled=true] Use multiple shadow maps to cover different partitions of the view frustum. - * @privateParam {Number} [options.numberOfCascades=4] The number of cascades to use for the shadow map. Supported values are one and four. - * @privateParam {Number} [options.maximumDistance=5000.0] The maximum distance used for generating cascaded shadows. Lower values improve shadow quality. - * @privateParam {Number} [options.size=2048] The width and height, in pixels, of each shadow map. - * @privateParam {Boolean} [options.softShadows=false] Whether percentage-closer-filtering is enabled for producing softer shadows. - * @privateParam {Number} [options.darkness=0.3] The shadow darkness. - * @privateParam {Boolean} [options.normalOffset=true] Whether a normal bias is applied to shadows. - * @privateParam {Boolean} [options.fadingEnabled=true] Whether shadows start to fade out once the light gets closer to the horizon. + * @privateParam {boolean} [options.enabled=true] Whether the shadow map is enabled. + * @privateParam {boolean} [options.isPointLight=false] Whether the light source is a point light. Point light shadows do not use cascades. + * @privateParam {number} [options.pointLightRadius=100.0] Radius of the point light. + * @privateParam {boolean} [options.cascadesEnabled=true] Use multiple shadow maps to cover different partitions of the view frustum. + * @privateParam {number} [options.numberOfCascades=4] The number of cascades to use for the shadow map. Supported values are one and four. + * @privateParam {number} [options.maximumDistance=5000.0] The maximum distance used for generating cascaded shadows. Lower values improve shadow quality. + * @privateParam {number} [options.size=2048] The width and height, in pixels, of each shadow map. + * @privateParam {boolean} [options.softShadows=false] Whether percentage-closer-filtering is enabled for producing softer shadows. + * @privateParam {number} [options.darkness=0.3] The shadow darkness. + * @privateParam {boolean} [options.normalOffset=true] Whether a normal bias is applied to shadows. + * @privateParam {boolean} [options.fadingEnabled=true] Whether shadows start to fade out once the light gets closer to the horizon. * * @exception {DeveloperError} Only one or four cascades are supported. * @@ -114,7 +114,7 @@ function ShadowMap(options) { /** * Determines the darkness of the shadows. * - * @type {Number} + * @type {number} * @default 0.3 */ this.darkness = defaultValue(options.darkness, 0.3); @@ -123,7 +123,7 @@ function ShadowMap(options) { /** * Determines whether shadows start to fade out once the light gets closer to the horizon. * - * @type {Boolean} + * @type {boolean} * @default true */ this.fadingEnabled = defaultValue(options.fadingEnabled, true); @@ -131,7 +131,7 @@ function ShadowMap(options) { /** * Determines the maximum distance of the shadow map. Only applicable for cascaded shadows. Larger distances may result in lower quality shadows. * - * @type {Number} + * @type {number} * @default 5000.0 */ this.maximumDistance = defaultValue(options.maximumDistance, 5000.0); @@ -355,7 +355,7 @@ Object.defineProperties(ShadowMap.prototype, { * Determines if the shadow map will be shown. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @default true */ enabled: { @@ -372,7 +372,7 @@ Object.defineProperties(ShadowMap.prototype, { * Determines if a normal bias will be applied to shadows. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @default true */ normalOffset: { @@ -392,7 +392,7 @@ Object.defineProperties(ShadowMap.prototype, { * Determines if soft shadows are enabled. Uses pcf filtering which requires more texture reads and may hurt performance. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @default false */ softShadows: { @@ -409,7 +409,7 @@ Object.defineProperties(ShadowMap.prototype, { * The width and height, in pixels, of each shadow map. * * @memberof ShadowMap.prototype - * @type {Number} + * @type {number} * @default 2048 */ size: { @@ -425,7 +425,7 @@ Object.defineProperties(ShadowMap.prototype, { * Whether the shadow map is out of view of the scene camera. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -467,7 +467,7 @@ Object.defineProperties(ShadowMap.prototype, { * Whether the light source is a point light. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @private */ @@ -481,7 +481,7 @@ Object.defineProperties(ShadowMap.prototype, { * Debug option for visualizing the cascades by color. * * @memberof ShadowMap.prototype - * @type {Boolean} + * @type {boolean} * @default false * @private */ diff --git a/packages/engine/Source/Scene/ShadowMode.js b/packages/engine/Source/Scene/ShadowMode.js index 031a15ba44a..df6e77ddce2 100644 --- a/packages/engine/Source/Scene/ShadowMode.js +++ b/packages/engine/Source/Scene/ShadowMode.js @@ -2,13 +2,13 @@ * Specifies whether the object casts or receives shadows from light sources when * shadows are enabled. * - * @enum {Number} + * @enum {number} */ const ShadowMode = { /** * The object does not cast or receive shadows. * - * @type {Number} + * @type {number} * @constant */ DISABLED: 0, @@ -16,7 +16,7 @@ const ShadowMode = { /** * The object casts and receives shadows. * - * @type {Number} + * @type {number} * @constant */ ENABLED: 1, @@ -24,7 +24,7 @@ const ShadowMode = { /** * The object casts shadows only. * - * @type {Number} + * @type {number} * @constant */ CAST_ONLY: 2, @@ -32,7 +32,7 @@ const ShadowMode = { /** * The object receives shadows only. * - * @type {Number} + * @type {number} * @constant */ RECEIVE_ONLY: 3, diff --git a/packages/engine/Source/Scene/ShadowVolumeAppearance.js b/packages/engine/Source/Scene/ShadowVolumeAppearance.js index 8a3186d24bf..1e6f0603486 100644 --- a/packages/engine/Source/Scene/ShadowVolumeAppearance.js +++ b/packages/engine/Source/Scene/ShadowVolumeAppearance.js @@ -18,8 +18,8 @@ import ShadowVolumeAppearanceFS from "../Shaders/ShadowVolumeAppearanceFS.js"; /** * Creates shaders for a ClassificationPrimitive to use a given Appearance, as well as for picking. * - * @param {Boolean} extentsCulling Discard fragments outside the instance's texture coordinate extents. - * @param {Boolean} planarExtents If true, texture coordinates will be computed using planes instead of spherical coordinates. + * @param {boolean} extentsCulling Discard fragments outside the instance's texture coordinate extents. + * @param {boolean} planarExtents If true, texture coordinates will be computed using planes instead of spherical coordinates. * @param {Appearance} appearance An Appearance to be used with a ClassificationPrimitive via GroundPrimitive. * @private */ @@ -73,7 +73,7 @@ function ShadowVolumeAppearance(extentsCulling, planarExtents, appearance) { /** * Create the fragment shader for a ClassificationPrimitive's color pass when rendering for color. * - * @param {Boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. + * @param {boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. * @returns {ShaderSource} Shader source for the fragment shader. */ ShadowVolumeAppearance.prototype.createFragmentShader = function ( @@ -175,11 +175,11 @@ ShadowVolumeAppearance.prototype.createPickFragmentShader = function ( /** * Create the vertex shader for a ClassificationPrimitive's color pass on the final of 3 shadow volume passes * - * @param {String[]} defines External defines to pass to the vertex shader. - * @param {String} vertexShaderSource ShadowVolumeAppearanceVS with any required modifications for computing position. - * @param {Boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. + * @param {string[]} defines External defines to pass to the vertex shader. + * @param {string} vertexShaderSource ShadowVolumeAppearanceVS with any required modifications for computing position. + * @param {boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. * @param {MapProjection} mapProjection Current scene's map projection. - * @returns {String} Shader source for the vertex shader. + * @returns {string} Shader source for the vertex shader. */ ShadowVolumeAppearance.prototype.createVertexShader = function ( defines, @@ -208,11 +208,11 @@ ShadowVolumeAppearance.prototype.createVertexShader = function ( /** * Create the vertex shader for a ClassificationPrimitive's pick pass on the final of 3 shadow volume passes * - * @param {String[]} defines External defines to pass to the vertex shader. - * @param {String} vertexShaderSource ShadowVolumeAppearanceVS with any required modifications for computing position and picking. - * @param {Boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. + * @param {string[]} defines External defines to pass to the vertex shader. + * @param {string} vertexShaderSource ShadowVolumeAppearanceVS with any required modifications for computing position and picking. + * @param {boolean} columbusView2D Whether the shader will be used for Columbus View or 2D. * @param {MapProjection} mapProjection Current scene's map projection. - * @returns {String} Shader source for the vertex shader. + * @returns {string} Shader source for the vertex shader. */ ShadowVolumeAppearance.prototype.createPickVertexShader = function ( defines, @@ -675,11 +675,11 @@ const encodeScratch = new EncodedCartesian3(); * @private * * @param {Rectangle} boundingRectangle Rectangle object that the points will approximately bound - * @param {Number[]} textureCoordinateRotationPoints Points in the computed texture coordinate system for remapping texture coordinates + * @param {number[]} textureCoordinateRotationPoints Points in the computed texture coordinate system for remapping texture coordinates * @param {Ellipsoid} ellipsoid Ellipsoid for converting Rectangle points to world coordinates * @param {MapProjection} projection The MapProjection used for 2D and Columbus View. - * @param {Number} [height=0] The maximum height for the shadow volume. - * @returns {Object} An attributes dictionary containing planar texture coordinate attributes. + * @param {number} [height=0] The maximum height for the shadow volume. + * @returns {object} An attributes dictionary containing planar texture coordinate attributes. */ ShadowVolumeAppearance.getPlanarTextureCoordinateAttributes = function ( boundingRectangle, @@ -793,10 +793,10 @@ const sphericalScratch = new Cartesian2(); * @private * * @param {Rectangle} boundingRectangle Rectangle object that the spherical extents will approximately bound - * @param {Number[]} textureCoordinateRotationPoints Points in the computed texture coordinate system for remapping texture coordinates + * @param {number[]} textureCoordinateRotationPoints Points in the computed texture coordinate system for remapping texture coordinates * @param {Ellipsoid} ellipsoid Ellipsoid for converting Rectangle points to world coordinates * @param {MapProjection} projection The MapProjection used for 2D and Columbus View. - * @returns {Object} An attributes dictionary containing spherical texture coordinate attributes. + * @returns {object} An attributes dictionary containing spherical texture coordinate attributes. */ ShadowVolumeAppearance.getSphericalExtentGeometryInstanceAttributes = function ( boundingRectangle, @@ -929,7 +929,7 @@ ShadowVolumeAppearance.shouldUseSphericalCoordinates = function (rectangle) { * Texture coordinates for ground primitives are computed either using spherical coordinates for large areas or * using distance from planes for small areas. * - * @type {Number} + * @type {number} * @constant * @private */ diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index d8d0b7eb6d1..ac7e013768f 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -11,13 +11,13 @@ import TileProviderError from "../Core/TileProviderError.js"; import ImageryProvider from "./ImageryProvider.js"; /** - * @typedef {Object} SingleTileImageryProvider.ConstructorOptions + * @typedef {object} SingleTileImageryProvider.ConstructorOptions * * Initialization options for the SingleTileImageryProvider constructor * - * @property {Resource|String} url The url for the tile. + * @property {Resource|string} url The url for the tile. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. */ @@ -51,7 +51,7 @@ function SingleTileImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -60,7 +60,7 @@ function SingleTileImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -69,7 +69,7 @@ function SingleTileImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -78,7 +78,7 @@ function SingleTileImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -87,7 +87,7 @@ function SingleTileImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -95,7 +95,7 @@ function SingleTileImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -104,7 +104,7 @@ function SingleTileImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -112,7 +112,7 @@ function SingleTileImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -201,7 +201,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { /** * Gets the URL of the single, top-level imagery tile. * @memberof SingleTileImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -226,7 +226,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link SingleTileImageryProvider#ready} returns true. * @memberof SingleTileImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -247,7 +247,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link SingleTileImageryProvider#ready} returns true. * @memberof SingleTileImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -268,7 +268,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link SingleTileImageryProvider#ready} returns true. * @memberof SingleTileImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -289,7 +289,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link SingleTileImageryProvider#ready} returns true. * @memberof SingleTileImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -380,7 +380,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof SingleTileImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -392,7 +392,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof SingleTileImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -421,7 +421,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof SingleTileImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -434,9 +434,9 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -449,11 +449,11 @@ SingleTileImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link SingleTileImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} The resolved image + * @returns {Promise<ImageryTypes>|undefined} The resolved image * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. */ @@ -482,11 +482,11 @@ SingleTileImageryProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ SingleTileImageryProvider.prototype.pickFeatures = function ( diff --git a/packages/engine/Source/Scene/SkyAtmosphere.js b/packages/engine/Source/Scene/SkyAtmosphere.js index bd761a9eb6e..11cccc5f23f 100644 --- a/packages/engine/Source/Scene/SkyAtmosphere.js +++ b/packages/engine/Source/Scene/SkyAtmosphere.js @@ -46,7 +46,7 @@ function SkyAtmosphere(ellipsoid) { /** * Determines if the atmosphere is shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = true; @@ -55,7 +55,7 @@ function SkyAtmosphere(ellipsoid) { * Compute atmosphere per-fragment instead of per-vertex. * This produces better looking atmosphere with a slight performance penalty. * - * @type {Boolean} + * @type {boolean} * @default false */ this.perFragmentAtmosphere = false; @@ -83,7 +83,7 @@ function SkyAtmosphere(ellipsoid) { /** * The intensity of the light that is used for computing the sky atmosphere color. * - * @type {Number} + * @type {number} * @default 50.0 */ this.atmosphereLightIntensity = 50.0; @@ -107,7 +107,7 @@ function SkyAtmosphere(ellipsoid) { /** * The Rayleigh scale height used in the atmospheric scattering equations for the sky atmosphere, in meters. * - * @type {Number} + * @type {number} * @default 10000.0 */ this.atmosphereRayleighScaleHeight = 10000.0; @@ -115,7 +115,7 @@ function SkyAtmosphere(ellipsoid) { /** * The Mie scale height used in the atmospheric scattering equations for the sky atmosphere, in meters. * - * @type {Number} + * @type {number} * @default 3200.0 */ this.atmosphereMieScaleHeight = 3200.0; @@ -125,7 +125,7 @@ function SkyAtmosphere(ellipsoid) { * <p> * Valid values are between -1.0 and 1.0. * </p> - * @type {Number} + * @type {number} * @default 0.9 */ this.atmosphereMieAnisotropy = 0.9; @@ -133,7 +133,7 @@ function SkyAtmosphere(ellipsoid) { /** * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A hue shift of 1.0 indicates a complete rotation of the hues available. - * @type {Number} + * @type {number} * @default 0.0 */ this.hueShift = 0.0; @@ -141,7 +141,7 @@ function SkyAtmosphere(ellipsoid) { /** * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A saturation shift of -1.0 is monochrome. - * @type {Number} + * @type {number} * @default 0.0 */ this.saturationShift = 0.0; @@ -149,7 +149,7 @@ function SkyAtmosphere(ellipsoid) { /** * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift). * A brightness shift of -1.0 is complete darkness, which will let space show through. - * @type {Number} + * @type {number} * @default 0.0 */ this.brightnessShift = 0.0; @@ -368,7 +368,7 @@ function hasColorCorrection(skyAtmosphere) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see SkyAtmosphere#destroy */ diff --git a/packages/engine/Source/Scene/SkyBox.js b/packages/engine/Source/Scene/SkyBox.js index 2af18ef25c3..99b1390b1c5 100644 --- a/packages/engine/Source/Scene/SkyBox.js +++ b/packages/engine/Source/Scene/SkyBox.js @@ -30,9 +30,9 @@ import SceneMode from "./SceneMode.js"; * @alias SkyBox * @constructor * - * @param {Object} options Object with the following properties: - * @param {Object} [options.sources] The source URL or <code>Image</code> object for each of the six cube map faces. See the example below. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {object} options Object with the following properties: + * @param {object} [options.sources] The source URL or <code>Image</code> object for each of the six cube map faces. See the example below. + * @param {boolean} [options.show=true] Determines if this primitive will be shown. * * * @example @@ -66,7 +66,7 @@ function SkyBox(options) { /** * Determines if the sky box will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -217,7 +217,7 @@ SkyBox.prototype.update = function (frameState, useHdr) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see SkyBox#destroy */ diff --git a/packages/engine/Source/Scene/SpatialNode.js b/packages/engine/Source/Scene/SpatialNode.js index cb284a4def6..d8659994fea 100644 --- a/packages/engine/Source/Scene/SpatialNode.js +++ b/packages/engine/Source/Scene/SpatialNode.js @@ -11,10 +11,10 @@ import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; * @alias SpatialNode * @constructor * - * @param {Number} level - * @param {Number} x - * @param {Number} y - * @param {Number} z + * @param {number} level + * @param {number} x + * @param {number} y + * @param {number} z * @param {SpatialNode} parent * @param {VoxelShapeType} shape * @param {Cartesian3} voxelDimensions @@ -68,7 +68,7 @@ function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { /** * @param {SpatialNode} a * @param {SpatialNode} b - * @returns {Boolean} + * @returns {boolean} */ SpatialNode.spatialComparator = function (a, b) { // The higher of the two screen space errors is prioritized @@ -104,8 +104,8 @@ SpatialNode.prototype.computeBoundingVolumes = function ( /** * @param {FrameState} frameState - * @param {Number} visibilityPlaneMask - * @returns {Number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. + * @param {number} visibilityPlaneMask + * @returns {number} A plane mask as described in {@link CullingVolume#computeVisibilityWithPlaneMask}. */ SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { const obb = this.orientedBoundingBox; @@ -115,7 +115,7 @@ SpatialNode.prototype.visibility = function (frameState, visibilityPlaneMask) { /** * @param {Cartesian3} cameraPosition - * @param {Number} screenSpaceErrorMultiplier + * @param {number} screenSpaceErrorMultiplier */ SpatialNode.prototype.computeScreenSpaceError = function ( cameraPosition, @@ -139,9 +139,9 @@ const scratchBinarySearchKeyframeNode = { /** * Find the index of a given key frame position within an array of KeyframeNodes, * or the complement (~) of the index where it would be in the sorted array. - * @param {Number} keyframe + * @param {number} keyframe * @param {KeyframeNode[]} keyframeNodes - * @returns {Number} + * @returns {number} * @private */ function findKeyframeIndex(keyframe, keyframeNodes) { @@ -156,7 +156,7 @@ function findKeyframeIndex(keyframe, keyframeNodes) { /** * Computes the most suitable keyframes for rendering, balancing between temporal and visual quality. * - * @param {Number} keyframeLocation + * @param {number} keyframeLocation */ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( keyframeLocation @@ -259,15 +259,15 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( }; /** - * @param {Number} frameNumber - * @returns {Boolean} + * @param {number} frameNumber + * @returns {boolean} */ SpatialNode.prototype.isVisited = function (frameNumber) { return this.visitedFrameNumber === frameNumber; }; /** - * @param {Number} keyframe + * @param {number} keyframe */ SpatialNode.prototype.createKeyframeNode = function (keyframe) { let index = findKeyframeIndex(keyframe, this.keyframeNodes); @@ -355,7 +355,7 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( }; /** - * @param {Number} frameNumber + * @param {number} frameNumber * @returns Boolean */ SpatialNode.prototype.isRenderable = function (frameNumber) { diff --git a/packages/engine/Source/Scene/SphereEmitter.js b/packages/engine/Source/Scene/SphereEmitter.js index a29d5fd8d69..4925d084722 100644 --- a/packages/engine/Source/Scene/SphereEmitter.js +++ b/packages/engine/Source/Scene/SphereEmitter.js @@ -10,7 +10,7 @@ import CesiumMath from "../Core/Math.js"; * @alias SphereEmitter * @constructor * - * @param {Number} [radius=1.0] The radius of the sphere in meters. + * @param {number} [radius=1.0] The radius of the sphere in meters. */ function SphereEmitter(radius) { radius = defaultValue(radius, 1.0); @@ -26,7 +26,7 @@ Object.defineProperties(SphereEmitter.prototype, { /** * The radius of the sphere in meters. * @memberof SphereEmitter.prototype - * @type {Number} + * @type {number} * @default 1.0 */ radius: { diff --git a/packages/engine/Source/Scene/SplitDirection.js b/packages/engine/Source/Scene/SplitDirection.js index ba53422f9a6..5d23aa289fb 100644 --- a/packages/engine/Source/Scene/SplitDirection.js +++ b/packages/engine/Source/Scene/SplitDirection.js @@ -1,7 +1,7 @@ /** * The direction to display a primitive or ImageryLayer relative to the {@link Scene#splitPosition}. * - * @enum {Number} + * @enum {number} * * @see ImageryLayer#splitDirection * @see Cesium3DTileset#splitDirection @@ -10,7 +10,7 @@ const SplitDirection = { /** * Display the primitive or ImageryLayer to the left of the {@link Scene#splitPosition}. * - * @type {Number} + * @type {number} * @constant */ LEFT: -1.0, @@ -18,7 +18,7 @@ const SplitDirection = { /** * Always display the primitive or ImageryLayer. * - * @type {Number} + * @type {number} * @constant */ NONE: 0.0, @@ -26,7 +26,7 @@ const SplitDirection = { /** * Display the primitive or ImageryLayer to the right of the {@link Scene#splitPosition}. * - * @type {Number} + * @type {number} * @constant */ RIGHT: 1.0, diff --git a/packages/engine/Source/Scene/Splitter.js b/packages/engine/Source/Scene/Splitter.js index 58dc51739e3..f27bd9d9bfb 100644 --- a/packages/engine/Source/Scene/Splitter.js +++ b/packages/engine/Source/Scene/Splitter.js @@ -36,8 +36,8 @@ const Splitter = { /** * Add `czm_splitDirection` to the given uniform map. * - * @param {Object} object The object on which the `splitDirection` property may be found. - * @param {Object} uniformMap The uniform map. + * @param {object} object The object on which the `splitDirection` property may be found. + * @param {object} uniformMap The uniform map. */ addUniforms: function addUniforms(object, uniformMap) { uniformMap.czm_splitDirection = function () { diff --git a/packages/engine/Source/Scene/StencilFunction.js b/packages/engine/Source/Scene/StencilFunction.js index b730bfc94ee..d7ac2c6d2fe 100644 --- a/packages/engine/Source/Scene/StencilFunction.js +++ b/packages/engine/Source/Scene/StencilFunction.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines the function used to compare stencil values for the stencil test. * - * @enum {Number} + * @enum {number} */ const StencilFunction = { /** * The stencil test never passes. * - * @type {Number} + * @type {number} * @constant */ NEVER: WebGLConstants.NEVER, @@ -17,7 +17,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is less than the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ LESS: WebGLConstants.LESS, @@ -25,7 +25,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is equal to the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ EQUAL: WebGLConstants.EQUAL, @@ -33,7 +33,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is less than or equal to the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ LESS_OR_EQUAL: WebGLConstants.LEQUAL, @@ -41,7 +41,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is greater than the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ GREATER: WebGLConstants.GREATER, @@ -49,7 +49,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is not equal to the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ NOT_EQUAL: WebGLConstants.NOTEQUAL, @@ -57,7 +57,7 @@ const StencilFunction = { /** * The stencil test passes when the masked reference value is greater than or equal to the masked stencil value. * - * @type {Number} + * @type {number} * @constant */ GREATER_OR_EQUAL: WebGLConstants.GEQUAL, @@ -65,7 +65,7 @@ const StencilFunction = { /** * The stencil test always passes. * - * @type {Number} + * @type {number} * @constant */ ALWAYS: WebGLConstants.ALWAYS, diff --git a/packages/engine/Source/Scene/StencilOperation.js b/packages/engine/Source/Scene/StencilOperation.js index 6f992c31b54..4781a9e53fa 100644 --- a/packages/engine/Source/Scene/StencilOperation.js +++ b/packages/engine/Source/Scene/StencilOperation.js @@ -3,13 +3,13 @@ import WebGLConstants from "../Core/WebGLConstants.js"; /** * Determines the action taken based on the result of the stencil test. * - * @enum {Number} + * @enum {number} */ const StencilOperation = { /** * Sets the stencil buffer value to zero. * - * @type {Number} + * @type {number} * @constant */ ZERO: WebGLConstants.ZERO, @@ -17,7 +17,7 @@ const StencilOperation = { /** * Does not change the stencil buffer. * - * @type {Number} + * @type {number} * @constant */ KEEP: WebGLConstants.KEEP, @@ -25,7 +25,7 @@ const StencilOperation = { /** * Replaces the stencil buffer value with the reference value. * - * @type {Number} + * @type {number} * @constant */ REPLACE: WebGLConstants.REPLACE, @@ -33,7 +33,7 @@ const StencilOperation = { /** * Increments the stencil buffer value, clamping to unsigned byte. * - * @type {Number} + * @type {number} * @constant */ INCREMENT: WebGLConstants.INCR, @@ -41,7 +41,7 @@ const StencilOperation = { /** * Decrements the stencil buffer value, clamping to zero. * - * @type {Number} + * @type {number} * @constant */ DECREMENT: WebGLConstants.DECR, @@ -49,7 +49,7 @@ const StencilOperation = { /** * Bitwise inverts the existing stencil buffer value. * - * @type {Number} + * @type {number} * @constant */ INVERT: WebGLConstants.INVERT, @@ -57,7 +57,7 @@ const StencilOperation = { /** * Increments the stencil buffer value, wrapping to zero when exceeding the unsigned byte range. * - * @type {Number} + * @type {number} * @constant */ INCREMENT_WRAP: WebGLConstants.INCR_WRAP, @@ -65,7 +65,7 @@ const StencilOperation = { /** * Decrements the stencil buffer value, wrapping to the maximum unsigned byte instead of going below zero. * - * @type {Number} + * @type {number} * @constant */ DECREMENT_WRAP: WebGLConstants.DECR_WRAP, diff --git a/packages/engine/Source/Scene/StructuralMetadata.js b/packages/engine/Source/Scene/StructuralMetadata.js index 04f108b99a0..a1aefacc943 100644 --- a/packages/engine/Source/Scene/StructuralMetadata.js +++ b/packages/engine/Source/Scene/StructuralMetadata.js @@ -9,14 +9,14 @@ import defined from "../Core/defined.js"; * previous {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {MetadataSchema} options.schema The parsed schema. * @param {PropertyTable[]} [options.propertyTables] An array of property table objects. For the legacy <code>EXT_feature_metadata</code> extension, this is sorted by the key in the propertyTables dictionary * @param {PropertyTexture[]} [options.propertyTextures] An array of property texture objects. For the legacy <code>EXT_feature_metadata</code> extension, this is sorted by the key in the propertyTextures dictionary * @param {PropertyAttribute[]} [options.propertyAttributes] An array of property attribute objects. This is new in <code>EXT_structural_metadata</code> - * @param {Object} [options.statistics] Statistics about metadata - * @param {Object} [options.extras] Extra user-defined properties - * @param {Object} [options.extensions] An object containing extensions + * @param {object} [options.statistics] Statistics about metadata + * @param {object} [options.extras] Extra user-defined properties + * @param {object} [options.extensions] An object containing extensions * * @alias StructuralMetadata * @constructor @@ -65,7 +65,7 @@ Object.defineProperties(StructuralMetadata.prototype, { * </p> * * @memberof StructuralMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -93,7 +93,7 @@ Object.defineProperties(StructuralMetadata.prototype, { * An object containing extensions. * * @memberof StructuralMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -107,7 +107,7 @@ Object.defineProperties(StructuralMetadata.prototype, { * Number of property tables in the metadata. * * @memberof StructuralMetadata.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -163,7 +163,7 @@ Object.defineProperties(StructuralMetadata.prototype, { * Total size in bytes across all property tables * * @memberof StructuralMetadata.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -191,7 +191,7 @@ Object.defineProperties(StructuralMetadata.prototype, { * by the key in the propertyTables dictionary. * </p> * - * @param {Number} propertyTableId The property table ID. + * @param {number} propertyTableId The property table ID. * @returns {PropertyTable} The property table. * @private */ @@ -210,7 +210,7 @@ StructuralMetadata.prototype.getPropertyTable = function (propertyTableId) { * by the key in the propertyTextures dictionary. * </p> * - * @param {Number} propertyTextureId The index into the property textures array. + * @param {number} propertyTextureId The index into the property textures array. * @returns {PropertyTexture} The property texture * @private */ @@ -226,7 +226,7 @@ StructuralMetadata.prototype.getPropertyTexture = function (propertyTextureId) { * Gets the property attribute with the given ID. This concept is new in * EXT_structural_metadata * - * @param {Number} propertyAttributeId The index into the property attributes array. + * @param {number} propertyAttributeId The index into the property attributes array. * @returns {PropertyAttribute} The property attribute * @private */ diff --git a/packages/engine/Source/Scene/StyleExpression.js b/packages/engine/Source/Scene/StyleExpression.js index c6baa386edb..10e49410f64 100644 --- a/packages/engine/Source/Scene/StyleExpression.js +++ b/packages/engine/Source/Scene/StyleExpression.js @@ -29,8 +29,8 @@ function StyleExpression() {} * a {@link Color}, the {@link Cartesian4} value is converted to a {@link Color} and then returned. * * @param {Cesium3DTileFeature} feature The feature whose properties may be used as variables in the expression. - * @param {Object} [result] The object onto which to store the result. - * @returns {Boolean|Number|String|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. + * @param {object} [result] The object onto which to store the result. + * @returns {boolean|number|string|RegExp|Cartesian2|Cartesian3|Cartesian4|Color} The result of evaluating the expression. */ StyleExpression.prototype.evaluate = function (feature, result) { DeveloperError.throwInstantiationError(); @@ -54,12 +54,12 @@ StyleExpression.prototype.evaluateColor = function (feature, result) { * Gets the shader function for this expression. * Returns undefined if the shader function can't be generated from this expression. * - * @param {String} functionSignature Signature of the generated function. - * @param {Object} variableSubstitutionMap Maps variable names to shader variable names. - * @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent. - * @param {String} returnType The return type of the generated function. + * @param {string} functionSignature Signature of the generated function. + * @param {object} variableSubstitutionMap Maps variable names to shader variable names. + * @param {object} shaderState Stores information about the generated shader function, including whether it is translucent. + * @param {string} returnType The return type of the generated function. * - * @returns {String} The shader function. + * @returns {string} The shader function. * * @private */ @@ -75,7 +75,7 @@ StyleExpression.prototype.getShaderFunction = function ( /** * Gets the variables used by the expression. * - * @returns {String[]} The variables used by the expression. + * @returns {string[]} The variables used by the expression. * * @private */ diff --git a/packages/engine/Source/Scene/Sun.js b/packages/engine/Source/Scene/Sun.js index 617c2cfd3dc..f109882c687 100644 --- a/packages/engine/Source/Scene/Sun.js +++ b/packages/engine/Source/Scene/Sun.js @@ -43,7 +43,7 @@ function Sun() { /** * Determines if the sun will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = true; @@ -89,7 +89,7 @@ Object.defineProperties(Sun.prototype, { * Use larger values for a more pronounced flare around the Sun. * * @memberof Sun.prototype - * @type {Number} + * @type {number} * @default 1.0 */ glowFactor: { @@ -322,7 +322,7 @@ Sun.prototype.update = function (frameState, passState, useHdr) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see Sun#destroy */ diff --git a/packages/engine/Source/Scene/SunLight.js b/packages/engine/Source/Scene/SunLight.js index f4d738238d4..a0441da2397 100644 --- a/packages/engine/Source/Scene/SunLight.js +++ b/packages/engine/Source/Scene/SunLight.js @@ -4,9 +4,9 @@ import defaultValue from "../Core/defaultValue.js"; /** * A directional light source that originates from the Sun. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Color} [options.color=Color.WHITE] The light's color. - * @param {Number} [options.intensity=2.0] The light's intensity. + * @param {number} [options.intensity=2.0] The light's intensity. * * @alias SunLight * @constructor @@ -22,7 +22,7 @@ function SunLight(options) { /** * The intensity of the light. - * @type {Number} + * @type {number} * @default 2.0 */ this.intensity = defaultValue(options.intensity, 2.0); diff --git a/packages/engine/Source/Scene/SupportedImageFormats.js b/packages/engine/Source/Scene/SupportedImageFormats.js index 60c7c3eefa6..f98a33e3201 100644 --- a/packages/engine/Source/Scene/SupportedImageFormats.js +++ b/packages/engine/Source/Scene/SupportedImageFormats.js @@ -3,9 +3,9 @@ import defaultValue from "../Core/defaultValue.js"; /** * Image formats supported by the browser. * - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.webp=false] Whether the browser supports WebP images. - * @param {Boolean} [options.basis=false] Whether the browser supports compressed textures required to view KTX2 + Basis Universal images. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.webp=false] Whether the browser supports WebP images. + * @param {boolean} [options.basis=false] Whether the browser supports compressed textures required to view KTX2 + Basis Universal images. * * @private */ diff --git a/packages/engine/Source/Scene/TextureAtlas.js b/packages/engine/Source/Scene/TextureAtlas.js index f55d4a3dca6..d53cf10b1ac 100644 --- a/packages/engine/Source/Scene/TextureAtlas.js +++ b/packages/engine/Source/Scene/TextureAtlas.js @@ -38,10 +38,10 @@ const defaultInitialSize = new Cartesian2(16.0, 16.0); * @alias TextureAtlas * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Scene} options.context The context in which the texture gets created. * @param {PixelFormat} [options.pixelFormat=PixelFormat.RGBA] The pixel format of the texture. - * @param {Number} [options.borderWidthInPixels=1] The amount of spacing between adjacent images in pixels. + * @param {number} [options.borderWidthInPixels=1] The amount of spacing between adjacent images in pixels. * @param {Cartesian2} [options.initialSize=new Cartesian2(16.0, 16.0)] The initial side lengths of the texture. * * @exception {DeveloperError} borderWidthInPixels must be greater than or equal to zero. @@ -84,7 +84,7 @@ Object.defineProperties(TextureAtlas.prototype, { /** * The amount of spacing between adjacent images in pixels. * @memberof TextureAtlas.prototype - * @type {Number} + * @type {number} */ borderWidthInPixels: { get: function () { @@ -130,7 +130,7 @@ Object.defineProperties(TextureAtlas.prototype, { * Texture coordinates are subject to change if the texture atlas resizes, so it is * important to check {@link TextureAtlas#getGUID} before using old values. * @memberof TextureAtlas.prototype - * @type {Number} + * @type {number} */ numberOfImages: { get: function () { @@ -144,7 +144,7 @@ Object.defineProperties(TextureAtlas.prototype, { * Classes that use a texture atlas should check if the GUID * has changed before processing the atlas data. * @memberof TextureAtlas.prototype - * @type {String} + * @type {string} */ guid: { get: function () { @@ -368,8 +368,8 @@ function getIndex(atlas, image) { /** * If the image is already in the atlas, the existing index is returned. Otherwise, the result is undefined. * - * @param {String} id An identifier to detect whether the image already exists in the atlas. - * @returns {Number|undefined} The image index, or undefined if the image does not exist in the atlas. + * @param {string} id An identifier to detect whether the image already exists in the atlas. + * @returns {number|undefined} The image index, or undefined if the image does not exist in the atlas. */ TextureAtlas.prototype.getImageIndex = function (id) { //>>includeStart('debug', pragmas.debug); @@ -385,9 +385,9 @@ TextureAtlas.prototype.getImageIndex = function (id) { * Adds an image to the atlas synchronously. If the image is already in the atlas, the atlas is unchanged and * the existing index is used. * - * @param {String} id An identifier to detect whether the image already exists in the atlas. + * @param {string} id An identifier to detect whether the image already exists in the atlas. * @param {HTMLImageElement|HTMLCanvasElement} image An image or canvas to add to the texture atlas. - * @returns {Number} The image index. + * @returns {number} The image index. */ TextureAtlas.prototype.addImageSync = function (id, image) { //>>includeStart('debug', pragmas.debug); @@ -417,10 +417,10 @@ TextureAtlas.prototype.addImageSync = function (id, image) { * Adds an image to the atlas. If the image is already in the atlas, the atlas is unchanged and * the existing index is used. * - * @param {String} id An identifier to detect whether the image already exists in the atlas. - * @param {HTMLImageElement|HTMLCanvasElement|String|Resource|Promise|TextureAtlas.CreateImageCallback} image An image or canvas to add to the texture atlas, + * @param {string} id An identifier to detect whether the image already exists in the atlas. + * @param {HTMLImageElement|HTMLCanvasElement|string|Resource|Promise|TextureAtlas.CreateImageCallback} image An image or canvas to add to the texture atlas, * or a URL to an Image, or a Promise for an image, or a function that creates an image. - * @returns {Promise.<Number>} A Promise for the image index. + * @returns {Promise<number>} A Promise for the image index. */ TextureAtlas.prototype.addImage = function (id, image) { //>>includeStart('debug', pragmas.debug); @@ -470,10 +470,10 @@ TextureAtlas.prototype.addImage = function (id, image) { /** * Add a sub-region of an existing atlas image as additional image indices. * - * @param {String} id The identifier of the existing image. + * @param {string} id The identifier of the existing image. * @param {BoundingRectangle} subRegion An {@link BoundingRectangle} sub-region measured in pixels from the bottom-left. * - * @returns {Promise.<Number>} A Promise for the image index. + * @returns {Promise<number>} A Promise for the image index. */ TextureAtlas.prototype.addSubRegion = function (id, subRegion) { //>>includeStart('debug', pragmas.debug); @@ -520,7 +520,7 @@ TextureAtlas.prototype.addSubRegion = function (id, subRegion) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see TextureAtlas#destroy */ @@ -552,7 +552,7 @@ TextureAtlas.prototype.destroy = function () { /** * A function that creates an image. * @callback TextureAtlas.CreateImageCallback - * @param {String} id The identifier of the image to load. + * @param {string} id The identifier of the image to load. * @returns {HTMLImageElement|Promise<HTMLImageElement>} The image, or a promise that will resolve to an image. */ export default TextureAtlas; diff --git a/packages/engine/Source/Scene/TileBoundingRegion.js b/packages/engine/Source/Scene/TileBoundingRegion.js index e43a8b4922c..733907695de 100644 --- a/packages/engine/Source/Scene/TileBoundingRegion.js +++ b/packages/engine/Source/Scene/TileBoundingRegion.js @@ -23,12 +23,12 @@ import SceneMode from "./SceneMode.js"; * @alias TileBoundingRegion * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Rectangle} options.rectangle The rectangle specifying the longitude and latitude range of the region. - * @param {Number} [options.minimumHeight=0.0] The minimum height of the region. - * @param {Number} [options.maximumHeight=0.0] The maximum height of the region. + * @param {number} [options.minimumHeight=0.0] The minimum height of the region. + * @param {number} [options.maximumHeight=0.0] The maximum height of the region. * @param {Ellipsoid} [options.ellipsoid=Cesium.Ellipsoid.WGS84] The ellipsoid. - * @param {Boolean} [options.computeBoundingVolumes=true] True to compute the {@link TileBoundingRegion#boundingVolume} and + * @param {boolean} [options.computeBoundingVolumes=true] True to compute the {@link TileBoundingRegion#boundingVolume} and * {@link TileBoundingVolume#boundingSphere}. If false, these properties will be undefined. * * @private @@ -116,7 +116,7 @@ Object.defineProperties(TileBoundingRegion.prototype, { * * @memberof TileBoundingRegion.prototype * - * @type {Object} + * @type {object} * @readonly */ boundingVolume: { @@ -414,7 +414,7 @@ function distanceToCameraRegion(tileBB, frameState) { * Gets the distance from the camera to the closest point on the tile. This is used for level of detail selection. * * @param {FrameState} frameState The state information of the current rendering frame. - * @returns {Number} The distance from the camera to the closest point on the tile, in meters. + * @returns {number} The distance from the camera to the closest point on the tile, in meters. */ TileBoundingRegion.prototype.distanceToCamera = function (frameState) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/TileBoundingS2Cell.js b/packages/engine/Source/Scene/TileBoundingS2Cell.js index 479d81e9fa1..872529473f4 100644 --- a/packages/engine/Source/Scene/TileBoundingS2Cell.js +++ b/packages/engine/Source/Scene/TileBoundingS2Cell.js @@ -23,12 +23,12 @@ let centerCartographicScratch = new Cartographic(); * @alias TileBoundingS2Cell * @constructor * - * @param {Object} options Object with the following properties: - * @param {String} options.token The token of the S2 cell. - * @param {Number} [options.minimumHeight=0.0] The minimum height of the bounding volume. - * @param {Number} [options.maximumHeight=0.0] The maximum height of the bounding volume. + * @param {object} options Object with the following properties: + * @param {string} options.token The token of the S2 cell. + * @param {number} [options.minimumHeight=0.0] The minimum height of the bounding volume. + * @param {number} [options.maximumHeight=0.0] The maximum height of the bounding volume. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid. - * @param {Boolean} [options.computeBoundingVolumes=true] True to compute the {@link TileBoundingS2Cell#boundingVolume} and + * @param {boolean} [options.computeBoundingVolumes=true] True to compute the {@link TileBoundingS2Cell#boundingVolume} and * {@link TileBoundingS2Cell#boundingSphere}. If false, these properties will be undefined. * * @private @@ -332,7 +332,7 @@ Object.defineProperties(TileBoundingS2Cell.prototype, { * * @memberof TileOrientedBoundingBox.prototype * - * @type {Object} + * @type {object} * @readonly */ boundingVolume: { diff --git a/packages/engine/Source/Scene/TileBoundingSphere.js b/packages/engine/Source/Scene/TileBoundingSphere.js index d623061f37c..3e517c1a1fa 100644 --- a/packages/engine/Source/Scene/TileBoundingSphere.js +++ b/packages/engine/Source/Scene/TileBoundingSphere.js @@ -15,7 +15,7 @@ import Primitive from "./Primitive.js"; * @constructor * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the bounding sphere. - * @param {Number} [radius=0.0] The radius of the bounding sphere. + * @param {number} [radius=0.0] The radius of the bounding sphere. * * @private */ @@ -46,7 +46,7 @@ Object.defineProperties(TileBoundingSphere.prototype, { * * @memberof TileBoundingSphere.prototype * - * @type {Number} + * @type {number} * @readonly */ radius: { @@ -60,7 +60,7 @@ Object.defineProperties(TileBoundingSphere.prototype, { * * @memberof TileBoundingSphere.prototype * - * @type {Object} + * @type {object} * @readonly */ boundingVolume: { @@ -87,7 +87,7 @@ Object.defineProperties(TileBoundingSphere.prototype, { * Computes the distance between this bounding sphere and the camera attached to frameState. * * @param {FrameState} frameState The frameState to which the camera is attached. - * @returns {Number} The distance between the camera and the bounding sphere in meters. Returns 0 if the camera is inside the bounding volume. + * @returns {number} The distance between the camera and the bounding sphere in meters. Returns 0 if the camera is inside the bounding volume. * */ TileBoundingSphere.prototype.distanceToCamera = function (frameState) { @@ -122,7 +122,7 @@ TileBoundingSphere.prototype.intersectPlane = function (plane) { * Update the bounding sphere after the tile is transformed. * * @param {Cartesian3} center The center of the bounding sphere. - * @param {Number} radius The radius of the bounding sphere. + * @param {number} radius The radius of the bounding sphere. */ TileBoundingSphere.prototype.update = function (center, radius) { Cartesian3.clone(center, this._boundingSphere.center); diff --git a/packages/engine/Source/Scene/TileBoundingVolume.js b/packages/engine/Source/Scene/TileBoundingVolume.js index 06d655078a8..f7c027edc16 100644 --- a/packages/engine/Source/Scene/TileBoundingVolume.js +++ b/packages/engine/Source/Scene/TileBoundingVolume.js @@ -18,7 +18,7 @@ function TileBoundingVolume() {} /** * The underlying bounding volume. * - * @type {Object} + * @type {object} * @readonly */ TileBoundingVolume.prototype.boundingVolume = undefined; @@ -35,7 +35,7 @@ TileBoundingVolume.prototype.boundingSphere = undefined; * Calculates the distance between the tile and the camera. * * @param {FrameState} frameState The frame state. - * @return {Number} The distance between the tile and the camera, in meters. + * @return {number} The distance between the tile and the camera, in meters. * Returns 0.0 if the camera is inside the tile. */ TileBoundingVolume.prototype.distanceToCamera = function (frameState) { diff --git a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js index 4618a09d96b..f514050bfeb 100644 --- a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js +++ b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js @@ -5,7 +5,7 @@ import Event from "../Core/Event.js"; import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; /** - * @typedef {Object} TileCoordinatesImageryProvider.ConstructorOptions + * @typedef {object} TileCoordinatesImageryProvider.ConstructorOptions * * Initialization options for the TileCoordinatesImageryProvider constructor * @@ -14,8 +14,8 @@ import GeographicTilingScheme from "../Core/GeographicTilingScheme.js"; * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. * @property {Color} [color=Color.YELLOW] The color to draw the tile box and label. - * @property {Number} [tileWidth=256] The width of the tile for level-of-detail selection purposes. - * @property {Number} [tileHeight=256] The height of the tile for level-of-detail selection purposes. + * @property {number} [tileWidth=256] The width of the tile for level-of-detail selection purposes. + * @property {number} [tileHeight=256] The height of the tile for level-of-detail selection purposes. */ /** @@ -44,7 +44,7 @@ function TileCoordinatesImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -53,7 +53,7 @@ function TileCoordinatesImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -62,7 +62,7 @@ function TileCoordinatesImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -71,7 +71,7 @@ function TileCoordinatesImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -80,7 +80,7 @@ function TileCoordinatesImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -88,7 +88,7 @@ function TileCoordinatesImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -97,7 +97,7 @@ function TileCoordinatesImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -105,7 +105,7 @@ function TileCoordinatesImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -144,7 +144,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -157,7 +157,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -170,7 +170,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -183,7 +183,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -250,7 +250,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -262,7 +262,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -291,7 +291,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. Setting this property to false reduces memory usage * and texture upload time. * @memberof TileCoordinatesImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -304,9 +304,9 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -323,11 +323,11 @@ TileCoordinatesImageryProvider.prototype.getTileCredits = function ( * Requests the image for a given tile. This function should * not be called before {@link TileCoordinatesImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<HTMLCanvasElement>} The resolved image as a Canvas DOM object. + * @returns {Promise<HTMLCanvasElement>} The resolved image as a Canvas DOM object. */ TileCoordinatesImageryProvider.prototype.requestImage = function ( x, @@ -360,11 +360,11 @@ TileCoordinatesImageryProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ TileCoordinatesImageryProvider.prototype.pickFeatures = function ( diff --git a/packages/engine/Source/Scene/TileDiscardPolicy.js b/packages/engine/Source/Scene/TileDiscardPolicy.js index 1977b881fca..b07424eb0b3 100644 --- a/packages/engine/Source/Scene/TileDiscardPolicy.js +++ b/packages/engine/Source/Scene/TileDiscardPolicy.js @@ -18,7 +18,7 @@ function TileDiscardPolicy(options) { * Determines if the discard policy is ready to process images. * @function * - * @returns {Boolean} True if the discard policy is ready to process images; otherwise, false. + * @returns {boolean} True if the discard policy is ready to process images; otherwise, false. */ TileDiscardPolicy.prototype.isReady = DeveloperError.throwInstantiationError; @@ -27,7 +27,7 @@ TileDiscardPolicy.prototype.isReady = DeveloperError.throwInstantiationError; * @function * * @param {HTMLImageElement} image An image to test. - * @returns {Boolean} True if the image should be discarded; otherwise, false. + * @returns {boolean} True if the image should be discarded; otherwise, false. */ TileDiscardPolicy.prototype.shouldDiscardImage = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/Scene/TileImagery.js b/packages/engine/Source/Scene/TileImagery.js index 8070126ebb7..5032408bdc3 100644 --- a/packages/engine/Source/Scene/TileImagery.js +++ b/packages/engine/Source/Scene/TileImagery.js @@ -10,7 +10,7 @@ import ImageryState from "./ImageryState.js"; * @param {Imagery} imagery The imagery tile. * @param {Cartesian4} textureCoordinateRectangle The texture rectangle of the tile that is covered * by the imagery, where X=west, Y=south, Z=east, W=north. - * @param {Boolean} useWebMercatorT true to use the Web Mercator texture coordinates for this imagery tile. + * @param {boolean} useWebMercatorT true to use the Web Mercator texture coordinates for this imagery tile. */ function TileImagery(imagery, textureCoordinateRectangle, useWebMercatorT) { this.readyImagery = undefined; @@ -38,10 +38,10 @@ TileImagery.prototype.freeResources = function () { * * @param {Tile} tile The tile to which this instance belongs. * @param {FrameState} frameState The frameState. - * @param {Boolean} skipLoading True to skip loading, e.g. new requests, creating textures. This function will + * @param {boolean} skipLoading True to skip loading, e.g. new requests, creating textures. This function will * still synchronously process imagery that's already mostly ready to go, e.g. use textures * already loaded on ancestor tiles. - * @returns {Boolean} True if this instance is done loading; otherwise, false. + * @returns {boolean} True if this instance is done loading; otherwise, false. */ TileImagery.prototype.processStateMachine = function ( tile, diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index 8054dd12933..320f8a9521a 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -14,17 +14,17 @@ import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js"; import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; /** - * @typedef {Object} TileMapServiceImageryProvider.ConstructorOptions + * @typedef {object} TileMapServiceImageryProvider.ConstructorOptions * * Initialization options for the TileMapServiceImageryProvider constructor * - * @property {Resource|String|Promise<Resource>|Promise<String>} [url='.'] Path to image tiles on server. - * @property {String} [fileExtension='png'] The file extension for images on the server. - * @property {Credit|String} [credit=''] A credit for the data source, which is displayed on the canvas. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * @property {Resource|string|Promise<Resource>|Promise<string>} [url='.'] Path to image tiles on server. + * @property {string} [fileExtension='png'] The file extension for images on the server. + * @property {Credit|string} [credit=''] A credit for the data source, which is displayed on the canvas. + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely * to result in rendering problems. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. * @property {TilingScheme} [tilingScheme] The tiling scheme specifying how the ellipsoidal * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} @@ -32,9 +32,9 @@ import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js"; * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @property {Number} [tileWidth=256] Pixel width of image tiles. - * @property {Number} [tileHeight=256] Pixel height of image tiles. - * @property {Boolean} [flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml. + * @property {number} [tileWidth=256] Pixel width of image tiles. + * @property {number} [tileHeight=256] Pixel height of image tiles. + * @property {boolean} [flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml. * Specifying this option will do the same, allowing for loading of these incorrect tilesets. */ diff --git a/packages/engine/Source/Scene/TileMetadata.js b/packages/engine/Source/Scene/TileMetadata.js index d960c638ac7..c2a62d9643d 100644 --- a/packages/engine/Source/Scene/TileMetadata.js +++ b/packages/engine/Source/Scene/TileMetadata.js @@ -9,8 +9,8 @@ import MetadataEntity from "./MetadataEntity.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.tile Either the tile metadata JSON (3D Tiles 1.1), or the extension JSON attached to the tile. + * @param {object} options Object with the following properties: + * @param {object} options.tile Either the tile metadata JSON (3D Tiles 1.1), or the extension JSON attached to the tile. * @param {MetadataClass} options.class The class that the tile metadata conforms to. * * @alias TileMetadata @@ -53,7 +53,7 @@ Object.defineProperties(TileMetadata.prototype, { * Extra user-defined properties. * * @memberof TileMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -67,7 +67,7 @@ Object.defineProperties(TileMetadata.prototype, { * An object containing extensions. * * @memberof TileMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -81,8 +81,8 @@ Object.defineProperties(TileMetadata.prototype, { /** * Returns whether the tile has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the tile has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the tile has this property. * @private */ TileMetadata.prototype.hasProperty = function (propertyId) { @@ -92,8 +92,8 @@ TileMetadata.prototype.hasProperty = function (propertyId) { /** * Returns whether the tile has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the tile has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the tile has a property with the given semantic. * @private */ TileMetadata.prototype.hasPropertyBySemantic = function (semantic) { @@ -107,8 +107,8 @@ TileMetadata.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {string[]} The property IDs. * @private */ TileMetadata.prototype.getPropertyIds = function (results) { @@ -121,7 +121,7 @@ TileMetadata.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the tile does not have this property. * @private */ @@ -135,9 +135,9 @@ TileMetadata.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ TileMetadata.prototype.setProperty = function (propertyId, value) { @@ -152,7 +152,7 @@ TileMetadata.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the tile does not have this semantic. * @private */ @@ -167,9 +167,9 @@ TileMetadata.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ TileMetadata.prototype.setPropertyBySemantic = function (semantic, value) { diff --git a/packages/engine/Source/Scene/TileOrientedBoundingBox.js b/packages/engine/Source/Scene/TileOrientedBoundingBox.js index 35d9d85fc2b..9737474a500 100644 --- a/packages/engine/Source/Scene/TileOrientedBoundingBox.js +++ b/packages/engine/Source/Scene/TileOrientedBoundingBox.js @@ -106,7 +106,7 @@ Object.defineProperties(TileOrientedBoundingBox.prototype, { * * @memberof TileOrientedBoundingBox.prototype * - * @type {Object} + * @type {object} * @readonly */ boundingVolume: { @@ -133,7 +133,7 @@ Object.defineProperties(TileOrientedBoundingBox.prototype, { * Computes the distance between this bounding box and the camera attached to frameState. * * @param {FrameState} frameState The frameState to which the camera is attached. - * @returns {Number} The distance between the camera and the bounding box in meters. Returns 0 if the camera is inside the bounding volume. + * @returns {number} The distance between the camera and the bounding box in meters. Returns 0 if the camera is inside the bounding volume. */ TileOrientedBoundingBox.prototype.distanceToCamera = function (frameState) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/TileReplacementQueue.js b/packages/engine/Source/Scene/TileReplacementQueue.js index fe4695b793a..1d0ccc73c88 100644 --- a/packages/engine/Source/Scene/TileReplacementQueue.js +++ b/packages/engine/Source/Scene/TileReplacementQueue.js @@ -27,7 +27,7 @@ TileReplacementQueue.prototype.markStartOfRenderFrame = function () { * tiles. Tiles that were used last frame will not be unloaded, even if that puts the number * of tiles above the specified maximum. * - * @param {Number} maximumTiles The maximum number of tiles in the queue. + * @param {number} maximumTiles The maximum number of tiles in the queue. */ TileReplacementQueue.prototype.trimTiles = function (maximumTiles) { let tileToTrim = this.tail; diff --git a/packages/engine/Source/Scene/TileSelectionResult.js b/packages/engine/Source/Scene/TileSelectionResult.js index f263c9e3f65..3f9525f9c15 100644 --- a/packages/engine/Source/Scene/TileSelectionResult.js +++ b/packages/engine/Source/Scene/TileSelectionResult.js @@ -52,7 +52,7 @@ const TileSelectionResult = { * or <code>REFINED_AND_KICKED</code>. * * @param {TileSelectionResult} value The selection result to test. - * @returns {Boolean} true if the tile was kicked, no matter if it was originally rendered or refined. + * @returns {boolean} true if the tile was kicked, no matter if it was originally rendered or refined. */ wasKicked: function (value) { return value >= TileSelectionResult.RENDERED_AND_KICKED; diff --git a/packages/engine/Source/Scene/TilesetMetadata.js b/packages/engine/Source/Scene/TilesetMetadata.js index 229da5fc13c..ef79ef3ec36 100644 --- a/packages/engine/Source/Scene/TilesetMetadata.js +++ b/packages/engine/Source/Scene/TilesetMetadata.js @@ -9,8 +9,8 @@ import MetadataEntity from "./MetadataEntity.js"; * See the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension} for 3D Tiles * </p> * - * @param {Object} options Object with the following properties: - * @param {Object} options.tileset The tileset metadata JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.tileset The tileset metadata JSON object. * @param {MetadataClass} options.class The class that tileset metadata conforms to. * * @alias TilesetMetadata @@ -69,7 +69,7 @@ Object.defineProperties(TilesetMetadata.prototype, { * An object containing extensions. * * @memberof TilesetMetadata.prototype - * @type {Object} + * @type {object} * @readonly * @private */ @@ -83,8 +83,8 @@ Object.defineProperties(TilesetMetadata.prototype, { /** * Returns whether the tileset has this property. * - * @param {String} propertyId The case-sensitive ID of the property. - * @returns {Boolean} Whether the tileset has this property. + * @param {string} propertyId The case-sensitive ID of the property. + * @returns {boolean} Whether the tileset has this property. * @private */ TilesetMetadata.prototype.hasProperty = function (propertyId) { @@ -94,8 +94,8 @@ TilesetMetadata.prototype.hasProperty = function (propertyId) { /** * Returns whether the tileset has a property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. - * @returns {Boolean} Whether the tileset has a property with the given semantic. + * @param {string} semantic The case-sensitive semantic of the property. + * @returns {boolean} Whether the tileset has a property with the given semantic. * @private */ TilesetMetadata.prototype.hasPropertyBySemantic = function (semantic) { @@ -109,8 +109,8 @@ TilesetMetadata.prototype.hasPropertyBySemantic = function (semantic) { /** * Returns an array of property IDs. * - * @param {String[]} [results] An array into which to store the results. - * @returns {String[]} The property IDs. + * @param {string[]} [results] An array into which to store the results. + * @returns {string[]} The property IDs. * @private */ TilesetMetadata.prototype.getPropertyIds = function (results) { @@ -123,7 +123,7 @@ TilesetMetadata.prototype.getPropertyIds = function (results) { * If the property is normalized the normalized value is returned. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @returns {*} The value of the property or <code>undefined</code> if the tileset does not have this property. * @private */ @@ -137,9 +137,9 @@ TilesetMetadata.prototype.getProperty = function (propertyId) { * If the property is normalized a normalized value must be provided to this function. * </p> * - * @param {String} propertyId The case-sensitive ID of the property. + * @param {string} propertyId The case-sensitive ID of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ TilesetMetadata.prototype.setProperty = function (propertyId, value) { @@ -154,7 +154,7 @@ TilesetMetadata.prototype.setProperty = function (propertyId, value) { /** * Returns a copy of the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @returns {*} The value of the property or <code>undefined</code> if the tileset does not have this semantic. * @private */ @@ -169,9 +169,9 @@ TilesetMetadata.prototype.getPropertyBySemantic = function (semantic) { /** * Sets the value of the property with the given semantic. * - * @param {String} semantic The case-sensitive semantic of the property. + * @param {string} semantic The case-sensitive semantic of the property. * @param {*} value The value of the property that will be copied. - * @returns {Boolean} <code>true</code> if the property was set, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if the property was set, <code>false</code> otherwise. * @private */ TilesetMetadata.prototype.setPropertyBySemantic = function (semantic, value) { diff --git a/packages/engine/Source/Scene/TimeDynamicImagery.js b/packages/engine/Source/Scene/TimeDynamicImagery.js index 45788ed4874..8a12e8902b7 100644 --- a/packages/engine/Source/Scene/TimeDynamicImagery.js +++ b/packages/engine/Source/Scene/TimeDynamicImagery.js @@ -12,7 +12,7 @@ import RequestType from "../Core/RequestType.js"; * @alias TimeDynamicImagery * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Clock} options.clock A Clock instance that is used when determining the value for the time dimension. Required when <code>options.times</code> is specified. * @param {TimeIntervalCollection} options.times TimeIntervalCollection with its <code>data</code> property being an object containing time dynamic dimension and their values. * @param {Function} options.requestImageFunction A function that will request imagery tiles. @@ -106,12 +106,12 @@ Object.defineProperties(TimeDynamicImagery.prototype, { /** * Gets the tile from the cache if its available. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. * - * @returns {Promise.<HTMLImageElement>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<HTMLImageElement>|undefined} A promise for the image that will resolve when the image is available, or * undefined if the tile is not in the cache. */ TimeDynamicImagery.prototype.getFromCache = function (x, y, level, request) { @@ -135,9 +135,9 @@ TimeDynamicImagery.prototype.getFromCache = function (x, y, level, request) { * Checks if the next interval is approaching and will start preload the tile if necessary. Otherwise it will * just add the tile to a list to preload when we approach the next interval. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. */ TimeDynamicImagery.prototype.checkApproachingInterval = function ( diff --git a/packages/engine/Source/Scene/TimeDynamicPointCloud.js b/packages/engine/Source/Scene/TimeDynamicPointCloud.js index 4a8a0269ee7..04b3f77cab5 100644 --- a/packages/engine/Source/Scene/TimeDynamicPointCloud.js +++ b/packages/engine/Source/Scene/TimeDynamicPointCloud.js @@ -27,14 +27,14 @@ import ShadowMode from "./ShadowMode.js"; * @alias TimeDynamicPointCloud * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Clock} options.clock A {@link Clock} instance that is used when determining the value for the time dimension. * @param {TimeIntervalCollection} options.intervals A {@link TimeIntervalCollection} with its data property being an object containing a <code>uri</code> to a 3D Tiles Point Cloud tile and an optional <code>transform</code>. - * @param {Boolean} [options.show=true] Determines if the point cloud will be shown. + * @param {boolean} [options.show=true] Determines if the point cloud will be shown. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the point cloud. * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the point cloud casts or receives shadows from light sources. - * @param {Number} [options.maximumMemoryUsage=256] The maximum amount of memory in MB that can be used by the point cloud. - * @param {Object} [options.shading] Options for constructing a {@link PointCloudShading} object to control point attenuation and eye dome lighting. + * @param {number} [options.maximumMemoryUsage=256] The maximum amount of memory in MB that can be used by the point cloud. + * @param {object} [options.shading] Options for constructing a {@link PointCloudShading} object to control point attenuation and eye dome lighting. * @param {Cesium3DTileStyle} [options.style] The style, defined using the {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling|3D Tiles Styling language}, applied to each point in the point cloud. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the point cloud. */ @@ -49,7 +49,7 @@ function TimeDynamicPointCloud(options) { /** * Determines if the point cloud will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); @@ -87,7 +87,7 @@ function TimeDynamicPointCloud(options) { * If decreasing this value results in unloading tiles, the tiles are unloaded the next frame. * </p> * - * @type {Number} + * @type {number} * @default 256 * * @see TimeDynamicPointCloud#totalMemoryUsageInBytes @@ -217,7 +217,7 @@ Object.defineProperties(TimeDynamicPointCloud.prototype, { * * @memberof TimeDynamicPointCloud.prototype * - * @type {Number} + * @type {number} * @readonly * * @see TimeDynamicPointCloud#maximumMemoryUsage @@ -250,7 +250,7 @@ Object.defineProperties(TimeDynamicPointCloud.prototype, { * * @memberof TimeDynamicPointCloud.prototype * - * @type {Promise.<TimeDynamicPointCloud>} + * @type {Promise<TimeDynamicPointCloud>} * @readonly */ readyPromise: { @@ -787,7 +787,7 @@ TimeDynamicPointCloud.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see TimeDynamicPointCloud#destroy */ diff --git a/packages/engine/Source/Scene/Tonemapper.js b/packages/engine/Source/Scene/Tonemapper.js index 2bd6812ca0a..b799e43ee7b 100644 --- a/packages/engine/Source/Scene/Tonemapper.js +++ b/packages/engine/Source/Scene/Tonemapper.js @@ -1,14 +1,14 @@ /** * A tonemapping algorithm when rendering with high dynamic range. * - * @enum {Number} + * @enum {number} * @private */ const Tonemapper = { /** * Use the Reinhard tonemapping operator. * - * @type {Number} + * @type {number} * @constant */ REINHARD: 0, @@ -16,7 +16,7 @@ const Tonemapper = { /** * Use the modified Reinhard tonemapping operator. * - * @type {Number} + * @type {number} * @constant */ MODIFIED_REINHARD: 1, @@ -24,7 +24,7 @@ const Tonemapper = { /** * Use the Filmic tonemapping operator. * - * @type {Number} + * @type {number} * @constant */ FILMIC: 2, @@ -32,7 +32,7 @@ const Tonemapper = { /** * Use the ACES tonemapping operator. * - * @type {Number} + * @type {number} * @constant */ ACES: 3, diff --git a/packages/engine/Source/Scene/TranslucentTileClassification.js b/packages/engine/Source/Scene/TranslucentTileClassification.js index 4b36673d889..b171fe76adf 100644 --- a/packages/engine/Source/Scene/TranslucentTileClassification.js +++ b/packages/engine/Source/Scene/TranslucentTileClassification.js @@ -76,7 +76,7 @@ Object.defineProperties(TranslucentTileClassification.prototype, { * Gets whether or not translucent depth was rendered. * @memberof TranslucentTileClassification.prototype * - * @type {Boolean} + * @type {boolean} * @readonly */ hasTranslucentDepth: { diff --git a/packages/engine/Source/Scene/TweenCollection.js b/packages/engine/Source/Scene/TweenCollection.js index c5ee6cf394f..e49bad844f5 100644 --- a/packages/engine/Source/Scene/TweenCollection.js +++ b/packages/engine/Source/Scene/TweenCollection.js @@ -60,7 +60,7 @@ Object.defineProperties(Tween.prototype, { * An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. * @memberof Tween.prototype * - * @type {Object} + * @type {object} * @readonly */ startObject: { @@ -73,7 +73,7 @@ Object.defineProperties(Tween.prototype, { * An object with properties for the final values of the tween. * @memberof Tween.prototype * - * @type {Object} + * @type {object} * @readonly */ stopObject: { @@ -86,7 +86,7 @@ Object.defineProperties(Tween.prototype, { * The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. * @memberof Tween.prototype * - * @type {Number} + * @type {number} * @readonly */ duration: { @@ -99,7 +99,7 @@ Object.defineProperties(Tween.prototype, { * The delay, in seconds, before the tween starts animating. * @memberof Tween.prototype * - * @type {Number} + * @type {number} * @readonly */ delay: { @@ -184,7 +184,7 @@ Object.defineProperties(TweenCollection.prototype, { * The number of tweens in the collection. * @memberof TweenCollection.prototype * - * @type {Number} + * @type {number} * @readonly */ length: { @@ -198,11 +198,11 @@ Object.defineProperties(TweenCollection.prototype, { * Creates a tween for animating between two sets of properties. The tween starts animating at the next call to {@link TweenCollection#update}, which * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. * - * @param {Object} [options] Object with the following properties: - * @param {Object} options.startObject An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. - * @param {Object} options.stopObject An object with properties for the final values of the tween. - * @param {Number} options.duration The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {object} [options] Object with the following properties: + * @param {object} options.startObject An object with properties for initial values of the tween. The properties of this object are changed during the tween's animation. + * @param {object} options.stopObject An object with properties for the final values of the tween. + * @param {number} options.duration The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. @@ -276,13 +276,13 @@ TweenCollection.prototype.add = function (options) { * Creates a tween for animating a scalar property on the given object. The tween starts animating at the next call to {@link TweenCollection#update}, which * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. * - * @param {Object} [options] Object with the following properties: - * @param {Object} options.object The object containing the property to animate. - * @param {String} options.property The name of the property to animate. - * @param {Number} options.startValue The initial value. - * @param {Number} options.stopValue The final value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {object} [options] Object with the following properties: + * @param {object} options.object The object containing the property to animate. + * @param {string} options.property The name of the property to animate. + * @param {number} options.startValue The initial value. + * @param {number} options.stopValue The final value. + * @param {number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. @@ -343,12 +343,12 @@ TweenCollection.prototype.addProperty = function (options) { * Creates a tween for animating the alpha of all color uniforms on a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Material} options.material The material to animate. - * @param {Number} [options.startValue=0.0] The initial alpha value. - * @param {Number} [options.stopValue=1.0] The final alpha value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {number} [options.startValue=0.0] The initial alpha value. + * @param {number} [options.stopValue=1.0] The final alpha value. + * @param {number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating. @@ -416,12 +416,12 @@ TweenCollection.prototype.addAlpha = function (options) { * Creates a tween for animating the offset uniform of a {@link Material}. The tween starts animating at the next call to {@link TweenCollection#update}, which * is implicit when {@link Viewer} or {@link CesiumWidget} render the scene. * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Material} options.material The material to animate. - * @param {Number} options.startValue The initial alpha value. - * @param {Number} options.stopValue The final alpha value. - * @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. - * @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. + * @param {number} options.startValue The initial alpha value. + * @param {number} options.stopValue The final alpha value. + * @param {number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops. + * @param {number} [options.delay=0.0] The delay, in seconds, before the tween starts animating. * @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion. * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame). * @param {TweenCollection.TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection. @@ -466,7 +466,7 @@ TweenCollection.prototype.addOffsetIncrement = function (options) { * </p> * * @param {Tween} tween The tween to remove. - * @returns {Boolean} <code>true</code> if the tween was removed; <code>false</code> if the tween was not found in the collection. + * @returns {boolean} <code>true</code> if the tween was removed; <code>false</code> if the tween was not found in the collection. */ TweenCollection.prototype.remove = function (tween) { if (!defined(tween)) { @@ -509,7 +509,7 @@ TweenCollection.prototype.removeAll = function () { * Determines whether this collection contains a given tween. * * @param {Tween} tween The tween to check for. - * @returns {Boolean} <code>true</code> if this collection contains the tween, <code>false</code> otherwise. + * @returns {boolean} <code>true</code> if this collection contains the tween, <code>false</code> otherwise. */ TweenCollection.prototype.contains = function (tween) { return defined(tween) && this._tweens.indexOf(tween) !== -1; @@ -521,7 +521,7 @@ TweenCollection.prototype.contains = function (tween) { * it to the left, changing their indices. This function is commonly used to iterate over * all the tween in the collection. * - * @param {Number} index The zero-based index of the tween. + * @param {number} index The zero-based index of the tween. * @returns {Tween} The tween at the specified index. * * @example @@ -546,7 +546,7 @@ TweenCollection.prototype.get = function (index) { * Updates the tweens in the collection to be at the provide time. When a tween finishes, it is removed * from the collection. * - * @param {Number} [time=getTimestamp()] The time in seconds. By default tweens are synced to the system clock. + * @param {number} [time=getTimestamp()] The time in seconds. By default tweens are synced to the system clock. */ TweenCollection.prototype.update = function (time) { const tweens = this._tweens; diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index a6aa08654ee..ddf0490a626 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -49,12 +49,12 @@ const pickFeaturesTags = combine(tags, { }); /** - * @typedef {Object} UrlTemplateImageryProvider.ConstructorOptions + * @typedef {object} UrlTemplateImageryProvider.ConstructorOptions * * Initialization options for the UrlTemplateImageryProvider constructor * - * @property {Promise.<Object>|Object} [options] Object with the following properties: - * @property {Resource|String} url The URL template to use to request tiles. It has the following keywords: + * @property {Promise<object>|Object} [options] Object with the following properties: + * @property {Resource|string} url The URL template to use to request tiles. It has the following keywords: * <ul> * <li><code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> * <li><code>{x}</code>: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.</li> @@ -74,7 +74,7 @@ const pickFeaturesTags = combine(tags, { * <li><code>{width}</code>: The width of each tile in pixels.</li> * <li><code>{height}</code>: The height of each tile in pixels.</li> * </ul> - * @property {Resource|String} [pickFeaturesUrl] The URL template to use to pick features. If this property is not specified, + * @property {Resource|string} [pickFeaturesUrl] The URL template to use to pick features. If this property is not specified, * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no * features picked. The URL template supports all of the keywords supported by the <code>url</code> * parameter, plus the following: @@ -89,7 +89,7 @@ const pickFeaturesTags = combine(tags, { * <li><code>{latitudeProjected}</code>: The latitude of the picked position in the projected coordinates of the tiling scheme.</li> * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> * </ul> - * @property {Object} [urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where + * @property {object} [urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where * each coordinate will be padded on the left with zeros to match the width of the passed string of zeros. e.g. Setting: * urlSchemeZeroPadding : { '{x}' : '0000'} * will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL. @@ -102,14 +102,14 @@ const pickFeaturesTags = combine(tags, { * <li> <code>{reverseY}</code>: The zero padding for the tile reverseY coordinate in the tiling scheme.</li> * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> * </ul> - * @property {String|String[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * @property {string|string[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. * If this parameter is a single string, each character in the string is a subdomain. If it is * an array, each element in the array is a subdomain. - * @property {Credit|String} [credit=''] A credit for the data source, which is displayed on the canvas. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying + * @property {Credit|string} [credit=''] A credit for the data source, which is displayed on the canvas. + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying * this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely * to result in rendering problems. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. * @property {TilingScheme} [tilingScheme=WebMercatorTilingScheme] The tiling scheme specifying how the ellipsoidal * surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme} @@ -117,9 +117,9 @@ const pickFeaturesTags = combine(tags, { * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @property {Number} [tileWidth=256] Pixel width of image tiles. - * @property {Number} [tileHeight=256] Pixel height of image tiles. - * @property {Boolean} [hasAlphaChannel=true] true if the images provided by this imagery provider + * @property {number} [tileWidth=256] Pixel width of image tiles. + * @property {number} [tileHeight=256] Pixel height of image tiles. + * @property {boolean} [hasAlphaChannel=true] true if the images provided by this imagery provider * include an alpha channel; otherwise, false. If this property is false, an alpha channel, if * present, will be ignored. If this property is true, any images without an alpha channel will * be treated as if their alpha is 1.0 everywhere. When this property is false, memory usage @@ -127,14 +127,14 @@ const pickFeaturesTags = combine(tags, { * @property {GetFeatureInfoFormat[]} [getFeatureInfoFormats] The formats in which to get feature information at a * specific location when {@link UrlTemplateImageryProvider#pickFeatures} is invoked. If this * parameter is not specified, feature picking is disabled. - * @property {Boolean} [enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will + * @property {boolean} [enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will * request the <code>pickFeaturesUrl</code> and attempt to interpret the features included in the response. If false, * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable * features) without communicating with the server. Set this property to false if you know your data * source does not support picking features or if you don't want this provider's features to be pickable. Note * that this can be dynamically overridden by modifying the {@link UriTemplateImageryProvider#enablePickFeatures} * property. - * @property {Object} [customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values. + * @property {object} [customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values. */ /** @@ -219,7 +219,7 @@ function UrlTemplateImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -228,7 +228,7 @@ function UrlTemplateImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -237,7 +237,7 @@ function UrlTemplateImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -246,7 +246,7 @@ function UrlTemplateImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -255,7 +255,7 @@ function UrlTemplateImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -263,7 +263,7 @@ function UrlTemplateImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -272,7 +272,7 @@ function UrlTemplateImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -280,7 +280,7 @@ function UrlTemplateImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -307,7 +307,7 @@ function UrlTemplateImageryProvider(options) { * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable * features) without communicating with the server. Set this property to false if you know your data * source does not support picking features or if you don't want this provider's features to be pickable. - * @type {Boolean} + * @type {boolean} * @default true */ this.enablePickFeatures = true; @@ -338,7 +338,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * <li> <code>{height}</code>: The height of each tile in pixels.</li> * </ul> * @memberof UrlTemplateImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -362,7 +362,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * <li> <code>{reverseZ}</code>: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.</li> * </ul> * @memberof UrlTemplateImageryProvider.prototype - * @type {Object} + * @type {object} * @readonly */ urlSchemeZeroPadding: { @@ -388,7 +388,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * <li><code>{format}</code>: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.</li> * </ul> * @memberof UrlTemplateImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ pickFeaturesUrl: { @@ -414,7 +414,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link UrlTemplateImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly * @default 256 */ @@ -435,7 +435,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link UrlTemplateImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly * @default 256 */ @@ -456,7 +456,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested, or undefined if there is no limit. * This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly * @default undefined */ @@ -477,7 +477,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link UrlTemplateImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly * @default 0 */ @@ -576,7 +576,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof UrlTemplateImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -588,7 +588,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof UrlTemplateImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -626,7 +626,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * and texture upload time are reduced. This function should * not be called before {@link ImageryProvider#ready} returns true. * @memberof UrlTemplateImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly * @default true */ @@ -648,7 +648,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Reinitializes this instance. Reinitializing an instance already in use is supported, but it is not * recommended because existing tiles provided by the imagery provider will not be updated. * - * @param {Promise.<Object>|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. + * @param {Promise<object>|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. */ UrlTemplateImageryProvider.prototype.reinitialize = function (options) { const that = this; @@ -726,9 +726,9 @@ UrlTemplateImageryProvider.prototype.reinitialize = function (options) { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -748,11 +748,11 @@ UrlTemplateImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link UrlTemplateImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. */ UrlTemplateImageryProvider.prototype.requestImage = function ( @@ -778,12 +778,12 @@ UrlTemplateImageryProvider.prototype.requestImage = function ( * Asynchronously determines what features, if any, are located at a given longitude and latitude within * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * It may also be undefined if picking is not supported. diff --git a/packages/engine/Source/Scene/Vector3DTileBatch.js b/packages/engine/Source/Scene/Vector3DTileBatch.js index a2c5950c5c5..121dfdc2fc0 100644 --- a/packages/engine/Source/Scene/Vector3DTileBatch.js +++ b/packages/engine/Source/Scene/Vector3DTileBatch.js @@ -4,23 +4,23 @@ * @alias Vector3DTileBatch * @constructor * - * @param {Object} options An object with the following properties: - * @param {Number} options.offset The offset of the batch into the indices buffer. - * @param {Number} options.count The number of indices in the batch. + * @param {object} options An object with the following properties: + * @param {number} options.offset The offset of the batch into the indices buffer. + * @param {number} options.count The number of indices in the batch. * @param {Color} options.color The color of the geometry in the batch. - * @param {Number[]} options.batchIds An array where each element is the batch id of the geometry in the batch. + * @param {number[]} options.batchIds An array where each element is the batch id of the geometry in the batch. * * @private */ function Vector3DTileBatch(options) { /** * The offset of the batch into the indices buffer. - * @type {Number} + * @type {number} */ this.offset = options.offset; /** * The number of indices in the batch. - * @type {Number} + * @type {number} */ this.count = options.count; /** @@ -30,7 +30,7 @@ function Vector3DTileBatch(options) { this.color = options.color; /** * An array where each element is the batch id of the geometry in the batch. - * @type {Number[]} + * @type {number[]} */ this.batchIds = options.batchIds; } diff --git a/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js b/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js index 30daa9d0acf..143b934892b 100644 --- a/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js +++ b/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js @@ -39,18 +39,18 @@ import Vector3DTilePolylines from "./Vector3DTilePolylines.js"; * @alias Vector3DTileClampedPolylines * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Uint16Array} options.positions The positions of the polylines * @param {Uint32Array} options.counts The number or positions in the each polyline. * @param {Uint16Array} options.widths The width of each polyline. - * @param {Number} options.minimumHeight The minimum height of the tile's region. - * @param {Number} options.maximumHeight The maximum height of the tile's region. + * @param {number} options.minimumHeight The minimum height of the tile's region. + * @param {number} options.maximumHeight The maximum height of the tile's region. * @param {Rectangle} options.rectangle The rectangle containing the tile. * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center. * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polylines. * @param {Uint16Array} options.batchIds The batch ids for each polyline. * @param {ClassificationType} options.classificationType The classification type. - * @param {Boolean} options.keepDecodedPositions Whether to keep decoded positions in memory. + * @param {boolean} options.keepDecodedPositions Whether to keep decoded positions in memory. * * @private */ @@ -123,7 +123,7 @@ Object.defineProperties(Vector3DTileClampedPolylines.prototype, { * * @memberof Vector3DTileClampedPolylines.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -137,7 +137,7 @@ Object.defineProperties(Vector3DTileClampedPolylines.prototype, { * * @memberof Vector3DTileClampedPolylines.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -610,7 +610,7 @@ function queueCommands(primitive, frameState) { /** * Get the polyline positions for the given feature. * - * @param {Number} batchId The batch ID of the feature. + * @param {number} batchId The batch ID of the feature. */ Vector3DTileClampedPolylines.prototype.getPositions = function (batchId) { return Vector3DTilePolylines.getPolylinePositions(this, batchId); @@ -637,7 +637,7 @@ Vector3DTileClampedPolylines.prototype.createFeatures = function ( /** * Colors the entire tile when enabled is true. The resulting color will be (polyline batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTileClampedPolylines.prototype.applyDebugSettings = function ( @@ -747,7 +747,7 @@ Vector3DTileClampedPolylines.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTileClampedPolylines.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/Vector3DTileGeometry.js b/packages/engine/Source/Scene/Vector3DTileGeometry.js index e54412d2dfc..4e4c9be5da8 100644 --- a/packages/engine/Source/Scene/Vector3DTileGeometry.js +++ b/packages/engine/Source/Scene/Vector3DTileGeometry.js @@ -16,7 +16,7 @@ import Vector3DTilePrimitive from "./Vector3DTilePrimitive.js"; * @alias Vector3DTileGeometry * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Float32Array} [options.boxes] The boxes in the tile. * @param {Uint16Array} [options.boxBatchIds] The batch ids for each box. * @param {Float32Array} [options.cylinders] The cylinders in the tile. @@ -80,14 +80,14 @@ function Vector3DTileGeometry(options) { /** * Draws the wireframe of the classification geometries. - * @type {Boolean} + * @type {boolean} * @default false */ this.debugWireframe = false; /** * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. - * @type {Boolean} + * @type {boolean} * @default false */ this.forceRebatch = false; @@ -106,7 +106,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { * * @memberof Vector3DTileGeometry.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -123,7 +123,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { * * @memberof Vector3DTileGeometry.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -393,7 +393,7 @@ Vector3DTileGeometry.prototype.createFeatures = function (content, features) { /** * Colors the entire tile when enabled is true. The resulting color will be (geometry batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTileGeometry.prototype.applyDebugSettings = function (enabled, color) { @@ -414,7 +414,7 @@ Vector3DTileGeometry.prototype.applyStyle = function (style, features) { * Call when updating the color of a geometry with batchId changes color. The geometries will need to be re-batched * on the next update. * - * @param {Number} batchId The batch id of the geometries whose color has changed. + * @param {number} batchId The batch id of the geometries whose color has changed. * @param {Color} color The new polygon color. */ Vector3DTileGeometry.prototype.updateCommands = function (batchId, color) { @@ -466,7 +466,7 @@ Vector3DTileGeometry.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTileGeometry.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/Vector3DTilePoints.js b/packages/engine/Source/Scene/Vector3DTilePoints.js index 35e61689ffb..d083bc81625 100644 --- a/packages/engine/Source/Scene/Vector3DTilePoints.js +++ b/packages/engine/Source/Scene/Vector3DTilePoints.js @@ -22,10 +22,10 @@ import VerticalOrigin from "./VerticalOrigin.js"; * @alias Vector3DTilePoints * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Uint16Array} options.positions The positions of the polygons. - * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. - * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {number} options.maximumHeight The maximum height of the terrain covered by the tile. * @param {Rectangle} options.rectangle The rectangle containing the tile. * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polygons. * @param {Uint16Array} options.batchIds The batch ids for each polygon. @@ -66,7 +66,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, { * * @memberof Vector3DTilePoints.prototype * - * @type {Number} + * @type {number} * @readonly */ pointsLength: { @@ -80,7 +80,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, { * * @memberof Vector3DTilePoints.prototype * - * @type {Number} + * @type {number} * @readonly */ texturesByteLength: { @@ -227,7 +227,7 @@ Vector3DTilePoints.prototype.createFeatures = function (content, features) { /** * Colors the entire tile when enabled is true. The resulting color will be (batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTilePoints.prototype.applyDebugSettings = function (enabled, color) { @@ -500,7 +500,7 @@ Vector3DTilePoints.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTilePoints.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/Vector3DTilePolygons.js b/packages/engine/Source/Scene/Vector3DTilePolygons.js index 17048f564f1..835ae4cd186 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolygons.js +++ b/packages/engine/Source/Scene/Vector3DTilePolygons.js @@ -18,7 +18,7 @@ import Vector3DTilePrimitive from "./Vector3DTilePrimitive.js"; * @alias Vector3DTilePolygons * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Float32Array|Uint16Array} options.positions The positions of the polygons. The positions must be contiguous * so that the positions for polygon n are in [c, c + counts[n]] where c = sum{counts[0], counts[n - 1]} and they are the outer ring of * the polygon in counter-clockwise order. @@ -26,8 +26,8 @@ import Vector3DTilePrimitive from "./Vector3DTilePrimitive.js"; * @param {Uint32Array} options.indices The indices of the triangulated polygons. The indices must be contiguous so that * the indices for polygon n are in [i, i + indexCounts[n]] where i = sum{indexCounts[0], indexCounts[n - 1]}. * @param {Uint32Array} options.indexCounts The number of indices for each polygon. - * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. - * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {number} options.maximumHeight The maximum height of the terrain covered by the tile. * @param {Float32Array} [options.polygonMinimumHeights] An array containing the minimum heights for each polygon. * @param {Float32Array} [options.polygonMaximumHeights] An array containing the maximum heights for each polygon. * @param {Rectangle} options.rectangle The rectangle containing the tile. @@ -83,14 +83,14 @@ function Vector3DTilePolygons(options) { /** * Draws the wireframe of the classification meshes. - * @type {Boolean} + * @type {boolean} * @default false */ this.debugWireframe = false; /** * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. - * @type {Boolean} + * @type {boolean} * @default false */ this.forceRebatch = false; @@ -109,7 +109,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { * * @memberof Vector3DTilePolygons.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -126,7 +126,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { * * @memberof Vector3DTilePolygons.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -383,7 +383,7 @@ Vector3DTilePolygons.prototype.createFeatures = function (content, features) { /** * Colors the entire tile when enabled is true. The resulting color will be (polygon batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTilePolygons.prototype.applyDebugSettings = function (enabled, color) { @@ -404,7 +404,7 @@ Vector3DTilePolygons.prototype.applyStyle = function (style, features) { * Call when updating the color of a polygon with batchId changes color. The polygons will need to be re-batched * on the next update. * - * @param {Number} batchId The batch id of the polygon whose color has changed. + * @param {number} batchId The batch id of the polygon whose color has changed. * @param {Color} color The new polygon color. */ Vector3DTilePolygons.prototype.updateCommands = function (batchId, color) { @@ -455,7 +455,7 @@ Vector3DTilePolygons.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTilePolygons.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/Vector3DTilePolylines.js b/packages/engine/Source/Scene/Vector3DTilePolylines.js index d3f5f61c5f4..e9dd0268fbc 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolylines.js +++ b/packages/engine/Source/Scene/Vector3DTilePolylines.js @@ -29,18 +29,18 @@ import Cesium3DTileFeature from "./Cesium3DTileFeature.js"; * @alias Vector3DTilePolylines * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Uint16Array} options.positions The positions of the polylines * @param {Uint32Array} options.counts The number or positions in the each polyline. * @param {Uint16Array} options.widths The width of each polyline. - * @param {Number} options.minimumHeight The minimum height of the terrain covered by the tile. - * @param {Number} options.maximumHeight The maximum height of the terrain covered by the tile. + * @param {number} options.minimumHeight The minimum height of the terrain covered by the tile. + * @param {number} options.maximumHeight The maximum height of the terrain covered by the tile. * @param {Rectangle} options.rectangle The rectangle containing the tile. * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center. * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polylines. * @param {Uint16Array} options.batchIds The batch ids for each polyline. * @param {BoundingSphere} options.boundingVolume The bounding volume for the entire batch of polylines. - * @param {Boolean} options.keepDecodedPositions Whether to keep decoded positions in memory. + * @param {boolean} options.keepDecodedPositions Whether to keep decoded positions in memory. * * @private */ @@ -99,7 +99,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { * * @memberof Vector3DTilePolylines.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -113,7 +113,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { * * @memberof Vector3DTilePolylines.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -528,7 +528,7 @@ Vector3DTilePolylines.getPolylinePositions = function (polylines, batchId) { /** * Get the polyline positions for the given feature. * - * @param {Number} batchId The batch ID of the feature. + * @param {number} batchId The batch ID of the feature. */ Vector3DTilePolylines.prototype.getPositions = function (batchId) { return Vector3DTilePolylines.getPolylinePositions(this, batchId); @@ -552,7 +552,7 @@ Vector3DTilePolylines.prototype.createFeatures = function (content, features) { /** * Colors the entire tile when enabled is true. The resulting color will be (polyline batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTilePolylines.prototype.applyDebugSettings = function (enabled, color) { @@ -651,7 +651,7 @@ Vector3DTilePolylines.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTilePolylines.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/Vector3DTilePrimitive.js b/packages/engine/Source/Scene/Vector3DTilePrimitive.js index e3cbba091ea..5ae75ea11d2 100644 --- a/packages/engine/Source/Scene/Vector3DTilePrimitive.js +++ b/packages/engine/Source/Scene/Vector3DTilePrimitive.js @@ -33,7 +33,7 @@ import Vector3DTileBatch from "./Vector3DTileBatch.js"; * @alias Vector3DTilePrimitive * @constructor * - * @param {Object} options An object with following properties: + * @param {object} options An object with following properties: * @param {Float32Array} options.positions The positions of the meshes. * @param {Uint16Array|Uint32Array} options.indices The indices of the triangulated meshes. The indices must be contiguous so that * the indices for mesh n are in [i, i + indexCounts[n]] where i = sum{indexCounts[0], indexCounts[n - 1]}. @@ -108,7 +108,7 @@ function Vector3DTilePrimitive(options) { /** * Draw the wireframe of the classification meshes. - * @type {Boolean} + * @type {boolean} * @default false */ this.debugWireframe = false; @@ -117,7 +117,7 @@ function Vector3DTilePrimitive(options) { /** * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only. - * @type {Boolean} + * @type {boolean} * @default false */ this.forceRebatch = false; @@ -156,7 +156,7 @@ Object.defineProperties(Vector3DTilePrimitive.prototype, { * * @memberof Vector3DTilePrimitive.prototype * - * @type {Number} + * @type {number} * @readonly */ trianglesLength: { @@ -170,7 +170,7 @@ Object.defineProperties(Vector3DTilePrimitive.prototype, { * * @memberof Vector3DTilePrimitive.prototype * - * @type {Number} + * @type {number} * @readonly */ geometryByteLength: { @@ -962,7 +962,7 @@ Vector3DTilePrimitive.prototype.createFeatures = function (content, features) { /** * Colors the entire tile when enabled is true. The resulting color will be (mesh batch table color * color). * - * @param {Boolean} enabled Whether to enable debug coloring. + * @param {boolean} enabled Whether to enable debug coloring. * @param {Color} color The debug color. */ Vector3DTilePrimitive.prototype.applyDebugSettings = function (enabled, color) { @@ -1053,7 +1053,7 @@ Vector3DTilePrimitive.prototype.applyStyle = function (style, features) { * Call when updating the color of a mesh with batchId changes color. The meshes will need to be re-batched * on the next update. * - * @param {Number} batchId The batch id of the meshes whose color has changed. + * @param {number} batchId The batch id of the meshes whose color has changed. * @param {Color} color The new polygon color. */ Vector3DTilePrimitive.prototype.updateCommands = function (batchId, color) { @@ -1255,7 +1255,7 @@ Vector3DTilePrimitive.prototype.update = function (frameState) { * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * </p> * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. */ Vector3DTilePrimitive.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Scene/VertexAttributeSemantic.js b/packages/engine/Source/Scene/VertexAttributeSemantic.js index 5bbe7ab69ce..c168997fca2 100644 --- a/packages/engine/Source/Scene/VertexAttributeSemantic.js +++ b/packages/engine/Source/Scene/VertexAttributeSemantic.js @@ -5,7 +5,7 @@ import DeveloperError from "../Core/DeveloperError.js"; /** * An enum describing the built-in vertex attribute semantics. * - * @enum {String} + * @enum {string} * * @private */ @@ -13,7 +13,7 @@ const VertexAttributeSemantic = { /** * Per-vertex position. * - * @type {String} + * @type {string} * @constant */ POSITION: "POSITION", @@ -21,7 +21,7 @@ const VertexAttributeSemantic = { /** * Per-vertex normal. * - * @type {String} + * @type {string} * @constant */ NORMAL: "NORMAL", @@ -29,7 +29,7 @@ const VertexAttributeSemantic = { /** * Per-vertex tangent. * - * @type {String} + * @type {string} * @constant */ TANGENT: "TANGENT", @@ -37,7 +37,7 @@ const VertexAttributeSemantic = { /** * Per-vertex texture coordinates. * - * @type {String} + * @type {string} * @constant */ TEXCOORD: "TEXCOORD", @@ -45,7 +45,7 @@ const VertexAttributeSemantic = { /** * Per-vertex color. * - * @type {String} + * @type {string} * @constant */ COLOR: "COLOR", @@ -53,7 +53,7 @@ const VertexAttributeSemantic = { /** * Per-vertex joint IDs for skinning. * - * @type {String} + * @type {string} * @constant */ JOINTS: "JOINTS", @@ -61,7 +61,7 @@ const VertexAttributeSemantic = { /** * Per-vertex joint weights for skinning. * - * @type {String} + * @type {string} * @constant */ WEIGHTS: "WEIGHTS", @@ -69,7 +69,7 @@ const VertexAttributeSemantic = { /** * Per-vertex feature ID. * - * @type {String} + * @type {string} * @constant */ FEATURE_ID: "_FEATURE_ID", @@ -105,7 +105,7 @@ function semanticToVariableName(semantic) { * * @param {VertexAttributeSemantic} semantic The semantic. * - * @returns {Boolean} Whether the semantic can have a set index. + * @returns {boolean} Whether the semantic can have a set index. * * @private */ @@ -135,7 +135,7 @@ VertexAttributeSemantic.hasSetIndex = function (semantic) { /** * Gets the vertex attribute semantic matching the glTF semantic. * - * @param {String} gltfSemantic The glTF semantic. + * @param {string} gltfSemantic The glTF semantic. * * @returns {VertexAttributeSemantic|undefined} The vertex attribute semantic, or undefined if there is no match. * @@ -180,7 +180,7 @@ VertexAttributeSemantic.fromGltfSemantic = function (gltfSemantic) { /** * Gets the vertex attribute semantic matching the pnts semantic. * - * @param {String} pntsSemantic The pnts semantic. + * @param {string} pntsSemantic The pnts semantic. * * @returns {VertexAttributeSemantic|undefined} The vertex attribute semantic, or undefined if there is no match. * @@ -217,7 +217,7 @@ VertexAttributeSemantic.fromPntsSemantic = function (pntsSemantic) { * * @param {VertexAttributeSemantic} semantic The semantic. * - * @returns {String} The shader type. + * @returns {string} The shader type. * * @private */ @@ -252,9 +252,9 @@ VertexAttributeSemantic.getGlslType = function (semantic) { * Gets the variable name for the given semantic and set index. * * @param {VertexAttributeSemantic} semantic The semantic. - * @param {Number} [setIndex] The set index. + * @param {number} [setIndex] The set index. * - * @returns {String} The variable name. + * @returns {string} The variable name. * * @private */ diff --git a/packages/engine/Source/Scene/VerticalOrigin.js b/packages/engine/Source/Scene/VerticalOrigin.js index a87b28449c6..40764831bc4 100644 --- a/packages/engine/Source/Scene/VerticalOrigin.js +++ b/packages/engine/Source/Scene/VerticalOrigin.js @@ -8,7 +8,7 @@ * <img src='Images/Billboard.setVerticalOrigin.png' width='695' height='175' /><br /> * </div> * - * @enum {Number} + * @enum {number} * * @see Billboard#verticalOrigin * @see Label#verticalOrigin @@ -17,7 +17,7 @@ const VerticalOrigin = { /** * The origin is at the vertical center between <code>BASELINE</code> and <code>TOP</code>. * - * @type {Number} + * @type {number} * @constant */ CENTER: 0, @@ -25,7 +25,7 @@ const VerticalOrigin = { /** * The origin is at the bottom of the object. * - * @type {Number} + * @type {number} * @constant */ BOTTOM: 1, @@ -33,7 +33,7 @@ const VerticalOrigin = { /** * If the object contains text, the origin is at the baseline of the text, else the origin is at the bottom of the object. * - * @type {Number} + * @type {number} * @constant */ BASELINE: 2, @@ -41,7 +41,7 @@ const VerticalOrigin = { /** * The origin is at the top of the object. * - * @type {Number} + * @type {number} * @constant */ TOP: -1, diff --git a/packages/engine/Source/Scene/ViewportQuad.js b/packages/engine/Source/Scene/ViewportQuad.js index cd25c663e37..4d63acdde23 100644 --- a/packages/engine/Source/Scene/ViewportQuad.js +++ b/packages/engine/Source/Scene/ViewportQuad.js @@ -27,7 +27,7 @@ function ViewportQuad(rectangle, material) { /** * Determines if the viewport quad primitive will be shown. * - * @type {Boolean} + * @type {boolean} * @default true */ this.show = true; @@ -147,7 +147,7 @@ ViewportQuad.prototype.update = function (frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} True if this object was destroyed; otherwise, false. + * @returns {boolean} True if this object was destroyed; otherwise, false. * * @see ViewportQuad#destroy */ diff --git a/packages/engine/Source/Scene/VoxelBoxShape.js b/packages/engine/Source/Scene/VoxelBoxShape.js index a08e333f73a..d164ada3884 100644 --- a/packages/engine/Source/Scene/VoxelBoxShape.js +++ b/packages/engine/Source/Scene/VoxelBoxShape.js @@ -96,7 +96,7 @@ function VoxelBoxShape() { /** * The maximum number of intersections against the shape for any ray direction. - * @type {Number} + * @type {number} * @readonly */ this.shaderMaximumIntersectionsLength = 0; // not known until update @@ -144,7 +144,7 @@ const transformXYZToXZY = Matrix4.fromRotation( * @param {Cartesian3} maxBounds The maximum bounds. * @param {Cartesian3} [clipMinBounds=VoxelBoxShape.DefaultMinBounds] The minimum clip bounds. * @param {Cartesian3} [clipMaxBounds=VoxelBoxShape.DefaultMaxBounds] The maximum clip bounds. - * @returns {Boolean} Whether the shape is visible. + * @returns {boolean} Whether the shape is visible. */ VoxelBoxShape.prototype.update = function ( modelMatrix, @@ -394,10 +394,10 @@ const scratchTileMaxBounds = new Cartesian3(); * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. * - * @param {Number} tileLevel The tile's level. - * @param {Number} tileX The tile's x coordinate. - * @param {Number} tileY The tile's y coordinate. - * @param {Number} tileZ The tile's z coordinate. + * @param {number} tileLevel The tile's level. + * @param {number} tileX The tile's x coordinate. + * @param {number} tileY The tile's y coordinate. + * @param {number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile * @returns {OrientedBoundingBox} The oriented bounding box. */ @@ -447,7 +447,7 @@ VoxelBoxShape.prototype.computeOrientedBoundingBoxForTile = function ( * The update function must be called before calling this function. * * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. - * @returns {Number} The step size. + * @returns {number} The step size. */ VoxelBoxShape.prototype.computeApproximateStepSize = function (dimensions) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/VoxelContent.js b/packages/engine/Source/Scene/VoxelContent.js index b57cd815882..eead3e8f72d 100644 --- a/packages/engine/Source/Scene/VoxelContent.js +++ b/packages/engine/Source/Scene/VoxelContent.js @@ -11,7 +11,7 @@ import MetadataTable from "./MetadataTable.js"; * @constructor * * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed. - * @param {Object} [json] Voxel JSON contents. Mutually exclusive with binary. + * @param {object} [json] Voxel JSON contents. Mutually exclusive with binary. * @param {Uint8Array} [binary] Voxel binary contents. Mutually exclusive with json. * @param {MetadataSchema} metadataSchema The metadata schema used by property tables in the voxel content * @@ -128,8 +128,8 @@ function requestBuffers(content, json, binary) { /** * A helper object for storing the two parts of the binary voxel content * - * @typedef {Object} VoxelChunks - * @property {Object} json The json chunk of the binary voxel content + * @typedef {object} VoxelChunks + * @property {object} json The json chunk of the binary voxel content * @property {Uint8Array} binary The binary chunk of the binary voxel content. This represents the internal buffer. * @private */ diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index 231a957e24a..633a325acf9 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -56,37 +56,37 @@ function VoxelCylinderShape() { this.shapeTransform = new Matrix4(); /** - * @type {Number} + * @type {number} * @private */ this._minimumRadius = VoxelCylinderShape.DefaultMinBounds.x; /** - * @type {Number} + * @type {number} * @private */ this._maximumRadius = VoxelCylinderShape.DefaultMaxBounds.x; /** - * @type {Number} + * @type {number} * @private */ this._minimumHeight = VoxelCylinderShape.DefaultMinBounds.y; /** - * @type {Number} + * @type {number} * @private */ this._maximumHeight = VoxelCylinderShape.DefaultMaxBounds.y; /** - * @type {Number} + * @type {number} * @private */ this._minimumAngle = VoxelCylinderShape.DefaultMinBounds.z; /** - * @type {Number} + * @type {number} * @private */ this._maximumAngle = VoxelCylinderShape.DefaultMaxBounds.z; @@ -140,7 +140,7 @@ function VoxelCylinderShape() { /** * The maximum number of intersections against the shape for any ray direction. - * @type {Number} + * @type {number} * @readonly */ this.shaderMaximumIntersectionsLength = 0; // not known until update @@ -167,7 +167,7 @@ const transformUvToLocal = Matrix4.fromRotationTranslation( * @param {Cartesian3} maxBounds The maximum bounds. * @param {Cartesian3} [clipMinBounds=VoxelCylinderShape.DefaultMinBounds] The minimum clip bounds. * @param {Cartesian3} [clipMaxBounds=VoxelCylinderShape.DefaultMaxBounds] The maximum clip bounds. - * @returns {Boolean} Whether the shape is visible. + * @returns {boolean} Whether the shape is visible. */ VoxelCylinderShape.prototype.update = function ( modelMatrix, @@ -571,10 +571,10 @@ VoxelCylinderShape.prototype.update = function ( * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. * - * @param {Number} tileLevel The tile's level. - * @param {Number} tileX The tile's x coordinate. - * @param {Number} tileY The tile's y coordinate. - * @param {Number} tileZ The tile's z coordinate. + * @param {number} tileLevel The tile's level. + * @param {number} tileX The tile's x coordinate. + * @param {number} tileY The tile's y coordinate. + * @param {number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile * @returns {OrientedBoundingBox} The oriented bounding box. */ @@ -655,7 +655,7 @@ const scratchScaleRatio = new Cartesian3(); * The update function must be called before calling this function. * * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. - * @returns {Number} The step size. + * @returns {number} The step size. */ VoxelCylinderShape.prototype.computeApproximateStepSize = function ( dimensions @@ -788,12 +788,12 @@ function computeLooseOrientedBoundingBox(matrix, result) { * * @function * - * @param {Number} radiusStart The radiusStart. - * @param {Number} radiusEnd The radiusEnd. - * @param {Number} heightStart The heightStart. - * @param {Number} heightEnd The heightEnd. - * @param {Number} angleStart The angleStart. - * @param {Number} angleEnd The angleEnd. + * @param {number} radiusStart The radiusStart. + * @param {number} radiusEnd The radiusEnd. + * @param {number} heightStart The heightStart. + * @param {number} heightEnd The heightEnd. + * @param {number} angleStart The angleStart. + * @param {number} angleEnd The angleEnd. * @param {Matrix4} matrix The matrix to transform the points. * @param {OrientedBoundingBox} result The object onto which to store the result. * @returns {OrientedBoundingBox} The oriented bounding box that contains this subregion. diff --git a/packages/engine/Source/Scene/VoxelEllipsoidShape.js b/packages/engine/Source/Scene/VoxelEllipsoidShape.js index 1802634e47b..cd30a2987b4 100644 --- a/packages/engine/Source/Scene/VoxelEllipsoidShape.js +++ b/packages/engine/Source/Scene/VoxelEllipsoidShape.js @@ -62,13 +62,13 @@ function VoxelEllipsoidShape() { this._rectangle = new Rectangle(); /** - * @type {Number} + * @type {number} * @private */ this._minimumHeight = VoxelEllipsoidShape.DefaultMinBounds.z; /** - * @type {Number} + * @type {number} * @private */ this._maximumHeight = VoxelEllipsoidShape.DefaultMaxBounds.z; @@ -147,7 +147,7 @@ function VoxelEllipsoidShape() { /** * The maximum number of intersections against the shape for any ray direction. - * @type {Number} + * @type {number} * @readonly */ this.shaderMaximumIntersectionsLength = 0; // not known until update @@ -169,7 +169,7 @@ const scratchRenderRectangle = new Rectangle(); * @param {Cartesian3} maxBounds The maximum bounds. * @param {Cartesian3} [clipMinBounds=VoxelEllipsoidShape.DefaultMinBounds] The minimum clip bounds. * @param {Cartesian3} [clipMaxBounds=VoxelEllipsoidShape.DefaultMaxBounds] The maximum clip bounds. - * @returns {Boolean} Whether the shape is visible. + * @returns {boolean} Whether the shape is visible. */ VoxelEllipsoidShape.prototype.update = function ( modelMatrix, @@ -792,10 +792,10 @@ const scratchRectangle = new Rectangle(); * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. * - * @param {Number} tileLevel The tile's level. - * @param {Number} tileX The tile's x coordinate. - * @param {Number} tileY The tile's y coordinate. - * @param {Number} tileZ The tile's z coordinate. + * @param {number} tileLevel The tile's level. + * @param {number} tileX The tile's x coordinate. + * @param {number} tileY The tile's y coordinate. + * @param {number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile * @returns {OrientedBoundingBox} The oriented bounding box. */ @@ -859,7 +859,7 @@ VoxelEllipsoidShape.prototype.computeOrientedBoundingBoxForTile = function ( * The update function must be called before calling this function. * * @param {Cartesian3} dimensions The voxel grid dimensions for a tile. - * @returns {Number} The step size. + * @returns {number} The step size. */ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( dimensions @@ -885,8 +885,8 @@ VoxelEllipsoidShape.prototype.computeApproximateStepSize = function ( * @function * * @param {Rectangle} rectangle The rectangle. - * @param {Number} minHeight The minimumZ. - * @param {Number} maxHeight The maximumZ. + * @param {number} minHeight The minimumZ. + * @param {number} maxHeight The maximumZ. * @param {Ellipsoid} ellipsoid The ellipsoid. * @param {Cartesian3} translation The translation applied to the shape * @param {Matrix3} rotation The rotation applied to the shape diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index 1061207674b..4c68ed5de99 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -30,7 +30,7 @@ import CustomShader from "./Model/CustomShader.js"; * @alias VoxelPrimitive * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {VoxelProvider} [options.provider] The voxel provider that supplies the primitive with tile data. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix used to transform the primitive. * @param {CustomShader} [options.customShader] The custom shader used to style the primitive. @@ -46,7 +46,7 @@ function VoxelPrimitive(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); /** - * @type {Boolean} + * @type {boolean} * @private */ this._ready = false; @@ -77,7 +77,7 @@ function VoxelPrimitive(options) { this._shape = undefined; /** - * @type {Boolean} + * @type {boolean} * @private */ this._shapeVisible = false; @@ -177,7 +177,7 @@ function VoxelPrimitive(options) { /** * Keeps track of when the clipping planes change * - * @type {Number} + * @type {number} * @private */ this._clippingPlanesState = 0; @@ -185,7 +185,7 @@ function VoxelPrimitive(options) { /** * Keeps track of when the clipping planes are enabled / disabled * - * @type {Boolean} + * @type {boolean} * @private */ this._clippingPlanesEnabled = false; @@ -234,7 +234,7 @@ function VoxelPrimitive(options) { this._customShaderCompilationEvent = new Event(); /** - * @type {Boolean} + * @type {boolean} * @private */ this._shaderDirty = true; @@ -252,7 +252,7 @@ function VoxelPrimitive(options) { this._drawCommandPick = undefined; /** - * @type {Object} + * @type {object} * @private */ this._pickId = undefined; @@ -290,50 +290,50 @@ function VoxelPrimitive(options) { this._transformNormalLocalToWorld = new Matrix3(); /** - * @type {Number} + * @type {number} * @private */ this._stepSizeUv = 1.0; // Rendering /** - * @type {Boolean} + * @type {boolean} * @private */ this._jitter = true; /** - * @type {Boolean} + * @type {boolean} * @private */ this._nearestSampling = false; /** - * @type {Number} + * @type {number} * @private */ this._levelBlendFactor = 0.0; /** - * @type {Number} + * @type {number} * @private */ this._stepSizeMultiplier = 1.0; /** - * @type {Boolean} + * @type {boolean} * @private */ this._depthTest = true; /** - * @type {Boolean} + * @type {boolean} * @private */ this._useLogDepth = undefined; /** - * @type {Number} + * @type {number} * @private */ this._screenSpaceError = 4.0; // in pixels @@ -346,19 +346,19 @@ function VoxelPrimitive(options) { this._debugPolylines = new PolylineCollection(); /** - * @type {Boolean} + * @type {boolean} * @private */ this._debugDraw = false; /** - * @type {Boolean} + * @type {boolean} * @private */ this._disableRender = false; /** - * @type {Boolean} + * @type {boolean} * @private */ this._disableUpdate = false; @@ -449,7 +449,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets a value indicating whether or not the primitive is ready for use. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -462,7 +462,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets the promise that will be resolved when the primitive is ready for use. * * @memberof VoxelPrimitive.prototype - * @type {Promise.<VoxelPrimitive>} + * @type {Promise<VoxelPrimitive>} * @readonly */ readyPromise: { @@ -600,7 +600,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets the minimum value per channel of the voxel data. * * @memberof VoxelPrimitive.prototype - * @type {Number[][]} + * @type {number[][]} * @readonly * * @exception {DeveloperError} If the primitive is not ready. @@ -623,7 +623,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets the maximum value per channel of the voxel data. * * @memberof VoxelPrimitive.prototype - * @type {Number[][]} + * @type {number[][]} * @readonly * * @exception {DeveloperError} If the primitive is not ready. @@ -646,7 +646,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets whether or not this primitive should be displayed. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ show: { get: function () { @@ -665,7 +665,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets whether or not the primitive should update when the view changes. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ disableUpdate: { get: function () { @@ -684,7 +684,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets whether or not to render debug visualizations. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ debugDraw: { get: function () { @@ -703,7 +703,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets whether or not to test against depth when rendering. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ depthTest: { get: function () { @@ -726,7 +726,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * This reduces stair-step artifacts but introduces noise. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ jitter: { get: function () { @@ -748,7 +748,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * Gets or sets the nearest sampling. * * @memberof VoxelPrimitive.prototype - * @type {Boolean} + * @type {boolean} */ nearestSampling: { get: function () { @@ -772,7 +772,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * 1.0 means a full linear blend. * * @memberof VoxelPrimitive.prototype - * @type {Number} + * @type {number} * @private */ levelBlendFactor: { @@ -795,7 +795,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * result in worse performance and higher memory consumption. * * @memberof VoxelPrimitive.prototype - * @type {Number} + * @type {number} */ screenSpaceError: { get: function () { @@ -816,7 +816,7 @@ Object.defineProperties(VoxelPrimitive.prototype, { * also the worse the performance. * * @memberof VoxelPrimitive.prototype - * @type {Number} + * @type {number} */ stepSize: { get: function () { @@ -1266,7 +1266,7 @@ function initFromProvider(primitive, provider, context) { * Track changes in provider transform and primitive bounds * @param {VoxelPrimitive} primitive * @param {VoxelProvider} provider - * @returns {Boolean} Whether any of the transform or bounds changed + * @returns {boolean} Whether any of the transform or bounds changed * @private */ function checkTransformAndBounds(primitive, provider) { @@ -1302,9 +1302,9 @@ function checkTransformAndBounds(primitive, provider) { /** * Compare old and new values of a bound and update the old if it is different. * @param {VoxelPrimitive} primitive The primitive with bounds properties - * @param {String} newBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 - * @param {String} oldBoundKey A key pointing to a bounds property of the same type as the property at newBoundKey - * @returns {Number} 1 if the bound value changed, 0 otherwise + * @param {string} newBoundKey A key pointing to a bounds property of type Cartesian3 or Matrix4 + * @param {string} oldBoundKey A key pointing to a bounds property of the same type as the property at newBoundKey + * @returns {number} 1 if the bound value changed, 0 otherwise * * @private */ @@ -1324,7 +1324,7 @@ function updateBound(primitive, newBoundKey, oldBoundKey) { * @param {VoxelPrimitive} primitive * @param {VoxelShape} shape * @param {VoxelProvider} provider - * @returns {Boolean} True if the shape is visible + * @returns {boolean} True if the shape is visible * @private */ function updateShapeAndTransforms(primitive, shape, provider) { @@ -1428,7 +1428,7 @@ function setupTraversal(primitive, provider, context) { /** * Set uniforms that come from the traversal. * @param {VoxelTraversal} traversal - * @param {Object} uniforms + * @param {object} uniforms * @private */ function setTraversalUniforms(traversal, uniforms) { @@ -1473,7 +1473,7 @@ function setTraversalUniforms(traversal, uniforms) { * Track changes in shape-related shader defines * @param {VoxelPrimitive} primitive * @param {VoxelShape} shape - * @returns {Boolean} True if any of the shape defines changed, requiring a shader rebuild + * @returns {boolean} True if any of the shape defines changed, requiring a shader rebuild * @private */ function checkShapeDefines(primitive, shape) { @@ -1491,7 +1491,7 @@ function checkShapeDefines(primitive, shape) { * Find the keyframe location to render at. Doesn't need to be a whole number. * @param {TimeIntervalCollection} timeIntervalCollection * @param {Clock} clock - * @returns {Number} + * @returns {number} * * @private */ @@ -1537,7 +1537,7 @@ function getKeyframeLocation(timeIntervalCollection, clock) { * * @param {VoxelPrimitive} primitive * @param {FrameState} frameState - * @returns {Boolean} Whether the clipping planes changed, requiring a shader rebuild + * @returns {boolean} Whether the clipping planes changed, requiring a shader rebuild * @private */ function updateClippingPlanes(primitive, frameState) { @@ -1592,7 +1592,7 @@ function updateClippingPlanes(primitive, frameState) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see VoxelPrimitive#destroy */ diff --git a/packages/engine/Source/Scene/VoxelProvider.js b/packages/engine/Source/Scene/VoxelProvider.js index 7dce93e6aac..48a20b1e9d2 100644 --- a/packages/engine/Source/Scene/VoxelProvider.js +++ b/packages/engine/Source/Scene/VoxelProvider.js @@ -22,7 +22,7 @@ Object.defineProperties(VoxelProvider.prototype, { * Gets a value indicating whether or not the provider is ready for use. * * @memberof VoxelProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -33,7 +33,7 @@ Object.defineProperties(VoxelProvider.prototype, { * Gets the promise that will be resolved when the provider is ready for use. * * @memberof VoxelProvider.prototype - * @type {Promise.<VoxelProvider>} + * @type {Promise<VoxelProvider>} * @readonly */ readyPromise: { @@ -141,7 +141,7 @@ Object.defineProperties(VoxelProvider.prototype, { * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype - * @type {String[]} + * @type {string[]} * @readonly */ names: { @@ -177,7 +177,7 @@ Object.defineProperties(VoxelProvider.prototype, { * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype - * @type {Number[][]|undefined} + * @type {number[][]|undefined} * @readonly */ minimumValues: { @@ -189,7 +189,7 @@ Object.defineProperties(VoxelProvider.prototype, { * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype - * @type {Number[][]|undefined} + * @type {number[][]|undefined} * @readonly */ maximumValues: { @@ -201,7 +201,7 @@ Object.defineProperties(VoxelProvider.prototype, { * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumTileCount: { @@ -213,7 +213,7 @@ Object.defineProperties(VoxelProvider.prototype, { * This should not be called before {@link VoxelProvider#ready} returns true. * * @memberof VoxelProvider.prototype - * @type {Number} + * @type {number} * @readonly * @private */ @@ -240,12 +240,12 @@ Object.defineProperties(VoxelProvider.prototype, { * This function should not be called before {@link VoxelProvider#ready} returns true. * @function * - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.tileLevel=0] The tile's level. - * @param {Number} [options.tileX=0] The tile's X coordinate. - * @param {Number} [options.tileY=0] The tile's Y coordinate. - * @param {Number} [options.tileZ=0] The tile's Z coordinate. - * @privateparam {Number} [options.keyframe=0] The requested keyframe. + * @param {object} [options] Object with the following properties: + * @param {number} [options.tileLevel=0] The tile's level. + * @param {number} [options.tileX=0] The tile's X coordinate. + * @param {number} [options.tileY=0] The tile's Y coordinate. + * @param {number} [options.tileZ=0] The tile's Z coordinate. + * @privateparam {number} [options.keyframe=0] The requested keyframe. * @returns {Promise<Array[]>|undefined} A promise to an array of typed arrays containing the requested voxel data or undefined if there was a problem loading the data. * * @exception {DeveloperError} The provider must be ready. diff --git a/packages/engine/Source/Scene/VoxelRenderResources.js b/packages/engine/Source/Scene/VoxelRenderResources.js index 922435690dc..2f61dca086f 100644 --- a/packages/engine/Source/Scene/VoxelRenderResources.js +++ b/packages/engine/Source/Scene/VoxelRenderResources.js @@ -68,7 +68,7 @@ function VoxelRenderResources(primitive) { * A dictionary mapping uniform name to functions that return the uniform * values. * - * @type {Object.<String, Function>} + * @type {Object.<string, Function>} */ this.uniformMap = uniformMap; diff --git a/packages/engine/Source/Scene/VoxelShape.js b/packages/engine/Source/Scene/VoxelShape.js index f8449276f11..cb9ce614734 100644 --- a/packages/engine/Source/Scene/VoxelShape.js +++ b/packages/engine/Source/Scene/VoxelShape.js @@ -85,7 +85,7 @@ Object.defineProperties(VoxelShape.prototype, { /** * The maximum number of intersections against the shape for any ray direction. - * @type {Number} + * @type {number} * @readonly */ shaderMaximumIntersectionsLength: { @@ -99,7 +99,7 @@ Object.defineProperties(VoxelShape.prototype, { * @param {Matrix4} modelMatrix The model matrix. * @param {Cartesian3} minBounds The minimum bounds. * @param {Cartesian3} maxBounds The maximum bounds. - * @returns {Boolean} Whether the shape is visible. + * @returns {boolean} Whether the shape is visible. */ VoxelShape.prototype.update = DeveloperError.throwInstantiationError; @@ -107,10 +107,10 @@ VoxelShape.prototype.update = DeveloperError.throwInstantiationError; * Computes an oriented bounding box for a specified tile. * The update function must be called before calling this function. * - * @param {Number} tileLevel The tile's level. - * @param {Number} tileX The tile's x coordinate. - * @param {Number} tileY The tile's y coordinate. - * @param {Number} tileZ The tile's z coordinate. + * @param {number} tileLevel The tile's level. + * @param {number} tileX The tile's x coordinate. + * @param {number} tileY The tile's y coordinate. + * @param {number} tileZ The tile's z coordinate. * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified tile. * @returns {OrientedBoundingBox} The oriented bounding box. */ @@ -122,7 +122,7 @@ VoxelShape.prototype.computeOrientedBoundingBoxForTile = * The update function must be called before calling this function. * * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile. - * @returns {Number} The step size. + * @returns {number} The step size. */ VoxelShape.prototype.computeApproximateStepSize = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Source/Scene/VoxelShapeType.js b/packages/engine/Source/Scene/VoxelShapeType.js index 6155e99c86d..92576dae389 100644 --- a/packages/engine/Source/Scene/VoxelShapeType.js +++ b/packages/engine/Source/Scene/VoxelShapeType.js @@ -6,7 +6,7 @@ import VoxelEllipsoidShape from "./VoxelEllipsoidShape.js"; /** * An enum of voxel shapes. The shape controls how the voxel grid is mapped to 3D space. * - * @enum {String} + * @enum {string} * * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ @@ -14,7 +14,7 @@ const VoxelShapeType = { /** * A box shape. * - * @type {String} + * @type {string} * @constant * @private */ @@ -22,7 +22,7 @@ const VoxelShapeType = { /** * An ellipsoid shape. * - * @type {String} + * @type {string} * @constant * @private */ @@ -30,7 +30,7 @@ const VoxelShapeType = { /** * A cylinder shape. * - * @type {String} + * @type {string} * @constant * @private */ diff --git a/packages/engine/Source/Scene/VoxelTraversal.js b/packages/engine/Source/Scene/VoxelTraversal.js index 97d81bef733..492d39f7d24 100644 --- a/packages/engine/Source/Scene/VoxelTraversal.js +++ b/packages/engine/Source/Scene/VoxelTraversal.js @@ -28,8 +28,8 @@ import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js" * @param {Cartesian3} dimensions * @param {MetadataType[]} types * @param {MetadataComponentType[]} componentTypes - * @param {Number} keyframeCount - * @param {Number} [maximumTextureMemoryByteLength] + * @param {number} keyframeCount + * @param {number} [maximumTextureMemoryByteLength] * * @private */ @@ -75,19 +75,19 @@ function VoxelTraversal( const maximumTileCount = this.megatextures[0].maximumTileCount; /** - * @type {Number} + * @type {number} * @private */ this._simultaneousRequestCount = 0; /** - * @type {Boolean} + * @type {boolean} * @private */ this._debugPrint = false; /** - * @type {Number} + * @type {number} * @private */ this._frameNumber = 0; @@ -135,25 +135,25 @@ function VoxelTraversal( this._keyframeNodesInMegatexture = new Array(maximumTileCount); /** - * @type {Number} + * @type {number} * @private */ this._keyframeCount = keyframeCount; /** - * @type {Number} + * @type {number} * @private */ this._sampleCount = undefined; /** - * @type {Number} + * @type {number} * @private */ this._keyframeLocation = 0; /** - * @type {Number[]} + * @type {number[]} * @private */ this._binaryTreeKeyframeWeighting = new Array(keyframeCount); @@ -205,7 +205,7 @@ function VoxelTraversal( }); /** - * @type {Number} + * @type {number} * @readonly */ this.internalNodeTilesPerRow = internalNodeTilesPerRow; @@ -228,7 +228,7 @@ function VoxelTraversal( /** * Only generated when there are two or more samples. - * @type {Number} + * @type {number} * @readonly */ this.leafNodeTilesPerRow = undefined; @@ -245,9 +245,9 @@ VoxelTraversal.simultaneousRequestCountMaximum = 50; /** * @param {FrameState} frameState - * @param {Number} keyframeLocation - * @param {Boolean} recomputeBoundingVolumes - * @param {Boolean} pauseUpdate + * @param {number} keyframeLocation + * @param {boolean} recomputeBoundingVolumes + * @param {boolean} pauseUpdate */ VoxelTraversal.prototype.update = function ( frameState, @@ -336,7 +336,7 @@ VoxelTraversal.prototype.update = function ( /** * Check if a node is renderable. * @param {SpatialNode} tile - * @returns {Boolean} + * @returns {boolean} */ VoxelTraversal.prototype.isRenderable = function (tile) { return tile.isRenderable(this._frameNumber); @@ -348,7 +348,7 @@ VoxelTraversal.prototype.isRenderable = function (tile) { * If this object was destroyed, it should not be used; calling any function other than * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. * - * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. + * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>. * * @see VoxelTraversal#destroy */ @@ -489,8 +489,8 @@ function requestData(that, keyframeNode) { /** * @function * - * @param {Number} x - * @returns {Number} + * @param {number} x + * @returns {number} * * @private */ @@ -526,7 +526,7 @@ function loadAndUnload(that, frameState) { /** * @ignore * @param {SpatialNode} spatialNode - * @param {Number} visibilityPlaneMask + * @param {number} visibilityPlaneMask */ function addToQueueRecursive(spatialNode, visibilityPlaneMask) { spatialNode.computeScreenSpaceError( @@ -863,8 +863,8 @@ const GpuOctreeFlag = { * * @param {VoxelTraversal} that * @param {FrameState} frameState - * @param {Number} sampleCount - * @param {Number} levelBlendFactor + * @param {number} sampleCount + * @param {number} levelBlendFactor * @private */ function generateOctree(that, sampleCount, levelBlendFactor) { @@ -881,10 +881,10 @@ function generateOctree(that, sampleCount, levelBlendFactor) { /** * @ignore * @param {SpatialNode} node - * @param {Number} childOctreeIndex - * @param {Number} childEntryIndex - * @param {Number} parentOctreeIndex - * @param {Number} parentEntryIndex + * @param {number} childOctreeIndex + * @param {number} childEntryIndex + * @param {number} parentOctreeIndex + * @param {number} parentEntryIndex */ function buildOctree( node, @@ -992,9 +992,9 @@ function generateOctree(that, sampleCount, levelBlendFactor) { /** * Compute an interpolation factor between a node and its parent * @param {SpatialNode} node - * @param {Number} targetSse - * @param {Number} levelBlendFactor - * @returns {Number} + * @param {number} targetSse + * @param {number} levelBlendFactor + * @returns {number} * @private */ function getLodLerp(node, targetSse, levelBlendFactor) { @@ -1011,9 +1011,9 @@ function getLodLerp(node, targetSse, levelBlendFactor) { /** * - * @param {Number[]} data - * @param {Number} texelsPerTile - * @param {Number} tilesPerRow + * @param {number[]} data + * @param {number} texelsPerTile + * @param {number} tilesPerRow * @param {Texture} texture * @private */ @@ -1052,9 +1052,9 @@ function copyToInternalNodeTexture(data, texelsPerTile, tilesPerRow, texture) { /** * - * @param {Number[]} data - * @param {Number} texelsPerTile - * @param {Number} tilesPerRow + * @param {number[]} data + * @param {number} texelsPerTile + * @param {number} tilesPerRow * @param {Texture} texture * @private */ @@ -1111,7 +1111,7 @@ function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) { } /** - * @param {Number} tileCount + * @param {number} tileCount * @param {Cartesian3} dimensions * @param {MetadataType[]} types * @param {MetadataComponentType[]} componentTypes diff --git a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js index 8364208a249..9cf1c72d68f 100644 --- a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js @@ -32,15 +32,15 @@ const excludesReverseAxis = [ ]; /** - * @typedef {Object} WebMapServiceImageryProvider.ConstructorOptions + * @typedef {object} WebMapServiceImageryProvider.ConstructorOptions * * Initialization options for the WebMapServiceImageryProvider constructor * - * @property {Resource|String} url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}. - * @property {String} layers The layers to include, separated by commas. - * @property {Object} [parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters to pass to the WMS server in the GetMap URL. - * @property {Object} [getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional parameters to pass to the WMS server in the GetFeatureInfo URL. - * @property {Boolean} [enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke + * @property {Resource|string} url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}. + * @property {string} layers The layers to include, separated by commas. + * @property {object} [parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters to pass to the WMS server in the GetMap URL. + * @property {object} [getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional parameters to pass to the WMS server in the GetFeatureInfo URL. + * @property {boolean} [enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke * the GetFeatureInfo operation on the WMS server and return the features included in the response. If false, * {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features) * without communicating with the server. Set this property to false if you know your WMS server does not support @@ -53,22 +53,22 @@ const excludesReverseAxis = [ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified, * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither * parameter is specified, the WGS84 ellipsoid is used. - * @property {Number} [tileWidth=256] The width of each tile in pixels. - * @property {Number} [tileHeight=256] The height of each tile in pixels. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when + * @property {number} [tileWidth=256] The width of each tile in pixels. + * @property {number} [tileHeight=256] The height of each tile in pixels. + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when * specifying this that the number of tiles at the minimum level is small, such as four or less. A larger number is * likely to result in rendering problems. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * If not specified, there is no limit. - * @property {String} [crs] CRS specification, for use with WMS specification >= 1.3.0. - * @property {String} [srs] SRS specification, for use with WMS specification 1.1.0 or 1.1.1 - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. - * @property {String|String[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * @property {string} [crs] CRS specification, for use with WMS specification >= 1.3.0. + * @property {string} [srs] SRS specification, for use with WMS specification 1.1.0 or 1.1.1 + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. + * @property {string|string[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. * If this parameter is a single string, each character in the string is a subdomain. If it is * an array, each element in the array is a subdomain. * @property {Clock} [clock] A Clock instance that is used when determining the value for the time dimension. Required when `times` is specified. * @property {TimeIntervalCollection} [times] TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values. - * @property {Resource|String} [getFeatureInfoUrl] The getFeatureInfo URL of the WMS service. If the property is not defined then we use the property value of url. + * @property {Resource|string} [getFeatureInfoUrl] The getFeatureInfo URL of the WMS service. If the property is not defined then we use the property value of url. */ /** @@ -122,7 +122,7 @@ function WebMapServiceImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -131,7 +131,7 @@ function WebMapServiceImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -140,7 +140,7 @@ function WebMapServiceImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -149,7 +149,7 @@ function WebMapServiceImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -158,7 +158,7 @@ function WebMapServiceImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -166,7 +166,7 @@ function WebMapServiceImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -175,7 +175,7 @@ function WebMapServiceImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -183,7 +183,7 @@ function WebMapServiceImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -376,7 +376,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets the URL of the WMS server. * @memberof WebMapServiceImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -400,7 +400,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets the names of the WMS layers, separated by commas. * @memberof WebMapServiceImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ layers: { @@ -413,7 +413,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -426,7 +426,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -439,7 +439,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * @memberof WebMapServiceImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -452,7 +452,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * @memberof WebMapServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -519,7 +519,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -531,7 +531,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof WebMapServiceImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -560,7 +560,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -576,7 +576,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { * features) without communicating with the server. Set this property to false if you know your data * source does not support picking features or if you don't want this provider's features to be pickable. * @memberof WebMapServiceImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @default true */ enablePickFeatures: { @@ -620,7 +620,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets the getFeatureInfo URL of the WMS server. * @memberof WebMapServiceImageryProvider.prototype - * @type {Resource|String} + * @type {Resource|string} * @readonly */ getFeatureInfoUrl: { @@ -633,9 +633,9 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -648,11 +648,11 @@ WebMapServiceImageryProvider.prototype.getTileCredits = function (x, y, level) { * Requests the image for a given tile. This function should * not be called before {@link WebMapServiceImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -690,12 +690,12 @@ WebMapServiceImageryProvider.prototype.requestImage = function ( * Asynchronously determines what features, if any, are located at a given longitude and latitude within * a tile. This function should not be called before {@link ImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. - * @return {Promise.<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. + * @return {Promise<ImageryLayerFeatureInfo[]>|undefined} A promise for the picked features that will resolve when the asynchronous * picking completes. The resolved value is an array of {@link ImageryLayerFeatureInfo} * instances. The array may be empty if no features are found at the given location. * @@ -725,7 +725,7 @@ WebMapServiceImageryProvider.prototype.pickFeatures = function ( * format=image/jpeg * * @constant - * @type {Object} + * @type {object} */ WebMapServiceImageryProvider.DefaultParameters = Object.freeze({ service: "WMS", @@ -742,7 +742,7 @@ WebMapServiceImageryProvider.DefaultParameters = Object.freeze({ * request=GetFeatureInfo * * @constant - * @type {Object} + * @type {object} */ WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters = Object.freeze({ service: "WMS", diff --git a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js index 18eb431deb2..dd1d95381c3 100644 --- a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js @@ -17,28 +17,28 @@ const defaultParameters = Object.freeze({ }); /** - * @typedef {Object} WebMapTileServiceImageryProvider.ConstructorOptions + * @typedef {object} WebMapTileServiceImageryProvider.ConstructorOptions * * Initialization options for the WebMapTileServiceImageryProvider constructor * - * @property {Resource|String} url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains. - * @property {String} [format='image/jpeg'] The MIME type for images to retrieve from the server. - * @property {String} layer The layer name for WMTS requests. - * @property {String} style The style name for WMTS requests. - * @property {String} tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests. + * @property {Resource|string} url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains. + * @property {string} [format='image/jpeg'] The MIME type for images to retrieve from the server. + * @property {string} layer The layer name for WMTS requests. + * @property {string} style The style name for WMTS requests. + * @property {string} tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests. * @property {Array} [tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level. * @property {Clock} [clock] A Clock instance that is used when determining the value for the time dimension. Required when `times` is specified. * @property {TimeIntervalCollection} [times] TimeIntervalCollection with its <code>data</code> property being an object containing time dynamic dimension and their values. - * @property {Object} [dimensions] A object containing static dimensions and their values. - * @property {Number} [tileWidth=256] The tile width in pixels. - * @property {Number} [tileHeight=256] The tile height in pixels. + * @property {object} [dimensions] A object containing static dimensions and their values. + * @property {number} [tileWidth=256] The tile width in pixels. + * @property {number} [tileHeight=256] The tile height in pixels. * @property {TilingScheme} [tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer. - * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. - * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. + * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. + * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. - * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. - * @property {String|String[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. + * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. + * @property {string|string[]} [subdomains='abc'] The subdomains to use for the <code>{s}</code> placeholder in the URL template. * If this parameter is a single string, each character in the string is a subdomain. If it is * an array, each element in the array is a subdomain. */ @@ -140,7 +140,7 @@ function WebMapTileServiceImageryProvider(options) { * The default alpha blending value of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultAlpha = undefined; @@ -149,7 +149,7 @@ function WebMapTileServiceImageryProvider(options) { * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultNightAlpha = undefined; @@ -158,7 +158,7 @@ function WebMapTileServiceImageryProvider(options) { * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and * 1.0 representing fully opaque. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultDayAlpha = undefined; @@ -167,7 +167,7 @@ function WebMapTileServiceImageryProvider(options) { * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 * makes the imagery darker while greater than 1.0 makes it brighter. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultBrightness = undefined; @@ -176,7 +176,7 @@ function WebMapTileServiceImageryProvider(options) { * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces * the contrast while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultContrast = undefined; @@ -184,7 +184,7 @@ function WebMapTileServiceImageryProvider(options) { /** * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultHue = undefined; @@ -193,7 +193,7 @@ function WebMapTileServiceImageryProvider(options) { * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the * saturation while greater than 1.0 increases it. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultSaturation = undefined; @@ -201,7 +201,7 @@ function WebMapTileServiceImageryProvider(options) { /** * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.defaultGamma = undefined; @@ -390,7 +390,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets the URL of the service hosting the imagery. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ url: { @@ -415,7 +415,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * Gets the width of each tile, in pixels. This function should * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileWidth: { @@ -428,7 +428,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * Gets the height of each tile, in pixels. This function should * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ tileHeight: { @@ -441,7 +441,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * Gets the maximum level-of-detail that can be requested. This function should * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Number|undefined} + * @type {number|undefined} * @readonly */ maximumLevel: { @@ -454,7 +454,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * Gets the minimum level-of-detail that can be requested. This function should * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Number} + * @type {number} * @readonly */ minimumLevel: { @@ -521,7 +521,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets the mime type of images returned by this imagery provider. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {String} + * @type {string} * @readonly */ format: { @@ -533,7 +533,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets a value indicating whether or not the provider is ready for use. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ ready: { @@ -543,7 +543,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets a promise that resolves to true when the provider is ready for use. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Promise.<Boolean>} + * @type {Promise<boolean>} * @readonly */ readyPromise: { @@ -572,7 +572,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { * as if their alpha is 1.0 everywhere. When this property is false, memory usage * and texture upload time are reduced. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Boolean} + * @type {boolean} * @readonly */ hasAlphaChannel: { @@ -611,7 +611,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets or sets an object that contains static dimensions and their values. * @memberof WebMapTileServiceImageryProvider.prototype - * @type {Object} + * @type {object} */ dimensions: { get: function () { @@ -631,9 +631,9 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { /** * Gets the credits to be displayed when a given tile is displayed. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level; + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level; * @returns {Credit[]} The credits to be displayed when the tile is displayed. * * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready. @@ -650,11 +650,11 @@ WebMapTileServiceImageryProvider.prototype.getTileCredits = function ( * Requests the image for a given tile. This function should * not be called before {@link WebMapTileServiceImageryProvider#ready} returns true. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. * @param {Request} [request] The request object. Intended for internal use only. - * @returns {Promise.<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or + * @returns {Promise<ImageryTypes>|undefined} A promise for the image that will resolve when the image is available, or * undefined if there are too many active requests to the server, and the request should be retried later. * * @exception {DeveloperError} <code>requestImage</code> must not be called before the imagery provider is ready. @@ -692,11 +692,11 @@ WebMapTileServiceImageryProvider.prototype.requestImage = function ( * Picking features is not currently supported by this imagery provider, so this function simply returns * undefined. * - * @param {Number} x The tile X coordinate. - * @param {Number} y The tile Y coordinate. - * @param {Number} level The tile level. - * @param {Number} longitude The longitude at which to pick features. - * @param {Number} latitude The latitude at which to pick features. + * @param {number} x The tile X coordinate. + * @param {number} y The tile Y coordinate. + * @param {number} level The tile level. + * @param {number} longitude The longitude at which to pick features. + * @param {number} latitude The latitude at which to pick features. * @return {undefined} Undefined since picking is not supported. */ WebMapTileServiceImageryProvider.prototype.pickFeatures = function ( diff --git a/packages/engine/Source/Scene/createBillboardPointCallback.js b/packages/engine/Source/Scene/createBillboardPointCallback.js index 6b2c842a0b9..a9340b81d3d 100644 --- a/packages/engine/Source/Scene/createBillboardPointCallback.js +++ b/packages/engine/Source/Scene/createBillboardPointCallback.js @@ -1,11 +1,11 @@ /** * Creates a {@link createBillboardPointCallback.CanvasFunction} that will create a canvas with a point. * - * @param {Number} centerAlpha The alpha of the center of the point. The value must be in the range [0.0, 1.0]. - * @param {String} cssColor The CSS color string. - * @param {String} cssOutlineColor The CSS color of the point outline. - * @param {Number} cssOutlineWidth The width of the outline in pixels. - * @param {Number} pixelSize The size of the point in pixels. + * @param {number} centerAlpha The alpha of the center of the point. The value must be in the range [0.0, 1.0]. + * @param {string} cssColor The CSS color string. + * @param {string} cssOutlineColor The CSS color of the point outline. + * @param {number} cssOutlineWidth The width of the outline in pixels. + * @param {number} pixelSize The size of the point in pixels. * @return {createBillboardPointCallback.CanvasFunction} The function that will return a canvas with the point drawn on it. * * @private diff --git a/packages/engine/Source/Scene/createElevationBandMaterial.js b/packages/engine/Source/Scene/createElevationBandMaterial.js index 375964c207d..544a1d67f6c 100644 --- a/packages/engine/Source/Scene/createElevationBandMaterial.js +++ b/packages/engine/Source/Scene/createElevationBandMaterial.js @@ -411,15 +411,15 @@ function createLayeredEntries(layers) { /** * @typedef createElevationBandMaterialEntry * - * @property {Number} height The height. + * @property {number} height The height. * @property {Color} color The color at this height. */ /** * @typedef createElevationBandMaterialBand * * @property {createElevationBandMaterialEntry[]} entries A list of elevation entries. They will automatically be sorted from lowest to highest. If there is only one entry and <code>extendsDownards</code> and <code>extendUpwards</code> are both <code>false</code>, they will both be set to <code>true</code>. - * @property {Boolean} [extendDownwards=false] If <code>true</code>, the band's minimum elevation color will extend infinitely downwards. - * @property {Boolean} [extendUpwards=false] If <code>true</code>, the band's maximum elevation color will extend infinitely upwards. + * @property {boolean} [extendDownwards=false] If <code>true</code>, the band's minimum elevation color will extend infinitely downwards. + * @property {boolean} [extendUpwards=false] If <code>true</code>, the band's maximum elevation color will extend infinitely upwards. */ /** @@ -430,7 +430,7 @@ function createLayeredEntries(layers) { * * @function createElevationBandMaterial * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Scene} options.scene The scene where the visualization is taking place. * @param {createElevationBandMaterialBand[]} options.layers A list of bands ordered from lowest to highest precedence. * @returns {Material} A new {@link Material} instance. @@ -550,7 +550,7 @@ function createElevationBandMaterial(options) { * Function for checking if the context will allow floating point textures for heights. * * @param {Context} context The {@link Context}. - * @returns {Boolean} <code>true</code> if floating point textures can be used for heights. + * @returns {boolean} <code>true</code> if floating point textures can be used for heights. * @private */ createElevationBandMaterial._useFloatTexture = function (context) { diff --git a/packages/engine/Source/Scene/createOsmBuildings.js b/packages/engine/Source/Scene/createOsmBuildings.js index 891b1e34071..d17e717ba37 100644 --- a/packages/engine/Source/Scene/createOsmBuildings.js +++ b/packages/engine/Source/Scene/createOsmBuildings.js @@ -13,7 +13,7 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; * * @function * - * @param {Object} [options] Construction options. Any options allowed by the {@link Cesium3DTileset} constructor + * @param {object} [options] Construction options. Any options allowed by the {@link Cesium3DTileset} constructor * may be specified here. In addition to those, the following properties are supported: * @param {Color} [options.defaultColor=Color.WHITE] The default color to use for buildings * that do not have a color. This parameter is ignored if <code>options.style</code> is specified. @@ -21,8 +21,8 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; * specified, a default style is used which gives each building or building part a * color inferred from its OpenStreetMap <code>tags</code>. If no color can be inferred, * <code>options.defaultColor</code> is used. - * @param {Boolean} [options.enableShowOutline=true] If true, enable rendering outlines. This can be set to false to avoid the additional processing of geometry at load time. - * @param {Boolean} [options.showOutline=true] Whether to show outlines around buildings. When true, + * @param {boolean} [options.enableShowOutline=true] If true, enable rendering outlines. This can be set to false to avoid the additional processing of geometry at load time. + * @param {boolean} [options.showOutline=true] Whether to show outlines around buildings. When true, * outlines are displayed. When false, outlines are not displayed. * @returns {Cesium3DTileset} * diff --git a/packages/engine/Source/Scene/createTangentSpaceDebugPrimitive.js b/packages/engine/Source/Scene/createTangentSpaceDebugPrimitive.js index 8b6f8584b8d..5c3086e11b3 100644 --- a/packages/engine/Source/Scene/createTangentSpaceDebugPrimitive.js +++ b/packages/engine/Source/Scene/createTangentSpaceDebugPrimitive.js @@ -16,9 +16,9 @@ import Primitive from "./Primitive.js"; * * @function * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Geometry} options.geometry The <code>Geometry</code> instance with the attribute. - * @param {Number} [options.length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. + * @param {number} [options.length=10000.0] The length of each line segment in meters. This can be negative to point the vector in the opposite direction. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The model matrix that transforms to transform the geometry from model to world coordinates. * @returns {Primitive} A new <code>Primitive</code> instance with geometry for the vectors. * diff --git a/packages/engine/Source/Scene/createWorldImagery.js b/packages/engine/Source/Scene/createWorldImagery.js index 36d07b0e7f8..6e834881691 100644 --- a/packages/engine/Source/Scene/createWorldImagery.js +++ b/packages/engine/Source/Scene/createWorldImagery.js @@ -7,7 +7,7 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * * @function * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. * @returns {IonImageryProvider} * diff --git a/packages/engine/Source/Scene/findContentMetadata.js b/packages/engine/Source/Scene/findContentMetadata.js index 264464a3448..db20826686b 100644 --- a/packages/engine/Source/Scene/findContentMetadata.js +++ b/packages/engine/Source/Scene/findContentMetadata.js @@ -12,7 +12,7 @@ import oneTimeWarning from "../Core/oneTimeWarning.js"; * @function * * @param {Cesium3DTileset} tileset The tileset to query for content metadata - * @param {Object} contentHeader the JSON header for a {@link Cesium3DTileContent} + * @param {object} contentHeader the JSON header for a {@link Cesium3DTileContent} * @return {ContentMetadata} the content metadata, or <code>undefined</code> if not found * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/findGroupMetadata.js b/packages/engine/Source/Scene/findGroupMetadata.js index 2642efe486a..c19bf0ba361 100644 --- a/packages/engine/Source/Scene/findGroupMetadata.js +++ b/packages/engine/Source/Scene/findGroupMetadata.js @@ -9,7 +9,7 @@ import hasExtension from "./hasExtension.js"; * @function * * @param {Cesium3DTileset} tileset The tileset to query for group metadata - * @param {Object} contentHeader the JSON header for a {@link Cesium3DTileContent} + * @param {object} contentHeader the JSON header for a {@link Cesium3DTileContent} * @return {GroupMetadata} the group metadata, or <code>undefined</code> if not found * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/findTileMetadata.js b/packages/engine/Source/Scene/findTileMetadata.js index fa83968b3d1..f455afdf9c9 100644 --- a/packages/engine/Source/Scene/findTileMetadata.js +++ b/packages/engine/Source/Scene/findTileMetadata.js @@ -14,7 +14,7 @@ import oneTimeWarning from "../Core/oneTimeWarning.js"; * @function * * @param {Cesium3DTileset} tileset The tileset to query for tile metadata - * @param {Object} tileHeader the JSON header for a {@link Cesium3DTile} + * @param {object} tileHeader the JSON header for a {@link Cesium3DTile} * @return {TileMetadata} the tile metadata, or <code>undefined</code> if not found * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/getClipAndStyleCode.js b/packages/engine/Source/Scene/getClipAndStyleCode.js index 41eddcf1407..5b3e71f61ea 100644 --- a/packages/engine/Source/Scene/getClipAndStyleCode.js +++ b/packages/engine/Source/Scene/getClipAndStyleCode.js @@ -3,10 +3,10 @@ import Check from "../Core/Check.js"; /** * Gets a GLSL snippet that clips a fragment using the `clip` function from {@link getClippingFunction} and styles it. * - * @param {String} samplerUniformName Name of the uniform for the clipping planes texture sampler. - * @param {String} matrixUniformName Name of the uniform for the clipping planes matrix. - * @param {String} styleUniformName Name of the uniform for the clipping planes style, a vec4. - * @returns {String} A string containing GLSL that clips and styles the current fragment. + * @param {string} samplerUniformName Name of the uniform for the clipping planes texture sampler. + * @param {string} matrixUniformName Name of the uniform for the clipping planes matrix. + * @param {string} styleUniformName Name of the uniform for the clipping planes style, a vec4. + * @returns {string} A string containing GLSL that clips and styles the current fragment. * @private */ function getClipAndStyleCode( diff --git a/packages/engine/Source/Scene/getClippingFunction.js b/packages/engine/Source/Scene/getClippingFunction.js index be41a8717b1..d17d9819b59 100644 --- a/packages/engine/Source/Scene/getClippingFunction.js +++ b/packages/engine/Source/Scene/getClippingFunction.js @@ -8,7 +8,7 @@ const textureResolutionScratch = new Cartesian2(); * * @param {ClippingPlaneCollection} clippingPlaneCollection ClippingPlaneCollection with a defined texture. * @param {Context} context The current rendering context. - * @returns {String} A string containing GLSL functions for retrieving clipping planes. + * @returns {string} A string containing GLSL functions for retrieving clipping planes. * @private */ function getClippingFunction(clippingPlaneCollection, context) { diff --git a/packages/engine/Source/Scene/hasExtension.js b/packages/engine/Source/Scene/hasExtension.js index de9622f5eb8..477f7adf3b2 100644 --- a/packages/engine/Source/Scene/hasExtension.js +++ b/packages/engine/Source/Scene/hasExtension.js @@ -3,9 +3,9 @@ import defined from "../Core/defined.js"; /** * Check if a specific extension is present on a JSON object. This can be used * for either 3D Tiles extensions or glTF extensions - * @param {Object} json The JSON object - * @param {String} extensionName The name of the extension, e.g. '3DTILES_implicit_tiling' - * @returns {Boolean} True if the extension is present + * @param {object} json The JSON object + * @param {string} extensionName The name of the extension, e.g. '3DTILES_implicit_tiling' + * @returns {boolean} True if the extension is present * @private */ function hasExtension(json, extensionName) { diff --git a/packages/engine/Source/Scene/parseBatchTable.js b/packages/engine/Source/Scene/parseBatchTable.js index da55b2122b4..2eede18d9c2 100644 --- a/packages/engine/Source/Scene/parseBatchTable.js +++ b/packages/engine/Source/Scene/parseBatchTable.js @@ -25,11 +25,11 @@ import oneTimeWarning from "../Core/oneTimeWarning.js"; * See the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata|EXT_structural_metadata Extension} for glTF. * </p> * - * @param {Object} options Object with the following properties: - * @param {Number} options.count The number of features in the batch table. - * @param {Object} options.batchTable The batch table JSON + * @param {object} options Object with the following properties: + * @param {number} options.count The number of features in the batch table. + * @param {object} options.batchTable The batch table JSON * @param {Uint8Array} [options.binaryBody] The batch table binary body - * @param {Boolean} [options.parseAsPropertyAttributes=false] If true, binary properties are parsed as property attributes instead of a property table. This is used for .pnts models for GPU styling. + * @param {boolean} [options.parseAsPropertyAttributes=false] If true, binary properties are parsed as property attributes instead of a property table. This is used for .pnts models for GPU styling. * @param {ModelComponents.Attribute[]} [options.customAttributeOutput] Pass in an empty array here and this method will populate it with a list of custom attributes that will store the values of the property attributes. The attributes will be created with typed arrays, the caller is responsible for uploading them to the GPU. This option is required when options.parseAsPropertyAttributes is true. * @return {StructuralMetadata} A transcoded structural metadata object * @@ -149,8 +149,8 @@ function parseBatchTable(options) { * Divide the batch table's properties into binary, JSON and hierarchy * extension as each is handled separately * - * @param {Object} batchTable The batch table JSON - * @returns {Object} The batch table divided into binary, JSON and hierarchy portions. Extras and extensions are also divided out for ease of processing. + * @param {object} batchTable The batch table JSON + * @returns {object} The batch table divided into binary, JSON and hierarchy portions. Extras and extensions are also divided out for ease of processing. * * @private */ @@ -208,11 +208,11 @@ function partitionProperties(batchTable) { * Transcode the binary properties of the batch table to be compatible with * <code>EXT_structural_metadata</code> * - * @param {Number} featureCount The number of features in the batch table - * @param {String} className The name of the metadata class to be created. - * @param {Object.<String, Object>} binaryProperties A dictionary of property ID to property definition + * @param {number} featureCount The number of features in the batch table + * @param {string} className The name of the metadata class to be created. + * @param {Object.<string, Object>} binaryProperties A dictionary of property ID to property definition * @param {Uint8Array} [binaryBody] The binary body of the batch table - * @return {Object} Transcoded data needed for constructing a {@link StructuralMetadata} object. + * @return {object} Transcoded data needed for constructing a {@link StructuralMetadata} object. * * @private */ @@ -405,8 +405,8 @@ function transcodeBinaryPropertiesAsPropertyAttributes( * Given a property definition from the batch table, compute the equivalent * <code>EXT_structural_metadata</code> type definition * - * @param {Object} property The batch table property definition - * @return {Object} The corresponding structural metadata property definition + * @param {object} property The batch table property definition + * @return {object} The corresponding structural metadata property definition * @private */ function transcodePropertyType(property) { @@ -422,8 +422,8 @@ function transcodePropertyType(property) { * Convert the component type of a batch table property to the corresponding * type used with structural metadata * - * @property {String} componentType the batch table's component type - * @return {String} The corresponding structural metadata data type + * @property {string} componentType the batch table's component type + * @return {string} The corresponding structural metadata data type * * @private */ diff --git a/packages/engine/Source/Scene/parseBoundingVolumeSemantics.js b/packages/engine/Source/Scene/parseBoundingVolumeSemantics.js index d649b6ac2da..d83935c4377 100644 --- a/packages/engine/Source/Scene/parseBoundingVolumeSemantics.js +++ b/packages/engine/Source/Scene/parseBoundingVolumeSemantics.js @@ -14,7 +14,7 @@ import defined from "../Core/defined.js"; * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification/Metadata/Semantics|3D Metadata Semantic Reference} for the various bounding volumes and minimum/maximum heights. * * @param {TileMetadata} tileMetadata The metadata object for looking up values by semantic. In practice, this will typically be a {@link ImplicitMetadataView} - * @return {Object} An object containing a <code>tile</code> property and a <code>content</code> property. These contain the bounding volume, and any minimum or maximum height. + * @return {object} An object containing a <code>tile</code> property and a <code>content</code> property. These contain the bounding volume, and any minimum or maximum height. * * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. @@ -47,9 +47,9 @@ function parseBoundingVolumeSemantics(tileMetadata) { * is the prefix. e.g. <code>TILE_BOUNDING_BOX</code> and * <code>CONTENT_BOUNDING_BOX</code> have the same memory layout. * - * @param {String} prefix Either "TILE" or "CONTENT" + * @param {string} prefix Either "TILE" or "CONTENT" * @param {TileMetadata} tileMetadata The tileMetadata for looking up values - * @return {Object} An object representing the JSON description of the tile metadata + * @return {object} An object representing the JSON description of the tile metadata * @private */ function parseBoundingVolume(prefix, tileMetadata) { @@ -93,9 +93,9 @@ function parseBoundingVolume(prefix, tileMetadata) { * quadtree bounds for implicit tiling. This works for both * <code>TILE_MINIMUM_HEIGHT</code> and <code>CONTENT_MINIMUM_HEIGHT</code> * - * @param {String} prefix Either "TILE" or "CONTENT" + * @param {string} prefix Either "TILE" or "CONTENT" * @param {TileMetadata} tileMetadata The tileMetadata for looking up values - * @return {Number} The minimum height + * @return {number} The minimum height * @private */ function parseMinimumHeight(prefix, tileMetadata) { @@ -108,9 +108,9 @@ function parseMinimumHeight(prefix, tileMetadata) { * quadtree bounds for implicit tiling. This works for both * <code>TILE_MAXIMUM_HEIGHT</code> and <code>CONTENT_MAXIMUM_HEIGHT</code> * - * @param {String} prefix Either "TILE" or "CONTENT" + * @param {string} prefix Either "TILE" or "CONTENT" * @param {TileMetadata} tileMetadata The tileMetadata for looking up values - * @return {Number} The maximum height + * @return {number} The maximum height * @private */ function parseMaximumHeight(prefix, tileMetadata) { diff --git a/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js b/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js index d522a9a121b..c3f9b78d390 100644 --- a/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js +++ b/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js @@ -11,11 +11,11 @@ import MetadataTable from "./MetadataTable.js"; * Parse the <code>EXT_feature_metadata</code> glTF extension to create a * structural metadata object. * - * @param {Object} options Object with the following properties: - * @param {Object} options.extension The extension JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.extension The extension JSON object. * @param {MetadataSchema} options.schema The parsed schema. - * @param {Object.<String, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. - * @param {Object.<String, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. + * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object.<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. * @return {StructuralMetadata} A structural metadata object * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/parseStructuralMetadata.js b/packages/engine/Source/Scene/parseStructuralMetadata.js index f3af672d3b5..eca5d4c6d84 100644 --- a/packages/engine/Source/Scene/parseStructuralMetadata.js +++ b/packages/engine/Source/Scene/parseStructuralMetadata.js @@ -11,11 +11,11 @@ import MetadataTable from "./MetadataTable.js"; * Parse the <code>EXT_structural_metadata</code> glTF extension to create a * structural metadata object. * - * @param {Object} options Object with the following properties: - * @param {Object} options.extension The extension JSON object. + * @param {object} options Object with the following properties: + * @param {object} options.extension The extension JSON object. * @param {MetadataSchema} options.schema The parsed schema. - * @param {Object.<String, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. - * @param {Object.<String, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. + * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object.<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. * @return {StructuralMetadata} A structural metadata object * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/preprocess3DTileContent.js b/packages/engine/Source/Scene/preprocess3DTileContent.js index ec8f44b84d4..8bb8f76d5c2 100644 --- a/packages/engine/Source/Scene/preprocess3DTileContent.js +++ b/packages/engine/Source/Scene/preprocess3DTileContent.js @@ -9,10 +9,10 @@ import Cesium3DTileContentType from "./Cesium3DTileContentType.js"; * {@link Cesium3DTileContentType} and the payload. The payload is either * binary or JSON depending on the content type. * - * @typedef {Object} PreprocessedContent + * @typedef {object} PreprocessedContent * @property {Cesium3DTileContentType} contentType The type of the content * @property {Uint8Array} [binaryPayload] For binary files, the payload is returned as a typed array with byteOffset of 0 - * @property {Object} [jsonPayload] For JSON files, the results are returned as a JSON object. + * @property {object} [jsonPayload] For JSON files, the results are returned as a JSON object. * @private */ diff --git a/packages/engine/Source/Scene/processVoxelProperties.js b/packages/engine/Source/Scene/processVoxelProperties.js index 46dc60fd613..edd6ed80e9b 100644 --- a/packages/engine/Source/Scene/processVoxelProperties.js +++ b/packages/engine/Source/Scene/processVoxelProperties.js @@ -355,7 +355,7 @@ function processVoxelProperties(renderResources, primitive) { * @function * * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. + * @returns {string} The GLSL type. * * @private */ @@ -377,7 +377,7 @@ function getGlslType(type) { * @function * * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL swizzle. + * @returns {string} The GLSL swizzle. * * @private */ @@ -399,7 +399,7 @@ function getGlslTextureSwizzle(type) { * @function * * @param {MetadataType} type The {@link MetadataType}. - * @returns {String} The GLSL type. + * @returns {string} The GLSL type. * * @private */ @@ -421,8 +421,8 @@ function getGlslPartialDerivativeType(type) { * * @function * - * @param {Number} number The number to convert. - * @returns {String} The number as floating point in GLSL. + * @param {number} number The number to convert. + * @returns {string} The number as floating point in GLSL. * * @private */ @@ -440,8 +440,8 @@ function getGlslNumberAsFloat(number) { * @function * * @param {MetadataType} type - * @param {Number} index - * @returns {String} + * @param {number} index + * @returns {string} * * @private */ diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index f76a92486ca..dc40aad99cf 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -120,33 +120,33 @@ function configureCameraFrustum(widget) { * @alias CesiumWidget * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. - * @param {Object} [options] Object with the following properties: + * @param {Element|string} container The DOM element or ID that will contain the widget. + * @param {object} [options] Object with the following properties: * @param {Clock} [options.clock=new Clock()] The clock to use to control current time. * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to <code>false</code>, no imagery provider will be added. * @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. * @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @param {SkyAtmosphere | false} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. * @param {SceneMode} [options.sceneMode=SceneMode.SCENE3D] The initial scene mode. - * @param {Boolean} [options.scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory. - * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. + * @param {boolean} [options.scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory. + * @param {boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. * @param {Globe | false} [options.globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to <code>false</code>, no globe will be added. - * @param {Boolean} [options.useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise. - * @param {Boolean} [options.useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>. - * @param {Number} [options.targetFrameRate] The target frame rate when using the default render loop. - * @param {Boolean} [options.showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs. + * @param {boolean} [options.useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise. + * @param {boolean} [options.useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>. + * @param {number} [options.targetFrameRate] The target frame rate when using the default render loop. + * @param {boolean} [options.showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs. * @param {ContextOptions} [options.contextOptions] Context and WebGL creation properties passed to {@link Scene}. - * @param {Element|String} [options.creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added + * @param {Element|string} [options.creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added * to the bottom of the widget itself. - * @param {Element|String} [options.creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself. - * @param {Boolean} [options.shadows=false] Determines if shadows are cast by light sources. + * @param {Element|string} [options.creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself. + * @param {boolean} [options.shadows=false] Determines if shadows are cast by light sources. * @param {ShadowMode} [options.terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from light sources. * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. - * @param {Boolean} [options.blurActiveElementOnCanvasFocus=true] If true, the active element will blur when the viewer's canvas is clicked. Setting this to false is useful for cases when the canvas is clicked only for retrieving position or an entity data without actually meaning to set the canvas to be the active element. - * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @param {Number} [options.msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. + * @param {boolean} [options.blurActiveElementOnCanvasFocus=true] If true, the active element will blur when the viewer's canvas is clicked. Setting this to false is useful for cases when the canvas is clicked only for retrieving position or an entity data without actually meaning to set the canvas to be the active element. + * @param {boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @param {number} [options.msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @@ -538,7 +538,7 @@ Object.defineProperties(CesiumWidget.prototype, { * than the underlying requestAnimationFrame implementation will have no effect. * @memberof CesiumWidget.prototype * - * @type {Number} + * @type {number} */ targetFrameRate: { get: function () { @@ -568,7 +568,7 @@ Object.defineProperties(CesiumWidget.prototype, { * after the error. * @memberof CesiumWidget.prototype * - * @type {Boolean} + * @type {boolean} */ useDefaultRenderLoop: { get: function () { @@ -593,7 +593,7 @@ Object.defineProperties(CesiumWidget.prototype, { * it to 2.0 will cause the scene to be rendered at 1280x960 and then scaled down. * @memberof CesiumWidget.prototype * - * @type {Number} + * @type {number} * @default 1.0 */ resolutionScale: { @@ -622,7 +622,7 @@ Object.defineProperties(CesiumWidget.prototype, { * this flag is true or false. * @memberof CesiumWidget.prototype * - * @type {Boolean} + * @type {boolean} * @default true */ useBrowserRecommendedResolution: { @@ -644,9 +644,9 @@ Object.defineProperties(CesiumWidget.prototype, { * when a render loop error occurs, if showRenderLoopErrors was not false when the * widget was constructed. * - * @param {String} title The title to be displayed on the error panel. This string is interpreted as text. - * @param {String} [message] A helpful, user-facing message to display prior to the detailed error information. This string is interpreted as HTML. - * @param {String} [error] The error to be displayed on the error panel. This string is formatted using {@link formatError} and then displayed as text. + * @param {string} title The title to be displayed on the error panel. This string is interpreted as text. + * @param {string} [message] A helpful, user-facing message to display prior to the detailed error information. This string is interpreted as HTML. + * @param {string} [error] The error to be displayed on the error panel. This string is formatted using {@link formatError} and then displayed as text. */ CesiumWidget.prototype.showErrorPanel = function (title, message, error) { const element = this._element; @@ -748,7 +748,7 @@ CesiumWidget.prototype.showErrorPanel = function (title, message, error) { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ CesiumWidget.prototype.isDestroyed = function () { return false; diff --git a/packages/engine/Source/Workers/cesiumWorkerBootstrapper.js b/packages/engine/Source/Workers/cesiumWorkerBootstrapper.js index 2aaadd725d2..505a4b99b03 100644 --- a/packages/engine/Source/Workers/cesiumWorkerBootstrapper.js +++ b/packages/engine/Source/Workers/cesiumWorkerBootstrapper.js @@ -200,8 +200,8 @@ var requirejs, require, define; /** * Constructs an error with a pointer to an URL with more information. - * @param {String} id the error ID that maps to an ID on a web page. - * @param {String} msg human readable error. + * @param {string} id the error ID that maps to an ID on a web page. + * @param {string} msg human readable error. * @param {Error} [err] the original error, if there is one. * @param {RequireModules} requireModules The modules required but not found. * @private @@ -307,12 +307,12 @@ var requirejs, require, define; * @private * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. - * @param {String} name the relative name - * @param {String} baseName a real name that the name arg is relative + * @param {string} name the relative name + * @param {string} baseName a real name that the name arg is relative * to. - * @param {Boolean} applyMap apply the map config to the value. Should + * @param {boolean} applyMap apply the map config to the value. Should * only be done if this normalization is for a dependency ID. - * @returns {String} normalized name + * @returns {string} normalized name */ function normalize(name, baseName, applyMap) { var pkgMain, @@ -464,15 +464,15 @@ var requirejs, require, define; * name, and path. If parentModuleMap is provided it will * also normalize the name via require.normalize() * - * @param {String} name the module name - * @param {String} [parentModuleMap] parent module map + * @param {string} name the module name + * @param {string} [parentModuleMap] parent module map * for the module name, used to resolve relative names. - * @param {Boolean} isNormalized: is the ID already normalized. + * @param {boolean} isNormalized: is the ID already normalized. * This is true if this call is done for a define() module ID. - * @param {Boolean} applyMap: apply the map config to the ID. + * @param {boolean} applyMap: apply the map config to the ID. * Should only be true if this map is for a dependency. * @private - * @returns {Object} + * @returns {object} */ function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { var url, @@ -1341,7 +1341,7 @@ var requirejs, require, define; * and then removes the event listeners on the node. * @param {Event} evt * @private - * @returns {Object} + * @returns {object} */ function getScriptData(evt) { //Using currentTarget instead of target for Firefox 2.0's sake. Not @@ -1400,7 +1400,7 @@ var requirejs, require, define; /** * @private * Set a configuration for the context. - * @param {Object} cfg config object to integrate. + * @param {object} cfg config object to integrate. */ configure: function (cfg) { //Make sure the baseUrl ends in a slash. @@ -1695,7 +1695,7 @@ var requirejs, require, define; * Internal method used by environment adapters to complete a load event. * A load event could be a script load or just a load pass from a synchronous * load call. - * @param {String} moduleName the name of the module to potentially complete. + * @param {string} moduleName the name of the module to potentially complete. * @private */ completeLoad: function (moduleName) { @@ -2031,9 +2031,9 @@ var requirejs, require, define; * Make this a separate function to allow other environments * to override it. * - * @param {Object} context the require context to find state. - * @param {String} moduleName the name of the module. - * @param {Object} url the URL to the module. + * @param {object} context the require context to find state. + * @param {string} moduleName the name of the module. + * @param {object} url the URL to the module. */ req.load = function (context, moduleName, url) { var config = (context && context.config) || {}, @@ -2278,7 +2278,7 @@ var requirejs, require, define; * Executes the text. Normally just uses eval, but can be modified * to use a better, environment-specific call. Only used for transpiling * loader plugins, not for plain JS modules. - * @param {String} text the text to execute/evaluate. + * @param {string} text the text to execute/evaluate. */ req.exec = function (text) { /*jslint evil: true */ diff --git a/packages/engine/Source/WorkersES6/createTaskProcessorWorker.js b/packages/engine/Source/WorkersES6/createTaskProcessorWorker.js index 723214f6722..93f201dd4d1 100644 --- a/packages/engine/Source/WorkersES6/createTaskProcessorWorker.js +++ b/packages/engine/Source/WorkersES6/createTaskProcessorWorker.js @@ -100,10 +100,10 @@ function createTaskProcessorWorker(workerFunction) { * A function that performs a calculation in a Web Worker. * @callback createTaskProcessorWorker.WorkerFunction * - * @param {Object} parameters Parameters to the calculation. + * @param {object} parameters Parameters to the calculation. * @param {Array} transferableObjects An array that should be filled with references to objects inside * the result that should be transferred back to the main document instead of copied. - * @returns {Object} The result of the calculation. + * @returns {object} The result of the calculation. * * @example * function calculate(parameters, transferableObjects) { @@ -124,6 +124,6 @@ function createTaskProcessorWorker(workerFunction) { * specifically, task ID management and posting a response message containing the result. * @callback createTaskProcessorWorker.TaskProcessorWorkerFunction * - * @param {Object} event The onmessage event object. + * @param {object} event The onmessage event object. */ export default createTaskProcessorWorker; diff --git a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js index e0a90dfc689..a1c4c2d8a63 100644 --- a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js @@ -266,7 +266,7 @@ describe( * * @param {Ray} ray The ray to test for intersection. * @param {Scene} scene The scene. - * @return {Promise.<Boolean>} + * @return {Promise<boolean>} * * @private * diff --git a/packages/engine/Specs/Scene/ImplicitTileCoordinatesSpec.js b/packages/engine/Specs/Scene/ImplicitTileCoordinatesSpec.js index 59389097a5f..30d5c1e04f8 100644 --- a/packages/engine/Specs/Scene/ImplicitTileCoordinatesSpec.js +++ b/packages/engine/Specs/Scene/ImplicitTileCoordinatesSpec.js @@ -7,10 +7,10 @@ import { describe("Scene/ImplicitTileCoordinates", function () { /** * Helper function for creating quadtree implicit tile coordinates - * @param {Number} level - * @param {Number} x - * @param {Number} y - * @param {Number} [subtreeLevels=2] + * @param {number} level + * @param {number} x + * @param {number} y + * @param {number} [subtreeLevels=2] * @returns {ImplicitTileCoordinates} */ function quadtreeCoordinates(level, x, y, subtreeLevels) { @@ -25,11 +25,11 @@ describe("Scene/ImplicitTileCoordinates", function () { /** * Helper function for creating octree implicit tile coordinates - * @param {Number} level - * @param {Number} x - * @param {Number} y - * @param {Number} z - * @param {Number} [subtreeLevels=2] + * @param {number} level + * @param {number} x + * @param {number} y + * @param {number} z + * @param {number} [subtreeLevels=2] * @returns {ImplicitTileCoordinates} */ function octreeCoordinates(level, x, y, z, subtreeLevels) { diff --git a/packages/widgets/Source/Animation/Animation.js b/packages/widgets/Source/Animation/Animation.js index 3e1b2293eb8..5d2990993a0 100644 --- a/packages/widgets/Source/Animation/Animation.js +++ b/packages/widgets/Source/Animation/Animation.js @@ -409,7 +409,7 @@ SvgButton.prototype.setTooltip = function (tooltip) { * @alias Animation * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {AnimationViewModel} viewModel The view model used by this widget. * * @exception {DeveloperError} Element with id "container" does not exist in the document. @@ -736,7 +736,7 @@ Object.defineProperties(Animation.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Animation.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Animation/AnimationViewModel.js b/packages/widgets/Source/Animation/AnimationViewModel.js index 76364d3b2fc..864b0bc51e6 100644 --- a/packages/widgets/Source/Animation/AnimationViewModel.js +++ b/packages/widgets/Source/Animation/AnimationViewModel.js @@ -116,7 +116,7 @@ function AnimationViewModel(clockViewModel) { /** * Gets or sets whether the shuttle ring is currently being dragged. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.shuttleRingDragging = false; @@ -125,7 +125,7 @@ function AnimationViewModel(clockViewModel) { * Gets or sets whether dragging the shuttle ring should cause the multiplier * to snap to the defined tick values rather than interpolating between them. * This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.snapToTicks = false; @@ -144,7 +144,7 @@ function AnimationViewModel(clockViewModel) { /** * Gets the string representation of the current time. This property is observable. - * @type {String} + * @type {string} */ this.timeLabel = undefined; knockout.defineProperty(this, "timeLabel", function () { @@ -153,7 +153,7 @@ function AnimationViewModel(clockViewModel) { /** * Gets the string representation of the current date. This property is observable. - * @type {String} + * @type {string} */ this.dateLabel = undefined; knockout.defineProperty(this, "dateLabel", function () { @@ -162,7 +162,7 @@ function AnimationViewModel(clockViewModel) { /** * Gets the string representation of the current multiplier. This property is observable. - * @type {String} + * @type {string} */ this.multiplierLabel = undefined; knockout.defineProperty(this, "multiplierLabel", function () { @@ -184,7 +184,7 @@ function AnimationViewModel(clockViewModel) { /** * Gets or sets the current shuttle ring angle. This property is observable. - * @type {Number} + * @type {number} */ this.shuttleRingAngle = undefined; knockout.defineProperty(this, "shuttleRingAngle", { @@ -393,7 +393,7 @@ AnimationViewModel.defaultDateFormatter = function (date, viewModel) { /** * Gets or sets the default array of known clock multipliers associated with new instances of the shuttle ring. - * @type {Number[]} + * @type {number[]} */ AnimationViewModel.defaultTicks = [ // @@ -457,7 +457,7 @@ AnimationViewModel.defaultTimeFormatter = function (date, viewModel) { /** * Gets a copy of the array of positive known clock multipliers to associate with the shuttle ring. * - * @returns {Number[]} The array of known clock multipliers associated with the shuttle ring. + * @returns {number[]} The array of known clock multipliers associated with the shuttle ring. */ AnimationViewModel.prototype.getShuttleRingTicks = function () { return this._sortedFilteredPositiveTicks.slice(0); @@ -470,7 +470,7 @@ AnimationViewModel.prototype.getShuttleRingTicks = function () { * to when a single click is made. The values need not be in order, as they will be sorted * automatically, and duplicate values will be removed. * - * @param {Number[]} positiveTicks The list of known positive clock multipliers to associate with the shuttle ring. + * @param {number[]} positiveTicks The list of known positive clock multipliers to associate with the shuttle ring. */ AnimationViewModel.prototype.setShuttleRingTicks = function (positiveTicks) { //>>includeStart('debug', pragmas.debug); @@ -648,7 +648,7 @@ AnimationViewModel._realtimeShuttleRingAngle = realtimeShuttleRingAngle; * * @param {JulianDate} date The date to be formatted * @param {AnimationViewModel} viewModel The AnimationViewModel instance requesting formatting. - * @returns {String} The string representation of the calendar date portion of the provided date. + * @returns {string} The string representation of the calendar date portion of the provided date. */ /** @@ -657,6 +657,6 @@ AnimationViewModel._realtimeShuttleRingAngle = realtimeShuttleRingAngle; * * @param {JulianDate} date The date to be formatted * @param {AnimationViewModel} viewModel The AnimationViewModel instance requesting formatting. - * @returns {String} The string representation of the time portion of the provided date. + * @returns {string} The string representation of the time portion of the provided date. */ export default AnimationViewModel; diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js index efae36d6ac9..80d145593e4 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js @@ -24,8 +24,8 @@ import BaseLayerPickerViewModel from "./BaseLayerPickerViewModel.js"; * @alias BaseLayerPicker * @constructor * - * @param {Element|String} container The parent HTML container node or ID for this widget. - * @param {Object} options Object with the following properties: + * @param {Element|string} container The parent HTML container node or ID for this widget. + * @param {object} options Object with the following properties: * @param {Globe} options.globe The Globe to use. * @param {ProviderViewModel[]} [options.imageryProviderViewModels=[]] The array of ProviderViewModel instances to use for imagery. * @param {ProviderViewModel} [options.selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available imagery layer is used. @@ -282,7 +282,7 @@ Object.defineProperties(BaseLayerPicker.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ BaseLayerPicker.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js index fbb4c6fad45..220b1af4217 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -12,7 +12,7 @@ import createCommand from "../createCommand.js"; * @alias BaseLayerPickerViewModel * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Globe} options.globe The Globe to use. * @param {ProviderViewModel[]} [options.imageryProviderViewModels=[]] The array of ProviderViewModel instances to use for imagery. * @param {ProviderViewModel} [options.selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available imagery layer is used. @@ -59,7 +59,7 @@ function BaseLayerPickerViewModel(options) { /** * Gets or sets whether the imagery selection drop-down is currently visible. - * @type {Boolean} + * @type {boolean} * @default false */ this.dropDownVisible = false; @@ -134,7 +134,7 @@ function BaseLayerPickerViewModel(options) { /** * Gets the button tooltip. This property is observable. - * @type {String} + * @type {string} */ this.buttonTooltip = undefined; knockout.defineProperty(this, "buttonTooltip", function () { @@ -158,7 +158,7 @@ function BaseLayerPickerViewModel(options) { /** * Gets the button background image. This property is observable. - * @type {String} + * @type {string} */ this.buttonImageUrl = undefined; knockout.defineProperty(this, "buttonImageUrl", function () { diff --git a/packages/widgets/Source/BaseLayerPicker/ProviderViewModel.js b/packages/widgets/Source/BaseLayerPicker/ProviderViewModel.js index 8e480dc4a62..5d8178cfb6d 100644 --- a/packages/widgets/Source/BaseLayerPicker/ProviderViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/ProviderViewModel.js @@ -8,11 +8,11 @@ import createCommand from "../createCommand.js"; * @alias ProviderViewModel * @constructor * - * @param {Object} options The object containing all parameters. - * @param {String} options.name The name of the layer. - * @param {String} options.tooltip The tooltip to show when the item is moused over. - * @param {String} options.iconUrl An icon representing the layer. - * @param {String} [options.category] A category for the layer. + * @param {object} options The object containing all parameters. + * @param {string} options.name The name of the layer. + * @param {string} options.tooltip The tooltip to show when the item is moused over. + * @param {string} options.iconUrl An icon representing the layer. + * @param {string} [options.category] A category for the layer. * @param {ProviderViewModel.CreationFunction|Command} options.creationFunction A function or Command * that creates one or more providers which will be added to the globe when this item is selected. * @@ -45,19 +45,19 @@ function ProviderViewModel(options) { /** * Gets the display name. This property is observable. - * @type {String} + * @type {string} */ this.name = options.name; /** * Gets the tooltip. This property is observable. - * @type {String} + * @type {string} */ this.tooltip = options.tooltip; /** * Gets the icon. This property is observable. - * @type {String} + * @type {string} */ this.iconUrl = options.iconUrl; @@ -83,7 +83,7 @@ Object.defineProperties(ProviderViewModel.prototype, { /** * Gets the category - * @type {String} + * @type {string} * @memberof ProviderViewModel.prototype * @readonly */ diff --git a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js index 41733257ff7..a88bb400ae9 100644 --- a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js +++ b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspector.js @@ -9,7 +9,7 @@ import Cesium3DTilesInspectorViewModel from "./Cesium3DTilesInspectorViewModel.j * @alias Cesium3DTilesInspector * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene the Scene instance to use. */ function Cesium3DTilesInspector(container, scene) { @@ -360,7 +360,7 @@ Object.defineProperties(Cesium3DTilesInspector.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Cesium3DTilesInspector.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js index 80027edd984..60c337fc9b7 100644 --- a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js +++ b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js @@ -192,7 +192,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to enable performance display. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.performance = false; @@ -200,7 +200,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show statistics. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showStatistics = true; @@ -208,7 +208,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show pick statistics. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default true */ this.showPickStatistics = true; @@ -217,7 +217,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { * Gets or sets the flag to show resource cache statistics. This property is * observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showResourceCacheStatistics = false; @@ -225,7 +225,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the inspector. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default true */ this.inspectorVisible = true; @@ -233,7 +233,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the tileset section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.tilesetVisible = false; @@ -241,7 +241,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the display section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.displayVisible = false; @@ -249,7 +249,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the update section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.updateVisible = false; @@ -257,7 +257,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the logging section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.loggingVisible = false; @@ -265,7 +265,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the style section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.styleVisible = false; @@ -273,7 +273,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the tile info section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.tileDebugLabelsVisible = false; @@ -281,7 +281,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the optimization info section. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false; */ this.optimizationVisible = false; @@ -289,7 +289,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the JSON for the tileset style. This property is observable. * - * @type {String} + * @type {string} * @default '{}' */ this.styleString = "{}"; @@ -297,7 +297,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the JSON for the tileset enableDebugWireframe attribute. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.hasEnabledWireframe = false; @@ -333,7 +333,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { this._properties = knockout.observable({}); /** * Gets the names of the properties in the tileset. This property is observable. - * @type {String[]} + * @type {string[]} * @readonly */ this.properties = []; @@ -363,7 +363,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to enable dynamic screen space error. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.dynamicScreenSpaceError = false; @@ -444,7 +444,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to enable picking. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default true */ this.picking = true; @@ -465,7 +465,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to colorize tiles. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.colorize = false; @@ -486,7 +486,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to draw with wireframe. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.wireframe = false; @@ -507,7 +507,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show bounding volumes. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showBoundingVolumes = false; @@ -528,7 +528,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show content volumes. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showContentBoundingVolumes = false; @@ -549,7 +549,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show request volumes. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showRequestVolumes = false; @@ -571,7 +571,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to suspend updates. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.freezeFrame = false; @@ -591,7 +591,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show debug labels only for the currently picked tile. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showOnlyPickedTileDebugLabel = false; @@ -612,7 +612,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show tile geometric error. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showGeometricError = false; @@ -633,7 +633,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Displays the number of commands, points, triangles and features used per tile. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showRenderingStatistics = false; @@ -654,7 +654,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Displays the memory used per tile. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showMemoryUsage = false; @@ -675,7 +675,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to show the tile url. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.showUrl = false; @@ -698,7 +698,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the maximum screen space error. This property is observable. * - * @type {Number} + * @type {number} * @default 16 */ this.maximumScreenSpaceError = 16; @@ -721,7 +721,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the dynamic screen space error density. This property is observable. * - * @type {Number} + * @type {number} * @default 0.00278 */ this.dynamicScreenSpaceErrorDensity = 0.00278; @@ -731,7 +731,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { * This allows the slider to be exponential because values tend to be closer to 0 than 1. * This property is observable. * - * @type {Number} + * @type {number} * @default 0.00278 */ this.dynamicScreenSpaceErrorDensitySliderValue = undefined; @@ -762,7 +762,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the dynamic screen space error factor. This property is observable. * - * @type {Number} + * @type {number} * @default 4.0 */ this.dynamicScreenSpaceErrorFactor = 4.0; @@ -801,7 +801,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to enable point cloud shading. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.pointCloudShading = false; @@ -824,7 +824,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the geometric error scale. This property is observable. * - * @type {Number} + * @type {number} * @default 1.0 */ this.geometricErrorScale = 1.0; @@ -848,7 +848,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the maximum attenuation. This property is observable. * - * @type {Number} + * @type {number} * @default 0 */ this.maximumAttenuation = 0; @@ -872,7 +872,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the base resolution. This property is observable. * - * @type {Number} + * @type {number} * @default 0 */ this.baseResolution = 0; @@ -892,7 +892,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to enable eye dome lighting. This property is observable. * - * @type {Boolean} + * @type {boolean} * @default false */ this.eyeDomeLighting = false; @@ -915,7 +915,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the eye dome lighting strength. This property is observable. * - * @type {Number} + * @type {number} * @default 1.0 */ this.eyeDomeLightingStrength = 1.0; @@ -938,7 +938,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the eye dome lighting radius. This property is observable. * - * @type {Number} + * @type {number} * @default 1.0 */ this.eyeDomeLightingRadius = 1.0; @@ -946,7 +946,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the pick state * - * @type {Boolean} + * @type {boolean} * @default false */ this.pickActive = false; @@ -966,7 +966,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag to determine if level of detail skipping should be applied during the traversal. * This property is observable. - * @type {Boolean} + * @type {boolean} * @default true */ this.skipLevelOfDetail = true; @@ -988,7 +988,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { }); /** * Gets or sets the multiplier defining the minimum screen space error to skip. This property is observable. - * @type {Number} + * @type {number} * @default 16 */ this.skipScreenSpaceErrorFactor = 16; @@ -1010,7 +1010,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { }); /** * Gets or sets the screen space error that must be reached before skipping levels of detail. This property is observable. - * @type {Number} + * @type {number} * @default 1024 */ this.baseScreenSpaceError = 1024; @@ -1032,7 +1032,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { }); /** * Gets or sets the constant defining the minimum number of levels to skip when loading tiles. This property is observable. - * @type {Number} + * @type {number} * @default 1 */ this.skipLevels = 1; @@ -1052,7 +1052,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag which, when true, only tiles that meet the maximum screen space error will ever be downloaded. * This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.immediatelyLoadDesiredLevelOfDetail = false; @@ -1072,7 +1072,7 @@ function Cesium3DTilesInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the flag which determines whether siblings of visible tiles are always downloaded during traversal. * This property is observable - * @type {Boolean} + * @type {boolean} * @default false */ this.loadSiblings = false; @@ -1150,7 +1150,7 @@ Object.defineProperties(Cesium3DTilesInspectorViewModel.prototype, { /** * Gets the statistics text. This property is observable. * @memberof Cesium3DTilesInspectorViewModel.prototype - * @type {String} + * @type {string} * @readonly */ statisticsText: { @@ -1161,7 +1161,7 @@ Object.defineProperties(Cesium3DTilesInspectorViewModel.prototype, { /** * Gets the pick statistics text. This property is observable. * @memberof Cesium3DTilesInspectorViewModel.prototype - * @type {String} + * @type {string} * @readonly */ pickStatisticsText: { @@ -1173,7 +1173,7 @@ Object.defineProperties(Cesium3DTilesInspectorViewModel.prototype, { /** * Gets the resource cache statistics text. This property is observable. * @memberof Cesium3DTilesInspectorViewModel.prototype - * @type {String} + * @type {string} * @readonly */ resourceCacheStatisticsText: { @@ -1197,7 +1197,7 @@ Object.defineProperties(Cesium3DTilesInspectorViewModel.prototype, { /** * Gets the editor error message * @memberof Cesium3DTilesInspectorViewModel.prototype - * @type {String} + * @type {string} * @readonly */ editorError: { @@ -1569,7 +1569,7 @@ Cesium3DTilesInspectorViewModel.prototype._update = function () { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Cesium3DTilesInspectorViewModel.prototype.isDestroyed = function () { return false; @@ -1596,8 +1596,8 @@ Cesium3DTilesInspectorViewModel.prototype.destroy = function () { * * @function * @param {Cesium3DTileset} tileset The tileset - * @param {Boolean} isPick Whether this is getting the statistics for the pick pass - * @returns {String} The formatted statistics + * @param {boolean} isPick Whether this is getting the statistics for the pick pass + * @returns {string} The formatted statistics */ Cesium3DTilesInspectorViewModel.getStatistics = getStatistics; export default Cesium3DTilesInspectorViewModel; diff --git a/packages/widgets/Source/CesiumInspector/CesiumInspector.js b/packages/widgets/Source/CesiumInspector/CesiumInspector.js index 9152cfd3a8d..54129b65417 100644 --- a/packages/widgets/Source/CesiumInspector/CesiumInspector.js +++ b/packages/widgets/Source/CesiumInspector/CesiumInspector.js @@ -14,7 +14,7 @@ import CesiumInspectorViewModel from "./CesiumInspectorViewModel.js"; * @alias CesiumInspector * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. * * @demo {@link https://sandcastle.cesium.com/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo} @@ -303,7 +303,7 @@ Object.defineProperties(CesiumInspector.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ CesiumInspector.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/CesiumInspector/CesiumInspectorViewModel.js b/packages/widgets/Source/CesiumInspector/CesiumInspectorViewModel.js index 70d59afed3d..25eb458a661 100644 --- a/packages/widgets/Source/CesiumInspector/CesiumInspectorViewModel.js +++ b/packages/widgets/Source/CesiumInspector/CesiumInspectorViewModel.js @@ -90,77 +90,77 @@ function CesiumInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the show frustums state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.frustums = false; /** * Gets or sets the show frustum planes state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.frustumPlanes = false; /** * Gets or sets the show performance display state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.performance = false; /** * Gets or sets the shader cache text. This property is observable. - * @type {String} + * @type {string} * @default '' */ this.shaderCacheText = ""; /** * Gets or sets the show primitive bounding sphere state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.primitiveBoundingSphere = false; /** * Gets or sets the show primitive reference frame state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.primitiveReferenceFrame = false; /** * Gets or sets the filter primitive state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.filterPrimitive = false; /** * Gets or sets the show tile bounding sphere state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.tileBoundingSphere = false; /** * Gets or sets the filter tile state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.filterTile = false; /** * Gets or sets the show wireframe state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.wireframe = false; /** * Gets or sets the index of the depth frustum to display. This property is observable. - * @type {Number} + * @type {number} * @default 1 */ this.depthFrustum = 1; @@ -168,91 +168,91 @@ function CesiumInspectorViewModel(scene, performanceContainer) { /** * Gets or sets the suspend updates state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.suspendUpdates = false; /** * Gets or sets the show tile coordinates state. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.tileCoordinates = false; /** * Gets or sets the frustum statistic text. This property is observable. - * @type {String} + * @type {string} * @default '' */ this.frustumStatisticText = false; /** * Gets or sets the selected tile information text. This property is observable. - * @type {String} + * @type {string} * @default '' */ this.tileText = ""; /** * Gets if a primitive has been selected. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.hasPickedPrimitive = false; /** * Gets if a tile has been selected. This property is observable - * @type {Boolean} + * @type {boolean} * @default false */ this.hasPickedTile = false; /** * Gets if the picking primitive command is active. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.pickPrimitiveActive = false; /** * Gets if the picking tile command is active. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.pickTileActive = false; /** * Gets or sets if the cesium inspector drop down is visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default true */ this.dropDownVisible = true; /** * Gets or sets if the general section is visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default true */ this.generalVisible = true; /** * Gets or sets if the primitive section is visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.primitivesVisible = false; /** * Gets or sets if the terrain section is visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.terrainVisible = false; /** * Gets or sets the index of the depth frustum text. This property is observable. - * @type {String} + * @type {string} * @default '' */ this.depthFrustumText = ""; @@ -948,7 +948,7 @@ CesiumInspectorViewModel.prototype._update = function () { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ CesiumInspectorViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/ClockViewModel.js b/packages/widgets/Source/ClockViewModel.js index b6f05685725..01a7e7e821a 100644 --- a/packages/widgets/Source/ClockViewModel.js +++ b/packages/widgets/Source/ClockViewModel.js @@ -76,7 +76,7 @@ function ClockViewModel(clock) { * Gets or sets the clock multiplier. * See {@link Clock#multiplier}. * This property is observable. - * @type {Number} + * @type {number} */ this.multiplier = knockout.observable(clock.multiplier); this.multiplier.subscribe(function (value) { @@ -112,7 +112,7 @@ function ClockViewModel(clock) { * Gets or sets whether the clock can animate. * See {@link Clock#canAnimate}. * This property is observable. - * @type {Boolean} + * @type {boolean} */ this.canAnimate = knockout.observable(clock.canAnimate); this.canAnimate.subscribe(function (value) { @@ -124,7 +124,7 @@ function ClockViewModel(clock) { * Gets or sets whether the clock should animate. * See {@link Clock#shouldAnimate}. * This property is observable. - * @type {Boolean} + * @type {boolean} */ this.shouldAnimate = knockout.observable(clock.shouldAnimate); this.shouldAnimate.subscribe(function (value) { @@ -178,7 +178,7 @@ ClockViewModel.prototype.synchronize = function () { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ ClockViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Command.js b/packages/widgets/Source/Command.js index 9a41c4fc4c1..67b235125d1 100644 --- a/packages/widgets/Source/Command.js +++ b/packages/widgets/Source/Command.js @@ -14,7 +14,7 @@ import { DeveloperError } from "@cesium/engine"; function Command() { /** * Gets whether this command can currently be executed. This property is observable. - * @type {Boolean} + * @type {boolean} * @default undefined */ this.canExecute = undefined; diff --git a/packages/widgets/Source/FullscreenButton/FullscreenButton.js b/packages/widgets/Source/FullscreenButton/FullscreenButton.js index 28c720d0c11..4dd5a677ae7 100644 --- a/packages/widgets/Source/FullscreenButton/FullscreenButton.js +++ b/packages/widgets/Source/FullscreenButton/FullscreenButton.js @@ -18,8 +18,8 @@ const exitFullScreenPath = * @alias FullscreenButton * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. - * @param {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode. + * @param {Element|string} container The DOM element or ID that will contain the widget. + * @param {Element|string} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @@ -87,7 +87,7 @@ Object.defineProperties(FullscreenButton.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ FullscreenButton.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/FullscreenButton/FullscreenButtonViewModel.js b/packages/widgets/Source/FullscreenButton/FullscreenButtonViewModel.js index 7456f140f5b..15e01ec5ba1 100644 --- a/packages/widgets/Source/FullscreenButton/FullscreenButtonViewModel.js +++ b/packages/widgets/Source/FullscreenButton/FullscreenButtonViewModel.js @@ -14,8 +14,8 @@ import createCommand from "../createCommand.js"; * @alias FullscreenButtonViewModel * @constructor * - * @param {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode. - * @param {Element|String} [container] The DOM element or ID that will contain the widget. + * @param {Element|string} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode. + * @param {Element|string} [container] The DOM element or ID that will contain the widget. */ function FullscreenButtonViewModel(fullscreenElement, container) { if (!defined(container)) { @@ -33,7 +33,7 @@ function FullscreenButtonViewModel(fullscreenElement, container) { /** * Gets whether or not fullscreen mode is active. This property is observable. * - * @type {Boolean} + * @type {boolean} */ this.isFullscreen = undefined; knockout.defineProperty(this, "isFullscreen", { @@ -45,7 +45,7 @@ function FullscreenButtonViewModel(fullscreenElement, container) { /** * Gets or sets whether or not fullscreen functionality should be enabled. This property is observable. * - * @type {Boolean} + * @type {boolean} * @see Fullscreen.enabled */ this.isFullscreenEnabled = undefined; @@ -61,7 +61,7 @@ function FullscreenButtonViewModel(fullscreenElement, container) { /** * Gets the tooltip. This property is observable. * - * @type {String} + * @type {string} */ this.tooltip = undefined; knockout.defineProperty(this, "tooltip", function () { @@ -128,7 +128,7 @@ Object.defineProperties(FullscreenButtonViewModel.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ FullscreenButtonViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Geocoder/Geocoder.js b/packages/widgets/Source/Geocoder/Geocoder.js index 8ab416a9c94..f6ab8080ea3 100644 --- a/packages/widgets/Source/Geocoder/Geocoder.js +++ b/packages/widgets/Source/Geocoder/Geocoder.js @@ -20,12 +20,12 @@ const stopSearchPath = * @alias Geocoder * @constructor * - * @param {Object} options Object with the following properties: - * @param {Element|String} options.container The DOM element or ID that will contain the widget. + * @param {object} options Object with the following properties: + * @param {Element|string} options.container The DOM element or ID that will contain the widget. * @param {Scene} options.scene The Scene instance to use. * @param {GeocoderService[]} [options.geocoderServices] The geocoder services to be used - * @param {Boolean} [options.autoComplete = true] True if the geocoder should query as the user types to autocomplete - * @param {Number} [options.flightDuration=1.5] The duration of the camera flight to an entered location, in seconds. + * @param {boolean} [options.autoComplete = true] True if the geocoder should query as the user types to autocomplete + * @param {number} [options.flightDuration=1.5] The duration of the camera flight to an entered location, in seconds. * @param {Geocoder.DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination. */ function Geocoder(options) { @@ -193,7 +193,7 @@ Object.defineProperties(Geocoder.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Geocoder.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Geocoder/GeocoderViewModel.js b/packages/widgets/Source/Geocoder/GeocoderViewModel.js index 61a22235a6f..23cdc521cfd 100644 --- a/packages/widgets/Source/Geocoder/GeocoderViewModel.js +++ b/packages/widgets/Source/Geocoder/GeocoderViewModel.js @@ -24,12 +24,12 @@ const DEFAULT_HEIGHT = 1000; * @alias GeocoderViewModel * @constructor * - * @param {Object} options Object with the following properties: + * @param {object} options Object with the following properties: * @param {Scene} options.scene The Scene instance to use. * @param {GeocoderService[]} [options.geocoderServices] Geocoder services to use for geocoding queries. * If more than one are supplied, suggestions will be gathered for the geocoders that support it, * and if no suggestion is selected the result from the first geocoder service wil be used. - * @param {Number} [options.flightDuration] The duration of the camera flight to an entered location, in seconds. + * @param {number} [options.flightDuration] The duration of the camera flight to an entered location, in seconds. * @param {Geocoder.DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination. */ function GeocoderViewModel(options) { @@ -144,14 +144,14 @@ function GeocoderViewModel(options) { /** * Gets or sets a value indicating if this instance should always show its text input field. * - * @type {Boolean} + * @type {boolean} * @default false */ this.keepExpanded = false; /** * True if the geocoder should query as the user types to autocomplete - * @type {Boolean} + * @type {boolean} * @default true */ this.autoComplete = defaultValue(options.autocomplete, true); @@ -185,7 +185,7 @@ function GeocoderViewModel(options) { /** * Gets a value indicating whether a search is currently in progress. This property is observable. * - * @type {Boolean} + * @type {boolean} */ this.isSearchInProgress = undefined; knockout.defineProperty(this, "isSearchInProgress", { @@ -198,7 +198,7 @@ function GeocoderViewModel(options) { * Gets or sets the text to search for. The text can be an address, or longitude, latitude, * and optional height, where longitude and latitude are in degrees and height is in meters. * - * @type {String} + * @type {string} */ this.searchText = undefined; knockout.defineProperty(this, "searchText", { @@ -224,7 +224,7 @@ function GeocoderViewModel(options) { * A value of zero causes the camera to instantly switch to the geocoding location. * The duration will be computed based on the distance when undefined. * - * @type {Number|undefined} + * @type {number|undefined} * @default undefined */ this.flightDuration = undefined; @@ -285,7 +285,7 @@ Object.defineProperties(GeocoderViewModel.prototype, { * Gets the currently selected geocoder search suggestion * @memberof GeocoderViewModel.prototype * - * @type {Object} + * @type {object} */ selectedSuggestion: { get: function () { diff --git a/packages/widgets/Source/HomeButton/HomeButton.js b/packages/widgets/Source/HomeButton/HomeButton.js index 63836aa8815..342a7d8ab93 100644 --- a/packages/widgets/Source/HomeButton/HomeButton.js +++ b/packages/widgets/Source/HomeButton/HomeButton.js @@ -13,9 +13,9 @@ import HomeButtonViewModel from "./HomeButtonViewModel.js"; * @alias HomeButton * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. - * @param {Number} [duration] The time, in seconds, it takes to complete the camera flight home. + * @param {number} [duration] The time, in seconds, it takes to complete the camera flight home. */ function HomeButton(container, scene, duration) { //>>includeStart('debug', pragmas.debug); @@ -78,7 +78,7 @@ Object.defineProperties(HomeButton.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ HomeButton.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/HomeButton/HomeButtonViewModel.js b/packages/widgets/Source/HomeButton/HomeButtonViewModel.js index b1688ca05d5..ba030c36607 100644 --- a/packages/widgets/Source/HomeButton/HomeButtonViewModel.js +++ b/packages/widgets/Source/HomeButton/HomeButtonViewModel.js @@ -8,7 +8,7 @@ import createCommand from "../createCommand.js"; * @constructor * * @param {Scene} scene The scene instance to use. - * @param {Number} [duration] The duration of the camera flight in seconds. + * @param {number} [duration] The duration of the camera flight in seconds. */ function HomeButtonViewModel(scene, duration) { //>>includeStart('debug', pragmas.debug); @@ -28,7 +28,7 @@ function HomeButtonViewModel(scene, duration) { /** * Gets or sets the tooltip. This property is observable. * - * @type {String} + * @type {string} */ this.tooltip = "View Home"; @@ -66,7 +66,7 @@ Object.defineProperties(HomeButtonViewModel.prototype, { * The duration will be computed based on the distance when undefined. * @memberof HomeButtonViewModel.prototype * - * @type {Number|undefined} + * @type {number|undefined} */ duration: { get: function () { diff --git a/packages/widgets/Source/InfoBox/InfoBox.js b/packages/widgets/Source/InfoBox/InfoBox.js index e865ba9615a..82dda94f90c 100644 --- a/packages/widgets/Source/InfoBox/InfoBox.js +++ b/packages/widgets/Source/InfoBox/InfoBox.js @@ -16,7 +16,7 @@ import InfoBoxViewModel from "./InfoBoxViewModel.js"; * @alias InfoBox * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * * @exception {DeveloperError} Element with id "container" does not exist in the document. */ @@ -185,7 +185,7 @@ Object.defineProperties(InfoBox.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ InfoBox.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/InfoBox/InfoBoxViewModel.js b/packages/widgets/Source/InfoBox/InfoBoxViewModel.js index f78a97a0e09..21603e73e89 100644 --- a/packages/widgets/Source/InfoBox/InfoBoxViewModel.js +++ b/packages/widgets/Source/InfoBox/InfoBoxViewModel.js @@ -17,37 +17,37 @@ function InfoBoxViewModel() { /** * Gets or sets the maximum height of the info box in pixels. This property is observable. - * @type {Number} + * @type {number} */ this.maxHeight = 500; /** * Gets or sets whether the camera tracking icon is enabled. - * @type {Boolean} + * @type {boolean} */ this.enableCamera = false; /** * Gets or sets the status of current camera tracking of the selected object. - * @type {Boolean} + * @type {boolean} */ this.isCameraTracking = false; /** * Gets or sets the visibility of the info box. - * @type {Boolean} + * @type {boolean} */ this.showInfo = false; /** * Gets or sets the title text in the info box. - * @type {String} + * @type {string} */ this.titleText = ""; /** * Gets or sets the description HTML for the info box. - * @type {String} + * @type {string} */ this.description = ""; @@ -65,7 +65,7 @@ function InfoBoxViewModel() { /** * Gets the SVG path of the camera icon, which can change to be "crossed out" or not. - * @type {String} + * @type {string} */ this.cameraIconPath = undefined; knockout.defineProperty(this, "cameraIconPath", { @@ -85,8 +85,8 @@ function InfoBoxViewModel() { /** * Gets the maximum height of sections within the info box, minus an offset, in CSS-ready form. - * @param {Number} offset The offset in pixels. - * @returns {String} + * @param {number} offset The offset in pixels. + * @returns {string} */ InfoBoxViewModel.prototype.maxHeightOffset = function (offset) { return `${this.maxHeight - offset}px`; diff --git a/packages/widgets/Source/InspectorShared.js b/packages/widgets/Source/InspectorShared.js index f503a1cb935..25e4d1326b8 100644 --- a/packages/widgets/Source/InspectorShared.js +++ b/packages/widgets/Source/InspectorShared.js @@ -8,9 +8,9 @@ const InspectorShared = {}; /** * Creates a checkbox component - * @param {String} labelText The text to display in the checkbox label - * @param {String} checkedBinding The name of the variable used for checked binding - * @param {String} [enableBinding] The name of the variable used for enable binding + * @param {string} labelText The text to display in the checkbox label + * @param {string} checkedBinding The name of the variable used for checked binding + * @param {string} [enableBinding] The name of the variable used for enable binding * @return {Element} */ InspectorShared.createCheckbox = function ( @@ -41,9 +41,9 @@ InspectorShared.createCheckbox = function ( /** * Creates a section element * @param {Element} panel The parent element - * @param {String} headerText The text to display at the top of the section - * @param {String} sectionVisibleBinding The name of the variable used for visible binding - * @param {String} toggleSectionVisibilityBinding The name of the function used to toggle visibility + * @param {string} headerText The text to display at the top of the section + * @param {string} sectionVisibleBinding The name of the variable used for visible binding + * @param {string} toggleSectionVisibilityBinding The name of the function used to toggle visibility * @return {Element} */ InspectorShared.createSection = function ( @@ -86,12 +86,12 @@ InspectorShared.createSection = function ( /** * Creates a range input - * @param {String} rangeText The text to display - * @param {String} sliderValueBinding The name of the variable used for slider value binding - * @param {Number} min The minimum value - * @param {Number} max The maximum value - * @param {Number} [step] The step size. Defaults to "any". - * @param {String} [inputValueBinding] The name of the variable used for input value binding + * @param {string} rangeText The text to display + * @param {string} sliderValueBinding The name of the variable used for slider value binding + * @param {number} min The minimum value + * @param {number} max The maximum value + * @param {number} [step] The step size. Defaults to "any". + * @param {string} [inputValueBinding] The name of the variable used for input value binding * @return {Element} */ InspectorShared.createRangeInput = function ( @@ -138,9 +138,9 @@ InspectorShared.createRangeInput = function ( /** * Creates a button component - * @param {String} buttonText The button text - * @param {String} clickedBinding The name of the variable used for clicked binding - * @param {String} [activeBinding] The name of the variable used for active binding + * @param {string} buttonText The button text + * @param {string} clickedBinding The name of the variable used for clicked binding + * @param {string} [activeBinding] The name of the variable used for active binding * @return {Element} */ InspectorShared.createButton = function ( diff --git a/packages/widgets/Source/NavigationHelpButton/NavigationHelpButton.js b/packages/widgets/Source/NavigationHelpButton/NavigationHelpButton.js index e86471f60e2..05b7573eb54 100644 --- a/packages/widgets/Source/NavigationHelpButton/NavigationHelpButton.js +++ b/packages/widgets/Source/NavigationHelpButton/NavigationHelpButton.js @@ -17,9 +17,9 @@ import NavigationHelpButtonViewModel from "./NavigationHelpButtonViewModel.js"; * @alias NavigationHelpButton * @constructor * - * @param {Object} options Object with the following properties: - * @param {Element|String} options.container The DOM element or ID that will contain the widget. - * @param {Boolean} [options.instructionsInitiallyVisible=false] True if the navigation instructions should initially be visible; otherwise, false. + * @param {object} options Object with the following properties: + * @param {Element|string} options.container The DOM element or ID that will contain the widget. + * @param {boolean} [options.instructionsInitiallyVisible=false] True if the navigation instructions should initially be visible; otherwise, false. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @@ -249,7 +249,7 @@ Object.defineProperties(NavigationHelpButton.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ NavigationHelpButton.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/NavigationHelpButton/NavigationHelpButtonViewModel.js b/packages/widgets/Source/NavigationHelpButton/NavigationHelpButtonViewModel.js index 32d89d744b4..804eef30774 100644 --- a/packages/widgets/Source/NavigationHelpButton/NavigationHelpButtonViewModel.js +++ b/packages/widgets/Source/NavigationHelpButton/NavigationHelpButtonViewModel.js @@ -9,7 +9,7 @@ import createCommand from "../createCommand.js"; function NavigationHelpButtonViewModel() { /** * Gets or sets whether the instructions are currently shown. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.showInstructions = false; @@ -30,7 +30,7 @@ function NavigationHelpButtonViewModel() { /** * Gets or sets the tooltip. This property is observable. * - * @type {String} + * @type {string} */ this.tooltip = "Navigation Instructions"; diff --git a/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdog.js b/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdog.js index 046bb84bffc..085bb0ebb89 100644 --- a/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdog.js +++ b/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdog.js @@ -13,10 +13,10 @@ import PerformanceWatchdogViewModel from "./PerformanceWatchdogViewModel.js"; * @alias PerformanceWatchdog * @constructor * - * @param {Object} [options] Object with the following properties: - * @param {Element|String} options.container The DOM element or ID that will contain the widget. + * @param {object} [options] Object with the following properties: + * @param {Element|string} options.container The DOM element or ID that will contain the widget. * @param {Scene} options.scene The {@link Scene} for which to monitor performance. - * @param {String} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The + * @param {string} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The * message to display when a low frame rate is detected. The message is interpeted as HTML, so make sure * it comes from a trusted source so that your application is not vulnerable to cross-site scripting attacks. */ @@ -87,7 +87,7 @@ Object.defineProperties(PerformanceWatchdog.prototype, { /** * @memberof PerformanceWatchdog - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ PerformanceWatchdog.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdogViewModel.js b/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdogViewModel.js index 3a47f583ad6..5f0fd411344 100644 --- a/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdogViewModel.js +++ b/packages/widgets/Source/PerformanceWatchdog/PerformanceWatchdogViewModel.js @@ -14,9 +14,9 @@ import createCommand from "../createCommand.js"; * @alias PerformanceWatchdogViewModel * @constructor * - * @param {Object} [options] Object with the following properties: + * @param {object} [options] Object with the following properties: * @param {Scene} options.scene The Scene instance for which to monitor performance. - * @param {String} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The + * @param {string} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The * message to display when a low frame rate is detected. The message is interpeted as HTML, so make sure * it comes from a trusted source so that your application is not vulnerable to cross-site scripting attacks. */ @@ -31,7 +31,7 @@ function PerformanceWatchdogViewModel(options) { /** * Gets or sets the message to display when a low frame rate is detected. This string will be interpreted as HTML. - * @type {String} + * @type {string} */ this.lowFrameRateMessage = defaultValue( options.lowFrameRateMessage, @@ -41,13 +41,13 @@ function PerformanceWatchdogViewModel(options) { /** * Gets or sets a value indicating whether the low frame rate message has previously been dismissed by the user. If it has * been dismissed, the message will not be redisplayed, no matter the frame rate. - * @type {Boolean} + * @type {boolean} */ this.lowFrameRateMessageDismissed = false; /** * Gets or sets a value indicating whether the low frame rate message is currently being displayed. - * @type {Boolean} + * @type {boolean} */ this.showingLowFrameRateMessage = false; diff --git a/packages/widgets/Source/ProjectionPicker/ProjectionPicker.js b/packages/widgets/Source/ProjectionPicker/ProjectionPicker.js index b421fc1e249..d1cc1dee8ca 100644 --- a/packages/widgets/Source/ProjectionPicker/ProjectionPicker.js +++ b/packages/widgets/Source/ProjectionPicker/ProjectionPicker.js @@ -19,7 +19,7 @@ const orthographicPath = * @alias ProjectionPicker * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. * * @exception {DeveloperError} Element with id "container" does not exist in the document. @@ -149,7 +149,7 @@ Object.defineProperties(ProjectionPicker.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ ProjectionPicker.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/ProjectionPicker/ProjectionPickerViewModel.js b/packages/widgets/Source/ProjectionPicker/ProjectionPickerViewModel.js index d772112e71f..bf51b586a9a 100644 --- a/packages/widgets/Source/ProjectionPicker/ProjectionPickerViewModel.js +++ b/packages/widgets/Source/ProjectionPicker/ProjectionPickerViewModel.js @@ -29,28 +29,28 @@ function ProjectionPickerViewModel(scene) { /** * Gets or sets whether the button drop-down is currently visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.dropDownVisible = false; /** * Gets or sets the perspective projection tooltip. This property is observable. - * @type {String} + * @type {string} * @default 'Perspective Projection' */ this.tooltipPerspective = "Perspective Projection"; /** * Gets or sets the orthographic projection tooltip. This property is observable. - * @type {String} + * @type {string} * @default 'Orthographic Projection' */ this.tooltipOrthographic = "Orthographic Projection"; /** * Gets the currently active tooltip. This property is observable. - * @type {String} + * @type {string} */ this.selectedTooltip = undefined; @@ -187,7 +187,7 @@ Object.defineProperties(ProjectionPickerViewModel.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ ProjectionPickerViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/SceneModePicker/SceneModePicker.js b/packages/widgets/Source/SceneModePicker/SceneModePicker.js index 48c412c0e23..3ab0c6465ef 100644 --- a/packages/widgets/Source/SceneModePicker/SceneModePicker.js +++ b/packages/widgets/Source/SceneModePicker/SceneModePicker.js @@ -31,9 +31,9 @@ const columbusViewPath = * @alias SceneModePicker * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. - * @param {Number} [duration=2.0] The time, in seconds, it takes for the scene to transition. + * @param {number} [duration=2.0] The time, in seconds, it takes for the scene to transition. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @@ -180,7 +180,7 @@ Object.defineProperties(SceneModePicker.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ SceneModePicker.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/SceneModePicker/SceneModePickerViewModel.js b/packages/widgets/Source/SceneModePicker/SceneModePickerViewModel.js index b4b3ce6deee..33884b8902f 100644 --- a/packages/widgets/Source/SceneModePicker/SceneModePickerViewModel.js +++ b/packages/widgets/Source/SceneModePicker/SceneModePickerViewModel.js @@ -15,7 +15,7 @@ import createCommand from "../createCommand.js"; * @constructor * * @param {Scene} scene The Scene to morph - * @param {Number} [duration=2.0] The duration of scene morph animations, in seconds + * @param {number} [duration=2.0] The duration of scene morph animations, in seconds */ function SceneModePickerViewModel(scene, duration) { //>>includeStart('debug', pragmas.debug); @@ -46,28 +46,28 @@ function SceneModePickerViewModel(scene, duration) { /** * Gets or sets whether the button drop-down is currently visible. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.dropDownVisible = false; /** * Gets or sets the 2D tooltip. This property is observable. - * @type {String} + * @type {string} * @default '2D' */ this.tooltip2D = "2D"; /** * Gets or sets the 3D tooltip. This property is observable. - * @type {String} + * @type {string} * @default '3D' */ this.tooltip3D = "3D"; /** * Gets or sets the Columbus View tooltip. This property is observable. - * @type {String} + * @type {string} * @default 'Columbus View' */ this.tooltipColumbusView = "Columbus View"; @@ -82,7 +82,7 @@ function SceneModePickerViewModel(scene, duration) { /** * Gets the currently active tooltip. This property is observable. - * @type {String} + * @type {string} */ this.selectedTooltip = undefined; knockout.defineProperty(this, "selectedTooltip", function () { @@ -132,7 +132,7 @@ Object.defineProperties(SceneModePickerViewModel.prototype, { * Gets or sets the the duration of scene mode transition animations in seconds. * A value of zero causes the scene to instantly change modes. * @memberof SceneModePickerViewModel.prototype - * @type {Number} + * @type {number} */ duration: { get: function () { @@ -199,7 +199,7 @@ Object.defineProperties(SceneModePickerViewModel.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ SceneModePickerViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/SelectionIndicator/SelectionIndicator.js b/packages/widgets/Source/SelectionIndicator/SelectionIndicator.js index aa5b659cec4..53c2ee83f9b 100644 --- a/packages/widgets/Source/SelectionIndicator/SelectionIndicator.js +++ b/packages/widgets/Source/SelectionIndicator/SelectionIndicator.js @@ -13,7 +13,7 @@ import SelectionIndicatorViewModel from "./SelectionIndicatorViewModel.js"; * @alias SelectionIndicator * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The Scene instance to use. * * @exception {DeveloperError} Element with id "container" does not exist in the document. @@ -97,7 +97,7 @@ Object.defineProperties(SelectionIndicator.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ SelectionIndicator.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/SelectionIndicator/SelectionIndicatorViewModel.js b/packages/widgets/Source/SelectionIndicator/SelectionIndicatorViewModel.js index 40897f2f1e7..5a382440fee 100644 --- a/packages/widgets/Source/SelectionIndicator/SelectionIndicatorViewModel.js +++ b/packages/widgets/Source/SelectionIndicator/SelectionIndicatorViewModel.js @@ -55,7 +55,7 @@ function SelectionIndicatorViewModel( /** * Gets or sets the visibility of the selection indicator. - * @type {Boolean} + * @type {boolean} */ this.showSelection = false; @@ -70,7 +70,7 @@ function SelectionIndicatorViewModel( /** * Gets the visibility of the position indicator. This can be false even if an * object is selected, when the selected object has no position. - * @type {Boolean} + * @type {boolean} */ this.isVisible = undefined; knockout.defineProperty(this, "isVisible", { diff --git a/packages/widgets/Source/Timeline/Timeline.js b/packages/widgets/Source/Timeline/Timeline.js index ad36cf36f96..581bb7a3373 100644 --- a/packages/widgets/Source/Timeline/Timeline.js +++ b/packages/widgets/Source/Timeline/Timeline.js @@ -204,7 +204,7 @@ Timeline.prototype.removeEventListener = function (type, listener, useCapture) { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Timeline.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/ToggleButtonViewModel.js b/packages/widgets/Source/ToggleButtonViewModel.js index 73f589f6004..b8f339a16e5 100644 --- a/packages/widgets/Source/ToggleButtonViewModel.js +++ b/packages/widgets/Source/ToggleButtonViewModel.js @@ -7,9 +7,9 @@ import knockout from "./ThirdParty/knockout.js"; * @constructor * * @param {Command} command The command which will be executed when the button is toggled. - * @param {Object} [options] Object with the following properties: - * @param {Boolean} [options.toggled=false] A boolean indicating whether the button should be initially toggled. - * @param {String} [options.tooltip=''] A string containing the button's tooltip. + * @param {object} [options] Object with the following properties: + * @param {boolean} [options.toggled=false] A boolean indicating whether the button should be initially toggled. + * @param {string} [options.tooltip=''] A string containing the button's tooltip. */ function ToggleButtonViewModel(command, options) { //>>includeStart('debug', pragmas.debug); @@ -24,14 +24,14 @@ function ToggleButtonViewModel(command, options) { /** * Gets or sets whether the button is currently toggled. This property is observable. - * @type {Boolean} + * @type {boolean} * @default false */ this.toggled = defaultValue(options.toggled, false); /** * Gets or sets the button's tooltip. This property is observable. - * @type {String} + * @type {string} * @default '' */ this.tooltip = defaultValue(options.tooltip, ""); diff --git a/packages/widgets/Source/VRButton/VRButton.js b/packages/widgets/Source/VRButton/VRButton.js index 5712068ace6..0c22bf11d8b 100644 --- a/packages/widgets/Source/VRButton/VRButton.js +++ b/packages/widgets/Source/VRButton/VRButton.js @@ -18,9 +18,9 @@ const exitVRPath = * @alias VRButton * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene The scene. - * @param {Element|String} [vrElement=document.body] The element or id to be placed into vr mode. + * @param {Element|string} [vrElement=document.body] The element or id to be placed into vr mode. * * @exception {DeveloperError} Element with id "container" does not exist in the document. */ @@ -90,7 +90,7 @@ Object.defineProperties(VRButton.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ VRButton.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/VRButton/VRButtonViewModel.js b/packages/widgets/Source/VRButton/VRButtonViewModel.js index 456cae1be46..1f5697fbb39 100644 --- a/packages/widgets/Source/VRButton/VRButtonViewModel.js +++ b/packages/widgets/Source/VRButton/VRButtonViewModel.js @@ -77,7 +77,7 @@ function toggleVR(viewModel, scene, isVRMode, isOrthographic) { * @constructor * * @param {Scene} scene The scene. - * @param {Element|String} [vrElement=document.body] The element or id to be placed into VR mode. + * @param {Element|string} [vrElement=document.body] The element or id to be placed into VR mode. */ function VRButtonViewModel(scene, vrElement) { //>>includeStart('debug', pragmas.debug); @@ -94,7 +94,7 @@ function VRButtonViewModel(scene, vrElement) { /** * Gets whether or not VR mode is active. * - * @type {Boolean} + * @type {boolean} */ this.isVRMode = undefined; knockout.defineProperty(this, "isVRMode", { @@ -106,7 +106,7 @@ function VRButtonViewModel(scene, vrElement) { /** * Gets or sets whether or not VR functionality should be enabled. * - * @type {Boolean} + * @type {boolean} * @see Fullscreen.enabled */ this.isVREnabled = undefined; @@ -122,7 +122,7 @@ function VRButtonViewModel(scene, vrElement) { /** * Gets the tooltip. This property is observable. * - * @type {String} + * @type {string} */ this.tooltip = undefined; knockout.defineProperty(this, "tooltip", function () { @@ -207,7 +207,7 @@ Object.defineProperties(VRButtonViewModel.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ VRButtonViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 554f484ea04..780af46acb3 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -290,24 +290,24 @@ function enableVRUI(viewer, enabled) { } /** - * @typedef {Object} Viewer.ConstructorOptions + * @typedef {object} Viewer.ConstructorOptions * * Initialization options for the Viewer constructor * - * @property {Boolean} [animation=true] If set to false, the Animation widget will not be created. - * @property {Boolean} [baseLayerPicker=true] If set to false, the BaseLayerPicker widget will not be created. - * @property {Boolean} [fullscreenButton=true] If set to false, the FullscreenButton widget will not be created. - * @property {Boolean} [vrButton=false] If set to true, the VRButton widget will be created. - * @property {Boolean|GeocoderService[]} [geocoder=true] If set to false, the Geocoder widget will not be created. - * @property {Boolean} [homeButton=true] If set to false, the HomeButton widget will not be created. - * @property {Boolean} [infoBox=true] If set to false, the InfoBox widget will not be created. - * @property {Boolean} [sceneModePicker=true] If set to false, the SceneModePicker widget will not be created. - * @property {Boolean} [selectionIndicator=true] If set to false, the SelectionIndicator widget will not be created. - * @property {Boolean} [timeline=true] If set to false, the Timeline widget will not be created. - * @property {Boolean} [navigationHelpButton=true] If set to false, the navigation help button will not be created. - * @property {Boolean} [navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button. - * @property {Boolean} [scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory. - * @property {Boolean} [shouldAnimate=false] <code>true</code> if the clock should attempt to advance simulation time by default, <code>false</code> otherwise. This option takes precedence over setting {@link Viewer#clockViewModel}. + * @property {boolean} [animation=true] If set to false, the Animation widget will not be created. + * @property {boolean} [baseLayerPicker=true] If set to false, the BaseLayerPicker widget will not be created. + * @property {boolean} [fullscreenButton=true] If set to false, the FullscreenButton widget will not be created. + * @property {boolean} [vrButton=false] If set to true, the VRButton widget will be created. + * @property {boolean|GeocoderService[]} [geocoder=true] If set to false, the Geocoder widget will not be created. + * @property {boolean} [homeButton=true] If set to false, the HomeButton widget will not be created. + * @property {boolean} [infoBox=true] If set to false, the InfoBox widget will not be created. + * @property {boolean} [sceneModePicker=true] If set to false, the SceneModePicker widget will not be created. + * @property {boolean} [selectionIndicator=true] If set to false, the SelectionIndicator widget will not be created. + * @property {boolean} [timeline=true] If set to false, the Timeline widget will not be created. + * @property {boolean} [navigationHelpButton=true] If set to false, the navigation help button will not be created. + * @property {boolean} [navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button. + * @property {boolean} [scene3DOnly=false] When <code>true</code>, each geometry instance will only be rendered in 3D to save GPU memory. + * @property {boolean} [shouldAnimate=false] <code>true</code> if the clock should attempt to advance simulation time by default, <code>false</code> otherwise. This option takes precedence over setting {@link Viewer#clockViewModel}. * @property {ClockViewModel} [clockViewModel=new ClockViewModel(clock)] The clock view model to use to control current time. * @property {ProviderViewModel} [selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel[]} [imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. @@ -317,30 +317,30 @@ function enableVRUI(viewer, enabled) { * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. - * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. - * @property {Boolean} [useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise. - * @property {Number} [targetFrameRate] The target frame rate when using the default render loop. - * @property {Boolean} [showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs. - * @property {Boolean} [useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>. - * @property {Boolean} [automaticallyTrackDataSourceClocks=true] If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes. Set this to false if you want to configure the clock independently. + * @property {Element|string} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. + * @property {boolean} [useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise. + * @property {number} [targetFrameRate] The target frame rate when using the default render loop. + * @property {boolean} [showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs. + * @property {boolean} [useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore <code>window.devicePixelRatio</code>. + * @property {boolean} [automaticallyTrackDataSourceClocks=true] If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes. Set this to false if you want to configure the clock independently. * @property {ContextOptions} [contextOptions] Context and WebGL creation properties passed to {@link Scene}. * @property {SceneMode} [sceneMode=SceneMode.SCENE3D] The initial scene mode. * @property {MapProjection} [mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. * @property {Globe|false} [globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to <code>false</code>, no globe will be added. - * @property {Boolean} [orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. - * @property {Element|String} [creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added to the bottom of the widget itself. - * @property {Element|String} [creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself. + * @property {boolean} [orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. + * @property {Element|string} [creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added to the bottom of the widget itself. + * @property {Element|string} [creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself. * @property {DataSourceCollection} [dataSources=new DataSourceCollection()] The collection of data sources visualized by the widget. If this parameter is provided, * the instance is assumed to be owned by the caller and will not be destroyed when the viewer is destroyed. - * @property {Boolean} [shadows=false] Determines if shadows are cast by light sources. + * @property {boolean} [shadows=false] Determines if shadows are cast by light sources. * @property {ShadowMode} [terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from light sources. * @property {MapMode2D} [mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. - * @property {Boolean} [projectionPicker=false] If set to true, the ProjectionPicker widget will be created. - * @property {Boolean} [blurActiveElementOnCanvasFocus=true] If true, the active element will blur when the viewer's canvas is clicked. Setting this to false is useful for cases when the canvas is clicked only for retrieving position or an entity data without actually meaning to set the canvas to be the active element. - * @property {Boolean} [requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @property {Number} [maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. - * @property {Number} [depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation. - * @property {Number} [msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. + * @property {boolean} [projectionPicker=false] If set to true, the ProjectionPicker widget will be created. + * @property {boolean} [blurActiveElementOnCanvasFocus=true] If true, the active element will blur when the viewer's canvas is clicked. Setting this to false is useful for cases when the canvas is clicked only for retrieving position or an entity data without actually meaning to set the canvas to be the active element. + * @property {boolean} [requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @property {number} [maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. + * @property {number} [depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation. + * @property {number} [msaaSamples=1] If provided, this value controls the rate of multisample antialiasing. Typical multisampling rates are 2, 4, and sometimes 8 samples per pixel. Higher sampling rates of MSAA may impact performance in exchange for improved visual quality. This value only applies to WebGL2 contexts that support multisample render targets. */ /** @@ -350,7 +350,7 @@ function enableVRUI(viewer, enabled) { * @alias Viewer * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Viewer.ConstructorOptions} [options] Object describing initialization options * * @exception {DeveloperError} Element with id "container" does not exist in the document. @@ -1178,7 +1178,7 @@ Object.defineProperties(Viewer.prototype, { /** * Determines if shadows are cast by light sources. * @memberof Viewer.prototype - * @type {Boolean} + * @type {boolean} */ shadows: { get: function () { @@ -1312,7 +1312,7 @@ Object.defineProperties(Viewer.prototype, { * than the underlying requestAnimationFrame implementation will have no effect. * @memberof Viewer.prototype * - * @type {Number} + * @type {number} */ targetFrameRate: { get: function () { @@ -1335,7 +1335,7 @@ Object.defineProperties(Viewer.prototype, { * after the error. * @memberof Viewer.prototype * - * @type {Boolean} + * @type {boolean} */ useDefaultRenderLoop: { get: function () { @@ -1355,7 +1355,7 @@ Object.defineProperties(Viewer.prototype, { * it to 2.0 will cause the scene to be rendered at 1280x960 and then scaled down. * @memberof Viewer.prototype * - * @type {Number} + * @type {number} * @default 1.0 */ resolutionScale: { @@ -1376,7 +1376,7 @@ Object.defineProperties(Viewer.prototype, { * this flag is true or false. * @memberof Viewer.prototype * - * @type {Boolean} + * @type {boolean} * @default true */ useBrowserRecommendedResolution: { @@ -1396,7 +1396,7 @@ Object.defineProperties(Viewer.prototype, { * * @memberof Viewer.prototype * - * @type {Boolean} + * @type {boolean} */ allowDataSourcesToSuspendAnimation: { get: function () { @@ -1533,7 +1533,7 @@ Object.defineProperties(Viewer.prototype, { * to the provided viewer instance. * * @param {Viewer.ViewerMixin} mixin The Viewer mixin to add to this instance. - * @param {Object} [options] The options object to be passed to the mixin function. + * @param {object} [options] The options object to be passed to the mixin function. * * @see viewerDragDropMixin */ @@ -1668,7 +1668,7 @@ Viewer.prototype.render = function () { }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ Viewer.prototype.isDestroyed = function () { return false; @@ -2029,9 +2029,9 @@ Viewer.prototype._onDataSourceRemoved = function ( * target will be the range. The heading will be determined from the offset. If the heading cannot be * determined from the offset, the heading will be north.</p> * - * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|VoxelPrimitive>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. + * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|VoxelPrimitive>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. * @param {HeadingPitchRange} [offset] The offset from the center of the entity in the local east-north-up reference frame. - * @returns {Promise.<Boolean>} A Promise that resolves to true if the zoom was successful or false if the target is not currently visualized in the scene or the zoom was cancelled. + * @returns {Promise<boolean>} A Promise that resolves to true if the zoom was successful or false if the target is not currently visualized in the scene or the zoom was cancelled. */ Viewer.prototype.zoomTo = function (target, offset) { const options = { @@ -2055,12 +2055,12 @@ Viewer.prototype.zoomTo = function (target, offset) { * target will be the range. The heading will be determined from the offset. If the heading cannot be * determined from the offset, the heading will be north.</p> * - * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise.<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|VoxelPrimitive>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.duration=3.0] The duration of the flight in seconds. - * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight. + * @param {Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|Promise<Entity|Entity[]|EntityCollection|DataSource|ImageryLayer|Cesium3DTileset|TimeDynamicPointCloud|VoxelPrimitive>} target The entity, array of entities, entity collection, data source, Cesium3DTileset, point cloud, or imagery layer to view. You can also pass a promise that resolves to one of the previously mentioned types. + * @param {object} [options] Object with the following properties: + * @param {number} [options.duration=3.0] The duration of the flight in seconds. + * @param {number} [options.maximumHeight] The maximum height at the peak of the flight. * @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target. - * @returns {Promise.<Boolean>} A Promise that resolves to true if the flight was successful or false if the target is not currently visualized in the scene or the flight was cancelled. //TODO: Cleanup entity mentions + * @returns {Promise<boolean>} A Promise that resolves to true if the flight was successful or false if the target is not currently visualized in the scene or the flight was cancelled. //TODO: Cleanup entity mentions */ Viewer.prototype.flyTo = function (target, options) { return zoomToOrFly(this, target, options, true); @@ -2409,7 +2409,7 @@ function updateTrackedEntity(viewer) { * A function that augments a Viewer instance with additional functionality. * @callback Viewer.ViewerMixin * @param {Viewer} viewer The viewer instance. - * @param {Object} options Options object to be passed to the mixin function. + * @param {object} options Options object to be passed to the mixin function. * * @see Viewer#extend */ diff --git a/packages/widgets/Source/Viewer/viewerDragDropMixin.js b/packages/widgets/Source/Viewer/viewerDragDropMixin.js index 03430c49794..24f6b896f50 100644 --- a/packages/widgets/Source/Viewer/viewerDragDropMixin.js +++ b/packages/widgets/Source/Viewer/viewerDragDropMixin.js @@ -17,11 +17,11 @@ import { * @function viewerDragDropMixin * @param {Viewer} viewer The viewer instance. - * @param {Object} [options] Object with the following properties: - * @param {Element|String} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target. - * @param {Boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones. - * @param {Boolean} [options.flyToOnDrop=true] When true, dropping files will fly to the data source once it is loaded. - * @param {Boolean} [options.clampToGround=true] When true, datasources are clamped to the ground. + * @param {object} [options] Object with the following properties: + * @param {Element|string} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target. + * @param {boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones. + * @param {boolean} [options.flyToOnDrop=true] When true, dropping files will fly to the data source once it is loaded. + * @param {boolean} [options.clampToGround=true] When true, datasources are clamped to the ground. * @param {Proxy} [options.proxy] The proxy to be used for KML network links. * * @exception {DeveloperError} Element with id <options.dropTarget> does not exist in the document. @@ -138,7 +138,7 @@ function viewerDragDropMixin(viewer, options) { /** * Gets or sets a value indicating if existing data sources should be cleared before adding the newly dropped sources. * @memberof viewerDragDropMixin.prototype - * @type {Boolean} + * @type {boolean} */ clearOnDrop: { get: function () { @@ -152,7 +152,7 @@ function viewerDragDropMixin(viewer, options) { /** * Gets or sets a value indicating if the camera should fly to the data source after it is loaded. * @memberof viewerDragDropMixin.prototype - * @type {Boolean} + * @type {boolean} */ flyToOnDrop: { get: function () { @@ -180,7 +180,7 @@ function viewerDragDropMixin(viewer, options) { /** * Gets or sets a value indicating if the datasources should be clamped to the ground * @memberof viewerDragDropMixin.prototype - * @type {Boolean} + * @type {boolean} */ clampToGround: { get: function () { diff --git a/packages/widgets/Source/Viewer/viewerPerformanceWatchdogMixin.js b/packages/widgets/Source/Viewer/viewerPerformanceWatchdogMixin.js index fcf97afb719..accaf51a8d5 100644 --- a/packages/widgets/Source/Viewer/viewerPerformanceWatchdogMixin.js +++ b/packages/widgets/Source/Viewer/viewerPerformanceWatchdogMixin.js @@ -8,8 +8,8 @@ import PerformanceWatchdog from "../PerformanceWatchdog/PerformanceWatchdog.js"; * @function * * @param {Viewer} viewer The viewer instance. - * @param {Object} [options] An object with properties. - * @param {String} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The + * @param {object} [options] An object with properties. + * @param {string} [options.lowFrameRateMessage='This application appears to be performing poorly on your system. Please try using a different web browser or updating your video drivers.'] The * message to display when a low frame rate is detected. The message is interpeted as HTML, so make sure * it comes from a trusted source so that your application is not vulnerable to cross-site scripting attacks. * diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspector.js b/packages/widgets/Source/VoxelInspector/VoxelInspector.js index eded9c63109..26871cfbe81 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspector.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspector.js @@ -17,7 +17,7 @@ import VoxelInspectorViewModel from "./VoxelInspectorViewModel.js"; * @alias VoxelInspector * @constructor * - * @param {Element|String} container The DOM element or ID that will contain the widget. + * @param {Element|string} container The DOM element or ID that will contain the widget. * @param {Scene} scene the Scene instance to use. */ function VoxelInspector(container, scene) { @@ -337,7 +337,7 @@ Object.defineProperties(VoxelInspector.prototype, { }); /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ VoxelInspector.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index f19d46ed623..af391c97aad 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -852,7 +852,7 @@ VoxelInspectorViewModel.prototype.shaderEditorKeyPress = function ( }; /** - * @returns {Boolean} true if the object has been destroyed, false otherwise. + * @returns {boolean} true if the object has been destroyed, false otherwise. */ VoxelInspectorViewModel.prototype.isDestroyed = function () { return false; diff --git a/packages/widgets/Source/createCommand.js b/packages/widgets/Source/createCommand.js index 6533384165c..305905a3c9c 100644 --- a/packages/widgets/Source/createCommand.js +++ b/packages/widgets/Source/createCommand.js @@ -12,7 +12,7 @@ import knockout from "./ThirdParty/knockout.js"; * @function * * @param {Function} func The function to execute. - * @param {Boolean} [canExecute=true] A boolean indicating whether the function can currently be executed. + * @param {boolean} [canExecute=true] A boolean indicating whether the function can currently be executed. */ function createCommand(func, canExecute) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/widgets/Source/subscribeAndEvaluate.js b/packages/widgets/Source/subscribeAndEvaluate.js index 8eef1167527..510615498a9 100644 --- a/packages/widgets/Source/subscribeAndEvaluate.js +++ b/packages/widgets/Source/subscribeAndEvaluate.js @@ -8,11 +8,11 @@ import knockout from "./ThirdParty/knockout.js"; * * @function subscribeAndEvaluate * - * @param {Object} owner The object containing the observable property. - * @param {String} observablePropertyName The name of the observable property. + * @param {object} owner The object containing the observable property. + * @param {string} observablePropertyName The name of the observable property. * @param {Function} callback The callback function. - * @param {Object} [target] The value of this in the callback function. - * @param {String} [event='change'] The name of the event to receive notification for. + * @param {object} [target] The value of this in the callback function. + * @param {string} [event='change'] The name of the event to receive notification for. * @returns The subscription object from Knockout which can be used to dispose the subscription later. */ function subscribeAndEvaluate( From 160ba46520808bacb5454ea7580fc78f22728366 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Fri, 10 Feb 2023 16:39:36 +0800 Subject: [PATCH 454/679] The missing types same as last commit --- .../Sandcastle/gallery/Custom DataSource.html | 2 +- Specs/ImplicitTilingTester.js | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index c4badac1fb3..820c7c41962 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -144,7 +144,7 @@ /** * Gets the array of series names. * @memberof WebGLGlobeDataSource.prototype - * @type {} + * @type {string} */ seriesNames: { get: function () { diff --git a/Specs/ImplicitTilingTester.js b/Specs/ImplicitTilingTester.js index f361813f8dc..7513a4b497d 100644 --- a/Specs/ImplicitTilingTester.js +++ b/Specs/ImplicitTilingTester.js @@ -10,38 +10,38 @@ function ImplicitTilingTester() {} /** * Description of a single availability bitstream - * @typedef {Object} AvailabilityDescription - * @property {String|Number} descriptor Either a string of <code>0</code>s and <code>1</code>s representing the bitstream values, or an integer <code>0</code> or <code>1</code> to indicate a constant value. - * @property {Number} lengthBits How many bits are in the bitstream. This must be specified, even if descriptor is a string of <code>0</code>s and <code>1</code>s - * @property {Boolean} isInternal <code>true</code> if an internal bufferView should be created. <code>false</code> indicates the bufferview is stored in an external buffer instead. - * @property {Boolean} [shareBuffer=false] This is only used for content availability. If <code>true</code>, then the content availability will share the same buffer as the tile availaibility, as this is a common optimization - * @property {Boolean} [includeAvailableCount=false] If true, set availableCount + * @typedef {object} AvailabilityDescription + * @property {string|number} descriptor Either a string of <code>0</code>s and <code>1</code>s representing the bitstream values, or an integer <code>0</code> or <code>1</code> to indicate a constant value. + * @property {number} lengthBits How many bits are in the bitstream. This must be specified, even if descriptor is a string of <code>0</code>s and <code>1</code>s + * @property {boolean} isInternal <code>true</code> if an internal bufferView should be created. <code>false</code> indicates the bufferview is stored in an external buffer instead. + * @property {boolean} [shareBuffer=false] This is only used for content availability. If <code>true</code>, then the content availability will share the same buffer as the tile availaibility, as this is a common optimization + * @property {boolean} [includeAvailableCount=false] If true, set availableCount */ /** * A description of metadata properties stored in the subtree. - * @typedef {Object} MetadataDescription - * @property {Boolean} isInternal True if the metadata should be stored in the subtree file, false if the metadata should be stored in an external buffer. + * @typedef {object} MetadataDescription + * @property {boolean} isInternal True if the metadata should be stored in the subtree file, false if the metadata should be stored in an external buffer. * @property {Array} propertyTables Array of property table objects to pass into {@link MetadataTester.createPropertyTables} in order to create the property table buffer views. * @private */ /** * A JSON description of a subtree file for easier generation - * @typedef {Object} SubtreeDescription - * @property {Boolean} [useLegacySchema=false] If true, the resulting JSON chunk will use the legacy schema for subtrees and metadata (e.g. use bufferViews rather than bitstream, use 3DTILES_metadata extension rather than tileMetadata or contentMetadata, use 3DTILES_multiple_contents extension rather than contents). Used to test backwards compatibility. + * @typedef {object} SubtreeDescription + * @property {boolean} [useLegacySchema=false] If true, the resulting JSON chunk will use the legacy schema for subtrees and metadata (e.g. use bufferViews rather than bitstream, use 3DTILES_metadata extension rather than tileMetadata or contentMetadata, use 3DTILES_multiple_contents extension rather than contents). Used to test backwards compatibility. * @property {AvailabilityDescription} tileAvailability A description of the tile availability bitstream to generate * @property {AvailabilityDescription} contentAvailability A description of the content availability bitstream to generate * @property {AvailabilityDescription} childSubtreeAvailability A description of the child subtree availability bitstream to generate * @property {AvailabilityDescription} other A description of another bitstream. This is not used for availability, but rather to simulate extra buffer views. * @property {MetadataDescription} [metadata] For testing metadata, additional options can be passed in here. - * @property {Boolean} [json] If true, return the result as a JSON with external buffers. Should not be true if any of the availability buffers are internal. + * @property {boolean} [json] If true, return the result as a JSON with external buffers. Should not be true if any of the availability buffers are internal. * @private */ /** * Results of procedurally generating a subtree. - * @typedef {Object} GeneratedSubtree + * @typedef {object} GeneratedSubtree * @property {Uint8Array} [subtreeJson] The JSON portion of the subtree file. Mutually exclusive with subtreeBuffer. * @property {Uint8Array} [subtreeBuffer] A typed array storing the contents of the subtree file (including the internal buffer). Mutually exclusive with subtreeJson. * @property {Uint8Array} externalBuffer A typed array representing an external .bin file. This is always returned, but it may be an empty typed array. @@ -51,7 +51,7 @@ function ImplicitTilingTester() {} /** * Generate a subtree buffer * @param {SubtreeDescription} subtreeDescription A JSON description of the subtree's structure and values - * @param {Boolean} constantOnly true if all the bitstreams are constant, i.e. no buffers/bufferViews are needed. + * @param {boolean} constantOnly true if all the bitstreams are constant, i.e. no buffers/bufferViews are needed. * @return {GeneratedSubtree} The procedurally generated subtree and an external buffer. * * @example From f13e84b666cb28e453080eac2a8342300fc28104 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Fri, 10 Feb 2023 16:54:45 +0800 Subject: [PATCH 455/679] Update CHANGES.md --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 38aab2d19c4..afcb51b2f79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,10 +8,13 @@ ##### Additions :tada: +- Support TypeScript `import()` type in JSDoc [#11080](https://github.com/CesiumGS/cesium/pull/11080) + ##### Fixes :wrench: - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) - Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) +- Replace constructor types with primitive types in JSDoc. [#11080](https://github.com/CesiumGS/cesium/pull/11080) ### 1.102 - 2023-02-01 From d03f16b92c42635fb22b2589b650190aec4a8770 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 10 Feb 2023 09:52:53 -0500 Subject: [PATCH 456/679] Update docs and deprecation warnings --- CHANGES.md | 2 +- packages/engine/Source/Scene/ImageryLayer.js | 2 +- packages/engine/Source/Scene/SingleTileImageryProvider.js | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2e7ce9c1d99..27870dbc7e9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,7 +26,7 @@ - `MapboxImageryProvider.ready` and `MapboxImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `MapboxStyleImageryProvider.ready` and `MapboxStyleImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `OpenStreetMapImageryProvider.ready` and `OpenStreetMapImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `SingleTileImageryProvider` constructor parameter `options.url` was deprecated in Cesium 1.102 and will be removed in 1.104. Provide `options.tileHeight` and `options.tileWidth`, or use `SingleTileImageryProvider.fromUrl` instead. +- `SingleTileImageryProvider` constructor parameters `options.tileHeight` and `options.tileWidth` became required in CesiumJS 1.102. Omitting these properties will result in an error in 1.104. Provide `options.tileHeight` and `options.tileWidth`, or use `SingleTileImageryProvider.fromUrl` instead. - `SingleTileImageryProvider.ready` and `SingleTileImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `SingleTileImageryProvider.fromUrl` instead. - `TileCoordinatesImageryProvider.ready` and `TileCoordinatesImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `TileMapServiceImageryProvider` constructor parameter `options.url`, `TileMapServiceImageryProvider.ready`, and `TileMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `TileMapServiceImageryProvider.fromUrl` instead. diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 86ebff22798..50a590d1305 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -514,7 +514,7 @@ ImageryLayer.prototype.getViewableRectangle = async function () { * Computes the intersection of this layer's rectangle with the imagery provider's availability rectangle, * producing the overall bounds of imagery that can be produced by this layer. * - * @returns {Rectangle} A promise to a rectangle which defines the overall bounds of imagery that can be produced by this layer. + * @returns {Rectangle} A rectangle which defines the overall bounds of imagery that can be produced by this layer. * * @example * // Zoom to an imagery layer. diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index 2b5452f4680..d73755379b9 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -159,6 +159,8 @@ function SingleTileImageryProvider(options) { const resource = Resource.createIfNeeded(options.url); this._resource = resource; + // After ready promise and the deprecation warning for these properties are removed, + // the if check is not needed, and this can become a top-level block if (defined(options.tileWidth) || defined(options.tileHeight)) { //>>includeStart('debug', pragmas.debug); Check.typeOf.number("options.tileWidth", options.tileWidth); @@ -173,8 +175,8 @@ function SingleTileImageryProvider(options) { } deprecationWarning( - "SingleTileImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Provide options.tileHeight and options.tileWidth, or use SingleTileImageryProvider.fromUrl instead." + "SingleTileImageryProvider options", + "options.tileHeight and options.tileWidth became required in CesiumJS 1.102. Omitting these properties will result in an error in 1.104. Provide options.tileHeight and options.tileWidth, or use SingleTileImageryProvider.fromUrl instead." ); this._tileWidth = 0; From e07c8629c11c89b060435935498f22acf69bbfb9 Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng90@live.com> Date: Sat, 11 Feb 2023 02:07:34 +0800 Subject: [PATCH 457/679] remove TODO comment --- packages/engine/Source/Scene/CameraEventAggregator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 823060d711e..59d67234c34 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -159,7 +159,6 @@ function listenToWheel(aggregator, modifier) { aggregator._eventHandler.setInputAction( function (delta) { - // TODO: magic numbers const arcLength = 7.5 * CesiumMath.toRadians(delta); pressTime[key] = releaseTime[key] = new Date(); movement.endPosition.x = 0.0; From ee5840ed16e0a44cc1fd4da40c1b2809d0fba299 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 13 Feb 2023 12:22:09 -0500 Subject: [PATCH 458/679] Fix typo in deprecation message --- .../engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index 5ef498722d4..aedf4bb8bb2 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -226,7 +226,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { if (defined(options.metadata)) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider options.metadata", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + "options.metadata was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." ); metadata = options.metadata; } From 284f2bdd6e9452e5168726d4407003d606cca6eb Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 13 Feb 2023 16:52:40 -0500 Subject: [PATCH 459/679] Use smaller functions in SpatialNode and VoxelTraversal --- packages/engine/Source/Scene/SpatialNode.js | 144 ++++++++++-------- .../engine/Source/Scene/VoxelTraversal.js | 141 ++++++----------- 2 files changed, 126 insertions(+), 159 deletions(-) diff --git a/packages/engine/Source/Scene/SpatialNode.js b/packages/engine/Source/Scene/SpatialNode.js index cb284a4def6..f352769e239 100644 --- a/packages/engine/Source/Scene/SpatialNode.js +++ b/packages/engine/Source/Scene/SpatialNode.js @@ -102,6 +102,33 @@ SpatialNode.prototype.computeBoundingVolumes = function ( maximumScale / Cartesian3.minimumComponent(voxelDimensions); }; +/** + * Compute the [level, x, y, z] coordinates of the children of a node + * @returns {Array[]} Child coordinate arrays + * @private + */ +SpatialNode.prototype.getChildCoordinates = function () { + const { level, x, y, z } = this; + const xMin = x * 2; + const yMin = y * 2; + const zMin = z * 2; + const yMax = yMin + 1; + const xMax = xMin + 1; + const zMax = zMin + 1; + const childLevel = level + 1; + + return [ + [childLevel, xMin, yMin, zMin], + [childLevel, xMax, yMin, zMin], + [childLevel, xMin, yMax, zMin], + [childLevel, xMax, yMax, zMin], + [childLevel, xMin, yMin, zMax], + [childLevel, xMax, yMin, zMax], + [childLevel, xMin, yMax, zMax], + [childLevel, xMax, yMax, zMax], + ]; +}; + /** * @param {FrameState} frameState * @param {Number} visibilityPlaneMask @@ -173,66 +200,43 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( let minimumDistanceNext = +Number.MAX_VALUE; while (defined(spatialNode)) { - const renderableKeyframeNodes = spatialNode.renderableKeyframeNodes; + const { renderableKeyframeNodes } = spatialNode; if (renderableKeyframeNodes.length >= 1) { - let keyframeNodeIndexPrev = findKeyframeIndex( + const indexPrev = getKeyframeIndexPrev( targetKeyframePrev, renderableKeyframeNodes ); - if (keyframeNodeIndexPrev < 0) { - keyframeNodeIndexPrev = CesiumMath.clamp( - ~keyframeNodeIndexPrev - 1, - 0, - renderableKeyframeNodes.length - 1 - ); - } - const keyframeNodePrev = renderableKeyframeNodes[keyframeNodeIndexPrev]; - const keyframePrev = keyframeNodePrev.keyframe; + const keyframeNodePrev = renderableKeyframeNodes[indexPrev]; - let keyframeNodeNext; - if ( + const indexNext = targetKeyframeNext === targetKeyframePrev || - targetKeyframePrev < keyframePrev - ) { - keyframeNodeNext = keyframeNodePrev; - } else { - const keyframeNodeIndexNext = Math.min( - keyframeNodeIndexPrev + 1, - renderableKeyframeNodes.length - 1 - ); - keyframeNodeNext = renderableKeyframeNodes[keyframeNodeIndexNext]; - } - const keyframeNext = keyframeNodeNext.keyframe; - - const keyframeDistancePrev = targetKeyframePrev - keyframePrev; - const keyframeDistanceNext = keyframeNext - targetKeyframeNext; - const levelDistance = startLevel - spatialNode.level; - - // Balance temporal and visual quality - const levelWeight = Math.exp(levelDistance * 4.0); - const normalKeyframeWeight = 1.0; - const reverseKeyframeWeight = 200.0; // Keyframes on the opposite of the desired direction are deprioritized. - const distancePrev = - levelDistance * levelWeight + - (keyframeDistancePrev >= 0 - ? keyframeDistancePrev * normalKeyframeWeight - : -keyframeDistancePrev * reverseKeyframeWeight); - const distanceNext = - levelDistance * levelWeight + - (keyframeDistanceNext >= 0 - ? keyframeDistanceNext * normalKeyframeWeight - : -keyframeDistanceNext * reverseKeyframeWeight); - - if (distancePrev < minimumDistancePrev) { - minimumDistancePrev = distancePrev; + targetKeyframePrev < keyframeNodePrev.keyframe + ? indexPrev + : Math.min(indexPrev + 1, renderableKeyframeNodes.length - 1); + const keyframeNodeNext = renderableKeyframeNodes[indexNext]; + + const distancePrev = targetKeyframePrev - keyframeNodePrev.keyframe; + const weightedDistancePrev = getWeightedKeyframeDistance( + startLevel - spatialNode.level, + distancePrev + ); + if (weightedDistancePrev < minimumDistancePrev) { + minimumDistancePrev = weightedDistancePrev; bestKeyframeNodePrev = keyframeNodePrev; } - if (distanceNext < minimumDistanceNext) { - minimumDistanceNext = distanceNext; + + const distanceNext = keyframeNodeNext.keyframe - targetKeyframeNext; + const weightedDistanceNext = getWeightedKeyframeDistance( + startLevel - spatialNode.level, + distanceNext + ); + if (weightedDistanceNext < minimumDistanceNext) { + minimumDistanceNext = weightedDistanceNext; bestKeyframeNodeNext = keyframeNodeNext; } - if (keyframeDistancePrev === 0 && keyframeDistanceNext === 0) { + + if (distancePrev === 0 && distanceNext === 0) { // Nothing higher up will be better, so break early. break; } @@ -243,21 +247,39 @@ SpatialNode.prototype.computeSurroundingRenderableKeyframeNodes = function ( this.renderableKeyframeNodePrevious = bestKeyframeNodePrev; this.renderableKeyframeNodeNext = bestKeyframeNodeNext; - if (defined(bestKeyframeNodePrev) && defined(bestKeyframeNodeNext)) { - const bestKeyframePrev = bestKeyframeNodePrev.keyframe; - const bestKeyframeNext = bestKeyframeNodeNext.keyframe; - this.renderableKeyframeNodeLerp = - bestKeyframePrev === bestKeyframeNext - ? 0.0 - : CesiumMath.clamp( - (keyframeLocation - bestKeyframePrev) / - (bestKeyframeNext - bestKeyframePrev), - 0.0, - 1.0 - ); + + if (!defined(bestKeyframeNodePrev) || !defined(bestKeyframeNodeNext)) { + return; } + + const bestKeyframePrev = bestKeyframeNodePrev.keyframe; + const bestKeyframeNext = bestKeyframeNodeNext.keyframe; + this.renderableKeyframeNodeLerp = + bestKeyframePrev === bestKeyframeNext + ? 0.0 + : CesiumMath.clamp( + (keyframeLocation - bestKeyframePrev) / + (bestKeyframeNext - bestKeyframePrev), + 0.0, + 1.0 + ); }; +function getKeyframeIndexPrev(targetKeyframe, keyframeNodes) { + const keyframeIndex = findKeyframeIndex(targetKeyframe, keyframeNodes); + return keyframeIndex < 0 + ? CesiumMath.clamp(~keyframeIndex - 1, 0, keyframeNodes.length - 1) + : keyframeIndex; +} + +function getWeightedKeyframeDistance(levelDistance, keyframeDistance) { + // Balance quality between visual (levelDistance) and temporal (keyframeDistance) + const levelWeight = Math.exp(levelDistance * 4.0); + // Keyframes on the opposite of the desired direction are deprioritized. + const keyframeWeight = keyframeDistance >= 0 ? 1.0 : -200.0; + return levelDistance * levelWeight + keyframeDistance * keyframeWeight; +} + /** * @param {Number} frameNumber * @returns {Boolean} diff --git a/packages/engine/Source/Scene/VoxelTraversal.js b/packages/engine/Source/Scene/VoxelTraversal.js index 97d81bef733..03d39b6b0a8 100644 --- a/packages/engine/Source/Scene/VoxelTraversal.js +++ b/packages/engine/Source/Scene/VoxelTraversal.js @@ -93,25 +93,12 @@ function VoxelTraversal( this._frameNumber = 0; const shape = primitive._shape; - const rootLevel = 0; - const rootX = 0; - const rootY = 0; - const rootZ = 0; - const rootParent = undefined; /** * @type {SpatialNode} * @readonly */ - this.rootNode = new SpatialNode( - rootLevel, - rootX, - rootY, - rootZ, - rootParent, - shape, - dimensions - ); + this.rootNode = new SpatialNode(0, 0, 0, 0, undefined, shape, dimensions); /** * @type {DoubleEndedPriorityQueue} @@ -425,12 +412,6 @@ function requestData(that, keyframeNode) { const primitive = that._primitive; const provider = primitive._provider; - const keyframe = keyframeNode.keyframe; - const spatialNode = keyframeNode.spatialNode; - const tileLevel = spatialNode.level; - const tileX = spatialNode.x; - const tileY = spatialNode.y; - const tileZ = spatialNode.z; function postRequestSuccess(result) { that._simultaneousRequestCount--; @@ -469,11 +450,12 @@ function requestData(that, keyframeNode) { keyframeNode.state = KeyframeNode.LoadState.FAILED; } + const { keyframe, spatialNode } = keyframeNode; const promise = provider.requestData({ - tileLevel: tileLevel, - tileX: tileX, - tileY: tileY, - tileZ: tileZ, + tileLevel: spatialNode.level, + tileX: spatialNode.x, + tileY: spatialNode.y, + tileZ: spatialNode.z, keyframe: keyframe, }); @@ -510,18 +492,41 @@ function loadAndUnload(that, frameState) { const frameNumber = that._frameNumber; const primitive = that._primitive; const shape = primitive._shape; - const voxelDimensions = primitive._provider.dimensions; - const targetScreenSpaceError = primitive._screenSpaceError; + const { dimensions } = primitive; + const targetScreenSpaceError = primitive.screenSpaceError; const priorityQueue = that._priorityQueue; const keyframeLocation = that._keyframeLocation; const keyframeCount = that._keyframeCount; const rootNode = that.rootNode; - const cameraPosition = frameState.camera.positionWC; - const screenSpaceErrorDenominator = frameState.camera.frustum.sseDenominator; - const screenHeight = - frameState.context.drawingBufferHeight / frameState.pixelRatio; - const screenSpaceErrorMultiplier = screenHeight / screenSpaceErrorDenominator; + const { camera, context, pixelRatio } = frameState; + const { positionWC, frustum } = camera; + const screenHeight = context.drawingBufferHeight / pixelRatio; + const screenSpaceErrorMultiplier = screenHeight / frustum.sseDenominator; + + function keyframePriority(previousKeyframe, keyframe, nextKeyframe) { + const keyframeDifference = Math.min( + Math.abs(keyframe - previousKeyframe), + Math.abs(keyframe - nextKeyframe) + ); + const maxKeyframeDifference = Math.max( + previousKeyframe, + keyframeCount - nextKeyframe - 1, + 1 + ); + const keyframeFactor = Math.pow( + 1.0 - keyframeDifference / maxKeyframeDifference, + 4.0 + ); + const binaryTreeFactor = Math.exp( + -that._binaryTreeKeyframeWeighting[keyframe] + ); + return CesiumMath.lerp( + binaryTreeFactor, + keyframeFactor, + 0.15 + 0.85 * keyframeFactor + ); + } /** * @ignore @@ -529,10 +534,7 @@ function loadAndUnload(that, frameState) { * @param {Number} visibilityPlaneMask */ function addToQueueRecursive(spatialNode, visibilityPlaneMask) { - spatialNode.computeScreenSpaceError( - cameraPosition, - screenSpaceErrorMultiplier - ); + spatialNode.computeScreenSpaceError(positionWC, screenSpaceErrorMultiplier); visibilityPlaneMask = spatialNode.visibility( frameState, @@ -565,31 +567,10 @@ function loadAndUnload(that, frameState) { const keyframeNodes = spatialNode.keyframeNodes; for (let i = 0; i < keyframeNodes.length; i++) { const keyframeNode = keyframeNodes[i]; - const keyframe = keyframeNode.keyframe; - // Balanced prioritization - const keyframeDifference = Math.min( - Math.abs(keyframe - previousKeyframe), - Math.abs(keyframe - nextKeyframe) - ); - const maxKeyframeDifference = Math.max( - previousKeyframe, - keyframeCount - nextKeyframe - 1, - 1 - ); - const keyframeFactor = Math.pow( - 1.0 - keyframeDifference / maxKeyframeDifference, - 4.0 - ); - const binaryTreeFactor = Math.exp( - -that._binaryTreeKeyframeWeighting[keyframe] - ); - keyframeNode.priority = 10.0 * ssePriority; - keyframeNode.priority += CesiumMath.lerp( - binaryTreeFactor, - keyframeFactor, - 0.15 + 0.85 * keyframeFactor - ); + keyframeNode.priority = + 10.0 * ssePriority + + keyframePriority(previousKeyframe, keyframeNode.keyframe, nextKeyframe); if ( keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE && @@ -612,18 +593,9 @@ function loadAndUnload(that, frameState) { } if (!defined(spatialNode.children)) { - const childCoords = getChildCoords(spatialNode); - const childLevel = spatialNode.level + 1; - spatialNode.children = childCoords.map(([x, y, z]) => { - return new SpatialNode( - childLevel, - x, - y, - z, - spatialNode, - shape, - voxelDimensions - ); + const childCoords = spatialNode.getChildCoordinates(); + spatialNode.children = childCoords.map(([level, x, y, z]) => { + return new SpatialNode(level, x, y, z, spatialNode, shape, dimensions); }); } for (let childIndex = 0; childIndex < 8; childIndex++) { @@ -706,33 +678,6 @@ function loadAndUnload(that, frameState) { } } -/** - * Compute the X, Y, Z coordinates of the children of a node - * @param {SpatialNode} spatialNode The parent node - * @returns {Array[]} Child coordinate arrays - * @private - */ -function getChildCoords(spatialNode) { - const { x, y, z } = spatialNode; - const xMin = x * 2; - const yMin = y * 2; - const zMin = z * 2; - const yMax = yMin + 1; - const xMax = xMin + 1; - const zMax = zMin + 1; - - return [ - [xMin, yMin, zMin], - [xMax, yMin, zMin], - [xMin, yMax, zMin], - [xMax, yMax, zMin], - [xMin, yMin, zMax], - [xMax, yMin, zMax], - [xMin, yMax, zMax], - [xMax, yMax, zMax], - ]; -} - /** * @function * From 9fae451ac8a5245175ed878209c78f289bd71958 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 13 Feb 2023 18:42:19 -0500 Subject: [PATCH 460/679] Add specs for SpatialNode --- packages/engine/Source/Scene/SpatialNode.js | 10 --- .../engine/Source/Scene/VoxelTraversal.js | 20 +++--- .../engine/Specs/Scene/SpatialNodeSpec.js | 67 ++++++++++++++++++- .../engine/Specs/Scene/VoxelTraversalSpec.js | 4 +- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/packages/engine/Source/Scene/SpatialNode.js b/packages/engine/Source/Scene/SpatialNode.js index f352769e239..ffe2b7dce42 100644 --- a/packages/engine/Source/Scene/SpatialNode.js +++ b/packages/engine/Source/Scene/SpatialNode.js @@ -65,16 +65,6 @@ function SpatialNode(level, x, y, z, parent, shape, voxelDimensions) { this.computeBoundingVolumes(shape, voxelDimensions); } -/** - * @param {SpatialNode} a - * @param {SpatialNode} b - * @returns {Boolean} - */ -SpatialNode.spatialComparator = function (a, b) { - // The higher of the two screen space errors is prioritized - return b.screenSpaceError - a.screenSpaceError; -}; - const scratchObbHalfScale = new Cartesian3(); /** diff --git a/packages/engine/Source/Scene/VoxelTraversal.js b/packages/engine/Source/Scene/VoxelTraversal.js index 03d39b6b0a8..755cbb2b2a7 100644 --- a/packages/engine/Source/Scene/VoxelTraversal.js +++ b/packages/engine/Source/Scene/VoxelTraversal.js @@ -145,16 +145,6 @@ function VoxelTraversal( */ this._binaryTreeKeyframeWeighting = new Array(keyframeCount); - function binaryTreeWeightingRecursive(arr, start, end, depth) { - if (start > end) { - return; - } - const mid = Math.floor((start + end) / 2); - arr[mid] = depth; - binaryTreeWeightingRecursive(arr, start, mid - 1, depth + 1); - binaryTreeWeightingRecursive(arr, mid + 1, end, depth + 1); - } - const binaryTreeKeyframeWeighting = this._binaryTreeKeyframeWeighting; binaryTreeKeyframeWeighting[0] = 0; binaryTreeKeyframeWeighting[keyframeCount - 1] = 0; @@ -228,6 +218,16 @@ function VoxelTraversal( this.leafNodeTexelSizeUv = new Cartesian2(); } +function binaryTreeWeightingRecursive(arr, start, end, depth) { + if (start > end) { + return; + } + const mid = Math.floor((start + end) / 2); + arr[mid] = depth; + binaryTreeWeightingRecursive(arr, start, mid - 1, depth + 1); + binaryTreeWeightingRecursive(arr, mid + 1, end, depth + 1); +} + VoxelTraversal.simultaneousRequestCountMaximum = 50; /** diff --git a/packages/engine/Specs/Scene/SpatialNodeSpec.js b/packages/engine/Specs/Scene/SpatialNodeSpec.js index 0c61b774135..e498b2cea7a 100644 --- a/packages/engine/Specs/Scene/SpatialNodeSpec.js +++ b/packages/engine/Specs/Scene/SpatialNodeSpec.js @@ -6,14 +6,19 @@ import { } from "../../index.js"; describe("Scene/SpatialNode", function () { - it("constructs", function () { + function getBasicBoxShape() { const shape = new VoxelBoxShape(); const modelMatrix = Matrix4.IDENTITY.clone(); const minBounds = VoxelBoxShape.DefaultMinBounds.clone(); const maxBounds = VoxelBoxShape.DefaultMaxBounds.clone(); shape.update(modelMatrix, minBounds, maxBounds); + return shape; + } - const level = 0; + it("constructs", function () { + const shape = getBasicBoxShape(); + + const level = 2; const x = 1; const y = 2; const z = 3; @@ -22,7 +27,63 @@ describe("Scene/SpatialNode", function () { const node = new SpatialNode(level, x, y, z, parent, shape, dimensions); - expect(node.level).toEqual(0); + expect(node.level).toEqual(2); expect(node.screenSpaceError).toEqual(0.0); }); + + it("returns coordinates of child", function () { + const shape = getBasicBoxShape(); + + const level = 2; + const x = 1; + const y = 2; + const z = 3; + const parent = undefined; + const dimensions = new Cartesian3(2, 3, 4); + + const node = new SpatialNode(level, x, y, z, parent, shape, dimensions); + + const expectedChildCoordinates = [ + [3, 2, 4, 6], + [3, 3, 4, 6], + [3, 2, 5, 6], + [3, 3, 5, 6], + [3, 2, 4, 7], + [3, 3, 4, 7], + [3, 2, 5, 7], + [3, 3, 5, 7], + ]; + + expect(node.getChildCoordinates()).toEqual(expectedChildCoordinates); + }); + + it("computes screen space error", function () { + const shape = getBasicBoxShape(); + + const level = 0; + const x = 0; + const y = 0; + const z = 0; + const parent = undefined; + const dimensions = new Cartesian3(2, 3, 4); + + const node = new SpatialNode(level, x, y, z, parent, shape, dimensions); + + const cameraPosition = new Cartesian3(0.0, 0.0, 2.0); + node.computeScreenSpaceError(cameraPosition, 1.0); + + expect(node.screenSpaceError).toEqual(1.0); + }); + + it("adds a keyframe node", function () { + const shape = getBasicBoxShape(); + + const parent = undefined; + const dimensions = new Cartesian3(2, 3, 4); + const node = new SpatialNode(0, 0, 0, 0, parent, shape, dimensions); + + const numberOfStartingKeyframes = node.keyframeNodes.length; + node.createKeyframeNode(0); + expect(node.keyframeNodes.length - numberOfStartingKeyframes).toEqual(1); + }); }); diff --git a/packages/engine/Specs/Scene/VoxelTraversalSpec.js b/packages/engine/Specs/Scene/VoxelTraversalSpec.js index 1d2e2f447e1..95a5d7499b0 100644 --- a/packages/engine/Specs/Scene/VoxelTraversalSpec.js +++ b/packages/engine/Specs/Scene/VoxelTraversalSpec.js @@ -22,7 +22,7 @@ function turnCameraAround(scene) { describe( "Scene/VoxelTraversal", function () { - const keyframeCount = 1; + const keyframeCount = 3; const textureMemory = 500; let scene; @@ -30,6 +30,7 @@ describe( let camera; let primitive; let traversal; + beforeEach(function () { scene = createScene(); provider = new Cesium3DTilesVoxelProvider({ @@ -162,7 +163,6 @@ describe( const tileInQueueWhenLookingAtRoot = tilesInMegatextureCount === 1; expect(tileInQueueWhenLookingAtRoot).toBe(true); - traversal.megatexture.remove(0); turnCameraAround(scene); traversal.update( scene.frameState, From 233b00bb5ce1b24096d86c4f9a59c4eab927b924 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 14 Feb 2023 10:44:42 -0500 Subject: [PATCH 461/679] Cleanup --- packages/engine/Source/Scene/Terrain.js | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/engine/Source/Scene/Terrain.js b/packages/engine/Source/Scene/Terrain.js index 1ed77b5a7e7..6d83298e92f 100644 --- a/packages/engine/Source/Scene/Terrain.js +++ b/packages/engine/Source/Scene/Terrain.js @@ -2,27 +2,6 @@ import Check from "../Core/Check.js"; import Event from "../Core/Event.js"; import createWorldTerrainAsync from "../Core/createWorldTerrainAsync.js"; -function handleError(errorEvent, error) { - if (errorEvent.numberOfListeners > 0) { - errorEvent.raiseEvent(error); - } else { - // Default handler is to log to the console - console.error(error); - } -} - -async function handlePromise(instance, promise) { - let provider; - try { - provider = await Promise.resolve(promise); - } catch (error) { - handleError(instance._errorEvent, error); - } - - instance._provider = provider; - instance._readyEvent.raiseEvent(provider); -} - /** * A helper to manage async operations of a terrain provider. * @@ -163,6 +142,27 @@ Terrain.fromWorldTerrain = function (options) { return new Terrain(createWorldTerrainAsync(options)); }; +function handleError(errorEvent, error) { + if (errorEvent.numberOfListeners > 0) { + errorEvent.raiseEvent(error); + } else { + // Default handler is to log to the console + console.error(error); + } +} + +async function handlePromise(instance, promise) { + let provider; + try { + provider = await Promise.resolve(promise); + } catch (error) { + handleError(instance._errorEvent, error); + } + + instance._provider = provider; + instance._readyEvent.raiseEvent(provider); +} + export default Terrain; /** From d2615060d2fdb129f253ae640b1b36666e1d8328 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 14 Feb 2023 12:56:17 -0500 Subject: [PATCH 462/679] Add specs for VoxelPrimitive --- .../engine/Specs/Scene/VoxelPrimitiveSpec.js | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js index ade10cd9bfd..b75f1a87654 100644 --- a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js +++ b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js @@ -6,6 +6,7 @@ import { VoxelPrimitive, } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; +import pollToPromise from "../../../../Specs/pollToPromise.js"; describe( "Scene/VoxelPrimitive", @@ -15,6 +16,11 @@ describe( beforeEach(function () { scene = createScene(); + + const camera = scene.camera; + camera.position = Cartesian3.fromElements(-10, -10, -10); + camera.direction = Cartesian3.fromElements(1, 1, 1); + provider = new Cesium3DTilesVoxelProvider({ url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", }); @@ -46,6 +52,55 @@ describe( expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); expect(primitive._tileCount).toBe(provider._tileCount); expect(primitive._traversal).toBeDefined(); + expect(primitive.minimumValues).toBe(provider.minimumValues); + expect(primitive.maximumValues).toBe(provider.maximumValues); + }); + }); + + it("toggles render options that require shader rebuilds", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + + function toggleOption(option, defaultValue, newValue) { + expect(primitive[option]).toBe(defaultValue); + primitive[option] = newValue; + expect(primitive._shaderDirty).toBe(true); + primitive.update(scene.frameState); + expect(primitive[option]).toBe(newValue); + expect(primitive._shaderDirty).toBe(false); + } + + return pollToPromise(function () { + scene.renderForSpecs(); + const traversal = primitive._traversal; + return traversal.isRenderable(traversal.rootNode); + }).then(function () { + toggleOption("depthTest", true, false); + toggleOption("jitter", true, false); + toggleOption("nearestSampling", false, true); + }); + }); + + it("sets render parameters", function () { + const primitive = new VoxelPrimitive({ provider }); + scene.primitives.add(primitive); + + function setParameter(parameter, defaultValue, newValue) { + expect(primitive[parameter]).toBe(defaultValue); + primitive[parameter] = newValue; + primitive.update(scene.frameState); + expect(primitive[parameter]).toBe(newValue); + } + + return pollToPromise(function () { + scene.renderForSpecs(); + const traversal = primitive._traversal; + return traversal.isRenderable(traversal.rootNode); + }).then(function () { + setParameter("levelBlendFactor", 0.0, 0.5); + setParameter("screenSpaceError", 4.0, 2.0); + setParameter("stepSize", 1.0, 0.5); + setParameter("debugDraw", false, true); }); }); From 48529bf0cd26a5e613486bfa21e0a91b2dd21b72 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 14 Feb 2023 13:18:05 -0500 Subject: [PATCH 463/679] Update terrain async Sandcastles --- .../gallery/3D Tiles Feature Picking.html | 2 +- .../gallery/3D Tiles Feature Styling.html | 2 +- .../gallery/3D Tiles Inspector.html | 2 +- .../gallery/3D Tiles Interactivity.html | 2 +- ...es Next Photogrammetry Classification.html | 2 +- ...D Tiles Photogrammetry Classification.html | 2 +- .../gallery/3D Tiles Photogrammetry.html | 2 +- .../3D Tiles Point Cloud Classification.html | 2 +- .../gallery/3D Tiles Point Cloud Shading.html | 2 +- .../gallery/3D Tiles Point Cloud.html | 2 +- .../3D Tiles Terrain Classification.html | 2 +- .../ArcGIS Tiled Elevation Terrain.html | 12 ++++-- Apps/Sandcastle/gallery/ArcticDEM.html | 12 ++++-- Apps/Sandcastle/gallery/Atmosphere.html | 5 +-- Apps/Sandcastle/gallery/Billboards.html | 27 +++++++------ Apps/Sandcastle/gallery/CZML Path.html | 2 +- Apps/Sandcastle/gallery/Cardboard.html | 2 +- .../gallery/Cartographic Limit Rectangle.html | 2 +- Apps/Sandcastle/gallery/Cesium Inspector.html | 2 +- .../gallery/Cesium OSM Buildings.html | 2 +- .../gallery/Cesium World Terrain.html | 2 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 2 +- Apps/Sandcastle/gallery/Clamp to Terrain.html | 34 ++++++++++++----- .../gallery/Classification Types.html | 2 +- Apps/Sandcastle/gallery/Classification.html | 2 +- Apps/Sandcastle/gallery/Clouds.html | 2 +- .../Custom Shaders Property Textures.html | 2 +- .../gallery/Drawing on Terrain.html | 2 +- .../gallery/Elevation Band Material.html | 2 +- Apps/Sandcastle/gallery/FXAA.html | 2 +- Apps/Sandcastle/gallery/GPX.html | 2 +- .../gallery/Geometry Height Reference.html | 11 ++---- Apps/Sandcastle/gallery/Globe Materials.html | 2 +- .../gallery/Globe Translucency.html | 2 +- .../gallery/Google Earth Enterprise.html | 36 +++++++++++------- .../gallery/High Dynamic Range.html | 2 +- .../gallery/I3S 3D Object Layer.html | 2 +- .../gallery/I3S Feature Picking.html | 2 +- .../gallery/I3S IntegratedMesh Layer.html | 2 +- Apps/Sandcastle/gallery/Interpolation.html | 2 +- Apps/Sandcastle/gallery/Lighting.html | 2 +- Apps/Sandcastle/gallery/MSAA.html | 2 +- .../gallery/Montreal Point Cloud.html | 2 +- Apps/Sandcastle/gallery/PAMAP Terrain.html | 12 ++++-- .../gallery/Particle System Weather.html | 2 +- .../gallery/Physically-Based Materials.html | 2 +- .../gallery/Procedural Terrain.html | 4 +- .../gallery/Sample Height from 3D Tiles.html | 2 +- .../gallery/Scene Rendering Performance.html | 2 +- Apps/Sandcastle/gallery/Shadows.html | 2 +- .../gallery/Terrain Clipping Planes.html | 2 +- .../gallery/Terrain Exaggeration.html | 2 +- .../development/BillboardClampToGround.html | 2 +- .../development/Billboards Instancing.html | 2 +- Apps/Sandcastle/gallery/development/Fog.html | 2 +- .../development/Ground Polyline Material.html | 2 +- .../Ground Primitive Materials.html | 2 +- .../gallery/development/Ground Primitive.html | 2 +- .../development/Many Clipping Planes.html | 2 +- .../gallery/development/Multiple Shadows.html | 2 +- .../gallery/development/Picking.html | 18 ++++----- .../development/Polylines On Terrain.html | 2 +- .../gallery/development/Shadows.html | 38 +++++++++++++------ .../development/Terrain Entity Batching.html | 2 +- .../development/Terrain Performance.html | 2 +- packages/engine/Source/Scene/Scene.js | 10 ++++- packages/engine/Source/Scene/Terrain.js | 20 ++++++++-- .../BaseLayerPickerViewModel.js | 12 ++++++ 68 files changed, 220 insertions(+), 139 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index 97033e63157..8174e5fdec8 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -36,7 +36,7 @@ // A simple demo of 3D Tiles feature picking with hover and select behavior // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.scene.globe.depthTestAgainstTerrain = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index 4340727762f..c9fe5b050eb 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -56,7 +56,7 @@ <h1>Loading...</h1> // How to use the 3D Tiles Styling language to style individual features, like buildings. // Styling language specification: https://github.com/CesiumGS/3d-tiles/tree/main/specification/Styling const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index b0439fe0852..736bde4e8f3 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -38,7 +38,7 @@ //Sandcastle_Begin // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.scene.globe.depthTestAgainstTerrain = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index 904e4eaa3f8..30426497ff7 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -75,7 +75,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 07074ed6b1d..97f23ac0aba 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -39,7 +39,7 @@ const viewer = new Cesium.Viewer("cesiumContainer", { infoBox: false, orderIndependentTranslucency: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index 0d96bfd5ade..f59d6b68833 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -38,7 +38,7 @@ //Sandcastle_Begin // An example of using a b3dm tileset to classify another b3dm tileset. const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); // A normal b3dm tileset containing photogrammetry diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index 68b2f6f3eda..ca2b8281520 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -37,7 +37,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const tileset = new Cesium.Cesium3DTileset({ diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index a2f0a3618ce..d07104ec585 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -38,7 +38,7 @@ //Sandcastle_Begin // An example showing a point cloud tileset classified by a Geometry tileset. const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index c4a5e7ea38b..cdc3ed6fc5d 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -161,7 +161,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index 0432f4efa17..2d5fa1d21e6 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -38,7 +38,7 @@ //Sandcastle_Begin //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const tileset = new Cesium.Cesium3DTileset({ diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index 1093592f986..ef9ea1301f1 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -37,7 +37,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const geocoder = viewer.geocoder.viewModel; diff --git a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html index 00296dec2b5..3b485c41240 100644 --- a/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html +++ b/Apps/Sandcastle/gallery/ArcGIS Tiled Elevation Terrain.html @@ -32,11 +32,15 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + const viewer = new Cesium.Viewer("cesiumContainer"); + + try { + viewer.scene.terrainProvider = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer" - ), - }); //Sandcastle_End + ); + } catch (error) { + window.alert(`Failed to load terrain. ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index 63898c9c0cb..8d6d3509b59 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -35,13 +35,17 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { + const viewer = new Cesium.Viewer("cesiumContainer"); + + try { // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. // https://www.pgc.umn.edu/data/arcticdem/ - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + viewer.scene.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( Cesium.IonResource.fromAssetId(3956) - ), - }); + ); + } catch (error) { + window.alert(`Failed to load terrain. ${error}`); + } // Add Alaskan locations Sandcastle.addDefaultToolbarMenu( diff --git a/Apps/Sandcastle/gallery/Atmosphere.html b/Apps/Sandcastle/gallery/Atmosphere.html index f72de2db6aa..fccd53dfee7 100644 --- a/Apps/Sandcastle/gallery/Atmosphere.html +++ b/Apps/Sandcastle/gallery/Atmosphere.html @@ -794,10 +794,9 @@ .getObservable(viewModel, "enableTerrain") .subscribe(async function (newValue) { if (newValue) { - const provider = await Cesium.createWorldTerrainAsync(); - globe.terrainProvider = provider; + scene.setTerrain(Cesium.Terrain.fromWorldTerrain()); } else { - globe.terrainProvider = new Cesium.EllipsoidTerrainProvider(); + scene.terrainProvider = new Cesium.EllipsoidTerrainProvider(); } }); Cesium.knockout diff --git a/Apps/Sandcastle/gallery/Billboards.html b/Apps/Sandcastle/gallery/Billboards.html index 2a84a6bd5be..b4d9a48585b 100644 --- a/Apps/Sandcastle/gallery/Billboards.html +++ b/Apps/Sandcastle/gallery/Billboards.html @@ -247,15 +247,24 @@ }); } - let terrainProvider; async function disableDepthTest() { Sandcastle.declare(disableDepthTest); - terrainProvider = viewer.terrainProvider; - const worldTerrainProvider = await Cesium.createWorldTerrainAsync(); - viewer.terrainProvider = worldTerrainProvider; viewer.scene.globe.depthTestAgainstTerrain = true; + try { + const worldTerrainProvider = await Cesium.createWorldTerrainAsync(); + + // Return early in case a different option has been selected in the meantime + if (!viewer.scene.globe.depthTestAgainstTerrain) { + return; + } + + viewer.terrainProvider = worldTerrainProvider; + } catch (error) { + window.alert(`Failed to load terrain. ${error}`); + } + viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), billboard: { @@ -351,15 +360,11 @@ }, ]); - Sandcastle.reset = function () { + Sandcastle.reset = async function () { viewer.camera.flyHome(0); viewer.entities.removeAll(); - - if (Cesium.defined(terrainProvider)) { - viewer.terrainProvider = terrainProvider; - terrainProvider = undefined; - viewer.scene.globe.depthTestAgainstTerrain = false; - } + viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider(); + viewer.scene.globe.depthTestAgainstTerrain = false; }; //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/CZML Path.html b/Apps/Sandcastle/gallery/CZML Path.html index 88705898430..ea38f129d0c 100644 --- a/Apps/Sandcastle/gallery/CZML Path.html +++ b/Apps/Sandcastle/gallery/CZML Path.html @@ -7244,7 +7244,7 @@ ]; const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), baseLayerPicker: false, shouldAnimate: true, }); diff --git a/Apps/Sandcastle/gallery/Cardboard.html b/Apps/Sandcastle/gallery/Cardboard.html index ad7cf758ecd..3febdf89e25 100644 --- a/Apps/Sandcastle/gallery/Cardboard.html +++ b/Apps/Sandcastle/gallery/Cardboard.html @@ -37,7 +37,7 @@ //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { vrButton: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); // Click the VR button in the bottom right of the screen to switch to VR mode. diff --git a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html index 5f23f3ba7a4..7b6da076857 100644 --- a/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html +++ b/Apps/Sandcastle/gallery/Cartographic Limit Rectangle.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Cesium Inspector.html b/Apps/Sandcastle/gallery/Cesium Inspector.html index 4a11858124b..203ee283221 100644 --- a/Apps/Sandcastle/gallery/Cesium Inspector.html +++ b/Apps/Sandcastle/gallery/Cesium Inspector.html @@ -40,7 +40,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index 6472a4ae6c5..6c1d6d635b5 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -39,7 +39,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.scene.primitives.add(Cesium.createOsmBuildings()); diff --git a/Apps/Sandcastle/gallery/Cesium World Terrain.html b/Apps/Sandcastle/gallery/Cesium World Terrain.html index 2a878d49bf7..5950f7ec89f 100644 --- a/Apps/Sandcastle/gallery/Cesium World Terrain.html +++ b/Apps/Sandcastle/gallery/Cesium World Terrain.html @@ -37,7 +37,7 @@ //Sandcastle_Begin // For more information on Cesium World Terrain, see https://cesium.com/platform/cesium-ion/content/cesium-world-terrain/ const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); //Sandcastle_End }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index afcb097af0a..ee38cdbfed9 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; const clock = viewer.clock; diff --git a/Apps/Sandcastle/gallery/Clamp to Terrain.html b/Apps/Sandcastle/gallery/Clamp to Terrain.html index 5a8442b19e6..afd345d8f7d 100644 --- a/Apps/Sandcastle/gallery/Clamp to Terrain.html +++ b/Apps/Sandcastle/gallery/Clamp to Terrain.html @@ -37,11 +37,17 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), - }); + const viewer = new Cesium.Viewer("cesiumContainer"); viewer.scene.globe.depthTestAgainstTerrain = true; + let worldTerrain; + try { + worldTerrain = await Cesium.createWorldTerrainAsync(); + viewer.scene.terrainProvider = worldTerrain; + } catch (error) { + window.alert(`There was an error creating world terrain. ${error}`); + } + Sandcastle.addDefaultToolbarMenu( [ { @@ -237,7 +243,14 @@ }, { text: "Sample line positions and draw with depth test disabled", - onselect: function () { + onselect: async function () { + if (!Cesium.defined(worldTerrain)) { + window.alert( + "Cannot sample terrain. World terrain failed to load." + ); + return; + } + const length = 1000; const startLon = Cesium.Math.toRadians(86.953793); @@ -256,12 +269,11 @@ terrainSamplePositions.push(position); } - Promise.resolve( - Cesium.sampleTerrainMostDetailed( - viewer.terrainProvider, + try { + const samples = await Cesium.sampleTerrainMostDetailed( + worldTerrain, terrainSamplePositions - ) - ).then(function (samples) { + ); let offset = 10.0; for (let i = 0; i < samples.length; ++i) { samples[i].height += offset; @@ -301,7 +313,9 @@ ); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); + } catch (error) { + window.alert(`There was an error sampling terrain ${error}`); + } }, }, { diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 48a91083aea..2e285c956b3 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const tileset = new Cesium.Cesium3DTileset({ diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index fe0c96719a9..092fd125631 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -80,7 +80,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index 2e1a9fc85ca..356a94f9c7f 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -33,7 +33,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), infoBox: false, shouldAnimate: true, }); diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index d9834b847ef..0a556bff380 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -43,7 +43,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = false; diff --git a/Apps/Sandcastle/gallery/Drawing on Terrain.html b/Apps/Sandcastle/gallery/Drawing on Terrain.html index d851d5510eb..80d118801ac 100644 --- a/Apps/Sandcastle/gallery/Drawing on Terrain.html +++ b/Apps/Sandcastle/gallery/Drawing on Terrain.html @@ -49,7 +49,7 @@ const viewer = new Cesium.Viewer("cesiumContainer", { selectionIndicator: false, infoBox: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( diff --git a/Apps/Sandcastle/gallery/Elevation Band Material.html b/Apps/Sandcastle/gallery/Elevation Band Material.html index d25df198fc7..b5c20ad2b9a 100644 --- a/Apps/Sandcastle/gallery/Elevation Band Material.html +++ b/Apps/Sandcastle/gallery/Elevation Band Material.html @@ -119,7 +119,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestVertexNormals: true, //Needed to visualize slope }), }); diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index 22cfa7bc706..00e94e1f1b1 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -33,7 +33,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.scene.camera.setView({ diff --git a/Apps/Sandcastle/gallery/GPX.html b/Apps/Sandcastle/gallery/GPX.html index aae9a2644ca..03c0b63c3ec 100755 --- a/Apps/Sandcastle/gallery/GPX.html +++ b/Apps/Sandcastle/gallery/GPX.html @@ -35,7 +35,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const pinBuilder = new Cesium.PinBuilder(); diff --git a/Apps/Sandcastle/gallery/Geometry Height Reference.html b/Apps/Sandcastle/gallery/Geometry Height Reference.html index 58c0b761150..70c23c7678a 100644 --- a/Apps/Sandcastle/gallery/Geometry Height Reference.html +++ b/Apps/Sandcastle/gallery/Geometry Height Reference.html @@ -36,10 +36,11 @@ "use strict"; //Sandcastle_Begin const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + const worldTerrain = Cesium.Terrain.fromWorldTerrain(); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayerPicker: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: worldTerrain, }); // depth test against terrain is required to make the polygons clamp to terrain @@ -66,12 +67,8 @@ Sandcastle.addToolbarMenu([ { text: "Terrain Enabled", - onselect: async function () { - try { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); - } catch (error) { - console.log(error); - } + onselect: function () { + viewer.scene.setTerrain(worldTerrain); }, }, { diff --git a/Apps/Sandcastle/gallery/Globe Materials.html b/Apps/Sandcastle/gallery/Globe Materials.html index 6f5d1152ecd..541eb296db3 100644 --- a/Apps/Sandcastle/gallery/Globe Materials.html +++ b/Apps/Sandcastle/gallery/Globe Materials.html @@ -123,7 +123,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestVertexNormals: true, //Needed to visualize slope }), }); diff --git a/Apps/Sandcastle/gallery/Globe Translucency.html b/Apps/Sandcastle/gallery/Globe Translucency.html index 2eb52f1cc43..559e0332f57 100644 --- a/Apps/Sandcastle/gallery/Globe Translucency.html +++ b/Apps/Sandcastle/gallery/Globe Translucency.html @@ -85,7 +85,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index e72a3fffba0..20ef94ec801 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -35,23 +35,33 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( - new Cesium.Resource({ - url: "http://www.earthenterprise.org/3d", - proxy: new Cesium.DefaultProxy("/proxy/"), - }) - ); - const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.GoogleEarthEnterpriseImageryProvider({ - metadata: geeMetadata, - }), - terrainProvider: Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( - geeMetadata - ), baseLayerPicker: false, }); + try { + const geeMetadata = await Cesium.GoogleEarthEnterpriseMetadata.fromUrl( + new Cesium.Resource({ + url: "http://www.earthenterprise.org/3d", + proxy: new Cesium.DefaultProxy("/proxy/"), + }) + ); + + viewer.scene.terrainProvider = Cesium.GoogleEarthEnterpriseTerrainProvider.fromMetadata( + geeMetadata + ); + + const layers = viewer.scene.imageryLayers; + const blackMarble = layers.addImageryProvider( + new Cesium.GoogleEarthEnterpriseImageryProvider({ + metadata: geeMetadata, + }) + ); + } catch (error) { + console.log(`Failed to create Google Earth providers from metadata. Confirm GEE service is correctly configured. + ${error}`); + } + // Start off looking at San Francisco. viewer.camera.setView({ destination: Cesium.Rectangle.fromDegrees(-123.0, 36.0, -121.7, 39.0), diff --git a/Apps/Sandcastle/gallery/High Dynamic Range.html b/Apps/Sandcastle/gallery/High Dynamic Range.html index a4bf40b32d6..597ab24155e 100644 --- a/Apps/Sandcastle/gallery/High Dynamic Range.html +++ b/Apps/Sandcastle/gallery/High Dynamic Range.html @@ -33,7 +33,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), shadows: true, }); diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 232a99021d9..778356edb8e 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -39,7 +39,7 @@ <h1>Loading...</h1> "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), animation: false, timeline: false, }); diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index 5678e7aed10..c8c8348b415 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -39,7 +39,7 @@ <h1>Loading...</h1> "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), animation: false, timeline: false, }); diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 03bb0cefccd..935b2fc0dd9 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -39,7 +39,7 @@ <h1>Loading...</h1> "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), animation: false, timeline: false, }); diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index bfdfd13be5f..d3538bb1165 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -41,7 +41,7 @@ infoBox: false, //Disable InfoBox widget selectionIndicator: false, //Disable selection indicator shouldAnimate: true, // Enable animations - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); //Enable lighting based on the sun position diff --git a/Apps/Sandcastle/gallery/Lighting.html b/Apps/Sandcastle/gallery/Lighting.html index c7d4f7d58ac..05603bd3bcc 100644 --- a/Apps/Sandcastle/gallery/Lighting.html +++ b/Apps/Sandcastle/gallery/Lighting.html @@ -33,7 +33,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }), diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index d7ca20bcb7a..bc381d56670 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -36,7 +36,7 @@ contextOptions: { requestWebgl1: false, }, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.clock.currentTime = Cesium.JulianDate.fromIso8601( diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index b95bcac4a31..77d78a50e7d 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -87,7 +87,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index 58bd496fd15..4d3d07e1fa4 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -35,13 +35,17 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin - const viewer = new Cesium.Viewer("cesiumContainer", { + const viewer = new Cesium.Viewer("cesiumContainer"); + + try { // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) // http://www.pasda.psu.edu/ - terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( Cesium.IonResource.fromAssetId(3957) - ), - }); + ); + } catch (error) { + window.alert(`Failed to load terrain. ${error}`); + } // Add PA locations Sandcastle.addDefaultToolbarMenu( diff --git a/Apps/Sandcastle/gallery/Particle System Weather.html b/Apps/Sandcastle/gallery/Particle System Weather.html index 5a422f13c8f..4f062cf0fa3 100644 --- a/Apps/Sandcastle/gallery/Particle System Weather.html +++ b/Apps/Sandcastle/gallery/Particle System Weather.html @@ -37,7 +37,7 @@ //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = true; diff --git a/Apps/Sandcastle/gallery/Physically-Based Materials.html b/Apps/Sandcastle/gallery/Physically-Based Materials.html index 9e55d885c24..f1703793bd2 100644 --- a/Apps/Sandcastle/gallery/Physically-Based Materials.html +++ b/Apps/Sandcastle/gallery/Physically-Based Materials.html @@ -48,7 +48,7 @@ const viewer = new Cesium.Viewer("cesiumContainer", { clockViewModel: new Cesium.ClockViewModel(clock), selectionIndicator: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); Sandcastle.addToggleButton("Shadows", viewer.shadows, function ( diff --git a/Apps/Sandcastle/gallery/Procedural Terrain.html b/Apps/Sandcastle/gallery/Procedural Terrain.html index 9ccae27cc1c..c09fa8d923b 100644 --- a/Apps/Sandcastle/gallery/Procedural Terrain.html +++ b/Apps/Sandcastle/gallery/Procedural Terrain.html @@ -130,9 +130,7 @@ }, }); - const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: noiseTerrainProvider, - }); + const viewer = new Cesium.Viewer("cesiumContainer"); Sandcastle.addDefaultToolbarMenu([ { diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index 822ee54a6ad..5e4c6b5d6ae 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index c19e6f795f2..bc865eedbe7 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -146,7 +146,7 @@ <h4>Max delta time</h4> const viewer = new Cesium.Viewer("cesiumContainer", { requestRenderMode: true, maximumRenderTimeChange: Infinity, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/Shadows.html b/Apps/Sandcastle/gallery/Shadows.html index 816b5cf7e49..676b184c114 100644 --- a/Apps/Sandcastle/gallery/Shadows.html +++ b/Apps/Sandcastle/gallery/Shadows.html @@ -41,7 +41,7 @@ shadows: true, terrainShadows: Cesium.ShadowMode.ENABLED, shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const shadowMap = viewer.shadowMap; diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index 8b20e699b29..fe9b60f6339 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -65,7 +65,7 @@ const viewer = new Cesium.Viewer("cesiumContainer", { skyAtmosphere: false, shouldAnimate: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), scene3DOnly: true, }); const globe = viewer.scene.globe; diff --git a/Apps/Sandcastle/gallery/Terrain Exaggeration.html b/Apps/Sandcastle/gallery/Terrain Exaggeration.html index 9f403cb3cfb..330eef8f148 100644 --- a/Apps/Sandcastle/gallery/Terrain Exaggeration.html +++ b/Apps/Sandcastle/gallery/Terrain Exaggeration.html @@ -77,7 +77,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html index 5464114add0..a64afbc4e5e 100644 --- a/Apps/Sandcastle/gallery/development/BillboardClampToGround.html +++ b/Apps/Sandcastle/gallery/development/BillboardClampToGround.html @@ -38,7 +38,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.scene.globe.depthTestAgainstTerrain = true; diff --git a/Apps/Sandcastle/gallery/development/Billboards Instancing.html b/Apps/Sandcastle/gallery/development/Billboards Instancing.html index f2b3d42b8aa..35fa357413f 100644 --- a/Apps/Sandcastle/gallery/development/Billboards Instancing.html +++ b/Apps/Sandcastle/gallery/development/Billboards Instancing.html @@ -38,7 +38,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/development/Fog.html b/Apps/Sandcastle/gallery/development/Fog.html index 6ee1da4951b..1cee8891ab1 100644 --- a/Apps/Sandcastle/gallery/development/Fog.html +++ b/Apps/Sandcastle/gallery/development/Fog.html @@ -51,7 +51,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.extend(Cesium.viewerCesiumInspectorMixin); diff --git a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html index 50c3720ef8b..8114048e966 100644 --- a/Apps/Sandcastle/gallery/development/Ground Polyline Material.html +++ b/Apps/Sandcastle/gallery/development/Ground Polyline Material.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html index 025e7273b5c..49f994da67c 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive Materials.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }), diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index 03d4b8c4ca9..efc45fe992f 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 00dfb8d73d8..e5cc49ba2b9 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -72,7 +72,7 @@ selectionIndicator: false, shouldAnimate: true, projectionPicker: true, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index af859df2067..a87df91fcc8 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -46,7 +46,7 @@ infoBox: false, selectionIndicator: false, timeline: false, - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; diff --git a/Apps/Sandcastle/gallery/development/Picking.html b/Apps/Sandcastle/gallery/development/Picking.html index 4e1dee21557..2c8c309193e 100644 --- a/Apps/Sandcastle/gallery/development/Picking.html +++ b/Apps/Sandcastle/gallery/development/Picking.html @@ -50,6 +50,9 @@ originalColor: new Cesium.Color(), }; + const worldTerrain = Cesium.Terrain.fromWorldTerrain(); + const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + Sandcastle.addToolbarMenu([ { text: "Billboard", @@ -477,8 +480,8 @@ }, { text: "Vector tile polygons", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + onselect: function () { + viewer.scene.setTerrain(worldTerrain); tileset = viewer.scene.primitives.add( new Cesium.Cesium3DTileset({ @@ -537,8 +540,8 @@ }, { text: "Vector tile polylines", - onselect: async function () { - viewer.terrainProvider = await Cesium.createWorldTerrainAsync(); + onselect: function () { + viewer.scene.setTerrain(worldTerrain); tileset = viewer.scene.primitives.add( new Cesium.Cesium3DTileset({ @@ -613,11 +616,8 @@ } handler = handler && handler.destroy(); viewer.scene.camera.flyHome(0.0); - if ( - !(viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider) - ) { - viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider(); - } + + viewer.terrainProvider = ellipsoidTerrainProvider; }; //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html index 9a6325466b2..2d7fbf10c88 100644 --- a/Apps/Sandcastle/gallery/development/Polylines On Terrain.html +++ b/Apps/Sandcastle/gallery/development/Polylines On Terrain.html @@ -54,7 +54,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }), diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index cef7861a6f1..67a7ac80420 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -743,8 +743,6 @@ scene.debugShowFramesPerSecond = true; - const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); - function getModelPosition() { if (viewModel.modelPosition === "Ground") { return 0.0; @@ -759,7 +757,14 @@ } } - const createWorldTerrainPromise = Cesium.createWorldTerrainAsync(); + const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + let worldTerrain; + try { + worldTerrain = await Cesium.createWorldTerrainAsync(); + } catch (error) { + console.log(`Failed to create world terrain. ${error}`); + } + async function updateLocation() { // Get the height of the terrain at the given longitude/latitude, then create the scene. const location = uiOptions.locations[viewModel.location]; @@ -769,19 +774,28 @@ location.centerLatitude ), ]; + let terrainProvider = ellipsoidTerrainProvider; - if (viewModel.terrain) { - terrainProvider = await createWorldTerrainPromise; + if (viewModel.terrain && Cesium.defined(worldTerrain)) { + terrainProvider = worldTerrain; } - globe.terrainProvider = terrainProvider; - const updatedPositions = await Cesium.sampleTerrain( - terrainProvider, - 11, - positions - ); - location.height = updatedPositions[0].height + getModelPosition(); + + scene.terrainProvider = terrainProvider; + + try { + const updatedPositions = await Cesium.sampleTerrain( + terrainProvider, + 11, + positions + ); + location.height = updatedPositions[0].height + getModelPosition(); + } catch (error) { + console.log(`There was an error sampling terrain. ${error}`); + } + createScene(); } + updateLocation(); function createScene() { diff --git a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html index 4f15619d76c..0b9e79eeda8 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html +++ b/Apps/Sandcastle/gallery/development/Terrain Entity Batching.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync({ + terrain: Cesium.Terrain.fromWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }), diff --git a/Apps/Sandcastle/gallery/development/Terrain Performance.html b/Apps/Sandcastle/gallery/development/Terrain Performance.html index 83d8c0f9e0d..3c2517bdc42 100644 --- a/Apps/Sandcastle/gallery/development/Terrain Performance.html +++ b/Apps/Sandcastle/gallery/development/Terrain Performance.html @@ -36,7 +36,7 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: await Cesium.createWorldTerrainAsync(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); const scene = viewer.scene; const camera = scene.camera; diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index 6e21011661e..29c9098d852 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -4390,9 +4390,15 @@ function setTerrain(scene, terrain) { scene._removeTerrainProviderReadyListener && scene._removeTerrainProviderReadyListener(); - // Set a placeholder + // If the terrain is already loaded, set it immediately + if (terrain.ready) { + if (defined(scene.globe)) { + scene.globe.terrainProvider = terrain.provider; + } + return; + } + // Otherwise, set a placeholder scene.globe.terrainProvider = undefined; - scene._removeTerrainProviderReadyListener = terrain.readyEvent.addEventListener( (provider) => { if (defined(scene) && defined(scene.globe)) { diff --git a/packages/engine/Source/Scene/Terrain.js b/packages/engine/Source/Scene/Terrain.js index 6d83298e92f..ccc5845ad77 100644 --- a/packages/engine/Source/Scene/Terrain.js +++ b/packages/engine/Source/Scene/Terrain.js @@ -44,6 +44,7 @@ function Terrain(terrainProviderPromise) { Check.typeOf.object("terrainProviderPromise", terrainProviderPromise); //>>includeEnd('debug'); + this._ready = false; this._provider = undefined; this._errorEvent = new Event(); this._readyEvent = new Event(); @@ -79,6 +80,19 @@ Object.defineProperties(Terrain.prototype, { }, }, + /** + * Returns true when the terrain provider has been successfully created. Otherwise, returns false. + * @memberof Viewer.prototype + * + * @type {boolean} + * @readonly + */ + ready: { + get: function () { + return this._ready; + }, + }, + /** * The terrain provider providing surface geometry to a globe. Do not use until {@link Terrain.readyEvent} is raised. * @memberof Viewer.prototype @@ -155,12 +169,12 @@ async function handlePromise(instance, promise) { let provider; try { provider = await Promise.resolve(promise); + instance._provider = provider; + instance._ready = true; + instance._readyEvent.raiseEvent(provider); } catch (error) { handleError(instance._errorEvent, error); } - - instance._provider = provider; - instance._readyEvent.raiseEvent(provider); } export default Terrain; diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js index 78c964be115..c7f03bc541a 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -254,9 +254,21 @@ function BaseLayerPickerViewModel(options) { newProvider = value.creationCommand(); } + let cancelUpdate = false; + const removeCancelListener = this._globe.terrainProviderChanged.addEventListener( + () => { + cancelUpdate = true; + removeCancelListener(); + } + ); const terrain = new Terrain(Promise.resolve(newProvider)); const removeEventListener = terrain.readyEvent.addEventListener( (terrainProvider) => { + if (cancelUpdate) { + // Early return in case something has outside of the picker. + return; + } + this._globe.depthTestAgainstTerrain = !( terrainProvider instanceof EllipsoidTerrainProvider ); From a70e106ebb77193d035fd7574bf16daca60a7a56 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 14 Feb 2023 13:52:23 -0500 Subject: [PATCH 464/679] Update baseLayerPicker specs --- .../BaseLayerPickerViewModelSpec.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js index 4485c03fe46..eca8540e775 100644 --- a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js +++ b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js @@ -1,5 +1,6 @@ import { EllipsoidTerrainProvider, + Event, ImageryLayerCollection, } from "@cesium/engine"; @@ -9,6 +10,7 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { function MockGlobe() { this.imageryLayers = new ImageryLayerCollection(); this.terrainProvider = new EllipsoidTerrainProvider(); + this.terrainProviderChanged = new Event(); } MockGlobe.prototype.isDestroyed = () => false; @@ -257,6 +259,23 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { expect(globe.terrainProvider).toBe(testProvider); }); + it("selectedTerrain cancels update if terrainProvider is set externally", async function () { + const terrainProviderViewModels = [ + testProviderViewModel, + testProviderViewModelAsync, + ]; + const globe = new MockGlobe(); + const viewModel = new BaseLayerPickerViewModel({ + globe: globe, + terrainProviderViewModels: terrainProviderViewModels, + }); + + viewModel.selectedTerrain = testProviderViewModelAsync; + globe.terrainProviderChanged.raiseEvent(); + await testProviderViewModelAsync.creationCommand(); + expect(globe.terrainProvider).not.toBe(testProvider); + }); + it("settings selectedImagery only removes layers added by view model", function () { const imageryViewModels = [testProviderViewModel]; const globe = new MockGlobe(); From b83bbbf6079ecd3f70336cd1f8a57143308e7987 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 14 Feb 2023 17:09:37 -0500 Subject: [PATCH 465/679] Document and clean up Cesium3DTilesetTraversal --- .../Source/Scene/Cesium3DTilesetTraversal.js | 361 +++++++++++++----- 1 file changed, 258 insertions(+), 103 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 5ea90344ad7..4b5c8c2cc81 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -9,10 +9,6 @@ import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; */ function Cesium3DTilesetTraversal() {} -function isVisible(tile) { - return tile._visible && tile._inRequestVolume; -} - const traversal = { stack: new ManagedArray(), stackMaximumLength: 0, @@ -37,6 +33,11 @@ const selectionTraversal = { const descendantSelectionDepth = 2; +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { tileset._requestedTiles.length = 0; @@ -90,55 +91,80 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { } }; +/** + * @private + * @param {Cesium3DTile} tile + * @returns {boolean} Whether the tile is visible + */ +function isVisible(tile) { + return tile._visible && tile._inRequestVolume; +} + +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ function executeBaseTraversal(tileset, root, frameState) { const baseScreenSpaceError = tileset._maximumScreenSpaceError; - const maximumScreenSpaceError = tileset._maximumScreenSpaceError; - executeTraversal( - tileset, - root, - baseScreenSpaceError, - maximumScreenSpaceError, - frameState - ); + executeTraversal(tileset, root, baseScreenSpaceError, frameState); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ function executeSkipTraversal(tileset, root, frameState) { const baseScreenSpaceError = Number.MAX_VALUE; - const maximumScreenSpaceError = tileset._maximumScreenSpaceError; - executeTraversal( - tileset, - root, - baseScreenSpaceError, - maximumScreenSpaceError, - frameState - ); + executeTraversal(tileset, root, baseScreenSpaceError, frameState); traverseAndSelect(tileset, root, frameState); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ function executeBaseAndSkipTraversal(tileset, root, frameState) { const baseScreenSpaceError = Math.max( tileset.baseScreenSpaceError, tileset.maximumScreenSpaceError ); - const maximumScreenSpaceError = tileset.maximumScreenSpaceError; - executeTraversal( - tileset, - root, - baseScreenSpaceError, - maximumScreenSpaceError, - frameState - ); + executeTraversal(tileset, root, baseScreenSpaceError, frameState); traverseAndSelect(tileset, root, frameState); } +/** + * The private ._skipLevelOfDetail flag on a Cesium3DTileset is updated in + * Cesium3DTileset.prototype.prePassesUpdate to confirm if skipping is actually + * possible and allowed, even when the public .skipLevelOfDetail flag is true + * @private + * @param {Cesium3DTileset} tileset + * @returns {boolean} Whether to do LOD skipping + */ function skipLevelOfDetail(tileset) { return tileset._skipLevelOfDetail; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function addEmptyTile(tileset, tile) { tileset._emptyTiles.push(tile); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function selectTile(tileset, tile, frameState) { if (tile.contentVisibility(frameState) !== Intersect.OUTSIDE) { const tileContent = tile.content; @@ -156,6 +182,12 @@ function selectTile(tileset, tile, frameState) { } } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ function selectDescendants(tileset, root, frameState) { const stack = descendantTraversal.stack; stack.push(root); @@ -166,8 +198,7 @@ function selectDescendants(tileset, root, frameState) { ); const tile = stack.pop(); const children = tile.children; - const childrenLength = children.length; - for (let i = 0; i < childrenLength; ++i) { + for (let i = 0; i < children.length; ++i) { const child = children[i]; if (isVisible(child)) { if (child.contentAvailable) { @@ -183,6 +214,12 @@ function selectDescendants(tileset, root, frameState) { } } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function selectDesiredTile(tileset, tile, frameState) { if (!skipLevelOfDetail(tileset)) { if (tile.contentAvailable) { @@ -206,11 +243,23 @@ function selectDesiredTile(tileset, tile, frameState) { } } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function visitTile(tileset, tile, frameState) { ++tileset._statistics.visited; tile._visitedFrame = frameState.frameNumber; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function touchTile(tileset, tile, frameState) { if (tile._touchedFrame === frameState.frameNumber) { // Prevents another pass from touching the frame again @@ -220,60 +269,81 @@ function touchTile(tileset, tile, frameState) { tile._touchedFrame = frameState.frameNumber; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function updateMinimumMaximumPriority(tileset, tile) { - tileset._maximumPriority.distance = Math.max( - tile._priorityHolder._distanceToCamera, - tileset._maximumPriority.distance - ); - tileset._minimumPriority.distance = Math.min( - tile._priorityHolder._distanceToCamera, - tileset._minimumPriority.distance - ); - tileset._maximumPriority.depth = Math.max( - tile._depth, - tileset._maximumPriority.depth + const maximumPriority = tileset._maximumPriority; + const minimumPriority = tileset._minimumPriority; + const priorityHolder = tile._priorityHolder; + + maximumPriority.distance = Math.max( + priorityHolder._distanceToCamera, + maximumPriority.distance ); - tileset._minimumPriority.depth = Math.min( - tile._depth, - tileset._minimumPriority.depth + minimumPriority.distance = Math.min( + priorityHolder._distanceToCamera, + minimumPriority.distance ); - tileset._maximumPriority.foveatedFactor = Math.max( - tile._priorityHolder._foveatedFactor, - tileset._maximumPriority.foveatedFactor + maximumPriority.depth = Math.max(tile._depth, maximumPriority.depth); + minimumPriority.depth = Math.min(tile._depth, minimumPriority.depth); + maximumPriority.foveatedFactor = Math.max( + priorityHolder._foveatedFactor, + maximumPriority.foveatedFactor ); - tileset._minimumPriority.foveatedFactor = Math.min( - tile._priorityHolder._foveatedFactor, - tileset._minimumPriority.foveatedFactor + minimumPriority.foveatedFactor = Math.min( + priorityHolder._foveatedFactor, + minimumPriority.foveatedFactor ); - tileset._maximumPriority.reverseScreenSpaceError = Math.max( + maximumPriority.reverseScreenSpaceError = Math.max( tile._priorityReverseScreenSpaceError, - tileset._maximumPriority.reverseScreenSpaceError + maximumPriority.reverseScreenSpaceError ); - tileset._minimumPriority.reverseScreenSpaceError = Math.min( + minimumPriority.reverseScreenSpaceError = Math.min( tile._priorityReverseScreenSpaceError, - tileset._minimumPriority.reverseScreenSpaceError + minimumPriority.reverseScreenSpaceError ); } +/** + * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. + * + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ function isOnScreenLongEnough(tileset, tile, frameState) { - // Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. if (!tileset._cullRequestsWhileMoving) { return true; } - const sphere = tile.boundingSphere; - const diameter = Math.max(sphere.radius * 2.0, 1.0); - - const camera = frameState.camera; + const { + positionWCDeltaMagnitude, + positionWCDeltaMagnitudeLastFrame, + } = frameState.camera; const deltaMagnitude = - camera.positionWCDeltaMagnitude !== 0.0 - ? camera.positionWCDeltaMagnitude - : camera.positionWCDeltaMagnitudeLastFrame; + positionWCDeltaMagnitude !== 0.0 + ? positionWCDeltaMagnitude + : positionWCDeltaMagnitudeLastFrame; + + // How do n frames of this movement compare to the tile's physical size. + const diameter = Math.max(tile.boundingSphere.radius * 2.0, 1.0); const movementRatio = - (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; // How do n frames of this movement compare to the tile's physical size. + (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; + return movementRatio < 1.0; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function loadTile(tileset, tile, frameState) { if ( tile._requestedFrame === frameState.frameNumber || @@ -296,6 +366,12 @@ function loadTile(tileset, tile, frameState) { tileset._requestedTiles.push(tile); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function updateVisibility(tileset, tile, frameState) { if (tile._updatedVisibilityFrame === tileset._updatedVisibilityFrame) { // Return early if visibility has already been checked during the traversal. @@ -307,6 +383,13 @@ function updateVisibility(tileset, tile, frameState) { tile._updatedVisibilityFrame = tileset._updatedVisibilityFrame; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ function anyChildrenVisible(tileset, tile, frameState) { let anyVisible = false; const children = tile.children; @@ -319,6 +402,13 @@ function anyChildrenVisible(tileset, tile, frameState) { return anyVisible; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ function meetsScreenSpaceErrorEarly(tileset, tile, frameState) { const parent = tile.parent; if ( @@ -337,6 +427,12 @@ function meetsScreenSpaceErrorEarly(tileset, tile, frameState) { ); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function updateTileVisibility(tileset, tile, frameState) { updateVisibility(tileset, tile, frameState); @@ -374,6 +470,12 @@ function updateTileVisibility(tileset, tile, frameState) { } } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function updateTile(tileset, tile, frameState) { // Reset some of the tile's flags and re-evaluate visibility updateTileVisibility(tileset, tile, frameState); @@ -389,6 +491,11 @@ function updateTile(tileset, tile, frameState) { tile._finalResolution = true; } +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ function updateTileAncestorContentLinks(tile, frameState) { tile._ancestorWithContent = undefined; tile._ancestorWithContentAvailable = undefined; @@ -410,16 +517,31 @@ function updateTileAncestorContentLinks(tile, frameState) { } } +/** + * @private + * @param {Cesium3DTile} tile + * @returns {boolean} + */ function hasEmptyContent(tile) { return ( tile.hasEmptyContent || tile.hasTilesetContent || tile.hasImplicitContent ); } +/** + * @private + * @param {Cesium3DTile} tile + * @returns {boolean} + */ function hasUnloadedContent(tile) { return !hasEmptyContent(tile) && tile.contentUnloaded; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function reachedSkippingThreshold(tileset, tile) { const ancestor = tile._ancestorWithContent; return ( @@ -432,8 +554,15 @@ function reachedSkippingThreshold(tileset, tile) { ); } +/** + * Sort by farthest child first since this is going on a stack + * + * @private + * @param {Cesium3DTile} a + * @param {Cesium3DTile} b + * @returns {number} + */ function sortChildrenByDistanceToCamera(a, b) { - // Sort by farthest child first since this is going on a stack if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { return b._centerZDepth - a._centerZDepth; } @@ -441,13 +570,19 @@ function sortChildrenByDistanceToCamera(a, b) { return b._distanceToCamera - a._distanceToCamera; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {ManagedArray} stack + * @param {FrameState} frameState + * @returns {boolean} + */ function updateAndPushChildren(tileset, tile, stack, frameState) { - let i; const replace = tile.refine === Cesium3DTileRefine.REPLACE; const children = tile.children; - const length = children.length; - for (i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { updateTile(tileset, children[i], frameState); } @@ -467,7 +602,7 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { let minimumPriority = Number.MAX_VALUE; let child; - for (i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { child = children[i]; if (isVisible(child)) { stack.push(child); @@ -522,7 +657,7 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { priorityHolder._distanceToCamera ); - for (i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { child = children[i]; child._priorityHolder = priorityHolder; } @@ -531,6 +666,13 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { return refines; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {number} baseScreenSpaceError + * @returns {boolean} + */ function inBaseTraversal(tileset, tile, baseScreenSpaceError) { if (!skipLevelOfDetail(tileset)) { return true; @@ -549,6 +691,12 @@ function inBaseTraversal(tileset, tile, baseScreenSpaceError) { return tile._screenSpaceError > baseScreenSpaceError; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {boolean} + */ function canTraverse(tileset, tile) { if (tile.children.length === 0) { return false; @@ -561,19 +709,21 @@ function canTraverse(tileset, tile) { return tile._screenSpaceError > tileset._maximumScreenSpaceError; } -function executeTraversal( - tileset, - root, - baseScreenSpaceError, - maximumScreenSpaceError, - frameState -) { - // Depth-first traversal that traverses all visible tiles and marks tiles for selection. - // If skipLevelOfDetail is off then a tile does not refine until all children are loaded. - // This is the traditional replacement refinement approach and is called the base traversal. - // Tiles that have a greater screen space error than the base screen space error are part of the base traversal, - // all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree - // and rendering children and parent tiles simultaneously. +/** + * Depth-first traversal that traverses all visible tiles and marks tiles for selection. + * If skipLevelOfDetail is off then a tile does not refine until all children are loaded. + * This is the traditional replacement refinement approach and is called the base traversal. + * Tiles that have a greater screen space error than the base screen space error are part of the base traversal, + * all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree + * and rendering children and parent tiles simultaneously. + * + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {number} baseScreenSpaceError + * @param {FrameState} frameState + */ +function executeTraversal(tileset, root, baseScreenSpaceError, frameState) { const stack = traversal.stack; stack.push(root); @@ -587,17 +737,12 @@ function executeTraversal( updateTileAncestorContentLinks(tile, frameState); const baseTraversal = inBaseTraversal(tileset, tile, baseScreenSpaceError); - const add = tile.refine === Cesium3DTileRefine.ADD; - const replace = tile.refine === Cesium3DTileRefine.REPLACE; const parent = tile.parent; const parentRefines = !defined(parent) || parent._refines; - let refines = false; - if (canTraverse(tileset, tile)) { - refines = - updateAndPushChildren(tileset, tile, stack, frameState) && - parentRefines; - } + const refines = canTraverse(tileset, tile) + ? updateAndPushChildren(tileset, tile, stack, frameState) && parentRefines + : false; const stoppedRefining = !refines && parentRefines; @@ -605,16 +750,16 @@ function executeTraversal( // Add empty tile just to show its debug bounding volume // If the tile has tileset content load the external tileset // If the tile cannot refine further select its nearest loaded ancestor - addEmptyTile(tileset, tile, frameState); + addEmptyTile(tileset, tile); loadTile(tileset, tile, frameState); if (stoppedRefining) { selectDesiredTile(tileset, tile, frameState); } - } else if (add) { + } else if (tile.refine === Cesium3DTileRefine.ADD) { // Additive tiles are always loaded and selected selectDesiredTile(tileset, tile, frameState); loadTile(tileset, tile, frameState); - } else if (replace) { + } else if (tile.refine === Cesium3DTileRefine.REPLACE) { if (baseTraversal) { // Always load tiles in the base traversal // Select tiles that can't refine further @@ -638,8 +783,17 @@ function executeTraversal( } } +/** + * Depth-first traversal that checks if all nearest descendants with content are loaded. + * Ignores visibility. + * + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState + * @returns {boolean} + */ function executeEmptyTraversal(tileset, root, frameState) { - // Depth-first traversal that checks if all nearest descendants with content are loaded. Ignores visibility. let allDescendantsLoaded = true; const stack = emptyTraversal.stack; stack.push(root); @@ -699,11 +853,14 @@ function executeEmptyTraversal(tileset, root, frameState) { * * NOTE: 3D Tiles uses 3 bits from the stencil buffer meaning this will not work when there is a chain of * selected tiles that is deeper than 7. This is not very likely. + * * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} root + * @param {FrameState} frameState */ function traverseAndSelect(tileset, root, frameState) { - const stack = selectionTraversal.stack; - const ancestorStack = selectionTraversal.ancestorStack; + const { stack, ancestorStack } = selectionTraversal; let lastAncestor; stack.push(root); @@ -736,14 +893,10 @@ function traverseAndSelect(tileset, root, frameState) { continue; } - const add = tile.refine === Cesium3DTileRefine.ADD; - const shouldSelect = tile._shouldSelect; - const children = tile.children; - const childrenLength = children.length; const traverse = canTraverse(tileset, tile); - if (shouldSelect) { - if (add) { + if (tile._shouldSelect) { + if (tile.refine === Cesium3DTileRefine.ADD) { selectTile(tileset, tile, frameState); } else { tile._selectionDepth = ancestorStack.length; @@ -761,7 +914,8 @@ function traverseAndSelect(tileset, root, frameState) { } if (traverse) { - for (let i = 0; i < childrenLength; ++i) { + const children = tile.children; + for (let i = 0; i < children.length; ++i) { const child = children[i]; if (isVisible(child)) { stack.push(child); @@ -770,4 +924,5 @@ function traverseAndSelect(tileset, root, frameState) { } } } + export default Cesium3DTilesetTraversal; From 2fb7c7d4658040bf737c8d08b6be8a3c8c7d5cdd Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 00:42:59 +0800 Subject: [PATCH 466/679] Types in Material module backup --- packages/engine/Source/Scene/Material.js | 112 ++++++----------------- 1 file changed, 29 insertions(+), 83 deletions(-) diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index 16c22d08ddc..4592350b9d2 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -36,55 +36,6 @@ import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.j import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; import WaterMaterial from "../Shaders/Materials/Water.js"; -/** - * @typedef {Object.<string, any>} GeneralValue Use for general uniform value, may be a struct in GLSL. - * @typedef { Color | - * String | - * Cartesian2 | - * import('../Core/Cartesian3').default | - * import('../Core/Cartesian4').default | - * Matrix2 | - * Matrix3 | - * Matrix4 | - * GeneralValue - * } FabricUniformValue Fabric material uniform value types. - */ - -/** - * @typedef {Object.<string, FabricUniformValue>} FabricUniforms An object contain all uniforms that fabric material will use. - */ - -/** - * @typedef {object} FabricComponents An object define all components will apply to fabric material. - * @property {string} [diffuse='vec3(0.0)'] Diffuse expression. - * @property {number | String} [specular=0.0] Specular Expression. - * @property {number | String} [shininess=1.0] Shininess Expression. - * @property {string} [normal] Normal Expression. - * @property {string} [emission='vec3(0.0)'] Emission Expression. - * @property {number | String} [alpha=1] Alpha Expression. - */ - -/** - * @typedef {object} Fabric The fabric definition to a material template object. - * @property {string} type The material type. - * @property {FabricUniforms} uniforms The uniforms that will use during shadering. - * @property {FabricComponents} components - * @property {string} source Shader code. - */ - -/** - * @callback TranslucentFunction A function determine material is translucent or not. - * @param {Material} material - * @returns {boolean} - */ - -/** - * @typedef {object} MaterialTemplate A material template object. - * @property {boolean} strict - * @property {Fabric} fabric - * @property {boolean | TranslucentFunction} translucent - */ - /** * A Material defines surface appearance through a combination of diffuse, specular, * normal, emission, and alpha components. These values are specified using a @@ -277,11 +228,11 @@ import WaterMaterial from "../Shaders/Materials/Water.js"; * * @param {object} [options] Object with the following properties: * @param {boolean} [options.strict=false] Throws errors for issues that would normally be ignored, including unused uniforms or materials. - * @param {boolean | TranslucentFunction} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry + * @param {boolean|Function} [options.translucent=true] When <code>true</code> or a function that returns <code>true</code>, the geometry * with this material is expected to appear translucent. * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The {@link TextureMinificationFilter} to apply to this material's textures. * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The {@link TextureMagnificationFilter} to apply to this material's textures. - * @param {Fabric} options.fabric The fabric JSON used to generate the material. + * @param {object} options.fabric The fabric JSON used to generate the material. *ructor * * @exception {DeveloperError} fabric: uniform has invalid type. @@ -399,7 +350,7 @@ Material._uniformList = {}; * Shorthand for: new Material({fabric : {type : type}}); * * @param {string} type The base material type. - * @param {FabricUniforms} [uniforms] Overrides for the default uniforms. + * @param {object} [uniforms] Overrides for the default uniforms. * @returns {Material} New material object. * * @exception {DeveloperError} material with that type does not exist. @@ -1255,11 +1206,6 @@ function getNumberOfTokens(material, token, excludePeriod) { Material._materialCache = { _materials: {}, - /** - * Add a fabric material to - * @param {string} type The material type. - * @param {MaterialTemplate} materialTemplate An object represent a fabric material. - */ addMaterial: function (type, materialTemplate) { this._materials[type] = materialTemplate; }, @@ -1270,19 +1216,19 @@ Material._materialCache = { /** * Gets or sets the default texture uniform value. - * @type {"czm_defaultImage"} + * @type {string} */ Material.DefaultImageId = "czm_defaultImage"; /** * Gets or sets the default cube map texture uniform value. - * @type {"czm_defaultCubeMap"} + * @type {string} */ Material.DefaultCubeMapId = "czm_defaultCubeMap"; /** * Gets the name of the color material. - * @type {"Color"} + * @type {string} * @readonly */ Material.ColorType = "Color"; @@ -1304,7 +1250,7 @@ Material._materialCache.addMaterial(Material.ColorType, { /** * Gets the name of the image material. - * @type {"Image"} + * @type {string} * @readonly */ Material.ImageType = "Image"; @@ -1329,7 +1275,7 @@ Material._materialCache.addMaterial(Material.ImageType, { /** * Gets the name of the diffuce map material. - * @type {"DiffuseMap"} + * @type {string} * @readonly */ Material.DiffuseMapType = "DiffuseMap"; @@ -1350,7 +1296,7 @@ Material._materialCache.addMaterial(Material.DiffuseMapType, { /** * Gets the name of the alpha map material. - * @type {"AlphaMap"} + * @type {string} * @readonly */ Material.AlphaMapType = "AlphaMap"; @@ -1371,7 +1317,7 @@ Material._materialCache.addMaterial(Material.AlphaMapType, { /** * Gets the name of the specular map material. - * @type {"SpecularMap"} + * @type {string} * @readonly */ Material.SpecularMapType = "SpecularMap"; @@ -1392,7 +1338,7 @@ Material._materialCache.addMaterial(Material.SpecularMapType, { /** * Gets the name of the emmision map material. - * @type {"EmissionMap"} + * @type {string} * @readonly */ Material.EmissionMapType = "EmissionMap"; @@ -1413,7 +1359,7 @@ Material._materialCache.addMaterial(Material.EmissionMapType, { /** * Gets the name of the bump map material. - * @type {"BumpMap"} + * @type {string} * @readonly */ Material.BumpMapType = "BumpMap"; @@ -1433,7 +1379,7 @@ Material._materialCache.addMaterial(Material.BumpMapType, { /** * Gets the name of the normal map material. - * @type {"NormalMap"} + * @type {string} * @readonly */ Material.NormalMapType = "NormalMap"; @@ -1453,7 +1399,7 @@ Material._materialCache.addMaterial(Material.NormalMapType, { /** * Gets the name of the grid material. - * @type {"Grid"} + * @type {string} * @readonly */ Material.GridType = "Grid"; @@ -1477,7 +1423,7 @@ Material._materialCache.addMaterial(Material.GridType, { /** * Gets the name of the stripe material. - * @type {"Stripe"} + * @type {string} * @readonly */ Material.StripeType = "Stripe"; @@ -1501,7 +1447,7 @@ Material._materialCache.addMaterial(Material.StripeType, { /** * Gets the name of the checkerboard material. - * @type {"Checkerboard"} + * @type {string} * @readonly */ Material.CheckerboardType = "Checkerboard"; @@ -1523,7 +1469,7 @@ Material._materialCache.addMaterial(Material.CheckerboardType, { /** * Gets the name of the dot material. - * @type {"Dot"} + * @type {string} * @readonly */ Material.DotType = "Dot"; @@ -1545,7 +1491,7 @@ Material._materialCache.addMaterial(Material.DotType, { /** * Gets the name of the water material. - * @type {"Water"} + * @type {string} * @readonly */ Material.WaterType = "Water"; @@ -1575,7 +1521,7 @@ Material._materialCache.addMaterial(Material.WaterType, { /** * Gets the name of the rim lighting material. - * @type {"RimLighting"} + * @type {string} * @readonly */ Material.RimLightingType = "RimLighting"; @@ -1597,7 +1543,7 @@ Material._materialCache.addMaterial(Material.RimLightingType, { /** * Gets the name of the fade material. - * @type {"Fade"} + * @type {string} * @readonly */ Material.FadeType = "Fade"; @@ -1627,7 +1573,7 @@ Material._materialCache.addMaterial(Material.FadeType, { /** * Gets the name of the polyline arrow material. - * @type {"PolylineArrow"} + * @type {string} * @readonly */ Material.PolylineArrowType = "PolylineArrow"; @@ -1644,7 +1590,7 @@ Material._materialCache.addMaterial(Material.PolylineArrowType, { /** * Gets the name of the polyline glow material. - * @type {"PolylineDash"} + * @type {string} * @readonly */ Material.PolylineDashType = "PolylineDash"; @@ -1664,7 +1610,7 @@ Material._materialCache.addMaterial(Material.PolylineDashType, { /** * Gets the name of the polyline glow material. - * @type {"PolylineGlow"} + * @type {string} * @readonly */ Material.PolylineGlowType = "PolylineGlow"; @@ -1683,7 +1629,7 @@ Material._materialCache.addMaterial(Material.PolylineGlowType, { /** * Gets the name of the polyline outline material. - * @type {"PolylineOutline"} + * @type {string} * @readonly */ Material.PolylineOutlineType = "PolylineOutline"; @@ -1705,7 +1651,7 @@ Material._materialCache.addMaterial(Material.PolylineOutlineType, { /** * Gets the name of the elevation contour material. - * @type {"ElevationContour"} + * @type {string} * @readonly */ Material.ElevationContourType = "ElevationContour"; @@ -1724,7 +1670,7 @@ Material._materialCache.addMaterial(Material.ElevationContourType, { /** * Gets the name of the elevation contour material. - * @type {"ElevationRamp"} + * @type {string} * @readonly */ Material.ElevationRampType = "ElevationRamp"; @@ -1743,7 +1689,7 @@ Material._materialCache.addMaterial(Material.ElevationRampType, { /** * Gets the name of the slope ramp material. - * @type {"SlopeRamp"} + * @type {string} * @readonly */ Material.SlopeRampMaterialType = "SlopeRamp"; @@ -1760,7 +1706,7 @@ Material._materialCache.addMaterial(Material.SlopeRampMaterialType, { /** * Gets the name of the aspect ramp material. - * @type {"AspectRamp"} + * @type {string} * @readonly */ Material.AspectRampMaterialType = "AspectRamp"; @@ -1777,7 +1723,7 @@ Material._materialCache.addMaterial(Material.AspectRampMaterialType, { /** * Gets the name of the elevation band material. - * @type {"ElevationBand"} + * @type {string} * @readonly */ Material.ElevationBandType = "ElevationBand"; From fa6d4522fc4480f051a02db45bd6e2e23caef736 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 01:02:18 +0800 Subject: [PATCH 467/679] Remove the missing backup types --- packages/engine/Source/Scene/Material.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Material.js b/packages/engine/Source/Scene/Material.js index 4592350b9d2..53d4155dcc2 100644 --- a/packages/engine/Source/Scene/Material.js +++ b/packages/engine/Source/Scene/Material.js @@ -299,7 +299,7 @@ function Material(options) { /** * When <code>true</code> or a function that returns <code>true</code>, * the geometry is expected to appear translucent. - * @type {boolean | TranslucentFunction} + * @type {boolean|Function} * @default undefined */ this.translucent = undefined; From aaa98a2f71a8754dc3d0bb691924c194c47ab8c6 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 01:28:03 +0800 Subject: [PATCH 468/679] Add missing constructor type to primitive type --- .../Sandcastle/gallery/Custom DataSource.html | 2 +- .../engine/Source/Core/RequestErrorEvent.js | 2 +- packages/engine/Source/Core/Resource.js | 22 +++++++++---------- .../Source/DataSources/CzmlDataSource.js | 6 ++--- .../Source/DataSources/GeoJsonDataSource.js | 6 ++--- .../Source/Scene/CameraEventAggregator.js | 2 +- .../Source/Scene/ImageryLayerFeatureInfo.js | 4 ++-- .../Source/Scene/Implicit3DTileContent.js | 2 +- .../Scene/UrlTemplateImageryProvider.js | 4 ++-- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 820c7c41962..860e38ca7a5 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -226,7 +226,7 @@ /** * Asynchronously loads the GeoJSON at the provided url, replacing any existing data. - * @param {Object} url The url to be processed. + * @param {object} url The url to be processed. * @returns {Promise} a promise that will resolve when the GeoJSON is loaded. */ WebGLGlobeDataSource.prototype.loadUrl = function (url) { diff --git a/packages/engine/Source/Core/RequestErrorEvent.js b/packages/engine/Source/Core/RequestErrorEvent.js index ba9d4b9fe1f..41f0e685e55 100644 --- a/packages/engine/Source/Core/RequestErrorEvent.js +++ b/packages/engine/Source/Core/RequestErrorEvent.js @@ -9,7 +9,7 @@ import parseResponseHeaders from "./parseResponseHeaders.js"; * * @param {number} [statusCode] The HTTP error status code, such as 404. * @param {object} [response] The response included along with the error. - * @param {string|Object} [responseHeaders] The response headers, represented either as an object literal or as a + * @param {string|object} [responseHeaders] The response headers, represented either as an object literal or as a * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. */ function RequestErrorEvent(statusCode, response, responseHeaders) { diff --git a/packages/engine/Source/Core/Resource.js b/packages/engine/Source/Core/Resource.js index c4292ebad06..a13e79f0e95 100644 --- a/packages/engine/Source/Core/Resource.js +++ b/packages/engine/Source/Core/Resource.js @@ -817,7 +817,7 @@ Resource.prototype.fetchArrayBuffer = function () { /** * Creates a Resource and calls fetchArrayBuffer() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -861,7 +861,7 @@ Resource.prototype.fetchBlob = function () { /** * Creates a Resource and calls fetchBlob() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1076,7 +1076,7 @@ function fetchImage(options) { /** * Creates a Resource and calls fetchImage() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1136,7 +1136,7 @@ Resource.prototype.fetchText = function () { /** * Creates a Resource and calls fetchText() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1197,7 +1197,7 @@ Resource.prototype.fetchJson = function () { /** * Creates a Resource and calls fetchJson() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1246,7 +1246,7 @@ Resource.prototype.fetchXML = function () { /** * Creates a Resource and calls fetchXML() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1351,7 +1351,7 @@ function fetchJsonp(resource, callbackParameterName, functionName) { /** * Creates a Resource from a URL and calls fetchJsonp() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1522,7 +1522,7 @@ Resource.prototype.fetch = function (options) { /** * Creates a Resource from a URL and calls fetch() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1578,7 +1578,7 @@ Resource.prototype.delete = function (options) { /** * Creates a Resource from a URL and calls delete() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.data] Data that is posted with the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. @@ -1636,7 +1636,7 @@ Resource.prototype.head = function (options) { /** * Creates a Resource from a URL and calls head() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). @@ -1692,7 +1692,7 @@ Resource.prototype.options = function (options) { /** * Creates a Resource from a URL and calls options() on it. * - * @param {string|Object} options A url or an object with the following properties + * @param {string|object} options A url or an object with the following properties * @param {string} options.url The url of the resource. * @param {object} [options.queryParameters] An object containing query parameters that will be sent when retrieving the resource. * @param {object} [options.templateValues] Key/Value pairs that are used to replace template values (eg. {x}). diff --git a/packages/engine/Source/DataSources/CzmlDataSource.js b/packages/engine/Source/DataSources/CzmlDataSource.js index 3c3e6dab676..ed733a1cca9 100644 --- a/packages/engine/Source/DataSources/CzmlDataSource.js +++ b/packages/engine/Source/DataSources/CzmlDataSource.js @@ -4859,7 +4859,7 @@ function CzmlDataSource(name) { /** * Creates a Promise to a new instance loaded with the provided CZML data. * - * @param {Resource|string|Object} czml A url or CZML object to be processed. + * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<CzmlDataSource>} A promise that resolves to the new instance once the data is processed. @@ -5032,7 +5032,7 @@ CzmlDataSource.updaters = [ /** * Processes the provided url or CZML object without clearing any existing data. * - * @param {Resource|string|Object} czml A url or CZML object to be processed. + * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<CzmlDataSource>} A promise that resolves to this instances once the data is processed. @@ -5044,7 +5044,7 @@ CzmlDataSource.prototype.process = function (czml, options) { /** * Loads the provided url or CZML object, replacing any existing data. * - * @param {Resource|string|Object} czml A url or CZML object to be processed. + * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<CzmlDataSource>} A promise that resolves to this instances once the data is processed. diff --git a/packages/engine/Source/DataSources/GeoJsonDataSource.js b/packages/engine/Source/DataSources/GeoJsonDataSource.js index c7670c904b8..ce8429d476e 100644 --- a/packages/engine/Source/DataSources/GeoJsonDataSource.js +++ b/packages/engine/Source/DataSources/GeoJsonDataSource.js @@ -607,7 +607,7 @@ function GeoJsonDataSource(name) { /** * Creates a Promise to a new instance loaded with the provided GeoJSON or TopoJSON data. * - * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<GeoJsonDataSource>} A promise that will resolve when the data is loaded. @@ -885,7 +885,7 @@ Object.defineProperties(GeoJsonDataSource.prototype, { /** * Asynchronously loads the provided GeoJSON or TopoJSON data, replacing any existing data. * - * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. @@ -897,7 +897,7 @@ GeoJsonDataSource.prototype.load = function (data, options) { /** * Asynchronously loads the provided GeoJSON or TopoJSON data, without replacing any existing data. * - * @param {Resource|string|Object} data A url, GeoJSON object, or TopoJSON object to be loaded. + * @param {Resource|string|object} data A url, GeoJSON object, or TopoJSON object to be loaded. * @param {GeoJsonDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise<GeoJsonDataSource>} a promise that will resolve when the GeoJSON is loaded. diff --git a/packages/engine/Source/Scene/CameraEventAggregator.js b/packages/engine/Source/Scene/CameraEventAggregator.js index 7cf268e6b6a..79be40dff2b 100644 --- a/packages/engine/Source/Scene/CameraEventAggregator.js +++ b/packages/engine/Source/Scene/CameraEventAggregator.js @@ -429,7 +429,7 @@ CameraEventAggregator.prototype.getMovement = function (type, modifier) { * * @param {CameraEventType} type The camera event type. * @param {KeyboardEventModifier} [modifier] The keyboard modifier. - * @returns {Object|undefined} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code> or <code>undefined</code>. + * @returns {object|undefined} An object with two {@link Cartesian2} properties: <code>startPosition</code> and <code>endPosition</code> or <code>undefined</code>. */ CameraEventAggregator.prototype.getLastMovement = function (type, modifier) { //>>includeStart('debug', pragmas.debug); diff --git a/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js b/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js index 7c2654da2e9..0ce99360f84 100644 --- a/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js +++ b/packages/engine/Source/Scene/ImageryLayerFeatureInfo.js @@ -30,13 +30,13 @@ function ImageryLayerFeatureInfo() { /** * Gets or sets the raw data describing the feature. The raw data may be in any * number of formats, such as GeoJSON, KML, etc. - * @type {Object|undefined} + * @type {object|undefined} */ this.data = undefined; /** * Gets or sets the image layer of the feature. - * @type {Object|undefined} + * @type {object|undefined} */ this.imageryLayer = undefined; } diff --git a/packages/engine/Source/Scene/Implicit3DTileContent.js b/packages/engine/Source/Scene/Implicit3DTileContent.js index 4e76d2b8d71..fc6bef81a2f 100644 --- a/packages/engine/Source/Scene/Implicit3DTileContent.js +++ b/packages/engine/Source/Scene/Implicit3DTileContent.js @@ -714,7 +714,7 @@ function getTileBoundingVolume( * * @param {object} tileBoundingVolume An object containing the JSON for the tile's bounding volume * @param {object} [contentBounds] The content bounds - * @returns {Object|undefined} An object containing the JSON for a bounding volume, or <code>undefined</code> if there is no bounding volume + * @returns {object|undefined} An object containing the JSON for a bounding volume, or <code>undefined</code> if there is no bounding volume * @private */ function getContentBoundingVolume(tileBoundingVolume, contentBounds) { diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index ddf0490a626..ea46b9ac685 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -53,7 +53,7 @@ const pickFeaturesTags = combine(tags, { * * Initialization options for the UrlTemplateImageryProvider constructor * - * @property {Promise<object>|Object} [options] Object with the following properties: + * @property {Promise<object>|object} [options] Object with the following properties: * @property {Resource|string} url The URL template to use to request tiles. It has the following keywords: * <ul> * <li><code>{z}</code>: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.</li> @@ -648,7 +648,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { * Reinitializes this instance. Reinitializing an instance already in use is supported, but it is not * recommended because existing tiles provided by the imagery provider will not be updated. * - * @param {Promise<object>|Object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. + * @param {Promise<object>|object} options Any of the options that may be passed to the {@link UrlTemplateImageryProvider} constructor. */ UrlTemplateImageryProvider.prototype.reinitialize = function (options) { const that = this; From 589bbd36bf61bcedb81b099d4bc9dbcdc31452ea Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 01:29:19 +0800 Subject: [PATCH 469/679] Change type in docs --- .../Contributors/DocumentationGuide/README.md | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/Documentation/Contributors/DocumentationGuide/README.md b/Documentation/Contributors/DocumentationGuide/README.md index 1f38dc85e7a..d5b9946158a 100644 --- a/Documentation/Contributors/DocumentationGuide/README.md +++ b/Documentation/Contributors/DocumentationGuide/README.md @@ -57,7 +57,7 @@ Consider one of the simplest functions in CesiumJS, `defined`: * @function * * @param {*} value The object. - * @returns {Boolean} Returns true if the object is defined, returns false otherwise. + * @returns {boolean} Returns true if the object is defined, returns false otherwise. * * @example * if (Cesium.defined(positions)) { @@ -88,7 +88,7 @@ This guide describes best practices for writing doc. For complete details on JSD - Use `[]` for optional parameters and include the default value, e.g., ```javascript -* @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. +* @param {number} [startingIndex=0] The index into the array at which to start packing the elements. ``` @@ -130,12 +130,12 @@ The CesiumJS classes in the `Type` column are links to their doc. Each property of an `options` parameter (see the [Coding Guide](https://github.com/CesiumGS/cesium/true/main/Documentation/Contributors/CodingGuide/README.md#options-parameters)) should be documented with a separate `@param` tag, e.g., ```javascript - * @param {Object} [options] Object with the following properties: - * @param {Number} [options.length=10000000.0] The length of the axes in meters. - * @param {Number} [options.width=2.0] The width of the axes in pixels. + * @param {object} [options] Object with the following properties: + * @param {number} [options.length=10000000.0] The length of the axes in meters. + * @param {number} [options.width=2.0] The width of the axes in pixels. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 matrix that defines the reference frame, i.e., origin plus axes, to visualize. - * @param {Boolean} [options.show=true] Determines if this primitive will be shown. - * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} + * @param {boolean} [options.show=true] Determines if this primitive will be shown. + * @param {object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick} ``` generates @@ -168,7 +168,7 @@ Matrix4.computePerspectiveFieldOfView = function(fovY, aspectRatio, near, far, r /** * Computes a Matrix4 instance from a column-major order array. * - * @param {Number[]} values The column-major order array. + * @param {number[]} values The column-major order array. * @param {Matrix4} [result] The object in which the result will be stored. If undefined a new instance will be created. * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided. */ @@ -287,7 +287,7 @@ function Cartesian3(x, y) { /** * The X component. * - * @type {Number} + * @type {number} * @default 0.0 */ this.x = defaultValue(x, 0.0); @@ -295,25 +295,25 @@ function Cartesian3(x, y) { // ... ``` -- Use `@memberOf` when documenting property getter/setters, e.g., +- Use `@memberof` when documenting property getter/setters, e.g., ```javascript Object.defineProperties(Entity.prototype, { - /** - * Gets or sets whether this entity should be displayed. When set to true, - * the entity is only displayed if the parent entity's show property is also true. - * - * @memberof Entity.prototype - * @type {Boolean} - */ - show : { - get : function() { - // ... - }, - set : function(value) { - // ... - } + /** + * Gets or sets whether this entity should be displayed. When set to true, + * the entity is only displayed if the parent entity's show property is also true. + * + * @memberof Entity.prototype + * @type {boolean} + */ + show: { + get: function() { + // ... }, + set: function(value) { + // ... + } + }, // ... ``` @@ -321,19 +321,19 @@ Object.defineProperties(Entity.prototype, { ```javascript Object.defineProperties(Entity.prototype, { - /** - * Gets the unique ID associated with this object. - * - * @memberof Entity.prototype - * @type {String} - * @readonly - */ - id : { - get : function() { - return this._id; - } - }, - // ... + /** + * Gets the unique ID associated with this object. + * + * @memberof Entity.prototype + * @type {string} + * @readonly + */ + id: { + get: function() { + return this._id; + } + }, + // ... ``` - The description for readonly properties should start with "Gets", and the description for read/write properties should start with "Gets or sets." @@ -358,8 +358,8 @@ Cartesian3.ZERO = Object.freeze(new Cartesian3(0.0, 0.0, 0.0)); * Creates a Cartesian4 from four consecutive elements in an array. * @function * - * @param {Number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. - * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. + * @param {number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively. + * @param {number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component. * @param {Cartesian4} [result] The object on which to store the result. * @returns {Cartesian4} The modified result parameter or a new Cartesian4 instance if one was not provided. * @@ -399,13 +399,13 @@ Queue.prototype.sort = function (compareFunction) { * * @param {*} a An item in the array. * @param {*} b An item in the array. - * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>, + * @returns {number} Returns a negative value if <code>a</code> is less than <code>b</code>, * a positive value if <code>a</code> is greater than <code>b</code>, or * 0 if <code>a</code> is equal to <code>b</code>. * * @example * function compareNumbers(a, b) { - * return a - b; + * return a - b; * } */ ``` From 9e6b8fbcc8b729b15567d06d5d908d48b26af773 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 15 Feb 2023 13:41:25 -0500 Subject: [PATCH 470/679] Use cleaner interface to construct SpatialNode children --- packages/engine/Source/Scene/SpatialNode.js | 14 +++++++++----- packages/engine/Source/Scene/VoxelTraversal.js | 5 +---- packages/engine/Specs/Scene/SpatialNodeSpec.js | 13 +++++++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Scene/SpatialNode.js b/packages/engine/Source/Scene/SpatialNode.js index ffe2b7dce42..6c078407e02 100644 --- a/packages/engine/Source/Scene/SpatialNode.js +++ b/packages/engine/Source/Scene/SpatialNode.js @@ -16,7 +16,7 @@ import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; * @param {Number} y * @param {Number} z * @param {SpatialNode} parent - * @param {VoxelShapeType} shape + * @param {VoxelShape} shape * @param {Cartesian3} voxelDimensions * * @private @@ -93,11 +93,11 @@ SpatialNode.prototype.computeBoundingVolumes = function ( }; /** - * Compute the [level, x, y, z] coordinates of the children of a node - * @returns {Array[]} Child coordinate arrays + * @param {VoxelShape} shape The shape of the parent VoxelPrimitive + * @param {Cartesian3} voxelDimensions * @private */ -SpatialNode.prototype.getChildCoordinates = function () { +SpatialNode.prototype.constructChildNodes = function (shape, voxelDimensions) { const { level, x, y, z } = this; const xMin = x * 2; const yMin = y * 2; @@ -107,7 +107,7 @@ SpatialNode.prototype.getChildCoordinates = function () { const zMax = zMin + 1; const childLevel = level + 1; - return [ + const childCoords = [ [childLevel, xMin, yMin, zMin], [childLevel, xMax, yMin, zMin], [childLevel, xMin, yMax, zMin], @@ -117,6 +117,10 @@ SpatialNode.prototype.getChildCoordinates = function () { [childLevel, xMin, yMax, zMax], [childLevel, xMax, yMax, zMax], ]; + + this.children = childCoords.map(([level, x, y, z]) => { + return new SpatialNode(level, x, y, z, this, shape, voxelDimensions); + }); }; /** diff --git a/packages/engine/Source/Scene/VoxelTraversal.js b/packages/engine/Source/Scene/VoxelTraversal.js index 755cbb2b2a7..915cf3e121b 100644 --- a/packages/engine/Source/Scene/VoxelTraversal.js +++ b/packages/engine/Source/Scene/VoxelTraversal.js @@ -593,10 +593,7 @@ function loadAndUnload(that, frameState) { } if (!defined(spatialNode.children)) { - const childCoords = spatialNode.getChildCoordinates(); - spatialNode.children = childCoords.map(([level, x, y, z]) => { - return new SpatialNode(level, x, y, z, spatialNode, shape, dimensions); - }); + spatialNode.constructChildNodes(shape, dimensions); } for (let childIndex = 0; childIndex < 8; childIndex++) { const child = spatialNode.children[childIndex]; diff --git a/packages/engine/Specs/Scene/SpatialNodeSpec.js b/packages/engine/Specs/Scene/SpatialNodeSpec.js index e498b2cea7a..18094dc1177 100644 --- a/packages/engine/Specs/Scene/SpatialNodeSpec.js +++ b/packages/engine/Specs/Scene/SpatialNodeSpec.js @@ -42,6 +42,9 @@ describe("Scene/SpatialNode", function () { const dimensions = new Cartesian3(2, 3, 4); const node = new SpatialNode(level, x, y, z, parent, shape, dimensions); + expect(node.children).toBeUndefined(); + node.constructChildNodes(shape, dimensions); + expect(node.children.length).toBe(8); const expectedChildCoordinates = [ [3, 2, 4, 6], @@ -53,8 +56,14 @@ describe("Scene/SpatialNode", function () { [3, 2, 5, 7], [3, 3, 5, 7], ]; - - expect(node.getChildCoordinates()).toEqual(expectedChildCoordinates); + const actualChildCoordinates = node.children.map((child) => [ + child.level, + child.x, + child.y, + child.z, + ]); + + expect(actualChildCoordinates).toEqual(expectedChildCoordinates); }); it("computes screen space error", function () { From 9a302f97b015bc33a47deaab62459781379c062f Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 15 Feb 2023 13:48:02 -0500 Subject: [PATCH 471/679] Use await syntax for promises in VoxelPrimitiveSpec --- .../engine/Specs/Scene/VoxelPrimitiveSpec.js | 109 +++++++++--------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js index b75f1a87654..68cc557ab41 100644 --- a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js +++ b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js @@ -41,23 +41,23 @@ describe( expect(primitive.show).toEqual(true); }); - it("constructs with options", function () { + it("constructs with options", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); scene.renderForSpecs(); expect(primitive.provider).toBe(provider); - return primitive.readyPromise.then(function () { - expect(primitive.shape._type).toBe(provider.shape._type); - expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); - expect(primitive._tileCount).toBe(provider._tileCount); - expect(primitive._traversal).toBeDefined(); - expect(primitive.minimumValues).toBe(provider.minimumValues); - expect(primitive.maximumValues).toBe(provider.maximumValues); - }); + await primitive.readyPromise; + + expect(primitive.shape._type).toBe(provider.shape._type); + expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); + expect(primitive._tileCount).toBe(provider._tileCount); + expect(primitive._traversal).toBeDefined(); + expect(primitive.minimumValues).toBe(provider.minimumValues); + expect(primitive.maximumValues).toBe(provider.maximumValues); }); - it("toggles render options that require shader rebuilds", function () { + it("toggles render options that require shader rebuilds", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); @@ -70,18 +70,18 @@ describe( expect(primitive._shaderDirty).toBe(false); } - return pollToPromise(function () { + await pollToPromise(function () { scene.renderForSpecs(); const traversal = primitive._traversal; return traversal.isRenderable(traversal.rootNode); - }).then(function () { - toggleOption("depthTest", true, false); - toggleOption("jitter", true, false); - toggleOption("nearestSampling", false, true); }); + + toggleOption("depthTest", true, false); + toggleOption("jitter", true, false); + toggleOption("nearestSampling", false, true); }); - it("sets render parameters", function () { + it("sets render parameters", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); @@ -92,16 +92,16 @@ describe( expect(primitive[parameter]).toBe(newValue); } - return pollToPromise(function () { + await pollToPromise(function () { scene.renderForSpecs(); const traversal = primitive._traversal; return traversal.isRenderable(traversal.rootNode); - }).then(function () { - setParameter("levelBlendFactor", 0.0, 0.5); - setParameter("screenSpaceError", 4.0, 2.0); - setParameter("stepSize", 1.0, 0.5); - setParameter("debugDraw", false, true); }); + + setParameter("levelBlendFactor", 0.0, 0.5); + setParameter("screenSpaceError", 4.0, 2.0); + setParameter("stepSize", 1.0, 0.5); + setParameter("debugDraw", false, true); }); it("sets clipping range extrema when given valid range between 0 and 1", function () { @@ -126,65 +126,64 @@ describe( expect(primitive.style).toBe(VoxelPrimitive.DefaultStyle); }); - it("updates step size", function () { + it("updates step size", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); scene.renderForSpecs(); const shape = primitive._shape; shape.translation = new Cartesian3(2.382, -3.643, 1.084); - return primitive.readyPromise.then(function () { - primitive.update(scene.frameState); - const stepSizeUv = shape.computeApproximateStepSize( - primitive.dimensions - ); - expect(primitive._stepSizeUv).toBe(stepSizeUv); - }); + + await primitive.readyPromise; + + primitive.update(scene.frameState); + const stepSizeUv = shape.computeApproximateStepSize(primitive.dimensions); + expect(primitive._stepSizeUv).toBe(stepSizeUv); }); - it("accepts a new Custom Shader", function () { + it("accepts a new Custom Shader", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); scene.renderForSpecs(); - return primitive.readyPromise.then(function () { - expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); + await primitive.readyPromise; - // If new shader is undefined, we should get DefaultCustomShader again - primitive.customShader = undefined; - scene.renderForSpecs(); - expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); + expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); - const modifiedShader = new CustomShader({ - fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) + // If new shader is undefined, we should get DefaultCustomShader again + primitive.customShader = undefined; + scene.renderForSpecs(); + expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); + + const modifiedShader = new CustomShader({ + fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { material.diffuse = vec3(1.0, 1.0, 0.0); material.alpha = 0.8; }`, - }); - primitive.customShader = modifiedShader; - scene.renderForSpecs(); - expect(primitive.customShader).toBe(modifiedShader); }); + primitive.customShader = modifiedShader; + scene.renderForSpecs(); + expect(primitive.customShader).toBe(modifiedShader); }); - it("destroys", function () { + it("destroys", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); scene.renderForSpecs(); expect(primitive.isDestroyed()).toBe(false); - return primitive.readyPromise.then(function () { - primitive.update(scene.frameState); - expect(primitive.isDestroyed()).toBe(false); - expect(primitive._pickId).toBeDefined(); - expect(primitive._traversal).toBeDefined(); - - scene.primitives.remove(primitive); - expect(primitive.isDestroyed()).toBe(true); - expect(primitive._pickId).toBeUndefined(); - expect(primitive._traversal).toBeUndefined(); - }); + await primitive.readyPromise; + + primitive.update(scene.frameState); + expect(primitive.isDestroyed()).toBe(false); + expect(primitive._pickId).toBeDefined(); + expect(primitive._traversal).toBeDefined(); + + scene.primitives.remove(primitive); + expect(primitive.isDestroyed()).toBe(true); + expect(primitive._pickId).toBeUndefined(); + expect(primitive._traversal).toBeUndefined(); }); }, "WebGL" From 8f150168acb31d7182cc479fd230a51036b7b818 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 15 Feb 2023 18:34:36 -0500 Subject: [PATCH 472/679] Document and clean up Cesium3DTile (WIP) --- packages/engine/Source/Scene/Cesium3DTile.js | 73 ++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 4495909c941..ab4cc653ae0 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -52,6 +52,9 @@ import Pass from "../Renderer/Pass.js"; * * @alias Cesium3DTile * @constructor + * @param {Cesium3DTileset} tileset + * @param {Resource} baseResource + * @param {Cesium3DTile} parent */ function Cesium3DTile(tileset, baseResource, header, parent) { this._tileset = tileset; @@ -757,6 +760,13 @@ Object.defineProperties(Cesium3DTile.prototype, { }); const scratchCartesian = new Cartesian3(); + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {Boolean} + */ function isPriorityDeferred(tile, frameState) { const tileset = tile._tileset; @@ -864,6 +874,9 @@ const scratchJulianDate = new JulianDate(); * Get the tile's screen space error. * * @private + * @param {FrameState} frameState + * @param {Boolean} useParentGeometricError + * @param {number} progressiveResolutionHeightFraction */ Cesium3DTile.prototype.getScreenSpaceError = function ( frameState, @@ -882,9 +895,8 @@ Cesium3DTile.prototype.getScreenSpaceError = function ( // Leaf tiles do not have any error so save the computation return 0.0; } - const camera = frameState.camera; + const { camera, context } = frameState; let frustum = camera.frustum; - const context = frameState.context; const width = context.drawingBufferWidth; const height = context.drawingBufferHeight * heightFraction; let error; @@ -902,7 +914,7 @@ Cesium3DTile.prototype.getScreenSpaceError = function ( } else { // Avoid divide by zero when viewer is inside the tile const distance = Math.max(this._distanceToCamera, CesiumMath.EPSILON7); - const sseDenominator = camera.frustum.sseDenominator; + const sseDenominator = frustum.sseDenominator; error = (geometricError * height) / (distance * sseDenominator); if (tileset.dynamicScreenSpaceError) { const density = tileset._dynamicScreenSpaceErrorComputedDensity; @@ -917,6 +929,12 @@ Cesium3DTile.prototype.getScreenSpaceError = function ( return error; }; +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {Boolean} + */ function isPriorityProgressiveResolution(tileset, tile) { if ( tileset.progressiveResolutionHeightFraction <= 0.0 || @@ -944,6 +962,12 @@ function isPriorityProgressiveResolution(tileset, tile) { return isProgressiveResolutionTile; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {number} + */ function getPriorityReverseScreenSpaceError(tileset, tile) { const parent = tile.parent; const useParentScreenSpaceError = @@ -962,10 +986,10 @@ function getPriorityReverseScreenSpaceError(tileset, tile) { * Update the tile's visibility. * * @private + * @param {FrameState} frameState */ Cesium3DTile.prototype.updateVisibility = function (frameState) { - const parent = this.parent; - const tileset = this._tileset; + const { parent, tileset } = this; const parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix; @@ -1018,6 +1042,10 @@ Cesium3DTile.prototype.updateExpiration = function () { } }; +/** + * @private + * @param {Cesium3DTile} tile + */ function updateExpireDate(tile) { if (defined(tile.expireDuration)) { const expireDurationDate = JulianDate.now(scratchJulianDate); @@ -1037,6 +1065,11 @@ function updateExpireDate(tile) { } } +/** + * @private + * @param {Cesium3DTile} tile + * @returns {Function} + */ function createPriorityFunction(tile) { return function () { return tile._priority; @@ -1076,6 +1109,8 @@ Cesium3DTile.prototype.requestContent = function () { * </p> * * @private + * @param {Cesium3DTile} tile + * @returns {number} */ function requestMultipleContents(tile) { let multipleContents = tile._content; @@ -1167,6 +1202,12 @@ function requestMultipleContents(tile) { return 0; } +/** + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + * @param {*} error + */ function multipleContentFailed(tile, tileset, error) { // note: The Multiple3DTileContent handles decrementing the number of pending // requests if the state is LOADING. @@ -1177,6 +1218,11 @@ function multipleContentFailed(tile, tileset, error) { tile._contentState = Cesium3DTileContentState.FAILED; } +/** + * @private + * @param {Cesium3DTile} tile + * @returns {number} + */ function requestSingleContent(tile) { // it is important to clone here. The fetchArrayBuffer() below uses // throttling, but other uses of the resources do not. @@ -1271,6 +1317,11 @@ function requestSingleContent(tile) { return 0; } +/** + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + */ function singleContentFailed(tile, tileset) { if (tile._contentState === Cesium3DTileContentState.PROCESSING) { --tileset.statistics.numberOfTilesProcessing; @@ -1402,6 +1453,12 @@ Cesium3DTile.prototype.unloadContent = function () { const scratchProjectedBoundingSphere = new BoundingSphere(); +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {TileBoundingVolume} + */ function getBoundingVolume(tile, frameState) { if ( frameState.mode !== SceneMode.SCENE3D && @@ -1424,6 +1481,12 @@ function getBoundingVolume(tile, frameState) { : tile._boundingVolume; } +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {TileBoundingVolume} + */ function getContentBoundingVolume(tile, frameState) { if ( frameState.mode !== SceneMode.SCENE3D && From eb3d4c31253c746b23b0c6d18e65570922d36cc2 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 14:46:53 +0800 Subject: [PATCH 473/679] Rollback dependency --- Tools/jsdoc/conf.json | 1 - Tools/jsdoc/ts-conf.json | 1 - package.json | 1 - packages/engine/tsd-conf.json | 1 - packages/widgets/tsd-conf.json | 1 - 5 files changed, 5 deletions(-) diff --git a/Tools/jsdoc/conf.json b/Tools/jsdoc/conf.json index cae7f00f043..840e70cb871 100644 --- a/Tools/jsdoc/conf.json +++ b/Tools/jsdoc/conf.json @@ -16,7 +16,6 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ - "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags" ], "templates": { diff --git a/Tools/jsdoc/ts-conf.json b/Tools/jsdoc/ts-conf.json index 871593ad322..14b6d7bdf07 100644 --- a/Tools/jsdoc/ts-conf.json +++ b/Tools/jsdoc/ts-conf.json @@ -16,7 +16,6 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ - "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], diff --git a/package.json b/package.json index a875185ce0e..ecf93bcc4bf 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,6 @@ "istanbul-lib-instrument": "^5.2.0", "jasmine-core": "^4.0.1", "jsdoc": "^3.6.7", - "jsdoc-tsimport-plugin": "^1.0.5", "karma": "^6.3.20", "karma-chrome-launcher": "^3.1.0", "karma-coverage": "^2.0.3", diff --git a/packages/engine/tsd-conf.json b/packages/engine/tsd-conf.json index 98807f59ae6..43cc31afea8 100644 --- a/packages/engine/tsd-conf.json +++ b/packages/engine/tsd-conf.json @@ -14,7 +14,6 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ - "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], diff --git a/packages/widgets/tsd-conf.json b/packages/widgets/tsd-conf.json index 5ee384a2e0a..135bf4d652b 100644 --- a/packages/widgets/tsd-conf.json +++ b/packages/widgets/tsd-conf.json @@ -13,7 +13,6 @@ "excludePattern": "(^|\\/|\\\\)_" }, "plugins": [ - "node_modules/jsdoc-tsimport-plugin/index.js", "./Tools/jsdoc/cesiumTags", "tsd-jsdoc/dist/plugin" ], From 98375d4e80d1441374163c2226d9ded81f5a1e78 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 14:54:33 +0800 Subject: [PATCH 474/679] Fix types in unlint list --- Apps/Sandcastle/gallery/Custom DataSource.html | 2 +- build.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Apps/Sandcastle/gallery/Custom DataSource.html b/Apps/Sandcastle/gallery/Custom DataSource.html index 860e38ca7a5..af5670d6ce7 100644 --- a/Apps/Sandcastle/gallery/Custom DataSource.html +++ b/Apps/Sandcastle/gallery/Custom DataSource.html @@ -144,7 +144,7 @@ /** * Gets the array of series names. * @memberof WebGLGlobeDataSource.prototype - * @type {string} + * @type {string[]} */ seriesNames: { get: function () { diff --git a/build.js b/build.js index 7201aac66fd..b91e0cb4808 100644 --- a/build.js +++ b/build.js @@ -721,7 +721,7 @@ const has_new_gallery_demos = ${newDemos.length > 0 ? "true;" : "false;"}\n`; /** * Helper function to copy files. * - * @param {Array.>} globs The file globs to be copied. + * @param {string[]} globs The file globs to be copied. * @param {string} destination The path to copy the files to. * @param {string} base The base path to omit from the globs when files are copied. Defaults to "". * @returns {Promise<Buffer>} A promise containing the stream output as a buffer. @@ -873,7 +873,7 @@ async function createIndexJs(workspace) { /** * Creates a single entry point file by importing all individual spec files. - * @param {Array.>} files The individual spec files. + * @param {string[]} files The individual spec files. * @param {string} workspace The workspace. * @param {string} outputPath The path the file is written to. */ @@ -897,7 +897,7 @@ async function createSpecListForWorkspace(files, workspace, outputPath) { * Bundles CSS files. * * @param {object} options - * @param {Array.>} options.filePaths The file paths to bundle. + * @param {string[]} options.filePaths The file paths to bundle. * @param {boolean} options.sourcemap * @param {boolean} options.minify * @param {string} options.outdir The output directory. From e2c4066a9d3721e8416bd3735e9688059b81c7ce Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Thu, 16 Feb 2023 15:12:04 +0800 Subject: [PATCH 475/679] Remove changes doc for ts import types --- CHANGES.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index afcb51b2f79..a2f3f687680 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,10 +6,6 @@ #### Major Announcements :loudspeaker: -##### Additions :tada: - -- Support TypeScript `import()` type in JSDoc [#11080](https://github.com/CesiumGS/cesium/pull/11080) - ##### Fixes :wrench: - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) From 2f8fba2ff3fa3af68c323bc8028244bc2b5c47a5 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 16 Feb 2023 17:14:31 -0500 Subject: [PATCH 476/679] Document remaining helper functions in Cesium3DTile --- packages/engine/Source/Scene/Cesium3DTile.js | 129 ++++++++++++++----- 1 file changed, 99 insertions(+), 30 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index ab4cc653ae0..7535bf4e342 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -768,12 +768,12 @@ const scratchCartesian = new Cartesian3(); * @returns {Boolean} */ function isPriorityDeferred(tile, frameState) { - const tileset = tile._tileset; + const { tileset, boundingSphere } = tile; + const { radius, center } = boundingSphere; + const { camera } = frameState; - // If closest point on line is inside the sphere then set foveatedFactor to 0. Otherwise, the dot product is with the line from camera to the point on the sphere that is closest to the line. - const camera = frameState.camera; - const boundingSphere = tile.boundingSphere; - const radius = boundingSphere.radius; + // If closest point on line is inside the sphere then set foveatedFactor to 0. + // Otherwise, the dot product is with the line from camera to the point on the sphere that is closest to the line. const scaledCameraDirection = Cartesian3.multiplyByScalar( camera.directionWC, tile._centerZDepth, @@ -787,7 +787,7 @@ function isPriorityDeferred(tile, frameState) { // The distance from the camera's view direction to the tile. const toLine = Cartesian3.subtract( closestPointOnLine, - boundingSphere.center, + center, scratchCartesian ); const distanceToCenterLine = Cartesian3.magnitude(toLine); @@ -805,7 +805,7 @@ function isPriorityDeferred(tile, frameState) { scratchCartesian ); const closestOnSphere = Cartesian3.add( - boundingSphere.center, + center, scaledToLine, scratchCartesian ); @@ -1047,21 +1047,22 @@ Cesium3DTile.prototype.updateExpiration = function () { * @param {Cesium3DTile} tile */ function updateExpireDate(tile) { - if (defined(tile.expireDuration)) { - const expireDurationDate = JulianDate.now(scratchJulianDate); - JulianDate.addSeconds( - expireDurationDate, - tile.expireDuration, - expireDurationDate - ); + if (!defined(tile.expireDuration)) { + return; + } + const expireDurationDate = JulianDate.now(scratchJulianDate); + JulianDate.addSeconds( + expireDurationDate, + tile.expireDuration, + expireDurationDate + ); - if (defined(tile.expireDate)) { - if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) { - JulianDate.clone(expireDurationDate, tile.expireDate); - } - } else { - tile.expireDate = JulianDate.clone(expireDurationDate); + if (defined(tile.expireDate)) { + if (JulianDate.lessThan(tile.expireDate, expireDurationDate)) { + JulianDate.clone(expireDurationDate, tile.expireDate); } + } else { + tile.expireDate = JulianDate.clone(expireDurationDate); } } @@ -1590,7 +1591,7 @@ Cesium3DTile.prototype.contentVisibility = function (frameState) { * Computes the (potentially approximate) distance from the closest point of the tile's bounding volume to the camera. * * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters, or zero if the camera is inside the bounding volume. + * @returns {number} The distance, in meters, or zero if the camera is inside the bounding volume. * * @private */ @@ -1605,7 +1606,7 @@ const scratchToTileCenter = new Cartesian3(); * Computes the distance from the center of the tile's bounding volume to the camera's plane defined by its position and view direction. * * @param {FrameState} frameState The frame state. - * @returns {Number} The distance, in meters. + * @returns {number} The distance, in meters. * * @private */ @@ -1624,7 +1625,7 @@ Cesium3DTile.prototype.distanceToTileCenter = function (frameState) { * Checks if the camera is inside the viewer request volume. * * @param {FrameState} frameState The frame state. - * @returns {Boolean} Whether the camera is inside the volume. + * @returns {boolean} Whether the camera is inside the volume. * * @private */ @@ -1644,6 +1645,13 @@ const scratchRectangle = new Rectangle(); const scratchOrientedBoundingBox = new OrientedBoundingBox(); const scratchTransform = new Matrix4(); +/** + * @private + * @param {*} box + * @param {Matrix4} transform + * @param {TileBoundingVolume} [result] + * @returns {TileOrientedBoundingBox} + */ function createBox(box, transform, result) { let center = Cartesian3.fromElements(box[0], box[1], box[2], scratchCenter); let halfAxes = Matrix3.fromArray(box, 3, scratchHalfAxes); @@ -1660,6 +1668,14 @@ function createBox(box, transform, result) { return new TileOrientedBoundingBox(center, halfAxes); } +/** + * @private + * @param {*} region + * @param {Matrix4} transform + * @param {Matrix4} initialTransform + * @param {TileOrientedBoundingBox} [result] + * @returns {TileOrientedBoundingBox} + */ function createBoxFromTransformedRegion( region, transform, @@ -1700,6 +1716,14 @@ function createBoxFromTransformedRegion( return new TileOrientedBoundingBox(center, halfAxes); } +/** + * @private + * @param {*} region + * @param {Matrix4} transform + * @param {Matrix4} initialTransform + * @param {TileBoundingVolume} [result] + * @returns {TileBoundingVolume} + */ function createRegion(region, transform, initialTransform, result) { if ( !Matrix4.equalsEpsilon(transform, initialTransform, CesiumMath.EPSILON8) @@ -1725,6 +1749,13 @@ function createRegion(region, transform, initialTransform, result) { }); } +/** + * @private + * @param {*} sphere + * @param {Matrix4} transform + * @param {TileBoundingVolume} [result] + * @returns {TileBoundingSphere} + */ function createSphere(sphere, transform, result) { let center = Cartesian3.fromElements( sphere[0], @@ -1796,6 +1827,7 @@ Cesium3DTile.prototype.createBoundingVolume = function ( * Update the tile's transform. The transform is applied to the tile's bounding volumes. * * @private + * @param {Matrix4} parentTransform */ Cesium3DTile.prototype.updateTransform = function (parentTransform) { parentTransform = defaultValue(parentTransform, Matrix4.IDENTITY); @@ -1862,6 +1894,13 @@ Cesium3DTile.prototype.updateGeometricErrorScale = function () { } }; +/** + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + * @param {object} passOptions + */ function applyDebugSettings(tile, tileset, frameState, passOptions) { if (!passOptions.isRender) { return; @@ -1955,8 +1994,13 @@ function applyDebugSettings(tile, tileset, frameState, passOptions) { } } +/** + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function updateContent(tile, tileset, frameState) { - const content = tile._content; const expiredContent = tile._expiredContent; // expired content is not supported for multiple contents @@ -1972,14 +2016,20 @@ function updateContent(tile, tileset, frameState) { tile._expiredContent = undefined; } - content.update(tileset, frameState); + tile.content.update(tileset, frameState); } +/** + * Compute and compare ClippingPlanes state: + * - enabled-ness - are clipping planes enabled? is this tile clipped? + * - clipping plane count + * - clipping function (union v. intersection) + + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + */ function updateClippingPlanes(tile, tileset) { - // Compute and compare ClippingPlanes state: - // - enabled-ness - are clipping planes enabled? is this tile clipped? - // - clipping plane count - // - clipping function (union v. intersection) const clippingPlanes = tileset.clippingPlanes; let currentClippingPlanesState = 0; if (defined(clippingPlanes) && tile._isClipped && clippingPlanes.enabled) { @@ -1996,6 +2046,9 @@ function updateClippingPlanes(tile, tileset) { * Get the draw commands needed to render this tile. * * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + * @param {object} passOptions */ Cesium3DTile.prototype.update = function (tileset, frameState, passOptions) { const commandStart = frameState.commandList.length; @@ -2037,17 +2090,32 @@ Cesium3DTile.prototype.process = function (tileset, frameState) { frameState.commandList = savedCommandList; }; +/** + * @private + * @param {number} normalizedValue + * @param {number} numberOfDigits + * @param {number} leftShift + * @returns {number} + */ function isolateDigits(normalizedValue, numberOfDigits, leftShift) { const scaled = normalizedValue * Math.pow(10, numberOfDigits); const integer = parseInt(scaled); return integer * Math.pow(10, leftShift); } +/** + * @private + * @param {number} value + * @param {number} minimum + * @param {number} maximum + * @returns {number} + */ function priorityNormalizeAndClamp(value, minimum, maximum) { + // Subtract epsilon since we only want decimal digits present in the output. return Math.max( CesiumMath.normalize(value, minimum, maximum) - CesiumMath.EPSILON7, 0.0 - ); // Subtract epsilon since we only want decimal digits present in the output. + ); } /** @@ -2181,4 +2249,5 @@ Cesium3DTile.prototype.destroy = function () { this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy(); return destroyObject(this); }; + export default Cesium3DTile; From 9fa800a5ac51342c23c9775540a4a4d73b3aae6a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 16 Feb 2023 18:47:53 -0500 Subject: [PATCH 477/679] re-remove deprecated polyfills --- .../Source/Core/cancelAnimationFrame.js | 53 ------------ .../Source/Core/requestAnimationFrame.js | 83 ------------------- .../Specs/Core/requestAnimationFrameSpec.js | 50 ----------- 3 files changed, 186 deletions(-) delete mode 100644 packages/engine/Source/Core/cancelAnimationFrame.js delete mode 100644 packages/engine/Source/Core/requestAnimationFrame.js delete mode 100644 packages/engine/Specs/Core/requestAnimationFrameSpec.js diff --git a/packages/engine/Source/Core/cancelAnimationFrame.js b/packages/engine/Source/Core/cancelAnimationFrame.js deleted file mode 100644 index d86c38ef1cb..00000000000 --- a/packages/engine/Source/Core/cancelAnimationFrame.js +++ /dev/null @@ -1,53 +0,0 @@ -import defined from "./defined.js"; -import deprecationWarning from "./deprecationWarning.js"; - -let implementation; -if (typeof cancelAnimationFrame !== "undefined") { - implementation = cancelAnimationFrame; -} - -(function () { - // look for vendor prefixed function - if (!defined(implementation) && typeof window !== "undefined") { - const vendors = ["webkit", "moz", "ms", "o"]; - let i = 0; - const len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[`${vendors[i]}CancelAnimationFrame`]; - if (!defined(implementation)) { - implementation = window[`${vendors[i]}CancelRequestAnimationFrame`]; - } - ++i; - } - } - - // otherwise, assume requestAnimationFrame is based on setTimeout, so use clearTimeout - if (!defined(implementation)) { - implementation = clearTimeout; - } -})(); - -/** - * A browser-independent function to cancel an animation frame requested using {@link requestAnimationFrame}. - * - * @function cancelAnimationFrame - * - * @param {Number} requestID The value returned by {@link requestAnimationFrame}. - * - * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} - * - * @deprecated - */ -function cancelAnimationFramePolyfill(requestID) { - // we need this extra wrapper function because the native cancelAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.cancelAnimationFrame(requestID) - - deprecationWarning( - "Cesium.cancelAnimationFrame", - "Cesium.cancelAnimationFrame was deprecated in CesiumJS 1.96 and will be removed in 1.99. Use the native cancelAnimationFrame method instead." - ); - - implementation(requestID); -} -export default cancelAnimationFramePolyfill; diff --git a/packages/engine/Source/Core/requestAnimationFrame.js b/packages/engine/Source/Core/requestAnimationFrame.js deleted file mode 100644 index bd873996ee2..00000000000 --- a/packages/engine/Source/Core/requestAnimationFrame.js +++ /dev/null @@ -1,83 +0,0 @@ -import defined from "./defined.js"; -import deprecationWarning from "./deprecationWarning.js"; -import getTimestamp from "./getTimestamp.js"; - -let implementation; -if (typeof requestAnimationFrame !== "undefined") { - implementation = requestAnimationFrame; -} - -(function () { - // look for vendor prefixed function - if (!defined(implementation) && typeof window !== "undefined") { - const vendors = ["webkit", "moz", "ms", "o"]; - let i = 0; - const len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[`${vendors[i]}RequestAnimationFrame`]; - ++i; - } - } - - // build an implementation based on setTimeout - if (!defined(implementation)) { - const msPerFrame = 1000.0 / 60.0; - let lastFrameTime = 0; - implementation = function (callback) { - const currentTime = getTimestamp(); - - // schedule the callback to target 60fps, 16.7ms per frame, - // accounting for the time taken by the callback - const delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0); - lastFrameTime = currentTime + delay; - - return setTimeout(function () { - callback(lastFrameTime); - }, delay); - }; - } -})(); - -/** - * A browser-independent function to request a new animation frame. This is used to create - * an application's draw loop as shown in the example below. - * - * @function requestAnimationFrame - * - * @param {requestAnimationFrameCallback} callback The function to call when the next frame should be drawn. - * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. - * - * - * @example - * // Create a draw loop using requestAnimationFrame. The - * // tick callback function is called for every animation frame. - * function tick() { - * scene.render(); - * Cesium.requestAnimationFrame(tick); - * } - * tick(); - * - * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface} - * - * @deprecated - */ -function requestAnimationFramePolyFill(callback) { - // we need this extra wrapper function because the native requestAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.requestAnimationFrame(callback) - - deprecationWarning( - "Cesium.requestAnimationFrame", - "Cesium.requestAnimationFrame was deprecated in CesiumJS 1.96 and will be removed in 1.99. Use the native requestAnimationFrame method instead." - ); - - return implementation(callback); -} - -/** - * A function that will be called when the next frame should be drawn. - * @callback requestAnimationFrameCallback - * - * @param {Number} timestamp A timestamp for the frame, in milliseconds. - */ -export default requestAnimationFramePolyFill; diff --git a/packages/engine/Specs/Core/requestAnimationFrameSpec.js b/packages/engine/Specs/Core/requestAnimationFrameSpec.js deleted file mode 100644 index 9519495c4e7..00000000000 --- a/packages/engine/Specs/Core/requestAnimationFrameSpec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { cancelAnimationFrame, requestAnimationFrame } from "../../index.js"; - -describe("Core/requestAnimationFrame", function () { - it("calls the callback", function () { - const promise = new Promise(requestAnimationFrame); - return promise.then(function (requestId) { - expect(requestId).toBeDefined(); - }); - }); - - it("provides a timestamp that increases each frame", function () { - return new Promise((resolve) => { - const callbackTimestamps = []; - - function callback(timestamp) { - callbackTimestamps.push(timestamp); - - if (callbackTimestamps.length < 3) { - requestAnimationFrame(callback); - } else { - expect(callbackTimestamps[0]).toBeLessThanOrEqual( - callbackTimestamps[1] - ); - expect(callbackTimestamps[1]).toBeLessThanOrEqual( - callbackTimestamps[2] - ); - resolve(); - } - } - - requestAnimationFrame(callback); - }); - }); - - it("can cancel a callback", function () { - return new Promise((resolve) => { - const shouldNotBeCalled = jasmine.createSpy("shouldNotBeCalled"); - - const requestID = requestAnimationFrame(shouldNotBeCalled); - cancelAnimationFrame(requestID); - - // schedule and wait for another callback - requestAnimationFrame(function () { - // make sure cancelled callback didn't run - expect(shouldNotBeCalled).not.toHaveBeenCalled(); - resolve(); - }); - }); - }); -}); From 723ee9f6e7ed8f870c8bb5130bf343b3c429968d Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Fri, 17 Feb 2023 10:22:50 +0800 Subject: [PATCH 478/679] Add missing type and bracket --- .../engine/Source/Core/CompressedTextureBuffer.js | 10 +++++----- ...tanceDisplayConditionGeometryInstanceAttribute.js | 2 +- packages/engine/Source/Core/Geometry.js | 2 +- packages/engine/Source/Core/GeometryAttribute.js | 6 +++--- packages/engine/Source/Core/GeometryInstance.js | 4 ++-- .../engine/Source/Core/GeometryInstanceAttribute.js | 4 ++-- packages/engine/Source/Core/ManagedArray.js | 4 ++-- packages/engine/Source/Core/RequestScheduler.js | 2 +- packages/engine/Source/Core/RequestState.js | 12 ++++++------ packages/engine/Source/Core/RequestType.js | 8 ++++---- packages/engine/Source/Core/Spline.js | 4 ++-- packages/engine/Source/Core/VertexFormat.js | 12 ++++++------ packages/engine/Source/DataSources/Entity.js | 2 +- packages/engine/Source/DataSources/KmlTour.js | 8 ++++---- packages/engine/Source/DataSources/ModelGraphics.js | 4 ++-- packages/engine/Source/DataSources/exportKml.js | 2 +- packages/engine/Source/Renderer/ShaderBuilder.js | 2 +- packages/engine/Source/Scene/Camera.js | 2 +- .../engine/Source/Scene/Cesium3DTilePointFeature.js | 2 +- packages/engine/Source/Scene/Cesium3DTileStyle.js | 2 +- packages/engine/Source/Scene/ConditionsExpression.js | 2 +- packages/engine/Source/Scene/DebugCameraPrimitive.js | 2 +- .../engine/Source/Scene/DebugModelMatrixPrimitive.js | 2 +- packages/engine/Source/Scene/DracoLoader.js | 2 +- packages/engine/Source/Scene/EllipsoidPrimitive.js | 2 +- packages/engine/Source/Scene/Expression.js | 2 +- packages/engine/Source/Scene/GroupMetadata.js | 2 +- packages/engine/Source/Scene/ImplicitMetadataView.js | 2 +- .../engine/Source/Scene/ImplicitSubtreeMetadata.js | 2 +- packages/engine/Source/Scene/JsonMetadataTable.js | 4 ++-- packages/engine/Source/Scene/MetadataClass.js | 8 ++++---- .../engine/Source/Scene/MetadataClassProperty.js | 2 +- packages/engine/Source/Scene/MetadataEntity.js | 4 ++-- packages/engine/Source/Scene/MetadataEnum.js | 4 ++-- packages/engine/Source/Scene/MetadataSchema.js | 8 ++++---- packages/engine/Source/Scene/MetadataTable.js | 2 +- .../engine/Source/Scene/MetadataTableProperty.js | 2 +- packages/engine/Source/Scene/Model/CustomShader.js | 10 +++++----- .../Source/Scene/Model/MaterialPipelineStage.js | 4 ++-- .../Source/Scene/Model/ModelRenderResources.js | 2 +- .../engine/Source/Scene/Model/NodeRenderResources.js | 2 +- .../Source/Scene/Model/PrimitiveRenderResources.js | 2 +- packages/engine/Source/Scene/ModelComponents.js | 2 +- packages/engine/Source/Scene/Primitive.js | 2 +- packages/engine/Source/Scene/PropertyAttribute.js | 2 +- packages/engine/Source/Scene/PropertyTexture.js | 2 +- .../engine/Source/Scene/PropertyTextureProperty.js | 2 +- packages/engine/Source/Scene/Scene.js | 12 ++++++------ .../Source/Scene/ScreenSpaceCameraController.js | 5 +++-- packages/engine/Source/Scene/SkyBox.js | 2 +- packages/engine/Source/Scene/SpatialNode.js | 2 +- packages/engine/Source/Scene/VoxelBoxShape.js | 4 ++-- packages/engine/Source/Scene/VoxelCylinderShape.js | 4 ++-- packages/engine/Source/Scene/VoxelEllipsoidShape.js | 4 ++-- packages/engine/Source/Scene/VoxelPrimitive.js | 6 +++--- packages/engine/Source/Scene/VoxelRenderResources.js | 2 +- packages/engine/Source/Scene/VoxelShape.js | 4 ++-- packages/engine/Source/Scene/parseBatchTable.js | 2 +- .../Source/Scene/parseFeatureMetadataLegacy.js | 4 ++-- .../engine/Source/Scene/parseStructuralMetadata.js | 4 ++-- 60 files changed, 116 insertions(+), 115 deletions(-) diff --git a/packages/engine/Source/Core/CompressedTextureBuffer.js b/packages/engine/Source/Core/CompressedTextureBuffer.js index 062d2fe4f1f..632c4b9a757 100644 --- a/packages/engine/Source/Core/CompressedTextureBuffer.js +++ b/packages/engine/Source/Core/CompressedTextureBuffer.js @@ -28,7 +28,7 @@ function CompressedTextureBuffer( Object.defineProperties(CompressedTextureBuffer.prototype, { /** * The format of the compressed texture. - * @type PixelFormat + * @type {PixelFormat} * @readonly * @memberof CompressedTextureBuffer.prototype */ @@ -39,7 +39,7 @@ Object.defineProperties(CompressedTextureBuffer.prototype, { }, /** * The datatype of the compressed texture. - * @type PixelDatatype + * @type {PixelDatatype} * @readonly * @memberof CompressedTextureBuffer.prototype */ @@ -50,7 +50,7 @@ Object.defineProperties(CompressedTextureBuffer.prototype, { }, /** * The width of the texture. - * @type Number + * @type {number} * @readonly * @memberof CompressedTextureBuffer.prototype */ @@ -61,7 +61,7 @@ Object.defineProperties(CompressedTextureBuffer.prototype, { }, /** * The height of the texture. - * @type Number + * @type {number} * @readonly * @memberof CompressedTextureBuffer.prototype */ @@ -72,7 +72,7 @@ Object.defineProperties(CompressedTextureBuffer.prototype, { }, /** * The compressed texture buffer. - * @type Uint8Array + * @type {Uint8Array} * @readonly * @memberof CompressedTextureBuffer.prototype */ diff --git a/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js b/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js index e962c9b0a2c..6bf81bd70db 100644 --- a/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/DistanceDisplayConditionGeometryInstanceAttribute.js @@ -47,7 +47,7 @@ function DistanceDisplayConditionGeometryInstanceAttribute(near, far) { /** * The values for the attributes stored in a typed array. * - * @type Float32Array + * @type {Float32Array} * * @default [0.0, 0.0, Number.MAX_VALUE] */ diff --git a/packages/engine/Source/Core/Geometry.js b/packages/engine/Source/Core/Geometry.js index 5fde5b98626..5d891e0a783 100644 --- a/packages/engine/Source/Core/Geometry.js +++ b/packages/engine/Source/Core/Geometry.js @@ -123,7 +123,7 @@ function Geometry(options) { * Optional index data that - along with {@link Geometry#primitiveType} - * determines the primitives in the geometry. * - * @type Array + * @type {Array} * * @default undefined */ diff --git a/packages/engine/Source/Core/GeometryAttribute.js b/packages/engine/Source/Core/GeometryAttribute.js index 972a48e22df..18c27af5d07 100644 --- a/packages/engine/Source/Core/GeometryAttribute.js +++ b/packages/engine/Source/Core/GeometryAttribute.js @@ -64,7 +64,7 @@ function GeometryAttribute(options) { * The datatype of each component in the attribute, e.g., individual elements in * {@link GeometryAttribute#values}. * - * @type ComponentDatatype + * @type {ComponentDatatype} * * @default undefined */ @@ -75,7 +75,7 @@ function GeometryAttribute(options) { * For example, a position attribute with x, y, and z components would have 3 as * shown in the code example. * - * @type Number + * @type {number} * * @default undefined * @@ -98,7 +98,7 @@ function GeometryAttribute(options) { * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. * </p> * - * @type Boolean + * @type {boolean} * * @default false * diff --git a/packages/engine/Source/Core/GeometryInstance.js b/packages/engine/Source/Core/GeometryInstance.js index 61e71b8ac53..572d9b81ef6 100644 --- a/packages/engine/Source/Core/GeometryInstance.js +++ b/packages/engine/Source/Core/GeometryInstance.js @@ -83,7 +83,7 @@ function GeometryInstance(options) { /** * User-defined object returned when the instance is picked or used to get/set per-instance attributes. * - * @type Object + * @type {object} * * @default undefined * @@ -103,7 +103,7 @@ function GeometryInstance(options) { * Per-instance attributes like {@link ColorGeometryInstanceAttribute} or {@link ShowGeometryInstanceAttribute}. * {@link Geometry} attributes varying per vertex; these attributes are constant for the entire instance. * - * @type Object + * @type {object} * * @default undefined */ diff --git a/packages/engine/Source/Core/GeometryInstanceAttribute.js b/packages/engine/Source/Core/GeometryInstanceAttribute.js index 5b7f4ff658d..f857326cf74 100644 --- a/packages/engine/Source/Core/GeometryInstanceAttribute.js +++ b/packages/engine/Source/Core/GeometryInstanceAttribute.js @@ -77,7 +77,7 @@ function GeometryInstanceAttribute(options) { * For example, a position attribute with x, y, and z components would have 3 as * shown in the code example. * - * @type Number + * @type {number} * * @default undefined * @@ -99,7 +99,7 @@ function GeometryInstanceAttribute(options) { * This is commonly used when storing colors using {@link ComponentDatatype.UNSIGNED_BYTE}. * </p> * - * @type Boolean + * @type {boolean} * * @default false * diff --git a/packages/engine/Source/Core/ManagedArray.js b/packages/engine/Source/Core/ManagedArray.js index 7b010687fda..9eeb280e5ff 100644 --- a/packages/engine/Source/Core/ManagedArray.js +++ b/packages/engine/Source/Core/ManagedArray.js @@ -22,7 +22,7 @@ Object.defineProperties(ManagedArray.prototype, { * If the set length is greater than the length of the internal array, the internal array is resized. * * @memberof ManagedArray.prototype - * @type Number + * @type {number} */ length: { get: function () { @@ -50,7 +50,7 @@ Object.defineProperties(ManagedArray.prototype, { * Gets the internal array. * * @memberof ManagedArray.prototype - * @type Array + * @type {Array} * @readonly */ values: { diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index 59cf7bdb372..a0e4b63c8e4 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -110,7 +110,7 @@ Object.defineProperties(RequestScheduler, { * * @memberof RequestScheduler * - * @type Object + * @type {object} * @readonly * @private */ diff --git a/packages/engine/Source/Core/RequestState.js b/packages/engine/Source/Core/RequestState.js index 2ef0134824a..fe83c4ffb64 100644 --- a/packages/engine/Source/Core/RequestState.js +++ b/packages/engine/Source/Core/RequestState.js @@ -7,7 +7,7 @@ const RequestState = { /** * Initial unissued state. * - * @type Number + * @type {number} * @constant */ UNISSUED: 0, @@ -15,7 +15,7 @@ const RequestState = { /** * Issued but not yet active. Will become active when open slots are available. * - * @type Number + * @type {number} * @constant */ ISSUED: 1, @@ -23,7 +23,7 @@ const RequestState = { /** * Actual http request has been sent. * - * @type Number + * @type {number} * @constant */ ACTIVE: 2, @@ -31,7 +31,7 @@ const RequestState = { /** * Request completed successfully. * - * @type Number + * @type {number} * @constant */ RECEIVED: 3, @@ -39,7 +39,7 @@ const RequestState = { /** * Request was cancelled, either explicitly or automatically because of low priority. * - * @type Number + * @type {number} * @constant */ CANCELLED: 4, @@ -47,7 +47,7 @@ const RequestState = { /** * Request failed. * - * @type Number + * @type {number} * @constant */ FAILED: 5, diff --git a/packages/engine/Source/Core/RequestType.js b/packages/engine/Source/Core/RequestType.js index 0c5358eb603..e8cda3d6497 100644 --- a/packages/engine/Source/Core/RequestType.js +++ b/packages/engine/Source/Core/RequestType.js @@ -7,7 +7,7 @@ const RequestType = { /** * Terrain request. * - * @type Number + * @type {number} * @constant */ TERRAIN: 0, @@ -15,7 +15,7 @@ const RequestType = { /** * Imagery request. * - * @type Number + * @type {number} * @constant */ IMAGERY: 1, @@ -23,7 +23,7 @@ const RequestType = { /** * 3D Tiles request. * - * @type Number + * @type {number} * @constant */ TILES3D: 2, @@ -31,7 +31,7 @@ const RequestType = { /** * Other request. * - * @type Number + * @type {number} * @constant */ OTHER: 3, diff --git a/packages/engine/Source/Core/Spline.js b/packages/engine/Source/Core/Spline.js index 036c0af77d6..5dba9c6d77e 100644 --- a/packages/engine/Source/Core/Spline.js +++ b/packages/engine/Source/Core/Spline.js @@ -43,7 +43,7 @@ function Spline() { * @param {number|Cartesian3|Quaternion} point * @returns {*} The type of the point. * - * @exception {DeveloperError} value must be a Cartesian3, Quaternion, or Number. + * @exception {DeveloperError} value must be a Cartesian3, Quaternion, or number. * * @private */ @@ -60,7 +60,7 @@ Spline.getPointType = function (point) { //>>includeStart('debug', pragmas.debug); throw new DeveloperError( - "point must be a Cartesian3, Quaternion, or Number." + "point must be a Cartesian3, Quaternion, or number." ); //>>includeEnd('debug'); }; diff --git a/packages/engine/Source/Core/VertexFormat.js b/packages/engine/Source/Core/VertexFormat.js index 11055426225..9754d06ba67 100644 --- a/packages/engine/Source/Core/VertexFormat.js +++ b/packages/engine/Source/Core/VertexFormat.js @@ -31,7 +31,7 @@ function VertexFormat(options) { * 64-bit floating-point (for precision). 3 components per attribute. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -43,7 +43,7 @@ function VertexFormat(options) { * 32-bit floating-point. 3 components per attribute. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -55,7 +55,7 @@ function VertexFormat(options) { * 32-bit floating-point. 2 components per attribute * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -67,7 +67,7 @@ function VertexFormat(options) { * 32-bit floating-point. 3 components per attribute. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -79,7 +79,7 @@ function VertexFormat(options) { * 32-bit floating-point. 3 components per attribute. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -91,7 +91,7 @@ function VertexFormat(options) { * 8-bit unsigned byte. 3 components per attribute. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index a781ce8503d..6b00702c16e 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -88,7 +88,7 @@ function createPropertyTypeDescriptor(name, Type) { * @property {PointGraphics | PointGraphics.ConstructorOptions} [point] A point to associate with this entity. * @property {PolygonGraphics | PolygonGraphics.ConstructorOptions} [polygon] A polygon to associate with this entity. * @property {PolylineGraphics | PolylineGraphics.ConstructorOptions} [polyline] A polyline to associate with this entity. - * @property {PropertyBag | Object.<string,*>} [properties] Arbitrary properties to associate with this entity. + * @property {PropertyBag | Object<string,*>} [properties] Arbitrary properties to associate with this entity. * @property {PolylineVolumeGraphics | PolylineVolumeGraphics.ConstructorOptions} [polylineVolume] A polylineVolume to associate with this entity. * @property {RectangleGraphics | RectangleGraphics.ConstructorOptions} [rectangle] A rectangle to associate with this entity. * @property {WallGraphics | WallGraphics.ConstructorOptions} [wall] A wall to associate with this entity. diff --git a/packages/engine/Source/DataSources/KmlTour.js b/packages/engine/Source/DataSources/KmlTour.js index dd60e28a105..f66f1e5a2a8 100644 --- a/packages/engine/Source/DataSources/KmlTour.js +++ b/packages/engine/Source/DataSources/KmlTour.js @@ -20,22 +20,22 @@ import Event from "../Core/Event.js"; function KmlTour(name, id) { /** * Id of kml gx:Tour entry - * @type String + * @type {string} */ this.id = id; /** * Tour name - * @type String + * @type {string} */ this.name = name; /** * Index of current entry from playlist - * @type Number + * @type {number} */ this.playlistIndex = 0; /** * Array of playlist entries - * @type Array + * @type {Array} */ this.playlist = []; /** diff --git a/packages/engine/Source/DataSources/ModelGraphics.js b/packages/engine/Source/DataSources/ModelGraphics.js index d80f77132ea..2c4f3379246 100644 --- a/packages/engine/Source/DataSources/ModelGraphics.js +++ b/packages/engine/Source/DataSources/ModelGraphics.js @@ -41,8 +41,8 @@ function createArticulationStagePropertyBag(value) { * @property {Property | Cartesian2} [imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting. * @property {Property | Color} [lightColor] A property specifying the light color when shading the model. When <code>undefined</code> the scene's light color is used instead. * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed. - * @property {PropertyBag | Object.<string, TranslationRotationScale>} [nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. The transformation is applied after the node's existing transformation as specified in the glTF, and does not replace the node's existing transformation. - * @property {PropertyBag | Object.<string, number>} [articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties. + * @property {PropertyBag | Object<string, TranslationRotationScale>} [nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. The transformation is applied after the node's existing transformation as specified in the glTF, and does not replace the node's existing transformation. + * @property {PropertyBag | Object<string, number>} [articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties. * @property {Property | ClippingPlaneCollection} [clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @property {Property | CustomShader} [customShader] A property specifying the {@link CustomShader} to apply to this model. */ diff --git a/packages/engine/Source/DataSources/exportKml.js b/packages/engine/Source/DataSources/exportKml.js index 1715dc9d021..9cfb3fa10a2 100644 --- a/packages/engine/Source/DataSources/exportKml.js +++ b/packages/engine/Source/DataSources/exportKml.js @@ -226,7 +226,7 @@ IdManager.prototype.get = function (id) { * @typedef exportKmlResultKml * @type {object} * @property {string} kml The generated KML. - * @property {Object.<string, Blob>} externalFiles An object dictionary of external files + * @property {Object<string, Blob>} externalFiles An object dictionary of external files */ /** diff --git a/packages/engine/Source/Renderer/ShaderBuilder.js b/packages/engine/Source/Renderer/ShaderBuilder.js index cf2756c28bb..f6cc1b3c643 100644 --- a/packages/engine/Source/Renderer/ShaderBuilder.js +++ b/packages/engine/Source/Renderer/ShaderBuilder.js @@ -92,7 +92,7 @@ Object.defineProperties(ShaderBuilder.prototype, { * the vertex shader. * * @memberof ShaderBuilder.prototype - * @type {Object.<string, Number>} + * @type {Object<string, number>} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/Camera.js b/packages/engine/Source/Scene/Camera.js index 9c006a1020b..caab469d1b3 100644 --- a/packages/engine/Source/Scene/Camera.js +++ b/packages/engine/Source/Scene/Camera.js @@ -297,7 +297,7 @@ Camera.DEFAULT_VIEW_RECTANGLE = Rectangle.fromDegrees( * A scalar to multiply to the camera position and add it back after setting the camera to view the rectangle. * A value of zero means the camera will view the entire {@link Camera#DEFAULT_VIEW_RECTANGLE}, a value greater than zero * will move it further away from the extent, and a value less than zero will move it close to the extent. - * @type Number + * @type {number} */ Camera.DEFAULT_VIEW_FACTOR = 0.5; diff --git a/packages/engine/Source/Scene/Cesium3DTilePointFeature.js b/packages/engine/Source/Scene/Cesium3DTilePointFeature.js index 63f30af2557..01158482ac5 100644 --- a/packages/engine/Source/Scene/Cesium3DTilePointFeature.js +++ b/packages/engine/Source/Scene/Cesium3DTilePointFeature.js @@ -733,7 +733,7 @@ Cesium3DTilePointFeature.prototype.hasProperty = function (name) { * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * * @param {string[]} [results] An array into which to store the results. - * @returns {} The IDs of the feature's properties. + * @returns {string[]} The IDs of the feature's properties. */ Cesium3DTilePointFeature.prototype.getPropertyIds = function (results) { return this._content.batchTable.getPropertyIds(this._batchId, results); diff --git a/packages/engine/Source/Scene/Cesium3DTileStyle.js b/packages/engine/Source/Scene/Cesium3DTileStyle.js index adea8e62bd1..b5cd56c60d3 100644 --- a/packages/engine/Source/Scene/Cesium3DTileStyle.js +++ b/packages/engine/Source/Scene/Cesium3DTileStyle.js @@ -1445,7 +1445,7 @@ Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function ( /** * Gets the variables used by the style. * - * @returns {} The variables used by the style. + * @returns {string[]} The variables used by the style. * * @private */ diff --git a/packages/engine/Source/Scene/ConditionsExpression.js b/packages/engine/Source/Scene/ConditionsExpression.js index ea1a355290e..1bed27442ac 100644 --- a/packages/engine/Source/Scene/ConditionsExpression.js +++ b/packages/engine/Source/Scene/ConditionsExpression.js @@ -188,7 +188,7 @@ ConditionsExpression.prototype.getShaderFunction = function ( /** * Gets the variables used by the expression. * - * @returns {} The variables used by the expression. + * @returns {string[]} The variables used by the expression. * * @private */ diff --git a/packages/engine/Source/Scene/DebugCameraPrimitive.js b/packages/engine/Source/Scene/DebugCameraPrimitive.js index 4b46ba57d05..414882b124a 100644 --- a/packages/engine/Source/Scene/DebugCameraPrimitive.js +++ b/packages/engine/Source/Scene/DebugCameraPrimitive.js @@ -54,7 +54,7 @@ function DebugCameraPrimitive(options) { /** * Determines if this primitive will be shown. * - * @type Boolean + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); diff --git a/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js b/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js index 26d6857ab47..7ab16bb7738 100644 --- a/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js +++ b/packages/engine/Source/Scene/DebugModelMatrixPrimitive.js @@ -62,7 +62,7 @@ function DebugModelMatrixPrimitive(options) { /** * Determines if this primitive will be shown. * - * @type Boolean + * @type {boolean} * @default true */ this.show = defaultValue(options.show, true); diff --git a/packages/engine/Source/Scene/DracoLoader.js b/packages/engine/Source/Scene/DracoLoader.js index af76477c17c..82901e159d7 100644 --- a/packages/engine/Source/Scene/DracoLoader.js +++ b/packages/engine/Source/Scene/DracoLoader.js @@ -57,7 +57,7 @@ DracoLoader.decodePointCloud = function (parameters) { * @param {object} options Object with the following properties: * @param {Uint8Array} options.array The typed array containing the buffer view data. * @param {object} options.bufferView The glTF buffer view object. - * @param {Object.<string, Number>} options.compressedAttributes The compressed attributes. + * @param {Object<string, number>} options.compressedAttributes The compressed attributes. * @param {boolean} options.dequantizeInShader Whether POSITION and NORMAL attributes should be dequantized on the GPU. * * @returns {Promise} A promise that resolves to the decoded indices and attributes. diff --git a/packages/engine/Source/Scene/EllipsoidPrimitive.js b/packages/engine/Source/Scene/EllipsoidPrimitive.js index deab0b747ac..82530a0463c 100644 --- a/packages/engine/Source/Scene/EllipsoidPrimitive.js +++ b/packages/engine/Source/Scene/EllipsoidPrimitive.js @@ -143,7 +143,7 @@ function EllipsoidPrimitive(options) { /** * User-defined object returned when the ellipsoid is picked. * - * @type Object + * @type {object} * * @default undefined * diff --git a/packages/engine/Source/Scene/Expression.js b/packages/engine/Source/Scene/Expression.js index 094994e23c0..2d413de4b39 100644 --- a/packages/engine/Source/Scene/Expression.js +++ b/packages/engine/Source/Scene/Expression.js @@ -223,7 +223,7 @@ Expression.prototype.getShaderExpression = function ( /** * Gets the variables used by the expression. * - * @returns {} The variables used by the expression. + * @returns {string[]} The variables used by the expression. * * @private */ diff --git a/packages/engine/Source/Scene/GroupMetadata.js b/packages/engine/Source/Scene/GroupMetadata.js index 54d8896a2e6..66b2e3c3d8f 100644 --- a/packages/engine/Source/Scene/GroupMetadata.js +++ b/packages/engine/Source/Scene/GroupMetadata.js @@ -127,7 +127,7 @@ GroupMetadata.prototype.hasPropertyBySemantic = function (semantic) { * Returns an array of property IDs. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ GroupMetadata.prototype.getPropertyIds = function (results) { diff --git a/packages/engine/Source/Scene/ImplicitMetadataView.js b/packages/engine/Source/Scene/ImplicitMetadataView.js index 36292af6e96..d00801aee96 100644 --- a/packages/engine/Source/Scene/ImplicitMetadataView.js +++ b/packages/engine/Source/Scene/ImplicitMetadataView.js @@ -108,7 +108,7 @@ ImplicitMetadataView.prototype.hasPropertyBySemantic = function (semantic) { * Returns an array of property IDs in the metadata table. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ ImplicitMetadataView.prototype.getPropertyIds = function (results) { diff --git a/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js b/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js index 2fa2c797c62..7814babf3cb 100644 --- a/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js +++ b/packages/engine/Source/Scene/ImplicitSubtreeMetadata.js @@ -112,7 +112,7 @@ ImplicitSubtreeMetadata.prototype.hasPropertyBySemantic = function (semantic) { * Returns an array of property IDs. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ ImplicitSubtreeMetadata.prototype.getPropertyIds = function (results) { diff --git a/packages/engine/Source/Scene/JsonMetadataTable.js b/packages/engine/Source/Scene/JsonMetadataTable.js index 6d6f8a932e1..ff6d963f988 100644 --- a/packages/engine/Source/Scene/JsonMetadataTable.js +++ b/packages/engine/Source/Scene/JsonMetadataTable.js @@ -9,7 +9,7 @@ import MetadataEntity from "./MetadataEntity.js"; * * @param {object} options Object with the following properties: * @param {number} options.count The number of entities in the table. - * @param {Object.<string, Array>} options.properties The JSON representation of the metadata table. All the arrays must have exactly options.count elements. + * @param {Object<string, Array>} options.properties The JSON representation of the metadata table. All the arrays must have exactly options.count elements. * * @alias JsonMetadataTable * @constructor @@ -45,7 +45,7 @@ JsonMetadataTable.prototype.hasProperty = function (propertyId) { * Returns an array of property IDs. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ JsonMetadataTable.prototype.getPropertyIds = function (results) { diff --git a/packages/engine/Source/Scene/MetadataClass.js b/packages/engine/Source/Scene/MetadataClass.js index 72d339e102a..49b9b609e18 100644 --- a/packages/engine/Source/Scene/MetadataClass.js +++ b/packages/engine/Source/Scene/MetadataClass.js @@ -15,7 +15,7 @@ import MetadataClassProperty from "./MetadataClassProperty.js"; * @param {string} options.id The ID of the class. * @param {string} [options.name] The name of the class. * @param {string} [options.description] The description of the class. - * @param {Object.<string, MetadataClassProperty>} [options.properties] The class properties, where each key is the property ID. + * @param {Object<string, MetadataClassProperty>} [options.properties] The class properties, where each key is the property ID. * @param {*} [options.extras] Extra user-defined properties. * @param {object} [options.extensions] An object containing extensions. * @@ -57,7 +57,7 @@ function MetadataClass(options) { * @param {object} options Object with the following properties: * @param {string} options.id The ID of the class. * @param {object} options.class The class JSON object. - * @param {Object.<string, MetadataEnum>} [options.enums] A dictionary of enums. + * @param {Object<string, MetadataEnum>} [options.enums] A dictionary of enums. * * @returns {MetadataClass} The newly created metadata class. * @@ -101,7 +101,7 @@ Object.defineProperties(MetadataClass.prototype, { * The class properties. * * @memberof MetadataClass.prototype - * @type {Object.<string, MetadataClassProperty>} + * @type {Object<string, MetadataClassProperty>} * @readonly */ properties: { @@ -114,7 +114,7 @@ Object.defineProperties(MetadataClass.prototype, { * A dictionary mapping semantics to class properties. * * @memberof MetadataClass.prototype - * @type {Object.<string, MetadataClassProperty>} + * @type {Object<string, MetadataClassProperty>} * @readonly * * @private diff --git a/packages/engine/Source/Scene/MetadataClassProperty.js b/packages/engine/Source/Scene/MetadataClassProperty.js index 9d60464be83..b21c05c06fd 100644 --- a/packages/engine/Source/Scene/MetadataClassProperty.js +++ b/packages/engine/Source/Scene/MetadataClassProperty.js @@ -128,7 +128,7 @@ function MetadataClassProperty(options) { * @param {object} options Object with the following properties: * @param {string} options.id The ID of the property. * @param {object} options.property The property JSON object. - * @param {Object.<string, MetadataEnum>} [options.enums] A dictionary of enums. + * @param {Object<string, MetadataEnum>} [options.enums] A dictionary of enums. * * @returns {MetadataClassProperty} The newly created metadata class property. * diff --git a/packages/engine/Source/Scene/MetadataEntity.js b/packages/engine/Source/Scene/MetadataEntity.js index b33b6c78769..750ab53dedb 100644 --- a/packages/engine/Source/Scene/MetadataEntity.js +++ b/packages/engine/Source/Scene/MetadataEntity.js @@ -63,7 +63,7 @@ MetadataEntity.prototype.hasPropertyBySemantic = function (semantic) { * Returns an array of property IDs. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ MetadataEntity.prototype.getPropertyIds = function (results) { @@ -196,7 +196,7 @@ MetadataEntity.hasPropertyBySemantic = function ( * @param {object} properties The dictionary containing properties. * @param {MetadataClass} classDefinition The class. * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * * @private */ diff --git a/packages/engine/Source/Scene/MetadataEnum.js b/packages/engine/Source/Scene/MetadataEnum.js index 913f6151d1f..ed23d940cd4 100644 --- a/packages/engine/Source/Scene/MetadataEnum.js +++ b/packages/engine/Source/Scene/MetadataEnum.js @@ -114,7 +114,7 @@ Object.defineProperties(MetadataEnum.prototype, { * A dictionary mapping enum integer values to names. * * @memberof MetadataEnum.prototype - * @type {Object.<Number, String>} + * @type {Object<number, string>} * @readonly * * @private @@ -129,7 +129,7 @@ Object.defineProperties(MetadataEnum.prototype, { * A dictionary mapping enum names to integer values. * * @memberof MetadataEnum.prototype - * @type {Object.<string, Number>} + * @type {Object<string, number>} * @readonly * * @private diff --git a/packages/engine/Source/Scene/MetadataSchema.js b/packages/engine/Source/Scene/MetadataSchema.js index 8aba71694df..b9fb5c0b505 100644 --- a/packages/engine/Source/Scene/MetadataSchema.js +++ b/packages/engine/Source/Scene/MetadataSchema.js @@ -16,8 +16,8 @@ import MetadataEnum from "./MetadataEnum.js"; * @param {string} [options.name] The name of the schema. * @param {string} [options.description] The description of the schema. * @param {string} [options.version] The application-specific version of the schema. - * @param {Object.<string, MetadataClass>} [options.classes] Classes defined in the schema, where each key is the class ID. - * @param {Object.<string, MetadataEnum>} [options.enums] Enums defined in the schema, where each key is the enum ID. + * @param {Object<string, MetadataClass>} [options.classes] Classes defined in the schema, where each key is the class ID. + * @param {Object<string, MetadataEnum>} [options.enums] Enums defined in the schema, where each key is the enum ID. * @param {*} [options.extras] Extra user-defined properties. * @param {object} [options.extensions] An object containing extensions. * @@ -98,7 +98,7 @@ Object.defineProperties(MetadataSchema.prototype, { * Classes defined in the schema. * * @memberof MetadataSchema.prototype - * @type {Object.<string, MetadataClass>} + * @type {Object<string, MetadataClass>} * @readonly */ classes: { @@ -111,7 +111,7 @@ Object.defineProperties(MetadataSchema.prototype, { * Enums defined in the schema. * * @memberof MetadataSchema.prototype - * @type {Object.<string, MetadataEnum>} + * @type {Object<string, MetadataEnum>} * @readonly */ enums: { diff --git a/packages/engine/Source/Scene/MetadataTable.js b/packages/engine/Source/Scene/MetadataTable.js index d1420080500..9a385771606 100644 --- a/packages/engine/Source/Scene/MetadataTable.js +++ b/packages/engine/Source/Scene/MetadataTable.js @@ -17,7 +17,7 @@ import MetadataTableProperty from "./MetadataTableProperty.js"; * @param {number} options.count The number of entities in the table. * @param {object} [options.properties] A dictionary containing properties. * @param {MetadataClass} options.class The class that properties conform to. - * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. * * @alias MetadataTable * @constructor diff --git a/packages/engine/Source/Scene/MetadataTableProperty.js b/packages/engine/Source/Scene/MetadataTableProperty.js index 5d444dd5a2b..8198e015165 100644 --- a/packages/engine/Source/Scene/MetadataTableProperty.js +++ b/packages/engine/Source/Scene/MetadataTableProperty.js @@ -23,7 +23,7 @@ import MetadataType from "./MetadataType.js"; * @param {number} options.count The number of elements in each property array. * @param {object} options.property The property JSON object. * @param {MetadataClassProperty} options.classProperty The class property. - * @param {Object.<string, Uint8Array>} options.bufferViews An object mapping bufferView IDs to Uint8Array objects. + * @param {Object<string, Uint8Array>} options.bufferViews An object mapping bufferView IDs to Uint8Array objects. * * @alias MetadataTableProperty * @constructor diff --git a/packages/engine/Source/Scene/Model/CustomShader.js b/packages/engine/Source/Scene/Model/CustomShader.js index c48311d030f..f3cb58ac413 100644 --- a/packages/engine/Source/Scene/Model/CustomShader.js +++ b/packages/engine/Source/Scene/Model/CustomShader.js @@ -78,8 +78,8 @@ import CustomShaderTranslucencyMode from "./CustomShaderTranslucencyMode.js"; * @param {CustomShaderMode} [options.mode=CustomShaderMode.MODIFY_MATERIAL] The custom shader mode, which determines how the custom shader code is inserted into the fragment shader. * @param {LightingModel} [options.lightingModel] The lighting model (e.g. PBR or unlit). If present, this overrides the default lighting for the model. * @param {CustomShaderTranslucencyMode} [options.translucencyMode=CustomShaderTranslucencyMode.INHERIT] The translucency mode, which determines how the custom shader will be applied. If the value is CustomShaderTransulcencyMode.OPAQUE or CustomShaderTransulcencyMode.TRANSLUCENT, the custom shader will override settings from the model's material. If the value is CustomShaderTransulcencyMode.INHERIT, the custom shader will render as either opaque or translucent depending on the primitive's material settings. - * @param {Object.<string, UniformSpecifier>} [options.uniforms] A dictionary for user-defined uniforms. The key is the uniform name that will appear in the GLSL code. The value is an object that describes the uniform type and initial value - * @param {Object.<string, VaryingType>} [options.varyings] A dictionary for declaring additional GLSL varyings used in the shader. The key is the varying name that will appear in the GLSL code. The value is the data type of the varying. For each varying, the declaration will be added to the top of the shader automatically. The caller is responsible for assigning a value in the vertex shader and using the value in the fragment shader. + * @param {Object<string, UniformSpecifier>} [options.uniforms] A dictionary for user-defined uniforms. The key is the uniform name that will appear in the GLSL code. The value is an object that describes the uniform type and initial value + * @param {Object<string, VaryingType>} [options.varyings] A dictionary for declaring additional GLSL varyings used in the shader. The key is the varying name that will appear in the GLSL code. The value is the data type of the varying. For each varying, the declaration will be added to the top of the shader automatically. The caller is responsible for assigning a value in the vertex shader and using the value in the fragment shader. * @param {string} [options.vertexShaderText] The custom vertex shader as a string of GLSL code. It must include a GLSL function called vertexMain. See the example for the expected signature. If not specified, the custom vertex shader step will be skipped in the computed vertex shader. * @param {string} [options.fragmentShaderText] The custom fragment shader as a string of GLSL code. It must include a GLSL function called fragmentMain. See the example for the expected signature. If not specified, the custom fragment shader step will be skipped in the computed fragment shader. * @@ -141,7 +141,7 @@ function CustomShader(options) { /** * Additional uniforms as declared by the user. * - * @type {Object.<string, UniformSpecifier>} + * @type {Object<string, UniformSpecifier>} * @readonly */ this.uniforms = defaultValue(options.uniforms, defaultValue.EMPTY_OBJECT); @@ -149,7 +149,7 @@ function CustomShader(options) { * Additional varyings as declared by the user. * This is used by {@link CustomShaderPipelineStage} * - * @type {Object.<string, VaryingType>} + * @type {Object<string, VaryingType>} * @readonly */ this.varyings = defaultValue(options.varyings, defaultValue.EMPTY_OBJECT); @@ -205,7 +205,7 @@ function CustomShader(options) { * The map of uniform names to a function that returns a value. This map * is combined with the overall uniform map used by the {@link DrawCommand} * - * @type {Object.<string, Function>} + * @type {Object<string, Function>} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js index 35ff4dd6468..d049899380d 100644 --- a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js +++ b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js @@ -142,7 +142,7 @@ MaterialPipelineStage.process = function ( * Process a single texture transformation and add it to the shader and uniform map. * * @param {ShaderBuilder} shaderBuilder The shader builder to modify - * @param {Object.<string, Function>} uniformMap The uniform map to modify. + * @param {Object<string, Function>} uniformMap The uniform map to modify. * @param {ModelComponents.TextureReader} textureReader The texture to add to the shader * @param {string} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> * @param {string} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" @@ -180,7 +180,7 @@ function processTextureTransform( * Process a single texture and add it to the shader and uniform map. * * @param {ShaderBuilder} shaderBuilder The shader builder to modify - * @param {Object.<string, Function>} uniformMap The uniform map to modify. + * @param {Object<string, Function>} uniformMap The uniform map to modify. * @param {ModelComponents.TextureReader} textureReader The texture to add to the shader * @param {string} uniformName The name of the sampler uniform such as <code>u_baseColorTexture</code> * @param {string} defineName The name of the texture for use in the defines, minus any prefix or suffix. For example, "BASE_COLOR" or "EMISSIVE" diff --git a/packages/engine/Source/Scene/Model/ModelRenderResources.js b/packages/engine/Source/Scene/Model/ModelRenderResources.js index b423fc7e793..e3f7610bd85 100644 --- a/packages/engine/Source/Scene/Model/ModelRenderResources.js +++ b/packages/engine/Source/Scene/Model/ModelRenderResources.js @@ -43,7 +43,7 @@ function ModelRenderResources(model) { * A dictionary mapping uniform name to functions that return the uniform * values. * - * @type {Object.<string, Function>} + * @type {Object<string, Function>} * @readonly * * @private diff --git a/packages/engine/Source/Scene/Model/NodeRenderResources.js b/packages/engine/Source/Scene/Model/NodeRenderResources.js index 9cb251e6bfa..aa908ffaee8 100644 --- a/packages/engine/Source/Scene/Model/NodeRenderResources.js +++ b/packages/engine/Source/Scene/Model/NodeRenderResources.js @@ -45,7 +45,7 @@ function NodeRenderResources(modelRenderResources, runtimeNode) { * A dictionary mapping uniform name to functions that return the uniform * values. Inherited from the model render resources. * - * @type {Object.<string, Function>} + * @type {Object<string, Function>} * @readonly * * @private diff --git a/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js b/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js index 3d9606bd937..ccf947bd3fd 100644 --- a/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js +++ b/packages/engine/Source/Scene/Model/PrimitiveRenderResources.js @@ -79,7 +79,7 @@ function PrimitiveRenderResources(nodeRenderResources, runtimePrimitive) { * A dictionary mapping uniform name to functions that return the uniform * values. Inherited from the node render resources. * - * @type {Object.<string, Function>} + * @type {Object<string, Function>} * @readonly * * @private diff --git a/packages/engine/Source/Scene/ModelComponents.js b/packages/engine/Source/Scene/ModelComponents.js index a2381934378..97cc61ae684 100644 --- a/packages/engine/Source/Scene/ModelComponents.js +++ b/packages/engine/Source/Scene/ModelComponents.js @@ -589,7 +589,7 @@ function Primitive() { * The feature IDs associated with this primitive. Feature ID types may * be interleaved * - * @type {ModelComponents.FeatureIdAttribute[]|ModelComponents.FeatureIdImplicitRange[]|ModelComponents.FeatureIdTexture[]} + * @type {Array<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRangeModelComponents.FeatureIdTexture>} * @private */ this.featureIds = []; diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index 257f97b37ea..a431decf52b 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -233,7 +233,7 @@ function Primitive(options) { * Determines if the primitive will be shown. This affects all geometry * instances in the primitive. * - * @type Boolean + * @type {boolean} * * @default true */ diff --git a/packages/engine/Source/Scene/PropertyAttribute.js b/packages/engine/Source/Scene/PropertyAttribute.js index 86ce1a6c7cb..e3da8c952ed 100644 --- a/packages/engine/Source/Scene/PropertyAttribute.js +++ b/packages/engine/Source/Scene/PropertyAttribute.js @@ -101,7 +101,7 @@ Object.defineProperties(PropertyAttribute.prototype, { * * @memberof PropertyAttribute.prototype * - * @type {Object.<string, PropertyAttributeProperty>} + * @type {Object<string, PropertyAttributeProperty>} * @readonly * @private */ diff --git a/packages/engine/Source/Scene/PropertyTexture.js b/packages/engine/Source/Scene/PropertyTexture.js index a6cd3a12fbe..4937827330a 100644 --- a/packages/engine/Source/Scene/PropertyTexture.js +++ b/packages/engine/Source/Scene/PropertyTexture.js @@ -15,7 +15,7 @@ import PropertyTextureProperty from "./PropertyTextureProperty.js"; * @param {string|number} [options.id] A unique id to identify the property texture, useful for debugging. For <code>EXT_structural_metadata</code>, this is the array index in the property textures array, for <code>EXT_feature_metadata</code> this is the dictionary key in the property textures dictionary. * @param {object} options.propertyTexture The property texture JSON, following the EXT_structural_metadata schema. * @param {MetadataClass} options.class The class that properties conform to. - * @param {Object.<string, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. + * @param {Object<string, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. * * @alias PropertyTexture * @constructor diff --git a/packages/engine/Source/Scene/PropertyTextureProperty.js b/packages/engine/Source/Scene/PropertyTextureProperty.js index 6bf3011f43e..9c1ed66239b 100644 --- a/packages/engine/Source/Scene/PropertyTextureProperty.js +++ b/packages/engine/Source/Scene/PropertyTextureProperty.js @@ -16,7 +16,7 @@ import MetadataComponentType from "./MetadataComponentType.js"; * @param {object} options Object with the following properties: * @param {object} options.property The property JSON object. * @param {MetadataClassProperty} options.classProperty The class property. - * @param {Object.<Number, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. + * @param {Object<number, Texture>} options.textures An object mapping texture IDs to {@link Texture} objects. * * @alias PropertyTextureProperty * @constructor diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index e1f1c31514b..9bd9bd90d06 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -392,7 +392,7 @@ function Scene(options) { * command-dense and could benefit from batching. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -409,7 +409,7 @@ function Scene(options) { * yellow. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -421,7 +421,7 @@ function Scene(options) { * Displays frames per second and time between frames. * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -433,7 +433,7 @@ function Scene(options) { * Indicates which frustum will have depth information displayed. * </p> * - * @type Number + * @type {number} * * @default 1 */ @@ -445,7 +445,7 @@ function Scene(options) { * When <code>true</code>, draws outlines to show the boundaries of the camera frustums * </p> * - * @type Boolean + * @type {boolean} * * @default false */ @@ -456,7 +456,7 @@ function Scene(options) { /** * When <code>true</code>, enables picking using the depth buffer. * - * @type Boolean + * @type {boolean} * @default true */ this.useDepthPicking = true; diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 8d982335447..7a28da23ca7 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -591,8 +591,9 @@ function handleZoom( return; } - const sameStartPosition = defaultValue( - movement.inertiaEnabled, + const sameStartPosition = Cartesian2.equals( + startPosition, + object._zoomMouseStart, Cartesian2.equals(startPosition, object._zoomMouseStart) ); let zoomingOnVector = object._zoomingOnVector; diff --git a/packages/engine/Source/Scene/SkyBox.js b/packages/engine/Source/Scene/SkyBox.js index 99b1390b1c5..e7a11fdebfb 100644 --- a/packages/engine/Source/Scene/SkyBox.js +++ b/packages/engine/Source/Scene/SkyBox.js @@ -57,7 +57,7 @@ function SkyBox(options) { * <code>negativeY</code>, <code>positiveZ</code>, and <code>negativeZ</code> properties. * These can be either URLs or <code>Image</code> objects. * - * @type Object + * @type {object} * @default undefined */ this.sources = options.sources; diff --git a/packages/engine/Source/Scene/SpatialNode.js b/packages/engine/Source/Scene/SpatialNode.js index 6cb0c4ab211..62d68f3dceb 100644 --- a/packages/engine/Source/Scene/SpatialNode.js +++ b/packages/engine/Source/Scene/SpatialNode.js @@ -372,7 +372,7 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function ( /** * @param {number} frameNumber - * @returns Boolean + * @returns {boolean} */ SpatialNode.prototype.isRenderable = function (frameNumber) { const previousNode = this.renderableKeyframeNodePrevious; diff --git a/packages/engine/Source/Scene/VoxelBoxShape.js b/packages/engine/Source/Scene/VoxelBoxShape.js index d164ada3884..594d387a710 100644 --- a/packages/engine/Source/Scene/VoxelBoxShape.js +++ b/packages/engine/Source/Scene/VoxelBoxShape.js @@ -72,7 +72,7 @@ function VoxelBoxShape() { ); /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderUniforms = { @@ -84,7 +84,7 @@ function VoxelBoxShape() { }; /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderDefines = { diff --git a/packages/engine/Source/Scene/VoxelCylinderShape.js b/packages/engine/Source/Scene/VoxelCylinderShape.js index 633a325acf9..a14c7e3bc5b 100644 --- a/packages/engine/Source/Scene/VoxelCylinderShape.js +++ b/packages/engine/Source/Scene/VoxelCylinderShape.js @@ -92,7 +92,7 @@ function VoxelCylinderShape() { this._maximumAngle = VoxelCylinderShape.DefaultMaxBounds.z; /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderUniforms = { @@ -108,7 +108,7 @@ function VoxelCylinderShape() { }; /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderDefines = { diff --git a/packages/engine/Source/Scene/VoxelEllipsoidShape.js b/packages/engine/Source/Scene/VoxelEllipsoidShape.js index cd30a2987b4..381a8948343 100644 --- a/packages/engine/Source/Scene/VoxelEllipsoidShape.js +++ b/packages/engine/Source/Scene/VoxelEllipsoidShape.js @@ -90,7 +90,7 @@ function VoxelEllipsoidShape() { this._rotation = new Matrix3(); /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderUniforms = { @@ -108,7 +108,7 @@ function VoxelEllipsoidShape() { }; /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ this.shaderDefines = { diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index 4c68ed5de99..cd862874da0 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -364,7 +364,7 @@ function VoxelPrimitive(options) { this._disableUpdate = false; /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @private */ this._uniforms = { @@ -397,14 +397,14 @@ function VoxelPrimitive(options) { /** * Shape specific shader defines from the previous shape update. Used to detect if the shader needs to be rebuilt. - * @type {Object.<string, any>} + * @type {Object<string, any>} * @private */ this._shapeDefinesOld = {}; /** * Map uniform names to functions that return the uniform values. - * @type {Object.<string, function():any>} + * @type {Object<string, function():any>} * @private */ this._uniformMap = {}; diff --git a/packages/engine/Source/Scene/VoxelRenderResources.js b/packages/engine/Source/Scene/VoxelRenderResources.js index 2f61dca086f..d83b4ac0fe6 100644 --- a/packages/engine/Source/Scene/VoxelRenderResources.js +++ b/packages/engine/Source/Scene/VoxelRenderResources.js @@ -68,7 +68,7 @@ function VoxelRenderResources(primitive) { * A dictionary mapping uniform name to functions that return the uniform * values. * - * @type {Object.<string, Function>} + * @type {Object<string, Function>} */ this.uniformMap = uniformMap; diff --git a/packages/engine/Source/Scene/VoxelShape.js b/packages/engine/Source/Scene/VoxelShape.js index cb9ce614734..ed177e89141 100644 --- a/packages/engine/Source/Scene/VoxelShape.js +++ b/packages/engine/Source/Scene/VoxelShape.js @@ -68,7 +68,7 @@ Object.defineProperties(VoxelShape.prototype, { }, /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ shaderUniforms: { @@ -76,7 +76,7 @@ Object.defineProperties(VoxelShape.prototype, { }, /** - * @type {Object.<string, any>} + * @type {Object<string, any>} * @readonly */ shaderDefines: { diff --git a/packages/engine/Source/Scene/parseBatchTable.js b/packages/engine/Source/Scene/parseBatchTable.js index 2eede18d9c2..26cb21abec7 100644 --- a/packages/engine/Source/Scene/parseBatchTable.js +++ b/packages/engine/Source/Scene/parseBatchTable.js @@ -210,7 +210,7 @@ function partitionProperties(batchTable) { * * @param {number} featureCount The number of features in the batch table * @param {string} className The name of the metadata class to be created. - * @param {Object.<string, Object>} binaryProperties A dictionary of property ID to property definition + * @param {Object<string, Object>} binaryProperties A dictionary of property ID to property definition * @param {Uint8Array} [binaryBody] The binary body of the batch table * @return {object} Transcoded data needed for constructing a {@link StructuralMetadata} object. * diff --git a/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js b/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js index c3f9b78d390..481ed2b0606 100644 --- a/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js +++ b/packages/engine/Source/Scene/parseFeatureMetadataLegacy.js @@ -14,8 +14,8 @@ import MetadataTable from "./MetadataTable.js"; * @param {object} options Object with the following properties: * @param {object} options.extension The extension JSON object. * @param {MetadataSchema} options.schema The parsed schema. - * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. - * @param {Object.<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. + * @param {Object<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. * @return {StructuralMetadata} A structural metadata object * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. diff --git a/packages/engine/Source/Scene/parseStructuralMetadata.js b/packages/engine/Source/Scene/parseStructuralMetadata.js index eca5d4c6d84..1e401fe7c27 100644 --- a/packages/engine/Source/Scene/parseStructuralMetadata.js +++ b/packages/engine/Source/Scene/parseStructuralMetadata.js @@ -14,8 +14,8 @@ import MetadataTable from "./MetadataTable.js"; * @param {object} options Object with the following properties: * @param {object} options.extension The extension JSON object. * @param {MetadataSchema} options.schema The parsed schema. - * @param {Object.<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. - * @param {Object.<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. + * @param {Object<string, Uint8Array>} [options.bufferViews] An object mapping bufferView IDs to Uint8Array objects. + * @param {Object<string, Texture>} [options.textures] An object mapping texture IDs to {@link Texture} objects. * @return {StructuralMetadata} A structural metadata object * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. From 59c60ba14546b9502fd1da74be8f4a9b6ccbcc24 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Fri, 17 Feb 2023 11:10:04 +0800 Subject: [PATCH 479/679] Add missing type --- packages/engine/Source/Scene/BatchTableHierarchy.js | 2 +- packages/engine/Source/Scene/Cesium3DTileFeature.js | 2 +- packages/engine/Source/Scene/ContentMetadata.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/BatchTableHierarchy.js b/packages/engine/Source/Scene/BatchTableHierarchy.js index 8d8cfd41113..4c1b2c4f1d9 100644 --- a/packages/engine/Source/Scene/BatchTableHierarchy.js +++ b/packages/engine/Source/Scene/BatchTableHierarchy.js @@ -409,7 +409,7 @@ BatchTableHierarchy.prototype.propertyExists = function (propertyId) { * @param {number} batchId the batch ID of the feature * @param {number} index The index of the entity. * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ BatchTableHierarchy.prototype.getPropertyIds = function (batchId, results) { diff --git a/packages/engine/Source/Scene/Cesium3DTileFeature.js b/packages/engine/Source/Scene/Cesium3DTileFeature.js index 5689f7e35ad..49d3dd06e1c 100644 --- a/packages/engine/Source/Scene/Cesium3DTileFeature.js +++ b/packages/engine/Source/Scene/Cesium3DTileFeature.js @@ -201,7 +201,7 @@ Cesium3DTileFeature.prototype.hasProperty = function (name) { * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy} * * @param {string[]} [results] An array into which to store the results. - * @returns {} The IDs of the feature's properties. + * @returns {string[]} The IDs of the feature's properties. */ Cesium3DTileFeature.prototype.getPropertyIds = function (results) { return this._content.batchTable.getPropertyIds(this._batchId, results); diff --git a/packages/engine/Source/Scene/ContentMetadata.js b/packages/engine/Source/Scene/ContentMetadata.js index 7a5c48d73f3..adc66fcd4ca 100644 --- a/packages/engine/Source/Scene/ContentMetadata.js +++ b/packages/engine/Source/Scene/ContentMetadata.js @@ -108,7 +108,7 @@ ContentMetadata.prototype.hasPropertyBySemantic = function (semantic) { * Returns an array of property IDs. * * @param {string[]} [results] An array into which to store the results. - * @returns {} The property IDs. + * @returns {string[]} The property IDs. * @private */ ContentMetadata.prototype.getPropertyIds = function (results) { From c22a9b6265f22d8f17390ccee4faef98104a78f6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 17 Feb 2023 15:40:46 -0500 Subject: [PATCH 480/679] Remove outdated files to fix merge conflict --- .../Source/Core/cancelAnimationFrame.js | 53 ------------ .../Source/Core/requestAnimationFrame.js | 83 ------------------- .../Specs/Core/requestAnimationFrameSpec.js | 50 ----------- 3 files changed, 186 deletions(-) delete mode 100644 packages/engine/Source/Core/cancelAnimationFrame.js delete mode 100644 packages/engine/Source/Core/requestAnimationFrame.js delete mode 100644 packages/engine/Specs/Core/requestAnimationFrameSpec.js diff --git a/packages/engine/Source/Core/cancelAnimationFrame.js b/packages/engine/Source/Core/cancelAnimationFrame.js deleted file mode 100644 index dd07ecf5bb5..00000000000 --- a/packages/engine/Source/Core/cancelAnimationFrame.js +++ /dev/null @@ -1,53 +0,0 @@ -import defined from "./defined.js"; -import deprecationWarning from "./deprecationWarning.js"; - -let implementation; -if (typeof cancelAnimationFrame !== "undefined") { - implementation = cancelAnimationFrame; -} - -(function () { - // look for vendor prefixed function - if (!defined(implementation) && typeof window !== "undefined") { - const vendors = ["webkit", "moz", "ms", "o"]; - let i = 0; - const len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[`${vendors[i]}CancelAnimationFrame`]; - if (!defined(implementation)) { - implementation = window[`${vendors[i]}CancelRequestAnimationFrame`]; - } - ++i; - } - } - - // otherwise, assume requestAnimationFrame is based on setTimeout, so use clearTimeout - if (!defined(implementation)) { - implementation = clearTimeout; - } -})(); - -/** - * A browser-independent function to cancel an animation frame requested using {@link requestAnimationFrame}. - * - * @function cancelAnimationFrame - * - * @param {number} requestID The value returned by {@link requestAnimationFrame}. - * - * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} - * - * @deprecated - */ -function cancelAnimationFramePolyfill(requestID) { - // we need this extra wrapper function because the native cancelAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.cancelAnimationFrame(requestID) - - deprecationWarning( - "Cesium.cancelAnimationFrame", - "Cesium.cancelAnimationFrame was deprecated in CesiumJS 1.96 and will be removed in 1.99. Use the native cancelAnimationFrame method instead." - ); - - implementation(requestID); -} -export default cancelAnimationFramePolyfill; diff --git a/packages/engine/Source/Core/requestAnimationFrame.js b/packages/engine/Source/Core/requestAnimationFrame.js deleted file mode 100644 index c94919f6e79..00000000000 --- a/packages/engine/Source/Core/requestAnimationFrame.js +++ /dev/null @@ -1,83 +0,0 @@ -import defined from "./defined.js"; -import deprecationWarning from "./deprecationWarning.js"; -import getTimestamp from "./getTimestamp.js"; - -let implementation; -if (typeof requestAnimationFrame !== "undefined") { - implementation = requestAnimationFrame; -} - -(function () { - // look for vendor prefixed function - if (!defined(implementation) && typeof window !== "undefined") { - const vendors = ["webkit", "moz", "ms", "o"]; - let i = 0; - const len = vendors.length; - while (i < len && !defined(implementation)) { - implementation = window[`${vendors[i]}RequestAnimationFrame`]; - ++i; - } - } - - // build an implementation based on setTimeout - if (!defined(implementation)) { - const msPerFrame = 1000.0 / 60.0; - let lastFrameTime = 0; - implementation = function (callback) { - const currentTime = getTimestamp(); - - // schedule the callback to target 60fps, 16.7ms per frame, - // accounting for the time taken by the callback - const delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0); - lastFrameTime = currentTime + delay; - - return setTimeout(function () { - callback(lastFrameTime); - }, delay); - }; - } -})(); - -/** - * A browser-independent function to request a new animation frame. This is used to create - * an application's draw loop as shown in the example below. - * - * @function requestAnimationFrame - * - * @param {requestAnimationFrameCallback} callback The function to call when the next frame should be drawn. - * @returns {number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. - * - * - * @example - * // Create a draw loop using requestAnimationFrame. The - * // tick callback function is called for every animation frame. - * function tick() { - * scene.render(); - * Cesium.requestAnimationFrame(tick); - * } - * tick(); - * - * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface} - * - * @deprecated - */ -function requestAnimationFramePolyFill(callback) { - // we need this extra wrapper function because the native requestAnimationFrame - // functions must be invoked on the global scope (window), which is not the case - // if invoked as Cesium.requestAnimationFrame(callback) - - deprecationWarning( - "Cesium.requestAnimationFrame", - "Cesium.requestAnimationFrame was deprecated in CesiumJS 1.96 and will be removed in 1.99. Use the native requestAnimationFrame method instead." - ); - - return implementation(callback); -} - -/** - * A function that will be called when the next frame should be drawn. - * @callback requestAnimationFrameCallback - * - * @param {number} timestamp A timestamp for the frame, in milliseconds. - */ -export default requestAnimationFramePolyFill; diff --git a/packages/engine/Specs/Core/requestAnimationFrameSpec.js b/packages/engine/Specs/Core/requestAnimationFrameSpec.js deleted file mode 100644 index 9519495c4e7..00000000000 --- a/packages/engine/Specs/Core/requestAnimationFrameSpec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { cancelAnimationFrame, requestAnimationFrame } from "../../index.js"; - -describe("Core/requestAnimationFrame", function () { - it("calls the callback", function () { - const promise = new Promise(requestAnimationFrame); - return promise.then(function (requestId) { - expect(requestId).toBeDefined(); - }); - }); - - it("provides a timestamp that increases each frame", function () { - return new Promise((resolve) => { - const callbackTimestamps = []; - - function callback(timestamp) { - callbackTimestamps.push(timestamp); - - if (callbackTimestamps.length < 3) { - requestAnimationFrame(callback); - } else { - expect(callbackTimestamps[0]).toBeLessThanOrEqual( - callbackTimestamps[1] - ); - expect(callbackTimestamps[1]).toBeLessThanOrEqual( - callbackTimestamps[2] - ); - resolve(); - } - } - - requestAnimationFrame(callback); - }); - }); - - it("can cancel a callback", function () { - return new Promise((resolve) => { - const shouldNotBeCalled = jasmine.createSpy("shouldNotBeCalled"); - - const requestID = requestAnimationFrame(shouldNotBeCalled); - cancelAnimationFrame(requestID); - - // schedule and wait for another callback - requestAnimationFrame(function () { - // make sure cancelled callback didn't run - expect(shouldNotBeCalled).not.toHaveBeenCalled(); - resolve(); - }); - }); - }); -}); From 8429a2212aa2c4a7d98ee2d948621f68a0bc2744 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 17 Feb 2023 17:21:35 -0500 Subject: [PATCH 481/679] ImageryLayer.fromProviderAsync, baseLayer --- Apps/CesiumViewer/CesiumViewer.js | 13 +- Apps/Sandcastle/gallery/ArcGIS MapServer.html | 9 +- Apps/Sandcastle/gallery/Blue Marble.html | 4 +- Apps/Sandcastle/gallery/Earth at Night.html | 11 +- .../gallery/Google Earth Enterprise.html | 3 +- .../gallery/Imagery Color To Alpha.html | 18 +- Apps/Sandcastle/gallery/Imagery Cutout.html | 26 +- .../gallery/Imagery Layers Manipulation.html | 99 +++-- .../gallery/Imagery Layers Split.html | 14 +- .../Imagery Layers Texture Filters.html | 18 +- Apps/Sandcastle/gallery/Imagery Layers.html | 32 +- Apps/Sandcastle/gallery/Natural Earth II.html | 4 +- Apps/Sandcastle/gallery/Offline.html | 8 +- Apps/Sandcastle/gallery/Sentinel-2.html | 4 +- .../gallery/Washington DC 2017.html | 6 +- .../gallery/Web Map Service (WMS).html | 4 +- .../Web Map Tile Service with Time.html | 31 +- .../gallery/development/Voxels.html | 8 +- CHANGES.md | 12 +- Documentation/OfflineGuide/README.md | 8 +- packages/engine/Source/Core/buildModuleUrl.js | 7 +- .../Scene/ArcGisMapServerImageryProvider.js | 331 +++++++++++----- .../Source/Scene/BingMapsImageryProvider.js | 354 +++++++++++++----- .../engine/Source/Scene/GlobeSurfaceTile.js | 4 +- .../Source/Scene/GlobeSurfaceTileProvider.js | 28 +- .../GoogleEarthEnterpriseImageryProvider.js | 332 +++++++++++----- .../GoogleEarthEnterpriseMapsProvider.js | 331 +++++++++++----- .../Source/Scene/GridImageryProvider.js | 331 +++++++++++----- packages/engine/Source/Scene/Imagery.js | 7 +- packages/engine/Source/Scene/ImageryLayer.js | 305 +++++++++++++-- .../Source/Scene/ImageryLayerCollection.js | 26 ++ .../engine/Source/Scene/ImageryProvider.js | 202 +++++----- .../engine/Source/Scene/IonImageryProvider.js | 351 ++++++++++++----- .../Source/Scene/MapboxImageryProvider.js | 331 +++++++++++----- .../Scene/MapboxStyleImageryProvider.js | 331 +++++++++++----- .../Source/Scene/SingleTileImageryProvider.js | 346 ++++++++++++----- .../Scene/TileCoordinatesImageryProvider.js | 331 +++++++++++----- .../Scene/UrlTemplateImageryProvider.js | 332 +++++++++++----- .../Scene/WebMapServiceImageryProvider.js | 335 ++++++++++++----- .../Scene/WebMapTileServiceImageryProvider.js | 332 +++++++++++----- .../engine/Source/Scene/createWorldImagery.js | 5 +- .../Source/Scene/createWorldImageryAsync.js | 23 +- packages/engine/Source/Widget/CesiumWidget.js | 45 ++- .../Scene/BingMapsImageryProviderSpec.js | 44 ++- .../Source/BaseLayerPicker/BaseLayerPicker.js | 46 +-- .../BaseLayerPickerViewModel.js | 26 +- .../createDefaultImageryProviderViewModels.js | 53 +-- packages/widgets/Source/Viewer/Viewer.js | 34 +- .../BaseLayerPickerViewModelSpec.js | 11 +- 49 files changed, 4051 insertions(+), 1515 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 5a7bb85825f..3237d5ef8be 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -11,6 +11,7 @@ import { queryToObject, CzmlDataSource, GeoJsonDataSource, + ImageryLayer, KmlDataSource, GpxDataSource, Terrain, @@ -42,15 +43,15 @@ async function main() { */ const endUserOptions = queryToObject(window.location.search.substring(1)); - let imageryProvider; + let baseLayer; if (defined(endUserOptions.tmsImageryUrl)) { - imageryProvider = new TileMapServiceImageryProvider({ - url: endUserOptions.tmsImageryUrl, - }); + baseLayer = ImageryLayer.fromProviderAsync( + TileMapServiceImageryProvider.fromUrl(endUserOptions.tmsImageryUrl) + ); } const loadingIndicator = document.getElementById("loadingIndicator"); - const hasBaseLayerPicker = !defined(imageryProvider); + const hasBaseLayerPicker = !defined(baseLayer); const terrain = Terrain.fromWorldTerrain({ requestWaterMask: true, @@ -60,7 +61,7 @@ async function main() { let viewer; try { viewer = new Viewer("cesiumContainer", { - imageryProvider: imageryProvider, + baseLayer: baseLayer, baseLayerPicker: hasBaseLayerPicker, scene3DOnly: endUserOptions.scene3DOnly, requestRenderMode: true, diff --git a/Apps/Sandcastle/gallery/ArcGIS MapServer.html b/Apps/Sandcastle/gallery/ArcGIS MapServer.html index 6ef348f9b27..007aa861425 100644 --- a/Apps/Sandcastle/gallery/ArcGIS MapServer.html +++ b/Apps/Sandcastle/gallery/ArcGIS MapServer.html @@ -33,10 +33,11 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/", - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/" + ) + ), }); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/Blue Marble.html b/Apps/Sandcastle/gallery/Blue Marble.html index f6bf5104167..977210bd83e 100644 --- a/Apps/Sandcastle/gallery/Blue Marble.html +++ b/Apps/Sandcastle/gallery/Blue Marble.html @@ -37,7 +37,9 @@ //Sandcastle_Begin // Blue Marble Next Generation July, 2004 imagery from NASA const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.IonImageryProvider({ assetId: 3845 }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3845) + ), }); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/Earth at Night.html b/Apps/Sandcastle/gallery/Earth at Night.html index 7e01e2c8eb4..4792b1e48b6 100644 --- a/Apps/Sandcastle/gallery/Earth at Night.html +++ b/Apps/Sandcastle/gallery/Earth at Night.html @@ -37,7 +37,9 @@ //Sandcastle_Begin // The Earth at Night, also known as Black Marble 2017 and Night Lights const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.IonImageryProvider({ assetId: 3812 }), + baseLayer: new Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3812) + ), }); // The rest of the code is for dynamic lighting @@ -47,11 +49,10 @@ const imageryLayers = viewer.imageryLayers; const nightLayer = imageryLayers.get(0); - const dayLayer = imageryLayers.addImageryProvider( - new Cesium.IonImageryProvider({ - assetId: 3845, - }) + const dayLayer = Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3845) ); + imageryLayers.add(dayLayer); imageryLayers.lowerToBottom(dayLayer); function updateLighting(dynamicLighting) { diff --git a/Apps/Sandcastle/gallery/Google Earth Enterprise.html b/Apps/Sandcastle/gallery/Google Earth Enterprise.html index 20ef94ec801..57174c3e8d1 100644 --- a/Apps/Sandcastle/gallery/Google Earth Enterprise.html +++ b/Apps/Sandcastle/gallery/Google Earth Enterprise.html @@ -52,11 +52,12 @@ ); const layers = viewer.scene.imageryLayers; - const blackMarble = layers.addImageryProvider( + const blackMarble = new Cesium.ImageryLayer( new Cesium.GoogleEarthEnterpriseImageryProvider({ metadata: geeMetadata, }) ); + layers.add(blackMarble); } catch (error) { console.log(`Failed to create Google Earth providers from metadata. Confirm GEE service is correctly configured. ${error}`); diff --git a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html index fd5d119da27..77786d0d465 100644 --- a/Apps/Sandcastle/gallery/Imagery Color To Alpha.html +++ b/Apps/Sandcastle/gallery/Imagery Color To Alpha.html @@ -67,12 +67,20 @@ baseLayer.colorToAlphaThreshold = 0.2; // Add a bump layer with adjustable threshold - const singleTileLayer = layers.addImageryProvider( - new Cesium.SingleTileImageryProvider({ - url: "../images/earthbump1k.jpg", - rectangle: Cesium.Rectangle.fromDegrees(-180.0, -90.0, 180.0, 90.0), - }) + const singleTileLayer = Cesium.ImageryLayer.fromProviderAsync( + Cesium.SingleTileImageryProvider.fromUrl( + "../images/earthbump1k.jpg", + { + rectangle: Cesium.Rectangle.fromDegrees( + -180.0, + -90.0, + 180.0, + 90.0 + ), + } + ) ); + layers.add(singleTileLayer); singleTileLayer.colorToAlpha = new Cesium.Color(0.0, 0.0, 0.0, 1.0); singleTileLayer.colorToAlphaThreshold = 0.1; diff --git a/Apps/Sandcastle/gallery/Imagery Cutout.html b/Apps/Sandcastle/gallery/Imagery Cutout.html index c18078ebd9e..28dc5c7303e 100644 --- a/Apps/Sandcastle/gallery/Imagery Cutout.html +++ b/Apps/Sandcastle/gallery/Imagery Cutout.html @@ -50,9 +50,11 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) + ), baseLayerPicker: false, }); @@ -78,16 +80,19 @@ imageryBaseLayer.cutoutRectangle = defaultImageryLayerCutout; // Fit a SingleTileImageryProvider inside the cutout on the lowest layer - layers.addImageryProvider( - new Cesium.SingleTileImageryProvider({ - url: "../images/Cesium_Logo_overlay.png", - rectangle: defaultImageryLayerCutout, - }) + const logo = Cesium.ImageryLayer.fromProviderAsync( + Cesium.SingleTileImageryProvider.fromUrl( + "../images/Cesium_Logo_overlay.png", + { + rectangle: defaultImageryLayerCutout, + } + ) ); + layers.add(logo); // Add an Earth at Night layer and a "traveling" cutout - const earthAtNight = layers.addImageryProvider( - new Cesium.IonImageryProvider({ assetId: 3812 }) + const earthAtNight = Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3812) ); earthAtNight.cutoutRectangle = Cesium.Rectangle.fromDegrees( -100, @@ -96,6 +101,7 @@ 50 ); earthAtNight.alpha = 0.9; + layers.add(earthAtNight); // "traveling" code const flags = { diff --git a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html index 77ca2e9616e..66e5b1e31e1 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Manipulation.html @@ -158,19 +158,21 @@ // These base layers aren't really special. It's possible to have multiple of them // enabled at once, just like the other layers, but it doesn't make much sense because // all of these layers cover the entire globe and are opaque. - addBaseLayerOption("Bing Maps Aerial", undefined); // the current base layer + addBaseLayerOption( + "Bing Maps Aerial", + Cesium.createWorldImageryAsync() + ); addBaseLayerOption( "Bing Maps Road", - Cesium.createWorldImagery({ + Cesium.createWorldImageryAsync({ style: Cesium.IonWorldImageryStyle.ROAD, }) ); addBaseLayerOption( "ArcGIS World Street Maps", - new Cesium.ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", - }) + Cesium.ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" + ) ); addBaseLayerOption( "OpenStreetMaps", @@ -187,9 +189,9 @@ ); addBaseLayerOption( "Natural Earth II (local)", - new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }) + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) ); addBaseLayerOption( "USGS Shaded Relief (via WMTS)", @@ -234,22 +236,24 @@ ); addAdditionalLayerOption( "TileMapService Image", - new Cesium.TileMapServiceImageryProvider({ - url: "../images/cesium_maptiler/Cesium_Logo_Color", - }), + Cesium.TileMapServiceImageryProvider.fromUrl( + "../images/cesium_maptiler/Cesium_Logo_Color" + ), 0.2 ); addAdditionalLayerOption( "Single Image", - new Cesium.SingleTileImageryProvider({ - url: "../images/Cesium_Logo_overlay.png", - rectangle: Cesium.Rectangle.fromDegrees( - -115.0, - 38.0, - -107, - 39.75 - ), - }), + Cesium.SingleTileImageryProvider.fromUrl( + "../images/Cesium_Logo_overlay.png", + { + rectangle: Cesium.Rectangle.fromDegrees( + -115.0, + 38.0, + -107, + 39.75 + ), + } + ), 1.0 ); addAdditionalLayerOption( @@ -266,25 +270,45 @@ ); } - function addBaseLayerOption(name, imageryProvider) { - let layer; - if (typeof imageryProvider === "undefined") { - layer = imageryLayers.get(0); - viewModel.selectedLayer = layer; - } else { - layer = new Cesium.ImageryLayer(imageryProvider); - } + async function addBaseLayerOption(name, imageryProviderPromise) { + try { + const imageryProvider = await Promise.resolve( + imageryProviderPromise + ); - layer.name = name; - baseLayers.push(layer); + const layer = new Cesium.ImageryLayer(imageryProvider); + layer.name = name; + baseLayers.push(layer); + updateLayerList(); + } catch (error) { + console.error( + `There was an error while creating ${name}. ${error}` + ); + } } - function addAdditionalLayerOption(name, imageryProvider, alpha, show) { - const layer = imageryLayers.addImageryProvider(imageryProvider); - layer.alpha = Cesium.defaultValue(alpha, 0.5); - layer.show = Cesium.defaultValue(show, true); - layer.name = name; - Cesium.knockout.track(layer, ["alpha", "show", "name"]); + async function addAdditionalLayerOption( + name, + imageryProviderPromise, + alpha, + show + ) { + try { + const imageryProvider = await Promise.resolve( + imageryProviderPromise + ); + const layer = new Cesium.ImageryLayer(imageryProvider); + layer.alpha = Cesium.defaultValue(alpha, 0.5); + layer.show = Cesium.defaultValue(show, true); + layer.name = name; + imageryLayers.add(layer); + Cesium.knockout.track(layer, ["alpha", "show", "name"]); + updateLayerList(); + } catch (error) { + console.error( + `There was an error while creating ${name}. ${error}` + ); + } } function updateLayerList() { @@ -296,7 +320,6 @@ } setupLayers(); - updateLayerList(); //Bind the viewModel to the DOM elements of the UI that call for it. const toolbar = document.getElementById("toolbar"); diff --git a/Apps/Sandcastle/gallery/Imagery Layers Split.html b/Apps/Sandcastle/gallery/Imagery Layers Split.html index 803fa48e8b9..038a7bba458 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Split.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Split.html @@ -57,19 +57,21 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" + ) + ), baseLayerPicker: false, infoBox: false, }); const layers = viewer.imageryLayers; - const earthAtNight = layers.addImageryProvider( - new Cesium.IonImageryProvider({ assetId: 3812 }) + const earthAtNight = Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3812) ); earthAtNight.splitDirection = Cesium.SplitDirection.LEFT; // Only show to the left of the slider. + layers.add(earthAtNight); // Sync the position of the slider with the split position const slider = document.getElementById("slider"); diff --git a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html index a419e3c913b..b21aac4c312 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html +++ b/Apps/Sandcastle/gallery/Imagery Layers Texture Filters.html @@ -64,17 +64,19 @@ const layers = viewer.imageryLayers; layers.removeAll(); - const layerLinear = layers.addImageryProvider( - new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }) + const layerLinear = Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) ); + layers.add(layerLinear); - const layerNearest = layers.addImageryProvider( - new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }) + const layerNearest = Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) ); + layers.add(layerNearest); // Set the texture minification and magnification filters of layerNearest. Default is LINEAR. layerNearest.minificationFilter = diff --git a/Apps/Sandcastle/gallery/Imagery Layers.html b/Apps/Sandcastle/gallery/Imagery Layers.html index 2687b6662ad..d923fd7c475 100644 --- a/Apps/Sandcastle/gallery/Imagery Layers.html +++ b/Apps/Sandcastle/gallery/Imagery Layers.html @@ -39,27 +39,35 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: Cesium.createWorldImagery({ + baseLayer: Cesium.ImageryLayer.fromWorldImagery({ style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS, }), baseLayerPicker: false, }); - const layers = viewer.scene.imageryLayers; - const blackMarble = layers.addImageryProvider( - new Cesium.IonImageryProvider({ assetId: 3812 }) - ); + const blackMarble = Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3812) + ); blackMarble.alpha = 0.5; - blackMarble.brightness = 2.0; + layers.add(blackMarble); - layers.addImageryProvider( - new Cesium.SingleTileImageryProvider({ - url: "../images/Cesium_Logo_overlay.png", - rectangle: Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75), - }) - ); //Sandcastle_End + const cesiumLogo = Cesium.ImageryLayer.fromProviderAsync( + Cesium.SingleTileImageryProvider.fromUrl( + "../images/Cesium_Logo_overlay.png", + { + rectangle: Cesium.Rectangle.fromDegrees( + -75.0, + 28.0, + -67.0, + 29.75 + ), + } + ) + ); + layers.add(cesiumLogo); + //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/Natural Earth II.html b/Apps/Sandcastle/gallery/Natural Earth II.html index 51d4cbbff0a..c8f3e7d745f 100644 --- a/Apps/Sandcastle/gallery/Natural Earth II.html +++ b/Apps/Sandcastle/gallery/Natural Earth II.html @@ -37,7 +37,9 @@ //Sandcastle_Begin // Natural Earth II with Shaded Relief, Water, and Drainages from http://www.naturalearthdata.com const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.IonImageryProvider({ assetId: 3813 }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3813) + ), }); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/Offline.html b/Apps/Sandcastle/gallery/Offline.html index 2ca33ce8782..cb9b3679b70 100644 --- a/Apps/Sandcastle/gallery/Offline.html +++ b/Apps/Sandcastle/gallery/Offline.html @@ -41,9 +41,11 @@ // https://github.com/CesiumGS/cesium/wiki/Offline-Guide const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) + ), baseLayerPicker: false, geocoder: false, }); diff --git a/Apps/Sandcastle/gallery/Sentinel-2.html b/Apps/Sandcastle/gallery/Sentinel-2.html index 5f9199e39ef..1a48c1b32b9 100644 --- a/Apps/Sandcastle/gallery/Sentinel-2.html +++ b/Apps/Sandcastle/gallery/Sentinel-2.html @@ -37,7 +37,9 @@ //Sandcastle_Begin // Sentinel-2 (mostly) cloudless global imagery between 10 and 60 meter resolution. const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.IonImageryProvider({ assetId: 3954 }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3954) + ), }); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/Washington DC 2017.html b/Apps/Sandcastle/gallery/Washington DC 2017.html index 269ea111f2c..0b963209e95 100644 --- a/Apps/Sandcastle/gallery/Washington DC 2017.html +++ b/Apps/Sandcastle/gallery/Washington DC 2017.html @@ -38,9 +38,11 @@ // 3 inch (0.08m) resolution imagery of Washington DC collected in 2017 const viewer = new Cesium.Viewer("cesiumContainer"); - const imageryLayer = viewer.imageryLayers.addImageryProvider( - new Cesium.IonImageryProvider({ assetId: 3827 }) + const imageryLayer = Cesium.ImageryLayer.fromProviderAsync( + Cesium.IonImageryProvider.fromAssetId(3827) ); + + viewer.imageryLayers.add(imageryLayer); viewer.flyTo(imageryLayer); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/Web Map Service (WMS).html b/Apps/Sandcastle/gallery/Web Map Service (WMS).html index c94994aa7e0..79ede9cfeda 100644 --- a/Apps/Sandcastle/gallery/Web Map Service (WMS).html +++ b/Apps/Sandcastle/gallery/Web Map Service (WMS).html @@ -38,8 +38,7 @@ const viewer = new Cesium.Viewer("cesiumContainer"); // Add a WMS imagery layer - const imageryLayers = viewer.imageryLayers; - imageryLayers.addImageryProvider( + const layer = new Cesium.ImageryLayer( new Cesium.WebMapServiceImageryProvider({ url: "https://nationalmap.gov.au/proxy/http://geoserver.nationalmap.nicta.com.au/geotopo_250k/ows", @@ -50,6 +49,7 @@ }, }) ); + viewer.imageryLayers.add(layer); // Start off looking at Australia. viewer.camera.setView({ diff --git a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html index b97e963e228..40433786ca3 100644 --- a/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html +++ b/Apps/Sandcastle/gallery/Web Map Tile Service with Time.html @@ -76,23 +76,24 @@ times: times, credit: "NASA Global Imagery Browse Services for EOSDIS", }); - const imageryLayers = viewer.imageryLayers; - const layer = imageryLayers.addImageryProvider(provider); - provider.readyPromise.then(function () { - const start = Cesium.JulianDate.fromIso8601("2015-07-30"); - const stop = Cesium.JulianDate.fromIso8601("2017-06-17"); + const layer = new Cesium.ImageryLayer(provider); - viewer.timeline.zoomTo(start, stop); + // Make the weather layer semi-transparent to see the underlying geography. + layer.alpha = 0.5; - const clock = viewer.clock; - clock.startTime = start; - clock.stopTime = stop; - clock.currentTime = start; - clock.clockRange = Cesium.ClockRange.LOOP_STOP; - clock.multiplier = 7200; - // Make the weather layer semi-transparent to see the underlying geography. - layer.alpha = 0.5; - }); + viewer.imageryLayers.add(layer); + + const start = Cesium.JulianDate.fromIso8601("2015-07-30"); + const stop = Cesium.JulianDate.fromIso8601("2017-06-17"); + + viewer.timeline.zoomTo(start, stop); + + const clock = viewer.clock; + clock.startTime = start; + clock.stopTime = stop; + clock.currentTime = start; + clock.clockRange = Cesium.ClockRange.LOOP_STOP; + clock.multiplier = 7200; //Sandcastle_End }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/development/Voxels.html b/Apps/Sandcastle/gallery/development/Voxels.html index 58abbc206ad..a4d414c95c8 100644 --- a/Apps/Sandcastle/gallery/development/Voxels.html +++ b/Apps/Sandcastle/gallery/development/Voxels.html @@ -33,9 +33,11 @@ "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) + ), baseLayerPicker: false, geocoder: false, }); diff --git a/CHANGES.md b/CHANGES.md index 27870dbc7e9..f277bde9fd2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,11 +12,14 @@ ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. ##### Deprecated :hourglass_flowing_sand: +- `CesiumWidget` constructor option `options.imageryProvider` haw been deprecated in Cesium 1.102. It will be removed in 1.104. Use `options.baseLayer` instead. - `ImageryProvider.ready` and `ImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. +- `ImageryProvider.defaultAlpha`, `ImageryProvider.defaultNightAlpha`, `ImageryProvider.defaultDayAlpha`, `ImageryProvider.defaultBrightness`, `ImageryProvider.defaultContrast`, `ImageryProvider.defaultHue`, `ImageryProvider.defaultSaturation`, `ImageryProvider.defaultGamma`, `ImageryProvider.defaultMinificationFilter`, `ImageryProvider.defaultMagnificationFilter` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ImageryLayer.alpha`, `ImageryLayer.nightAlpha`, `ImageryLayer.dayAlpha`, `ImageryLayer.brightness`, `ImageryLayer.contrast`, `ImageryLayer.hue`, `ImageryLayer.saturation`, `ImageryLayer.gamma`, `ImageryLayer.minificationFilter`, `ImageryLayer.magnificationFilter`instead. +- `ImageryLayer.getViewableRectangle` was deprecated in Cesium 1.102. It will be removed in 1.104. Use `ImageryLayer.getImageryRectangle` instead. - `ArcGisMapServerImageryProvider` constructor parameter `url`,`ArcGisMapServerImageryProvider.ready`, and `ArcGisMapServerImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGisMapServerImageryProvider.fromUrl` instead. - `BingMapsImageryProvider` constructor parameter `url`,`BingMapsImageryProvider.ready`, and `BingMapsImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `BingMapsImageryProvider.fromUrl` instead. - `GoogleEarthEnterpriseImageryProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseImageryProvider.ready`, and `GoogleEarthEnterpriseImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseImageryProvider.fromMetadata` instead. @@ -34,7 +37,6 @@ - `WebMapServiceImageryProvider.ready`, and `WebMapServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `WebMapTileServiceImageryProvider.ready`, and `WebMapTileServiceImageryProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. - `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `ImageryLayer.getViewableRectangle` was deprecated in Cesium 1.102. It will be removed in 1.104. Use `ImageryLayer.getImageryRectangle` instead. - `createWorldImagery` was deprecated in Cesium 1.102. It will be removed in 1.104. Use `createWorldImageryAsync` instead. - `ArcGISTiledElevationTerrainProvider` constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. - `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `CesiumTerrainProvider.fromUrl` instead. @@ -45,6 +47,12 @@ - `VRTheWorldTerrainProvider` constructor parameter `options.url`, `VRTheWorldTerrainProvider.ready`, and `VRTheWorldTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `VRTheWorldTerrainProvider.fromUrl` instead. - `createWorldTerrain` was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use createWorldTerrainAsync instead. +#### @cesium/widgets + +##### Deprecated :hourglass_flowing_sand: + +- `Viewer` constructor option `options.imageryProvider` haw been deprecated in Cesium 1.102. It will be removed in 1.104. Use `options.baseLayer` instead. + ### 1.101 - 2023-01-02 #### Major Announcements :loudspeaker: diff --git a/Documentation/OfflineGuide/README.md b/Documentation/OfflineGuide/README.md index 920e573860f..cb32caf9c0e 100644 --- a/Documentation/OfflineGuide/README.md +++ b/Documentation/OfflineGuide/README.md @@ -20,9 +20,11 @@ This example shows how to configure CesiumJS to avoid use of online data sources ```javascript const viewer = new Cesium.Viewer("cesiumContainer", { - imageryProvider: new Cesium.TileMapServiceImageryProvider({ - url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - }), + baseLayer: Cesium.ImageryLayer.fromProviderAsync( + Cesium.TileMapServiceImageryProvider.fromUrl( + Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + ) + ), baseLayerPicker: false, geocoder: false, }); diff --git a/packages/engine/Source/Core/buildModuleUrl.js b/packages/engine/Source/Core/buildModuleUrl.js index 44b878a3c9b..42f9ca80417 100644 --- a/packages/engine/Source/Core/buildModuleUrl.js +++ b/packages/engine/Source/Core/buildModuleUrl.js @@ -98,9 +98,10 @@ let implementation; * * @example * const viewer = new Cesium.Viewer("cesiumContainer", { - * imageryProvider: new Cesium.TileMapServiceImageryProvider({ - * url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), - * }), + * baseLayer: Cesium.ImageryLayer.fromProviderAsync( + * Cesium.TileMapServiceImageryProvider.fromUrl( + * Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"), + * )), * baseLayerPicker: false, * }); */ diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index c219a737902..680be1c822a 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -296,91 +296,16 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { function ArcGisMapServerImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._tileDiscardPolicy = options.tileDiscardPolicy; this._tileWidth = defaultValue(options.tileWidth, 256); @@ -720,6 +645,242 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { return this._layers; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultAlpha", + "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultAlpha", + "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultNightAlpha", + "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultNightAlpha", + "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultDayAlpha", + "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultDayAlpha", + "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultBrightness", + "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultBrightness", + "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultContrast", + "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultContrast", + "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultHue", + "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultHue", + "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultSaturation", + "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultSaturation", + "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultGamma", + "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultGamma", + "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultMinificationFilter", + "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultMinificationFilter", + "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof ArcGisMapServerImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultMagnificationFilter", + "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "ArcGisMapServerImageryProvider.defaultMagnificationFilter", + "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index 8e6db34c6c6..9a8840d5674 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -22,7 +22,7 @@ import ImageryProvider from "./ImageryProvider.js"; * * @property {Resource|String} [url] The url of the Bing Maps server hosting the imagery. Deprecated. * @property {String} [key] The Bing Maps key for your application, which can be - * created at {@link https://www.bingmapsportal.com/}. Deprecated. + * created at {@link https://www.bingmapsportal.com/}. * @property {String} [tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'. * By default, tiles are loaded using the same protocol as the page. * @property {BingMapsStyle} [mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load. @@ -190,8 +190,8 @@ async function requestMetadata( * * @example * const bing = await Cesium.BingMapsImageryProvider.fromUrl( - * "https://dev.virtualearth.net", - * "get-yours-at-https://www.bingmapsportal.com/", { + * "https://dev.virtualearth.net", { + * key: "get-yours-at-https://www.bingmapsportal.com/", * mapStyle: Cesium.BingMapsStyle.AERIAL * }); * @@ -201,91 +201,16 @@ async function requestMetadata( function BingMapsImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default 1.0 - */ - this.defaultGamma = 1.0; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = 1.0; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._mapStyle = defaultValue(options.mapStyle, BingMapsStyle.AERIAL); this._culture = defaultValue(options.culture, ""); @@ -593,34 +518,268 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { return false; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultAlpha", + "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultAlpha", + "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultNightAlpha", + "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultNightAlpha", + "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultDayAlpha", + "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultDayAlpha", + "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultBrightness", + "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultBrightness", + "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultContrast", + "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultContrast", + "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultHue", + "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultHue", + "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultSaturation", + "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultSaturation", + "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof BingMapsImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultGamma", + "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultGamma", + "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof BingMapsImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultMinificationFilter", + "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultMinificationFilter", + "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof BingMapsImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "BingMapsImageryProvider.defaultMagnificationFilter", + "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "BingMapsImageryProvider.defaultMagnificationFilter", + "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** * Creates an {@link ImageryProvider} which provides tiled imagery using the Bing Maps Imagery REST API. * * @param {Resource|String} url The url of the Bing Maps server hosting the imagery. - * @param {String} key The Bing Maps key for your application, which can be - * created at {@link https://www.bingmapsportal.com/}. * @param {BingMapsImageryProvider.ConstructorOptions} options Object describing initialization options * @returns {Promise<BingMapsImageryProvider>} A promise that resolves to the created BingMapsImageryProvider * * @example * const bing = await Cesium.BingMapsImageryProvider.fromUrl( - * "https://dev.virtualearth.net", - * "get-yours-at-https://www.bingmapsportal.com/", { + * "https://dev.virtualearth.net", { + * key: "get-yours-at-https://www.bingmapsportal.com/", * mapStyle: Cesium.BingMapsStyle.AERIAL * }); * * @exception {RuntimeError} metadata does not specify one resource in resourceSets */ -BingMapsImageryProvider.fromUrl = async function (url, key, options) { +BingMapsImageryProvider.fromUrl = async function (url, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + //>>includeStart('debug', pragmas.debug); Check.defined("url", url); - Check.defined("key", key); + Check.defined("options.key", options.key); //>>includeEnd('debug'); - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - let tileProtocol = options.tileProtocol; // For backward compatibility reasons, the tileProtocol may end with @@ -645,14 +804,13 @@ BingMapsImageryProvider.fromUrl = async function (url, key, options) { url: `REST/v1/Imagery/Metadata/${mapStyle}`, queryParameters: { incl: "ImageryProviders", - key: key, + key: options.key, uriScheme: tileProtocol, }, }); const provider = new BingMapsImageryProvider(options); provider._resource = resource; - provider._key = key; const imageryProviderBuilder = new ImageryProviderBuilder(options); await requestMetadata(metadataResource, imageryProviderBuilder); imageryProviderBuilder.build(provider); diff --git a/packages/engine/Source/Scene/GlobeSurfaceTile.js b/packages/engine/Source/Scene/GlobeSurfaceTile.js index 84bb2cb9e4e..c89c1c0e05b 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTile.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTile.js @@ -345,8 +345,8 @@ GlobeSurfaceTile.prototype.processImagery = function ( if (tileImagery.loadingImagery.state === ImageryState.PLACEHOLDER) { const imageryLayer = tileImagery.loadingImagery.imageryLayer; - // ready is deprecated. This is here for backwards compatibility - if (imageryLayer.imageryProvider._ready) { + // ImageryProvider.ready is deprecated. This is here for backwards compatibility + if (imageryLayer.ready && imageryLayer.imageryProvider._ready) { // Remove the placeholder and add the actual skeletons (if any) // at the same position. Then continue the loop at the same index. tileImagery.freeResources(); diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 055c511255b..05c8b2875f3 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -239,10 +239,12 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { get: function () { return ( defined(this._terrainProvider) && - // ready is deprecated; This is here for backwards compatibility + // TerrainProvider.ready is deprecated; This is here for backwards compatibility this._terrainProvider._ready && (this._imageryLayers.length === 0 || - this._imageryLayers.get(0).imageryProvider._ready) + // ImageryProvider.ready is deprecated; This is here for backwards compatibility + (this._imageryLayers.get(0).ready && + this._imageryLayers.get(0).imageryProvider._ready)) ); }, }, @@ -355,10 +357,14 @@ function updateCredits(surface, frameState) { const imageryLayers = surface._imageryLayers; for (let i = 0, len = imageryLayers.length; i < len; ++i) { - const imageryProvider = imageryLayers.get(i).imageryProvider; - // ready is deprecated; This is here for backwards compatibility - if (imageryProvider._ready && defined(imageryProvider.credit)) { - creditDisplay.addCredit(imageryProvider.credit); + const layer = imageryLayers.get(i); + // ImageryProvider.ready is deprecated; This is here for backwards compatibility + if ( + layer.ready && + layer.imageryProvider._ready && + defined(layer.imageryProvider.credit) + ) { + creditDisplay.addCredit(layer.imageryProvider.credit); } } } @@ -1439,9 +1445,8 @@ GlobeSurfaceTileProvider.prototype._onLayerAdded = function (layer, index) { const terrainProvider = this._terrainProvider; const that = this; - const imageryProvider = layer.imageryProvider; const tileImageryUpdatedEvent = this._imageryLayersUpdatedEvent; - imageryProvider._reload = function () { + const reloadFunction = function () { // Clear the layer's cache layer._imageryCache = {}; @@ -1503,6 +1508,11 @@ GlobeSurfaceTileProvider.prototype._onLayerAdded = function (layer, index) { }); }; + if (layer.ready) { + const imageryProvider = layer.imageryProvider; + imageryProvider._reload = reloadFunction; + } + // create TileImageries for this layer for all previously loaded tiles this._quadtree.forEachLoadedTile(function (tile) { if (layer._createTileImagerySkeletons(tile, terrainProvider)) { @@ -2125,7 +2135,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { const hasVertexNormals = defined(tileProvider.terrainProvider) && // ready is deprecated; This is here for backwards compatibility - tileProvider.terrainProvider._ready && + tileProvider.terrainP && tileProvider.terrainProvider.hasVertexNormals; const enableFog = frameState.fog.enabled && frameState.fog.renderable && !cameraUnderground; diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index aedf4bb8bb2..0d73daddc8c 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -92,92 +92,16 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function ( */ function GoogleEarthEnterpriseImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._tileDiscardPolicy = options.tileDiscardPolicy; @@ -459,6 +383,242 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { return false; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha", + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultBrightness", + "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultBrightness", + "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultContrast", + "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultContrast", + "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultHue", + "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultHue", + "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultSaturation", + "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultSaturation", + "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultGamma", + "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultGamma", + "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter", + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter", + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof GoogleEarthEnterpriseImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter", + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter", + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js index 4dd0c17d8f2..44fce031630 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js @@ -206,91 +206,16 @@ async function requestMetadata( function GoogleEarthEnterpriseMapsProvider(options) { options = defaultValue(options, {}); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default 1.9 - */ - this.defaultGamma = 1.9; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = 1.9; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._tileDiscardPolicy = options.tileDiscardPolicy; this._channel = options.channel; @@ -595,6 +520,242 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { return true; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha", + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultBrightness", + "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultBrightness", + "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultContrast", + "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultContrast", + "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultHue", + "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultHue", + "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultSaturation", + "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultSaturation", + "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultGamma", + "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultGamma", + "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter", + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter", + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof GoogleEarthEnterpriseMapsProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter", + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter", + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/GridImageryProvider.js b/packages/engine/Source/Scene/GridImageryProvider.js index 2daca9a188d..d6c8e7477b2 100644 --- a/packages/engine/Source/Scene/GridImageryProvider.js +++ b/packages/engine/Source/Scene/GridImageryProvider.js @@ -40,91 +40,16 @@ const defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2); function GridImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._tilingScheme = defined(options.tilingScheme) ? options.tilingScheme @@ -328,6 +253,242 @@ Object.defineProperties(GridImageryProvider.prototype, { return true; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultAlpha", + "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultAlpha", + "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultNightAlpha", + "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultNightAlpha", + "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultDayAlpha", + "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultDayAlpha", + "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultBrightness", + "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultBrightness", + "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultContrast", + "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultContrast", + "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultHue", + "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultHue", + "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultSaturation", + "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultSaturation", + "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof GridImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultGamma", + "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultGamma", + "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof GridImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultMinificationFilter", + "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultMinificationFilter", + "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof GridImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "GridImageryProvider.defaultMagnificationFilter", + "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "GridImageryProvider.defaultMagnificationFilter", + "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/Imagery.js b/packages/engine/Source/Scene/Imagery.js index 4b23f7a83a2..bdcf5407f81 100644 --- a/packages/engine/Source/Scene/Imagery.js +++ b/packages/engine/Source/Scene/Imagery.js @@ -34,7 +34,12 @@ function Imagery(imageryLayer, x, y, level, rectangle) { this.credits = undefined; this.referenceCount = 0; - if (!defined(rectangle) && imageryLayer.imageryProvider._ready) { + // imageryProvider._ready is deprecated; This is here for backward compatibility + if ( + !defined(rectangle) && + imageryLayer.ready && + imageryLayer.imageryProvider._ready + ) { const tilingScheme = imageryLayer.imageryProvider.tilingScheme; rectangle = tilingScheme.tileXYToRectangle(x, y, level); } diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 81f0fc5a2b7..4ae97da1b43 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -1,10 +1,13 @@ import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian4 from "../Core/Cartesian4.js"; +import Check from "../Core/Check.js"; +import createWorldImageryAsync from "../Scene/createWorldImageryAsync.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import deprecationWarning from "../Core/deprecationWarning.js"; import DeveloperError from "../Core/DeveloperError.js"; +import Event from "../Core/Event.js"; import FeatureDetection from "../Core/FeatureDetection.js"; import GeographicProjection from "../Core/GeographicProjection.js"; import IndexDatatype from "../Core/IndexDatatype.js"; @@ -38,35 +41,31 @@ import SplitDirection from "./SplitDirection.js"; import TileImagery from "./TileImagery.js"; /** - * An imagery layer that displays tiled image data from a single imagery provider - * on a {@link Globe}. + * @typedef {Object} ImageryLayer.ConstructorOptions * - * @alias ImageryLayer - * @constructor + * Initialization options for the ImageryLayer constructor. * - * @param {ImageryProvider} imageryProvider The imagery provider to use. - * @param {Object} [options] Object with the following properties: - * @param {Rectangle} [options.rectangle=imageryProvider.rectangle] The rectangle of the layer. This rectangle + * @property {Rectangle} [options.rectangle=imageryProvider.rectangle] The rectangle of the layer. This rectangle * can limit the visible portion of the imagery provider. - * @param {Number|Function} [options.alpha=1.0] The alpha blending value of this layer, from 0.0 to 1.0. + * @property {Number|Function} [options.alpha=1.0] The alpha blending value of this layer, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. - * @param {Number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0. + * @property {Number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>. - * @param {Number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0. + * @property {Number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the alpha is required, and it is expected to return * the alpha value to use for the tile. This only takes effect when <code>enableLighting</code> is <code>true</code>. - * @param {Number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery + * @property {Number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery * color. Less than 1.0 makes the imagery darker while greater than 1.0 makes it brighter. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -74,7 +73,7 @@ import TileImagery from "./TileImagery.js"; * imagery tile for which the brightness is required, and it is expected to return * the brightness value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.contrast=1.0] The contrast of this layer. 1.0 uses the unmodified imagery color. + * @property {Number|Function} [options.contrast=1.0] The contrast of this layer. 1.0 uses the unmodified imagery color. * Less than 1.0 reduces the contrast while greater than 1.0 increases it. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -82,14 +81,14 @@ import TileImagery from "./TileImagery.js"; * imagery tile for which the contrast is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.hue=0.0] The hue of this layer. 0.0 uses the unmodified imagery color. + * @property {Number|Function} [options.hue=0.0] The hue of this layer. 0.0 uses the unmodified imagery color. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates * of the imagery tile for which the hue is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.saturation=1.0] The saturation of this layer. 1.0 uses the unmodified imagery color. + * @property {Number|Function} [options.saturation=1.0] The saturation of this layer. 1.0 uses the unmodified imagery color. * Less than 1.0 reduces the saturation while greater than 1.0 increases it. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the @@ -97,39 +96,75 @@ import TileImagery from "./TileImagery.js"; * of the imagery tile for which the saturation is required, and it is expected to return * the contrast value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {Number|Function} [options.gamma=1.0] The gamma correction to apply to this layer. 1.0 uses the unmodified imagery color. + * @property {Number|Function} [options.gamma=1.0] The gamma correction to apply to this layer. 1.0 uses the unmodified imagery color. * This can either be a simple number or a function with the signature * <code>function(frameState, layer, x, y, level)</code>. The function is passed the * current frame state, this layer, and the x, y, and level coordinates of the * imagery tile for which the gamma is required, and it is expected to return * the gamma value to use for the tile. The function is executed for every * frame and for every tile, so it must be fast. - * @param {SplitDirection|Function} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this layer. - * @param {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The + * @property {SplitDirection|Function} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this layer. + * @property {TextureMinificationFilter} [options.minificationFilter=TextureMinificationFilter.LINEAR] The * texture minification filter to apply to this layer. Possible values * are <code>TextureMinificationFilter.LINEAR</code> and * <code>TextureMinificationFilter.NEAREST</code>. - * @param {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The + * @property {TextureMagnificationFilter} [options.magnificationFilter=TextureMagnificationFilter.LINEAR] The * texture minification filter to apply to this layer. Possible values * are <code>TextureMagnificationFilter.LINEAR</code> and * <code>TextureMagnificationFilter.NEAREST</code>. - * @param {Boolean} [options.show=true] True if the layer is shown; otherwise, false. - * @param {Number} [options.maximumAnisotropy=maximum supported] The maximum anisotropy level to use + * @property {Boolean} [options.show=true] True if the layer is shown; otherwise, false. + * @property {Number} [options.maximumAnisotropy=maximum supported] The maximum anisotropy level to use * for texture filtering. If this parameter is not specified, the maximum anisotropy supported * by the WebGL stack will be used. Larger values make the imagery look better in horizon * views. - * @param {Number} [options.minimumTerrainLevel] The minimum terrain level-of-detail at which to show this imagery layer, + * @property {Number} [options.minimumTerrainLevel] The minimum terrain level-of-detail at which to show this imagery layer, * or undefined to show it at all levels. Level zero is the least-detailed level. - * @param {Number} [options.maximumTerrainLevel] The maximum terrain level-of-detail at which to show this imagery layer, + * @property {Number} [options.maximumTerrainLevel] The maximum terrain level-of-detail at which to show this imagery layer, * or undefined to show it at all levels. Level zero is the least-detailed level. - * @param {Rectangle} [options.cutoutRectangle] Cartographic rectangle for cutting out a portion of this ImageryLayer. - * @param {Color} [options.colorToAlpha] Color to be used as alpha. - * @param {Number} [options.colorToAlphaThreshold=0.004] Threshold for color-to-alpha. + * @property {Rectangle} [options.cutoutRectangle] Cartographic rectangle for cutting out a portion of this ImageryLayer. + * @property {Color} [options.colorToAlpha] Color to be used as alpha. + * @property {Number} [options.colorToAlphaThreshold=0.004] Threshold for color-to-alpha. + */ + +/** + * An imagery layer that displays tiled image data from a single imagery provider + * on a {@link Globe}. + * + * @alias ImageryLayer + * @constructor + * + * @param {ImageryProvider} imageryProvider The imagery provider to use. + * @param {ImageryLayer.ConstructorOptions} options An object describing initialization options + * + * @see ImageryLayer.fromProviderAsync + * @see ImageryLayer.fromWorldImagery + * + * @example + * // Add an OpenStreetMaps layer + * const imageryLayer = new Cesium.ImageryLayer(OpenStreetMapImageryProvider({ + * url: "https://a.tile.openstreetmap.org/" + * })), + * scene.imageryLayers.add(imageryLayer); + * + * @example + * // Add Cesium ion's default world imagery layer + * const imageryLayer = Cesium.ImageryLayer.fromWorldImagery(); + * scene.imageryLayers.add(imageryLayer); + * + * @example + * // Add a new transparent layer from Cesium ion + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * imageryLayer.alpha = 0.5; + * scene.imageryLayers.add(imageryLayer); */ function ImageryLayer(imageryProvider, options) { this._imageryProvider = imageryProvider; + this._readyEvent = new Event(); + this._errorEvent = new Event(); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + imageryProvider = defaultValue(imageryProvider, defaultValue.EMPTY_OBJECT); /** * The alpha blending value of this layer, with 0.0 representing fully transparent and @@ -140,7 +175,7 @@ function ImageryLayer(imageryProvider, options) { */ this.alpha = defaultValue( options.alpha, - defaultValue(imageryProvider.defaultAlpha, 1.0) + defaultValue(imageryProvider._defaultAlpha, 1.0) ); /** @@ -152,7 +187,7 @@ function ImageryLayer(imageryProvider, options) { */ this.nightAlpha = defaultValue( options.nightAlpha, - defaultValue(imageryProvider.defaultNightAlpha, 1.0) + defaultValue(imageryProvider._defaultNightAlpha, 1.0) ); /** @@ -164,7 +199,7 @@ function ImageryLayer(imageryProvider, options) { */ this.dayAlpha = defaultValue( options.dayAlpha, - defaultValue(imageryProvider.defaultDayAlpha, 1.0) + defaultValue(imageryProvider._defaultDayAlpha, 1.0) ); /** @@ -177,7 +212,7 @@ function ImageryLayer(imageryProvider, options) { this.brightness = defaultValue( options.brightness, defaultValue( - imageryProvider.defaultBrightness, + imageryProvider._defaultBrightness, ImageryLayer.DEFAULT_BRIGHTNESS ) ); @@ -191,7 +226,10 @@ function ImageryLayer(imageryProvider, options) { */ this.contrast = defaultValue( options.contrast, - defaultValue(imageryProvider.defaultContrast, ImageryLayer.DEFAULT_CONTRAST) + defaultValue( + imageryProvider._defaultContrast, + ImageryLayer.DEFAULT_CONTRAST + ) ); /** @@ -202,7 +240,7 @@ function ImageryLayer(imageryProvider, options) { */ this.hue = defaultValue( options.hue, - defaultValue(imageryProvider.defaultHue, ImageryLayer.DEFAULT_HUE) + defaultValue(imageryProvider._defaultHue, ImageryLayer.DEFAULT_HUE) ); /** @@ -215,7 +253,7 @@ function ImageryLayer(imageryProvider, options) { this.saturation = defaultValue( options.saturation, defaultValue( - imageryProvider.defaultSaturation, + imageryProvider._defaultSaturation, ImageryLayer.DEFAULT_SATURATION ) ); @@ -228,7 +266,7 @@ function ImageryLayer(imageryProvider, options) { */ this.gamma = defaultValue( options.gamma, - defaultValue(imageryProvider.defaultGamma, ImageryLayer.DEFAULT_GAMMA) + defaultValue(imageryProvider._defaultGamma, ImageryLayer.DEFAULT_GAMMA) ); /** @@ -239,7 +277,7 @@ function ImageryLayer(imageryProvider, options) { */ this.splitDirection = defaultValue( options.splitDirection, - defaultValue(imageryProvider.defaultSplit, ImageryLayer.DEFAULT_SPLIT) + ImageryLayer.DEFAULT_SPLIT ); /** @@ -256,7 +294,7 @@ function ImageryLayer(imageryProvider, options) { this.minificationFilter = defaultValue( options.minificationFilter, defaultValue( - imageryProvider.defaultMinificationFilter, + imageryProvider._defaultMinificationFilter, ImageryLayer.DEFAULT_MINIFICATION_FILTER ) ); @@ -275,7 +313,7 @@ function ImageryLayer(imageryProvider, options) { this.magnificationFilter = defaultValue( options.magnificationFilter, defaultValue( - imageryProvider.defaultMagnificationFilter, + imageryProvider._defaultMagnificationFilter, ImageryLayer.DEFAULT_MAGNIFICATION_FILTER ) ); @@ -338,7 +376,7 @@ function ImageryLayer(imageryProvider, options) { Object.defineProperties(ImageryLayer.prototype, { /** - * Gets the imagery provider for this layer. + * Gets the imagery provider for this layer. This should not be called before {@link ImageryLayer#ready} returns true. * @memberof ImageryLayer.prototype * @type {ImageryProvider} * @readonly @@ -349,6 +387,45 @@ Object.defineProperties(ImageryLayer.prototype, { }, }, + /** + * Returns true when the terrain provider has been successfully created. Otherwise, returns false. + * @memberof ImageryLayer.prototype + * @type {boolean} + * @readonly + */ + ready: { + get: function () { + return defined(this._imageryProvider); + }, + }, + + /** + * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of the thrown error. + * @memberof Imagery.prototype + * @type {Event<Imagery.ErrorEventCallback>} + * @readonly + */ + errorEvent: { + get: function () { + return this._errorEvent; + }, + }, + + /** + * Gets an event that is raised when the imagery provider has been successfully created. Event listeners + * are passed the created instance of {@link ImageryProvider}. + * @memberof ImageryLayer.prototype + * @type {Event<ImageryLayer.ReadyEventCallback>} + * @readonly + */ + readyEvent: { + get: function () { + return this._readyEvent; + }, + }, + /** * Gets the rectangle of this layer. If this rectangle is smaller than the rectangle of the * {@link ImageryProvider}, only a portion of the imagery provider is shown. @@ -431,6 +508,113 @@ ImageryLayer.DEFAULT_MAGNIFICATION_FILTER = TextureMagnificationFilter.LINEAR; */ ImageryLayer.DEFAULT_APPLY_COLOR_TO_ALPHA_THRESHOLD = 0.004; +/** + * Create a new imagery layer from an asynchronous imagery provider. The layer will handle any asynchronous loads or errors, and begin rendering the imagery layer once ready. + * + * @param {Promise<ImageryProvider>} imageryProviderPromise A promise which resolves to a imagery provider + * @param {ImageryLayer.ConstructorOptions} options An object describing initialization options + * @returns {ImageryLayer} The created imagery layer. + * + * @example + * // Create a new base layer + * const viewer = new Cesium.Viewer("cesiumContainer", { + * baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * }); + * + * @example + * // Add a new transparent layer + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * imageryLayer.alpha = 0.5; + * viewer.imageryLayers.add(imageryLayer); + * + * @example + * // Handle loading events + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * viewer.imageryLayers.add(imageryLayer); + * + * imageryLayer.readyEvent.addEventListener(provider => { + * imageryLayer.provider.errorEvent.addEventListener(error => { + * alert(`Encountered an error while loading imagery tiles! ${error}`); + * }); + * }); + * + * imageryLayer.errorEvent.addEventListener(error => { + * alert(`Encountered an error while creating an imagery layer! ${error}`); + * }); + * + * @see ImageryLayer.errorEvent + * @see ImageryLayer.readyEvent + * @see ImageryLayer.provider + * @see ImageryLayer.fromWorldImagery + */ +ImageryLayer.fromProviderAsync = function (imageryProviderPromise, options) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("imageryProviderPromise", imageryProviderPromise); + //>>includeEnd('debug'); + + const layer = new ImageryLayer(undefined, options); + + handlePromise(layer, Promise.resolve(imageryProviderPromise)); + + return layer; +}; + +/** + * @typedef {ImageryLayer.ConstructorOptions} ImageryLayer.WorldImageryConstructorOptions + * + * Initialization options for ImageryLayer.fromWorldImagery + * + * @property {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. + */ + +/** + * Create a new imagery layer for ion's default global base imagery layer, currently Bing Maps. The layer will handle any asynchronous loads or errors, and begin rendering the imagery layer once ready. + * + * @param {ImageryLayer.WorldImageryConstructorOptions} options An object describing initialization options + * @returns {ImageryLayer} The created imagery layer. + * + * * @example + * // Create a new base layer + * const viewer = new Cesium.Viewer("cesiumContainer", { + * baseLayer: Cesium.ImageryLayer.fromWorldImagery(); + * }); + * + * @example + * // Add a new transparent layer + * const imageryLayer = Cesium.ImageryLayer.fromWorldImagery(); + * imageryLayer.alpha = 0.5; + * viewer.imageryLayers.add(imageryLayer); + * + * @example + * // Handle loading events + * const imageryLayer = Cesium.ImageryLayer.fromWorldImagery(); + * viewer.imageryLayers.add(imageryLayer); + * + * imageryLayer.readyEvent.addEventListener(provider => { + * imageryLayer.provider.errorEvent.addEventListener(error => { + * alert(`Encountered an error while loading imagery tiles! ${error}`); + * }); + * }); + * + * imageryLayer.errorEvent.addEventListener(error => { + * alert(`Encountered an error while creating an imagery layer! ${error}`); + * }); + * + * @see ImageryLayer.errorEvent + * @see ImageryLayer.readyEvent + * @see ImageryLayer.provider + */ +ImageryLayer.fromWorldImagery = function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + return ImageryLayer.fromProviderAsync( + createWorldImageryAsync({ + style: options.style, + }), + options + ); +}; + /** * Gets a value indicating whether this layer is the base layer in the * {@link ImageryLayerCollection}. The base layer is the one that underlies all @@ -562,14 +746,13 @@ ImageryLayer.prototype._createTileImagerySkeletons = function ( return false; } - const imageryProvider = this._imageryProvider; - if (!defined(insertionPoint)) { insertionPoint = surfaceTile.imagery.length; } + const imageryProvider = this._imageryProvider; // ready is deprecated. This is here for backwards compatibility - if (!imageryProvider._ready) { + if (!this.ready || !imageryProvider._ready) { // The imagery provider is not ready, so we can't create skeletons, yet. // Instead, add a placeholder so that we'll know to create // the skeletons once the provider is ready. @@ -987,7 +1170,7 @@ ImageryLayer.prototype._requestImagery = function (imagery) { return; } - // Initially assume failure. handleError may retry, in which case the state will + // Initially assume failure. An error handler may retry, in which case the state will // change to TRANSITIONING. imagery.state = ImageryState.FAILED; imagery.request = undefined; @@ -1566,4 +1749,44 @@ function getLevelWithMaximumTexelSpacing( const rounded = Math.round(level); return rounded | 0; } + +function handleError(errorEvent, error) { + if (errorEvent.numberOfListeners > 0) { + errorEvent.raiseEvent(error); + } else { + // Default handler is to log to the console + console.error(error); + } +} + +async function handlePromise(instance, promise) { + let provider; + try { + provider = await Promise.resolve(promise); + if (instance.isDestroyed()) { + return; + } + instance._imageryProvider = provider; + instance._readyEvent.raiseEvent(provider); + } catch (error) { + handleError(instance._errorEvent, error); + } +} + export default ImageryLayer; + +/** + * A function that is called when an error occurs. + * @callback ImageryLayer.ErrorEventCallback + * + * @this ImageryLayer + * @param {Error} err An object holding details about the error that occurred. + */ + +/** + * A function that is called when the provider has been created + * @callback ImageryLayer.ReadyEventCallback + * + * @this ImageryLayer + * @param {ImageryProvider} provider The created imagery provider. + */ diff --git a/packages/engine/Source/Scene/ImageryLayerCollection.js b/packages/engine/Source/Scene/ImageryLayerCollection.js index 81c22614c07..e69370460a5 100644 --- a/packages/engine/Source/Scene/ImageryLayerCollection.js +++ b/packages/engine/Source/Scene/ImageryLayerCollection.js @@ -76,6 +76,14 @@ Object.defineProperties(ImageryLayerCollection.prototype, { * be added on top of all existing layers. * * @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of the layers. + * + * @example + * const imageryLayer = Cesium.ImageryLayer.fromWorldImagery(); + * scene.imageryLayers.addImageryProvider(imageryLayer); + * + * @example + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * scene.imageryLayers.addImageryProvider(imageryLayer); */ ImageryLayerCollection.prototype.add = function (layer, index) { const hasIndex = defined(index); @@ -104,6 +112,10 @@ ImageryLayerCollection.prototype.add = function (layer, index) { this._update(); this.layerAdded.raiseEvent(layer, index); + const removeReadyEventListener = layer.readyEvent.addEventListener(() => { + this.layerShownOrHidden.raiseEvent(layer, layer._layerIndex, layer.show); + removeReadyEventListener(); + }); }; /** @@ -113,6 +125,14 @@ ImageryLayerCollection.prototype.add = function (layer, index) { * @param {Number} [index] the index to add the layer at. If omitted, the layer will * added on top of all existing layers. * @returns {ImageryLayer} The newly created layer. + * + * @example + * try { + * const provider = await Cesium.IonImageryProvider.fromAssetId(3812); + * scene.imageryLayers.addImageryProvider(provider); + * } catch (error) { + * console.log(`There was an error creating the imagery layer. ${error}`) + * } */ ImageryLayerCollection.prototype.addImageryProvider = function ( imageryProvider, @@ -353,6 +373,9 @@ function pickImageryHelper(scene, pickedLocation, pickFeatures, callback) { if (!defined(imagery)) { continue; } + if (!imagery.imageryLayer.ready) { + continue; + } const provider = imagery.imageryLayer.imageryProvider; if (pickFeatures && !defined(provider.pickFeatures)) { continue; @@ -476,6 +499,9 @@ ImageryLayerCollection.prototype.pickImageryLayerFeatures = function ( const imageryLayers = []; pickImageryHelper(scene, pickedLocation, true, function (imagery) { + if (!imagery.imageryLayer.ready) { + return undefined; + } const provider = imagery.imageryLayer.imageryProvider; const promise = provider.pickFeatures( imagery.x, diff --git a/packages/engine/Source/Scene/ImageryProvider.js b/packages/engine/Source/Scene/ImageryProvider.js index 453739e4fe8..5b18ca4dab1 100644 --- a/packages/engine/Source/Scene/ImageryProvider.js +++ b/packages/engine/Source/Scene/ImageryProvider.js @@ -43,92 +43,6 @@ import Resource from "../Core/Resource.js"; * @demo {@link https://sandcastle.cesium.com/index.html?src=Imagery%20Layers%20Manipulation.html|Cesium Sandcastle Imagery Manipulation Demo} */ function ImageryProvider() { - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; - DeveloperError.throwInstantiationError(); } @@ -277,6 +191,122 @@ Object.defineProperties(ImageryProvider.prototype, { hasAlphaChannel: { get: DeveloperError.throwInstantiationError, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof ImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof ImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof ImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: DeveloperError.throwInstantiationError, + set: DeveloperError.throwInstantiationError, + }, }); /** diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 4473550bbf1..c71fe6cb93b 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -38,9 +38,7 @@ const ImageryProviderMapping = { const ImageryProviderAsyncMapping = { ARCGIS_MAPSERVER: ArcGisMapServerImageryProvider.fromUrl, BING: async (url, options) => { - const key = options.key; - delete options.key; - return BingMapsImageryProvider.fromUrl(url, key, options); + return BingMapsImageryProvider.fromUrl(url, options); }, GOOGLE_EARTH: async (url, options) => { const channel = options.channel; @@ -98,99 +96,24 @@ const ImageryProviderAsyncMapping = { * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options * * @example - * const imageryProvider = await Cesium.IonImageryProvider.fromAssetId(2348902); - * viewer.imageryLayers.addImageryProvider(imageryProvider); + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * viewer.imageryLayers.add(imageryLayer); * * @see IonImageryProvider.fromAssetId */ function IonImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._ready = false; this._tileCredits = undefined; @@ -387,6 +310,242 @@ Object.defineProperties(IonImageryProvider.prototype, { }, }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultAlpha", + "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultAlpha", + "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultNightAlpha", + "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultNightAlpha", + "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultDayAlpha", + "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultDayAlpha", + "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultBrightness", + "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultBrightness", + "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultContrast", + "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultContrast", + "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultHue", + "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultHue", + "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultSaturation", + "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultSaturation", + "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof IonImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultGamma", + "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultGamma", + "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof IonImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultMinificationFilter", + "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultMinificationFilter", + "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof IonImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "IonImageryProvider.defaultMagnificationFilter", + "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "IonImageryProvider.defaultMagnificationFilter", + "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); // This is here for backwards compatibility @@ -462,8 +621,8 @@ IonImageryProvider._initialize = function (provider, assetId, options) { * @returns {Promise<IonImageryProvider>} A promise which resolves to the created IonImageryProvider. * * @example - * const imageryProvider = await Cesium.IonImageryProvider.fromAssetId(2348902); - * viewer.imageryLayers.addImageryProvider(imageryProvider); + * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); + * viewer.imageryLayers.add(imageryLayer); * * @exception {RuntimeError} Cesium ion assetId is not an imagery asset * @exception {RuntimeError} Unrecognized Cesium ion imagery type @@ -511,9 +670,11 @@ IonImageryProvider.fromAssetId = async function (assetId, options) { `Unrecognized Cesium ion imagery type: ${externalType}` ); } - const url = endpoint.options.url; - delete endpoint.options.url; - imageryProvider = await factory(url, endpoint.options); + // Make a copy before editing since this object reference is cached; + const options = { ...endpoint.options }; + const url = options.url; + delete options.url; + imageryProvider = await factory(url, options); } const provider = new IonImageryProvider(options); diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index 1b3b2399179..1ba41224e9e 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -63,91 +63,16 @@ function MapboxImageryProvider(options) { } //>>includeEnd('debug'); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; const resource = Resource.createIfNeeded( defaultValue(options.url, "https://{s}.tiles.mapbox.com/v4/") @@ -388,6 +313,242 @@ Object.defineProperties(MapboxImageryProvider.prototype, { return this._imageryProvider.hasAlphaChannel; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultAlpha", + "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultAlpha", + "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultNightAlpha", + "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this.defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultNightAlpha", + "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this.defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultDayAlpha", + "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultDayAlpha", + "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultBrightness", + "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultBrightness", + "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultContrast", + "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultContrast", + "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultHue", + "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultHue", + "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultSaturation", + "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultSaturation", + "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof MapboxImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultGamma", + "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultGamma", + "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof MapboxImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultMinificationFilter", + "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultMinificationFilter", + "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof MapboxImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "MapboxImageryProvider.defaultMagnificationFilter", + "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "MapboxImageryProvider.defaultMagnificationFilter", + "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js index 391eac23105..79a1f4437af 100644 --- a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js @@ -65,91 +65,16 @@ function MapboxStyleImageryProvider(options) { } //>>includeEnd('debug'); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; const resource = Resource.createIfNeeded( defaultValue(options.url, "https://api.mapbox.com/styles/v1/") @@ -392,6 +317,242 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { return this._imageryProvider.hasAlphaChannel; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultAlpha", + "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultAlpha", + "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultNightAlpha", + "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultNightAlpha", + "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultDayAlpha", + "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultDayAlpha", + "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultBrightness", + "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultBrightness", + "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultContrast", + "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultContrast", + "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultHue", + "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultHue", + "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultSaturation", + "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultSaturation", + "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof MapboxStyleImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultGamma", + "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultGamma", + "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof MapboxStyleImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultMinificationFilter", + "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultMinificationFilter", + "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof MapboxStyleImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "MapboxStyleImageryProvider.defaultMagnificationFilter", + "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "MapboxStyleImageryProvider.defaultMagnificationFilter", + "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index d73755379b9..370dbfd18d6 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -17,8 +17,8 @@ import ImageryProvider from "./ImageryProvider.js"; * Initialization options for the SingleTileImageryProvider constructor * * @property {Resource|String} url The url for the tile. - * @property {Number} tileWidth The width of the tile, in pixels. - * @property {Number} tileHeight The height of the tile, in pixels. + * @property {Number} [tileWidth] The width of the tile, in pixels. + * @property {Number} [tileHeight] The height of the tile, in pixels. * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. @@ -44,91 +44,17 @@ import ImageryProvider from "./ImageryProvider.js"; */ function SingleTileImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; const rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE); const tilingScheme = new GeographicTilingScheme({ @@ -378,6 +304,242 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { return true; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultAlpha", + "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultAlpha", + "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultNightAlpha", + "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultNightAlpha", + "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultDayAlpha", + "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultDayAlpha", + "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultBrightness", + "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultBrightness", + "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultContrast", + "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultContrast", + "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultHue", + "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultHue", + "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultSaturation", + "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultSaturation", + "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof SingleTileImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultGamma", + "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultGamma", + "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof SingleTileImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultMinificationFilter", + "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultMinificationFilter", + "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof SingleTileImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "SingleTileImageryProvider.defaultMagnificationFilter", + "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "SingleTileImageryProvider.defaultMagnificationFilter", + "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); function failure(resource, error, provider, previousError) { @@ -415,10 +577,20 @@ async function doRequest(resource, provider, previousError) { } } +/** + * @typedef {Object} SingleTileImageryProvider.fromUrlOptions + * + * Initialization options for the SingleTileImageryProvider constructor when using SingleTileImageryProvider.fromUrl + * + * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image. + * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. + * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used. + */ + /** * Creates a provider for a single, top-level imagery tile. The single image is assumed to use a * @param {Resource|String} url The url for the tile - * @param {SingleTileImageryProvider.ConstructorOptions} [options] Object describing initialization options. + * @param {SingleTileImageryProvider.fromUrlOptions} [options] Object describing initialization options. * * @example * const provider = await SingleTileImageryProvider.fromUrl("https://yoururl.com/image.png"); diff --git a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js index 94ea6f034f8..fb4a5507bb6 100644 --- a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js +++ b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js @@ -42,91 +42,16 @@ function TileCoordinatesImageryProvider(options) { this._ready = true; this._readyPromise = Promise.resolve(true); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; } Object.defineProperties(TileCoordinatesImageryProvider.prototype, { @@ -304,6 +229,242 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { return true; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultAlpha", + "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultAlpha", + "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultNightAlpha", + "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultNightAlpha", + "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultDayAlpha", + "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultDayAlpha", + "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultBrightness", + "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultBrightness", + "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultContrast", + "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultContrast", + "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultHue", + "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultHue", + "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultSaturation", + "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultSaturation", + "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultGamma", + "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultGamma", + "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultMinificationFilter", + "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultMinificationFilter", + "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof TileCoordinatesImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultMagnificationFilter", + "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "TileCoordinatesImageryProvider.defaultMagnificationFilter", + "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index 2f47420ae1b..854efa3b58d 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -152,7 +152,6 @@ const pickFeaturesTags = combine(tags, { * // Access Natural Earth II imagery, which uses a TMS tiling scheme and Geographic (EPSG:4326) project * const tms = new Cesium.UrlTemplateImageryProvider({ * url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII') + '/{z}/{x}/{reverseY}.jpg', - * credit : '© Analytical Graphics, Inc.', * tilingScheme : new Cesium.GeographicTilingScheme(), * maximumLevel : 5 * }); @@ -258,91 +257,16 @@ function UrlTemplateImageryProvider(options) { this._readyPromise = Promise.resolve(true); this._ready = true; - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; /** * Gets or sets a value indicating whether feature picking is enabled. If true, {@link UrlTemplateImageryProvider#pickFeatures} will @@ -622,6 +546,242 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { return this._hasAlphaChannel; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultAlpha", + "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultAlpha", + "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultNightAlpha", + "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultNightAlpha", + "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultDayAlpha", + "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultDayAlpha", + "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultBrightness", + "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultBrightness", + "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultContrast", + "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultContrast", + "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultHue", + "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultHue", + "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultSaturation", + "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultSaturation", + "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof UrlTemplateImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultGamma", + "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultGamma", + "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof UrlTemplateImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultMinificationFilter", + "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultMinificationFilter", + "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof UrlTemplateImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "UrlTemplateImageryProvider.defaultMagnificationFilter", + "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "UrlTemplateImageryProvider.defaultMagnificationFilter", + "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js index 2bf6fd5454b..34e0d52969f 100644 --- a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js @@ -98,8 +98,8 @@ const excludesReverseAxis = [ * layers : '0', * proxy: new Cesium.DefaultProxy('/proxy/') * }); - * - * viewer.imageryLayers.addImageryProvider(provider); + * const imageryLayer = new Cesium.ImageryLayer(provider); + * viewer.imageryLayers.add(imageryLayer); */ function WebMapServiceImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -119,91 +119,16 @@ function WebMapServiceImageryProvider(options) { ); } - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; this._getFeatureInfoUrl = defaultValue( options.getFeatureInfoUrl, @@ -635,6 +560,242 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { return this._getFeatureInfoUrl; }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultAlpha", + "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultAlpha", + "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultNightAlpha", + "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultNightAlpha", + "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultDayAlpha", + "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultDayAlpha", + "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultBrightness", + "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultBrightness", + "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultContrast", + "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultContrast", + "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultHue", + "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultHue", + "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultSaturation", + "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultSaturation", + "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof WebMapServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultGamma", + "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultGamma", + "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof WebMapServiceImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultMinificationFilter", + "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultMinificationFilter", + "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof WebMapServiceImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "WebMapServiceImageryProvider.defaultMagnificationFilter", + "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "WebMapServiceImageryProvider.defaultMagnificationFilter", + "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js index e544e5871fd..afd5b1ae829 100644 --- a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js @@ -137,91 +137,16 @@ function WebMapTileServiceImageryProvider(options) { } //>>includeEnd('debug'); - /** - * The default alpha blending value of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultAlpha = undefined; - - /** - * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultNightAlpha = undefined; - - /** - * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and - * 1.0 representing fully opaque. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultDayAlpha = undefined; - - /** - * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 - * makes the imagery darker while greater than 1.0 makes it brighter. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultBrightness = undefined; - - /** - * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces - * the contrast while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultContrast = undefined; - - /** - * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultHue = undefined; - - /** - * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the - * saturation while greater than 1.0 increases it. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultSaturation = undefined; - - /** - * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. - * - * @type {Number|undefined} - * @default undefined - */ - this.defaultGamma = undefined; - - /** - * The default texture minification filter to apply to this provider. - * - * @type {TextureMinificationFilter} - * @default undefined - */ - this.defaultMinificationFilter = undefined; - - /** - * The default texture magnification filter to apply to this provider. - * - * @type {TextureMagnificationFilter} - * @default undefined - */ - this.defaultMagnificationFilter = undefined; + this._defaultAlpha = undefined; + this._defaultNightAlpha = undefined; + this._defaultDayAlpha = undefined; + this._defaultBrightness = undefined; + this._defaultContrast = undefined; + this._defaultHue = undefined; + this._defaultSaturation = undefined; + this._defaultGamma = undefined; + this._defaultMinificationFilter = undefined; + this._defaultMagnificationFilter = undefined; const resource = Resource.createIfNeeded(options.url); @@ -288,6 +213,7 @@ function WebMapTileServiceImageryProvider(options) { } this._readyPromise = Promise.resolve(true); + this._ready = true; // Check the number of tiles at the minimum level. If it's more than four, // throw an exception, because starting at the higher minimum @@ -632,6 +558,242 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { } }, }, + + /** + * The default alpha blending value of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultAlpha: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultAlpha", + "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + return this._defaultAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultAlpha", + "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.alpha instead." + ); + this._defaultAlpha = value; + }, + }, + + /** + * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultNightAlpha: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultNightAlpha", + "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + return this._defaultNightAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultNightAlpha", + "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.nightAlpha instead." + ); + this._defaultNightAlpha = value; + }, + }, + + /** + * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and + * 1.0 representing fully opaque. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultDayAlpha: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultDayAlpha", + "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + return this._defaultDayAlpha; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultDayAlpha", + "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.dayAlpha instead." + ); + this._defaultDayAlpha = value; + }, + }, + + /** + * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 + * makes the imagery darker while greater than 1.0 makes it brighter. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultBrightness: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultBrightness", + "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + return this._defaultBrightness; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultBrightness", + "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.brightness instead." + ); + this._defaultBrightness = value; + }, + }, + + /** + * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces + * the contrast while greater than 1.0 increases it. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultContrast: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultContrast", + "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + return this._defaultContrast; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultContrast", + "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.contrast instead." + ); + this._defaultContrast = value; + }, + }, + + /** + * The default hue of this provider in radians. 0.0 uses the unmodified imagery color. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultHue: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultHue", + "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + return this._defaultHue; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultHue", + "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.hue instead." + ); + this._defaultHue = value; + }, + }, + + /** + * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the + * saturation while greater than 1.0 increases it. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultSaturation: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultSaturation", + "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + return this._defaultSaturation; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultSaturation", + "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.saturation instead." + ); + this._defaultSaturation = value; + }, + }, + + /** + * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {Number|undefined} + * @deprecated + */ + defaultGamma: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultGamma", + "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + return this._defaultGamma; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultGamma", + "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.gamma instead." + ); + this._defaultGamma = value; + }, + }, + + /** + * The default texture minification filter to apply to this provider. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {TextureMinificationFilter} + * @deprecated + */ + defaultMinificationFilter: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultMinificationFilter", + "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + return this._defaultMinificationFilter; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultMinificationFilter", + "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.minificationFilter instead." + ); + this._defaultMinificationFilter = value; + }, + }, + + /** + * The default texture magnification filter to apply to this provider. + * @memberof WebMapTileServiceImageryProvider.prototype + * @type {TextureMagnificationFilter} + * @deprecated + */ + defaultMagnificationFilter: { + get: function () { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultMagnificationFilter", + "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + return this._defaultMagnificationFilter; + }, + set: function (value) { + deprecationWarning( + "WebMapTileServiceImageryProvider.defaultMagnificationFilter", + "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ImageryLayer.magnificationFilter instead." + ); + this._defaultMagnificationFilter = value; + }, + }, }); /** diff --git a/packages/engine/Source/Scene/createWorldImagery.js b/packages/engine/Source/Scene/createWorldImagery.js index 227e3d47fb2..391bcd76f6a 100644 --- a/packages/engine/Source/Scene/createWorldImagery.js +++ b/packages/engine/Source/Scene/createWorldImagery.js @@ -11,17 +11,18 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * @param {Object} [options] Object with the following properties: * @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported. * @returns {IonImageryProvider} + * @deprecated * * @see Ion * * @example - * // Create Cesium World Terrain with default settings + * // Create Cesium World Imagery with default settings * const viewer = new Cesium.Viewer('cesiumContainer', { * imageryProvider : Cesium.createWorldImagery(); * }); * * @example - * // Create Cesium World Terrain with water and normals. + * // Create Cesium World Imagery with a different style * const viewer = new Cesium.Viewer('cesiumContainer', { * imageryProvider : Cesium.createWorldImagery({ * style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS diff --git a/packages/engine/Source/Scene/createWorldImageryAsync.js b/packages/engine/Source/Scene/createWorldImageryAsync.js index edcb82e8d89..24151b0a8df 100644 --- a/packages/engine/Source/Scene/createWorldImageryAsync.js +++ b/packages/engine/Source/Scene/createWorldImageryAsync.js @@ -14,19 +14,22 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; * @see Ion * * @example - * // Create Cesium World Terrain with default settings - * const viewer = new Cesium.Viewer("cesiumContainer", { - * imageryProvider: await Cesium.createWorldImageryAsync(); - * }); + * // Create a Cesium World Imagery base layer with default settings + * try { + * const imageryProvider = await Cesium.createWorldImageryAsync(); + * } catch (error) { + * console.log(`There was an error creating world imagery: ${error}`); + * } * * @example - * // Create Cesium World Terrain with water and normals. - * const viewer = new Cesium.Viewer("cesiumContainer", { - * imageryProvider: await Cesium.createWorldImageryAsync({ + * // Create Cesium World Imagery with different style + * try { + * const imageryProvider = await Cesium.createWorldImageryAsync({ * style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS - * }) - * }); - * + * }); + * } catch (error) { + * console.log(`There was an error creating world imagery: ${error}`); + * } */ function createWorldImageryAsync(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 8565cbfaa26..ad48d5e50e7 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -1,9 +1,9 @@ import buildModuleUrl from "../Core/buildModuleUrl.js"; -import createWorldImagery from "../Scene/createWorldImagery.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Clock from "../Core/Clock.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import Ellipsoid from "../Core/Ellipsoid.js"; @@ -11,6 +11,7 @@ import FeatureDetection from "../Core/FeatureDetection.js"; import formatError from "../Core/formatError.js"; import getElement from "../DataSources/getElement.js"; import Globe from "../Scene/Globe.js"; +import ImageryLayer from "../Scene/ImageryLayer.js"; import Moon from "../Scene/Moon.js"; import Scene from "../Scene/Scene.js"; import SceneMode from "../Scene/SceneMode.js"; @@ -123,7 +124,8 @@ function configureCameraFrustum(widget) { * @param {Element|String} container The DOM element or ID that will contain the widget. * @param {Object} [options] Object with the following properties: * @param {Clock} [options.clock=new Clock()] The clock to use to control current time. - * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to <code>false</code>, no imagery provider will be added. + * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to <code>false</code>, no imagery provider will be added. Deprecated. + * @param {ImageryLayer|false} [baseLayer=ImageryLayer.fromWorldImagery()] The bottommost imagery layer applied to the globe. If set to <code>false</code>, no imagery provider will be added. * @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. * @param {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. * @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. @@ -161,9 +163,8 @@ function configureCameraFrustum(widget) { * const widget = new Cesium.CesiumWidget("cesiumContainer"); * * // Widget with ion imagery and Cesium World Terrain. - * try { - * const widget2 = new Cesium.CesiumWidget("cesiumContainer", { - * imageryProvider: Cesium.createWorldImagery(), + * const widget2 = new Cesium.CesiumWidget("cesiumContainer", { + * baseLayer: Cesium.ImageryLayer.fromWorldTerrain(), * terrain: Cesium.Terrain.fromWorldTerrain() * skyBox: new Cesium.SkyBox({ * sources: { @@ -178,10 +179,7 @@ function configureCameraFrustum(widget) { * // Show Columbus View map with Web Mercator projection * sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, * mapProjection: new Cesium.WebMercatorProjection() - * }); - * } catch (error) { - * console.log(error); - * } + * }); */ function CesiumWidget(container, options) { //>>includeStart('debug', pragmas.debug); @@ -345,18 +343,31 @@ function CesiumWidget(container, options) { scene.skyAtmosphere = skyAtmosphere; } - //Set the base imagery layer - let imageryProvider = - options.globe === false ? false : options.imageryProvider; - if (!defined(imageryProvider)) { - imageryProvider = createWorldImagery(); + if (defined(options.imageryProvider)) { + deprecationWarning( + "CesiumWidget options.imageryProvider", + "options.imageryProvider was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use options.baseLayer instead." + ); } - if (imageryProvider !== false) { - scene.imageryLayers.addImageryProvider(imageryProvider); + // Set the base imagery layer + let baseLayer = options.baseLayer; + if ( + options.globe !== false && + baseLayer !== false && + options.imageryProvider !== false + ) { + if (defined(options.imageryProvider) && !defined(baseLayer)) { + baseLayer = new ImageryLayer(options.imageryProvider); + } + + if (!defined(baseLayer)) { + baseLayer = ImageryLayer.fromWorldImagery(); + } + scene.imageryLayers.add(baseLayer); } - //Set the terrain provider if one is provided. + // Set the terrain provider if one is provided. if (defined(options.terrainProvider) && options.globe !== false) { scene.terrainProvider = options.terrainProvider; } diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index 9d9315b7b9a..4a5d05677ba 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -373,7 +373,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); expect(provider).toBeInstanceOf(BingMapsImageryProvider); @@ -387,10 +388,12 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); - const provider2 = await BingMapsImageryProvider.fromUrl(url, "", { + const provider2 = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); @@ -400,7 +403,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, BingMapsStyle.AERIAL); installFakeImageRequest(); - const provider3 = await BingMapsImageryProvider.fromUrl(url, "", { + const provider3 = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: BingMapsStyle.AERIAL, }); @@ -415,7 +419,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); expect(provider).toBeInstanceOf(BingMapsImageryProvider); @@ -429,7 +434,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); expect(provider).toBeInstanceOf(BingMapsImageryProvider); @@ -447,7 +453,8 @@ describe("Scene/BingMapsImageryProvider", function () { url: url, }); - const provider = await BingMapsImageryProvider.fromUrl(resource, "", { + const provider = await BingMapsImageryProvider.fromUrl(resource, { + key: "", mapStyle: mapStyle, }); expect(provider).toBeInstanceOf(BingMapsImageryProvider); @@ -458,7 +465,9 @@ describe("Scene/BingMapsImageryProvider", function () { const url = "http://fake.fake.invalid"; await expectAsync( - BingMapsImageryProvider.fromUrl(url, "") + BingMapsImageryProvider.fromUrl(url, { + key: "", + }) ).toBeRejectedWithError( RuntimeError, new RegExp("An error occurred while accessing") @@ -497,7 +506,9 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeImageRequest(); await expectAsync( - BingMapsImageryProvider.fromUrl(url, "") + BingMapsImageryProvider.fromUrl(url, { + key: "", + }) ).toBeRejectedWithError( RuntimeError, new RegExp("metadata does not specify one resource in resourceSets") @@ -511,7 +522,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); @@ -525,7 +537,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "fake Key", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "fake Key", mapStyle: mapStyle, }); @@ -564,7 +577,8 @@ describe("Scene/BingMapsImageryProvider", function () { const culture = "ja-jp"; - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, culture: culture, }); @@ -590,7 +604,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); installFakeImageRequest(); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); @@ -683,7 +698,8 @@ describe("Scene/BingMapsImageryProvider", function () { installFakeMetadataRequest(url, mapStyle); - const provider = await BingMapsImageryProvider.fromUrl(url, "", { + const provider = await BingMapsImageryProvider.fromUrl(url, { + key: "", mapStyle: mapStyle, }); diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js index efae36d6ac9..59f9d48598b 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPicker.js @@ -44,46 +44,46 @@ import BaseLayerPickerViewModel from "./BaseLayerPickerViewModel.js"; * //This example uses 3, OpenStreetMap, The Black Marble, and a single, non-streaming world image. * const imageryViewModels = []; * imageryViewModels.push(new Cesium.ProviderViewModel({ - * name : 'Open\u00adStreet\u00adMap', - * iconUrl : Cesium.buildModuleUrl('Widgets/Images/ImageryProviders/openStreetMap.png'), - * tooltip : 'OpenStreetMap (OSM) is a collaborative project to create a free editable \ - * map of the world.\nhttp://www.openstreetmap.org', - * creationFunction : function() { + * name: "Open\u00adStreet\u00adMap", + * iconUrl: Cesium.buildModuleUrl("Widgets/Images/ImageryProviders/openStreetMap.png"), + * tooltip: "OpenStreetMap (OSM) is a collaborative project to create a free editable \ + * map of the world.\nhttp://www.openstreetmap.org", + * creationFunction: function() { * return new Cesium.OpenStreetMapImageryProvider({ - * url : 'https://a.tile.openstreetmap.org/' + * url: "https://a.tile.openstreetmap.org/" * }); * } * })); * * imageryViewModels.push(new Cesium.ProviderViewModel({ - * name : 'Earth at Night', - * iconUrl : Cesium.buildModuleUrl('Widgets/Images/ImageryProviders/blackMarble.png'), - * tooltip : 'The lights of cities and villages trace the outlines of civilization \ - * in this global view of the Earth at night as seen by NASA/NOAA\'s Suomi NPP satellite.', - * creationFunction : function() { - * return new Cesium.IonImageryProvider({ assetId: 3812 }); + * name: "Earth at Night", + * iconUrl: Cesium.buildModuleUrl("Widgets/Images/ImageryProviders/blackMarble.png"), + * tooltip: "The lights of cities and villages trace the outlines of civilization \ + * in this global view of the Earth at night as seen by NASA/NOAA's Suomi NPP satellite.", + * creationFunction: function() { + * return Cesium.IonImageryProvider.fromAssetId(3812); * } * })); * * imageryViewModels.push(new Cesium.ProviderViewModel({ - * name : 'Natural Earth\u00a0II', - * iconUrl : Cesium.buildModuleUrl('Widgets/Images/ImageryProviders/naturalEarthII.png'), - * tooltip : 'Natural Earth II, darkened for contrast.\nhttp://www.naturalearthdata.com/', - * creationFunction : function() { - * return new Cesium.TileMapServiceImageryProvider({ - * url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII') - * }); + * name: "Natural Earth\u00a0II", + * iconUrl: Cesium.buildModuleUrl("Widgets/Images/ImageryProviders/naturalEarthII.png"), + * tooltip: "Natural Earth II, darkened for contrast.\nhttp://www.naturalearthdata.com/", + * creationFunction: function() { + * return Cesium.TileMapServiceImageryProvider.fromUrl( + * Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII") + * ); * } * })); * * //Create a CesiumWidget without imagery, if you haven't already done so. - * const cesiumWidget = new Cesium.CesiumWidget('cesiumContainer', { imageryProvider: false }); + * const cesiumWidget = new Cesium.CesiumWidget("cesiumContainer", { baseLayer: false }); * * //Finally, create the baseLayerPicker widget using our view models. * const layers = cesiumWidget.imageryLayers; - * const baseLayerPicker = new Cesium.BaseLayerPicker('baseLayerPickerContainer', { - * globe : cesiumWidget.scene.globe, - * imageryProviderViewModels : imageryViewModels + * const baseLayerPicker = new Cesium.BaseLayerPicker("baseLayerPickerContainer", { + * globe: cesiumWidget.scene.globe, + * imageryProviderViewModels: imageryViewModels * }); * * @see TerrainProvider diff --git a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js index c7f03bc541a..5f43c134251 100644 --- a/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js +++ b/packages/widgets/Source/BaseLayerPicker/BaseLayerPickerViewModel.js @@ -3,6 +3,7 @@ import { defined, DeveloperError, EllipsoidTerrainProvider, + ImageryLayer, Terrain, } from "@cesium/engine"; import knockout from "../ThirdParty/knockout.js"; @@ -177,7 +178,7 @@ function BaseLayerPickerViewModel(options) { this.selectedImagery = undefined; const selectedImageryViewModel = knockout.observable(); - this._currentImageryProviders = []; + this._currentImageryLayers = []; knockout.defineProperty(this, "selectedImagery", { get: function () { return selectedImageryViewModel(); @@ -189,15 +190,15 @@ function BaseLayerPickerViewModel(options) { } let i; - const currentImageryProviders = this._currentImageryProviders; - const currentImageryProvidersLength = currentImageryProviders.length; + const currentImageryLayers = this._currentImageryLayers; + const currentImageryLayersLength = currentImageryLayers.length; const imageryLayers = this._globe.imageryLayers; let hadExistingBaseLayer = false; - for (i = 0; i < currentImageryProvidersLength; i++) { + for (i = 0; i < currentImageryLayersLength; i++) { const layersLength = imageryLayers.length; for (let x = 0; x < layersLength; x++) { const layer = imageryLayers.get(x); - if (layer.imageryProvider === currentImageryProviders[i]) { + if (layer === currentImageryLayers[i]) { imageryLayers.remove(layer); hadExistingBaseLayer = true; break; @@ -209,21 +210,26 @@ function BaseLayerPickerViewModel(options) { const newProviders = value.creationCommand(); if (Array.isArray(newProviders)) { const newProvidersLength = newProviders.length; + this._currentImageryLayers = []; for (i = newProvidersLength - 1; i >= 0; i--) { - imageryLayers.addImageryProvider(newProviders[i], 0); + const layer = ImageryLayer.fromProviderAsync(newProviders[i]); + imageryLayers.add(layer, 0); + this._currentImageryLayers.push(layer); } - this._currentImageryProviders = newProviders.slice(0); } else { - this._currentImageryProviders = [newProviders]; + this._currentImageryLayers = []; + const layer = ImageryLayer.fromProviderAsync(newProviders); + layer.name = value.name; if (hadExistingBaseLayer) { - imageryLayers.addImageryProvider(newProviders, 0); + imageryLayers.add(layer, 0); } else { const baseLayer = imageryLayers.get(0); if (defined(baseLayer)) { imageryLayers.remove(baseLayer); } - imageryLayers.addImageryProvider(newProviders, 0); + imageryLayers.add(layer, 0); } + this._currentImageryLayers.push(layer); } } selectedImageryViewModel(value); diff --git a/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js b/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js index 9b2cfb24658..05702413171 100644 --- a/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js +++ b/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js @@ -1,7 +1,7 @@ import { ArcGisMapServerImageryProvider, buildModuleUrl, - createWorldImagery, + createWorldImageryAsync, IonImageryProvider, IonWorldImageryStyle, OpenStreetMapImageryProvider, @@ -21,7 +21,7 @@ function createDefaultImageryProviderViewModels() { tooltip: "Bing Maps aerial imagery, provided by Cesium ion", category: "Cesium ion", creationFunction: function () { - return createWorldImagery({ + return createWorldImageryAsync({ style: IonWorldImageryStyle.AERIAL, }); }, @@ -37,7 +37,7 @@ function createDefaultImageryProviderViewModels() { tooltip: "Bing Maps aerial imagery with labels, provided by Cesium ion", category: "Cesium ion", creationFunction: function () { - return createWorldImagery({ + return createWorldImageryAsync({ style: IonWorldImageryStyle.AERIAL_WITH_LABELS, }); }, @@ -51,7 +51,7 @@ function createDefaultImageryProviderViewModels() { tooltip: "Bing Maps standard road maps, provided by Cesium ion", category: "Cesium ion", creationFunction: function () { - return createWorldImagery({ + return createWorldImageryAsync({ style: IonWorldImageryStyle.ROAD, }); }, @@ -75,11 +75,12 @@ i-cubed Nationwide Prime, Getmapping, AeroGRID, IGN Spain, and IGP Portugal. Ad contributed by the GIS User Community.\nhttp://www.esri.com", category: "Other", creationFunction: function () { - return new ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", - enablePickFeatures: false, - }); + return ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", + { + enablePickFeatures: false, + } + ); }, }) ); @@ -98,11 +99,12 @@ Chile, Colombia, and Venezuela; Ghana; and parts of southern Africa including Bo http://www.esri.com", category: "Other", creationFunction: function () { - return new ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", - enablePickFeatures: false, - }); + return ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", + { + enablePickFeatures: false, + } + ); }, }) ); @@ -120,11 +122,12 @@ for informational and educational purposes as well as a basemap by GIS professio mapping applications.\nhttp://www.esri.com", category: "Other", creationFunction: function () { - return new ArcGisMapServerImageryProvider({ - url: - "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/", - enablePickFeatures: false, - }); + return ArcGisMapServerImageryProvider.fromUrl( + "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/", + { + enablePickFeatures: false, + } + ); }, }) ); @@ -193,7 +196,7 @@ area washes and organic edges over a paper texture to add warm pop to any map.\n "Sentinel-2 cloudless by EOX IT Services GmbH (Contains modified Copernicus Sentinel data 2016 and 2017).", category: "Cesium ion", creationFunction: function () { - return new IonImageryProvider({ assetId: 3954 }); + return IonImageryProvider.fromAssetId(3954); }, }) ); @@ -205,7 +208,7 @@ area washes and organic edges over a paper texture to add warm pop to any map.\n tooltip: "Blue Marble Next Generation July, 2004 imagery from NASA.", category: "Cesium ion", creationFunction: function () { - return new IonImageryProvider({ assetId: 3845 }); + return IonImageryProvider.fromAssetId(3845); }, }) ); @@ -220,7 +223,7 @@ area washes and organic edges over a paper texture to add warm pop to any map.\n "The Earth at night, also known as The Black Marble, is a 500 meter resolution global composite imagery layer released by NASA.", category: "Cesium ion", creationFunction: function () { - return new IonImageryProvider({ assetId: 3812 }); + return IonImageryProvider.fromAssetId(3812); }, }) ); @@ -235,9 +238,9 @@ area washes and organic edges over a paper texture to add warm pop to any map.\n "Natural Earth II, darkened for contrast.\nhttp://www.naturalearthdata.com/", category: "Cesium ion", creationFunction: function () { - return new TileMapServiceImageryProvider({ - url: buildModuleUrl("Assets/Textures/NaturalEarthII"), - }); + return TileMapServiceImageryProvider.fromUrl( + buildModuleUrl("Assets/Textures/NaturalEarthII") + ); }, }) ); diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index d5a902be89f..a4dfa1ca255 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -13,6 +13,7 @@ import { DataSourceDisplay, defaultValue, defined, + deprecationWarning, destroyObject, DeveloperError, Entity, @@ -313,9 +314,10 @@ function enableVRUI(viewer, enabled) { * @property {ProviderViewModel[]} [imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel} [selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. - * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. + * @property {ImageryProvider|false} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. Deprecated. + * @property {ImageryLayer|false} [baseLayer=ImageryLayer.fromWorldImagery()] The bottommost imagery layer applied to the globe. If set to <code>false</code>, no imagery provider will be added. This value is only valid if `baseLayerPicker` is set to false. * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use - * @param {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. + * @property {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. @@ -355,7 +357,7 @@ function enableVRUI(viewer, enabled) { * @param {Viewer.ConstructorOptions} [options] Object describing initialization options * * @exception {DeveloperError} Element with id "container" does not exist in the document. - * @exception {DeveloperError} options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.imageryProvider instead. + * @exception {DeveloperError} options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.baseLayer instead. * @exception {DeveloperError} options.selectedTerrainProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.terrainProvider instead. * * @see Animation @@ -380,9 +382,9 @@ function enableVRUI(viewer, enabled) { * // Hide the base layer picker * baseLayerPicker: false, * // Use OpenStreetMaps - * imageryProvider: new Cesium.OpenStreetMapImageryProvider({ + * baseLayer: new Cesium.ImageryLayer(OpenStreetMapImageryProvider({ * url: "https://a.tile.openstreetmap.org/" - * }), + * })), * skyBox: new Cesium.SkyBox({ * sources: { * positiveX: "stars/TychoSkymapII.t3_08192x04096_80_px.jpg", @@ -431,7 +433,7 @@ function Viewer(container, options) { ) { throw new DeveloperError( "options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget. \ -Either specify options.imageryProvider instead or set options.baseLayerPicker to true." +Either specify options.baseLayer instead or set options.baseLayerPicker to true." ); } @@ -484,8 +486,10 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to // Cesium widget const cesiumWidget = new CesiumWidget(cesiumWidgetContainer, { - imageryProvider: - createBaseLayerPicker || defined(options.imageryProvider) + baseLayer: + createBaseLayerPicker || + defined(options.baseLayer) || + defined(options.imageryProvider) ? false : undefined, clock: clock, @@ -678,12 +682,26 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to // These need to be set after the BaseLayerPicker is created in order to take effect if (defined(options.imageryProvider) && options.imageryProvider !== false) { + deprecationWarning( + "Viewer options.imageryProvider", + "options.imageryProvider was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use options.baseLayer instead." + ); + if (createBaseLayerPicker) { baseLayerPicker.viewModel.selectedImagery = undefined; } scene.imageryLayers.removeAll(); scene.imageryLayers.addImageryProvider(options.imageryProvider); } + + if (defined(options.baseLayer) && options.baseLayer !== false) { + if (createBaseLayerPicker) { + baseLayerPicker.viewModel.selectedImagery = undefined; + } + scene.imageryLayers.removeAll(); + scene.imageryLayers.add(options.baseLayer); + } + if (defined(options.terrainProvider)) { if (createBaseLayerPicker) { baseLayerPicker.viewModel.selectedTerrain = undefined; diff --git a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js index eca8540e775..2c02225b836 100644 --- a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js +++ b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js @@ -5,6 +5,7 @@ import { } from "@cesium/engine"; import { BaseLayerPickerViewModel, ProviderViewModel } from "../../index.js"; +import pollToPromise from "../../../../Specs/pollToPromise.js"; describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { function MockGlobe() { @@ -206,7 +207,7 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { expect(viewModel.buttonImageUrl).toEqual(testProviderViewModel.iconUrl); }); - it("selectedImagery actually sets base layer", function () { + it("selectedImagery actually sets base layer", async function () { const imageryViewModels = [testProviderViewModel]; const globe = new MockGlobe(); const imageryLayers = globe.imageryLayers; @@ -219,11 +220,14 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { viewModel.selectedImagery = testProviderViewModel; expect(imageryLayers.length).toEqual(1); + await pollToPromise(() => imageryLayers.get(0).ready); expect(imageryLayers.get(0).imageryProvider).toBe(testProvider); viewModel.selectedImagery = testProviderViewModel2; expect(imageryLayers.length).toEqual(2); + await pollToPromise(() => imageryLayers.get(0).ready); expect(imageryLayers.get(0).imageryProvider).toBe(testProvider); + await pollToPromise(() => imageryLayers.get(1).ready); expect(imageryLayers.get(1).imageryProvider).toBe(testProvider2); }); @@ -276,7 +280,7 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { expect(globe.terrainProvider).not.toBe(testProvider); }); - it("settings selectedImagery only removes layers added by view model", function () { + it("settings selectedImagery only removes layers added by view model", async function () { const imageryViewModels = [testProviderViewModel]; const globe = new MockGlobe(); const imageryLayers = globe.imageryLayers; @@ -289,7 +293,9 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { viewModel.selectedImagery = testProviderViewModel2; expect(imageryLayers.length).toEqual(2); + await pollToPromise(() => imageryLayers.get(0).ready); expect(imageryLayers.get(0).imageryProvider).toBe(testProvider); + await pollToPromise(() => imageryLayers.get(1).ready); expect(imageryLayers.get(1).imageryProvider).toBe(testProvider2); imageryLayers.addImageryProvider(testProvider3, 1); @@ -298,6 +304,7 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { viewModel.selectedImagery = undefined; expect(imageryLayers.length).toEqual(1); + await pollToPromise(() => imageryLayers.get(0).ready); expect(imageryLayers.get(0).imageryProvider).toBe(testProvider3); }); From 08f3886903c8ebb31e97da5ae3911ddbba0aee65 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Sat, 18 Feb 2023 16:59:31 +0800 Subject: [PATCH 482/679] Fix some type typo and remove unrelate code --- packages/engine/Source/Scene/ModelComponents.js | 4 ++-- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/engine/Source/Scene/ModelComponents.js b/packages/engine/Source/Scene/ModelComponents.js index 97cc61ae684..4cbb1e2fec1 100644 --- a/packages/engine/Source/Scene/ModelComponents.js +++ b/packages/engine/Source/Scene/ModelComponents.js @@ -589,7 +589,7 @@ function Primitive() { * The feature IDs associated with this primitive. Feature ID types may * be interleaved * - * @type {Array<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRangeModelComponents.FeatureIdTexture>} + * @type {Array<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange|ModelComponents.FeatureIdTexture>} * @private */ this.featureIds = []; @@ -643,7 +643,7 @@ function Instances() { * The feature ID attributes associated with this set of instances. * Feature ID attribute types may be interleaved. * - * @type {ModelComponents.FeatureIdAttribute[]|ModelComponents.FeatureIdImplicitRange[]} + * @type {Array<ModelComponents.FeatureIdAttribute|ModelComponents.FeatureIdImplicitRange>} * @private */ this.featureIds = []; diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 7a28da23ca7..c52a36eeade 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -593,8 +593,7 @@ function handleZoom( const sameStartPosition = Cartesian2.equals( startPosition, - object._zoomMouseStart, - Cartesian2.equals(startPosition, object._zoomMouseStart) + object._zoomMouseStart ); let zoomingOnVector = object._zoomingOnVector; let rotatingZoom = object._rotatingZoom; @@ -2163,7 +2162,6 @@ function zoom3D(controller, startPosition, movement) { if (defined(movement.distance)) { movement = movement.distance; } - const inertiaMovement = movement.inertiaEnabled; const ellipsoid = controller._ellipsoid; const scene = controller._scene; @@ -2189,7 +2187,7 @@ function zoom3D(controller, startPosition, movement) { camera.position, zoom3DCartographic ).height; - if (height < controller._minimumPickingTerrainHeight && !inertiaMovement) { + if (height < controller._minimumPickingTerrainHeight) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); } From 1e59130dcb0901c25fd2e07a16010bc0652f5dfe Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 20 Feb 2023 10:03:44 -0500 Subject: [PATCH 483/679] Update tests --- .../Source/Scene/ImageryLayerCollection.js | 4 +- .../Scene/BingMapsImageryProviderSpec.js | 2 +- .../engine/Specs/Scene/ImageryLayerSpec.js | 50 +++++++++++++++++++ .../engine/Specs/Widget/CesiumWidgetSpec.js | 21 ++++++++ packages/widgets/Specs/Viewer/ViewerSpec.js | 26 +++++++++- 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/ImageryLayerCollection.js b/packages/engine/Source/Scene/ImageryLayerCollection.js index e69370460a5..9f3b0674029 100644 --- a/packages/engine/Source/Scene/ImageryLayerCollection.js +++ b/packages/engine/Source/Scene/ImageryLayerCollection.js @@ -79,11 +79,11 @@ Object.defineProperties(ImageryLayerCollection.prototype, { * * @example * const imageryLayer = Cesium.ImageryLayer.fromWorldImagery(); - * scene.imageryLayers.addImageryProvider(imageryLayer); + * scene.imageryLayers.add(imageryLayer); * * @example * const imageryLayer = Cesium.ImageryLayer.fromProviderAsync(Cesium.IonImageryProvider.fromAssetId(3812)); - * scene.imageryLayers.addImageryProvider(imageryLayer); + * scene.imageryLayers.add(imageryLayer); */ ImageryLayerCollection.prototype.add = function (layer, index) { const hasIndex = defined(index); diff --git a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js index 4a5d05677ba..33e11c220be 100644 --- a/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/BingMapsImageryProviderSpec.js @@ -362,7 +362,7 @@ describe("Scene/BingMapsImageryProvider", function () { await expectAsync( BingMapsImageryProvider.fromUrl("http://fake.fake.invalid/") ).toBeRejectedWithDeveloperError( - "key is required, actual value was undefined" + "options.key is required, actual value was undefined" ); }); diff --git a/packages/engine/Specs/Scene/ImageryLayerSpec.js b/packages/engine/Specs/Scene/ImageryLayerSpec.js index 255b576440f..b76adc0ed4e 100644 --- a/packages/engine/Specs/Scene/ImageryLayerSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerSpec.js @@ -18,6 +18,7 @@ import { NeverTileDiscardPolicy, QuadtreeTile, SingleTileImageryProvider, + TileCoordinatesImageryProvider, UrlTemplateImageryProvider, WebMapServiceImageryProvider, } from "../../index.js"; @@ -64,6 +65,55 @@ describe( return this.shouldDiscard; }; + it("constructs with default options", function () { + const provider = new TileCoordinatesImageryProvider(); + const layer = new ImageryLayer(provider); + + expect(layer.imageryProvider).toBe(provider); + expect(layer.show).toBeTrue(); + expect(layer.errorEvent).toBeDefined(); + expect(layer.readyEvent).toBeDefined(); + expect(layer.ready).toBeTrue(); + }); + + it("fromProviderAsync throws without provider promise", function () { + expect(() => ImageryLayer.fromProviderAsync()).toThrowDeveloperError( + "expected" + ); + }); + + it("readyEvent is raised when asynchronous provider become ready", async function () { + const providerPromise = SingleTileImageryProvider.fromUrl( + "Data/Images/Red16x16.png" + ); + const layer = ImageryLayer.fromProviderAsync(providerPromise); + expect(layer.ready).toBe(false); + + const spyListener = jasmine.createSpy("listener"); + layer.readyEvent.addEventListener(spyListener); + + await providerPromise; + + expect(spyListener).toHaveBeenCalled(); + expect(layer.ready).toBeTrue(); + expect(layer.imageryProvider).toBeInstanceOf(SingleTileImageryProvider); + }); + + it("errorEvent is raised when asynchronous provider cannot be constructed", async function () { + const providerPromise = Promise.reject(); + const layer = ImageryLayer.fromProviderAsync(providerPromise); + expect(layer.ready).toBe(false); + + const spyListener = jasmine.createSpy("listener"); + layer.errorEvent.addEventListener(spyListener); + + await expectAsync(providerPromise).toBeRejected(); + + expect(spyListener).toHaveBeenCalled(); + expect(layer.ready).toBeFalse(); + expect(layer.imageryProvider).toBeUndefined(); + }); + it("discards tiles when the ImageryProviders discard policy says to do so", function () { Resource._Implementations.createImage = function ( request, diff --git a/packages/engine/Specs/Widget/CesiumWidgetSpec.js b/packages/engine/Specs/Widget/CesiumWidgetSpec.js index 142632e734d..3982b31914a 100644 --- a/packages/engine/Specs/Widget/CesiumWidgetSpec.js +++ b/packages/engine/Specs/Widget/CesiumWidgetSpec.js @@ -6,6 +6,7 @@ import { ScreenSpaceEventHandler, WebMercatorProjection, Camera, + ImageryLayer, ImageryLayerCollection, Scene, SceneMode, @@ -145,6 +146,26 @@ describe( expect(imageryLayers.length).toEqual(0); }); + it("sets expected options baseLayer", function () { + const provider = new TileCoordinatesImageryProvider(); + const options = { + baseLayer: new ImageryLayer(provider), + }; + widget = createCesiumWidget(container, options); + const imageryLayers = widget.scene.imageryLayers; + expect(imageryLayers.length).toEqual(1); + expect(imageryLayers.get(0).imageryProvider).toBe(provider); + }); + + it("does not create imagery if baseLayer option is false", function () { + const options = { + baseLayer: false, + }; + widget = createCesiumWidget(container, options); + const imageryLayers = widget.scene.imageryLayers; + expect(imageryLayers.length).toEqual(0); + }); + it("sets expected options terrainProvider", function () { const options = { terrainProvider: new EllipsoidTerrainProvider(), diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index e5964bcb42e..b626261028e 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -24,6 +24,7 @@ import { Camera, CameraFlightPath, Cesium3DTileset, + ImageryLayer, ImageryLayerCollection, Cesium3DTilesVoxelProvider, SceneMode, @@ -519,10 +520,11 @@ describe( expect(viewer.scene.mapProjection).toEqual(mapProjection); }); - it("can set selectedImageryProviderViewModel", function () { + it("can set selectedImageryProviderViewModel", async function () { viewer = createViewer(container, { selectedImageryProviderViewModel: testProviderViewModel, }); + await pollToPromise(() => viewer.scene.imageryLayers.get(0).ready); expect(viewer.scene.imageryLayers.length).toEqual(1); expect(viewer.scene.imageryLayers.get(0).imageryProvider).toBe( testProvider @@ -543,12 +545,13 @@ describe( ); }); - it("can set imageryProviderViewModels", function () { + it("can set imageryProviderViewModels", async function () { const models = [testProviderViewModel]; viewer = createViewer(container, { imageryProviderViewModels: models, }); + await pollToPromise(() => viewer.scene.imageryLayers.get(0).ready); expect(viewer.scene.imageryLayers.length).toEqual(1); expect(viewer.scene.imageryLayers.get(0).imageryProvider).toBe( testProvider @@ -564,6 +567,25 @@ describe( ).toEqual(models[0]); }); + it("can set baseLayer when BaseLayerPicker is disabled", function () { + viewer = createViewer(container, { + baseLayerPicker: false, + baseLayer: new ImageryLayer(testProvider), + }); + expect(viewer.scene.imageryLayers.length).toEqual(1); + expect(viewer.scene.imageryLayers.get(0).imageryProvider).toBe( + testProvider + ); + }); + + it("can set baseLayer to false when BaseLayerPicker is disabled", function () { + viewer = createViewer(container, { + baseLayerPicker: false, + baseLayer: false, + }); + expect(viewer.scene.imageryLayers.length).toEqual(0); + }); + it("can disable render loop", function () { viewer = createViewer(container, { useDefaultRenderLoop: false, From 9bcfa35eac055bd5ed85df1343baca79d784e5df Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 20 Feb 2023 20:16:30 -0500 Subject: [PATCH 484/679] Use multiplicative shift for voxel ray steps --- .../engine/Source/Shaders/Voxels/IntersectionUtils.glsl | 3 ++- packages/engine/Source/Shaders/Voxels/VoxelFS.glsl | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl index 66ae307dce1..c10465ec0bf 100644 --- a/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl +++ b/packages/engine/Source/Shaders/Voxels/IntersectionUtils.glsl @@ -4,7 +4,8 @@ #define NO_HIT (-czm_infinity) #define INF_HIT (czm_infinity * 0.5) -#define RAY_SHIFT (czm_epsilon4) +#define RAY_SHIFT (0.000003163) +#define RAY_SCALE (1.003163) struct Ray { vec3 pos; diff --git a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl index 10c172dbfd9..5a7b82e7f96 100644 --- a/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl +++ b/packages/engine/Source/Shaders/Voxels/VoxelFS.glsl @@ -34,7 +34,8 @@ vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersecti RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox); vec4 entry = shapeIntersection.entry.w >= voxelIntersection.entry.w ? shapeIntersection.entry : voxelIntersection.entry; float exit = min(voxelIntersection.exit.w, shapeIntersection.exit.w); - return vec4(normalize(entry.xyz), exit - entry.w); + float dt = (exit - entry.w) * RAY_SCALE; + return vec4(normalize(entry.xyz), dt); #else float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w)); return vec4(viewRay.dir, u_stepSize / dimAtLevel); @@ -64,7 +65,7 @@ void main() discard; } - float currT = shapeIntersection.entry.w + RAY_SHIFT; + float currT = shapeIntersection.entry.w * RAY_SCALE; float endT = shapeIntersection.exit.w; vec3 positionUv = viewPosUv + currT * viewDirUv; vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv); @@ -140,7 +141,7 @@ void main() break; } else { // Found another intersection. Resume raymarching there - currT = shapeIntersection.entry.w; + currT = shapeIntersection.entry.w * RAY_SCALE; endT = shapeIntersection.exit.w; positionUv = viewPosUv + currT * viewDirUv; } From 3f262e2f6f1d8735ec79904d639516d6756ecb40 Mon Sep 17 00:00:00 2001 From: jiangheng <“jiangheng@geoway.com.cn”> Date: Tue, 21 Feb 2023 09:40:32 +0800 Subject: [PATCH 485/679] fix inertia jumpy when inertia approaching ground --- .../engine/Source/Scene/ScreenSpaceCameraController.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 8d982335447..4b81c9ac290 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2188,7 +2188,13 @@ function zoom3D(controller, startPosition, movement) { camera.position, zoom3DCartographic ).height; - if (height < controller._minimumPickingTerrainHeight && !inertiaMovement) { + + const inertiaMovementApproachingGround = height < 5; + + if ( + height < controller._minimumPickingTerrainHeight || + (inertiaMovement && height < inertiaMovementApproachingGround) + ) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); } From bc1de11e9edafe98cdaf50a9346c22f6b50dbbfa Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Tue, 21 Feb 2023 11:10:02 +0800 Subject: [PATCH 486/679] fix pickGlobe condition --- .../engine/Source/Scene/ScreenSpaceCameraController.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 4b81c9ac290..38e767dd16d 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2189,12 +2189,12 @@ function zoom3D(controller, startPosition, movement) { zoom3DCartographic ).height; - const inertiaMovementApproachingGround = height < 5; + const inertiaMovementApproachingGround = Math.abs(height) < 50; - if ( - height < controller._minimumPickingTerrainHeight || - (inertiaMovement && height < inertiaMovementApproachingGround) - ) { + const needPickGlobe = inertiaMovement + ? inertiaMovementApproachingGround + : height < controller._minimumPickingTerrainHeight; + if (needPickGlobe) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); } From 68056794a463f1d04e7b461cd1c1853c38f64339 Mon Sep 17 00:00:00 2001 From: onsummer <onsummer@foxmail.com> Date: Tue, 21 Feb 2023 15:21:20 +0800 Subject: [PATCH 487/679] Upgrade rollup plugin dependency --- build.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.js b/build.js index b91e0cb4808..ec891d85710 100644 --- a/build.js +++ b/build.js @@ -13,7 +13,7 @@ import gulp from "gulp"; import rimraf from "rimraf"; import { rollup } from "rollup"; import rollupPluginStripPragma from "rollup-plugin-strip-pragma"; -import { terser } from "rollup-plugin-terser"; +import terser from "@rollup/plugin-terser"; import rollupCommonjs from "@rollup/plugin-commonjs"; import rollupResolve from "@rollup/plugin-node-resolve"; import streamToPromise from "stream-to-promise"; diff --git a/package.json b/package.json index ecf93bcc4bf..23c04092952 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^23.0.5", "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-terser": "^0.4.0", "aws-sdk": "^2.1276.0", "chokidar": "^3.5.3", "cloc": "^2.8.0", @@ -110,7 +111,6 @@ "rimraf": "^4.1.2", "rollup": "^2.79.1", "rollup-plugin-strip-pragma": "^1.0.0", - "rollup-plugin-terser": "^7.0.2", "stream-to-promise": "^3.0.0", "tsd-jsdoc": "^2.5.0", "typescript": "^4.9.4", From 5e4e316226f355519d9feba96717ac03eb072f03 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Feb 2023 10:11:07 -0500 Subject: [PATCH 488/679] Update esbuild --- build.js | 72 ++++++++++++++++++++++++++++++++-------------------- gulpfile.js | 29 +++++++++++++-------- package.json | 4 +-- server.js | 65 ++++++++++++++++++----------------------------- 4 files changed, 90 insertions(+), 80 deletions(-) diff --git a/build.js b/build.js index f14aed2b94b..a864220f430 100644 --- a/build.js +++ b/build.js @@ -170,7 +170,6 @@ export async function bundleCesiumJs(options) { buildConfig.sourcemap = options.sourcemap; buildConfig.external = ["https", "http", "url", "zlib"]; buildConfig.plugins = options.removePragmas ? [stripPragmaPlugin] : undefined; - buildConfig.incremental = options.incremental; buildConfig.write = options.write; buildConfig.banner = { js: combinedCopyrightHeader, @@ -178,35 +177,44 @@ export async function bundleCesiumJs(options) { // print errors immediately, and collect warnings so we can filter out known ones buildConfig.logLevel = "info"; - const bundles = {}; + const contexts = {}; + const incremental = options.incremental; + let build = esbuild.build; + if (incremental) { + build = esbuild.context; + } // Build ESM - const esmBundle = await esbuild.build({ + const esm = await build({ ...buildConfig, format: "esm", outfile: path.join(options.path, "index.js"), }); - handleBuildWarnings(esmBundle); - - bundles.esmBundle = esmBundle; + if (incremental) { + contexts.esm = esm; + } else { + handleBuildWarnings(esm); + } // Build IIFE if (options.iife) { - const iifeBundle = await esbuild.build({ + const iife = await build({ ...buildConfig, format: "iife", globalName: "Cesium", outfile: path.join(options.path, "Cesium.js"), }); - handleBuildWarnings(iifeBundle); - - bundles.iifeBundle = iifeBundle; + if (incremental) { + contexts.iife = iife; + } else { + handleBuildWarnings(iife); + } } if (options.node) { - const nodeBundle = await esbuild.build({ + const node = await build({ ...buildConfig, format: "cjs", platform: "node", @@ -217,11 +225,14 @@ export async function bundleCesiumJs(options) { outfile: path.join(options.path, "index.cjs"), }); - handleBuildWarnings(nodeBundle); - bundles.nodeBundle = nodeBundle; + if (incremental) { + contexts.node = node; + } else { + handleBuildWarnings(node); + } } - return bundles; + return contexts; } function filePathToModuleId(moduleId) { @@ -813,7 +824,12 @@ export async function createJsHintOptions() { export function bundleCombinedSpecs(options) { options = options || {}; - return esbuild.build({ + let build = esbuild.build; + if (options.incremental) { + build = esbuild.context; + } + + return build({ entryPoints: [ "Specs/spec-main.js", "Specs/SpecList.js", @@ -826,7 +842,6 @@ export function bundleCombinedSpecs(options) { outdir: path.join("Build", "Specs"), plugins: [externalResolvePlugin], external: [`http`, `https`, `url`, `zlib`], - incremental: options.incremental, write: options.write, }); } @@ -837,7 +852,7 @@ export function bundleCombinedSpecs(options) { * @param {String} workspace The workspace to create the index.js for. * @returns */ -async function createIndexJs(workspace) { +export async function createIndexJs(workspace) { let contents = ""; // Iterate over all provided source files for the workspace and export the assignment based on file name. @@ -942,7 +957,6 @@ async function bundleSpecs(options) { const buildOptions = { bundle: true, format: "esm", - incremental: incremental, outdir: options.outdir, sourcemap: true, external: ["https", "http", "zlib", "url"], @@ -950,14 +964,19 @@ async function bundleSpecs(options) { write: write, }; + let build = esbuild.build; + if (incremental) { + build = esbuild.context; + } + // When bundling specs for a workspace, the spec-main.js and karma-main.js // are bundled separately since they use a different outbase than the workspace's SpecList.js. - await esbuild.build({ + await build({ ...buildOptions, entryPoints: ["Specs/spec-main.js", "Specs/karma-main.js"], }); - return await esbuild.build({ + return build({ ...buildOptions, entryPoints: [options.specListFile], outbase: options.outbase, @@ -1011,8 +1030,6 @@ export const buildEngine = async (options) => { specListFile: specListFile, write: write, }); - - return; }; /** @@ -1026,7 +1043,6 @@ export const buildWidgets = async (options) => { options = options || {}; const incremental = options.incremental ?? false; - const write = options.write ?? true; // Generate Build folder to place build artifacts. @@ -1118,7 +1134,7 @@ export async function buildCesium(options) { }); // Generate bundles. - const bundles = await bundleCesiumJs({ + const contexts = await bundleCesiumJs({ minify: minify, iife: iife, incremental: incremental, @@ -1141,7 +1157,7 @@ export async function buildCesium(options) { ]); // Generate Specs bundle. - const specsBundle = await bundleCombinedSpecs({ + const specsContext = await bundleCombinedSpecs({ incremental: incremental, write: write, }); @@ -1184,7 +1200,9 @@ export async function buildCesium(options) { await writeFile("Source/Widgets/lighter.css", lighterCssContents); return { - ...bundles, - specsBundle: specsBundle, + esm: contexts.esm, + iife: contexts.iife, + node: contexts.node, + specs: specsContext, }; } diff --git a/gulpfile.js b/gulpfile.js index a31f29bfc60..e8bd2dc39ba 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -41,7 +41,6 @@ import { createJsHintOptions, defaultESBuildOptions, bundleCombinedWorkers, - bundleCombinedSpecs, } from "./build.js"; // Determines the scope of the workspace packages. If the scope is set to cesium, the workspaces should be @cesium/engine. @@ -463,12 +462,8 @@ export const websiteRelease = gulp.series( ); export const buildRelease = gulp.series( - function () { - return buildEngine(); - }, - function () { - return buildWidgets(); - }, + buildEngine, + buildWidgets, // Generate Build/CesiumUnminified function () { return buildCesium({ @@ -536,6 +531,14 @@ async function pruneScriptsForZip(packageJsonPath) { // Set server tasks to use production flag scripts["start"] = "node server.js --production"; scripts["start-public"] = "node server.js --public --production"; + scripts["start-public"] = "node server.js --public --production"; + scripts["test"] = "gulp test --production"; + scripts["test-all"] = "gulp test --all --production"; + scripts["test-webgl"] = "gulp test --include WebGL --production"; + scripts["test-non-webgl"] = "gulp test --exclude WebGL --production"; + scripts["test-webgl-validation"] = "gulp test --webglValidation --production"; + scripts["test-webgl-stub"] = "gulp test --webglStub --production"; + scripts["test-release"] = "gulp test --release --production"; // Write to a temporary package.json file. const noPreparePackageJson = join( @@ -1495,10 +1498,8 @@ export async function coverage() { }); } +// Cache contexts for successive calls to test export async function test() { - await createCombinedSpecList(); - await bundleCombinedSpecs(); - const enableAllBrowsers = argv.all ? true : false; const includeCategory = argv.include ? argv.include : ""; const excludeCategory = argv.exclude ? argv.exclude : ""; @@ -1511,12 +1512,20 @@ export async function test() { const debugCanvasWidth = argv.debugCanvasWidth; const debugCanvasHeight = argv.debugCanvasHeight; const includeName = argv.includeName ? argv.includeName : ""; + const isProduction = argv.production; let workspace = argv.workspace; if (workspace) { workspace = workspace.replaceAll(`@${scope}/`, ``); } + if (!isProduction) { + console.log("Building specs..."); + await buildCesium({ + iife: true, + }); + } + let browsers = ["Chrome"]; if (argv.browsers) { browsers = argv.browsers.split(","); diff --git a/package.json b/package.json index ecf93bcc4bf..1a0654966ad 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "decompress": "^4.2.1", "download": "^8.0.0", "draco3d": "^1.5.1", - "esbuild": "^0.16.7", + "esbuild": "^0.17.10", "eslint": "^8.29.0", "eslint-config-cesium": "^9.0.0", "eslint-config-prettier": "^8.3.0", @@ -166,4 +166,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} diff --git a/server.js b/server.js index 7da1be06afd..b6836ba9237 100644 --- a/server.js +++ b/server.js @@ -41,8 +41,7 @@ import { createJsHintOptions, createCombinedSpecList, glslToJavaScript, - buildEngine, - buildWidgets, + createIndexJs, buildCesium, } from "./build.js"; @@ -85,27 +84,17 @@ function formatTimeSinceInSeconds(start) { async function generateDevelopmentBuild() { const startTime = performance.now(); - // Build @cesium/engine + // Build @cesium/engine index.js console.log("[1/3] Building @cesium/engine..."); - await buildEngine({ - sourcemap: true, - incremental: true, - write: false, - minify: false, - }); + await createIndexJs("engine"); - // Build @cesium/widgets + // Build @cesium/widgets index.js console.log("[2/3] Building @cesium/widgets..."); - await buildWidgets({ - sourcemap: true, - incremental: true, - write: false, - minify: false, - }); + await createIndexJs("widgets"); - // Build CesiumJS + // Build CesiumJS and save returned contexts for rebuilding upon request console.log("[3/3] Building CesiumJS..."); - const bundles = await buildCesium({ + const contexts = await buildCesium({ development: true, iife: true, incremental: true, @@ -121,11 +110,7 @@ async function generateDevelopmentBuild() { `Cesium built in ${formatTimeSinceInSeconds(startTime)} seconds.` ); - return { - esmResult: bundles.esmBundle, - iifeResult: bundles.iifeBundle, - specResult: bundles.specsBundle, - }; + return contexts; } const serveResult = (result, fileName, res, next) => { @@ -151,11 +136,9 @@ const serveResult = (result, fileName, res, next) => { let esmResult, iifeResult, specResult; const production = argv.production; + let contexts; if (!production) { - const bundles = await generateDevelopmentBuild(); - esmResult = bundles.esmResult; - iifeResult = bundles.iifeResult; - specResult = bundles.specResult; + contexts = await generateDevelopmentBuild(); } // eventually this mime type configuration will need to change @@ -241,7 +224,7 @@ const serveResult = (result, fileName, res, next) => { sourcemap: true, }); console.log( - `Rebuilt Workers/* in ${formatTimeSinceInSeconds(start)} seconds.` + `Built Workers/* in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { console.error(e); @@ -258,9 +241,9 @@ const serveResult = (result, fileName, res, next) => { try { const start = performance.now(); await createCesiumJs(); - iifeResult = await iifeResult.rebuild(); + iifeResult = await contexts.iife.rebuild(); console.log( - `Rebuilt Cesium.js in ${formatTimeSinceInSeconds(start)} seconds.` + `Built Cesium.js in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { next(e); @@ -280,9 +263,9 @@ const serveResult = (result, fileName, res, next) => { try { const start = performance.now(); await createCesiumJs(); - iifeResult = await iifeResult.rebuild(); + iifeResult = await contexts.iife.rebuild(); console.log( - `Rebuilt Cesium.js in ${formatTimeSinceInSeconds(start)} seconds.` + `Built Cesium.js in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { next(e); @@ -302,9 +285,9 @@ const serveResult = (result, fileName, res, next) => { try { const start = performance.now(); await createCesiumJs(); - esmResult = await esmResult.rebuild(); + esmResult = await contexts.esm.rebuild(); console.log( - `Rebuilt index.js in ${formatTimeSinceInSeconds(start)} seconds.` + `Built index.js in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { next(e); @@ -323,9 +306,9 @@ const serveResult = (result, fileName, res, next) => { try { const start = performance.now(); await createCesiumJs(); - esmResult = await esmResult.rebuild(); + esmResult = await contexts.esm.rebuild(); console.log( - `Rebuilt index.js in ${formatTimeSinceInSeconds(start)} seconds.` + `Built index.js in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { next(e); @@ -378,10 +361,10 @@ const serveResult = (result, fileName, res, next) => { if (!specResult?.outputFiles || specResult.outputFiles.length === 0) { try { const start = performance.now(); - specRebuildPromise = specResult.rebuild(); + specRebuildPromise = contexts.specs.rebuild(); specResult = await specRebuildPromise; console.log( - `Rebuilt Specs/* in ${formatTimeSinceInSeconds(start)} seconds.` + `Built Specs/* in ${formatTimeSinceInSeconds(start)} seconds.` ); } catch (e) { next(e); @@ -545,9 +528,9 @@ const serveResult = (result, fileName, res, next) => { }); if (!production) { - esmResult.rebuild.dispose(); - iifeResult.rebuild.dispose(); - specResult.rebuild.dispose(); + contexts.esm.dispose(); + contexts.iife.dispose(); + contexts.specs.dispose(); } isFirstSig = false; From c4cb602b3c123863c79e410488fb7ae44ce1cb0d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Feb 2023 12:00:03 -0500 Subject: [PATCH 489/679] Update to the latest version of cesium eslint config --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ecf93bcc4bf..f333337ba61 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "draco3d": "^1.5.1", "esbuild": "^0.16.7", "eslint": "^8.29.0", - "eslint-config-cesium": "^9.0.0", + "eslint-config-cesium": "^9.0.1", "eslint-config-prettier": "^8.3.0", "eslint-plugin-es": "^4.1.0", "eslint-plugin-html": "^7.1.0", @@ -166,4 +166,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} From f4428347a44d391ddeed54d47a62fb0adb8f4648 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Feb 2023 11:42:00 -0500 Subject: [PATCH 490/679] Update aws-sdk from v2 to v3 --- gulpfile.js | 112 +++++++++++++++++++++++++++++---------------------- package.json | 5 ++- 2 files changed, 66 insertions(+), 51 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index f877b500801..568864a4baa 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,7 +22,14 @@ import mergeStream from "merge-stream"; import streamToPromise from "stream-to-promise"; import karma from "karma"; import yargs from "yargs"; -import aws from "aws-sdk"; +import { + S3Client, + DeleteObjectsCommand, + HeadObjectCommand, + ListObjectsCommand, + PutObjectCommand, +} from "@aws-sdk/client-s3"; +import { Upload } from "@aws-sdk/lib-storage"; import mime from "mime"; import typeScript from "typescript"; import { build as esbuild } from "esbuild"; @@ -778,7 +785,8 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { const sandcastlePrefix = "sandcastle/"; const cesiumViewerPrefix = "cesiumjs/cesium-viewer/"; - const s3 = new aws.S3({ + const s3Client = new S3Client({ + region: "us-east-1", maxRetries: 10, retryDelayOptions: { base: 500, @@ -792,7 +800,7 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { const errors = []; if (!isProduction) { - await listAll(s3, bucketName, `${uploadDirectory}/`, existingBlobs); + await listAll(s3Client, bucketName, `${uploadDirectory}/`, existingBlobs); } async function getContents(file, blobName) { @@ -835,13 +843,11 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { existingBlobs.splice(index, 1); // get file info - const data = await s3 - .headObject({ - Bucket: bucketName, - Key: blobName, - }) - .promise(); - + const headObjectCommand = new HeadObjectCommand({ + Bucket: bucketName, + Key: blobName, + }); + const data = await s3Client.send(headObjectCommand); const hash = createHash("md5").update(content).digest("hex"); if ( @@ -895,13 +901,15 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { CacheControl: cacheControl, }; + const putObjectCommand = new PutObjectCommand(params); + if (dryRun) { uploaded++; return; } try { - await s3.putObject(params).promise(); + await s3Client.send(putObjectCommand); uploaded++; } catch (e) { errors.push(e); @@ -947,7 +955,7 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { uploadSandcastle(), uploadRefDoc(), uploadCesiumViewer(), - deployCesiumRelease(bucketName, s3, errors), + deployCesiumRelease(bucketName, s3Client, errors), ]; } else { const files = await globby( @@ -1007,24 +1015,24 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { batches.push(objectsToDelete); const deleteObjects = async (objects) => { + const deleteObjectsCommand = new DeleteObjectsCommand({ + Bucket: bucketName, + Delete: { + Objects: objects, + }, + }); + try { if (!dryRun) { - await s3 - .deleteObjects({ - Bucket: bucketName, - Delete: { - Objects: objects, - }, - }) - .promise(); - } - - if (verbose) { - console.log(`Cleaned ${objects.length} files.`); + await s3Client.send(deleteObjectsCommand); } } catch (e) { errors.push(e); } + + if (verbose) { + console.log(`Cleaned ${objects.length} files.`); + } }; await Promise.all(batches.map(deleteObjects)); @@ -1040,7 +1048,7 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { return Promise.reject("There was an error while deploying Cesium"); } -async function deployCesiumRelease(bucketName, s3, errors) { +async function deployCesiumRelease(bucketName, s3Client, errors) { const releaseDir = "cesiumjs/releases"; const quiet = process.env.TRAVIS; @@ -1068,12 +1076,11 @@ async function deployCesiumRelease(bucketName, s3, errors) { url: body.assets[0].browser_download_url, }; - await s3 - .headObject({ - Bucket: bucketName, - Key: posix.join(releaseDir, release.tag, "cesium.zip"), - }) - .promise(); + const headObjectCommand = new HeadObjectCommand({ + Bucket: bucketName, + Key: posix.join(releaseDir, release.tag, "cesium.zip"), + }); + await s3Client.send(headObjectCommand); console.log( `Cesium version ${release.tag} up to date. Skipping release deployment.` ); @@ -1084,7 +1091,7 @@ async function deployCesiumRelease(bucketName, s3, errors) { const data = await download(release.url); // upload and unzip contents const key = posix.join(releaseDir, release.tag, "cesium.zip"); - await uploadObject(bucketName, s3, key, data, quiet); + await uploadObject(bucketName, s3Client, key, data, quiet); const files = await decompress(data); const limit = pLimit(5); return Promise.all( @@ -1097,7 +1104,7 @@ async function deployCesiumRelease(bucketName, s3, errors) { // Upload to release directory const key = posix.join(releaseDir, release.tag, file.path); - return uploadObject(bucketName, s3, key, file.data, quiet); + return uploadObject(bucketName, s3Client, key, file.data, quiet); }); }) ); @@ -1108,20 +1115,22 @@ async function deployCesiumRelease(bucketName, s3, errors) { } } -function uploadObject(bucketName, s3, key, contents, quiet) { +async function uploadObject(bucketName, s3Client, key, contents, quiet) { if (!quiet) { console.log(`Uploading ${key}...`); } - return s3 - .upload({ + const upload = new Upload({ + client: s3Client, + params: { Bucket: bucketName, Key: key, Body: contents, ContentType: mime.getType(key) || undefined, CacheControl: "public, max-age=1800", - }) - .promise(); + }, + }); + return upload.done(); } function getMimeType(filename) { @@ -1165,15 +1174,14 @@ function getMimeType(filename) { } // get all files currently in bucket asynchronously -async function listAll(s3, bucketName, prefix, files, marker) { - const data = await s3 - .listObjects({ - Bucket: bucketName, - MaxKeys: 1000, - Prefix: prefix, - Marker: marker, - }) - .promise(); +async function listAll(s3Client, bucketName, prefix, files, marker) { + const listObjectsCommand = new ListObjectsCommand({ + Bucket: bucketName, + MaxKeys: 1000, + Prefix: prefix, + Marker: marker, + }); + const data = await s3Client.send(listObjectsCommand); const items = data.Contents; for (let i = 0; i < items.length; i++) { files.push(items[i].Key); @@ -1181,7 +1189,13 @@ async function listAll(s3, bucketName, prefix, files, marker) { if (data.IsTruncated) { // get next page of results - return listAll(s3, bucketName, prefix, files, files[files.length - 1]); + return listAll( + s3Client, + bucketName, + prefix, + files, + files[files.length - 1] + ); } } @@ -2200,7 +2214,7 @@ async function buildCesiumViewer() { }; config.format = "iife"; config.inject = ["Apps/CesiumViewer/index.js"]; - config.external = ["https", "http", "zlib"]; + config.external = ["https", "http", "url", "zlib"]; config.outdir = cesiumViewerOutputDirectory; config.outbase = "Apps/CesiumViewer"; config.logLevel = "error"; // print errors immediately, and collect warnings so we can filter out known ones diff --git a/package.json b/package.json index ecf93bcc4bf..7f4314f23dc 100644 --- a/package.json +++ b/package.json @@ -55,9 +55,10 @@ "@cesium/widgets": "2.0.0" }, "devDependencies": { + "@aws-sdk/client-s3": "^3.276.0", + "@aws-sdk/lib-storage": "^3.276.0", "@rollup/plugin-commonjs": "^23.0.5", "@rollup/plugin-node-resolve": "^15.0.1", - "aws-sdk": "^2.1276.0", "chokidar": "^3.5.3", "cloc": "^2.8.0", "compression": "^1.7.4", @@ -166,4 +167,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} From 8be73fa80c3784e4eb6ca7dc42b6444666380903 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 22 Feb 2023 14:19:21 -0500 Subject: [PATCH 491/679] Use primitive and provider transforms in voxel draw command --- packages/engine/Source/Scene/buildVoxelDrawCommands.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/engine/Source/Scene/buildVoxelDrawCommands.js b/packages/engine/Source/Scene/buildVoxelDrawCommands.js index e2d5e872e77..89bf784fca6 100644 --- a/packages/engine/Source/Scene/buildVoxelDrawCommands.js +++ b/packages/engine/Source/Scene/buildVoxelDrawCommands.js @@ -82,6 +82,7 @@ function buildVoxelDrawCommands(primitive, context) { renderState: renderState, shaderProgram: shaderProgram, uniformMap: renderResources.uniformMap, + modelMatrix: primitive._compoundModelMatrix, pass: Pass.VOXELS, executeInClosestFrustum: true, owner: this, From 5e1b56219279449a8d93461bc4870fd155a32d50 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Feb 2023 14:43:14 -0500 Subject: [PATCH 492/679] Update aws cli used in CI --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 816924f6e2d..bc4ad92dc4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,15 @@ notifications: secure: JKzk2sJSbZ9h2PUVWj6KtOAdFbEEnOtv/VZy05pJ2H41xRgUHiGdtMW/vMSeq6XX3IJN8eW2zd0cJTgkFn0ioAlYvID8zRhcvkFHg60QXquoqtp5y65dxjtVz79hefxSo7FO1NhMZBQWE9Tg6R7XkoyTMth62+T9vqOgu2Hms6M= if: (branch = main) AND (type = push) on_success: change # default: always -before_script: pip install awscli --user jobs: include: - stage: name: "Coverage" node_js: "18" + before_script: + - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + - unzip awscliv2.zip + - sudo ./aws/install script: - ./travis/coverage.sh - name: "Release Tests" From 446eadbb197f5d6c28c37b22cc33e98d3fce6b86 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Feb 2023 15:53:49 -0500 Subject: [PATCH 493/679] Add willReadFrequently option to 2d contexts where applicable --- CHANGES.md | 1 + packages/engine/Source/Core/getImagePixels.js | 3 ++- packages/engine/Source/Core/writeTextToCanvas.js | 3 ++- packages/engine/Source/Scene/LabelCollection.js | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5d69123edb9..783ed63c9ef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) - Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) - Replace constructor types with primitive types in JSDoc. [#11080](https://github.com/CesiumGS/cesium/pull/11080) +- Fixed browser warning for `willReadFrequently` option. [#11025](https://github.com/CesiumGS/cesium/issues/11025) ### 1.102 - 2023-02-01 diff --git a/packages/engine/Source/Core/getImagePixels.js b/packages/engine/Source/Core/getImagePixels.js index b027c3d6a3b..055ab47c85b 100644 --- a/packages/engine/Source/Core/getImagePixels.js +++ b/packages/engine/Source/Core/getImagePixels.js @@ -32,7 +32,8 @@ function getImagePixels(image, width, height) { const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; - context2d = canvas.getContext("2d"); + // Since we re-use contexts, use the willReadFrequently option – See https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently + context2d = canvas.getContext("2d", { willReadFrequently: true }); context2d.globalCompositeOperation = "copy"; context2DsByHeight[height] = context2d; } diff --git a/packages/engine/Source/Core/writeTextToCanvas.js b/packages/engine/Source/Core/writeTextToCanvas.js index 599ced41b78..1db8a0ba0d1 100644 --- a/packages/engine/Source/Core/writeTextToCanvas.js +++ b/packages/engine/Source/Core/writeTextToCanvas.js @@ -143,7 +143,8 @@ function writeTextToCanvas(text, options) { canvas.width = 1; canvas.height = 1; canvas.style.font = font; - const context2D = canvas.getContext("2d"); + // Since multiple read-back operations are expected for labels, use the willReadFrequently option – See https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently + const context2D = canvas.getContext("2d", { willReadFrequently: true }); if (!defined(imageSmoothingEnabledName)) { if (defined(context2D.imageSmoothingEnabled)) { diff --git a/packages/engine/Source/Scene/LabelCollection.js b/packages/engine/Source/Scene/LabelCollection.js index 87cdc39ae44..558af776f2d 100644 --- a/packages/engine/Source/Scene/LabelCollection.js +++ b/packages/engine/Source/Scene/LabelCollection.js @@ -226,6 +226,7 @@ function rebindAllGlyphs(labelCollection, label) { radius: SDFSettings.RADIUS, }); + // Context is originally created in writeTextToCanvas() const ctx = canvas.getContext("2d"); const canvasWidth = canvas.width; const canvasHeight = canvas.height; From eb4b9ef46f77121bff93b8a30c8dcfdc7df7463d Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Thu, 23 Feb 2023 12:16:30 +0800 Subject: [PATCH 494/679] fix camera go througth building --- .../engine/Source/Scene/ScreenSpaceCameraController.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 38e767dd16d..825fede4987 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2158,6 +2158,8 @@ function pan3D(controller, startPosition, movement, ellipsoid) { const zoom3DUnitPosition = new Cartesian3(); const zoom3DCartographic = new Cartographic(); +let preIntersectionDistance = 0; + function zoom3D(controller, startPosition, movement) { if (defined(movement.distance)) { movement = movement.distance; @@ -2189,10 +2191,10 @@ function zoom3D(controller, startPosition, movement) { zoom3DCartographic ).height; - const inertiaMovementApproachingGround = Math.abs(height) < 50; + const approachingCollision = Math.abs(preIntersectionDistance) < 100; const needPickGlobe = inertiaMovement - ? inertiaMovementApproachingGround + ? approachingCollision : height < controller._minimumPickingTerrainHeight; if (needPickGlobe) { intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); @@ -2201,6 +2203,7 @@ function zoom3D(controller, startPosition, movement) { let distance; if (defined(intersection)) { distance = Cartesian3.distance(ray.origin, intersection); + preIntersectionDistance = distance; } if (cameraUnderground) { From a548448a308396a522d3e09b99d2cdd6aeb23cb6 Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Thu, 23 Feb 2023 10:18:31 +0300 Subject: [PATCH 495/679] Performance improvement Context: https://github.com/CesiumGS/cesium/issues/10510#issuecomment-1438267847 --- .../Source/Shaders/AtmosphereCommon.glsl | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 5f2dda3109a..03eeb36df66 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -8,8 +8,10 @@ uniform vec3 u_atmosphereRayleighCoefficient; uniform vec3 u_atmosphereMieCoefficient; const float ATMOSPHERE_THICKNESS = 111e3; // The thickness of the atmosphere in meters. -const int PRIMARY_STEPS = 16; // Number of times the ray from the camera to the world position (primary ray) is sampled. -const int LIGHT_STEPS = 4; // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. + +// --- Modified: constants +const int PRIMARY_STEPS = 4; // Number of times the ray from the camera to the world position (primary ray) is sampled. +const int LIGHT_STEPS = 2; // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. /** * This function computes the colors contributed by Rayliegh and Mie scattering on a given ray, as well as @@ -50,10 +52,27 @@ void computeScattering( return; } + // To deal with smaller values of PRIMARY_STEPS (e.g. 4) + // we implement a split strategy: sky or horizon. + // + // For performance reasons, instead of a if/else branch + // a soft choice is implemented through a weight 0.0 <= w_stop_gt_lprl <= 1.0 + float lprl = length(primaryRayLength); + float x = 1e-7 * primaryRayAtmosphereIntersect.stop / lprl; + // w_stop_gt_lprl: similar to (1+tanh)/2 + // Value close to 0.0: close to the horizon + // Value close to 1.0: above in the sky + float w_stop_gt_lprl = max(0.0,min(1.0,(1.0 + x * ( 27.0 + x * x ) / ( 27.0 + 9.0 * x * x ))/2.0)); + // The ray should start from the first intersection with the outer atmopshere, or from the camera position, if it is inside the atmosphere. primaryRayAtmosphereIntersect.start = max(primaryRayAtmosphereIntersect.start, 0.0); // The ray should end at the exit from the atmosphere or at the distance to the vertex, whichever is smaller. - primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, length(primaryRayLength)); + primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, lprl); + + // Sky vs horizon: constant step in one case, increasing step in the other case + float rayStepLengthIncrease = (1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0); + float rayStepLength = w_stop_gt_lprl * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0,float(PRIMARY_STEPS)); + // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. float rayStepLength = (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / float(PRIMARY_STEPS); @@ -65,9 +84,14 @@ void computeScattering( vec2 heightScale = vec2(u_atmosphereRayleighScaleHeight, u_atmosphereMieScaleHeight); // Sample positions on the primary ray. + + // Possible small optimization + vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength); + vec3 primaryPositionDelta = primaryRay.direction * rayStepLength; + for (int i = 0; i < PRIMARY_STEPS; i++) { // Calculate sample position along viewpoint ray. - vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength); + samplePosition += primaryPositionDelta; // Possible small optimization // Calculate height of sample position above ellipsoid. float sampleHeight = length(samplePosition) - atmosphereInnerRadius; @@ -86,10 +110,14 @@ void computeScattering( vec2 lightOpticalDepth = vec2(0.0); // Sample positions along the light ray, to accumulate incidence of light on the latest sample segment. + + // Possible small optimization + vec3 lightPosition = samplePosition + lightDirection * (lightStepLength * 0.5); + vec3 lightPositionDelta = lightDirection * lightStepLength; for (int j = 0; j < LIGHT_STEPS; j++) { // Calculate sample position along light ray. - vec3 lightPosition = samplePosition + lightDirection * (lightPositionLength + lightStepLength * 0.5); + lightPosition += lightPositionDelta; // Possible small optimization // Calculate height of the light sample position above ellipsoid. float lightHeight = length(lightPosition) - atmosphereInnerRadius; @@ -109,7 +137,9 @@ void computeScattering( mieAccumulation += sampleDensity.y * attenuation; // Increment distance on primary ray. - rayPositionLength += rayStepLength; + + // --- Modified: increasing step length + rayPositionLength += (rayStepLength+=rayStepLengthIncrease); } // Compute the scattering amount. From 99aa76c0eecb1c7c82fd33ff28be05d8917c3597 Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Thu, 23 Feb 2023 10:24:19 +0300 Subject: [PATCH 496/679] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 80243bd7dd1..de69d02be62 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -345,3 +345,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [JiaoJianing](https://github.com/JiaoJianing) - [Southjor](https://github.com/Southjor) - [Lakshmipriya](https://github.com/Lakshmi0710) +- [Guillaume Lathoud](https://github.com/glathoud) From 41857d1e870bd2c847cb3c8de0aaff50f85a5711 Mon Sep 17 00:00:00 2001 From: bbbbx <venus@venusworld.cn> Date: Thu, 23 Feb 2023 21:14:03 +0800 Subject: [PATCH 497/679] Fixed textures visibility for particle systems --- CHANGES.md | 1 + packages/engine/Source/Scene/ParticleSystem.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 783ed63c9ef..4ba90ba3635 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) - Replace constructor types with primitive types in JSDoc. [#11080](https://github.com/CesiumGS/cesium/pull/11080) - Fixed browser warning for `willReadFrequently` option. [#11025](https://github.com/CesiumGS/cesium/issues/11025) +- Fixed textures visibility for particle systems. [#11099](https://github.com/CesiumGS/cesium/pull/11099) ### 1.102 - 2023-02-01 diff --git a/packages/engine/Source/Scene/ParticleSystem.js b/packages/engine/Source/Scene/ParticleSystem.js index acb93e90725..7fab2c50d98 100644 --- a/packages/engine/Source/Scene/ParticleSystem.js +++ b/packages/engine/Source/Scene/ParticleSystem.js @@ -564,6 +564,11 @@ function updateParticlePool(system) { const particle = new Particle(); particle._billboard = billboardCollection.add({ image: image, + // Make the newly added billboards invisible when updating the particle pool + // to prevent the billboards from being displayed when the particles + // are not created. The billboard will always be set visible in + // updateBillboard function when its corresponding particle update. + show: false, }); particlePool.push(particle); } From b182960ac6f80313df42d90994b23c4b242fad8b Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Fri, 24 Feb 2023 10:24:13 +0800 Subject: [PATCH 498/679] adjust max approaching collision distance --- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 825fede4987..ba2b91264bf 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2191,7 +2191,7 @@ function zoom3D(controller, startPosition, movement) { zoom3DCartographic ).height; - const approachingCollision = Math.abs(preIntersectionDistance) < 100; + const approachingCollision = Math.abs(preIntersectionDistance) < 4000; const needPickGlobe = inertiaMovement ? approachingCollision From 3f8acbd33aed09f218df07a0b1fedf234ca49f01 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 24 Feb 2023 17:06:24 -0500 Subject: [PATCH 499/679] Update peer dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1853ee80a11..dc47a364144 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "devDependencies": { "@aws-sdk/client-s3": "^3.276.0", "@aws-sdk/lib-storage": "^3.276.0", - "@rollup/plugin-commonjs": "^23.0.5", + "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-terser": "^0.4.0", "chokidar": "^3.5.3", @@ -110,7 +110,7 @@ "prismjs": "^1.28.0", "request": "^2.79.0", "rimraf": "^4.1.2", - "rollup": "^2.79.1", + "rollup": "^3.17.2", "rollup-plugin-strip-pragma": "^1.0.0", "stream-to-promise": "^3.0.0", "tsd-jsdoc": "^2.5.0", From 03bd704b61ecc147cab7f7b3b96d43ddd9ceae4b Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Feb 2023 11:41:36 -0500 Subject: [PATCH 500/679] Fix type qualifier in ShadowMapShader --- packages/engine/Source/Scene/ShadowMapShader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ShadowMapShader.js b/packages/engine/Source/Scene/ShadowMapShader.js index 7c9744d90c7..fc78fcfdd93 100644 --- a/packages/engine/Source/Scene/ShadowMapShader.js +++ b/packages/engine/Source/Scene/ShadowMapShader.js @@ -39,7 +39,7 @@ ShadowMapShader.createShadowCastVertexShader = function ( } const shadowVS = - "in vec3 v_positionEC; \n" + + "out vec3 v_positionEC; \n" + "void main() \n" + "{ \n" + " czm_shadow_cast_main(); \n" + From 7fca05034d3360b17ba5f0c0d05df5d976777b38 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 27 Feb 2023 11:57:28 -0500 Subject: [PATCH 501/679] Fix deploy by accounting for possibly undefined items after sdk update --- gulpfile.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 75746a4a38c..27ce4870f07 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1186,6 +1186,10 @@ async function listAll(s3Client, bucketName, prefix, files, marker) { }); const data = await s3Client.send(listObjectsCommand); const items = data.Contents; + if (!items) { + return; + } + for (let i = 0; i < items.length; i++) { files.push(items[i].Key); } From 3a9ac1c02296c485e1c4b1207c31977dfdddc5ad Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Feb 2023 12:38:46 -0500 Subject: [PATCH 502/679] Render voxels before opaque entities --- packages/engine/Source/Scene/Scene.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index 9bd9bd90d06..29beccfa668 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -2564,6 +2564,12 @@ function executeCommands(scene, passState) { clearStencil.execute(context, passState); } + us.updatePass(Pass.VOXELS); + commands = frustumCommands.commands[Pass.VOXELS]; + length = frustumCommands.indices[Pass.VOXELS]; + commands.length = length; + executeVoxelCommands(scene, executeCommand, passState, commands); + us.updatePass(Pass.OPAQUE); commands = frustumCommands.commands[Pass.OPAQUE]; length = frustumCommands.indices[Pass.OPAQUE]; @@ -2634,12 +2640,6 @@ function executeCommands(scene, passState) { pickDepth.executeCopyDepth(context, passState); } - us.updatePass(Pass.VOXELS); - commands = frustumCommands.commands[Pass.VOXELS]; - length = frustumCommands.indices[Pass.VOXELS]; - commands.length = length; - executeVoxelCommands(scene, executeCommand, passState, commands); - if (picking || !usePostProcessSelected) { continue; } From 9668df58ed4a565062a97feb41cd3ed7d3a39f0c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Feb 2023 14:16:10 -0500 Subject: [PATCH 503/679] Add missing types in Cesium3DTile --- packages/engine/Source/Scene/Cesium3DTile.js | 29 +++++++------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 7535bf4e342..a8804ed6adf 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -583,7 +583,7 @@ Object.defineProperties(Cesium3DTile.prototype, { * * @memberof Cesium3DTile.prototype * - * @type {*} + * @type {object} * @readonly * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification#specifying-extensions-and-application-specific-extras|Extras in the 3D Tiles specification.} */ @@ -1151,11 +1151,7 @@ function requestMultipleContents(tile) { } if (tile.isDestroyed()) { - multipleContentFailed( - tile, - tileset, - "Tile was unloaded while content was loading" - ); + multipleContentFailed(tile, tileset); return; } @@ -1180,11 +1176,7 @@ function requestMultipleContents(tile) { } if (tile.isDestroyed()) { - multipleContentFailed( - tile, - tileset, - "Tile was unloaded while content was processing" - ); + multipleContentFailed(tile, tileset); return; } @@ -1196,8 +1188,8 @@ function requestMultipleContents(tile) { tile._contentState = Cesium3DTileContentState.READY; return content; }) - .catch(function (error) { - multipleContentFailed(tile, tileset, error); + .catch(function () { + multipleContentFailed(tile, tileset); }); return 0; @@ -1207,9 +1199,8 @@ function requestMultipleContents(tile) { * @private * @param {Cesium3DTile} tile * @param {Cesium3DTileset} tileset - * @param {*} error */ -function multipleContentFailed(tile, tileset, error) { +function multipleContentFailed(tile, tileset) { // note: The Multiple3DTileContent handles decrementing the number of pending // requests if the state is LOADING. if (tile._contentState === Cesium3DTileContentState.PROCESSING) { @@ -1647,7 +1638,7 @@ const scratchTransform = new Matrix4(); /** * @private - * @param {*} box + * @param {Array} box An array of 12 numbers that define an oriented bounding box * @param {Matrix4} transform * @param {TileBoundingVolume} [result] * @returns {TileOrientedBoundingBox} @@ -1670,7 +1661,7 @@ function createBox(box, transform, result) { /** * @private - * @param {*} region + * @param {Array} region An array of six numbers that define a bounding geographic region in EPSG:4979 coordinates with the order [west, south, east, north, minimum height, maximum height] * @param {Matrix4} transform * @param {Matrix4} initialTransform * @param {TileOrientedBoundingBox} [result] @@ -1718,7 +1709,7 @@ function createBoxFromTransformedRegion( /** * @private - * @param {*} region + * @param {Array} region An array of six numbers that define a bounding geographic region in EPSG:4979 coordinates with the order [west, south, east, north, minimum height, maximum height] * @param {Matrix4} transform * @param {Matrix4} initialTransform * @param {TileBoundingVolume} [result] @@ -1751,7 +1742,7 @@ function createRegion(region, transform, initialTransform, result) { /** * @private - * @param {*} sphere + * @param {Array} sphere An array of four numbers that define a bounding sphere * @param {Matrix4} transform * @param {TileBoundingVolume} [result] * @returns {TileBoundingSphere} From db95418c9b38870ecc501e3a13e2313cab6ab060 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Feb 2023 16:37:03 -0500 Subject: [PATCH 504/679] Document and clean up helper functions in Cesium3DTileset --- .../engine/Source/Scene/Cesium3DTileset.js | 344 +++++++++++------- 1 file changed, 221 insertions(+), 123 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index c4b67cc0a68..5b531d8c111 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -884,6 +884,10 @@ function Cesium3DTileset(options) { false ); + /** + * @private + * @type {LabelCollection|undefined} + */ this._tileDebugLabels = undefined; this.debugPickedTileLabelOnly = false; this.debugPickedTile = undefined; @@ -2088,53 +2092,53 @@ function makeTile(tileset, baseResource, tileHeader, parentTile) { defined(tileHeader.implicitTiling) || hasExtension(tileHeader, "3DTILES_implicit_tiling"); - if (hasImplicitTiling) { - const metadataSchema = tileset.schema; + if (!hasImplicitTiling) { + return new Cesium3DTile(tileset, baseResource, tileHeader, parentTile); + } - const implicitTileset = new ImplicitTileset( - baseResource, - tileHeader, - metadataSchema - ); - const rootCoordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitTileset.subdivisionScheme, - subtreeLevels: implicitTileset.subtreeLevels, - level: 0, - x: 0, - y: 0, - // The constructor will only use this for octrees. - z: 0, - }); + const metadataSchema = tileset.schema; - // Create a placeholder Cesium3DTile that has an ImplicitTileset - // object and whose content will resolve to an Implicit3DTileContent - const contentUri = implicitTileset.subtreeUriTemplate.getDerivedResource({ - templateValues: rootCoordinates.getTemplateValues(), - }).url; - - const deepCopy = true; - const tileJson = clone(tileHeader, deepCopy); - // Replace contents with the subtree - tileJson.contents = [ - { - uri: contentUri, - }, - ]; - - delete tileJson.content; - - // The placeholder tile does not have any extensions. If there are any - // extensions beyond 3DTILES_implicit_tiling, Implicit3DTileContent will - // copy them to the transcoded tiles. - delete tileJson.extensions; - - const tile = new Cesium3DTile(tileset, baseResource, tileJson, parentTile); - tile.implicitTileset = implicitTileset; - tile.implicitCoordinates = rootCoordinates; - return tile; - } + const implicitTileset = new ImplicitTileset( + baseResource, + tileHeader, + metadataSchema + ); + const rootCoordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: 0, + x: 0, + y: 0, + // The constructor will only use this for octrees. + z: 0, + }); + + // Create a placeholder Cesium3DTile that has an ImplicitTileset + // object and whose content will resolve to an Implicit3DTileContent + const contentUri = implicitTileset.subtreeUriTemplate.getDerivedResource({ + templateValues: rootCoordinates.getTemplateValues(), + }).url; + + const deepCopy = true; + const tileJson = clone(tileHeader, deepCopy); + // Replace contents with the subtree + tileJson.contents = [ + { + uri: contentUri, + }, + ]; + + delete tileJson.content; + + // The placeholder tile does not have any extensions. If there are any + // extensions beyond 3DTILES_implicit_tiling, Implicit3DTileContent will + // copy them to the transcoded tiles. + delete tileJson.extensions; - return new Cesium3DTile(tileset, baseResource, tileHeader, parentTile); + const tile = new Cesium3DTile(tileset, baseResource, tileJson, parentTile); + tile.implicitTileset = implicitTileset; + tile.implicitCoordinates = rootCoordinates; + return tile; } /** @@ -2186,6 +2190,11 @@ const scratchCenter = new Cartesian3(); const scratchPosition = new Cartesian3(); const scratchDirection = new Cartesian3(); +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function updateDynamicScreenSpaceError(tileset, frameState) { let up; let direction; @@ -2269,28 +2278,27 @@ function updateDynamicScreenSpaceError(tileset, frameState) { ); // Increase density as the camera tilts towards the horizon - const dot = Math.abs(Cartesian3.dot(direction, up)); - let horizonFactor = 1.0 - dot; + let horizonFactor = 1.0 - Math.abs(Cartesian3.dot(direction, up)); // Weaken the horizon factor as the camera height increases, implying the camera is further away from the tileset. // The goal is to increase density for the "street view", not when viewing the tileset from a distance. horizonFactor = horizonFactor * (1.0 - t); - let density = tileset.dynamicScreenSpaceErrorDensity; - density *= horizonFactor; - - tileset._dynamicScreenSpaceErrorComputedDensity = density; + tileset._dynamicScreenSpaceErrorComputedDensity = + tileset.dynamicScreenSpaceErrorDensity * horizonFactor; } -/////////////////////////////////////////////////////////////////////////// - +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function requestContent(tileset, tile) { if (tile.hasEmptyContent) { return; } const statistics = tileset._statistics; - const expired = tile.contentExpired; const attemptedRequests = tile.requestContent(); if (attemptedRequests > 0) { @@ -2298,7 +2306,7 @@ function requestContent(tileset, tile) { return; } - if (expired) { + if (tile.contentExpired) { if (tile.hasTilesetContent || tile.hasImplicitContent) { destroySubtree(tileset, tile); } else { @@ -2326,6 +2334,7 @@ function sortRequestByPriority(a, b) { /** * Perform any pass invariant tasks here. Called after the render pass. * @private + * @param {FrameState} frameState */ Cesium3DTileset.prototype.postPassesUpdate = function (frameState) { if (!this.ready) { @@ -2348,6 +2357,7 @@ Cesium3DTileset.prototype.postPassesUpdate = function (frameState) { /** * Perform any pass invariant tasks here. Called before any passes are executed. * @private + * @param {FrameState} frameState */ Cesium3DTileset.prototype.prePassesUpdate = function (frameState) { if (!this.ready) { @@ -2386,11 +2396,15 @@ Cesium3DTileset.prototype.prePassesUpdate = function (frameState) { } }; +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function cancelOutOfViewRequests(tileset, frameState) { const requestedTilesInFlight = tileset._requestedTilesInFlight; let removeCount = 0; - const length = requestedTilesInFlight.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < requestedTilesInFlight.length; ++i) { const tile = requestedTilesInFlight[i]; // NOTE: This is framerate dependant so make sure the threshold check is small @@ -2414,17 +2428,26 @@ function cancelOutOfViewRequests(tileset, frameState) { requestedTilesInFlight.length -= removeCount; } -function requestTiles(tileset, isAsync) { - // Sort requests by priority before making any requests. - // This makes it less likely that requests will be cancelled after being issued. +/** + * Sort requests by priority before making any requests. + * This makes it less likely that requests will be cancelled after being issued. + * @private + * @param {Cesium3DTileset} tileset + */ +function requestTiles(tileset) { const requestedTiles = tileset._requestedTiles; - const length = requestedTiles.length; requestedTiles.sort(sortRequestByPriority); - for (let i = 0; i < length; ++i) { + for (let i = 0; i < requestedTiles.length; ++i) { requestContent(tileset, requestedTiles[i]); } } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {Function} + */ function addToProcessingQueue(tileset, tile) { return function () { tileset._processingQueue.push(tile); @@ -2433,6 +2456,12 @@ function addToProcessingQueue(tileset, tile) { }; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {Function} + */ function handleTileFailure(tileset, tile) { return function (error) { if (tile._contentState !== Cesium3DTileContentState.FAILED) { @@ -2454,6 +2483,12 @@ function handleTileFailure(tileset, tile) { }; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {Function} + */ function handleTileSuccess(tileset, tile) { return function (content) { --tileset._statistics.numberOfTilesProcessing; @@ -2478,12 +2513,15 @@ function handleTileSuccess(tileset, tile) { }; } +/** + * @private + * @param {Cesium3DTileset} tileset + */ function filterProcessingQueue(tileset) { const tiles = tileset._processingQueue; - const length = tiles.length; let removeCount = 0; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < tiles.length; ++i) { const tile = tiles[i]; if (tile._contentState !== Cesium3DTileContentState.PROCESSING) { ++removeCount; @@ -2496,24 +2534,31 @@ function filterProcessingQueue(tileset) { tiles.length -= removeCount; } +/** + * Process tiles in the PROCESSING state so they will eventually move to the READY state. + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function processTiles(tileset, frameState) { filterProcessingQueue(tileset); const tiles = tileset._processingQueue; - const length = tiles.length; - // Process tiles in the PROCESSING state so they will eventually move to the READY state. - for (let i = 0; i < length; ++i) { + for (let i = 0; i < tiles.length; ++i) { tiles[i].process(tileset, frameState); } } -/////////////////////////////////////////////////////////////////////////// - const scratchCartesian = new Cartesian3(); const stringOptions = { maximumFractionDigits: 3, }; +/** + * @private + * @param {number} memorySizeInBytes + * @returns {string} + */ function formatMemoryString(memorySizeInBytes) { const memoryInMegabytes = memorySizeInBytes / 1048576; if (memoryInMegabytes < 1.0) { @@ -2522,28 +2567,38 @@ function formatMemoryString(memorySizeInBytes) { return Math.round(memoryInMegabytes).toLocaleString(); } +/** + * @private + * @param {Cesium3DTile} tile + * @returns {Cartesian3} + */ function computeTileLabelPosition(tile) { - const boundingVolume = tile.boundingVolume.boundingVolume; - const halfAxes = boundingVolume.halfAxes; - const radius = boundingVolume.radius; + const { halfAxes, radius, center } = tile.boundingVolume.boundingVolume; - let position = Cartesian3.clone(boundingVolume.center, scratchCartesian); + let position = Cartesian3.clone(center, scratchCartesian); if (defined(halfAxes)) { position.x += 0.75 * (halfAxes[0] + halfAxes[3] + halfAxes[6]); position.y += 0.75 * (halfAxes[1] + halfAxes[4] + halfAxes[7]); position.z += 0.75 * (halfAxes[2] + halfAxes[5] + halfAxes[8]); } else if (defined(radius)) { - let normal = Cartesian3.normalize(boundingVolume.center, scratchCartesian); + let normal = Cartesian3.normalize(center, scratchCartesian); normal = Cartesian3.multiplyByScalar( normal, 0.75 * radius, scratchCartesian ); - position = Cartesian3.add(normal, boundingVolume.center, scratchCartesian); + position = Cartesian3.add(normal, center, scratchCartesian); } return position; } +/** + * @private + * @param {Cesium3DTile} tile + * @param {Cesium3DTileset} tileset + * @param {Cartesian3} position + * @returns {Label} + */ function addTileDebugLabel(tile, tileset, position) { let labelString = ""; let attributes = 0; @@ -2609,9 +2664,12 @@ function addTileDebugLabel(tile, tileset, position) { return tileset._tileDebugLabels.add(newLabel); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function updateTileDebugLabels(tileset, frameState) { - let i; - let tile; const selectedTiles = tileset._selectedTiles; const selectedLength = selectedTiles.length; const emptyTiles = tileset._emptyTiles; @@ -2631,12 +2689,12 @@ function updateTileDebugLabels(tileset, frameState) { label.pixelOffset = new Cartesian2(15, -15); // Offset to avoid picking the label. } } else { - for (i = 0; i < selectedLength; ++i) { - tile = selectedTiles[i]; + for (let i = 0; i < selectedLength; ++i) { + const tile = selectedTiles[i]; addTileDebugLabel(tile, tileset, computeTileLabelPosition(tile)); } - for (i = 0; i < emptyLength; ++i) { - tile = emptyTiles[i]; + for (let i = 0; i < emptyLength; ++i) { + const tile = emptyTiles[i]; if (tile.hasTilesetContent || tile.hasImplicitContent) { addTileDebugLabel(tile, tileset, computeTileLabelPosition(tile)); } @@ -2645,21 +2703,22 @@ function updateTileDebugLabels(tileset, frameState) { tileset._tileDebugLabels.update(frameState); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + * @param {object} passOptions + */ function updateTiles(tileset, frameState, passOptions) { tileset._styleEngine.applyStyle(tileset); tileset._styleApplied = true; const isRender = passOptions.isRender; - const statistics = tileset._statistics; + const { statistics, tileVisible } = tileset; const commandList = frameState.commandList; const numberOfInitialCommands = commandList.length; const selectedTiles = tileset._selectedTiles; const selectedLength = selectedTiles.length; - const emptyTiles = tileset._emptyTiles; - const emptyLength = emptyTiles.length; - const tileVisible = tileset.tileVisible; - let i; - let tile; const bivariateVisibilityTest = tileset._skipLevelOfDetail && @@ -2683,8 +2742,8 @@ function updateTiles(tileset, frameState, passOptions) { } const lengthBeforeUpdate = commandList.length; - for (i = 0; i < selectedLength; ++i) { - tile = selectedTiles[i]; + for (let i = 0; i < selectedLength; ++i) { + const tile = selectedTiles[i]; // Raise the tileVisible event before update in case the tileVisible event // handler makes changes that update needs to apply to WebGL resources if (isRender) { @@ -2694,8 +2753,9 @@ function updateTiles(tileset, frameState, passOptions) { statistics.incrementSelectionCounts(tile.content); ++statistics.selected; } - for (i = 0; i < emptyLength; ++i) { - tile = emptyTiles[i]; + const emptyTiles = tileset._emptyTiles; + for (let i = 0; i < emptyTiles.length; ++i) { + const tile = emptyTiles[i]; tile.update(tileset, frameState, passOptions); } @@ -2734,13 +2794,13 @@ function updateTiles(tileset, frameState, passOptions) { commandList.length += backfaceCommandsLength; // copy commands to the back of the commandList - for (i = addedCommandsLength - 1; i >= 0; --i) { + for (let i = addedCommandsLength - 1; i >= 0; --i) { commandList[lengthBeforeUpdate + backfaceCommandsLength + i] = commandList[lengthBeforeUpdate + i]; } // move backface commands to the front of the commandList - for (i = 0; i < backfaceCommandsLength; ++i) { + for (let i = 0; i < backfaceCommandsLength; ++i) { commandList[lengthBeforeUpdate + i] = backfaceCommands[i]; } } @@ -2749,9 +2809,12 @@ function updateTiles(tileset, frameState, passOptions) { addedCommandsLength = commandList.length - numberOfInitialCommands; statistics.numberOfCommands = addedCommandsLength; + if (!isRender) { + return; + } + // Only run EDL if simple attenuation is on if ( - isRender && tileset.pointCloudShading.attenuation && tileset.pointCloudShading.eyeDomeLighting && addedCommandsLength > 0 @@ -2764,26 +2827,29 @@ function updateTiles(tileset, frameState, passOptions) { ); } - if (isRender) { - if ( - tileset.debugShowGeometricError || - tileset.debugShowRenderingStatistics || - tileset.debugShowMemoryUsage || - tileset.debugShowUrl - ) { - if (!defined(tileset._tileDebugLabels)) { - tileset._tileDebugLabels = new LabelCollection(); - } - updateTileDebugLabels(tileset, frameState); - } else { - tileset._tileDebugLabels = - tileset._tileDebugLabels && tileset._tileDebugLabels.destroy(); + if ( + tileset.debugShowGeometricError || + tileset.debugShowRenderingStatistics || + tileset.debugShowMemoryUsage || + tileset.debugShowUrl + ) { + if (!defined(tileset._tileDebugLabels)) { + tileset._tileDebugLabels = new LabelCollection(); } + updateTileDebugLabels(tileset, frameState); + } else { + tileset._tileDebugLabels = + tileset._tileDebugLabels && tileset._tileDebugLabels.destroy(); } } const scratchStack = []; +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function destroySubtree(tileset, tile) { const root = tile; const stack = scratchStack; @@ -2803,6 +2869,11 @@ function destroySubtree(tileset, tile) { root.children = []; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function unloadTile(tileset, tile) { tileset.tileUnload.raiseEvent(tile); tileset._statistics.decrementLoadCounts(tile.content); @@ -2810,6 +2881,11 @@ function unloadTile(tileset, tile) { tile.unloadContent(); } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + */ function destroyTile(tileset, tile) { tileset._cache.unloadTile(tileset, tile, unloadTile); tile.destroy(); @@ -2828,8 +2904,11 @@ Cesium3DTileset.prototype.trimLoadedTiles = function () { this._cache.trim(); }; -/////////////////////////////////////////////////////////////////////////// - +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function raiseLoadProgressEvent(tileset, frameState) { const statistics = tileset._statistics; const statisticsLast = tileset._statisticsLast; @@ -2879,6 +2958,10 @@ function raiseLoadProgressEvent(tileset, frameState) { } } +/** + * @private + * @param {Cesium3DTileset} tileset + */ function resetMinimumMaximum(tileset) { tileset._heatmap.resetMinimumMaximum(); tileset._minimumPriority.depth = Number.MAX_VALUE; @@ -2891,27 +2974,40 @@ function resetMinimumMaximum(tileset) { tileset._maximumPriority.reverseScreenSpaceError = -Number.MAX_VALUE; } +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ function detectModelMatrixChanged(tileset, frameState) { if ( - frameState.frameNumber !== tileset._updatedModelMatrixFrame || - !defined(tileset._previousModelMatrix) + frameState.frameNumber === tileset._updatedModelMatrixFrame && + defined(tileset._previousModelMatrix) ) { - tileset._updatedModelMatrixFrame = frameState.frameNumber; - tileset._modelMatrixChanged = !Matrix4.equals( + return; + } + + tileset._updatedModelMatrixFrame = frameState.frameNumber; + tileset._modelMatrixChanged = !Matrix4.equals( + tileset.modelMatrix, + tileset._previousModelMatrix + ); + if (tileset._modelMatrixChanged) { + tileset._previousModelMatrix = Matrix4.clone( tileset.modelMatrix, tileset._previousModelMatrix ); - if (tileset._modelMatrixChanged) { - tileset._previousModelMatrix = Matrix4.clone( - tileset.modelMatrix, - tileset._previousModelMatrix - ); - } } } -/////////////////////////////////////////////////////////////////////////// - +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + * @param {Cesium3DTilesetStatistics} passStatistics + * @param {object} passOptions + * @returns {boolean} + */ function update(tileset, frameState, passStatistics, passOptions) { if (frameState.mode === SceneMode.MORPHING) { return false; @@ -2950,8 +3046,7 @@ function update(tileset, frameState, passStatistics, passOptions) { if (isRender) { const credits = tileset._credits; if (defined(credits) && statistics.selected !== 0) { - const length = credits.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < credits.length; ++i) { const credit = credits[i]; credit.showOnScreen = tileset._showCreditsOnScreen; frameState.creditDisplay.addCredit(credit); @@ -2964,6 +3059,7 @@ function update(tileset, frameState, passStatistics, passOptions) { /** * @private + * @param {FrameState} frameState */ Cesium3DTileset.prototype.update = function (frameState) { this.updateForPass(frameState, frameState.tilesetPassState); @@ -2971,6 +3067,8 @@ Cesium3DTileset.prototype.update = function (frameState) { /** * @private + * @param {FrameState} frameState + * @param {object} tilesetPassState */ Cesium3DTileset.prototype.updateForPass = function ( frameState, From 456f01c9057de46c7f036f1bd6300f104342f176 Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Tue, 28 Feb 2023 09:53:06 +0800 Subject: [PATCH 505/679] add minimumPickingTerrainDistanceWithInertia --- .../engine/Source/Scene/ScreenSpaceCameraController.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index ba2b91264bf..5d592c00670 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -223,6 +223,12 @@ function ScreenSpaceCameraController(scene) { */ this.minimumPickingTerrainHeight = 150000.0; this._minimumPickingTerrainHeight = this.minimumPickingTerrainHeight; + /** + * The minimum distance the camera must be before testing for collision with terrain when zoom with inertia. + * @type {number} + * @default 4000.0 + */ + this.minimumPickingTerrainDistanceWithInertia = 4000.0; /** * The minimum height the camera must be before testing for collision with terrain. * @type {number} @@ -2191,7 +2197,9 @@ function zoom3D(controller, startPosition, movement) { zoom3DCartographic ).height; - const approachingCollision = Math.abs(preIntersectionDistance) < 4000; + const approachingCollision = + Math.abs(preIntersectionDistance) < + controller.minimumPickingTerrainDistanceWithInertia; const needPickGlobe = inertiaMovement ? approachingCollision From c6931d1c1cad46d0507f87dc57d9f0abe030ef95 Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Tue, 28 Feb 2023 12:46:34 +0100 Subject: [PATCH 506/679] CreditDisplay.js: appendCss() modify to add styles to shadowRoot if found --- packages/engine/Source/Scene/CreditDisplay.js | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 0649d655236..f46ab9a02bc 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -174,7 +174,7 @@ function addStyle(selector, styles) { return style; } -function appendCss() { +function appendCss(container) { let style = ""; style += addStyle(".cesium-credit-lightbox-overlay", { display: "none", @@ -270,10 +270,23 @@ function appendCss() { } ); - const head = document.head; + function getShadowRoot(container) { + if (container.shadowRoot) { + return container.shadowRoot; + } + if (container.getRootNode) { + const root = container.getRootNode(); + if (root instanceof ShadowRoot) { + return root; + } + } + return undefined; + } + + const shadowRootOrDocumentHead = getShadowRoot(container) || document.head; const css = document.createElement("style"); css.innerHTML = style; - head.insertBefore(css, head.firstChild); + shadowRootOrDocumentHead.appendChild(css); } /** @@ -343,7 +356,7 @@ function CreditDisplay(container, delimiter, viewport) { expandLink.textContent = "Data attribution"; container.appendChild(expandLink); - appendCss(); + appendCss(container); const cesiumCredit = Credit.clone(CreditDisplay.cesiumCredit); this._delimiter = defaultValue(delimiter, " • "); From eeae9a3cedc61b3b5c3ebb47217527b2476e66e7 Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Wed, 1 Mar 2023 15:08:45 +0100 Subject: [PATCH 507/679] add my name to CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 80243bd7dd1..1860e5a75cc 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -345,3 +345,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [JiaoJianing](https://github.com/JiaoJianing) - [Southjor](https://github.com/Southjor) - [Lakshmipriya](https://github.com/Lakshmi0710) +- [Rudolf Farkas](https://github.com/rudifa) From eb71297f11c2a63a194731c2b68bd53d5971802f Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Mar 2023 09:23:20 -0500 Subject: [PATCH 508/679] Updates for 1.103 release --- CHANGES.md | 17 ++++++++++++----- ThirdParty.json | 6 +++--- package.json | 8 ++++---- packages/engine/Source/Core/Ion.js | 2 +- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4ba90ba3635..e46f149c1f3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,19 +4,26 @@ #### @cesium/engine -#### Major Announcements :loudspeaker: - ##### Additions :tada: - Added smooth zoom with mouse wheel. [#11062](https://github.com/CesiumGS/cesium/pull/11062) +- Enabled lighting on voxels with BOX shape. [#11076](https://github.com/CesiumGS/cesium/pull/11076) ##### Fixes :wrench: +- Fixed browser warning for `willReadFrequently` option. [#11025](https://github.com/CesiumGS/cesium/issues/11025) +- Replaced constructor types with primitive types in JSDoc and generated TypeScript definitions. [#11080](https://github.com/CesiumGS/cesium/pull/11080) +- Adjusted render order of voxels and opaque entities. [#11120](https://github.com/CesiumGS/cesium/pull/11120) +- Fixed artifacts on edges of voxels with BOX shape. [#11050](https://github.com/CesiumGS/cesium/pull/11050) +- Fixed initial textures visibility for particle systems. [#11099](https://github.com/CesiumGS/cesium/pull/11099) - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) - Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) -- Replace constructor types with primitive types in JSDoc. [#11080](https://github.com/CesiumGS/cesium/pull/11080) -- Fixed browser warning for `willReadFrequently` option. [#11025](https://github.com/CesiumGS/cesium/issues/11025) -- Fixed textures visibility for particle systems. [#11099](https://github.com/CesiumGS/cesium/pull/11099) + +#### @cesium/widgets + +##### Fixes :wrench: + +- Replaced constructor types with primitive types in JSDoc and generated TypeScript definitions. [#11080](https://github.com/CesiumGS/cesium/pull/11080) ### 1.102 - 2023-02-01 diff --git a/ThirdParty.json b/ThirdParty.json index c1a2f184970..24aa6825dc1 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -36,7 +36,7 @@ "license": [ "Apache-2.0" ], - "version": "2.4.3", + "version": "2.4.5", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -45,7 +45,7 @@ "license": [ "Apache-2.0" ], - "version": "1.5.5", + "version": "1.5.6", "url": "https://www.npmjs.com/package/draco3d" }, { @@ -150,7 +150,7 @@ "license": [ "BSD-3-Clause" ], - "version": "7.2.0", + "version": "7.2.2", "url": "https://www.npmjs.com/package/protobufjs" }, { diff --git a/package.json b/package.json index dc47a364144..2c82aac775f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.102.0", + "version": "1.103.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.0.0", - "@cesium/widgets": "2.0.0" + "@cesium/engine": "2.1.0", + "@cesium/widgets": "2.1.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.276.0", @@ -167,4 +167,4 @@ "packages/engine", "packages/widgets" ] -} +} \ No newline at end of file diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index f566d49ac37..30ccb28c53d 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,7 +4,7 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3NTUwMzYxOS04YmYzLTRkMzAtYjIyMy03ZmY3MjExZWNiNzciLCJpZCI6MjU5LCJpYXQiOjE2NzUyNzM5NjF9.rR_X1Phio3WgkIiwLJfSPMVTJEdSHKzj6GY9oNwttfo"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4ZTMwYjM0Yy1lYTdkLTQ5YjEtOTUyYS01Y2YxMjE5OWJjMmEiLCJpZCI6MjU5LCJpYXQiOjE2Nzc2Nzk3MTZ9.OGOiqPh0He1XDVU6azp_c5w3jJcmPXcA1briVUcyrvQ"; /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/package.json b/packages/engine/package.json index 6c53c51ce46..b69507f5fa0 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "2.0.0", + "version": "2.1.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 9b4524f050d..9dc62ba1b8d 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "2.0.0", + "version": "2.1.0", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "2.0.0", + "@cesium/engine": "2.1.0", "nosleep.js": "^0.12.0" }, "type": "module", From f06252a4e69b4455e769b06fcb685a87c7d016ba Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Mar 2023 09:42:23 -0500 Subject: [PATCH 509/679] Fix ParticleSystemSpec --- packages/engine/Specs/Scene/ParticleSystemSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Specs/Scene/ParticleSystemSpec.js b/packages/engine/Specs/Scene/ParticleSystemSpec.js index c7f722e1f7c..28893459370 100644 --- a/packages/engine/Specs/Scene/ParticleSystemSpec.js +++ b/packages/engine/Specs/Scene/ParticleSystemSpec.js @@ -370,7 +370,7 @@ describe("Scene/ParticleSystem", function () { new ParticleSystem({ image: greenImage, emitter: new CircleEmitter(1.0), - emissoinRate: 10000, + emissionRate: 10000, imageSize: new Cartesian2(100, 100), }) ); From 185ec8c7089849852a4ac463bb656ea81f05d1a7 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Mar 2023 11:31:08 -0500 Subject: [PATCH 510/679] Add docs and clean up in Cesium3DTilesTraversal --- .../Source/Scene/Cesium3DTilesetTraversal.js | 75 +++++++++++-------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 4b5c8c2cc81..8af1a012bd8 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -142,6 +142,7 @@ function executeBaseAndSkipTraversal(tileset, root, frameState) { * The private ._skipLevelOfDetail flag on a Cesium3DTileset is updated in * Cesium3DTileset.prototype.prePassesUpdate to confirm if skipping is actually * possible and allowed, even when the public .skipLevelOfDetail flag is true + * * @private * @param {Cesium3DTileset} tileset * @returns {boolean} Whether to do LOD skipping @@ -166,20 +167,22 @@ function addEmptyTile(tileset, tile) { * @param {FrameState} frameState */ function selectTile(tileset, tile, frameState) { - if (tile.contentVisibility(frameState) !== Intersect.OUTSIDE) { - const tileContent = tile.content; - if (tileContent.featurePropertiesDirty) { - // A feature's property in this tile changed, the tile needs to be re-styled. - tileContent.featurePropertiesDirty = false; - tile.lastStyleTime = 0; // Force applying the style to this tile - tileset._selectedTilesToStyle.push(tile); - } else if (tile._selectedFrame < frameState.frameNumber - 1) { - // Tile is newly selected; it is selected this frame, but was not selected last frame. - tileset._selectedTilesToStyle.push(tile); - } - tile._selectedFrame = frameState.frameNumber; - tileset._selectedTiles.push(tile); + if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { + return; + } + + const tileContent = tile.content; + if (tileContent.featurePropertiesDirty) { + // A feature's property in this tile changed, the tile needs to be re-styled. + tileContent.featurePropertiesDirty = false; + tile.lastStyleTime = 0; // Force applying the style to this tile + tileset._selectedTilesToStyle.push(tile); + } else if (tile._selectedFrame < frameState.frameNumber - 1) { + // Tile is newly selected; it is selected this frame, but was not selected last frame. + tileset._selectedTilesToStyle.push(tile); } + tile._selectedFrame = frameState.frameNumber; + tileset._selectedTiles.push(tile); } /** @@ -339,6 +342,8 @@ function isOnScreenLongEnough(tileset, tile, frameState) { } /** + * Add a tile to the list of requested tiles, if appropriate + * * @private * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile @@ -367,6 +372,8 @@ function loadTile(tileset, tile, frameState) { } /** + * Wrap Cesium3DTile.prototype.updateVisibility to avoid repeated updates + * * @private * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile @@ -393,8 +400,7 @@ function updateVisibility(tileset, tile, frameState) { function anyChildrenVisible(tileset, tile, frameState) { let anyVisible = false; const children = tile.children; - const length = children.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { const child = children[i]; updateVisibility(tileset, child, frameState); anyVisible = anyVisible || isVisible(child); @@ -492,6 +498,8 @@ function updateTile(tileset, tile, frameState) { } /** + * Update links to the ancestor tiles that have content + * * @private * @param {Cesium3DTile} tile * @param {FrameState} frameState @@ -500,21 +508,24 @@ function updateTileAncestorContentLinks(tile, frameState) { tile._ancestorWithContent = undefined; tile._ancestorWithContentAvailable = undefined; - const parent = tile.parent; - if (defined(parent)) { - // ancestorWithContent is an ancestor that has content or has the potential to have - // content. Used in conjunction with tileset.skipLevels to know when to skip a tile. - // ancestorWithContentAvailable is an ancestor that is rendered if a desired tile is not loaded. - const hasContent = - !hasUnloadedContent(parent) || - parent._requestedFrame === frameState.frameNumber; - tile._ancestorWithContent = hasContent - ? parent - : parent._ancestorWithContent; - tile._ancestorWithContentAvailable = parent.contentAvailable - ? parent - : parent._ancestorWithContentAvailable; // Links a descendant up to its contentAvailable ancestor as the traversal progresses. + const { parent } = tile; + if (!defined(parent)) { + return; } + const parentHasContent = + !hasUnloadedContent(parent) || + parent._requestedFrame === frameState.frameNumber; + + // ancestorWithContent is an ancestor that has content or has the potential to have + // content. Used in conjunction with tileset.skipLevels to know when to skip a tile. + tile._ancestorWithContent = parentHasContent + ? parent + : parent._ancestorWithContent; + + // ancestorWithContentAvailable is an ancestor that is rendered if a desired tile is not loaded + tile._ancestorWithContentAvailable = parent.contentAvailable + ? parent + : parent._ancestorWithContentAvailable; } /** @@ -601,9 +612,8 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { let minIndex = -1; let minimumPriority = Number.MAX_VALUE; - let child; for (let i = 0; i < children.length; ++i) { - child = children[i]; + const child = children[i]; if (isVisible(child)) { stack.push(child); if (child._foveatedFactor < minimumPriority) { @@ -658,8 +668,7 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { ); for (let i = 0; i < children.length; ++i) { - child = children[i]; - child._priorityHolder = priorityHolder; + children[i]._priorityHolder = priorityHolder; } } From 94cf13bd0616f075b310943cf7287158488b5f40 Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Wed, 1 Mar 2023 21:17:10 +0100 Subject: [PATCH 511/679] CHANGES.md: add Fixed ... [#10907] --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 4ba90ba3635..5f108864bf3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ ##### Fixes :wrench: +- Fixed Cesium.Viewer instantiated inside my lit component: CreditDisplay is missing its styles [#10907](https://github.com/CesiumGS/cesium/issues/10907) - Fixed Primitive.getGeometryInstanceAttributes cache acquisition speed. [#11066](https://github.com/CesiumGS/cesium/issues/11066) - Fixed requestWebgl1 hint error in context. [#11082](https://github.com/CesiumGS/cesium/issues/11082) - Replace constructor types with primitive types in JSDoc. [#11080](https://github.com/CesiumGS/cesium/pull/11080) From e2d391a0fb76ffb80dead945260a74bde4c10ac1 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Mar 2023 15:39:08 -0500 Subject: [PATCH 512/679] Simplify function signatures in Cesium3DTilesetTraversal --- .../engine/Source/Scene/Cesium3DTileset.js | 9 +- .../Source/Scene/Cesium3DTilesetTraversal.js | 216 ++++++++---------- 2 files changed, 99 insertions(+), 126 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 5b531d8c111..f8532ca50e7 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -2056,8 +2056,7 @@ Cesium3DTileset.prototype.loadTileset = function ( this._allTilesAdditive && tile.refine === Cesium3DTileRefine.ADD; const children = tile._header.children; if (defined(children)) { - const length = children.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { const childHeader = children[i]; const childTile = makeTile(this, resource, childHeader, tile); tile.children.push(childTile); @@ -2857,8 +2856,7 @@ function destroySubtree(tileset, tile) { while (stack.length > 0) { tile = stack.pop(); const children = tile.children; - const length = children.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { stack.push(children[i]); } if (tile !== root) { @@ -3198,8 +3196,7 @@ Cesium3DTileset.prototype.destroy = function () { tile.destroy(); const children = tile.children; - const length = children.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { stack.push(children[i]); } } diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 8af1a012bd8..ac768266113 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -51,7 +51,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { tileset._hasMixedContent = false; const root = tileset.root; - updateTile(tileset, root, frameState); + updateTile(root, frameState); // The root tile is not visible if (!isVisible(root)) { @@ -67,11 +67,11 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { } if (!skipLevelOfDetail(tileset)) { - executeBaseTraversal(tileset, root, frameState); + executeBaseTraversal(root, frameState); } else if (tileset.immediatelyLoadDesiredLevelOfDetail) { - executeSkipTraversal(tileset, root, frameState); + executeSkipTraversal(root, frameState); } else { - executeBaseAndSkipTraversal(tileset, root, frameState); + executeBaseAndSkipTraversal(root, frameState); } traversal.stack.trim(traversal.stackMaximumLength); @@ -102,40 +102,37 @@ function isVisible(tile) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState */ -function executeBaseTraversal(tileset, root, frameState) { - const baseScreenSpaceError = tileset._maximumScreenSpaceError; - executeTraversal(tileset, root, baseScreenSpaceError, frameState); +function executeBaseTraversal(root, frameState) { + const baseScreenSpaceError = root.tileset._maximumScreenSpaceError; + executeTraversal(root, baseScreenSpaceError, frameState); } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState */ -function executeSkipTraversal(tileset, root, frameState) { +function executeSkipTraversal(root, frameState) { const baseScreenSpaceError = Number.MAX_VALUE; - executeTraversal(tileset, root, baseScreenSpaceError, frameState); - traverseAndSelect(tileset, root, frameState); + executeTraversal(root, baseScreenSpaceError, frameState); + traverseAndSelect(root, frameState); } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState */ -function executeBaseAndSkipTraversal(tileset, root, frameState) { +function executeBaseAndSkipTraversal(root, frameState) { const baseScreenSpaceError = Math.max( - tileset.baseScreenSpaceError, - tileset.maximumScreenSpaceError + root.tileset.baseScreenSpaceError, + root.tileset.maximumScreenSpaceError ); - executeTraversal(tileset, root, baseScreenSpaceError, frameState); - traverseAndSelect(tileset, root, frameState); + executeTraversal(root, baseScreenSpaceError, frameState); + traverseAndSelect(root, frameState); } /** @@ -153,28 +150,18 @@ function skipLevelOfDetail(tileset) { /** * @private - * @param {Cesium3DTileset} tileset - * @param {Cesium3DTile} tile - */ -function addEmptyTile(tileset, tile) { - tileset._emptyTiles.push(tile); -} - -/** - * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function selectTile(tileset, tile, frameState) { +function selectTile(tile, frameState) { if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { return; } - const tileContent = tile.content; - if (tileContent.featurePropertiesDirty) { + const { content, tileset } = tile; + if (content.featurePropertiesDirty) { // A feature's property in this tile changed, the tile needs to be re-styled. - tileContent.featurePropertiesDirty = false; + content.featurePropertiesDirty = false; tile.lastStyleTime = 0; // Force applying the style to this tile tileset._selectedTilesToStyle.push(tile); } else if (tile._selectedFrame < frameState.frameNumber - 1) { @@ -187,11 +174,10 @@ function selectTile(tileset, tile, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState */ -function selectDescendants(tileset, root, frameState) { +function selectDescendants(root, frameState) { const stack = descendantTraversal.stack; stack.push(root); while (stack.length > 0) { @@ -205,9 +191,9 @@ function selectDescendants(tileset, root, frameState) { const child = children[i]; if (isVisible(child)) { if (child.contentAvailable) { - updateTile(tileset, child, frameState); - touchTile(tileset, child, frameState); - selectTile(tileset, child, frameState); + updateTile(child, frameState); + touchTile(child, frameState); + selectTile(child, frameState); } else if (child._depth - root._depth < descendantSelectionDepth) { // Continue traversing, but not too far stack.push(child); @@ -219,15 +205,14 @@ function selectDescendants(tileset, root, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function selectDesiredTile(tileset, tile, frameState) { - if (!skipLevelOfDetail(tileset)) { +function selectDesiredTile(tile, frameState) { + if (!skipLevelOfDetail(tile.tileset)) { if (tile.contentAvailable) { // The tile can be selected right away and does not require traverseAndSelect - selectTile(tileset, tile, frameState); + selectTile(tile, frameState); } return; } @@ -242,44 +227,43 @@ function selectDesiredTile(tileset, tile, frameState) { } else { // If no ancestors are ready traverse down and select tiles to minimize empty regions. // This happens often for immediatelyLoadDesiredLevelOfDetail where parent tiles are not necessarily loaded before zooming out. - selectDescendants(tileset, tile, frameState); + selectDescendants(tile, frameState); } } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function visitTile(tileset, tile, frameState) { - ++tileset._statistics.visited; +function visitTile(tile, frameState) { + ++tile.tileset._statistics.visited; tile._visitedFrame = frameState.frameNumber; } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function touchTile(tileset, tile, frameState) { +function touchTile(tile, frameState) { if (tile._touchedFrame === frameState.frameNumber) { // Prevents another pass from touching the frame again return; } - tileset._cache.touch(tile); + tile.tileset._cache.touch(tile); tile._touchedFrame = frameState.frameNumber; } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile */ -function updateMinimumMaximumPriority(tileset, tile) { - const maximumPriority = tileset._maximumPriority; - const minimumPriority = tileset._minimumPriority; +function updateMinimumMaximumPriority(tile) { + const { + _maximumPriority: maximumPriority, + _minimumPriority: minimumPriority, + } = tile.tileset; const priorityHolder = tile._priorityHolder; maximumPriority.distance = Math.max( @@ -314,12 +298,12 @@ function updateMinimumMaximumPriority(tileset, tile) { * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState * @returns {boolean} */ -function isOnScreenLongEnough(tileset, tile, frameState) { +function isOnScreenLongEnough(tile, frameState) { + const { tileset } = tile; if (!tileset._cullRequestsWhileMoving) { return true; } @@ -345,11 +329,11 @@ function isOnScreenLongEnough(tileset, tile, frameState) { * Add a tile to the list of requested tiles, if appropriate * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function loadTile(tileset, tile, frameState) { +function loadTile(tile, frameState) { + const { tileset } = tile; if ( tile._requestedFrame === frameState.frameNumber || (!hasUnloadedContent(tile) && !tile.contentExpired) @@ -357,7 +341,7 @@ function loadTile(tileset, tile, frameState) { return; } - if (!isOnScreenLongEnough(tileset, tile, frameState)) { + if (!isOnScreenLongEnough(tile, frameState)) { return; } @@ -375,34 +359,33 @@ function loadTile(tileset, tile, frameState) { * Wrap Cesium3DTile.prototype.updateVisibility to avoid repeated updates * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function updateVisibility(tileset, tile, frameState) { - if (tile._updatedVisibilityFrame === tileset._updatedVisibilityFrame) { +function updateVisibility(tile, frameState) { + const updatedVisibilityFrame = tile.tileset._updatedVisibilityFrame; + if (tile._updatedVisibilityFrame === updatedVisibilityFrame) { // Return early if visibility has already been checked during the traversal. // The visibility may have already been checked if the cullWithChildrenBounds optimization is used. return; } tile.updateVisibility(frameState); - tile._updatedVisibilityFrame = tileset._updatedVisibilityFrame; + tile._updatedVisibilityFrame = updatedVisibilityFrame; } /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState * @returns {boolean} */ -function anyChildrenVisible(tileset, tile, frameState) { +function anyChildrenVisible(tile, frameState) { let anyVisible = false; const children = tile.children; for (let i = 0; i < children.length; ++i) { const child = children[i]; - updateVisibility(tileset, child, frameState); + updateVisibility(child, frameState); anyVisible = anyVisible || isVisible(child); } return anyVisible; @@ -410,13 +393,12 @@ function anyChildrenVisible(tileset, tile, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState * @returns {boolean} */ -function meetsScreenSpaceErrorEarly(tileset, tile, frameState) { - const parent = tile.parent; +function meetsScreenSpaceErrorEarly(tile, frameState) { + const { parent, tileset } = tile; if ( !defined(parent) || parent.hasTilesetContent || @@ -435,12 +417,11 @@ function meetsScreenSpaceErrorEarly(tileset, tile, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function updateTileVisibility(tileset, tile, frameState) { - updateVisibility(tileset, tile, frameState); +function updateTileVisibility(tile, frameState) { + updateVisibility(tile, frameState); if (!isVisible(tile)) { return; @@ -452,12 +433,12 @@ function updateTileVisibility(tileset, tile, frameState) { // The root tile may be culled by the children bounds optimization in which // case this tile should also be culled. const child = tile.children[0]; - updateTileVisibility(tileset, child, frameState); + updateTileVisibility(child, frameState); tile._visible = child._visible; return; } - if (meetsScreenSpaceErrorEarly(tileset, tile, frameState)) { + if (meetsScreenSpaceErrorEarly(tile, frameState)) { tile._visible = false; return; } @@ -468,8 +449,8 @@ function updateTileVisibility(tileset, tile, frameState) { tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; if (replace && useOptimization && hasChildren) { - if (!anyChildrenVisible(tileset, tile, frameState)) { - ++tileset._statistics.numberOfTilesCulledWithChildrenUnion; + if (!anyChildrenVisible(tile, frameState)) { + ++tile.tileset._statistics.numberOfTilesCulledWithChildrenUnion; tile._visible = false; return; } @@ -478,19 +459,18 @@ function updateTileVisibility(tileset, tile, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function updateTile(tileset, tile, frameState) { +function updateTile(tile, frameState) { // Reset some of the tile's flags and re-evaluate visibility - updateTileVisibility(tileset, tile, frameState); + updateTileVisibility(tile, frameState); tile.updateExpiration(); // Request priority tile._wasMinPriorityChild = false; tile._priorityHolder = tile; - updateMinimumMaximumPriority(tileset, tile); + updateMinimumMaximumPriority(tile); // SkipLOD tile._shouldSelect = false; @@ -583,18 +563,17 @@ function sortChildrenByDistanceToCamera(a, b) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {ManagedArray} stack * @param {FrameState} frameState * @returns {boolean} */ -function updateAndPushChildren(tileset, tile, stack, frameState) { +function updateAndPushChildren(tile, stack, frameState) { const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const children = tile.children; + const { tileset, children } = tile; for (let i = 0; i < children.length; ++i) { - updateTile(tileset, children[i], frameState); + updateTile(children[i], frameState); } // Sort by distance to take advantage of early Z and reduce artifacts for skipLevelOfDetail @@ -628,15 +607,15 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { minIndex = i; minimumPriority = child._foveatedFactor; } - loadTile(tileset, child, frameState); - touchTile(tileset, child, frameState); + loadTile(child, frameState); + touchTile(child, frameState); } if (checkRefines) { let childRefines; if (!child._inRequestVolume) { childRefines = false; } else if (hasEmptyContent(child)) { - childRefines = executeEmptyTraversal(tileset, child, frameState); + childRefines = executeEmptyTraversal(child, frameState); } else { childRefines = child.contentAvailable; } @@ -677,12 +656,12 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {number} baseScreenSpaceError * @returns {boolean} */ -function inBaseTraversal(tileset, tile, baseScreenSpaceError) { +function inBaseTraversal(tile, baseScreenSpaceError) { + const { tileset } = tile; if (!skipLevelOfDetail(tileset)) { return true; } @@ -702,11 +681,10 @@ function inBaseTraversal(tileset, tile, baseScreenSpaceError) { /** * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @returns {boolean} */ -function canTraverse(tileset, tile) { +function canTraverse(tile) { if (tile.children.length === 0) { return false; } @@ -715,7 +693,7 @@ function canTraverse(tileset, tile) { // Don't traverse if the subtree is expired because it will be destroyed return !tile.contentExpired; } - return tile._screenSpaceError > tileset._maximumScreenSpaceError; + return tile._screenSpaceError > tile.tileset._maximumScreenSpaceError; } /** @@ -727,12 +705,12 @@ function canTraverse(tileset, tile) { * and rendering children and parent tiles simultaneously. * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {number} baseScreenSpaceError * @param {FrameState} frameState */ -function executeTraversal(tileset, root, baseScreenSpaceError, frameState) { +function executeTraversal(root, baseScreenSpaceError, frameState) { + const { tileset } = root; const stack = traversal.stack; stack.push(root); @@ -745,12 +723,12 @@ function executeTraversal(tileset, root, baseScreenSpaceError, frameState) { const tile = stack.pop(); updateTileAncestorContentLinks(tile, frameState); - const baseTraversal = inBaseTraversal(tileset, tile, baseScreenSpaceError); + const baseTraversal = inBaseTraversal(tile, baseScreenSpaceError); const parent = tile.parent; const parentRefines = !defined(parent) || parent._refines; - const refines = canTraverse(tileset, tile) - ? updateAndPushChildren(tileset, tile, stack, frameState) && parentRefines + const refines = canTraverse(tile) + ? updateAndPushChildren(tile, stack, frameState) && parentRefines : false; const stoppedRefining = !refines && parentRefines; @@ -759,35 +737,35 @@ function executeTraversal(tileset, root, baseScreenSpaceError, frameState) { // Add empty tile just to show its debug bounding volume // If the tile has tileset content load the external tileset // If the tile cannot refine further select its nearest loaded ancestor - addEmptyTile(tileset, tile); - loadTile(tileset, tile, frameState); + tileset._emptyTiles.push(tile); + loadTile(tile, frameState); if (stoppedRefining) { - selectDesiredTile(tileset, tile, frameState); + selectDesiredTile(tile, frameState); } } else if (tile.refine === Cesium3DTileRefine.ADD) { // Additive tiles are always loaded and selected - selectDesiredTile(tileset, tile, frameState); - loadTile(tileset, tile, frameState); + selectDesiredTile(tile, frameState); + loadTile(tile, frameState); } else if (tile.refine === Cesium3DTileRefine.REPLACE) { if (baseTraversal) { // Always load tiles in the base traversal // Select tiles that can't refine further - loadTile(tileset, tile, frameState); + loadTile(tile, frameState); if (stoppedRefining) { - selectDesiredTile(tileset, tile, frameState); + selectDesiredTile(tile, frameState); } } else if (stoppedRefining) { // In skip traversal, load and select tiles that can't refine further - selectDesiredTile(tileset, tile, frameState); - loadTile(tileset, tile, frameState); + selectDesiredTile(tile, frameState); + loadTile(tile, frameState); } else if (reachedSkippingThreshold(tileset, tile)) { // In skip traversal, load tiles that aren't skipped. In practice roughly half the tiles stay unloaded. - loadTile(tileset, tile, frameState); + loadTile(tile, frameState); } } - visitTile(tileset, tile, frameState); - touchTile(tileset, tile, frameState); + visitTile(tile, frameState); + touchTile(tile, frameState); tile._refines = refines; } } @@ -797,12 +775,11 @@ function executeTraversal(tileset, root, baseScreenSpaceError, frameState) { * Ignores visibility. * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState * @returns {boolean} */ -function executeEmptyTraversal(tileset, root, frameState) { +function executeEmptyTraversal(root, frameState) { let allDescendantsLoaded = true; const stack = emptyTraversal.stack; stack.push(root); @@ -819,7 +796,7 @@ function executeEmptyTraversal(tileset, root, frameState) { // Only traverse if the tile is empty - traversal stop at descendants with content const emptyContent = hasEmptyContent(tile); - const traverse = emptyContent && canTraverse(tileset, tile); + const traverse = emptyContent && canTraverse(tile); const emptyLeaf = emptyContent && tile.children.length === 0; // Traversal stops but the tile does not have content yet @@ -829,11 +806,11 @@ function executeEmptyTraversal(tileset, root, frameState) { allDescendantsLoaded = false; } - updateTile(tileset, tile, frameState); + updateTile(tile, frameState); if (!isVisible(tile)) { // Load tiles that aren't visible since they are still needed for the parent to refine - loadTile(tileset, tile, frameState); - touchTile(tileset, tile, frameState); + loadTile(tile, frameState); + touchTile(tile, frameState); } if (traverse) { @@ -864,11 +841,10 @@ function executeEmptyTraversal(tileset, root, frameState) { * selected tiles that is deeper than 7. This is not very likely. * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} root * @param {FrameState} frameState */ -function traverseAndSelect(tileset, root, frameState) { +function traverseAndSelect(root, frameState) { const { stack, ancestorStack } = selectionTraversal; let lastAncestor; @@ -891,7 +867,7 @@ function traverseAndSelect(tileset, root, frameState) { if (waitingTile !== lastAncestor) { waitingTile._finalResolution = false; } - selectTile(tileset, waitingTile, frameState); + selectTile(waitingTile, frameState); continue; } } @@ -902,19 +878,19 @@ function traverseAndSelect(tileset, root, frameState) { continue; } - const traverse = canTraverse(tileset, tile); + const traverse = canTraverse(tile); if (tile._shouldSelect) { if (tile.refine === Cesium3DTileRefine.ADD) { - selectTile(tileset, tile, frameState); + selectTile(tile, frameState); } else { tile._selectionDepth = ancestorStack.length; if (tile._selectionDepth > 0) { - tileset._hasMixedContent = true; + tile.tileset._hasMixedContent = true; } lastAncestor = tile; if (!traverse) { - selectTile(tileset, tile, frameState); + selectTile(tile, frameState); continue; } ancestorStack.push(tile); From 37ad09dc1fa49784d3a1e2970d87aa8dc56980ad Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 1 Mar 2023 17:15:01 -0500 Subject: [PATCH 513/679] Fix release publish step --- gulpfile.js | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 27ce4870f07..8b0691a9ae9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1088,29 +1088,32 @@ async function deployCesiumRelease(bucketName, s3Client, errors) { `Cesium version ${release.tag} up to date. Skipping release deployment.` ); } catch (error) { - // The current version is not uploaded - if (error.code === "NotFound") { - console.log("Updating cesium version..."); - const data = await download(release.url); - // upload and unzip contents - const key = posix.join(releaseDir, release.tag, "cesium.zip"); - await uploadObject(bucketName, s3Client, key, data, quiet); - const files = await decompress(data); - const limit = pLimit(5); - return Promise.all( - files.map((file) => { - return limit(() => { - if (file.path.startsWith("Apps")) { - // skip uploading apps and sandcastle - return; - } - - // Upload to release directory - const key = posix.join(releaseDir, release.tag, file.path); - return uploadObject(bucketName, s3Client, key, file.data, quiet); - }); - }) - ); + if (error.$metadata) { + const { httpStatusCode } = error.$metadata; + // The current version is not uploaded + if (httpStatusCode === 404) { + console.log("Updating cesium version..."); + const data = await download(release.url); + // upload and unzip contents + const key = posix.join(releaseDir, release.tag, "cesium.zip"); + await uploadObject(bucketName, s3Client, key, data, quiet); + const files = await decompress(data); + const limit = pLimit(5); + return Promise.all( + files.map((file) => { + return limit(async () => { + if (file.path.startsWith("Apps")) { + // skip uploading apps and sandcastle + return; + } + + // Upload to release directory + const key = posix.join(releaseDir, release.tag, file.path); + return uploadObject(bucketName, s3Client, key, file.data, quiet); + }); + }) + ); + } } // else, unexpected error From 5c1f128e04071a882afc1a69f6d652996a540f3c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 1 Mar 2023 18:29:42 -0500 Subject: [PATCH 514/679] Reduce indirection in Cesium3DTilesetTraversal --- .../Source/Scene/Cesium3DTilesetTraversal.js | 60 ++++--------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index ac768266113..12609ff12de 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -53,12 +53,10 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { const root = tileset.root; updateTile(root, frameState); - // The root tile is not visible if (!isVisible(root)) { return; } - // The tileset doesn't meet the SSE requirement, therefore the tree does not need to be rendered if ( root.getScreenSpaceError(frameState, true) <= tileset._maximumScreenSpaceError @@ -66,12 +64,16 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { return; } - if (!skipLevelOfDetail(tileset)) { - executeBaseTraversal(root, frameState); - } else if (tileset.immediatelyLoadDesiredLevelOfDetail) { - executeSkipTraversal(root, frameState); - } else { - executeBaseAndSkipTraversal(root, frameState); + const baseScreenSpaceError = !skipLevelOfDetail(tileset) + ? tileset._maximumScreenSpaceError + : tileset.immediatelyLoadDesiredLevelOfDetail + ? Number.MAX_VALUE + : Math.max(tileset.baseScreenSpaceError, tileset.maximumScreenSpaceError); + + executeTraversal(root, baseScreenSpaceError, frameState); + + if (skipLevelOfDetail(tileset)) { + traverseAndSelect(root, frameState); } traversal.stack.trim(traversal.stackMaximumLength); @@ -85,8 +87,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { // Update the priority for any requests found during traversal // Update after traversal so that min and max values can be used to normalize priority values const requestedTiles = tileset._requestedTiles; - const length = requestedTiles.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < requestedTiles.length; ++i) { requestedTiles[i].updatePriority(); } }; @@ -100,41 +101,6 @@ function isVisible(tile) { return tile._visible && tile._inRequestVolume; } -/** - * @private - * @param {Cesium3DTile} root - * @param {FrameState} frameState - */ -function executeBaseTraversal(root, frameState) { - const baseScreenSpaceError = root.tileset._maximumScreenSpaceError; - executeTraversal(root, baseScreenSpaceError, frameState); -} - -/** - * @private - * @param {Cesium3DTile} root - * @param {FrameState} frameState - */ -function executeSkipTraversal(root, frameState) { - const baseScreenSpaceError = Number.MAX_VALUE; - executeTraversal(root, baseScreenSpaceError, frameState); - traverseAndSelect(root, frameState); -} - -/** - * @private - * @param {Cesium3DTile} root - * @param {FrameState} frameState - */ -function executeBaseAndSkipTraversal(root, frameState) { - const baseScreenSpaceError = Math.max( - root.tileset.baseScreenSpaceError, - root.tileset.maximumScreenSpaceError - ); - executeTraversal(root, baseScreenSpaceError, frameState); - traverseAndSelect(root, frameState); -} - /** * The private ._skipLevelOfDetail flag on a Cesium3DTileset is updated in * Cesium3DTileset.prototype.prePassesUpdate to confirm if skipping is actually @@ -532,6 +498,7 @@ function hasUnloadedContent(tile) { * @private * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile + * @returns {boolean} */ function reachedSkippingThreshold(tileset, tile) { const ancestor = tile._ancestorWithContent; @@ -723,7 +690,6 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { const tile = stack.pop(); updateTileAncestorContentLinks(tile, frameState); - const baseTraversal = inBaseTraversal(tile, baseScreenSpaceError); const parent = tile.parent; const parentRefines = !defined(parent) || parent._refines; @@ -747,7 +713,7 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { selectDesiredTile(tile, frameState); loadTile(tile, frameState); } else if (tile.refine === Cesium3DTileRefine.REPLACE) { - if (baseTraversal) { + if (inBaseTraversal(tile, baseScreenSpaceError)) { // Always load tiles in the base traversal // Select tiles that can't refine further loadTile(tile, frameState); From b2b529183cfaa99d4d81122da3af23c025c5273c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Mar 2023 14:41:37 -0500 Subject: [PATCH 515/679] Fix docs for Cesium3DTile constructor --- packages/engine/Source/Scene/Cesium3DTile.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index cd85cf90cf5..1fb9138aa66 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -52,9 +52,10 @@ import Pass from "../Renderer/Pass.js"; * * @alias Cesium3DTile * @constructor - * @param {Cesium3DTileset} tileset - * @param {Resource} baseResource - * @param {Cesium3DTile} parent + * @param {Cesium3DTileset} tileset The tileset + * @param {Resource} baseResource The base resource for the tileset + * @param {object} header The JSON header for the tile + * @param {Cesium3DTile} parent The parent tile of the new tile */ function Cesium3DTile(tileset, baseResource, header, parent) { this._tileset = tileset; From d07eedc8d60247a94c4aee794f0154c9fa25408e Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Mar 2023 15:12:10 -0500 Subject: [PATCH 516/679] Fix contentExpired behavior broken in #db95418 --- packages/engine/Source/Scene/Cesium3DTileset.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index f8532ca50e7..a5042eabefe 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -2297,7 +2297,8 @@ function requestContent(tileset, tile) { return; } - const statistics = tileset._statistics; + const { statistics } = tileset; + const { contentExpired } = tile; const attemptedRequests = tile.requestContent(); if (attemptedRequests > 0) { @@ -2305,7 +2306,7 @@ function requestContent(tileset, tile) { return; } - if (tile.contentExpired) { + if (contentExpired) { if (tile.hasTilesetContent || tile.hasImplicitContent) { destroySubtree(tileset, tile); } else { From f65aa1ce0358c13dbb0095455175bdeeabd08fa7 Mon Sep 17 00:00:00 2001 From: Rudolf Farkas <rudi.farkas@gmail.com> Date: Thu, 2 Mar 2023 21:37:53 +0100 Subject: [PATCH 517/679] Update packages/engine/Source/Scene/CreditDisplay.js Co-authored-by: Gabby Getz <gabby@cesium.com> --- packages/engine/Source/Scene/CreditDisplay.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index f46ab9a02bc..43ae15db295 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -283,7 +283,7 @@ function appendCss(container) { return undefined; } - const shadowRootOrDocumentHead = getShadowRoot(container) || document.head; + const shadowRootOrDocumentHead = defaultValue(getShadowRoot(container), document.head); const css = document.createElement("style"); css.innerHTML = style; shadowRootOrDocumentHead.appendChild(css); From 572e5ef4dd75d9af07990e5337051593c434c520 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 2 Mar 2023 17:59:37 -0500 Subject: [PATCH 518/679] Minor clarifications in Cesium3DTilesetTraversal --- .../Source/Scene/Cesium3DTilesetTraversal.js | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 12609ff12de..7da76155fed 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -95,7 +95,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { /** * @private * @param {Cesium3DTile} tile - * @returns {boolean} Whether the tile is visible + * @returns {boolean} Whether the tile is within the current field of view */ function isVisible(tile) { return tile._visible && tile._inRequestVolume; @@ -115,6 +115,8 @@ function skipLevelOfDetail(tileset) { } /** + * Mark a tile as selected, and add it to the tileset's list of selected tiles + * * @private * @param {Cesium3DTile} tile * @param {FrameState} frameState @@ -139,6 +141,8 @@ function selectTile(tile, frameState) { } /** + * Mark descendant tiles for rendering, and update as needed + * * @private * @param {Cesium3DTile} root * @param {FrameState} frameState @@ -170,6 +174,10 @@ function selectDescendants(root, frameState) { } /** + * Mark a tile as selected if it has content available. + * If its content is not available, and we are skipping levels of detail, + * select an ancestor or descendant tile instead + * * @private * @param {Cesium3DTile} tile * @param {FrameState} frameState @@ -424,16 +432,16 @@ function updateTileVisibility(tile, frameState) { } /** + * Reset some of the tile's flags and re-evaluate visibility and priority + * * @private * @param {Cesium3DTile} tile * @param {FrameState} frameState */ function updateTile(tile, frameState) { - // Reset some of the tile's flags and re-evaluate visibility updateTileVisibility(tile, frameState); tile.updateExpiration(); - // Request priority tile._wasMinPriorityChild = false; tile._priorityHolder = tile; updateMinimumMaximumPriority(tile); @@ -495,10 +503,13 @@ function hasUnloadedContent(tile) { } /** + * Determine if a tile has reached the limit of level of detail skipping. + * If so, it should _not_ be skipped: it should be loaded and rendered + * * @private * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile - * @returns {boolean} + * @returns {boolean} true if this tile should not be skipped */ function reachedSkippingThreshold(tileset, tile) { const ancestor = tile._ancestorWithContent; @@ -622,6 +633,9 @@ function updateAndPushChildren(tile, stack, frameState) { } /** + * Determine if a tile is part of the base traversal. + * If not, this tile could be considered for level of detail skipping + * * @private * @param {Cesium3DTile} tile * @param {number} baseScreenSpaceError @@ -647,6 +661,9 @@ function inBaseTraversal(tile, baseScreenSpaceError) { } /** + * Determine if a tile can and should be traversed for children tiles that + * would contribute to rendering the current view + * * @private * @param {Cesium3DTile} tile * @returns {boolean} @@ -693,11 +710,11 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { const parent = tile.parent; const parentRefines = !defined(parent) || parent._refines; - const refines = canTraverse(tile) + tile._refines = canTraverse(tile) ? updateAndPushChildren(tile, stack, frameState) && parentRefines : false; - const stoppedRefining = !refines && parentRefines; + const stoppedRefining = !tile._refines && parentRefines; if (hasEmptyContent(tile)) { // Add empty tile just to show its debug bounding volume @@ -725,14 +742,13 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { selectDesiredTile(tile, frameState); loadTile(tile, frameState); } else if (reachedSkippingThreshold(tileset, tile)) { - // In skip traversal, load tiles that aren't skipped. In practice roughly half the tiles stay unloaded. + // In skip traversal, load tiles that aren't skipped loadTile(tile, frameState); } } visitTile(tile, frameState); touchTile(tile, frameState); - tile._refines = refines; } } From 63b52bf5114e43d5af57c254c4aa5e5c5063f6ed Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Fri, 3 Mar 2023 08:06:53 +0300 Subject: [PATCH 519/679] Fixed duplicate `rayStepLength` init --- packages/engine/Source/Shaders/AtmosphereCommon.glsl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 03eeb36df66..9a6c942fd97 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -69,15 +69,12 @@ void computeScattering( // The ray should end at the exit from the atmosphere or at the distance to the vertex, whichever is smaller. primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, lprl); + // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. + float rayPositionLength = primaryRayAtmosphereIntersect.start; // Sky vs horizon: constant step in one case, increasing step in the other case float rayStepLengthIncrease = (1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0); float rayStepLength = w_stop_gt_lprl * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0,float(PRIMARY_STEPS)); - - // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. - float rayStepLength = (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / float(PRIMARY_STEPS); - float rayPositionLength = primaryRayAtmosphereIntersect.start; - vec3 rayleighAccumulation = vec3(0.0); vec3 mieAccumulation = vec3(0.0); vec2 opticalDepth = vec2(0.0); From 3337b2f2ccc0a99185d3ffbe69ffaf328564c5ea Mon Sep 17 00:00:00 2001 From: Tengfei <tengfei@tengfei.fun> Date: Wed, 1 Mar 2023 00:26:23 +0800 Subject: [PATCH 520/679] Entity.merge does not overwrite _children. --- packages/engine/Source/DataSources/Entity.js | 7 ++++++- packages/engine/Specs/DataSources/EntitySpec.js | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index 6b00702c16e..774103a8298 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -597,7 +597,12 @@ Entity.prototype.merge = function (source) { //While source is required by the API to be an Entity, we internally call this method from the //constructor with an options object to configure initial custom properties. //So we need to ignore reserved-non-property. - if (name === "parent" || name === "name" || name === "availability") { + if ( + name === "parent" || + name === "name" || + name === "availability" || + name === "children" + ) { continue; } diff --git a/packages/engine/Specs/DataSources/EntitySpec.js b/packages/engine/Specs/DataSources/EntitySpec.js index a220e611e70..6d46f7b3f5d 100644 --- a/packages/engine/Specs/DataSources/EntitySpec.js +++ b/packages/engine/Specs/DataSources/EntitySpec.js @@ -213,6 +213,15 @@ describe("DataSources/Entity", function () { expect(entity.availability).toBe(interval); }); + it("merge does not overwrite _children", function () { + const entity = new Entity(); + + entity.merge({ + children: true, + }); + expect(entity._children).toEqual([]); + }); + it("merge works with custom properties.", function () { const propertyName = "customProperty"; const value = "fizzbuzz"; From 16eb8eb8b88f2fbd3f3eb17f3f94e1fb2d65c988 Mon Sep 17 00:00:00 2001 From: Tengfei <tengfei@tengfei.fun> Date: Wed, 1 Mar 2023 20:36:38 +0800 Subject: [PATCH 521/679] update CHANGES and CONTRIBUTORS --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 80243bd7dd1..9f476bbac08 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -345,3 +345,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [JiaoJianing](https://github.com/JiaoJianing) - [Southjor](https://github.com/Southjor) - [Lakshmipriya](https://github.com/Lakshmi0710) +- [Tengfei](https://github.com/i-tengfei) From 6391dadb7ea2fc5cb66f32ed7751e77282e80f04 Mon Sep 17 00:00:00 2001 From: Tengfei <tengfei@tengfei.fun> Date: Fri, 3 Mar 2023 13:44:21 +0800 Subject: [PATCH 522/679] update CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e46f149c1f3..8d0532b2f7e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.104 - 2023-04-03 + +#### @cesium/engine + +##### Fixes :wrench: + +- Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) + ### 1.103 - 2023-03-01 #### @cesium/engine From 06d39ada0a2b7afa5b4fb401029d95bf0e401786 Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Fri, 3 Mar 2023 12:58:44 +0100 Subject: [PATCH 523/679] npm run prettier: it folded 1 long line and inserted a space next to each brace --- gulpfile.js | 122 +++++++++--------- packages/engine/Source/Core/Ion.js | 2 +- packages/engine/Source/Scene/CreditDisplay.js | 5 +- 3 files changed, 66 insertions(+), 63 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 58d7587cc8a..8b0691a9ae9 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,20 +1,20 @@ /*eslint-env node*/ -import {writeFileSync, copyFileSync, readFileSync, existsSync} from "fs"; -import {readFile, writeFile} from "fs/promises"; -import {join, basename, resolve, posix, dirname} from "path"; -import {exec, execSync} from "child_process"; -import {createHash} from "crypto"; -import {gzipSync} from "zlib"; -import {createInterface} from "readline"; +import { writeFileSync, copyFileSync, readFileSync, existsSync } from "fs"; +import { readFile, writeFile } from "fs/promises"; +import { join, basename, resolve, posix, dirname } from "path"; +import { exec, execSync } from "child_process"; +import { createHash } from "crypto"; +import { gzipSync } from "zlib"; +import { createInterface } from "readline"; import fetch from "node-fetch"; -import {createRequire} from "module"; +import { createRequire } from "module"; import gulp from "gulp"; import gulpTap from "gulp-tap"; import gulpZip from "gulp-zip"; import gulpRename from "gulp-rename"; import gulpReplace from "gulp-replace"; -import {globby} from "globby"; +import { globby } from "globby"; import open from "open"; import rimraf from "rimraf"; import mkdirp from "mkdirp"; @@ -29,11 +29,11 @@ import { ListObjectsCommand, PutObjectCommand, } from "@aws-sdk/client-s3"; -import {Upload} from "@aws-sdk/lib-storage"; +import { Upload } from "@aws-sdk/lib-storage"; import mime from "mime"; import typeScript from "typescript"; -import {build as esbuild} from "esbuild"; -import {createInstrumenter} from "istanbul-lib-instrument"; +import { build as esbuild } from "esbuild"; +import { createInstrumenter } from "istanbul-lib-instrument"; import pLimit from "p-limit"; import download from "download"; import decompress from "decompress"; @@ -106,8 +106,8 @@ const shaderFiles = [ ]; // Print an esbuild warning -function printBuildWarning({location, text}) { - const {column, file, line, lineText, suggestion} = location; +function printBuildWarning({ location, text }) { + const { column, file, line, lineText, suggestion } = location; let message = `\n > ${file}:${line}:${column}: warning: ${text} @@ -1003,7 +1003,7 @@ async function deployCesium(bucketName, uploadDirectory, cacheControl, dryRun) { existingBlobs.forEach(function (file) { // Don't delete generated zip files if (!/\.(zip|tgz)$/.test(file)) { - objectsToDelete.push({Key: file}); + objectsToDelete.push({ Key: file }); } }); @@ -1089,7 +1089,7 @@ async function deployCesiumRelease(bucketName, s3Client, errors) { ); } catch (error) { if (error.$metadata) { - const {httpStatusCode} = error.$metadata; + const { httpStatusCode } = error.$metadata; // The current version is not uploaded if (httpStatusCode === 404) { console.log("Updating cesium version..."); @@ -1152,22 +1152,22 @@ function getMimeType(filename) { if (mimeType === "image/svg+xml") { compress = true; } - return {type: mimeType, compress: compress}; + return { type: mimeType, compress: compress }; } //Non-standard mime types not handled by mime if (/\.(glsl|LICENSE|config|state)$/i.test(filename)) { - return {type: "text/plain", compress: true}; + return { type: "text/plain", compress: true }; } else if (/\.(czml|topojson)$/i.test(filename)) { - return {type: "application/json", compress: true}; + return { type: "application/json", compress: true }; } else if (/\.tgz$/i.test(filename)) { - return {type: "application/octet-stream", compress: false}; + return { type: "application/octet-stream", compress: false }; } // Handle dotfiles, such as .jshintrc const baseName = basename(filename); if (baseName[0] === "." || baseName.indexOf(".") === -1) { - return {type: "text/plain", compress: true}; + return { type: "text/plain", compress: true }; } // Everything else can be octet-stream compressed but print a warning @@ -1176,7 +1176,7 @@ function getMimeType(filename) { console.log(`Unknown mime type for ${filename}`); } - return {type: "application/octet-stream", compress: true}; + return { type: "application/octet-stream", compress: true }; } // get all files currently in bucket asynchronously @@ -1310,14 +1310,14 @@ export async function runCoverage(options) { filter: options.filter, }, async (args) => { - const source = await readFile(args.path, {encoding: "utf8"}); + const source = await readFile(args.path, { encoding: "utf8" }); try { const generatedCode = instrumenter.instrumentSync( source, args.path ); - return {contents: generatedCode}; + return { contents: generatedCode }; } catch (e) { return { errors: { @@ -1369,10 +1369,10 @@ export async function runCoverage(options) { type: "module", }, // Static assets are always served from the shared/combined folders. - {pattern: "Build/CesiumUnminified/**", included: false}, - {pattern: "Specs/Data/**", included: false}, - {pattern: "Specs/TestWorkers/**", included: false}, - {pattern: "Specs/TestWorkers/**/*.wasm", included: false}, + { pattern: "Build/CesiumUnminified/**", included: false }, + { pattern: "Specs/Data/**", included: false }, + { pattern: "Specs/TestWorkers/**", included: false }, + { pattern: "Specs/TestWorkers/**/*.wasm", included: false }, ]; let proxies; @@ -1389,13 +1389,13 @@ export async function runCoverage(options) { included: true, type: "module", }, - {pattern: "Specs/Data/**", included: false}, - {pattern: "packages/engine/Build/Workers/**", included: false}, - {pattern: "packages/engine/Source/Assets/**", included: false}, - {pattern: "packages/engine/Source/ThirdParty/**", included: false}, - {pattern: "packages/engine/Source/Widget/*.css", included: false}, - {pattern: "Specs/TestWorkers/**/*.wasm", included: false}, - {pattern: "Specs/TestWorkers/**", included: false}, + { pattern: "Specs/Data/**", included: false }, + { pattern: "packages/engine/Build/Workers/**", included: false }, + { pattern: "packages/engine/Source/Assets/**", included: false }, + { pattern: "packages/engine/Source/ThirdParty/**", included: false }, + { pattern: "packages/engine/Source/Widget/*.css", included: false }, + { pattern: "Specs/TestWorkers/**/*.wasm", included: false }, + { pattern: "Specs/TestWorkers/**", included: false }, ]; proxies = { @@ -1447,7 +1447,7 @@ export async function runCoverage(options) { ], }, }, - {promiseConfig: true, throwErrors: true} + { promiseConfig: true, throwErrors: true } ); return new Promise((resolve, reject) => { @@ -1553,14 +1553,14 @@ export async function test() { } let files = [ - {pattern: "Specs/Data/**", included: false}, - {pattern: "Specs/TestWorkers/**/*.wasm", included: false}, - {pattern: "Build/CesiumUnminified/Cesium.js", included: true}, - {pattern: "Build/CesiumUnminified/Cesium.js.map", included: false}, - {pattern: "Build/CesiumUnminified/**", included: false}, - {pattern: "Build/Specs/karma-main.js", included: true, type: "module"}, - {pattern: "Build/Specs/SpecList.js", included: true, type: "module"}, - {pattern: "Specs/TestWorkers/**", included: false}, + { pattern: "Specs/Data/**", included: false }, + { pattern: "Specs/TestWorkers/**/*.wasm", included: false }, + { pattern: "Build/CesiumUnminified/Cesium.js", included: true }, + { pattern: "Build/CesiumUnminified/Cesium.js.map", included: false }, + { pattern: "Build/CesiumUnminified/**", included: false }, + { pattern: "Build/Specs/karma-main.js", included: true, type: "module" }, + { pattern: "Build/Specs/SpecList.js", included: true, type: "module" }, + { pattern: "Specs/TestWorkers/**", included: false }, ]; let proxies; @@ -1578,13 +1578,13 @@ export async function test() { included: true, type: "module", }, - {pattern: "Specs/Data/**", included: false}, - {pattern: "packages/engine/Build/Workers/**", included: false}, - {pattern: "packages/engine/Source/Assets/**", included: false}, - {pattern: "packages/engine/Source/ThirdParty/**", included: false}, - {pattern: "packages/engine/Source/Widget/*.css", included: false}, - {pattern: "Specs/TestWorkers/**/*.wasm", included: false}, - {pattern: "Specs/TestWorkers/**", included: false}, + { pattern: "Specs/Data/**", included: false }, + { pattern: "packages/engine/Build/Workers/**", included: false }, + { pattern: "packages/engine/Source/Assets/**", included: false }, + { pattern: "packages/engine/Source/ThirdParty/**", included: false }, + { pattern: "packages/engine/Source/Widget/*.css", included: false }, + { pattern: "Specs/TestWorkers/**/*.wasm", included: false }, + { pattern: "Specs/TestWorkers/**", included: false }, ]; proxies = { @@ -1601,15 +1601,15 @@ export async function test() { if (release) { files = [ - {pattern: "Specs/Data/**", included: false}, - {pattern: "Specs/TestWorkers/**/*.wasm", included: false}, - {pattern: "Specs/ThirdParty/**", included: false, type: "module"}, - {pattern: "Build/Cesium/Cesium.js", included: true}, - {pattern: "Build/Cesium/Cesium.js.map", included: false}, - {pattern: "Build/Cesium/**", included: false}, - {pattern: "Build/Specs/karma-main.js", included: true}, - {pattern: "Build/Specs/SpecList.js", included: true, type: "module"}, - {pattern: "Specs/TestWorkers/**", included: false}, + { pattern: "Specs/Data/**", included: false }, + { pattern: "Specs/TestWorkers/**/*.wasm", included: false }, + { pattern: "Specs/ThirdParty/**", included: false, type: "module" }, + { pattern: "Build/Cesium/Cesium.js", included: true }, + { pattern: "Build/Cesium/Cesium.js.map", included: false }, + { pattern: "Build/Cesium/**", included: false }, + { pattern: "Build/Specs/karma-main.js", included: true }, + { pattern: "Build/Specs/SpecList.js", included: true, type: "module" }, + { pattern: "Specs/TestWorkers/**", included: false }, ]; } @@ -1646,7 +1646,7 @@ export async function test() { ], }, }, - {promiseConfig: true, throwErrors: true} + { promiseConfig: true, throwErrors: true } ); return new Promise((resolve, reject) => { diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index 9b81e067485..30ccb28c53d 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -34,7 +34,7 @@ Ion.defaultAccessToken = defaultAccessToken; * @type {string|Resource} * @default https://api.cesium.com */ -Ion.defaultServer = new Resource({url: "https://api.cesium.com/"}); +Ion.defaultServer = new Resource({ url: "https://api.cesium.com/" }); Ion.getDefaultTokenCredit = function (providedKey) { if (providedKey !== defaultAccessToken) { diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 43ae15db295..6752fda1fca 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -283,7 +283,10 @@ function appendCss(container) { return undefined; } - const shadowRootOrDocumentHead = defaultValue(getShadowRoot(container), document.head); + const shadowRootOrDocumentHead = defaultValue( + getShadowRoot(container), + document.head + ); const css = document.createElement("style"); css.innerHTML = style; shadowRootOrDocumentHead.appendChild(css); From 249c94213ea6ab3b2e23a1a7446a33ea15f8c89d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 3 Mar 2023 10:03:20 -0500 Subject: [PATCH 524/679] server build results can be undefined if not yet built --- server.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index b6836ba9237..677776c1d6d 100644 --- a/server.js +++ b/server.js @@ -321,8 +321,12 @@ const serveResult = (result, fileName, res, next) => { const glslWatcher = chokidar.watch(shaderFiles, { ignoreInitial: true }); glslWatcher.on("all", async () => { await glslToJavaScript(false, "Build/minifyShaders.state", "engine"); - esmResult.outputFiles = []; - iifeResult.outputFiles = []; + if (esmResult) { + esmResult.outputFiles = []; + } + if (iifeResult) { + iifeResult.outputFiles = []; + } }); let jsHintOptionsCache; @@ -330,8 +334,12 @@ const serveResult = (result, fileName, res, next) => { ignoreInitial: true, }); sourceCodeWatcher.on("all", () => { - esmResult.outputFiles = []; - iifeResult.outputFiles = []; + if (esmResult) { + esmResult.outputFiles = []; + } + if (iifeResult) { + iifeResult.outputFiles = []; + } jsHintOptionsCache = undefined; }); From a616a6c7276a1c7655fcc677c5b9a116a9d150cc Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 3 Mar 2023 10:32:22 -0500 Subject: [PATCH 525/679] Use the no-config option with prettier to prevent conflicts --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index dc47a364144..981be508f0e 100644 --- a/package.json +++ b/package.json @@ -147,8 +147,8 @@ "deploy-s3": "gulp deployS3", "deploy-status": "gulp deployStatus", "deploy-set-version": "gulp deploySetVersion", - "prettier": "prettier --write \"**/*\"", - "prettier-check": "prettier --check \"**/*\"" + "prettier": "prettier --write --no-config \"**/*\"", + "prettier-check": "prettier --check --no-config \"**/*\"" }, "engines": { "node": ">=14.0.0" @@ -156,11 +156,11 @@ "lint-staged": { "*.{js,cjs,html}": [ "eslint --cache --quiet", - "prettier --write" + "prettier --write --no-config" ], "*.md": [ "markdownlint --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", - "prettier --write" + "prettier --write --no-config" ] }, "workspaces": [ From 76d4a34d251d6d22d3dee8be7418159504e8bcfe Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 3 Mar 2023 18:20:33 -0500 Subject: [PATCH 526/679] Add network throttling recommendations to Performance Testing Guide --- .../PerformanceTestingGuide/README.md | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Documentation/Contributors/PerformanceTestingGuide/README.md b/Documentation/Contributors/PerformanceTestingGuide/README.md index 56261a82415..9244c10bc86 100644 --- a/Documentation/Contributors/PerformanceTestingGuide/README.md +++ b/Documentation/Contributors/PerformanceTestingGuide/README.md @@ -167,17 +167,24 @@ tileset.initialTilesLoaded.addEventListener(() => { }); ``` -### Caching vs throttling +### Separating network time from code execution time -Depending on the scenario you are trying to test for, you may want to enable -caching of network requests or throttling network speed. +Depending on the scenario you are trying to test for, you may want to distinguish between the time used for network requests and code execution. -- If you want to simulate slow network connections, consider throttling the - connection. For example, in Chrome, see [these instructions](https://developer.chrome.com/docs/devtools/network/#throttle) -- If you want to eliminate network latency and focus on measuring how long the - initialization code takes to run, enable caching. In Chrome, this option - can be done by _unchecking_ the `Disable Cache` option in the Network tab. - You will also need to enable caching on the server. +#### Quantifying network request time + +For repeatability, you can throttle your connection speed to a fixed value, to eliminate network variations from time to time and from user to user. For example, in Chrome, see [these instructions](https://developer.chrome.com/docs/devtools/network/#throttle). + +The speed you throttle to can be adjusted based on your target user base. For example, for tests targeting US users, you can throttle to the [US median internet speed](https://www.speedtest.net/global-index/united-states). Note that these speeds will change over time, so you will want to report the exact throttling speed as part of your test results. + +Before throttling the connection, make sure to verify that your unthrottled network speed is at least as fast as the speed you are throttling to. + +#### Quantifying code execution time + +If you want to eliminate network latency and focus on measuring how long the +initialization code takes to run, enable caching. In Chrome, this option +can be done by _unchecking_ the `Disable Cache` option in the Network tab. +You will also need to enable caching on the server. ![Uncheck disable cache](no-disable-cache.png) From e7ef4577b7ac9be231bd74f36bf5ed4a752cac68 Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Sun, 5 Mar 2023 22:56:34 +0100 Subject: [PATCH 527/679] CreditDisplaySpec.js: modify to test CreditDisplay also under shadowRoot --- .../engine/Specs/Scene/CreditDisplaySpec.js | 933 +++++++++--------- 1 file changed, 482 insertions(+), 451 deletions(-) diff --git a/packages/engine/Specs/Scene/CreditDisplaySpec.js b/packages/engine/Specs/Scene/CreditDisplaySpec.js index 59cdd891e3f..ac0bb34bfb9 100644 --- a/packages/engine/Specs/Scene/CreditDisplaySpec.js +++ b/packages/engine/Specs/Scene/CreditDisplaySpec.js @@ -7,509 +7,540 @@ describe("Scene/CreditDisplay", function () { let creditDisplay; let imageUrl; - beforeEach(function () { - imageUrl = absolutize("./Data/Images/Green.png"); - container = document.createElement("div"); - container.id = "credit-container"; - document.body.appendChild(container); + describe("Scene/CreditDisplay under document.head", function () { + beforeEach(function () { + imageUrl = absolutize("./Data/Images/Green.png"); + container = document.createElement("div"); + container.id = "credit-container"; + document.body.appendChild(container); + }); + + afterEach(function () { + document.body.removeChild(container); + CreditDisplay.cesiumCredit = undefined; + CreditDisplay._cesiumCreditInitialized = false; + if (defined(creditDisplay)) { + creditDisplay.destroy(); + creditDisplay = undefined; + } + }); + runTests(); }); - afterEach(function () { - document.body.removeChild(container); - CreditDisplay.cesiumCredit = undefined; - CreditDisplay._cesiumCreditInitialized = false; - if (defined(creditDisplay)) { - creditDisplay.destroy(); - creditDisplay = undefined; - } - }); + describe("Scene/CreditDisplay under shadowRoot", function () { + beforeEach(function () { + imageUrl = absolutize("./Data/Images/Green.png"); + container = document.createElement("div"); + container.id = "credit-container"; - // For the sake of the tests, we remove the logo - // credit at the beginning of every frame - function beginFrame(creditDisplay) { - creditDisplay.beginFrame(); - } + const outerContainer = document.createElement("div"); + outerContainer.id = "credit-outer-container"; - it("credit display throws with no container", function () { - expect(function () { - return new CreditDisplay(); - }).toThrowDeveloperError(); - }); + const shadowRoot = outerContainer.attachShadow({ mode: "open" }); + shadowRoot.appendChild(container); - it("credit display addCredit throws when credit is undefined", function () { - expect(function () { - creditDisplay = new CreditDisplay(container); - creditDisplay.addCredit(); - }).toThrowDeveloperError(); - }); + document.body.appendChild(outerContainer); + }); - it("credit display addDefaultCredit throws when credit is undefined", function () { - expect(function () { - creditDisplay = new CreditDisplay(container); - creditDisplay.addDefaultCredit(); - }).toThrowDeveloperError(); + afterEach(function () { + const element = document.querySelector("credit-outer-container"); + if (defined(element)) { + element.remove(); + } + CreditDisplay.cesiumCredit = undefined; + CreditDisplay._cesiumCreditInitialized = false; + if (defined(creditDisplay)) { + creditDisplay.destroy(); + creditDisplay = undefined; + } + }); + runTests(); }); - it("credit display removeDefaultCredit throws when credit is undefined", function () { - expect(function () { + function runTests() { + // For the sake of the tests, we remove the logo + // credit at the beginning of every frame + function beginFrame(creditDisplay) { + creditDisplay.beginFrame(); + } + it("credit display throws with no container", function () { + expect(function () { + return new CreditDisplay(); + }).toThrowDeveloperError(); + }); + it("credit display addCredit throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.addCredit(); + }).toThrowDeveloperError(); + }); + it("credit display addDefaultCredit throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.addDefaultCredit(); + }).toThrowDeveloperError(); + }); + it("credit display removeDefaultCredit throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.removeDefaultCredit(); + }).toThrowDeveloperError(); + }); + + it("credits have unique ids", function () { + const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + const credit2 = new Credit('<a href="http://cesiumjs.org/">credit2</a>'); + expect(credit1.id).not.toEqual(credit2.id); + + const credit3 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + expect(credit1.id).toEqual(credit3.id); + }); + + it("credit clone works", function () { + const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + const credit2 = Credit.clone(credit1); + expect(credit1).toEqual(credit2); + const credit3 = Credit.clone(undefined); + expect(credit3).toBeUndefined(); + }); + + it("credit display displays a credit", function () { creditDisplay = new CreditDisplay(container); - creditDisplay.removeDefaultCredit(); - }).toThrowDeveloperError(); - }); - - it("credits have unique ids", function () { - const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - const credit2 = new Credit('<a href="http://cesiumjs.org/">credit2</a>'); - expect(credit1.id).not.toEqual(credit2.id); - - const credit3 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - expect(credit1.id).toEqual(credit3.id); - }); - - it("credit clone works", function () { - const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - const credit2 = Credit.clone(credit1); - expect(credit1).toEqual(credit2); - const credit3 = Credit.clone(undefined); - expect(credit3).toBeUndefined(); - }); - - it("credit display displays a credit", function () { - creditDisplay = new CreditDisplay(container); - const credit = new Credit( - '<a href="http://cesiumjs.org">CesiumJS.org</a>', - true - ); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit); - creditDisplay.endFrame(); - - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(1); - const child10 = creditContainer.childNodes[0]; - expect(child10.childNodes.length).toEqual(1); - }); - - it("credit display updates html when credits change", function () { - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - - creditDisplay = new CreditDisplay(container); - - // add only credit1 during the frame - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - const innerHTMLWithCredit1 = container.innerHTML; - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); - - // add only credit2 during the frame - beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - const innerHTMLWithCredit2 = container.innerHTML; - expect(innerHTMLWithCredit2).not.toEqual(innerHTMLWithCredit1); - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0].innerHTML).toEqual("credit2"); - - // add both credit1 and credit2 during the frame - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - const innerHTMLWithCredit1AndCredit2 = container.innerHTML; - expect(innerHTMLWithCredit1AndCredit2).not.toEqual(innerHTMLWithCredit1); - expect(innerHTMLWithCredit1AndCredit2).not.toEqual(innerHTMLWithCredit2); - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); - expect(creditContainer.childNodes[2].innerHTML).toEqual("credit2"); - - // add neither credit during the frame - beginFrame(creditDisplay); - creditDisplay.endFrame(); - expect(container.innerHTML).not.toEqual(innerHTMLWithCredit1); - expect(container.innerHTML).not.toEqual(innerHTMLWithCredit2); - expect(container.innerHTML).not.toEqual(innerHTMLWithCredit1AndCredit2); - expect(creditContainer.childNodes.length).toEqual(0); - }); - - it("credit display uses delimeter", function () { - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - const delimiter = ", "; - creditDisplay = new CreditDisplay(container, ", "); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); - expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); - expect(creditContainer.childNodes[2].innerHTML).toEqual("credit2"); - }); - - it("credit display manages delimeters correctly for text credits", function () { - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - const credit3 = new Credit("credit3", true); - const delimiter = ", "; - creditDisplay = new CreditDisplay(container, delimiter); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); - creditDisplay.endFrame(); - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(5); - expect(creditContainer.childNodes[0]).toEqual(credit1.element); - expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); - expect(creditContainer.childNodes[2]).toEqual(credit2.element); - expect(creditContainer.childNodes[3].innerHTML).toEqual(delimiter); - expect(creditContainer.childNodes[4]).toEqual(credit3.element); - - beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); - creditDisplay.endFrame(); - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0]).toEqual(credit2.element); - expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); - expect(creditContainer.childNodes[2]).toEqual(credit3.element); - - beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0]).toEqual(credit2.element); - - beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); - creditDisplay.endFrame(); - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0]).toEqual(credit2.element); - expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); - expect(creditContainer.childNodes[2]).toEqual(credit3.element); - }); - - it("credit display displays default credit", function () { - const defaultCredit = new Credit("default credit", true); - const credit1 = new Credit("credit1", true); - - creditDisplay = new CreditDisplay(container, ", "); - creditDisplay.addDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); - expect(creditContainer.childNodes[1].innerHTML).toEqual(", "); - expect(creditContainer.childNodes[2]).toEqual(credit1.element); - - beginFrame(creditDisplay); - creditDisplay.endFrame(); - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); - }); + const credit = new Credit( + '<a href="http://cesiumjs.org">CesiumJS.org</a>', + true + ); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit); + creditDisplay.endFrame(); + + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + const child10 = creditContainer.childNodes[0]; + expect(child10.childNodes.length).toEqual(1); + }); + + it("credit display updates html when credits change", function () { + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); - it("credit display displays credits when default is removed", function () { - const defaultCredit = new Credit("default credit", true); - const credit1 = new Credit("credit1", true); - - creditDisplay = new CreditDisplay(container, ", "); - creditDisplay.addDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(3); - expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); - expect(creditContainer.childNodes[1].innerHTML).toEqual(", "); - expect(creditContainer.childNodes[2]).toEqual(credit1.element); - - creditDisplay.removeDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0]).toEqual(credit1.element); - }); + creditDisplay = new CreditDisplay(container); - it("credit display only displays one if two credits are equal", function () { - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit1", true); - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(1); - expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); - }); + // add only credit1 during the frame + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.endFrame(); + const innerHTMLWithCredit1 = container.innerHTML; + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); + + // add only credit2 during the frame + beginFrame(creditDisplay); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + const innerHTMLWithCredit2 = container.innerHTML; + expect(innerHTMLWithCredit2).not.toEqual(innerHTMLWithCredit1); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual("credit2"); + + // add both credit1 and credit2 during the frame + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + const innerHTMLWithCredit1AndCredit2 = container.innerHTML; + expect(innerHTMLWithCredit1AndCredit2).not.toEqual(innerHTMLWithCredit1); + expect(innerHTMLWithCredit1AndCredit2).not.toEqual(innerHTMLWithCredit2); + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); + expect(creditContainer.childNodes[2].innerHTML).toEqual("credit2"); + + // add neither credit during the frame + beginFrame(creditDisplay); + creditDisplay.endFrame(); + expect(container.innerHTML).not.toEqual(innerHTMLWithCredit1); + expect(container.innerHTML).not.toEqual(innerHTMLWithCredit2); + expect(container.innerHTML).not.toEqual(innerHTMLWithCredit1AndCredit2); + expect(creditContainer.childNodes.length).toEqual(0); + }); + + it("credit display uses delimeter", function () { + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); + const delimiter = ", "; + creditDisplay = new CreditDisplay(container, ", "); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2].innerHTML).toEqual("credit2"); + }); + + it("credit display manages delimeters correctly for text credits", function () { + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); + const credit3 = new Credit("credit3", true); + const delimiter = ", "; + creditDisplay = new CreditDisplay(container, delimiter); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.addCredit(credit3); + creditDisplay.endFrame(); + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(5); + expect(creditContainer.childNodes[0]).toEqual(credit1.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit2.element); + expect(creditContainer.childNodes[3].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[4]).toEqual(credit3.element); + + beginFrame(creditDisplay); + creditDisplay.addCredit(credit2); + creditDisplay.addCredit(credit3); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit3.element); + + beginFrame(creditDisplay); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + + beginFrame(creditDisplay); + creditDisplay.addCredit(credit2); + creditDisplay.addCredit(credit3); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit3.element); + }); + + it("credit display displays default credit", function () { + const defaultCredit = new Credit("default credit", true); + const credit1 = new Credit("credit1", true); + + creditDisplay = new CreditDisplay(container, ", "); + creditDisplay.addDefaultCredit(defaultCredit); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.endFrame(); + + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(", "); + expect(creditContainer.childNodes[2]).toEqual(credit1.element); + + beginFrame(creditDisplay); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + }); + + it("credit display displays credits when default is removed", function () { + const defaultCredit = new Credit("default credit", true); + const credit1 = new Credit("credit1", true); + + creditDisplay = new CreditDisplay(container, ", "); + creditDisplay.addDefaultCredit(defaultCredit); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.endFrame(); + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(", "); + expect(creditContainer.childNodes[2]).toEqual(credit1.element); + + creditDisplay.removeDefaultCredit(defaultCredit); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(credit1.element); + }); + + it("credit display only displays one if two credits are equal", function () { + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit1", true); + creditDisplay = new CreditDisplay(container); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual("credit1"); + }); + + it("credit display keeps count of repeated credits", function () { + const repeatedCreditCount = 4; + creditDisplay = new CreditDisplay(container); + beginFrame(creditDisplay); - it("credit display keeps count of repeated credits", function () { - const repeatedCreditCount = 4; - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); + for (let i = 0; i < repeatedCreditCount; i++) { + creditDisplay.addCredit(new Credit("credit1", true)); + } + creditDisplay.addCredit(new Credit("credit2", true)); - for (let i = 0; i < repeatedCreditCount; i++) { - creditDisplay.addCredit(new Credit("credit1", true)); - } - creditDisplay.addCredit(new Credit("credit2", true)); + const credits = creditDisplay._currentFrameCredits.screenCredits.values; + expect(credits.length).toEqual(2); - const credits = creditDisplay._currentFrameCredits.screenCredits.values; - expect(credits.length).toEqual(2); + const firstCredit = credits[0]; + expect(firstCredit.credit.html).toEqual("credit1"); + expect(firstCredit.count).toEqual(repeatedCreditCount); - const firstCredit = credits[0]; - expect(firstCredit.credit.html).toEqual("credit1"); - expect(firstCredit.count).toEqual(repeatedCreditCount); + const secondCredit = credits[1]; + expect(secondCredit.credit.html).toEqual("credit2"); + expect(secondCredit.count).toEqual(1); + }); - const secondCredit = credits[1]; - expect(secondCredit.credit.html).toEqual("credit2"); - expect(secondCredit.count).toEqual(1); - }); + it("credit display sorts credits by frequency", function () { + const creditCounts = [2, 10, 6, 1]; + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); + const credit3 = new Credit("credit3", true); + const credit4 = new Credit("credit4", true); - it("credit display sorts credits by frequency", function () { - const creditCounts = [2, 10, 6, 1]; - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - const credit3 = new Credit("credit3", true); - const credit4 = new Credit("credit4", true); - - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - - for (let i = 0; i < creditCounts.length; i++) { - const creditString = "credit".concat((i + 1).toString()); - const count = creditCounts[i]; - for (let j = 0; j < count; j++) { - creditDisplay.addCredit(new Credit(creditString, true)); + creditDisplay = new CreditDisplay(container); + beginFrame(creditDisplay); + + for (let i = 0; i < creditCounts.length; i++) { + const creditString = "credit".concat((i + 1).toString()); + const count = creditCounts[i]; + for (let j = 0; j < count; j++) { + creditDisplay.addCredit(new Credit(creditString, true)); + } } - } - creditDisplay.endFrame(); - - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(7); - expect(creditContainer.childNodes[0]).toEqual(credit2.element); - expect(creditContainer.childNodes[2]).toEqual(credit3.element); - expect(creditContainer.childNodes[4]).toEqual(credit1.element); - expect(creditContainer.childNodes[6]).toEqual(credit4.element); - }); + creditDisplay.endFrame(); + + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(7); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + expect(creditContainer.childNodes[2]).toEqual(credit3.element); + expect(creditContainer.childNodes[4]).toEqual(credit1.element); + expect(creditContainer.childNodes[6]).toEqual(credit4.element); + }); + + it("credit display sorts credits by frequency with default credit", function () { + const defaultCredit = new Credit("default credit", true); + const creditCounts = [2, 10, 6, 1]; + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); + const credit3 = new Credit("credit3", true); + const credit4 = new Credit("credit4", true); - it("credit display sorts credits by frequency with default credit", function () { - const defaultCredit = new Credit("default credit", true); - const creditCounts = [2, 10, 6, 1]; - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - const credit3 = new Credit("credit3", true); - const credit4 = new Credit("credit4", true); - - creditDisplay = new CreditDisplay(container); - creditDisplay.addDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - - for (let i = 0; i < creditCounts.length; i++) { - const creditString = "credit".concat((i + 1).toString()); - const count = creditCounts[i]; - for (let j = 0; j < count; j++) { - creditDisplay.addCredit(new Credit(creditString, true)); + creditDisplay = new CreditDisplay(container); + creditDisplay.addDefaultCredit(defaultCredit); + beginFrame(creditDisplay); + + for (let i = 0; i < creditCounts.length; i++) { + const creditString = "credit".concat((i + 1).toString()); + const count = creditCounts[i]; + for (let j = 0; j < count; j++) { + creditDisplay.addCredit(new Credit(creditString, true)); + } } - } - creditDisplay.endFrame(); - - const creditContainer = container.childNodes[1]; - expect(creditContainer.childNodes.length).toEqual(9); - expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); - expect(creditContainer.childNodes[2]).toEqual(credit2.element); - expect(creditContainer.childNodes[4]).toEqual(credit3.element); - expect(creditContainer.childNodes[6]).toEqual(credit1.element); - expect(creditContainer.childNodes[8]).toEqual(credit4.element); - }); + creditDisplay.endFrame(); - it("displays credits in a lightbox", function () { - const credit1 = new Credit("credit1"); - const credit2 = new Credit(`<img src="${imageUrl}"/>`); + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(9); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[2]).toEqual(credit2.element); + expect(creditContainer.childNodes[4]).toEqual(credit3.element); + expect(creditContainer.childNodes[6]).toEqual(credit1.element); + expect(creditContainer.childNodes[8]).toEqual(credit4.element); + }); - creditDisplay = new CreditDisplay(container); - const creditList = creditDisplay._creditList; + it("displays credits in a lightbox", function () { + const credit1 = new Credit("credit1"); + const credit2 = new Credit(`<img src="${imageUrl}"/>`); - creditDisplay.showLightbox(); + creditDisplay = new CreditDisplay(container); + const creditList = creditDisplay._creditList; - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - creditDisplay.update(); + creditDisplay.showLightbox(); - let innerHTML = creditList.innerHTML; - expect(creditList.childNodes.length).toEqual(1); - expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.endFrame(); + creditDisplay.update(); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - creditDisplay.update(); + let innerHTML = creditList.innerHTML; + expect(creditList.childNodes.length).toEqual(1); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); - expect(creditList.innerHTML).not.toEqual(innerHTML); - innerHTML = creditList.innerHTML; - expect(creditList.childNodes.length).toEqual(1); - expect(creditList.childNodes[0].childNodes[0]).toEqual(credit2.element); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - creditDisplay.update(); + expect(creditList.innerHTML).not.toEqual(innerHTML); + innerHTML = creditList.innerHTML; + expect(creditList.childNodes.length).toEqual(1); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit2.element); - expect(creditList.innerHTML).not.toEqual(innerHTML); - innerHTML = creditList.innerHTML; - expect(creditList.childNodes.length).toEqual(2); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); - beginFrame(creditDisplay); - creditDisplay.endFrame(); - creditDisplay.update(); + expect(creditList.innerHTML).not.toEqual(innerHTML); + innerHTML = creditList.innerHTML; + expect(creditList.childNodes.length).toEqual(2); - expect(creditList.innerHTML).not.toEqual(innerHTML); - expect(creditList.childNodes.length).toEqual(0); + beginFrame(creditDisplay); + creditDisplay.endFrame(); + creditDisplay.update(); - creditDisplay.hideLightbox(); - }); + expect(creditList.innerHTML).not.toEqual(innerHTML); + expect(creditList.childNodes.length).toEqual(0); - it("handles showOnScreen toggles at runtime", function () { - // Credits are constructed to show on screen - const credit1 = new Credit("credit1", true); - const credit2 = new Credit("credit2", true); - - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - - const screenCreditContainer = container.childNodes[1]; - expect(screenCreditContainer.childNodes.length).toEqual(3); - expect(screenCreditContainer.childNodes[0]).toEqual(credit1.element); - expect(screenCreditContainer.childNodes[2]).toEqual(credit2.element); - - // Show credits in lightbox instead - credit1.showOnScreen = false; - credit2.showOnScreen = false; - - creditDisplay.showLightbox(); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - - const lightboxCreditList = creditDisplay._creditList; - expect(lightboxCreditList.childNodes.length).toEqual(2); - expect(lightboxCreditList.childNodes[0].childNodes[0]).toEqual( - credit1.element - ); - expect(lightboxCreditList.childNodes[1].childNodes[0]).toEqual( - credit2.element - ); - - // Show credits on screen again - credit1.showOnScreen = true; - credit2.showOnScreen = true; - - creditDisplay.hideLightbox(); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - - expect(screenCreditContainer.childNodes.length).toEqual(3); - expect(screenCreditContainer.childNodes[0]).toEqual(credit1.element); - expect(screenCreditContainer.childNodes[2]).toEqual(credit2.element); - }); + creditDisplay.hideLightbox(); + }); - it("renders lightbox credits", function () { - const credit1 = new Credit("credit1"); - const credit2 = new Credit(`<img src="${imageUrl}"/>`); + it("handles showOnScreen toggles at runtime", function () { + // Credits are constructed to show on screen + const credit1 = new Credit("credit1", true); + const credit2 = new Credit("credit2", true); - creditDisplay = new CreditDisplay(container); - const creditList = creditDisplay._creditList; + creditDisplay = new CreditDisplay(container); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + + const screenCreditContainer = container.childNodes[1]; + expect(screenCreditContainer.childNodes.length).toEqual(3); + expect(screenCreditContainer.childNodes[0]).toEqual(credit1.element); + expect(screenCreditContainer.childNodes[2]).toEqual(credit2.element); + + // Show credits in lightbox instead + credit1.showOnScreen = false; + credit2.showOnScreen = false; + + creditDisplay.showLightbox(); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + + const lightboxCreditList = creditDisplay._creditList; + expect(lightboxCreditList.childNodes.length).toEqual(2); + expect(lightboxCreditList.childNodes[0].childNodes[0]).toEqual( + credit1.element + ); + expect(lightboxCreditList.childNodes[1].childNodes[0]).toEqual( + credit2.element + ); + + // Show credits on screen again + credit1.showOnScreen = true; + credit2.showOnScreen = true; + + creditDisplay.hideLightbox(); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + + expect(screenCreditContainer.childNodes.length).toEqual(3); + expect(screenCreditContainer.childNodes[0]).toEqual(credit1.element); + expect(screenCreditContainer.childNodes[2]).toEqual(credit2.element); + }); + + it("renders lightbox credits", function () { + const credit1 = new Credit("credit1"); + const credit2 = new Credit(`<img src="${imageUrl}"/>`); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - creditDisplay.update(); + creditDisplay = new CreditDisplay(container); + const creditList = creditDisplay._creditList; - expect(creditList.childNodes.length).toEqual(2); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); - creditDisplay.showLightbox(); + expect(creditList.childNodes.length).toEqual(2); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - creditDisplay.update(); + creditDisplay.showLightbox(); - expect(creditList.childNodes.length).toEqual(2); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); - creditDisplay.hideLightbox(); - }); + expect(creditList.childNodes.length).toEqual(2); - it("updates lightbox when a new frames are not rendered", function () { - const credit1 = new Credit("credit1"); - const credit2 = new Credit(`<img src="${imageUrl}"/>`); + creditDisplay.hideLightbox(); + }); - creditDisplay = new CreditDisplay(container); - const creditList = creditDisplay._creditList; + it("updates lightbox when a new frames are not rendered", function () { + const credit1 = new Credit("credit1"); + const credit2 = new Credit(`<img src="${imageUrl}"/>`); - creditDisplay.update(); + creditDisplay = new CreditDisplay(container); + const creditList = creditDisplay._creditList; - expect(creditList.childNodes.length).toEqual(0); + creditDisplay.update(); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - creditDisplay.update(); + expect(creditList.childNodes.length).toEqual(0); - expect(creditList.childNodes.length).toEqual(2); + beginFrame(creditDisplay); + creditDisplay.addCredit(credit1); + creditDisplay.addCredit(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); - creditDisplay.showLightbox(); - creditDisplay.update(); + expect(creditList.childNodes.length).toEqual(2); - expect(creditList.childNodes.length).toEqual(2); + creditDisplay.showLightbox(); + creditDisplay.update(); - creditDisplay.hideLightbox(); - creditDisplay.update(); + expect(creditList.childNodes.length).toEqual(2); - expect(creditList.childNodes.length).toEqual(2); + creditDisplay.hideLightbox(); + creditDisplay.update(); - creditDisplay.hideLightbox(); - }); + expect(creditList.childNodes.length).toEqual(2); - it("works if Cesium credit removed", function () { - creditDisplay = new CreditDisplay(container); - const cesiumCredit = CreditDisplay.cesiumCredit; - CreditDisplay.cesiumCredit = undefined; - creditDisplay.beginFrame(); - creditDisplay.endFrame(); - expect(creditDisplay._cesiumCreditContainer.childNodes.length).toBe(0); - CreditDisplay.cesiumCredit = cesiumCredit; - }); + creditDisplay.hideLightbox(); + }); - it("each credit display has a unique cesium credit", function () { - creditDisplay = new CreditDisplay(container); - const container2 = document.createElement("div"); - const creditDisplay2 = new CreditDisplay(container2); - expect(creditDisplay._currentCesiumCredit).toEqual( - creditDisplay2._currentCesiumCredit - ); - expect(creditDisplay._currentCesiumCredit).not.toBe( - creditDisplay2._currentCesiumCredit - ); - }); + it("works if Cesium credit removed", function () { + creditDisplay = new CreditDisplay(container); + const cesiumCredit = CreditDisplay.cesiumCredit; + CreditDisplay.cesiumCredit = undefined; + creditDisplay.beginFrame(); + creditDisplay.endFrame(); + expect(creditDisplay._cesiumCreditContainer.childNodes.length).toBe(0); + CreditDisplay.cesiumCredit = cesiumCredit; + }); + + it("each credit display has a unique cesium credit", function () { + creditDisplay = new CreditDisplay(container); + const container2 = document.createElement("div"); + const creditDisplay2 = new CreditDisplay(container2); + expect(creditDisplay._currentCesiumCredit).toEqual( + creditDisplay2._currentCesiumCredit + ); + expect(creditDisplay._currentCesiumCredit).not.toBe( + creditDisplay2._currentCesiumCredit + ); + }); + } }); From e99258595f8131ef36c00368405054203a6d1586 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 6 Mar 2023 19:25:06 -0500 Subject: [PATCH 528/679] Fix typo in GlobeSurfaceTileProvider.js --- packages/engine/Source/Scene/GlobeSurfaceTileProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 05c8b2875f3..4d568f606c4 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -2135,7 +2135,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { const hasVertexNormals = defined(tileProvider.terrainProvider) && // ready is deprecated; This is here for backwards compatibility - tileProvider.terrainP && + tileProvider.terrainProvider._ready && tileProvider.terrainProvider.hasVertexNormals; const enableFog = frameState.fog.enabled && frameState.fog.renderable && !cameraUnderground; From 065c9a61b32b8766d6b4d1430bfd271a6735e529 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 7 Mar 2023 17:09:38 -0500 Subject: [PATCH 529/679] Updated deprecation warnings --- CHANGES.md | 32 +++++++++---------- .../ArcGISTiledElevationTerrainProvider.js | 6 ++-- .../Source/Core/CesiumTerrainProvider.js | 6 ++-- .../Core/CustomHeightmapTerrainProvider.js | 4 +-- .../Source/Core/EllipsoidTerrainProvider.js | 4 +-- .../Core/GoogleEarthEnterpriseMetadata.js | 4 +-- .../GoogleEarthEnterpriseTerrainProvider.js | 8 ++--- .../Source/Core/VRTheWorldTerrainProvider.js | 6 ++-- .../engine/Source/Core/createWorldTerrain.js | 2 +- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 71c5a97cf3a..685cdeca377 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,10 +4,26 @@ #### @cesium/engine +##### Additions :tada: + +- Added `ArcGISTiledElevationTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. + ##### Fixes :wrench: - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) +##### Deprecated :hourglass_flowing_sand: + +- `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. +- `ArcGISTiledElevationTerrainProvider `constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. +- `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. Use `CesiumTerrainProvider.fromUrl` instead. +- `CustomHeightmapTerrainProvider.ready`, and `CustomHeightmapTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. +- `EllipsoidTerrainProvider.ready`, and `EllipsoidTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. +- `GoogleEarthEnterpriseMetadata` constructor parameter `options.url` and `GoogleEarthEnterpriseMetadata.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseMetadata.fromUrl` instead. +- `GoogleEarthEnterpriseTerrainProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseTerrainProvider.ready`, and `GoogleEarthEnterpriseTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseTerrainProvider.fromMetadata` instead. +- `VRTheWorldTerrainProvider` constructor parameter `options.url`, `VRTheWorldTerrainProvider.ready`, and `VRTheWorldTerrainProvider.readyPromise` were deprecated in Cesium 1.104. They will be removed in 1.107. Use `VRTheWorldTerrainProvider.fromUrl` instead. +- `createWorldTerrain` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use createWorldTerrainAsync instead. + ### 1.103 - 2023-03-01 #### @cesium/engine @@ -64,22 +80,6 @@ - Fixed a bug where scale was not being applied to the top-level tileset geometric error. [#11047](https://github.com/CesiumGS/cesium/pull/11047) - Updating Bing Maps top page hyperlink to Bing Maps ToU hyperlink [#11049](https://github.com/CesiumGS/cesium/pull/11049) -##### Additions :tada: - -- Added `ArcGISTiledElevationTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. - -##### Deprecated :hourglass_flowing_sand: - -- `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. -- `ArcGISTiledElevationTerrainProvider `constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. -- `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `CesiumTerrainProvider.fromUrl` instead. -- `CustomHeightmapTerrainProvider.ready`, and `CustomHeightmapTerrainProvider.readyPromise` were deprecated in Cesium 1.102. -- `EllipsoidTerrainProvider.ready`, and `EllipsoidTerrainProvider.readyPromise` were deprecated in Cesium 1.102. -- `GoogleEarthEnterpriseMetadata` constructor parameter `options.url` and `GoogleEarthEnterpriseMetadata.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseMetadata.fromUrl` instead. -- `GoogleEarthEnterpriseTerrainProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseTerrainProvider.ready`, and `GoogleEarthEnterpriseTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `GoogleEarthEnterpriseTerrainProvider.fromMetadata` instead. -- `VRTheWorldTerrainProvider` constructor parameter `options.url`, `VRTheWorldTerrainProvider.ready`, and `VRTheWorldTerrainProvider.readyPromise` were deprecated in Cesium 1.102. They will be removed in 1.104. Use `VRTheWorldTerrainProvider.fromUrl` instead. -- `createWorldTerrain` was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use createWorldTerrainAsync instead. - ### 1.101 - 2023-01-02 #### Major Announcements :loudspeaker: diff --git a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js index cc031f66bc6..8e45da5f752 100644 --- a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js +++ b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js @@ -261,7 +261,7 @@ function ArcGISTiledElevationTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "ArcGISTiledElevationTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); const that = this; @@ -345,7 +345,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { get: function () { deprecationWarning( "ArcGISTiledElevationTerrainProvider.ready", - "ArcGISTiledElevationTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "ArcGISTiledElevationTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -362,7 +362,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { get: function () { deprecationWarning( "ArcGISTiledElevationTerrainProvider.readyPromise", - "ArcGISTiledElevationTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "ArcGISTiledElevationTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index 2ec0562ded9..8b9f141aabe 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -538,7 +538,7 @@ function CesiumTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "CesiumTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use CesiumTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." ); this._readyPromise = CesiumTerrainProvider._initializeReadyPromise( options, @@ -1065,7 +1065,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.ready", - "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -1082,7 +1082,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.readyPromise", - "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js index bb50e94e163..f6879b82abb 100644 --- a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js +++ b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js @@ -145,7 +145,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { get: function () { deprecationWarning( "CustomHeightmapTerrainProvider.ready", - "CustomHeightmapTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "CustomHeightmapTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return true; }, @@ -162,7 +162,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { get: function () { deprecationWarning( "CustomHeightmapTerrainProvider.readyPromise", - "CustomHeightmapTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "CustomHeightmapTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/EllipsoidTerrainProvider.js b/packages/engine/Source/Core/EllipsoidTerrainProvider.js index 548e0f986d6..b9aa2ba5142 100644 --- a/packages/engine/Source/Core/EllipsoidTerrainProvider.js +++ b/packages/engine/Source/Core/EllipsoidTerrainProvider.js @@ -98,7 +98,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { get: function () { deprecationWarning( "EllipsoidTerrainProvider.ready", - "EllipsoidTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "EllipsoidTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return true; }, @@ -115,7 +115,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { get: function () { deprecationWarning( "EllipsoidTerrainProvider.readyPromise", - "EllipsoidTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "EllipsoidTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js index 8b9bb565214..100abc63ec1 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js @@ -105,7 +105,7 @@ function GoogleEarthEnterpriseMetadata(resourceOrUrl) { if (defined(resourceOrUrl)) { deprecationWarning( "GoogleEarthEnterpriseMetadata options.url", - "GoogleEarthEnterpriseMetadata constructor parmeter resourceOrUrl was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseMetadata.fromUrl instead." + "GoogleEarthEnterpriseMetadata constructor parmeter resourceOrUrl was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." ); let url = resourceOrUrl; @@ -183,7 +183,7 @@ Object.defineProperties(GoogleEarthEnterpriseMetadata.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMetadata.readyPromise", - "GoogleEarthEnterpriseMetadata.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseMetadata.fromUrl instead." + "GoogleEarthEnterpriseMetadata.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index 877c4db0d32..6be87f06321 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -135,7 +135,7 @@ function GoogleEarthEnterpriseTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." + "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." ); const resource = Resource.createIfNeeded(options.url); const that = this; @@ -181,7 +181,7 @@ function GoogleEarthEnterpriseTerrainProvider(options) { } else if (defined(options.metadata)) { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider options.metadata", - "options.metadata was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." + "options.metadata was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." ); const metadata = options.metadata; this._metadata = metadata; @@ -262,7 +262,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider.ready", - "GoogleEarthEnterpriseTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "GoogleEarthEnterpriseTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return this._ready; }, @@ -279,7 +279,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider.readyPromise", - "GoogleEarthEnterpriseTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104." + "GoogleEarthEnterpriseTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js index c4dcc27f20a..73a66d669ae 100644 --- a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js +++ b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js @@ -185,7 +185,7 @@ function VRTheWorldTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "VRTheWorldTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.102. It will be removed in 1.104. VRTheWorldTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. VRTheWorldTerrainProvider.fromUrl instead." ); const that = this; const terrainProviderBuilder = new TerrainProviderBuilder(options); @@ -255,7 +255,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { get: function () { deprecationWarning( "VRTheWorldTerrainProvider.ready", - "VRTheWorldTerrainProvider.ready was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use VRTheWorldTerrainProvider.fromUrl instead." + "VRTheWorldTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -272,7 +272,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { get: function () { deprecationWarning( "VRTheWorldTerrainProvider.readyPromise", - "VRTheWorldTerrainProvider.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use VRTheWorldTerrainProvider.fromUrl instead." + "VRTheWorldTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/createWorldTerrain.js b/packages/engine/Source/Core/createWorldTerrain.js index 0d8c39d3c71..54790e3474a 100644 --- a/packages/engine/Source/Core/createWorldTerrain.js +++ b/packages/engine/Source/Core/createWorldTerrain.js @@ -34,7 +34,7 @@ import IonResource from "./IonResource.js"; function createWorldTerrain(options) { deprecationWarning( "createWorldTerrain", - "createWorldTerrain was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use createWorldTerrainAsync instead." + "createWorldTerrain was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use createWorldTerrainAsync instead." ); options = defaultValue(options, defaultValue.EMPTY_OBJECT); From 42cbc6645f1f2bd854f17643746000281fd84e9a Mon Sep 17 00:00:00 2001 From: Rudi Farkas <rudi.farkas@gmail.com> Date: Wed, 8 Mar 2023 15:23:04 +0100 Subject: [PATCH 530/679] CreditDisplaySpec.js: move out of runTests() 3 tests that need no container --- .../engine/Specs/Scene/CreditDisplaySpec.js | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/packages/engine/Specs/Scene/CreditDisplaySpec.js b/packages/engine/Specs/Scene/CreditDisplaySpec.js index ac0bb34bfb9..45621f576e2 100644 --- a/packages/engine/Specs/Scene/CreditDisplaySpec.js +++ b/packages/engine/Specs/Scene/CreditDisplaySpec.js @@ -57,29 +57,50 @@ describe("Scene/CreditDisplay", function () { runTests(); }); + it("credit display throws with no container", function () { + expect(function () { + return new CreditDisplay(); + }).toThrowDeveloperError(); + }); + + it("credits have unique ids", function () { + const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + const credit2 = new Credit('<a href="http://cesiumjs.org/">credit2</a>'); + expect(credit1.id).not.toEqual(credit2.id); + + const credit3 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + expect(credit1.id).toEqual(credit3.id); + }); + + it("credit clone works", function () { + const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); + const credit2 = Credit.clone(credit1); + expect(credit1).toEqual(credit2); + const credit3 = Credit.clone(undefined); + expect(credit3).toBeUndefined(); + }); + function runTests() { // For the sake of the tests, we remove the logo // credit at the beginning of every frame function beginFrame(creditDisplay) { creditDisplay.beginFrame(); } - it("credit display throws with no container", function () { - expect(function () { - return new CreditDisplay(); - }).toThrowDeveloperError(); - }); + it("credit display addCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); creditDisplay.addCredit(); }).toThrowDeveloperError(); }); + it("credit display addDefaultCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); creditDisplay.addDefaultCredit(); }).toThrowDeveloperError(); }); + it("credit display removeDefaultCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); @@ -87,23 +108,6 @@ describe("Scene/CreditDisplay", function () { }).toThrowDeveloperError(); }); - it("credits have unique ids", function () { - const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - const credit2 = new Credit('<a href="http://cesiumjs.org/">credit2</a>'); - expect(credit1.id).not.toEqual(credit2.id); - - const credit3 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - expect(credit1.id).toEqual(credit3.id); - }); - - it("credit clone works", function () { - const credit1 = new Credit('<a href="http://cesiumjs.org/">credit1</a>'); - const credit2 = Credit.clone(credit1); - expect(credit1).toEqual(credit2); - const credit3 = Credit.clone(undefined); - expect(credit3).toBeUndefined(); - }); - it("credit display displays a credit", function () { creditDisplay = new CreditDisplay(container); const credit = new Credit( From 46a40bddc49caca9e0e4d3510a7ed83dcff1c93a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 8 Mar 2023 14:00:38 -0500 Subject: [PATCH 531/679] Minor edits for clarity and consistency with Coding Guide --- packages/engine/Source/Scene/Cesium3DTile.js | 30 ++++++-------- .../engine/Source/Scene/Cesium3DTileset.js | 18 ++++---- packages/engine/Source/Scene/Model/Model.js | 3 +- .../Source/Scene/Model/ModelDrawCommand.js | 41 +++++++------------ 4 files changed, 37 insertions(+), 55 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 1fb9138aa66..db922b9a637 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -1796,19 +1796,15 @@ Cesium3DTile.prototype.createBoundingVolume = function ( ); } - if (defined(boundingVolumeHeader.box)) { - return createBox(boundingVolumeHeader.box, transform, result); + const { box, region, sphere } = boundingVolumeHeader; + if (defined(box)) { + return createBox(box, transform, result); } - if (defined(boundingVolumeHeader.region)) { - return createRegion( - boundingVolumeHeader.region, - transform, - this._initialTransform, - result - ); + if (defined(region)) { + return createRegion(region, transform, this._initialTransform, result); } - if (defined(boundingVolumeHeader.sphere)) { - return createSphere(boundingVolumeHeader.sphere, transform, result); + if (defined(sphere)) { + return createSphere(sphere, transform, result); } throw new RuntimeError( "boundingVolume must contain a sphere, region, or box" @@ -2043,18 +2039,18 @@ function updateClippingPlanes(tile, tileset) { * @param {object} passOptions */ Cesium3DTile.prototype.update = function (tileset, frameState, passOptions) { - const commandStart = frameState.commandList.length; + const { commandList } = frameState; + const commandStart = commandList.length; updateClippingPlanes(this, tileset); applyDebugSettings(this, tileset, frameState, passOptions); updateContent(this, tileset, frameState); - const commandEnd = frameState.commandList.length; - const commandsLength = commandEnd - commandStart; - this._commandsLength = commandsLength; + const commandEnd = commandList.length; + this._commandsLength = commandEnd - commandStart; - for (let i = 0; i < commandsLength; ++i) { - const command = frameState.commandList[commandStart + i]; + for (let i = commandStart; i < commandEnd; ++i) { + const command = commandList[i]; const translucent = command.pass === Pass.TRANSLUCENT; command.depthForTranslucentClassification = translucent; } diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index a5042eabefe..5511a21ef52 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -2713,18 +2713,15 @@ function updateTiles(tileset, frameState, passOptions) { tileset._styleEngine.applyStyle(tileset); tileset._styleApplied = true; - const isRender = passOptions.isRender; - const { statistics, tileVisible } = tileset; - const commandList = frameState.commandList; + const { commandList, context } = frameState; const numberOfInitialCommands = commandList.length; const selectedTiles = tileset._selectedTiles; - const selectedLength = selectedTiles.length; const bivariateVisibilityTest = tileset._skipLevelOfDetail && tileset._hasMixedContent && - frameState.context.stencilBuffer && - selectedLength > 0; + context.stencilBuffer && + selectedTiles.length > 0; tileset._backfaceCommands.length = 0; @@ -2741,8 +2738,11 @@ function updateTiles(tileset, frameState, passOptions) { commandList.push(tileset._stencilClearCommand); } + const { statistics, tileVisible } = tileset; + const isRender = passOptions.isRender; const lengthBeforeUpdate = commandList.length; - for (let i = 0; i < selectedLength; ++i) { + + for (let i = 0; i < selectedTiles.length; ++i) { const tile = selectedTiles[i]; // Raise the tileVisible event before update in case the tileVisible event // handler makes changes that update needs to apply to WebGL resources @@ -3019,8 +3019,6 @@ function update(tileset, frameState, passStatistics, passOptions) { const statistics = tileset._statistics; statistics.clear(); - const isRender = passOptions.isRender; - // Resets the visibility check for each pass ++tileset._updatedVisibilityFrame; @@ -3042,7 +3040,7 @@ function update(tileset, frameState, passStatistics, passOptions) { // Update pass statistics Cesium3DTilesetStatistics.clone(statistics, passStatistics); - if (isRender) { + if (passOptions.isRender) { const credits = tileset._credits; if (defined(credits) && statistics.selected !== 0) { for (let i = 0; i < credits.length; ++i) { diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 59980de218e..a25ea3b0806 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -2444,8 +2444,7 @@ function supportsSkipLevelOfDetail(frameState) { * @private */ Model.prototype.hasSkipLevelOfDetail = function (frameState) { - const is3DTiles = ModelType.is3DTiles(this.type); - if (!is3DTiles) { + if (!ModelType.is3DTiles(this.type)) { return false; } diff --git a/packages/engine/Source/Scene/Model/ModelDrawCommand.js b/packages/engine/Source/Scene/Model/ModelDrawCommand.js index a82b75fc4b5..d24adea9cf1 100644 --- a/packages/engine/Source/Scene/Model/ModelDrawCommand.js +++ b/packages/engine/Source/Scene/Model/ModelDrawCommand.js @@ -437,9 +437,8 @@ function updateShadows(drawCommand) { const receiveShadows = ShadowMode.receiveShadows(shadows); const derivedCommands = drawCommand._derivedCommands; - const length = derivedCommands.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < derivedCommands.length; ++i) { const derivedCommand = derivedCommands[i]; if (derivedCommand.updateShadows) { const command = derivedCommand.command; @@ -451,11 +450,9 @@ function updateShadows(drawCommand) { function updateBackFaceCulling(drawCommand) { const backFaceCulling = drawCommand.backFaceCulling; - const derivedCommands = drawCommand._derivedCommands; - const length = derivedCommands.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < derivedCommands.length; ++i) { const derivedCommand = derivedCommands[i]; if (derivedCommand.updateBackFaceCulling) { const command = derivedCommand.command; @@ -468,11 +465,9 @@ function updateBackFaceCulling(drawCommand) { function updateCullFace(drawCommand) { const cullFace = drawCommand.cullFace; - const derivedCommands = drawCommand._derivedCommands; - const length = derivedCommands.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < derivedCommands.length; ++i) { const derivedCommand = derivedCommands[i]; if (derivedCommand.updateCullFace) { const command = derivedCommand.command; @@ -485,11 +480,9 @@ function updateCullFace(drawCommand) { function updateDebugShowBoundingVolume(drawCommand) { const debugShowBoundingVolume = drawCommand.debugShowBoundingVolume; - const derivedCommands = drawCommand._derivedCommands; - const length = derivedCommands.length; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < derivedCommands.length; ++i) { const derivedCommand = derivedCommands[i]; if (derivedCommand.updateDebugShowBoundingVolume) { const command = derivedCommand.command; @@ -537,15 +530,10 @@ ModelDrawCommand.prototype.pushCommands = function (frameState, result) { } if (this._needsSkipLevelOfDetailCommands) { - const content = this._model.content; - const tileset = content.tileset; - const tile = content.tile; - - const hasMixedContent = tileset._hasMixedContent; - const finalResolution = tile._finalResolution; + const { tileset, tile } = this._model.content; - if (hasMixedContent) { - if (!finalResolution) { + if (tileset._hasMixedContent) { + if (!tile._finalResolution) { pushCommand( tileset._backfaceCommands, this._skipLodBackfaceCommand, @@ -846,13 +834,14 @@ function deriveSkipLodStencilCommand(command) { const stencilCommand = DrawCommand.shallowClone(command); const renderState = clone(command.renderState, true); // The stencil reference is updated dynamically; see updateSkipLodStencilCommand(). - renderState.stencilTest.enabled = true; - renderState.stencilTest.mask = StencilConstants.SKIP_LOD_MASK; - renderState.stencilTest.reference = StencilConstants.CESIUM_3D_TILE_MASK; - renderState.stencilTest.frontFunction = StencilFunction.GREATER_OR_EQUAL; - renderState.stencilTest.frontOperation.zPass = StencilOperation.REPLACE; - renderState.stencilTest.backFunction = StencilFunction.GREATER_OR_EQUAL; - renderState.stencilTest.backOperation.zPass = StencilOperation.REPLACE; + const { stencilTest } = renderState; + stencilTest.enabled = true; + stencilTest.mask = StencilConstants.SKIP_LOD_MASK; + stencilTest.reference = StencilConstants.CESIUM_3D_TILE_MASK; + stencilTest.frontFunction = StencilFunction.GREATER_OR_EQUAL; + stencilTest.frontOperation.zPass = StencilOperation.REPLACE; + stencilTest.backFunction = StencilFunction.GREATER_OR_EQUAL; + stencilTest.backOperation.zPass = StencilOperation.REPLACE; renderState.stencilMask = StencilConstants.CESIUM_3D_TILE_MASK | StencilConstants.SKIP_LOD_MASK; From f3097718606c392d76754922bad1bab76ca54681 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 8 Mar 2023 15:58:23 -0500 Subject: [PATCH 532/679] Model readyPromise deprecation and minor loader refactor --- Specs/loaderProcess.js | 3 +- Specs/waitForLoaderProcess.js | 24 +- .../Source/DataSources/ModelVisualizer.js | 79 +- packages/engine/Source/Scene/BufferLoader.js | 61 +- .../Scene/Cesium3DTileContentFactory.js | 2 + .../Scene/Cesium3DTilesVoxelProvider.js | 7 +- .../engine/Source/Scene/Cesium3DTileset.js | 6 +- .../Source/Scene/GltfBufferViewLoader.js | 127 +- .../engine/Source/Scene/GltfDracoLoader.js | 205 +- .../engine/Source/Scene/GltfImageLoader.js | 144 +- .../Source/Scene/GltfIndexBufferLoader.js | 223 +- .../engine/Source/Scene/GltfJsonLoader.js | 145 +- packages/engine/Source/Scene/GltfLoader.js | 586 ++-- .../Scene/GltfStructuralMetadataLoader.js | 203 +- .../engine/Source/Scene/GltfTextureLoader.js | 174 +- .../Source/Scene/GltfVertexBufferLoader.js | 256 +- .../engine/Source/Scene/ImplicitSubtree.js | 4 +- .../Source/Scene/MetadataSchemaLoader.js | 62 +- packages/engine/Source/Scene/Model/Model.js | 528 +++- .../Source/Scene/Model/Model3DTileContent.js | 25 +- .../Scene/Model/ModelAnimationCollection.js | 4 +- .../engine/Source/Scene/Model/ModelUtility.js | 32 +- packages/engine/Source/Scene/ResourceCache.js | 152 +- .../Source/Scene/ResourceCacheStatistics.js | 83 +- .../engine/Source/Scene/ResourceLoader.js | 22 +- .../Source/Scene/ResourceLoaderState.js | 16 +- .../Specs/DataSources/ModelVisualizerSpec.js | 203 +- .../engine/Specs/Scene/BufferLoaderSpec.js | 100 +- .../Scene/GlobeSurfaceTileProviderSpec.js | 4 +- .../Specs/Scene/GltfBufferViewLoaderSpec.js | 143 +- .../engine/Specs/Scene/GltfDracoLoaderSpec.js | 129 +- .../engine/Specs/Scene/GltfImageLoaderSpec.js | 271 +- .../Specs/Scene/GltfIndexBufferLoaderSpec.js | 260 +- .../engine/Specs/Scene/GltfJsonLoaderSpec.js | 216 +- packages/engine/Specs/Scene/GltfLoaderSpec.js | 264 +- .../Scene/GltfStructuralMetadataLoaderSpec.js | 274 +- .../Specs/Scene/GltfTextureLoaderSpec.js | 216 +- .../Specs/Scene/GltfVertexBufferLoaderSpec.js | 302 +- .../Specs/Scene/MetadataSchemaLoaderSpec.js | 95 +- .../Model/ModelAnimationCollectionSpec.js | 80 +- .../Scene/Model/ModelMatrixUpdateStageSpec.js | 12 +- .../Specs/Scene/Model/ModelSceneGraphSpec.js | 102 +- .../engine/Specs/Scene/Model/ModelSpec.js | 714 +++-- .../Specs/Scene/Model/loadAndZoomToModel.js | 86 - .../Scene/Model/loadAndZoomToModelAsync.js | 67 + .../Scene/PostProcessStageLibrarySpec.js | 8 +- .../Specs/Scene/PostProcessStageSpec.js | 4 +- .../engine/Specs/Scene/ResourceCacheSpec.js | 2574 +++++++---------- packages/engine/Specs/Scene/ShadowMapSpec.js | 11 +- 49 files changed, 4372 insertions(+), 4936 deletions(-) delete mode 100644 packages/engine/Specs/Scene/Model/loadAndZoomToModel.js create mode 100644 packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js diff --git a/Specs/loaderProcess.js b/Specs/loaderProcess.js index d91ca294d4b..5953cb7dcf7 100644 --- a/Specs/loaderProcess.js +++ b/Specs/loaderProcess.js @@ -4,8 +4,9 @@ function loaderProcess(loader, scene) { // explicitly. This is only required for loaders that use the job scheduler // like GltfVertexBufferLoader, GltfIndexBufferLoader, and GltfTextureLoader scene.jobScheduler.resetBudgets(); - loader.process(scene.frameState); + const ready = loader.process(scene.frameState); scene.jobScheduler.resetBudgets(); + return ready; } export default loaderProcess; diff --git a/Specs/waitForLoaderProcess.js b/Specs/waitForLoaderProcess.js index 737fa7c6771..d46cc9ed3c0 100644 --- a/Specs/waitForLoaderProcess.js +++ b/Specs/waitForLoaderProcess.js @@ -2,26 +2,12 @@ import loaderProcess from "./loaderProcess.js"; import pollToPromise from "./pollToPromise.js"; function waitForLoaderProcess(loader, scene) { - return new Promise(function (resolve, reject) { - let loaderFinished = false; + return pollToPromise(function () { + if (loader.isDestroyed()) { + return true; + } - pollToPromise(function () { - loaderProcess(loader, scene); - return loaderFinished; - }).catch(function (e) { - reject(e); - }); - - loader.promise - .then(function (result) { - resolve(result); - }) - .catch(function (e) { - reject(e); - }) - .finally(function () { - loaderFinished = true; - }); + return loaderProcess(loader, scene); }); } diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index b86c061ffc5..9c2a49b1d29 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -102,45 +102,72 @@ ModelVisualizer.prototype.update = function (time) { } if (!show) { - if (defined(modelData)) { + if (defined(modelData) && modelData.modelPrimitive) { modelData.modelPrimitive.show = false; } continue; } - let model = defined(modelData) ? modelData.modelPrimitive : undefined; - if (!defined(model) || resource.url !== modelData.url) { - if (defined(model)) { - primitives.removeAndDestroy(model); + if (!defined(modelData) || resource.url !== modelData.url) { + if (defined(modelData?.modelPrimitive)) { + primitives.removeAndDestroy(modelData.modelPrimitive); delete modelHash[entity.id]; } - model = Model.fromGltf({ - url: resource, - incrementallyLoadTextures: Property.getValueOrDefault( - modelGraphics._incrementallyLoadTextures, - time, - defaultIncrementallyLoadTextures - ), - scene: this._scene, - }); - model.id = entity; - primitives.add(model); - modelData = { - modelPrimitive: model, + modelPrimitive: undefined, url: resource.url, animationsRunning: false, nodeTransformationsScratch: {}, articulationsScratch: {}, - loadFail: false, + loadFailed: false, awaitingSampleTerrain: false, clampedBoundingSphere: undefined, sampleTerrainFailed: false, }; modelHash[entity.id] = modelData; - checkModelLoad(model, entity, modelHash); + (async () => { + try { + const model = await Model.fromGltfAsync({ + url: resource, + incrementallyLoadTextures: Property.getValueOrDefault( + modelGraphics._incrementallyLoadTextures, + time, + defaultIncrementallyLoadTextures + ), + scene: this._scene, + }); + model.id = entity; + primitives.add(model); + modelHash[entity.id].modelPrimitive = model; + model.errorEvent.addEventListener((error) => { + if (!defined(modelHash[entity.id])) { + return; + } + + console.error(error); + + // Texture failures when incrementallyLoadTextures + // will not affect the ability to compute the bounding sphere + if (error.name !== "TextureError") { + modelHash[entity.id].loadFailed = true; + } + }); + } catch (error) { + if (!defined(modelHash[entity.id])) { + return; + } + + console.error(error); + modelHash[entity.id].loadFailed = true; + } + })(); + } + + const model = modelData.modelPrimitive; + if (!defined(model)) { + continue; } model.show = true; @@ -365,7 +392,11 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { //>>includeEnd('debug'); const modelData = this._modelHash[entity.id]; - if (!defined(modelData) || modelData.loadFail) { + if (!defined(modelData)) { + return BoundingSphereState.PENDING; + } + + if (modelData.loadFailed) { return BoundingSphereState.FAILED; } @@ -539,10 +570,4 @@ function clearNodeTransformationsArticulationsScratch(entity, modelHash) { } } -function checkModelLoad(model, entity, modelHash) { - model.readyPromise.catch(function (error) { - console.error(error); - modelHash[entity.id].loadFail = true; - }); -} export default ModelVisualizer; diff --git a/packages/engine/Source/Scene/BufferLoader.js b/packages/engine/Source/Scene/BufferLoader.js index f04cd75ad19..2246f485ac6 100644 --- a/packages/engine/Source/Scene/BufferLoader.js +++ b/packages/engine/Source/Scene/BufferLoader.js @@ -50,19 +50,6 @@ if (defined(Object.create)) { } Object.defineProperties(BufferLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof BufferLoader.prototype - * - * @type {Promise.<BufferLoader>|undefined} - * @readonly - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -96,35 +83,41 @@ Object.defineProperties(BufferLoader.prototype, { * @returns {Promise.<BufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -BufferLoader.prototype.load = function () { +BufferLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } + if (defined(this._typedArray)) { this._promise = Promise.resolve(this); - } else { - this._promise = loadExternalBuffer(this); + return this._promise; } + + this._promise = loadExternalBuffer(this); return this._promise; }; -function loadExternalBuffer(bufferLoader) { +async function loadExternalBuffer(bufferLoader) { const resource = bufferLoader._resource; bufferLoader._state = ResourceLoaderState.LOADING; - return BufferLoader._fetchArrayBuffer(resource) - .then(function (arrayBuffer) { - if (bufferLoader.isDestroyed()) { - return; - } - bufferLoader._typedArray = new Uint8Array(arrayBuffer); - bufferLoader._state = ResourceLoaderState.READY; - return bufferLoader; - }) - .catch(function (error) { - if (bufferLoader.isDestroyed()) { - return; - } - bufferLoader._state = ResourceLoaderState.FAILED; - const errorMessage = `Failed to load external buffer: ${resource.url}`; - return Promise.reject(bufferLoader.getError(errorMessage, error)); - }); + try { + const arrayBuffer = await BufferLoader._fetchArrayBuffer(resource); + if (bufferLoader.isDestroyed()) { + return; + } + + bufferLoader._typedArray = new Uint8Array(arrayBuffer); + bufferLoader._state = ResourceLoaderState.READY; + return bufferLoader; + } catch (error) { + if (bufferLoader.isDestroyed()) { + return; + } + + bufferLoader._state = ResourceLoaderState.FAILED; + const errorMessage = `Failed to load external buffer: ${resource.url}`; + throw bufferLoader.getError(errorMessage, error); + } } /** diff --git a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js index 9c8dd3e6230..23c6b39e892 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js +++ b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js @@ -92,9 +92,11 @@ const Cesium3DTileContentFactory = { const dataView = new DataView(arrayBuffer, byteOffset); const byteLength = dataView.getUint32(8, true); const glb = new Uint8Array(arrayBuffer, byteOffset, byteLength); + // This should be replace with fromGltfAsync when readyPromise is deprecated across 3D Tiles functions return Model3DTileContent.fromGltf(tileset, tile, resource, glb); }, gltf: function (tileset, tile, resource, json) { + // This should be replace with fromGltfAsync when readyPromise is deprecated across 3D Tiles functions return Model3DTileContent.fromGltf(tileset, tile, resource, json); }, geoJson: function (tileset, tile, resource, json) { diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 90477276db8..348462c03d3 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -106,7 +106,8 @@ function Cesium3DTilesVoxelProvider(options) { .then(function (tileset) { tilesetJson = tileset; validate(tilesetJson); - return getMetadataSchemaLoader(tilesetJson, resource).promise; + const schemaLoader = getMetadataSchemaLoader(tilesetJson, resource); + return schemaLoader.load(); }) .then(function (schemaLoader) { const root = tilesetJson.root; @@ -306,9 +307,9 @@ function getCylinderShape(cylinder, tileTransform) { function getMetadataSchemaLoader(tilesetJson, resource) { const { schemaUri, schema } = tilesetJson; if (!defined(schemaUri)) { - return ResourceCache.loadSchema({ schema }); + return ResourceCache.getSchemaLoader({ schema }); } - return ResourceCache.loadSchema({ + return ResourceCache.getSchemaLoader({ resource: resource.getDerivedResource({ url: schemaUri, }), diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index d3f8209d05c..977464a2506 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -2151,11 +2151,11 @@ function processMetadataExtension(tileset, tilesetJson) { const resource = tileset._resource.getDerivedResource({ url: metadataJson.schemaUri, }); - schemaLoader = ResourceCache.loadSchema({ + schemaLoader = ResourceCache.getSchemaLoader({ resource: resource, }); } else if (defined(metadataJson.schema)) { - schemaLoader = ResourceCache.loadSchema({ + schemaLoader = ResourceCache.getSchemaLoader({ schema: metadataJson.schema, }); } else { @@ -2164,7 +2164,7 @@ function processMetadataExtension(tileset, tilesetJson) { tileset._schemaLoader = schemaLoader; - return schemaLoader.promise.then(function (schemaLoader) { + return schemaLoader.load().then(function (schemaLoader) { tileset._metadataExtension = new Cesium3DTilesetMetadata({ schema: schemaLoader.schema, metadataJson: metadataJson, diff --git a/packages/engine/Source/Scene/GltfBufferViewLoader.js b/packages/engine/Source/Scene/GltfBufferViewLoader.js index e43b2ace1b8..717ba0b09fa 100644 --- a/packages/engine/Source/Scene/GltfBufferViewLoader.js +++ b/packages/engine/Source/Scene/GltfBufferViewLoader.js @@ -87,7 +87,6 @@ function GltfBufferViewLoader(options) { this._typedArray = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; - this._process = function (loader, frameState) {}; } if (defined(Object.create)) { @@ -96,20 +95,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfBufferViewLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfBufferViewLoader.prototype - * - * @type {Promise.<GltfBufferViewLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -145,77 +130,61 @@ Object.defineProperties(GltfBufferViewLoader.prototype, { * @returns {Promise.<GltfBufferViewLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfBufferViewLoader.prototype.load = function () { - const bufferLoader = getBufferLoader(this); - this._bufferLoader = bufferLoader; - this._state = ResourceLoaderState.LOADING; - - const that = this; - const bufferViewPromise = new Promise(function (resolve) { - that._process = function (loader, frameState) { - if (!loader._hasMeshopt) { - return; - } +GltfBufferViewLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } - if (!defined(loader._typedArray)) { - return; - } + this._promise = (async () => { + this._state = ResourceLoaderState.LOADING; + try { + const bufferLoader = getBufferLoader(this); + this._bufferLoader = bufferLoader; + await bufferLoader.load(); - if (loader._state !== ResourceLoaderState.PROCESSING) { + if (this.isDestroyed()) { return; } - const count = loader._meshoptCount; - const byteStride = loader._meshoptByteStride; - const result = new Uint8Array(count * byteStride); - MeshoptDecoder.decodeGltfBuffer( - result, - count, - byteStride, - loader._typedArray, - loader._meshoptMode, - loader._meshoptFilter - ); - - loader._typedArray = result; - loader._state = ResourceLoaderState.READY; - resolve(loader); - }; - }); - - this._promise = bufferLoader.promise - .then(function () { - if (that.isDestroyed()) { - return; - } const bufferTypedArray = bufferLoader.typedArray; const bufferViewTypedArray = new Uint8Array( bufferTypedArray.buffer, - bufferTypedArray.byteOffset + that._byteOffset, - that._byteLength + bufferTypedArray.byteOffset + this._byteOffset, + this._byteLength ); // Unload the buffer - that.unload(); - - that._typedArray = bufferViewTypedArray; - if (that._hasMeshopt) { - that._state = ResourceLoaderState.PROCESSING; - return bufferViewPromise; + this.unload(); + + this._typedArray = bufferViewTypedArray; + if (this._hasMeshopt) { + const count = this._meshoptCount; + const byteStride = this._meshoptByteStride; + const result = new Uint8Array(count * byteStride); + MeshoptDecoder.decodeGltfBuffer( + result, + count, + byteStride, + this._typedArray, + this._meshoptMode, + this._meshoptFilter + ); + this._typedArray = result; } - that._state = ResourceLoaderState.READY; - return that; - }) - .catch(function (error) { - if (that.isDestroyed()) { + this._state = ResourceLoaderState.READY; + return this; + } catch (error) { + if (this.isDestroyed()) { return; } - that.unload(); - that._state = ResourceLoaderState.FAILED; + + this.unload(); + this._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load buffer view"; - return Promise.reject(that.getError(errorMessage, error)); - }); + throw this.getError(errorMessage, error); + } + })(); return this._promise; }; @@ -228,30 +197,16 @@ function getBufferLoader(bufferViewLoader) { const resource = baseResource.getDerivedResource({ url: buffer.uri, }); - return resourceCache.loadExternalBuffer({ + return resourceCache.getExternalBufferLoader({ resource: resource, }); } - return resourceCache.loadEmbeddedBuffer({ + return resourceCache.getEmbeddedBufferLoader({ parentResource: bufferViewLoader._gltfResource, bufferId: bufferViewLoader._bufferId, }); } -/** - * Processes the resources. For a BufferView that does not have the EXT_meshopt_compression extension, there - * is no processing that needs to happen, so this function returns immediately. - * - * @param {FrameState} frameState The frame state. - */ -GltfBufferViewLoader.prototype.process = function (frameState) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.object("frameState", frameState); - //>>includeEnd('debug'); - - return this._process(this, frameState); -}; - /** * Unloads the resource. * @private diff --git a/packages/engine/Source/Scene/GltfDracoLoader.js b/packages/engine/Source/Scene/GltfDracoLoader.js index 49481b13af0..038e73d5c0d 100644 --- a/packages/engine/Source/Scene/GltfDracoLoader.js +++ b/packages/engine/Source/Scene/GltfDracoLoader.js @@ -54,7 +54,7 @@ function GltfDracoLoader(options) { this._decodedData = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; - this._process = function (loader, frameState) {}; + this._dracoError = undefined; } if (defined(Object.create)) { @@ -63,20 +63,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfDracoLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready. - * - * @memberof GltfDracoLoader.prototype - * - * @type {Promise.<GltfDracoLoader>} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -112,101 +98,39 @@ Object.defineProperties(GltfDracoLoader.prototype, { * @returns {Promise.<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfDracoLoader.prototype.load = function () { - const resourceCache = this._resourceCache; - const bufferViewLoader = resourceCache.loadBufferView({ - gltf: this._gltf, - bufferViewId: this._draco.bufferView, - gltfResource: this._gltfResource, - baseResource: this._baseResource, - }); - - this._bufferViewLoader = bufferViewLoader; +GltfDracoLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } + this._state = ResourceLoaderState.LOADING; - const that = this; - const dracoPromise = new Promise(function (resolve, reject) { - that._process = function (loader, frameState) { - if (!defined(loader._bufferViewTypedArray)) { - // Not ready to decode the Draco buffer + const resourceCache = this._resourceCache; + this._promise = (async () => { + try { + const bufferViewLoader = resourceCache.getBufferViewLoader({ + gltf: this._gltf, + bufferViewId: this._draco.bufferView, + gltfResource: this._gltfResource, + baseResource: this._baseResource, + }); + this._bufferViewLoader = bufferViewLoader; + await bufferViewLoader.load(); + + if (this.isDestroyed()) { return; } - if (defined(loader._decodePromise)) { - // Currently decoding + this._bufferViewTypedArray = bufferViewLoader.typedArray; + this._state = ResourceLoaderState.PROCESSING; + return this; + } catch (error) { + if (this.isDestroyed()) { return; } - const draco = loader._draco; - const gltf = loader._gltf; - const bufferViews = gltf.bufferViews; - const bufferViewId = draco.bufferView; - const bufferView = bufferViews[bufferViewId]; - const compressedAttributes = draco.attributes; - - const decodeOptions = { - // Need to make a copy of the typed array otherwise the underlying - // ArrayBuffer may be accessed on both the worker and the main thread. This - // leads to errors such as "ArrayBuffer at index 0 is already detached". - // PERFORMANCE_IDEA: Look into SharedArrayBuffer to get around this. - array: new Uint8Array(loader._bufferViewTypedArray), - bufferView: bufferView, - compressedAttributes: compressedAttributes, - dequantizeInShader: true, - }; - - const decodePromise = DracoLoader.decodeBufferView(decodeOptions); - - if (!defined(decodePromise)) { - // Cannot schedule task this frame - return; - } - - loader._decodePromise = decodePromise - .then(function (results) { - if (loader.isDestroyed()) { - resolve(); - return; - } - - // Unload everything except the decoded data - loader.unload(); - - loader._decodedData = { - indices: results.indexArray, - vertexAttributes: results.attributeData, - }; - loader._state = ResourceLoaderState.READY; - resolve(loader); - }) - .catch(function (e) { - if (loader.isDestroyed()) { - resolve(); - return; - } - - reject(e); - }); - }; - }); - - this._promise = bufferViewLoader.promise - .then(function () { - if (that.isDestroyed()) { - return; - } - // Now wait for process() to run to finish loading - that._bufferViewTypedArray = bufferViewLoader.typedArray; - that._state = ResourceLoaderState.PROCESSING; - - return dracoPromise; - }) - .catch(function (error) { - if (that.isDestroyed()) { - return; - } - - return handleError(that, error); - }); + handleError(this, error); + } + })(); return this._promise; }; @@ -215,7 +139,7 @@ function handleError(dracoLoader, error) { dracoLoader.unload(); dracoLoader._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load Draco"; - return Promise.reject(dracoLoader.getError(errorMessage, error)); + throw dracoLoader.getError(errorMessage, error); } /** @@ -229,7 +153,78 @@ GltfDracoLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - return this._process(this, frameState); + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if (this._state !== ResourceLoaderState.PROCESSING) { + return false; + } + + if (defined(this._dracoError)) { + handleError(this, this._dracoError); + } + + if (!defined(this._bufferViewTypedArray)) { + // Not ready to decode the Draco buffer + return false; + } + + if (defined(this._decodePromise)) { + // Currently decoding + return false; + } + + const draco = this._draco; + const gltf = this._gltf; + const bufferViews = gltf.bufferViews; + const bufferViewId = draco.bufferView; + const bufferView = bufferViews[bufferViewId]; + const compressedAttributes = draco.attributes; + + const decodeOptions = { + // Need to make a copy of the typed array otherwise the underlying + // ArrayBuffer may be accessed on both the worker and the main thread. This + // leads to errors such as "ArrayBuffer at index 0 is already detached". + // PERFORMANCE_IDEA: Look into SharedArrayBuffer to get around this. + array: new Uint8Array(this._bufferViewTypedArray), + bufferView: bufferView, + compressedAttributes: compressedAttributes, + dequantizeInShader: true, + }; + + const decodePromise = DracoLoader.decodeBufferView(decodeOptions); + + if (!defined(decodePromise)) { + // Cannot schedule task this frame + return false; + } + + this._decodePromise = (async () => { + try { + const results = await decodePromise; + if (this.isDestroyed()) { + return; + } + + // Unload everything except the decoded data + this.unload(); + + this._decodedData = { + indices: results.indexArray, + vertexAttributes: results.attributeData, + }; + this._state = ResourceLoaderState.READY; + return this._baseResource; + } catch (error) { + if (this.isDestroyed()) { + return; + } + + // Capture this error so it can be thrown on the next `process` call + this._dracoError = error; + } + })(); }; /** diff --git a/packages/engine/Source/Scene/GltfImageLoader.js b/packages/engine/Source/Scene/GltfImageLoader.js index 53e42898325..5994ed9e94e 100644 --- a/packages/engine/Source/Scene/GltfImageLoader.js +++ b/packages/engine/Source/Scene/GltfImageLoader.js @@ -68,20 +68,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfImageLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfImageLoader.prototype - * - * @type {Promise.<GltfImageLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -132,6 +118,10 @@ Object.defineProperties(GltfImageLoader.prototype, { * @private */ GltfImageLoader.prototype.load = function () { + if (defined(this._promise)) { + return this._promise; + } + if (defined(this._bufferViewId)) { this._promise = loadFromBufferView(this); return this._promise; @@ -158,78 +148,78 @@ function getImageAndMipLevels(image) { }; } -function loadFromBufferView(imageLoader) { +async function loadFromBufferView(imageLoader) { + imageLoader._state = ResourceLoaderState.LOADING; const resourceCache = imageLoader._resourceCache; - const bufferViewLoader = resourceCache.loadBufferView({ - gltf: imageLoader._gltf, - bufferViewId: imageLoader._bufferViewId, - gltfResource: imageLoader._gltfResource, - baseResource: imageLoader._baseResource, - }); + try { + const bufferViewLoader = resourceCache.getBufferViewLoader({ + gltf: imageLoader._gltf, + bufferViewId: imageLoader._bufferViewId, + gltfResource: imageLoader._gltfResource, + baseResource: imageLoader._baseResource, + }); + imageLoader._bufferViewLoader = bufferViewLoader; + await bufferViewLoader.load(); - imageLoader._bufferViewLoader = bufferViewLoader; - imageLoader._state = ResourceLoaderState.LOADING; + if (imageLoader.isDestroyed()) { + return; + } - return bufferViewLoader.promise - .then(function () { - if (imageLoader.isDestroyed()) { - return; - } - - const typedArray = bufferViewLoader.typedArray; - return loadImageFromBufferTypedArray(typedArray).then(function (image) { - if (imageLoader.isDestroyed()) { - return; - } - - const imageAndMipLevels = getImageAndMipLevels(image); - - // Unload everything except the image - imageLoader.unload(); - - imageLoader._image = imageAndMipLevels.image; - imageLoader._mipLevels = imageAndMipLevels.mipLevels; - imageLoader._state = ResourceLoaderState.READY; - return imageLoader; - }); - }) - .catch(function (error) { - if (imageLoader.isDestroyed()) { - return; - } - return handleError(imageLoader, error, "Failed to load embedded image"); - }); + const typedArray = bufferViewLoader.typedArray; + const image = await loadImageFromBufferTypedArray(typedArray); + if (imageLoader.isDestroyed()) { + return; + } + + const imageAndMipLevels = getImageAndMipLevels(image); + + // Unload everything except the image + imageLoader.unload(); + + imageLoader._image = imageAndMipLevels.image; + imageLoader._mipLevels = imageAndMipLevels.mipLevels; + imageLoader._state = ResourceLoaderState.READY; + + return imageLoader; + } catch (error) { + if (imageLoader.isDestroyed()) { + return; + } + + return handleError(imageLoader, error, "Failed to load embedded image"); + } } -function loadFromUri(imageLoader) { +async function loadFromUri(imageLoader) { + imageLoader._state = ResourceLoaderState.LOADING; const baseResource = imageLoader._baseResource; const uri = imageLoader._uri; const resource = baseResource.getDerivedResource({ url: uri, }); - imageLoader._state = ResourceLoaderState.LOADING; - return loadImageFromUri(resource) - .then(function (image) { - if (imageLoader.isDestroyed()) { - return; - } - - const imageAndMipLevels = getImageAndMipLevels(image); - - // Unload everything except the image - imageLoader.unload(); - - imageLoader._image = imageAndMipLevels.image; - imageLoader._mipLevels = imageAndMipLevels.mipLevels; - imageLoader._state = ResourceLoaderState.READY; - return imageLoader; - }) - .catch(function (error) { - if (imageLoader.isDestroyed()) { - return; - } - return handleError(imageLoader, error, `Failed to load image: ${uri}`); - }); + + try { + const image = await loadImageFromUri(resource); + if (imageLoader.isDestroyed()) { + return; + } + + const imageAndMipLevels = getImageAndMipLevels(image); + + // Unload everything except the image + imageLoader.unload(); + + imageLoader._image = imageAndMipLevels.image; + imageLoader._mipLevels = imageAndMipLevels.mipLevels; + imageLoader._state = ResourceLoaderState.READY; + + return imageLoader; + } catch (error) { + if (imageLoader.isDestroyed()) { + return; + } + return handleError(imageLoader, error, `Failed to load image: ${uri}`); + } } function handleError(imageLoader, error, errorMessage) { @@ -269,7 +259,7 @@ function getMimeTypeFromTypedArray(typedArray) { throw new RuntimeError("Image format is not recognized"); } -function loadImageFromBufferTypedArray(typedArray) { +async function loadImageFromBufferTypedArray(typedArray) { const mimeType = getMimeTypeFromTypedArray(typedArray); if (mimeType === "image/ktx2") { // Need to make a copy of the embedded KTX2 buffer otherwise the underlying diff --git a/packages/engine/Source/Scene/GltfIndexBufferLoader.js b/packages/engine/Source/Scene/GltfIndexBufferLoader.js index b5006e4cbef..dc7bdcf9b6d 100644 --- a/packages/engine/Source/Scene/GltfIndexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfIndexBufferLoader.js @@ -79,7 +79,6 @@ function GltfIndexBufferLoader(options) { this._buffer = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; - this._process = function (loader, frameState) {}; } if (defined(Object.create)) { @@ -88,20 +87,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfIndexBufferLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource has not yet started loading. - * - * @memberof GltfIndexBufferLoader.prototype - * - * @type {Promise.<GltfIndexBufferLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -168,135 +153,72 @@ const scratchIndexBufferJob = new CreateIndexBufferJob(); * @returns {Promise.<GltfIndexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfIndexBufferLoader.prototype.load = function () { - let promise; +GltfIndexBufferLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } if (defined(this._draco)) { - promise = loadFromDraco(this); - } else { - promise = loadFromBufferView(this); + this._promise = loadFromDraco(this); + return this._promise; } - const that = this; - const processPromise = new Promise(function (resolve) { - that._process = function (loader, frameState) { - if (loader._state === ResourceLoaderState.READY) { - return; - } - - const typedArray = loader._typedArray; - const indexDatatype = loader._indexDatatype; - - if (defined(loader._dracoLoader)) { - loader._dracoLoader.process(frameState); - } - - if (defined(loader._bufferViewLoader)) { - loader._bufferViewLoader.process(frameState); - } - - if (!defined(typedArray)) { - // Buffer view hasn't been loaded yet - return; - } - - let buffer; - if (loader._loadBuffer && loader._asynchronous) { - const indexBufferJob = scratchIndexBufferJob; - indexBufferJob.set(typedArray, indexDatatype, frameState.context); - const jobScheduler = frameState.jobScheduler; - if (!jobScheduler.execute(indexBufferJob, JobType.BUFFER)) { - // Job scheduler is full. Try again next frame. - return; - } - buffer = indexBufferJob.buffer; - } else if (loader._loadBuffer) { - buffer = createIndexBuffer( - typedArray, - indexDatatype, - frameState.context - ); - } - - // Unload everything except the index buffer and/or typed array. - loader.unload(); - - loader._buffer = buffer; - loader._typedArray = loader._loadTypedArray ? typedArray : undefined; - loader._state = ResourceLoaderState.READY; - resolve(loader); - }; - }); - - this._promise = promise - .then(function () { - if (that.isDestroyed()) { - return; - } - - return processPromise; - }) - .catch(function (error) { - if (that.isDestroyed()) { - return; - } - - return handleError(that, error); - }); - + this._promise = loadFromBufferView(this); return this._promise; }; -function loadFromDraco(indexBufferLoader) { +async function loadFromDraco(indexBufferLoader) { + indexBufferLoader._state = ResourceLoaderState.LOADING; const resourceCache = indexBufferLoader._resourceCache; - const dracoLoader = resourceCache.loadDraco({ - gltf: indexBufferLoader._gltf, - draco: indexBufferLoader._draco, - gltfResource: indexBufferLoader._gltfResource, - baseResource: indexBufferLoader._baseResource, - }); - indexBufferLoader._dracoLoader = dracoLoader; - indexBufferLoader._state = ResourceLoaderState.LOADING; + try { + const dracoLoader = resourceCache.getDracoLoader({ + gltf: indexBufferLoader._gltf, + draco: indexBufferLoader._draco, + gltfResource: indexBufferLoader._gltfResource, + baseResource: indexBufferLoader._baseResource, + }); + indexBufferLoader._dracoLoader = dracoLoader; + await dracoLoader.load(); - return dracoLoader.promise.then(function () { if (indexBufferLoader.isDestroyed()) { return; } + // Now wait for process() to run to finish loading - const typedArray = dracoLoader.decodedData.indices.typedArray; - indexBufferLoader._typedArray = typedArray; - // The index datatype may be a smaller datatype after draco decode - indexBufferLoader._indexDatatype = ComponentDatatype.fromTypedArray( - typedArray - ); - indexBufferLoader._state = ResourceLoaderState.PROCESSING; + indexBufferLoader._state = ResourceLoaderState.LOADED; return indexBufferLoader; - }); + } catch (error) { + if (indexBufferLoader.isDestroyed()) { + return; + } + + handleError(indexBufferLoader, error); + } } -function loadFromBufferView(indexBufferLoader) { +async function loadFromBufferView(indexBufferLoader) { const gltf = indexBufferLoader._gltf; const accessorId = indexBufferLoader._accessorId; const accessor = gltf.accessors[accessorId]; const bufferViewId = accessor.bufferView; - const resourceCache = indexBufferLoader._resourceCache; - const bufferViewLoader = resourceCache.loadBufferView({ - gltf: gltf, - bufferViewId: bufferViewId, - gltfResource: indexBufferLoader._gltfResource, - baseResource: indexBufferLoader._baseResource, - }); indexBufferLoader._state = ResourceLoaderState.LOADING; - indexBufferLoader._bufferViewLoader = bufferViewLoader; + const resourceCache = indexBufferLoader._resourceCache; + try { + const bufferViewLoader = resourceCache.getBufferViewLoader({ + gltf: gltf, + bufferViewId: bufferViewId, + gltfResource: indexBufferLoader._gltfResource, + baseResource: indexBufferLoader._baseResource, + }); + indexBufferLoader._bufferViewLoader = bufferViewLoader; - return bufferViewLoader.promise.then(function () { + await bufferViewLoader.load(); if (indexBufferLoader.isDestroyed()) { return; } - // Now wait for process() to run to finish loading const bufferViewTypedArray = bufferViewLoader.typedArray; indexBufferLoader._typedArray = createIndicesTypedArray( indexBufferLoader, @@ -304,7 +226,13 @@ function loadFromBufferView(indexBufferLoader) { ); indexBufferLoader._state = ResourceLoaderState.PROCESSING; return indexBufferLoader; - }); + } catch (error) { + if (indexBufferLoader.isDestroyed()) { + return; + } + + handleError(indexBufferLoader, error); + } } function createIndicesTypedArray(indexBufferLoader, bufferViewTypedArray) { @@ -346,8 +274,7 @@ function handleError(indexBufferLoader, error) { indexBufferLoader.unload(); indexBufferLoader._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load index buffer"; - error = indexBufferLoader.getError(errorMessage, error); - return Promise.reject(error); + throw indexBufferLoader.getError(errorMessage, error); } function CreateIndexBufferJob() { @@ -397,7 +324,63 @@ GltfIndexBufferLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - return this._process(this, frameState); + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if ( + this._state !== ResourceLoaderState.LOADED && + this._state !== ResourceLoaderState.PROCESSING + ) { + return false; + } + + const typedArray = this._typedArray; + const indexDatatype = this._indexDatatype; + + if (defined(this._dracoLoader)) { + try { + const ready = this._dracoLoader.process(frameState); + if (ready) { + const dracoLoader = this._dracoLoader; + const typedArray = dracoLoader.decodedData.indices.typedArray; + this._typedArray = typedArray; + // The index datatype may be a smaller datatype after draco decode + this._indexDatatype = ComponentDatatype.fromTypedArray(typedArray); + } + } catch (error) { + handleError(this, error); + } + } + + if (!defined(typedArray)) { + // Buffer view hasn't been loaded yet + return false; + } + + let buffer; + if (this._loadBuffer && this._asynchronous) { + const indexBufferJob = scratchIndexBufferJob; + indexBufferJob.set(typedArray, indexDatatype, frameState.context); + const jobScheduler = frameState.jobScheduler; + if (!jobScheduler.execute(indexBufferJob, JobType.BUFFER)) { + // Job scheduler is full. Try again next frame. + return false; + } + buffer = indexBufferJob.buffer; + } else if (this._loadBuffer) { + buffer = createIndexBuffer(typedArray, indexDatatype, frameState.context); + } + + // Unload everything except the index buffer and/or typed array. + this.unload(); + + this._buffer = buffer; + this._typedArray = this._loadTypedArray ? typedArray : undefined; + this._state = ResourceLoaderState.READY; + + this._resourceCache.statistics.addGeometryLoader(this); + return true; }; /** diff --git a/packages/engine/Source/Scene/GltfJsonLoader.js b/packages/engine/Source/Scene/GltfJsonLoader.js index fdf7acb60ef..c61017ba087 100644 --- a/packages/engine/Source/Scene/GltfJsonLoader.js +++ b/packages/engine/Source/Scene/GltfJsonLoader.js @@ -68,20 +68,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfJsonLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfJsonLoader.prototype - * - * @type {Promise.<GltfJsonLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -117,56 +103,55 @@ Object.defineProperties(GltfJsonLoader.prototype, { * @returns {Promise.<GltfJsonLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfJsonLoader.prototype.load = function () { +GltfJsonLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } + this._state = ResourceLoaderState.LOADING; - let processPromise; if (defined(this._gltfJson)) { - processPromise = processGltfJson(this, this._gltfJson); - } else if (defined(this._typedArray)) { - processPromise = processGltfTypedArray(this, this._typedArray); - } else { - processPromise = loadFromUri(this); + this._promise = processGltfJson(this, this._gltfJson); + return this._promise; } - const that = this; - this._promise = processPromise - .then(function (gltf) { - if (that.isDestroyed()) { - return; - } - that._gltf = gltf; - that._state = ResourceLoaderState.READY; - return that; - }) - .catch(function (error) { - if (that.isDestroyed()) { - return; - } - return handleError(that, error); - }); + if (defined(this._typedArray)) { + this._promise = processGltfTypedArray(this, this._typedArray); + return this._promise; + } + this._promise = loadFromUri(this); return this._promise; }; -function loadFromUri(gltfJsonLoader) { - return gltfJsonLoader._fetchGltf().then(function (arrayBuffer) { +async function loadFromUri(gltfJsonLoader) { + let typedArray; + try { + const arrayBuffer = await gltfJsonLoader._fetchGltf(); if (gltfJsonLoader.isDestroyed()) { return; } - const typedArray = new Uint8Array(arrayBuffer); - return processGltfTypedArray(gltfJsonLoader, typedArray); - }); + + typedArray = new Uint8Array(arrayBuffer); + } catch (error) { + if (gltfJsonLoader.isDestroyed()) { + return; + } + + handleError(gltfJsonLoader, error); + } + + return processGltfTypedArray(gltfJsonLoader, typedArray); } function handleError(gltfJsonLoader, error) { gltfJsonLoader.unload(); gltfJsonLoader._state = ResourceLoaderState.FAILED; const errorMessage = `Failed to load glTF: ${gltfJsonLoader._gltfResource.url}`; - return Promise.reject(gltfJsonLoader.getError(errorMessage, error)); + throw gltfJsonLoader.getError(errorMessage, error); } -function upgradeVersion(gltfJsonLoader, gltf) { +async function upgradeVersion(gltfJsonLoader, gltf) { if ( defined(gltf.asset) && gltf.asset.version === "2.0" && @@ -188,23 +173,25 @@ function upgradeVersion(gltfJsonLoader, gltf) { url: buffer.uri, }); const resourceCache = gltfJsonLoader._resourceCache; - const bufferLoader = resourceCache.loadExternalBuffer({ + const bufferLoader = resourceCache.getExternalBufferLoader({ resource: resource, }); - gltfJsonLoader._bufferLoaders.push(bufferLoader); promises.push( - bufferLoader.promise.then(function (bufferLoader) { + bufferLoader.load().then(function () { + if (bufferLoader.isDestroyed()) { + return; + } + buffer.extras._pipeline.source = bufferLoader.typedArray; }) ); } }); - return Promise.all(promises).then(function () { - updateVersion(gltf); - }); + await Promise.all(promises); + updateVersion(gltf); } function decodeDataUris(gltf) { @@ -233,42 +220,54 @@ function loadEmbeddedBuffers(gltfJsonLoader, gltf) { const source = buffer.extras._pipeline.source; if (defined(source) && !defined(buffer.uri)) { const resourceCache = gltfJsonLoader._resourceCache; - const bufferLoader = resourceCache.loadEmbeddedBuffer({ + const bufferLoader = resourceCache.getEmbeddedBufferLoader({ parentResource: gltfJsonLoader._gltfResource, bufferId: bufferId, typedArray: source, }); - gltfJsonLoader._bufferLoaders.push(bufferLoader); - promises.push(bufferLoader.promise); + promises.push(bufferLoader.load()); } }); return Promise.all(promises); } -function processGltfJson(gltfJsonLoader, gltf) { - addPipelineExtras(gltf); - - return decodeDataUris(gltf) - .then(function () { - return upgradeVersion(gltfJsonLoader, gltf); - }) - .then(function () { - addDefaults(gltf); - return loadEmbeddedBuffers(gltfJsonLoader, gltf); - }) - .then(function () { - removePipelineExtras(gltf); - return gltf; - }); +async function processGltfJson(gltfJsonLoader, gltf) { + try { + addPipelineExtras(gltf); + + await decodeDataUris(gltf); + await upgradeVersion(gltfJsonLoader, gltf); + addDefaults(gltf); + await loadEmbeddedBuffers(gltfJsonLoader, gltf); + removePipelineExtras(gltf); + + gltfJsonLoader._gltf = gltf; + gltfJsonLoader._state = ResourceLoaderState.READY; + return gltfJsonLoader; + } catch (error) { + if (gltfJsonLoader.isDestroyed()) { + return; + } + + handleError(gltfJsonLoader, error); + } } -function processGltfTypedArray(gltfJsonLoader, typedArray) { +async function processGltfTypedArray(gltfJsonLoader, typedArray) { let gltf; - if (getMagic(typedArray) === "glTF") { - gltf = parseGlb(typedArray); - } else { - gltf = getJsonFromTypedArray(typedArray); + try { + if (getMagic(typedArray) === "glTF") { + gltf = parseGlb(typedArray); + } else { + gltf = getJsonFromTypedArray(typedArray); + } + } catch (error) { + if (gltfJsonLoader.isDestroyed()) { + return; + } + + handleError(gltfJsonLoader, error); } return processGltfJson(gltfJsonLoader, gltf); diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index 20655d764f4..6b2b5ca7f41 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -242,9 +242,8 @@ function GltfLoader(options) { this._state = GltfLoaderState.NOT_LOADED; this._textureState = GltfLoaderState.NOT_LOADED; this._promise = undefined; - this._texturesLoadedPromise = undefined; - this._process = function (loader, frameState) {}; - this._processTextures = function (loader, frameState) {}; + this._processError = undefined; + this._textureErrors = []; // Information about whether to load primitives as typed arrays or buffers, // and whether post-processing is needed after loading (e.g. for @@ -255,9 +254,12 @@ function GltfLoader(options) { this._loaderPromises = []; this._textureLoaders = []; this._texturesPromises = []; + this._textureCallbacks = {}; this._bufferViewLoaders = []; this._geometryLoaders = []; + this._geometryCallbacks = []; this._structuralMetadataLoader = undefined; + this._loadResourcesPromise = undefined; // In some cases where geometry post-processing is needed (like generating // outlines) new attributes are added that may have GPU resources attached. @@ -275,231 +277,207 @@ if (defined(Object.create)) { Object.defineProperties(GltfLoader.prototype, { /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. + * The cache key of the resource. * * @memberof GltfLoader.prototype * - * @type {Promise.<GltfLoader>|undefined} + * @type {String} * @readonly * @private */ - promise: { + cacheKey: { get: function () { - return this._promise; + return undefined; }, }, /** - * The cache key of the resource. + * The loaded components. * * @memberof GltfLoader.prototype * - * @type {String} + * @type {ModelComponents.Components} * @readonly * @private */ - cacheKey: { + components: { get: function () { - return undefined; + return this._components; }, }, /** - * The loaded components. + * The loaded glTF json. * * @memberof GltfLoader.prototype * - * @type {ModelComponents.Components} + * @type {object} * @readonly * @private */ - components: { + gltfJson: { get: function () { - return this._components; + if (defined(this._gltfJsonLoader)) { + return this._gltfJsonLoader.gltf; + } + return this._gltfJson; }, }, - /** - * A promise that resolves when all textures are loaded. - * When <code>incrementallyLoadTextures</code> is true this may resolve after - * <code>promise</code> resolves. + * true if textures are loaded separately from the other glTF resources. * * @memberof GltfLoader.prototype * - * @type {Promise<void>} + * @type {boolean} * @readonly * @private */ - texturesLoadedPromise: { + incrementallyLoadTextures: { get: function () { - return this._texturesLoadedPromise; + return this._incrementallyLoadTextures; }, }, }); /** - * Loads the resource. - * @returns {Promise.<GltfLoader>} A promise which resolves to the loader when the resource loading is completed. - * @private + * Loads the gltf object */ -GltfLoader.prototype.load = function () { - const gltfJsonLoader = ResourceCache.loadGltfJson({ - gltfResource: this._gltfResource, - baseResource: this._baseResource, - typedArray: this._typedArray, - gltfJson: this._gltfJson, - }); - - this._gltfJsonLoader = gltfJsonLoader; - this._state = GltfLoaderState.LOADING; - this._textureState = GltfLoaderState.LOADING; +async function loadGltfJson(loader) { + loader._state = GltfLoaderState.LOADING; + loader._textureState = GltfLoaderState.LOADING; + + try { + const gltfJsonLoader = ResourceCache.getGltfJsonLoader({ + gltfResource: loader._gltfResource, + baseResource: loader._baseResource, + typedArray: loader._typedArray, + gltfJson: loader._gltfJson, + }); + loader._gltfJsonLoader = gltfJsonLoader; + await gltfJsonLoader.load(); - const that = this; - let textureProcessPromise; - const processPromise = new Promise(function (resolve, reject) { - textureProcessPromise = new Promise(function ( - resolveTextures, - rejectTextures + if ( + loader.isDestroyed() || + loader.isUnloaded() || + gltfJsonLoader.isDestroyed() ) { - that._process = function (loader, frameState) { - if (!FeatureDetection.supportsWebP.initialized) { - FeatureDetection.supportsWebP.initialize(); - return; - } - - if (loader._state === GltfLoaderState.LOADED) { - loader._state = GltfLoaderState.PROCESSING; - - const supportedImageFormats = new SupportedImageFormats({ - webp: FeatureDetection.supportsWebP(), - basis: frameState.context.supportsBasis, - }); - - let gltf; - if (defined(loader._gltfJsonLoader)) { - gltf = loader._gltfJsonLoader.gltf; - } else { - gltf = loader._gltfJson; - } - - // Parse the glTF which populates the loaders arrays. The promise will - // resolve once all the loaders are ready (i.e. all external resources - // have been fetched and all GPU resources have been created). Loaders that - // create GPU resources need to be processed every frame until they become - // ready since the JobScheduler is not able to execute all jobs in a single - // frame. Also note that it's fine to call process before a loader is ready - // to process; nothing will happen. - parse( - loader, - gltf, - supportedImageFormats, - frameState, - reject, - rejectTextures - ); - - if (defined(loader._gltfJsonLoader) && loader._releaseGltfJson) { - // Check that the glTF JSON loader is still defined before trying to unload it. - // It may be undefined if the ready promise rejects immediately (which can happen in unit tests) - ResourceCache.unload(loader._gltfJsonLoader); - loader._gltfJsonLoader = undefined; - } - } + return; + } - if (loader._state === GltfLoaderState.PROCESSING) { - processLoaders(loader, frameState); - } + const gltf = gltfJsonLoader.gltf; + const version = gltf.asset.version; + if (version !== "1.0" && version !== "2.0") { + const url = loader._gltfResource.url; + throw new RuntimeError( + `Failed to load ${url}: \nUnsupported glTF version: ${version}` + ); + } - if (loader._state === GltfLoaderState.POST_PROCESSING) { - postProcessGeometry(loader, frameState.context); - loader._state = GltfLoaderState.PROCESSED; - } + const extensionsRequired = gltf.extensionsRequired; + if (defined(extensionsRequired)) { + ModelUtility.checkSupportedExtensions(extensionsRequired); - if (loader._state === GltfLoaderState.PROCESSED) { - // The buffer views can be unloaded once the data is copied. - unloadBufferViews(loader); + // Check for the KHR_mesh_quantization extension here, it will be used later + // in loadAttribute(). + loader._hasKhrMeshQuantization = extensionsRequired.includes( + "KHR_mesh_quantization" + ); + } - // Similarly, if the glTF was loaded from a typed array, release the memory - loader._typedArray = undefined; + loader._state = GltfLoaderState.LOADED; + loader._textureState = GltfLoaderState.LOADED; - loader._state = GltfLoaderState.READY; - resolve(loader); - } - }; + return loader; + } catch (error) { + if (loader.isDestroyed()) { + return; + } - that._processTextures = function (loader, frameState) { - if (loader._textureState === GltfLoaderState.LOADED) { - loader._textureState = GltfLoaderState.PROCESSING; - } + loader._state = GltfLoaderState.FAILED; + loader._textureState = GltfLoaderState.FAILED; + handleError(loader, error); + } +} - if (loader._textureState === GltfLoaderState.PROCESSING) { - let i; - const textureLoaders = loader._textureLoaders; - const textureLoadersLength = textureLoaders.length; - for (i = 0; i < textureLoadersLength; ++i) { - textureLoaders[i].process(frameState); - } - } +async function loadResources(loader, frameState) { + if (!FeatureDetection.supportsWebP.initialized) { + await FeatureDetection.supportsWebP.initialize(); + } - if (loader._textureState === GltfLoaderState.PROCESSED) { - loader._textureState = GltfLoaderState.READY; - resolveTextures(loader); - } - }; - }); + const supportedImageFormats = new SupportedImageFormats({ + webp: FeatureDetection.supportsWebP(), + basis: frameState.context.supportsBasis, }); - this._promise = gltfJsonLoader.promise - .then(function () { - if (that.isDestroyed()) { - return; - } - that._state = GltfLoaderState.LOADED; - that._textureState = GltfLoaderState.LOADED; + // Parse the glTF which populates the loaders arrays. Loading promises will be created, and will + // resolve once the loaders are ready (i.e. all external resources + // have been fetched and all GPU resources have been created). Loaders that + // create GPU resources need to be processed every frame until they become + // ready since the JobScheduler is not able to execute all jobs in a single + // frame. Any promise failures are collected, and will be handled synchronously in process(). Also note that it's fine to call process before a loader is ready + // to process or after it has failed; nothing will happen. + const gltf = loader.gltfJson; + parse(loader, gltf, supportedImageFormats, frameState); - return processPromise; - }) - .catch(function (error) { - if (that.isDestroyed()) { - return; - } - that._state = GltfLoaderState.FAILED; - that._textureState = GltfLoaderState.FAILED; - return handleError(that, error); - }); + // All resource loaders have been created, so we can begin processing + loader._state = GltfLoaderState.PROCESSING; + loader._textureState = GltfLoaderState.PROCESSING; - this._texturesLoadedPromise = textureProcessPromise.catch(function (error) { - if (that.isDestroyed()) { - return; - } + if (defined(loader._gltfJsonLoader) && loader._releaseGltfJson) { + // Check that the glTF JSON loader is still defined before trying to unload it. + // It can be unloaded if the glTF loader is destroyed. + ResourceCache.unload(loader._gltfJsonLoader); + loader._gltfJsonLoader = undefined; + } +} - that._textureState = GltfLoaderState.FAILED; - return handleError(that, error); - }); +/** + * Loads the resource. + * @returns {Promise.<GltfLoader>} A promise which resolves to the loader when the resource loading is completed. + * @exception {RuntimeError} Unsupported glTF version + * @exception {RuntimeError} Unsupported glTF Extension + * @private + */ +GltfLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } + this._promise = loadGltfJson(this); return this._promise; }; function handleError(gltfLoader, error) { gltfLoader.unload(); const errorMessage = "Failed to load glTF"; - error = gltfLoader.getError(errorMessage, error); - return Promise.reject(error); + throw gltfLoader.getError(errorMessage, error); } function processLoaders(loader, frameState) { - const bufferViewLoaders = loader._bufferViewLoaders; - const bufferViewLoadersLength = bufferViewLoaders.length; - for (let i = 0; i < bufferViewLoadersLength; ++i) { - bufferViewLoaders[i].process(frameState); - } - + let i; + let ready = true; const geometryLoaders = loader._geometryLoaders; const geometryLoadersLength = geometryLoaders.length; - for (let i = 0; i < geometryLoadersLength; ++i) { - geometryLoaders[i].process(frameState); + for (i = 0; i < geometryLoadersLength; ++i) { + const geometryReady = geometryLoaders[i].process(frameState); + if (geometryReady && defined(loader._geometryCallbacks[i])) { + loader._geometryCallbacks[i](); + loader._geometryCallbacks[i] = undefined; + } + ready = ready && geometryReady; } - if (defined(loader._structuralMetadataLoader)) { - loader._structuralMetadataLoader.process(frameState); + const structuralMetadataLoader = loader._structuralMetadataLoader; + if (defined(structuralMetadataLoader)) { + const metadataReady = structuralMetadataLoader.process(frameState); + if (metadataReady) { + loader._components.structuralMetadata = + structuralMetadataLoader.structuralMetadata; + } + ready = ready && metadataReady; + } + + if (ready) { + // Geometry requires further processing + loader._state = GltfLoaderState.POST_PROCESSING; } } @@ -549,6 +527,73 @@ function gatherPostProcessBuffers(loader, primitiveLoadPlan) { } } +/** + * Process loaders other than textures + * @private + */ +GltfLoader.prototype._process = function (frameState) { + if (this._state === GltfLoaderState.READY) { + return true; + } + + if (this._state === GltfLoaderState.PROCESSING) { + processLoaders(this, frameState); + } + + if (this._state === GltfLoaderState.POST_PROCESSING) { + postProcessGeometry(this, frameState.context); + this._state = GltfLoaderState.PROCESSED; + } + + if (this._state === GltfLoaderState.PROCESSED) { + // The buffer views can be unloaded once the data is copied. + unloadBufferViewLoaders(this); + + // Similarly, if the glTF was loaded from a typed array, release the memory + this._typedArray = undefined; + + this._state = GltfLoaderState.READY; + return true; + } + + return false; +}; + +/** + * Process textures other than textures + * @private + */ +GltfLoader.prototype._processTextures = function (frameState) { + if (this._textureState === GltfLoaderState.READY) { + return true; + } + + if (this._textureState !== GltfLoaderState.PROCESSING) { + return false; + } + + let i; + let ready = true; + const textureLoaders = this._textureLoaders; + const textureLoadersLength = textureLoaders.length; + for (i = 0; i < textureLoadersLength; ++i) { + const textureReady = textureLoaders[i].process(frameState); + if (textureReady && defined(this._textureCallbacks[i])) { + this._textureCallbacks[i](); + this._textureCallbacks[i] = undefined; + } + + ready = ready && textureReady; + } + + if (!ready) { + return false; + } + + this._textureState = GltfLoaderState.READY; + return true; +}; + /** * Processes the resource until it becomes ready. * @@ -560,12 +605,62 @@ GltfLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - this._process(this, frameState); + if ( + this._state === GltfLoaderState.LOADED && + !defined(this._loadResourcesPromise) + ) { + this._loadResourcesPromise = loadResources(this, frameState).catch( + (error) => { + this._processError = error; + } + ); + } + + if (defined(this._processError)) { + this._state = GltfLoaderState.FAILED; + const error = this._processError; + this._processError = undefined; + handleError(this, error); + } + + // Pop the next error of the list in case there are multiple + const textureError = this._textureErrors.pop(); + if (defined(textureError)) { + // There shouldn't be the need to completely unload in this case. Just throw the error. + const error = this.getError("Failed to load glTF texture", textureError); + error.name = "TextureError"; + throw error; + } + + let ready = false; + if (this._state === GltfLoaderState.FAILED) { + return ready; + } + + try { + ready = this._process(frameState); + } catch (error) { + this._state = GltfLoaderState.FAILED; + handleError(this, error); + } + // Since textures can be loaded independently and are handled through a separate promise, they are processed in their own function - this._processTextures(this, frameState); + let texturesReady = false; + try { + texturesReady = this._processTextures(frameState); + } catch (error) { + this._textureState = GltfLoaderState.FAILED; + handleError(this, error); + } + + if (this._incrementallyLoadTextures) { + return ready; + } + + return ready && texturesReady; }; -function loadVertexBuffer( +function getVertexBufferLoader( loader, gltf, accessorId, @@ -578,7 +673,7 @@ function loadVertexBuffer( const accessor = gltf.accessors[accessorId]; const bufferViewId = accessor.bufferView; - const vertexBufferLoader = ResourceCache.loadVertexBuffer({ + const vertexBufferLoader = ResourceCache.getVertexBufferLoader({ gltf: gltf, gltfResource: loader._gltfResource, baseResource: loader._baseResource, @@ -592,12 +687,10 @@ function loadVertexBuffer( loadTypedArray: loadTypedArray, }); - loader._geometryLoaders.push(vertexBufferLoader); - return vertexBufferLoader; } -function loadIndexBuffer( +function getIndexBufferLoader( loader, gltf, accessorId, @@ -606,7 +699,7 @@ function loadIndexBuffer( loadTypedArray, frameState ) { - const indexBufferLoader = ResourceCache.loadIndexBuffer({ + const indexBufferLoader = ResourceCache.getIndexBufferLoader({ gltf: gltf, accessorId: accessorId, gltfResource: loader._gltfResource, @@ -618,13 +711,11 @@ function loadIndexBuffer( loadTypedArray: loadTypedArray, }); - loader._geometryLoaders.push(indexBufferLoader); - return indexBufferLoader; } -function loadBufferView(loader, gltf, bufferViewId) { - const bufferViewLoader = ResourceCache.loadBufferView({ +function getBufferViewLoader(loader, gltf, bufferViewId) { + const bufferViewLoader = ResourceCache.getBufferViewLoader({ gltf: gltf, bufferViewId: bufferViewId, gltfResource: loader._gltfResource, @@ -727,11 +818,13 @@ function loadAccessor(loader, gltf, accessorId, useQuaternion) { const bufferViewId = accessor.bufferView; if (defined(bufferViewId)) { - const bufferViewLoader = loadBufferView(loader, gltf, bufferViewId); - const promise = bufferViewLoader.promise.then(function (bufferViewLoader) { + const bufferViewLoader = getBufferViewLoader(loader, gltf, bufferViewId); + const promise = (async () => { + await bufferViewLoader.load(); if (loader.isDestroyed()) { return; } + const bufferViewTypedArray = bufferViewLoader.typedArray; const typedArray = getPackedTypedArray( gltf, @@ -741,7 +834,8 @@ function loadAccessor(loader, gltf, accessorId, useQuaternion) { useQuaternion = defaultValue(useQuaternion, false); loadAccessorValues(accessor, typedArray, values, useQuaternion); - }); + })(); + loader._loaderPromises.push(promise); return values; @@ -1062,7 +1156,7 @@ function loadAttribute( return attribute; } - const vertexBufferLoader = loadVertexBuffer( + const vertexBufferLoader = getVertexBufferLoader( loader, gltf, accessorId, @@ -1072,13 +1166,15 @@ function loadAttribute( loadTypedArray, frameState ); - const promise = vertexBufferLoader.promise.then(function ( - vertexBufferLoader - ) { - if (loader.isDestroyed()) { - return; - } + const index = loader._geometryLoaders.length; + loader._geometryLoaders.push(vertexBufferLoader); + const promise = vertexBufferLoader.load(); + loader._loaderPromises.push(promise); + // This can only execute once vertexBufferLoader.process() has run and returns true + // Save this finish callback by the loader index so it can be called + // in process(). + loader._geometryCallbacks[index] = () => { if ( defined(draco) && defined(draco.attributes) && @@ -1100,9 +1196,7 @@ function loadAttribute( loadTypedArray ); } - }); - - loader._loaderPromises.push(promise); + }; return attribute; } @@ -1276,7 +1370,7 @@ function loadIndices( const loadBuffer = needsPostProcessing ? false : outputBuffer; const loadTypedArray = needsPostProcessing ? true : outputTypedArray; - const indexBufferLoader = loadIndexBuffer( + const indexBufferLoader = getIndexBufferLoader( loader, gltf, accessorId, @@ -1286,18 +1380,18 @@ function loadIndices( frameState ); - const promise = indexBufferLoader.promise.then(function (indexBufferLoader) { - if (loader.isDestroyed()) { - return; - } - + const index = loader._geometryLoaders.length; + loader._geometryLoaders.push(indexBufferLoader); + const promise = indexBufferLoader.load(); + loader._loaderPromises.push(promise); + // This can only execute once indexBufferLoader.process() has run and returns true + // Save this finish callback by the loader index so it can be called + // in process(). + loader._geometryCallbacks[index] = () => { indices.indexDatatype = indexBufferLoader.indexDatatype; - indices.buffer = indexBufferLoader.buffer; indices.typedArray = indexBufferLoader.typedArray; - }); - - loader._loaderPromises.push(promise); + }; const indicesPlan = new PrimitiveLoadPlan.IndicesLoadPlan(indices); indicesPlan.loadBuffer = outputBuffer; @@ -1324,7 +1418,7 @@ function loadTexture( return undefined; } - const textureLoader = ResourceCache.loadTexture({ + const textureLoader = ResourceCache.getTextureLoader({ gltf: gltf, textureInfo: textureInfo, gltfResource: loader._gltfResource, @@ -1334,23 +1428,37 @@ function loadTexture( asynchronous: loader._asynchronous, }); - loader._textureLoaders.push(textureLoader); - const textureReader = GltfLoaderUtil.createModelTextureReader({ textureInfo: textureInfo, }); - const promise = textureLoader.promise.then(function (textureLoader) { - if (loader.isUnloaded() || loader.isDestroyed()) { + const index = loader._textureLoaders.length; + loader._textureLoaders.push(textureLoader); + const promise = textureLoader.load().catch((error) => { + if (loader.isDestroyed()) { return; } + + if (!loader._incrementallyLoadTextures) { + // If incrementallyLoadTextures is false, throw the error to ensure the loader state + // immediately is set to have failed + throw error; + } + + // Otherwise, save the error so it can be thrown next + loader._textureState = GltfLoaderState.FAILED; + loader._textureErrors.push(error); + }); + loader._texturesPromises.push(promise); + // This can only execute once textureLoader.process() has run and returns true + // Save this finish callback by the loader index so it can be called + // in process(). + loader._textureCallbacks[index] = () => { textureReader.texture = textureLoader.texture; if (defined(samplerOverride)) { textureReader.texture.sampler = samplerOverride; } - }); - - loader._texturesPromises.push(promise); + }; return textureReader; } @@ -2246,7 +2354,7 @@ function loadSkins(loader, gltf, nodes) { return skins; } -function loadStructuralMetadata( +async function loadStructuralMetadata( loader, gltf, extension, @@ -2264,11 +2372,8 @@ function loadStructuralMetadata( frameState: frameState, asynchronous: loader._asynchronous, }); - structuralMetadataLoader.load(); - loader._structuralMetadataLoader = structuralMetadataLoader; - - return structuralMetadataLoader; + return structuralMetadataLoader.load(); } function loadAnimationSampler(loader, gltf, gltfSampler) { @@ -2442,32 +2547,7 @@ function loadScene(gltf, nodes) { const scratchCenter = new Cartesian3(); -function parse( - loader, - gltf, - supportedImageFormats, - frameState, - rejectPromise, - rejectTexturesPromise -) { - const version = gltf.asset.version; - if (version !== "1.0" && version !== "2.0") { - const url = loader._gltfResource.url; - throw new RuntimeError( - `Failed to load ${url}: \nUnsupported glTF version: ${version}` - ); - } - const extensionsRequired = gltf.extensionsRequired; - if (defined(extensionsRequired)) { - ModelUtility.checkSupportedExtensions(extensionsRequired); - - // Check for the KHR_mesh_quantization extension here, it will be used later - // in loadAttribute(). - loader._hasKhrMeshQuantization = extensionsRequired.includes( - "KHR_mesh_quantization" - ); - } - +function parse(loader, gltf, supportedImageFormats, frameState) { const extensions = defaultValue(gltf.extensions, defaultValue.EMPTY_OBJECT); const structuralMetadataExtension = extensions.EXT_structural_metadata; const featureMetadataExtensionLegacy = extensions.EXT_feature_metadata; @@ -2535,7 +2615,7 @@ function parse( defined(structuralMetadataExtension) || defined(featureMetadataExtensionLegacy) ) { - const structuralMetadataLoader = loadStructuralMetadata( + const promise = loadStructuralMetadata( loader, gltf, structuralMetadataExtension, @@ -2543,46 +2623,24 @@ function parse( supportedImageFormats, frameState ); - const promise = structuralMetadataLoader.promise.then(function ( - structuralMetadataLoader - ) { - if (loader.isDestroyed()) { - return; - } - components.structuralMetadata = - structuralMetadataLoader.structuralMetadata; - }); loader._loaderPromises.push(promise); } - // Gather promises and reject if any promises fail. + // Gather promises and handle any errors const readyPromises = []; readyPromises.push.apply(readyPromises, loader._loaderPromises); + // When incrementallyLoadTextures is true, the errors are caught and thrown individually + // since it doesn't affect the overall loader state if (!loader._incrementallyLoadTextures) { readyPromises.push.apply(readyPromises, loader._texturesPromises); } - Promise.all(readyPromises) - .then(function () { - if (loader.isDestroyed()) { - return; - } - loader._state = GltfLoaderState.POST_PROCESSING; - }) - .catch(rejectPromise); - - // Separate promise will resolve once textures are loaded. - Promise.all(loader._texturesPromises) - .then(function () { - if (loader.isDestroyed()) { - return; - } - - // post processing only applies for geometry - loader._textureState = GltfLoaderState.PROCESSED; - }) - .catch(rejectTexturesPromise); + Promise.all(readyPromises).catch((error) => { + // This error will be thrown synchronously during the next call + // to process() + loader._processError = error; + }); } function unloadTextures(loader) { @@ -2594,7 +2652,7 @@ function unloadTextures(loader) { loader._textureLoaders.length = 0; } -function unloadBufferViews(loader) { +function unloadBufferViewLoaders(loader) { const bufferViewLoaders = loader._bufferViewLoaders; const bufferViewLoadersLength = bufferViewLoaders.length; for (let i = 0; i < bufferViewLoadersLength; ++i) { @@ -2644,13 +2702,13 @@ GltfLoader.prototype.isUnloaded = function () { * @private */ GltfLoader.prototype.unload = function () { - if (defined(this._gltfJsonLoader)) { + if (defined(this._gltfJsonLoader) && !this._gltfJsonLoader.isDestroyed()) { ResourceCache.unload(this._gltfJsonLoader); } this._gltfJsonLoader = undefined; unloadTextures(this); - unloadBufferViews(this); + unloadBufferViewLoaders(this); unloadGeometry(this); unloadGeneratedAttributes(this); unloadStructuralMetadata(this); diff --git a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js index 032bcdf3f77..c320f05b31d 100644 --- a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js +++ b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js @@ -68,7 +68,9 @@ function GltfStructuralMetadataLoader(options) { this._cacheKey = cacheKey; this._asynchronous = asynchronous; this._bufferViewLoaders = []; + this._bufferViewIds = []; this._textureLoaders = []; + this._textureIds = []; this._schemaLoader = undefined; this._structuralMetadata = undefined; this._state = ResourceLoaderState.UNLOADED; @@ -83,20 +85,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfStructuralMetadataLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfStructuralMetadataLoader.prototype - * - * @type {Promise.<GltfStructuralMetadataLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -133,55 +121,39 @@ Object.defineProperties(GltfStructuralMetadataLoader.prototype, { * @private */ GltfStructuralMetadataLoader.prototype.load = function () { - const bufferViewsPromise = loadBufferViews(this); - const texturesPromise = loadTextures(this); - const schemaPromise = loadSchema(this); + if (defined(this._promise)) { + return this._promise; + } - this._gltf = undefined; // No longer need to hold onto the glTF this._state = ResourceLoaderState.LOADING; + this._promise = (async () => { + try { + const bufferViewsPromise = loadBufferViews(this); + const texturesPromise = loadTextures(this); + const schemaPromise = loadSchema(this); - const that = this; + await Promise.all([bufferViewsPromise, texturesPromise, schemaPromise]); - this._promise = Promise.all([ - bufferViewsPromise, - texturesPromise, - schemaPromise, - ]) - .then(function (results) { - if (that.isDestroyed()) { + if (this.isDestroyed()) { return; } - const bufferViews = results[0]; - const textures = results[1]; - const schema = results[2]; - - if (defined(that._extension)) { - that._structuralMetadata = parseStructuralMetadata({ - extension: that._extension, - schema: schema, - bufferViews: bufferViews, - textures: textures, - }); - } else { - that._structuralMetadata = parseFeatureMetadataLegacy({ - extension: that._extensionLegacy, - schema: schema, - bufferViews: bufferViews, - textures: textures, - }); - } - that._state = ResourceLoaderState.READY; - return that; - }) - .catch(function (error) { - if (that.isDestroyed()) { + + this._gltf = undefined; // No longer need to hold onto the glTF + + this._state = ResourceLoaderState.LOADED; + return this; + } catch (error) { + if (this.isDestroyed()) { return; } - that.unload(); - that._state = ResourceLoaderState.FAILED; + + this.unload(); + this._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load structural metadata"; - return Promise.reject(that.getError(errorMessage, error)); - }); + throw this.getError(errorMessage, error); + } + })(); + return this._promise; }; function gatherBufferViewIdsFromProperties(properties, bufferViewIdSet) { @@ -261,7 +233,7 @@ function gatherUsedBufferViewIdsLegacy(extensionLegacy) { return bufferViewIdSet; } -function loadBufferViews(structuralMetadataLoader) { +async function loadBufferViews(structuralMetadataLoader) { let bufferViewIds; if (defined(structuralMetadataLoader._extension)) { bufferViewIds = gatherUsedBufferViewIds( @@ -275,40 +247,23 @@ function loadBufferViews(structuralMetadataLoader) { // Load the buffer views const bufferViewPromises = []; - const bufferViewLoaders = {}; for (const bufferViewId in bufferViewIds) { if (bufferViewIds.hasOwnProperty(bufferViewId)) { - const bufferViewLoader = ResourceCache.loadBufferView({ + const bufferViewLoader = ResourceCache.getBufferViewLoader({ gltf: structuralMetadataLoader._gltf, bufferViewId: parseInt(bufferViewId), gltfResource: structuralMetadataLoader._gltfResource, baseResource: structuralMetadataLoader._baseResource, }); - bufferViewPromises.push(bufferViewLoader.promise); + structuralMetadataLoader._bufferViewLoaders.push(bufferViewLoader); - bufferViewLoaders[bufferViewId] = bufferViewLoader; - } - } + structuralMetadataLoader._bufferViewIds.push(bufferViewId); - // Return a promise to a map of buffer view IDs to typed arrays - return Promise.all(bufferViewPromises).then(function () { - const bufferViews = {}; - for (const bufferViewId in bufferViewLoaders) { - if (bufferViewLoaders.hasOwnProperty(bufferViewId)) { - const bufferViewLoader = bufferViewLoaders[bufferViewId]; - // Copy the typed array and let the underlying ArrayBuffer be freed - const bufferViewTypedArray = new Uint8Array( - bufferViewLoader.typedArray - ); - bufferViews[bufferViewId] = bufferViewTypedArray; - } + bufferViewPromises.push(bufferViewLoader.load()); } + } - // Buffer views can be unloaded after the data has been copied - unloadBufferViews(structuralMetadataLoader); - - return bufferViews; - }); + return Promise.all(bufferViewPromises); } function gatherUsedTextureIds(structuralMetadataExtension) { @@ -385,10 +340,9 @@ function loadTextures(structuralMetadataLoader) { // Load the textures const texturePromises = []; - const textureLoaders = {}; for (const textureId in textureIds) { if (textureIds.hasOwnProperty(textureId)) { - const textureLoader = ResourceCache.loadTexture({ + const textureLoader = ResourceCache.getTextureLoader({ gltf: gltf, textureInfo: textureIds[textureId], gltfResource: gltfResource, @@ -397,26 +351,16 @@ function loadTextures(structuralMetadataLoader) { frameState: frameState, asynchronous: asynchronous, }); - texturePromises.push(textureLoader.promise); structuralMetadataLoader._textureLoaders.push(textureLoader); - textureLoaders[textureId] = textureLoader; + structuralMetadataLoader._textureIds.push(textureId); + texturePromises.push(textureLoader.load()); } } - // Return a promise to a map of texture IDs to Texture objects - return Promise.all(texturePromises).then(function () { - const textures = {}; - for (const textureId in textureLoaders) { - if (textureLoaders.hasOwnProperty(textureId)) { - const textureLoader = textureLoaders[textureId]; - textures[textureId] = textureLoader.texture; - } - } - return textures; - }); + return Promise.all(texturePromises); } -function loadSchema(structuralMetadataLoader) { +async function loadSchema(structuralMetadataLoader) { const extension = defaultValue( structuralMetadataLoader._extension, structuralMetadataLoader._extensionLegacy @@ -427,20 +371,20 @@ function loadSchema(structuralMetadataLoader) { const resource = structuralMetadataLoader._baseResource.getDerivedResource({ url: extension.schemaUri, }); - schemaLoader = ResourceCache.loadSchema({ + schemaLoader = ResourceCache.getSchemaLoader({ resource: resource, }); } else { - schemaLoader = ResourceCache.loadSchema({ + schemaLoader = ResourceCache.getSchemaLoader({ schema: extension.schema, }); } structuralMetadataLoader._schemaLoader = schemaLoader; - - return schemaLoader.promise.then(function (schemaLoader) { + await schemaLoader.load(); + if (!schemaLoader.isDestroyed()) { return schemaLoader.schema; - }); + } } /** @@ -454,17 +398,68 @@ GltfStructuralMetadataLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - if (this._state !== ResourceLoaderState.LOADING) { - return; + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if (this._state !== ResourceLoaderState.LOADED) { + return false; } const textureLoaders = this._textureLoaders; const textureLoadersLength = textureLoaders.length; - + let ready = true; for (let i = 0; i < textureLoadersLength; ++i) { const textureLoader = textureLoaders[i]; - textureLoader.process(frameState); + const textureReady = textureLoader.process(frameState); + ready = ready && textureReady; + } + + if (!ready) { + return false; + } + + const schema = this._schemaLoader.schema; + const bufferViews = {}; + for (let i = 0; i < this._bufferViewIds.length; ++i) { + const bufferViewId = this._bufferViewIds[i]; + const bufferViewLoader = this._bufferViewLoaders[i]; + if (!bufferViewLoader.isDestroyed()) { + // Copy the typed array and let the underlying ArrayBuffer be freed + const bufferViewTypedArray = new Uint8Array(bufferViewLoader.typedArray); + bufferViews[bufferViewId] = bufferViewTypedArray; + } } + + const textures = {}; + for (let i = 0; i < this._textureIds.length; ++i) { + const textureId = this._textureIds[i]; + const textureLoader = textureLoaders[i]; + if (!textureLoader.isDestroyed()) { + textures[textureId] = textureLoader.texture; + } + } + if (defined(this._extension)) { + this._structuralMetadata = parseStructuralMetadata({ + extension: this._extension, + schema: schema, + bufferViews: bufferViews, + textures: textures, + }); + } else { + this._structuralMetadata = parseFeatureMetadataLegacy({ + extension: this._extensionLegacy, + schema: schema, + bufferViews: bufferViews, + textures: textures, + }); + } + + // Buffer views can be unloaded after the data has been copied + unloadBufferViews(this); + + this._state = ResourceLoaderState.READY; + return true; }; function unloadBufferViews(structuralMetadataLoader) { @@ -474,6 +469,7 @@ function unloadBufferViews(structuralMetadataLoader) { ResourceCache.unload(bufferViewLoaders[i]); } structuralMetadataLoader._bufferViewLoaders.length = 0; + structuralMetadataLoader._bufferViewIds.length = 0; } function unloadTextures(structuralMetadataLoader) { @@ -483,6 +479,7 @@ function unloadTextures(structuralMetadataLoader) { ResourceCache.unload(textureLoaders[i]); } structuralMetadataLoader._textureLoaders.length = 0; + structuralMetadataLoader._textureIds.length = 0; } /** diff --git a/packages/engine/Source/Scene/GltfTextureLoader.js b/packages/engine/Source/Scene/GltfTextureLoader.js index 4c6139914c9..a71a36448d8 100644 --- a/packages/engine/Source/Scene/GltfTextureLoader.js +++ b/packages/engine/Source/Scene/GltfTextureLoader.js @@ -78,7 +78,6 @@ function GltfTextureLoader(options) { this._texture = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; - this._process = function (loader, frameState) {}; } if (defined(Object.create)) { @@ -87,20 +86,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfTextureLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfTextureLoader.prototype - * - * @type {Promise.<GltfTextureLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -138,86 +123,45 @@ const scratchTextureJob = new CreateTextureJob(); * @returns {Promise.<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfTextureLoader.prototype.load = function () { - const resourceCache = this._resourceCache; - const imageLoader = resourceCache.loadImage({ - gltf: this._gltf, - imageId: this._imageId, - gltfResource: this._gltfResource, - baseResource: this._baseResource, - }); +GltfTextureLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } - this._imageLoader = imageLoader; this._state = ResourceLoaderState.LOADING; - const that = this; - const processPromise = new Promise(function (resolve) { - that._process = function (loader, frameState) { - if (defined(loader._texture)) { - // Already created texture - return; - } - - if (!defined(loader._image)) { - // Not ready to create texture + const resourceCache = this._resourceCache; + this._promise = (async () => { + try { + const imageLoader = resourceCache.getImageLoader({ + gltf: this._gltf, + imageId: this._imageId, + gltfResource: this._gltfResource, + baseResource: this._baseResource, + }); + this._imageLoader = imageLoader; + await imageLoader.load(); + + if (this.isDestroyed()) { return; } - let texture; - - if (loader._asynchronous) { - const textureJob = scratchTextureJob; - textureJob.set( - loader._gltf, - loader._textureInfo, - loader._image, - loader._mipLevels, - frameState.context - ); - const jobScheduler = frameState.jobScheduler; - if (!jobScheduler.execute(textureJob, JobType.TEXTURE)) { - // Job scheduler is full. Try again next frame. - return; - } - texture = textureJob.texture; - } else { - texture = createTexture( - loader._gltf, - loader._textureInfo, - loader._image, - loader._mipLevels, - frameState.context - ); - } - - // Unload everything except the texture - loader.unload(); - - loader._texture = texture; - loader._state = ResourceLoaderState.READY; - resolve(loader); - }; - }); - - this._promise = imageLoader.promise - .then(function () { - if (that.isDestroyed()) { - return; - } // Now wait for process() to run to finish loading - that._image = imageLoader.image; - that._mipLevels = imageLoader.mipLevels; - that._state = ResourceLoaderState.PROCESSING; - return processPromise; - }) - .catch(function (error) { - if (that.isDestroyed()) { + this._image = imageLoader.image; + this._mipLevels = imageLoader.mipLevels; + this._state = ResourceLoaderState.LOADED; + + return this; + } catch (error) { + if (this.isDestroyed()) { return; } - that.unload(); - that._state = ResourceLoaderState.FAILED; + + this.unload(); + this._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load texture"; - return Promise.reject(that.getError(errorMessage, error)); - }); + throw this.getError(errorMessage, error); + } + })(); return this._promise; }; @@ -350,6 +294,7 @@ function createTexture(gltf, textureInfo, image, mipLevels, context) { * Processes the resource until it becomes ready. * * @param {FrameState} frameState The frame state. + * @returns {boolean} true once all resourced are ready. * @private */ GltfTextureLoader.prototype.process = function (frameState) { @@ -357,7 +302,62 @@ GltfTextureLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - return this._process(this, frameState); + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if ( + this._state !== ResourceLoaderState.LOADED && + this._state !== ResourceLoaderState.PROCESSING + ) { + return false; + } + + if (defined(this._texture)) { + // Already created texture + return false; + } + + if (!defined(this._image)) { + // Not ready to create texture + return false; + } + + this._state = ResourceLoaderState.PROCESSING; + + let texture; + if (this._asynchronous) { + const textureJob = scratchTextureJob; + textureJob.set( + this._gltf, + this._textureInfo, + this._image, + this._mipLevels, + frameState.context + ); + const jobScheduler = frameState.jobScheduler; + if (!jobScheduler.execute(textureJob, JobType.TEXTURE)) { + // Job scheduler is full. Try again next frame. + return; + } + texture = textureJob.texture; + } else { + texture = createTexture( + this._gltf, + this._textureInfo, + this._image, + this._mipLevels, + frameState.context + ); + } + + // Unload everything except the texture + this.unload(); + + this._texture = texture; + this._state = ResourceLoaderState.READY; + this._resourceCache.statistics.addTextureLoader(this); + return true; }; /** diff --git a/packages/engine/Source/Scene/GltfVertexBufferLoader.js b/packages/engine/Source/Scene/GltfVertexBufferLoader.js index 425d3bad123..a2769521a39 100644 --- a/packages/engine/Source/Scene/GltfVertexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfVertexBufferLoader.js @@ -115,7 +115,6 @@ function GltfVertexBufferLoader(options) { this._buffer = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = undefined; - this._process = function (loader, frameState) {}; } if (defined(Object.create)) { @@ -124,20 +123,6 @@ if (defined(Object.create)) { } Object.defineProperties(GltfVertexBufferLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof GltfVertexBufferLoader.prototype - * - * @type {Promise.<GltfVertexBufferLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -209,77 +194,17 @@ function hasDracoCompression(draco, semantic) { * @returns {Promise.<GltfVertexBufferLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -GltfVertexBufferLoader.prototype.load = function () { - let promise; +GltfVertexBufferLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } if (hasDracoCompression(this._draco, this._attributeSemantic)) { - promise = loadFromDraco(this); - } else { - promise = loadFromBufferView(this); + this._promise = loadFromDraco(this); + return this._promise; } - const that = this; - const scratchVertexBufferJob = new CreateVertexBufferJob(); - const processPromise = new Promise(function (resolve) { - that._process = function (loader, frameState) { - if (loader._state === ResourceLoaderState.READY) { - return; - } - - const typedArray = loader._typedArray; - - if (defined(loader._dracoLoader)) { - loader._dracoLoader.process(frameState); - } - - if (defined(loader._bufferViewLoader)) { - loader._bufferViewLoader.process(frameState); - } - - if (!defined(typedArray)) { - // Buffer view hasn't been loaded yet - return; - } - - let buffer; - if (loader._loadBuffer && loader._asynchronous) { - const vertexBufferJob = scratchVertexBufferJob; - vertexBufferJob.set(typedArray, frameState.context); - const jobScheduler = frameState.jobScheduler; - if (!jobScheduler.execute(vertexBufferJob, JobType.BUFFER)) { - // Job scheduler is full. Try again next frame. - return; - } - buffer = vertexBufferJob.buffer; - } else if (loader._loadBuffer) { - buffer = createVertexBuffer(typedArray, frameState.context); - } - - // Unload everything except the vertex buffer - loader.unload(); - - loader._buffer = buffer; - loader._typedArray = loader._loadTypedArray ? typedArray : undefined; - loader._state = ResourceLoaderState.READY; - resolve(loader); - }; - }); - - this._promise = promise - .then(function () { - if (that.isDestroyed()) { - return; - } - - return processPromise; - }) - .catch(function (error) { - if (that.isDestroyed()) { - return; - } - - return handleError(that, error); - }); + this._promise = loadFromBufferView(this); return this._promise; }; @@ -335,79 +260,98 @@ function getQuantizationInformation( return quantization; } -function loadFromDraco(vertexBufferLoader) { - const resourceCache = vertexBufferLoader._resourceCache; - const dracoLoader = resourceCache.loadDraco({ - gltf: vertexBufferLoader._gltf, - draco: vertexBufferLoader._draco, - gltfResource: vertexBufferLoader._gltfResource, - baseResource: vertexBufferLoader._baseResource, - }); - - vertexBufferLoader._dracoLoader = dracoLoader; +async function loadFromDraco(vertexBufferLoader) { vertexBufferLoader._state = ResourceLoaderState.LOADING; + const resourceCache = vertexBufferLoader._resourceCache; + try { + const dracoLoader = resourceCache.getDracoLoader({ + gltf: vertexBufferLoader._gltf, + draco: vertexBufferLoader._draco, + gltfResource: vertexBufferLoader._gltfResource, + baseResource: vertexBufferLoader._baseResource, + }); + vertexBufferLoader._dracoLoader = dracoLoader; + await dracoLoader.load(); - return dracoLoader.promise.then(function () { if (vertexBufferLoader.isDestroyed()) { return; } - // Get the typed array and quantization information - const decodedVertexAttributes = dracoLoader.decodedData.vertexAttributes; - const attributeSemantic = vertexBufferLoader._attributeSemantic; - const dracoAttribute = decodedVertexAttributes[attributeSemantic]; - const accessorId = vertexBufferLoader._accessorId; - const accessor = vertexBufferLoader._gltf.accessors[accessorId]; - const type = accessor.type; - const typedArray = dracoAttribute.array; - const dracoQuantization = dracoAttribute.data.quantization; - if (defined(dracoQuantization)) { - vertexBufferLoader._quantization = getQuantizationInformation( - dracoQuantization, - dracoAttribute.data.componentDatatype, - dracoAttribute.data.componentsPerAttribute, - type - ); - } // Now wait for process() to run to finish loading - vertexBufferLoader._typedArray = new Uint8Array( - typedArray.buffer, - typedArray.byteOffset, - typedArray.byteLength - ); - vertexBufferLoader._state = ResourceLoaderState.PROCESSING; + vertexBufferLoader._state = ResourceLoaderState.LOADED; return vertexBufferLoader; - }); + } catch { + if (vertexBufferLoader.isDestroyed()) { + return; + } + + handleError(vertexBufferLoader); + } } -function loadFromBufferView(vertexBufferLoader) { - const resourceCache = vertexBufferLoader._resourceCache; - const bufferViewLoader = resourceCache.loadBufferView({ - gltf: vertexBufferLoader._gltf, - bufferViewId: vertexBufferLoader._bufferViewId, - gltfResource: vertexBufferLoader._gltfResource, - baseResource: vertexBufferLoader._baseResource, - }); +function processDraco(vertexBufferLoader) { + vertexBufferLoader._state = ResourceLoaderState.PROCESSING; + const dracoLoader = vertexBufferLoader._dracoLoader; + + // Get the typed array and quantization information + const decodedVertexAttributes = dracoLoader.decodedData.vertexAttributes; + const attributeSemantic = vertexBufferLoader._attributeSemantic; + const dracoAttribute = decodedVertexAttributes[attributeSemantic]; + const accessorId = vertexBufferLoader._accessorId; + const accessor = vertexBufferLoader._gltf.accessors[accessorId]; + const type = accessor.type; + const typedArray = dracoAttribute.array; + const dracoQuantization = dracoAttribute.data.quantization; + if (defined(dracoQuantization)) { + vertexBufferLoader._quantization = getQuantizationInformation( + dracoQuantization, + dracoAttribute.data.componentDatatype, + dracoAttribute.data.componentsPerAttribute, + type + ); + } + + vertexBufferLoader._typedArray = new Uint8Array( + typedArray.buffer, + typedArray.byteOffset, + typedArray.byteLength + ); +} + +async function loadFromBufferView(vertexBufferLoader) { vertexBufferLoader._state = ResourceLoaderState.LOADING; - vertexBufferLoader._bufferViewLoader = bufferViewLoader; + const resourceCache = vertexBufferLoader._resourceCache; + try { + const bufferViewLoader = resourceCache.getBufferViewLoader({ + gltf: vertexBufferLoader._gltf, + bufferViewId: vertexBufferLoader._bufferViewId, + gltfResource: vertexBufferLoader._gltfResource, + baseResource: vertexBufferLoader._baseResource, + }); + vertexBufferLoader._bufferViewLoader = bufferViewLoader; + await bufferViewLoader.load(); - return bufferViewLoader.promise.then(function () { if (vertexBufferLoader.isDestroyed()) { return; } - // Now wait for process() to run to finish loading + vertexBufferLoader._typedArray = bufferViewLoader.typedArray; vertexBufferLoader._state = ResourceLoaderState.PROCESSING; return vertexBufferLoader; - }); + } catch (error) { + if (vertexBufferLoader.isDestroyed()) { + return; + } + + handleError(vertexBufferLoader, error); + } } function handleError(vertexBufferLoader, error) { vertexBufferLoader.unload(); vertexBufferLoader._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load vertex buffer"; - error = vertexBufferLoader.getError(errorMessage, error); - return Promise.reject(error); + throw vertexBufferLoader.getError(errorMessage, error); } function CreateVertexBufferJob() { @@ -435,6 +379,8 @@ function createVertexBuffer(typedArray, context) { return buffer; } +const scratchVertexBufferJob = new CreateVertexBufferJob(); + /** * Processes the resource until it becomes ready. * @@ -446,7 +392,53 @@ GltfVertexBufferLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - return this._process(this, frameState); + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if ( + this._state !== ResourceLoaderState.LOADED && + this._state !== ResourceLoaderState.PROCESSING + ) { + return false; + } + + if (defined(this._dracoLoader)) { + try { + const ready = this._dracoLoader.process(frameState); + if (!ready) { + return false; + } + } catch (error) { + handleError(this, error); + } + + processDraco(this); + } + + let buffer; + const typedArray = this._typedArray; + if (this._loadBuffer && this._asynchronous) { + const vertexBufferJob = scratchVertexBufferJob; + vertexBufferJob.set(typedArray, frameState.context); + const jobScheduler = frameState.jobScheduler; + if (!jobScheduler.execute(vertexBufferJob, JobType.BUFFER)) { + // Job scheduler is full. Try again next frame. + return false; + } + buffer = vertexBufferJob.buffer; + } else if (this._loadBuffer) { + buffer = createVertexBuffer(typedArray, frameState.context); + } + + // Unload everything except the vertex buffer + this.unload(); + + this._buffer = buffer; + this._typedArray = this._loadTypedArray ? typedArray : undefined; + this._state = ResourceLoaderState.READY; + this._resourceCache.statistics.addGeometryLoader(this); + return true; }; /** diff --git a/packages/engine/Source/Scene/ImplicitSubtree.js b/packages/engine/Source/Scene/ImplicitSubtree.js index 9f0ec3cc8ba..3c7f585ba58 100644 --- a/packages/engine/Source/Scene/ImplicitSubtree.js +++ b/packages/engine/Source/Scene/ImplicitSubtree.js @@ -714,12 +714,12 @@ function requestExternalBuffer(subtree, bufferHeader) { url: bufferHeader.uri, }); - const bufferLoader = ResourceCache.loadExternalBuffer({ + const bufferLoader = ResourceCache.getExternalBufferLoader({ resource: bufferResource, }); subtree._bufferLoader = bufferLoader; - return bufferLoader.promise.then(function (bufferLoader) { + return bufferLoader.load().then(function (bufferLoader) { return bufferLoader.typedArray; }); } diff --git a/packages/engine/Source/Scene/MetadataSchemaLoader.js b/packages/engine/Source/Scene/MetadataSchemaLoader.js index be21b606d47..0aab97eb23a 100644 --- a/packages/engine/Source/Scene/MetadataSchemaLoader.js +++ b/packages/engine/Source/Scene/MetadataSchemaLoader.js @@ -52,20 +52,6 @@ if (defined(Object.create)) { } Object.defineProperties(MetadataSchemaLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof MetadataSchemaLoader.prototype - * - * @type {Promise.<MetadataSchemaLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -101,37 +87,41 @@ Object.defineProperties(MetadataSchemaLoader.prototype, { * @returns {Promise.<MetadataSchemaLoader>} A promise which resolves to the loader when the resource loading is completed. * @private */ -MetadataSchemaLoader.prototype.load = function () { +MetadataSchemaLoader.prototype.load = async function () { + if (defined(this._promise)) { + return this._promise; + } + if (defined(this._schema)) { this._promise = Promise.resolve(this); - } else { - this._promise = loadExternalSchema(this); + return this._promise; } + this._promise = loadExternalSchema(this); return this._promise; }; -function loadExternalSchema(schemaLoader) { +async function loadExternalSchema(schemaLoader) { const resource = schemaLoader._resource; schemaLoader._state = ResourceLoaderState.LOADING; - return resource - .fetchJson() - .then(function (json) { - if (schemaLoader.isDestroyed()) { - return; - } - schemaLoader._schema = MetadataSchema.fromJson(json); - schemaLoader._state = ResourceLoaderState.READY; - return schemaLoader; - }) - .catch(function (error) { - if (schemaLoader.isDestroyed()) { - return; - } - schemaLoader._state = ResourceLoaderState.FAILED; - const errorMessage = `Failed to load schema: ${resource.url}`; - return Promise.reject(schemaLoader.getError(errorMessage, error)); - }); + try { + const json = await resource.fetchJson(); + if (schemaLoader.isDestroyed()) { + return; + } + + schemaLoader._schema = MetadataSchema.fromJson(json); + schemaLoader._state = ResourceLoaderState.READY; + return schemaLoader; + } catch (error) { + if (schemaLoader.isDestroyed()) { + return; + } + + schemaLoader._state = ResourceLoaderState.FAILED; + const errorMessage = `Failed to load schema: ${resource.url}`; + throw schemaLoader.getError(errorMessage, error); + } } /** diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index cc1888dc4e0..5500c8faa33 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -6,9 +6,11 @@ import Credit from "../../Core/Credit.js"; import Color from "../../Core/Color.js"; import defined from "../../Core/defined.js"; import defaultValue from "../../Core/defaultValue.js"; +import deprecationWarning from "../../Core/deprecationWarning.js"; import DeveloperError from "../../Core/DeveloperError.js"; import destroyObject from "../../Core/destroyObject.js"; import DistanceDisplayCondition from "../../Core/DistanceDisplayCondition.js"; +import Event from "../../Core/Event.js"; import Matrix3 from "../../Core/Matrix3.js"; import Matrix4 from "../../Core/Matrix4.js"; import Resource from "../../Core/Resource.js"; @@ -39,7 +41,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; /** * <div class="notice"> - * To construct a Model, call {@link Model.fromGltf}. Do not call the constructor directly. + * To construct a Model, call {@link Model.fromGltfAsync}. Do not call the constructor directly. * </div> * A 3D model based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL. * <p> @@ -155,7 +157,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * @privateParam {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded. * - * @see Model.fromGltf + * @see Model.fromGltfAsync * * @demo {@link https://sandcastle.cesium.com/index.html?src=3D%20Models.html|Cesium Sandcastle Models Demo} */ @@ -455,9 +457,65 @@ function Model(options) { this._skipLevelOfDetail = false; this._ignoreCommands = defaultValue(options.ignoreCommands, false); - this._completeLoad = function (model, frameState) {}; this._texturesLoadedPromise = undefined; - this._readyPromise = initialize(this); + + this._completeLoad = undefined; + this._rejectLoad = undefined; + this._completeTexturesLoad = undefined; + this._rejectTexturesLoad = undefined; + + // This is for backward compatibility. When readyPromise is removed, this block can be too + if (!defined(this._loader._promise)) { + this._readyPromise = new Promise((resolve, reject) => { + this._completeLoad = () => { + resolve(this); + return false; + }; + this._rejectLoad = (error) => { + reject(error); + return false; + }; + }); + + // Transcoded .pnts models do not have textures + if (this._loader instanceof PntsLoader) { + this._texturesLoadedPromise = Promise.resolve(this); + } else { + this._texturesLoadedPromise = new Promise((resolve, reject) => { + this._completeTexturesLoad = () => { + resolve(this); + return false; + }; + this._rejectTexturesLoad = (error) => { + reject(error); + return false; + }; + }); + } + + this._loader.load().catch((error) => { + // If the model is destroyed before the promise resolves, then + // the loader will have been destroyed as well. Return early. + if ( + this.isDestroyed() || + !defined(this._loader) || + this._loader.isDestroyed() + ) { + return; + } + + this._rejectLoad = this._rejectLoad( + ModelUtility.getError("model", this._resource, error) + ); + }); + } else { + this._readyPromise = Promise.resolve(this); + this._texturesLoadedPromise = Promise.resolve(this); + } + + this._errorEvent = new Event(); + this._readyEvent = new Event(); + this._texturesReadyEvent = new Event(); this._sceneGraph = undefined; this._nodesByName = {}; // Stores the nodes by their names in the glTF. @@ -470,6 +528,15 @@ function Model(options) { this.pickObject = options.pickObject; } +function handleError(model, error) { + if (model._errorEvent.numberOfListeners > 0) { + model._errorEvent.raiseEvent(error); + return; + } + + console.error(error); +} + function createModelFeatureTables(model, structuralMetadata) { const featureTables = model._featureTables; @@ -561,101 +628,10 @@ function isColorAlphaDirty(currentColor, previousColor) { ); } -function initialize(model) { - const loader = model._loader; - const resource = model._resource; - - loader.load(); - - const loaderPromise = loader.promise.then(function (loader) { - // If the model is destroyed before the promise resolves, then - // the loader will have been destroyed as well. Return early. - if (!defined(loader)) { - return; - } - - const components = loader.components; - if (!defined(components)) { - if (loader.isUnloaded()) { - return; - } - - throw new RuntimeError("Failed to load model."); - } - - const structuralMetadata = components.structuralMetadata; - - if ( - defined(structuralMetadata) && - structuralMetadata.propertyTableCount > 0 - ) { - createModelFeatureTables(model, structuralMetadata); - } - - const sceneGraph = new ModelSceneGraph({ - model: model, - modelComponents: components, - }); - - model._sceneGraph = sceneGraph; - model._gltfCredits = sceneGraph.components.asset.credits; - - const resourceCredits = model._resource.credits; - if (defined(resourceCredits)) { - const length = resourceCredits.length; - for (let i = 0; i < length; i++) { - model._resourceCredits.push(resourceCredits[i]); - } - } - - model._resourcesLoaded = true; - }); - - // Transcoded .pnts models do not have textures - const texturesLoadedPromise = defaultValue( - loader.texturesLoadedPromise, - Promise.resolve() - ); - model._texturesLoadedPromise = texturesLoadedPromise - .then(function () { - // If the model was destroyed while loading textures, return. - if (!defined(model) || model.isDestroyed()) { - return; - } - - model._texturesLoaded = true; - - // Re-run the pipeline so texture memory statistics are re-computed - if (loader._incrementallyLoadTextures) { - model.resetDrawCommands(); - } - }) - .catch(ModelUtility.getFailedLoadFunction(model, "model", resource)); - - const promise = new Promise(function (resolve, reject) { - model._completeLoad = function (model, frameState) { - // Set the model as ready after the first frame render since the user might set up events subscribed to - // the post render event, and the model may not be ready for those past the first frame. - frameState.afterRender.push(function () { - model._ready = true; - resolve(model); - return true; - }); - }; - }); - - return loaderPromise - .then(function () { - return promise; - }) - .catch(ModelUtility.getFailedLoadFunction(model, "model", resource)); -} - Object.defineProperties(Model.prototype, { /** * When <code>true</code>, this model is ready to render, i.e., the external binary, image, - * and shader files were downloaded and the WebGL resources were created. This is set to - * <code>true</code> right before {@link Model#readyPromise} is resolved. + * and shader files were downloaded and the WebGL resources were created. * * @memberof Model.prototype * @@ -670,6 +646,54 @@ Object.defineProperties(Model.prototype, { }, }, + /** + * Gets an event that is raised when the model encounters an asynchronous rendering error. By subscribing + * to the event, you will be notified of the error and can potentially recover from it. Event listeners + * are passed an instance of {@link ModelError}. + * @memberof Model.prototype + * @type {Event} + * @readonly + */ + errorEvent: { + get: function () { + return this._errorEvent; + }, + }, + + /** + * Gets an event that is raised when the model is loaded and ready for rendering, i.e. when the external resources + * have been downloaded and the WebGL resources are created. Event listeners + * are passed an instance of the {@link Model}. + * + * <p> + * If {@link Model.incrementallyLoadTextures} is true, this event will be raised before all textures are loaded and ready for rendering. Subscribe to {@link Model.texturesReadyEvent} to be notified when the textures are ready. + * </p> + * + * @memberof Model.prototype + * @type {Event} + * @readonly + */ + readyEvent: { + get: function () { + return this._readyEvent; + }, + }, + + /** + * Gets an event that, if {@link Model.incrementallyLoadTextures} is true, is raised when the model textures are loaded and ready for rendering, i.e. when the external resources + * have been downloaded and the WebGL resources are created. Event listeners + * are passed an instance of the {@link Model}. + * + * @memberof Model.prototype + * @type {Event} + * @readonly + */ + texturesReadyEvent: { + get: function () { + return this._texturesReadyEvent; + }, + }, + /** * Gets the promise that will be resolved when this model is ready to render, i.e. when the external resources * have been downloaded and the WebGL resources are created. @@ -681,9 +705,14 @@ Object.defineProperties(Model.prototype, { * * @type {Promise.<Model>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "Model.readyPromise", + "Model.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync and Model.readyEvent instead." + ); return this._readyPromise; }, }, @@ -697,11 +726,16 @@ Object.defineProperties(Model.prototype, { * * @type {Promise<void>} * @readonly + * @deprecated * * @private */ texturesLoadedPromise: { get: function () { + deprecationWarning( + "Model.texturesLoadedPromise", + "Model.texturesLoadedPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync and Model.texturesReadyEvent instead." + ); return this._texturesLoadedPromise; }, }, @@ -1155,7 +1189,7 @@ Object.defineProperties(Model.prototype, { //>>includeStart('debug', pragmas.debug); if (!this._ready) { throw new DeveloperError( - "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true." + "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true." ); } //>>includeEnd('debug'); @@ -1223,7 +1257,7 @@ Object.defineProperties(Model.prototype, { ) { oneTimeWarning( "model-debug-wireframe-ignored", - "enableDebugWireframe must be set to true in Model.fromGltf, otherwise debugWireframe will be ignored." + "enableDebugWireframe must be set to true in Model.fromGltfAsync, otherwise debugWireframe will be ignored." ); } }, @@ -1664,7 +1698,7 @@ Object.defineProperties(Model.prototype, { * @param {String} name The name of the node in the glTF. * @returns {ModelNode} The node, or <code>undefined</code> if no node with the <code>name</code> exists. * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true. * * @example * // Apply non-uniform scale to node "Hand" @@ -1675,7 +1709,7 @@ Model.prototype.getNode = function (name) { //>>includeStart('debug', pragmas.debug); if (!this._ready) { throw new DeveloperError( - "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true." + "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true." ); } Check.typeOf.string("name", name); @@ -1692,7 +1726,7 @@ Model.prototype.getNode = function (name) { * @param {String} articulationStageKey The name of the articulation, a space, and the name of the stage. * @param {Number} value The numeric value of this stage of the articulation. * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true. * * @see Model#applyArticulations * @@ -1705,7 +1739,7 @@ Model.prototype.setArticulationStage = function (articulationStageKey, value) { Check.typeOf.number("value", value); if (!this._ready) { throw new DeveloperError( - "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true." + "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true." ); } //>>includeEnd('debug'); @@ -1718,13 +1752,13 @@ Model.prototype.setArticulationStage = function (articulationStageKey, value) { * participates in any articulation. Note that this will overwrite any node * transformations on participating nodes. * - * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true. + * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true. */ Model.prototype.applyArticulations = function () { //>>includeStart('debug', pragmas.debug); if (!this._ready) { throw new DeveloperError( - "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true." + "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true." ); } //>>includeEnd('debug'); @@ -1764,10 +1798,40 @@ const scratchClippingPlanesMatrix = new Matrix4(); * @exception {RuntimeError} Failed to load external reference. */ Model.prototype.update = function (frameState) { - // Keep processing the model every frame until the main resources - // (buffer views) and textures (which may be loaded asynchronously) - // are processed. - processLoader(this, frameState); + let finishedProcessing = false; + try { + // Keep processing the model every frame until the main resources + // (buffer views) and textures (which may be loaded asynchronously) + // are processed. + finishedProcessing = processLoader(this, frameState); + } catch (error) { + if (!this._loader.incrementallyLoadTextures) { + const runtimeError = ModelUtility.getError( + "model", + this._resource, + error + ); + handleError(this, runtimeError); + + this._rejectLoad = this._rejectLoad && this._rejectLoad(runtimeError); + this._rejectTexturesLoad = + this._rejectTexturesLoad && this._rejectTexturesLoad(runtimeError); + } else if (error.name === "TextureError") { + handleError(this, error); + + this._rejectTexturesLoad = + this._rejectTexturesLoad && this._rejectTexturesLoad(error); + } else { + const runtimeError = ModelUtility.getError( + "model", + this._resource, + error + ); + handleError(this, runtimeError); + + this._rejectLoad = this._rejectLoad && this._rejectLoad(runtimeError); + } + } // A custom shader may have to load texture uniforms. updateCustomShader(this, frameState); @@ -1776,6 +1840,41 @@ Model.prototype.update = function (frameState) { // for specular maps. updateImageBasedLighting(this, frameState); + if (!this._resourcesLoaded && finishedProcessing) { + this._resourcesLoaded = true; + + const components = this._loader.components; + if (!defined(components)) { + if (this._loader.isUnloaded()) { + return; + } + + const error = ModelUtility.getError( + "model", + this._resource, + new RuntimeError("Failed to load model.") + ); + handleError(error); + this._rejectLoad = this._rejectLoad && this._rejectLoad(error); + } + + const structuralMetadata = components.structuralMetadata; + if ( + defined(structuralMetadata) && + structuralMetadata.propertyTableCount > 0 + ) { + createModelFeatureTables(this, structuralMetadata); + } + + const sceneGraph = new ModelSceneGraph({ + model: this, + modelComponents: components, + }); + + this._sceneGraph = sceneGraph; + this._gltfCredits = sceneGraph.components.asset.credits; + } + // Short-circuit if the model resources aren't ready or the scene // is currently morphing. if (!this._resourcesLoaded || frameState.mode === SceneMode.MORPHING) { @@ -1806,14 +1905,37 @@ Model.prototype.update = function (frameState) { // This check occurs after the bounding sphere has been updated so that // zooming to the bounding sphere can account for any modifications // from the clamp-to-ground setting. - const model = this; - if (!model._ready) { - model._completeLoad(model, frameState); + if (!this._ready) { + // Set the model as ready after the first frame render since the user might set up events subscribed to + // the post render event, and the model may not be ready for those past the first frame. + frameState.afterRender.push(() => { + this._ready = true; + this._readyEvent.raiseEvent(this); + // This is here for backwards compatibility and can be removed when readyPromise is removed. + this._completeLoad = this._completeLoad && this._completeLoad(); + if (!this._loader.incrementallyLoadTextures) { + this._texturesLoaded = true; + this._texturesReadyEvent.raiseEvent(this); + this._completeTexturesLoad = + this._completeTexturesLoad && this._completeTexturesLoad(); + } + }); // Don't render until the next frame after the ready promise is resolved return; } + if (this._loader.incrementallyLoadTextures && !this._texturesLoaded) { + // TODO: Check if textures are actually ready + // Re-run the pipeline so texture memory statistics are re-computed + this.resetDrawCommands(); + + this._texturesLoaded = true; + this._texturesReadyEvent.raiseEvent(this); + this._completeTexturesLoad = + this._completeTexturesLoad && this._completeTexturesLoad(); + } + updatePickIds(this); // Update the scene graph and draw commands for any changes in model's properties @@ -1825,8 +1947,12 @@ Model.prototype.update = function (frameState) { function processLoader(model, frameState) { if (!model._resourcesLoaded || !model._texturesLoaded) { - model._loader.process(frameState); + // Ensures frames continue to render in requestRender mode while resources are processing + frameState.afterRender.push(() => true); + return model._loader.process(frameState); } + + return true; } function updateCustomShader(model, frameState) { @@ -2635,6 +2761,11 @@ Model.prototype.destroyModelResources = function () { * @returns {Model} The newly created model. */ Model.fromGltf = function (options) { + deprecationWarning( + "Model.fromGltf", + "Model.fromGltf was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync instead." + ); + options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); @@ -2688,6 +2819,179 @@ Model.fromGltf = function (options) { return model; }; +/** + * <p> + * Asynchronously creates a model from a glTF asset. This function returns a promise that resolves when the model is ready to render, i.e., when the external binary, image, + * and shader files are downloaded and the WebGL resources are created. + * </p> + * <p> + * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the .glb extension. + * + * @param {Object} options Object with the following properties: + * @param {String|Resource} options.url The url to the .gltf or .glb file. + * @param {String|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {Boolean} [options.show=true] Whether or not to render the model. + * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. + * @param {Number} [options.scale=1.0] A uniform scale applied to this model. + * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. + * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from light sources. + * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @param {Boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. + * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. + * @param {Boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. + * @param {Boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. + * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. + * @param {Axis} [options.forwardAxis=Axis.Z] The forward-axis of the glTF model. + * @param {CustomShader} [options.customShader] A custom shader. This will add user-defined GLSL code to the vertex and fragment shaders. Using custom shaders with a {@link Cesium3DTileStyle} may lead to undefined behavior. + * @param {Cesium3DTileContent} [options.content] The tile content this model belongs to. This property will be undefined if model is not loaded as part of a tileset. + * @param {HeightReference} [options.heightReference=HeightReference.NONE] Determines how the model is drawn relative to terrain. + * @param {Scene} [options.scene] Must be passed in for models that use the height reference property. + * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. + * @param {Color} [options.color] A color that blends with the model's rendered color. + * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. + * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. + * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @param {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. + * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. + * @param {Cartesian3} [options.lightColor] The light color when shading the model. When <code>undefined</code> the scene's light color is used instead. + * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting on this model. + * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. + * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. + * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this model. + * @param {Boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. + * @param {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting. + * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded. + * + * @returns {Promise<Model>} A promise that resolves to the created model when it is ready to render. + * + * @exception {RuntimeError} The model failed to load. + * + * @example + * // Load a model and add it to the scene + * try { + * const model = await Cesium.Model.fromGltfAsync({ + * url: "../../SampleData/models/CesiumMan/Cesium_Man.glb" + * }); + * viewer.scene.primitives.add(model); + * } catch (error) { + * console.log(`Failed to load model. ${error}`); + * } + * + * @example + * // Position a model with modelMatrix and display it with a minimum size of 128 pixels + * const position = Cesium.Cartesian3.fromDegrees( + * -123.0744619, + * 44.0503706, + * 5000.0 + * ); + * const headingPositionRoll = new Cesium.HeadingPitchRoll(); + * const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator( + * "north", + * "west" + * ); + * try { + * const model = await Cesium.Model.fromGltfAsync({ + * url: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + * modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + * position, + * headingPositionRoll, + * Cesium.Ellipsoid.WGS84, + * fixedFrameTransform + * ), + * minimumPixelSize: 128, + * }); + * viewer.scene.primitives.add(model); + * } catch (error) { + * console.log(`Failed to load model. ${error}`); + * } + */ +Model.fromGltfAsync = async function (options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + //>>includeStart('debug', pragmas.debug); + if (!defined(options.url) && !defined(options.gltf)) { + throw new DeveloperError("options.url is required."); + } + //>>includeEnd('debug'); + + // options.gltf is used internally for 3D Tiles. It can be a Resource, a URL + // to a glTF/glb file, a binary glTF buffer, or a JSON object containing the + // glTF contents. + const gltf = defaultValue(options.url, options.gltf); + + const loaderOptions = { + releaseGltfJson: options.releaseGltfJson, + asynchronous: options.asynchronous, + incrementallyLoadTextures: options.incrementallyLoadTextures, + upAxis: options.upAxis, + forwardAxis: options.forwardAxis, + loadAttributesFor2D: options.projectTo2D, + loadIndicesForWireframe: options.enableDebugWireframe, + loadPrimitiveOutline: options.enableShowOutline, + loadForClassification: defined(options.classificationType), + }; + + const basePath = defaultValue(options.basePath, ""); + const baseResource = Resource.createIfNeeded(basePath); + + if (defined(gltf.asset)) { + loaderOptions.gltfJson = gltf; + loaderOptions.baseResource = baseResource; + loaderOptions.gltfResource = baseResource; + } else if (gltf instanceof Uint8Array) { + loaderOptions.typedArray = gltf; + loaderOptions.baseResource = baseResource; + loaderOptions.gltfResource = baseResource; + } else { + loaderOptions.gltfResource = Resource.createIfNeeded(gltf); + } + + const loader = new GltfLoader(loaderOptions); + + const is3DTiles = defined(options.content); + const type = is3DTiles ? ModelType.TILE_GLTF : ModelType.GLTF; + + const resource = loaderOptions.gltfResource; + + const modelOptions = makeModelOptions(loader, type, options); + modelOptions.resource = resource; + + try { + // This load the gltf JSON and ensures the gltf is valid + // Further resource loading is handled synchronously in loader.process(), and requires + // hooking into model's update() as the frameState is needed + await loader.load(); + + const model = new Model(modelOptions); + + const resourceCredits = model._resource.credits; + if (defined(resourceCredits)) { + const length = resourceCredits.length; + for (let i = 0; i < length; i++) { + model._resourceCredits.push(resourceCredits[i]); + } + } + + return model; + } catch (error) { + loader.destroy(); + throw ModelUtility.getError("model", resource, error); + } +}; + /* * @private */ diff --git a/packages/engine/Source/Scene/Model/Model3DTileContent.js b/packages/engine/Source/Scene/Model/Model3DTileContent.js index 54c98c4b4aa..51744b06bf2 100644 --- a/packages/engine/Source/Scene/Model/Model3DTileContent.js +++ b/packages/engine/Source/Scene/Model/Model3DTileContent.js @@ -276,6 +276,7 @@ Model3DTileContent.fromGltf = function (tileset, tile, resource, gltf) { modelOptions.classificationType = classificationType; + // This should be removed when readyPromise is deprecated across 3D Tiles functions const model = Model.fromGltf(modelOptions); content._model = model; // Include the animation setup in the ready promise to avoid an uncaught exception @@ -319,13 +320,8 @@ Model3DTileContent.fromB3dm = function ( const model = Model.fromB3dm(modelOptions); content._model = model; - // Include the animation setup in the ready promise to avoid an uncaught exception - content._readyPromise = model.readyPromise.then(function (model) { - model.activeAnimations.addAll({ - loop: ModelAnimationLoop.REPEAT, - }); - return model; - }); + // This should be removed when readyPromise is deprecated across 3D Tiles functions + content._readyPromise = model._readyPromise; return content; }; @@ -354,13 +350,8 @@ Model3DTileContent.fromI3dm = function ( const model = Model.fromI3dm(modelOptions); content._model = model; - // Include the animation setup in the ready promise to avoid an uncaught exception - content._readyPromise = model.readyPromise.then(function (model) { - model.activeAnimations.addAll({ - loop: ModelAnimationLoop.REPEAT, - }); - return model; - }); + // This should be removed when readyPromise is deprecated across 3D Tiles functions + content._readyPromise = model._readyPromise; return content; }; @@ -388,7 +379,8 @@ Model3DTileContent.fromPnts = function ( ); const model = Model.fromPnts(modelOptions); content._model = model; - content._readyPromise = model.readyPromise; + // This should be removed when readyPromise is deprecated across 3D Tiles functions + content._readyPromise = model._readyPromise; return content; }; @@ -409,7 +401,8 @@ Model3DTileContent.fromGeoJson = function (tileset, tile, resource, geoJson) { ); const model = Model.fromGeoJson(modelOptions); content._model = model; - content._readyPromise = model.readyPromise; + // This should be removed when readyPromise is deprecated across 3D Tiles functions + content._readyPromise = model._readyPromise; return content; }; diff --git a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js index 8c1c0eb7697..8cd93901fed 100644 --- a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js +++ b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js @@ -174,7 +174,7 @@ ModelAnimationCollection.prototype.add = function (options) { //>>includeStart('debug', pragmas.debug); if (!model.ready) { throw new DeveloperError( - "Animations are not loaded. Wait for Model.readyPromise to resolve." + "Animations are not loaded. Wait for Model.ready to be true." ); } //>>includeEnd('debug'); @@ -258,7 +258,7 @@ ModelAnimationCollection.prototype.addAll = function (options) { //>>includeStart('debug', pragmas.debug); if (!model.ready) { throw new DeveloperError( - "Animations are not loaded. Wait for Model.readyPromise to resolve." + "Animations are not loaded. Wait for Model.ready to be true." ); } diff --git a/packages/engine/Source/Scene/Model/ModelUtility.js b/packages/engine/Source/Scene/Model/ModelUtility.js index b99f9e8076b..f9f0c052b65 100644 --- a/packages/engine/Source/Scene/Model/ModelUtility.js +++ b/packages/engine/Source/Scene/Model/ModelUtility.js @@ -20,29 +20,27 @@ function ModelUtility() {} /** * Create a function for reporting when a model fails to load * - * @param {Model} model The model to report about * @param {String} type The type of object to report about * @param {String} path The URI of the model file - * @returns {Function} An error function that throws an error for the failed model + * @param {Error} [error] The error which caused the failure + * @returns {RuntimeError} An error for the failed model * * @private */ -ModelUtility.getFailedLoadFunction = function (model, type, path) { - return function (error) { - let message = `Failed to load ${type}: ${path}`; - if (defined(error)) { - message += `\n${error.message}`; - } +ModelUtility.getError = function (type, path, error) { + let message = `Failed to load ${type}: ${path}`; + if (defined(error) && defined(error.message)) { + message += `\n${error.message}`; + } - const runtimeError = new RuntimeError(message); - if (defined(error)) { - // the original call stack is often more useful than the new error's stack, - // so add the information here - runtimeError.stack = `Original stack:\n${error.stack}\nHandler stack:\n${runtimeError.stack}`; - } + const runtimeError = new RuntimeError(message); + if (defined(error)) { + // the original call stack is often more useful than the new error's stack, + // so add the information here + runtimeError.stack = `Original stack:\n${error.stack}\nHandler stack:\n${runtimeError.stack}`; + } - return Promise.reject(runtimeError); - }; + return runtimeError; }; /** @@ -372,6 +370,8 @@ ModelUtility.supportedExtensions = { * a {@link RuntimeError} with the extension name. * * @param {Array<String>} extensionsRequired The extensionsRequired array in the glTF. + * + * @exception {RuntimeError} Unsupported glTF Extension */ ModelUtility.checkSupportedExtensions = function (extensionsRequired) { const length = extensionsRequired.length; diff --git a/packages/engine/Source/Scene/ResourceCache.js b/packages/engine/Source/Scene/ResourceCache.js index 862b39aeeaa..649e34294d0 100644 --- a/packages/engine/Source/Scene/ResourceCache.js +++ b/packages/engine/Source/Scene/ResourceCache.js @@ -69,20 +69,17 @@ ResourceCache.get = function (cacheKey) { }; /** - * Loads a resource and adds it to the cache. + * Adds it to the cache. * - * @param {Object} options Object with the following properties: - * @param {ResourceLoader} options.resourceLoader The resource. + * @param {ResourceLoader} resourceLoader The resource. + * @returns {ResourceLoader} The resource. * - * @exception {DeveloperError} Resource with this cacheKey is already in the cach + * @exception {DeveloperError} Resource with this cacheKey is already in the cache * @private */ -ResourceCache.load = function (options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - const resourceLoader = options.resourceLoader; - +ResourceCache.add = function (resourceLoader) { //>>includeStart('debug', pragmas.debug); - Check.typeOf.object("options.resourceLoader", resourceLoader); + Check.typeOf.object("resourceLoader", resourceLoader); //>>includeEnd('debug'); const cacheKey = resourceLoader.cacheKey; @@ -99,7 +96,7 @@ ResourceCache.load = function (options) { ResourceCache.cacheEntries[cacheKey] = new CacheEntry(resourceLoader); - resourceLoader.load(); + return resourceLoader; }; /** @@ -136,18 +133,18 @@ ResourceCache.unload = function (resourceLoader) { }; /** - * Loads a schema from the cache. + * Gets an existing schema loader from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} [options.schema] An object that explicitly defines a schema JSON. Mutually exclusive with options.resource. * @param {Resource} [options.resource] The {@link Resource} pointing to the schema JSON. Mutually exclusive with options.schema. * - * @returns {MetadataSchemaLoader} The schema resource. + * @returns {MetadataSchemaLoader} The cached schema resource. * * @exception {DeveloperError} One of options.schema and options.resource must be defined. * @private */ -ResourceCache.loadSchema = function (options) { +ResourceCache.getSchemaLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const schema = options.schema; const resource = options.resource; @@ -176,25 +173,21 @@ ResourceCache.loadSchema = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: schemaLoader, - }); - - return schemaLoader; + return ResourceCache.add(schemaLoader); }; /** - * Load an embedded buffer from the cache. + * Gets an existing embedded buffer loader from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Resource} options.parentResource The {@link Resource} containing the embedded buffer. * @param {Number} options.bufferId A unique identifier of the embedded buffer within the parent resource. * @param {Uint8Array} [options.typedArray] The typed array containing the embedded buffer contents. * - * @returns {BufferLoader} The buffer loader. + * @returns {BufferLoader} The cached buffer loader. * @private */ -ResourceCache.loadEmbeddedBuffer = function (options) { +ResourceCache.getEmbeddedBufferLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const parentResource = options.parentResource; const bufferId = options.bufferId; @@ -224,23 +217,19 @@ ResourceCache.loadEmbeddedBuffer = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: bufferLoader, - }); - - return bufferLoader; + return ResourceCache.add(bufferLoader); }; /** - * Loads an external buffer from the cache. + * Gets an existing external buffer from loader the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Resource} options.resource The {@link Resource} pointing to the external buffer. * - * @returns {BufferLoader} The buffer loader. + * @returns {BufferLoader} The cached buffer loader. * @private */ -ResourceCache.loadExternalBuffer = function (options) { +ResourceCache.getExternalBufferLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const resource = options.resource; @@ -262,15 +251,11 @@ ResourceCache.loadExternalBuffer = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: bufferLoader, - }); - - return bufferLoader; + return ResourceCache.add(bufferLoader); }; /** - * Loads a glTF JSON from the cache. + * Gets an existing glTF JSON loader from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. @@ -278,10 +263,10 @@ ResourceCache.loadExternalBuffer = function (options) { * @param {Uint8Array} [options.typedArray] The typed array containing the glTF contents. * @param {Object} [options.gltfJson] The parsed glTF JSON contents. * - * @returns {GltfJsonLoader} The glTF JSON. + * @returns {GltfJsonLoader} The cached glTF JSON loader. * @private */ -ResourceCache.loadGltfJson = function (options) { +ResourceCache.getGltfJsonLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltfResource = options.gltfResource; const baseResource = options.baseResource; @@ -311,15 +296,11 @@ ResourceCache.loadGltfJson = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: gltfJsonLoader, - }); - - return gltfJsonLoader; + return ResourceCache.add(gltfJsonLoader); }; /** - * Loads a glTF buffer view from the cache. + * Gets an existing glTF buffer view from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -327,10 +308,10 @@ ResourceCache.loadGltfJson = function (options) { * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {GltfBufferViewLoader} The buffer view loader. + * @returns {GltfBufferViewLoader>} The cached buffer view loader. * @private */ -ResourceCache.loadBufferView = function (options) { +ResourceCache.getBufferViewLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const bufferViewId = options.bufferViewId; @@ -365,15 +346,11 @@ ResourceCache.loadBufferView = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: bufferViewLoader, - }); - - return bufferViewLoader; + return ResourceCache.add(bufferViewLoader); }; /** - * Loads Draco data from the cache. + * Gets an existing Draco data from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -381,10 +358,10 @@ ResourceCache.loadBufferView = function (options) { * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {GltfDracoLoader} The Draco loader. + * @returns {GltfDracoLoader} The cached Draco loader. * @private */ -ResourceCache.loadDraco = function (options) { +ResourceCache.getDracoLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const draco = options.draco; @@ -419,15 +396,11 @@ ResourceCache.loadDraco = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: dracoLoader, - }); - - return dracoLoader; + return ResourceCache.add(dracoLoader); }; /** - * Loads a glTF vertex buffer from the cache. + * Gets an existing glTF vertex buffer from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -446,10 +419,10 @@ ResourceCache.loadDraco = function (options) { * @exception {DeveloperError} When options.draco is defined options.attributeSemantic must also be defined. * @exception {DeveloperError} When options.draco is defined options.accessorId must also be defined. * - * @returns {GltfVertexBufferLoader} The vertex buffer loader. + * @returns {GltfVertexBufferLoader} The cached vertex buffer loader. * @private */ -ResourceCache.loadVertexBuffer = function (options) { +ResourceCache.getVertexBufferLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const gltfResource = options.gltfResource; @@ -539,18 +512,7 @@ ResourceCache.loadVertexBuffer = function (options) { loadTypedArray: loadTypedArray, }); - ResourceCache.load({ - resourceLoader: vertexBufferLoader, - }); - - const promise = ResourceCache.statistics.addGeometryLoader( - vertexBufferLoader - ); - - // Needed for unit testing - ResourceCache.cacheEntries[cacheKey]._statisticsPromise = promise; - - return vertexBufferLoader; + return ResourceCache.add(vertexBufferLoader); }; function hasDracoCompression(draco, semantic) { @@ -562,7 +524,7 @@ function hasDracoCompression(draco, semantic) { } /** - * Loads a glTF index buffer from the cache. + * Gets an existing glTF index buffer from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -574,10 +536,10 @@ function hasDracoCompression(draco, semantic) { * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * @param {Boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. * @param {Boolean} [options.loadTypedArray=false] Load index buffer as a typed array. - * @returns {GltfIndexBufferLoader} The index buffer loader. + * @returns {GltfIndexBufferLoader} The cached index buffer loader. * @private */ -ResourceCache.loadIndexBuffer = function (options) { +ResourceCache.getIndexBufferLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const accessorId = options.accessorId; @@ -631,19 +593,11 @@ ResourceCache.loadIndexBuffer = function (options) { loadTypedArray: loadTypedArray, }); - ResourceCache.load({ - resourceLoader: indexBufferLoader, - }); - const promise = ResourceCache.statistics.addGeometryLoader(indexBufferLoader); - - // Needed for unit testing - ResourceCache.cacheEntries[cacheKey]._statisticsPromise = promise; - - return indexBufferLoader; + return ResourceCache.add(indexBufferLoader); }; /** - * Loads a glTF image from the cache. + * Gets an existing glTF image from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -651,10 +605,10 @@ ResourceCache.loadIndexBuffer = function (options) { * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {GltfImageLoader} The image loader. + * @returns {GltfImageLoader} The cached image loader. * @private */ -ResourceCache.loadImage = function (options) { +ResourceCache.getImageLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const imageId = options.imageId; @@ -689,15 +643,11 @@ ResourceCache.loadImage = function (options) { cacheKey: cacheKey, }); - ResourceCache.load({ - resourceLoader: imageLoader, - }); - - return imageLoader; + return ResourceCache.add(imageLoader); }; /** - * Loads a glTF texture from the cache. + * Gets an existing glTF texture from the cache, or creates a new loader if one does not already exist. * * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. @@ -708,10 +658,10 @@ ResourceCache.loadImage = function (options) { * @param {FrameState} options.frameState The frame state. * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * - * @returns {GltfTextureLoader} The texture loader. + * @returns {GltfTextureLoader} The cached texture loader. * @private */ -ResourceCache.loadTexture = function (options) { +ResourceCache.getTextureLoader = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltf = options.gltf; const textureInfo = options.textureInfo; @@ -755,15 +705,7 @@ ResourceCache.loadTexture = function (options) { asynchronous: asynchronous, }); - ResourceCache.load({ - resourceLoader: textureLoader, - }); - const promise = ResourceCache.statistics.addTextureLoader(textureLoader); - - // Needed for unit testing - ResourceCache.cacheEntries[cacheKey]._statisticsPromise = promise; - - return textureLoader; + return ResourceCache.add(textureLoader); }; /** diff --git a/packages/engine/Source/Scene/ResourceCacheStatistics.js b/packages/engine/Source/Scene/ResourceCacheStatistics.js index 70fef98fbc3..cdc954298a8 100644 --- a/packages/engine/Source/Scene/ResourceCacheStatistics.js +++ b/packages/engine/Source/Scene/ResourceCacheStatistics.js @@ -47,14 +47,12 @@ ResourceCacheStatistics.prototype.clear = function () { }; /** - * Track the resources for a vertex or index buffer loader. This is implemented - * asynchronously since resources may not be immediately available to count. + * Track the resources for a vertex or index buffer loader. This should be called after a loader is ready; that + * is it has been loaded and processed. * This method handles the following cases gracefully: * <ul> * <li>If the loader is added twice, its resources will not be double-counted</li> * <li>If the geometry has a CPU copy of the GPU buffer, it will be added to the count</li> - * <li>If the resource loading failed, its resources will not be counted</li> - * <li>If removeLoader() was called before the loader promise resolves, its resources will not be counted</li> * </ul> * @param {GltfVertexBufferLoader|GltfIndexBufferLoader} loader The geometry buffer with resources to track * @returns {Promise} A promise that resolves once the count is updated. @@ -75,51 +73,33 @@ ResourceCacheStatistics.prototype.addGeometryLoader = function (loader) { this._geometrySizes[cacheKey] = 0; - const that = this; - return loader.promise - .then(function (loader) { - // loader was unloaded before its promise resolved - if (!that._geometrySizes.hasOwnProperty(cacheKey)) { - return; - } - - const buffer = loader.buffer; - const typedArray = loader.typedArray; - - let totalSize = 0; - - if (defined(buffer)) { - totalSize += buffer.sizeInBytes; - } - - if (defined(typedArray)) { - totalSize += typedArray.byteLength; - } - - that.geometryByteLength += totalSize; - that._geometrySizes[cacheKey] = totalSize; - }) - .catch(function () { - // If the resource failed to load, remove it from the cache - delete that._geometrySizes[cacheKey]; - }); + const buffer = loader.buffer; + const typedArray = loader.typedArray; + + let totalSize = 0; + + if (defined(buffer)) { + totalSize += buffer.sizeInBytes; + } + + if (defined(typedArray)) { + totalSize += typedArray.byteLength; + } + + this.geometryByteLength += totalSize; + this._geometrySizes[cacheKey] = totalSize; }; /** - * Track the resources for a texture loader. This is implemented - * asynchronously since resources may not be immediately available to count. - * This method handles the following cases gracefully: - * <ul> - * <li>If the loader is added twice, its resources will not be double-counted</li> - * <li>If the resource loading failed, its resources will not be counted</li> - * <li>If removeLoader() was called before the loader promise resolves, its resources will not be counted</li> - * </ul> + * Track the resources for a texture loader. This should be called after a loader is ready; that + * is it has been loaded and processed. + * If the loader is added twice, its resources will not be double-counted. + * * @param {GltfTextureLoader} loader The texture loader with resources to track - * @returns {Promise} A promise that resolves once the count is updated. * * @private */ -ResourceCacheStatistics.prototype.addTextureLoader = function (loader) { +ResourceCacheStatistics.prototype.addTextureLoader = async function (loader) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("loader", loader); //>>includeEnd('debug'); @@ -132,22 +112,9 @@ ResourceCacheStatistics.prototype.addTextureLoader = function (loader) { } this._textureSizes[cacheKey] = 0; - - const that = this; - return loader.promise - .then(function (loader) { - // loader was unloaded before its promise resolved - if (!that._textureSizes.hasOwnProperty(cacheKey)) { - return; - } - - const totalSize = loader.texture.sizeInBytes; - that.texturesByteLength += loader.texture.sizeInBytes; - that._textureSizes[cacheKey] = totalSize; - }) - .catch(function () { - delete that._textureSizes[cacheKey]; - }); + const totalSize = loader.texture.sizeInBytes; + this.texturesByteLength += loader.texture.sizeInBytes; + this._textureSizes[cacheKey] = totalSize; }; /** diff --git a/packages/engine/Source/Scene/ResourceLoader.js b/packages/engine/Source/Scene/ResourceLoader.js index aa5756207e6..e3ebe08ef0c 100644 --- a/packages/engine/Source/Scene/ResourceLoader.js +++ b/packages/engine/Source/Scene/ResourceLoader.js @@ -20,21 +20,6 @@ import RuntimeError from "../Core/RuntimeError.js"; function ResourceLoader() {} Object.defineProperties(ResourceLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof ResourceLoader.prototype - * - * @type {Promise.<ResourceLoader>|undefined} - * @readonly - * @private - */ - promise: { - // eslint-disable-next-line getter-return - get: function () { - DeveloperError.throwInstantiationError(); - }, - }, /** * The cache key of the resource. * @@ -71,9 +56,12 @@ ResourceLoader.prototype.unload = function () {}; * Processes the resource until it becomes ready. * * @param {FrameState} frameState The frame state. + * @returns {boolean} true once all resourced are ready. * @private */ -ResourceLoader.prototype.process = function (frameState) {}; +ResourceLoader.prototype.process = function (frameState) { + return false; +}; /** * Constructs a {@link RuntimeError} from an errorMessage and an error. @@ -89,7 +77,7 @@ ResourceLoader.prototype.getError = function (errorMessage, error) { Check.typeOf.string("errorMessage", errorMessage); //>>includeEnd('debug'); - if (defined(error)) { + if (defined(error) && defined(error.message)) { errorMessage += `\n${error.message}`; } diff --git a/packages/engine/Source/Scene/ResourceLoaderState.js b/packages/engine/Source/Scene/ResourceLoaderState.js index df206e2943f..f48c10fac2d 100644 --- a/packages/engine/Source/Scene/ResourceLoaderState.js +++ b/packages/engine/Source/Scene/ResourceLoaderState.js @@ -21,13 +21,21 @@ const ResourceLoaderState = { */ LOADING: 1, /** - * The resource has finished loading, but requires further processing. GPU resources are allocated in this state as needed. + * The resource has finished loading, but requires further processing. * * @type {Number} * @constant * @private */ - PROCESSING: 2, + LOADED: 2, + /** + * The resource is processing. GPU resources are allocated in this state as needed. + * + * @type {Number} + * @constant + * @private + */ + PROCESSING: 3, /** * The resource has finished loading and processing; the results are ready to be used. * @@ -35,7 +43,7 @@ const ResourceLoaderState = { * @constant * @private */ - READY: 3, + READY: 4, /** * The resource loading or processing has failed due to an error. * @@ -43,6 +51,6 @@ const ResourceLoaderState = { * @constant * @private */ - FAILED: 4, + FAILED: 5, }; export default Object.freeze(ResourceLoaderState); diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 27c8c3181f5..3f3325dd348 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -3,6 +3,7 @@ import { Cartesian2, Cartesian3, Color, + defined, DistanceDisplayCondition, HeightReference, JulianDate, @@ -58,25 +59,25 @@ describe( scene.destroyForSpecs(); }); - it("constructor throws if no scene is passed.", function () { + it("constructor throws if no scene is passed", function () { expect(function () { return new ModelVisualizer(undefined, entityCollection); }).toThrowDeveloperError(); }); - it("constructor throws if no entityCollection is passed.", function () { + it("constructor throws if no entityCollection is passed", function () { expect(function () { return new ModelVisualizer(scene, undefined); }).toThrowDeveloperError(); }); - it("update throws if no time specified.", function () { + it("update throws if no time specified", function () { expect(function () { visualizer.update(); }).toThrowDeveloperError(); }); - it("isDestroy returns false until destroyed.", function () { + it("isDestroy returns false until destroyed", function () { expect(visualizer.isDestroyed()).toEqual(false); visualizer.destroy(); expect(visualizer.isDestroyed()).toEqual(true); @@ -90,7 +91,7 @@ describe( visualizer = undefined; }); - it("object with no model does not create one.", function () { + it("object with no model does not create one", function () { const testObject = entityCollection.getOrCreateEntity("test"); testObject.position = new ConstantProperty( new Cartesian3(1234, 5678, 9101112) @@ -99,7 +100,7 @@ describe( expect(scene.primitives.length).toEqual(0); }); - it("object with no position does not create a model.", function () { + it("object with no position does not create a model", function () { const testObject = entityCollection.getOrCreateEntity("test"); const model = (testObject.model = new ModelGraphics()); model.uri = new ConstantProperty(boxUrl); @@ -108,7 +109,7 @@ describe( expect(scene.primitives.length).toEqual(0); }); - it("A ModelGraphics causes a primitive to be created and updated.", function () { + it("creates and updates a primitive from ModelGraphics", async function () { const time = JulianDate.now(); const model = new ModelGraphics(); @@ -153,10 +154,14 @@ describe( visualizer.update(time); - expect(scene.primitives.length).toEqual(1); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); - const primitive = scene.primitives.get(0); visualizer.update(time); + expect(primitive.show).toEqual(true); expect(primitive.scale).toEqual(2); expect(primitive.minimumPixelSize).toEqual(24.0); @@ -187,35 +192,36 @@ describe( expect(primitive.imageBasedLighting.imageBasedLightingFactor).toEqual( new Cartesian2(0.5, 0.5) ); + expect(primitive.lightColor).toEqual(new Color(1.0, 1.0, 0.0, 1.0)); // wait till the model is loaded before we can check node transformations - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); return primitive.ready; - }).then(function () { - visualizer.update(time); + }); - const node = primitive.getNode("Root"); - expect(node).toBeDefined(); + visualizer.update(time); - const transformationMatrix = Matrix4.fromTranslationQuaternionRotationScale( - translation, - rotation, - scale - ); + const node = primitive.getNode("Root"); + expect(node).toBeDefined(); - Matrix4.multiplyTransformation( - node.originalMatrix, - transformationMatrix, - transformationMatrix - ); + const transformationMatrix = Matrix4.fromTranslationQuaternionRotationScale( + translation, + rotation, + scale + ); - expect(node.matrix).toEqual(transformationMatrix); - }); + Matrix4.multiplyTransformation( + node.originalMatrix, + transformationMatrix, + transformationMatrix + ); + + expect(node.matrix).toEqual(transformationMatrix); }); - it("can apply model articulations", function () { + it("can apply model articulations", async function () { const time = JulianDate.now(); const model = new ModelGraphics(); @@ -243,43 +249,44 @@ describe( visualizer.update(time); - expect(scene.primitives.length).toEqual(1); - - const primitive = scene.primitives.get(0); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); // wait till the model is loaded before we can check articulations - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); return primitive.ready; - }).then(function () { - visualizer.update(time); - - const node = primitive.getNode("Root"); - - const expected = [ - 0.7147690483240505, - -0.04340611926232735, - -0.0749741046529782, - 0, - -0.06188330295778636, - 0.05906797312763484, - -0.6241645867602773, - 0, - 0.03752515582279579, - 0.5366347296529127, - 0.04706410108373541, - 0, - 1, - 3, - -2, - 1, - ]; - - expect(node.matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14); }); + visualizer.update(time); + + const node = primitive.getNode("Root"); + + const expected = [ + 0.7147690483240505, + -0.04340611926232735, + -0.0749741046529782, + 0, + -0.06188330295778636, + 0.05906797312763484, + -0.6241645867602773, + 0, + 0.03752515582279579, + 0.5366347296529127, + 0.04706410108373541, + 0, + 1, + 3, + -2, + 1, + ]; + + expect(node.matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14); }); - it("A ModelGraphics with a Resource causes a primitive to be created.", function () { + it("creates a primitive from ModelGraphics with a Resource", async function () { const time = JulianDate.now(); const model = new ModelGraphics(); @@ -298,23 +305,25 @@ describe( visualizer.update(time); - expect(scene.primitives.length).toEqual(1); - - const primitive = scene.primitives.get(0); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); // wait till the model is loaded before we can check node transformations - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); return primitive.ready; - }).then(function () { - visualizer.update(time); - - const node = primitive.getNode("Root"); - expect(node).toBeDefined(); }); + + visualizer.update(time); + + const node = primitive.getNode("Root"); + expect(node).toBeDefined(); }); - it("removing removes primitives.", function () { + it("removes primitives on Entity removal", async function () { const model = new ModelGraphics(); model.uri = new ConstantProperty(boxUrl); @@ -326,14 +335,19 @@ describe( testObject.model = model; visualizer.update(time); - expect(scene.primitives.length).toEqual(1); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); + visualizer.update(time); entityCollection.removeAll(); visualizer.update(time); expect(scene.primitives.length).toEqual(0); }); - it("Visualizer sets id property.", function () { + it("sets id property", async function () { const time = JulianDate.now(); const testObject = entityCollection.getOrCreateEntity("test"); const model = new ModelGraphics(); @@ -345,11 +359,16 @@ describe( model.uri = new ConstantProperty(boxUrl); visualizer.update(time); - const modelPrimitive = scene.primitives.get(0); - expect(modelPrimitive.id).toEqual(testObject); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); + + expect(primitive.id).toEqual(testObject); }); - it("Computes bounding sphere.", function () { + it("computes bounding sphere", async function () { const time = JulianDate.now(); const testObject = entityCollection.getOrCreateEntity("test"); const model = new ModelGraphics(); @@ -361,26 +380,30 @@ describe( model.uri = new ConstantProperty(boxUrl); visualizer.update(time); - const modelPrimitive = scene.primitives.get(0); + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); + const result = new BoundingSphere(); let state = visualizer.getBoundingSphere(testObject, result); expect(state).toBe(BoundingSphereState.PENDING); - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; - }).then(function () { - expect(state).toBe(BoundingSphereState.DONE); - const expected = BoundingSphere.clone( - modelPrimitive.boundingSphere, - new BoundingSphere() - ); - expect(result).toEqual(expected); }); + expect(state).toBe(BoundingSphereState.DONE); + const expected = BoundingSphere.clone( + primitive.boundingSphere, + new BoundingSphere() + ); + expect(result).toEqual(expected); }); - it("Computes bounding sphere with height reference clamp to ground", function () { + it("computes bounding sphere with height reference clamp to ground", function () { // Setup a position for the model. const position = Cartesian3.fromDegrees(149.515332, -34.984799); const positionCartographic = Cartographic.fromCartesian(position); @@ -455,7 +478,7 @@ describe( }); }); - it("Computes bounding sphere with height reference clamp to ground on terrain provider without availability", function () { + it("computes bounding sphere with height reference clamp to ground on terrain provider without availability", function () { // Setup a position for the model. const longitude = CesiumMath.toRadians(149.515332); const latitude = CesiumMath.toRadians(-34.984799); @@ -507,7 +530,7 @@ describe( }); }); - it("Computes bounding sphere with height reference relative to ground", function () { + it("computes bounding sphere with height reference relative to ground", function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -588,7 +611,7 @@ describe( }); }); - it("Computes bounding sphere with height reference relative to ground on terrain provider without availability", function () { + it("computes bounding sphere with height reference relative to ground on terrain provider without availability", function () { // Setup a position for the model. const longitude = CesiumMath.toRadians(149.515332); const latitude = CesiumMath.toRadians(-34.984799); @@ -638,7 +661,7 @@ describe( }); }); - it("Fails bounding sphere for entity without billboard.", function () { + it("fails bounding sphere for entity without ModelGraphics", function () { const testObject = entityCollection.getOrCreateEntity("test"); visualizer.update(JulianDate.now()); const result = new BoundingSphere(); @@ -646,7 +669,7 @@ describe( expect(state).toBe(BoundingSphereState.FAILED); }); - it("Fails bounding sphere when model fails to load.", function () { + it("fails bounding sphere when model fails to load", function () { const time = JulianDate.now(); const testObject = entityCollection.getOrCreateEntity("test"); const model = new ModelGraphics(); @@ -670,7 +693,7 @@ describe( }); }); - it("Fails bounding sphere when sampleTerrainMostDetailed fails.", function () { + it("fails bounding sphere when sampleTerrainMostDetailed fails", function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -727,14 +750,14 @@ describe( }); }); - it("Compute bounding sphere throws without entity.", function () { + it("compute bounding sphere throws without entity", function () { const result = new BoundingSphere(); expect(function () { visualizer.getBoundingSphere(undefined, result); }).toThrowDeveloperError(); }); - it("Compute bounding sphere throws without result.", function () { + it("compute bounding sphere throws without result", function () { const testObject = entityCollection.getOrCreateEntity("test"); expect(function () { visualizer.getBoundingSphere(testObject, undefined); diff --git a/packages/engine/Specs/Scene/BufferLoaderSpec.js b/packages/engine/Specs/Scene/BufferLoaderSpec.js index f567b8821ee..884ab8e001e 100644 --- a/packages/engine/Specs/Scene/BufferLoaderSpec.js +++ b/packages/engine/Specs/Scene/BufferLoaderSpec.js @@ -1,4 +1,9 @@ -import { BufferLoader, Resource, ResourceCache } from "../../index.js"; +import { + BufferLoader, + Resource, + ResourceCache, + RuntimeError, +} from "../../index.js"; describe("Scene/BufferLoader", function () { const typedArray = new Uint8Array([1, 3, 7, 15, 31, 63, 127, 255]); @@ -27,7 +32,7 @@ describe("Scene/BufferLoader", function () { }).toThrowDeveloperError(); }); - it("rejects promise if buffer cannot be fetched", function () { + it("load throws if buffer cannot be fetched", async function () { const error = new Error("404 Not Found"); spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { return Promise.reject(error); @@ -37,31 +42,23 @@ describe("Scene/BufferLoader", function () { resource: resource, }); - bufferLoader.load(); - - return bufferLoader.promise - .then(function (bufferLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(bufferLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("loads buffer from typed array", function () { + it("loads buffer from typed array", async function () { const bufferLoader = new BufferLoader({ typedArray: typedArray, }); - bufferLoader.load(); - return bufferLoader.promise.then(function (bufferLoader) { - expect(bufferLoader.typedArray).toBe(typedArray); - }); + await bufferLoader.load(); + + expect(bufferLoader.typedArray).toBe(typedArray); }); - it("loads external buffer", function () { + it("loads external buffer", async function () { const fetchBuffer = spyOn( Resource.prototype, "fetchArrayBuffer" @@ -71,15 +68,13 @@ describe("Scene/BufferLoader", function () { resource: resource, }); - bufferLoader.load(); + await bufferLoader.load(); - return bufferLoader.promise.then(function (bufferLoader) { - expect(fetchBuffer).toHaveBeenCalled(); - expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer); - }); + expect(fetchBuffer).toHaveBeenCalled(); + expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer); }); - it("destroys buffer", function () { + it("destroys buffer", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -90,27 +85,20 @@ describe("Scene/BufferLoader", function () { expect(bufferLoader.typedArray).not.toBeDefined(); - bufferLoader.load(); + await bufferLoader.load(); - return bufferLoader.promise.then(function (bufferLoader) { - expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer); - expect(bufferLoader.isDestroyed()).toBe(false); + expect(bufferLoader.typedArray.buffer).toBe(arrayBuffer); + expect(bufferLoader.isDestroyed()).toBe(false); - bufferLoader.destroy(); - expect(bufferLoader.typedArray).not.toBeDefined(); - expect(bufferLoader.isDestroyed()).toBe(true); - }); + bufferLoader.destroy(); + expect(bufferLoader.typedArray).not.toBeDefined(); + expect(bufferLoader.isDestroyed()).toBe(true); }); - function resolveAfterDestroy(rejectPromise) { - const fetchPromise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(arrayBuffer); - } - }); - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(fetchPromise); + it("handles asynchronous load after destroy", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.resolve(arrayBuffer) + ); const bufferLoader = new BufferLoader({ resource: resource, @@ -121,17 +109,27 @@ describe("Scene/BufferLoader", function () { const loadPromise = bufferLoader.load(); bufferLoader.destroy(); - return loadPromise.finally(function () { - expect(bufferLoader.typedArray).not.toBeDefined(); - expect(bufferLoader.isDestroyed()).toBe(true); + await expectAsync(loadPromise).toBeResolved(); + expect(bufferLoader.typedArray).not.toBeDefined(); + expect(bufferLoader.isDestroyed()).toBe(true); + }); + + it("handles asynchronous error after destroy", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.reject(new Error()) + ); + + const bufferLoader = new BufferLoader({ + resource: resource, }); - } - it("handles resolving uri after destroy", function () { - return resolveAfterDestroy(false); - }); + expect(bufferLoader.typedArray).not.toBeDefined(); + + const loadPromise = bufferLoader.load(); + bufferLoader.destroy(); - it("handles rejecting uri after destroy", function () { - return resolveAfterDestroy(true); + await expectAsync(loadPromise).toBeResolved(); + expect(bufferLoader.typedArray).not.toBeDefined(); + expect(bufferLoader.isDestroyed()).toBe(true); }); }); diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js index 12f7b341e9c..ec5eb154ca0 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js @@ -1210,12 +1210,12 @@ describe( expect(clippingPlanes.isDestroyed()).toBe(true); }); - it("throws a DeveloperError when given a ClippingPlaneCollection attached to a Model", function () { + it("throws a DeveloperError when given a ClippingPlaneCollection attached to a Model", async function () { const clippingPlanes = new ClippingPlaneCollection({ planes: [new ClippingPlane(Cartesian3.UNIT_Z, 10000000.0)], }); const model = scene.primitives.add( - Model.fromGltf({ + await Model.fromGltf({ url: "./Data/Models/glTF-2.0/BoxTextured/glTF/BoxTextured.gltf", }) ); diff --git a/packages/engine/Specs/Scene/GltfBufferViewLoaderSpec.js b/packages/engine/Specs/Scene/GltfBufferViewLoaderSpec.js index 1a5009e12e0..97fb9610212 100644 --- a/packages/engine/Specs/Scene/GltfBufferViewLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfBufferViewLoaderSpec.js @@ -3,6 +3,7 @@ import { GltfBufferViewLoader, Resource, ResourceCache, + RuntimeError, } from "../../index.js"; describe("Scene/GltfBufferViewLoader", function () { @@ -101,9 +102,6 @@ describe("Scene/GltfBufferViewLoader", function () { const gltfResource = new Resource({ url: gltfUri, }); - const bufferResource = new Resource({ - url: "https://example.com/external.bin", - }); afterEach(function () { ResourceCache.clearForSpecs(); @@ -169,11 +167,10 @@ describe("Scene/GltfBufferViewLoader", function () { }).toThrowDeveloperError(); }); - it("rejects promise if buffer fails to load", function () { - const error = new Error("404 Not Found"); - spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { - return Promise.reject(error); - }); + it("load throws if buffer fails to load", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + Promise.reject(new Error("404 Not Found")) + ); const bufferViewLoader = new GltfBufferViewLoader({ resourceCache: ResourceCache, @@ -183,26 +180,21 @@ describe("Scene/GltfBufferViewLoader", function () { baseResource: gltfResource, }); - bufferViewLoader.load(); - - return bufferViewLoader.promise - .then(function (bufferViewLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(bufferViewLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("loads buffer view for embedded buffer", function () { - ResourceCache.loadEmbeddedBuffer({ + it("loads buffer view for embedded buffer", async function () { + const bufferLoader = ResourceCache.getEmbeddedBufferLoader({ parentResource: gltfResource, bufferId: 0, typedArray: bufferTypedArray, }); + await bufferLoader.load(); + const bufferViewLoader = new GltfBufferViewLoader({ resourceCache: ResourceCache, gltf: gltfEmbedded, @@ -210,14 +202,13 @@ describe("Scene/GltfBufferViewLoader", function () { gltfResource: gltfResource, baseResource: gltfResource, }); - bufferViewLoader.load(); - return bufferViewLoader.promise.then(function (bufferViewLoader) { - expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); - }); + await bufferViewLoader.load(); + + expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); }); - it("loads buffer view for external buffer", function () { + it("loads buffer view for external buffer", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(bufferArrayBuffer) ); @@ -229,14 +220,13 @@ describe("Scene/GltfBufferViewLoader", function () { gltfResource: gltfResource, baseResource: gltfResource, }); - bufferViewLoader.load(); - return bufferViewLoader.promise.then(function (bufferViewLoader) { - expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); - }); + await bufferViewLoader.load(); + + expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); }); - it("destroys buffer view", function () { + it("destroys buffer view", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(bufferArrayBuffer) ); @@ -256,27 +246,27 @@ describe("Scene/GltfBufferViewLoader", function () { expect(bufferViewLoader.typedArray).not.toBeDefined(); - bufferViewLoader.load(); + await bufferViewLoader.load(); - return bufferViewLoader.promise.then(function (bufferViewLoader) { - expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); - expect(bufferViewLoader.isDestroyed()).toBe(false); + expect(bufferViewLoader.typedArray).toEqual(new Uint8Array([7, 15, 31])); + expect(bufferViewLoader.isDestroyed()).toBe(false); - bufferViewLoader.destroy(); + bufferViewLoader.destroy(); - expect(bufferViewLoader.typedArray).not.toBeDefined(); - expect(bufferViewLoader.isDestroyed()).toBe(true); - expect(unloadBuffer).toHaveBeenCalled(); - }); + expect(bufferViewLoader.typedArray).not.toBeDefined(); + expect(bufferViewLoader.isDestroyed()).toBe(true); + expect(unloadBuffer).toHaveBeenCalled(); }); - it("decodes positions with EXT_meshopt_compression", function () { - const bufferLoader = ResourceCache.loadEmbeddedBuffer({ + it("decodes positions with EXT_meshopt_compression", async function () { + const bufferLoader = ResourceCache.getEmbeddedBufferLoader({ parentResource: gltfResource, bufferId: 0, typedArray: meshoptPositionTypedArray, }); + await bufferLoader.load(); + const bufferViewLoader = new GltfBufferViewLoader({ resourceCache: ResourceCache, gltf: meshoptGltfEmbedded, @@ -285,35 +275,18 @@ describe("Scene/GltfBufferViewLoader", function () { baseResource: gltfResource, }); - bufferViewLoader.load(); - return bufferLoader.promise - .then(function () { - bufferViewLoader.process({}); - return bufferViewLoader.promise; - }) - .then(function (bufferViewLoader) { - const decodedPositionBase64 = getBase64FromTypedArray( - bufferViewLoader.typedArray - ); - expect(decodedPositionBase64).toEqual(fallbackPositionBufferBase64); - }); - }); + await bufferViewLoader.load(); - function resolveAfterDestroy(rejectPromise) { - const fetchPromise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(bufferArrayBuffer); - } - }); - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(fetchPromise); + const decodedPositionBase64 = getBase64FromTypedArray( + bufferViewLoader.typedArray + ); + expect(decodedPositionBase64).toEqual(fallbackPositionBufferBase64); + }); - // Load a copy of the buffer into the cache so that the buffer promise - // resolves even if the buffer view loader is destroyed - const bufferLoaderCopy = ResourceCache.loadExternalBuffer({ - resource: bufferResource, - }); + it("handles asynchronous load after destroy", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.resolve(bufferArrayBuffer) + ); const bufferViewLoader = new GltfBufferViewLoader({ resourceCache: ResourceCache, @@ -328,19 +301,31 @@ describe("Scene/GltfBufferViewLoader", function () { const loadPromise = bufferViewLoader.load(); bufferViewLoader.destroy(); - return loadPromise.finally(function () { - expect(bufferViewLoader.typedArray).not.toBeDefined(); - expect(bufferViewLoader.isDestroyed()).toBe(true); + await expectAsync(loadPromise).toBeResolved(); + expect(bufferViewLoader.typedArray).not.toBeDefined(); + expect(bufferViewLoader.isDestroyed()).toBe(true); + }); + + it("handles asynchronous error after destroy", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + Promise.reject(new Error()) + ); - ResourceCache.unload(bufferLoaderCopy); + const bufferViewLoader = new GltfBufferViewLoader({ + resourceCache: ResourceCache, + gltf: gltfExternal, + bufferViewId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, }); - } - it("handles resolving buffer after destroy", function () { - return resolveAfterDestroy(false); - }); + expect(bufferViewLoader.typedArray).not.toBeDefined(); - it("handles rejecting buffer after destroy", function () { - return resolveAfterDestroy(true); + const loadPromise = bufferViewLoader.load(); + bufferViewLoader.destroy(); + + await expectAsync(loadPromise).toBeResolved(); + expect(bufferViewLoader.typedArray).not.toBeDefined(); + expect(bufferViewLoader.isDestroyed()).toBe(true); }); }); diff --git a/packages/engine/Specs/Scene/GltfDracoLoaderSpec.js b/packages/engine/Specs/Scene/GltfDracoLoaderSpec.js index 596e6947a16..4d99a8c995f 100644 --- a/packages/engine/Specs/Scene/GltfDracoLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfDracoLoaderSpec.js @@ -5,11 +5,10 @@ import { GltfDracoLoader, Resource, ResourceCache, - ResourceLoaderState, + RuntimeError, } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; import loaderProcess from "../../../../Specs/loaderProcess.js"; -import pollToPromise from "../../../../Specs/pollToPromise.js"; import waitForLoaderProcess from "../../../../Specs/waitForLoaderProcess.js"; describe( @@ -200,7 +199,7 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if buffer view fails to load", function () { + it("load throws if buffer view fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -214,20 +213,13 @@ describe( baseResource: gltfResource, }); - dracoLoader.load(); - - return dracoLoader.promise - .then(function (dracoLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load Draco\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(dracoLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load Draco\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if draco decoding fails", function () { + it("process throws if draco decoding fails", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(bufferArrayBuffer) ); @@ -245,20 +237,18 @@ describe( baseResource: gltfResource, }); - dracoLoader.load(); + await dracoLoader.load(); - return waitForLoaderProcess(dracoLoader, scene) - .then(function (dracoLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load Draco\nDraco decode failed" - ); - }); + await expectAsync( + waitForLoaderProcess(dracoLoader, scene) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load Draco\nDraco decode failed" + ); + expect(() => loaderProcess(dracoLoader, scene)).not.toThrowError(); }); - it("loads draco", function () { + it("loads draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(bufferArrayBuffer) ); @@ -281,30 +271,19 @@ describe( baseResource: gltfResource, }); - dracoLoader.load(); - - return pollToPromise(function () { - loaderProcess(dracoLoader, scene); - return ( - dracoLoader._state === ResourceLoaderState.READY || - dracoLoader._state === ResourceLoaderState.FAILED - ); - }) - .then(function () { - return dracoLoader.promise; - }) - .then(function (dracoLoader) { - loaderProcess(dracoLoader, scene); // Check that calling process after load doesn't break anything - expect(dracoLoader.decodedData.indices).toBe( - decodeDracoResults.indexArray - ); - expect(dracoLoader.decodedData.vertexAttributes).toBe( - decodeDracoResults.attributeData - ); - }); + await dracoLoader.load(); + await waitForLoaderProcess(dracoLoader, scene); + + expect(() => loaderProcess(dracoLoader, scene)).not.toThrowError(); + expect(dracoLoader.decodedData.indices).toBe( + decodeDracoResults.indexArray + ); + expect(dracoLoader.decodedData.vertexAttributes).toBe( + decodeDracoResults.attributeData + ); }); - it("destroys draco loader", function () { + it("destroys draco loader", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(bufferArrayBuffer) ); @@ -326,23 +305,20 @@ describe( baseResource: gltfResource, }); - dracoLoader.load(); + await dracoLoader.load(); + await waitForLoaderProcess(dracoLoader, scene); - return waitForLoaderProcess(dracoLoader, scene).then(function ( - dracoLoader - ) { - expect(dracoLoader.decodedData).toBeDefined(); - expect(dracoLoader.isDestroyed()).toBe(false); + expect(dracoLoader.decodedData).toBeDefined(); + expect(dracoLoader.isDestroyed()).toBe(false); - dracoLoader.destroy(); + dracoLoader.destroy(); - expect(dracoLoader.decodedData).not.toBeDefined(); - expect(dracoLoader.isDestroyed()).toBe(true); - expect(unloadBufferView).toHaveBeenCalled(); - }); + expect(dracoLoader.decodedData).not.toBeDefined(); + expect(dracoLoader.isDestroyed()).toBe(true); + expect(unloadBufferView).toHaveBeenCalled(); }); - function resolveBufferViewAfterDestroy(reject) { + async function resolveBufferViewAfterDestroy(reject) { spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { if (reject) { return Promise.reject(new Error()); @@ -355,15 +331,6 @@ describe( Promise.resolve(decodeDracoResults) ); - // Load a copy of the buffer view into the cache so that the buffer view - // promise resolves even if the draco loader is destroyed - const bufferViewLoaderCopy = ResourceCache.loadBufferView({ - gltf: gltfDraco, - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - const dracoLoader = new GltfDracoLoader({ resourceCache: ResourceCache, gltf: gltfDraco, @@ -376,12 +343,11 @@ describe( const promise = dracoLoader.load(); dracoLoader.destroy(); - return promise.finally(function () { - expect(dracoLoader.decodedData).not.toBeDefined(); - expect(dracoLoader.isDestroyed()).toBe(true); - ResourceCache.unload(bufferViewLoaderCopy); - }); + await expectAsync(promise).toBeResolved(); + + expect(dracoLoader.decodedData).not.toBeDefined(); + expect(dracoLoader.isDestroyed()).toBe(true); } it("handles resolving buffer view after destroy", function () { @@ -392,7 +358,7 @@ describe( return resolveBufferViewAfterDestroy(true); }); - function resolveDracoAfterDestroy(rejectPromise) { + async function resolveDracoAfterDestroy(rejectPromise) { const dracoLoader = new GltfDracoLoader({ resourceCache: ResourceCache, gltf: gltfDraco, @@ -404,7 +370,6 @@ describe( spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { // After we resolve, process again, then destroy setTimeout(function () { - loaderProcess(dracoLoader, scene); dracoLoader.destroy(); }, 1); return Promise.resolve(bufferArrayBuffer); @@ -425,14 +390,12 @@ describe( expect(dracoLoader.decodedData).not.toBeDefined(); - dracoLoader.load(); - loaderProcess(dracoLoader, scene); - return dracoLoader.promise.finally(function () { - expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts + await dracoLoader.load(); + await waitForLoaderProcess(dracoLoader, scene); // Destroy happens in mock above + expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts - expect(dracoLoader.decodedData).not.toBeDefined(); - expect(dracoLoader.isDestroyed()).toBe(true); - }); + expect(dracoLoader.decodedData).not.toBeDefined(); + expect(dracoLoader.isDestroyed()).toBe(true); } it("handles resolving draco after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfImageLoaderSpec.js b/packages/engine/Specs/Scene/GltfImageLoaderSpec.js index d36ac465cb4..ef1310a09c1 100644 --- a/packages/engine/Specs/Scene/GltfImageLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfImageLoaderSpec.js @@ -7,10 +7,10 @@ import { FeatureDetection, Resource, ResourceCache, + RuntimeError, } from "../../index.js"; import createContext from "../../../../Specs/createContext.js"; import dataUriToBuffer from "../../../../Specs/dataUriToBuffer.js"; -import pollToPromise from "../../../../Specs/pollToPromise.js"; describe( "Scene/GltfImageLoader", @@ -170,7 +170,7 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if buffer view fails to load", function () { + it("load throws if buffer view fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -184,20 +184,13 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); - - return imageLoader.promise - .then(function (imageLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load embedded image\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(imageLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load embedded image\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if image format is not recognized", function () { + it("load throws if image format is not recognized", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(gifBuffer) ); @@ -210,20 +203,13 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); - - return imageLoader.promise - .then(function (imageLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load embedded image\nImage format is not recognized" - ); - }); + await expectAsync(imageLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load embedded image\nImage format is not recognized" + ); }); - it("rejects promise if uri fails to load", function () { + it("load throws if uri fails to load", async function () { spyOn(Resource.prototype, "fetchImage").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -237,20 +223,13 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); - - return imageLoader.promise - .then(function (imageLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load image: image.png\n404 Not Found" - ); - }); + await expectAsync(imageLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load image: image.png\n404 Not Found" + ); }); - function loadsFromBufferView(imageBuffer) { + async function loadsFromBufferView(imageBuffer) { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(imageBuffer) ); @@ -263,12 +242,10 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image.width).toBe(1); - expect(imageLoader.image.height).toBe(1); - }); + expect(imageLoader.image.width).toBe(1); + expect(imageLoader.image.height).toBe(1); } it("loads PNG from buffer view", function () { @@ -279,19 +256,17 @@ describe( return loadsFromBufferView(jpgBuffer); }); - it("loads WebP from buffer view", function () { - return pollToPromise(function () { - FeatureDetection.supportsWebP.initialize(); - return FeatureDetection.supportsWebP.initialized; - }).then(function () { - if (!FeatureDetection.supportsWebP()) { - return; - } - return loadsFromBufferView(webpBuffer); - }); + it("loads WebP from buffer view", async function () { + await FeatureDetection.supportsWebP.initialize(); + + if (!FeatureDetection.supportsWebP()) { + return; + } + + return loadsFromBufferView(webpBuffer); }); - it("loads KTX2/Basis from buffer view", function () { + it("loads KTX2/Basis from buffer view", async function () { if (!context.supportsBasis) { return; } @@ -308,17 +283,15 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); - expect(imageLoader.image.width).toBe(4); - expect(imageLoader.image.height).toBe(4); - expect(imageLoader.mipLevels).toBeUndefined(); - }); + expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels).toBeUndefined(); }); - it("loads KTX2/Basis with mipmap from buffer view", function () { + it("loads KTX2/Basis with mipmap from buffer view", async function () { if (!context.supportsBasis) { return; } @@ -335,17 +308,15 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); - expect(imageLoader.image.width).toBe(4); - expect(imageLoader.image.height).toBe(4); - expect(imageLoader.mipLevels.length).toBe(2); - }); + expect(imageLoader.image).toBeInstanceOf(CompressedTextureBuffer); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels.length).toBe(2); }); - it("loads from uri", function () { + it("loads from uri", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); @@ -358,15 +329,13 @@ describe( baseResource: gltfResource, }); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image.width).toBe(1); - expect(imageLoader.image.height).toBe(1); - }); + expect(imageLoader.image.width).toBe(1); + expect(imageLoader.image.height).toBe(1); }); - it("loads KTX2/Basis from uri ", function () { + it("loads KTX2/Basis from uri ", async function () { if (!context.supportsBasis) { return; } @@ -386,14 +355,12 @@ describe( baseResource: baseResource, }); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); - expect(imageLoader.image.width).toBe(4); - expect(imageLoader.image.height).toBe(4); - expect(imageLoader.mipLevels).toBeUndefined(); - }); + expect(imageLoader.image).toBeInstanceOf(CompressedTextureBuffer); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels).toBeUndefined(); }); it("match the ktx2 url with the ktx2Regex", function () { @@ -408,7 +375,7 @@ describe( expect(ktx2Regex.test(uri)).toBe(true); }); - it("destroys image loader", function () { + it("destroys image loader", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(pngBuffer) ); @@ -427,38 +394,29 @@ describe( }); expect(imageLoader.image).not.toBeDefined(); - imageLoader.load(); + await imageLoader.load(); - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image).toBeDefined(); - expect(imageLoader.isDestroyed()).toBe(false); + expect(imageLoader.image).toBeDefined(); + expect(imageLoader.isDestroyed()).toBe(false); - imageLoader.destroy(); + imageLoader.destroy(); - expect(imageLoader.image).not.toBeDefined(); - expect(imageLoader.isDestroyed()).toBe(true); - expect(unloadBufferView).toHaveBeenCalled(); - }); + expect(imageLoader.image).not.toBeDefined(); + expect(imageLoader.isDestroyed()).toBe(true); + expect(unloadBufferView).toHaveBeenCalled(); }); - function resolveBufferViewAfterDestroy(rejectPromise) { - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(pngBuffer); - } - }); - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(promise); - - // Load a copy of the buffer view into the cache so that the buffer view - // promise resolves even if the image loader is destroyed - const bufferViewLoaderCopy = ResourceCache.loadBufferView({ - gltf: getGltf(pngBuffer), - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); + async function resolveBufferViewAfterDestroy(rejectPromise) { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake( + () => + new Promise(function (resolve, reject) { + if (rejectPromise) { + reject(new Error()); + } else { + resolve(pngBuffer); + } + }) + ); const imageLoader = new GltfImageLoader({ resourceCache: ResourceCache, @@ -470,14 +428,13 @@ describe( expect(imageLoader.image).not.toBeDefined(); - imageLoader.load(); + const loadPromise = imageLoader.load(); imageLoader.destroy(); - return imageLoader.promise.finally(function () { - expect(imageLoader.image).not.toBeDefined(); - expect(imageLoader.isDestroyed()).toBe(true); - ResourceCache.unload(bufferViewLoaderCopy); - }); + await expectAsync(loadPromise).toBeResolved(); + + expect(imageLoader.image).not.toBeDefined(); + expect(imageLoader.isDestroyed()).toBe(true); } it("handles resolving buffer view after destroy", function () { @@ -488,36 +445,22 @@ describe( return resolveBufferViewAfterDestroy(true); }); - function resolveImageFromTypedArrayAfterDestroy(rejectPromise) { + async function resolveImageFromTypedArrayAfterDestroy(rejectPromise) { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(pngBuffer) ); - let promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(image); - } - }); - if (rejectPromise) { - promise = promise.catch(function (e) { - // swallow that error we just threw - }); - } - spyOn(GltfImageLoader, "_loadImageFromTypedArray").and.returnValue( - promise + spyOn(GltfImageLoader, "_loadImageFromTypedArray").and.callFake( + () => + new Promise(function (resolve, reject) { + if (rejectPromise) { + reject(new Error()); + } else { + resolve(image); + } + }) ); - // Load a copy of the buffer view into the cache so that the buffer view - // promise resolves even if the image loader is destroyed - const bufferViewLoaderCopy = ResourceCache.loadBufferView({ - gltf: getGltf(pngBuffer), - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - const imageLoader = new GltfImageLoader({ resourceCache: ResourceCache, gltf: getGltf(pngBuffer), @@ -528,14 +471,12 @@ describe( expect(imageLoader.image).not.toBeDefined(); - imageLoader.load(); + const loadPromise = imageLoader.load(); imageLoader.destroy(); - return promise.then(function () { - expect(imageLoader.image).not.toBeDefined(); - expect(imageLoader.isDestroyed()).toBe(true); - ResourceCache.unload(bufferViewLoaderCopy); - }); + await expectAsync(loadPromise).toBeResolved(); + expect(imageLoader.image).not.toBeDefined(); + expect(imageLoader.isDestroyed()).toBe(true); } it("handles resolving image from typed array after destroy", function () { @@ -546,20 +487,17 @@ describe( return resolveImageFromTypedArrayAfterDestroy(true); }); - function resolveUriAfterDestroy(rejectPromise) { - let promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(image); - } - }); - if (rejectPromise) { - promise = promise.catch(function (e) { - // swallow that error we just threw - }); - } - spyOn(Resource.prototype, "fetchImage").and.returnValue(promise); + async function resolveUriAfterDestroy(rejectPromise) { + spyOn(Resource.prototype, "fetchImage").and.callFake( + () => + new Promise(function (resolve, reject) { + if (rejectPromise) { + reject(new Error()); + } else { + resolve(image); + } + }) + ); const imageLoader = new GltfImageLoader({ resourceCache: ResourceCache, @@ -571,12 +509,13 @@ describe( expect(imageLoader.image).not.toBeDefined(); - imageLoader.load(); + const loadPromise = imageLoader.load(); imageLoader.destroy(); - return promise.then(function () { - expect(imageLoader.image).not.toBeDefined(); - expect(imageLoader.isDestroyed()).toBe(true); - }); + + await expectAsync(loadPromise).toBeResolved(); + + expect(imageLoader.image).not.toBeDefined(); + expect(imageLoader.isDestroyed()).toBe(true); } it("handles resolving uri after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfIndexBufferLoaderSpec.js b/packages/engine/Specs/Scene/GltfIndexBufferLoaderSpec.js index ea8e5fc5f2f..ecd36f1209d 100644 --- a/packages/engine/Specs/Scene/GltfIndexBufferLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfIndexBufferLoaderSpec.js @@ -9,6 +9,7 @@ import { JobScheduler, Resource, ResourceCache, + RuntimeError, } from "../../index.js"; import concatTypedArrays from "../../../../Specs/concatTypedArrays.js"; import createScene from "../../../../Specs/createScene.js"; @@ -348,11 +349,10 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if buffer view fails to load", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { - const error = new Error("404 Not Found"); - return Promise.reject(error); - }); + it("load throws if buffer view fails to load", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + Promise.reject(new Error("404 Not Found")) + ); const indexBufferLoader = new GltfIndexBufferLoader({ resourceCache: ResourceCache, @@ -363,20 +363,13 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); - - return indexBufferLoader.promise - .then(function (indexBufferLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load index buffer\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(indexBufferLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load index buffer\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if draco fails to load", function () { + it("process throws if draco fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(dracoArrayBuffer) ); @@ -396,20 +389,16 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); - - return waitForLoaderProcess(indexBufferLoader, scene) - .then(function (indexBufferLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load index buffer\nFailed to load Draco\nDraco decode failed" - ); - }); + await indexBufferLoader.load(); + await expectAsync( + waitForLoaderProcess(indexBufferLoader, scene) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load index buffer\nFailed to load Draco\nDraco decode failed" + ); }); - it("loads from accessor into buffer", function () { + it("loads from accessor into buffer", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -438,20 +427,20 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - loaderProcess(indexBufferLoader, scene); // Check that calling process after load doesn't break anything - expect(indexBufferLoader.buffer.sizeInBytes).toBe( - indicesUint16.byteLength - ); - expect(indexBufferLoader.typedArray).toBeUndefined(); - }); + expect(() => loaderProcess(indexBufferLoader, scene)).not.toThrow(); + expect(indexBufferLoader.buffer.sizeInBytes).toBe( + indicesUint16.byteLength + ); + expect(indexBufferLoader.typedArray).toBeUndefined(); + expect(ResourceCache.statistics.geometryByteLength).toBe( + indexBufferLoader.buffer.sizeInBytes + ); }); - it("loads from accessor as typed array", function () { + it("loads from accessor as typed array", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -467,20 +456,20 @@ describe( loadTypedArray: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.typedArray.byteLength).toBe( - indicesUint16.byteLength - ); - expect(indexBufferLoader.buffer).toBeUndefined(); - expect(Buffer.createIndexBuffer.calls.count()).toBe(0); - }); + await waitForLoaderProcess(indexBufferLoader, scene); + expect(indexBufferLoader.typedArray.byteLength).toBe( + indicesUint16.byteLength + ); + expect(indexBufferLoader.buffer).toBeUndefined(); + expect(Buffer.createIndexBuffer.calls.count()).toBe(0); + expect(ResourceCache.statistics.geometryByteLength).toBe( + indexBufferLoader.typedArray.byteLength + ); }); - it("loads from accessor as buffer and typed array", function () { + it("loads from accessor as buffer and typed array", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -495,21 +484,21 @@ describe( loadTypedArray: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer.sizeInBytes).toBe( - indicesUint16.byteLength - ); - expect(indexBufferLoader.typedArray.byteLength).toBe( - indicesUint16.byteLength - ); - }); + expect(indexBufferLoader.buffer.sizeInBytes).toBe( + indicesUint16.byteLength + ); + expect(indexBufferLoader.typedArray.byteLength).toBe( + indicesUint16.byteLength + ); + expect(ResourceCache.statistics.geometryByteLength).toBe( + 2 * indexBufferLoader.typedArray.byteLength + ); }); - it("creates index buffer synchronously", function () { + it("creates index buffer synchronously", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -524,18 +513,15 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer.sizeInBytes).toBe( - indicesUint16.byteLength - ); - }); + expect(indexBufferLoader.buffer.sizeInBytes).toBe( + indicesUint16.byteLength + ); }); - function loadIndices(accessorId, expectedByteLength) { + async function loadIndices(accessorId, expectedByteLength) { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -549,13 +535,10 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer.sizeInBytes).toBe(expectedByteLength); - }); + expect(indexBufferLoader.buffer.sizeInBytes).toBe(expectedByteLength); } it("loads uint32 indices", function () { @@ -574,7 +557,7 @@ describe( return loadIndices(4, indicesUint8.byteLength); }); - it("loads from draco", function () { + it("loads from draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -599,19 +582,19 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - loaderProcess(indexBufferLoader, scene); // Check that calling process after load doesn't break anything - expect(indexBufferLoader.buffer.sizeInBytes).toBe( - decodedIndices.byteLength - ); - }); + expect(() => loaderProcess(indexBufferLoader, scene)).not.toThrow(); + expect(indexBufferLoader.buffer.sizeInBytes).toBe( + decodedIndices.byteLength + ); + expect(ResourceCache.statistics.geometryByteLength).toBe( + indexBufferLoader.buffer.sizeInBytes + ); }); - it("uses the decoded data's type instead of the accessor component type", function () { + it("uses the decoded data's type instead of the accessor component type", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -633,17 +616,14 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.indexDatatype).toBe(5123); - expect(indexBufferLoader.buffer.indexDatatype).toBe(5123); - }); + expect(indexBufferLoader.indexDatatype).toBe(5123); + expect(indexBufferLoader.buffer.indexDatatype).toBe(5123); }); - it("destroys index buffer loaded from buffer view", function () { + it("destroys index buffer loaded from buffer view", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -667,24 +647,21 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer).toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(false); + expect(indexBufferLoader.buffer).toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(false); - indexBufferLoader.destroy(); + indexBufferLoader.destroy(); - expect(indexBufferLoader.buffer).not.toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(true); - expect(unloadBufferView).toHaveBeenCalled(); - expect(destroyIndexBuffer).toHaveBeenCalled(); - }); + expect(indexBufferLoader.buffer).not.toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(true); + expect(unloadBufferView).toHaveBeenCalled(); + expect(destroyIndexBuffer).toHaveBeenCalled(); }); - it("destroys index buffer loaded from draco", function () { + it("destroys index buffer loaded from draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -713,24 +690,21 @@ describe( loadBuffer: true, }); - indexBufferLoader.load(); + await indexBufferLoader.load(); + await waitForLoaderProcess(indexBufferLoader, scene); - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer).toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(false); + expect(indexBufferLoader.buffer).toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(false); - indexBufferLoader.destroy(); + indexBufferLoader.destroy(); - expect(indexBufferLoader.buffer).not.toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(true); - expect(unloadDraco).toHaveBeenCalled(); - expect(destroyIndexBuffer).toHaveBeenCalled(); - }); + expect(indexBufferLoader.buffer).not.toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(true); + expect(unloadDraco).toHaveBeenCalled(); + expect(destroyIndexBuffer).toHaveBeenCalled(); }); - function resolveBufferViewAfterDestroy(rejectPromise) { + async function resolveBufferViewAfterDestroy(rejectPromise) { const indexBufferLoader = new GltfIndexBufferLoader({ resourceCache: ResourceCache, gltf: gltfUncompressed, @@ -740,24 +714,21 @@ describe( loadBuffer: true, }); - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(arrayBuffer); - } - }); - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(promise); + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + rejectPromise + ? Promise.reject(new Error()) + : Promise.resolve(arrayBuffer) + ); expect(indexBufferLoader.buffer).not.toBeDefined(); - indexBufferLoader.load(); + const promise = indexBufferLoader.load(); indexBufferLoader.destroy(); - return indexBufferLoader.promise.then(function () { - expect(indexBufferLoader.buffer).not.toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(true); - }); + await expectAsync(promise).toBeResolved(); + + expect(indexBufferLoader.buffer).not.toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(true); } it("handles resolving buffer view after destroy", function () { @@ -768,7 +739,7 @@ describe( return resolveBufferViewAfterDestroy(true); }); - function resolveDracoAfterDestroy(rejectPromise) { + async function resolveDracoAfterDestroy(rejectPromise) { const indexBufferLoader = new GltfIndexBufferLoader({ resourceCache: ResourceCache, gltf: gltfDraco, @@ -782,7 +753,6 @@ describe( spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { // After we resolve, process again, then destroy setTimeout(function () { - loaderProcess(indexBufferLoader, scene); indexBufferLoader.destroy(); }, 1); return Promise.resolve(arrayBuffer); @@ -803,14 +773,14 @@ describe( expect(indexBufferLoader.buffer).not.toBeDefined(); - indexBufferLoader.load(); - loaderProcess(indexBufferLoader, scene); - return indexBufferLoader.promise.then(function () { - expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts + await indexBufferLoader.load(); // Destroy is called in mock function above + await expectAsync( + waitForLoaderProcess(indexBufferLoader, scene) + ).toBeResolved(); + expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts - expect(indexBufferLoader.buffer).not.toBeDefined(); - expect(indexBufferLoader.isDestroyed()).toBe(true); - }); + expect(indexBufferLoader.buffer).not.toBeDefined(); + expect(indexBufferLoader.isDestroyed()).toBe(true); } it("handles resolving draco after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js b/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js index c069814b0cd..96561ba3c9a 100644 --- a/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js @@ -4,6 +4,7 @@ import { GltfJsonLoader, Resource, ResourceCache, + RuntimeError, } from "../../index.js"; import generateJsonBuffer from "../../../../Specs/generateJsonBuffer.js"; @@ -579,7 +580,7 @@ describe("Scene/GltfJsonLoader", function () { }).toThrowDeveloperError(); }); - it("rejects promise if resource fails to load", function () { + it("load throws if resource fails to load", async function () { spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -591,20 +592,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); - - return gltfJsonLoader.promise - .then(function (gltfJsonLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF: https://example.com/model.glb\n404 Not Found" - ); - }); + await expectAsync(gltfJsonLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF: https://example.com/model.glb\n404 Not Found" + ); }); - it("rejects promise if glTF fails to process", function () { + it("load throws if glTF fails to process", async function () { const arrayBuffer = generateJsonBuffer(gltf1).buffer; spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( @@ -622,20 +616,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); - - return gltfJsonLoader.promise - .then(function (gltfJsonLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF: https://example.com/model.glb\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(gltfJsonLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF: https://example.com/model.glb\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if glTF fails to process from typed array", function () { + it("load throws if glTF fails to process from typed array", async function () { const typedArray = createGlb1(gltf1); spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { @@ -650,20 +637,13 @@ describe("Scene/GltfJsonLoader", function () { typedArray: typedArray, }); - gltfJsonLoader.load(); - - return gltfJsonLoader.promise - .then(function (gltfJsonLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF: https://example.com/model.glb\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(gltfJsonLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF: https://example.com/model.glb\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("loads glTF 1.0", function () { + it("loads glTF 1.0", async function () { const arrayBuffer = generateJsonBuffer(gltf1).buffer; spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( @@ -680,15 +660,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2Updated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2Updated); }); - it("loads glTF 1.0 with KHR_materials_common", function () { + it("loads glTF 1.0 with KHR_materials_common", async function () { const arrayBuffer = generateJsonBuffer(gltf1MaterialsCommon).buffer; spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( @@ -705,15 +683,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2Updated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2Updated); }); - it("loads glTF 1.0 binary", function () { + it("loads glTF 1.0 binary", async function () { const gltf1Binary = clone(gltf1, true); gltf1Binary.buffers = { binary_glTF: { @@ -741,15 +717,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf1BinaryUpdated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf1BinaryUpdated); }); - it("loads glTF 1.0 with data uri", function () { + it("loads glTF 1.0 with data uri", async function () { const gltf1DataUri = clone(gltf1, true); gltf1DataUri.buffers.buffer = { uri: "data:application/octet-stream;base64,AAAAAAAAAAAAAAAA", @@ -770,15 +744,12 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); - - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf1DataUriUpdated); - }); + await gltfJsonLoader.load(); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf1DataUriUpdated); }); - it("loads glTF 2.0", function () { + it("loads glTF 2.0", async function () { const arrayBuffer = generateJsonBuffer(gltf2).buffer; spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( @@ -795,15 +766,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2Updated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2Updated); }); - it("loads glTF 2.0 with KHR_techniques_webgl", function () { + it("loads glTF 2.0 with KHR_techniques_webgl", async function () { const arrayBuffer = generateJsonBuffer(gltf2TechniquesWebgl).buffer; spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( @@ -820,15 +789,12 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); - - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2Updated); - }); + await gltfJsonLoader.load(); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2Updated); }); - it("loads glTF 2.0 binary", function () { + it("loads glTF 2.0 binary", async function () { const gltf2Binary = clone(gltf2, true); delete gltf2Binary.buffers[0].uri; @@ -847,15 +813,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2BinaryUpdated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2BinaryUpdated); }); - it("loads glTF 2.0 with data uri", function () { + it("loads glTF 2.0 with data uri", async function () { const gltf2DataUri = clone(gltf2, true); gltf2DataUri.buffers[0].uri = "data:application/octet-stream;base64,AAAAAAAAAAAAAAAA"; @@ -875,15 +839,13 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2DataUriUpdated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2DataUriUpdated); }); - it("loads typed array", function () { + it("loads typed array", async function () { const gltf2Binary = clone(gltf2, true); delete gltf2Binary.buffers[0].uri; @@ -899,15 +861,13 @@ describe("Scene/GltfJsonLoader", function () { typedArray: typedArray, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2BinaryUpdated); - }); + const gltf = gltfJsonLoader.gltf; + expect(gltf).toEqual(gltf2BinaryUpdated); }); - it("loads JSON directly", function () { + it("loads JSON directly", async function () { const gltf = clone(gltf2, true); spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( @@ -921,15 +881,13 @@ describe("Scene/GltfJsonLoader", function () { gltfJson: gltf, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - const gltf = gltfJsonLoader.gltf; - expect(gltf).toEqual(gltf2Updated); - }); + const loadedGltf = gltfJsonLoader.gltf; + expect(loadedGltf).toEqual(gltf2Updated); }); - it("destroys", function () { + it("destroys", async function () { const gltf2Binary = clone(gltf2, true); delete gltf2Binary.buffers[0].uri; @@ -950,32 +908,23 @@ describe("Scene/GltfJsonLoader", function () { baseResource: gltfResource, }); - gltfJsonLoader.load(); + await gltfJsonLoader.load(); - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - expect(gltfJsonLoader.gltf).toBeDefined(); - expect(gltfJsonLoader.isDestroyed()).toBe(false); + expect(gltfJsonLoader.gltf).toBeDefined(); + expect(gltfJsonLoader.isDestroyed()).toBe(false); - gltfJsonLoader.destroy(); + gltfJsonLoader.destroy(); - expect(gltfJsonLoader.gltf).not.toBeDefined(); - expect(gltfJsonLoader.isDestroyed()).toBe(true); - expect(unloadBuffer).toHaveBeenCalled(); - }); + expect(gltfJsonLoader.gltf).not.toBeDefined(); + expect(gltfJsonLoader.isDestroyed()).toBe(true); + expect(unloadBuffer).toHaveBeenCalled(); }); - function resolvesGltfAfterDestroy(rejectPromise) { + async function resolvesGltfAfterDestroy(rejectPromise) { const arrayBuffer = generateJsonBuffer(gltf2).buffer; - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - return; - } - - resolve(arrayBuffer); - }); - - spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue(promise); + spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.callFake(() => + rejectPromise ? Promise.reject(new Error()) : Promise.resolve(arrayBuffer) + ); const gltfJsonLoader = new GltfJsonLoader({ resourceCache: ResourceCache, @@ -985,12 +934,11 @@ describe("Scene/GltfJsonLoader", function () { expect(gltfJsonLoader.gltf).not.toBeDefined(); - gltfJsonLoader.load(); + const promise = gltfJsonLoader.load(); gltfJsonLoader.destroy(); - return gltfJsonLoader.promise.then(function () { - expect(gltfJsonLoader.gltf).not.toBeDefined(); - expect(gltfJsonLoader.isDestroyed()).toBe(true); - }); + await expectAsync(promise).toBeResolved(); + expect(gltfJsonLoader.gltf).not.toBeDefined(); + expect(gltfJsonLoader.isDestroyed()).toBe(true); } it("handles resolving glTF after destroy", function () { @@ -1001,7 +949,7 @@ describe("Scene/GltfJsonLoader", function () { return resolvesGltfAfterDestroy(true); }); - function resolvesProcessedGltfAfterDestroy(rejectPromise) { + async function resolvesProcessedGltfAfterDestroy(rejectPromise) { spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( Promise.resolve(generateJsonBuffer(gltf2).buffer) ); @@ -1027,10 +975,9 @@ describe("Scene/GltfJsonLoader", function () { const promise = gltfJsonLoader.load(); gltfJsonLoader.destroy(); - return promise.finally(function () { - expect(gltfJsonLoader.gltf).not.toBeDefined(); - expect(gltfJsonLoader.isDestroyed()).toBe(true); - }); + await expectAsync(promise).toBeResolved(); + expect(gltfJsonLoader.gltf).not.toBeDefined(); + expect(gltfJsonLoader.isDestroyed()).toBe(true); } it("handles resolving processed glTF after destroy", function () { @@ -1041,7 +988,7 @@ describe("Scene/GltfJsonLoader", function () { return resolvesProcessedGltfAfterDestroy(true); }); - function resolvesTypedArrayAfterDestroy(rejectPromise) { + async function resolvesTypedArrayAfterDestroy(rejectPromise) { const typedArray = generateJsonBuffer(gltf1); const gltfJsonLoader = new GltfJsonLoader({ @@ -1064,12 +1011,11 @@ describe("Scene/GltfJsonLoader", function () { }); expect(gltfJsonLoader.gltf).not.toBeDefined(); - gltfJsonLoader.load(); + const promise = gltfJsonLoader.load(); gltfJsonLoader.destroy(); - return gltfJsonLoader.promise.then(function () { - expect(gltfJsonLoader.gltf).not.toBeDefined(); - expect(gltfJsonLoader.isDestroyed()).toBe(true); - }); + await expectAsync(promise).toBeResolved(); + expect(gltfJsonLoader.gltf).not.toBeDefined(); + expect(gltfJsonLoader.isDestroyed()).toBe(true); } it("handles resolving typed array after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfLoaderSpec.js b/packages/engine/Specs/Scene/GltfLoaderSpec.js index 4ab49554fd1..3a4f36ec7f3 100644 --- a/packages/engine/Specs/Scene/GltfLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfLoaderSpec.js @@ -154,19 +154,68 @@ describe( }).toThrowDeveloperError(); }); - it("throws if an unsupported extension is required", function () { + it("load throws if glTF JSON fails to load", async function () { + const error = new Error("404 Not Found"); + spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( + Promise.reject(error) + ); + + const gltfResource = new Resource({ + url: "https://example.com/model.glb", + }); + + const gltfLoader = new GltfLoader({ + gltfResource: gltfResource, + releaseGltfJson: true, + }); + gltfLoaders.push(gltfLoader); + + await expectAsync(gltfLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nFailed to load glTF: https://example.com/model.glb\n404 Not Found" + ); + }); + + // This cannot actually ever happen due to gltfPipeline's updateVersion + xit("load throws if the gltf specifies an unknown version", async function () { + spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( + Promise.resolve( + generateJsonBuffer({ + asset: { + version: "3.0", + }, + }).buffer + ) + ); + + const gltfResource = new Resource({ + url: "https://example.com/model.glb", + }); + + const gltfLoader = new GltfLoader({ + gltfResource: gltfResource, + releaseGltfJson: true, + }); + gltfLoaders.push(gltfLoader); + + await expectAsync(gltfLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nUnsupported glTF version: 0.1" + ); + }); + + it("load throws if an unsupported extension is required", async function () { function modifyGltf(gltf) { gltf.extensionsRequired = ["NOT_supported_extension"]; return gltf; } - return loadModifiedGltfAndTest(boxTextured, undefined, modifyGltf) - .then(function () { - fail(); - }) - .catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); + await expectAsync( + loadModifiedGltfAndTest(boxTextured, undefined, modifyGltf) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nUnsupported glTF Extension: NOT_supported_extension" + ); }); function getOptions(gltfPath, options) { @@ -180,51 +229,53 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); const targetScene = defaultValue(options.scene, scene); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, targetScene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, targetScene); + return gltfLoader; } - function loadGltfFromJson(gltfPath, options) { - return Resource.fetchJson({ + async function loadGltfFromJson(gltfPath, options) { + const gltf = await Resource.fetchJson({ url: gltfPath, - }).then(function (gltf) { - const loaderOptions = combine(options, { - gltf: gltf, - gltfResource: new Resource({ - url: gltfPath, - }), - incrementallyLoadTextures: false, - }); - const gltfLoader = new GltfLoader(loaderOptions); - gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); }); + const loaderOptions = combine(options, { + gltf: gltf, + gltfResource: new Resource({ + url: gltfPath, + }), + incrementallyLoadTextures: false, + }); + const gltfLoader = new GltfLoader(loaderOptions); + gltfLoaders.push(gltfLoader); + + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } - function loadModifiedGltfAndTest(gltfPath, options, modifyFunction) { - return Resource.fetchJson({ + async function loadModifiedGltfAndTest(gltfPath, options, modifyFunction) { + let gltf = await Resource.fetchJson({ url: gltfPath, - }).then(function (gltf) { - gltf = modifyFunction(gltf); + }); - spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( - Promise.resolve(generateJsonBuffer(gltf).buffer) - ); + gltf = modifyFunction(gltf); - const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); - gltfLoaders.push(gltfLoader); - gltfLoader.load(); + spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( + Promise.resolve(generateJsonBuffer(gltf).buffer) + ); - return waitForLoaderProcess(gltfLoader, scene); - }); + const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); + gltfLoaders.push(gltfLoader); + + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + + return gltfLoader; } function getAttribute(attributes, semantic, setIndex) { @@ -252,13 +303,14 @@ describe( return undefined; } - it("preserves query string in url", function () { + it("preserves query string in url", async function () { const params = "?param1=1¶m2=2"; const url = boxTextured + params; - return loadGltf(url).then(function (gltfLoader) { - const loaderResource = gltfLoader._gltfResource; - expect(loaderResource.url).toEndWith(params); - }); + const gltfLoader = new GltfLoader(getOptions(url)); + gltfLoaders.push(gltfLoader); + await gltfLoader.load(); + const loaderResource = gltfLoader._gltfResource; + expect(loaderResource.url).toEndWith(params); }); it("releases GLB typed array when finished loading", function () { @@ -3207,43 +3259,39 @@ describe( }); }); - it("resolves before textures are loaded when incrementallyLoadTextures is true", function () { + it("becomes ready before textures are loaded when incrementallyLoadTextures is true", async function () { const textureCreate = spyOn(Texture, "create").and.callThrough(); const options = { incrementallyLoadTextures: true, }; - const promise = loadGltf(boxTextured, options); - spyOn(Resource.prototype, "fetchImage").and.returnValue( - promise.then(function () { - const image = new Image(); - image.src = - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="; - - return image; - }) - ); - return promise.then(function (gltfLoader) { - expect(textureCreate).not.toHaveBeenCalled(); - - // Continue processing to load in textures - return pollToPromise(function () { - loaderProcess(gltfLoader, scene); - return gltfLoader._textureLoaders.every(function (loader) { - return ( - loader._state === ResourceLoaderState.READY || - loader._state === ResourceLoaderState.FAILED - ); - }); - }) - .then(function () { - return gltfLoader.texturesLoadedPromise; - }) - .then(function () { - expect(textureCreate).toHaveBeenCalled(); - }); + let resolver; + const promise = new Promise((resolve) => { + resolver = resolve; }); + spyOn(Resource.prototype, "fetchImage").and.returnValue(promise); + + const gltfLoader = await loadGltf(boxTextured, options); + expect(textureCreate).not.toHaveBeenCalled(); + + const image = new Image(); + image.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="; + resolver(image); + + // Continue processing to load in textures + await pollToPromise(function () { + loaderProcess(gltfLoader, scene); + return gltfLoader._textureLoaders.every(function (loader) { + return ( + loader._state === ResourceLoaderState.READY || + loader._state === ResourceLoaderState.FAILED + ); + }); + }); + + expect(textureCreate).toHaveBeenCalled(); }); it("sets default transform", function () { @@ -3288,35 +3336,8 @@ describe( }); }); - it("rejects promise if glTF JSON fails to load", function () { - const error = new Error("404 Not Found"); - spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( - Promise.reject(error) - ); - - const gltfResource = new Resource({ - url: "https://example.com/model.glb", - }); - - const gltfLoader = new GltfLoader({ - gltfResource: gltfResource, - releaseGltfJson: true, - }); - - gltfLoader.load(); - - return gltfLoader.promise - .then(function () { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF\nFailed to load glTF: https://example.com/model.glb\n404 Not Found" - ); - }); - }); - - it("rejects promises if resource fails to load", function () { + // TODO + xit("process throws if image resource fails to load", function () { spyOn(Resource.prototype, "fetchImage").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -3395,11 +3416,6 @@ describe( url: gltfUri, }); - const gltfJsonLoaderCopy = ResourceCache.loadGltfJson({ - gltfResource: gltfResource, - baseResource: gltfResource, - }); - const gltfLoader = new GltfLoader({ gltfResource: gltfResource, }); @@ -3412,8 +3428,6 @@ describe( return promise.then(function () { expect(gltfLoader.components).not.toBeDefined(); expect(gltfLoader.isDestroyed()).toBe(true); - - ResourceCache.unload(gltfJsonLoaderCopy); }); } @@ -4008,32 +4022,30 @@ describe( }); }); - it("throws when loading instanced model for classification", function () { + it("throws when loading instanced model for classification", async function () { const options = { loadForClassification: true, }; - return loadGltf(boxInstanced, options) - .then(function () { - fail(); - }) - .catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); + await expectAsync( + loadGltf(boxInstanced, options) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nModels with the EXT_mesh_gpu_instancing extension cannot be used for classification." + ); }); - it("throws when loading non-triangle mesh for classification", function () { + it("throws when loading non-triangle mesh for classification", async function () { const options = { loadForClassification: true, }; - return loadGltf(pointCloudWithPropertyAttributes, options) - .then(function () { - fail(); - }) - .catch(function (error) { - expect(error).toBeInstanceOf(RuntimeError); - }); + await expectAsync( + loadGltf(pointCloudWithPropertyAttributes, options) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nOnly triangle meshes can be used for classification." + ); }); }); diff --git a/packages/engine/Specs/Scene/GltfStructuralMetadataLoaderSpec.js b/packages/engine/Specs/Scene/GltfStructuralMetadataLoaderSpec.js index be4790ebe6f..6901bbdf165 100644 --- a/packages/engine/Specs/Scene/GltfStructuralMetadataLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfStructuralMetadataLoaderSpec.js @@ -6,6 +6,7 @@ import { MetadataSchemaLoader, Resource, ResourceCache, + RuntimeError, SupportedImageFormats, } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; @@ -250,7 +251,7 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if buffer view fails to load", function () { + it("load throws if buffer view fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -269,20 +270,13 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); - - return structuralMetadataLoader.promise - .then(function (structuralMetadataLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load structural metadata\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(structuralMetadataLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load structural metadata\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if texture fails to load", function () { + it("load throws if texture fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); @@ -301,20 +295,13 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); - - return structuralMetadataLoader.promise - .then(function (structuralMetadataLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load structural metadata\nFailed to load texture\nFailed to load image: map.png\n404 Not Found" - ); - }); + await expectAsync(structuralMetadataLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load structural metadata\nFailed to load texture\nFailed to load image: map.png\n404 Not Found" + ); }); - it("rejects promise if external schema fails to load", function () { + it("load throws if external schema fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); @@ -337,20 +324,13 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); - - return structuralMetadataLoader.promise - .then(function () { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load structural metadata\nFailed to load schema: https://example.com/schema.json\n404 Not Found" - ); - }); + await expectAsync(structuralMetadataLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load structural metadata\nFailed to load schema: https://example.com/schema.json\n404 Not Found" + ); }); - it("loads structural metadata", function () { + it("loads structural metadata", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); @@ -368,56 +348,56 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); - - return waitForLoaderProcess(structuralMetadataLoader, scene).then( - function (structuralMetadataLoader) { - loaderProcess(structuralMetadataLoader, scene); // Check that calling process after load doesn't break anything - - const structuralMetadata = - structuralMetadataLoader.structuralMetadata; - const buildingsTable = structuralMetadata.getPropertyTable(0); - expect(buildingsTable.id).toBe(0); - const treesTable = structuralMetadata.getPropertyTable(1); - expect(treesTable.id).toBe(1); - - const mapTexture = structuralMetadata.getPropertyTexture(0); - expect(mapTexture.id).toBe(0); - const orthoTexture = structuralMetadata.getPropertyTexture(1); - expect(orthoTexture.id).toBe(1); - - expect(buildingsTable.getProperty(0, "name")).toBe("House"); - expect(buildingsTable.getProperty(1, "name")).toBe("Hospital"); - expect(treesTable.getProperty(0, "species")).toEqual([ - "Sparrow", - "Squirrel", - ]); - expect(treesTable.getProperty(1, "species")).toEqual(["Crow"]); - - const colorProperty = mapTexture.getProperty("color"); - const intensityProperty = mapTexture.getProperty("intensity"); - const vegetationProperty = orthoTexture.getProperty("vegetation"); - - expect(colorProperty.textureReader.texture.width).toBe(1); - expect(colorProperty.textureReader.texture.height).toBe(1); - expect(colorProperty.textureReader.texture).toBe( - intensityProperty.textureReader.texture - ); - - expect(vegetationProperty.textureReader.texture.width).toBe(1); - expect(vegetationProperty.textureReader.texture.height).toBe(1); - expect(vegetationProperty.textureReader.texture).not.toBe( - colorProperty.textureReader.texture - ); - - expect( - Object.keys(structuralMetadata.schema.classes).sort() - ).toEqual(["building", "map", "ortho", "tree"]); - } + await structuralMetadataLoader.load(); + await waitForLoaderProcess(structuralMetadataLoader, scene); + expect(() => + loaderProcess(structuralMetadataLoader, scene) + ).not.toThrow(); + + const structuralMetadata = structuralMetadataLoader.structuralMetadata; + const buildingsTable = structuralMetadata.getPropertyTable(0); + expect(buildingsTable.id).toBe(0); + const treesTable = structuralMetadata.getPropertyTable(1); + expect(treesTable.id).toBe(1); + + const mapTexture = structuralMetadata.getPropertyTexture(0); + expect(mapTexture.id).toBe(0); + const orthoTexture = structuralMetadata.getPropertyTexture(1); + expect(orthoTexture.id).toBe(1); + + expect(buildingsTable.getProperty(0, "name")).toBe("House"); + expect(buildingsTable.getProperty(1, "name")).toBe("Hospital"); + expect(treesTable.getProperty(0, "species")).toEqual([ + "Sparrow", + "Squirrel", + ]); + expect(treesTable.getProperty(1, "species")).toEqual(["Crow"]); + + const colorProperty = mapTexture.getProperty("color"); + const intensityProperty = mapTexture.getProperty("intensity"); + const vegetationProperty = orthoTexture.getProperty("vegetation"); + + expect(colorProperty.textureReader.texture.width).toBe(1); + expect(colorProperty.textureReader.texture.height).toBe(1); + expect(colorProperty.textureReader.texture).toBe( + intensityProperty.textureReader.texture + ); + + expect(vegetationProperty.textureReader.texture.width).toBe(1); + expect(vegetationProperty.textureReader.texture.height).toBe(1); + expect(vegetationProperty.textureReader.texture).not.toBe( + colorProperty.textureReader.texture ); + + expect(Object.keys(structuralMetadata.schema.classes).sort()).toEqual([ + "building", + "map", + "ortho", + "tree", + ]); }); - it("loads structural metadata with external schema", function () { + it("loads structural metadata with external schema", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); @@ -439,20 +419,19 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); + await structuralMetadataLoader.load(); + await waitForLoaderProcess(structuralMetadataLoader, scene); - return waitForLoaderProcess(structuralMetadataLoader, scene).then( - function (structuralMetadataLoader) { - const structuralMetadata = - structuralMetadataLoader.structuralMetadata; - expect( - Object.keys(structuralMetadata.schema.classes).sort() - ).toEqual(["building", "map", "ortho", "tree"]); - } - ); + const structuralMetadata = structuralMetadataLoader.structuralMetadata; + expect(Object.keys(structuralMetadata.schema.classes).sort()).toEqual([ + "building", + "map", + "ortho", + "tree", + ]); }); - it("destroys structural metadata", function () { + it("destroys structural metadata", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); @@ -489,46 +468,34 @@ describe( frameState: mockFrameState, }); - structuralMetadataLoader.load(); + await structuralMetadataLoader.load(); - return waitForLoaderProcess(structuralMetadataLoader, scene).then( - function (structuralMetadataLoader) { - expect(structuralMetadataLoader.structuralMetadata).toBeDefined(); - expect(structuralMetadataLoader.isDestroyed()).toBe(false); + await waitForLoaderProcess(structuralMetadataLoader, scene); + expect(structuralMetadataLoader.structuralMetadata).toBeDefined(); + expect(structuralMetadataLoader.isDestroyed()).toBe(false); - structuralMetadataLoader.destroy(); + structuralMetadataLoader.destroy(); - expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); - expect(structuralMetadataLoader.isDestroyed()).toBe(true); + expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); + expect(structuralMetadataLoader.isDestroyed()).toBe(true); - expect(destroyBufferView.calls.count()).toBe(6); - expect(destroyTexture.calls.count()).toBe(2); - expect(destroySchema.calls.count()).toBe(1); - } - ); + expect(destroyBufferView.calls.count()).toBe(6); + expect(destroyTexture.calls.count()).toBe(2); + expect(destroySchema.calls.count()).toBe(1); }); - function resolveAfterDestroy(rejectPromise) { + async function resolveAfterDestroy(rejectPromise) { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(buffer) ); spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); - - let promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - const error = new Error("404 Not Found"); - reject(error); - return; - } - resolve(schemaJson); - }); - if (rejectPromise) { - // handle the error so Jasmine doesn't fail the test - promise = promise.catch(function () {}); - } - spyOn(Resource.prototype, "fetchJson").and.returnValue(promise); + spyOn(Resource.prototype, "fetchJson").and.callFake(() => + rejectPromise + ? Promise.reject(new Error("")) + : Promise.resolve(schemaJson) + ); const destroyBufferView = spyOn( GltfBufferViewLoader.prototype, @@ -543,60 +510,25 @@ describe( "destroy" ).and.callThrough(); - // Load a copy of structural metadata into the cache so that the resource - // promises resolve even if the structural metadata loader is destroyed - const structuralMetadataLoaderCopy = new GltfStructuralMetadataLoader({ - gltf: gltf, - extension: extension, + const structuralMetadataLoader = new GltfStructuralMetadataLoader({ + gltf: gltfSchemaUri, + extension: extensionSchemaUri, gltfResource: gltfResource, baseResource: gltfResource, supportedImageFormats: new SupportedImageFormats(), frameState: mockFrameState, }); - // Also load a copy of the schema into the cache - const schemaResource = gltfResource.getDerivedResource({ - url: "schema.json", - }); - const schemaCopy = ResourceCache.loadSchema({ - resource: schemaResource, - }); + expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); + const promise = structuralMetadataLoader.load(); + structuralMetadataLoader.destroy(); - if (rejectPromise) { - // handle the error so Jasmine doesn't fail the test - schemaCopy.promise.catch(function () {}); - } - - structuralMetadataLoaderCopy.load(); - - return waitForLoaderProcess(structuralMetadataLoaderCopy, scene).then( - function (structuralMetadataLoaderCopy) { - // Ignore structuralMetadataLoaderCopy destroying its buffer views - destroyBufferView.calls.reset(); - - const structuralMetadataLoader = new GltfStructuralMetadataLoader({ - gltf: gltfSchemaUri, - extension: extensionSchemaUri, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), - frameState: mockFrameState, - }); - expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); - structuralMetadataLoader.load(); - structuralMetadataLoader.destroy(); - - expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); - expect(structuralMetadataLoader.isDestroyed()).toBe(true); - - structuralMetadataLoaderCopy.destroy(); - - expect(destroyBufferView.calls.count()).toBe(6); - expect(destroyTexture.calls.count()).toBe(2); - expect(destroySchema.calls.count()).toBe(1); - - ResourceCache.unload(schemaCopy); - } - ); + expect(structuralMetadataLoader.structuralMetadata).not.toBeDefined(); + expect(structuralMetadataLoader.isDestroyed()).toBe(true); + + expect(destroyBufferView.calls.count()).toBe(6); + expect(destroyTexture.calls.count()).toBe(2); + expect(destroySchema.calls.count()).toBe(1); + await expectAsync(promise).toBeResolved(); } it("handles resolving resources after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfTextureLoaderSpec.js b/packages/engine/Specs/Scene/GltfTextureLoaderSpec.js index 3ce02133195..0845aca115a 100644 --- a/packages/engine/Specs/Scene/GltfTextureLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfTextureLoaderSpec.js @@ -6,6 +6,7 @@ import { JobScheduler, Resource, ResourceCache, + RuntimeError, SupportedImageFormats, Texture, TextureMinificationFilter, @@ -232,10 +233,9 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if image fails to load", function () { - const error = new Error("404 Not Found"); - spyOn(Resource.prototype, "fetchImage").and.returnValue( - Promise.reject(error) + it("load throws if image fails to load", async function () { + spyOn(Resource.prototype, "fetchImage").and.callFake(() => + Promise.reject(new Error("404 Not Found")) ); const textureLoader = new GltfTextureLoader({ @@ -247,20 +247,13 @@ describe( supportedImageFormats: new SupportedImageFormats(), }); - textureLoader.load(); - - return textureLoader.promise - .then(function (textureLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load texture\nFailed to load image: image.png\n404 Not Found" - ); - }); + await expectAsync(textureLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load texture\nFailed to load image: image.png\n404 Not Found" + ); }); - it("loads texture", function () { + it("loads texture", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); @@ -289,20 +282,20 @@ describe( supportedImageFormats: new SupportedImageFormats(), }); - loaderProcess(textureLoader, scene); // Check that calling process before load doesn't break anything + expect(() => loaderProcess(textureLoader, scene)).not.toThrowError(); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - loaderProcess(textureLoader, scene); // Check that calling process after load doesn't break anything - expect(textureLoader.texture.width).toBe(1); - expect(textureLoader.texture.height).toBe(1); - }); + expect(() => loaderProcess(textureLoader, scene)).not.toThrowError(); + expect(textureLoader.texture.width).toBe(1); + expect(textureLoader.texture.height).toBe(1); + expect(ResourceCache.statistics.texturesByteLength).toBe( + textureLoader.texture.sizeInBytes + ); }); - it("creates texture synchronously", function () { + it("creates texture synchronously", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); @@ -317,18 +310,15 @@ describe( asynchronous: false, }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - loaderProcess(textureLoader, scene); // Check that calling process after load doesn't break anything - expect(textureLoader.texture.width).toBe(1); - expect(textureLoader.texture.height).toBe(1); - }); + expect(() => loaderProcess(textureLoader, scene)).not.toThrowError(); + expect(textureLoader.texture.width).toBe(1); + expect(textureLoader.texture.height).toBe(1); }); - it("loads KTX2/Basis texture", function () { + it("loads KTX2/Basis texture", async function () { if (!scene.context.supportsBasis) { return; } @@ -347,18 +337,15 @@ describe( }), }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture.width).toBe(4); - expect(textureLoader.texture.height).toBe(4); - expect(gl.compressedTexImage2D.calls.count()).toEqual(1); - }); + expect(textureLoader.texture.width).toBe(4); + expect(textureLoader.texture.height).toBe(4); + expect(gl.compressedTexImage2D.calls.count()).toEqual(1); }); - it("loads KTX2/Basis texture with mipmap", function () { + it("loads KTX2/Basis texture with mipmap", async function () { if (!scene.context.supportsBasis) { return; } @@ -377,18 +364,15 @@ describe( }), }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture.width).toBe(4); - expect(textureLoader.texture.height).toBe(4); - expect(gl.compressedTexImage2D.calls.count()).toEqual(3); - }); + expect(textureLoader.texture.width).toBe(4); + expect(textureLoader.texture.height).toBe(4); + expect(gl.compressedTexImage2D.calls.count()).toEqual(3); }); - it("loads KTX2/Basis texture with incompatible mipmap sampler", function () { + it("loads KTX2/Basis texture with incompatible mipmap sampler", async function () { if (!scene.context.supportsBasis) { return; } @@ -411,23 +395,20 @@ describe( asynchronous: false, }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(GltfLoaderUtil.createSampler).toHaveBeenCalledWith({ - gltf: gltfKtx2MissingMipmap, - textureInfo: gltf.materials[0].emissiveTexture, - compressedTextureNoMipmap: true, - }); - expect(textureLoader.texture.sampler.minificationFilter).toBe( - TextureMinificationFilter.NEAREST - ); + expect(GltfLoaderUtil.createSampler).toHaveBeenCalledWith({ + gltf: gltfKtx2MissingMipmap, + textureInfo: gltf.materials[0].emissiveTexture, + compressedTextureNoMipmap: true, }); + expect(textureLoader.texture.sampler.minificationFilter).toBe( + TextureMinificationFilter.NEAREST + ); }); - it("generates mipmap if sampler requires it", function () { + it("generates mipmap if sampler requires it", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); @@ -446,18 +427,15 @@ describe( supportedImageFormats: new SupportedImageFormats(), }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture.width).toBe(1); - expect(textureLoader.texture.height).toBe(1); - expect(generateMipmap).toHaveBeenCalled(); - }); + expect(textureLoader.texture.width).toBe(1); + expect(textureLoader.texture.height).toBe(1); + expect(generateMipmap).toHaveBeenCalled(); }); - it("generates power-of-two texture if sampler requires it", function () { + it("generates power-of-two texture if sampler requires it", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(imageNpot) ); @@ -471,17 +449,14 @@ describe( supportedImageFormats: new SupportedImageFormats(), }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture.width).toBe(4); - expect(textureLoader.texture.height).toBe(2); - }); + expect(textureLoader.texture.width).toBe(4); + expect(textureLoader.texture.height).toBe(2); }); - it("does not generate power-of-two texture if sampler does not require it", function () { + it("does not generate power-of-two texture if sampler does not require it", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(imageNpot) ); @@ -495,17 +470,14 @@ describe( supportedImageFormats: new SupportedImageFormats(), }); - textureLoader.load(); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture.width).toBe(3); - expect(textureLoader.texture.height).toBe(2); - }); + expect(textureLoader.texture.width).toBe(3); + expect(textureLoader.texture.height).toBe(2); }); - it("destroys texture loader", function () { + it("destroys texture loader", async function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( Promise.resolve(image) ); @@ -531,41 +503,30 @@ describe( expect(textureLoader.texture).not.toBeDefined(); - textureLoader.load(); - - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture).toBeDefined(); - expect(textureLoader.isDestroyed()).toBe(false); + await textureLoader.load(); + await waitForLoaderProcess(textureLoader, scene); + expect(textureLoader.texture).toBeDefined(); + expect(textureLoader.isDestroyed()).toBe(false); - textureLoader.destroy(); + textureLoader.destroy(); - expect(textureLoader.texture).not.toBeDefined(); - expect(textureLoader.isDestroyed()).toBe(true); - expect(unloadImage).toHaveBeenCalled(); - expect(destroyTexture).toHaveBeenCalled(); - }); + expect(textureLoader.texture).not.toBeDefined(); + expect(textureLoader.isDestroyed()).toBe(true); + expect(unloadImage).toHaveBeenCalled(); + expect(destroyTexture).toHaveBeenCalled(); }); - function resolveImageAfterDestroy(rejectPromise) { - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(image); - } - }); - spyOn(Resource.prototype, "fetchImage").and.returnValue(promise); - - // Load a copy of the image into the cache so that the image - // promise resolves even if the texture loader is destroyed - const imageLoaderCopy = ResourceCache.loadImage({ - gltf: gltf, - imageId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); + async function resolveImageAfterDestroy(rejectPromise) { + spyOn(Resource.prototype, "fetchImage").and.callFake( + () => + new Promise(function (resolve, reject) { + if (rejectPromise) { + reject(new Error()); + } else { + resolve(image); + } + }) + ); const textureLoader = new GltfTextureLoader({ resourceCache: ResourceCache, @@ -578,15 +539,12 @@ describe( expect(textureLoader.texture).not.toBeDefined(); - textureLoader.load(); + const promise = textureLoader.load(); textureLoader.destroy(); - return textureLoader.promise.then(function () { - expect(textureLoader.texture).not.toBeDefined(); - expect(textureLoader.isDestroyed()).toBe(true); - - ResourceCache.unload(imageLoaderCopy); - }); + await expectAsync(promise).toBeResolved(); + expect(textureLoader.texture).not.toBeDefined(); + expect(textureLoader.isDestroyed()).toBe(true); } it("handles resolving image after destroy", function () { diff --git a/packages/engine/Specs/Scene/GltfVertexBufferLoaderSpec.js b/packages/engine/Specs/Scene/GltfVertexBufferLoaderSpec.js index b09b37832be..8351e05d96d 100644 --- a/packages/engine/Specs/Scene/GltfVertexBufferLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfVertexBufferLoaderSpec.js @@ -9,6 +9,7 @@ import { JobScheduler, Resource, ResourceCache, + RuntimeError, } from "../../index.js"; import concatTypedArrays from "../../../../Specs/concatTypedArrays.js"; import createScene from "../../../../Specs/createScene.js"; @@ -351,10 +352,9 @@ describe( }).toThrowDeveloperError(); }); - it("rejects promise if buffer view fails to load", function () { - const error = new Error("404 Not Found"); - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.reject(error) + it("load throws if buffer view fails to load", async function () { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + Promise.reject(new Error("404 Not Found")) ); const vertexBufferLoader = new GltfVertexBufferLoader({ @@ -366,20 +366,13 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); - - return vertexBufferLoader.promise - .then(function (vertexBufferLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load vertex buffer\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" - ); - }); + await expectAsync(vertexBufferLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load vertex buffer\nFailed to load buffer view\nFailed to load external buffer: https://example.com/external.bin\n404 Not Found" + ); }); - it("rejects promise if draco fails to load", function () { + it("process throws if draco fails to load", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(dracoArrayBuffer) ); @@ -400,20 +393,16 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); - - return waitForLoaderProcess(vertexBufferLoader, scene) - .then(function (vertexBufferLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load vertex buffer\nFailed to load Draco\nDraco decode failed" - ); - }); + await vertexBufferLoader.load(); + await expectAsync( + waitForLoaderProcess(vertexBufferLoader, scene) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load vertex buffer\nFailed to load Draco\nDraco decode failed" + ); }); - it("loads as buffer", function () { + it("loads as buffer", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -443,20 +432,18 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - loaderProcess(vertexBufferLoader, scene); // Check that calling process after load doesn't break anything - expect(vertexBufferLoader.buffer.sizeInBytes).toBe( - positions.byteLength - ); - expect(vertexBufferLoader.typedArray).toBeUndefined(); - }); + expect(() => loaderProcess(vertexBufferLoader, scene)).not.toThrowError(); + expect(vertexBufferLoader.buffer.sizeInBytes).toBe(positions.byteLength); + expect(vertexBufferLoader.typedArray).toBeUndefined(); + expect(ResourceCache.statistics.geometryByteLength).toBe( + vertexBufferLoader.buffer.sizeInBytes + ); }); - it("loads as typed array", function () { + it("loads as typed array", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -473,20 +460,22 @@ describe( loadTypedArray: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.typedArray.byteLength).toBe( - positions.byteLength - ); - expect(vertexBufferLoader.buffer).toBeUndefined(); - expect(Buffer.createVertexBuffer.calls.count()).toBe(0); - }); + expect(() => loaderProcess(vertexBufferLoader, scene)).not.toThrowError(); + expect(vertexBufferLoader.typedArray.byteLength).toBe( + positions.byteLength + ); + expect(vertexBufferLoader.buffer).toBeUndefined(); + expect(Buffer.createVertexBuffer.calls.count()).toBe(0); + + expect(ResourceCache.statistics.geometryByteLength).toBe( + vertexBufferLoader.typedArray.byteLength + ); }); - it("loads as both buffer and typed array", function () { + it("loads as both buffer and typed array", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -517,22 +506,21 @@ describe( loadTypedArray: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - loaderProcess(vertexBufferLoader, scene); // Check that calling process after load doesn't break anything - expect(vertexBufferLoader.buffer.sizeInBytes).toBe( - positions.byteLength - ); - expect(vertexBufferLoader.typedArray.byteLength).toBe( - positions.byteLength - ); - }); + expect(() => loaderProcess(vertexBufferLoader, scene)).not.toThrowError(); + expect(vertexBufferLoader.buffer.sizeInBytes).toBe(positions.byteLength); + expect(vertexBufferLoader.typedArray.byteLength).toBe( + positions.byteLength + ); + const totalSize = + vertexBufferLoader.typedArray.byteLength + + vertexBufferLoader.buffer.sizeInBytes; + expect(ResourceCache.statistics.geometryByteLength).toBe(totalSize); }); - it("creates vertex buffer synchronously", function () { + it("creates vertex buffer synchronously", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -548,19 +536,13 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer.sizeInBytes).toBe( - positions.byteLength - ); - expect(vertexBufferLoader.typedArray).toBeUndefined(); - }); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); + expect(vertexBufferLoader.buffer.sizeInBytes).toBe(positions.byteLength); + expect(vertexBufferLoader.typedArray).toBeUndefined(); }); - it("loads positions from draco", function () { + it("loads positions from draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -586,34 +568,34 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - loaderProcess(vertexBufferLoader, scene); // Check that calling process after load doesn't break anything - expect(vertexBufferLoader.buffer.sizeInBytes).toBe( - decodedPositions.byteLength - ); - expect(vertexBufferLoader.typedArray).toBeUndefined(); - const quantization = vertexBufferLoader.quantization; - expect(quantization.octEncoded).toBe(false); - expect(quantization.quantizedVolumeOffset).toEqual( - new Cartesian3(-1.0, -1.0, -1.0) - ); - expect(quantization.quantizedVolumeDimensions).toEqual( - new Cartesian3(2.0, 2.0, 2.0) - ); - expect(quantization.normalizationRange).toEqual( - new Cartesian3(16383, 16383, 16383) - ); - expect(quantization.componentDatatype).toBe( - ComponentDatatype.UNSIGNED_SHORT - ); - }); + expect(() => loaderProcess(vertexBufferLoader, scene)).not.toThrowError(); + expect(vertexBufferLoader.buffer.sizeInBytes).toBe( + decodedPositions.byteLength + ); + expect(vertexBufferLoader.typedArray).toBeUndefined(); + const quantization = vertexBufferLoader.quantization; + expect(quantization.octEncoded).toBe(false); + expect(quantization.quantizedVolumeOffset).toEqual( + new Cartesian3(-1.0, -1.0, -1.0) + ); + expect(quantization.quantizedVolumeDimensions).toEqual( + new Cartesian3(2.0, 2.0, 2.0) + ); + expect(quantization.normalizationRange).toEqual( + new Cartesian3(16383, 16383, 16383) + ); + expect(quantization.componentDatatype).toBe( + ComponentDatatype.UNSIGNED_SHORT + ); + expect(ResourceCache.statistics.geometryByteLength).toBe( + vertexBufferLoader.buffer.sizeInBytes + ); }); - it("loads normals from draco", function () { + it("loads normals from draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -633,28 +615,25 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer.sizeInBytes).toBe( - decodedNormals.byteLength - ); - - const quantization = vertexBufferLoader.quantization; - expect(quantization.octEncoded).toBe(true); - expect(quantization.octEncodedZXY).toBe(true); - expect(quantization.quantizedVolumeOffset).toBeUndefined(); - expect(quantization.quantizedVolumeDimensions).toBeUndefined(); - expect(quantization.normalizationRange).toBe(1023); - expect(quantization.componentDatatype).toBe( - ComponentDatatype.UNSIGNED_BYTE - ); - }); + expect(vertexBufferLoader.buffer.sizeInBytes).toBe( + decodedNormals.byteLength + ); + + const quantization = vertexBufferLoader.quantization; + expect(quantization.octEncoded).toBe(true); + expect(quantization.octEncodedZXY).toBe(true); + expect(quantization.quantizedVolumeOffset).toBeUndefined(); + expect(quantization.quantizedVolumeDimensions).toBeUndefined(); + expect(quantization.normalizationRange).toBe(1023); + expect(quantization.componentDatatype).toBe( + ComponentDatatype.UNSIGNED_BYTE + ); }); - it("destroys vertex buffer loaded from buffer view", function () { + it("destroys vertex buffer loaded from buffer view", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -679,24 +658,20 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer).toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(false); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); + expect(vertexBufferLoader.buffer).toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(false); - vertexBufferLoader.destroy(); + vertexBufferLoader.destroy(); - expect(vertexBufferLoader.buffer).not.toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(true); - expect(unloadBufferView).toHaveBeenCalled(); - expect(destroyVertexBuffer).toHaveBeenCalled(); - }); + expect(vertexBufferLoader.buffer).not.toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(true); + expect(unloadBufferView).toHaveBeenCalled(); + expect(destroyVertexBuffer).toHaveBeenCalled(); }); - it("destroys vertex buffer loaded from draco", function () { + it("destroys vertex buffer loaded from draco", async function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( Promise.resolve(arrayBuffer) ); @@ -726,33 +701,26 @@ describe( loadBuffer: true, }); - vertexBufferLoader.load(); + await vertexBufferLoader.load(); + await waitForLoaderProcess(vertexBufferLoader, scene); - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer).toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(false); + expect(vertexBufferLoader.buffer).toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(false); - vertexBufferLoader.destroy(); + vertexBufferLoader.destroy(); - expect(vertexBufferLoader.buffer).not.toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(true); - expect(unloadDraco).toHaveBeenCalled(); - expect(destroyVertexBuffer).toHaveBeenCalled(); - }); + expect(vertexBufferLoader.buffer).not.toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(true); + expect(unloadDraco).toHaveBeenCalled(); + expect(destroyVertexBuffer).toHaveBeenCalled(); }); - function resolveBufferViewAfterDestroy(rejectPromise) { - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(arrayBuffer); - } - }); - - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue(promise); + async function resolveBufferViewAfterDestroy(rejectPromise) { + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => + rejectPromise + ? Promise.reject(new Error()) + : Promise.resolve(arrayBuffer) + ); const vertexBufferLoader = new GltfVertexBufferLoader({ resourceCache: ResourceCache, @@ -765,13 +733,13 @@ describe( expect(vertexBufferLoader.buffer).not.toBeDefined(); - vertexBufferLoader.load(); + const promise = vertexBufferLoader.load(); vertexBufferLoader.destroy(); - return vertexBufferLoader.promise.finally(function () { - expect(vertexBufferLoader.buffer).not.toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(true); - }); + await expectAsync(promise).toBeResolved(); + + expect(vertexBufferLoader.buffer).not.toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(true); } it("handles resolving buffer view after destroy", function () { @@ -782,7 +750,7 @@ describe( return resolveBufferViewAfterDestroy(true); }); - function resolveDracoAfterDestroy(rejectPromise) { + async function resolveDracoAfterDestroy(rejectPromise) { const vertexBufferLoader = new GltfVertexBufferLoader({ resourceCache: ResourceCache, gltf: gltfDraco, @@ -820,14 +788,14 @@ describe( expect(vertexBufferLoader.buffer).not.toBeDefined(); - vertexBufferLoader.load(); - loaderProcess(vertexBufferLoader, scene); - return vertexBufferLoader.promise.finally(function () { - expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts + await vertexBufferLoader.load(); // Destroy happens in mock function above + await expectAsync( + waitForLoaderProcess(vertexBufferLoader, scene) + ).toBeResolved(); - expect(vertexBufferLoader.buffer).not.toBeDefined(); - expect(vertexBufferLoader.isDestroyed()).toBe(true); - }); + expect(decodeBufferView).toHaveBeenCalled(); // Make sure the decode actually starts + expect(vertexBufferLoader.buffer).not.toBeDefined(); + expect(vertexBufferLoader.isDestroyed()).toBe(true); } it("handles resolving draco after destroy", function () { diff --git a/packages/engine/Specs/Scene/MetadataSchemaLoaderSpec.js b/packages/engine/Specs/Scene/MetadataSchemaLoaderSpec.js index 2aab3e9421f..9c14c187e94 100644 --- a/packages/engine/Specs/Scene/MetadataSchemaLoaderSpec.js +++ b/packages/engine/Specs/Scene/MetadataSchemaLoaderSpec.js @@ -3,6 +3,7 @@ import { ResourceCache, ResourceLoaderState, MetadataSchemaLoader, + RuntimeError, } from "../../index.js"; describe("Scene/MetadataSchemaLoader", function () { @@ -61,7 +62,7 @@ describe("Scene/MetadataSchemaLoader", function () { }).toThrowDeveloperError(); }); - it("rejects promise if schema cannot be fetched", function () { + it("load throws if schema cannot be fetched", async function () { spyOn(Resource.prototype, "fetchJson").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -71,38 +72,29 @@ describe("Scene/MetadataSchemaLoader", function () { resource: resource, }); - schemaLoader.load(); - - return schemaLoader.promise - .then(function (schemaLoader) { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load schema: https://example.com/schema.json\n404 Not Found" - ); - }); + await expectAsync(schemaLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load schema: https://example.com/schema.json\n404 Not Found" + ); }); - it("loads schema from JSON", function () { + it("loads schema from JSON", async function () { const schemaLoader = new MetadataSchemaLoader({ schema: schemaJson, }); - schemaLoader.load(); + await schemaLoader.load(); - return schemaLoader.promise.then(function (schemaLoader) { - const schema = schemaLoader.schema; - expect(schema).toBeDefined(); + const schema = schemaLoader.schema; + expect(schema).toBeDefined(); - const enums = schema.enums; - expect(enums.treeType).toBeDefined(); + const enums = schema.enums; + expect(enums.treeType).toBeDefined(); - const classes = schema.classes; - expect(classes.tree).toBeDefined(); - }); + const classes = schema.classes; + expect(classes.tree).toBeDefined(); }); - it("loads external schema", function () { + it("loads external schema", async function () { const fetchJson = spyOn(Resource.prototype, "fetchJson").and.returnValue( Promise.resolve(schemaJson) ); @@ -111,23 +103,21 @@ describe("Scene/MetadataSchemaLoader", function () { resource: resource, }); - schemaLoader.load(); + await schemaLoader.load(); - return schemaLoader.promise.then(function (schemaLoader) { - expect(fetchJson).toHaveBeenCalled(); + expect(fetchJson).toHaveBeenCalled(); - const schema = schemaLoader.schema; - expect(schema).toBeDefined(); + const schema = schemaLoader.schema; + expect(schema).toBeDefined(); - const enums = schema.enums; - expect(enums.treeType).toBeDefined(); + const enums = schema.enums; + expect(enums.treeType).toBeDefined(); - const classes = schema.classes; - expect(classes.tree).toBeDefined(); - }); + const classes = schema.classes; + expect(classes.tree).toBeDefined(); }); - it("destroys schema", function () { + it("destroys schema", async function () { spyOn(Resource.prototype, "fetchJson").and.returnValue( Promise.resolve(schemaJson) ); @@ -138,27 +128,20 @@ describe("Scene/MetadataSchemaLoader", function () { expect(schemaLoader.schema).not.toBeDefined(); - schemaLoader.load(); + await schemaLoader.load(); - return schemaLoader.promise.then(function (schemaLoader) { - expect(schemaLoader.schema).toBeDefined(); - expect(schemaLoader.isDestroyed()).toBe(false); + expect(schemaLoader.schema).toBeDefined(); + expect(schemaLoader.isDestroyed()).toBe(false); - schemaLoader.destroy(); - expect(schemaLoader.schema).not.toBeDefined(); - expect(schemaLoader.isDestroyed()).toBe(true); - }); + schemaLoader.destroy(); + expect(schemaLoader.schema).not.toBeDefined(); + expect(schemaLoader.isDestroyed()).toBe(true); }); - function resolveJsonAfterDestroy(rejectPromise) { - const promise = new Promise(function (resolve, reject) { - if (rejectPromise) { - reject(new Error()); - } else { - resolve(schemaJson); - } - }); - spyOn(Resource.prototype, "fetchJson").and.returnValue(promise); + async function resolveJsonAfterDestroy(rejectPromise) { + spyOn(Resource.prototype, "fetchJson").and.callFake(() => + rejectPromise ? Promise.reject(new Error()) : Promise.resolve(schemaJson) + ); const schemaLoader = new MetadataSchemaLoader({ resource: resource, @@ -166,13 +149,13 @@ describe("Scene/MetadataSchemaLoader", function () { expect(schemaLoader.schema).not.toBeDefined(); - schemaLoader.load(); + const promise = schemaLoader.load(); expect(schemaLoader._state).toBe(ResourceLoaderState.LOADING); schemaLoader.destroy(); - return schemaLoader.promise.then(function () { - expect(schemaLoader.schema).not.toBeDefined(); - expect(schemaLoader.isDestroyed()).toBe(true); - }); + + await expectAsync(promise).toBeResolved(); + expect(schemaLoader.schema).not.toBeDefined(); + expect(schemaLoader.isDestroyed()).toBe(true); } it("handles resolving json after destroy", function () { diff --git a/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js b/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js index e8a16c32940..17e69035133 100644 --- a/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js @@ -7,7 +7,7 @@ import { } from "../../../index.js"; import createScene from "../../../../../Specs/createScene.js"; -import loadAndZoomToModel from "./loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./loadAndZoomToModelAsync.js"; import pollToPromise from "../../../../../Specs/pollToPromise.js"; describe( @@ -38,7 +38,7 @@ describe( }); it("initializes", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -51,8 +51,8 @@ describe( }); }); - it("throws when add is called on non-ready model", function () { - const model = Model.fromGltf({ + it("throws when add is called on non-ready model", async function () { + const model = await Model.fromGltfAsync({ gltf: animatedTriangleUrl, }); @@ -64,7 +64,7 @@ describe( }); it("throws when add is not given a name or index", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -77,7 +77,7 @@ describe( }); it("throws when add is given invalid name", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -92,7 +92,7 @@ describe( }); it("throws when add is given invalid index", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -107,7 +107,7 @@ describe( }); it("throws when add is given invalid multiplier", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -123,7 +123,7 @@ describe( }); it("add works with name", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -150,7 +150,7 @@ describe( }); it("add works with index", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -177,7 +177,7 @@ describe( }); it("add works with options", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -215,8 +215,8 @@ describe( }); }); - it("throws when addAll is called on non-ready model", function () { - const model = Model.fromGltf({ + it("throws when addAll is called on non-ready model", async function () { + const model = await Model.fromGltfAsync({ gltf: animatedTriangleUrl, }); @@ -226,7 +226,7 @@ describe( }); it("throws when addAll is given invalid multiplier", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -241,7 +241,7 @@ describe( }); it("addAll works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -270,7 +270,7 @@ describe( }); it("addAll works with options", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -312,7 +312,7 @@ describe( }); it("contains returns false for undefined", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -325,13 +325,13 @@ describe( }); it("contains returns false for animation not in collection", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, scene ).then(function (firstModel) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -346,7 +346,7 @@ describe( }); it("contains returns true for animation in collection", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -359,7 +359,7 @@ describe( }); it("throws when get is not given index", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -374,7 +374,7 @@ describe( }); it("throws when get is given out-of-range index", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -389,7 +389,7 @@ describe( }); it("get works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -402,7 +402,7 @@ describe( }); it("remove returns false for undefined", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -415,13 +415,13 @@ describe( }); it("remove returns false for animation not in collection", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, scene ).then(function (firstModel) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -436,7 +436,7 @@ describe( }); it("remove returns true for animation in collection", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -456,7 +456,7 @@ describe( }); it("removeAll works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -471,7 +471,7 @@ describe( }); it("update returns false when there are no animations", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: interpolationTestUrl, }, @@ -484,7 +484,7 @@ describe( }); it("raises animation start, update, and stop events when removeOnStop is true", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -536,7 +536,7 @@ describe( }); it("finishes animation when it reaches its end", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -568,7 +568,7 @@ describe( }); it("animates with a delay", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -595,7 +595,7 @@ describe( }); it("animates with startTime", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -625,7 +625,7 @@ describe( }); it("animates with an explicit stopTime", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -664,7 +664,7 @@ describe( }); it("animates with an explicit animation time", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -719,7 +719,7 @@ describe( }); it("animates while paused with an explicit animation time", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -764,7 +764,7 @@ describe( }); it("animates with a multiplier", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -797,7 +797,7 @@ describe( }); it("animates with reverse", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -830,7 +830,7 @@ describe( }); it("animates with REPEAT", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, @@ -867,7 +867,7 @@ describe( }); it("animates with MIRRORED_REPEAT", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, }, diff --git a/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js b/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js index 6ad1c434230..d4c912fff10 100644 --- a/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js @@ -10,7 +10,7 @@ import { Quaternion, } from "../../../index.js"; import createScene from "../../../../../Specs/createScene.js"; -import loadAndZoomToModel from "./loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./loadAndZoomToModelAsync.js"; describe( "Scene/Model/ModelMatrixUpdateStage", @@ -118,7 +118,7 @@ describe( } it("updates leaf nodes using node transform setter", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: simpleSkin, }, @@ -196,7 +196,7 @@ describe( } it("updates nodes with children using node transform setter", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: simpleSkin, }, @@ -258,7 +258,7 @@ describe( }); it("updates with new model matrix", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: simpleSkin, }, @@ -305,7 +305,7 @@ describe( }); it("updates with new model matrix and model scale", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: simpleSkin, }, @@ -360,7 +360,7 @@ describe( }); it("updates render state cull face when scale is negative", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: simpleSkin, }, diff --git a/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js b/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js index a66c117689d..e3e8f2873cd 100644 --- a/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js @@ -13,7 +13,7 @@ import { ResourceCache, } from "../../../index.js"; import createScene from "../../../../../Specs/createScene.js"; -import loadAndZoomToModel from "./loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./loadAndZoomToModelAsync.js"; describe( "Scene/Model/ModelSceneGraph", @@ -45,7 +45,7 @@ describe( }); it("creates runtime nodes and runtime primitives from a model", function () { - return loadAndZoomToModel({ gltf: vertexColorGltfUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: vertexColorGltfUrl }, scene).then( function (model) { const sceneGraph = model._sceneGraph; const components = sceneGraph._components; @@ -68,7 +68,7 @@ describe( }, }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -95,7 +95,7 @@ describe( conditions: [["${height} > 1", "color('red', 0.1)"]], }, }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -126,7 +126,7 @@ describe( }, }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -151,54 +151,58 @@ describe( it("builds draw commands for each primitive", function () { spyOn(ModelSceneGraph.prototype, "buildDrawCommands").and.callThrough(); spyOn(ModelSceneGraph.prototype, "pushDrawCommands").and.callThrough(); - return loadAndZoomToModel({ gltf: parentGltfUrl }, scene).then(function ( - model - ) { - const sceneGraph = model._sceneGraph; - const runtimeNodes = sceneGraph._runtimeNodes; + return loadAndZoomToModelAsync({ gltf: parentGltfUrl }, scene).then( + function (model) { + const sceneGraph = model._sceneGraph; + const runtimeNodes = sceneGraph._runtimeNodes; - let primitivesCount = 0; - for (let i = 0; i < runtimeNodes.length; i++) { - primitivesCount += runtimeNodes[i].runtimePrimitives.length; + let primitivesCount = 0; + for (let i = 0; i < runtimeNodes.length; i++) { + primitivesCount += runtimeNodes[i].runtimePrimitives.length; + } + + const frameState = scene.frameState; + frameState.commandList.length = 0; + scene.renderForSpecs(); + expect( + ModelSceneGraph.prototype.buildDrawCommands + ).toHaveBeenCalled(); + expect(ModelSceneGraph.prototype.pushDrawCommands).toHaveBeenCalled(); + expect(frameState.commandList.length).toEqual(primitivesCount); + + expect(model._drawCommandsBuilt).toEqual(true); + + // Reset the draw command list to see if they're re-built. + model._drawCommandsBuilt = false; + frameState.commandList.length = 0; + scene.renderForSpecs(); + expect( + ModelSceneGraph.prototype.buildDrawCommands + ).toHaveBeenCalled(); + expect(ModelSceneGraph.prototype.pushDrawCommands).toHaveBeenCalled(); + expect(frameState.commandList.length).toEqual(primitivesCount); } - - const frameState = scene.frameState; - frameState.commandList.length = 0; - scene.renderForSpecs(); - expect(ModelSceneGraph.prototype.buildDrawCommands).toHaveBeenCalled(); - expect(ModelSceneGraph.prototype.pushDrawCommands).toHaveBeenCalled(); - expect(frameState.commandList.length).toEqual(primitivesCount); - - expect(model._drawCommandsBuilt).toEqual(true); - - // Reset the draw command list to see if they're re-built. - model._drawCommandsBuilt = false; - frameState.commandList.length = 0; - scene.renderForSpecs(); - expect(ModelSceneGraph.prototype.buildDrawCommands).toHaveBeenCalled(); - expect(ModelSceneGraph.prototype.pushDrawCommands).toHaveBeenCalled(); - expect(frameState.commandList.length).toEqual(primitivesCount); - }); + ); }); it("stores runtime nodes correctly", function () { - return loadAndZoomToModel({ gltf: parentGltfUrl }, scene).then(function ( - model - ) { - const sceneGraph = model._sceneGraph; - const components = sceneGraph._components; - const runtimeNodes = sceneGraph._runtimeNodes; + return loadAndZoomToModelAsync({ gltf: parentGltfUrl }, scene).then( + function (model) { + const sceneGraph = model._sceneGraph; + const components = sceneGraph._components; + const runtimeNodes = sceneGraph._runtimeNodes; - expect(runtimeNodes[0].node).toEqual(components.nodes[0]); - expect(runtimeNodes[1].node).toEqual(components.nodes[1]); + expect(runtimeNodes[0].node).toEqual(components.nodes[0]); + expect(runtimeNodes[1].node).toEqual(components.nodes[1]); - const rootNodes = sceneGraph._rootNodes; - expect(rootNodes[0]).toEqual(0); - }); + const rootNodes = sceneGraph._rootNodes; + expect(rootNodes[0]).toEqual(0); + } + ); }); it("propagates node transforms correctly", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: parentGltfUrl, upAxis: Axis.Z, @@ -227,7 +231,7 @@ describe( }); it("creates runtime skin from model", function () { - return loadAndZoomToModel({ gltf: simpleSkinGltfUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: simpleSkinGltfUrl }, scene).then( function (model) { const sceneGraph = model._sceneGraph; const components = sceneGraph._components; @@ -258,7 +262,7 @@ describe( }); it("creates articulation from model", function () { - return loadAndZoomToModel({ gltf: boxArticulationsUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxArticulationsUrl }, scene).then( function (model) { const sceneGraph = model._sceneGraph; const components = sceneGraph._components; @@ -281,7 +285,7 @@ describe( }); it("applies articulations", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -326,7 +330,7 @@ describe( it("adds ModelColorPipelineStage when color is set on the model", function () { spyOn(ModelColorPipelineStage, "process"); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { color: Color.RED, gltf: parentGltfUrl, @@ -339,7 +343,7 @@ describe( it("adds CustomShaderPipelineStage when customShader is set on the model", function () { spyOn(CustomShaderPipelineStage, "process"); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -352,7 +356,7 @@ describe( }); it("pushDrawCommands ignores hidden nodes", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: duckUrl, }, diff --git a/packages/engine/Specs/Scene/Model/ModelSpec.js b/packages/engine/Specs/Scene/Model/ModelSpec.js index 180ab45ec0e..2ccd2cb068d 100644 --- a/packages/engine/Specs/Scene/Model/ModelSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSpec.js @@ -34,6 +34,7 @@ import { PrimitiveType, Resource, ResourceCache, + RuntimeError, ShaderProgram, ShadowMode, SplitDirection, @@ -43,7 +44,7 @@ import { } from "../../../index.js"; import createScene from "../../../../../Specs/createScene.js"; import pollToPromise from "../../../../../Specs/pollToPromise.js"; -import loadAndZoomToModel from "./loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./loadAndZoomToModelAsync.js"; describe( "Scene/Model/Model", @@ -254,25 +255,36 @@ describe( }).toThrowDeveloperError(); }); + it("fromGltfAsync throws with undefined options", async function () { + await expectAsync(Model.fromGltfAsync()).toBeRejectedWithDeveloperError(); + }); + + it("fromGltfAsync throws with undefined url", async function () { + await expectAsync( + Model.fromGltfAsync({}) + ).toBeRejectedWithDeveloperError(); + }); + it("initializes and renders from Uint8Array", function () { const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel({ gltf: new Uint8Array(buffer) }, scene).then( - function (model) { - expect(model.ready).toEqual(true); - expect(model._sceneGraph).toBeDefined(); - expect(model._resourcesLoaded).toEqual(true); - verifyRender(model, true); - } - ); + return loadAndZoomToModelAsync( + { gltf: new Uint8Array(buffer) }, + scene + ).then(function (model) { + expect(model.ready).toEqual(true); + expect(model._sceneGraph).toBeDefined(); + expect(model._resourcesLoaded).toEqual(true); + verifyRender(model, true); + }); }); }); it("initializes and renders from JSON object", function () { const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxTexturedGltfUrl, @@ -290,7 +302,7 @@ describe( it("initializes and renders from JSON object with external buffers", function () { const resource = Resource.createIfNeeded(microcosm); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: microcosm, @@ -306,7 +318,7 @@ describe( }); it("initializes and renders with url", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: boxTexturedGltfUrl, }, @@ -319,6 +331,60 @@ describe( }); }); + it("raises errorEvent when a texture fails to load and incrementallyLoadTextures is true", async function () { + const resource = Resource.createIfNeeded(boxTexturedGltfUrl); + const gltf = await resource.fetchJson(); + gltf.images[0].uri = "non-existent-path.png"; + const model = await Model.fromGltfAsync({ + gltf: gltf, + basePath: boxTexturedGltfUrl, + incrementallyLoadTextures: true, + }); + scene.primitives.add(model); + let finished = false; + + model.errorEvent.addEventListener((e) => { + expect(e).toBeInstanceOf(RuntimeError); + expect(e.message).toContain( + `Failed to load model: ${boxTexturedGltfUrl}` + ); + expect(e.message).toContain("Failed to load texture"); + finished = true; + }); + + return pollToPromise(function () { + scene.renderForSpecs(); + return finished; + }); + }); + + it("raises errorEvent when a texture fails to load and incrementallyLoadTextures is false", async function () { + const resource = Resource.createIfNeeded(boxTexturedGltfUrl); + const gltf = await resource.fetchJson(); + gltf.images[0].uri = "non-existent-path.png"; + const model = await Model.fromGltfAsync({ + gltf: gltf, + basePath: boxTexturedGltfUrl, + incrementallyLoadTextures: false, + }); + scene.primitives.add(model); + let finished = false; + + model.errorEvent.addEventListener((e) => { + expect(e).toBeInstanceOf(RuntimeError); + expect(e.message).toContain( + `Failed to load model: ${boxTexturedGltfUrl}` + ); + expect(e.message).toContain("Failed to load texture"); + finished = true; + }); + + return pollToPromise(function () { + scene.renderForSpecs(); + return finished; + }); + }); + it("rejects ready promise when texture fails to load", function () { const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { @@ -358,23 +424,60 @@ describe( }); }); + it("raises errorEvent when external buffer fails to load", async function () { + const resource = Resource.createIfNeeded(boxTexturedGltfUrl); + const gltf = await resource.fetchJson(); + gltf.buffers[0].uri = "non-existent-path.bin"; + const model = await Model.fromGltfAsync({ + gltf: gltf, + basePath: boxTexturedGltfUrl, + incrementallyLoadTextures: false, + }); + scene.primitives.add(model); + let finished = false; + + model.errorEvent.addEventListener((e) => { + expect(e).toBeInstanceOf(RuntimeError); + expect(e.message).toContain( + `Failed to load model: ${boxTexturedGltfUrl}` + ); + expect(e.message).toContain("Failed to load vertex buffer"); + finished = true; + }); + + return pollToPromise(function () { + scene.renderForSpecs(); + return finished; + }); + }); + it("rejects ready promise when external buffer fails to load", function () { const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { gltf.buffers[0].uri = "non-existent-path.bin"; - return loadAndZoomToModel( - { - gltf: gltf, - basePath: boxTexturedGltfUrl, - }, - scene - ) + const model = Model.fromGltf({ + gltf: gltf, + basePath: boxTexturedGltfUrl, + }); + scene.primitives.add(model); + let finished = false; + model.readyPromise .then(function (model) { + finished = true; fail(); }) .catch(function (error) { + finished = true; expect(error).toBeDefined(); }); + + return pollToPromise( + function () { + scene.renderForSpecs(); + return finished; + }, + { timeout: 10000 } + ); }); }); @@ -384,7 +487,7 @@ describe( "execute" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, asynchronous: true, @@ -404,7 +507,7 @@ describe( "execute" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, asynchronous: false, @@ -419,7 +522,7 @@ describe( }); it("initializes feature table", function () { - return loadAndZoomToModel({ gltf: buildingsMetadata }, scene).then( + return loadAndZoomToModelAsync({ gltf: buildingsMetadata }, scene).then( function (model) { expect(model.ready).toEqual(true); expect(model.featureTables).toBeDefined(); @@ -446,7 +549,7 @@ describe( }); it("sets default properties", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, }, @@ -502,7 +605,7 @@ describe( it("renders model without indices", function () { const resource = Resource.createIfNeeded(triangleWithoutIndicesUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: triangleWithoutIndicesUrl, @@ -533,7 +636,7 @@ describe( it("renders model with vertex colors", function () { const resource = Resource.createIfNeeded(vertexColorTestUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: vertexColorTestUrl, @@ -569,7 +672,7 @@ describe( it("renders model with double-sided material", function () { const resource = Resource.createIfNeeded(twoSidedPlaneUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: twoSidedPlaneUrl, @@ -623,7 +726,7 @@ describe( xit("renders model with emissive texture", function () { const resource = Resource.createIfNeeded(emissiveTextureUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: emissiveTextureUrl, @@ -653,7 +756,7 @@ describe( const resource = Resource.createIfNeeded(boomBoxUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boomBoxUrl, @@ -675,7 +778,7 @@ describe( const resource = Resource.createIfNeeded(morphPrimitivesTestUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: morphPrimitivesTestUrl, @@ -701,57 +804,52 @@ describe( }); it("renders Draco-compressed model", function () { - return loadAndZoomToModel({ gltf: dracoCesiumManUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: dracoCesiumManUrl }, scene).then( function (model) { verifyRender(model, true); } ); }); - it("fails to load with Draco decoding error", function () { - const readyPromise = pollToPromise(function () { + it("fails to load with Draco decoding error", async function () { + DracoLoader._getDecoderTaskProcessor(); + await pollToPromise(function () { return DracoLoader._taskProcessorReady; }); - DracoLoader._getDecoderTaskProcessor(); - return readyPromise - .then(function () { - const decoder = DracoLoader._getDecoderTaskProcessor(); - spyOn(decoder, "scheduleTask").and.callFake(function () { - return Promise.reject({ message: "Custom error" }); - }); - const model = scene.primitives.add( - Model.fromGltf({ - url: dracoCesiumManUrl, - }) - ); + const decoder = DracoLoader._getDecoderTaskProcessor(); + spyOn(decoder, "scheduleTask").and.callFake(function () { + return Promise.reject({ message: "Custom error" }); + }); - return Promise.all([ - pollToPromise( - function () { - scene.renderForSpecs(); - return model.loader._state === 7; // FAILED - }, - { timeout: 10000 } - ), - model.readyPromise, - ]); + const model = scene.primitives.add( + await Model.fromGltfAsync({ + url: dracoCesiumManUrl, }) - .then(function (e) { - fail("Should not resolve"); - }) - .catch(function (e) { - expect(e).toBeDefined(); - expect( - e.message.includes(`Failed to load model: ${dracoCesiumManUrl}`) - ).toBe(true); - expect(e.message.includes(`Failed to load Draco`)).toBe(true); - expect(e.message.includes(`Custom error`)).toBe(true); - }); + ); + + let failed = false; + model.errorEvent.addEventListener((e) => { + expect(e).toBeInstanceOf(RuntimeError); + expect(e.message).toContain( + `Failed to load model: ${dracoCesiumManUrl}` + ); + expect(e.message).toContain("Failed to load Draco"); + expect(e.message).toContain("Custom error"); + failed = true; + }); + + await pollToPromise( + function () { + scene.renderForSpecs(); + return failed; + }, + { timeout: 10000 } + ); }); it("renders model without animations added", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, offset: animatedTriangleOffset, @@ -771,7 +869,7 @@ describe( }); it("renders model with animations added", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: animatedTriangleUrl, offset: animatedTriangleOffset, @@ -804,7 +902,7 @@ describe( }); it("renders model with CESIUM_RTC extension", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxCesiumRtcUrl, }, @@ -815,7 +913,7 @@ describe( }); it("adds animation to draco-compressed model", function () { - return loadAndZoomToModel({ gltf: dracoCesiumManUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: dracoCesiumManUrl }, scene).then( function (model) { verifyRender(model, true); @@ -840,7 +938,7 @@ describe( const resource = Resource.createIfNeeded(boxInstancedNoNormalsUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxInstancedNoNormalsUrl, @@ -861,7 +959,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), show: false }, scene ).then(function (model) { @@ -877,7 +975,7 @@ describe( }); it("renders in 2D", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -893,7 +991,7 @@ describe( }); it("renders in 2D over the IDL", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -919,7 +1017,7 @@ describe( }); it("renders in CV", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -936,7 +1034,7 @@ describe( }); it("renders in CV after draw commands are reset", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -959,7 +1057,7 @@ describe( }); it("projectTo2D works for 2D", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -977,7 +1075,7 @@ describe( }); it("projectTo2D works for CV", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -996,7 +1094,7 @@ describe( }); it("does not render during morph", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -1024,7 +1122,7 @@ describe( it("renders model with style", function () { let model; let style; - return loadAndZoomToModel({ gltf: buildingsMetadata }, scene).then( + return loadAndZoomToModelAsync({ gltf: buildingsMetadata }, scene).then( function (result) { model = result; // Renders without style. @@ -1088,7 +1186,7 @@ describe( const credit = new Credit("User Credit"); const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxTexturedGltfUrl, @@ -1111,7 +1209,7 @@ describe( const creditString = "User Credit"; const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxTexturedGltfUrl, @@ -1133,7 +1231,7 @@ describe( it("gets copyrights from gltf", function () { const resource = Resource.createIfNeeded(boxWithCreditsUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxWithCreditsUrl, @@ -1162,7 +1260,7 @@ describe( it("displays all types of credits", function () { const resource = Resource.createIfNeeded(boxWithCreditsUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxWithCreditsUrl, @@ -1195,7 +1293,7 @@ describe( it("initializes with showCreditsOnScreen", function () { const resource = Resource.createIfNeeded(boxWithCreditsUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxWithCreditsUrl, @@ -1227,7 +1325,7 @@ describe( it("changing showCreditsOnScreen works", function () { const resource = Resource.createIfNeeded(boxWithCreditsUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxWithCreditsUrl, @@ -1285,7 +1383,7 @@ describe( it("showCreditsOnScreen overrides existing credit setting", function () { const resource = Resource.createIfNeeded(boxTexturedGltfUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: gltf, basePath: boxTexturedGltfUrl, @@ -1336,7 +1434,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), enableDebugWireframe: true }, sceneWithWebgl1 ).then(function (model) { @@ -1349,7 +1447,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), enableDebugWireframe: false }, sceneWithWebgl1 ).then(function (model) { @@ -1383,7 +1481,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer) }, scene ).then(function (model) { @@ -1395,7 +1493,7 @@ describe( }); it("debugWireframe works for model without indices", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: triangleWithoutIndicesUrl, enableDebugWireframe: true }, scene ).then(function (model) { @@ -1406,7 +1504,7 @@ describe( }); it("debugWireframe works for model with triangle strip", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: triangleStripUrl, enableDebugWireframe: true }, scene ).then(function (model) { @@ -1415,7 +1513,7 @@ describe( }); it("debugWireframe works for model with triangle fan", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: triangleFanUrl, enableDebugWireframe: true }, scene ).then(function (model) { @@ -1424,7 +1522,7 @@ describe( }); it("debugWireframe ignores points", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: pointCloudUrl, enableDebugWireframe: true }, scene ).then(function (model) { @@ -1451,7 +1549,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), debugShowBoundingVolume: true }, scene ).then(function (model) { @@ -1472,8 +1570,8 @@ describe( }); describe("boundingSphere", function () { - it("boundingSphere throws if model is not ready", function () { - const model = Model.fromGltf({ + it("boundingSphere throws if model is not ready", async function () { + const model = await Model.fromGltfAsync({ url: boxTexturedGlbUrl, }); expect(function () { @@ -1485,7 +1583,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer) }, scene ).then(function (model) { @@ -1503,7 +1601,7 @@ describe( it("boundingSphere accounts for axis correction", function () { const resource = Resource.createIfNeeded(riggedFigureUrl); return resource.fetchJson().then(function (gltf) { - return loadAndZoomToModel({ gltf: gltf }, scene).then(function ( + return loadAndZoomToModelAsync({ gltf: gltf }, scene).then(function ( model ) { // The bounding sphere should transform from z-forward @@ -1523,7 +1621,7 @@ describe( }); it("boundingSphere accounts for transform from CESIUM_RTC extension", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxCesiumRtcUrl, }, @@ -1536,7 +1634,7 @@ describe( }); it("boundingSphere updates bounding sphere when invoked", function () { - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { const expectedRadius = 0.8660254037844386; const translation = new Cartesian3(10, 0, 0); @@ -1563,7 +1661,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1584,7 +1682,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1617,7 +1715,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1641,7 +1739,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1667,7 +1765,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1700,7 +1798,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, allowPicking: false, @@ -1724,7 +1822,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, offset: offset, @@ -1761,7 +1859,7 @@ describe( } it("resets draw commands when the style commands needed are changed", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -1807,7 +1905,7 @@ describe( if (webglStub) { return; } - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxInstanced, instanceFeatureIdLabel: "section", @@ -1819,7 +1917,7 @@ describe( }); it("selects feature table for feature ID textures", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: microcosm, }, @@ -1830,7 +1928,7 @@ describe( }); it("selects feature table for feature ID attributes", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -1841,7 +1939,7 @@ describe( }); it("featureIdLabel setter works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: buildingsMetadata, }, @@ -1859,7 +1957,7 @@ describe( if (webglStub) { return; } - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxInstanced, }, @@ -1879,7 +1977,7 @@ describe( const translation = new Cartesian3(10, 0, 0); const transform = Matrix4.fromTranslation(translation); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -1905,7 +2003,7 @@ describe( ModelSceneGraph.prototype, "updateModelMatrix" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, forwardAxis: Axis.X }, scene ).then(function (model) { @@ -1932,7 +2030,7 @@ describe( it("changing model matrix affects bounding sphere", function () { const translation = new Cartesian3(10, 0, 0); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, forwardAxis: Axis.X }, scene ).then(function (model) { @@ -1951,7 +2049,7 @@ describe( }); it("changing model matrix in 2D mode works if projectTo2D is false", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -1974,7 +2072,7 @@ describe( }); it("changing model matrix in 2D mode throws if projectTo2D is true", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: modelMatrix, @@ -2059,7 +2157,7 @@ describe( }); it("initializes with height reference", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, heightReference: HeightReference.CLAMP_TO_GROUND, @@ -2076,7 +2174,7 @@ describe( }); it("changing height reference works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, heightReference: HeightReference.NONE, @@ -2100,7 +2198,7 @@ describe( }); it("creates height update callback when initializing with height reference", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2119,7 +2217,7 @@ describe( }); it("creates height update callback after setting height reference", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2143,7 +2241,7 @@ describe( }); it("updates height reference callback when the height reference changes", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2173,7 +2271,7 @@ describe( const modelMatrix = Transforms.eastNorthUpToFixedFrame( Cartesian3.fromDegrees(-72.0, 40.0) ); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Matrix4.clone(modelMatrix), @@ -2204,7 +2302,7 @@ describe( }); it("height reference callback updates the position", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2232,7 +2330,7 @@ describe( }); it("height reference accounts for change in terrain provider", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2256,7 +2354,7 @@ describe( }); it("throws when initializing height reference with no scene", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2274,7 +2372,7 @@ describe( }); it("throws when changing height reference with no scene", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2292,7 +2390,7 @@ describe( }); it("throws when initializing height reference with no globe", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2310,7 +2408,7 @@ describe( }); it("throws when changing height reference with no globe", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2328,7 +2426,7 @@ describe( }); it("destroys height reference callback", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: Transforms.eastNorthUpToFixedFrame( @@ -2353,7 +2451,7 @@ describe( const near = 10.0; const far = 100.0; const condition = new DistanceDisplayCondition(near, far); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, distanceDisplayCondition: condition, @@ -2368,7 +2466,7 @@ describe( const near = 10.0; const far = 100.0; const condition = new DistanceDisplayCondition(near, far); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, }, @@ -2388,7 +2486,7 @@ describe( const near = 10.0; const far = 100.0; const condition = new DistanceDisplayCondition(near, far); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, }, @@ -2426,7 +2524,7 @@ describe( const near = 101.0; const far = 100.0; const condition = new DistanceDisplayCondition(near, far); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, }, @@ -2441,7 +2539,7 @@ describe( describe("model color", function () { it("initializes with model color", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, color: Color.BLACK }, scene ).then(function (model) { @@ -2450,20 +2548,21 @@ describe( }); it("changing model color works", function () { - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - verifyRender(model, true); + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + verifyRender(model, true); - model.color = Color.BLACK; - verifyRender(model, false); + model.color = Color.BLACK; + verifyRender(model, false); - model.color = Color.RED; - verifyRender(model, true); + model.color = Color.RED; + verifyRender(model, true); - model.color = undefined; - verifyRender(model, true); - } - ); + model.color = undefined; + verifyRender(model, true); + }); }); it("renders with translucent color", function () { @@ -2471,7 +2570,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2503,7 +2602,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, color: Color.fromAlpha(Color.BLACK, 0.0), @@ -2553,7 +2652,7 @@ describe( const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); it("initializes with ColorBlendMode.HIGHLIGHT", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2575,7 +2674,7 @@ describe( }); it("initializes with ColorBlendMode.REPLACE", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2597,7 +2696,7 @@ describe( }); it("initializes with ColorBlendMode.MIX", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2619,7 +2718,7 @@ describe( }); it("toggles colorBlendMode", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2661,7 +2760,7 @@ describe( const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); it("initializes with colorBlendAmount", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2686,7 +2785,7 @@ describe( }); it("changing colorBlendAmount works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, offset: offset, @@ -2736,7 +2835,7 @@ describe( describe("silhouette", function () { it("initializes with silhouette size", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0 }, scene ).then(function (model) { @@ -2751,33 +2850,34 @@ describe( }); it("changing silhouette size works", function () { - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - const commands = scene.frameState.commandList; - scene.renderForSpecs(); - expect(commands.length).toBe(1); - expect(commands[0].renderState.stencilTest.enabled).toBe(false); - expect(commands[0].pass).toBe(Pass.OPAQUE); + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + const commands = scene.frameState.commandList; + scene.renderForSpecs(); + expect(commands.length).toBe(1); + expect(commands[0].renderState.stencilTest.enabled).toBe(false); + expect(commands[0].pass).toBe(Pass.OPAQUE); - model.silhouetteSize = 1.0; - scene.renderForSpecs(); - expect(commands.length).toBe(2); - expect(commands[0].renderState.stencilTest.enabled).toBe(true); - expect(commands[0].pass).toBe(Pass.OPAQUE); - expect(commands[1].renderState.stencilTest.enabled).toBe(true); - expect(commands[1].pass).toBe(Pass.OPAQUE); + model.silhouetteSize = 1.0; + scene.renderForSpecs(); + expect(commands.length).toBe(2); + expect(commands[0].renderState.stencilTest.enabled).toBe(true); + expect(commands[0].pass).toBe(Pass.OPAQUE); + expect(commands[1].renderState.stencilTest.enabled).toBe(true); + expect(commands[1].pass).toBe(Pass.OPAQUE); - model.silhouetteSize = 0.0; - scene.renderForSpecs(); - expect(commands.length).toBe(1); - expect(commands[0].renderState.stencilTest.enabled).toBe(false); - expect(commands[0].pass).toBe(Pass.OPAQUE); - } - ); + model.silhouetteSize = 0.0; + scene.renderForSpecs(); + expect(commands.length).toBe(1); + expect(commands[0].renderState.stencilTest.enabled).toBe(false); + expect(commands[0].pass).toBe(Pass.OPAQUE); + }); }); it("silhouette works with translucent color", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, @@ -2796,7 +2896,7 @@ describe( }); it("silhouette is disabled by invisible color", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0 }, scene ).then(function (model) { @@ -2817,7 +2917,7 @@ describe( }); it("silhouette works for invisible model", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, @@ -2843,7 +2943,7 @@ describe( }); it("silhouette works for translucent model", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, @@ -2865,7 +2965,7 @@ describe( }); it("silhouette works for translucent model and translucent silhouette color", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, @@ -2886,14 +2986,14 @@ describe( }); it("silhouette works for multiple models", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, }, scene ).then(function (model) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, silhouetteSize: 1.0, @@ -2920,7 +3020,7 @@ describe( describe("light color", function () { it("initializes with light color", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, lightColor: Cartesian3.ZERO }, scene ).then(function (model) { @@ -2929,34 +3029,35 @@ describe( }); it("changing light color works", function () { - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - model.lightColor = Cartesian3.ZERO; - verifyRender(model, false); + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + model.lightColor = Cartesian3.ZERO; + verifyRender(model, false); - model.lightColor = new Cartesian3(1.0, 0.0, 0.0); - verifyRender(model, true); + model.lightColor = new Cartesian3(1.0, 0.0, 0.0); + verifyRender(model, true); - model.lightColor = undefined; - verifyRender(model, true); - } - ); + model.lightColor = undefined; + verifyRender(model, true); + }); }); it("light color doesn't affect unlit models", function () { - return loadAndZoomToModel({ gltf: boxUnlitUrl }, scene).then(function ( - model - ) { - const options = { - zoomToModel: false, - }; - // Move the camera to face one of the two boxes. - scene.camera.moveRight(1.0); - verifyRender(model, true, options); + return loadAndZoomToModelAsync({ gltf: boxUnlitUrl }, scene).then( + function (model) { + const options = { + zoomToModel: false, + }; + // Move the camera to face one of the two boxes. + scene.camera.moveRight(1.0); + verifyRender(model, true, options); - model.lightColor = Cartesian3.ZERO; - verifyRender(model, true, options); - }); + model.lightColor = Cartesian3.ZERO; + verifyRender(model, true, options); + } + ); }); }); @@ -2970,7 +3071,7 @@ describe( imageBasedLightingFactor: Cartesian2.ZERO, luminanceAtZenith: 0.5, }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, imageBasedLighting: ibl }, scene ).then(function (model) { @@ -2979,52 +3080,54 @@ describe( }); it("creates default imageBasedLighting", function () { - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - const imageBasedLighting = model.imageBasedLighting; - expect(imageBasedLighting).toBeDefined(); - expect( - Cartesian2.equals( - imageBasedLighting.imageBasedLightingFactor, - new Cartesian2(1, 1) - ) - ).toBe(true); - expect(imageBasedLighting.luminanceAtZenith).toBe(0.2); - expect( - imageBasedLighting.sphericalHarmonicCoefficients - ).toBeUndefined(); - expect(imageBasedLighting.specularEnvironmentMaps).toBeUndefined(); - } - ); + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + const imageBasedLighting = model.imageBasedLighting; + expect(imageBasedLighting).toBeDefined(); + expect( + Cartesian2.equals( + imageBasedLighting.imageBasedLightingFactor, + new Cartesian2(1, 1) + ) + ).toBe(true); + expect(imageBasedLighting.luminanceAtZenith).toBe(0.2); + expect( + imageBasedLighting.sphericalHarmonicCoefficients + ).toBeUndefined(); + expect(imageBasedLighting.specularEnvironmentMaps).toBeUndefined(); + }); }); it("changing imageBasedLighting works", function () { const imageBasedLighting = new ImageBasedLighting({ imageBasedLightingFactor: Cartesian2.ZERO, }); - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - const renderOptions = { - scene: scene, - time: defaultDate, - }; + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + const renderOptions = { + scene: scene, + time: defaultDate, + }; - let result; - verifyRender(model, true); - expect(renderOptions).toRenderAndCall(function (rgba) { - result = rgba; - }); + let result; + verifyRender(model, true); + expect(renderOptions).toRenderAndCall(function (rgba) { + result = rgba; + }); - model.imageBasedLighting = imageBasedLighting; - expect(renderOptions).toRenderAndCall(function (rgba) { - expect(rgba).not.toEqual(result); - }); - } - ); + model.imageBasedLighting = imageBasedLighting; + expect(renderOptions).toRenderAndCall(function (rgba) { + expect(rgba).not.toEqual(result); + }); + }); }); it("changing imageBasedLightingFactor works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, imageBasedLighting: new ImageBasedLighting({ @@ -3053,7 +3156,7 @@ describe( }); it("changing luminanceAtZenith works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, imageBasedLighting: new ImageBasedLighting({ @@ -3131,7 +3234,7 @@ describe( 0.121102528320197 ); // L22, irradiance, pre-scaled base const coefficients = [L00, L1_1, L10, L11, L2_2, L2_1, L20, L21, L22]; - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, imageBasedLighting: new ImageBasedLighting({ @@ -3166,7 +3269,7 @@ describe( return; } const url = "./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2"; - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boomBoxUrl, scale: 10.0, @@ -3209,7 +3312,7 @@ describe( it("renders when specularEnvironmentMaps aren't supported", function () { spyOn(OctahedralProjectedCubeMap, "isSupported").and.returnValue(false); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boomBoxUrl, scale: 10.0, @@ -3224,7 +3327,7 @@ describe( describe("scale", function () { it("initializes with scale", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -3246,7 +3349,7 @@ describe( ModelSceneGraph.prototype, "updateModelMatrix" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -3271,7 +3374,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), scale: 10, @@ -3308,7 +3411,7 @@ describe( const resource = Resource.createIfNeeded(boxWithOffsetUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), scale: 10, @@ -3365,7 +3468,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), upAxis: Axis.Z, @@ -3398,7 +3501,7 @@ describe( ModelSceneGraph.prototype, "updateModelMatrix" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -3433,7 +3536,7 @@ describe( ModelSceneGraph.prototype, "updateModelMatrix" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -3478,7 +3581,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), upAxis: Axis.Z, @@ -3500,7 +3603,7 @@ describe( ModelSceneGraph.prototype, "updateModelMatrix" ).and.callThrough(); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, upAxis: Axis.Z, @@ -3528,7 +3631,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), scale: 20, @@ -3566,7 +3669,7 @@ describe( const resource = Resource.createIfNeeded(boxTexturedGlbUrl); const loadPromise = resource.fetchArrayBuffer(); return loadPromise.then(function (buffer) { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: new Uint8Array(buffer), minimumPixelSize: 1, @@ -3602,7 +3705,7 @@ describe( }); it("does not issue draw commands when ignoreCommands is true", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, }, @@ -3618,7 +3721,7 @@ describe( describe("frustum culling ", function () { it("enables frustum culling", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, cull: true, @@ -3641,7 +3744,7 @@ describe( }); it("disables frustum culling", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, cull: false, @@ -3675,7 +3778,7 @@ describe( ); it("enables back-face culling", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxBackFaceCullingUrl, backFaceCulling: true, @@ -3690,7 +3793,7 @@ describe( }); it("disables back-face culling", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxBackFaceCullingUrl, backFaceCulling: false, @@ -3705,7 +3808,7 @@ describe( }); it("ignores back-face culling when translucent", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxBackFaceCullingUrl, backFaceCulling: true, @@ -3726,7 +3829,7 @@ describe( }); it("toggles back-face culling at runtime", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxBackFaceCullingUrl, backFaceCulling: false, @@ -3747,7 +3850,7 @@ describe( }); it("ignores back-face culling toggles when translucent", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxBackFaceCullingUrl, backFaceCulling: false, @@ -3776,7 +3879,7 @@ describe( }); it("reverses winding order for negatively scaled models", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, modelMatrix: Matrix4.fromUniformScale(-1.0), @@ -3815,12 +3918,12 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, clippingPlanes: clippingPlanes }, scene ) .then(function (model) { - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene); + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene); }) .then(function (model2) { expect(function () { @@ -3834,7 +3937,7 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { const gl = scene.frameState.context._gl; spyOn(gl, "texImage2D").and.callThrough(); @@ -3860,7 +3963,7 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, clippingPlanes: clippingPlanes }, scene ).then(function (model) { @@ -3881,7 +3984,7 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { let modelColor; verifyRender(model, true); @@ -3909,7 +4012,7 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, clippingPlanes: clippingPlanes }, scene ).then(function (model) { @@ -3925,7 +4028,7 @@ describe( const clippingPlanes = new ClippingPlaneCollection({ planes: [plane], }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, clippingPlanes: clippingPlanes }, scene ).then(function (model) { @@ -3944,7 +4047,7 @@ describe( planes: [modelClippedPlane], }); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, clippingPlanes: clippingPlanes }, scene ).then(function (model) { @@ -3972,7 +4075,7 @@ describe( edgeColor: Color.BLUE, }); - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { let modelColor; verifyRender(model, true); @@ -4002,7 +4105,7 @@ describe( ], unionClippingRegions: true, }); - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { verifyRender(model, true); @@ -4017,7 +4120,7 @@ describe( }); it("destroys attached ClippingPlaneCollections", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, }, @@ -4039,7 +4142,7 @@ describe( it("destroys ClippingPlaneCollections that are detached", function () { let clippingPlanes; - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGlbUrl, }, @@ -4058,7 +4161,7 @@ describe( }); it("renders with classificationType", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: boxTexturedGltfUrl, classificationType: ClassificationType.CESIUM_3D_TILE, @@ -4076,16 +4179,17 @@ describe( describe("statistics", function () { it("gets triangle count", function () { - return loadAndZoomToModel({ gltf: boxTexturedGltfUrl }, scene).then( - function (model) { - const statistics = model.statistics; - expect(statistics.trianglesLength).toEqual(12); - } - ); + return loadAndZoomToModelAsync( + { gltf: boxTexturedGltfUrl }, + scene + ).then(function (model) { + const statistics = model.statistics; + expect(statistics.trianglesLength).toEqual(12); + }); }); it("gets point count", function () { - return loadAndZoomToModel({ gltf: pointCloudUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: pointCloudUrl }, scene).then( function (model) { const statistics = model.statistics; expect(statistics.pointsLength).toEqual(2500); @@ -4094,7 +4198,7 @@ describe( }); it("gets memory usage for geometry and textures", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxTexturedGltfUrl, incrementallyLoadTextures: false }, scene ).then(function (model) { @@ -4109,7 +4213,7 @@ describe( }); it("gets memory usage for property tables", function () { - return loadAndZoomToModel({ gltf: buildingsMetadata }, scene).then( + return loadAndZoomToModelAsync({ gltf: buildingsMetadata }, scene).then( function (model) { const expectedPropertyTableMemory = 110; @@ -4123,8 +4227,8 @@ describe( }); describe("AGI_articulations", function () { - it("setArticulationStage throws when model is not ready", function () { - const model = Model.fromGltf({ + it("setArticulationStage throws when model is not ready", async function () { + const model = await Model.fromGltfAsync({ url: boxArticulationsUrl, }); @@ -4134,7 +4238,7 @@ describe( }); it("setArticulationStage throws with invalid value", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4146,8 +4250,8 @@ describe( }); }); - it("applyArticulations throws when model is not ready", function () { - const model = Model.fromGltf({ + it("applyArticulations throws when model is not ready", async function () { + const model = await Model.fromGltfAsync({ url: boxArticulationsUrl, }); @@ -4157,7 +4261,7 @@ describe( }); it("applies articulations", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4185,8 +4289,8 @@ describe( }); describe("getNode", function () { - it("getNode throws when model is not ready", function () { - const model = Model.fromGltf({ + it("getNode throws when model is not ready", async function () { + const model = await Model.fromGltfAsync({ url: boxArticulationsUrl, }); @@ -4196,7 +4300,7 @@ describe( }); it("getNode throws when name is undefined", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4209,7 +4313,7 @@ describe( }); it("getNode returns undefined for nonexistent node", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4221,7 +4325,7 @@ describe( }); it("getNode returns a node", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4239,7 +4343,7 @@ describe( }); it("changing node.show works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4255,7 +4359,7 @@ describe( }); it("changing node.matrix works", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { gltf: boxArticulationsUrl, }, @@ -4276,7 +4380,7 @@ describe( it("destroy works", function () { spyOn(ShaderProgram.prototype, "destroy").and.callThrough(); - return loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene).then( + return loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene).then( function (model) { const resources = model._pipelineResources; const loader = model._loader; @@ -4309,8 +4413,8 @@ describe( it("destroy doesn't destroy resources when they're in use", function () { return Promise.all([ - loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene), - loadAndZoomToModel({ gltf: boxTexturedGlbUrl }, scene), + loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene), + loadAndZoomToModelAsync({ gltf: boxTexturedGlbUrl }, scene), ]).then(function (models) { const cacheEntries = ResourceCache.cacheEntries; let cacheKey; diff --git a/packages/engine/Specs/Scene/Model/loadAndZoomToModel.js b/packages/engine/Specs/Scene/Model/loadAndZoomToModel.js deleted file mode 100644 index 833f1e9f9e4..00000000000 --- a/packages/engine/Specs/Scene/Model/loadAndZoomToModel.js +++ /dev/null @@ -1,86 +0,0 @@ -import { Model } from "../../../index.js"; -import pollToPromise from "../../../../../Specs/pollToPromise.js"; - -function loadAndZoomToModel(options, scene) { - return new Promise(function (resolve, reject) { - let model; - try { - model = Model.fromGltf({ - url: options.url, - gltf: options.gltf, - basePath: options.basePath, - show: options.show, - modelMatrix: options.modelMatrix, - scale: options.scale, - minimumPixelSize: options.minimumPixelSize, - maximumScale: options.maximumScale, - id: options.id, - allowPicking: options.allowPicking, - incrementallyLoadTextures: options.incrementallyLoadTextures, - asynchronous: options.asynchronous, - clampAnimations: options.clampAnimations, - shadows: options.shadows, - debugShowBoundingVolume: options.debugShowBoundingVolume, - enableDebugWireframe: options.enableDebugWireframe, - debugWireframe: options.debugWireframe, - cull: options.cull, - opaquePass: options.opaquePass, - upAxis: options.upAxis, - forwardAxis: options.forwardAxis, - customShader: options.customShader, - content: options.content, - heightReference: options.heightReference, - scene: options.scene, - distanceDisplayCondition: options.distanceDisplayCondition, - color: options.color, - colorBlendAmount: options.colorBlendAmount, - colorBlendMode: options.colorBlendMode, - silhouetteColor: options.silhouetteColor, - silhouetteSize: options.silhouetteSize, - clippingPlanes: options.clippingPlanes, - lightColor: options.lightColor, - imageBasedLighting: options.imageBasedLighting, - backFaceCulling: options.backFaceCulling, - credit: options.credit, - showCreditsOnScreen: options.showCreditsOnScreen, - projectTo2D: options.projectTo2D, - featureIdLabel: options.featureIdLabel, - instanceFeatureIdLabel: options.instanceFeatureIdLabel, - classificationType: options.classificationType, - }); - } catch (error) { - reject(error); - return; - } - - scene.primitives.add(model); - - let finished = false; - model.readyPromise - .then(function (model) { - finished = true; - scene.camera.flyToBoundingSphere(model.boundingSphere, { - duration: 0, - offset: options.offset, - }); - - resolve(model); - }) - .catch(function (error) { - finished = true; - reject(error); - }); - - pollToPromise( - function () { - scene.renderForSpecs(); - return finished; - }, - { timeout: 10000 } - ).catch(function (error) { - reject(error); - }); - }); -} - -export default loadAndZoomToModel; diff --git a/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js b/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js new file mode 100644 index 00000000000..1c645260b02 --- /dev/null +++ b/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js @@ -0,0 +1,67 @@ +import { Model } from "../../../index.js"; +import pollToPromise from "../../../../../Specs/pollToPromise.js"; + +async function loadAndZoomToModelAsync(options, scene) { + const model = await Model.fromGltfAsync({ + url: options.url, + gltf: options.gltf, + basePath: options.basePath, + show: options.show, + modelMatrix: options.modelMatrix, + scale: options.scale, + minimumPixelSize: options.minimumPixelSize, + maximumScale: options.maximumScale, + id: options.id, + allowPicking: options.allowPicking, + incrementallyLoadTextures: options.incrementallyLoadTextures, + asynchronous: options.asynchronous, + clampAnimations: options.clampAnimations, + shadows: options.shadows, + debugShowBoundingVolume: options.debugShowBoundingVolume, + enableDebugWireframe: options.enableDebugWireframe, + debugWireframe: options.debugWireframe, + cull: options.cull, + opaquePass: options.opaquePass, + upAxis: options.upAxis, + forwardAxis: options.forwardAxis, + customShader: options.customShader, + content: options.content, + heightReference: options.heightReference, + scene: options.scene, + distanceDisplayCondition: options.distanceDisplayCondition, + color: options.color, + colorBlendAmount: options.colorBlendAmount, + colorBlendMode: options.colorBlendMode, + silhouetteColor: options.silhouetteColor, + silhouetteSize: options.silhouetteSize, + clippingPlanes: options.clippingPlanes, + lightColor: options.lightColor, + imageBasedLighting: options.imageBasedLighting, + backFaceCulling: options.backFaceCulling, + credit: options.credit, + showCreditsOnScreen: options.showCreditsOnScreen, + projectTo2D: options.projectTo2D, + featureIdLabel: options.featureIdLabel, + instanceFeatureIdLabel: options.instanceFeatureIdLabel, + classificationType: options.classificationType, + }); + + scene.primitives.add(model); + + await pollToPromise( + function () { + scene.renderForSpecs(); + return model.ready; + }, + { timeout: 10000 } + ); + + scene.camera.flyToBoundingSphere(model.boundingSphere, { + duration: 0, + offset: options.offset, + }); + + return model; +} + +export default loadAndZoomToModelAsync; diff --git a/packages/engine/Specs/Scene/PostProcessStageLibrarySpec.js b/packages/engine/Specs/Scene/PostProcessStageLibrarySpec.js index 886e90aa927..7f398be1e77 100644 --- a/packages/engine/Specs/Scene/PostProcessStageLibrarySpec.js +++ b/packages/engine/Specs/Scene/PostProcessStageLibrarySpec.js @@ -10,7 +10,7 @@ import createCanvas from "../../../../Specs/createCanvas.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; import ViewportPrimitive from "../../../../Specs/ViewportPrimitive.js"; -import loadAndZoomToModel from "./Model/loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./Model/loadAndZoomToModelAsync.js"; describe( "Scene/PostProcessStageLibrary", @@ -87,7 +87,7 @@ describe( }); it("per-feature black and white", function () { - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: boxTexturedUrl, }, @@ -305,7 +305,7 @@ describe( new HeadingPitchRoll() ); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: boxTexturedUrl, // Ensure the texture loads every time @@ -426,7 +426,7 @@ describe( new HeadingPitchRoll() ); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: boxTexturedUrl, // Ensure the texture loads every time diff --git a/packages/engine/Specs/Scene/PostProcessStageSpec.js b/packages/engine/Specs/Scene/PostProcessStageSpec.js index 1dd5b786a7c..486f528d1b6 100644 --- a/packages/engine/Specs/Scene/PostProcessStageSpec.js +++ b/packages/engine/Specs/Scene/PostProcessStageSpec.js @@ -12,7 +12,7 @@ import { import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; -import loadAndZoomToModel from "./Model/loadAndZoomToModel.js"; +import loadAndZoomToModelAsync from "./Model/loadAndZoomToModelAsync.js"; describe( "Scene/PostProcessStage", @@ -239,7 +239,7 @@ describe( // the camera just a little const offset = new HeadingPitchRange(0, -CesiumMath.PI_OVER_FOUR, 2); - return loadAndZoomToModel( + return loadAndZoomToModelAsync( { url: "./Data/Models/glTF-2.0/BoxTextured/glTF/BoxTextured.gltf", offset: offset, diff --git a/packages/engine/Specs/Scene/ResourceCacheSpec.js b/packages/engine/Specs/Scene/ResourceCacheSpec.js index b476fd69e01..aaded214a56 100644 --- a/packages/engine/Specs/Scene/ResourceCacheSpec.js +++ b/packages/engine/Specs/Scene/ResourceCacheSpec.js @@ -1,7 +1,12 @@ import { - ComponentDatatype, - DracoLoader, + BufferLoader, + GltfBufferViewLoader, + GltfDracoLoader, + GltfImageLoader, + GltfIndexBufferLoader, GltfJsonLoader, + GltfTextureLoader, + GltfVertexBufferLoader, MetadataSchemaLoader, Resource, ResourceCache, @@ -10,1286 +15,946 @@ import { } from "../../index.js"; import concatTypedArrays from "../../../../Specs/concatTypedArrays.js"; import createScene from "../../../../Specs/createScene.js"; -import generateJsonBuffer from "../../../../Specs/generateJsonBuffer.js"; -import waitForLoaderProcess from "../../../../Specs/waitForLoaderProcess.js"; - -describe( - "ResourceCache", - function () { - const schemaResource = new Resource({ - url: "https://example.com/schema.json", - }); - const schemaJson = {}; - - const bufferParentResource = new Resource({ - url: "https://example.com/model.glb", - }); - const bufferResource = new Resource({ - url: "https://example.com/external.bin", - }); - - const gltfUri = "https://example.com/model.glb"; - const gltfResource = new Resource({ - url: gltfUri, - }); - - const image = new Image(); - image.src = - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="; - - const positions = new Float32Array([-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0]); // prettier-ignore - const normals = new Float32Array([-1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0]); // prettier-ignore - const indices = new Uint16Array([0, 1, 2]); - - const bufferTypedArray = concatTypedArrays([positions, normals, indices]); - const bufferArrayBuffer = bufferTypedArray.buffer; - - const dracoBufferTypedArray = new Uint8Array([ - 1, - 3, - 7, - 15, - 31, - 63, - 127, - 255, - ]); - const dracoArrayBuffer = dracoBufferTypedArray.buffer; - - const decodedPositions = new Uint16Array([0, 0, 0, 65535, 65535, 65535, 0, 65535, 0]); // prettier-ignore - const decodedNormals = new Uint8Array([0, 255, 128, 128, 255, 0]); - const decodedIndices = new Uint16Array([0, 1, 2]); - - const decodeDracoResults = { - indexArray: { - typedArray: decodedIndices, - numberOfIndices: decodedIndices.length, +describe("ResourceCache", function () { + const schemaResource = new Resource({ + url: "https://example.com/schema.json", + }); + const schemaJson = {}; + + const bufferParentResource = new Resource({ + url: "https://example.com/model.glb", + }); + const bufferResource = new Resource({ + url: "https://example.com/external.bin", + }); + + const gltfUri = "https://example.com/model.glb"; + + const gltfResource = new Resource({ + url: gltfUri, + }); + + const image = new Image(); + image.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII="; + + const positions = new Float32Array([-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0]); // prettier-ignore + const normals = new Float32Array([-1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0]); // prettier-ignore + const indices = new Uint16Array([0, 1, 2]); + + const bufferTypedArray = concatTypedArrays([positions, normals, indices]); + const gltfDraco = { + buffers: [ + { + uri: "external.bin", + byteLength: 8, + }, + ], + bufferViews: [ + { + buffer: 0, + byteOffset: 4, + byteLength: 4, + }, + ], + accessors: [ + { + componentType: 5126, + count: 3, + max: [-1.0, -1.0, -1.0], + min: [1.0, 1.0, 1.0], + type: "VEC3", + }, + { + componentType: 5126, + count: 3, + type: "VEC3", }, - attributeData: { - POSITION: { - array: decodedPositions, - data: { - byteOffset: 0, - byteStride: 6, - componentDatatype: ComponentDatatype.UNSIGNED_SHORT, - componentsPerAttribute: 3, - normalized: false, - quantization: { - octEncoded: false, - quantizationBits: 14, - minValues: [-1.0, -1.0, -1.0], - range: 2.0, + { + componentType: 5123, + count: 3, + type: "SCALAR", + }, + ], + meshes: [ + { + primitives: [ + { + attributes: { + POSITION: 0, + NORMAL: 1, + }, + indices: 2, + extensions: { + KHR_draco_mesh_compression: { + bufferView: 0, + attributes: { + POSITION: 0, + NORMAL: 1, + }, + }, }, }, - }, - NORMAL: { - array: decodedNormals, - data: { - byteOffset: 0, - byteStride: 2, - componentDatatype: ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute: 2, - normalized: false, - quantization: { - octEncoded: true, - quantizationBits: 10, + ], + }, + ], + }; + + const dracoExtension = + gltfDraco.meshes[0].primitives[0].extensions.KHR_draco_mesh_compression; + + const gltfUncompressed = { + buffers: [ + { + uri: "external.bin", + byteLength: 78, + }, + ], + bufferViews: [ + { + buffer: 0, + byteOffset: 0, + byteLength: 36, + }, + { + buffer: 0, + byteOffset: 36, + byteLength: 36, + }, + { + buffer: 0, + byteOffset: 72, + byteLength: 6, + }, + ], + accessors: [ + { + componentType: 5126, + count: 3, + max: [-1.0, -1.0, -1.0], + min: [1.0, 1.0, 1.0], + type: "VEC3", + bufferView: 0, + byteOffset: 0, + }, + { + componentType: 5126, + count: 3, + type: "VEC3", + bufferView: 1, + byteOffset: 0, + }, + { + componentType: 5123, + count: 3, + type: "SCALAR", + bufferView: 2, + byteOffset: 0, + }, + ], + meshes: [ + { + primitives: [ + { + attributes: { + POSITION: 0, + NORMAL: 1, }, + indices: 2, }, - }, + ], }, - }; + ], + }; - const gltfDraco = { - buffers: [ - { - uri: "external.bin", - byteLength: 8, - }, - ], - bufferViews: [ - { - buffer: 0, - byteOffset: 4, - byteLength: 4, - }, - ], - accessors: [ - { - componentType: 5126, - count: 3, - max: [-1.0, -1.0, -1.0], - min: [1.0, 1.0, 1.0], - type: "VEC3", - }, - { - componentType: 5126, - count: 3, - type: "VEC3", - }, - { - componentType: 5123, - count: 3, - type: "SCALAR", + const gltfWithTextures = { + images: [ + { + uri: "image.png", + }, + ], + textures: [ + { + source: 0, + }, + ], + materials: [ + { + emissiveTexture: { + index: 0, }, - ], - meshes: [ - { - primitives: [ - { - attributes: { - POSITION: 0, - NORMAL: 1, - }, - indices: 2, - extensions: { - KHR_draco_mesh_compression: { - bufferView: 0, - attributes: { - POSITION: 0, - NORMAL: 1, - }, - }, - }, - }, - ], + occlusionTexture: { + index: 1, }, - ], - }; + }, + ], + }; - const dracoExtension = - gltfDraco.meshes[0].primitives[0].extensions.KHR_draco_mesh_compression; + const mockFrameState = { + context: { + id: "01234", + }, + }; - const gltfUncompressed = { - buffers: [ - { - uri: "external.bin", - byteLength: 78, - }, - ], - bufferViews: [ - { - buffer: 0, - byteOffset: 0, - byteLength: 36, - }, - { - buffer: 0, - byteOffset: 36, - byteLength: 36, - }, - { - buffer: 0, - byteOffset: 72, - byteLength: 6, - }, - ], - accessors: [ - { - componentType: 5126, - count: 3, - max: [-1.0, -1.0, -1.0], - min: [1.0, 1.0, 1.0], - type: "VEC3", - bufferView: 0, - byteOffset: 0, - }, - { - componentType: 5126, - count: 3, - type: "VEC3", - bufferView: 1, - byteOffset: 0, - }, - { - componentType: 5123, - count: 3, - type: "SCALAR", - bufferView: 2, - byteOffset: 0, - }, - ], - meshes: [ - { - primitives: [ - { - attributes: { - POSITION: 0, - NORMAL: 1, - }, - indices: 2, - }, - ], - }, - ], - }; + const mockFrameState2 = { + context: { + id: "56789", + }, + }; - const gltfWithTextures = { - images: [ - { - uri: "image.png", - }, - ], - textures: [ - { - source: 0, - }, - ], - materials: [ - { - emissiveTexture: { - index: 0, - }, - occlusionTexture: { - index: 1, - }, - }, - ], - }; + let scene; - const mockFrameState = { - context: { - id: "01234", - }, - }; + beforeAll(function () { + scene = createScene(); + }); - const mockFrameState2 = { - context: { - id: "56789", - }, - }; + afterAll(function () { + scene.destroyForSpecs(); + }); - let scene; + afterEach(function () { + ResourceCache.clearForSpecs(); + }); - beforeAll(function () { - scene = createScene(); + it("adds resource", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, }); - - afterAll(function () { - scene.destroyForSpecs(); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, }); - afterEach(function () { - ResourceCache.clearForSpecs(); + ResourceCache.add(resourceLoader); + + const cacheEntry = ResourceCache.cacheEntries[cacheKey]; + expect(cacheEntry.referenceCount).toBe(1); + expect(cacheEntry.resourceLoader).toBe(resourceLoader); + }); + + it("add throws if resourceLoader is undefined", function () { + expect(() => ResourceCache.add()).toThrowDeveloperError(); + }); + + it("add throws if resourceLoader's cacheKey is undefined", function () { + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, }); - it("loads resource", function () { - const fetchJson = spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(schemaJson) - ); - - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); - - ResourceCache.load({ - resourceLoader: resourceLoader, - }); - - const cacheEntry = ResourceCache.cacheEntries[cacheKey]; - expect(cacheEntry.referenceCount).toBe(1); - expect(cacheEntry.resourceLoader).toBe(resourceLoader); - - return resourceLoader.promise.then(function (resourceLoader) { - expect(fetchJson).toHaveBeenCalled(); - - const schema = resourceLoader.schema; - expect(schema).toBeDefined(); - }); + expect(() => ResourceCache.add(resourceLoader)).toThrowDeveloperError(); + }); + + it("add throws if a resource with this cacheKey is already in the cache", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, }); - it("load throws if resourceLoader is undefined", function () { - expect(function () { - ResourceCache.load({ - resourceLoader: undefined, - }); - }).toThrowDeveloperError(); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, }); - it("load throws if resourceLoader's cacheKey is undefined", function () { - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - }); + ResourceCache.add(resourceLoader); - expect(function () { - ResourceCache.load({ - resourceLoader: resourceLoader, - }); - }).toThrowDeveloperError(); - }); + expect(() => ResourceCache.add(resourceLoader)).toThrowDeveloperError(); + }); - it("load throws if a resource with this cacheKey is already in the cache", function () { - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); - - ResourceCache.load({ - resourceLoader: resourceLoader, - }); - - expect(function () { - ResourceCache.load({ - resourceLoader: resourceLoader, - }); - }).toThrowDeveloperError(); + it("destroys resource when reference count reaches 0", function () { + const destroy = spyOn( + MetadataSchemaLoader.prototype, + "destroy" + ).and.callThrough(); + + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, + }); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, }); - it("destroys resource when reference count reaches 0", function () { - spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(schemaJson) - ); + ResourceCache.add(resourceLoader); - const destroy = spyOn( - MetadataSchemaLoader.prototype, - "destroy" - ).and.callThrough(); + ResourceCache.get(cacheKey); - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); + const cacheEntry = ResourceCache.cacheEntries[cacheKey]; + expect(cacheEntry.referenceCount).toBe(2); - ResourceCache.load({ - resourceLoader: resourceLoader, - }); + ResourceCache.unload(resourceLoader); + expect(cacheEntry.referenceCount).toBe(1); + expect(destroy).not.toHaveBeenCalled(); - ResourceCache.get(cacheKey); + ResourceCache.unload(resourceLoader); + expect(cacheEntry.referenceCount).toBe(0); + expect(destroy).toHaveBeenCalled(); + expect(ResourceCache.cacheEntries[cacheKey]).toBeUndefined(); + }); - const cacheEntry = ResourceCache.cacheEntries[cacheKey]; - expect(cacheEntry.referenceCount).toBe(2); + it("unload throws if resourceLoader is undefined", function () { + expect(function () { + ResourceCache.unload(); + }).toThrowDeveloperError(); + }); - ResourceCache.unload(resourceLoader); - expect(cacheEntry.referenceCount).toBe(1); - expect(destroy).not.toHaveBeenCalled(); + it("unload throws if resourceLoader is not in the cache", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, + }); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, + }); + expect(function () { ResourceCache.unload(resourceLoader); - expect(cacheEntry.referenceCount).toBe(0); - expect(destroy).toHaveBeenCalled(); - expect(ResourceCache.cacheEntries[cacheKey]).toBeUndefined(); - }); + }).toThrowDeveloperError(); + }); - it("unload throws if resourceLoader is undefined", function () { - expect(function () { - ResourceCache.unload(); - }).toThrowDeveloperError(); + it("unload throws if resourceLoader has already been unloaded from the cache", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, }); - - it("unload throws if resourceLoader is not in the cache", function () { - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); - - expect(function () { - ResourceCache.unload(resourceLoader); - }).toThrowDeveloperError(); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, }); - it("unload throws if resourceLoader has already been unloaded from the cache", function () { - spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(schemaJson) - ); - - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); + ResourceCache.add(resourceLoader); - ResourceCache.load({ - resourceLoader: resourceLoader, - }); + ResourceCache.unload(resourceLoader); + expect(function () { ResourceCache.unload(resourceLoader); + }).toThrowDeveloperError(); + }); - expect(function () { - ResourceCache.unload(resourceLoader); - }).toThrowDeveloperError(); + it("gets resource", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, + }); + const resourceLoader = new MetadataSchemaLoader({ + resource: schemaResource, + cacheKey: cacheKey, }); - it("gets resource", function () { - spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(schemaJson) - ); - - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const resourceLoader = new MetadataSchemaLoader({ - resource: schemaResource, - cacheKey: cacheKey, - }); + ResourceCache.add(resourceLoader); - ResourceCache.load({ - resourceLoader: resourceLoader, - }); + const cacheEntry = ResourceCache.cacheEntries[cacheKey]; - const cacheEntry = ResourceCache.cacheEntries[cacheKey]; + ResourceCache.get(cacheKey); + expect(cacheEntry.referenceCount).toBe(2); - ResourceCache.get(cacheKey); - expect(cacheEntry.referenceCount).toBe(2); + ResourceCache.get(cacheKey); + expect(cacheEntry.referenceCount).toBe(3); + }); - ResourceCache.get(cacheKey); - expect(cacheEntry.referenceCount).toBe(3); + it("get returns undefined if there is no resource with this cache key", function () { + const cacheKey = ResourceCacheKey.getSchemaCacheKey({ + resource: schemaResource, }); - it("get returns undefined if there is no resource with this cache key", function () { - const cacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); + expect(ResourceCache.get(cacheKey)).toBeUndefined(); + }); - expect(ResourceCache.get(cacheKey)).toBeUndefined(); + it("gets schema loader", function () { + const expectedCacheKey = ResourceCacheKey.getSchemaCacheKey({ + schema: schemaJson, }); - - it("loads schema from JSON", function () { - const expectedCacheKey = ResourceCacheKey.getSchemaCacheKey({ - schema: schemaJson, - }); - const schemaLoader = ResourceCache.loadSchema({ - schema: schemaJson, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(schemaLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadSchema({ - schema: schemaJson, - }) - ).toBe(schemaLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return schemaLoader.promise.then(function (schemaLoader) { - const schema = schemaLoader.schema; - expect(schema).toBeDefined(); - }); - }); - - it("loads external schema", function () { - spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(schemaJson) - ); - - const expectedCacheKey = ResourceCacheKey.getSchemaCacheKey({ - resource: schemaResource, - }); - const schemaLoader = ResourceCache.loadSchema({ - resource: schemaResource, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(schemaLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadSchema({ - resource: schemaResource, - }) - ).toBe(schemaLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return schemaLoader.promise.then(function (schemaLoader) { - const schema = schemaLoader.schema; - expect(schema).toBeDefined(); - }); + const schemaLoader = ResourceCache.getSchemaLoader({ + schema: schemaJson, }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(schemaLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(schemaLoader).toBeInstanceOf(MetadataSchemaLoader); - it("loadSchema throws if neither options.schema nor options.resource are defined", function () { - expect(function () { - ResourceCache.loadSchema({ - schema: undefined, - resource: undefined, - }); - }).toThrowDeveloperError(); - }); + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getSchemaLoader({ + schema: schemaJson, + }) + ).toBe(schemaLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("gets embedded buffer loader", function () { + const expectedCacheKey = ResourceCacheKey.getEmbeddedBufferCacheKey({ + parentResource: bufferParentResource, + bufferId: 0, + }); + const bufferLoader = ResourceCache.getEmbeddedBufferLoader({ + parentResource: bufferParentResource, + bufferId: 0, + typedArray: bufferTypedArray, + }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(bufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(bufferLoader).toBeInstanceOf(BufferLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getEmbeddedBufferLoader({ + parentResource: bufferParentResource, + bufferId: 0, + typedArray: bufferTypedArray, + }) + ).toBe(bufferLoader); - it("loadSchema throws if both options.schema and options.resource are defined", function () { - expect(function () { - ResourceCache.loadSchema({ - schema: schemaJson, - resource: schemaResource, - }); - }).toThrowDeveloperError(); - }); + expect(cacheEntry.referenceCount).toBe(2); + }); - it("loads embedded buffer", function () { - const expectedCacheKey = ResourceCacheKey.getEmbeddedBufferCacheKey({ - parentResource: bufferParentResource, + it("getEmbeddedBufferLoader throws if parentResource is undefined", function () { + expect(() => + ResourceCache.getEmbeddedBufferLoader({ bufferId: 0, - }); - const bufferLoader = ResourceCache.loadEmbeddedBuffer({ + typedArray: bufferTypedArray, + }) + ).toThrowDeveloperError(); + }); + + it("getEmbeddedBufferLoader throws if bufferId is undefined", function () { + expect(() => + ResourceCache.getEmbeddedBufferLoader({ parentResource: bufferParentResource, - bufferId: 0, typedArray: bufferTypedArray, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(bufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadEmbeddedBuffer({ - parentResource: bufferParentResource, - bufferId: 0, - typedArray: bufferTypedArray, - }) - ).toBe(bufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return bufferLoader.promise.then(function (bufferLoader) { - expect(bufferLoader.typedArray).toBe(bufferTypedArray); - }); - }); + }) + ).toThrowDeveloperError(); + }); - it("loadEmbeddedBuffer throws if parentResource is undefined", function () { - expect(function () { - ResourceCache.loadEmbeddedBuffer({ - bufferId: 0, - typedArray: bufferTypedArray, - }); - }).toThrowDeveloperError(); - }); + it("getEmbeddedBufferLoader throws if typedArray is undefined", function () { + expect(() => + ResourceCache.getEmbeddedBufferLoader({ + parentResource: bufferParentResource, + bufferId: 0, + }) + ).toThrowDeveloperError(); + }); - it("loadEmbeddedBuffer throws if bufferId is undefined", function () { - expect(function () { - ResourceCache.loadEmbeddedBuffer({ - parentResource: bufferParentResource, - typedArray: bufferTypedArray, - }); - }).toThrowDeveloperError(); + it("gets external buffer loader", function () { + const expectedCacheKey = ResourceCacheKey.getExternalBufferCacheKey({ + resource: bufferResource, }); - - it("loadEmbeddedBuffer throws if typedArray is undefined", function () { - expect(function () { - ResourceCache.loadEmbeddedBuffer({ - parentResource: bufferParentResource, - bufferId: 0, - }); - }).toThrowDeveloperError(); + const bufferLoader = ResourceCache.getExternalBufferLoader({ + resource: bufferResource, }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(bufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(bufferLoader).toBeInstanceOf(BufferLoader); - it("loads external buffer", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); - - const expectedCacheKey = ResourceCacheKey.getExternalBufferCacheKey({ - resource: bufferResource, - }); - const bufferLoader = ResourceCache.loadExternalBuffer({ + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getExternalBufferLoader({ resource: bufferResource, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(bufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadExternalBuffer({ - resource: bufferResource, - }) - ).toBe(bufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return bufferLoader.promise.then(function (bufferLoader) { - expect(bufferLoader.typedArray.buffer).toBe(bufferArrayBuffer); - }); - }); - - it("loadExternalBuffer throws if resource is undefined", function () { - expect(function () { - ResourceCache.loadExternalBuffer({ - resource: undefined, - }); - }).toThrowDeveloperError(); - }); + }) + ).toBe(bufferLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("getExternalBufferLoader throws if resource is undefined", function () { + expect(() => + ResourceCache.getExternalBufferLoader({ + resource: undefined, + }) + ).toThrowDeveloperError(); + }); + + it("gets glTF loader", function () { + const expectedCacheKey = ResourceCacheKey.getGltfCacheKey({ + gltfResource: gltfResource, + }); + const gltfJsonLoader = ResourceCache.getGltfJsonLoader({ + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(gltfJsonLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(gltfJsonLoader).toBeInstanceOf(GltfJsonLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getGltfJsonLoader({ + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toBe(gltfJsonLoader); - it("loads glTF", function () { - const gltf = { - asset: { - version: "2.0", - }, - }; - const arrayBuffer = generateJsonBuffer(gltf).buffer; + expect(cacheEntry.referenceCount).toBe(2); + }); - spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( - Promise.resolve(arrayBuffer) - ); + it("getGltfJsonLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getGltfJsonLoader({ + gltfResource: undefined, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getGltfCacheKey({ + it("loadGltfJson throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getGltfJsonLoader({ gltfResource: gltfResource, - }); - const gltfJsonLoader = ResourceCache.loadGltfJson({ + baseResource: undefined, + }) + ).toThrowDeveloperError(); + }); + + it("gets buffer view loader", function () { + const expectedCacheKey = ResourceCacheKey.getBufferViewCacheKey({ + gltf: gltfUncompressed, + bufferViewId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const bufferViewLoader = ResourceCache.getBufferViewLoader({ + gltf: gltfUncompressed, + bufferViewId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(bufferViewLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(bufferViewLoader).toBeInstanceOf(GltfBufferViewLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getBufferViewLoader({ + gltf: gltfUncompressed, + bufferViewId: 0, gltfResource: gltfResource, baseResource: gltfResource, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(gltfJsonLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadGltfJson({ - gltfResource: gltfResource, - baseResource: gltfResource, - }) - ).toBe(gltfJsonLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return gltfJsonLoader.promise.then(function (gltfJsonLoader) { - expect(gltfJsonLoader.gltf).toBeDefined(); - }); - }); + }) + ).toBe(bufferViewLoader); - it("loadGltfJson throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadGltfJson({ - gltfResource: undefined, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); + expect(cacheEntry.referenceCount).toBe(2); + }); - it("loadGltfJson throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadGltfJson({ - gltfResource: gltfResource, - baseResource: undefined, - }); - }).toThrowDeveloperError(); - }); + it("getBufferViewLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getBufferViewLoader({ + gltf: undefined, + bufferViewId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - it("loads buffer view", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + it("getBufferViewLoader throws if bufferViewId is undefined", function () { + expect(() => + ResourceCache.getBufferViewLoader({ + gltf: gltfUncompressed, + bufferViewId: undefined, + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getBufferViewCacheKey({ + it("getBufferViewLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getBufferViewLoader({ gltf: gltfUncompressed, bufferViewId: 0, - gltfResource: gltfResource, + gltfResource: undefined, baseResource: gltfResource, - }); - const bufferViewLoader = ResourceCache.loadBufferView({ + }) + ).toThrowDeveloperError(); + }); + + it("getBufferViewLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getBufferViewLoader({ gltf: gltfUncompressed, bufferViewId: 0, gltfResource: gltfResource, + baseResource: undefined, + }) + ).toThrowDeveloperError(); + }); + + it("gets draco loader", function () { + const expectedCacheKey = ResourceCacheKey.getDracoCacheKey({ + gltf: gltfDraco, + draco: dracoExtension, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const dracoLoader = ResourceCache.getDracoLoader({ + gltf: gltfDraco, + draco: dracoExtension, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(dracoLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(dracoLoader).toBeInstanceOf(GltfDracoLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getDracoLoader({ + gltf: gltfDraco, + draco: dracoExtension, + gltfResource: gltfResource, baseResource: gltfResource, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(bufferViewLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadBufferView({ - gltf: gltfUncompressed, - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }) - ).toBe(bufferViewLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return bufferViewLoader.promise.then(function (bufferViewLoader) { - expect(bufferViewLoader.typedArray).toBeDefined(); - }); - }); - - it("loadBufferView throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: undefined, - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); + }) + ).toBe(dracoLoader); - it("loadBufferView throws if bufferViewId is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfUncompressed, - bufferViewId: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); - - it("loadBufferView throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfUncompressed, - bufferViewId: 0, - gltfResource: undefined, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); - - it("loadBufferView throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfUncompressed, - bufferViewId: 0, - gltfResource: gltfResource, - baseResource: undefined, - }); - }).toThrowDeveloperError(); - }); + expect(cacheEntry.referenceCount).toBe(2); + }); - it("loads draco", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(dracoArrayBuffer) - ); - - spyOn(DracoLoader, "decodeBufferView").and.returnValue( - Promise.resolve(decodeDracoResults) - ); - - const expectedCacheKey = ResourceCacheKey.getDracoCacheKey({ - gltf: gltfDraco, + it("getDracoLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getDracoLoader({ + gltf: undefined, draco: dracoExtension, gltfResource: gltfResource, baseResource: gltfResource, - }); - const dracoLoader = ResourceCache.loadDraco({ + }) + ).toThrowDeveloperError(); + }); + + it("getDracoLoader throws if draco is undefined", function () { + expect(() => + ResourceCache.getDracoLoader({ gltf: gltfDraco, - draco: dracoExtension, + draco: undefined, gltfResource: gltfResource, baseResource: gltfResource, - }); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(dracoLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadDraco({ - gltf: gltfDraco, - draco: dracoExtension, - gltfResource: gltfResource, - baseResource: gltfResource, - }) - ).toBe(dracoLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(dracoLoader, scene).then(function ( - dracoLoader - ) { - expect(dracoLoader.decodedData).toBeDefined(); - }); - }); - - it("loadDraco throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: undefined, - draco: dracoExtension, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); - - it("loadDraco throws if draco is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfDraco, - draco: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); + }) + ).toThrowDeveloperError(); + }); - it("loadDraco throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfDraco, - draco: dracoExtension, - gltfResource: undefined, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); - - it("loadDraco throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadBufferView({ - gltf: gltfDraco, - draco: dracoExtension, - gltfResource: gltfResource, - baseResource: undefined, - }); - }).toThrowDeveloperError(); - }); - - it("loads vertex buffer from buffer view", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + it("getDracoLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getDracoLoader({ + gltf: gltfDraco, + draco: dracoExtension, + gltfResource: undefined, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ - gltf: gltfUncompressed, + it("getDracoLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getDracoLoader({ + gltf: gltfDraco, + draco: dracoExtension, gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: true, - }); - const vertexBufferLoader = ResourceCache.loadVertexBuffer({ + baseResource: undefined, + }) + ).toThrowDeveloperError(); + }); + + it("gets vertex buffer loader for buffer view", function () { + const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ + gltf: gltfUncompressed, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + bufferViewId: 0, + loadBuffer: true, + }); + const vertexBufferLoader = ResourceCache.getVertexBufferLoader({ + gltf: gltfUncompressed, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + bufferViewId: 0, + accessorId: 0, + loadBuffer: true, + }); + + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(vertexBufferLoader).toBeInstanceOf(GltfVertexBufferLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getVertexBufferLoader({ gltf: gltfUncompressed, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, bufferViewId: 0, - accessorId: 0, loadBuffer: true, - }); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: true, - }) - ).toBe(vertexBufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer).toBeDefined(); - - return cacheEntry._statisticsPromise.then(function () { - // The vertex buffer should only be counted once - expect(ResourceCache.statistics.geometryByteLength).toBe( - vertexBufferLoader.buffer.sizeInBytes - ); - }); - }); - }); - - it("loads vertex buffer from draco", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(dracoArrayBuffer) - ); - - spyOn(DracoLoader, "decodeBufferView").and.returnValue( - Promise.resolve(decodeDracoResults) - ); - - const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ + }) + ).toBe(vertexBufferLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("gets vertex buffer loader for draco", function () { + const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ + gltf: gltfDraco, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + draco: dracoExtension, + attributeSemantic: "POSITION", + loadBuffer: true, + }); + const vertexBufferLoader = ResourceCache.getVertexBufferLoader({ + gltf: gltfDraco, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + draco: dracoExtension, + attributeSemantic: "POSITION", + accessorId: 0, + loadBuffer: true, + }); + + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(vertexBufferLoader).toBeInstanceOf(GltfVertexBufferLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getVertexBufferLoader({ gltf: gltfDraco, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, draco: dracoExtension, attributeSemantic: "POSITION", + accessorId: 0, loadBuffer: true, - }); - const vertexBufferLoader = ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, + }) + ).toBe(vertexBufferLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("gets vertex buffer loaders on different contexts", function () { + const vertexBufferLoader1 = ResourceCache.getVertexBufferLoader({ + gltf: gltfUncompressed, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + bufferViewId: 0, + accessorId: 0, + loadBuffer: true, + }); + + const vertexBufferLoader2 = ResourceCache.getVertexBufferLoader({ + gltf: gltfUncompressed, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState2, + bufferViewId: 0, + accessorId: 0, + loadBuffer: true, + }); + + expect(vertexBufferLoader1).toBeDefined(); + expect(vertexBufferLoader2).toBeDefined(); + + expect(vertexBufferLoader1).not.toBe(vertexBufferLoader2); + }); + + it("getVertexBufferLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ + gltf: undefined, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - draco: dracoExtension, - attributeSemantic: "POSITION", - accessorId: 0, + bufferViewId: 0, loadBuffer: true, - }); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - draco: dracoExtension, - attributeSemantic: "POSITION", - accessorId: 0, - loadBuffer: true, - }) - ).toBe(vertexBufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.buffer).toBeDefined(); - - return cacheEntry._statisticsPromise.then(function () { - // The vertex buffer should only be counted once - expect(ResourceCache.statistics.geometryByteLength).toBe( - vertexBufferLoader.buffer.sizeInBytes - ); - }); - }); - }); - - it("loads vertex buffer as typed array", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ + it("getVertexBufferLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ gltf: gltfUncompressed, - gltfResource: gltfResource, + gltfResource: undefined, baseResource: gltfResource, frameState: mockFrameState, bufferViewId: 0, - loadTypedArray: true, - }); - const vertexBufferLoader = ResourceCache.loadVertexBuffer({ + loadBuffer: true, + }) + ).toThrowDeveloperError(); + }); + + it("getVertexBufferLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ gltf: gltfUncompressed, gltfResource: gltfResource, - baseResource: gltfResource, + baseResource: undefined, frameState: mockFrameState, bufferViewId: 0, - accessorId: 0, - loadTypedArray: true, - }); - - expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.typedArray).toBeDefined(); - expect(vertexBufferLoader.buffer).toBeUndefined(); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - return cacheEntry._statisticsPromise.then(function () { - expect(ResourceCache.statistics.geometryByteLength).toBe( - vertexBufferLoader.typedArray.byteLength - ); - }); - }); - }); - - it("loads vertex buffer as buffer and typed array for 2D", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + loadBuffer: true, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getVertexBufferCacheKey({ + it("getVertexBufferLoader throws if frameState is undefined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ gltf: gltfUncompressed, gltfResource: gltfResource, baseResource: gltfResource, - frameState: mockFrameState, + frameState: undefined, bufferViewId: 0, loadBuffer: true, - loadTypedArray: true, - }); - const vertexBufferLoader = ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, + }) + ).toThrowDeveloperError(); + }); + + it("getVertexBufferLoader throws if bufferViewId and draco are both defined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ + gltf: gltfDraco, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, bufferViewId: 0, + draco: dracoExtension, + attributeSemantic: "POSITION", accessorId: 0, loadBuffer: true, - loadTypedArray: true, - }); - - expect(vertexBufferLoader.cacheKey).toBe(expectedCacheKey); - - return waitForLoaderProcess(vertexBufferLoader, scene).then(function ( - vertexBufferLoader - ) { - expect(vertexBufferLoader.typedArray).toBeDefined(); - expect(vertexBufferLoader.buffer).toBeDefined(); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - return cacheEntry._statisticsPromise.then(function () { - const totalSize = - vertexBufferLoader.typedArray.byteLength + - vertexBufferLoader.buffer.sizeInBytes; - expect(ResourceCache.statistics.geometryByteLength).toBe(totalSize); - }); - }); - }); + }) + ).toThrowDeveloperError(); + }); - it("loads vertex buffer on different contexts", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); - - const vertexBufferLoader1 = ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, + it("getVertexBufferLoader throws if bufferViewId and draco are both undefined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ + gltf: gltfDraco, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - bufferViewId: 0, - accessorId: 0, loadBuffer: true, - }); + }) + ).toThrowDeveloperError(); + }); - const vertexBufferLoader2 = ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, + it("getVertexBufferLoader throws if draco is defined and attributeSemantic is not defined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ + gltf: gltfDraco, gltfResource: gltfResource, baseResource: gltfResource, - frameState: mockFrameState2, - bufferViewId: 0, + frameState: mockFrameState, + draco: dracoExtension, + attributeSemantic: undefined, accessorId: 0, loadBuffer: true, - }); - - const promises = [ - waitForLoaderProcess(vertexBufferLoader1, scene), - waitForLoaderProcess(vertexBufferLoader2, scene), - ]; - - return Promise.all(promises).then(function (vertexBufferLoaders) { - const vertexBuffer1 = vertexBufferLoaders[0]; - const vertexBuffer2 = vertexBufferLoaders[1]; - - expect(vertexBuffer1).toBeDefined(); - expect(vertexBuffer2).toBeDefined(); - - expect(vertexBuffer1).not.toBe(vertexBuffer2); - }); - }); - - it("loadVertexBuffer throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, - gltfResource: undefined, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, - gltfResource: gltfResource, - baseResource: undefined, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); + }) + ).toThrowDeveloperError(); + }); - it("loadVertexBuffer throws if frameState is undefined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: undefined, - bufferViewId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if bufferViewId and draco are both defined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - draco: dracoExtension, - attributeSemantic: "POSITION", - accessorId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if bufferViewId and draco are both undefined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if draco is defined and attributeSemantic is not defined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - draco: dracoExtension, - attributeSemantic: undefined, - accessorId: 0, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if draco is defined and accessorId is not defined", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfDraco, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - draco: dracoExtension, - attributeSemantic: "POSITION", - accessorId: undefined, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadVertexBuffer throws if both loadBuffer and loadTypedArray are false", function () { - expect(function () { - ResourceCache.loadVertexBuffer({ - gltf: gltfUncompressed, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - bufferViewId: 0, - loadBuffer: false, - loadTypedArray: false, - }); - }).toThrowDeveloperError(); - }); - - it("loads index buffer from accessor as buffer", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); - - const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ - gltf: gltfUncompressed, - accessorId: 2, + it("getVertexBufferLoader throws if draco is defined and accessorId is not defined", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ + gltf: gltfDraco, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, + draco: dracoExtension, + attributeSemantic: "POSITION", + accessorId: undefined, loadBuffer: true, - }); - const indexBufferLoader = ResourceCache.loadIndexBuffer({ + }) + ).toThrowDeveloperError(); + }); + + it("getVertexBufferLoader throws if both loadBuffer and loadTypedArray are false", function () { + expect(() => + ResourceCache.getVertexBufferLoader({ gltf: gltfUncompressed, - accessorId: 2, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - loadBuffer: true, - }); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: 2, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: true, - }) - ).toBe(indexBufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer).toBeDefined(); - expect(indexBufferLoader.typedArray).toBeUndefined(); - - expect(ResourceCache.statistics.geometryByteLength).toBe( - indexBufferLoader.buffer.sizeInBytes - ); - }); - }); - - it("loads index buffer from draco", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(dracoArrayBuffer) - ); - - spyOn(DracoLoader, "decodeBufferView").and.returnValue( - Promise.resolve(decodeDracoResults) - ); - - const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ - gltf: gltfDraco, + bufferViewId: 0, + loadBuffer: false, + loadTypedArray: false, + }) + ).toThrowDeveloperError(); + }); + + it("gets index buffer loader for accessor as buffer", function () { + const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ + gltf: gltfUncompressed, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + loadBuffer: true, + }); + const indexBufferLoader = ResourceCache.getIndexBufferLoader({ + gltf: gltfUncompressed, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + loadBuffer: true, + }); + + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(indexBufferLoader).toBeInstanceOf(GltfIndexBufferLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getIndexBufferLoader({ + gltf: gltfUncompressed, accessorId: 2, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - draco: dracoExtension, loadBuffer: true, - }); - const indexBufferLoader = ResourceCache.loadIndexBuffer({ + }) + ).toBe(indexBufferLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("loads index buffer from draco", function () { + const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ + gltf: gltfDraco, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + draco: dracoExtension, + loadBuffer: true, + }); + const indexBufferLoader = ResourceCache.getIndexBufferLoader({ + gltf: gltfDraco, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + draco: dracoExtension, + loadBuffer: true, + }); + + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(indexBufferLoader).toBeInstanceOf(GltfIndexBufferLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getIndexBufferLoader({ gltf: gltfDraco, accessorId: 2, gltfResource: gltfResource, @@ -1297,491 +962,328 @@ describe( frameState: mockFrameState, draco: dracoExtension, loadBuffer: true, - }); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadIndexBuffer({ - gltf: gltfDraco, - accessorId: 2, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - draco: dracoExtension, - loadBuffer: true, - }) - ).toBe(indexBufferLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.buffer).toBeDefined(); - - return cacheEntry._statisticsPromise.then(function () { - // The index buffer should only be counted once - expect(ResourceCache.statistics.geometryByteLength).toBe( - indexBufferLoader.buffer.sizeInBytes - ); - }); - }); + }) + ).toBe(indexBufferLoader); + + expect(cacheEntry.referenceCount).toBe(2); + }); + + it("gets index buffer loaders on different contexts", function () { + const indexBufferLoader1 = ResourceCache.getIndexBufferLoader({ + gltf: gltfUncompressed, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + loadBuffer: true, }); - it("loads index buffer as typed array", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + const indexBufferLoader2 = ResourceCache.getIndexBufferLoader({ + gltf: gltfUncompressed, + accessorId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState2, + loadBuffer: true, + }); - const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ - gltf: gltfUncompressed, + expect(indexBufferLoader1).toBeDefined(); + expect(indexBufferLoader2).toBeDefined(); + + expect(indexBufferLoader1).not.toBe(indexBufferLoader2); + }); + + it("getIndexBufferLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ + gltf: undefined, accessorId: 2, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - loadTypedArray: true, - }); - const indexBufferLoader = ResourceCache.loadIndexBuffer({ + loadBuffer: true, + }) + ).toThrowDeveloperError(); + }); + + it("getIndexBufferLoader throws if accessorId is undefined", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ gltf: gltfUncompressed, - accessorId: 2, + accessorId: undefined, gltfResource: gltfResource, baseResource: gltfResource, frameState: mockFrameState, - loadTypedArray: true, - }); - - expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); - - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.typedArray).toBeDefined(); - expect(indexBufferLoader.buffer).toBeUndefined(); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - return cacheEntry._statisticsPromise.then(function () { - expect(ResourceCache.statistics.geometryByteLength).toBe( - indexBufferLoader.typedArray.byteLength - ); - }); - }); - }); - - it("loads index buffer as buffer and typed array", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + loadBuffer: true, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getIndexBufferCacheKey({ + it("getIndexBufferLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ gltf: gltfUncompressed, accessorId: 2, - gltfResource: gltfResource, + gltfResource: undefined, baseResource: gltfResource, frameState: mockFrameState, loadBuffer: true, - loadTypedArray: true, - }); - const indexBufferLoader = ResourceCache.loadIndexBuffer({ + }) + ).toThrowDeveloperError(); + }); + + it("getIndexBufferLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ gltf: gltfUncompressed, accessorId: 2, gltfResource: gltfResource, - baseResource: gltfResource, + baseResource: undefined, frameState: mockFrameState, loadBuffer: true, - loadTypedArray: true, - }); - - expect(indexBufferLoader.cacheKey).toBe(expectedCacheKey); - - return waitForLoaderProcess(indexBufferLoader, scene).then(function ( - indexBufferLoader - ) { - expect(indexBufferLoader.typedArray).toBeDefined(); - expect(indexBufferLoader.buffer).toBeDefined(); - - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - return cacheEntry._statisticsPromise.then(function () { - // The statistics will count both buffer and typed array - expect(ResourceCache.statistics.geometryByteLength).toBe( - 2 * indexBufferLoader.typedArray.byteLength - ); - }); - }); - }); - - it("loads index buffer on different contexts", function () { - spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( - Promise.resolve(bufferArrayBuffer) - ); + }) + ).toThrowDeveloperError(); + }); - const indexBufferLoader1 = ResourceCache.loadIndexBuffer({ + it("getIndexBufferLoader throws if frameState is undefined", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ gltf: gltfUncompressed, accessorId: 2, gltfResource: gltfResource, baseResource: gltfResource, - frameState: mockFrameState, + frameState: undefined, loadBuffer: true, - }); + }) + ).toThrowDeveloperError(); + }); - const indexBufferLoader2 = ResourceCache.loadIndexBuffer({ + it("getIndexBufferLoader throws if both loadBuffer and loadTypedArray are false", function () { + expect(() => + ResourceCache.getIndexBufferLoader({ gltf: gltfUncompressed, accessorId: 2, gltfResource: gltfResource, baseResource: gltfResource, - frameState: mockFrameState2, - loadBuffer: true, - }); - - const promises = [ - waitForLoaderProcess(indexBufferLoader1, scene), - waitForLoaderProcess(indexBufferLoader2, scene), - ]; - - return Promise.all(promises).then(function (indexBufferLoaders) { - const indexBuffer1 = indexBufferLoaders[0]; - const indexBuffer2 = indexBufferLoaders[1]; - - expect(indexBuffer1).toBeDefined(); - expect(indexBuffer2).toBeDefined(); - - expect(indexBuffer1).not.toBe(indexBuffer2); - }); - }); - - it("loadIndexBuffer throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: undefined, - accessorId: 2, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadIndexBuffer throws if accessorId is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadIndexBuffer throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: 2, - gltfResource: undefined, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); - - it("loadIndexBuffer throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: 2, - gltfResource: gltfResource, - baseResource: undefined, - frameState: mockFrameState, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); + frameState: mockFrameState, + loadBuffer: false, + loadTypedArray: false, + }) + ).toThrowDeveloperError(); + }); + + it("gets image loader", function () { + const expectedCacheKey = ResourceCacheKey.getImageCacheKey({ + gltf: gltfWithTextures, + imageId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const imageLoader = ResourceCache.getImageLoader({ + gltf: gltfWithTextures, + imageId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(imageLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(imageLoader).toBeInstanceOf(GltfImageLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getImageLoader({ + gltf: gltfWithTextures, + imageId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toBe(imageLoader); - it("loadIndexBuffer throws if frameState is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: 2, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: undefined, - loadBuffer: true, - }); - }).toThrowDeveloperError(); - }); + expect(cacheEntry.referenceCount).toBe(2); + }); - it("loadIndexBuffer throws if both loadBuffer and loadTypedArray are false", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfUncompressed, - accessorId: 2, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - loadBuffer: false, - loadTypedArray: false, - }); - }).toThrowDeveloperError(); - }); + it("getImageLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getImageLoader({ + gltf: undefined, + imageId: 0, + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - it("loads image", function () { - spyOn(Resource.prototype, "fetchImage").and.returnValue( - Promise.resolve(image) - ); + it("getImageLoader throws if imageId is undefined", function () { + expect(() => + ResourceCache.getImageLoader({ + gltf: gltfWithTextures, + imageId: undefined, + gltfResource: gltfResource, + baseResource: gltfResource, + }) + ).toThrowDeveloperError(); + }); - const expectedCacheKey = ResourceCacheKey.getImageCacheKey({ + it("getImageLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getImageLoader({ gltf: gltfWithTextures, imageId: 0, - gltfResource: gltfResource, + gltfResource: undefined, baseResource: gltfResource, - }); - const imageLoader = ResourceCache.loadImage({ + }) + ).toThrowDeveloperError(); + }); + + it("getImageLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getImageLoader({ gltf: gltfWithTextures, imageId: 0, gltfResource: gltfResource, + baseResource: undefined, + }) + ).toThrowDeveloperError(); + }); + + it("gets texture loader", function () { + const expectedCacheKey = ResourceCacheKey.getTextureCacheKey({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfResource, + supportedImageFormats: new SupportedImageFormats(), + frameState: mockFrameState, + }); + const textureLoader = ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + supportedImageFormats: new SupportedImageFormats(), + }); + const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; + expect(textureLoader.cacheKey).toBe(expectedCacheKey); + expect(cacheEntry.referenceCount).toBe(1); + expect(textureLoader).toBeInstanceOf(GltfTextureLoader); + + // The existing resource is returned if the computed cache key is the same + expect( + ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, baseResource: gltfResource, - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(imageLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadImage({ - gltf: gltfWithTextures, - imageId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }) - ).toBe(imageLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return imageLoader.promise.then(function (imageLoader) { - expect(imageLoader.image).toBeDefined(); - }); - }); + frameState: mockFrameState, + supportedImageFormats: new SupportedImageFormats(), + }) + ).toBe(textureLoader); - it("loadImage throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadImage({ - gltf: undefined, - imageId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); - }); + expect(cacheEntry.referenceCount).toBe(2); + }); - it("loadImage throws if imageId is undefined", function () { - expect(function () { - ResourceCache.loadImage({ - gltf: gltfWithTextures, - imageId: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); + it("get texture loaders in different contexts", function () { + const textureLoader1 = ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState, + supportedImageFormats: new SupportedImageFormats(), }); - it("loadImage throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadImage({ - gltf: gltfWithTextures, - imageId: 0, - gltfResource: undefined, - baseResource: gltfResource, - }); - }).toThrowDeveloperError(); + const textureLoader2 = ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfResource, + frameState: mockFrameState2, + supportedImageFormats: new SupportedImageFormats(), }); - it("loadImage throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadImage({ - gltf: gltfWithTextures, - imageId: 0, - gltfResource: gltfResource, - baseResource: undefined, - }); - }).toThrowDeveloperError(); - }); + expect(textureLoader1).toBeDefined(); + expect(textureLoader2).toBeDefined(); - it("loads texture", function () { - spyOn(Resource.prototype, "fetchImage").and.returnValue( - Promise.resolve(image) - ); + expect(textureLoader1).not.toBe(textureLoader2); + }); - const expectedCacheKey = ResourceCacheKey.getTextureCacheKey({ - gltf: gltfWithTextures, + it("getTextureLoader throws if gltf is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ + gltf: undefined, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, baseResource: gltfResource, supportedImageFormats: new SupportedImageFormats(), frameState: mockFrameState, - }); - const textureLoader = ResourceCache.loadTexture({ + }) + ).toThrowDeveloperError(); + }); + + it("getTextureLoader throws if textureInfo is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, + textureInfo: undefined, gltfResource: gltfResource, baseResource: gltfResource, + supportedImageFormats: new SupportedImageFormats(), frameState: mockFrameState, + }) + ).toThrowDeveloperError(); + }); + + it("getTextureLoader throws if gltfResource is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: undefined, + baseResource: gltfResource, supportedImageFormats: new SupportedImageFormats(), - }); - const cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; - expect(textureLoader.cacheKey).toBe(expectedCacheKey); - expect(cacheEntry.referenceCount).toBe(1); - - // The existing resource is returned if the computed cache key is the same - expect( - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: gltfResource, - baseResource: gltfResource, - frameState: mockFrameState, - supportedImageFormats: new SupportedImageFormats(), - }) - ).toBe(textureLoader); - - expect(cacheEntry.referenceCount).toBe(2); - - return waitForLoaderProcess(textureLoader, scene).then(function ( - textureLoader - ) { - expect(textureLoader.texture).toBeDefined(); - - return cacheEntry._statisticsPromise.then(function () { - // The texture should only be counted once - expect(ResourceCache.statistics.texturesByteLength).toBe( - textureLoader.texture.sizeInBytes - ); - }); - }); - }); + frameState: mockFrameState, + }) + ).toThrowDeveloperError(); + }); - it("loads texture on different contexts", function () { - spyOn(Resource.prototype, "fetchImage").and.returnValue( - Promise.resolve(image) - ); + it("getTextureLoader throws if baseResource is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ + gltf: gltfWithTextures, + textureInfo: gltfWithTextures.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: undefined, + supportedImageFormats: new SupportedImageFormats(), + frameState: mockFrameState, + }) + ).toThrowDeveloperError(); + }); - const textureLoader1 = ResourceCache.loadTexture({ + it("getTextureLoader throws if supportedImageFormats is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ gltf: gltfWithTextures, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, baseResource: gltfResource, + supportedImageFormats: undefined, frameState: mockFrameState, - supportedImageFormats: new SupportedImageFormats(), - }); + }) + ).toThrowDeveloperError(); + }); - const textureLoader2 = ResourceCache.loadTexture({ + it("getTextureLoader throws if frameState is undefined", function () { + expect(() => + ResourceCache.getTextureLoader({ gltf: gltfWithTextures, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, baseResource: gltfResource, - frameState: mockFrameState2, supportedImageFormats: new SupportedImageFormats(), - }); - - const promises = [ - waitForLoaderProcess(textureLoader1, scene), - waitForLoaderProcess(textureLoader2, scene), - ]; - - return Promise.all(promises).then(function (textureLoaders) { - const texture1 = textureLoaders[0]; - const texture2 = textureLoaders[1]; - - expect(texture1).toBeDefined(); - expect(texture2).toBeDefined(); - - expect(texture1).not.toBe(texture2); - }); - }); - - it("loadTexture throws if gltf is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: undefined, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), - frameState: mockFrameState, - }); - }).toThrowDeveloperError(); - }); - - it("loadTexture throws if textureInfo is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: undefined, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), - frameState: mockFrameState, - }); - }).toThrowDeveloperError(); - }); - - it("loadTexture throws if gltfResource is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: undefined, - baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), - frameState: mockFrameState, - }); - }).toThrowDeveloperError(); - }); - - it("loadTexture throws if baseResource is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: gltfResource, - baseResource: undefined, - supportedImageFormats: new SupportedImageFormats(), - frameState: mockFrameState, - }); - }).toThrowDeveloperError(); - }); - - it("loadTexture throws if supportedImageFormats is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: undefined, - frameState: mockFrameState, - }); - }).toThrowDeveloperError(); - }); - - it("loadTexture throws if frameState is undefined", function () { - expect(function () { - ResourceCache.loadTexture({ - gltf: gltfWithTextures, - textureInfo: gltfWithTextures.materials[0].emissiveTexture, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), - frameState: undefined, - }); - }).toThrowDeveloperError(); - }); - }, - "WebGL" -); + frameState: undefined, + }) + ).toThrowDeveloperError(); + }); +}); diff --git a/packages/engine/Specs/Scene/ShadowMapSpec.js b/packages/engine/Specs/Scene/ShadowMapSpec.js index cc1d93085a0..a31056b9c36 100644 --- a/packages/engine/Specs/Scene/ShadowMapSpec.js +++ b/packages/engine/Specs/Scene/ShadowMapSpec.js @@ -281,18 +281,17 @@ describe( ); } - function loadModel(options) { - const model = scene.primitives.add(Model.fromGltf(options)); - return pollToPromise( + async function loadModel(options) { + const model = scene.primitives.add(await Model.fromGltf(options)); + await pollToPromise( function () { // Render scene to progressively load the model scene.render(); return model.ready; }, { timeout: 10000 } - ).then(function () { - return model; - }); + ); + return model; } /** From 1eaec3fd44534d19824bb05e631cd91da19e452e Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 9 Mar 2023 09:21:50 -0500 Subject: [PATCH 533/679] Fix deprecation warning --- packages/engine/Source/Scene/SingleTileImageryProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index df443ec1e7e..b2096be5724 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -102,7 +102,7 @@ function SingleTileImageryProvider(options) { deprecationWarning( "SingleTileImageryProvider options", - "options.tileHeight and options.tileWidth became required in CesiumJS 1.102. Omitting these properties will result in an error in 1.104. Provide options.tileHeight and options.tileWidth, or use SingleTileImageryProvider.fromUrl instead." + "options.tileHeight and options.tileWidth became required in CesiumJS 1.104. Omitting these properties will result in an error in 1.107. Provide options.tileHeight and options.tileWidth, or use SingleTileImageryProvider.fromUrl instead." ); this._tileWidth = 0; From 0baf0e8f97c142353c392963c39dded2a06951a0 Mon Sep 17 00:00:00 2001 From: nnoce14 <nnoce12@gmail.com> Date: Thu, 9 Mar 2023 10:24:48 -0500 Subject: [PATCH 534/679] Added Cartesian3 type to PolygonGraphics hierarchy property --- packages/engine/Source/DataSources/PolygonGraphics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/DataSources/PolygonGraphics.js b/packages/engine/Source/DataSources/PolygonGraphics.js index d0339c682fd..8e45da5edd5 100644 --- a/packages/engine/Source/DataSources/PolygonGraphics.js +++ b/packages/engine/Source/DataSources/PolygonGraphics.js @@ -21,7 +21,7 @@ function createPolygonHierarchyProperty(value) { * Initialization options for the PolygonGraphics constructor * * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the polygon. - * @property {Property | PolygonHierarchy} [hierarchy] A Property specifying the {@link PolygonHierarchy}. + * @property {Property | PolygonHierarchy | Cartesian3[]} [hierarchy] A Property specifying the {@link PolygonHierarchy}. * @property {Property | number} [height=0] A numeric Property specifying the altitude of the polygon relative to the ellipsoid surface. * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to. * @property {Property | number} [extrudedHeight] A numeric Property specifying the altitude of the polygon's extruded face relative to the ellipsoid surface. From fc3018974ba45857a3920c6b057f5bd092190321 Mon Sep 17 00:00:00 2001 From: nnoce14 <nnoce12@gmail.com> Date: Thu, 9 Mar 2023 10:28:31 -0500 Subject: [PATCH 535/679] update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9f476bbac08..1d51d515320 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -346,3 +346,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Southjor](https://github.com/Southjor) - [Lakshmipriya](https://github.com/Lakshmi0710) - [Tengfei](https://github.com/i-tengfei) +- [Nick Noce](https://github.com/nnoce14) From 8f8a869ef2a126cd33383c3dcf46684ccb47bfc6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 9 Mar 2023 14:24:13 -0500 Subject: [PATCH 536/679] Move basic tile checks from traversals to Cesium3DTile --- packages/engine/Source/Scene/Cesium3DTile.js | 59 +++++++++++---- .../Cesium3DTilesetMostDetailedTraversal.js | 18 ++--- .../Source/Scene/Cesium3DTilesetTraversal.js | 72 +++++-------------- 3 files changed, 67 insertions(+), 82 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index db922b9a637..ef846759eee 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -578,6 +578,22 @@ Object.defineProperties(Cesium3DTile.prototype, { }, }, + /** + * Determines if the tile is visible within the current field of view + * + * @memberof Cesium3DTile.prototype + * + * @type {boolean} + * @readonly + * + * @private + */ + isVisible: { + get: function () { + return this._visible && this._inRequestVolume; + }, + }, + /** * Returns the <code>extras</code> property in the tileset JSON for this tile, which contains application specific metadata. * Returns <code>undefined</code> if <code>extras</code> does not exist. @@ -618,6 +634,27 @@ Object.defineProperties(Cesium3DTile.prototype, { }, }, + /** + * Determines if the tile's content is renderable. <code>false</code> if the + * tile has empty content or if it points to an external tileset or implicit content + * + * @memberof Cesium3DTile.prototype + * + * @type {boolean} + * @readonly + * + * @private + */ + hasRenderableContent: { + get: function () { + return ( + !this.hasEmptyContent && + !this.hasTilesetContent && + !this.hasImplicitContent + ); + }, + }, + /** * Determines if the tile has available content to render. <code>true</code> if the tile's * content is ready or if it has expired content that renders while new content loads; otherwise, @@ -633,10 +670,7 @@ Object.defineProperties(Cesium3DTile.prototype, { contentAvailable: { get: function () { return ( - (this.contentReady && - !this.hasEmptyContent && - !this.hasTilesetContent && - !this.hasImplicitContent) || + (this.contentReady && this.hasRenderableContent) || (defined(this._expiredContent) && !this.contentFailed) ); }, @@ -991,6 +1025,11 @@ function getPriorityReverseScreenSpaceError(tileset, tile) { */ Cesium3DTile.prototype.updateVisibility = function (frameState) { const { parent, tileset } = this; + if (this._updatedVisibilityFrame === tileset._updatedVisibilityFrame) { + // The tile has already been updated for this frame + return; + } + const parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix; @@ -1021,6 +1060,8 @@ Cesium3DTile.prototype.updateVisibility = function (frameState) { this ); this.priorityDeferred = isPriorityDeferred(this, frameState); + + this._updatedVisibilityFrame = tileset._updatedVisibilityFrame; }; /** @@ -1416,11 +1457,7 @@ Cesium3DTile.prototype.cancelRequests = function () { * @private */ Cesium3DTile.prototype.unloadContent = function () { - if ( - this.hasEmptyContent || - this.hasTilesetContent || - this.hasImplicitContent - ) { + if (!this.hasRenderableContent) { return; } @@ -1896,8 +1933,6 @@ function applyDebugSettings(tile, tileset, frameState, passOptions) { const hasContentBoundingVolume = defined(tile._contentHeader) && defined(tile._contentHeader.boundingVolume); - const empty = - tile.hasEmptyContent || tile.hasTilesetContent || tile.hasImplicitContent; const showVolume = tileset.debugShowBoundingVolume || @@ -1906,7 +1941,7 @@ function applyDebugSettings(tile, tileset, frameState, passOptions) { let color; if (!tile._finalResolution) { color = Color.YELLOW; - } else if (empty) { + } else if (!tile.hasRenderableContent) { color = Color.DARKGRAY; } else { color = Color.WHITE; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js index 7fe1e10ba20..4b7f0a3858e 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js @@ -28,7 +28,7 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( const root = tileset.root; root.updateVisibility(frameState); - if (!isVisible(root)) { + if (!root.isVisible) { return ready; } @@ -55,7 +55,7 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( touchTile(tileset, tile, frameState); selectDesiredTile(tileset, tile, frameState); - if (!hasEmptyContent(tile) && !tile.contentAvailable) { + if (tile.hasRenderableContent && !tile.contentAvailable) { ready = false; } } @@ -68,18 +68,8 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( return ready; }; -function isVisible(tile) { - return tile._visible && tile._inRequestVolume; -} - -function hasEmptyContent(tile) { - return ( - tile.hasEmptyContent || tile.hasTilesetContent || tile.hasImplicitContent - ); -} - function hasUnloadedContent(tile) { - return !hasEmptyContent(tile) && tile.contentUnloaded; + return tile.hasRenderableContent && tile.contentUnloaded; } function canTraverse(tileset, tile) { @@ -107,7 +97,7 @@ function updateAndPushChildren(tileset, tile, stack, frameState) { for (let i = 0; i < length; ++i) { const child = children[i]; child.updateVisibility(frameState); - if (isVisible(child)) { + if (child.isVisible) { stack.push(child); } } diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 7da76155fed..e04794e71f2 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -53,7 +53,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { const root = tileset.root; updateTile(root, frameState); - if (!isVisible(root)) { + if (!root.isVisible) { return; } @@ -92,15 +92,6 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { } }; -/** - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} Whether the tile is within the current field of view - */ -function isVisible(tile) { - return tile._visible && tile._inRequestVolume; -} - /** * The private ._skipLevelOfDetail flag on a Cesium3DTileset is updated in * Cesium3DTileset.prototype.prePassesUpdate to confirm if skipping is actually @@ -159,7 +150,7 @@ function selectDescendants(root, frameState) { const children = tile.children; for (let i = 0; i < children.length; ++i) { const child = children[i]; - if (isVisible(child)) { + if (child.isVisible) { if (child.contentAvailable) { updateTile(child, frameState); touchTile(child, frameState); @@ -329,25 +320,6 @@ function loadTile(tile, frameState) { tileset._requestedTiles.push(tile); } -/** - * Wrap Cesium3DTile.prototype.updateVisibility to avoid repeated updates - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function updateVisibility(tile, frameState) { - const updatedVisibilityFrame = tile.tileset._updatedVisibilityFrame; - if (tile._updatedVisibilityFrame === updatedVisibilityFrame) { - // Return early if visibility has already been checked during the traversal. - // The visibility may have already been checked if the cullWithChildrenBounds optimization is used. - return; - } - - tile.updateVisibility(frameState); - tile._updatedVisibilityFrame = updatedVisibilityFrame; -} - /** * @private * @param {Cesium3DTile} tile @@ -359,8 +331,8 @@ function anyChildrenVisible(tile, frameState) { const children = tile.children; for (let i = 0; i < children.length; ++i) { const child = children[i]; - updateVisibility(child, frameState); - anyVisible = anyVisible || isVisible(child); + child.updateVisibility(frameState); + anyVisible = anyVisible || child.isVisible; } return anyVisible; } @@ -395,9 +367,9 @@ function meetsScreenSpaceErrorEarly(tile, frameState) { * @param {FrameState} frameState */ function updateTileVisibility(tile, frameState) { - updateVisibility(tile, frameState); + tile.updateVisibility(frameState); - if (!isVisible(tile)) { + if (!tile.isVisible) { return; } @@ -482,24 +454,13 @@ function updateTileAncestorContentLinks(tile, frameState) { : parent._ancestorWithContentAvailable; } -/** - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} - */ -function hasEmptyContent(tile) { - return ( - tile.hasEmptyContent || tile.hasTilesetContent || tile.hasImplicitContent - ); -} - /** * @private * @param {Cesium3DTile} tile * @returns {boolean} */ function hasUnloadedContent(tile) { - return !hasEmptyContent(tile) && tile.contentUnloaded; + return tile.hasRenderableContent && tile.contentUnloaded; } /** @@ -560,7 +521,7 @@ function updateAndPushChildren(tile, stack, frameState) { // For traditional replacement refinement only refine if all children are loaded. // Empty tiles are exempt since it looks better if children stream in as they are loaded to fill the empty space. const checkRefines = - !skipLevelOfDetail(tileset) && replace && !hasEmptyContent(tile); + !skipLevelOfDetail(tileset) && replace && tile.hasRenderableContent; let refines = true; let anyChildrenVisible = false; @@ -571,7 +532,7 @@ function updateAndPushChildren(tile, stack, frameState) { for (let i = 0; i < children.length; ++i) { const child = children[i]; - if (isVisible(child)) { + if (child.isVisible) { stack.push(child); if (child._foveatedFactor < minimumPriority) { minIndex = i; @@ -592,7 +553,7 @@ function updateAndPushChildren(tile, stack, frameState) { let childRefines; if (!child._inRequestVolume) { childRefines = false; - } else if (hasEmptyContent(child)) { + } else if (!child.hasRenderableContent) { childRefines = executeEmptyTraversal(child, frameState); } else { childRefines = child.contentAvailable; @@ -716,7 +677,7 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { const stoppedRefining = !tile._refines && parentRefines; - if (hasEmptyContent(tile)) { + if (!tile.hasRenderableContent) { // Add empty tile just to show its debug bounding volume // If the tile has tileset content load the external tileset // If the tile cannot refine further select its nearest loaded ancestor @@ -776,10 +737,9 @@ function executeEmptyTraversal(root, frameState) { const children = tile.children; const childrenLength = children.length; - // Only traverse if the tile is empty - traversal stop at descendants with content - const emptyContent = hasEmptyContent(tile); - const traverse = emptyContent && canTraverse(tile); - const emptyLeaf = emptyContent && tile.children.length === 0; + // Only traverse if the tile is empty - traversal stops at descendants with content + const traverse = !tile.hasRenderableContent && canTraverse(tile); + const emptyLeaf = !tile.hasRenderableContent && tile.children.length === 0; // Traversal stops but the tile does not have content yet // There will be holes if the parent tries to refine to its children, so don't refine @@ -789,7 +749,7 @@ function executeEmptyTraversal(root, frameState) { } updateTile(tile, frameState); - if (!isVisible(tile)) { + if (!tile.isVisible) { // Load tiles that aren't visible since they are still needed for the parent to refine loadTile(tile, frameState); touchTile(tile, frameState); @@ -884,7 +844,7 @@ function traverseAndSelect(root, frameState) { const children = tile.children; for (let i = 0; i < children.length; ++i) { const child = children[i]; - if (isVisible(child)) { + if (child.isVisible) { stack.push(child); } } From fb3ef493407c85b016fa14f54ef63d83e1093464 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 9 Mar 2023 16:22:54 -0500 Subject: [PATCH 537/679] Tweak CHANGES.md --- CHANGES.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index e396c6fc4f2..b2e896226f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,12 @@ - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) +#### @cesium/widgets + +##### Fixes :wrench: + +- Fixed Cesium.Viewer instantiated inside my lit component: CreditDisplay is missing its styles [#10907](https://github.com/CesiumGS/cesium/issues/10907) + ### 1.103 - 2023-03-01 #### @cesium/engine @@ -19,7 +25,6 @@ ##### Fixes :wrench: -- Fixed Cesium.Viewer instantiated inside my lit component: CreditDisplay is missing its styles [#10907](https://github.com/CesiumGS/cesium/issues/10907) - Fixed browser warning for `willReadFrequently` option. [#11025](https://github.com/CesiumGS/cesium/issues/11025) - Replaced constructor types with primitive types in JSDoc and generated TypeScript definitions. [#11080](https://github.com/CesiumGS/cesium/pull/11080) - Adjusted render order of voxels and opaque entities. [#11120](https://github.com/CesiumGS/cesium/pull/11120) From 73bf2f32113bbe92b87401e9d460b70e6927edea Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 9 Mar 2023 18:57:50 -0500 Subject: [PATCH 538/679] Use private skipLevelOfDetail flag more consistently --- .../engine/Source/Scene/Cesium3DTileset.js | 9 +++++++ .../Source/Scene/Cesium3DTilesetTraversal.js | 25 +++++-------------- packages/engine/Source/Scene/Model/Model.js | 2 +- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 5511a21ef52..85efe729096 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -654,6 +654,15 @@ function Cesium3DTileset(options) { * @default false */ this.skipLevelOfDetail = defaultValue(options.skipLevelOfDetail, false); + + /** + * Whether this tileset is actually skipping levels of detail. + * The user option may have been disabled if all tiles are using additive refinement, + * or if some tiles have a content type for which rendering does not support skipping + * + * @private + * @type {boolean} + */ this._skipLevelOfDetail = this.skipLevelOfDetail; this._disableSkipLevelOfDetail = false; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index e04794e71f2..a58ca1c0a46 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -64,7 +64,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { return; } - const baseScreenSpaceError = !skipLevelOfDetail(tileset) + const baseScreenSpaceError = !tileset._skipLevelOfDetail ? tileset._maximumScreenSpaceError : tileset.immediatelyLoadDesiredLevelOfDetail ? Number.MAX_VALUE @@ -72,7 +72,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { executeTraversal(root, baseScreenSpaceError, frameState); - if (skipLevelOfDetail(tileset)) { + if (tileset._skipLevelOfDetail) { traverseAndSelect(root, frameState); } @@ -92,19 +92,6 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { } }; -/** - * The private ._skipLevelOfDetail flag on a Cesium3DTileset is updated in - * Cesium3DTileset.prototype.prePassesUpdate to confirm if skipping is actually - * possible and allowed, even when the public .skipLevelOfDetail flag is true - * - * @private - * @param {Cesium3DTileset} tileset - * @returns {boolean} Whether to do LOD skipping - */ -function skipLevelOfDetail(tileset) { - return tileset._skipLevelOfDetail; -} - /** * Mark a tile as selected, and add it to the tileset's list of selected tiles * @@ -174,7 +161,7 @@ function selectDescendants(root, frameState) { * @param {FrameState} frameState */ function selectDesiredTile(tile, frameState) { - if (!skipLevelOfDetail(tile.tileset)) { + if (!tile.tileset._skipLevelOfDetail) { if (tile.contentAvailable) { // The tile can be selected right away and does not require traverseAndSelect selectTile(tile, frameState); @@ -521,7 +508,7 @@ function updateAndPushChildren(tile, stack, frameState) { // For traditional replacement refinement only refine if all children are loaded. // Empty tiles are exempt since it looks better if children stream in as they are loaded to fill the empty space. const checkRefines = - !skipLevelOfDetail(tileset) && replace && tile.hasRenderableContent; + !tileset._skipLevelOfDetail && replace && tile.hasRenderableContent; let refines = true; let anyChildrenVisible = false; @@ -566,7 +553,7 @@ function updateAndPushChildren(tile, stack, frameState) { refines = false; } - if (minIndex !== -1 && !skipLevelOfDetail(tileset) && replace) { + if (minIndex !== -1 && !tileset.skipLevelOfDetail && replace) { // An ancestor will hold the _foveatedFactor and _distanceToCamera for descendants between itself and its highest priority descendant. Siblings of a min children along the way use this ancestor as their priority holder as well. // Priority of all tiles that refer to the _foveatedFactor and _distanceToCamera stored in the common ancestor will be differentiated based on their _depth. const minPriorityChild = children[minIndex]; @@ -604,7 +591,7 @@ function updateAndPushChildren(tile, stack, frameState) { */ function inBaseTraversal(tile, baseScreenSpaceError) { const { tileset } = tile; - if (!skipLevelOfDetail(tileset)) { + if (!tileset._skipLevelOfDetail) { return true; } if (tileset.immediatelyLoadDesiredLevelOfDetail) { diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index a25ea3b0806..da958787bf2 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -2449,7 +2449,7 @@ Model.prototype.hasSkipLevelOfDetail = function (frameState) { } const tileset = this._content.tileset; - return supportsSkipLevelOfDetail(frameState) && tileset.skipLevelOfDetail; + return supportsSkipLevelOfDetail(frameState) && tileset._skipLevelOfDetail; }; /** From b5962b097a8dd94febc6bccf1444e36fdf4755f3 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 9 Mar 2023 20:37:35 -0500 Subject: [PATCH 539/679] Pull TraversalUtility functions out of Cesium3DTilesetTraversal --- .../Source/Scene/Cesium3DTilesetTraversal.js | 303 +---------------- .../engine/Source/Scene/TraversalUtility.js | 311 ++++++++++++++++++ 2 files changed, 320 insertions(+), 294 deletions(-) create mode 100644 packages/engine/Source/Scene/TraversalUtility.js diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index a58ca1c0a46..afd1637ea0c 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -1,8 +1,7 @@ import defined from "../Core/defined.js"; -import Intersect from "../Core/Intersect.js"; import ManagedArray from "../Core/ManagedArray.js"; -import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js"; import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; +import TraversalUtility from "./TraversalUtility.js"; /** * @private @@ -51,7 +50,7 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { tileset._hasMixedContent = false; const root = tileset.root; - updateTile(root, frameState); + TraversalUtility.updateTile(root, frameState); if (!root.isVisible) { return; @@ -92,32 +91,6 @@ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { } }; -/** - * Mark a tile as selected, and add it to the tileset's list of selected tiles - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function selectTile(tile, frameState) { - if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { - return; - } - - const { content, tileset } = tile; - if (content.featurePropertiesDirty) { - // A feature's property in this tile changed, the tile needs to be re-styled. - content.featurePropertiesDirty = false; - tile.lastStyleTime = 0; // Force applying the style to this tile - tileset._selectedTilesToStyle.push(tile); - } else if (tile._selectedFrame < frameState.frameNumber - 1) { - // Tile is newly selected; it is selected this frame, but was not selected last frame. - tileset._selectedTilesToStyle.push(tile); - } - tile._selectedFrame = frameState.frameNumber; - tileset._selectedTiles.push(tile); -} - /** * Mark descendant tiles for rendering, and update as needed * @@ -126,6 +99,7 @@ function selectTile(tile, frameState) { * @param {FrameState} frameState */ function selectDescendants(root, frameState) { + const { updateTile, touchTile, selectTile } = TraversalUtility; const stack = descendantTraversal.stack; stack.push(root); while (stack.length > 0) { @@ -164,7 +138,7 @@ function selectDesiredTile(tile, frameState) { if (!tile.tileset._skipLevelOfDetail) { if (tile.contentAvailable) { // The tile can be selected right away and does not require traverseAndSelect - selectTile(tile, frameState); + TraversalUtility.selectTile(tile, frameState); } return; } @@ -183,233 +157,6 @@ function selectDesiredTile(tile, frameState) { } } -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function visitTile(tile, frameState) { - ++tile.tileset._statistics.visited; - tile._visitedFrame = frameState.frameNumber; -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function touchTile(tile, frameState) { - if (tile._touchedFrame === frameState.frameNumber) { - // Prevents another pass from touching the frame again - return; - } - tile.tileset._cache.touch(tile); - tile._touchedFrame = frameState.frameNumber; -} - -/** - * @private - * @param {Cesium3DTile} tile - */ -function updateMinimumMaximumPriority(tile) { - const { - _maximumPriority: maximumPriority, - _minimumPriority: minimumPriority, - } = tile.tileset; - const priorityHolder = tile._priorityHolder; - - maximumPriority.distance = Math.max( - priorityHolder._distanceToCamera, - maximumPriority.distance - ); - minimumPriority.distance = Math.min( - priorityHolder._distanceToCamera, - minimumPriority.distance - ); - maximumPriority.depth = Math.max(tile._depth, maximumPriority.depth); - minimumPriority.depth = Math.min(tile._depth, minimumPriority.depth); - maximumPriority.foveatedFactor = Math.max( - priorityHolder._foveatedFactor, - maximumPriority.foveatedFactor - ); - minimumPriority.foveatedFactor = Math.min( - priorityHolder._foveatedFactor, - minimumPriority.foveatedFactor - ); - maximumPriority.reverseScreenSpaceError = Math.max( - tile._priorityReverseScreenSpaceError, - maximumPriority.reverseScreenSpaceError - ); - minimumPriority.reverseScreenSpaceError = Math.min( - tile._priorityReverseScreenSpaceError, - minimumPriority.reverseScreenSpaceError - ); -} - -/** - * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function isOnScreenLongEnough(tile, frameState) { - const { tileset } = tile; - if (!tileset._cullRequestsWhileMoving) { - return true; - } - - const { - positionWCDeltaMagnitude, - positionWCDeltaMagnitudeLastFrame, - } = frameState.camera; - const deltaMagnitude = - positionWCDeltaMagnitude !== 0.0 - ? positionWCDeltaMagnitude - : positionWCDeltaMagnitudeLastFrame; - - // How do n frames of this movement compare to the tile's physical size. - const diameter = Math.max(tile.boundingSphere.radius * 2.0, 1.0); - const movementRatio = - (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; - - return movementRatio < 1.0; -} - -/** - * Add a tile to the list of requested tiles, if appropriate - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function loadTile(tile, frameState) { - const { tileset } = tile; - if ( - tile._requestedFrame === frameState.frameNumber || - (!hasUnloadedContent(tile) && !tile.contentExpired) - ) { - return; - } - - if (!isOnScreenLongEnough(tile, frameState)) { - return; - } - - const cameraHasNotStoppedMovingLongEnough = - frameState.camera.timeSinceMoved < tileset.foveatedTimeDelay; - if (tile.priorityDeferred && cameraHasNotStoppedMovingLongEnough) { - return; - } - - tile._requestedFrame = frameState.frameNumber; - tileset._requestedTiles.push(tile); -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function anyChildrenVisible(tile, frameState) { - let anyVisible = false; - const children = tile.children; - for (let i = 0; i < children.length; ++i) { - const child = children[i]; - child.updateVisibility(frameState); - anyVisible = anyVisible || child.isVisible; - } - return anyVisible; -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function meetsScreenSpaceErrorEarly(tile, frameState) { - const { parent, tileset } = tile; - if ( - !defined(parent) || - parent.hasTilesetContent || - parent.hasImplicitContent || - parent.refine !== Cesium3DTileRefine.ADD - ) { - return false; - } - - // Use parent's geometric error with child's box to see if the tile already meet the SSE - return ( - tile.getScreenSpaceError(frameState, true) <= - tileset._maximumScreenSpaceError - ); -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function updateTileVisibility(tile, frameState) { - tile.updateVisibility(frameState); - - if (!tile.isVisible) { - return; - } - - const hasChildren = tile.children.length > 0; - if ((tile.hasTilesetContent || tile.hasImplicitContent) && hasChildren) { - // Use the root tile's visibility instead of this tile's visibility. - // The root tile may be culled by the children bounds optimization in which - // case this tile should also be culled. - const child = tile.children[0]; - updateTileVisibility(child, frameState); - tile._visible = child._visible; - return; - } - - if (meetsScreenSpaceErrorEarly(tile, frameState)) { - tile._visible = false; - return; - } - - // Optimization - if none of the tile's children are visible then this tile isn't visible - const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const useOptimization = - tile._optimChildrenWithinParent === - Cesium3DTileOptimizationHint.USE_OPTIMIZATION; - if (replace && useOptimization && hasChildren) { - if (!anyChildrenVisible(tile, frameState)) { - ++tile.tileset._statistics.numberOfTilesCulledWithChildrenUnion; - tile._visible = false; - return; - } - } -} - -/** - * Reset some of the tile's flags and re-evaluate visibility and priority - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function updateTile(tile, frameState) { - updateTileVisibility(tile, frameState); - tile.updateExpiration(); - - tile._wasMinPriorityChild = false; - tile._priorityHolder = tile; - updateMinimumMaximumPriority(tile); - - // SkipLOD - tile._shouldSelect = false; - tile._finalResolution = true; -} - /** * Update links to the ancestor tiles that have content * @@ -471,22 +218,6 @@ function reachedSkippingThreshold(tileset, tile) { ); } -/** - * Sort by farthest child first since this is going on a stack - * - * @private - * @param {Cesium3DTile} a - * @param {Cesium3DTile} b - * @returns {number} - */ -function sortChildrenByDistanceToCamera(a, b) { - if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { - return b._centerZDepth - a._centerZDepth; - } - - return b._distanceToCamera - a._distanceToCamera; -} - /** * @private * @param {Cesium3DTile} tile @@ -497,13 +228,14 @@ function sortChildrenByDistanceToCamera(a, b) { function updateAndPushChildren(tile, stack, frameState) { const replace = tile.refine === Cesium3DTileRefine.REPLACE; const { tileset, children } = tile; + const { updateTile, loadTile, touchTile } = TraversalUtility; for (let i = 0; i < children.length; ++i) { updateTile(children[i], frameState); } // Sort by distance to take advantage of early Z and reduce artifacts for skipLevelOfDetail - children.sort(sortChildrenByDistanceToCamera); + children.sort(TraversalUtility.sortChildrenByDistanceToCamera); // For traditional replacement refinement only refine if all children are loaded. // Empty tiles are exempt since it looks better if children stream in as they are loaded to fill the empty space. @@ -608,26 +340,6 @@ function inBaseTraversal(tile, baseScreenSpaceError) { return tile._screenSpaceError > baseScreenSpaceError; } -/** - * Determine if a tile can and should be traversed for children tiles that - * would contribute to rendering the current view - * - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} - */ -function canTraverse(tile) { - if (tile.children.length === 0) { - return false; - } - if (tile.hasTilesetContent || tile.hasImplicitContent) { - // Traverse external tileset to visit its root tile - // Don't traverse if the subtree is expired because it will be destroyed - return !tile.contentExpired; - } - return tile._screenSpaceError > tile.tileset._maximumScreenSpaceError; -} - /** * Depth-first traversal that traverses all visible tiles and marks tiles for selection. * If skipLevelOfDetail is off then a tile does not refine until all children are loaded. @@ -643,6 +355,7 @@ function canTraverse(tile) { */ function executeTraversal(root, baseScreenSpaceError, frameState) { const { tileset } = root; + const { canTraverse, loadTile, visitTile, touchTile } = TraversalUtility; const stack = traversal.stack; stack.push(root); @@ -710,6 +423,7 @@ function executeTraversal(root, baseScreenSpaceError, frameState) { * @returns {boolean} */ function executeEmptyTraversal(root, frameState) { + const { canTraverse, updateTile, loadTile, touchTile } = TraversalUtility; let allDescendantsLoaded = true; const stack = emptyTraversal.stack; stack.push(root); @@ -774,6 +488,7 @@ function executeEmptyTraversal(root, frameState) { * @param {FrameState} frameState */ function traverseAndSelect(root, frameState) { + const { selectTile, canTraverse } = TraversalUtility; const { stack, ancestorStack } = selectionTraversal; let lastAncestor; diff --git a/packages/engine/Source/Scene/TraversalUtility.js b/packages/engine/Source/Scene/TraversalUtility.js new file mode 100644 index 00000000000..c02e5c050ee --- /dev/null +++ b/packages/engine/Source/Scene/TraversalUtility.js @@ -0,0 +1,311 @@ +import defined from "../Core/defined.js"; +import Intersect from "../Core/Intersect.js"; +import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js"; +import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; + +/** + * Utility functions for {@link Cesium3DTilesetTraversal}. + * + * @private + */ +function TraversalUtility() {} + +/** + * Sort by farthest child first since this is going on a stack + * + * @private + * @param {Cesium3DTile} a + * @param {Cesium3DTile} b + * @returns {number} + */ +TraversalUtility.sortChildrenByDistanceToCamera = function (a, b) { + if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { + return b._centerZDepth - a._centerZDepth; + } + + return b._distanceToCamera - a._distanceToCamera; +}; + +/** + * Determine if a tile can and should be traversed for children tiles that + * would contribute to rendering the current view + * + * @private + * @param {Cesium3DTile} tile + * @returns {boolean} + */ +TraversalUtility.canTraverse = function (tile) { + if (tile.children.length === 0) { + return false; + } + if (tile.hasTilesetContent || tile.hasImplicitContent) { + // Traverse external tileset to visit its root tile + // Don't traverse if the subtree is expired because it will be destroyed + return !tile.contentExpired; + } + return tile._screenSpaceError > tile.tileset._maximumScreenSpaceError; +}; + +/** + * Mark a tile as selected, and add it to the tileset's list of selected tiles + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +TraversalUtility.selectTile = function (tile, frameState) { + if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { + return; + } + + const { content, tileset } = tile; + if (content.featurePropertiesDirty) { + // A feature's property in this tile changed, the tile needs to be re-styled. + content.featurePropertiesDirty = false; + tile.lastStyleTime = 0; // Force applying the style to this tile + tileset._selectedTilesToStyle.push(tile); + } else if (tile._selectedFrame < frameState.frameNumber - 1) { + // Tile is newly selected; it is selected this frame, but was not selected last frame. + tileset._selectedTilesToStyle.push(tile); + } + tile._selectedFrame = frameState.frameNumber; + tileset._selectedTiles.push(tile); +}; + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +TraversalUtility.visitTile = function (tile, frameState) { + ++tile.tileset._statistics.visited; + tile._visitedFrame = frameState.frameNumber; +}; + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +TraversalUtility.touchTile = function (tile, frameState) { + if (tile._touchedFrame === frameState.frameNumber) { + // Prevents another pass from touching the frame again + return; + } + tile.tileset._cache.touch(tile); + tile._touchedFrame = frameState.frameNumber; +}; + +/** + * Add a tile to the list of requested tiles, if appropriate + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +TraversalUtility.loadTile = function (tile, frameState) { + const { tileset } = tile; + if ( + tile._requestedFrame === frameState.frameNumber || + (!hasUnloadedContent(tile) && !tile.contentExpired) + ) { + return; + } + + if (!isOnScreenLongEnough(tile, frameState)) { + return; + } + + const cameraHasNotStoppedMovingLongEnough = + frameState.camera.timeSinceMoved < tileset.foveatedTimeDelay; + if (tile.priorityDeferred && cameraHasNotStoppedMovingLongEnough) { + return; + } + + tile._requestedFrame = frameState.frameNumber; + tileset._requestedTiles.push(tile); +}; + +/** + * @private + * @param {Cesium3DTile} tile + * @returns {boolean} + */ +function hasUnloadedContent(tile) { + return tile.hasRenderableContent && tile.contentUnloaded; +} + +/** + * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ +function isOnScreenLongEnough(tile, frameState) { + const { tileset } = tile; + if (!tileset._cullRequestsWhileMoving) { + return true; + } + + const { + positionWCDeltaMagnitude, + positionWCDeltaMagnitudeLastFrame, + } = frameState.camera; + const deltaMagnitude = + positionWCDeltaMagnitude !== 0.0 + ? positionWCDeltaMagnitude + : positionWCDeltaMagnitudeLastFrame; + + // How do n frames of this movement compare to the tile's physical size. + const diameter = Math.max(tile.boundingSphere.radius * 2.0, 1.0); + const movementRatio = + (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; + + return movementRatio < 1.0; +} + +/** + * Reset some of the tile's flags and re-evaluate visibility and priority + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +TraversalUtility.updateTile = function (tile, frameState) { + updateTileVisibility(tile, frameState); + tile.updateExpiration(); + + tile._wasMinPriorityChild = false; + tile._priorityHolder = tile; + updateMinimumMaximumPriority(tile); + + // SkipLOD + tile._shouldSelect = false; + tile._finalResolution = true; +}; + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +function updateTileVisibility(tile, frameState) { + tile.updateVisibility(frameState); + + if (!tile.isVisible) { + return; + } + + const hasChildren = tile.children.length > 0; + if ((tile.hasTilesetContent || tile.hasImplicitContent) && hasChildren) { + // Use the root tile's visibility instead of this tile's visibility. + // The root tile may be culled by the children bounds optimization in which + // case this tile should also be culled. + const child = tile.children[0]; + updateTileVisibility(child, frameState); + tile._visible = child._visible; + return; + } + + if (meetsScreenSpaceErrorEarly(tile, frameState)) { + tile._visible = false; + return; + } + + // Optimization - if none of the tile's children are visible then this tile isn't visible + const replace = tile.refine === Cesium3DTileRefine.REPLACE; + const useOptimization = + tile._optimChildrenWithinParent === + Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + if (replace && useOptimization && hasChildren) { + if (!anyChildrenVisible(tile, frameState)) { + ++tile.tileset._statistics.numberOfTilesCulledWithChildrenUnion; + tile._visible = false; + return; + } + } +} + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ +function meetsScreenSpaceErrorEarly(tile, frameState) { + const { parent, tileset } = tile; + if ( + !defined(parent) || + parent.hasTilesetContent || + parent.hasImplicitContent || + parent.refine !== Cesium3DTileRefine.ADD + ) { + return false; + } + + // Use parent's geometric error with child's box to see if the tile already meet the SSE + return ( + tile.getScreenSpaceError(frameState, true) <= + tileset._maximumScreenSpaceError + ); +} + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + * @returns {boolean} + */ +function anyChildrenVisible(tile, frameState) { + let anyVisible = false; + const children = tile.children; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + child.updateVisibility(frameState); + anyVisible = anyVisible || child.isVisible; + } + return anyVisible; +} + +/** + * @private + * @param {Cesium3DTile} tile + */ +function updateMinimumMaximumPriority(tile) { + const { + _maximumPriority: maximumPriority, + _minimumPriority: minimumPriority, + } = tile.tileset; + const priorityHolder = tile._priorityHolder; + + maximumPriority.distance = Math.max( + priorityHolder._distanceToCamera, + maximumPriority.distance + ); + minimumPriority.distance = Math.min( + priorityHolder._distanceToCamera, + minimumPriority.distance + ); + maximumPriority.depth = Math.max(tile._depth, maximumPriority.depth); + minimumPriority.depth = Math.min(tile._depth, minimumPriority.depth); + maximumPriority.foveatedFactor = Math.max( + priorityHolder._foveatedFactor, + maximumPriority.foveatedFactor + ); + minimumPriority.foveatedFactor = Math.min( + priorityHolder._foveatedFactor, + minimumPriority.foveatedFactor + ); + maximumPriority.reverseScreenSpaceError = Math.max( + tile._priorityReverseScreenSpaceError, + maximumPriority.reverseScreenSpaceError + ); + minimumPriority.reverseScreenSpaceError = Math.min( + tile._priorityReverseScreenSpaceError, + minimumPriority.reverseScreenSpaceError + ); +} + +export default TraversalUtility; From a9942be24a2dac5b1cce2a174a143cd26b068468 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 10 Mar 2023 13:10:04 -0500 Subject: [PATCH 540/679] Continue separating traversal logic --- packages/engine/Source/Scene/Cesium3DTile.js | 16 +++++++ .../Cesium3DTilesetMostDetailedTraversal.js | 44 +++++++------------ .../Source/Scene/Cesium3DTilesetTraversal.js | 11 +---- .../engine/Source/Scene/TraversalUtility.js | 11 +---- 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index ef846759eee..f3de7ee3fb0 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -710,6 +710,22 @@ Object.defineProperties(Cesium3DTile.prototype, { }, }, + /** + * Determines if the tile has renderable content which is unloaded + * + * @memberof Cesium3DTile.prototype + * + * @type {boolean} + * @readonly + * + * @private + */ + hasUnloadedRenderableContent: { + get: function () { + return this.hasRenderableContent && this.contentUnloaded; + }, + }, + /** * Determines if the tile's content is expired. <code>true</code> if tile's * content is expired; otherwise, <code>false</code>. diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js index 4b7f0a3858e..af99a6a0595 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js @@ -1,6 +1,7 @@ import Intersect from "../Core/Intersect.js"; import ManagedArray from "../Core/ManagedArray.js"; import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; +import TraversalUtility from "./TraversalUtility.js"; /** * Traversal that loads all leaves that intersect the camera frustum. @@ -32,8 +33,10 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( return ready; } + const { touchTile, visitTile } = TraversalUtility; + const stack = traversal.stack; - stack.push(tileset.root); + stack.push(root); while (stack.length > 0) { traversal.stackMaximumLength = Math.max( @@ -44,23 +47,23 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( const tile = stack.pop(); const add = tile.refine === Cesium3DTileRefine.ADD; const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const traverse = canTraverse(tileset, tile); + const traverse = canTraverse(tile); if (traverse) { - updateAndPushChildren(tileset, tile, stack, frameState); + updateAndPushChildren(tile, stack, frameState); } if (add || (replace && !traverse)) { loadTile(tileset, tile); - touchTile(tileset, tile, frameState); - selectDesiredTile(tileset, tile, frameState); + touchTile(tile, frameState); + selectDesiredTile(tile, frameState); if (tile.hasRenderableContent && !tile.contentAvailable) { ready = false; } } - visitTile(tileset); + visitTile(tile, frameState); } traversal.stack.trim(traversal.stackMaximumLength); @@ -72,7 +75,7 @@ function hasUnloadedContent(tile) { return tile.hasRenderableContent && tile.contentUnloaded; } -function canTraverse(tileset, tile) { +function canTraverse(tile) { if (tile.children.length === 0) { return false; } @@ -87,14 +90,13 @@ function canTraverse(tileset, tile) { return true; } - return true; // Keep traversing until a leave is hit + return true; // Keep traversing until a leaf is hit } -function updateAndPushChildren(tileset, tile, stack, frameState) { - const children = tile.children; - const length = children.length; +function updateAndPushChildren(tile, stack, frameState) { + const { children } = tile; - for (let i = 0; i < length; ++i) { + for (let i = 0; i < children.length; ++i) { const child = children[i]; child.updateVisibility(frameState); if (child.isVisible) { @@ -110,25 +112,13 @@ function loadTile(tileset, tile) { } } -function touchTile(tileset, tile, frameState) { - if (tile._touchedFrame === frameState.frameNumber) { - // Prevents another pass from touching the frame again - return; - } - tileset._cache.touch(tile); - tile._touchedFrame = frameState.frameNumber; -} - -function visitTile(tileset) { - ++tileset.statistics.visited; -} - -function selectDesiredTile(tileset, tile, frameState) { +function selectDesiredTile(tile, frameState) { if ( tile.contentAvailable && tile.contentVisibility(frameState) !== Intersect.OUTSIDE ) { - tileset._selectedTiles.push(tile); + tile.tileset._selectedTiles.push(tile); } } + export default Cesium3DTilesetMostDetailedTraversal; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index afd1637ea0c..a0423856dd4 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -173,7 +173,7 @@ function updateTileAncestorContentLinks(tile, frameState) { return; } const parentHasContent = - !hasUnloadedContent(parent) || + !parent.hasUnloadedRenderableContent || parent._requestedFrame === frameState.frameNumber; // ancestorWithContent is an ancestor that has content or has the potential to have @@ -188,15 +188,6 @@ function updateTileAncestorContentLinks(tile, frameState) { : parent._ancestorWithContentAvailable; } -/** - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} - */ -function hasUnloadedContent(tile) { - return tile.hasRenderableContent && tile.contentUnloaded; -} - /** * Determine if a tile has reached the limit of level of detail skipping. * If so, it should _not_ be skipped: it should be loaded and rendered diff --git a/packages/engine/Source/Scene/TraversalUtility.js b/packages/engine/Source/Scene/TraversalUtility.js index c02e5c050ee..ffd90c70663 100644 --- a/packages/engine/Source/Scene/TraversalUtility.js +++ b/packages/engine/Source/Scene/TraversalUtility.js @@ -107,7 +107,7 @@ TraversalUtility.loadTile = function (tile, frameState) { const { tileset } = tile; if ( tile._requestedFrame === frameState.frameNumber || - (!hasUnloadedContent(tile) && !tile.contentExpired) + (!tile.hasUnloadedRenderableContent && !tile.contentExpired) ) { return; } @@ -126,15 +126,6 @@ TraversalUtility.loadTile = function (tile, frameState) { tileset._requestedTiles.push(tile); }; -/** - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} - */ -function hasUnloadedContent(tile) { - return tile.hasRenderableContent && tile.contentUnloaded; -} - /** * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. * From 4fb18c956ccf7d5d223953ab00068d325f1e5620 Mon Sep 17 00:00:00 2001 From: JakeVanDine <jv477@drexel.edu> Date: Fri, 10 Mar 2023 19:59:21 -0500 Subject: [PATCH 541/679] docs-issue-10303: -initial commit -added name to CONTRIBUTORS.md -added more description for enableCollisionDetection in HTML file --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 822a5ea600f..77083950bd9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -348,3 +348,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Tengfei](https://github.com/i-tengfei) - [Rudolf Farkas](https://github.com/rudifa) - [Nick Noce](https://github.com/nnoce14) +- [Jacob Van Dine](https://github.com/JacobVanDine) From 5a390e4e7e7fd500ab520f39f4e38763a1711976 Mon Sep 17 00:00:00 2001 From: JakeVanDine <jv477@drexel.edu> Date: Fri, 10 Mar 2023 20:43:27 -0500 Subject: [PATCH 542/679] Changed ScreenSpaceCameraController.enableCollisionDetection documentation. --- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 5d592c00670..823bcd46452 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -245,7 +245,7 @@ function ScreenSpaceCameraController(scene) { this.minimumTrackBallHeight = 7500000.0; this._minimumTrackBallHeight = this.minimumTrackBallHeight; /** - * Enables or disables camera collision detection with terrain. + * Enables or disables camera collision detection with terrain. When enabled, the camera's maximumZoomDistance and minimumZoomDistance become locked. * @type {boolean} * @default true */ From a5d584bcf148fbf9cadecbd2f1bf2928d1a53be5 Mon Sep 17 00:00:00 2001 From: L <wangtianliangyaya@gmail.com> Date: Tue, 14 Mar 2023 11:51:03 +0800 Subject: [PATCH 543/679] update MapboxImageryProvider example mapId --- CONTRIBUTORS.md | 1 + packages/engine/Source/Scene/MapboxImageryProvider.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 822a5ea600f..d23765d30b7 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -348,3 +348,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Tengfei](https://github.com/i-tengfei) - [Rudolf Farkas](https://github.com/rudifa) - [Nick Noce](https://github.com/nnoce14) +- [L](https://github.com/L-hikari) diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index 0768b54ac8d..160e6556dfe 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -39,7 +39,7 @@ const defaultCredit = new Credit( * @example * // Mapbox tile provider * const mapbox = new Cesium.MapboxImageryProvider({ - * mapId: 'mapbox.streets', + * mapId: 'mapbox.mapbox-terrain-v2', * accessToken: 'thisIsMyAccessToken' * }); * From 860a7c5f8443fb1449bbd1f6f88953139cd02fd0 Mon Sep 17 00:00:00 2001 From: Marcel Wendler <marcel.wendler@pointcloudtechnology.com> Date: Tue, 14 Mar 2023 10:31:24 +0100 Subject: [PATCH 544/679] Make build-watch compatible with new esbuild rebuild API --- build.js | 6 +++--- gulpfile.js | 45 +++++++++++++++++++++++---------------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/build.js b/build.js index 798a2040b4c..ba6f6f545be 100644 --- a/build.js +++ b/build.js @@ -145,9 +145,9 @@ export async function getFilesFromWorkspaceGlobs(workspaceGlobs) { /** * @typedef {object} CesiumBundles - * @property {object} esmBundle The ESM bundle. - * @property {object} iifeBundle The IIFE bundle, for use in browsers. - * @property {object} nodeBundle The CommonJS bundle, for use in NodeJS. + * @property {object} esm The ESM bundle. + * @property {object} iife The IIFE bundle, for use in browsers. + * @property {object} node The CommonJS bundle, for use in NodeJS. */ /** diff --git a/gulpfile.js b/gulpfile.js index 8b0691a9ae9..ef228912e4f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -178,21 +178,22 @@ export const buildWatch = gulp.series(build, async function () { sourcemap: sourcemap, incremental: true, }); - let esmResult = bundles.esmBundle; - let cjsResult = bundles.nodeBundle; - let iifeResult = bundles.iifeBundle; - let specResult = bundles.specsBundle; + + const esm = bundles.esm; + const cjs = bundles.node; + const iife = bundles.iife; + const specs = bundles.specs; gulp.watch(shaderFiles, async () => { glslToJavaScript(minify, "Build/minifyShaders.state", "engine"); - esmResult = await esmResult.rebuild(); + await esm.rebuild(); - if (iifeResult) { - iifeResult = await iifeResult.rebuild(); + if (iife) { + await iife.rebuild(); } - if (cjsResult) { - cjsResult = await cjsResult.rebuild(); + if (cjs) { + await cjs.rebuild(); } }); @@ -204,14 +205,14 @@ export const buildWatch = gulp.series(build, async function () { ], async () => { createJsHintOptions(); - esmResult = await esmResult.rebuild(); + await esm.rebuild(); - if (iifeResult) { - iifeResult = await iifeResult.rebuild(); + if (iife) { + await iife.rebuild(); } - if (cjsResult) { - cjsResult = await cjsResult.rebuild(); + if (cjs) { + await cjs.rebuild(); } } ); @@ -223,7 +224,7 @@ export const buildWatch = gulp.series(build, async function () { }, async () => { createCombinedSpecList(); - specResult = await specResult.rebuild(); + await specs.rebuild(); } ); @@ -233,7 +234,7 @@ export const buildWatch = gulp.series(build, async function () { events: ["change"], }, async () => { - specResult = await specResult.rebuild(); + await specs.rebuild(); } ); @@ -248,17 +249,17 @@ export const buildWatch = gulp.series(build, async function () { process.on("SIGINT", () => { // Free up resources - esmResult.rebuild.dispose(); + esm.dispose(); - if (iifeResult) { - iifeResult.rebuild.dispose(); + if (iife) { + iife.dispose(); } - if (cjsResult) { - cjsResult.rebuild.dispose(); + if (cjs) { + cjs.dispose(); } - specResult.rebuild.dispose(); + specs.dispose(); process.exit(0); }); }); From 17a84ebf718a087495f2bfc4478b808b57b24d0b Mon Sep 17 00:00:00 2001 From: Kevin Ring <kevin@kotachrome.com> Date: Wed, 15 Mar 2023 17:08:11 +1100 Subject: [PATCH 545/679] Fix description of OrientedBoundingBox cube. And add a test that demonstrates that the new description is the correct one. --- packages/engine/Source/Core/OrientedBoundingBox.js | 2 +- .../engine/Specs/Core/OrientedBoundingBoxSpec.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Core/OrientedBoundingBox.js b/packages/engine/Source/Core/OrientedBoundingBox.js index 59fe1d019ae..2c8131de8ef 100644 --- a/packages/engine/Source/Core/OrientedBoundingBox.js +++ b/packages/engine/Source/Core/OrientedBoundingBox.js @@ -24,7 +24,7 @@ import Rectangle from "./Rectangle.js"; * * @param {Cartesian3} [center=Cartesian3.ZERO] The center of the box. * @param {Matrix3} [halfAxes=Matrix3.ZERO] The three orthogonal half-axes of the bounding box. - * Equivalently, the transformation matrix, to rotate and scale a 1x1x1 + * Equivalently, the transformation matrix, to rotate and scale a 2x2x2 * cube centered at the origin. * * diff --git a/packages/engine/Specs/Core/OrientedBoundingBoxSpec.js b/packages/engine/Specs/Core/OrientedBoundingBoxSpec.js index 7300826f861..37d506dfc38 100644 --- a/packages/engine/Specs/Core/OrientedBoundingBoxSpec.js +++ b/packages/engine/Specs/Core/OrientedBoundingBoxSpec.js @@ -2780,6 +2780,18 @@ describe("Core/OrientedBoundingBox", function () { expect(box.equals(undefined)).toEqual(false); }); + it("is a rotated/scaled 2x2x2 cube centered at the origin", function () { + const box = new OrientedBoundingBox(Cartesian3.ZERO, Matrix3.IDENTITY); + + // All corners are 1 unit from the origin in each direction, so the cube is 2x2x2. + const corners = box.computeCorners(); + for (const corner of corners) { + expect(Math.abs(corner.x)).toEqual(1.0); + expect(Math.abs(corner.y)).toEqual(1.0); + expect(Math.abs(corner.z)).toEqual(1.0); + } + }); + createPackableSpecs( OrientedBoundingBox, new OrientedBoundingBox(new Cartesian3(1.0, 2.0, 3.0), Matrix3.IDENTITY), From 38d19219da152c7fd7a42c8090ef370a9c497756 Mon Sep 17 00:00:00 2001 From: Kevin Ring <kevin@kotachrome.com> Date: Wed, 15 Mar 2023 17:11:05 +1100 Subject: [PATCH 546/679] Improve doc of halfAxes property, too. --- packages/engine/Source/Core/OrientedBoundingBox.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Core/OrientedBoundingBox.js b/packages/engine/Source/Core/OrientedBoundingBox.js index 2c8131de8ef..c7fe3c29228 100644 --- a/packages/engine/Source/Core/OrientedBoundingBox.js +++ b/packages/engine/Source/Core/OrientedBoundingBox.js @@ -46,7 +46,9 @@ function OrientedBoundingBox(center, halfAxes) { */ this.center = Cartesian3.clone(defaultValue(center, Cartesian3.ZERO)); /** - * The transformation matrix, to rotate the box to the right position. + * The three orthogonal half-axes of the bounding box. Equivalently, the + * transformation matrix, to rotate and scale a 2x2x2 cube centered at the + * origin. * @type {Matrix3} * @default {@link Matrix3.ZERO} */ From fd2d32dc758f571213e1044044c5a0bb2d4d6e72 Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Wed, 15 Mar 2023 15:52:30 +0800 Subject: [PATCH 547/679] Fix DebugCameraPrimitive render error --- CHANGES.md | 1 + packages/engine/Source/Core/OrthographicFrustum.js | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index b2e896226f2..cf721dcd0bb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ ##### Fixes :wrench: - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) +- Fixed issue when render `OrthographicFrustum` geometry by `DebugCameraPrimitive`. [#11159](https://github.com/CesiumGS/cesium/issues/11159) #### @cesium/widgets diff --git a/packages/engine/Source/Core/OrthographicFrustum.js b/packages/engine/Source/Core/OrthographicFrustum.js index 6e45f6b1b19..ff629fa1e25 100644 --- a/packages/engine/Source/Core/OrthographicFrustum.js +++ b/packages/engine/Source/Core/OrthographicFrustum.js @@ -63,6 +63,15 @@ function OrthographicFrustum(options) { */ this.far = defaultValue(options.far, 500000000.0); this._far = this.far; + + if ( + defined(this.width) && + defined(this.aspectRatio) && + defined(this.near) && + defined(this.far) + ) { + update(this); + } } /** From 06bd027edc4e4bd4f59583853846ffe5c8800429 Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Wed, 15 Mar 2023 11:47:12 +0200 Subject: [PATCH 548/679] Improved ground atmosphere as seen from outer space Flying low, i.e. close to the relief, should still be performant. --- .../Source/Shaders/AtmosphereCommon.glsl | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 9a6c942fd97..d1c9917a761 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -9,10 +9,6 @@ uniform vec3 u_atmosphereMieCoefficient; const float ATMOSPHERE_THICKNESS = 111e3; // The thickness of the atmosphere in meters. -// --- Modified: constants -const int PRIMARY_STEPS = 4; // Number of times the ray from the camera to the world position (primary ray) is sampled. -const int LIGHT_STEPS = 2; // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. - /** * This function computes the colors contributed by Rayliegh and Mie scattering on a given ray, as well as * the transmittance value for the ray. @@ -65,15 +61,33 @@ void computeScattering( float w_stop_gt_lprl = max(0.0,min(1.0,(1.0 + x * ( 27.0 + x * x ) / ( 27.0 + 9.0 * x * x ))/2.0)); // The ray should start from the first intersection with the outer atmopshere, or from the camera position, if it is inside the atmosphere. + float start_0 = primaryRayAtmosphereIntersect.start; primaryRayAtmosphereIntersect.start = max(primaryRayAtmosphereIntersect.start, 0.0); // The ray should end at the exit from the atmosphere or at the distance to the vertex, whichever is smaller. primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, lprl); + + // Distinguish inside or outside atmosphere (outer space) + // Reasons: + // (1) from outer space we have to use the original implementation to get an unmodified/acceptable rendering + // (2) within atmosphere we need a speedup + float x_o_a = start_0 - ATMOSPHERE_THICKNESS; // ATMOSPHERE_THICKNESS used as an ad-hoc constant, no precise meaning here, only the order of magnitude matters + float w_inside_atmosphere = 1.0 - max(0.0,min(1.0,(1.0 + x_o_a * ( 27.0 + x_o_a * x_o_a ) / ( 27.0 + 9.0 * x_o_a * x_o_a ))/2.0)); // similar to 1.0 - (1+tanh)/2 + + // (1) Outside of the atmosphere: original (16.0,4.0) values for good rendering + // (2) Inside atmosphere: smaller (4.0,2.0) values for a speedup + int PRIMARY_STEPS = int(16.0 - w_inside_atmosphere * 12.0); // Number of times the ray from the camera to the world position (primary ray) is sampled. + int LIGHT_STEPS = int(4.0 - w_inside_atmosphere * 2.0); // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. + // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. float rayPositionLength = primaryRayAtmosphereIntersect.start; - // Sky vs horizon: constant step in one case, increasing step in the other case - float rayStepLengthIncrease = (1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0); - float rayStepLength = w_stop_gt_lprl * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0,float(PRIMARY_STEPS)); + // (1) Outside of the atmosphere: original implementation + // (2) Inside atmosphere: variable rayStepLength to compensate the originally rough rendering of the smaller (4.0,2.0) values + // Implementation: sky vs horizon: constant step in one case, increasing step in the other case + float rayStepLengthIncrease = w_inside_atmosphere * ((1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0)); + float rayStepLength = max(1.0-w_inside_atmosphere, w_stop_gt_lprl) * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0*w_inside_atmosphere,float(PRIMARY_STEPS)); + + vec3 rayleighAccumulation = vec3(0.0); vec3 mieAccumulation = vec3(0.0); @@ -81,14 +95,9 @@ void computeScattering( vec2 heightScale = vec2(u_atmosphereRayleighScaleHeight, u_atmosphereMieScaleHeight); // Sample positions on the primary ray. - - // Possible small optimization - vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength); - vec3 primaryPositionDelta = primaryRay.direction * rayStepLength; - for (int i = 0; i < PRIMARY_STEPS; i++) { // Calculate sample position along viewpoint ray. - samplePosition += primaryPositionDelta; // Possible small optimization + vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength); // Calculate height of sample position above ellipsoid. float sampleHeight = length(samplePosition) - atmosphereInnerRadius; @@ -107,14 +116,10 @@ void computeScattering( vec2 lightOpticalDepth = vec2(0.0); // Sample positions along the light ray, to accumulate incidence of light on the latest sample segment. - - // Possible small optimization - vec3 lightPosition = samplePosition + lightDirection * (lightStepLength * 0.5); - vec3 lightPositionDelta = lightDirection * lightStepLength; for (int j = 0; j < LIGHT_STEPS; j++) { // Calculate sample position along light ray. - lightPosition += lightPositionDelta; // Possible small optimization + vec3 lightPosition = samplePosition + lightDirection * (lightPositionLength + lightStepLength * 0.5); // Calculate height of the light sample position above ellipsoid. float lightHeight = length(lightPosition) - atmosphereInnerRadius; From 141032fd204ae5d06fe5deb21d348057da0b85d4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 16 Mar 2023 14:25:40 -0400 Subject: [PATCH 549/679] Split base and skip traversal into separate classes --- .../engine/Source/Scene/Cesium3DTilePass.js | 19 +- .../engine/Source/Scene/Cesium3DTileset.js | 25 +- .../Scene/Cesium3DTilesetBaseTraversal.js | 294 ++++++++ .../Cesium3DTilesetMostDetailedTraversal.js | 10 +- .../Scene/Cesium3DTilesetSkipTraversal.js | 413 +++++++++++ .../Source/Scene/Cesium3DTilesetTraversal.js | 664 ++++++------------ .../engine/Source/Scene/TraversalUtility.js | 302 -------- 7 files changed, 960 insertions(+), 767 deletions(-) create mode 100644 packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js create mode 100644 packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js delete mode 100644 packages/engine/Source/Scene/TraversalUtility.js diff --git a/packages/engine/Source/Scene/Cesium3DTilePass.js b/packages/engine/Source/Scene/Cesium3DTilePass.js index c210f917734..4d3017d3055 100644 --- a/packages/engine/Source/Scene/Cesium3DTilePass.js +++ b/packages/engine/Source/Scene/Cesium3DTilePass.js @@ -1,6 +1,3 @@ -import Cesium3DTilesetMostDetailedTraversal from "./Cesium3DTilesetMostDetailedTraversal.js"; -import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; - /** * The pass in which a 3D Tileset is updated. * @@ -21,56 +18,56 @@ const Cesium3DTilePass = { const passOptions = new Array(Cesium3DTilePass.NUMBER_OF_PASSES); passOptions[Cesium3DTilePass.RENDER] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.RENDER, isRender: true, requestTiles: true, ignoreCommands: false, }); passOptions[Cesium3DTilePass.PICK] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.PICK, isRender: false, requestTiles: false, ignoreCommands: false, }); passOptions[Cesium3DTilePass.SHADOW] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.SHADOW, isRender: false, requestTiles: true, ignoreCommands: false, }); passOptions[Cesium3DTilePass.PRELOAD] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.SHADOW, isRender: false, requestTiles: true, ignoreCommands: true, }); passOptions[Cesium3DTilePass.PRELOAD_FLIGHT] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.PRELOAD_FLIGHT, isRender: false, requestTiles: true, ignoreCommands: true, }); passOptions[Cesium3DTilePass.REQUEST_RENDER_MODE_DEFER_CHECK] = Object.freeze({ - traversal: Cesium3DTilesetTraversal, + pass: Cesium3DTilePass.REQUEST_RENDER_MODE_DEFER_CHECK, isRender: false, requestTiles: true, ignoreCommands: true, }); passOptions[Cesium3DTilePass.MOST_DETAILED_PRELOAD] = Object.freeze({ - traversal: Cesium3DTilesetMostDetailedTraversal, + pass: Cesium3DTilePass.MOST_DETAILED_PRELOAD, isRender: false, requestTiles: true, ignoreCommands: true, }); passOptions[Cesium3DTilePass.MOST_DETAILED_PICK] = Object.freeze({ - traversal: Cesium3DTilesetMostDetailedTraversal, + pass: Cesium3DTilePass.MOST_DETAILED_PICK, isRender: false, requestTiles: false, ignoreCommands: false, diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 85efe729096..181f63ec81f 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -52,6 +52,9 @@ import StencilConstants from "./StencilConstants.js"; import TileBoundingRegion from "./TileBoundingRegion.js"; import TileBoundingSphere from "./TileBoundingSphere.js"; import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; +import Cesium3DTilesetMostDetailedTraversal from "./Cesium3DTilesetMostDetailedTraversal.js"; +import Cesium3DTilesetBaseTraversal from "./Cesium3DTilesetBaseTraversal.js"; +import Cesium3DTilesetSkipTraversal from "./Cesium3DTilesetSkipTraversal.js"; /** * A {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles tileset}, @@ -3038,7 +3041,9 @@ function update(tileset, frameState, passStatistics, passOptions) { tileset._cullRequestsWhileMoving = tileset.cullRequestsWhileMoving && !tileset._modelMatrixChanged; - const ready = passOptions.traversal.selectTiles(tileset, frameState); + const ready = tileset + .getTraversal(passOptions) + .selectTiles(tileset, frameState); if (passOptions.requestTiles) { requestTiles(tileset); @@ -3063,6 +3068,24 @@ function update(tileset, frameState, passStatistics, passOptions) { return ready; } +/** + * @private + * @param {object} passOptions + * @returns {Cesium3DTilesetTraversal} + */ +Cesium3DTileset.prototype.getTraversal = function (passOptions) { + const { pass } = passOptions; + if ( + pass === Cesium3DTilePass.MOST_DETAILED_PRELOAD || + pass === Cesium3DTilePass.MOST_DETAILED_PICK + ) { + return Cesium3DTilesetMostDetailedTraversal; + } + return this._skipLevelOfDetail + ? Cesium3DTilesetSkipTraversal + : Cesium3DTilesetBaseTraversal; +}; + /** * @private * @param {FrameState} frameState diff --git a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js new file mode 100644 index 00000000000..fbb56f56cb8 --- /dev/null +++ b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js @@ -0,0 +1,294 @@ +import defined from "../Core/defined.js"; +import ManagedArray from "../Core/ManagedArray.js"; +import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; +import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; + +/** + * @private + */ +function Cesium3DTilesetBaseTraversal() {} + +const traversal = { + stack: new ManagedArray(), + stackMaximumLength: 0, +}; + +const emptyTraversal = { + stack: new ManagedArray(), + stackMaximumLength: 0, +}; + +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ +Cesium3DTilesetBaseTraversal.selectTiles = function (tileset, frameState) { + tileset._requestedTiles.length = 0; + + if (tileset.debugFreezeFrame) { + return; + } + + tileset._selectedTiles.length = 0; + tileset._selectedTilesToStyle.length = 0; + tileset._emptyTiles.length = 0; + tileset._hasMixedContent = false; + + const root = tileset.root; + Cesium3DTilesetTraversal.updateTile(root, frameState); + + if (!root.isVisible) { + return; + } + + if ( + root.getScreenSpaceError(frameState, true) <= + tileset._maximumScreenSpaceError + ) { + return; + } + + executeTraversal(root, frameState); + + traversal.stack.trim(traversal.stackMaximumLength); + emptyTraversal.stack.trim(emptyTraversal.stackMaximumLength); + + // Update the priority for any requests found during traversal + // Update after traversal so that min and max values can be used to normalize priority values + const requestedTiles = tileset._requestedTiles; + for (let i = 0; i < requestedTiles.length; ++i) { + requestedTiles[i].updatePriority(); + } +}; + +/** + * Mark a tile as selected if it has content available. + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +function selectDesiredTile(tile, frameState) { + if (tile.contentAvailable) { + // The tile can be selected right away and does not require traverseAndSelect + Cesium3DTilesetTraversal.selectTile(tile, frameState); + } + return; +} + +/** + * @private + * @param {Cesium3DTile} tile + * @param {ManagedArray} stack + * @param {FrameState} frameState + * @returns {boolean} + */ +function updateAndPushChildren(tile, stack, frameState) { + const replace = tile.refine === Cesium3DTileRefine.REPLACE; + const { tileset, children } = tile; + const { updateTile, loadTile, touchTile } = Cesium3DTilesetTraversal; + + for (let i = 0; i < children.length; ++i) { + updateTile(children[i], frameState); + } + + // Sort by distance to take advantage of early Z and reduce artifacts for skipLevelOfDetail + children.sort(Cesium3DTilesetTraversal.sortChildrenByDistanceToCamera); + + // For traditional replacement refinement only refine if all children are loaded. + // Empty tiles are exempt since it looks better if children stream in as they are loaded to fill the empty space. + const checkRefines = replace && tile.hasRenderableContent; + let refines = true; + + let anyChildrenVisible = false; + + // Determining min child + let minIndex = -1; + let minimumPriority = Number.MAX_VALUE; + + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + if (child.isVisible) { + stack.push(child); + if (child._foveatedFactor < minimumPriority) { + minIndex = i; + minimumPriority = child._foveatedFactor; + } + anyChildrenVisible = true; + } else if (checkRefines || tileset.loadSiblings) { + // Keep non-visible children loaded since they are still needed before the parent can refine. + // Or loadSiblings is true so always load tiles regardless of visibility. + if (child._foveatedFactor < minimumPriority) { + minIndex = i; + minimumPriority = child._foveatedFactor; + } + loadTile(child, frameState); + touchTile(child, frameState); + } + if (checkRefines) { + let childRefines; + if (!child._inRequestVolume) { + childRefines = false; + } else if (!child.hasRenderableContent) { + childRefines = executeEmptyTraversal(child, frameState); + } else { + childRefines = child.contentAvailable; + } + refines = refines && childRefines; + } + } + + if (!anyChildrenVisible) { + refines = false; + } + + if (minIndex !== -1 && replace) { + // An ancestor will hold the _foveatedFactor and _distanceToCamera for descendants between itself and its highest priority descendant. Siblings of a min children along the way use this ancestor as their priority holder as well. + // Priority of all tiles that refer to the _foveatedFactor and _distanceToCamera stored in the common ancestor will be differentiated based on their _depth. + const minPriorityChild = children[minIndex]; + minPriorityChild._wasMinPriorityChild = true; + const priorityHolder = + (tile._wasMinPriorityChild || tile === tileset.root) && + minimumPriority <= tile._priorityHolder._foveatedFactor + ? tile._priorityHolder + : tile; // This is where priority dependency chains are wired up or started anew. + priorityHolder._foveatedFactor = Math.min( + minPriorityChild._foveatedFactor, + priorityHolder._foveatedFactor + ); + priorityHolder._distanceToCamera = Math.min( + minPriorityChild._distanceToCamera, + priorityHolder._distanceToCamera + ); + + for (let i = 0; i < children.length; ++i) { + children[i]._priorityHolder = priorityHolder; + } + } + + return refines; +} + +/** + * Depth-first traversal that traverses all visible tiles and marks tiles for selection. + * A tile does not refine until all children are loaded. + * This is the traditional replacement refinement approach and is called the base traversal. + * + * @private + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ +function executeTraversal(root, frameState) { + const { tileset } = root; + + const { + canTraverse, + loadTile, + visitTile, + touchTile, + } = Cesium3DTilesetTraversal; + const stack = traversal.stack; + stack.push(root); + + while (stack.length > 0) { + traversal.stackMaximumLength = Math.max( + traversal.stackMaximumLength, + stack.length + ); + + const tile = stack.pop(); + + const parent = tile.parent; + const parentRefines = !defined(parent) || parent._refines; + + tile._refines = canTraverse(tile) + ? updateAndPushChildren(tile, stack, frameState) && parentRefines + : false; + + const stoppedRefining = !tile._refines && parentRefines; + + if (!tile.hasRenderableContent) { + // Add empty tile just to show its debug bounding volume + // If the tile has tileset content load the external tileset + tileset._emptyTiles.push(tile); + loadTile(tile, frameState); + if (stoppedRefining) { + selectDesiredTile(tile, frameState); + } + } else if (tile.refine === Cesium3DTileRefine.ADD) { + // Additive tiles are always loaded and selected + selectDesiredTile(tile, frameState); + loadTile(tile, frameState); + } else if (tile.refine === Cesium3DTileRefine.REPLACE) { + loadTile(tile, frameState); + if (stoppedRefining) { + selectDesiredTile(tile, frameState); + } + } + + visitTile(tile, frameState); + touchTile(tile, frameState); + } +} + +/** + * Depth-first traversal that checks if all nearest descendants with content are loaded. + * Ignores visibility. + * + * @private + * @param {Cesium3DTile} root + * @param {FrameState} frameState + * @returns {boolean} + */ +function executeEmptyTraversal(root, frameState) { + const { + canTraverse, + updateTile, + loadTile, + touchTile, + } = Cesium3DTilesetTraversal; + let allDescendantsLoaded = true; + const stack = emptyTraversal.stack; + stack.push(root); + + while (stack.length > 0) { + emptyTraversal.stackMaximumLength = Math.max( + emptyTraversal.stackMaximumLength, + stack.length + ); + + const tile = stack.pop(); + const children = tile.children; + const childrenLength = children.length; + + // Only traverse if the tile is empty - traversal stops at descendants with content + const traverse = !tile.hasRenderableContent && canTraverse(tile); + const emptyLeaf = !tile.hasRenderableContent && tile.children.length === 0; + + // Traversal stops but the tile does not have content yet + // There will be holes if the parent tries to refine to its children, so don't refine + // One exception: a parent may refine even if one of its descendants is an empty leaf + if (!traverse && !tile.contentAvailable && !emptyLeaf) { + allDescendantsLoaded = false; + } + + updateTile(tile, frameState); + if (!tile.isVisible) { + // Load tiles that aren't visible since they are still needed for the parent to refine + loadTile(tile, frameState); + touchTile(tile, frameState); + } + + if (traverse) { + for (let i = 0; i < childrenLength; ++i) { + const child = children[i]; + stack.push(child); + } + } + } + + return allDescendantsLoaded; +} + +export default Cesium3DTilesetBaseTraversal; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js index af99a6a0595..f8a66b2f551 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js @@ -1,7 +1,7 @@ import Intersect from "../Core/Intersect.js"; import ManagedArray from "../Core/ManagedArray.js"; import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; -import TraversalUtility from "./TraversalUtility.js"; +import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; /** * Traversal that loads all leaves that intersect the camera frustum. @@ -33,7 +33,7 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( return ready; } - const { touchTile, visitTile } = TraversalUtility; + const { touchTile, visitTile } = Cesium3DTilesetTraversal; const stack = traversal.stack; stack.push(root); @@ -71,10 +71,6 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( return ready; }; -function hasUnloadedContent(tile) { - return tile.hasRenderableContent && tile.contentUnloaded; -} - function canTraverse(tile) { if (tile.children.length === 0) { return false; @@ -106,7 +102,7 @@ function updateAndPushChildren(tile, stack, frameState) { } function loadTile(tileset, tile) { - if (hasUnloadedContent(tile) || tile.contentExpired) { + if (tile.hasUnloadedRenderableContent || tile.contentExpired) { tile._priority = 0.0; // Highest priority tileset._requestedTiles.push(tile); } diff --git a/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js new file mode 100644 index 00000000000..a74e04481de --- /dev/null +++ b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js @@ -0,0 +1,413 @@ +import defined from "../Core/defined.js"; +import ManagedArray from "../Core/ManagedArray.js"; +import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; +import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; + +/** + * @private + */ +function Cesium3DTilesetSkipTraversal() {} + +const traversal = { + stack: new ManagedArray(), + stackMaximumLength: 0, +}; + +const descendantTraversal = { + stack: new ManagedArray(), + stackMaximumLength: 0, +}; + +const selectionTraversal = { + stack: new ManagedArray(), + stackMaximumLength: 0, + ancestorStack: new ManagedArray(), + ancestorStackMaximumLength: 0, +}; + +const descendantSelectionDepth = 2; + +/** + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + */ +Cesium3DTilesetSkipTraversal.selectTiles = function (tileset, frameState) { + tileset._requestedTiles.length = 0; + + if (tileset.debugFreezeFrame) { + return; + } + + tileset._selectedTiles.length = 0; + tileset._selectedTilesToStyle.length = 0; + tileset._emptyTiles.length = 0; + tileset._hasMixedContent = false; + + const root = tileset.root; + Cesium3DTilesetTraversal.updateTile(root, frameState); + + if (!root.isVisible) { + return; + } + + if ( + root.getScreenSpaceError(frameState, true) <= + tileset._maximumScreenSpaceError + ) { + return; + } + + executeTraversal(root, frameState); + traverseAndSelect(root, frameState); + + traversal.stack.trim(traversal.stackMaximumLength); + descendantTraversal.stack.trim(descendantTraversal.stackMaximumLength); + selectionTraversal.stack.trim(selectionTraversal.stackMaximumLength); + selectionTraversal.ancestorStack.trim( + selectionTraversal.ancestorStackMaximumLength + ); + + // Update the priority for any requests found during traversal + // Update after traversal so that min and max values can be used to normalize priority values + const requestedTiles = tileset._requestedTiles; + for (let i = 0; i < requestedTiles.length; ++i) { + requestedTiles[i].updatePriority(); + } +}; + +/** + * Mark descendant tiles for rendering, and update as needed + * + * @private + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ +function selectDescendants(root, frameState) { + const { updateTile, touchTile, selectTile } = Cesium3DTilesetTraversal; + const stack = descendantTraversal.stack; + stack.push(root); + while (stack.length > 0) { + descendantTraversal.stackMaximumLength = Math.max( + descendantTraversal.stackMaximumLength, + stack.length + ); + const tile = stack.pop(); + const children = tile.children; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + if (child.isVisible) { + if (child.contentAvailable) { + updateTile(child, frameState); + touchTile(child, frameState); + selectTile(child, frameState); + } else if (child._depth - root._depth < descendantSelectionDepth) { + // Continue traversing, but not too far + stack.push(child); + } + } + } + } +} + +/** + * Mark a tile as selected if it has content available. + * If its content is not available, and we are skipping levels of detail, + * select an ancestor or descendant tile instead + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +function selectDesiredTile(tile, frameState) { + // If this tile is not loaded attempt to select its ancestor instead + const loadedTile = tile.contentAvailable + ? tile + : tile._ancestorWithContentAvailable; + if (defined(loadedTile)) { + // Tiles will actually be selected in traverseAndSelect + loadedTile._shouldSelect = true; + } else { + // If no ancestors are ready traverse down and select tiles to minimize empty regions. + // This happens often for immediatelyLoadDesiredLevelOfDetail where parent tiles are not necessarily loaded before zooming out. + selectDescendants(tile, frameState); + } +} + +/** + * Update links to the ancestor tiles that have content + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +function updateTileAncestorContentLinks(tile, frameState) { + tile._ancestorWithContent = undefined; + tile._ancestorWithContentAvailable = undefined; + + const { parent } = tile; + if (!defined(parent)) { + return; + } + const parentHasContent = + !parent.hasUnloadedRenderableContent || + parent._requestedFrame === frameState.frameNumber; + + // ancestorWithContent is an ancestor that has content or has the potential to have + // content. Used in conjunction with tileset.skipLevels to know when to skip a tile. + tile._ancestorWithContent = parentHasContent + ? parent + : parent._ancestorWithContent; + + // ancestorWithContentAvailable is an ancestor that is rendered if a desired tile is not loaded + tile._ancestorWithContentAvailable = parent.contentAvailable + ? parent + : parent._ancestorWithContentAvailable; +} + +/** + * Determine if a tile has reached the limit of level of detail skipping. + * If so, it should _not_ be skipped: it should be loaded and rendered + * + * @private + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @returns {boolean} true if this tile should not be skipped + */ +function reachedSkippingThreshold(tileset, tile) { + const ancestor = tile._ancestorWithContent; + return ( + !tileset.immediatelyLoadDesiredLevelOfDetail && + (tile._priorityProgressiveResolutionScreenSpaceErrorLeaf || + (defined(ancestor) && + tile._screenSpaceError < + ancestor._screenSpaceError / tileset.skipScreenSpaceErrorFactor && + tile._depth > ancestor._depth + tileset.skipLevels)) + ); +} + +/** + * @private + * @param {Cesium3DTile} tile + * @param {ManagedArray} stack + * @param {FrameState} frameState + * @returns {boolean} + */ +function updateAndPushChildren(tile, stack, frameState) { + const { tileset, children } = tile; + const { updateTile, loadTile, touchTile } = Cesium3DTilesetTraversal; + + for (let i = 0; i < children.length; ++i) { + updateTile(children[i], frameState); + } + + // Sort by distance to take advantage of early Z and reduce artifacts + children.sort(Cesium3DTilesetTraversal.sortChildrenByDistanceToCamera); + + let anyChildrenVisible = false; + + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + if (child.isVisible) { + stack.push(child); + anyChildrenVisible = true; + } else if (tileset.loadSiblings) { + loadTile(child, frameState); + touchTile(child, frameState); + } + } + + return anyChildrenVisible; +} + +/** + * Determine if a tile is part of the base traversal. + * If not, this tile could be considered for level of detail skipping + * + * @private + * @param {Cesium3DTile} tile + * @param {number} baseScreenSpaceError + * @returns {boolean} + */ +function inBaseTraversal(tile, baseScreenSpaceError) { + const { tileset } = tile; + if (tileset.immediatelyLoadDesiredLevelOfDetail) { + return false; + } + if (!defined(tile._ancestorWithContent)) { + // Include root or near-root tiles in the base traversal so there is something to select up to + return true; + } + if (tile._screenSpaceError === 0.0) { + // If a leaf, use parent's SSE + return tile.parent._screenSpaceError > baseScreenSpaceError; + } + return tile._screenSpaceError > baseScreenSpaceError; +} + +/** + * Depth-first traversal that traverses all visible tiles and marks tiles for selection. + * Tiles that have a greater screen space error than the base screen space error are part of the base traversal, + * all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree + * and rendering children and parent tiles simultaneously. + * + * @private + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ +function executeTraversal(root, frameState) { + const { tileset } = root; + const baseScreenSpaceError = tileset.immediatelyLoadDesiredLevelOfDetail + ? Number.MAX_VALUE + : Math.max(tileset.baseScreenSpaceError, tileset.maximumScreenSpaceError); + const { + canTraverse, + loadTile, + visitTile, + touchTile, + } = Cesium3DTilesetTraversal; + const stack = traversal.stack; + stack.push(root); + + while (stack.length > 0) { + traversal.stackMaximumLength = Math.max( + traversal.stackMaximumLength, + stack.length + ); + + const tile = stack.pop(); + + updateTileAncestorContentLinks(tile, frameState); + const parent = tile.parent; + const parentRefines = !defined(parent) || parent._refines; + + tile._refines = canTraverse(tile) + ? updateAndPushChildren(tile, stack, frameState) && parentRefines + : false; + + const stoppedRefining = !tile._refines && parentRefines; + + if (!tile.hasRenderableContent) { + // Add empty tile just to show its debug bounding volume + // If the tile has tileset content load the external tileset + // If the tile cannot refine further select its nearest loaded ancestor + tileset._emptyTiles.push(tile); + loadTile(tile, frameState); + if (stoppedRefining) { + selectDesiredTile(tile, frameState); + } + } else if (tile.refine === Cesium3DTileRefine.ADD) { + // Additive tiles are always loaded and selected + selectDesiredTile(tile, frameState); + loadTile(tile, frameState); + } else if (tile.refine === Cesium3DTileRefine.REPLACE) { + if (inBaseTraversal(tile, baseScreenSpaceError)) { + // Always load tiles in the base traversal + // Select tiles that can't refine further + loadTile(tile, frameState); + if (stoppedRefining) { + selectDesiredTile(tile, frameState); + } + } else if (stoppedRefining) { + // In skip traversal, load and select tiles that can't refine further + selectDesiredTile(tile, frameState); + loadTile(tile, frameState); + } else if (reachedSkippingThreshold(tileset, tile)) { + // In skip traversal, load tiles that aren't skipped + loadTile(tile, frameState); + } + } + + visitTile(tile, frameState); + touchTile(tile, frameState); + } +} + +/** + * Traverse the tree and check if their selected frame is the current frame. If so, add it to a selection queue. + * This is a preorder traversal so children tiles are selected before ancestor tiles. + * + * The reason for the preorder traversal is so that tiles can easily be marked with their + * selection depth. A tile's _selectionDepth is its depth in the tree where all non-selected tiles are removed. + * This property is important for use in the stencil test because we want to render deeper tiles on top of their + * ancestors. If a tileset is very deep, the depth is unlikely to fit into the stencil buffer. + * + * We want to select children before their ancestors because there is no guarantee on the relationship between + * the children's z-depth and the ancestor's z-depth. We cannot rely on Z because we want the child to appear on top + * of ancestor regardless of true depth. The stencil tests used require children to be drawn first. + * + * NOTE: 3D Tiles uses 3 bits from the stencil buffer meaning this will not work when there is a chain of + * selected tiles that is deeper than 7. This is not very likely. + * + * @private + * @param {Cesium3DTile} root + * @param {FrameState} frameState + */ +function traverseAndSelect(root, frameState) { + const { selectTile, canTraverse } = Cesium3DTilesetTraversal; + const { stack, ancestorStack } = selectionTraversal; + let lastAncestor; + + stack.push(root); + + while (stack.length > 0 || ancestorStack.length > 0) { + selectionTraversal.stackMaximumLength = Math.max( + selectionTraversal.stackMaximumLength, + stack.length + ); + selectionTraversal.ancestorStackMaximumLength = Math.max( + selectionTraversal.ancestorStackMaximumLength, + ancestorStack.length + ); + + if (ancestorStack.length > 0) { + const waitingTile = ancestorStack.peek(); + if (waitingTile._stackLength === stack.length) { + ancestorStack.pop(); + if (waitingTile !== lastAncestor) { + waitingTile._finalResolution = false; + } + selectTile(waitingTile, frameState); + continue; + } + } + + const tile = stack.pop(); + if (!defined(tile)) { + // stack is empty but ancestorStack isn't + continue; + } + + const traverse = canTraverse(tile); + + if (tile._shouldSelect) { + if (tile.refine === Cesium3DTileRefine.ADD) { + selectTile(tile, frameState); + } else { + tile._selectionDepth = ancestorStack.length; + if (tile._selectionDepth > 0) { + tile.tileset._hasMixedContent = true; + } + lastAncestor = tile; + if (!traverse) { + selectTile(tile, frameState); + continue; + } + ancestorStack.push(tile); + tile._stackLength = stack.length; + } + } + + if (traverse) { + const children = tile.children; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + if (child.isVisible) { + stack.push(child); + } + } + } + } +} + +export default Cesium3DTilesetSkipTraversal; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index a0423856dd4..2c32ced7721 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -1,548 +1,320 @@ import defined from "../Core/defined.js"; -import ManagedArray from "../Core/ManagedArray.js"; +import DeveloperError from "../Core/DeveloperError.js"; +import Intersect from "../Core/Intersect.js"; +import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js"; import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; -import TraversalUtility from "./TraversalUtility.js"; /** + * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render. + * This type describes an interface and is not intended to be instantiated directly. + * + * @alias Cesium3DTilesetTraversal + * @constructor + * + * @see Cesium3DTilesetBaseTraversal + * @see Cesium3DTilesetSkipTraversal + * @see Cesium3DTilesetMostDetailedTraversal + * * @private */ function Cesium3DTilesetTraversal() {} -const traversal = { - stack: new ManagedArray(), - stackMaximumLength: 0, -}; - -const emptyTraversal = { - stack: new ManagedArray(), - stackMaximumLength: 0, -}; - -const descendantTraversal = { - stack: new ManagedArray(), - stackMaximumLength: 0, -}; - -const selectionTraversal = { - stack: new ManagedArray(), - stackMaximumLength: 0, - ancestorStack: new ManagedArray(), - ancestorStackMaximumLength: 0, -}; - -const descendantSelectionDepth = 2; - /** * @private * @param {Cesium3DTileset} tileset * @param {FrameState} frameState */ Cesium3DTilesetTraversal.selectTiles = function (tileset, frameState) { - tileset._requestedTiles.length = 0; - - if (tileset.debugFreezeFrame) { - return; - } - - tileset._selectedTiles.length = 0; - tileset._selectedTilesToStyle.length = 0; - tileset._emptyTiles.length = 0; - tileset._hasMixedContent = false; - - const root = tileset.root; - TraversalUtility.updateTile(root, frameState); - - if (!root.isVisible) { - return; - } - - if ( - root.getScreenSpaceError(frameState, true) <= - tileset._maximumScreenSpaceError - ) { - return; - } - - const baseScreenSpaceError = !tileset._skipLevelOfDetail - ? tileset._maximumScreenSpaceError - : tileset.immediatelyLoadDesiredLevelOfDetail - ? Number.MAX_VALUE - : Math.max(tileset.baseScreenSpaceError, tileset.maximumScreenSpaceError); - - executeTraversal(root, baseScreenSpaceError, frameState); - - if (tileset._skipLevelOfDetail) { - traverseAndSelect(root, frameState); - } - - traversal.stack.trim(traversal.stackMaximumLength); - emptyTraversal.stack.trim(emptyTraversal.stackMaximumLength); - descendantTraversal.stack.trim(descendantTraversal.stackMaximumLength); - selectionTraversal.stack.trim(selectionTraversal.stackMaximumLength); - selectionTraversal.ancestorStack.trim( - selectionTraversal.ancestorStackMaximumLength - ); - - // Update the priority for any requests found during traversal - // Update after traversal so that min and max values can be used to normalize priority values - const requestedTiles = tileset._requestedTiles; - for (let i = 0; i < requestedTiles.length; ++i) { - requestedTiles[i].updatePriority(); - } + DeveloperError.throwInstantiationError(); }; /** - * Mark descendant tiles for rendering, and update as needed + * Sort by farthest child first since this is going on a stack * * @private - * @param {Cesium3DTile} root - * @param {FrameState} frameState + * @param {Cesium3DTile} a + * @param {Cesium3DTile} b + * @returns {number} */ -function selectDescendants(root, frameState) { - const { updateTile, touchTile, selectTile } = TraversalUtility; - const stack = descendantTraversal.stack; - stack.push(root); - while (stack.length > 0) { - descendantTraversal.stackMaximumLength = Math.max( - descendantTraversal.stackMaximumLength, - stack.length - ); - const tile = stack.pop(); - const children = tile.children; - for (let i = 0; i < children.length; ++i) { - const child = children[i]; - if (child.isVisible) { - if (child.contentAvailable) { - updateTile(child, frameState); - touchTile(child, frameState); - selectTile(child, frameState); - } else if (child._depth - root._depth < descendantSelectionDepth) { - // Continue traversing, but not too far - stack.push(child); - } - } - } +Cesium3DTilesetTraversal.sortChildrenByDistanceToCamera = function (a, b) { + if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { + return b._centerZDepth - a._centerZDepth; } -} + + return b._distanceToCamera - a._distanceToCamera; +}; /** - * Mark a tile as selected if it has content available. - * If its content is not available, and we are skipping levels of detail, - * select an ancestor or descendant tile instead + * Determine if a tile can and should be traversed for children tiles that + * would contribute to rendering the current view * * @private * @param {Cesium3DTile} tile - * @param {FrameState} frameState + * @returns {boolean} */ -function selectDesiredTile(tile, frameState) { - if (!tile.tileset._skipLevelOfDetail) { - if (tile.contentAvailable) { - // The tile can be selected right away and does not require traverseAndSelect - TraversalUtility.selectTile(tile, frameState); - } - return; +Cesium3DTilesetTraversal.canTraverse = function (tile) { + if (tile.children.length === 0) { + return false; } - - // If this tile is not loaded attempt to select its ancestor instead - const loadedTile = tile.contentAvailable - ? tile - : tile._ancestorWithContentAvailable; - if (defined(loadedTile)) { - // Tiles will actually be selected in traverseAndSelect - loadedTile._shouldSelect = true; - } else { - // If no ancestors are ready traverse down and select tiles to minimize empty regions. - // This happens often for immediatelyLoadDesiredLevelOfDetail where parent tiles are not necessarily loaded before zooming out. - selectDescendants(tile, frameState); + if (tile.hasTilesetContent || tile.hasImplicitContent) { + // Traverse external tileset to visit its root tile + // Don't traverse if the subtree is expired because it will be destroyed + return !tile.contentExpired; } -} + return tile._screenSpaceError > tile.tileset._maximumScreenSpaceError; +}; /** - * Update links to the ancestor tiles that have content + * Mark a tile as selected, and add it to the tileset's list of selected tiles * * @private * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function updateTileAncestorContentLinks(tile, frameState) { - tile._ancestorWithContent = undefined; - tile._ancestorWithContentAvailable = undefined; - - const { parent } = tile; - if (!defined(parent)) { +Cesium3DTilesetTraversal.selectTile = function (tile, frameState) { + if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { return; } - const parentHasContent = - !parent.hasUnloadedRenderableContent || - parent._requestedFrame === frameState.frameNumber; - // ancestorWithContent is an ancestor that has content or has the potential to have - // content. Used in conjunction with tileset.skipLevels to know when to skip a tile. - tile._ancestorWithContent = parentHasContent - ? parent - : parent._ancestorWithContent; - - // ancestorWithContentAvailable is an ancestor that is rendered if a desired tile is not loaded - tile._ancestorWithContentAvailable = parent.contentAvailable - ? parent - : parent._ancestorWithContentAvailable; -} + const { content, tileset } = tile; + if (content.featurePropertiesDirty) { + // A feature's property in this tile changed, the tile needs to be re-styled. + content.featurePropertiesDirty = false; + tile.lastStyleTime = 0; // Force applying the style to this tile + tileset._selectedTilesToStyle.push(tile); + } else if (tile._selectedFrame < frameState.frameNumber - 1) { + // Tile is newly selected; it is selected this frame, but was not selected last frame. + tileset._selectedTilesToStyle.push(tile); + } + tile._selectedFrame = frameState.frameNumber; + tileset._selectedTiles.push(tile); +}; /** - * Determine if a tile has reached the limit of level of detail skipping. - * If so, it should _not_ be skipped: it should be loaded and rendered - * * @private - * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile - * @returns {boolean} true if this tile should not be skipped + * @param {FrameState} frameState */ -function reachedSkippingThreshold(tileset, tile) { - const ancestor = tile._ancestorWithContent; - return ( - !tileset.immediatelyLoadDesiredLevelOfDetail && - (tile._priorityProgressiveResolutionScreenSpaceErrorLeaf || - (defined(ancestor) && - tile._screenSpaceError < - ancestor._screenSpaceError / tileset.skipScreenSpaceErrorFactor && - tile._depth > ancestor._depth + tileset.skipLevels)) - ); -} +Cesium3DTilesetTraversal.visitTile = function (tile, frameState) { + ++tile.tileset._statistics.visited; + tile._visitedFrame = frameState.frameNumber; +}; /** * @private * @param {Cesium3DTile} tile - * @param {ManagedArray} stack * @param {FrameState} frameState - * @returns {boolean} */ -function updateAndPushChildren(tile, stack, frameState) { - const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const { tileset, children } = tile; - const { updateTile, loadTile, touchTile } = TraversalUtility; - - for (let i = 0; i < children.length; ++i) { - updateTile(children[i], frameState); +Cesium3DTilesetTraversal.touchTile = function (tile, frameState) { + if (tile._touchedFrame === frameState.frameNumber) { + // Prevents another pass from touching the frame again + return; } + tile.tileset._cache.touch(tile); + tile._touchedFrame = frameState.frameNumber; +}; - // Sort by distance to take advantage of early Z and reduce artifacts for skipLevelOfDetail - children.sort(TraversalUtility.sortChildrenByDistanceToCamera); - - // For traditional replacement refinement only refine if all children are loaded. - // Empty tiles are exempt since it looks better if children stream in as they are loaded to fill the empty space. - const checkRefines = - !tileset._skipLevelOfDetail && replace && tile.hasRenderableContent; - let refines = true; - - let anyChildrenVisible = false; - - // Determining min child - let minIndex = -1; - let minimumPriority = Number.MAX_VALUE; - - for (let i = 0; i < children.length; ++i) { - const child = children[i]; - if (child.isVisible) { - stack.push(child); - if (child._foveatedFactor < minimumPriority) { - minIndex = i; - minimumPriority = child._foveatedFactor; - } - anyChildrenVisible = true; - } else if (checkRefines || tileset.loadSiblings) { - // Keep non-visible children loaded since they are still needed before the parent can refine. - // Or loadSiblings is true so always load tiles regardless of visibility. - if (child._foveatedFactor < minimumPriority) { - minIndex = i; - minimumPriority = child._foveatedFactor; - } - loadTile(child, frameState); - touchTile(child, frameState); - } - if (checkRefines) { - let childRefines; - if (!child._inRequestVolume) { - childRefines = false; - } else if (!child.hasRenderableContent) { - childRefines = executeEmptyTraversal(child, frameState); - } else { - childRefines = child.contentAvailable; - } - refines = refines && childRefines; - } +/** + * Add a tile to the list of requested tiles, if appropriate + * + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +Cesium3DTilesetTraversal.loadTile = function (tile, frameState) { + const { tileset } = tile; + if ( + tile._requestedFrame === frameState.frameNumber || + (!tile.hasUnloadedRenderableContent && !tile.contentExpired) + ) { + return; } - if (!anyChildrenVisible) { - refines = false; + if (!isOnScreenLongEnough(tile, frameState)) { + return; } - if (minIndex !== -1 && !tileset.skipLevelOfDetail && replace) { - // An ancestor will hold the _foveatedFactor and _distanceToCamera for descendants between itself and its highest priority descendant. Siblings of a min children along the way use this ancestor as their priority holder as well. - // Priority of all tiles that refer to the _foveatedFactor and _distanceToCamera stored in the common ancestor will be differentiated based on their _depth. - const minPriorityChild = children[minIndex]; - minPriorityChild._wasMinPriorityChild = true; - const priorityHolder = - (tile._wasMinPriorityChild || tile === tileset.root) && - minimumPriority <= tile._priorityHolder._foveatedFactor - ? tile._priorityHolder - : tile; // This is where priority dependency chains are wired up or started anew. - priorityHolder._foveatedFactor = Math.min( - minPriorityChild._foveatedFactor, - priorityHolder._foveatedFactor - ); - priorityHolder._distanceToCamera = Math.min( - minPriorityChild._distanceToCamera, - priorityHolder._distanceToCamera - ); - - for (let i = 0; i < children.length; ++i) { - children[i]._priorityHolder = priorityHolder; - } + const cameraHasNotStoppedMovingLongEnough = + frameState.camera.timeSinceMoved < tileset.foveatedTimeDelay; + if (tile.priorityDeferred && cameraHasNotStoppedMovingLongEnough) { + return; } - return refines; -} + tile._requestedFrame = frameState.frameNumber; + tileset._requestedTiles.push(tile); +}; /** - * Determine if a tile is part of the base traversal. - * If not, this tile could be considered for level of detail skipping + * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. * * @private * @param {Cesium3DTile} tile - * @param {number} baseScreenSpaceError + * @param {FrameState} frameState * @returns {boolean} */ -function inBaseTraversal(tile, baseScreenSpaceError) { +function isOnScreenLongEnough(tile, frameState) { const { tileset } = tile; - if (!tileset._skipLevelOfDetail) { + if (!tileset._cullRequestsWhileMoving) { return true; } - if (tileset.immediatelyLoadDesiredLevelOfDetail) { - return false; - } - if (!defined(tile._ancestorWithContent)) { - // Include root or near-root tiles in the base traversal so there is something to select up to - return true; - } - if (tile._screenSpaceError === 0.0) { - // If a leaf, use parent's SSE - return tile.parent._screenSpaceError > baseScreenSpaceError; - } - return tile._screenSpaceError > baseScreenSpaceError; + + const { + positionWCDeltaMagnitude, + positionWCDeltaMagnitudeLastFrame, + } = frameState.camera; + const deltaMagnitude = + positionWCDeltaMagnitude !== 0.0 + ? positionWCDeltaMagnitude + : positionWCDeltaMagnitudeLastFrame; + + // How do n frames of this movement compare to the tile's physical size. + const diameter = Math.max(tile.boundingSphere.radius * 2.0, 1.0); + const movementRatio = + (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; + + return movementRatio < 1.0; } /** - * Depth-first traversal that traverses all visible tiles and marks tiles for selection. - * If skipLevelOfDetail is off then a tile does not refine until all children are loaded. - * This is the traditional replacement refinement approach and is called the base traversal. - * Tiles that have a greater screen space error than the base screen space error are part of the base traversal, - * all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree - * and rendering children and parent tiles simultaneously. + * Reset some of the tile's flags and re-evaluate visibility and priority * * @private - * @param {Cesium3DTile} root - * @param {number} baseScreenSpaceError + * @param {Cesium3DTile} tile * @param {FrameState} frameState */ -function executeTraversal(root, baseScreenSpaceError, frameState) { - const { tileset } = root; - const { canTraverse, loadTile, visitTile, touchTile } = TraversalUtility; - const stack = traversal.stack; - stack.push(root); +Cesium3DTilesetTraversal.updateTile = function (tile, frameState) { + updateTileVisibility(tile, frameState); + tile.updateExpiration(); - while (stack.length > 0) { - traversal.stackMaximumLength = Math.max( - traversal.stackMaximumLength, - stack.length - ); + tile._wasMinPriorityChild = false; + tile._priorityHolder = tile; + updateMinimumMaximumPriority(tile); - const tile = stack.pop(); + // SkipLOD + tile._shouldSelect = false; + tile._finalResolution = true; +}; + +/** + * @private + * @param {Cesium3DTile} tile + * @param {FrameState} frameState + */ +function updateTileVisibility(tile, frameState) { + tile.updateVisibility(frameState); - updateTileAncestorContentLinks(tile, frameState); - const parent = tile.parent; - const parentRefines = !defined(parent) || parent._refines; + if (!tile.isVisible) { + return; + } - tile._refines = canTraverse(tile) - ? updateAndPushChildren(tile, stack, frameState) && parentRefines - : false; + const hasChildren = tile.children.length > 0; + if ((tile.hasTilesetContent || tile.hasImplicitContent) && hasChildren) { + // Use the root tile's visibility instead of this tile's visibility. + // The root tile may be culled by the children bounds optimization in which + // case this tile should also be culled. + const child = tile.children[0]; + updateTileVisibility(child, frameState); + tile._visible = child._visible; + return; + } - const stoppedRefining = !tile._refines && parentRefines; + if (meetsScreenSpaceErrorEarly(tile, frameState)) { + tile._visible = false; + return; + } - if (!tile.hasRenderableContent) { - // Add empty tile just to show its debug bounding volume - // If the tile has tileset content load the external tileset - // If the tile cannot refine further select its nearest loaded ancestor - tileset._emptyTiles.push(tile); - loadTile(tile, frameState); - if (stoppedRefining) { - selectDesiredTile(tile, frameState); - } - } else if (tile.refine === Cesium3DTileRefine.ADD) { - // Additive tiles are always loaded and selected - selectDesiredTile(tile, frameState); - loadTile(tile, frameState); - } else if (tile.refine === Cesium3DTileRefine.REPLACE) { - if (inBaseTraversal(tile, baseScreenSpaceError)) { - // Always load tiles in the base traversal - // Select tiles that can't refine further - loadTile(tile, frameState); - if (stoppedRefining) { - selectDesiredTile(tile, frameState); - } - } else if (stoppedRefining) { - // In skip traversal, load and select tiles that can't refine further - selectDesiredTile(tile, frameState); - loadTile(tile, frameState); - } else if (reachedSkippingThreshold(tileset, tile)) { - // In skip traversal, load tiles that aren't skipped - loadTile(tile, frameState); - } + // Optimization - if none of the tile's children are visible then this tile isn't visible + const replace = tile.refine === Cesium3DTileRefine.REPLACE; + const useOptimization = + tile._optimChildrenWithinParent === + Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + if (replace && useOptimization && hasChildren) { + if (!anyChildrenVisible(tile, frameState)) { + ++tile.tileset._statistics.numberOfTilesCulledWithChildrenUnion; + tile._visible = false; + return; } - - visitTile(tile, frameState); - touchTile(tile, frameState); } } /** - * Depth-first traversal that checks if all nearest descendants with content are loaded. - * Ignores visibility. - * * @private - * @param {Cesium3DTile} root + * @param {Cesium3DTile} tile * @param {FrameState} frameState * @returns {boolean} */ -function executeEmptyTraversal(root, frameState) { - const { canTraverse, updateTile, loadTile, touchTile } = TraversalUtility; - let allDescendantsLoaded = true; - const stack = emptyTraversal.stack; - stack.push(root); - - while (stack.length > 0) { - emptyTraversal.stackMaximumLength = Math.max( - emptyTraversal.stackMaximumLength, - stack.length - ); - - const tile = stack.pop(); - const children = tile.children; - const childrenLength = children.length; - - // Only traverse if the tile is empty - traversal stops at descendants with content - const traverse = !tile.hasRenderableContent && canTraverse(tile); - const emptyLeaf = !tile.hasRenderableContent && tile.children.length === 0; - - // Traversal stops but the tile does not have content yet - // There will be holes if the parent tries to refine to its children, so don't refine - // One exception: a parent may refine even if one of its descendants is an empty leaf - if (!traverse && !tile.contentAvailable && !emptyLeaf) { - allDescendantsLoaded = false; - } - - updateTile(tile, frameState); - if (!tile.isVisible) { - // Load tiles that aren't visible since they are still needed for the parent to refine - loadTile(tile, frameState); - touchTile(tile, frameState); - } - - if (traverse) { - for (let i = 0; i < childrenLength; ++i) { - const child = children[i]; - stack.push(child); - } - } +function meetsScreenSpaceErrorEarly(tile, frameState) { + const { parent, tileset } = tile; + if ( + !defined(parent) || + parent.hasTilesetContent || + parent.hasImplicitContent || + parent.refine !== Cesium3DTileRefine.ADD + ) { + return false; } - return allDescendantsLoaded; + // Use parent's geometric error with child's box to see if the tile already meet the SSE + return ( + tile.getScreenSpaceError(frameState, true) <= + tileset._maximumScreenSpaceError + ); } /** - * Traverse the tree and check if their selected frame is the current frame. If so, add it to a selection queue. - * This is a preorder traversal so children tiles are selected before ancestor tiles. - * - * The reason for the preorder traversal is so that tiles can easily be marked with their - * selection depth. A tile's _selectionDepth is its depth in the tree where all non-selected tiles are removed. - * This property is important for use in the stencil test because we want to render deeper tiles on top of their - * ancestors. If a tileset is very deep, the depth is unlikely to fit into the stencil buffer. - * - * We want to select children before their ancestors because there is no guarantee on the relationship between - * the children's z-depth and the ancestor's z-depth. We cannot rely on Z because we want the child to appear on top - * of ancestor regardless of true depth. The stencil tests used require children to be drawn first. - * - * NOTE: 3D Tiles uses 3 bits from the stencil buffer meaning this will not work when there is a chain of - * selected tiles that is deeper than 7. This is not very likely. - * * @private - * @param {Cesium3DTile} root + * @param {Cesium3DTile} tile * @param {FrameState} frameState + * @returns {boolean} */ -function traverseAndSelect(root, frameState) { - const { selectTile, canTraverse } = TraversalUtility; - const { stack, ancestorStack } = selectionTraversal; - let lastAncestor; - - stack.push(root); - - while (stack.length > 0 || ancestorStack.length > 0) { - selectionTraversal.stackMaximumLength = Math.max( - selectionTraversal.stackMaximumLength, - stack.length - ); - selectionTraversal.ancestorStackMaximumLength = Math.max( - selectionTraversal.ancestorStackMaximumLength, - ancestorStack.length - ); - - if (ancestorStack.length > 0) { - const waitingTile = ancestorStack.peek(); - if (waitingTile._stackLength === stack.length) { - ancestorStack.pop(); - if (waitingTile !== lastAncestor) { - waitingTile._finalResolution = false; - } - selectTile(waitingTile, frameState); - continue; - } - } - - const tile = stack.pop(); - if (!defined(tile)) { - // stack is empty but ancestorStack isn't - continue; - } - - const traverse = canTraverse(tile); - - if (tile._shouldSelect) { - if (tile.refine === Cesium3DTileRefine.ADD) { - selectTile(tile, frameState); - } else { - tile._selectionDepth = ancestorStack.length; - if (tile._selectionDepth > 0) { - tile.tileset._hasMixedContent = true; - } - lastAncestor = tile; - if (!traverse) { - selectTile(tile, frameState); - continue; - } - ancestorStack.push(tile); - tile._stackLength = stack.length; - } - } - - if (traverse) { - const children = tile.children; - for (let i = 0; i < children.length; ++i) { - const child = children[i]; - if (child.isVisible) { - stack.push(child); - } - } - } +function anyChildrenVisible(tile, frameState) { + let anyVisible = false; + const children = tile.children; + for (let i = 0; i < children.length; ++i) { + const child = children[i]; + child.updateVisibility(frameState); + anyVisible = anyVisible || child.isVisible; } + return anyVisible; +} + +/** + * @private + * @param {Cesium3DTile} tile + */ +function updateMinimumMaximumPriority(tile) { + const { + _maximumPriority: maximumPriority, + _minimumPriority: minimumPriority, + } = tile.tileset; + const priorityHolder = tile._priorityHolder; + + maximumPriority.distance = Math.max( + priorityHolder._distanceToCamera, + maximumPriority.distance + ); + minimumPriority.distance = Math.min( + priorityHolder._distanceToCamera, + minimumPriority.distance + ); + maximumPriority.depth = Math.max(tile._depth, maximumPriority.depth); + minimumPriority.depth = Math.min(tile._depth, minimumPriority.depth); + maximumPriority.foveatedFactor = Math.max( + priorityHolder._foveatedFactor, + maximumPriority.foveatedFactor + ); + minimumPriority.foveatedFactor = Math.min( + priorityHolder._foveatedFactor, + minimumPriority.foveatedFactor + ); + maximumPriority.reverseScreenSpaceError = Math.max( + tile._priorityReverseScreenSpaceError, + maximumPriority.reverseScreenSpaceError + ); + minimumPriority.reverseScreenSpaceError = Math.min( + tile._priorityReverseScreenSpaceError, + minimumPriority.reverseScreenSpaceError + ); } export default Cesium3DTilesetTraversal; diff --git a/packages/engine/Source/Scene/TraversalUtility.js b/packages/engine/Source/Scene/TraversalUtility.js deleted file mode 100644 index ffd90c70663..00000000000 --- a/packages/engine/Source/Scene/TraversalUtility.js +++ /dev/null @@ -1,302 +0,0 @@ -import defined from "../Core/defined.js"; -import Intersect from "../Core/Intersect.js"; -import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js"; -import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; - -/** - * Utility functions for {@link Cesium3DTilesetTraversal}. - * - * @private - */ -function TraversalUtility() {} - -/** - * Sort by farthest child first since this is going on a stack - * - * @private - * @param {Cesium3DTile} a - * @param {Cesium3DTile} b - * @returns {number} - */ -TraversalUtility.sortChildrenByDistanceToCamera = function (a, b) { - if (b._distanceToCamera === 0 && a._distanceToCamera === 0) { - return b._centerZDepth - a._centerZDepth; - } - - return b._distanceToCamera - a._distanceToCamera; -}; - -/** - * Determine if a tile can and should be traversed for children tiles that - * would contribute to rendering the current view - * - * @private - * @param {Cesium3DTile} tile - * @returns {boolean} - */ -TraversalUtility.canTraverse = function (tile) { - if (tile.children.length === 0) { - return false; - } - if (tile.hasTilesetContent || tile.hasImplicitContent) { - // Traverse external tileset to visit its root tile - // Don't traverse if the subtree is expired because it will be destroyed - return !tile.contentExpired; - } - return tile._screenSpaceError > tile.tileset._maximumScreenSpaceError; -}; - -/** - * Mark a tile as selected, and add it to the tileset's list of selected tiles - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -TraversalUtility.selectTile = function (tile, frameState) { - if (tile.contentVisibility(frameState) === Intersect.OUTSIDE) { - return; - } - - const { content, tileset } = tile; - if (content.featurePropertiesDirty) { - // A feature's property in this tile changed, the tile needs to be re-styled. - content.featurePropertiesDirty = false; - tile.lastStyleTime = 0; // Force applying the style to this tile - tileset._selectedTilesToStyle.push(tile); - } else if (tile._selectedFrame < frameState.frameNumber - 1) { - // Tile is newly selected; it is selected this frame, but was not selected last frame. - tileset._selectedTilesToStyle.push(tile); - } - tile._selectedFrame = frameState.frameNumber; - tileset._selectedTiles.push(tile); -}; - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -TraversalUtility.visitTile = function (tile, frameState) { - ++tile.tileset._statistics.visited; - tile._visitedFrame = frameState.frameNumber; -}; - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -TraversalUtility.touchTile = function (tile, frameState) { - if (tile._touchedFrame === frameState.frameNumber) { - // Prevents another pass from touching the frame again - return; - } - tile.tileset._cache.touch(tile); - tile._touchedFrame = frameState.frameNumber; -}; - -/** - * Add a tile to the list of requested tiles, if appropriate - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -TraversalUtility.loadTile = function (tile, frameState) { - const { tileset } = tile; - if ( - tile._requestedFrame === frameState.frameNumber || - (!tile.hasUnloadedRenderableContent && !tile.contentExpired) - ) { - return; - } - - if (!isOnScreenLongEnough(tile, frameState)) { - return; - } - - const cameraHasNotStoppedMovingLongEnough = - frameState.camera.timeSinceMoved < tileset.foveatedTimeDelay; - if (tile.priorityDeferred && cameraHasNotStoppedMovingLongEnough) { - return; - } - - tile._requestedFrame = frameState.frameNumber; - tileset._requestedTiles.push(tile); -}; - -/** - * Prevent unnecessary loads while camera is moving by getting the ratio of travel distance to tile size. - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function isOnScreenLongEnough(tile, frameState) { - const { tileset } = tile; - if (!tileset._cullRequestsWhileMoving) { - return true; - } - - const { - positionWCDeltaMagnitude, - positionWCDeltaMagnitudeLastFrame, - } = frameState.camera; - const deltaMagnitude = - positionWCDeltaMagnitude !== 0.0 - ? positionWCDeltaMagnitude - : positionWCDeltaMagnitudeLastFrame; - - // How do n frames of this movement compare to the tile's physical size. - const diameter = Math.max(tile.boundingSphere.radius * 2.0, 1.0); - const movementRatio = - (tileset.cullRequestsWhileMovingMultiplier * deltaMagnitude) / diameter; - - return movementRatio < 1.0; -} - -/** - * Reset some of the tile's flags and re-evaluate visibility and priority - * - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -TraversalUtility.updateTile = function (tile, frameState) { - updateTileVisibility(tile, frameState); - tile.updateExpiration(); - - tile._wasMinPriorityChild = false; - tile._priorityHolder = tile; - updateMinimumMaximumPriority(tile); - - // SkipLOD - tile._shouldSelect = false; - tile._finalResolution = true; -}; - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - */ -function updateTileVisibility(tile, frameState) { - tile.updateVisibility(frameState); - - if (!tile.isVisible) { - return; - } - - const hasChildren = tile.children.length > 0; - if ((tile.hasTilesetContent || tile.hasImplicitContent) && hasChildren) { - // Use the root tile's visibility instead of this tile's visibility. - // The root tile may be culled by the children bounds optimization in which - // case this tile should also be culled. - const child = tile.children[0]; - updateTileVisibility(child, frameState); - tile._visible = child._visible; - return; - } - - if (meetsScreenSpaceErrorEarly(tile, frameState)) { - tile._visible = false; - return; - } - - // Optimization - if none of the tile's children are visible then this tile isn't visible - const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const useOptimization = - tile._optimChildrenWithinParent === - Cesium3DTileOptimizationHint.USE_OPTIMIZATION; - if (replace && useOptimization && hasChildren) { - if (!anyChildrenVisible(tile, frameState)) { - ++tile.tileset._statistics.numberOfTilesCulledWithChildrenUnion; - tile._visible = false; - return; - } - } -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function meetsScreenSpaceErrorEarly(tile, frameState) { - const { parent, tileset } = tile; - if ( - !defined(parent) || - parent.hasTilesetContent || - parent.hasImplicitContent || - parent.refine !== Cesium3DTileRefine.ADD - ) { - return false; - } - - // Use parent's geometric error with child's box to see if the tile already meet the SSE - return ( - tile.getScreenSpaceError(frameState, true) <= - tileset._maximumScreenSpaceError - ); -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {FrameState} frameState - * @returns {boolean} - */ -function anyChildrenVisible(tile, frameState) { - let anyVisible = false; - const children = tile.children; - for (let i = 0; i < children.length; ++i) { - const child = children[i]; - child.updateVisibility(frameState); - anyVisible = anyVisible || child.isVisible; - } - return anyVisible; -} - -/** - * @private - * @param {Cesium3DTile} tile - */ -function updateMinimumMaximumPriority(tile) { - const { - _maximumPriority: maximumPriority, - _minimumPriority: minimumPriority, - } = tile.tileset; - const priorityHolder = tile._priorityHolder; - - maximumPriority.distance = Math.max( - priorityHolder._distanceToCamera, - maximumPriority.distance - ); - minimumPriority.distance = Math.min( - priorityHolder._distanceToCamera, - minimumPriority.distance - ); - maximumPriority.depth = Math.max(tile._depth, maximumPriority.depth); - minimumPriority.depth = Math.min(tile._depth, minimumPriority.depth); - maximumPriority.foveatedFactor = Math.max( - priorityHolder._foveatedFactor, - maximumPriority.foveatedFactor - ); - minimumPriority.foveatedFactor = Math.min( - priorityHolder._foveatedFactor, - minimumPriority.foveatedFactor - ); - maximumPriority.reverseScreenSpaceError = Math.max( - tile._priorityReverseScreenSpaceError, - maximumPriority.reverseScreenSpaceError - ); - minimumPriority.reverseScreenSpaceError = Math.min( - tile._priorityReverseScreenSpaceError, - minimumPriority.reverseScreenSpaceError - ); -} - -export default TraversalUtility; From 556ff8823738dfc035ca518fc2e30a9cd65afc9b Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 16 Mar 2023 18:12:02 -0400 Subject: [PATCH 550/679] Add specs to check Cesium3DTilesetTraversal interfaces --- .../Source/Scene/Cesium3DTilesetBaseTraversal.js | 2 -- .../Specs/Scene/Cesium3DTilesetBaseTraversalSpec.js | 12 ++++++++++++ .../Cesium3DTilesetMostDetailedTraversalSpec.js | 12 ++++++++++++ .../Specs/Scene/Cesium3DTilesetSkipTraversalSpec.js | 12 ++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 packages/engine/Specs/Scene/Cesium3DTilesetBaseTraversalSpec.js create mode 100644 packages/engine/Specs/Scene/Cesium3DTilesetMostDetailedTraversalSpec.js create mode 100644 packages/engine/Specs/Scene/Cesium3DTilesetSkipTraversalSpec.js diff --git a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js index fbb56f56cb8..57b776b6b08 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js @@ -71,10 +71,8 @@ Cesium3DTilesetBaseTraversal.selectTiles = function (tileset, frameState) { */ function selectDesiredTile(tile, frameState) { if (tile.contentAvailable) { - // The tile can be selected right away and does not require traverseAndSelect Cesium3DTilesetTraversal.selectTile(tile, frameState); } - return; } /** diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetBaseTraversalSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetBaseTraversalSpec.js new file mode 100644 index 00000000000..3c4782ee83c --- /dev/null +++ b/packages/engine/Specs/Scene/Cesium3DTilesetBaseTraversalSpec.js @@ -0,0 +1,12 @@ +import { + Cesium3DTilesetTraversal, + Cesium3DTilesetBaseTraversal, +} from "../../index.js"; + +describe("Scene/Cesium3DTilesetBaseTraversal", function () { + it("conforms to Cesium3DTilesetTraversal interface", function () { + expect(Cesium3DTilesetBaseTraversal).toConformToInterface( + Cesium3DTilesetTraversal + ); + }); +}); diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetMostDetailedTraversalSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetMostDetailedTraversalSpec.js new file mode 100644 index 00000000000..364c9369df1 --- /dev/null +++ b/packages/engine/Specs/Scene/Cesium3DTilesetMostDetailedTraversalSpec.js @@ -0,0 +1,12 @@ +import { + Cesium3DTilesetTraversal, + Cesium3DTilesetMostDetailedTraversal, +} from "../../index.js"; + +describe("Scene/Cesium3DTilesetMostDetailedTraversal", function () { + it("conforms to Cesium3DTilesetTraversal interface", function () { + expect(Cesium3DTilesetMostDetailedTraversal).toConformToInterface( + Cesium3DTilesetTraversal + ); + }); +}); diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSkipTraversalSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSkipTraversalSpec.js new file mode 100644 index 00000000000..bb1418cebfc --- /dev/null +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSkipTraversalSpec.js @@ -0,0 +1,12 @@ +import { + Cesium3DTilesetTraversal, + Cesium3DTilesetSkipTraversal, +} from "../../index.js"; + +describe("Scene/Cesium3DTilesetSkipTraversal", function () { + it("conforms to Cesium3DTilesetTraversal interface", function () { + expect(Cesium3DTilesetSkipTraversal).toConformToInterface( + Cesium3DTilesetTraversal + ); + }); +}); From d02e73908adf38f55365ec23fa673a7ceecf0e41 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 17 Mar 2023 14:20:46 -0400 Subject: [PATCH 551/679] Refactor loading promises --- Specs/Cesium3DTilesTester.js | 78 +- .../Source/DataSources/ModelVisualizer.js | 49 +- packages/engine/Source/Scene/Cesium3DTile.js | 315 ++-- .../Source/Scene/Cesium3DTileContent.js | 18 +- .../Scene/Cesium3DTileContentFactory.js | 11 +- .../Scene/Cesium3DTilesVoxelProvider.js | 43 +- .../engine/Source/Scene/Cesium3DTileset.js | 122 +- .../Source/Scene/Composite3DTileContent.js | 53 +- .../engine/Source/Scene/Empty3DTileContent.js | 4 +- .../Source/Scene/Geometry3DTileContent.js | 19 +- .../Source/Scene/GltfBufferViewLoader.js | 2 +- .../engine/Source/Scene/GltfImageLoader.js | 5 +- .../Source/Scene/GltfIndexBufferLoader.js | 5 +- .../engine/Source/Scene/GltfJsonLoader.js | 4 +- packages/engine/Source/Scene/GltfLoader.js | 77 +- .../engine/Source/Scene/GltfTextureLoader.js | 2 +- .../Source/Scene/GltfVertexBufferLoader.js | 5 +- .../Source/Scene/Implicit3DTileContent.js | 66 +- .../engine/Source/Scene/ImplicitSubtree.js | 109 +- .../engine/Source/Scene/Model/B3dmLoader.js | 88 +- .../Source/Scene/Model/GeoJsonLoader.js | 40 +- .../engine/Source/Scene/Model/I3dmLoader.js | 122 +- packages/engine/Source/Scene/Model/Model.js | 76 +- .../Source/Scene/Model/Model3DTileContent.js | 58 +- .../engine/Source/Scene/Model/PntsLoader.js | 59 +- .../Source/Scene/Multiple3DTileContent.js | 166 +- packages/engine/Source/Scene/ResourceCache.js | 10 +- .../Source/Scene/ResourceCacheStatistics.js | 3 +- .../Source/Scene/Tileset3DTileContent.js | 24 +- .../Scene/Vector3DTileClampedPolylines.js | 180 ++- .../Source/Scene/Vector3DTileContent.js | 34 +- .../Source/Scene/Vector3DTileGeometry.js | 106 +- .../engine/Source/Scene/Vector3DTilePoints.js | 136 +- .../Source/Scene/Vector3DTilePolygons.js | 228 +-- .../Source/Scene/Vector3DTilePolylines.js | 165 +- .../Specs/DataSources/ModelVisualizerSpec.js | 199 ++- .../engine/Specs/Scene/Cesium3DTilesetSpec.js | 763 +++++---- .../Specs/Scene/Composite3DTileContentSpec.js | 41 +- .../Specs/Scene/Geometry3DTileContentSpec.js | 28 +- .../Scene/GlobeSurfaceTileProviderSpec.js | 2 +- packages/engine/Specs/Scene/GltfLoaderSpec.js | 40 +- packages/engine/Specs/Scene/I3SNodeSpec.js | 6 +- .../Specs/Scene/Implicit3DTileContentSpec.js | 509 +++--- .../Specs/Scene/ImplicitMetadataViewSpec.js | 84 +- .../Specs/Scene/ImplicitSubtreeCacheSpec.js | 38 +- .../engine/Specs/Scene/ImplicitSubtreeSpec.js | 1424 ++++++++--------- .../Specs/Scene/Model/B3dmLoaderSpec.js | 24 +- .../Model/DequantizationPipelineStageSpec.js | 8 +- .../Scene/Model/FeatureIdPipelineStageSpec.js | 8 +- .../Specs/Scene/Model/GeoJsonLoaderSpec.js | 21 +- .../Scene/Model/GeometryPipelineStageSpec.js | 8 +- .../Specs/Scene/Model/I3dmLoaderSpec.js | 58 +- .../Model/InstancingPipelineStageSpec.js | 28 +- .../Scene/Model/MaterialPipelineStageSpec.js | 8 +- .../Scene/Model/MetadataPipelineStageSpec.js | 8 +- .../Scene/Model/Model3DTileContentSpec.js | 18 +- .../Model/ModelAnimationCollectionSpec.js | 2 +- .../Scene/Model/ModelMatrixUpdateStageSpec.js | 70 +- .../Specs/Scene/Model/ModelSceneGraphSpec.js | 2 - .../engine/Specs/Scene/Model/ModelSpec.js | 6 +- .../Model/MorphTargetsPipelineStageSpec.js | 8 +- .../Model/NodeStatisticsPipelineStageSpec.js | 8 +- .../Scene/Model/PickingPipelineStageSpec.js | 8 +- .../Specs/Scene/Model/PntsLoaderSpec.js | 70 +- .../PrimitiveOutlinePipelineStageSpec.js | 8 +- .../PrimitiveStatisticsPipelineStageSpec.js | 8 +- .../Model/SceneMode2DPipelineStageSpec.js | 8 +- .../SelectedFeatureIdPipelineStageSpec.js | 8 +- .../Scene/Model/SkinningPipelineStageSpec.js | 9 +- .../Scene/Model/WireframePipelineStageSpec.js | 8 +- .../Specs/Scene/Multiple3DTileContentSpec.js | 82 +- .../Scene/ResourceCacheStatisticsSpec.js | 312 ++-- .../engine/Specs/Scene/ResourceLoaderSpec.js | 3 - packages/engine/Specs/Scene/ShadowMapSpec.js | 2 +- .../Specs/Scene/Tileset3DTileContentSpec.js | 7 +- .../Specs/Scene/Vector3DTileContentSpec.js | 37 +- .../Specs/Scene/Vector3DTileGeometrySpec.js | 6 +- .../Specs/Scene/Vector3DTilePointsSpec.js | 6 +- .../Specs/Scene/Vector3DTilePolygonsSpec.js | 6 +- .../Specs/Scene/Vector3DTilePolylinesSpec.js | 6 +- 80 files changed, 3091 insertions(+), 3404 deletions(-) diff --git a/Specs/Cesium3DTilesTester.js b/Specs/Cesium3DTilesTester.js index 961829be893..04318ceeadf 100644 --- a/Specs/Cesium3DTilesTester.js +++ b/Specs/Cesium3DTilesTester.js @@ -1,16 +1,12 @@ import { - Cartesian2, Color, defaultValue, defined, JulianDate, - ImageBasedLighting, Resource, Cesium3DTileContentFactory, Cesium3DTileset, - PointCloudShading, TileBoundingSphere, - RuntimeError, } from "@cesium/engine"; import pollToPromise from "./pollToPromise.js"; @@ -129,87 +125,19 @@ Cesium3DTilesTester.loadTileset = function (scene, url, options) { }); }; -Cesium3DTilesTester.loadTileExpectError = function (scene, arrayBuffer, type) { - const tileset = {}; - const url = Resource.createIfNeeded(""); - expect(function () { - return Cesium3DTileContentFactory[type]( - tileset, - mockTile, - url, - arrayBuffer, - 0 - ); - }).toThrowError(RuntimeError); -}; - -Cesium3DTilesTester.loadTile = function (scene, arrayBuffer, type) { - const tileset = { - _statistics: { - batchTableByteLength: 0, - }, - root: {}, - }; - const url = Resource.createIfNeeded(""); - const content = Cesium3DTileContentFactory[type]( - tileset, - mockTile, - url, - arrayBuffer, - 0 - ); - content.update(tileset, scene.frameState); - return content; -}; - -// Use counter to prevent models from sharing the same cache key, -// this fixes tests that load a model with the same invalid url -let counter = 0; -Cesium3DTilesTester.rejectsReadyPromiseOnError = function ( - scene, +Cesium3DTilesTester.createContentForMockTile = async function ( arrayBuffer, type ) { - const tileset = { - basePath: counter++, - _statistics: { - batchTableByteLength: 0, - }, - imageBasedLighting: new ImageBasedLighting({ - imageBasedLighting: new Cartesian2(1, 1), - }), - pointCloudShading: new PointCloudShading(), - featureIdLabel: "featureId_0", - instanceFeatureIdLabel: "instanceFeatureId_0", - }; + const tileset = {}; const url = Resource.createIfNeeded(""); - const content = Cesium3DTileContentFactory[type]( + return Cesium3DTileContentFactory[type]( tileset, mockTile, url, arrayBuffer, 0 ); - content.update(tileset, scene.frameState); - - return content.readyPromise - .then(function (content) { - fail("should not resolve"); - }) - .catch(function (error) { - expect(error).toBeDefined(); - }); -}; - -Cesium3DTilesTester.resolvesReadyPromise = function (scene, url, options) { - return Cesium3DTilesTester.loadTileset(scene, url, options).then(function ( - tileset - ) { - const content = tileset.root.content; - return content.readyPromise.then(function (content) { - expect(content).toBeDefined(); - }); - }); }; Cesium3DTilesTester.tileDestroys = function (scene, url, options) { diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 325ba027c67..337e8012822 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -36,6 +36,9 @@ const modelMatrixScratch = new Matrix4(); const nodeMatrixScratch = new Matrix4(); const scratchColor = new Color(); +const scratchArray = new Array(4); +const scratchCartesian = new Cartesian3(); + /** * A {@link Visualizer} which maps {@link Entity#model} to a {@link Model}. * @alias ModelVisualizer @@ -121,6 +124,7 @@ ModelVisualizer.prototype.update = function (time) { nodeTransformationsScratch: {}, articulationsScratch: {}, loadFailed: false, + modelUpdated: false, awaitingSampleTerrain: false, clampedBoundingSphere: undefined, sampleTerrainFailed: false, @@ -138,6 +142,11 @@ ModelVisualizer.prototype.update = function (time) { ), scene: this._scene, }); + + if (this.isDestroyed() || !defined(modelHash[entity.id])) { + return; + } + model.id = entity; primitives.add(model); modelHash[entity.id].modelPrimitive = model; @@ -146,20 +155,23 @@ ModelVisualizer.prototype.update = function (time) { return; } - console.error(error); + console.log(error); // Texture failures when incrementallyLoadTextures // will not affect the ability to compute the bounding sphere - if (error.name !== "TextureError") { + if ( + error.name !== "TextureError" && + model.incrementallyLoadTextures + ) { modelHash[entity.id].loadFailed = true; } }); } catch (error) { - if (!defined(modelHash[entity.id])) { + if (this.isDestroyed() || !defined(modelHash[entity.id])) { return; } - console.error(error); + console.log(error); modelHash[entity.id].loadFailed = true; } })(); @@ -241,15 +253,27 @@ ModelVisualizer.prototype.update = function (time) { time, defaultImageBasedLightingFactor ); - model.lightColor = Property.getValueOrUndefined( + let lightColor = Property.getValueOrUndefined( modelGraphics._lightColor, time ); + + // Convert from Color to Cartesian3 + if (defined(lightColor)) { + Color.pack(lightColor, scratchArray, 0); + lightColor = Cartesian3.unpack(scratchArray, 0, scratchCartesian); + } + + model.lightColor = lightColor; model.customShader = Property.getValueOrUndefined( modelGraphics._customShader, time ); + // It's possible for getBoundingSphere to run before + // model becomes ready and these properties are updated + modelHash[entity.id].modelUpdated = true; + if (model.ready) { const runAnimations = Property.getValueOrDefault( modelGraphics._runAnimations, @@ -393,7 +417,7 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { const modelData = this._modelHash[entity.id]; if (!defined(modelData)) { - return BoundingSphereState.PENDING; + return BoundingSphereState.FAILED; } if (modelData.loadFailed) { @@ -402,12 +426,13 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { const model = modelData.modelPrimitive; if (!defined(model) || !model.show) { - return BoundingSphereState.FAILED; + return BoundingSphereState.PENDING; } - if (!model.ready) { + if (!model.ready || !modelData.modelUpdated) { return BoundingSphereState.PENDING; } + const scene = this._scene; const globe = scene.globe; const ellipsoid = globe.ellipsoid; @@ -473,6 +498,10 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { scratchCartographic, ]) .then((result) => { + if (this.isDestroyed()) { + return; + } + this._modelHash[entity.id].awaitingSampleTerrain = false; const updatedCartographic = result[0]; @@ -495,6 +524,10 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { ); }) .catch((e) => { + if (this.isDestroyed()) { + return; + } + this._modelHash[entity.id].sampleTerrainFailed = true; this._modelHash[entity.id].awaitingSampleTerrain = false; }); diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 1fb9138aa66..de95fdc92b4 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -259,8 +259,6 @@ function Cesium3DTile(tileset, baseResource, header, parent) { this._content = content; this._contentResource = contentResource; this._contentState = contentState; - this._contentReadyToProcessPromise = undefined; - this._contentReadyPromise = undefined; this._expiredContent = undefined; this._serverKey = serverKey; @@ -710,42 +708,6 @@ Object.defineProperties(Cesium3DTile.prototype, { }, }, - /** - * Gets the promise that will be resolved when the tile's content is ready to process. - * This happens after the content is downloaded but before the content is ready - * to render. - * <p> - * The promise remains <code>undefined</code> until the tile's content is requested. - * </p> - * - * @type {Promise<Cesium3DTileContent>} - * @readonly - * - * @private - */ - contentReadyToProcessPromise: { - get: function () { - return this._contentReadyToProcessPromise; - }, - }, - - /** - * Gets the promise that will be resolved when the tile's content is ready to render. - * <p> - * The promise remains <code>undefined</code> until the tile's content is requested. - * </p> - * - * @type {Promise<Cesium3DTileContent>} - * @readonly - * - * @private - */ - contentReadyPromise: { - get: function () { - return this._contentReadyPromise; - }, - }, - /** * Returns the number of draw commands used by this tile. * @@ -1084,13 +1046,13 @@ function createPriorityFunction(tile) { * The request may not be made if the Cesium Request Scheduler can't prioritize it. * </p> * - * @return {number} The number of requests that were attempted but not scheduled. + * @return {Promise<void>|undefined} A promise that resolves when the request completes, or undefined if there is no request needed, or the request cannot be scheduled. * @private */ Cesium3DTile.prototype.requestContent = function () { // empty contents don't require any HTTP requests if (this.hasEmptyContent) { - return 0; + return; } if (this.hasMultipleContents) { @@ -1112,7 +1074,7 @@ Cesium3DTile.prototype.requestContent = function () { * * @private * @param {Cesium3DTile} tile - * @returns {number} + * @returns {Promise<Cesium3DTileContent>|Promise<undefined>|undefined} A promise that resolves to the tile content once loaded, or a promise that resolves to undefined if the request was cancelled mid-flight, or undefined if the request cannot be scheduled this frame */ function requestMultipleContents(tile) { let multipleContents = tile._content; @@ -1134,87 +1096,44 @@ function requestMultipleContents(tile) { tile._content = multipleContents; } - const backloggedRequestCount = multipleContents.requestInnerContents(); - if (backloggedRequestCount > 0) { - return backloggedRequestCount; + const promise = multipleContents.requestInnerContents(); + + if (!defined(promise)) { + // Request could not all be scheduled this frame + return; } tile._contentState = Cesium3DTileContentState.LOADING; - const contentReadyToProcessPromise = multipleContents.contentsFetchedPromise.then( - function () { - if ( - tile._contentState !== Cesium3DTileContentState.LOADING || - !defined(multipleContents.readyPromise) - ) { - // The tile or one of the inner content requests was canceled, - // short circuit. - return; - } - + return promise + .then(async (content) => { if (tile.isDestroyed()) { - multipleContentFailed(tile, tileset); + // Tile is unloaded before the content can process return; } - tile._contentState = Cesium3DTileContentState.PROCESSING; - return multipleContents; - } - ); - tile._contentReadyToProcessPromise = contentReadyToProcessPromise; - tile._contentReadyPromise = contentReadyToProcessPromise - .then(function (content) { + // Tile was canceled, try again later if (!defined(content)) { - // request was canceled, short circuit. return; } - return multipleContents.readyPromise; + tile._contentState = Cesium3DTileContentState.PROCESSING; + return multipleContents; }) - .then(function (content) { - if (!defined(content)) { - // tile was canceled, short circuit. - return; - } - + .catch((error) => { if (tile.isDestroyed()) { - multipleContentFailed(tile, tileset); + // Tile is unloaded before the content can process return; } - // Refresh style for expired content - tile._selectedFrame = 0; - tile.lastStyleTime = 0.0; - - JulianDate.now(tile._loadTimestamp); - tile._contentState = Cesium3DTileContentState.READY; - return content; - }) - .catch(function () { - multipleContentFailed(tile, tileset); + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; }); - - return 0; -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {Cesium3DTileset} tileset - */ -function multipleContentFailed(tile, tileset) { - // note: The Multiple3DTileContent handles decrementing the number of pending - // requests if the state is LOADING. - if (tile._contentState === Cesium3DTileContentState.PROCESSING) { - --tileset.statistics.numberOfTilesProcessing; - } - - tile._contentState = Cesium3DTileContentState.FAILED; } /** * @private * @param {Cesium3DTile} tile - * @returns {number} + * @returns {Promise<Cesium3DTileContent>|Promise<undefined>|undefined} A promise that resolves to the tile content once loaded; a promise that resolves to undefined if the tile was destroyed before processing can happen or the request was cancelled mid-flight; or undefined if the request cannot be scheduled this frame. */ function requestSingleContent(tile) { // it is important to clone here. The fetchArrayBuffer() below uses @@ -1238,90 +1157,81 @@ function requestSingleContent(tile) { tile._request = request; resource.request = request; - + const tileset = tile._tileset; const promise = resource.fetchArrayBuffer(); if (!defined(promise)) { - return 1; + ++tileset.statistics.numberOfAttemptedRequests; + return; } const previousState = tile._contentState; - const tileset = tile._tileset; tile._contentState = Cesium3DTileContentState.LOADING; ++tileset.statistics.numberOfPendingRequests; - const contentReadyToProcessPromise = promise.then(function (arrayBuffer) { + + return (async () => { + let arrayBuffer; + try { + arrayBuffer = await promise; + } catch (error) { + --tileset.statistics.numberOfPendingRequests; + if (tile.isDestroyed()) { + // Tile is unloaded before the content can process + return; + } + + if (request.cancelled || request.state === RequestState.CANCELLED) { + // Cancelled due to low priority - try again later. + tile._contentState = previousState; + ++tileset.statistics.numberOfAttemptedRequests; + return; + } + + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; + } + if (tile.isDestroyed()) { - // Tile is unloaded before the content finishes loading - singleContentFailed(tile, tileset); + --tileset.statistics.numberOfPendingRequests; + // Tile is unloaded before the content can process return; } - const content = makeContent(tile, arrayBuffer); - - if (expired) { - tile.expireDate = undefined; + if (request.cancelled || request.state === RequestState.CANCELLED) { + // Cancelled due to low priority - try again later. + tile._contentState = previousState; + --tileset.statistics.numberOfPendingRequests; + ++tileset.statistics.numberOfAttemptedRequests; + return; } - tile._content = content; - tile._contentState = Cesium3DTileContentState.PROCESSING; - return content; - }); - tile._contentReadyToProcessPromise = contentReadyToProcessPromise; - tile._contentReadyPromise = contentReadyToProcessPromise - .then(function (content) { - if (!defined(content)) { - return; - } - + try { + const content = await makeContent(tile, arrayBuffer); --tileset.statistics.numberOfPendingRequests; - return content.readyPromise; - }) - .then(function (content) { - if (!defined(content)) { - return; - } if (tile.isDestroyed()) { - // Tile is unloaded before the content finishes processing - singleContentFailed(tile, tileset); + // Tile is unloaded before the content can process return; } - updateExpireDate(tile); - // Refresh style for expired content - tile._selectedFrame = 0; - tile.lastStyleTime = 0.0; + if (expired) { + tile.expireDate = undefined; + } + + tile._content = content; + tile._contentState = Cesium3DTileContentState.PROCESSING; - JulianDate.now(tile._loadTimestamp); - tile._contentState = Cesium3DTileContentState.READY; return content; - }) - .catch(function (error) { - if (request.state === RequestState.CANCELLED) { - // Cancelled due to low priority - try again later. - tile._contentState = previousState; - --tileset.statistics.numberOfPendingRequests; - ++tileset.statistics.numberOfAttemptedRequests; - return Promise.reject("Cancelled"); + } catch (error) { + --tileset.statistics.numberOfPendingRequests; + if (tile.isDestroyed()) { + // Tile is unloaded before the content can process + return; } - singleContentFailed(tile, tileset); - return Promise.reject(error); - }); - return 0; -} - -/** - * @private - * @param {Cesium3DTile} tile - * @param {Cesium3DTileset} tileset - */ -function singleContentFailed(tile, tileset) { - if (tile._contentState === Cesium3DTileContentState.PROCESSING) { - --tileset.statistics.numberOfTilesProcessing; - } else { - --tileset.statistics.numberOfPendingRequests; - } - tile._contentState = Cesium3DTileContentState.FAILED; + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; + } + })(); } /** @@ -1332,10 +1242,10 @@ function singleContentFailed(tile, tileset) { * * @param {Cesium3DTile} tile The tile * @param {ArrayBuffer} arrayBuffer The downloaded payload containing data for the content - * @return {Cesium3DTileContent} A content object + * @return {Promise<Cesium3DTileContent>} A content object * @private */ -function makeContent(tile, arrayBuffer) { +async function makeContent(tile, arrayBuffer) { const preprocessed = preprocess3DTileContent(arrayBuffer); // Vector and Geometry tile rendering do not support the skip LOD optimization. @@ -1358,21 +1268,29 @@ function makeContent(tile, arrayBuffer) { let content; const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType]; + if (tile.isDestroyed()) { + return; + } + if (defined(preprocessed.binaryPayload)) { - content = contentFactory( - tileset, - tile, - tile._contentResource, - preprocessed.binaryPayload.buffer, - 0 + content = await Promise.resolve( + contentFactory( + tileset, + tile, + tile._contentResource, + preprocessed.binaryPayload.buffer, + 0 + ) ); } else { // JSON formats - content = contentFactory( - tileset, - tile, - tile._contentResource, - preprocessed.jsonPayload + content = await Promise.resolve( + contentFactory( + tileset, + tile, + tile._contentResource, + preprocessed.jsonPayload + ) ); } @@ -1426,8 +1344,6 @@ Cesium3DTile.prototype.unloadContent = function () { this._content = this._content && this._content.destroy(); this._contentState = Cesium3DTileContentState.UNLOADED; - this._contentReadyToProcessPromise = undefined; - this._contentReadyPromise = undefined; this.lastStyleTime = 0.0; this.clippingPlanesDirty = this._clippingPlanesState === 0; @@ -1999,7 +1915,11 @@ function updateContent(tile, tileset, frameState) { if (!tile.hasMultipleContents && defined(expiredContent)) { if (!tile.contentReady) { // Render the expired content while the content loads - expiredContent.update(tileset, frameState); + try { + expiredContent.update(tileset, frameState); + } catch (error) { + // Eat error for expired content + } return; } @@ -2008,7 +1928,17 @@ function updateContent(tile, tileset, frameState) { tile._expiredContent = undefined; } - tile.content.update(tileset, frameState); + if (!defined(tile.content)) { + // Implicit placeholder tile + return; + } + + try { + tile.content.update(tileset, frameState); + } catch (error) { + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; + } } /** @@ -2073,10 +2003,37 @@ const scratchCommandList = []; * @private */ Cesium3DTile.prototype.process = function (tileset, frameState) { + if (!this.contentExpired && !this.contentReady && this._content.ready) { + updateExpireDate(this); + + // Refresh style for expired content + this._selectedFrame = 0; + this.lastStyleTime = 0.0; + + JulianDate.now(this._loadTimestamp); + this._contentState = Cesium3DTileContentState.READY; + + if (!this.hasTilesetContent && !this.hasImplicitContent) { + // RESEARCH_IDEA: ability to unload tiles (without content) for an + // external tileset when all the tiles are unloaded. + tileset._statistics.incrementLoadCounts(this.content); + ++tileset._statistics.numberOfTilesWithContentReady; + ++tileset._statistics.numberOfLoadedTilesTotal; + + // Add to the tile cache. Previously expired tiles are already in the cache and won't get re-added. + tileset._cache.add(this); + } + } + const savedCommandList = frameState.commandList; frameState.commandList = scratchCommandList; - this._content.update(tileset, frameState); + try { + this._content.update(tileset, frameState); + } catch (error) { + this._contentState = Cesium3DTileContentState.FAILED; + throw error; + } scratchCommandList.length = 0; frameState.commandList = savedCommandList; diff --git a/packages/engine/Source/Scene/Cesium3DTileContent.js b/packages/engine/Source/Scene/Cesium3DTileContent.js index c5464c418e0..714cd0adc3e 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContent.js +++ b/packages/engine/Source/Scene/Cesium3DTileContent.js @@ -146,12 +146,28 @@ Object.defineProperties(Cesium3DTileContent.prototype, { }, /** - * Gets the promise that will be resolved when the tile's content is ready to render. + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Cesium3DTileContent.prototype + * + * @type {boolean} + * @readonly + */ + ready: { + // eslint-disable-next-line getter-return + get: function () { + DeveloperError.throwInstantiationError(); + }, + }, + + /** + * Returns true when the tile's content is ready to render; otherwise false * * @memberof Cesium3DTileContent.prototype * * @type {Promise<Cesium3DTileContent>} * @readonly + * @deprecated */ readyPromise: { // eslint-disable-next-line getter-return diff --git a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js index 23c6b39e892..6e2186c31ca 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js +++ b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js @@ -41,7 +41,7 @@ const Cesium3DTileContentFactory = { }, cmpt: function (tileset, tile, resource, arrayBuffer, byteOffset) { // Send in the factory in order to avoid a cyclical dependency - return new Composite3DTileContent( + return Composite3DTileContent.fromTileType( tileset, tile, resource, @@ -51,7 +51,7 @@ const Cesium3DTileContentFactory = { ); }, externalTileset: function (tileset, tile, resource, json) { - return new Tileset3DTileContent(tileset, tile, resource, json); + return Tileset3DTileContent.fromJson(tileset, tile, resource, json); }, geom: function (tileset, tile, resource, arrayBuffer, byteOffset) { return new Geometry3DTileContent( @@ -67,12 +67,13 @@ const Cesium3DTileContentFactory = { tileset, tile, resource, + arrayBuffer, byteOffset ); }, subt: function (tileset, tile, resource, arrayBuffer, byteOffset) { - return new Implicit3DTileContent( + return Implicit3DTileContent.fromSubtreeJson( tileset, tile, resource, @@ -82,7 +83,7 @@ const Cesium3DTileContentFactory = { ); }, subtreeJson: function (tileset, tile, resource, json) { - return new Implicit3DTileContent(tileset, tile, resource, json); + return Implicit3DTileContent.fromSubtreeJson(tileset, tile, resource, json); }, glb: function (tileset, tile, resource, arrayBuffer, byteOffset) { const arrayBufferByteLength = arrayBuffer.byteLength; @@ -92,11 +93,9 @@ const Cesium3DTileContentFactory = { const dataView = new DataView(arrayBuffer, byteOffset); const byteLength = dataView.getUint32(8, true); const glb = new Uint8Array(arrayBuffer, byteOffset, byteLength); - // This should be replace with fromGltfAsync when readyPromise is deprecated across 3D Tiles functions return Model3DTileContent.fromGltf(tileset, tile, resource, glb); }, gltf: function (tileset, tile, resource, json) { - // This should be replace with fromGltfAsync when readyPromise is deprecated across 3D Tiles functions return Model3DTileContent.fromGltf(tileset, tile, resource, json); }, geoJson: function (tileset, tile, resource, json) { diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index baea5346306..02e1904a612 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -381,15 +381,15 @@ function getVoxelPromise(implicitTileset, tileCoordinates) { }); } -function getSubtreePromise(provider, subtreeCoord) { +async function getSubtreePromise(provider, subtreeCoord) { const implicitTileset = provider._implicitTileset; const subtreeCache = provider._subtreeCache; // First load the subtree to check if the tile is available. // If the subtree has been requested previously it might still be in the cache - const subtree = subtreeCache.find(subtreeCoord); + let subtree = subtreeCache.find(subtreeCoord); if (defined(subtree)) { - return subtree.readyPromise; + return subtree; } const subtreeRelative = implicitTileset.subtreeUriTemplate.getDerivedResource( @@ -401,26 +401,25 @@ function getSubtreePromise(provider, subtreeCoord) { url: subtreeRelative.url, }); - return subtreeResource.fetchArrayBuffer().then(function (arrayBuffer) { - // Check one more time if the subtree is in the cache. - // This could happen if there are two in-flight tile requests from the same - // subtree and one finishes before the other. - let subtree = subtreeCache.find(subtreeCoord); - if (defined(subtree)) { - return subtree.readyPromise; - } + const arrayBuffer = await subtreeResource.fetchArrayBuffer(); + // Check one more time if the subtree is in the cache. + // This could happen if there are two in-flight tile requests from the same + // subtree and one finishes before the other. + subtree = subtreeCache.find(subtreeCoord); + if (defined(subtree)) { + return subtree; + } - const preprocessed = preprocess3DTileContent(arrayBuffer); - subtree = new ImplicitSubtree( - subtreeResource, - preprocessed.jsonPayload, - preprocessed.binaryPayload, - implicitTileset, - subtreeCoord - ); - subtreeCache.addSubtree(subtree); - return subtree.readyPromise; - }); + const preprocessed = preprocess3DTileContent(arrayBuffer); + subtree = await ImplicitSubtree.fromSubtreeJson( + subtreeResource, + preprocessed.jsonPayload, + preprocessed.binaryPayload, + implicitTileset, + subtreeCoord + ); + subtreeCache.addSubtree(subtree); + return subtree; } /** @inheritdoc */ diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index b8c4639a030..d5c7674a03a 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -2298,14 +2298,26 @@ function requestContent(tileset, tile) { } const { statistics } = tileset; - const { contentExpired } = tile; - const attemptedRequests = tile.requestContent(); + const contentExpired = tile.contentExpired; - if (attemptedRequests > 0) { - statistics.numberOfAttemptedRequests += attemptedRequests; + const promise = tile.requestContent(); + if (!defined(promise)) { return; } + promise + .then((content) => { + if (!defined(content) || tile.isDestroyed() || tileset.isDestroyed()) { + return; + } + + tileset._processingQueue.push(tile); + ++statistics.numberOfTilesProcessing; + }) + .catch((error) => { + handleTileFailure(error, tileset, tile); + }); + if (contentExpired) { if (tile.hasTilesetContent || tile.hasImplicitContent) { destroySubtree(tileset, tile); @@ -2316,15 +2328,6 @@ function requestContent(tileset, tile) { } tileset._requestedTilesInFlight.push(tile); - - tile.contentReadyToProcessPromise - .then(addToProcessingQueue(tileset, tile)) - .catch(function (e) { - // Any error will propagate through contentReadyPromise and will be handled below - }); - tile.contentReadyPromise - .then(handleTileSuccess(tileset, tile)) - .catch(handleTileFailure(tileset, tile)); } function sortRequestByPriority(a, b) { @@ -2444,43 +2447,30 @@ function requestTiles(tileset) { /** * @private + * @param {Error} error * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile - * @returns {Function} */ -function addToProcessingQueue(tileset, tile) { - return function () { - tileset._processingQueue.push(tile); - - ++tileset._statistics.numberOfTilesProcessing; - }; -} +function handleTileFailure(error, tileset, tile) { + if (tileset.isDestroyed()) { + return; + } -/** - * @private - * @param {Cesium3DTileset} tileset - * @param {Cesium3DTile} tile - * @returns {Function} - */ -function handleTileFailure(tileset, tile) { - return function (error) { - if (tile._contentState !== Cesium3DTileContentState.FAILED) { - // If the tile has not failed, the request has been rejected this frame, but will be retried. Do not bubble up the error. - return; - } + let url; + if (!tile.isDestroyed()) { + url = tile._contentResource.url; + } - const url = tile._contentResource.url; - const message = defined(error.message) ? error.message : error.toString(); - if (tileset.tileFailed.numberOfListeners > 0) { - tileset.tileFailed.raiseEvent({ - url: url, - message: message, - }); - } else { - console.log(`A 3D tile failed to load: ${url}`); - console.log(`Error: ${message}`); - } - }; + const message = defined(error.message) ? error.message : error.toString(); + if (tileset.tileFailed.numberOfListeners > 0) { + tileset.tileFailed.raiseEvent({ + url: url, + message: message, + }); + } else { + console.log(`A 3D tile failed to load: ${url}`); + console.log(`Error: ${message}`); + } } /** @@ -2490,27 +2480,7 @@ function handleTileFailure(tileset, tile) { * @returns {Function} */ function handleTileSuccess(tileset, tile) { - return function (content) { - --tileset._statistics.numberOfTilesProcessing; - - if (!defined(content)) { - // A request was cancelled. Do not update successful statistics. The request will be retried. - return; - } - - if (!tile.hasTilesetContent && !tile.hasImplicitContent) { - // RESEARCH_IDEA: ability to unload tiles (without content) for an - // external tileset when all the tiles are unloaded. - tileset._statistics.incrementLoadCounts(tile.content); - ++tileset._statistics.numberOfTilesWithContentReady; - ++tileset._statistics.numberOfLoadedTilesTotal; - - // Add to the tile cache. Previously expired tiles are already in the cache and won't get re-added. - tileset._cache.add(tile); - } - - tileset.tileLoad.raiseEvent(tile); - }; + tileset.tileLoad.raiseEvent(tile); } /** @@ -2523,7 +2493,10 @@ function filterProcessingQueue(tileset) { let removeCount = 0; for (let i = 0; i < tiles.length; ++i) { const tile = tiles[i]; - if (tile._contentState !== Cesium3DTileContentState.PROCESSING) { + if ( + tile.isDestroyed() || + tile._contentState !== Cesium3DTileContentState.PROCESSING + ) { ++removeCount; continue; } @@ -2543,8 +2516,21 @@ function filterProcessingQueue(tileset) { function processTiles(tileset, frameState) { filterProcessingQueue(tileset); const tiles = tileset._processingQueue; + const statistics = tileset._statistics; + let tile; for (let i = 0; i < tiles.length; ++i) { - tiles[i].process(tileset, frameState); + tile = tiles[i]; + try { + tile.process(tileset, frameState); + + if (tile.contentReady) { + --statistics.numberOfTilesProcessing; + handleTileSuccess(tileset, tile, tile.content); + } + } catch (error) { + --statistics.numberOfTilesProcessing; + handleTileFailure(error, tileset, tile); + } } } diff --git a/packages/engine/Source/Scene/Composite3DTileContent.js b/packages/engine/Source/Scene/Composite3DTileContent.js index d1fc612bd18..0c224a38cfa 100644 --- a/packages/engine/Source/Scene/Composite3DTileContent.js +++ b/packages/engine/Source/Scene/Composite3DTileContent.js @@ -17,14 +17,7 @@ import RuntimeError from "../Core/RuntimeError.js"; * * @private */ -function Composite3DTileContent( - tileset, - tile, - resource, - arrayBuffer, - byteOffset, - factory -) { +function Composite3DTileContent(tileset, tile, resource) { this._tileset = tileset; this._tile = tile; this._resource = resource; @@ -32,8 +25,7 @@ function Composite3DTileContent( this._metadata = undefined; this._group = undefined; - - this._readyPromise = initialize(this, arrayBuffer, byteOffset, factory); + this._ready = false; } Object.defineProperties(Composite3DTileContent.prototype, { @@ -130,9 +122,9 @@ Object.defineProperties(Composite3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -210,7 +202,14 @@ Object.defineProperties(Composite3DTileContent.prototype, { const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT; -function initialize(content, arrayBuffer, byteOffset, factory) { +Composite3DTileContent.fromTileType = async function ( + tileset, + tile, + resource, + arrayBuffer, + byteOffset, + factory +) { byteOffset = defaultValue(byteOffset, 0); const uint8Array = new Uint8Array(arrayBuffer); @@ -231,14 +230,13 @@ function initialize(content, arrayBuffer, byteOffset, factory) { const tilesLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - const contentPromises = []; + const content = new Composite3DTileContent(tileset, tile, resource); // For caching purposes, models within the composite tile must be // distinguished. To do this, add a query parameter ?compositeIndex=i. // Since composite tiles may contain other composite tiles, check for an // existing prefix and separate them with underscores. e.g. // ?compositeIndex=0_1_1 - const resource = content._resource; let prefix = resource.queryParameters.compositeIndex; if (defined(prefix)) { // We'll be adding another value at the end, so add an underscore. @@ -265,15 +263,16 @@ function initialize(content, arrayBuffer, byteOffset, factory) { }); if (defined(contentFactory)) { - const innerContent = contentFactory( - content._tileset, - content._tile, - childResource, - arrayBuffer, - byteOffset + const innerContent = await Promise.resolve( + contentFactory( + content._tileset, + content._tile, + childResource, + arrayBuffer, + byteOffset + ) ); content._contents.push(innerContent); - contentPromises.push(innerContent.readyPromise); } else { throw new RuntimeError( `Unknown tile content type, ${tileType}, inside Composite tile` @@ -283,10 +282,8 @@ function initialize(content, arrayBuffer, byteOffset, factory) { byteOffset += tileByteLength; } - return Promise.all(contentPromises).then(function () { - return content; - }); -} + return content; +}; /** * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code> @@ -326,9 +323,13 @@ Composite3DTileContent.prototype.applyStyle = function (style) { Composite3DTileContent.prototype.update = function (tileset, frameState) { const contents = this._contents; const length = contents.length; + let ready = true; for (let i = 0; i < length; ++i) { contents[i].update(tileset, frameState); + ready = ready && contents[i].ready; } + + this._ready = ready; }; Composite3DTileContent.prototype.isDestroyed = function () { diff --git a/packages/engine/Source/Scene/Empty3DTileContent.js b/packages/engine/Source/Scene/Empty3DTileContent.js index 59f31a58b1f..13f427b0e02 100644 --- a/packages/engine/Source/Scene/Empty3DTileContent.js +++ b/packages/engine/Source/Scene/Empty3DTileContent.js @@ -64,9 +64,9 @@ Object.defineProperties(Empty3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return undefined; + return true; }, }, diff --git a/packages/engine/Source/Scene/Geometry3DTileContent.js b/packages/engine/Source/Scene/Geometry3DTileContent.js index 572cfe4fb68..f9ea775d910 100644 --- a/packages/engine/Source/Scene/Geometry3DTileContent.js +++ b/packages/engine/Source/Scene/Geometry3DTileContent.js @@ -42,7 +42,8 @@ function Geometry3DTileContent( this.featurePropertiesDirty = false; this._group = undefined; - this._readyPromise = initialize(this, arrayBuffer, byteOffset); + this._ready = false; + initialize(this, arrayBuffer, byteOffset); } Object.defineProperties(Geometry3DTileContent.prototype, { @@ -96,9 +97,9 @@ Object.defineProperties(Geometry3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -224,7 +225,7 @@ function getBatchIds(featureTableJson, featureTableBinary) { if (atLeastOneDefined && atLeastOneUndefined) { throw new RuntimeError( - "If one group of batch ids is defined, then all batch ids must be defined." + "If one group of batch ids is defined, then all batch ids must be defined" ); } @@ -290,7 +291,7 @@ function initialize(content, arrayBuffer, byteOffset) { byteOffset += sizeOfUint32; if (byteLength === 0) { - content._readyPromise.resolve(content); + this._ready = true; return; } @@ -451,9 +452,7 @@ function initialize(content, arrayBuffer, byteOffset) { boundingVolume: content.tile.boundingVolume.boundingVolume, }); - return content._geometries.readyPromise.then(function () { - return content; - }); + return content; } return Promise.resolve(content); @@ -509,8 +508,10 @@ Geometry3DTileContent.prototype.update = function (tileset, frameState) { this._geometries.debugWireframe = this._tileset.debugWireframe; this._geometries.update(frameState); } - if (defined(this._batchTable) && this._geometries._ready) { + + if (defined(this._batchTable) && this._geometries.ready) { this._batchTable.update(tileset, frameState); + this._ready = true; } }; diff --git a/packages/engine/Source/Scene/GltfBufferViewLoader.js b/packages/engine/Source/Scene/GltfBufferViewLoader.js index 4a79f097b39..a0bb01d6d37 100644 --- a/packages/engine/Source/Scene/GltfBufferViewLoader.js +++ b/packages/engine/Source/Scene/GltfBufferViewLoader.js @@ -212,7 +212,7 @@ function getBufferLoader(bufferViewLoader) { * @private */ GltfBufferViewLoader.prototype.unload = function () { - if (defined(this._bufferLoader)) { + if (defined(this._bufferLoader) && !this._bufferLoader.isDestroyed()) { this._resourceCache.unload(this._bufferLoader); } diff --git a/packages/engine/Source/Scene/GltfImageLoader.js b/packages/engine/Source/Scene/GltfImageLoader.js index 873b0cf1ec7..91ae40022b8 100644 --- a/packages/engine/Source/Scene/GltfImageLoader.js +++ b/packages/engine/Source/Scene/GltfImageLoader.js @@ -300,7 +300,10 @@ function loadImageFromUri(resource) { * @private */ GltfImageLoader.prototype.unload = function () { - if (defined(this._bufferViewLoader)) { + if ( + defined(this._bufferViewLoader) && + !this._bufferViewLoader.isDestroyed() + ) { this._resourceCache.unload(this._bufferViewLoader); } diff --git a/packages/engine/Source/Scene/GltfIndexBufferLoader.js b/packages/engine/Source/Scene/GltfIndexBufferLoader.js index 563545e21ae..ca6ace4e053 100644 --- a/packages/engine/Source/Scene/GltfIndexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfIndexBufferLoader.js @@ -394,7 +394,10 @@ GltfIndexBufferLoader.prototype.unload = function () { const resourceCache = this._resourceCache; - if (defined(this._bufferViewLoader)) { + if ( + defined(this._bufferViewLoader) && + !this._bufferViewLoader.isDestroyed() + ) { resourceCache.unload(this._bufferViewLoader); } diff --git a/packages/engine/Source/Scene/GltfJsonLoader.js b/packages/engine/Source/Scene/GltfJsonLoader.js index 782f3231e3c..616c28a4265 100644 --- a/packages/engine/Source/Scene/GltfJsonLoader.js +++ b/packages/engine/Source/Scene/GltfJsonLoader.js @@ -281,7 +281,9 @@ GltfJsonLoader.prototype.unload = function () { const bufferLoaders = this._bufferLoaders; const bufferLoadersLength = bufferLoaders.length; for (let i = 0; i < bufferLoadersLength; ++i) { - this._resourceCache.unload(bufferLoaders[i]); + bufferLoaders[i] = + !bufferLoaders[i].isDestroyed() && + this._resourceCache.unload(bufferLoaders[i]); } this._bufferLoaders.length = 0; diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index a32ad01bbef..24db24b33bc 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -260,6 +260,8 @@ function GltfLoader(options) { this._geometryCallbacks = []; this._structuralMetadataLoader = undefined; this._loadResourcesPromise = undefined; + this._resourcesLoaded = false; + this._texturesLoaded = false; // In some cases where geometry post-processing is needed (like generating // outlines) new attributes are added that may have GPU resources attached. @@ -295,11 +297,7 @@ Object.defineProperties(GltfLoader.prototype, { * * @memberof GltfLoader.prototype * -<<<<<<< HEAD * @type {ModelComponents.Components} -======= - * @type {string} ->>>>>>> no-ready-promises * @readonly * @private */ @@ -326,7 +324,7 @@ Object.defineProperties(GltfLoader.prototype, { }, }, /** - * true if textures are loaded separately from the other glTF resources. + * Returns true if textures are loaded separately from the other glTF resources. * * @memberof GltfLoader.prototype * @@ -339,16 +337,24 @@ Object.defineProperties(GltfLoader.prototype, { return this._incrementallyLoadTextures; }, }, + /** + * true if textures are loaded, useful when incrementallyLoadTextures is true + * + * @memberof GltfLoader.prototype + * + * @type {boolean} + * @readonly + * @private + */ + texturesLoaded: { + get: function () { + return this._texturesLoaded; + }, + }, }); /** -<<<<<<< HEAD * Loads the gltf object -======= - * Loads the resource. - * @returns {Promise<GltfLoader>} A promise which resolves to the loader when the resource loading is completed. - * @private ->>>>>>> no-ready-promises */ async function loadGltfJson(loader) { loader._state = GltfLoaderState.LOADING; @@ -425,7 +431,7 @@ async function loadResources(loader, frameState) { // frame. Any promise failures are collected, and will be handled synchronously in process(). Also note that it's fine to call process before a loader is ready // to process or after it has failed; nothing will happen. const gltf = loader.gltfJson; - parse(loader, gltf, supportedImageFormats, frameState); + const promise = parse(loader, gltf, supportedImageFormats, frameState); // All resource loaders have been created, so we can begin processing loader._state = GltfLoaderState.PROCESSING; @@ -437,6 +443,8 @@ async function loadResources(loader, frameState) { ResourceCache.unload(loader._gltfJsonLoader); loader._gltfJsonLoader = undefined; } + + return promise; } /** @@ -550,12 +558,15 @@ GltfLoader.prototype._process = function (frameState) { processLoaders(this, frameState); } - if (this._state === GltfLoaderState.POST_PROCESSING) { + if ( + this._resourcesLoaded && + this._state === GltfLoaderState.POST_PROCESSING + ) { postProcessGeometry(this, frameState.context); this._state = GltfLoaderState.PROCESSED; } - if (this._state === GltfLoaderState.PROCESSED) { + if (this._resourcesLoaded && this._state === GltfLoaderState.PROCESSED) { // The buffer views can be unloaded once the data is copied. unloadBufferViewLoaders(this); @@ -601,6 +612,7 @@ GltfLoader.prototype._processTextures = function (frameState) { } this._textureState = GltfLoaderState.READY; + this._texturesLoaded = true; return true; }; @@ -619,11 +631,13 @@ GltfLoader.prototype.process = function (frameState) { this._state === GltfLoaderState.LOADED && !defined(this._loadResourcesPromise) ) { - this._loadResourcesPromise = loadResources(this, frameState).catch( - (error) => { + this._loadResourcesPromise = loadResources(this, frameState) + .then(() => { + this._resourcesLoaded = true; + }) + .catch((error) => { this._processError = error; - } - ); + }); } if (defined(this._processError)) { @@ -642,11 +656,11 @@ GltfLoader.prototype.process = function (frameState) { throw error; } - let ready = false; if (this._state === GltfLoaderState.FAILED) { - return ready; + return false; } + let ready = false; try { ready = this._process(frameState); } catch (error) { @@ -2646,18 +2660,16 @@ function parse(loader, gltf, supportedImageFormats, frameState) { readyPromises.push.apply(readyPromises, loader._texturesPromises); } - Promise.all(readyPromises).catch((error) => { - // This error will be thrown synchronously during the next call - // to process() - loader._processError = error; - }); + return Promise.all(readyPromises); } function unloadTextures(loader) { const textureLoaders = loader._textureLoaders; const textureLoadersLength = textureLoaders.length; for (let i = 0; i < textureLoadersLength; ++i) { - ResourceCache.unload(textureLoaders[i]); + textureLoaders[i] = + !textureLoaders[i].isDestroyed() && + ResourceCache.unload(textureLoaders[i]); } loader._textureLoaders.length = 0; } @@ -2666,7 +2678,9 @@ function unloadBufferViewLoaders(loader) { const bufferViewLoaders = loader._bufferViewLoaders; const bufferViewLoadersLength = bufferViewLoaders.length; for (let i = 0; i < bufferViewLoadersLength; ++i) { - ResourceCache.unload(bufferViewLoaders[i]); + bufferViewLoaders[i] = + !bufferViewLoaders[i].isDestroyed() && + ResourceCache.unload(bufferViewLoaders[i]); } loader._bufferViewLoaders.length = 0; } @@ -2675,7 +2689,9 @@ function unloadGeometry(loader) { const geometryLoaders = loader._geometryLoaders; const geometryLoadersLength = geometryLoaders.length; for (let i = 0; i < geometryLoadersLength; ++i) { - ResourceCache.unload(geometryLoaders[i]); + geometryLoaders[i] = + !geometryLoaders[i].isDestroyed() && + ResourceCache.unload(geometryLoaders[i]); } loader._geometryLoaders.length = 0; } @@ -2693,7 +2709,10 @@ function unloadGeneratedAttributes(loader) { } function unloadStructuralMetadata(loader) { - if (defined(loader._structuralMetadataLoader)) { + if ( + defined(loader._structuralMetadataLoader) && + !loader._structuralMetadataLoader.isDestroyed() + ) { loader._structuralMetadataLoader.destroy(); loader._structuralMetadataLoader = undefined; } diff --git a/packages/engine/Source/Scene/GltfTextureLoader.js b/packages/engine/Source/Scene/GltfTextureLoader.js index f97d1ec2f27..277c077bb42 100644 --- a/packages/engine/Source/Scene/GltfTextureLoader.js +++ b/packages/engine/Source/Scene/GltfTextureLoader.js @@ -369,7 +369,7 @@ GltfTextureLoader.prototype.unload = function () { this._texture.destroy(); } - if (defined(this._imageLoader)) { + if (defined(this._imageLoader) && !this._imageLoader.isDestroyed()) { this._resourceCache.unload(this._imageLoader); } diff --git a/packages/engine/Source/Scene/GltfVertexBufferLoader.js b/packages/engine/Source/Scene/GltfVertexBufferLoader.js index 9835fa6c317..52cc5e5dc4a 100644 --- a/packages/engine/Source/Scene/GltfVertexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfVertexBufferLoader.js @@ -452,7 +452,10 @@ GltfVertexBufferLoader.prototype.unload = function () { const resourceCache = this._resourceCache; - if (defined(this._bufferViewLoader)) { + if ( + defined(this._bufferViewLoader) && + !this._bufferViewLoader.isDestroyed() + ) { resourceCache.unload(this._bufferViewLoader); } diff --git a/packages/engine/Source/Scene/Implicit3DTileContent.js b/packages/engine/Source/Scene/Implicit3DTileContent.js index fc6bef81a2f..8f93e9dc5de 100644 --- a/packages/engine/Source/Scene/Implicit3DTileContent.js +++ b/packages/engine/Source/Scene/Implicit3DTileContent.js @@ -26,6 +26,7 @@ import parseBoundingVolumeSemantics from "./parseBoundingVolumeSemantics.js"; * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> + * This object is normally not instantiated directly, use {@link Implicit3DTileContent.fromSubtreeJson}. * * @alias Implicit3DTileContent * @constructor @@ -42,20 +43,10 @@ import parseBoundingVolumeSemantics from "./parseBoundingVolumeSemantics.js"; * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ -function Implicit3DTileContent( - tileset, - tile, - resource, - json, - arrayBuffer, - byteOffset -) { +function Implicit3DTileContent(tileset, tile, resource) { //>>includeStart('debug', pragmas.debug); Check.defined("tile.implicitTileset", tile.implicitTileset); Check.defined("tile.implicitCoordinates", tile.implicitCoordinates); - if (defined(json) === defined(arrayBuffer)) { - throw new DeveloperError("One of json and arrayBuffer must be defined."); - } //>>includeEnd('debug'); const implicitTileset = tile.implicitTileset; @@ -81,7 +72,7 @@ function Implicit3DTileContent( ); this._url = subtreeResource.getUrlComponent(true); - this._readyPromise = initialize(this, json, arrayBuffer, byteOffset); + this._ready = false; } Object.defineProperties(Implicit3DTileContent.prototype, { @@ -127,9 +118,9 @@ Object.defineProperties(Implicit3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -188,33 +179,58 @@ Object.defineProperties(Implicit3DTileContent.prototype, { * Initialize the implicit content by parsing the subtree resource and setting * up a promise chain to expand the immediate subtree. * - * @param {Implicit3DTileContent} content The implicit content + * @param {Cesium3DTileset} tileset The tileset this content belongs to + * @param {Cesium3DTile} tile The tile this content belongs to. + * @param {Resource} resource The resource for the tileset * @param {object} [json] The JSON containing the subtree. Mutually exclusive with arrayBuffer. * @param {ArrayBuffer} [arrayBuffer] The ArrayBuffer containing a subtree binary. Mutually exclusive with json. * @param {number} [byteOffset=0] The byte offset into the arrayBuffer + * @return {Promise<Implicit3DTileContent>} + * + * @exception {DeveloperError} One of json and arrayBuffer must be defined. + * * @private */ -function initialize(content, json, arrayBuffer, byteOffset) { +Implicit3DTileContent.fromSubtreeJson = async function ( + tileset, + tile, + resource, + json, + arrayBuffer, + byteOffset +) { + //>>includeStart('debug', pragmas.debug); + Check.defined("tile.implicitTileset", tile.implicitTileset); + Check.defined("tile.implicitCoordinates", tile.implicitCoordinates); + if (defined(json) === defined(arrayBuffer)) { + throw new DeveloperError("One of json and arrayBuffer must be defined."); + } + //>>includeEnd('debug'); + byteOffset = defaultValue(byteOffset, 0); let uint8Array; if (defined(arrayBuffer)) { uint8Array = new Uint8Array(arrayBuffer, byteOffset); } - const subtree = new ImplicitSubtree( - content._resource, + const implicitTileset = tile.implicitTileset; + const implicitCoordinates = tile.implicitCoordinates; + + const subtree = await ImplicitSubtree.fromSubtreeJson( + resource, json, uint8Array, - content._implicitTileset, - content._implicitCoordinates + implicitTileset, + implicitCoordinates ); + const content = new Implicit3DTileContent(tileset, tile, resource); + content._implicitSubtree = subtree; - return subtree.readyPromise.then(function () { - expandSubtree(content, subtree); - return content; - }); -} + expandSubtree(content, subtree); + content._ready = true; + return content; +}; /** * Expand a single subtree placeholder tile. This transcodes the subtree into diff --git a/packages/engine/Source/Scene/ImplicitSubtree.js b/packages/engine/Source/Scene/ImplicitSubtree.js index ea8060f1673..97133ffa17d 100644 --- a/packages/engine/Source/Scene/ImplicitSubtree.js +++ b/packages/engine/Source/Scene/ImplicitSubtree.js @@ -22,34 +22,24 @@ import ResourceCache from "./ResourceCache.js"; * Subtrees also handle content metadata and metadata about the subtree itself. * </p> * + * This object is normally not instantiated directly, use {@link ImplicitSubtree.fromSubtreeJson}. + * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata#implicit-tile-properties|Implicit Tile Properties in the 3DTILES_metadata specification} + * @see ImplicitSubtree.fromSubtreeJson * * @alias ImplicitSubtree * @constructor * * @param {Resource} resource The resource for this subtree. This is used for fetching external buffers as needed. - * @param {object} [json] The JSON object for this subtree. Mutually exclusive with subtreeView. - * @param {Uint8Array} [subtreeView] The contents of a subtree binary in a Uint8Array. Mutually exclusive with json. * @param {ImplicitTileset} implicitTileset The implicit tileset. This includes information about the size of subtrees * @param {ImplicitTileCoordinates} implicitCoordinates The coordinates of the subtree's root tile. * - * @exception {DeveloperError} One of json and subtreeView must be defined. - * * @private * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy. */ -function ImplicitSubtree( - resource, - json, - subtreeView, - implicitTileset, - implicitCoordinates -) { +function ImplicitSubtree(resource, implicitTileset, implicitCoordinates) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("resource", resource); - if (defined(json) === defined(subtreeView)) { - throw new DeveloperError("One of json and subtreeView must be defined."); - } Check.typeOf.object("implicitTileset", implicitTileset); Check.typeOf.object("implicitCoordinates", implicitCoordinates); //>>includeEnd('debug'); @@ -77,21 +67,21 @@ function ImplicitSubtree( this._tileJumpBuffer = undefined; this._contentJumpBuffers = []; - this._readyPromise = initialize(this, json, subtreeView, implicitTileset); + this._ready = false; } Object.defineProperties(ImplicitSubtree.prototype, { /** - * A promise that resolves once all necessary availability buffers + * Returns true once all necessary availability buffers * are loaded. * - * @type {Promise} + * @type {boolean} * @readonly * @private */ - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -309,16 +299,40 @@ ImplicitSubtree.prototype.getParentMortonIndex = function (mortonIndex) { /** * Parse all relevant information out of the subtree. This fetches any - * external buffers that are used by the implicit tileset. When finished, - * it resolves/rejects subtree.readyPromise. + * external buffers that are used by the implicit tileset. * - * @param {ImplicitSubtree} subtree The subtree + * @param {Resource} resource The resource for this subtree. This is used for fetching external buffers as needed. * @param {object} [json] The JSON object for this subtree. If parsing from a binary subtree file, this will be undefined. * @param {Uint8Array} [subtreeView] The contents of the subtree binary * @param {ImplicitTileset} implicitTileset The implicit tileset this subtree belongs to. + * @param {ImplicitTileCoordinates} implicitCoordinates The coordinates of the subtree's root tile. + * @return {Promise<ImplicitSubtree>} The created subtree * @private + * + * @exception {DeveloperError} One of json and subtreeView must be defined. */ -function initialize(subtree, json, subtreeView, implicitTileset) { +ImplicitSubtree.fromSubtreeJson = async function ( + resource, + json, + subtreeView, + implicitTileset, + implicitCoordinates +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("resource", resource); + if (defined(json) === defined(subtreeView)) { + throw new DeveloperError("One of json and subtreeView must be defined."); + } + Check.typeOf.object("implicitTileset", implicitTileset); + Check.typeOf.object("implicitCoordinates", implicitCoordinates); + //>>includeEnd('debug'); + + const subtree = new ImplicitSubtree( + resource, + implicitTileset, + implicitCoordinates + ); + let chunks; if (defined(json)) { chunks = { @@ -409,26 +423,25 @@ function initialize(subtree, json, subtreeView, implicitTileset) { markActiveMetadataBufferViews(contentPropertyTableJson, bufferViewHeaders); } - return requestActiveBuffers(subtree, bufferHeaders, chunks.binary).then( - function (buffersU8) { - const bufferViewsU8 = parseActiveBufferViews( - bufferViewHeaders, - buffersU8 - ); - parseAvailability(subtree, subtreeJson, implicitTileset, bufferViewsU8); + const buffersU8 = await requestActiveBuffers( + subtree, + bufferHeaders, + chunks.binary + ); + const bufferViewsU8 = parseActiveBufferViews(bufferViewHeaders, buffersU8); + parseAvailability(subtree, subtreeJson, implicitTileset, bufferViewsU8); - if (defined(tilePropertyTableJson)) { - parseTileMetadataTable(subtree, implicitTileset, bufferViewsU8); - makeTileJumpBuffer(subtree); - } + if (defined(tilePropertyTableJson)) { + parseTileMetadataTable(subtree, implicitTileset, bufferViewsU8); + makeTileJumpBuffer(subtree); + } - parseContentMetadataTables(subtree, implicitTileset, bufferViewsU8); - makeContentJumpBuffers(subtree); + parseContentMetadataTables(subtree, implicitTileset, bufferViewsU8); + makeContentJumpBuffers(subtree); - return subtree; - } - ); -} + subtree._ready = true; + return subtree; +}; /** * A helper object for storing the two parts of the subtree binary @@ -708,7 +721,7 @@ function requestActiveBuffers(subtree, bufferHeaders, internalBuffer) { }); } -function requestExternalBuffer(subtree, bufferHeader) { +async function requestExternalBuffer(subtree, bufferHeader) { const baseResource = subtree._resource; const bufferResource = baseResource.getDerivedResource({ url: bufferHeader.uri, @@ -719,9 +732,17 @@ function requestExternalBuffer(subtree, bufferHeader) { }); subtree._bufferLoader = bufferLoader; - return bufferLoader.load().then(function (bufferLoader) { - return bufferLoader.typedArray; - }); + try { + await bufferLoader.load(); + } catch (error) { + if (bufferLoader.isDestroyed()) { + return; + } + + throw error; + } + + return bufferLoader.typedArray; } /** diff --git a/packages/engine/Source/Scene/Model/B3dmLoader.js b/packages/engine/Source/Scene/Model/B3dmLoader.js index ebdb1bbf711..7385f18a690 100644 --- a/packages/engine/Source/Scene/Model/B3dmLoader.js +++ b/packages/engine/Source/Scene/Model/B3dmLoader.js @@ -129,34 +129,17 @@ if (defined(Object.create)) { Object.defineProperties(B3dmLoader.prototype, { /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. + * true if textures are loaded, useful when incrementallyLoadTextures is true * * @memberof B3dmLoader.prototype * - * @type {Promise<B3dmLoader>|undefined} + * @type {boolean} * @readonly * @private */ - promise: { + texturesLoaded: { get: function () { - return this._promise; - }, - }, - - /** - * A promise that resolves when all textures are loaded. - * When <code>incrementallyLoadTextures</code> is true this may resolve after - * <code>promise</code> resolves. - * - * @memberof B3dmLoader.prototype - * - * @type {Promise} - * @readonly - * @private - */ - texturesLoadedPromise: { - get: function () { - return this._gltfLoader.texturesLoadedPromise; + return this._gltfLoader?.texturesLoaded; }, }, /** @@ -196,6 +179,10 @@ Object.defineProperties(B3dmLoader.prototype, { * @private */ B3dmLoader.prototype.load = function () { + if (defined(this._promise)) { + return this._promise; + } + const b3dm = B3dmParser.parse(this._arrayBuffer, this._byteOffset); let batchLength = b3dm.batchLength; @@ -246,37 +233,21 @@ B3dmLoader.prototype.load = function () { this._state = B3dmLoaderState.LOADING; const that = this; - gltfLoader.load(); - this._promise = gltfLoader.promise + this._promise = gltfLoader + .load() .then(function () { if (that.isDestroyed()) { return; } - const components = gltfLoader.components; - - // Combine the RTC_CENTER transform from the b3dm and the CESIUM_RTC - // transform from the glTF. In practice usually only one or the - // other is supplied. If they don't exist the transforms will - // be identity matrices. - components.transform = Matrix4.multiplyTransformation( - that._transform, - components.transform, - components.transform - ); - createStructuralMetadata(that, components); - that._components = components; - - // Now that we have the parsed components, we can release the array buffer - that._arrayBuffer = undefined; - - that._state = B3dmLoaderState.READY; + that._state = B3dmLoaderState.PROCESSING; return that; }) .catch(function (error) { if (that.isDestroyed()) { return; } + return handleError(that, error); }); @@ -296,13 +267,38 @@ B3dmLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - if (this._state === B3dmLoaderState.LOADING) { - this._state = B3dmLoaderState.PROCESSING; + if (this._state === B3dmLoaderState.READY) { + return true; + } + + if (this._state !== B3dmLoaderState.PROCESSING) { + return false; } - if (this._state === B3dmLoaderState.PROCESSING) { - this._gltfLoader.process(frameState); + const ready = this._gltfLoader.process(frameState); + if (!ready) { + return false; } + + const components = this._gltfLoader.components; + + // Combine the RTC_CENTER transform from the b3dm and the CESIUM_RTC + // transform from the glTF. In practice usually only one or the + // other is supplied. If they don't exist the transforms will + // be identity matrices. + components.transform = Matrix4.multiplyTransformation( + this._transform, + components.transform, + components.transform + ); + createStructuralMetadata(this, components); + this._components = components; + + // Now that we have the parsed components, we can release the array buffer + this._arrayBuffer = undefined; + + this._state = B3dmLoaderState.READY; + return true; }; function createStructuralMetadata(loader, components) { @@ -368,7 +364,7 @@ function processNode(node) { } B3dmLoader.prototype.unload = function () { - if (defined(this._gltfLoader)) { + if (defined(this._gltfLoader) && !this._gltfLoader.isDestroyed()) { this._gltfLoader.unload(); } diff --git a/packages/engine/Source/Scene/Model/GeoJsonLoader.js b/packages/engine/Source/Scene/Model/GeoJsonLoader.js index 239edbb679c..5bc67d5ec9c 100644 --- a/packages/engine/Source/Scene/Model/GeoJsonLoader.js +++ b/packages/engine/Source/Scene/Model/GeoJsonLoader.js @@ -48,8 +48,6 @@ function GeoJsonLoader(options) { //>>includeEnd('debug'); this._geoJson = options.geoJson; - this._promise = undefined; - this._process = function (loader, frameState) {}; this._components = undefined; } @@ -59,20 +57,6 @@ if (defined(Object.create)) { } Object.defineProperties(GeoJsonLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource has not yet started loading. - * - * @memberof GeoJsonLoader.prototype - * - * @type {Promise<GeoJsonLoader>|Undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource. * @@ -109,21 +93,7 @@ Object.defineProperties(GeoJsonLoader.prototype, { * @private */ GeoJsonLoader.prototype.load = function () { - const loader = this; - const promise = new Promise(function (resolve) { - loader._process = function (loader, frameState) { - if (defined(loader._components)) { - return; - } - - loader._components = parse(loader._geoJson, frameState); - loader._geoJson = undefined; - resolve(loader); - }; - }); - - this._promise = promise; - return promise; + return Promise.resolve(this); }; /** @@ -137,7 +107,13 @@ GeoJsonLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - this._process(this, frameState); + if (defined(this._components)) { + return true; + } + + this._components = parse(this._geoJson, frameState); + this._geoJson = undefined; + return true; }; function ParsedFeature() { diff --git a/packages/engine/Source/Scene/Model/I3dmLoader.js b/packages/engine/Source/Scene/Model/I3dmLoader.js index 0bb74d09981..ceffc90f272 100644 --- a/packages/engine/Source/Scene/Model/I3dmLoader.js +++ b/packages/engine/Source/Scene/Model/I3dmLoader.js @@ -116,9 +116,6 @@ function I3dmLoader(options) { this._promise = undefined; this._gltfLoader = undefined; - this._gltfLoaderPromise = undefined; - this._process = function (loader, frameState) {}; - this._postProcess = function (loader, frameState) {}; // Instanced attributes are initially parsed as typed arrays, but if they // do not need to be further processed (e.g. turned into transform matrices), @@ -140,34 +137,17 @@ if (defined(Object.create)) { Object.defineProperties(I3dmLoader.prototype, { /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. + * true if textures are loaded, useful when incrementallyLoadTextures is true * - * @memberof I3dmLoader.prototype - * - * @type {Promise<I3dmLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, - - /** - * A promise that resolves when all textures are loaded. - * When <code>incrementallyLoadTextures</code> is true this may resolve after - * <code>promise</code> resolves. + * @memberof I3dmLoader.prototype * - * @memberof I3dmLoader.prototype - * - * @type {Promise} + * @type {boolean} * @readonly * @private */ - texturesLoadedPromise: { + texturesLoaded: { get: function () { - return this._gltfLoader.texturesLoadedPromise; + return this._gltfLoader?.texturesLoaded; }, }, /** @@ -208,6 +188,10 @@ Object.defineProperties(I3dmLoader.prototype, { * @private */ I3dmLoader.prototype.load = function () { + if (defined(this._promise)) { + return this._promise; + } + // Parse the i3dm into its various sections. const i3dm = I3dmParser.parse(this._arrayBuffer, this._byteOffset); @@ -282,53 +266,21 @@ I3dmLoader.prototype.load = function () { this._gltfLoader = gltfLoader; this._state = I3dmLoaderState.LOADING; - gltfLoader.load(); - - const that = this; - const processPromise = new Promise(function (resolve) { - that._process = function (loader, frameState) { - loader._gltfLoader.process(frameState); - }; - - that._postProcess = function (loader, frameState) { - const gltfLoader = loader._gltfLoader; - const components = gltfLoader.components; - - // Combine the RTC_CENTER transform from the i3dm and the CESIUM_RTC - // transform from the glTF. In practice CESIUM_RTC is not set for - // instanced models but multiply the transforms just in case. - components.transform = Matrix4.multiplyTransformation( - loader._transform, - components.transform, - components.transform - ); - - createInstances(loader, components, frameState); - createStructuralMetadata(loader, components); - loader._components = components; - - // Now that we have the parsed components, we can release the array buffer - loader._arrayBuffer = undefined; - - loader._state = I3dmLoaderState.READY; - resolve(loader); - }; - }); - - this._promise = gltfLoader.promise - .then(function () { - if (that.isDestroyed()) { + this._promise = gltfLoader + .load() + .then(() => { + if (this.isDestroyed()) { return; } - that._state = I3dmLoaderState.POST_PROCESSING; - return processPromise; + this._state = I3dmLoaderState.PROCESSING; + return this; }) - .catch(function (error) { - if (that.isDestroyed()) { + .catch((error) => { + if (this.isDestroyed()) { return; } - return handleError(that, error); + throw handleError(this, error); }); return this._promise; @@ -338,8 +290,7 @@ function handleError(i3dmLoader, error) { i3dmLoader.unload(); i3dmLoader._state = I3dmLoaderState.FAILED; const errorMessage = "Failed to load i3dm"; - error = i3dmLoader.getError(errorMessage, error); - return Promise.reject(error); + return i3dmLoader.getError(errorMessage, error); } I3dmLoader.prototype.process = function (frameState) { @@ -347,17 +298,40 @@ I3dmLoader.prototype.process = function (frameState) { Check.typeOf.object("frameState", frameState); //>>includeEnd('debug'); - if (this._state === I3dmLoaderState.LOADING) { - this._state = I3dmLoaderState.PROCESSING; + if (this._state === I3dmLoaderState.READY) { + return true; } + const gltfLoader = this._gltfLoader; + let ready = false; if (this._state === I3dmLoaderState.PROCESSING) { - this._process(this, frameState); + ready = gltfLoader.process(frameState); } - if (this._state === I3dmLoaderState.POST_PROCESSING) { - this._postProcess(this, frameState); + if (!ready) { + return false; } + + const components = gltfLoader.components; + + // Combine the RTC_CENTER transform from the i3dm and the CESIUM_RTC + // transform from the glTF. In practice CESIUM_RTC is not set for + // instanced models but multiply the transforms just in case. + components.transform = Matrix4.multiplyTransformation( + this._transform, + components.transform, + components.transform + ); + + createInstances(this, components, frameState); + createStructuralMetadata(this, components); + this._components = components; + + // Now that we have the parsed components, we can release the array buffer + this._arrayBuffer = undefined; + + this._state = I3dmLoaderState.READY; + return true; }; function createStructuralMetadata(loader, components) { @@ -895,7 +869,7 @@ I3dmLoader.prototype.isUnloaded = function () { }; I3dmLoader.prototype.unload = function () { - if (defined(this._gltfLoader)) { + if (defined(this._gltfLoader) && !this._gltfLoader.isDestroyed()) { this._gltfLoader.unload(); } diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 2dbbfd09432..d7fbad7f790 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -534,7 +534,7 @@ function handleError(model, error) { return; } - console.error(error); + console.log(error); } function createModelFeatureTables(model, structuralMetadata) { @@ -679,6 +679,21 @@ Object.defineProperties(Model.prototype, { }, }, + /** + * Returns true if textures are loaded separately from the other glTF resources. + * + * @memberof GltfLoader.prototype + * + * @type {boolean} + * @readonly + * @private + */ + incrementallyLoadTextures: { + get: function () { + return defaultValue(this._loader.incrementallyLoadTextures, false); + }, + }, + /** * Gets an event that, if {@link Model.incrementallyLoadTextures} is true, is raised when the model textures are loaded and ready for rendering, i.e. when the external resources * have been downloaded and the WebGL resources are created. Event listeners @@ -711,7 +726,7 @@ Object.defineProperties(Model.prototype, { get: function () { deprecationWarning( "Model.readyPromise", - "Model.readyPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync and Model.readyEvent instead." + "Model.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync and Model.readyEvent instead." ); return this._readyPromise; }, @@ -734,7 +749,7 @@ Object.defineProperties(Model.prototype, { get: function () { deprecationWarning( "Model.texturesLoadedPromise", - "Model.texturesLoadedPromise was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync and Model.texturesReadyEvent instead." + "Model.texturesLoadedPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync and Model.texturesReadyEvent instead." ); return this._texturesLoadedPromise; }, @@ -1925,8 +1940,11 @@ Model.prototype.update = function (frameState) { return; } - if (this._loader.incrementallyLoadTextures && !this._texturesLoaded) { - // TODO: Check if textures are actually ready + if ( + this._loader.incrementallyLoadTextures && + !this._texturesLoaded && + this._loader.texturesLoaded + ) { // Re-run the pipeline so texture memory statistics are re-computed this.resetDrawCommands(); @@ -2763,7 +2781,7 @@ Model.prototype.destroyModelResources = function () { Model.fromGltf = function (options) { deprecationWarning( "Model.fromGltf", - "Model.fromGltf was deprecated in CesiumJS 1.102. It will be removed in 1.104. Use Model.fromGltfAsync instead." + "Model.fromGltf was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync instead." ); options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -2995,7 +3013,7 @@ Model.fromGltfAsync = async function (options) { /* * @private */ -Model.fromB3dm = function (options) { +Model.fromB3dm = async function (options) { const loaderOptions = { b3dmResource: options.resource, arrayBuffer: options.arrayBuffer, @@ -3013,15 +3031,22 @@ Model.fromB3dm = function (options) { const loader = new B3dmLoader(loaderOptions); - const modelOptions = makeModelOptions(loader, ModelType.TILE_B3DM, options); - const model = new Model(modelOptions); - return model; + try { + await loader.load(); + + const modelOptions = makeModelOptions(loader, ModelType.TILE_B3DM, options); + const model = new Model(modelOptions); + return model; + } catch (error) { + loader.destroy(); + throw error; + } }; /** * @private */ -Model.fromPnts = function (options) { +Model.fromPnts = async function (options) { const loaderOptions = { arrayBuffer: options.arrayBuffer, byteOffset: options.byteOffset, @@ -3029,15 +3054,21 @@ Model.fromPnts = function (options) { }; const loader = new PntsLoader(loaderOptions); - const modelOptions = makeModelOptions(loader, ModelType.TILE_PNTS, options); - const model = new Model(modelOptions); - return model; + try { + await loader.load(); + const modelOptions = makeModelOptions(loader, ModelType.TILE_PNTS, options); + const model = new Model(modelOptions); + return model; + } catch (error) { + loader.destroy(); + throw error; + } }; /* * @private */ -Model.fromI3dm = function (options) { +Model.fromI3dm = async function (options) { const loaderOptions = { i3dmResource: options.resource, arrayBuffer: options.arrayBuffer, @@ -3053,15 +3084,22 @@ Model.fromI3dm = function (options) { }; const loader = new I3dmLoader(loaderOptions); - const modelOptions = makeModelOptions(loader, ModelType.TILE_I3DM, options); - const model = new Model(modelOptions); - return model; + try { + await loader.load(); + + const modelOptions = makeModelOptions(loader, ModelType.TILE_I3DM, options); + const model = new Model(modelOptions); + return model; + } catch (error) { + loader.destroy(); + throw error; + } }; /* * @private */ -Model.fromGeoJson = function (options) { +Model.fromGeoJson = async function (options) { const loaderOptions = { geoJson: options.geoJson, }; diff --git a/packages/engine/Source/Scene/Model/Model3DTileContent.js b/packages/engine/Source/Scene/Model/Model3DTileContent.js index 51744b06bf2..52c51879f4b 100644 --- a/packages/engine/Source/Scene/Model/Model3DTileContent.js +++ b/packages/engine/Source/Scene/Model/Model3DTileContent.js @@ -14,6 +14,8 @@ import Model from "./Model.js"; * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> + * This object is normally not instantiated directly, use {@link Model3DTileContent.fromGltf}, {@link Model3DTileContent.fromB3dm}, {@link Model3DTileContent.fromI3dm}, {@link Model3DTileContent.fromPnts}, or {@link Model3DTileContent.fromGeoJson}. + * * @alias Model3DTileContent * @constructor * @private @@ -24,9 +26,9 @@ function Model3DTileContent(tileset, tile, resource) { this._resource = resource; this._model = undefined; - this._readyPromise = undefined; this._metadata = undefined; this._group = undefined; + this._ready = false; } Object.defineProperties(Model3DTileContent.prototype, { @@ -83,9 +85,9 @@ Object.defineProperties(Model3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -244,6 +246,15 @@ Model3DTileContent.prototype.update = function (tileset, frameState) { } model.update(frameState); + + if (!this._ready && model.ready) { + // Animation can only be added once the model is ready + model.activeAnimations.addAll({ + loop: ModelAnimationLoop.REPEAT, + }); + + this._ready = true; + } }; Model3DTileContent.prototype.isDestroyed = function () { @@ -255,7 +266,7 @@ Model3DTileContent.prototype.destroy = function () { return destroyObject(this); }; -Model3DTileContent.fromGltf = function (tileset, tile, resource, gltf) { +Model3DTileContent.fromGltf = async function (tileset, tile, resource, gltf) { const content = new Model3DTileContent(tileset, tile, resource); const additionalOptions = { @@ -276,21 +287,13 @@ Model3DTileContent.fromGltf = function (tileset, tile, resource, gltf) { modelOptions.classificationType = classificationType; - // This should be removed when readyPromise is deprecated across 3D Tiles functions - const model = Model.fromGltf(modelOptions); + const model = await Model.fromGltfAsync(modelOptions); content._model = model; - // Include the animation setup in the ready promise to avoid an uncaught exception - content._readyPromise = model.readyPromise.then(function (model) { - model.activeAnimations.addAll({ - loop: ModelAnimationLoop.REPEAT, - }); - return model; - }); return content; }; -Model3DTileContent.fromB3dm = function ( +Model3DTileContent.fromB3dm = async function ( tileset, tile, resource, @@ -318,15 +321,13 @@ Model3DTileContent.fromB3dm = function ( modelOptions.classificationType = classificationType; - const model = Model.fromB3dm(modelOptions); + const model = await Model.fromB3dm(modelOptions); content._model = model; - // This should be removed when readyPromise is deprecated across 3D Tiles functions - content._readyPromise = model._readyPromise; return content; }; -Model3DTileContent.fromI3dm = function ( +Model3DTileContent.fromI3dm = async function ( tileset, tile, resource, @@ -348,15 +349,13 @@ Model3DTileContent.fromI3dm = function ( additionalOptions ); - const model = Model.fromI3dm(modelOptions); + const model = await Model.fromI3dm(modelOptions); content._model = model; - // This should be removed when readyPromise is deprecated across 3D Tiles functions - content._readyPromise = model._readyPromise; return content; }; -Model3DTileContent.fromPnts = function ( +Model3DTileContent.fromPnts = async function ( tileset, tile, resource, @@ -377,15 +376,18 @@ Model3DTileContent.fromPnts = function ( content, additionalOptions ); - const model = Model.fromPnts(modelOptions); + const model = await Model.fromPnts(modelOptions); content._model = model; - // This should be removed when readyPromise is deprecated across 3D Tiles functions - content._readyPromise = model._readyPromise; return content; }; -Model3DTileContent.fromGeoJson = function (tileset, tile, resource, geoJson) { +Model3DTileContent.fromGeoJson = async function ( + tileset, + tile, + resource, + geoJson +) { const content = new Model3DTileContent(tileset, tile, resource); const additionalOptions = { @@ -399,10 +401,8 @@ Model3DTileContent.fromGeoJson = function (tileset, tile, resource, geoJson) { content, additionalOptions ); - const model = Model.fromGeoJson(modelOptions); + const model = await Model.fromGeoJson(modelOptions); content._model = model; - // This should be removed when readyPromise is deprecated across 3D Tiles functions - content._readyPromise = model._readyPromise; return content; }; diff --git a/packages/engine/Source/Scene/Model/PntsLoader.js b/packages/engine/Source/Scene/Model/PntsLoader.js index ac6013e1cd7..2565dd01a42 100644 --- a/packages/engine/Source/Scene/Model/PntsLoader.js +++ b/packages/engine/Source/Scene/Model/PntsLoader.js @@ -66,7 +66,7 @@ function PntsLoader(options) { this._decodedAttributes = undefined; this._promise = undefined; - this._process = function (frameState) {}; + this._error = undefined; this._state = ResourceLoaderState.UNLOADED; this._buffers = []; @@ -81,20 +81,6 @@ if (defined(Object.create)) { } Object.defineProperties(PntsLoader.prototype, { - /** - * A promise that resolves to the resource when the resource is ready, or undefined if the resource hasn't started loading. - * - * @memberof PntsLoader.prototype - * - * @type {Promise<PntsLoader>|undefined} - * @readonly - * @private - */ - promise: { - get: function () { - return this._promise; - }, - }, /** * The cache key of the resource * @@ -148,28 +134,36 @@ Object.defineProperties(PntsLoader.prototype, { * @private */ PntsLoader.prototype.load = function () { + if (defined(this._promise)) { + return this._promise; + } + this._parsedContent = PntsParser.parse(this._arrayBuffer, this._byteOffset); this._state = ResourceLoaderState.PROCESSING; - const loader = this; - this._promise = new Promise(function (resolve, reject) { - loader._process = function (frameState) { - if (loader._state === ResourceLoaderState.PROCESSING) { - if (defined(loader._decodePromise)) { - return; - } - - const decodePromise = decodeDraco(loader, frameState.context); - if (defined(decodePromise)) { - decodePromise.then(resolve).catch(reject); - } - } - }; - }); + this._promise = Promise.resolve(this); }; PntsLoader.prototype.process = function (frameState) { - this._process(frameState); + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + if (this._state === ResourceLoaderState.READY) { + return true; + } + + if (this._state === ResourceLoaderState.PROCESSING) { + if (defined(this._decodePromise)) { + return false; + } + + this._decodePromise = decodeDraco(this, frameState.context); + } + + return false; }; function decodeDraco(loader, context) { @@ -207,7 +201,8 @@ function decodeDraco(loader, context) { loader.unload(); loader._state = ResourceLoaderState.FAILED; const errorMessage = "Failed to load Draco pnts"; - return Promise.reject(loader.getError(errorMessage, error)); + // This error will be thrown next time process is called; + loader._error = loader.getError(errorMessage, error); }); } diff --git a/packages/engine/Source/Scene/Multiple3DTileContent.js b/packages/engine/Source/Scene/Multiple3DTileContent.js index 51b20bb93a4..c5ebb7e8a81 100644 --- a/packages/engine/Source/Scene/Multiple3DTileContent.js +++ b/packages/engine/Source/Scene/Multiple3DTileContent.js @@ -54,6 +54,7 @@ function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) { const contentCount = this._innerContentHeaders.length; this._arrayFetchPromises = new Array(contentCount); this._requests = new Array(contentCount); + this._ready = false; this._innerContentResources = new Array(contentCount); this._serverKeys = new Array(contentCount); @@ -70,9 +71,6 @@ function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) { this._innerContentResources[i] = contentResource; this._serverKeys[i] = serverKey; } - - // undefined until the first time requests are scheduled - this._contentsFetchedPromise = undefined; } Object.defineProperties(Multiple3DTileContent.prototype, { @@ -213,35 +211,13 @@ Object.defineProperties(Multiple3DTileContent.prototype, { }, }, - /** - * Part of the {@link Cesium3DTileContent} interface. This behaves - * differently for <code>Multiple3DTileContent</code>: it returns - * undefined if the inner contents have not yet been created. This - * is handled specially in {@link Cesium3DTile}. - * - * @memberof Multiple3DTileContent.prototype - * - * @type {Promise<Cesium3DTileContent>|undefined} - * @readonly - * - * @private - */ - readyPromise: { + ready: { get: function () { - // The contents haven't been created yet, short-circuit. The tile - // will handle this as a special case if (!this._contentsCreated) { - return undefined; + return false; } - const readyPromises = this._contents.map(function (content) { - return content.readyPromise; - }); - - const that = this; - return Promise.all(readyPromises).then(function () { - return that; - }); + return this._ready; }, }, @@ -338,21 +314,6 @@ Object.defineProperties(Multiple3DTileContent.prototype, { }); }, }, - - /** - * A promise that resolves when all of the inner contents have been fetched. - * This promise is undefined until the first frame where all array buffer - * requests have been scheduled. - * @memberof Multiple3DTileContent.prototype - * - * @type {Promise} - * @private - */ - contentsFetchedPromise: { - get: function () { - return this._contentsFetchedPromise; - }, - }, }); function updatePendingRequests(multipleContents, deltaRequestCount) { @@ -386,7 +347,7 @@ function cancelPendingRequests(multipleContents, originalContentState) { * requests are successfully scheduled. * </p> * - * @return {number} The number of attempted requests that were unable to be scheduled. + * @return {Promise<void>|undefined} A promise that resolves when the request completes, or undefined if there is no request needed, or the request cannot be scheduled. * @private */ Multiple3DTileContent.prototype.requestInnerContents = function () { @@ -395,26 +356,26 @@ Multiple3DTileContent.prototype.requestInnerContents = function () { // if we can schedule all the requests at once. If not, no requests are // scheduled if (!canScheduleAllRequests(this._serverKeys)) { - return this._serverKeys.length; + this.tileset.statistics.numberOfAttemptedRequests += this._serverKeys.length; + return; } const contentHeaders = this._innerContentHeaders; updatePendingRequests(this, contentHeaders.length); + const originalCancelCount = this._cancelCount; for (let i = 0; i < contentHeaders.length; i++) { // The cancel count is needed to avoid a race condition where a content // is canceled multiple times. this._arrayFetchPromises[i] = requestInnerContent( this, i, - this._cancelCount, + originalCancelCount, this._tile._contentState ); } - this._contentsFetchedPromise = createInnerContents(this); - - return 0; + return createInnerContents(this); }; /** @@ -476,28 +437,39 @@ function requestInnerContent( const promise = contentResource.fetchArrayBuffer(); if (!defined(promise)) { - return Promise.resolve(undefined); + return; } return promise .then(function (arrayBuffer) { - // Short circuit if another inner content was canceled. + // Pending requests have already been canceled. if (originalCancelCount < multipleContents._cancelCount) { - return undefined; + return; + } + + if ( + contentResource.request.cancelled || + contentResource.request.state === RequestState.CANCELLED + ) { + cancelPendingRequests(multipleContents, originalContentState); + return; } updatePendingRequests(multipleContents, -1); return arrayBuffer; }) .catch(function (error) { - // Short circuit if another inner content was canceled. + // Pending requests have already been canceled. if (originalCancelCount < multipleContents._cancelCount) { - return undefined; + return; } - if (contentResource.request.state === RequestState.CANCELLED) { + if ( + contentResource.request.cancelled || + contentResource.request.state === RequestState.CANCELLED + ) { cancelPendingRequests(multipleContents, originalContentState); - return undefined; + return; } updatePendingRequests(multipleContents, -1); @@ -505,42 +477,54 @@ function requestInnerContent( }); } -function createInnerContents(multipleContents) { +async function createInnerContents(multipleContents) { const originalCancelCount = multipleContents._cancelCount; - return Promise.all(multipleContents._arrayFetchPromises).then(function ( - arrayBuffers - ) { - // Short circuit if inner contents were canceled - if (originalCancelCount < multipleContents._cancelCount) { - return undefined; + const arrayBuffers = await Promise.all(multipleContents._arrayFetchPromises); + // Request have been cancelled + if (originalCancelCount < multipleContents._cancelCount) { + return; + } + + const createPromise = async (arrayBuffer, i) => { + if (!defined(arrayBuffer)) { + // Content was not fetched. The error was handled in + // the fetch promise. Return undefined to indicate partial failure. + return; } - const contents = arrayBuffers.map(function (arrayBuffer, i) { - if (!defined(arrayBuffer)) { - // Content was not fetched. The error was handled in - // the fetch promise. Return undefined to indicate partial failure. - return undefined; - } + try { + const contents = await createInnerContent( + multipleContents, + arrayBuffer, + i + ); + return contents; + } catch (error) { + handleInnerContentFailed(multipleContents, i, error); + } + }; - return createInnerContent(multipleContents, arrayBuffer, i); - }); + const promises = []; + for (let i = 0; i < arrayBuffers.length; ++i) { + const arrayBuffer = arrayBuffers[i]; + promises.push(createPromise(arrayBuffer, i)); + } - // Even if we had a partial success, mark that we finished creating - // contents - multipleContents._contentsCreated = true; - multipleContents._contents = contents.filter(defined); - }); + // Even if we had a partial success, mark that we finished creating + // contents + const contents = await Promise.all(promises); + multipleContents._contentsCreated = true; + multipleContents._contents = contents.filter(defined); + return contents; } -function createInnerContent(multipleContents, arrayBuffer, index) { +async function createInnerContent(multipleContents, arrayBuffer, index) { const preprocessed = preprocess3DTileContent(arrayBuffer); if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) { - const error = new RuntimeError( + throw new RuntimeError( "External tilesets are disallowed inside multiple contents" ); - - return handleInnerContentFailed(multipleContents, index, error); } multipleContents._disableSkipLevelOfDetail = @@ -555,16 +539,20 @@ function createInnerContent(multipleContents, arrayBuffer, index) { let content; const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType]; if (defined(preprocessed.binaryPayload)) { - content = contentFactory( - tileset, - tile, - resource, - preprocessed.binaryPayload.buffer, - 0 + content = await Promise.resolve( + contentFactory( + tileset, + tile, + resource, + preprocessed.binaryPayload.buffer, + 0 + ) ); } else { // JSON formats - content = contentFactory(tileset, tile, resource, preprocessed.jsonPayload); + content = await Promise.resolve( + contentFactory(tileset, tile, resource, preprocessed.jsonPayload) + ); } const contentHeader = multipleContents._innerContentHeaders[index]; @@ -653,9 +641,13 @@ Multiple3DTileContent.prototype.applyStyle = function (style) { Multiple3DTileContent.prototype.update = function (tileset, frameState) { const contents = this._contents; const length = contents.length; + let ready = true; for (let i = 0; i < length; ++i) { contents[i].update(tileset, frameState); + ready = ready && contents[i].ready; } + + this._ready = ready; }; Multiple3DTileContent.prototype.isDestroyed = function () { diff --git a/packages/engine/Source/Scene/ResourceCache.js b/packages/engine/Source/Scene/ResourceCache.js index 1aaaedbd05b..21d8e8c4a66 100644 --- a/packages/engine/Source/Scene/ResourceCache.js +++ b/packages/engine/Source/Scene/ResourceCache.js @@ -532,19 +532,11 @@ function hasDracoCompression(draco, semantic) { * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * @param {FrameState} options.frameState The frame state. -<<<<<<< HEAD - * @param {Object} [options.draco] The Draco extension object. - * @param {Boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. - * @param {Boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. - * @param {Boolean} [options.loadTypedArray=false] Load index buffer as a typed array. - * @returns {GltfIndexBufferLoader} The cached index buffer loader. -======= * @param {object} [options.draco] The Draco extension object. * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created. * @param {boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer. * @param {boolean} [options.loadTypedArray=false] Load index buffer as a typed array. - * @returns {GltfIndexBufferLoader} The index buffer loader. ->>>>>>> no-ready-promises + * @returns {GltfIndexBufferLoader} The cached index buffer loader. * @private */ ResourceCache.getIndexBufferLoader = function (options) { diff --git a/packages/engine/Source/Scene/ResourceCacheStatistics.js b/packages/engine/Source/Scene/ResourceCacheStatistics.js index 08aaf513dad..3492d757be1 100644 --- a/packages/engine/Source/Scene/ResourceCacheStatistics.js +++ b/packages/engine/Source/Scene/ResourceCacheStatistics.js @@ -55,7 +55,6 @@ ResourceCacheStatistics.prototype.clear = function () { * <li>If the geometry has a CPU copy of the GPU buffer, it will be added to the count</li> * </ul> * @param {GltfVertexBufferLoader|GltfIndexBufferLoader} loader The geometry buffer with resources to track - * @returns {Promise} A promise that resolves once the count is updated. * * @private */ @@ -99,7 +98,7 @@ ResourceCacheStatistics.prototype.addGeometryLoader = function (loader) { * * @private */ -ResourceCacheStatistics.prototype.addTextureLoader = async function (loader) { +ResourceCacheStatistics.prototype.addTextureLoader = function (loader) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("loader", loader); //>>includeEnd('debug'); diff --git a/packages/engine/Source/Scene/Tileset3DTileContent.js b/packages/engine/Source/Scene/Tileset3DTileContent.js index 37780112b4a..e3ea176125b 100644 --- a/packages/engine/Source/Scene/Tileset3DTileContent.js +++ b/packages/engine/Source/Scene/Tileset3DTileContent.js @@ -13,7 +13,7 @@ import destroyObject from "../Core/destroyObject.js"; * * @private */ -function Tileset3DTileContent(tileset, tile, resource, json) { +function Tileset3DTileContent(tileset, tile, resource) { this._tileset = tileset; this._tile = tile; this._resource = resource; @@ -23,7 +23,7 @@ function Tileset3DTileContent(tileset, tile, resource, json) { this._metadata = undefined; this._group = undefined; - this._readyPromise = initialize(this, json); + this._ready = false; } Object.defineProperties(Tileset3DTileContent.prototype, { @@ -69,9 +69,9 @@ Object.defineProperties(Tileset3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, @@ -118,10 +118,20 @@ Object.defineProperties(Tileset3DTileContent.prototype, { }, }); -function initialize(content, json) { +/** + * + * @param {Cesium3DTileset} tileset + * @param {Cesium3DTile} tile + * @param {Resource} resource + * @param {object} json + * @returns + */ +Tileset3DTileContent.fromJson = function (tileset, tile, resource, json) { + const content = new Tileset3DTileContent(tileset, tile, resource); content._tileset.loadTileset(content._resource, json, content._tile); - return Promise.resolve(content); -} + content._ready = true; + return content; +}; /** * Part of the {@link Cesium3DTileContent} interface. <code>Tileset3DTileContent</code> diff --git a/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js b/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js index 143b934892b..65759949297 100644 --- a/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js +++ b/packages/engine/Source/Scene/Vector3DTileClampedPolylines.js @@ -112,9 +112,8 @@ function Vector3DTileClampedPolylines(options) { this._geometryByteLength = 0; this._ready = false; - this._update = function (polylines, frameState) {}; - this._readyPromise = initialize(this); - this._verticesPromise = undefined; + this._promise = undefined; + this._error = undefined; } Object.defineProperties(Vector3DTileClampedPolylines.prototype, { @@ -147,14 +146,14 @@ Object.defineProperties(Vector3DTileClampedPolylines.prototype, { }, /** - * Gets a promise that resolves when the primitive is ready to render. + * Returns true when the primitive is ready to render. * @memberof Vector3DTileClampedPolylines.prototype - * @type {Promise} + * @type {boolean} * @readonly */ - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, }); @@ -222,51 +221,55 @@ function createVertexArray(polylines, context) { return; } - if (!defined(polylines._verticesPromise)) { - let positions = polylines._positions; - let widths = polylines._widths; - let counts = polylines._counts; - let batchIds = polylines._transferrableBatchIds; + let positions = polylines._positions; + let widths = polylines._widths; + let counts = polylines._counts; + let batchIds = polylines._transferrableBatchIds; - let packedBuffer = polylines._packedBuffer; + let packedBuffer = polylines._packedBuffer; - if (!defined(packedBuffer)) { - // Copy because they may be the views on the same buffer. - positions = polylines._positions = positions.slice(); - widths = polylines._widths = widths.slice(); - counts = polylines._counts = counts.slice(); + if (!defined(packedBuffer)) { + // Copy because they may be the views on the same buffer. + positions = polylines._positions = positions.slice(); + widths = polylines._widths = widths.slice(); + counts = polylines._counts = counts.slice(); - batchIds = polylines._transferrableBatchIds = polylines._batchIds.slice(); + batchIds = polylines._transferrableBatchIds = polylines._batchIds.slice(); - packedBuffer = polylines._packedBuffer = packBuffer(polylines); - } + packedBuffer = polylines._packedBuffer = packBuffer(polylines); + } - const transferrableObjects = [ - positions.buffer, - widths.buffer, - counts.buffer, - batchIds.buffer, - packedBuffer.buffer, - ]; - const parameters = { - positions: positions.buffer, - widths: widths.buffer, - counts: counts.buffer, - batchIds: batchIds.buffer, - packedBuffer: packedBuffer.buffer, - keepDecodedPositions: polylines._keepDecodedPositions, - }; - - const verticesPromise = (polylines._verticesPromise = createVerticesTaskProcessor.scheduleTask( - parameters, - transferrableObjects - )); - if (!defined(verticesPromise)) { - // Postponed - return; - } + const transferrableObjects = [ + positions.buffer, + widths.buffer, + counts.buffer, + batchIds.buffer, + packedBuffer.buffer, + ]; + const parameters = { + positions: positions.buffer, + widths: widths.buffer, + counts: counts.buffer, + batchIds: batchIds.buffer, + packedBuffer: packedBuffer.buffer, + keepDecodedPositions: polylines._keepDecodedPositions, + }; + + const verticesPromise = createVerticesTaskProcessor.scheduleTask( + parameters, + transferrableObjects + ); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + return verticesPromise + .then(function (result) { + if (polylines.isDestroyed()) { + return; + } - return verticesPromise.then(function (result) { if (polylines._keepDecodedPositions) { polylines._decodedPositions = new Float64Array(result.decodedPositions); polylines._decodedPositionOffsets = new Uint32Array( @@ -300,13 +303,21 @@ function createVertexArray(polylines, context) { ? new Uint16Array(result.indices) : new Uint32Array(result.indices); + finishVertexArray(polylines, context); polylines._ready = true; + }) + .catch((error) => { + if (polylines.isDestroyed()) { + return; + } + + // Throw the error next frame + polylines._error = error; }); - } } function finishVertexArray(polylines, context) { - if (polylines._ready && !defined(polylines._va)) { + if (!defined(polylines._va)) { const startEllipsoidNormals = polylines._startEllipsoidNormals; const endEllipsoidNormals = polylines._endEllipsoidNormals; const startPositionAndHeights = polylines._startPositionAndHeights; @@ -692,43 +703,22 @@ Vector3DTileClampedPolylines.prototype.applyStyle = function (style, features) { }; function initialize(polylines) { - return ApproximateTerrainHeights.initialize().then(function () { - updateMinimumMaximumHeights( - polylines, - polylines._rectangle, - polylines._ellipsoid - ); + return ApproximateTerrainHeights.initialize() + .then(function () { + updateMinimumMaximumHeights( + polylines, + polylines._rectangle, + polylines._ellipsoid + ); + }) + .catch((error) => { + if (polylines.isDestroyed()) { + return; + } - return new Promise(function (resolve, reject) { - polylines._update = function (polylines, frameState) { - const context = frameState.context; - const promise = createVertexArray(polylines, context); - createUniformMap(polylines, context); - createShaders(polylines, context); - createRenderStates(polylines); - - if (polylines._ready) { - const passes = frameState.passes; - if (passes.render || passes.pick) { - queueCommands(polylines, frameState); - } - } - - if (!defined(promise)) { - return; - } - - promise - .then(function () { - finishVertexArray(polylines, context); - resolve(polylines); - }) - .catch(function (e) { - reject(e); - }); - }; + // Throw the error next frame + polylines._error = error; }); - }); } /** @@ -737,7 +727,29 @@ function initialize(polylines) { * @param {FrameState} frameState The current frame state. */ Vector3DTileClampedPolylines.prototype.update = function (frameState) { - this._update(this, frameState); + const context = frameState.context; + if (!this._ready) { + if (!defined(this._promise)) { + this._promise = initialize(this).then(createVertexArray(this, context)); + } + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + return; + } + + createUniformMap(this, context); + createShaders(this, context); + createRenderStates(this); + + const passes = frameState.passes; + if (passes.render || passes.pick) { + queueCommands(this, frameState); + } }; /** diff --git a/packages/engine/Source/Scene/Vector3DTileContent.js b/packages/engine/Source/Scene/Vector3DTileContent.js index b2f970403bd..56d7e750b5f 100644 --- a/packages/engine/Source/Scene/Vector3DTileContent.js +++ b/packages/engine/Source/Scene/Vector3DTileContent.js @@ -25,6 +25,7 @@ import decodeVectorPolylinePositions from "../Core/decodeVectorPolylinePositions * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> + * This object is normally not instantiated directly, use {@link Vector3DTileContent.fromTile}. * * @alias Vector3DTileContent * @constructor @@ -51,6 +52,7 @@ function Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { this.featurePropertiesDirty = false; this._group = undefined; + this._ready = false; initialize(this, arrayBuffer, byteOffset); } @@ -119,24 +121,9 @@ Object.defineProperties(Vector3DTileContent.prototype, { }, }, - readyPromise: { + ready: { get: function () { - const pointsPromise = defined(this._points) - ? this._points.readyPromise - : undefined; - const polygonPromise = defined(this._polygons) - ? this._polygons.readyPromise - : undefined; - const polylinePromise = defined(this._polylines) - ? this._polylines.readyPromise - : undefined; - - const that = this; - return Promise.all([pointsPromise, polygonPromise, polylinePromise]).then( - function () { - return that; - } - ); + return this._ready; }, }, @@ -245,7 +232,7 @@ function getBatchIds(featureTableJson, featureTableBinary) { if (atLeastOneDefined && atLeastOneUndefined) { throw new RuntimeError( - "If one group of batch ids is defined, then all batch ids must be defined." + "If one group of batch ids is defined, then all batch ids must be defined" ); } @@ -311,7 +298,7 @@ function initialize(content, arrayBuffer, byteOffset) { byteOffset += sizeOfUint32; if (byteLength === 0) { - return Promise.resolve(content); + return; } const featureTableJSONByteLength = view.getUint32(byteOffset, true); @@ -636,7 +623,7 @@ function initialize(content, arrayBuffer, byteOffset) { }); } - return Promise.resolve(content); + return; } function createFeatures(content) { @@ -713,21 +700,22 @@ Vector3DTileContent.prototype.update = function (tileset, frameState) { this._polygons.classificationType = this._tileset.classificationType; this._polygons.debugWireframe = this._tileset.debugWireframe; this._polygons.update(frameState); - ready = ready && this._polygons._ready; + ready = ready && this._polygons.ready; } if (defined(this._polylines)) { this._polylines.update(frameState); - ready = ready && this._polylines._ready; + ready = ready && this._polylines.ready; } if (defined(this._points)) { this._points.update(frameState); - ready = ready && this._points._ready; + ready = ready && this._points.ready; } if (defined(this._batchTable) && ready) { if (!defined(this._features)) { createFeatures(this); } this._batchTable.update(tileset, frameState); + this._ready = true; } }; diff --git a/packages/engine/Source/Scene/Vector3DTileGeometry.js b/packages/engine/Source/Scene/Vector3DTileGeometry.js index 4e4c9be5da8..9dd4c3e7138 100644 --- a/packages/engine/Source/Scene/Vector3DTileGeometry.js +++ b/packages/engine/Source/Scene/Vector3DTileGeometry.js @@ -71,8 +71,8 @@ function Vector3DTileGeometry(options) { this._packedBuffer = undefined; this._ready = false; - this._update = function (geometries, frameState) {}; - this._readyPromise = initialize(this); + this._promise = undefined; + this._error = undefined; this._verticesPromise = undefined; @@ -136,14 +136,14 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { }, /** - * Gets a promise that resolves when the primitive is ready to render. + * Return true when the primitive is ready to render. * @memberof Vector3DTileGeometry.prototype - * @type {Promise<void>} + * @type {boolean} * @readonly */ - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, }); @@ -308,31 +308,45 @@ function createPrimitive(geometries) { return; } - return verticesPromise.then(function (result) { - const packedBuffer = new Float64Array(result.packedBuffer); - const indicesBytesPerElement = unpackBuffer(geometries, packedBuffer); + return verticesPromise + .then(function (result) { + if (geometries.isDestroyed()) { + return; + } - if (indicesBytesPerElement === 2) { - geometries._indices = new Uint16Array(result.indices); - } else { - geometries._indices = new Uint32Array(result.indices); - } + const packedBuffer = new Float64Array(result.packedBuffer); + const indicesBytesPerElement = unpackBuffer(geometries, packedBuffer); - geometries._indexOffsets = new Uint32Array(result.indexOffsets); - geometries._indexCounts = new Uint32Array(result.indexCounts); + if (indicesBytesPerElement === 2) { + geometries._indices = new Uint16Array(result.indices); + } else { + geometries._indices = new Uint32Array(result.indices); + } - geometries._positions = new Float32Array(result.positions); - geometries._vertexBatchIds = new Uint16Array(result.vertexBatchIds); + geometries._indexOffsets = new Uint32Array(result.indexOffsets); + geometries._indexCounts = new Uint32Array(result.indexCounts); - geometries._batchIds = new Uint16Array(result.batchIds); + geometries._positions = new Float32Array(result.positions); + geometries._vertexBatchIds = new Uint16Array(result.vertexBatchIds); - geometries._ready = true; - }); + geometries._batchIds = new Uint16Array(result.batchIds); + + finishPrimitive(geometries); + + geometries._ready = true; + }) + .catch((error) => { + if (geometries.isDestroyed()) { + return; + } + + this._error = error; + }); } } function finishPrimitive(geometries) { - if (geometries._ready && !defined(geometries._primitive)) { + if (!defined(geometries._primitive)) { geometries._primitive = new Vector3DTilePrimitive({ batchTable: geometries._batchTable, positions: geometries._positions, @@ -421,42 +435,30 @@ Vector3DTileGeometry.prototype.updateCommands = function (batchId, color) { this._primitive.updateCommands(batchId, color); }; -function initialize(geometries) { - return new Promise(function (resolve, reject) { - geometries._update = function (geometries, frameState) { - const promise = createPrimitive(geometries); - - if (geometries._ready) { - geometries._primitive.debugWireframe = geometries.debugWireframe; - geometries._primitive.forceRebatch = geometries.forceRebatch; - geometries._primitive.classificationType = - geometries.classificationType; - geometries._primitive.update(frameState); - } - - if (!defined(promise)) { - return; - } - - promise - .then(function () { - finishPrimitive(geometries); - resolve(geometries); - }) - .catch(function (e) { - reject(e); - }); - }; - }); -} - /** * Updates the batches and queues the commands for rendering. * * @param {FrameState} frameState The current frame state. */ Vector3DTileGeometry.prototype.update = function (frameState) { - this._update(this, frameState); + if (!this._ready) { + if (!defined(this._promise)) { + this._promise = createPrimitive(this); + } + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + return; + } + + this._primitive.debugWireframe = this.debugWireframe; + this._primitive.forceRebatch = this.forceRebatch; + this._primitive.classificationType = this.classificationType; + this._primitive.update(frameState); }; /** diff --git a/packages/engine/Source/Scene/Vector3DTilePoints.js b/packages/engine/Source/Scene/Vector3DTilePoints.js index d083bc81625..76e151edc6f 100644 --- a/packages/engine/Source/Scene/Vector3DTilePoints.js +++ b/packages/engine/Source/Scene/Vector3DTilePoints.js @@ -56,11 +56,25 @@ function Vector3DTilePoints(options) { this._packedBuffer = undefined; this._ready = false; - this._update = function (points, frameState) {}; - this._readyPromise = initialize(this); + this._promise = undefined; + this._error = undefined; } Object.defineProperties(Vector3DTilePoints.prototype, { + /** + * Returns true if the points are ready to render + * + * @memberof Vector3DTilePoints.prototype + * + * @type {boolean} + * @readonly + */ + ready: { + get: function () { + return this._ready; + }, + }, + /** * Gets the number of points. * @@ -91,18 +105,6 @@ Object.defineProperties(Vector3DTilePoints.prototype, { return billboardSize + labelSize; }, }, - - /** - * Gets a promise that resolves when the primitive is ready to render. - * @memberof Vector3DTilePoints.prototype - * @type {Promise<void>} - * @readonly - */ - readyPromise: { - get: function () { - return this._readyPromise; - }, - }, }); function packBuffer(points, ellipsoid) { @@ -132,35 +134,38 @@ const createVerticesTaskProcessor = new TaskProcessor( const scratchPosition = new Cartesian3(); function createPoints(points, ellipsoid) { - let positions; - if (!defined(points._verticesPromise)) { - positions = points._positions; - let packedBuffer = points._packedBuffer; + let positions = points._positions; + let packedBuffer = points._packedBuffer; - if (!defined(packedBuffer)) { - // Copy because they may be the views on the same buffer. - positions = points._positions = positions.slice(); - points._batchIds = points._batchIds.slice(); + if (!defined(packedBuffer)) { + // Copy because they may be the views on the same buffer. + positions = points._positions = positions.slice(); + points._batchIds = points._batchIds.slice(); - packedBuffer = points._packedBuffer = packBuffer(points, ellipsoid); - } + packedBuffer = points._packedBuffer = packBuffer(points, ellipsoid); + } - const transferrableObjects = [positions.buffer, packedBuffer.buffer]; - const parameters = { - positions: positions.buffer, - packedBuffer: packedBuffer.buffer, - }; - - const verticesPromise = (points._verticesPromise = createVerticesTaskProcessor.scheduleTask( - parameters, - transferrableObjects - )); - if (!defined(verticesPromise)) { - // Postponed - return; - } + const transferrableObjects = [positions.buffer, packedBuffer.buffer]; + const parameters = { + positions: positions.buffer, + packedBuffer: packedBuffer.buffer, + }; + + const verticesPromise = createVerticesTaskProcessor.scheduleTask( + parameters, + transferrableObjects + ); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + return verticesPromise + .then((result) => { + if (points.isDestroyed()) { + return; + } - return verticesPromise.then(function (result) { points._positions = new Float64Array(result.positions); const billboardCollection = points._billboardCollection; const labelCollection = points._labelCollection; @@ -190,8 +195,15 @@ function createPoints(points, ellipsoid) { points._positions = undefined; points._packedBuffer = undefined; points._ready = true; + }) + .catch((error) => { + if (points.isDestroyed()) { + return; + } + + // Throw the error next frame + points._error = error; }); - } } /** @@ -460,37 +472,27 @@ Vector3DTilePoints.prototype.applyStyle = function (style, features) { } }; -function initialize(points) { - return new Promise(function (resolve, reject) { - points._update = function (points, frameState) { - const promise = createPoints(points, frameState.mapProjection.ellipsoid); - - if (points._ready) { - points._polylineCollection.update(frameState); - points._billboardCollection.update(frameState); - points._labelCollection.update(frameState); - } - - if (!defined(promise)) { - return; - } - - promise - .then(function () { - resolve(); - }) - .catch(function (e) { - reject(e); - }); - }; - }); -} - /** * @private */ Vector3DTilePoints.prototype.update = function (frameState) { - this._update(this, frameState); + if (!this._ready) { + if (!defined(this._promise)) { + this._promise = createPoints(this, frameState.mapProjection.ellipsoid); + } + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + return; + } + + this._polylineCollection.update(frameState); + this._billboardCollection.update(frameState); + this._labelCollection.update(frameState); }; /** diff --git a/packages/engine/Source/Scene/Vector3DTilePolygons.js b/packages/engine/Source/Scene/Vector3DTilePolygons.js index 835ae4cd186..a5a37be0fc7 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolygons.js +++ b/packages/engine/Source/Scene/Vector3DTilePolygons.js @@ -75,10 +75,8 @@ function Vector3DTilePolygons(options) { this._batchedIndices = undefined; this._ready = false; - this._update = function (polygons, frameState) {}; - this._readyPromise = initialize(this); - this._verticesPromise = undefined; - + this._promise = undefined; + this._error = undefined; this._primitive = undefined; /** @@ -139,14 +137,14 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { }, /** - * Gets a promise that resolves when the primitive is ready to render. + * Returns true when the primitive is ready to render. * @memberof Vector3DTilePolygons.prototype - * @type {Promise<void>} + * @type {boolean} * @readonly */ - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, }); @@ -224,85 +222,89 @@ function createPrimitive(polygons) { return; } - if (!defined(polygons._verticesPromise)) { - let positions = polygons._positions; - let counts = polygons._counts; - let indexCounts = polygons._indexCounts; - let indices = polygons._indices; - - let batchIds = polygons._transferrableBatchIds; - let batchTableColors = polygons._batchTableColors; - - let packedBuffer = polygons._packedBuffer; - - if (!defined(batchTableColors)) { - // Copy because they may be the views on the same buffer. - positions = polygons._positions = polygons._positions.slice(); - counts = polygons._counts = polygons._counts.slice(); - indexCounts = polygons._indexCounts = polygons._indexCounts.slice(); - indices = polygons._indices = polygons._indices.slice(); - - polygons._center = polygons._ellipsoid.cartographicToCartesian( - Rectangle.center(polygons._rectangle) - ); - - batchIds = polygons._transferrableBatchIds = new Uint32Array( - polygons._batchIds - ); - batchTableColors = polygons._batchTableColors = new Uint32Array( - batchIds.length - ); - const batchTable = polygons._batchTable; - - const length = batchTableColors.length; - for (let i = 0; i < length; ++i) { - const color = batchTable.getColor(i, scratchColor); - batchTableColors[i] = color.toRgba(); - } - - packedBuffer = polygons._packedBuffer = packBuffer(polygons); + let positions = polygons._positions; + let counts = polygons._counts; + let indexCounts = polygons._indexCounts; + let indices = polygons._indices; + + let batchIds = polygons._transferrableBatchIds; + let batchTableColors = polygons._batchTableColors; + + let packedBuffer = polygons._packedBuffer; + + if (!defined(batchTableColors)) { + // Copy because they may be the views on the same buffer. + positions = polygons._positions = polygons._positions.slice(); + counts = polygons._counts = polygons._counts.slice(); + indexCounts = polygons._indexCounts = polygons._indexCounts.slice(); + indices = polygons._indices = polygons._indices.slice(); + + polygons._center = polygons._ellipsoid.cartographicToCartesian( + Rectangle.center(polygons._rectangle) + ); + + batchIds = polygons._transferrableBatchIds = new Uint32Array( + polygons._batchIds + ); + batchTableColors = polygons._batchTableColors = new Uint32Array( + batchIds.length + ); + const batchTable = polygons._batchTable; + + const length = batchTableColors.length; + for (let i = 0; i < length; ++i) { + const color = batchTable.getColor(i, scratchColor); + batchTableColors[i] = color.toRgba(); } - const transferrableObjects = [ - positions.buffer, - counts.buffer, - indexCounts.buffer, - indices.buffer, - batchIds.buffer, - batchTableColors.buffer, - packedBuffer.buffer, - ]; - const parameters = { - packedBuffer: packedBuffer.buffer, - positions: positions.buffer, - counts: counts.buffer, - indexCounts: indexCounts.buffer, - indices: indices.buffer, - batchIds: batchIds.buffer, - batchTableColors: batchTableColors.buffer, - }; - - let minimumHeights = polygons._polygonMinimumHeights; - let maximumHeights = polygons._polygonMaximumHeights; - if (defined(minimumHeights) && defined(maximumHeights)) { - minimumHeights = minimumHeights.slice(); - maximumHeights = maximumHeights.slice(); - - transferrableObjects.push(minimumHeights.buffer, maximumHeights.buffer); - parameters.minimumHeights = minimumHeights; - parameters.maximumHeights = maximumHeights; - } + packedBuffer = polygons._packedBuffer = packBuffer(polygons); + } - const verticesPromise = (polygons._verticesPromise = createVerticesTaskProcessor.scheduleTask( - parameters, - transferrableObjects - )); - if (!defined(verticesPromise)) { - // Postponed - return; - } + const transferrableObjects = [ + positions.buffer, + counts.buffer, + indexCounts.buffer, + indices.buffer, + batchIds.buffer, + batchTableColors.buffer, + packedBuffer.buffer, + ]; + const parameters = { + packedBuffer: packedBuffer.buffer, + positions: positions.buffer, + counts: counts.buffer, + indexCounts: indexCounts.buffer, + indices: indices.buffer, + batchIds: batchIds.buffer, + batchTableColors: batchTableColors.buffer, + }; + + let minimumHeights = polygons._polygonMinimumHeights; + let maximumHeights = polygons._polygonMaximumHeights; + if (defined(minimumHeights) && defined(maximumHeights)) { + minimumHeights = minimumHeights.slice(); + maximumHeights = maximumHeights.slice(); + + transferrableObjects.push(minimumHeights.buffer, maximumHeights.buffer); + parameters.minimumHeights = minimumHeights; + parameters.maximumHeights = maximumHeights; + } + + const verticesPromise = createVerticesTaskProcessor.scheduleTask( + parameters, + transferrableObjects + ); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + return verticesPromise + .then((result) => { + if (polygons.isDestroyed()) { + return; + } - return verticesPromise.then(function (result) { polygons._positions = undefined; polygons._counts = undefined; polygons._polygonMinimumHeights = undefined; @@ -323,13 +325,22 @@ function createPrimitive(polygons) { polygons._batchedPositions = new Float32Array(result.positions); polygons._vertexBatchIds = new Uint16Array(result.batchIds); + finishPrimitive(polygons); + polygons._ready = true; + }) + .catch((error) => { + if (polygons.isDestroyed()) { + return; + } + + // Throw the error next frame + polygons._error = error; }); - } } function finishPrimitive(polygons) { - if (polygons._ready && !defined(polygons._primitive)) { + if (!defined(polygons._primitive)) { polygons._primitive = new Vector3DTilePrimitive({ batchTable: polygons._batchTable, positions: polygons._batchedPositions, @@ -411,41 +422,30 @@ Vector3DTilePolygons.prototype.updateCommands = function (batchId, color) { this._primitive.updateCommands(batchId, color); }; -function initialize(polygons) { - return new Promise(function (resolve, reject) { - polygons._update = function (polygons, frameState) { - const promise = createPrimitive(polygons); - - if (polygons._ready) { - polygons._primitive.debugWireframe = polygons.debugWireframe; - polygons._primitive.forceRebatch = polygons.forceRebatch; - polygons._primitive.classificationType = polygons.classificationType; - polygons._primitive.update(frameState); - } - - if (!defined(promise)) { - return; - } - - promise - .then(function () { - finishPrimitive(polygons); - resolve(polygons); - }) - .catch(function (e) { - reject(e); - }); - }; - }); -} - /** * Updates the batches and queues the commands for rendering. * * @param {FrameState} frameState The current frame state. */ Vector3DTilePolygons.prototype.update = function (frameState) { - this._update(this, frameState); + if (!this._ready) { + if (!defined(this._promise)) { + this._promise = createPrimitive(this); + } + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + return; + } + + this._primitive.debugWireframe = this.debugWireframe; + this._primitive.forceRebatch = this.forceRebatch; + this._primitive.classificationType = this.classificationType; + this._primitive.update(frameState); }; /** diff --git a/packages/engine/Source/Scene/Vector3DTilePolylines.js b/packages/engine/Source/Scene/Vector3DTilePolylines.js index e9dd0268fbc..70baacb6d69 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolylines.js +++ b/packages/engine/Source/Scene/Vector3DTilePolylines.js @@ -87,10 +87,8 @@ function Vector3DTilePolylines(options) { this._geometryByteLength = 0; this._ready = false; - this._update = function (polylines, frameState) {}; - this._readyPromise = initialize(this); - - this._verticesPromise = undefined; + this._promise = undefined; + this._error = undefined; } Object.defineProperties(Vector3DTilePolylines.prototype, { @@ -123,14 +121,14 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { }, /** - * Gets a promise that resolves when the primitive is ready to render. + * Returns true when the primitive is ready to render. * @memberof Vector3DTilePolylines.prototype - * @type {Promise<void>} + * @type {boolean} * @readonly */ - readyPromise: { + ready: { get: function () { - return this._readyPromise; + return this._ready; }, }, }); @@ -181,51 +179,55 @@ function createVertexArray(polylines, context) { return; } - if (!defined(polylines._verticesPromise)) { - let positions = polylines._positions; - let widths = polylines._widths; - let counts = polylines._counts; - let batchIds = polylines._transferrableBatchIds; + let positions = polylines._positions; + let widths = polylines._widths; + let counts = polylines._counts; + let batchIds = polylines._transferrableBatchIds; - let packedBuffer = polylines._packedBuffer; + let packedBuffer = polylines._packedBuffer; - if (!defined(packedBuffer)) { - // Copy because they may be the views on the same buffer. - positions = polylines._positions = positions.slice(); - widths = polylines._widths = widths.slice(); - counts = polylines._counts = counts.slice(); + if (!defined(packedBuffer)) { + // Copy because they may be the views on the same buffer. + positions = polylines._positions = positions.slice(); + widths = polylines._widths = widths.slice(); + counts = polylines._counts = counts.slice(); - batchIds = polylines._transferrableBatchIds = polylines._batchIds.slice(); + batchIds = polylines._transferrableBatchIds = polylines._batchIds.slice(); - packedBuffer = polylines._packedBuffer = packBuffer(polylines); - } + packedBuffer = polylines._packedBuffer = packBuffer(polylines); + } - const transferrableObjects = [ - positions.buffer, - widths.buffer, - counts.buffer, - batchIds.buffer, - packedBuffer.buffer, - ]; - const parameters = { - positions: positions.buffer, - widths: widths.buffer, - counts: counts.buffer, - batchIds: batchIds.buffer, - packedBuffer: packedBuffer.buffer, - keepDecodedPositions: polylines._keepDecodedPositions, - }; - - const verticesPromise = (polylines._verticesPromise = createVerticesTaskProcessor.scheduleTask( - parameters, - transferrableObjects - )); - if (!defined(verticesPromise)) { - // Postponed - return; - } + const transferrableObjects = [ + positions.buffer, + widths.buffer, + counts.buffer, + batchIds.buffer, + packedBuffer.buffer, + ]; + const parameters = { + positions: positions.buffer, + widths: widths.buffer, + counts: counts.buffer, + batchIds: batchIds.buffer, + packedBuffer: packedBuffer.buffer, + keepDecodedPositions: polylines._keepDecodedPositions, + }; + + const verticesPromise = createVerticesTaskProcessor.scheduleTask( + parameters, + transferrableObjects + ); + if (!defined(verticesPromise)) { + // Postponed + return; + } + + return verticesPromise + .then(function (result) { + if (polylines.isDestroyed()) { + return; + } - return verticesPromise.then(function (result) { if (polylines._keepDecodedPositions) { polylines._decodedPositions = new Float64Array(result.decodedPositions); polylines._decodedPositionOffsets = new Uint32Array( @@ -245,13 +247,22 @@ function createVertexArray(polylines, context) { ? new Uint16Array(result.indices) : new Uint32Array(result.indices); + finishVertexArray(polylines, context); + polylines._ready = true; + }) + .catch((error) => { + if (polylines.isDestroyed()) { + return; + } + + // Throw the error next frame + polylines._error = error; }); - } } function finishVertexArray(polylines, context) { - if (polylines._ready && !defined(polylines._va)) { + if (!defined(polylines._va)) { const curPositions = polylines._currentPositions; const prevPositions = polylines._previousPositions; const nextPositions = polylines._nextPositions; @@ -603,45 +614,35 @@ Vector3DTilePolylines.prototype.applyStyle = function (style, features) { } }; -function initialize(polylines) { - return new Promise(function (resolve, reject) { - polylines._update = function (polylines, frameState) { - const context = frameState.context; - const promise = createVertexArray(polylines, context); - createUniformMap(polylines, context); - createShaders(polylines, context); - createRenderStates(polylines); - - if (polylines._ready) { - const passes = frameState.passes; - if (passes.render || passes.pick) { - queueCommands(polylines, frameState); - } - } - - if (!defined(promise)) { - return; - } - - promise - .then(function () { - finishVertexArray(polylines, context); - resolve(); - }) - .catch(function (e) { - reject(e); - }); - }; - }); -} - /** * Updates the batches and queues the commands for rendering. * * @param {FrameState} frameState The current frame state. */ Vector3DTilePolylines.prototype.update = function (frameState) { - this._update(this, frameState); + const context = frameState.context; + if (!this._ready) { + if (!defined(this._promise)) { + this._promise = createVertexArray(this, context); + } + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + + return; + } + + createUniformMap(this, context); + createShaders(this, context); + createRenderStates(this); + + const passes = frameState.passes; + if (passes.render || passes.pick) { + queueCommands(this, frameState); + } }; /** diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index 3f3325dd348..afd6cef84f3 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -24,7 +24,7 @@ import { CustomShader, Globe, Cartographic, - createWorldTerrain, + createWorldTerrainAsync, } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; @@ -39,10 +39,12 @@ describe( let scene; let entityCollection; let visualizer; + let originalTerrainProvider; beforeAll(function () { scene = createScene(); scene.globe = new Globe(); + originalTerrainProvider = scene.globe.terrainProvider; }); beforeEach(function () { @@ -53,6 +55,7 @@ describe( afterEach(function () { visualizer = visualizer && visualizer.destroy(); entityCollection.removeAll(); + scene.globe.terrainProvider = originalTerrainProvider; }); afterAll(function () { @@ -193,7 +196,7 @@ describe( new Cartesian2(0.5, 0.5) ); - expect(primitive.lightColor).toEqual(new Color(1.0, 1.0, 0.0, 1.0)); + expect(primitive.lightColor).toEqual(new Cartesian3(1.0, 1.0, 0.0)); // wait till the model is loaded before we can check node transformations await pollToPromise(function () { @@ -392,6 +395,7 @@ describe( await pollToPromise(function () { scene.render(); + visualizer.update(time); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; }); @@ -403,17 +407,11 @@ describe( expect(result).toEqual(expected); }); - it("computes bounding sphere with height reference clamp to ground", function () { + it("computes bounding sphere with height reference clamp to ground", async function () { // Setup a position for the model. const position = Cartesian3.fromDegrees(149.515332, -34.984799); const positionCartographic = Cartographic.fromCartesian(position); - // Setup a spy so we can track how often sampleTerrain is called. - const sampleTerrainSpy = spyOn( - ModelVisualizer, - "_sampleTerrainMostDetailed" - ).and.callThrough(); - // Initialize the Entity and the ModelGraphics. const time = JulianDate.now(); const testObject = entityCollection.getOrCreateEntity("test"); @@ -433,49 +431,45 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; - const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = createWorldTerrain(); - - let sampledResultCartographic; - let sampledResult; - - return ModelVisualizer._sampleTerrainMostDetailed(globe.terrainProvider, [ - positionCartographic, - ]) - .then((updatedCartographics) => { - sampledResultCartographic = updatedCartographics[0]; - sampledResult = globe.ellipsoid.cartographicToCartesian( - sampledResultCartographic - ); - - // Repeatedly request the bounding sphere until it's ready. - return pollToPromise(function () { - scene.render(); - state = visualizer.getBoundingSphere(testObject, result); - return state !== BoundingSphereState.PENDING; - }); - }) - .then(() => { - expect(state).toBe(BoundingSphereState.DONE); - - // Ensure that flags and results computed for this model are reset. - const modelData = visualizer._modelHash[testObject.id]; - expect(modelData.awaitingSampleTerrain).toBe(false); - expect(modelData.clampedBoundingSphere).toBeUndefined(); - - // Ensure that we only sample the terrain once from the visualizer. - // We check for 2 calls here because we call it once in the test. - expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); - - // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. - // Since sampleTerrainMostDetailed isn't always precise, we account for some error. - const distance = Cartesian3.distance(result.center, sampledResult); - const errorMargin = 100.0; - expect(distance).toBeLessThan(errorMargin); - - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; - }); + globe.terrainProvider = await createWorldTerrainAsync(); + + const updatedCartographics = await ModelVisualizer._sampleTerrainMostDetailed( + globe.terrainProvider, + [positionCartographic] + ); + const sampledResultCartographic = updatedCartographics[0]; + const sampledResult = globe.ellipsoid.cartographicToCartesian( + sampledResultCartographic + ); + + const sampleTerrainSpy = spyOn( + ModelVisualizer, + "_sampleTerrainMostDetailed" + ).and.callThrough(); + + // Repeatedly request the bounding sphere until it's ready. + await pollToPromise(function () { + scene.render(); + visualizer.update(time); + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + + expect(state).toBe(BoundingSphereState.DONE); + + // Ensure that flags and results computed for this model are reset. + const modelData = visualizer._modelHash[testObject.id]; + expect(modelData.awaitingSampleTerrain).toBe(false); + expect(modelData.clampedBoundingSphere).toBeUndefined(); + + // Ensure that we only sample the terrain once from the visualizer. + expect(sampleTerrainSpy).toHaveBeenCalledTimes(1); + + // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. + // Since sampleTerrainMostDetailed isn't always precise, we account for some error. + const distance = Cartesian3.distance(result.center, sampledResult); + const errorMargin = 100.0; + expect(distance).toBeLessThan(errorMargin); }); it("computes bounding sphere with height reference clamp to ground on terrain provider without availability", function () { @@ -510,6 +504,7 @@ describe( // Repeatedly request the bounding sphere until it's ready. return pollToPromise(function () { scene.render(); + visualizer.update(time); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; }).then(() => { @@ -530,7 +525,7 @@ describe( }); }); - it("computes bounding sphere with height reference relative to ground", function () { + it("computes bounding sphere with height reference relative to ground", async function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -565,50 +560,41 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; - const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = createWorldTerrain(); - - let sampledResultCartographic; - let sampledResult; - - return ModelVisualizer._sampleTerrainMostDetailed(globe.terrainProvider, [ - positionCartographic, - ]) - .then((updatedCartographics) => { - sampledResultCartographic = updatedCartographics[0]; - sampledResult = globe.ellipsoid.cartographicToCartesian( - sampledResultCartographic - ); - - // Repeatedly request the bounding sphere until it's ready. - return pollToPromise(function () { - scene.render(); - state = visualizer.getBoundingSphere(testObject, result); - return state !== BoundingSphereState.PENDING; - }); - }) - .then(() => { - expect(state).toBe(BoundingSphereState.DONE); - - // Ensure that flags and results computed for this model are reset. - const modelData = visualizer._modelHash[testObject.id]; - expect(modelData.awaitingSampleTerrain).toBe(false); - expect(modelData.clampedBoundingSphere).toBeUndefined(); - - // Ensure that we only sample the terrain once from the visualizer. - // We check for 2 calls here because we call it once in the test. - expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); - - // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. - // Since sampleTerrainMostDetailed isn't always precise, we account for some error. - const distance = - Cartesian3.distance(result.center, sampledResult) - heightOffset; - const errorMargin = 100.0; - expect(distance).toBeLessThan(errorMargin); - - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; - }); + globe.terrainProvider = await createWorldTerrainAsync(); + + const updatedCartographics = await ModelVisualizer._sampleTerrainMostDetailed( + globe.terrainProvider, + [positionCartographic] + ); + const sampledResultCartographic = updatedCartographics[0]; + const sampledResult = globe.ellipsoid.cartographicToCartesian( + sampledResultCartographic + ); + + // Repeatedly request the bounding sphere until it's ready. + await pollToPromise(function () { + scene.render(); + visualizer.update(time); + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + expect(state).toBe(BoundingSphereState.DONE); + + // Ensure that flags and results computed for this model are reset. + const modelData = visualizer._modelHash[testObject.id]; + expect(modelData.awaitingSampleTerrain).toBe(false); + expect(modelData.clampedBoundingSphere).toBeUndefined(); + + // Ensure that we only sample the terrain once from the visualizer. + // We check for 2 calls here because we call it once in the test. + expect(sampleTerrainSpy).toHaveBeenCalledTimes(2); + + // Calculate the distance of the bounding sphere returned from the position returned from sample terrain. + // Since sampleTerrainMostDetailed isn't always precise, we account for some error. + const distance = + Cartesian3.distance(result.center, sampledResult) - heightOffset; + const errorMargin = 100.0; + expect(distance).toBeLessThan(errorMargin); }); it("computes bounding sphere with height reference relative to ground on terrain provider without availability", function () { @@ -643,6 +629,7 @@ describe( // Repeatedly request the bounding sphere until it's ready. return pollToPromise(function () { scene.render(); + visualizer.update(time); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; }).then(() => { @@ -669,7 +656,7 @@ describe( expect(state).toBe(BoundingSphereState.FAILED); }); - it("fails bounding sphere when model fails to load", function () { + it("fails bounding sphere when model fails to load", async function () { const time = JulianDate.now(); const testObject = entityCollection.getOrCreateEntity("test"); const model = new ModelGraphics(); @@ -683,17 +670,17 @@ describe( const result = new BoundingSphere(); let state = visualizer.getBoundingSphere(testObject, result); - expect(state).toBe(BoundingSphereState.PENDING); - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); + visualizer.update(time); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; - }).then(function () { - expect(state).toBe(BoundingSphereState.FAILED); }); + + expect(state).toBe(BoundingSphereState.FAILED); }); - it("fails bounding sphere when sampleTerrainMostDetailed fails", function () { + it("fails bounding sphere when sampleTerrainMostDetailed fails", async function () { // Setup a position for the model. const heightOffset = 1000.0; const position = Cartesian3.fromDegrees( @@ -724,8 +711,7 @@ describe( // Assign a tiled terrain provider to the globe. const globe = scene.globe; - const previousTerrainProvider = globe.terrainProvider; - globe.terrainProvider = createWorldTerrain(); + globe.terrainProvider = await createWorldTerrainAsync(); // Request the bounding sphere once. const result = new BoundingSphere(); @@ -734,6 +720,7 @@ describe( // Repeatedly request the bounding sphere until it's ready. return pollToPromise(function () { scene.render(); + visualizer.update(time); state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; }).then(() => { @@ -745,8 +732,6 @@ describe( // Ensure that we only sample the terrain once from the visualizer. expect(sampleTerrainSpy).toHaveBeenCalledTimes(1); - // Reset the terrain provider. - globe.terrainProvider = previousTerrainProvider; }); }); diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 624d3b7a2f0..10bef3ed990 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -293,7 +293,7 @@ describe( }); }); - it("loads json with static loadJson method", function () { + it("loads json with static loadJson method", async function () { const tilesetJson = { asset: { version: 2.0, @@ -301,14 +301,9 @@ describe( }; const uri = `data:text/plain;base64,${btoa(JSON.stringify(tilesetJson))}`; - - Cesium3DTileset.loadJson(uri) - .then(function (result) { - expect(result).toEqual(tilesetJson); - }) - .catch(function (error) { - fail("should not fail"); - }); + await expectAsync(Cesium3DTileset.loadJson(uri)).toBeResolvedTo( + tilesetJson + ); }); it("static method loadJson is used in Cesium3DTileset constructor", function () { @@ -329,7 +324,6 @@ describe( return tileset.readyPromise .then(function () { expect(tileset.ready).toEqual(true); - // restore original version Cesium3DTileset.loadJson = originalLoadJson; }) .catch(function (error) { @@ -597,108 +591,105 @@ describe( return tileset.readyPromise; }); - it("requests tile with invalid magic", function () { + it("requests tile with invalid magic", async function () { const invalidMagicBuffer = Cesium3DTilesTester.generateBatchedTileBuffer({ magic: [120, 120, 120, 120], }); options.url = tilesetUrl; const tileset = scene.primitives.add(new Cesium3DTileset(options)); - return tileset.readyPromise.then(function (tileset) { - // Start spying after the tileset json has been loaded - spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - deferred.resolve(invalidMagicBuffer); - }); - scene.renderForSpecs(); // Request root - const root = tileset.root; - return root.contentReadyPromise - .then(function () { - fail("should not resolve"); - }) - .catch(function (error) { - expect(error.message).toBe("Invalid tile content."); - expect(root._contentState).toEqual(Cesium3DTileContentState.FAILED); - }); + await tileset.readyPromise; + + const failedSpy = jasmine.createSpy("listenerSpy"); + tileset.tileFailed.addEventListener(failedSpy); + + // Start spying after the tileset json has been loaded + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.resolve(invalidMagicBuffer) + ); + + scene.renderForSpecs(); // Request root + const root = tileset.root; + await pollToPromise(() => { + scene.renderForSpecs(); + return root.contentFailed || root.contentReady; }); + + expect(failedSpy).toHaveBeenCalledWith( + jasmine.objectContaining({ + message: "Invalid tile content.", + }) + ); + expect(root.contentFailed).toBeTrue(); }); - it("handles failed tile requests", function () { + it("handles failed tile requests", async function () { viewRootOnly(); options.url = tilesetUrl; const tileset = scene.primitives.add(new Cesium3DTileset(options)); - return tileset.readyPromise.then(function (tileset) { - // Start spying after the tileset json has been loaded - spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - deferred.reject(new Error()); - }); - scene.renderForSpecs(); // Request root - const root = tileset.root; - return root.contentReadyPromise - .then(function () { - fail("should not resolve"); - }) - .catch(function (error) { - expect(root._contentState).toEqual(Cesium3DTileContentState.FAILED); - const statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); - }); + await tileset.readyPromise; + + const failedSpy = jasmine.createSpy("listenerSpy"); + tileset.tileFailed.addEventListener(failedSpy); + + // Start spying after the tileset json has been loaded + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => { + return Promise.reject(new Error("404")); + }); + scene.renderForSpecs(); // Request root + const root = tileset.root; + await pollToPromise(() => { + scene.renderForSpecs(); + return root.contentFailed || root.contentReady; }); + + expect(root.contentFailed).toBeTrue(); + expect(failedSpy).toHaveBeenCalledWith( + jasmine.objectContaining({ + message: "404", + }) + ); + const statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); }); - it("handles failed tile processing", function () { + it("handles failed tile processing", async function () { viewRootOnly(); options.url = tilesetUrl; const tileset = scene.primitives.add(new Cesium3DTileset(options)); - return tileset.readyPromise.then(function (tileset) { - // Start spying after the tileset json has been loaded - spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - deferred.resolve( - Cesium3DTilesTester.generateBatchedTileBuffer({ - version: 0, // Invalid version - }) - ); - }); - scene.renderForSpecs(); // Request root - const root = tileset.root; - return root.contentReadyPromise - .then(function () { - fail("should not resolve"); + await tileset.readyPromise; + + const failedSpy = jasmine.createSpy("listenerSpy"); + tileset.tileFailed.addEventListener(failedSpy); + + // Start spying after the tileset json has been loaded + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.resolve( + Cesium3DTilesTester.generateBatchedTileBuffer({ + version: 0, // Invalid version }) - .catch(function (error) { - expect(root._contentState).toEqual(Cesium3DTileContentState.FAILED); - const statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); - }); + ) + ); + scene.renderForSpecs(); // Request root + const root = tileset.root; + await pollToPromise(() => { + scene.renderForSpecs(); + return root.contentFailed || root.contentReady; }); + expect(root.contentFailed).toBeTrue(); + expect(failedSpy).toHaveBeenCalledWith( + jasmine.objectContaining({ + message: + "Only Batched 3D Model version 1 is supported. Version 0 is not.", + }) + ); + const statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); }); it("renders tileset", function () { @@ -1544,7 +1535,7 @@ describe( }); }); - it("replacement refinement - selects root when sse is not met and subtree is not refinable (3)", function () { + it("replacement refinement - selects root when sse is not met and subtree is not refinable (3)", async function () { // Check that the root is refinable once its child is loaded // // C @@ -1554,31 +1545,30 @@ describe( // viewRootOnly(); - return Cesium3DTilesTester.loadTileset( + const tileset = await Cesium3DTilesTester.loadTileset( scene, tilesetReplacement3Url - ).then(function (tileset) { - tileset.skipLevelOfDetail = false; - const statistics = tileset._statistics; - const root = tileset.root; - expect(statistics.numberOfCommands).toEqual(1); + ); + tileset.skipLevelOfDetail = false; + const statistics = tileset._statistics; + const root = tileset.root; + expect(statistics.numberOfCommands).toEqual(1); - viewAllTiles(); + viewAllTiles(); + scene.renderForSpecs(); + await pollToPromise(() => { scene.renderForSpecs(); - return root.children[0].contentReadyPromise.then(function () { - // The external tileset json is loaded, but the external tileset isn't. - scene.renderForSpecs(); - expect(statistics.numberOfCommands).toEqual(1); // root - expect(statistics.numberOfPendingRequests).toEqual(4); // Loading child content tiles - - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(isSelected(tileset, root)).toEqual(false); - expect(statistics.numberOfCommands).toEqual(4); // Render child content tiles - } - ); - }); + return root.children[0].contentFailed || root.children[0].contentReady; }); + // The external tileset json is loaded, but the external tileset isn't. + scene.renderForSpecs(); + expect(statistics.numberOfCommands).toEqual(1); // root + expect(statistics.numberOfPendingRequests).toEqual(4); // Loading child content tiles + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + + expect(isSelected(tileset, root)).toEqual(false); + expect(statistics.numberOfCommands).toEqual(4); // Render child content tiles }); it("replacement refinement - refines if descendant is empty leaf tile", function () { @@ -1906,41 +1896,44 @@ describe( }); }); - it("loads tileset with external tileset JSON file", function () { + it("loads tileset with external tileset JSON file", async function () { // Set view so that no tiles are loaded initially viewNothing(); - return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then( - function (tileset) { - // Root points to an external tileset JSON file and has no children until it is requested - const root = tileset.root; - expect(root.children.length).toEqual(0); - - // Set view so that root's content is requested - viewRootOnly(); - scene.renderForSpecs(); - return root.contentReadyPromise.then(function () { - expect(root.hasTilesetContent).toEqual(true); + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + tilesetOfTilesetsUrl + ); + // Root points to an external tileset JSON file and has no children until it is requested + const root = tileset.root; + expect(root.children.length).toEqual(0); - // Root has one child now, the root of the external tileset - expect(root.children.length).toEqual(1); + // Set view so that root's content is requested + viewRootOnly(); + scene.renderForSpecs(); + await pollToPromise(() => { + scene.renderForSpecs(); + return root.contentFailed || root.contentReady; + }); + expect(root.contentReady).toEqual(true); + expect(root.hasTilesetContent).toEqual(true); - // Check that headers are equal - const subtreeRoot = root.children[0]; - expect(root.refine).toEqual(subtreeRoot.refine); - expect(root.contentBoundingVolume.boundingVolume).toEqual( - subtreeRoot.contentBoundingVolume.boundingVolume - ); + // Root has one child now, the root of the external tileset + expect(root.children.length).toEqual(1); - // Check that subtree root has 4 children - expect(subtreeRoot.hasTilesetContent).toEqual(false); - expect(subtreeRoot.children.length).toEqual(4); - }); - } + // Check that headers are equal + const subtreeRoot = root.children[0]; + expect(root.refine).toEqual(subtreeRoot.refine); + expect(root.contentBoundingVolume.boundingVolume).toEqual( + subtreeRoot.contentBoundingVolume.boundingVolume ); + + // Check that subtree root has 4 children + expect(subtreeRoot.hasTilesetContent).toEqual(false); + expect(subtreeRoot.children.length).toEqual(4); }); - it("preserves query string with external tileset JSON file", function () { + it("preserves query string with external tileset JSON file", async function () { // Set view so that no tiles are loaded initially viewNothing(); @@ -1949,33 +1942,32 @@ describe( const queryParams = "a=1&b=boy"; let expectedUrl = `Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json?${queryParams}`; - return Cesium3DTilesTester.loadTileset( + const tileset = await Cesium3DTilesTester.loadTileset( scene, `${tilesetOfTilesetsUrl}?${queryParams}` - ) - .then(function (tileset) { - //Make sure tileset JSON file was requested with query parameters - expect( - Resource._Implementations.loadWithXhr.calls.argsFor(0)[0] - ).toEqual(expectedUrl); + ); + //Make sure tileset JSON file was requested with query parameters + expect(Resource._Implementations.loadWithXhr.calls.argsFor(0)[0]).toEqual( + expectedUrl + ); - Resource._Implementations.loadWithXhr.calls.reset(); + Resource._Implementations.loadWithXhr.calls.reset(); - // Set view so that root's content is requested - viewRootOnly(); - scene.renderForSpecs(); + // Set view so that root's content is requested + viewRootOnly(); + scene.renderForSpecs(); - return tileset.root.contentReadyPromise; - }) - .then(function () { - //Make sure tileset2.json was requested with query parameters and does not use parent tilesetVersion - expectedUrl = getAbsoluteUri( - `Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset2.json?v=1.2.3&${queryParams}` - ); - expect( - Resource._Implementations.loadWithXhr.calls.argsFor(0)[0] - ).toEqual(expectedUrl); - }); + await pollToPromise(() => { + scene.renderForSpecs(); + return tileset.tilesLoaded; + }); + //Make sure tileset2.json was requested with query parameters and does not use parent tilesetVersion + expectedUrl = getAbsoluteUri( + `Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset2.json?v=1.2.3&${queryParams}` + ); + expect(Resource._Implementations.loadWithXhr.calls.argsFor(0)[0]).toEqual( + expectedUrl + ); }); it("renders tileset with external tileset JSON file", function () { @@ -2052,7 +2044,6 @@ describe( expect(rgba).not.toEqual(color); }); - // Check for original color tileset.debugColorizeTiles = false; Cesium3DTilesTester.expectRender(scene, tileset, function (rgba) { expect(rgba).toEqual(color); @@ -2385,24 +2376,25 @@ describe( }); }); - it("does not process tiles when picking", function () { - const spy = spyOn(Cesium3DTile.prototype, "process").and.callThrough(); - + it("does not process tiles when picking", async function () { viewNothing(); - return Cesium3DTilesTester.loadTileset(scene, tilesetUrl).then(function ( - tileset - ) { - viewRootOnly(); - scene.renderForSpecs(); // Request root - expect(tileset._statistics.numberOfPendingRequests).toEqual(1); - return tileset.root.contentReadyToProcessPromise.then(function () { - scene.pickForSpecs(); - expect(spy).not.toHaveBeenCalled(); - scene.renderForSpecs(); - expect(spy).toHaveBeenCalled(); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); - }); + const tileset = await Cesium3DTilesTester.loadTileset(scene, tilesetUrl); + viewRootOnly(); + scene.renderForSpecs(); // Request root + expect(tileset._statistics.numberOfPendingRequests).toEqual(1); + await pollToPromise(() => { + scene.renderForSpecs(); + return ( + tileset.root._contentState === Cesium3DTileContentState.PROCESSING + ); }); + + const spy = spyOn(Cesium3DTile.prototype, "process").and.callThrough(); + scene.pickForSpecs(); + expect(spy).not.toHaveBeenCalled(); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(spy).toHaveBeenCalled(); }); // https://github.com/CesiumGS/cesium/issues/6482 @@ -2593,43 +2585,47 @@ describe( }); }); - it("destroys before external tileset JSON file finishes loading", function () { + it("destroys before external tileset JSON file finishes loading", async function () { viewNothing(); - return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then( - function (tileset) { - const root = tileset.root; + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + tilesetOfTilesetsUrl + ); + const root = tileset.root; - viewRootOnly(); - scene.renderForSpecs(); // Request external tileset JSON file + viewRootOnly(); + scene.renderForSpecs(); // Request external tileset JSON file - const statistics = tileset._statistics; - expect(statistics.numberOfPendingRequests).toEqual(1); - scene.primitives.remove(tileset); + const statistics = tileset._statistics; + expect(statistics.numberOfPendingRequests).toEqual(1); + scene.primitives.remove(tileset); - return root.contentReadyPromise.then(function (content) { - expect(content).toBeUndefined(); + await pollToPromise(() => { + scene.renderForSpecs(); + return statistics.numberOfPendingRequests === 0; + }); - // Expect the root to not have added any children from the external tileset JSON file - expect(root.children.length).toEqual(0); - }); - } - ); + expect(root.content).toBeUndefined(); + + // Expect the root to not have added any children from the external tileset JSON file + expect(root.children.length).toEqual(0); }); - it("destroys before tile finishes loading", function () { + it("destroys before tile finishes loading", async function () { viewRootOnly(); options.url = tilesetUrl; const tileset = scene.primitives.add(new Cesium3DTileset(options)); - return tileset.readyPromise.then(function (tileset) { - const root = tileset.root; - scene.renderForSpecs(); // Request root - scene.primitives.remove(tileset); + await tileset.readyPromise; + const root = tileset.root; + scene.renderForSpecs(); // Request root + scene.primitives.remove(tileset); - return root.contentReadyPromise.then(function (content) { - expect(content).toBeUndefined(); - expect(root._contentState).toBe(Cesium3DTileContentState.FAILED); - }); + await pollToPromise(() => { + scene.renderForSpecs(); + return tileset._statistics.numberOfPendingRequests === 0; }); + + expect(root.content).toBeUndefined(); }); it("renders with imageBaseLightingFactor", function () { @@ -4075,7 +4071,6 @@ describe( it("tile expires", function () { return Cesium3DTilesTester.loadTileset(scene, batchedExpirationUrl).then( function (tileset) { - // Intercept the request and load content that produces more draw commands, to simulate fetching new content after the original expires spyOn(Resource._Implementations, "loadWithXhr").and.callFake( function ( url, @@ -4193,7 +4188,7 @@ describe( return Cesium3DTilesTester.loadTileset( scene, tilesetSubtreeExpirationUrl - ).then(function (tileset) { + ).then(async function (tileset) { // Intercept the request and load a subtree with one less child. Still want to make an actual request to simulate // real use cases instead of immediately returning a pre-created array buffer. spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( @@ -4267,52 +4262,42 @@ describe( }); }); - it("tile expires and request fails", function () { - return Cesium3DTilesTester.loadTileset(scene, batchedExpirationUrl).then( - function (tileset) { - spyOn(Resource._Implementations, "loadWithXhr").and.callFake( - function ( - url, - responseType, - method, - data, - headers, - deferred, - overrideMimeType - ) { - deferred.reject(new Error()); - } - ); - const tile = tileset.root; - const statistics = tileset._statistics; + it("tile expires and request fails", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + batchedExpirationUrl + ); + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(() => { + return Promise.reject(new Error("404")); + }); + const tile = tileset.root; + const statistics = tileset._statistics; - // Trigger expiration to happen next frame - tile.expireDate = JulianDate.addSeconds( - JulianDate.now(), - -1.0, - new JulianDate() - ); + // Trigger expiration to happen next frame + tile.expireDate = JulianDate.addSeconds( + JulianDate.now(), + -1.0, + new JulianDate() + ); - // After update the tile is expired - scene.renderForSpecs(); + const failedSpy = jasmine.createSpy("listenerSpy"); + tileset.tileFailed.addEventListener(failedSpy); - // Make request (it will fail) - scene.renderForSpecs(); + // After update the tile is expired + scene.renderForSpecs(); - return tile.contentReadyPromise - .then(function () { - fail(); - }) - .catch(function () { - // Render scene - scene.renderForSpecs(); + await pollToPromise(() => { + scene.renderForSpecs(); + return tileset.tilesLoaded; + }); - expect(tile._contentState).toBe(Cesium3DTileContentState.FAILED); - expect(statistics.numberOfCommands).toBe(0); - expect(statistics.numberOfTilesTotal).toBe(1); - }); - } + expect(failedSpy).toHaveBeenCalledWith( + jasmine.objectContaining({ + message: "404", + }) ); + expect(statistics.numberOfCommands).toBe(0); + expect(statistics.numberOfTilesTotal).toBe(1); }); it("tile expiration date", function () { @@ -4549,7 +4534,6 @@ describe( function (tileset) { // The bounding volume of this tileset puts it under the surface, so no // east-north-up should be applied. Check that it matches the orientation - // of the original transform. let offsetMatrix = tileset.clippingPlanesOriginMatrix; expect( @@ -4561,7 +4545,6 @@ describe( // The bounding volume of this tileset puts it on the surface, // so we want to apply east-north-up as our best guess. offsetMatrix = tileset.clippingPlanesOriginMatrix; - // The clipping plane matrix is not the same as the original because we applied east-north-up. expect( Matrix4.equals(offsetMatrix, tileset.root.computedTransform) ).toBe(false); @@ -5586,7 +5569,7 @@ describe( ); }); - it("request statistics are updated for partial success", function () { + it("request statistics are updated for partial success", async function () { const originalLoadJson = Cesium3DTileset.loadJson; spyOn(Cesium3DTileset, "loadJson").and.callFake(function (tilesetUrl) { return originalLoadJson(tilesetUrl).then(function (tilesetJson) { @@ -5601,41 +5584,39 @@ describe( }); viewNothing(); - let statistics; const tileset = scene.primitives.add( new Cesium3DTileset({ url: multipleContentsUrl, }) ); - return tileset.readyPromise - .then(function (tileset) { - viewAllTiles(); - scene.renderForSpecs(); + await tileset.readyPromise; + viewAllTiles(); + scene.renderForSpecs(); - statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(3); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); + const statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(3); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); - return tileset.root.contentReadyToProcessPromise; - }) - .then(function () { - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(1); - expect(statistics.numberOfTilesWithContentReady).toBe(0); + await pollToPromise(() => { + scene.renderForSpecs(); + return ( + tileset.root._contentState === Cesium3DTileContentState.PROCESSING + ); + }); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(1); - } - ); - }); + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(1); + expect(statistics.numberOfTilesWithContentReady).toBe(0); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(1); }); it("request statistics are updated correctly if requests are not scheduled", function () { @@ -5660,50 +5641,50 @@ describe( ); }); - it("statistics update correctly if tile is canceled", function () { + it("statistics update correctly if tile is canceled", async function () { viewNothing(); - return Cesium3DTilesTester.loadTileset(scene, multipleContentsUrl).then( - function (tileset) { - let callCount = 0; - tileset.tileFailed.addEventListener(function (event) { - callCount++; - }); + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + multipleContentsUrl + ); + let callCount = 0; + tileset.tileFailed.addEventListener(function (event) { + callCount++; + }); - viewAllTiles(); - scene.renderForSpecs(); + viewAllTiles(); + scene.renderForSpecs(); - const statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(2); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); + const statistics = tileset.statistics; - const multipleContents = tileset.root.content; - multipleContents.cancelRequests(); + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(2); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); - tileset.root.contentReadyToProcessPromise - .then(function () { - expect(statistics.numberOfAttemptedRequests).toBe(2); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(1); - expect(statistics.numberOfTilesWithContentReady).toBe(0); - }) - .catch(fail); + const multipleContents = tileset.root.content; + multipleContents.cancelRequests(); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - // Resetting content should be handled gracefully; it should - // not trigger the tileFailed event - expect(callCount).toBe(0); - - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(1); - } - ); - } - ); + await pollToPromise(() => { + return ( + tileset.root._contentState !== Cesium3DTileContentState.LOADING + ); + }); + + expect(statistics.numberOfAttemptedRequests).toBe(2); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + // Resetting content should be handled gracefully; it should + // not trigger the tileFailed event + expect(callCount).toBe(0); + + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(1); }); it("verify multiple content statistics", function () { @@ -5762,7 +5743,7 @@ describe( ); }); - it("raises tileFailed for external tileset inside multiple contents", function () { + it("raises tileFailed for external tileset inside multiple contents", async function () { const originalLoadJson = Cesium3DTileset.loadJson; spyOn(Cesium3DTileset, "loadJson").and.callFake(function (tilesetUrl) { return originalLoadJson(tilesetUrl).then(function (tilesetJson) { @@ -5780,17 +5761,6 @@ describe( }); }); - spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { - const externalTileset = { - asset: { - version: "1.1", - }, - root: {}, - }; - const buffer = generateJsonBuffer(externalTileset).buffer; - return Promise.resolve(buffer); - }); - viewNothing(); let errorCount = 0; const tileset = scene.primitives.add( @@ -5805,16 +5775,22 @@ describe( "External tilesets are disallowed inside multiple contents" ); }); - return tileset.readyPromise.then(function (tileset) { - viewAllTiles(); - scene.renderForSpecs(); + await tileset.readyPromise; - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(errorCount).toBe(2); - } - ); + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { + const externalTileset = { + asset: { + version: "1.1", + }, + root: {}, + }; + const buffer = generateJsonBuffer(externalTileset).buffer; + return Promise.resolve(buffer); }); + viewAllTiles(); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(errorCount).toBe(2); }); it("debugColorizeTiles for multiple contents", function () { @@ -5893,7 +5869,7 @@ describe( }); }); - it("request statistics are updated for partial success (legacy)", function () { + it("request statistics are updated for partial success (legacy)", async function () { const originalLoadJson = Cesium3DTileset.loadJson; spyOn(Cesium3DTileset, "loadJson").and.callFake(function (tilesetUrl) { return originalLoadJson(tilesetUrl).then(function (tilesetJson) { @@ -5909,37 +5885,36 @@ describe( }); viewNothing(); - return Cesium3DTilesTester.loadTileset( + const tileset = await Cesium3DTilesTester.loadTileset( scene, multipleContentsLegacyUrl - ).then(function (tileset) { - viewAllTiles(); - scene.renderForSpecs(); - - const statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(3); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); + ); + viewAllTiles(); + scene.renderForSpecs(); - tileset.root.contentReadyToProcessPromise - .then(function () { - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(1); - expect(statistics.numberOfTilesWithContentReady).toBe(0); - }) - .catch(fail); + const statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(3); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(1); - } + await pollToPromise(() => { + scene.renderForSpecs(); + return ( + tileset.root._contentState === Cesium3DTileContentState.PROCESSING ); }); + + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(1); + expect(statistics.numberOfTilesWithContentReady).toBe(0); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(1); }); it("request statistics are updated correctly if requests are not scheduled (legacy)", function () { @@ -5965,51 +5940,49 @@ describe( }); }); - it("statistics update correctly if tile is canceled (legacy)", function () { + it("statistics update correctly if tile is canceled (legacy)", async function () { viewNothing(); - return Cesium3DTilesTester.loadTileset( + const tileset = await Cesium3DTilesTester.loadTileset( scene, multipleContentsLegacyUrl - ).then(function (tileset) { - let callCount = 0; - tileset.tileFailed.addEventListener(function (event) { - callCount++; - }); - - viewAllTiles(); - scene.renderForSpecs(); + ); + let callCount = 0; + tileset.tileFailed.addEventListener(function (event) { + callCount++; + }); - const statistics = tileset.statistics; - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(2); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(0); + viewAllTiles(); + scene.renderForSpecs(); - const multipleContents = tileset.root.content; - multipleContents.cancelRequests(); + const statistics = tileset.statistics; + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(2); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); - tileset.root.contentReadyToProcessPromise - .then(function () { - expect(statistics.numberOfAttemptedRequests).toBe(2); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(1); - expect(statistics.numberOfTilesWithContentReady).toBe(0); - }) - .catch(fail); + const multipleContents = tileset.root.content; + multipleContents.cancelRequests(); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - // Resetting content should be handled gracefully; it should - // not trigger the tileFailed event - expect(callCount).toBe(0); - - expect(statistics.numberOfAttemptedRequests).toBe(0); - expect(statistics.numberOfPendingRequests).toBe(0); - expect(statistics.numberOfTilesProcessing).toBe(0); - expect(statistics.numberOfTilesWithContentReady).toBe(1); - } + await pollToPromise(() => { + return ( + tileset.root._contentState !== Cesium3DTileContentState.LOADING ); }); + + expect(statistics.numberOfAttemptedRequests).toBe(2); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(0); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + // Resetting content should be handled gracefully; it should + // not trigger the tileFailed event + expect(callCount).toBe(0); + + expect(statistics.numberOfAttemptedRequests).toBe(0); + expect(statistics.numberOfPendingRequests).toBe(0); + expect(statistics.numberOfTilesProcessing).toBe(0); + expect(statistics.numberOfTilesWithContentReady).toBe(1); }); it("verify multiple content statistics (legacy)", function () { diff --git a/packages/engine/Specs/Scene/Composite3DTileContentSpec.js b/packages/engine/Specs/Scene/Composite3DTileContentSpec.js index cfcb57b6675..2d454a9912d 100644 --- a/packages/engine/Specs/Scene/Composite3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Composite3DTileContentSpec.js @@ -5,6 +5,7 @@ import { ContentMetadata, HeadingPitchRange, MetadataClass, + RuntimeError, GroupMetadata, ImplicitMetadataView, } from "../../index.js"; @@ -84,14 +85,19 @@ describe( }); } - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generateCompositeTileBuffer({ version: 2, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "cmpt"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "cmpt") + ).toBeRejectedWithError( + RuntimeError, + "Only Composite Tile version 1 is supported. Version 2 is not." + ); }); - it("throws with invalid inner tile content type", function () { + it("throws with invalid inner tile content type", async function () { const arrayBuffer = Cesium3DTilesTester.generateCompositeTileBuffer({ tiles: [ Cesium3DTilesTester.generateInstancedTileBuffer({ @@ -99,16 +105,25 @@ describe( }), ], }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "cmpt"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "cmpt") + ).toBeRejectedWithError( + RuntimeError, + "Unknown tile content type, xxxx, inside Composite tile" + ); }); - it("resolves readyPromise", function () { - return Cesium3DTilesTester.resolvesReadyPromise(scene, compositeUrl); + it("becomes ready", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + compositeUrl + ); + expect(tileset.root.contentReady).toBeTrue(); + expect(tileset.root.content).toBeDefined(); }); - it("rejects readyPromise on error", function () { + it("throws with invalid tile content", async function () { // Try loading a composite tile with an instanced tile that has an invalid url. - // Expect promise to be rejected in Model, Model3DTileContent and Composite3DTileContent. const arrayBuffer = Cesium3DTilesTester.generateCompositeTileBuffer({ tiles: [ Cesium3DTilesTester.generateInstancedTileBuffer({ @@ -117,10 +132,12 @@ describe( }), ], }); - return Cesium3DTilesTester.rejectsReadyPromiseOnError( - scene, - arrayBuffer, - "cmpt" + + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "cmpt") + ).toBeRejectedWithError( + RuntimeError, + "Failed to load i3dm\nFailed to load glTF\nFailed to load glTF: http://localhost:8080/Specs/invalid?compositeIndex=0" ); }); diff --git a/packages/engine/Specs/Scene/Geometry3DTileContentSpec.js b/packages/engine/Specs/Scene/Geometry3DTileContentSpec.js index 946c0613b27..344dca690ce 100644 --- a/packages/engine/Specs/Scene/Geometry3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Geometry3DTileContentSpec.js @@ -17,6 +17,7 @@ import { Rectangle, RectangleGeometry, RenderState, + RuntimeError, StencilConstants, } from "../../index.js"; import Cesium3DTilesTester from "../../../../Specs/Cesium3DTilesTester.js"; @@ -827,21 +828,31 @@ describe( }); }); - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generateGeometryTileBuffer({ version: 2, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "geom"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "geom") + ).toBeRejectedWithError( + RuntimeError, + "Only Geometry tile version 1 is supported. Version 2 is not." + ); }); - it("throws with empty feature table", function () { + it("throws with empty async feature table", async function () { const arrayBuffer = Cesium3DTilesTester.generateGeometryTileBuffer({ defineFeatureTable: false, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "geom"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "geom") + ).toBeRejectedWithError( + RuntimeError, + "Feature table must have a byte length greater than zero" + ); }); - it("throws without all batch ids", function () { + it("throws without all batch ids", async function () { const arrayBuffer = Cesium3DTilesTester.generateGeometryTileBuffer({ boxesLength: 1, cylindersLength: 1, @@ -851,7 +862,12 @@ describe( cylinderBatchIds: [0], ellipsoidBatchIds: [2], }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "geom"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "geom") + ).toBeRejectedWithError( + RuntimeError, + "If one group of batch ids is defined, then all batch ids must be defined" + ); }); it("destroys", function () { diff --git a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js index dc5a3774f46..f5570011c99 100644 --- a/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js +++ b/packages/engine/Specs/Scene/GlobeSurfaceTileProviderSpec.js @@ -1160,7 +1160,7 @@ describe( planes: [new ClippingPlane(Cartesian3.UNIT_Z, 10000000.0)], }); const model = scene.primitives.add( - await Model.fromGltf({ + await Model.fromGltfAsync({ url: "./Data/Models/glTF-2.0/BoxTextured/glTF/BoxTextured.gltf", }) ); diff --git a/packages/engine/Specs/Scene/GltfLoaderSpec.js b/packages/engine/Specs/Scene/GltfLoaderSpec.js index 0a7cecc8205..8b868906184 100644 --- a/packages/engine/Specs/Scene/GltfLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfLoaderSpec.js @@ -3340,8 +3340,7 @@ describe( }); }); - // TODO - xit("process throws if image resource fails to load", function () { + it("process throws if image resource fails to load", async function () { spyOn(Resource.prototype, "fetchImage").and.callFake(function () { const error = new Error("404 Not Found"); return Promise.reject(error); @@ -3368,31 +3367,18 @@ describe( const gltfLoader = new GltfLoader(getOptions(boxTextured, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene) - .then(function () { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF\nFailed to load texture\nFailed to load image: CesiumLogoFlat.png\n404 Not Found" - ); - }) - .then(function () { - return gltfLoader.texturesLoadedPromise; - }) - .then(function () { - fail(); - }) - .catch(function (runtimeError) { - expect(runtimeError.message).toBe( - "Failed to load glTF\nFailed to load texture\nFailed to load image: CesiumLogoFlat.png\n404 Not Found" - ); - expect(destroyVertexBufferLoader.calls.count()).toBe(2); - expect(destroyIndexBufferLoader.calls.count()).toBe(1); - expect(destroyTextureLoader.calls.count()).toBe(1); - }); + await gltfLoader.load(); + + await expectAsync( + waitForLoaderProcess(gltfLoader, scene) + ).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF\nFailed to load texture\nFailed to load image: CesiumLogoFlat.png\n404 Not Found" + ); + + expect(destroyVertexBufferLoader.calls.count()).toBe(2); + expect(destroyIndexBufferLoader.calls.count()).toBe(1); + expect(destroyTextureLoader.calls.count()).toBe(1); }); function resolveGltfJsonAfterDestroy(rejectPromise) { diff --git a/packages/engine/Specs/Scene/I3SNodeSpec.js b/packages/engine/Specs/Scene/I3SNodeSpec.js index afda3ea0708..6e6941b374a 100644 --- a/packages/engine/Specs/Scene/I3SNodeSpec.js +++ b/packages/engine/Specs/Scene/I3SNodeSpec.js @@ -1425,16 +1425,12 @@ describe("Scene/I3SNode", function () { spyOn(childNode.tile, "_hookedRequestContent").and.callFake( function () { childNode.tile._contentReadyToProcessPromise = Promise.resolve(); - childNode.tile._contentReadyPromise = Promise.resolve(); } ); childNode.tile._contentResource = { _url: "mockOriginalContentUrl" }; childNode.tile.requestContent(); - return Promise.all([ - childNode.tile._contentReadyToProcessPromise, - childNode.tile._contentReadyPromise, - ]); + return Promise.all([childNode.tile._contentReadyToProcessPromise]); }) .then(function () { expect(childNode.tile._contentResource._url).toEqual("mockGlbUrl"); diff --git a/packages/engine/Specs/Scene/Implicit3DTileContentSpec.js b/packages/engine/Specs/Scene/Implicit3DTileContentSpec.js index 38b3a69fc6e..e4c5025c968 100644 --- a/packages/engine/Specs/Scene/Implicit3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Implicit3DTileContentSpec.js @@ -19,6 +19,7 @@ import { Model3DTileContent, Multiple3DTileContent, Resource, + ResourceCache, TileBoundingSphere, TileBoundingS2Cell, } from "../../index.js"; @@ -149,6 +150,7 @@ describe( let mockPlaceholderTile; beforeEach(function () { + ResourceCache.clearForSpecs(); mockTileset.statistics.numberOfTilesTotal = 0; mockPlaceholderTile = new Cesium3DTile(mockTileset, tilesetResource, { geometricError: 400, @@ -167,30 +169,29 @@ describe( afterEach(function () { scene.primitives.removeAll(); + ResourceCache.clearForSpecs(); }); - it("loads subtree using JSON", function () { - const content = new Implicit3DTileContent( + it("loads subtree using JSON", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, quadtreeJson ); - return content.readyPromise.then(function () { - const expectedChildrenCounts = [4, 0, 0, 0, 0]; - const tiles = []; - const subtreeRootTile = mockPlaceholderTile.children[0]; - gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); - expect(expectedChildrenCounts.length).toEqual(tiles.length); - for (let i = 0; i < tiles.length; i++) { - expect(tiles[i].children.length).toEqual(expectedChildrenCounts[i]); - } - expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); - }); + const expectedChildrenCounts = [4, 0, 0, 0, 0]; + const tiles = []; + const subtreeRootTile = mockPlaceholderTile.children[0]; + gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); + expect(expectedChildrenCounts.length).toEqual(tiles.length); + for (let i = 0; i < tiles.length; i++) { + expect(tiles[i].children.length).toEqual(expectedChildrenCounts[i]); + } + expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); }); - it("expands subtree", function () { - const content = new Implicit3DTileContent( + it("expands subtree", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -198,21 +199,19 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const expectedChildrenCounts = [2, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0]; - const tiles = []; - const subtreeRootTile = mockPlaceholderTile.children[0]; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - expect(expectedChildrenCounts.length).toEqual(tiles.length); - for (let i = 0; i < tiles.length; i++) { - expect(tiles[i].children.length).toEqual(expectedChildrenCounts[i]); - } - expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); - }); + const expectedChildrenCounts = [2, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0]; + const tiles = []; + const subtreeRootTile = mockPlaceholderTile.children[0]; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + expect(expectedChildrenCounts.length).toEqual(tiles.length); + for (let i = 0; i < tiles.length; i++) { + expect(tiles[i].children.length).toEqual(expectedChildrenCounts[i]); + } + expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); }); - it("sets tile coordinates on each tile", function () { - const content = new Implicit3DTileContent( + it("sets tile coordinates on each tile", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -220,38 +219,36 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const expectedCoordinates = [ - [0, 0, 0], - [1, 0, 0], - [2, 0, 0], - [2, 1, 0], - [2, 0, 1], - [2, 1, 1], - [1, 0, 1], - [2, 0, 2], - [2, 1, 2], - [2, 0, 3], - [2, 1, 3], - ]; - const tiles = []; - const subtreeRootTile = mockPlaceholderTile.children[0]; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - for (let i = 0; i < tiles.length; i++) { - const expected = expectedCoordinates[i]; - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitTileset.subdivisionScheme, - subtreeLevels: implicitTileset.subtreeLevels, - level: expected[0], - x: expected[1], - y: expected[2], - }); - expect(tiles[i].implicitCoordinates).toEqual(coordinates); - } - }); + const expectedCoordinates = [ + [0, 0, 0], + [1, 0, 0], + [2, 0, 0], + [2, 1, 0], + [2, 0, 1], + [2, 1, 1], + [1, 0, 1], + [2, 0, 2], + [2, 1, 2], + [2, 0, 3], + [2, 1, 3], + ]; + const tiles = []; + const subtreeRootTile = mockPlaceholderTile.children[0]; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + for (let i = 0; i < tiles.length; i++) { + const expected = expectedCoordinates[i]; + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: expected[0], + x: expected[1], + y: expected[2], + }); + expect(tiles[i].implicitCoordinates).toEqual(coordinates); + } }); - it("handles deeper subtrees correctly", function () { + it("handles deeper subtrees correctly", async function () { mockPlaceholderTile.implicitCoordinates = new ImplicitTileCoordinates({ subdivisionScheme: implicitTileset.subdivisionScheme, subtreeLevels: implicitTileset.subtreeLevels, @@ -259,7 +256,7 @@ describe( x: 2, y: 1, }); - const content = new Implicit3DTileContent( + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -292,29 +289,27 @@ describe( childCoordinates.y ); - return content.readyPromise.then(function () { - const subtreeRootTile = mockPlaceholderTile.children[0]; - const childTile = subtreeRootTile.children[0]; - expect(subtreeRootTile.implicitCoordinates).toEqual(parentCoordinates); - expect(childTile.implicitCoordinates).toEqual(childCoordinates); + const subtreeRootTile = mockPlaceholderTile.children[0]; + const childTile = subtreeRootTile.children[0]; + expect(subtreeRootTile.implicitCoordinates).toEqual(parentCoordinates); + expect(childTile.implicitCoordinates).toEqual(childCoordinates); - expect(subtreeRootTile.refine).toEqual(refine); - expect(childTile.refine).toEqual(refine); + expect(subtreeRootTile.refine).toEqual(refine); + expect(childTile.refine).toEqual(refine); - expect(subtreeRootTile.geometricError).toEqual(parentGeometricError); - expect(childTile.geometricError).toEqual(childGeometricError); + expect(subtreeRootTile.geometricError).toEqual(parentGeometricError); + expect(childTile.geometricError).toEqual(childGeometricError); - expect(getBoundingBoxArray(subtreeRootTile)).toEqual(parentBox); - expect(getBoundingBoxArray(childTile)).toEqual(childBox); + expect(getBoundingBoxArray(subtreeRootTile)).toEqual(parentBox); + expect(getBoundingBoxArray(childTile)).toEqual(childBox); - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 2, 4, tiles); - expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); - }); + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 2, 4, tiles); + expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); }); - it("puts the root tile inside the placeholder tile", function () { - const content = new Implicit3DTileContent( + it("puts the root tile inside the placeholder tile", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -322,13 +317,11 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - expect(mockPlaceholderTile.children.length).toEqual(1); - }); + expect(mockPlaceholderTile.children.length).toEqual(1); }); - it("preserves tile extras", function () { - const content = new Implicit3DTileContent( + it("preserves tile extras", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -336,13 +329,11 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - expect(mockPlaceholderTile.children[0].extras).toEqual(tileJson.extras); - }); + expect(mockPlaceholderTile.children[0].extras).toEqual(tileJson.extras); }); - it("stores a reference to the subtree in each transcoded tile", function () { - const content = new Implicit3DTileContent( + it("stores a reference to the subtree in each transcoded tile", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -350,23 +341,21 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - expect(mockPlaceholderTile.implicitSubtree).not.toBeDefined(); + expect(mockPlaceholderTile.implicitSubtree).not.toBeDefined(); - const subtreeRootTile = mockPlaceholderTile.children[0]; - const subtree = subtreeRootTile.implicitSubtree; - expect(subtree).toBeDefined(); + const subtreeRootTile = mockPlaceholderTile.children[0]; + const subtree = subtreeRootTile.implicitSubtree; + expect(subtree).toBeDefined(); - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); - for (let i = 0; i < tiles.length; i++) { - expect(tiles[i].implicitSubtree).toBe(subtree); - } - }); + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); + for (let i = 0; i < tiles.length; i++) { + expect(tiles[i].implicitSubtree).toBe(subtree); + } }); - it("does not store references to subtrees in placeholder tiles", function () { - const content = new Implicit3DTileContent( + it("does not store references to subtrees in placeholder tiles", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -374,21 +363,19 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - expect(mockPlaceholderTile.implicitSubtree).not.toBeDefined(); + expect(mockPlaceholderTile.implicitSubtree).not.toBeDefined(); - const subtreeRootTile = mockPlaceholderTile.children[0]; + const subtreeRootTile = mockPlaceholderTile.children[0]; - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 2, 2, tiles); - for (let i = 0; i < tiles.length; i++) { - expect(tiles[i].implicitSubtree).not.toBeDefined(); - } - }); + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 2, 2, tiles); + for (let i = 0; i < tiles.length; i++) { + expect(tiles[i].implicitSubtree).not.toBeDefined(); + } }); - it("destroys", function () { - const content = new Implicit3DTileContent( + it("destroys", async function () { + const content = await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -396,19 +383,17 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const subtree = content._implicitSubtree; - expect(content.isDestroyed()).toBe(false); - expect(subtree.isDestroyed()).toBe(false); - - content.destroy(); - expect(content.isDestroyed()).toBe(true); - expect(subtree.isDestroyed()).toBe(true); - }); + const subtree = content._implicitSubtree; + expect(content.isDestroyed()).toBe(false); + expect(subtree.isDestroyed()).toBe(false); + + content.destroy(); + expect(content.isDestroyed()).toBe(true); + expect(subtree.isDestroyed()).toBe(true); }); - it("returns default values for most Cesium3DTileContent properties", function () { - const content = new Implicit3DTileContent( + it("returns default values for most Cesium3DTileContent properties", async function () { + const content = await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -430,8 +415,8 @@ describe( expect(content.batchTable).not.toBeDefined(); }); - it("url returns the subtree url", function () { - const content = new Implicit3DTileContent( + it("url returns the subtree url", async function () { + const content = await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -442,8 +427,8 @@ describe( expect(content.url).toBe("https://example.com/0/0/0.subtree"); }); - it("templates content URIs for each tile with content", function () { - const content = new Implicit3DTileContent( + it("templates content URIs for each tile with content", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -451,41 +436,39 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const expectedCoordinates = [ - [0, 0, 0], - [1, 0, 0], - [1, 0, 1], - ]; - const contentAvailability = [false, true, true]; - const templateUri = implicitTileset.contentUriTemplates[0]; - const subtreeRootTile = mockPlaceholderTile.children[0]; - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); - expect(expectedCoordinates.length).toEqual(tiles.length); - for (let i = 0; i < tiles.length; i++) { - const expected = expectedCoordinates[i]; - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitTileset.subdivisionScheme, - subtreeLevels: implicitTileset.subtreeLevels, - level: expected[0], - x: expected[1], - y: expected[2], - }); - const expectedResource = templateUri.getDerivedResource({ - templateValues: coordinates.getTemplateValues(), - }); - if (contentAvailability[i]) { - expect(tiles[i]._contentResource.url).toEqual(expectedResource.url); - } else { - expect(tiles[i]._contentResource).not.toBeDefined(); - } + const expectedCoordinates = [ + [0, 0, 0], + [1, 0, 0], + [1, 0, 1], + ]; + const contentAvailability = [false, true, true]; + const templateUri = implicitTileset.contentUriTemplates[0]; + const subtreeRootTile = mockPlaceholderTile.children[0]; + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 1, tiles); + expect(expectedCoordinates.length).toEqual(tiles.length); + for (let i = 0; i < tiles.length; i++) { + const expected = expectedCoordinates[i]; + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: expected[0], + x: expected[1], + y: expected[2], + }); + const expectedResource = templateUri.getDerivedResource({ + templateValues: coordinates.getTemplateValues(), + }); + if (contentAvailability[i]) { + expect(tiles[i]._contentResource.url).toEqual(expectedResource.url); + } else { + expect(tiles[i]._contentResource).not.toBeDefined(); } - }); + } }); - it("constructs placeholder tiles for child subtrees", function () { - const content = new Implicit3DTileContent( + it("constructs placeholder tiles for child subtrees", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -493,51 +476,49 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const expectedCoordinates = [ - [2, 0, 0], - [2, 1, 0], - [2, 0, 1], - [2, 1, 1], - [2, 0, 2], - [2, 1, 2], - [2, 0, 3], - [2, 1, 3], - ]; - const templateUri = implicitTileset.subtreeUriTemplate; - const subtreeRootTile = mockPlaceholderTile.children[0]; - let tiles = []; - gatherTilesPreorder(subtreeRootTile, 2, 2, tiles); - - expect(expectedCoordinates.length).toEqual(tiles.length); - for (let i = 0; i < tiles.length; i++) { - const expected = expectedCoordinates[i]; - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitTileset.subdivisionScheme, - subtreeLevels: implicitTileset.subtreeLevels, - level: expected[0], - x: expected[1], - y: expected[2], - }); - const expectedResource = templateUri.getDerivedResource({ - templateValues: coordinates.getTemplateValues(), - }); - const placeholderTile = tiles[i]; - expect(placeholderTile._contentResource.url).toEqual( - expectedResource.url - ); - expect(placeholderTile.implicitTileset).toBeDefined(); - expect(placeholderTile.implicitCoordinates).toBeDefined(); - } + const expectedCoordinates = [ + [2, 0, 0], + [2, 1, 0], + [2, 0, 1], + [2, 1, 1], + [2, 0, 2], + [2, 1, 2], + [2, 0, 3], + [2, 1, 3], + ]; + const templateUri = implicitTileset.subtreeUriTemplate; + const subtreeRootTile = mockPlaceholderTile.children[0]; + let tiles = []; + gatherTilesPreorder(subtreeRootTile, 2, 2, tiles); + + expect(expectedCoordinates.length).toEqual(tiles.length); + for (let i = 0; i < tiles.length; i++) { + const expected = expectedCoordinates[i]; + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitTileset.subdivisionScheme, + subtreeLevels: implicitTileset.subtreeLevels, + level: expected[0], + x: expected[1], + y: expected[2], + }); + const expectedResource = templateUri.getDerivedResource({ + templateValues: coordinates.getTemplateValues(), + }); + const placeholderTile = tiles[i]; + expect(placeholderTile._contentResource.url).toEqual( + expectedResource.url + ); + expect(placeholderTile.implicitTileset).toBeDefined(); + expect(placeholderTile.implicitCoordinates).toBeDefined(); + } - tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); - }); + tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + expect(mockTileset.statistics.numberOfTilesTotal).toBe(tiles.length); }); - it("propagates refine down the tree", function () { - const content = new Implicit3DTileContent( + it("propagates refine down the tree", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -549,18 +530,16 @@ describe( implicitTileset.refine === "ADD" ? Cesium3DTileRefine.ADD : Cesium3DTileRefine.REPLACE; - return content.readyPromise.then(function () { - const subtreeRootTile = mockPlaceholderTile.children[0]; - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - for (let i = 0; i < tiles.length; i++) { - expect(tiles[i].refine).toEqual(refine); - } - }); + const subtreeRootTile = mockPlaceholderTile.children[0]; + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + for (let i = 0; i < tiles.length; i++) { + expect(tiles[i].refine).toEqual(refine); + } }); - it("divides the geometricError by 2 for each level of the tree", function () { - const content = new Implicit3DTileContent( + it("divides the geometricError by 2 for each level of the tree", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -569,21 +548,19 @@ describe( 0 ); const rootGeometricError = implicitTileset.geometricError; - return content.readyPromise.then(function () { - const subtreeRootTile = mockPlaceholderTile.children[0]; - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - for (let i = 0; i < tiles.length; i++) { - const level = tiles[i].implicitCoordinates.level; - expect(tiles[i].geometricError).toEqual( - rootGeometricError / Math.pow(2, level) - ); - } - }); + const subtreeRootTile = mockPlaceholderTile.children[0]; + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + for (let i = 0; i < tiles.length; i++) { + const level = tiles[i].implicitCoordinates.level; + expect(tiles[i].geometricError).toEqual( + rootGeometricError / Math.pow(2, level) + ); + } }); - it("subdivides bounding volumes for each tile", function () { - const content = new Implicit3DTileContent( + it("subdivides bounding volumes for each tile", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -591,48 +568,46 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const expectedCoordinates = [ - [0, 0, 0], - [1, 0, 0], - [2, 0, 0], - [2, 1, 0], - [2, 0, 1], - [2, 1, 1], - [1, 0, 1], - [2, 0, 2], - [2, 1, 2], - [2, 0, 3], - [2, 1, 3], - ]; - const rootBoundingVolume = [10, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256]; - - const subtreeRootTile = mockPlaceholderTile.children[0]; - const tiles = []; - gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); - - expect(expectedCoordinates.length).toEqual(tiles.length); - for (let i = 0; i < tiles.length; i++) { - const coordinates = expectedCoordinates[i]; - - const boundingBox = tiles[i].boundingVolume.boundingVolume; - const childBox = new Array(12); - Cartesian3.pack(boundingBox.center, childBox); - Matrix3.pack(boundingBox.halfAxes, childBox, 3); - - const expectedBounds = Implicit3DTileContent._deriveBoundingBox( - rootBoundingVolume, - coordinates[0], - coordinates[1], - coordinates[2] - ); - expect(childBox).toEqual(expectedBounds); - } - }); + const expectedCoordinates = [ + [0, 0, 0], + [1, 0, 0], + [2, 0, 0], + [2, 1, 0], + [2, 0, 1], + [2, 1, 1], + [1, 0, 1], + [2, 0, 2], + [2, 1, 2], + [2, 0, 3], + [2, 1, 3], + ]; + const rootBoundingVolume = [10, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256]; + + const subtreeRootTile = mockPlaceholderTile.children[0]; + const tiles = []; + gatherTilesPreorder(subtreeRootTile, 0, 2, tiles); + + expect(expectedCoordinates.length).toEqual(tiles.length); + for (let i = 0; i < tiles.length; i++) { + const coordinates = expectedCoordinates[i]; + + const boundingBox = tiles[i].boundingVolume.boundingVolume; + const childBox = new Array(12); + Cartesian3.pack(boundingBox.center, childBox); + Matrix3.pack(boundingBox.halfAxes, childBox, 3); + + const expectedBounds = Implicit3DTileContent._deriveBoundingBox( + rootBoundingVolume, + coordinates[0], + coordinates[1], + coordinates[2] + ); + expect(childBox).toEqual(expectedBounds); + } }); - it("propagates transform", function () { - const content = new Implicit3DTileContent( + it("propagates transform", async function () { + await Implicit3DTileContent.fromSubtreeJson( mockTileset, mockPlaceholderTile, tilesetResource, @@ -640,12 +615,10 @@ describe( quadtreeBuffer, 0 ); - return content.readyPromise.then(function () { - const subtreeRootTile = mockPlaceholderTile.children[0]; - expect(subtreeRootTile.computedTransform).toEqual( - mockPlaceholderTile.transform - ); - }); + const subtreeRootTile = mockPlaceholderTile.children[0]; + expect(subtreeRootTile.computedTransform).toEqual( + mockPlaceholderTile.transform + ); }); describe("_deriveBoundingVolumeS2", function () { diff --git a/packages/engine/Specs/Scene/ImplicitMetadataViewSpec.js b/packages/engine/Specs/Scene/ImplicitMetadataViewSpec.js index 1a5915a8b2f..089d3a3de96 100644 --- a/packages/engine/Specs/Scene/ImplicitMetadataViewSpec.js +++ b/packages/engine/Specs/Scene/ImplicitMetadataViewSpec.js @@ -230,12 +230,12 @@ describe("Scene/ImplicitMetadataView", function () { let treeView; let secondTreeView; - beforeEach(function () { + beforeEach(async function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - subtree = new ImplicitSubtree( + subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -243,52 +243,50 @@ describe("Scene/ImplicitMetadataView", function () { rootCoordinates ); - return subtree.readyPromise.then(function () { - tileView = new ImplicitMetadataView({ - metadataTable: subtree.tileMetadataTable, - class: tileClass, - entityId: 0, - propertyTableJson: emptyJson, - }); + tileView = new ImplicitMetadataView({ + metadataTable: subtree.tileMetadataTable, + class: tileClass, + entityId: 0, + propertyTableJson: emptyJson, + }); - secondTileView = new ImplicitMetadataView({ - metadataTable: subtree.tileMetadataTable, - class: tileClass, - entityId: 1, - propertyTableJson: emptyJson, - }); + secondTileView = new ImplicitMetadataView({ + metadataTable: subtree.tileMetadataTable, + class: tileClass, + entityId: 1, + propertyTableJson: emptyJson, + }); - buildingView = new ImplicitMetadataView({ - metadataTable: subtree.contentMetadataTables[0], - class: buildingClass, - entityId: 0, - contentIndex: 0, - propertyTableJson: emptyJson, - }); + buildingView = new ImplicitMetadataView({ + metadataTable: subtree.contentMetadataTables[0], + class: buildingClass, + entityId: 0, + contentIndex: 0, + propertyTableJson: emptyJson, + }); - secondBuildingView = new ImplicitMetadataView({ - metadataTable: subtree.contentMetadataTables[0], - class: buildingClass, - entityId: 1, - contentIndex: 0, - propertyTableJson: emptyJson, - }); + secondBuildingView = new ImplicitMetadataView({ + metadataTable: subtree.contentMetadataTables[0], + class: buildingClass, + entityId: 1, + contentIndex: 0, + propertyTableJson: emptyJson, + }); - treeView = new ImplicitMetadataView({ - metadataTable: subtree.contentMetadataTables[1], - class: treeClass, - entityId: 0, - contentIndex: 1, - propertyTableJson: emptyJson, - }); + treeView = new ImplicitMetadataView({ + metadataTable: subtree.contentMetadataTables[1], + class: treeClass, + entityId: 0, + contentIndex: 1, + propertyTableJson: emptyJson, + }); - secondTreeView = new ImplicitMetadataView({ - metadataTable: subtree.contentMetadataTables[1], - class: treeClass, - entityId: 1, - contentIndex: 1, - propertyTableJson: emptyJson, - }); + secondTreeView = new ImplicitMetadataView({ + metadataTable: subtree.contentMetadataTables[1], + class: treeClass, + entityId: 1, + contentIndex: 1, + propertyTableJson: emptyJson, }); }); diff --git a/packages/engine/Specs/Scene/ImplicitSubtreeCacheSpec.js b/packages/engine/Specs/Scene/ImplicitSubtreeCacheSpec.js index 899f6935fef..9cfafaac261 100644 --- a/packages/engine/Specs/Scene/ImplicitSubtreeCacheSpec.js +++ b/packages/engine/Specs/Scene/ImplicitSubtreeCacheSpec.js @@ -65,7 +65,7 @@ describe("Scene/ImplicitSubtreeCache", function () { expect(cache._subtreeRequestCounter).toBe(0); }); - it("can add a subtree", function () { + it("can add a subtree", async function () { const cache = new ImplicitSubtreeCache(); const octreeCoordinates = new ImplicitTileCoordinates({ subdivisionScheme: implicitOctree.subdivisionScheme, @@ -75,7 +75,7 @@ describe("Scene/ImplicitSubtreeCache", function () { y: 0, z: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, subtreeConstantJson, undefined, @@ -86,7 +86,7 @@ describe("Scene/ImplicitSubtreeCache", function () { expect(cache._subtreeRequestCounter).toBe(1); }); - it("addSubtree throws if parent does not exist", function () { + it("addSubtree throws if parent does not exist", async function () { const cache = new ImplicitSubtreeCache(); const octreeCoordinates = new ImplicitTileCoordinates({ subdivisionScheme: implicitOctree.subdivisionScheme, @@ -96,7 +96,7 @@ describe("Scene/ImplicitSubtreeCache", function () { y: 1, z: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, subtreeConstantJson, undefined, @@ -106,7 +106,7 @@ describe("Scene/ImplicitSubtreeCache", function () { expect(() => cache.addSubtree(subtree)).toThrowDeveloperError(); }); - it("addSubtree trims cache as needed", function () { + it("addSubtree trims cache as needed", async function () { const cache = new ImplicitSubtreeCache({ maximumSubtreeCount: 3, }); @@ -120,19 +120,21 @@ describe("Scene/ImplicitSubtreeCache", function () { subdivisionScheme: implicitOctree.subdivisionScheme, subtreeLevels: implicitOctree.subtreeLevels, }; - octreeCoordArray.forEach((octreeCoord) => { - const octreeCoordinates = new ImplicitTileCoordinates( - Object.assign({}, octreeCoordParams, octreeCoord) - ); - const subtree = new ImplicitSubtree( - subtreeResource, - subtreeConstantJson, - undefined, - implicitOctree, - octreeCoordinates - ); - cache.addSubtree(subtree); - }); + await Promise.all( + octreeCoordArray.map(async (octreeCoord) => { + const octreeCoordinates = new ImplicitTileCoordinates( + Object.assign({}, octreeCoordParams, octreeCoord) + ); + const subtree = await ImplicitSubtree.fromSubtreeJson( + subtreeResource, + subtreeConstantJson, + undefined, + implicitOctree, + octreeCoordinates + ); + cache.addSubtree(subtree); + }) + ); expect(cache._subtreeRequestCounter).toBe(4); expect(cache._queue.length).toBe(3); }); diff --git a/packages/engine/Specs/Scene/ImplicitSubtreeSpec.js b/packages/engine/Specs/Scene/ImplicitSubtreeSpec.js index ab612f2acab..7e275c53ae2 100644 --- a/packages/engine/Specs/Scene/ImplicitSubtreeSpec.js +++ b/packages/engine/Specs/Scene/ImplicitSubtreeSpec.js @@ -91,12 +91,15 @@ describe("Scene/ImplicitSubtree", function () { } // used for spying on ResourceCache.load() - function fakeLoad(arrayBuffer) { + function fakeResourceLoader(arrayBuffer) { return function (options) { const fakeCacheResource = { typedArray: arrayBuffer, + load: async () => {}, + process: () => true, + isDestroyed: () => false, }; - options.resourceLoader._promise = Promise.resolve(fakeCacheResource); + return fakeCacheResource; }; } @@ -243,24 +246,7 @@ describe("Scene/ImplicitSubtree", function () { it("throws without resource", function () { expect(function () { - const results = ImplicitTilingTester.generateSubtreeBuffers( - internalQuadtreeDescription - ); return new ImplicitSubtree( - undefined, - undefined, - results.subtreeBuffer, - implicitQuadtree, - quadtreeCoordinates - ); - }).toThrowDeveloperError(); - }); - - it("throws without json or subtreeView", function () { - expect(function () { - return new ImplicitSubtree( - subtreeResource, - undefined, undefined, implicitQuadtree, quadtreeCoordinates @@ -270,14 +256,9 @@ describe("Scene/ImplicitSubtree", function () { it("throws without implicitTileset", function () { expect(function () { - const results = ImplicitTilingTester.generateSubtreeBuffers( - internalQuadtreeDescription - ); return new ImplicitSubtree( subtreeResource, undefined, - results.subtreeBuffer, - undefined, quadtreeCoordinates ); }).toThrowDeveloperError(); @@ -285,24 +266,15 @@ describe("Scene/ImplicitSubtree", function () { it("throws without implicitCoordinates", function () { expect(function () { - const results = ImplicitTilingTester.generateSubtreeBuffers( - internalQuadtreeDescription - ); - return new ImplicitSubtree( - subtreeResource, - undefined, - results.subtreeBuffer, - implicitQuadtree, - undefined - ); + return new ImplicitSubtree(subtreeResource, implicitQuadtree, undefined); }).toThrowDeveloperError(); }); - it("sets the implicit coordinates of the subtree's root", function () { + it("sets the implicit coordinates of the subtree's root", async function () { const results = ImplicitTilingTester.generateSubtreeBuffers( internalQuadtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -315,34 +287,44 @@ describe("Scene/ImplicitSubtree", function () { ); }); - it("gets availability from internal buffer", function () { + it("ImplicitSubtree.fromSubtreeJson throws without json or subtreeView", async function () { + await expectAsync( + ImplicitSubtree.fromSubtreeJson( + subtreeResource, + undefined, + undefined, + implicitQuadtree, + quadtreeCoordinates + ) + ).toBeRejectedWithDeveloperError(); + }); + + it("gets availability from internal buffer", async function () { const results = ImplicitTilingTester.generateSubtreeBuffers( internalQuadtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability( - subtree, - internalQuadtreeDescription.tileAvailability - ); - expectContentAvailability( - subtree, - internalQuadtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - internalQuadtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability( + subtree, + internalQuadtreeDescription.tileAvailability + ); + expectContentAvailability( + subtree, + internalQuadtreeDescription.contentAvailability + ); + expectChildSubtreeAvailability( + subtree, + internalQuadtreeDescription.childSubtreeAvailability + ); }); - it("gets availability from external buffer", function () { + it("gets availability from external buffer", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11010", @@ -365,33 +347,28 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); - expect(fetchExternal.calls.count()).toEqual(1); - }); + expect(fetchExternal.calls.count()).toEqual(1); }); - it("gets availability from JSON constants", function () { - const subtree = new ImplicitSubtree( + it("gets availability from JSON constants", async function () { + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, subtreeConstantJson, undefined, @@ -399,23 +376,21 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability( - subtree, - constantQuadtreeDescription.tileAvailability - ); - expectContentAvailability( - subtree, - constantQuadtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - constantQuadtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability( + subtree, + constantQuadtreeDescription.tileAvailability + ); + expectContentAvailability( + subtree, + constantQuadtreeDescription.contentAvailability + ); + expectChildSubtreeAvailability( + subtree, + constantQuadtreeDescription.childSubtreeAvailability + ); }); - it("gets availability from JSON and external buffers", function () { + it("gets availability from JSON and external buffers", async function () { const description = { tileAvailability: { descriptor: "11010", @@ -439,11 +414,11 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers(description); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, results.subtreeJson, undefined, @@ -451,26 +426,24 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, description.tileAvailability); - expectContentAvailability(subtree, description.contentAvailability); - expectChildSubtreeAvailability( - subtree, - description.childSubtreeAvailability - ); + expectTileAvailability(subtree, description.tileAvailability); + expectContentAvailability(subtree, description.contentAvailability); + expectChildSubtreeAvailability( + subtree, + description.childSubtreeAvailability + ); - expect(fetchExternal.calls.count()).toEqual(1); - }); + expect(fetchExternal.calls.count()).toEqual(1); }); // Test for backwards compatibility - it("gets availability with bufferViews", function () { + it("gets availability with bufferViews", async function () { const description = clone(internalQuadtreeDescription); description.useLegacySchema = true; const results = ImplicitTilingTester.generateSubtreeBuffers(description); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -478,23 +451,21 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability( - subtree, - internalQuadtreeDescription.tileAvailability - ); - expectContentAvailability( - subtree, - internalQuadtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - internalQuadtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability( + subtree, + internalQuadtreeDescription.tileAvailability + ); + expectContentAvailability( + subtree, + internalQuadtreeDescription.contentAvailability + ); + expectChildSubtreeAvailability( + subtree, + internalQuadtreeDescription.childSubtreeAvailability + ); }); - it("handles typed arrays with a byte offset", function () { + it("handles typed arrays with a byte offset", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11010", @@ -527,27 +498,22 @@ describe("Scene/ImplicitSubtree", function () { biggerBuffer.set(results.subtreeBuffer, paddingLength); const subtreeView = new Uint8Array(biggerBuffer.buffer, paddingLength); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, subtreeView, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); }); - it("tile and content availability can share the same buffer", function () { + it("tile and content availability can share the same buffer", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11010", @@ -572,31 +538,26 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - expect(fetchExternal.calls.count()).toEqual(1); - }); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); + expect(fetchExternal.calls.count()).toEqual(1); }); - it("external buffer is fetched if it is used for availability", function () { + it("external buffer is fetched if it is used for availability", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -620,22 +581,20 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal.calls.count()).toEqual(1); - }); + expect(fetchExternal.calls.count()).toEqual(1); }); - it("unused external buffers are not fetched", function () { + it("unused external buffers are not fetched", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -668,19 +627,17 @@ describe("Scene/ImplicitSubtree", function () { Resource.prototype, "fetchArrayBuffer" ).and.returnValue(Promise.resolve(results.externalBuffer)); - const subtree = new ImplicitSubtree( + await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - }); + expect(fetchExternal).not.toHaveBeenCalled(); }); - it("missing contentAvailability is interpreted as 0s", function () { + it("missing contentAvailability is interpreted as 0s", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11010", @@ -703,24 +660,22 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability(subtree, expectedContentAvailability); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, expectedContentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); }); - it("availability works for quadtrees", function () { + it("availability works for quadtrees", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -744,27 +699,22 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); }); - it("computes level offset", function () { + it("computes level offset", async function () { const subtreeDescription = { tileAvailability: { descriptor: "110101111", @@ -787,7 +737,7 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -798,7 +748,7 @@ describe("Scene/ImplicitSubtree", function () { expect(subtree.getLevelOffset(2)).toEqual(9); }); - it("getTileIndex throws for a tile not in the subtree", function () { + it("getTileIndex throws for a tile not in the subtree", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -830,7 +780,7 @@ describe("Scene/ImplicitSubtree", function () { y: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -860,7 +810,7 @@ describe("Scene/ImplicitSubtree", function () { }).toThrowError(RuntimeError); }); - it("getTileIndex computes bit index for a tile in the subtree", function () { + it("getTileIndex computes bit index for a tile in the subtree", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -890,7 +840,7 @@ describe("Scene/ImplicitSubtree", function () { x: 0, y: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -906,40 +856,38 @@ describe("Scene/ImplicitSubtree", function () { x: 0, y: 0, }); - return subtree.readyPromise.then(function () { - const indexFull = subtree.getTileIndex(implicitCoordinatesFull); - expect(indexFull).toBe(1); - expect(subtree.tileIsAvailableAtIndex(indexFull)).toEqual(true); - expect( - subtree.tileIsAvailableAtCoordinates(implicitCoordinatesFull) - ).toEqual(true); - expect(subtree.contentIsAvailableAtIndex(indexFull)).toEqual(true); - expect( - subtree.contentIsAvailableAtCoordinates(implicitCoordinatesFull) - ).toEqual(true); - - // level offset: 1, morton index: 3, so tile index is 1 + 3 = 4 - const implicitCoordinatesEmpty = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 1, - x: 1, - y: 1, - }); - const indexEmpty = subtree.getTileIndex(implicitCoordinatesEmpty); - expect(indexEmpty).toBe(4); - expect(subtree.tileIsAvailableAtIndex(indexEmpty)).toEqual(false); - expect( - subtree.tileIsAvailableAtCoordinates(implicitCoordinatesEmpty) - ).toEqual(false); - expect(subtree.contentIsAvailableAtIndex(indexEmpty)).toEqual(false); - expect( - subtree.contentIsAvailableAtCoordinates(implicitCoordinatesEmpty) - ).toEqual(false); + const indexFull = subtree.getTileIndex(implicitCoordinatesFull); + expect(indexFull).toBe(1); + expect(subtree.tileIsAvailableAtIndex(indexFull)).toEqual(true); + expect( + subtree.tileIsAvailableAtCoordinates(implicitCoordinatesFull) + ).toEqual(true); + expect(subtree.contentIsAvailableAtIndex(indexFull)).toEqual(true); + expect( + subtree.contentIsAvailableAtCoordinates(implicitCoordinatesFull) + ).toEqual(true); + + // level offset: 1, morton index: 3, so tile index is 1 + 3 = 4 + const implicitCoordinatesEmpty = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 1, + x: 1, + y: 1, }); + const indexEmpty = subtree.getTileIndex(implicitCoordinatesEmpty); + expect(indexEmpty).toBe(4); + expect(subtree.tileIsAvailableAtIndex(indexEmpty)).toEqual(false); + expect( + subtree.tileIsAvailableAtCoordinates(implicitCoordinatesEmpty) + ).toEqual(false); + expect(subtree.contentIsAvailableAtIndex(indexEmpty)).toEqual(false); + expect( + subtree.contentIsAvailableAtCoordinates(implicitCoordinatesEmpty) + ).toEqual(false); }); - it("getChildSubtreeIndex throws for a tile not in the child subtrees", function () { + it("getChildSubtreeIndex throws for a tile not in the child subtrees", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -969,7 +917,7 @@ describe("Scene/ImplicitSubtree", function () { x: 0, y: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -999,7 +947,7 @@ describe("Scene/ImplicitSubtree", function () { }).toThrowError(RuntimeError); }); - it("getChildSubtreeIndex computes bit index for a tile in the subtree", function () { + it("getChildSubtreeIndex computes bit index for a tile in the subtree", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -1029,7 +977,7 @@ describe("Scene/ImplicitSubtree", function () { x: 0, y: 0, }); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1045,34 +993,32 @@ describe("Scene/ImplicitSubtree", function () { y: 0, }); - return subtree.readyPromise.then(function () { - // morton index is 0, so child subtree index is 0 - const indexFull = subtree.getChildSubtreeIndex(implicitCoordinatesFull); - expect(indexFull).toBe(0); - expect(subtree.childSubtreeIsAvailableAtIndex(indexFull)).toEqual(true); - expect( - subtree.childSubtreeIsAvailableAtCoordinates(implicitCoordinatesFull) - ).toEqual(true); - - const implicitCoordinatesEmpty = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 2, - x: 1, - y: 1, - }); + // morton index is 0, so child subtree index is 0 + const indexFull = subtree.getChildSubtreeIndex(implicitCoordinatesFull); + expect(indexFull).toBe(0); + expect(subtree.childSubtreeIsAvailableAtIndex(indexFull)).toEqual(true); + expect( + subtree.childSubtreeIsAvailableAtCoordinates(implicitCoordinatesFull) + ).toEqual(true); - // morton index is 3, so child subtree index is 3 - const indexEmpty = subtree.getChildSubtreeIndex(implicitCoordinatesEmpty); - expect(indexEmpty).toBe(3); - expect(subtree.childSubtreeIsAvailableAtIndex(indexEmpty)).toEqual(false); - expect( - subtree.childSubtreeIsAvailableAtCoordinates(implicitCoordinatesEmpty) - ).toEqual(false); + const implicitCoordinatesEmpty = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 2, + x: 1, + y: 1, }); + + // morton index is 3, so child subtree index is 3 + const indexEmpty = subtree.getChildSubtreeIndex(implicitCoordinatesEmpty); + expect(indexEmpty).toBe(3); + expect(subtree.childSubtreeIsAvailableAtIndex(indexEmpty)).toEqual(false); + expect( + subtree.childSubtreeIsAvailableAtCoordinates(implicitCoordinatesEmpty) + ).toEqual(false); }); - it("computes parent Morton index", function () { + it("computes parent Morton index", async function () { const subtreeDescription = { tileAvailability: { descriptor: "110101111", @@ -1095,7 +1041,7 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1108,7 +1054,7 @@ describe("Scene/ImplicitSubtree", function () { expect(subtree.getParentMortonIndex(341)).toBe(42); }); - it("availability works for octrees", function () { + it("availability works for octrees", async function () { const subtreeDescription = { tileAvailability: { descriptor: "110101111", @@ -1132,27 +1078,22 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitOctree, octreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - }); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability + ); }); - it("handles subtree with constant-only data", function () { + it("handles subtree with constant-only data", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1178,71 +1119,22 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription, constantOnly ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitOctree, octreeCoordinates ); - return subtree.readyPromise.then(function () { - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - expectChildSubtreeAvailability( - subtree, - subtreeDescription.childSubtreeAvailability - ); - }); - }); - - it("rejects ready promise on error", function () { - const error = new Error("simulated error"); - spyOn(Promise, "all").and.callFake(function () { - return Promise.reject(error); - }); - const subtreeDescription = { - tileAvailability: { - descriptor: 1, - lengthBits: 5, - isInternal: true, - }, - contentAvailability: [ - { - descriptor: 1, - lengthBits: 5, - isInternal: true, - }, - ], - childSubtreeAvailability: { - descriptor: 0, - lengthBits: 16, - isInternal: true, - }, - }; - - const results = ImplicitTilingTester.generateSubtreeBuffers( - subtreeDescription - ); - const subtree = new ImplicitSubtree( - subtreeResource, - undefined, - results.subtreeBuffer, - implicitQuadtree, - quadtreeCoordinates + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability(subtree, subtreeDescription.contentAvailability); + expectChildSubtreeAvailability( + subtree, + subtreeDescription.childSubtreeAvailability ); - return subtree.readyPromise - .then(function () { - fail(); - }) - .catch(function (error) { - expect(error).toEqual(error); - }); }); - it("destroys", function () { + it("destroys", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11010", @@ -1265,24 +1157,24 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - spyOn(ResourceCache, "load").and.callFake(fakeLoad(results.externalBuffer)); + spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) + ); const unload = spyOn(ResourceCache, "unload"); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, implicitQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const bufferLoader = subtree._bufferLoader; - expect(bufferLoader).toBeDefined(); + const bufferLoader = subtree._bufferLoader; + expect(bufferLoader).toBeDefined(); - expect(subtree.isDestroyed()).toBe(false); - subtree.destroy(); - expect(subtree.isDestroyed()).toBe(true); - expect(unload).toHaveBeenCalled(); - }); + expect(subtree.isDestroyed()).toBe(false); + subtree.destroy(); + expect(subtree.isDestroyed()).toBe(true); + expect(unload).toHaveBeenCalled(); }); describe("multiple contents", function () { @@ -1328,7 +1220,7 @@ describe("Scene/ImplicitSubtree", function () { }); }); - it("contentIsAvailableAtIndex throws for out-of-bounds contentIndex", function () { + it("contentIsAvailableAtIndex throws for out-of-bounds contentIndex", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1356,7 +1248,7 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1365,14 +1257,12 @@ describe("Scene/ImplicitSubtree", function () { ); const outOfBounds = 100; - return subtree.readyPromise.then(function () { - expect(function () { - subtree.contentIsAvailableAtIndex(0, outOfBounds); - }).toThrowDeveloperError(); - }); + expect(function () { + subtree.contentIsAvailableAtIndex(0, outOfBounds); + }).toThrowDeveloperError(); }); - it("contentIsAvailableAtIndex works for multiple contents", function () { + it("contentIsAvailableAtIndex works for multiple contents", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1401,11 +1291,11 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1413,17 +1303,15 @@ describe("Scene/ImplicitSubtree", function () { multipleContentsCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).toHaveBeenCalled(); - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - }); + expect(fetchExternal).toHaveBeenCalled(); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability( + subtree, + subtreeDescription.contentAvailability + ); }); - it("contentIsAvailableAtIndex works for multiple contents (legacy)", function () { + it("contentIsAvailableAtIndex works for multiple contents (legacy)", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1453,11 +1341,11 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1465,14 +1353,12 @@ describe("Scene/ImplicitSubtree", function () { multipleContentsCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).toHaveBeenCalled(); - expectTileAvailability(subtree, subtreeDescription.tileAvailability); - expectContentAvailability( - subtree, - subtreeDescription.contentAvailability - ); - }); + expect(fetchExternal).toHaveBeenCalled(); + expectTileAvailability(subtree, subtreeDescription.tileAvailability); + expectContentAvailability( + subtree, + subtreeDescription.contentAvailability + ); }); }); @@ -1660,7 +1546,7 @@ describe("Scene/ImplicitSubtree", function () { ); }); - it("creates subtree metadata from JSON", function () { + it("creates subtree metadata from JSON", async function () { const metadataSubtreeJson = { tileAvailability: { constant: 1, @@ -1680,7 +1566,7 @@ describe("Scene/ImplicitSubtree", function () { }, }; - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeJsonResource, metadataSubtreeJson, undefined, @@ -1688,19 +1574,17 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const metadata = subtree.metadata; - expect(metadata).toBeDefined(); + const metadata = subtree.metadata; + expect(metadata).toBeDefined(); - expect(metadata.hasProperty("author")).toBe(true); - expect(metadata.hasProperty("credits")).toBe(true); + expect(metadata.hasProperty("author")).toBe(true); + expect(metadata.hasProperty("credits")).toBe(true); - expect(metadata.getProperty("author")).toEqual("Cesium"); - expect(metadata.getProperty("credits")).toEqual(["A", "B", "C"]); - }); + expect(metadata.getProperty("author")).toEqual("Cesium"); + expect(metadata.getProperty("credits")).toEqual(["A", "B", "C"]); }); - it("creates a metadata table from internal metadata for tiles", function () { + it("creates a metadata table from internal metadata for tiles", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1729,10 +1613,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1740,25 +1624,23 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); + expect(fetchExternal).not.toHaveBeenCalled(); - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(5); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(5); - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "highlightColor")).toEqual( - Cartesian3.unpack(highlightColors[i]) - ); - expect(metadataTable.getProperty(i, "buildingCount")).toBe( - buildingCounts[i] - ); - } - }); + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "highlightColor")).toEqual( + Cartesian3.unpack(highlightColors[i]) + ); + expect(metadataTable.getProperty(i, "buildingCount")).toBe( + buildingCounts[i] + ); + } }); - it("creates a metadata table from external metadata for tiles", function () { + it("creates a metadata table from external metadata for tiles", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1787,10 +1669,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1798,25 +1680,23 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).toHaveBeenCalled(); + expect(fetchExternal).toHaveBeenCalled(); - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(5); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(5); - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "highlightColor")).toEqual( - Cartesian3.unpack(highlightColors[i]) - ); - expect(metadataTable.getProperty(i, "buildingCount")).toBe( - buildingCounts[i] - ); - } - }); + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "highlightColor")).toEqual( + Cartesian3.unpack(highlightColors[i]) + ); + expect(metadataTable.getProperty(i, "buildingCount")).toBe( + buildingCounts[i] + ); + } }); - it("creates a metadata table from internal metadata for single content", function () { + it("creates a metadata table from internal metadata for single content", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1845,10 +1725,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1856,28 +1736,26 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(1); - - const metadataTable = metadataTables[0]; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(3); - - for (let i = 0; i < buildingHeights.length; i++) { - expect(metadataTable.getProperty(i, "height")).toEqual( - buildingHeights[i] - ); - expect(metadataTable.getProperty(i, "buildingType")).toBe( - buildingTypes[i] - ); - } - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(1); + + const metadataTable = metadataTables[0]; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(3); + + for (let i = 0; i < buildingHeights.length; i++) { + expect(metadataTable.getProperty(i, "height")).toEqual( + buildingHeights[i] + ); + expect(metadataTable.getProperty(i, "buildingType")).toBe( + buildingTypes[i] + ); + } }); - it("creates a metadata table from external metadata for single content", function () { + it("creates a metadata table from external metadata for single content", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1906,10 +1784,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1917,28 +1795,26 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).toHaveBeenCalled(); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(1); - - const metadataTable = metadataTables[0]; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(3); - - for (let i = 0; i < buildingHeights.length; i++) { - expect(metadataTable.getProperty(i, "height")).toEqual( - buildingHeights[i] - ); - expect(metadataTable.getProperty(i, "buildingType")).toBe( - buildingTypes[i] - ); - } - }); + expect(fetchExternal).toHaveBeenCalled(); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(1); + + const metadataTable = metadataTables[0]; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(3); + + for (let i = 0; i < buildingHeights.length; i++) { + expect(metadataTable.getProperty(i, "height")).toEqual( + buildingHeights[i] + ); + expect(metadataTable.getProperty(i, "buildingType")).toBe( + buildingTypes[i] + ); + } }); - it("creates a metadata table from internal metadata for multiple contents", function () { + it("creates a metadata table from internal metadata for multiple contents", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -1972,10 +1848,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -1983,41 +1859,39 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(2); - - const buildingMetadataTable = metadataTables[0]; - expect(buildingMetadataTable).toBeDefined(); - expect(buildingMetadataTable.count).toBe(3); - - for (let i = 0; i < buildingHeights.length; i++) { - expect(buildingMetadataTable.getProperty(i, "height")).toEqual( - buildingHeights[i] - ); - expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( - buildingTypes[i] - ); - } - - const treeMetadataTable = metadataTables[1]; - expect(treeMetadataTable).toBeDefined(); - expect(treeMetadataTable.count).toBe(4); - - for (let i = 0; i < treeHeights.length; i++) { - expect(treeMetadataTable.getProperty(i, "height")).toEqual( - treeHeights[i] - ); - expect(treeMetadataTable.getProperty(i, "species")).toBe( - treeSpecies[i] - ); - } - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(2); + + const buildingMetadataTable = metadataTables[0]; + expect(buildingMetadataTable).toBeDefined(); + expect(buildingMetadataTable.count).toBe(3); + + for (let i = 0; i < buildingHeights.length; i++) { + expect(buildingMetadataTable.getProperty(i, "height")).toEqual( + buildingHeights[i] + ); + expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( + buildingTypes[i] + ); + } + + const treeMetadataTable = metadataTables[1]; + expect(treeMetadataTable).toBeDefined(); + expect(treeMetadataTable.count).toBe(4); + + for (let i = 0; i < treeHeights.length; i++) { + expect(treeMetadataTable.getProperty(i, "height")).toEqual( + treeHeights[i] + ); + expect(treeMetadataTable.getProperty(i, "species")).toBe( + treeSpecies[i] + ); + } }); - it("creates a metadata table from external metadata for multiple contents", function () { + it("creates a metadata table from external metadata for multiple contents", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2051,10 +1925,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2062,41 +1936,39 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).toHaveBeenCalled(); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(2); - - const buildingMetadataTable = metadataTables[0]; - expect(buildingMetadataTable).toBeDefined(); - expect(buildingMetadataTable.count).toBe(3); - - for (let i = 0; i < buildingHeights.length; i++) { - expect(buildingMetadataTable.getProperty(i, "height")).toEqual( - buildingHeights[i] - ); - expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( - buildingTypes[i] - ); - } - - const treeMetadataTable = metadataTables[1]; - expect(treeMetadataTable).toBeDefined(); - expect(treeMetadataTable.count).toBe(4); - - for (let i = 0; i < treeHeights.length; i++) { - expect(treeMetadataTable.getProperty(i, "height")).toEqual( - treeHeights[i] - ); - expect(treeMetadataTable.getProperty(i, "species")).toBe( - treeSpecies[i] - ); - } - }); + expect(fetchExternal).toHaveBeenCalled(); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(2); + + const buildingMetadataTable = metadataTables[0]; + expect(buildingMetadataTable).toBeDefined(); + expect(buildingMetadataTable.count).toBe(3); + + for (let i = 0; i < buildingHeights.length; i++) { + expect(buildingMetadataTable.getProperty(i, "height")).toEqual( + buildingHeights[i] + ); + expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( + buildingTypes[i] + ); + } + + const treeMetadataTable = metadataTables[1]; + expect(treeMetadataTable).toBeDefined(); + expect(treeMetadataTable.count).toBe(4); + + for (let i = 0; i < treeHeights.length; i++) { + expect(treeMetadataTable.getProperty(i, "height")).toEqual( + treeHeights[i] + ); + expect(treeMetadataTable.getProperty(i, "species")).toBe( + treeSpecies[i] + ); + } }); - it("creates tile metadata view", function () { + it("creates tile metadata view", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2126,11 +1998,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2138,20 +2010,18 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const metadataView = subtree.getTileMetadataView(quadtreeCoordinates); - expect(metadataView).toBeDefined(); - expect(metadataView.getProperty("highlightColor")).toEqual( - Cartesian3.unpack(highlightColors[0]) - ); - expect(metadataView.getProperty("buildingCount")).toEqual( - buildingCounts[0] - ); - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const metadataView = subtree.getTileMetadataView(quadtreeCoordinates); + expect(metadataView).toBeDefined(); + expect(metadataView.getProperty("highlightColor")).toEqual( + Cartesian3.unpack(highlightColors[0]) + ); + expect(metadataView.getProperty("buildingCount")).toEqual( + buildingCounts[0] + ); }); - it("returns undefined tile metadata view for invalid coordinates", function () { + it("returns undefined tile metadata view for invalid coordinates", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -2181,11 +2051,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2193,23 +2063,21 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 1, - x: 1, - y: 1, - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 1, + x: 1, + y: 1, + }); - const metadataView = subtree.getTileMetadataView(coordinates); + const metadataView = subtree.getTileMetadataView(coordinates); - expect(metadataView).not.toBeDefined(); - }); + expect(metadataView).not.toBeDefined(); }); - it("creates content metadata view", function () { + it("creates content metadata view", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2239,11 +2107,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2251,21 +2119,19 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const metadataView = subtree.getContentMetadataView( - quadtreeCoordinates, - 0 - ); - expect(metadataView).toBeDefined(); - expect(metadataView.getProperty("height")).toEqual(buildingHeights[0]); - expect(metadataView.getProperty("buildingType")).toEqual( - buildingTypes[0] - ); - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const metadataView = subtree.getContentMetadataView( + quadtreeCoordinates, + 0 + ); + expect(metadataView).toBeDefined(); + expect(metadataView.getProperty("height")).toEqual(buildingHeights[0]); + expect(metadataView.getProperty("buildingType")).toEqual( + buildingTypes[0] + ); }); - it("returns undefined content metadata view for invalid coordinates", function () { + it("returns undefined content metadata view for invalid coordinates", async function () { const subtreeDescription = { tileAvailability: { descriptor: "11000", @@ -2295,11 +2161,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2307,23 +2173,21 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 1, - x: 1, - y: 1, - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 1, + x: 1, + y: 1, + }); - const metadataView = subtree.getContentMetadataView(coordinates, 0); + const metadataView = subtree.getContentMetadataView(coordinates, 0); - expect(metadataView).not.toBeDefined(); - }); + expect(metadataView).not.toBeDefined(); }); - it("creates content metadata view for multiple contents", function () { + it("creates content metadata view for multiple contents", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2358,11 +2222,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2370,36 +2234,34 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 1, - x: 0, - y: 1, - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 1, + x: 0, + y: 1, + }); - const buildingMetadataView = subtree.getContentMetadataView( - coordinates, - 0 - ); - expect(buildingMetadataView).toBeDefined(); - expect(buildingMetadataView.getProperty("height")).toEqual( - buildingHeights[2] - ); - expect(buildingMetadataView.getProperty("buildingType")).toEqual( - buildingTypes[2] - ); + const buildingMetadataView = subtree.getContentMetadataView( + coordinates, + 0 + ); + expect(buildingMetadataView).toBeDefined(); + expect(buildingMetadataView.getProperty("height")).toEqual( + buildingHeights[2] + ); + expect(buildingMetadataView.getProperty("buildingType")).toEqual( + buildingTypes[2] + ); - const treeMetadataView = subtree.getContentMetadataView(coordinates, 1); - expect(treeMetadataView).toBeDefined(); - expect(treeMetadataView.getProperty("height")).toEqual(treeHeights[2]); - expect(treeMetadataView.getProperty("species")).toEqual(treeSpecies[2]); - }); + const treeMetadataView = subtree.getContentMetadataView(coordinates, 1); + expect(treeMetadataView).toBeDefined(); + expect(treeMetadataView.getProperty("height")).toEqual(treeHeights[2]); + expect(treeMetadataView.getProperty("species")).toEqual(treeSpecies[2]); }); - it("returns undefined content metadata view for invalid coordinates and mutliple contents", function () { + it("returns undefined content metadata view for invalid coordinates and multiple contents", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2434,11 +2296,11 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2446,31 +2308,29 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const coordinates = new ImplicitTileCoordinates({ - subdivisionScheme: implicitQuadtree.subdivisionScheme, - subtreeLevels: implicitQuadtree.subtreeLevels, - level: 1, - x: 1, - y: 1, - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const coordinates = new ImplicitTileCoordinates({ + subdivisionScheme: implicitQuadtree.subdivisionScheme, + subtreeLevels: implicitQuadtree.subtreeLevels, + level: 1, + x: 1, + y: 1, + }); - const buildingMetadataView = subtree.getContentMetadataView( - coordinates, - 0 - ); - expect(buildingMetadataView).not.toBeDefined(); + const buildingMetadataView = subtree.getContentMetadataView( + coordinates, + 0 + ); + expect(buildingMetadataView).not.toBeDefined(); - const treeMetadataView = subtree.getContentMetadataView( - quadtreeCoordinates, - 1 - ); - expect(treeMetadataView).not.toBeDefined(); - }); + const treeMetadataView = subtree.getContentMetadataView( + quadtreeCoordinates, + 1 + ); + expect(treeMetadataView).not.toBeDefined(); }); - it("handles 3DTILES_metadata extension for backwards compatibility", function () { + it("handles 3DTILES_metadata extension for backwards compatibility", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2500,10 +2360,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2511,28 +2371,26 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(1); - - const metadataTable = metadataTables[0]; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(3); - - for (let i = 0; i < buildingHeights.length; i++) { - expect(metadataTable.getProperty(i, "height")).toEqual( - buildingHeights[i] - ); - expect(metadataTable.getProperty(i, "buildingType")).toBe( - buildingTypes[i] - ); - } - }); + expect(fetchExternal).not.toHaveBeenCalled(); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(1); + + const metadataTable = metadataTables[0]; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(3); + + for (let i = 0; i < buildingHeights.length; i++) { + expect(metadataTable.getProperty(i, "height")).toEqual( + buildingHeights[i] + ); + expect(metadataTable.getProperty(i, "buildingType")).toBe( + buildingTypes[i] + ); + } }); - it("works correctly if availableCount is undefined", function () { + it("works correctly if availableCount is undefined", async function () { const subtreeDescription = { tileAvailability: { descriptor: 1, @@ -2562,10 +2420,10 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const fetchExternal = spyOn(ResourceCache, "load").and.callFake( - fakeLoad(results.externalBuffer) + const fetchExternal = spyOn(ResourceCache, "get").and.callFake( + fakeResourceLoader(results.externalBuffer) ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2573,25 +2431,23 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(fetchExternal).not.toHaveBeenCalled(); + expect(fetchExternal).not.toHaveBeenCalled(); - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(5); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(5); - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "highlightColor")).toEqual( - Cartesian3.unpack(highlightColors[i]) - ); - expect(metadataTable.getProperty(i, "buildingCount")).toBe( - buildingCounts[i] - ); - } - }); + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "highlightColor")).toEqual( + Cartesian3.unpack(highlightColors[i]) + ); + expect(metadataTable.getProperty(i, "buildingCount")).toBe( + buildingCounts[i] + ); + } }); - it("handles unavailable tiles correctly", function () { + it("handles unavailable tiles correctly", async function () { const highlightColors = [ [255, 0, 0], [255, 255, 0], @@ -2641,34 +2497,30 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, tileMetadataQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - expect(subtree._tileJumpBuffer).toEqual( - new Uint8Array([0, 0, 0, 1, 2]) - ); + expect(subtree._tileJumpBuffer).toEqual(new Uint8Array([0, 0, 0, 1, 2])); - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(3); - - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "highlightColor")).toEqual( - Cartesian3.unpack(highlightColors[i]) - ); - expect(metadataTable.getProperty(i, "buildingCount")).toBe( - buildingCounts[i] - ); - } - }); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(3); + + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "highlightColor")).toEqual( + Cartesian3.unpack(highlightColors[i]) + ); + expect(metadataTable.getProperty(i, "buildingCount")).toBe( + buildingCounts[i] + ); + } }); - it("handles unavailable content correctly", function () { + it("handles unavailable content correctly", async function () { const buildingHeightsTruncated = buildingHeights.slice(0, 2); const buildingTypesTruncated = buildingTypes.slice(0, 2); @@ -2701,7 +2553,7 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2709,30 +2561,28 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const jumpBuffer = subtree._contentJumpBuffers[0]; - expect(jumpBuffer).toEqual(new Uint8Array([0, 0, 0, 1, 0])); + const jumpBuffer = subtree._contentJumpBuffers[0]; + expect(jumpBuffer).toEqual(new Uint8Array([0, 0, 0, 1, 0])); - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(1); + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(1); - const metadataTable = metadataTables[0]; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(2); + const metadataTable = metadataTables[0]; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(2); - for (let i = 0; i < buildingHeightsTruncated.length; i++) { - expect(metadataTable.getProperty(i, "height")).toEqual( - buildingHeightsTruncated[i] - ); - expect(metadataTable.getProperty(i, "buildingType")).toBe( - buildingTypesTruncated[i] - ); - } - }); + for (let i = 0; i < buildingHeightsTruncated.length; i++) { + expect(metadataTable.getProperty(i, "height")).toEqual( + buildingHeightsTruncated[i] + ); + expect(metadataTable.getProperty(i, "buildingType")).toBe( + buildingTypesTruncated[i] + ); + } }); - it("handles unavailable multiple contents correctly", function () { + it("handles unavailable multiple contents correctly", async function () { const buildingHeightsTruncated = buildingHeights.slice(0, 1); const buildingTypesTruncated = buildingTypes.slice(0, 1); @@ -2773,7 +2623,7 @@ describe("Scene/ImplicitSubtree", function () { subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, @@ -2781,46 +2631,44 @@ describe("Scene/ImplicitSubtree", function () { quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const buildingJumpBuffer = subtree._contentJumpBuffers[0]; - expect(buildingJumpBuffer).toEqual(new Uint8Array([0, 0, 0, 0, 0])); - - const treeJumpBuffer = subtree._contentJumpBuffers[1]; - expect(treeJumpBuffer).toEqual(new Uint8Array([0, 0, 0, 0, 1])); - - const metadataTables = subtree.contentMetadataTables; - expect(metadataTables).toBeDefined(); - expect(metadataTables.length).toBe(2); - - const buildingMetadataTable = metadataTables[0]; - expect(buildingMetadataTable).toBeDefined(); - expect(buildingMetadataTable.count).toBe(1); - - for (let i = 0; i < buildingHeightsTruncated.length; i++) { - expect(buildingMetadataTable.getProperty(i, "height")).toEqual( - buildingHeightsTruncated[i] - ); - expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( - buildingTypesTruncated[i] - ); - } - - const treeMetadataTable = metadataTables[1]; - expect(treeMetadataTable).toBeDefined(); - expect(treeMetadataTable.count).toBe(2); - - for (let i = 0; i < treeHeightsTruncated.length; i++) { - expect(treeMetadataTable.getProperty(i, "height")).toEqual( - treeHeightsTruncated[i] - ); - expect(treeMetadataTable.getProperty(i, "species")).toBe( - treeSpeciesTruncated[i] - ); - } - }); + const buildingJumpBuffer = subtree._contentJumpBuffers[0]; + expect(buildingJumpBuffer).toEqual(new Uint8Array([0, 0, 0, 0, 0])); + + const treeJumpBuffer = subtree._contentJumpBuffers[1]; + expect(treeJumpBuffer).toEqual(new Uint8Array([0, 0, 0, 0, 1])); + + const metadataTables = subtree.contentMetadataTables; + expect(metadataTables).toBeDefined(); + expect(metadataTables.length).toBe(2); + + const buildingMetadataTable = metadataTables[0]; + expect(buildingMetadataTable).toBeDefined(); + expect(buildingMetadataTable.count).toBe(1); + + for (let i = 0; i < buildingHeightsTruncated.length; i++) { + expect(buildingMetadataTable.getProperty(i, "height")).toEqual( + buildingHeightsTruncated[i] + ); + expect(buildingMetadataTable.getProperty(i, "buildingType")).toBe( + buildingTypesTruncated[i] + ); + } + + const treeMetadataTable = metadataTables[1]; + expect(treeMetadataTable).toBeDefined(); + expect(treeMetadataTable.count).toBe(2); + + for (let i = 0; i < treeHeightsTruncated.length; i++) { + expect(treeMetadataTable.getProperty(i, "height")).toEqual( + treeHeightsTruncated[i] + ); + expect(treeMetadataTable.getProperty(i, "species")).toBe( + treeSpeciesTruncated[i] + ); + } }); - it("handles metadata with string and array offsets", function () { + it("handles metadata with string and array offsets", async function () { if (!MetadataTester.isSupported()) { return; } @@ -2906,33 +2754,31 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, arrayQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(5); - - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "stringProperty")).toBe( - stringValues[i] - ); - expect(metadataTable.getProperty(i, "arrayProperty")).toEqual( - arrayValues[i] - ); - expect(metadataTable.getProperty(i, "arrayOfStringProperty")).toEqual( - stringArrayValues[i] - ); - } - }); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(5); + + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "stringProperty")).toBe( + stringValues[i] + ); + expect(metadataTable.getProperty(i, "arrayProperty")).toEqual( + arrayValues[i] + ); + expect(metadataTable.getProperty(i, "arrayOfStringProperty")).toEqual( + stringArrayValues[i] + ); + } }); - it("handles legacy 3DTILES_metadata schema correctly for arrays and strings", function () { + it("handles legacy 3DTILES_metadata schema correctly for arrays and strings", async function () { if (!MetadataTester.isSupported()) { return; } @@ -3019,30 +2865,28 @@ describe("Scene/ImplicitSubtree", function () { const results = ImplicitTilingTester.generateSubtreeBuffers( subtreeDescription ); - const subtree = new ImplicitSubtree( + const subtree = await ImplicitSubtree.fromSubtreeJson( subtreeResource, undefined, results.subtreeBuffer, arrayQuadtree, quadtreeCoordinates ); - return subtree.readyPromise.then(function () { - const metadataTable = subtree.tileMetadataTable; - expect(metadataTable).toBeDefined(); - expect(metadataTable.count).toBe(5); - - for (let i = 0; i < buildingCounts.length; i++) { - expect(metadataTable.getProperty(i, "stringProperty")).toBe( - stringValues[i] - ); - expect(metadataTable.getProperty(i, "arrayProperty")).toEqual( - arrayValues[i] - ); - expect(metadataTable.getProperty(i, "arrayOfStringProperty")).toEqual( - stringArrayValues[i] - ); - } - }); + const metadataTable = subtree.tileMetadataTable; + expect(metadataTable).toBeDefined(); + expect(metadataTable.count).toBe(5); + + for (let i = 0; i < buildingCounts.length; i++) { + expect(metadataTable.getProperty(i, "stringProperty")).toBe( + stringValues[i] + ); + expect(metadataTable.getProperty(i, "arrayProperty")).toEqual( + arrayValues[i] + ); + expect(metadataTable.getProperty(i, "arrayOfStringProperty")).toEqual( + stringArrayValues[i] + ); + } }); }); }); diff --git a/packages/engine/Specs/Scene/Model/B3dmLoaderSpec.js b/packages/engine/Specs/Scene/Model/B3dmLoaderSpec.js index 2db292a8c4e..7933375ca4b 100644 --- a/packages/engine/Specs/Scene/Model/B3dmLoaderSpec.js +++ b/packages/engine/Specs/Scene/Model/B3dmLoaderSpec.js @@ -52,15 +52,15 @@ describe( ResourceCache.clearForSpecs(); }); - function loadB3dmArrayBuffer(resource, arrayBuffer) { + async function loadB3dmArrayBuffer(resource, arrayBuffer) { const loader = new B3dmLoader({ b3dmResource: resource, arrayBuffer: arrayBuffer, }); b3dmLoaders.push(loader); - loader.load(); - - return waitForLoaderProcess(loader, scene); + await loader.load(); + await waitForLoaderProcess(loader, scene); + return loader; } function loadB3dm(b3dmPath) { @@ -73,11 +73,11 @@ describe( }); } - function expectLoadError(arrayBuffer) { + async function expectLoadError(arrayBuffer) { const resource = new Resource("http://example.com/test.b3dm"); - expect(function () { - return loadB3dmArrayBuffer(resource, arrayBuffer); - }).toThrowError(RuntimeError); + await expectAsync( + loadB3dmArrayBuffer(resource, arrayBuffer) + ).toBeRejectedWithError(RuntimeError); } it("releases array buffer when finished loading", function () { @@ -154,17 +154,17 @@ describe( }); }); - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generateBatchedTileBuffer({ version: 2, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws with empty gltf", function () { + it("throws with empty gltf", async function () { // Expect to throw DeveloperError in Model due to invalid gltf magic const arrayBuffer = Cesium3DTilesTester.generateBatchedTileBuffer(); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); it("destroys b3dm loader", function () { diff --git a/packages/engine/Specs/Scene/Model/DequantizationPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/DequantizationPipelineStageSpec.js index df23fe2f23c..c8eed6be5bd 100644 --- a/packages/engine/Specs/Scene/Model/DequantizationPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/DequantizationPipelineStageSpec.js @@ -61,12 +61,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources() { diff --git a/packages/engine/Specs/Scene/Model/FeatureIdPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/FeatureIdPipelineStageSpec.js index e73c69036a8..13cd3feaf75 100644 --- a/packages/engine/Specs/Scene/Model/FeatureIdPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/FeatureIdPipelineStageSpec.js @@ -68,12 +68,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(node) { diff --git a/packages/engine/Specs/Scene/Model/GeoJsonLoaderSpec.js b/packages/engine/Specs/Scene/Model/GeoJsonLoaderSpec.js index 0d399bcfc58..adb5ca1b8bd 100644 --- a/packages/engine/Specs/Scene/Model/GeoJsonLoaderSpec.js +++ b/packages/engine/Specs/Scene/Model/GeoJsonLoaderSpec.js @@ -55,18 +55,19 @@ describe( ResourceCache.clearForSpecs(); }); - function loadGeoJson(geoJsonPath) { - return Resource.fetchJson({ + async function loadGeoJson(geoJsonPath) { + const json = await Resource.fetchJson({ url: geoJsonPath, - }).then(function (json) { - const loader = new GeoJsonLoader({ - geoJson: json, - }); - geoJsonLoaders.push(loader); - loader.load(); - - return waitForLoaderProcess(loader, scene); }); + + const loader = new GeoJsonLoader({ + geoJson: json, + }); + + geoJsonLoaders.push(loader); + await loader.load(); + await waitForLoaderProcess(loader, scene); + return loader; } function getAttribute(attributes, semantic, setIndex) { diff --git a/packages/engine/Specs/Scene/Model/GeometryPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/GeometryPipelineStageSpec.js index 1fea0d0f060..cc34a4795f4 100644 --- a/packages/engine/Specs/Scene/Model/GeometryPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/GeometryPipelineStageSpec.js @@ -132,12 +132,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(primitive) { diff --git a/packages/engine/Specs/Scene/Model/I3dmLoaderSpec.js b/packages/engine/Specs/Scene/Model/I3dmLoaderSpec.js index 3a565948bdb..b3243f50772 100644 --- a/packages/engine/Specs/Scene/Model/I3dmLoaderSpec.js +++ b/packages/engine/Specs/Scene/Model/I3dmLoaderSpec.js @@ -68,37 +68,37 @@ describe( ResourceCache.clearForSpecs(); }); - function loadI3dm(path) { + async function loadI3dm(path) { const resource = Resource.createIfNeeded(path); - return Resource.fetchArrayBuffer({ + const arrayBuffer = await Resource.fetchArrayBuffer({ url: path, - }).then(function (arrayBuffer) { - const loader = new I3dmLoader({ - i3dmResource: resource, - arrayBuffer: arrayBuffer, - }); - i3dmLoaders.push(loader); - loader.load(); - - return waitForLoaderProcess(loader, scene); }); + const loader = new I3dmLoader({ + i3dmResource: resource, + arrayBuffer: arrayBuffer, + }); + i3dmLoaders.push(loader); + await loader.load(); + await waitForLoaderProcess(loader, scene); + return loader; } - function expectLoadError(arrayBuffer) { - expect(function () { - const resource = Resource.createIfNeeded( - "http://example.com/content.i3dm" - ); - const loader = new I3dmLoader({ - i3dmResource: resource, - arrayBuffer: arrayBuffer, - }); - i3dmLoaders.push(loader); - loader.load(); - - return waitForLoaderProcess(loader, scene); - }).toThrowError(RuntimeError); + async function expectLoadError(arrayBuffer) { + const resource = Resource.createIfNeeded( + "http://example.com/content.i3dm" + ); + const loader = new I3dmLoader({ + i3dmResource: resource, + arrayBuffer: arrayBuffer, + }); + i3dmLoaders.push(loader); + await expectAsync( + (async () => { + await loader.load(); + await waitForLoaderProcess(loader, scene); + })() + ).toBeRejectedWithError(RuntimeError); } function verifyInstances(loader, expectedSemantics, instancesLength) { @@ -394,18 +394,18 @@ describe( }); }); - it("throws with invalid format", function () { + it("throws with invalid format", async function () { const arrayBuffer = Cesium3DTilesTester.generateInstancedTileBuffer({ gltfFormat: 2, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generateInstancedTileBuffer({ version: 2, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); }, "WebGL" diff --git a/packages/engine/Specs/Scene/Model/InstancingPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/InstancingPipelineStageSpec.js index 6c77534d7d2..bc739a877da 100644 --- a/packages/engine/Specs/Scene/Model/InstancingPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/InstancingPipelineStageSpec.js @@ -133,25 +133,23 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } - function loadI3dm(i3dmPath) { - const result = Resource.fetchArrayBuffer(i3dmPath); - - return result.then(function (arrayBuffer) { - const i3dmLoader = new I3dmLoader( - getI3dmOptions(i3dmPath, { arrayBuffer: arrayBuffer }) - ); - gltfLoaders.push(i3dmLoader); - i3dmLoader.load(); - return waitForLoaderProcess(i3dmLoader, scene); - }); + async function loadI3dm(i3dmPath) { + const arrayBuffer = await Resource.fetchArrayBuffer(i3dmPath); + const i3dmLoader = new I3dmLoader( + getI3dmOptions(i3dmPath, { arrayBuffer: arrayBuffer }) + ); + gltfLoaders.push(i3dmLoader); + await i3dmLoader.load(); + await waitForLoaderProcess(i3dmLoader, scene); + return i3dmLoader; } function verifyTypedArraysUnloaded(instances) { diff --git a/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js index 76770a79b07..c5b9cd0edd5 100644 --- a/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js @@ -67,12 +67,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } const boomBox = "./Data/Models/glTF-2.0/BoomBox/glTF/BoomBox.gltf"; diff --git a/packages/engine/Specs/Scene/Model/MetadataPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/MetadataPipelineStageSpec.js index 42cd1bbc4c7..2a8f0f2197d 100644 --- a/packages/engine/Specs/Scene/Model/MetadataPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/MetadataPipelineStageSpec.js @@ -56,15 +56,15 @@ describe( ResourceCache.clearForSpecs(); }); - function loadGltf(gltfPath) { + async function loadGltf(gltfPath) { const gltfLoader = new GltfLoader({ gltfResource: new Resource({ url: gltfPath }), incrementallyLoadTextures: false, }); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(components) { diff --git a/packages/engine/Specs/Scene/Model/Model3DTileContentSpec.js b/packages/engine/Specs/Scene/Model/Model3DTileContentSpec.js index efd033a07c3..857ba637ed7 100644 --- a/packages/engine/Specs/Scene/Model/Model3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Model/Model3DTileContentSpec.js @@ -1275,12 +1275,22 @@ describe( setCamera(centerLongitude, centerLatitude, 100.0); }); - it("resolves readyPromise with glb", function () { - return Cesium3DTilesTester.resolvesReadyPromise(scene, glbContentUrl); + it("becomes ready with glb", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + glbContentUrl + ); + expect(tileset.root.contentReady).toBeTrue(); + expect(tileset.root.content).toBeDefined(); }); - it("resolves readyPromise with glTF", function () { - return Cesium3DTilesTester.resolvesReadyPromise(scene, gltfContentUrl); + it("becomes ready with glTF", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( + scene, + gltfContentUrl + ); + expect(tileset.root.contentReady).toBeTrue(); + expect(tileset.root.content).toBeDefined(); }); it("renders glb content", function () { diff --git a/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js b/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js index 17e69035133..cc938fab972 100644 --- a/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelAnimationCollectionSpec.js @@ -520,7 +520,7 @@ describe( ).then(function () { expect(spyStart).toHaveBeenCalledWith(model, animation); - expect(spyUpdate.calls.count()).toEqual(2); + expect(spyUpdate.calls.count()).toBeGreaterThanOrEqual(2); expect(spyUpdate.calls.argsFor(0)[0]).toBe(model); expect(spyUpdate.calls.argsFor(0)[1]).toBe(animation); diff --git a/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js b/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js index d4c912fff10..eddd956faa5 100644 --- a/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelMatrixUpdateStageSpec.js @@ -6,6 +6,7 @@ import { Matrix4, Math as CesiumMath, ModelDrawCommand, + ModelRuntimePrimitive, ResourceCache, Quaternion, } from "../../../index.js"; @@ -63,6 +64,13 @@ describe( material: { doubleSided: false, }, + attributes: [ + { + semantic: "POSITION", + max: new Cartesian3(0.5, 2.0, 0.0), + min: new Cartesian3(-0.5, 0.0, 0.0), + }, + ], }; function mockRenderResources(model) { @@ -90,30 +98,36 @@ describe( const rootNode = getParentRootNode(model); const rootDrawCommand = clone(drawCommand); - rootDrawCommand.modelMatrix = new Matrix4(); + rootDrawCommand.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); rootDrawCommand.boundingVolume = new BoundingSphere(); - rootNode.runtimePrimitives.push({ - updateStages: [], - drawCommand: new ModelDrawCommand({ - command: rootDrawCommand, - primitiveRenderResources: renderResources, - }), + let runtimePrimitive = new ModelRuntimePrimitive({ + node: rootNode, + model: model, primitive: mockPrimitive, }); + runtimePrimitive.drawCommand = new ModelDrawCommand({ + command: rootDrawCommand, + primitiveRenderResources: renderResources, + }); + spyOn(runtimePrimitive, "configurePipeline"); + rootNode.runtimePrimitives.push(runtimePrimitive); rootNode._transformDirty = true; const leafNode = getChildLeafNode(model); const leafDrawCommand = clone(drawCommand); - leafDrawCommand.modelMatrix = new Matrix4(); + leafDrawCommand.modelMatrix = Matrix4.clone(Matrix4.IDENTITY); leafDrawCommand.boundingVolume = new BoundingSphere(); - leafNode.runtimePrimitives.push({ - updateStages: [], - drawCommand: new ModelDrawCommand({ - command: leafDrawCommand, - primitiveRenderResources: renderResources, - }), + runtimePrimitive = new ModelRuntimePrimitive({ + node: leafNode, + model: model, primitive: mockPrimitive, }); + runtimePrimitive.drawCommand = new ModelDrawCommand({ + command: leafDrawCommand, + primitiveRenderResources: renderResources, + }); + spyOn(runtimePrimitive, "configurePipeline"); + leafNode.runtimePrimitives.push(runtimePrimitive); leafNode._transformDirty = true; } @@ -209,9 +223,9 @@ describe( const staticLeafNode = getStaticLeafNode(model); const transformedLeafNode = getChildLeafNode(model); - const rootDrawCommand = getDrawCommand(rootNode); - const staticDrawCommand = getDrawCommand(staticLeafNode); - const transformedDrawCommand = getDrawCommand(transformedLeafNode); + let rootDrawCommand = getDrawCommand(rootNode); + let staticDrawCommand = getDrawCommand(staticLeafNode); + let transformedDrawCommand = getDrawCommand(transformedLeafNode); const childTransformation = Matrix4.fromTranslation( new Cartesian3(0, 5, 0) @@ -246,6 +260,9 @@ describe( ); scene.renderForSpecs(); + rootDrawCommand = getDrawCommand(rootNode); + staticDrawCommand = getDrawCommand(staticLeafNode); + transformedDrawCommand = getDrawCommand(transformedLeafNode); expect(rootDrawCommand.modelMatrix).toEqual(expectedRootModelMatrix); expect(staticDrawCommand.modelMatrix).toEqual( @@ -271,9 +288,9 @@ describe( const staticLeafNode = getStaticLeafNode(model); const transformedLeafNode = getChildLeafNode(model); - const rootDrawCommand = getDrawCommand(rootNode); - const staticDrawCommand = getDrawCommand(staticLeafNode); - const transformedDrawCommand = getDrawCommand(transformedLeafNode); + let rootDrawCommand = getDrawCommand(rootNode); + let staticDrawCommand = getDrawCommand(staticLeafNode); + let transformedDrawCommand = getDrawCommand(transformedLeafNode); const expectedRootModelMatrix = Matrix4.multiplyTransformation( modelMatrix, @@ -294,6 +311,10 @@ describe( model.modelMatrix = modelMatrix; scene.renderForSpecs(); + rootDrawCommand = getDrawCommand(rootNode); + staticDrawCommand = getDrawCommand(staticLeafNode); + transformedDrawCommand = getDrawCommand(transformedLeafNode); + expect(rootDrawCommand.modelMatrix).toEqual(expectedRootModelMatrix); expect(staticDrawCommand.modelMatrix).toEqual( expectedStaticLeafModelMatrix @@ -325,9 +346,9 @@ describe( const staticLeafNode = getStaticLeafNode(model); const transformedLeafNode = getChildLeafNode(model); - const rootDrawCommand = getDrawCommand(rootNode); - const staticDrawCommand = getDrawCommand(staticLeafNode); - const transformedDrawCommand = getDrawCommand(transformedLeafNode); + let rootDrawCommand = getDrawCommand(rootNode); + let staticDrawCommand = getDrawCommand(staticLeafNode); + let transformedDrawCommand = getDrawCommand(transformedLeafNode); const expectedRootModelMatrix = Matrix4.multiplyTransformation( scaledModelMatrix, @@ -348,6 +369,9 @@ describe( model.modelMatrix = modelMatrix; model.scale = modelScale; scene.renderForSpecs(); + rootDrawCommand = getDrawCommand(rootNode); + staticDrawCommand = getDrawCommand(staticLeafNode); + transformedDrawCommand = getDrawCommand(transformedLeafNode); expect(rootDrawCommand.modelMatrix).toEqual(expectedRootModelMatrix); expect(staticDrawCommand.modelMatrix).toEqual( diff --git a/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js b/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js index e3e8f2873cd..b5196ff355d 100644 --- a/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSceneGraphSpec.js @@ -170,8 +170,6 @@ describe( expect(ModelSceneGraph.prototype.pushDrawCommands).toHaveBeenCalled(); expect(frameState.commandList.length).toEqual(primitivesCount); - expect(model._drawCommandsBuilt).toEqual(true); - // Reset the draw command list to see if they're re-built. model._drawCommandsBuilt = false; frameState.commandList.length = 0; diff --git a/packages/engine/Specs/Scene/Model/ModelSpec.js b/packages/engine/Specs/Scene/Model/ModelSpec.js index 2ccd2cb068d..ee3c3260f58 100644 --- a/packages/engine/Specs/Scene/Model/ModelSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSpec.js @@ -345,16 +345,16 @@ describe( model.errorEvent.addEventListener((e) => { expect(e).toBeInstanceOf(RuntimeError); + expect(e.message).toContain("Failed to load texture"); expect(e.message).toContain( - `Failed to load model: ${boxTexturedGltfUrl}` + "Failed to load image: non-existent-path.png" ); - expect(e.message).toContain("Failed to load texture"); finished = true; }); return pollToPromise(function () { scene.renderForSpecs(); - return finished; + return model.ready && finished; }); }); diff --git a/packages/engine/Specs/Scene/Model/MorphTargetsPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/MorphTargetsPipelineStageSpec.js index 3bf6dea562e..82b547bd50d 100644 --- a/packages/engine/Specs/Scene/Model/MorphTargetsPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/MorphTargetsPipelineStageSpec.js @@ -51,12 +51,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function verifyMorphTargetAttribute( diff --git a/packages/engine/Specs/Scene/Model/NodeStatisticsPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/NodeStatisticsPipelineStageSpec.js index f301ba11916..d900e93dbbd 100644 --- a/packages/engine/Specs/Scene/Model/NodeStatisticsPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/NodeStatisticsPipelineStageSpec.js @@ -54,12 +54,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(components) { diff --git a/packages/engine/Specs/Scene/Model/PickingPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/PickingPipelineStageSpec.js index 180ffe197d3..5e44cd7e1c6 100644 --- a/packages/engine/Specs/Scene/Model/PickingPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/PickingPipelineStageSpec.js @@ -58,12 +58,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources() { diff --git a/packages/engine/Specs/Scene/Model/PntsLoaderSpec.js b/packages/engine/Specs/Scene/Model/PntsLoaderSpec.js index 9b4c030a1d2..5fec3e9e999 100644 --- a/packages/engine/Specs/Scene/Model/PntsLoaderSpec.js +++ b/packages/engine/Specs/Scene/Model/PntsLoaderSpec.js @@ -79,15 +79,16 @@ describe( ResourceCache.clearForSpecs(); }); - function loadPntsArrayBuffer(arrayBuffer, options) { + async function loadPntsArrayBuffer(arrayBuffer, options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); const loader = new PntsLoader({ arrayBuffer: arrayBuffer, loadAttributesFor2D: options.loadAttributesFor2D, }); pntsLoaders.push(loader); - loader.load(); - return waitForLoaderProcess(loader, scene); + await loader.load(); + await waitForLoaderProcess(loader, scene); + return loader; } function loadPnts(pntsPath, options) { @@ -98,10 +99,10 @@ describe( }); } - function expectLoadError(arrayBuffer) { - expect(function () { - return loadPntsArrayBuffer(arrayBuffer); - }).toThrowError(RuntimeError); + async function expectLoadError(arrayBuffer) { + await expectAsync(loadPntsArrayBuffer(arrayBuffer)).toBeRejectedWithError( + RuntimeError + ); } function expectEmptyMetadata(structuralMetadata) { @@ -765,21 +766,21 @@ describe( ); }); - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ version: 2, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if featureTableJsonByteLength is 0", function () { + it("throws if featureTableJsonByteLength is 0", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJsonByteLength: 0, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if the feature table does not contain POINTS_LENGTH", function () { + it("throws if the feature table does not contain POINTS_LENGTH", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJson: { POSITION: { @@ -787,19 +788,19 @@ describe( }, }, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if the feature table does not contain POSITION or POSITION_QUANTIZED", function () { + it("throws if the feature table does not contain POSITION or POSITION_QUANTIZED", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJson: { POINTS_LENGTH: 1, }, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if the positions are quantized and the feature table does not contain QUANTIZED_VOLUME_SCALE", function () { + it("throws if the positions are quantized and the feature table does not contain QUANTIZED_VOLUME_SCALE", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJson: { POINTS_LENGTH: 1, @@ -809,10 +810,10 @@ describe( QUANTIZED_VOLUME_OFFSET: [0.0, 0.0, 0.0], }, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if the positions are quantized and the feature table does not contain QUANTIZED_VOLUME_OFFSET", function () { + it("throws if the positions are quantized and the feature table does not contain QUANTIZED_VOLUME_OFFSET", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJson: { POINTS_LENGTH: 1, @@ -822,10 +823,10 @@ describe( QUANTIZED_VOLUME_SCALE: [1.0, 1.0, 1.0], }, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("throws if the BATCH_ID semantic is defined but BATCH_LENGTH is not", function () { + it("throws if the BATCH_ID semantic is defined but BATCH_LENGTH is not", async function () { const arrayBuffer = Cesium3DTilesTester.generatePointCloudTileBuffer({ featureTableJson: { POINTS_LENGTH: 2, @@ -833,29 +834,24 @@ describe( BATCH_ID: [0, 1], }, }); - expectLoadError(arrayBuffer); + await expectLoadError(arrayBuffer); }); - it("error decoding a draco point cloud causes loading to fail", function () { + it("error decoding a draco point cloud causes loading to fail", async function () { const readyPromise = pollToPromise(function () { return DracoLoader._taskProcessorReady; }); DracoLoader._getDecoderTaskProcessor(); - return readyPromise - .then(function () { - const decoder = DracoLoader._getDecoderTaskProcessor(); - spyOn(decoder, "scheduleTask").and.callFake(function () { - return Promise.reject({ message: "my error" }); - }); - - return loadPnts(pointCloudDracoUrl); - }) - .then(function () { - fail("should not resolve"); - }) - .catch(function (error) { - expect(error.message).toBe("Failed to load Draco pnts\nmy error"); - }); + await readyPromise; + const decoder = DracoLoader._getDecoderTaskProcessor(); + spyOn(decoder, "scheduleTask").and.callFake(function () { + return Promise.reject({ message: "my error" }); + }); + + await expectAsync(loadPnts(pointCloudDracoUrl)).toBeRejectedWithError( + RuntimeError, + "Failed to load Draco pnts\nmy error" + ); }); it("destroys pnts loader", function () { diff --git a/packages/engine/Specs/Scene/Model/PrimitiveOutlinePipelineStageSpec.js b/packages/engine/Specs/Scene/Model/PrimitiveOutlinePipelineStageSpec.js index 4a124406ce7..fa37b883cca 100644 --- a/packages/engine/Specs/Scene/Model/PrimitiveOutlinePipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/PrimitiveOutlinePipelineStageSpec.js @@ -59,12 +59,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources() { diff --git a/packages/engine/Specs/Scene/Model/PrimitiveStatisticsPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/PrimitiveStatisticsPipelineStageSpec.js index d7e9cc58021..54c2840a8f3 100644 --- a/packages/engine/Specs/Scene/Model/PrimitiveStatisticsPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/PrimitiveStatisticsPipelineStageSpec.js @@ -78,12 +78,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockModel(components) { diff --git a/packages/engine/Specs/Scene/Model/SceneMode2DPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/SceneMode2DPipelineStageSpec.js index 11b7a49ea70..e5998f7f031 100644 --- a/packages/engine/Specs/Scene/Model/SceneMode2DPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/SceneMode2DPipelineStageSpec.js @@ -64,12 +64,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources() { diff --git a/packages/engine/Specs/Scene/Model/SelectedFeatureIdPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/SelectedFeatureIdPipelineStageSpec.js index 67e9d4af542..afa2f5da13d 100644 --- a/packages/engine/Specs/Scene/Model/SelectedFeatureIdPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/SelectedFeatureIdPipelineStageSpec.js @@ -83,12 +83,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(node) { diff --git a/packages/engine/Specs/Scene/Model/SkinningPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/SkinningPipelineStageSpec.js index ade501bca76..4449c281bfd 100644 --- a/packages/engine/Specs/Scene/Model/SkinningPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/SkinningPipelineStageSpec.js @@ -50,12 +50,12 @@ describe( }); } - function loadGltf(gltfPath, options) { + async function loadGltf(gltfPath, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } const simpleSkinUrl = @@ -139,7 +139,6 @@ describe( return loadGltf(cesiumManUrl).then(function (gltfLoader) { const components = gltfLoader.components; const primitive = components.nodes[1].primitives[0]; - console.log(components); SkinningPipelineStage.process(renderResources, primitive); diff --git a/packages/engine/Specs/Scene/Model/WireframePipelineStageSpec.js b/packages/engine/Specs/Scene/Model/WireframePipelineStageSpec.js index f7e93c7892c..5cf9183b999 100644 --- a/packages/engine/Specs/Scene/Model/WireframePipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/WireframePipelineStageSpec.js @@ -64,12 +64,12 @@ describe( }); } - function loadGltf(gltfPath, scene, options) { + async function loadGltf(gltfPath, scene, options) { const gltfLoader = new GltfLoader(getOptions(gltfPath, options)); gltfLoaders.push(gltfLoader); - gltfLoader.load(); - - return waitForLoaderProcess(gltfLoader, scene); + await gltfLoader.load(); + await waitForLoaderProcess(gltfLoader, scene); + return gltfLoader; } function mockRenderResources(primitive) { diff --git a/packages/engine/Specs/Scene/Multiple3DTileContentSpec.js b/packages/engine/Specs/Scene/Multiple3DTileContentSpec.js index 12a79c9bc3d..7e84bd96d4e 100644 --- a/packages/engine/Specs/Scene/Multiple3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Multiple3DTileContentSpec.js @@ -3,6 +3,7 @@ import { Cesium3DContentGroup, Cesium3DTileset, Color, + Event, HeadingPitchRange, Multiple3DTileContent, MetadataClass, @@ -175,10 +176,11 @@ describe( ]); }); - it("contentsFetchedPromise is undefined until requestInnerContents is successful", function () { + it("requestInnerContents returns promise that resolves to content if successful", async function () { const mockTileset = { statistics: { numberOfPendingRequests: 0, + numberOfAttemptedRequests: 0, }, }; const tile = {}; @@ -189,19 +191,24 @@ describe( contentsJson ); - expect(content.contentsFetchedPromise).not.toBeDefined(); - spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { return Promise.resolve(makeGltfBuffer()); }); - content.requestInnerContents(); - expect(content.contentsFetchedPromise).toBeDefined(); + + const promise = content.requestInnerContents(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(3); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(0); + + await expectAsync(promise).toBeResolvedTo(jasmine.any(Array)); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(0); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(0); }); - it("contentsFetchedPromise is undefined if no requests are scheduled", function () { + it("requestInnerContents returns undefined and updates statistics if all requests cannot be scheduled", function () { const mockTileset = { statistics: { numberOfPendingRequests: 0, + numberOfAttemptedRequests: 0, }, }; const tile = {}; @@ -212,19 +219,19 @@ describe( contentsJson ); - expect(content.contentsFetchedPromise).not.toBeDefined(); - RequestScheduler.maximumRequestsPerServer = 2; - content.requestInnerContents(); - - expect(content.contentsFetchedPromise).not.toBeDefined(); + expect(content.requestInnerContents()).toBeUndefined(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(0); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(3); }); - it("requestInnerContents returns 0 if successful", function () { + it("requestInnerContents handles inner content failures", async function () { const mockTileset = { statistics: { numberOfPendingRequests: 0, + numberOfAttemptedRequests: 0, }, + tileFailed: new Event(), }; const tile = {}; const content = new Multiple3DTileContent( @@ -234,20 +241,32 @@ describe( contentsJson ); - const fetchArray = spyOn( - Resource.prototype, - "fetchArrayBuffer" - ).and.callFake(function () { - return Promise.resolve(makeGltfBuffer()); + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { + return Promise.reject(new Error("my error")); }); - expect(content.requestInnerContents()).toBe(0); - expect(fetchArray.calls.count()).toBe(3); + + const failureSpy = jasmine.createSpy(); + mockTileset.tileFailed.addEventListener(failureSpy); + + const promise = content.requestInnerContents(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(3); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(0); + + await expectAsync(promise).toBeResolved(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(0); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(0); + expect(failureSpy).toHaveBeenCalledWith( + jasmine.objectContaining({ + message: "my error", + }) + ); }); - it("requestInnerContents schedules no requests if there are not enough open slots", function () { + it("requestInnerContents handles cancelled requests", async function () { const mockTileset = { statistics: { numberOfPendingRequests: 0, + numberOfAttemptedRequests: 0, }, }; const tile = {}; @@ -258,17 +277,28 @@ describe( contentsJson ); - const fetchArray = spyOn(Resource.prototype, "fetchArrayBuffer"); - RequestScheduler.maximumRequestsPerServer = 2; - expect(content.requestInnerContents()).toBe(3); - expect(fetchArray).not.toHaveBeenCalled(); + spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { + return Promise.resolve(makeGltfBuffer()); + }); + + const promise = content.requestInnerContents(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(3); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(0); + + content.cancelRequests(); + + await expectAsync(promise).toBeResolved(); + expect(mockTileset.statistics.numberOfPendingRequests).toBe(0); + expect(mockTileset.statistics.numberOfAttemptedRequests).toBe(3); }); - it("resolves readyPromise", function () { - return Cesium3DTilesTester.resolvesReadyPromise( + it("becomes ready", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( scene, multipleContentsUrl ); + expect(tileset.root.contentReady).toBeTrue(); + expect(tileset.root.content).toBeDefined(); }); it("renders multiple contents", function () { diff --git a/packages/engine/Specs/Scene/ResourceCacheStatisticsSpec.js b/packages/engine/Specs/Scene/ResourceCacheStatisticsSpec.js index bc2c0db0915..b73e3f9f18c 100644 --- a/packages/engine/Specs/Scene/ResourceCacheStatisticsSpec.js +++ b/packages/engine/Specs/Scene/ResourceCacheStatisticsSpec.js @@ -9,280 +9,164 @@ describe("Scene/ResourceCacheStatistics", function () { expect(statistics._textureSizes).toEqual({}); }); - function mockLoader(cacheKey, shouldResolve, data) { - const loader = combine(data, { + function mockLoader(cacheKey, data) { + return combine(data, { cacheKey: cacheKey, }); - - if (shouldResolve) { - loader.promise = Promise.resolve(loader); - } else { - loader.promise = Promise.reject(); - } - - return loader; - } - - function mockCanceledLoader(cacheKey, data) { - const loader = combine(data, { - cacheKey: cacheKey, - }); - - loader.promise = new Promise(function (resolve) { - // Deferred so the unit test can decide when the cancellation happens - // via loader.cancel(); - loader.cancel = resolve; - }); - - return loader; } it("clears", function () { const statistics = new ResourceCacheStatistics(); - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, }); - const textureLoader = mockLoader("texture", true, { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 300, }, }); - const geometryPromise = statistics.addGeometryLoader(geometryLoader); - const texturePromise = statistics.addTextureLoader(textureLoader); + statistics.addGeometryLoader(geometryLoader); + statistics.addTextureLoader(textureLoader); - return Promise.all([geometryPromise, texturePromise]).then(function () { - expect(statistics.geometryByteLength).not.toBe(0); - expect(statistics.texturesByteLength).not.toBe(0); - expect(statistics._geometrySizes).not.toEqual({}); - expect(statistics._textureSizes).not.toEqual({}); + expect(statistics.geometryByteLength).not.toBe(0); + expect(statistics.texturesByteLength).not.toBe(0); + expect(statistics._geometrySizes).not.toEqual({}); + expect(statistics._textureSizes).not.toEqual({}); - statistics.clear(); + statistics.clear(); - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({}); - }); + expect(statistics.geometryByteLength).toBe(0); + expect(statistics.texturesByteLength).toBe(0); + expect(statistics._geometrySizes).toEqual({}); + expect(statistics._textureSizes).toEqual({}); }); it("addGeometryLoader throws for undefined loader", function () { const statistics = new ResourceCacheStatistics(); expect(function () { - return statistics.addGeometryLoader(undefined); + statistics.addGeometryLoader(undefined); }).toThrowDeveloperError(); }); it("addGeometryLoader counts geometry memory", function () { const statistics = new ResourceCacheStatistics(); - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, }); - return statistics.addGeometryLoader(geometryLoader).then(function () { - expect(statistics.geometryByteLength).toBe(100); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({ vertices: 100 }); - expect(statistics._textureSizes).toEqual({}); - }); + statistics.addGeometryLoader(geometryLoader); + expect(statistics.geometryByteLength).toBe(100); + expect(statistics.texturesByteLength).toBe(0); + expect(statistics._geometrySizes).toEqual({ vertices: 100 }); + expect(statistics._textureSizes).toEqual({}); }); it("addGeometryLoader counts buffers with typed arrays", function () { const statistics = new ResourceCacheStatistics(); - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, typedArray: new Uint8Array(100), }); - return statistics.addGeometryLoader(geometryLoader).then(function () { - expect(statistics.geometryByteLength).toBe(200); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({ vertices: 200 }); - expect(statistics._textureSizes).toEqual({}); - }); + statistics.addGeometryLoader(geometryLoader); + expect(statistics.geometryByteLength).toBe(200); + expect(statistics.texturesByteLength).toBe(0); + expect(statistics._geometrySizes).toEqual({ vertices: 200 }); + expect(statistics._textureSizes).toEqual({}); }); it("addGeometryLoader does not double count memory", function () { const statistics = new ResourceCacheStatistics(); - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, typedArray: new Uint8Array(100), }); - const promise = statistics.addGeometryLoader(geometryLoader); - const promise2 = statistics.addGeometryLoader(geometryLoader); - - return Promise.all([promise, promise2]).then(function () { - expect(statistics.geometryByteLength).toBe(200); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({ vertices: 200 }); - expect(statistics._textureSizes).toEqual({}); - }); - }); - - it("addGeometryLoader handles failed buffer load", function () { - const statistics = new ResourceCacheStatistics(); - - const geometryLoader = mockLoader("vertices", false, { - buffer: { - sizeInBytes: 100, - }, - }); - - return statistics.addGeometryLoader(geometryLoader).then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({}); - }); - }); - - it("addGeometryLoader handles canceled buffer load", function () { - const statistics = new ResourceCacheStatistics(); - - const geometryLoader = mockCanceledLoader("vertices", { - buffer: { - sizeInBytes: 100, - }, - }); - - const promise = statistics.addGeometryLoader(geometryLoader); - - expect(statistics.geometryByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({ vertices: 0 }); + statistics.addGeometryLoader(geometryLoader); + statistics.addGeometryLoader(geometryLoader); - // simulate removing the loader before the promise resolves - statistics.removeLoader(geometryLoader); - geometryLoader.cancel(); - - return promise.then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({}); - }); + expect(statistics.geometryByteLength).toBe(200); + expect(statistics.texturesByteLength).toBe(0); + expect(statistics._geometrySizes).toEqual({ vertices: 200 }); + expect(statistics._textureSizes).toEqual({}); }); it("addTextureLoader throws for undefined loader", function () { const statistics = new ResourceCacheStatistics(); expect(function () { - return statistics.addTextureLoader(undefined); + statistics.addTextureLoader(undefined); }).toThrowDeveloperError(); }); it("addTextureLoader counts texture memory", function () { const statistics = new ResourceCacheStatistics(); - const textureLoader = mockLoader("texture", true, { - texture: { - sizeInBytes: 100, - }, - }); - - return statistics.addTextureLoader(textureLoader).then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(100); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({ texture: 100 }); - }); - }); - - it("addTextureLoader handles failed texture load", function () { - const statistics = new ResourceCacheStatistics(); - - const textureLoader = mockLoader("texture", false, { - texture: { - sizeInBytes: 100, - }, - }); - - return statistics.addTextureLoader(textureLoader).then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({}); - }); - }); - - it("addTextureLoader handles canceled texture load", function () { - const statistics = new ResourceCacheStatistics(); - - const textureLoader = mockCanceledLoader("texture", { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 100, }, }); - const promise = statistics.addTextureLoader(textureLoader); - - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._textureSizes).toEqual({ texture: 0 }); - - // simulate removing the loader before the promise resolves - statistics.removeLoader(textureLoader); - textureLoader.cancel(); - - return promise.then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(0); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({}); - }); + statistics.addTextureLoader(textureLoader); + expect(statistics.geometryByteLength).toBe(0); + expect(statistics.texturesByteLength).toBe(100); + expect(statistics._geometrySizes).toEqual({}); + expect(statistics._textureSizes).toEqual({ texture: 100 }); }); it("addTextureLoader does not double count memory", function () { const statistics = new ResourceCacheStatistics(); - const textureLoader = mockLoader("texture", true, { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 100, }, }); - const promise = statistics.addTextureLoader(textureLoader); - const promise2 = statistics.addTextureLoader(textureLoader); - return Promise.all([promise, promise2]).then(function () { - expect(statistics.geometryByteLength).toBe(0); - expect(statistics.texturesByteLength).toBe(100); - expect(statistics._geometrySizes).toEqual({}); - expect(statistics._textureSizes).toEqual({ texture: 100 }); - }); + statistics.addTextureLoader(textureLoader); + statistics.addTextureLoader(textureLoader); + + expect(statistics.geometryByteLength).toBe(0); + expect(statistics.texturesByteLength).toBe(100); + expect(statistics._geometrySizes).toEqual({}); + expect(statistics._textureSizes).toEqual({ texture: 100 }); }); it("removeLoader throws for undefined loader", function () { const statistics = new ResourceCacheStatistics(); expect(function () { - return statistics.removeLoader(undefined); + statistics.removeLoader(undefined); }).toThrowDeveloperError(); }); it("removeLoader correctly updates memory for buffers", function () { - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, }); - const geometryLoader2 = mockLoader("indices", true, { + const geometryLoader2 = mockLoader("indices", { buffer: { sizeInBytes: 200, }, }); - const textureLoader = mockLoader("texture", true, { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 300, }, @@ -290,45 +174,39 @@ describe("Scene/ResourceCacheStatistics", function () { const statistics = new ResourceCacheStatistics(); - const geometryPromise = statistics.addGeometryLoader(geometryLoader); - const geometryPromise2 = statistics.addGeometryLoader(geometryLoader2); - const texturePromise = statistics.addTextureLoader(textureLoader); - - return Promise.all([ - geometryPromise, - geometryPromise2, - texturePromise, - ]).then(function () { - expect(statistics.geometryByteLength).toBe(300); - expect(statistics.texturesByteLength).toBe(300); - expect(statistics._geometrySizes).toEqual({ - vertices: 100, - indices: 200, - }); - - statistics.removeLoader(geometryLoader2); - - expect(statistics.geometryByteLength).toBe(100); - expect(statistics.texturesByteLength).toBe(300); - expect(statistics._geometrySizes).toEqual({ vertices: 100 }); - expect(statistics._textureSizes).toEqual({ texture: 300 }); + statistics.addGeometryLoader(geometryLoader); + statistics.addGeometryLoader(geometryLoader2); + statistics.addTextureLoader(textureLoader); + + expect(statistics.geometryByteLength).toBe(300); + expect(statistics.texturesByteLength).toBe(300); + expect(statistics._geometrySizes).toEqual({ + vertices: 100, + indices: 200, }); + + statistics.removeLoader(geometryLoader2); + + expect(statistics.geometryByteLength).toBe(100); + expect(statistics.texturesByteLength).toBe(300); + expect(statistics._geometrySizes).toEqual({ vertices: 100 }); + expect(statistics._textureSizes).toEqual({ texture: 300 }); }); it("removeLoader correctly updates memory for textures", function () { - const geometryLoader = mockLoader("vertices", true, { + const geometryLoader = mockLoader("vertices", { buffer: { sizeInBytes: 100, }, }); - const textureLoader = mockLoader("texture", true, { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 300, }, }); - const textureLoader2 = mockLoader("texture2", true, { + const textureLoader2 = mockLoader("texture2", { texture: { sizeInBytes: 500, }, @@ -336,40 +214,36 @@ describe("Scene/ResourceCacheStatistics", function () { const statistics = new ResourceCacheStatistics(); - const geometryPromise = statistics.addGeometryLoader(geometryLoader); - const texturePromise = statistics.addTextureLoader(textureLoader); - const texturePromise2 = statistics.addTextureLoader(textureLoader2); - - return Promise.all([geometryPromise, texturePromise, texturePromise2]).then( - function () { - expect(statistics.geometryByteLength).toBe(100); - expect(statistics.texturesByteLength).toBe(800); - expect(statistics._geometrySizes).toEqual({ vertices: 100 }); - expect(statistics._textureSizes).toEqual({ - texture: 300, - texture2: 500, - }); - - statistics.removeLoader(textureLoader2); - - expect(statistics.geometryByteLength).toBe(100); - expect(statistics.texturesByteLength).toBe(300); - expect(statistics._geometrySizes).toEqual({ vertices: 100 }); - expect(statistics._textureSizes).toEqual({ texture: 300 }); - } - ); + statistics.addGeometryLoader(geometryLoader); + statistics.addTextureLoader(textureLoader); + statistics.addTextureLoader(textureLoader2); + + expect(statistics.geometryByteLength).toBe(100); + expect(statistics.texturesByteLength).toBe(800); + expect(statistics._geometrySizes).toEqual({ vertices: 100 }); + expect(statistics._textureSizes).toEqual({ + texture: 300, + texture2: 500, + }); + + statistics.removeLoader(textureLoader2); + + expect(statistics.geometryByteLength).toBe(100); + expect(statistics.texturesByteLength).toBe(300); + expect(statistics._geometrySizes).toEqual({ vertices: 100 }); + expect(statistics._textureSizes).toEqual({ texture: 300 }); }); it("removeLoader gracefully handles loader without tracked resources", function () { const statistics = new ResourceCacheStatistics(); - const textureLoader = mockLoader("texture", true, { + const textureLoader = mockLoader("texture", { texture: { sizeInBytes: 300, }, }); expect(function () { - return statistics.removeLoader(textureLoader); + statistics.removeLoader(textureLoader); }).not.toThrowDeveloperError(); expect(statistics.geometryByteLength).toBe(0); diff --git a/packages/engine/Specs/Scene/ResourceLoaderSpec.js b/packages/engine/Specs/Scene/ResourceLoaderSpec.js index 39fbd6cd069..59a58452255 100644 --- a/packages/engine/Specs/Scene/ResourceLoaderSpec.js +++ b/packages/engine/Specs/Scene/ResourceLoaderSpec.js @@ -3,9 +3,6 @@ import { ResourceLoader } from "../../index.js"; describe("Scene/ResourceLoader", function () { it("throws when using ResourceLoader directly", function () { const resourceLoader = new ResourceLoader(); - expect(function () { - return resourceLoader.promise; - }).toThrowDeveloperError(); expect(function () { return resourceLoader.cacheKey; }).toThrowDeveloperError(); diff --git a/packages/engine/Specs/Scene/ShadowMapSpec.js b/packages/engine/Specs/Scene/ShadowMapSpec.js index 8e472ae164d..8cfd0db1f74 100644 --- a/packages/engine/Specs/Scene/ShadowMapSpec.js +++ b/packages/engine/Specs/Scene/ShadowMapSpec.js @@ -282,7 +282,7 @@ describe( } async function loadModel(options) { - const model = scene.primitives.add(await Model.fromGltf(options)); + const model = scene.primitives.add(await Model.fromGltfAsync(options)); await pollToPromise( function () { // Render scene to progressively load the model diff --git a/packages/engine/Specs/Scene/Tileset3DTileContentSpec.js b/packages/engine/Specs/Scene/Tileset3DTileContentSpec.js index 39d9cabc843..f161f7dbe49 100644 --- a/packages/engine/Specs/Scene/Tileset3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Tileset3DTileContentSpec.js @@ -35,11 +35,13 @@ describe( scene.primitives.removeAll(); }); - it("resolves readyPromise", function () { - return Cesium3DTilesTester.resolvesReadyPromise( + it("becomes ready", async function () { + const tileset = await Cesium3DTilesTester.loadTileset( scene, tilesetOfTilesetsUrl ); + expect(tileset.root.contentReady).toBeTrue(); + expect(tileset.root.content).toBeDefined(); }); it("destroys", function () { @@ -58,7 +60,6 @@ describe( expect(content.texturesByteLength).toBe(0); expect(content.batchTableByteLength).toBe(0); expect(content.innerContents).toBeUndefined(); - expect(content.readyPromise).toBeDefined(); expect(content.tileset).toBe(tileset); expect(content.tile).toBe(tile); expect(content.url).toBeDefined(); diff --git a/packages/engine/Specs/Scene/Vector3DTileContentSpec.js b/packages/engine/Specs/Scene/Vector3DTileContentSpec.js index 8091aaeed53..6bdf4724dc7 100644 --- a/packages/engine/Specs/Scene/Vector3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTileContentSpec.js @@ -19,6 +19,7 @@ import { Rectangle, RectangleGeometry, RenderState, + RuntimeError, StencilConstants, } from "../../index.js"; @@ -2165,29 +2166,44 @@ describe( }); }); - it("throws with invalid version", function () { + it("throws with invalid version", async function () { const arrayBuffer = Cesium3DTilesTester.generateVectorTileBuffer({ version: 2, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "vctr"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "vctr") + ).toBeRejectedWithError( + RuntimeError, + "Only Vector tile version 1 is supported. Version 2 is not." + ); }); - it("throws with empty feature table", function () { + it("throws with empty feature table", async function () { const arrayBuffer = Cesium3DTilesTester.generateVectorTileBuffer({ defineFeatureTable: false, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "vctr"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "vctr") + ).toBeRejectedWithError( + RuntimeError, + "Feature table must have a byte length greater than zero" + ); }); - it("throws without region", function () { + it("throws without region", async function () { const arrayBuffer = Cesium3DTilesTester.generateVectorTileBuffer({ defineRegion: false, polygonsLength: 1, }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "vctr"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "vctr") + ).toBeRejectedWithError( + RuntimeError, + "Feature table global property: REGION must be defined" + ); }); - it("throws without all batch ids", function () { + it("throws without all batch ids", async function () { const arrayBuffer = Cesium3DTilesTester.generateVectorTileBuffer({ polygonsLength: 1, pointsLength: 1, @@ -2195,7 +2211,12 @@ describe( polygonBatchIds: [1], pointBatchIds: [0], }); - Cesium3DTilesTester.loadTileExpectError(scene, arrayBuffer, "vctr"); + await expectAsync( + Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "vctr") + ).toBeRejectedWithError( + RuntimeError, + "If one group of batch ids is defined, then all batch ids must be defined" + ); }); it("destroys", function () { diff --git a/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js b/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js index 8a91e0fff2e..f5c9d67609b 100644 --- a/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js +++ b/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js @@ -168,14 +168,10 @@ describe( }); function loadGeometries(geometries) { - let ready = false; - geometries.readyPromise.then(function () { - ready = true; - }); return pollToPromise(function () { geometries.update(scene.frameState); scene.frameState.commandList.length = 0; - return ready; + return geometries.ready; }); } diff --git a/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js b/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js index 9b62ed6d012..9aef5e30df9 100644 --- a/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js @@ -83,14 +83,10 @@ describe( } function loadPoints(points) { - let ready = false; - points.readyPromise.then(function () { - ready = true; - }); return pollToPromise(function () { points.update(scene.frameState); scene.frameState.commandList.length = 0; - return ready; + return points.ready; }); } diff --git a/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js b/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js index 9f2e022b9bf..0388cf89f10 100644 --- a/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js @@ -176,14 +176,10 @@ describe( }); function loadPolygons(polygons) { - let ready = false; - polygons.readyPromise.then(function () { - ready = true; - }); return pollToPromise(function () { polygons.update(scene.frameState); scene.frameState.commandList.length = 0; - return ready; + return polygons.ready; }); } diff --git a/packages/engine/Specs/Scene/Vector3DTilePolylinesSpec.js b/packages/engine/Specs/Scene/Vector3DTilePolylinesSpec.js index c42d108948e..7a82e8db713 100644 --- a/packages/engine/Specs/Scene/Vector3DTilePolylinesSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTilePolylinesSpec.js @@ -56,14 +56,10 @@ describe( }); function loadPolylines(polylines) { - let ready = false; - polylines.readyPromise.then(function () { - ready = true; - }); return pollToPromise(function () { polylines.update(scene.frameState); scene.frameState.commandList.length = 0; - return ready; + return polylines.ready; }); } From 0d5ff05df9ea32ba10c521f42259aabad54e2531 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 17 Mar 2023 15:06:39 -0400 Subject: [PATCH 552/679] Update examples and CHANGES.md --- .../gallery/Custom Shaders Models.html | 42 +-- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 239 +++++++++--------- .../gallery/Image-Based Lighting.html | 24 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 48 ++-- .../Manually Controlled Animation.html | 70 ++--- .../development/3D Models Articulations.html | 24 +- .../development/3D Models Node Explorer.html | 24 +- .../gallery/development/3D Models.html | 26 +- .../development/Display Conditions.html | 28 +- .../gallery/development/Multiple Shadows.html | 42 +-- .../gallery/development/Shadows.html | 26 +- CHANGES.md | 17 +- .../Contributors/TestingGuide/README.md | 66 ++--- Documentation/CustomShaderGuide/README.md | 2 +- 14 files changed, 362 insertions(+), 316 deletions(-) diff --git a/Apps/Sandcastle/gallery/Custom Shaders Models.html b/Apps/Sandcastle/gallery/Custom Shaders Models.html index 5fe67b934e4..5fb5960c87e 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Models.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Models.html @@ -393,26 +393,32 @@ }, ]; - function selectModel(url, customShader) { + async function selectModel(url, customShader) { viewer.scene.primitives.removeAll(); - const model = viewer.scene.primitives.add( - Cesium.Model.fromGltf({ - url: url, - customShader: customShader, - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - position, - hpr, - Cesium.Ellipsoid.WGS84, - fixedFrameTransform - ), - }) - ); - - model.readyPromise.then(function (model) { - viewer.camera.flyToBoundingSphere(model.boundingSphere, { - duration: 0.5, + try { + const model = viewer.scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: url, + customShader: customShader, + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + position, + hpr, + Cesium.Ellipsoid.WGS84, + fixedFrameTransform + ), + }) + ); + + const removeListener = model.readyEvent.addEventListener(() => { + viewer.camera.flyToBoundingSphere(model.boundingSphere, { + duration: 0.5, + }); + + removeListener(); }); - }); + } catch (error) { + console.log(`Error loading model: ${error}`); + } } Sandcastle.addToolbarMenu(demos); diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index 3863beec47e..9629f74df1f 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -125,132 +125,141 @@ <h1>Loading...</h1> "west" ); - const planePrimitive = scene.primitives.add( - Cesium.Model.fromGltf({ - url: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - position, - hpRoll, - Cesium.Ellipsoid.WGS84, - fixedFrameTransform - ), - minimumPixelSize: 128, - }) - ); - - planePrimitive.readyPromise.then(function (model) { - // Play and loop all animations at half-speed - model.activeAnimations.addAll({ - multiplier: 0.5, - loop: Cesium.ModelAnimationLoop.REPEAT, - }); - - // Zoom to model - r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near); - controller.minimumZoomDistance = r * 0.5; - const center = model.boundingSphere.center; - const heading = Cesium.Math.toRadians(230.0); - const pitch = Cesium.Math.toRadians(-20.0); - hpRange.heading = heading; - hpRange.pitch = pitch; - hpRange.range = r * 50.0; - camera.lookAt(center, hpRange); - }); - - document.addEventListener("keydown", function (e) { - switch (e.keyCode) { - case 40: - if (e.shiftKey) { - // speed down - speed = Math.max(--speed, 1); - } else { - // pitch down - hpRoll.pitch -= deltaRadians; - if (hpRoll.pitch < -Cesium.Math.TWO_PI) { - hpRoll.pitch += Cesium.Math.TWO_PI; - } - } - break; - case 38: - if (e.shiftKey) { - // speed up - speed = Math.min(++speed, 100); - } else { - // pitch up - hpRoll.pitch += deltaRadians; - if (hpRoll.pitch > Cesium.Math.TWO_PI) { - hpRoll.pitch -= Cesium.Math.TWO_PI; - } - } - break; - case 39: - if (e.shiftKey) { - // roll right - hpRoll.roll += deltaRadians; - if (hpRoll.roll > Cesium.Math.TWO_PI) { - hpRoll.roll -= Cesium.Math.TWO_PI; - } - } else { - // turn right - hpRoll.heading += deltaRadians; - if (hpRoll.heading > Cesium.Math.TWO_PI) { - hpRoll.heading -= Cesium.Math.TWO_PI; - } - } - break; - case 37: - if (e.shiftKey) { - // roll left until - hpRoll.roll -= deltaRadians; - if (hpRoll.roll < 0.0) { - hpRoll.roll += Cesium.Math.TWO_PI; - } - } else { - // turn left - hpRoll.heading -= deltaRadians; - if (hpRoll.heading < 0.0) { - hpRoll.heading += Cesium.Math.TWO_PI; - } - } - break; - default: - } - }); - const headingSpan = document.getElementById("heading"); const pitchSpan = document.getElementById("pitch"); const rollSpan = document.getElementById("roll"); const speedSpan = document.getElementById("speed"); const fromBehind = document.getElementById("fromBehind"); - viewer.scene.preUpdate.addEventListener(function (scene, time) { - speedVector = Cesium.Cartesian3.multiplyByScalar( - Cesium.Cartesian3.UNIT_X, - speed / 10, - speedVector - ); - position = Cesium.Matrix4.multiplyByPoint( - planePrimitive.modelMatrix, - speedVector, - position - ); - pathPosition.addSample(Cesium.JulianDate.now(), position); - Cesium.Transforms.headingPitchRollToFixedFrame( - position, - hpRoll, - Cesium.Ellipsoid.WGS84, - fixedFrameTransform, - planePrimitive.modelMatrix + try { + const planePrimitive = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + position, + hpRoll, + Cesium.Ellipsoid.WGS84, + fixedFrameTransform + ), + minimumPixelSize: 128, + }) ); - if (fromBehind.checked) { + planePrimitive.readyEvent.addEventListener(() => { + // Play and loop all animations at half-speed + planePrimitive.activeAnimations.addAll({ + multiplier: 0.5, + loop: Cesium.ModelAnimationLoop.REPEAT, + }); + // Zoom to model + r = + 2.0 * + Math.max( + planePrimitive.boundingSphere.radius, + camera.frustum.near + ); + controller.minimumZoomDistance = r * 0.5; const center = planePrimitive.boundingSphere.center; - hpRange.heading = hpRoll.heading; - hpRange.pitch = hpRoll.pitch; + const heading = Cesium.Math.toRadians(230.0); + const pitch = Cesium.Math.toRadians(-20.0); + hpRange.heading = heading; + hpRange.pitch = pitch; + hpRange.range = r * 50.0; camera.lookAt(center, hpRange); - } - }); + }); + + document.addEventListener("keydown", function (e) { + switch (e.keyCode) { + case 40: + if (e.shiftKey) { + // speed down + speed = Math.max(--speed, 1); + } else { + // pitch down + hpRoll.pitch -= deltaRadians; + if (hpRoll.pitch < -Cesium.Math.TWO_PI) { + hpRoll.pitch += Cesium.Math.TWO_PI; + } + } + break; + case 38: + if (e.shiftKey) { + // speed up + speed = Math.min(++speed, 100); + } else { + // pitch up + hpRoll.pitch += deltaRadians; + if (hpRoll.pitch > Cesium.Math.TWO_PI) { + hpRoll.pitch -= Cesium.Math.TWO_PI; + } + } + break; + case 39: + if (e.shiftKey) { + // roll right + hpRoll.roll += deltaRadians; + if (hpRoll.roll > Cesium.Math.TWO_PI) { + hpRoll.roll -= Cesium.Math.TWO_PI; + } + } else { + // turn right + hpRoll.heading += deltaRadians; + if (hpRoll.heading > Cesium.Math.TWO_PI) { + hpRoll.heading -= Cesium.Math.TWO_PI; + } + } + break; + case 37: + if (e.shiftKey) { + // roll left until + hpRoll.roll -= deltaRadians; + if (hpRoll.roll < 0.0) { + hpRoll.roll += Cesium.Math.TWO_PI; + } + } else { + // turn left + hpRoll.heading -= deltaRadians; + if (hpRoll.heading < 0.0) { + hpRoll.heading += Cesium.Math.TWO_PI; + } + } + break; + default: + } + }); + + viewer.scene.preUpdate.addEventListener(function (scene, time) { + speedVector = Cesium.Cartesian3.multiplyByScalar( + Cesium.Cartesian3.UNIT_X, + speed / 10, + speedVector + ); + position = Cesium.Matrix4.multiplyByPoint( + planePrimitive.modelMatrix, + speedVector, + position + ); + pathPosition.addSample(Cesium.JulianDate.now(), position); + Cesium.Transforms.headingPitchRollToFixedFrame( + position, + hpRoll, + Cesium.Ellipsoid.WGS84, + fixedFrameTransform, + planePrimitive.modelMatrix + ); + + if (fromBehind.checked) { + // Zoom to model + const center = planePrimitive.boundingSphere.center; + hpRange.heading = hpRoll.heading; + hpRange.pitch = hpRoll.pitch; + camera.lookAt(center, hpRange); + } + }); + } catch (error) { + console.log(`Error loading model: ${error}`); + } viewer.scene.preRender.addEventListener(function (scene, time) { headingSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.heading).toFixed( diff --git a/Apps/Sandcastle/gallery/Image-Based Lighting.html b/Apps/Sandcastle/gallery/Image-Based Lighting.html index e65402087ff..7c038f6ab58 100644 --- a/Apps/Sandcastle/gallery/Image-Based Lighting.html +++ b/Apps/Sandcastle/gallery/Image-Based Lighting.html @@ -137,16 +137,16 @@ hpr ); - const model = viewer.scene.primitives.add( - Cesium.Model.fromGltf({ - url: modelURL, - modelMatrix: modelMatrix, - minimumPixelSize: 128, - }) - ); + try { + const model = viewer.scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: modelURL, + modelMatrix: modelMatrix, + minimumPixelSize: 128, + }) + ); - model.readyPromise - .then(function (model) { + model.readyEvent.addEventListener(() => { const camera = viewer.camera; // Zoom to model @@ -202,10 +202,10 @@ } } ); - }) - .catch(function (error) { - window.alert(error); }); + } catch (error) { + window.alert(`Error loading model: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 1539df70542..bfb66ea1707 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -129,24 +129,28 @@ <h1>Loading...</h1> const position = localFrames[i].pos; const converter = localFrames[i].converter; const comments = localFrames[i].comments; - const planePrimitive = scene.primitives.add( - Cesium.Model.fromGltf({ - url: "../../SampleData/models/CesiumAir/Cesium_Air.glb", - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - position, - hpRoll, - Cesium.Ellipsoid.WGS84, - converter - ), - minimumPixelSize: 128, - }) - ); + try { + const planePrimitive = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: "../../SampleData/models/CesiumAir/Cesium_Air.glb", + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + position, + hpRoll, + Cesium.Ellipsoid.WGS84, + converter + ), + minimumPixelSize: 128, + }) + ); - primitives.push({ - primitive: planePrimitive, - converter: converter, - position: position, - }); + primitives.push({ + primitive: planePrimitive, + converter: converter, + position: position, + }); + } catch (error) { + console.log(`Error loading model: ${error}`); + } const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( position, hprRollZero, @@ -178,14 +182,8 @@ <h1>Loading...</h1> }); } - primitives[0].primitive.readyPromise.then(function (model) { - // Play and loop all animations at half-speed - model.activeAnimations.addAll({ - multiplier: 0.5, - loop: Cesium.ModelAnimationLoop.REPEAT, - }); - - // Zoom to model + primitives[0].primitive.readyEvent.addEventListener((model) => { + // Zoom to first model r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near); controller.minimumZoomDistance = r * 0.5; const center = model.boundingSphere.center; diff --git a/Apps/Sandcastle/gallery/Manually Controlled Animation.html b/Apps/Sandcastle/gallery/Manually Controlled Animation.html index 7ee0b66ed6a..dca08d980e7 100644 --- a/Apps/Sandcastle/gallery/Manually Controlled Animation.html +++ b/Apps/Sandcastle/gallery/Manually Controlled Animation.html @@ -109,36 +109,25 @@ } // Add our model. - const modelPrimitive = viewer.scene.primitives.add( - Cesium.Model.fromGltf({ - url: "../../SampleData/models/CesiumMan/Cesium_Man.glb", - scale: 4, - }) - ); - const modelLabel = viewer.entities.add({ - position: position, - orientation: new Cesium.VelocityOrientationProperty(position), // Automatically set the model's orientation to the direction it's facing. - label: { - text: new Cesium.CallbackProperty(updateSpeedLabel, false), - font: "20px sans-serif", - showBackground: true, - distanceDisplayCondition: new Cesium.DistanceDisplayCondition( - 0.0, - 100.0 - ), - eyeOffset: new Cesium.Cartesian3(0, 7.2, 0), - }, - }); + try { + const modelPrimitive = viewer.scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + scale: 4, + }) + ); - modelPrimitive.readyPromise.then(function (model) { - model.activeAnimations.addAll({ - loop: Cesium.ModelAnimationLoop.REPEAT, - animationTime: function (duration) { - return distance.getValue(viewer.clock.currentTime) / duration; - }, - multiplier: 0.25, + modelPrimitive.readyEvent.addEventListener(() => { + modelPrimitive.activeAnimations.addAll({ + loop: Cesium.ModelAnimationLoop.REPEAT, + animationTime: function (duration) { + return distance.getValue(viewer.clock.currentTime) / duration; + }, + multiplier: 0.25, + }); }); - const rot = new Cesium.Matrix3(); + + const rotation = new Cesium.Matrix3(); viewer.scene.preUpdate.addEventListener(function () { const time = viewer.clock.currentTime; const pos = position.getValue(time); @@ -148,10 +137,31 @@ pos, vel, viewer.scene.globe.ellipsoid, - rot + rotation + ); + Cesium.Matrix4.fromRotationTranslation( + rotation, + pos, + modelPrimitive.modelMatrix ); - Cesium.Matrix4.fromRotationTranslation(rot, pos, model.modelMatrix); }); + } catch (error) { + window.alert(error); + } + + const modelLabel = viewer.entities.add({ + position: position, + orientation: new Cesium.VelocityOrientationProperty(position), // Automatically set the model's orientation to the direction it's facing. + label: { + text: new Cesium.CallbackProperty(updateSpeedLabel, false), + font: "20px sans-serif", + showBackground: true, + distanceDisplayCondition: new Cesium.DistanceDisplayCondition( + 0.0, + 100.0 + ), + eyeOffset: new Cesium.Cartesian3(0, 7.2, 0), + }, }); viewer.trackedEntity = modelLabel; modelLabel.viewFrom = new Cesium.Cartesian3(-30.0, -10.0, 10.0); diff --git a/Apps/Sandcastle/gallery/development/3D Models Articulations.html b/Apps/Sandcastle/gallery/development/3D Models Articulations.html index d276ccb100e..97a795c2b98 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Articulations.html +++ b/Apps/Sandcastle/gallery/development/3D Models Articulations.html @@ -107,16 +107,16 @@ new Cesium.HeadingPitchRoll() ); - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: modelUrl, - modelMatrix: modelMatrix, - minimumPixelSize: 128, - }) - ); + try { + const model = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: modelUrl, + modelMatrix: modelMatrix, + minimumPixelSize: 128, + }) + ); - model.readyPromise - .then(function (model) { + model.readyEvent.addEventListener(() => { const camera = viewer.camera; // Zoom to model @@ -176,10 +176,10 @@ }; }); viewModel.selectedArticulation = viewModel.articulations[0]; - }) - .catch(function (error) { - console.error(error); }); + } catch (error) { + console.log(`Error loading model: ${error}`); + } //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html index 84165f2d7a4..7c13672c029 100644 --- a/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html +++ b/Apps/Sandcastle/gallery/development/3D Models Node Explorer.html @@ -302,16 +302,16 @@ new Cesium.HeadingPitchRoll() ); - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: modelUrl, - modelMatrix: modelMatrix, - minimumPixelSize: 128, - }) - ); + try { + const model = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: modelUrl, + modelMatrix: modelMatrix, + minimumPixelSize: 128, + }) + ); - model.readyPromise - .then(function (model) { + model.readyEvent.addEventListener(() => { const camera = viewer.camera; // Zoom to model @@ -363,10 +363,10 @@ new Cesium.Matrix4() ); }); - }) - .catch(function (error) { - window.alert(error); }); + } catch (error) { + window.alert(error); + } //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/development/3D Models.html b/Apps/Sandcastle/gallery/development/3D Models.html index d182236569f..6fc693c9a41 100644 --- a/Apps/Sandcastle/gallery/development/3D Models.html +++ b/Apps/Sandcastle/gallery/development/3D Models.html @@ -160,7 +160,7 @@ model.colorBlendAmount = Number(newValue); }); - function createModel(url, height, heading, pitch, roll) { + async function createModel(url, height, heading, pitch, roll) { height = Cesium.defaultValue(height, 0.0); heading = Cesium.defaultValue(heading, 0.0); pitch = Cesium.defaultValue(pitch, 0.0); @@ -178,16 +178,16 @@ ); scene.primitives.removeAll(); // Remove previous model - model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: url, - modelMatrix: modelMatrix, - minimumPixelSize: 128, - }) - ); + try { + model = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: url, + modelMatrix: modelMatrix, + minimumPixelSize: 128, + }) + ); - model.readyPromise - .then(function (model) { + model.readyEvent.addEventListener(() => { model.color = Cesium.Color.fromAlpha( getColor(viewModel.color), Number(viewModel.alpha) @@ -218,10 +218,10 @@ center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0) ); - }) - .catch(function (error) { - window.alert(error); }); + } catch (error) { + window.alert(error); + } } const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); diff --git a/Apps/Sandcastle/gallery/development/Display Conditions.html b/Apps/Sandcastle/gallery/development/Display Conditions.html index f3838c40208..1c38d42e364 100644 --- a/Apps/Sandcastle/gallery/development/Display Conditions.html +++ b/Apps/Sandcastle/gallery/development/Display Conditions.html @@ -78,7 +78,7 @@ ); } - function addPointAndModel() { + async function addPointAndModel() { Sandcastle.declare(addPointAndModel); const position = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); @@ -94,16 +94,22 @@ ), }); - scene.primitives.add( - Cesium.Model.fromGltf({ - url: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", - modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position), - distanceDisplayCondition: new Cesium.DistanceDisplayCondition( - 0.0, - 250.5 - ), - }) - ); + try { + scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: "../../SampleData/models/GroundVehicle/GroundVehicle.glb", + modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame( + position + ), + distanceDisplayCondition: new Cesium.DistanceDisplayCondition( + 0.0, + 250.5 + ), + }) + ); + } catch (error) { + window.alert(error); + } } Sandcastle.addToolbarMenu([ diff --git a/Apps/Sandcastle/gallery/development/Multiple Shadows.html b/Apps/Sandcastle/gallery/development/Multiple Shadows.html index a87df91fcc8..e72b532ec68 100644 --- a/Apps/Sandcastle/gallery/development/Multiple Shadows.html +++ b/Apps/Sandcastle/gallery/development/Multiple Shadows.html @@ -72,28 +72,30 @@ shadowMap.enabled = true; - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: - "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", - modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( - center, - new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) - ), - }) - ); - - model.readyPromise - .then(function (model) { - // Play and loop all animations at half-speed - model.activeAnimations.addAll({ - multiplier: 0.5, - loop: Cesium.ModelAnimationLoop.REPEAT, + (async () => { + try { + const model = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: + "../../SampleData/models/ShadowTester/Shadow_Tester_Point.glb", + modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame( + center, + new Cesium.HeadingPitchRoll(heading, 0.0, 0.0) + ), + }) + ); + + model.readyEvent.addEventListener(() => { + // Play and loop all animations at half-speed + model.activeAnimations.addAll({ + multiplier: 0.5, + loop: Cesium.ModelAnimationLoop.REPEAT, + }); }); - }) - .catch(function (error) { + } catch (error) { window.alert(error); - }); + } + })(); return shadowMap; } diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index 67a7ac80420..f6d39e4adcb 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -913,32 +913,32 @@ }); } - function createModel(url, origin) { + async function createModel(url, origin) { const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( origin, new Cesium.HeadingPitchRoll() ); - const model = scene.primitives.add( - Cesium.Model.fromGltf({ - url: url, - modelMatrix: modelMatrix, - }) - ); + try { + const model = scene.primitives.add( + await Cesium.Model.fromGltfAsync({ + url: url, + modelMatrix: modelMatrix, + }) + ); - model.readyPromise - .then(function (model) { + model.readyEvent.addEventListener(() => { // Play and loop all animations at half-speed model.activeAnimations.addAll({ multiplier: 0.5, loop: Cesium.ModelAnimationLoop.REPEAT, }); - }) - .catch(function (error) { - window.alert(error); }); - return model; + return model; + } catch (error) { + window.alert(error); + } } function createBoxRTC(origin) { diff --git a/CHANGES.md b/CHANGES.md index c3ffcc9b3e9..ee6040c27b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Model.fromGltfAsync`, , `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. ##### Fixes :wrench: @@ -45,6 +45,21 @@ - `GoogleEarthEnterpriseTerrainProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseTerrainProvider.ready`, and `GoogleEarthEnterpriseTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseTerrainProvider.fromMetadata` instead. - `VRTheWorldTerrainProvider` constructor parameter `options.url`, `VRTheWorldTerrainProvider.ready`, and `VRTheWorldTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `VRTheWorldTerrainProvider.fromUrl` instead. - `createWorldTerrain` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use createWorldTerrainAsync instead. +- `Model.fromGltf`, `Model.readyPromise`, and `Model.texturesLoadedPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` instead. For example: + + ```js + try { + const model = await Cesium.Model.fromGltfAsync({ + url: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + }); + viewer.scene.primitives.add(model); + model.readyEvent.addEventListener(() => { + // model is ready for rendering + }); + } catch (error) { + console.log(`Failed to load model. ${error}`); + } + ``` #### @cesium/widgets diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index 2488dae152c..fdf75033ccb 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -678,9 +678,18 @@ Make external requests that assume the tests are being used with an Internet con (For an introduction to promises, see [JavaScript Promises - There and back again](http://www.html5rocks.com/en/tutorials/es6/promises/)). -For asynchronous testing, Jasmine's `it` function uses a `done` callback. For better integration with CesiumJS's asynchronous patterns, CesiumJS replaces `it` with a function that can return promises. +Jasmine also has support for running specs that require testing asynchronous operations. The functions that you pass to `beforeAll`, `afterAll`, `beforeEach`, `afterEach`, and `it` can be declared `async`. These functions can also return promises. There are also cases where asynchronous functions that explicitly return promises should be tested. See the [Asynchronous Work tutorial](https://jasmine.github.io/tutorials/async) for more information. -Here is a simplified example of a test from [ModelSpec.js](https://github.com/CesiumGS/cesium/blob/main/Specs/Scene/Model/ModelSpec.js): +Here is a simplified example of `beforeAll` from [sampleTerrainSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Core/sampleTerrainSpec.js): + +```javascript +let worldTerrain; +beforeAll(async function () { + worldTerrain = await createWorldTerrainAsync(); +}); +``` + +Here is a simplified example of a test from [ModelSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Scene/Model/ModelSpec.js): ```javascript const modelUrl = "./Data/Models/glTF-2.0/Box/glTF/Box.gltf"; @@ -694,59 +703,50 @@ afterAll(function () { scene.destroyForSpecs(); }); -it("renders glTF model", function () { - return loadAndZoomToModel({ gltf: modelUrl }, scene).then(function (model) { - expect(scene).toRenderAndCall(function (rgba) { - expect(rgba[0]).toBeGreaterThan(0); - expect(rgba[1]).toBeGreaterThan(0); - expect(rgba[2]).toBeGreaterThan(0); - expect(rgba[3]).toBe(255); - }); +it("renders glTF model", async function () { + const model = await loadAndZoomToModelAsync({ gltf: modelUrl }, scene); + expect(scene).toRenderAndCall(function (rgba) { + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[1]).toBeGreaterThan(0); + expect(rgba[2]).toBeGreaterThan(0); + expect(rgba[3]).toBe(255); }); }); ``` -Given a model's url and other options, [`loadAndZoomToModel`](https://github.com/CesiumGS/cesium/blob/main/Specs/Scene/Model/loadAndZoomToModel.js) loads a model, configures the camera, and returns a promise that resolves when a model's `readyPromise` resolves. +Given a model's url and other options, [`loadAndZoomToModelAsync`](https://github.com/CesiumGS/cesium/blob/main/paclages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js) loads a model, configures the camera, and returns a promise that resolves when a model is ready for rendering. -Since loading a model requires asynchronous requests and creating WebGL resources that may be spread over several frames, CesiumJS's [`pollToPromise`](https://github.com/CesiumGS/cesium/blob/main/Specs/pollToPromise.js) is used to return a promise that resolves when the model is ready, which occurs by rendering the scene in an implicit loop (hence the name "poll") until `model.readyPromise` resolves or the `timeout` is reached. `loadAndZoomToModel` uses `pollToPromise` to wait until the model is finished loading. +Since loading a model requires asynchronous requests and creating WebGL resources that may be spread over several frames, CesiumJS's [`pollToPromise`](https://github.com/CesiumGS/cesium/blob/main/Specs/pollToPromise.js) is used to return a promise that resolves when the model is ready, which occurs by rendering the scene in an implicit loop (hence the name "poll") until `model.ready` is `true` or the `timeout` is reached. -`pollToPromise` is also used in many places where a test needs to wait for an asynchronous event before testing its expectations. Here is an excerpt from [BillboardCollectionSpec.js](https://github.com/CesiumGS/cesium/blob/main/Specs/Scene/BillboardCollectionSpec.js): +`pollToPromise` is also used in many places where a test needs to wait for an asynchronous event before testing its expectations. Here is an excerpt from [BillboardCollectionSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Scene/BillboardCollectionSpec.js): ```javascript -it("can create a billboard using a URL", function () { +it("can create a billboard using a URL", async function () { const b = billboards.add({ image: "./Data/Images/Green.png", }); expect(b.ready).toEqual(false); - return pollToPromise(function () { + await pollToPromise(function () { return b.ready; - }).then(function () { - expect(scene).toRender([0, 255, 0, 255]); }); + + expect(scene).toRender([0, 255, 0, 255]); }); ``` -Here a billboard is loaded using a url to image. Internally, `Billboard` makes an asynchronous request for the image and then sets its `ready` property to `true`. The function passed to `pollToPromise` just returns the value of `ready`; it does not need to render the scene to progressively complete the request like `Model`. Finally, the resolve function (passed to `then`) verifies that the billboard is green. +Here a billboard is loaded using a url to image. Internally, `Billboard` makes an asynchronous request for the image and then sets its `ready` property to `true`. The function passed to `pollToPromise` just returns the value of `ready`; it does not need to render the scene to progressively complete the request like `Model`. Finally, the test verifies that the billboard is green. -To test if a promises rejects, we call `fail` in the resolve function and put the expectation in the reject function. Here is an excerpt from [ArcGisMapServerImageryProviderSpec.js](https://github.com/CesiumGS/cesium/blob/main/Specs/Scene/ArcGisMapServerImageryProviderSpec.js): +To test if a promises rejects, we use `expectAsync` and provide the expected error type and message. Here is an excerpt from [ArcGISTiledElevationTerrainProviderSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js): ```javascript -it("rejects readyPromise on error", function () { - const baseUrl = "//tiledArcGisMapServer.invalid"; - - const provider = new ArcGisMapServerImageryProvider({ - url: baseUrl, - }); +it("fromUrl throws if the SRS is not supported", async function () { + const baseUrl = "made/up/url"; + metadata.spatialReference.latestWkid = 1234; - return provider.readyPromise - .then(function () { - fail("should not resolve"); - }) - .catch(function (e) { - expect(e.message).toContain(baseUrl); - expect(provider.ready).toBe(false); - }); + await expectAsync( + ArcGISTiledElevationTerrainProvider.fromUrl(baseUrl) + ).toBeRejectedWithError(RuntimeError, "Invalid spatial reference"); }); ``` diff --git a/Documentation/CustomShaderGuide/README.md b/Documentation/CustomShaderGuide/README.md index 7a95e34cac7..681559dbdf3 100644 --- a/Documentation/CustomShaderGuide/README.md +++ b/Documentation/CustomShaderGuide/README.md @@ -73,7 +73,7 @@ const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ })); // Applying to a model directly -const model = Cesium.Model.fromGltf({, +const model = await Cesium.Model.fromGltfAsync({, url: "http://example.com/model.gltf", customShader: customShader }); From eab73140bfc706f3ba7a6ab984b1e99bdb0245f8 Mon Sep 17 00:00:00 2001 From: JakeVanDine <jv477@drexel.edu> Date: Sun, 19 Mar 2023 20:28:11 -0400 Subject: [PATCH 553/679] Updated Documenation to reflect Gabby's suggestion --- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 823bcd46452..d3a00212e3a 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -245,7 +245,7 @@ function ScreenSpaceCameraController(scene) { this.minimumTrackBallHeight = 7500000.0; this._minimumTrackBallHeight = this.minimumTrackBallHeight; /** - * Enables or disables camera collision detection with terrain. When enabled, the camera's maximumZoomDistance and minimumZoomDistance become locked. + * When disabled, the values of <code>maximumZoomDistance</code> and <code>minimumZoomDistance</code> are ignored. * @type {boolean} * @default true */ From 0a498caa36c5dcf533daebbd04933bff0b05bb28 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 20 Mar 2023 11:57:06 -0400 Subject: [PATCH 554/679] Deprecate Cesium3DTileset ready and readyPromise --- .../gallery/3D Tiles Adjust Height.html | 41 +- Apps/Sandcastle/gallery/3D Tiles BIM.html | 52 +- .../3D Tiles Batch Table Hierarchy.html | 32 +- CHANGES.md | 20 +- .../PerformanceTestingGuide/README.md | 25 +- .../Contributors/TestingGuide/README.md | 10 + Specs/Cesium3DTilesTester.js | 22 +- packages/engine/Source/Core/IonResource.js | 12 +- .../DataSources/Cesium3DTilesetVisualizer.js | 63 +- .../Source/Scene/Cesium3DTileStyleEngine.js | 2 +- .../engine/Source/Scene/Cesium3DTileset.js | 681 +++++++++++------- packages/engine/Source/Scene/I3SLayer.js | 63 +- .../engine/Source/Scene/createOsmBuildings.js | 6 + .../Source/Scene/createOsmBuildingsAsync.js | 84 +++ .../Cesium3DTilesetVisualizerSpec.js | 93 +-- .../engine/Specs/Scene/Cesium3DTilesetSpec.js | 358 ++++----- packages/engine/Specs/Scene/I3SLayerSpec.js | 80 +- .../Specs/Scene/Vector3DTileContentSpec.js | 8 +- .../Cesium3DTilesInspectorViewModel.js | 3 +- packages/widgets/Source/Viewer/Viewer.js | 3 +- .../Cesium3DTilesInspectorViewModelSpec.js | 38 +- packages/widgets/Specs/Viewer/ViewerSpec.js | 239 +++--- 22 files changed, 1035 insertions(+), 900 deletions(-) create mode 100644 packages/engine/Source/Scene/createOsmBuildingsAsync.js diff --git a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html index c8e8f6c139a..31de2f9fcbd 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html +++ b/Apps/Sandcastle/gallery/3D Tiles Adjust Height.html @@ -60,8 +60,6 @@ shadows: true, }); - viewer.scene.globe.depthTestAgainstTerrain = true; - const viewModel = { height: 0, }; @@ -71,31 +69,30 @@ const toolbar = document.getElementById("toolbar"); Cesium.knockout.applyBindings(viewModel, toolbar); - const tileset = new Cesium.Cesium3DTileset({ - url: "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json", - }); - - tileset.readyPromise - .then(function (tileset) { - viewer.scene.primitives.add(tileset); - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - tileset.boundingSphere.radius * 2.0 - ) - ); - }) - .catch(function (error) { - console.log(error); - }); + let tileset; + try { + tileset = await Cesium.Cesium3DTileset.fromUrl( + "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json" + ); + viewer.scene.primitives.add(tileset); + viewer.scene.globe.depthTestAgainstTerrain = true; + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + tileset.boundingSphere.radius * 2.0 + ) + ); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } Cesium.knockout .getObservable(viewModel, "height") .subscribe(function (height) { height = Number(height); - if (isNaN(height)) { + if (isNaN(height) || !Cesium.defined(tileset)) { return; } diff --git a/Apps/Sandcastle/gallery/3D Tiles BIM.html b/Apps/Sandcastle/gallery/3D Tiles BIM.html index 2f403e73091..06df8cba02b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles BIM.html +++ b/Apps/Sandcastle/gallery/3D Tiles BIM.html @@ -43,29 +43,6 @@ "2022-08-01T00:00:00Z" ); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - }) - ); - - tileset.readyPromise - .then(function (tileset) { - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.5, - -0.2, - tileset.boundingSphere.radius * 4.0 - ) - ); - }) - .catch(function (error) { - console.log(error); - }); - - tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.REPLACE; - let selectedFeature; let picking = false; @@ -209,13 +186,30 @@ } } - tileset.tileLoad.addEventListener(function (tile) { - processTileFeatures(tile, loadFeature); - }); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(1240402); + scene.primitives.add(tileset); + + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.5, + -0.2, + tileset.boundingSphere.radius * 4.0 + ) + ); + + tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.REPLACE; + tileset.tileLoad.addEventListener(function (tile) { + processTileFeatures(tile, loadFeature); + }); - tileset.tileUnload.addEventListener(function (tile) { - processTileFeatures(tile, unloadFeature); - }); + tileset.tileUnload.addEventListener(function (tile) { + processTileFeatures(tile, unloadFeature); + }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html index de0497ca1f4..5e7a1731d76 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html +++ b/Apps/Sandcastle/gallery/3D Tiles Batch Table Hierarchy.html @@ -95,13 +95,27 @@ const viewer = new Cesium.Viewer("cesiumContainer"); viewer.clock.currentTime = new Cesium.JulianDate(2457522.154792); - const tileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json", - }); + let tileset; + try { + tileset = await Cesium.Cesium3DTileset.fromUrl( + "../../SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tileset.json" + ); + + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.3, 0.0)); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.3, 0.0)); + function setStyle(style) { + return function () { + if (!Cesium.defined(tileset)) { + return; + } + + tileset.style = new Cesium.Cesium3DTileStyle(style); + }; + } const styles = []; function addStyle(name, style) { @@ -167,12 +181,6 @@ }, }); - function setStyle(style) { - return function () { - tileset.style = new Cesium.Cesium3DTileStyle(style); - }; - } - const styleOptions = []; for (let i = 0; i < styles.length; ++i) { const style = styles[i]; diff --git a/CHANGES.md b/CHANGES.md index ee6040c27b5..9dff17ef164 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,11 +2,24 @@ ### 1.104 - 2023-04-03 +#### Major Announcements :loudspeaker: + +- Starting with CesiumJS 1.104 The `readyPromise` pattern has been deprecated across the API. It will be removed in CesiumJS 1.107. This has been done to facilitate better asynchronous flow and error management. For example: + +```js +try { + const tileset = await Cesium.Cesium3DTileset.fromUrl(url); + viewer.scene.primitives.add(tileset); +} catch (error) { + console.log(`Failed to load tileset: ${error}`); +} +``` + #### @cesium/engine ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Model.fromGltfAsync`, , `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, , `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. ##### Fixes :wrench: @@ -44,9 +57,10 @@ - `GoogleEarthEnterpriseMetadata` constructor parameter `options.url` and `GoogleEarthEnterpriseMetadata.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseMetadata.fromUrl` instead. - `GoogleEarthEnterpriseTerrainProvider` constructor parameters `options.url` and `options.metadata`, `GoogleEarthEnterpriseTerrainProvider.ready`, and `GoogleEarthEnterpriseTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseTerrainProvider.fromMetadata` instead. - `VRTheWorldTerrainProvider` constructor parameter `options.url`, `VRTheWorldTerrainProvider.ready`, and `VRTheWorldTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `VRTheWorldTerrainProvider.fromUrl` instead. -- `createWorldTerrain` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use createWorldTerrainAsync instead. +- `createWorldTerrain` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `createWorldTerrainAsync` instead. +- `Cesium3DTileset` constructor parameter `options.url`, `Cesium3DTileset.ready`, and `Cesium3DTileset.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `Cesium3DTileset.fromUrl` instead. +- `createOsmBuildings` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `createOsmBuildingsAsync` instead. - `Model.fromGltf`, `Model.readyPromise`, and `Model.texturesLoadedPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` instead. For example: - ```js try { const model = await Cesium.Model.fromGltfAsync({ diff --git a/Documentation/Contributors/PerformanceTestingGuide/README.md b/Documentation/Contributors/PerformanceTestingGuide/README.md index 9244c10bc86..decea410bfe 100644 --- a/Documentation/Contributors/PerformanceTestingGuide/README.md +++ b/Documentation/Contributors/PerformanceTestingGuide/README.md @@ -127,37 +127,26 @@ class Timer { To time how long it takes for the tileset.json to be fetched and the `Cesium3DTileset` to be initialized (not including the tile content), start -the timer just before creating the tileset, and stop it in the `readyPromise` +the timer just before creating the tileset with `Cesium3DTileset.fromUrl`, and stop it after the asynchronous function has completed. ```js tilesetTimer.start(); -const tileset = new Cesium.Cesium3DTileset({ - url, -}); -tileset.maximumScreenSpaceError = 4; -// and any other initialization code - -viewer.scene.primitives.add(tileset); - -tileset.readyPromise.then(() => { - tilesetTimer.stop(); - tilesetTimer.print(); -}); +const tileset = await Cesium.Cesium3DTileset.fromUrl(url); +tilesetTimer.stop(); +tilesetTimer.print(); ``` ### How to measure tile load time To time how long it takes for all the tiles in the current camera view to load -(not including the tileset load time), start the timer in the ready promise -and stop it in the `initialTilesLoaded` event handler. This event is used +(not including the tileset load time), after the tileset has been created with `Cesium3DTileset.fromUrl` and stop it in the `initialTilesLoaded` event handler. This event is used because we only care about our initial fixed camera view. `allTilesLoaded`, in contrast, may trigger multiple times if the camera moves, which is undesireable here. ```js -tileset.readyPromise.then(() => { - tileTimer.start(); -}); +const tileset = await Cesium.Cesium3DTileset.fromUrl(url); +tileTimer.start(); // This callback is fired the first time that all the visible tiles are loaded. // It indicates the end of the test. diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index fdf75033ccb..6b367b69ebd 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -750,6 +750,16 @@ it("fromUrl throws if the SRS is not supported", async function () { }); ``` +Since developer errors are removed for release builds, CesiumJS's `toBeRejectedWithDeveloperError` matcher is used to verify asynchronous Developer Errors. Here is an excerpt from [Cesium3DTilesetSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js): + +```javascript +it("fromUrl throws without url", async function () { + await expectAsync(Cesium3DTileset.fromUrl()).toBeRejectedWithDeveloperError( + "url is required, actual value was undefined" + ); +}); +``` + ### Mocks To isolate testing, mock objects can be used to simulate real objects. Here is an excerpt from [SceneSpec.js](https://github.com/CesiumGS/cesium/blob/main/Specs/Scene/SceneSpec.js); diff --git a/Specs/Cesium3DTilesTester.js b/Specs/Cesium3DTilesTester.js index 04318ceeadf..b52d0e73cea 100644 --- a/Specs/Cesium3DTilesTester.js +++ b/Specs/Cesium3DTilesTester.js @@ -102,27 +102,19 @@ Cesium3DTilesTester.waitForTilesLoaded = function (scene, tileset) { }); }; -Cesium3DTilesTester.waitForReady = function (scene, tileset) { - return pollToPromise(function () { - scene.renderForSpecs(); - return tileset.ready; - }).then(function () { - return tileset; - }); -}; - -Cesium3DTilesTester.loadTileset = function (scene, url, options) { +Cesium3DTilesTester.loadTileset = async function (scene, url, options) { options = defaultValue(options, {}); - options.url = url; options.cullRequestsWhileMoving = defaultValue( options.cullRequestsWhileMoving, false ); + + const tileset = await Cesium3DTileset.fromUrl(url, options); + // Load all visible tiles - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - return tileset.readyPromise.then(function () { - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); - }); + scene.primitives.add(tileset); + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + return tileset; }; Cesium3DTilesTester.createContentForMockTile = async function ( diff --git a/packages/engine/Source/Core/IonResource.js b/packages/engine/Source/Core/IonResource.js index 137be3899ee..91ce926c34a 100644 --- a/packages/engine/Source/Core/IonResource.js +++ b/packages/engine/Source/Core/IonResource.js @@ -16,7 +16,7 @@ import RuntimeError from "./RuntimeError.js"; * @augments Resource * * @param {object} endpoint The result of the Cesium ion asset endpoint service. - * @param {Resource} endpointResource The resource used to retreive the endpoint. + * @param {Resource} endpointResource The resource used to retrieve the endpoint. * * @see Ion * @see IonImageryProvider @@ -87,8 +87,14 @@ if (defined(Object.create)) { * @returns {Promise<IonResource>} A Promise to am instance representing the Cesium ion Asset. * * @example - * //Load a Cesium3DTileset with asset ID of 124624234 - * viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(124624234) })); + * // Load a Cesium3DTileset with asset ID of 124624234 + * try { + * const resource = await Cesium.IonResource.fromAssetId(124624234); + * const tileset = await Cesium.Cesium3DTileset.fromUrl(resource); + * scene.primitives.add(tileset); + * } catch (error) { + * console.error(`Error creating tileset: ${error}`); + * } * * @example * //Load a CZML file with asset ID of 10890 diff --git a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js index f0c5a9f794d..950c365b847 100644 --- a/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js +++ b/packages/engine/Source/DataSources/Cesium3DTilesetVisualizer.js @@ -65,7 +65,7 @@ Cesium3DTilesetVisualizer.prototype.update = function (time) { const tilesetGraphics = entity._tileset; let resource; - let tilesetData = tilesetHash[entity.id]; + const tilesetData = tilesetHash[entity.id]; const show = entity.isShowing && entity.isAvailable(time) && @@ -86,28 +86,21 @@ Cesium3DTilesetVisualizer.prototype.update = function (time) { continue; } - let tileset = defined(tilesetData) + const tileset = defined(tilesetData) ? tilesetData.tilesetPrimitive : undefined; - if (!defined(tileset) || resource.url !== tilesetData.url) { + if (!defined(tilesetData) || resource.url !== tilesetData.url) { if (defined(tileset)) { primitives.removeAndDestroy(tileset); - delete tilesetHash[entity.id]; } - tileset = new Cesium3DTileset({ - url: resource, - }); - tileset.id = entity; - primitives.add(tileset); - - tilesetData = { - tilesetPrimitive: tileset, - url: resource.url, - loadFail: false, - }; - tilesetHash[entity.id] = tilesetData; - - checkLoad(tileset, entity, tilesetHash); + + delete tilesetHash[entity.id]; + + createTileset(resource, tilesetHash, entity, primitives); + } + + if (!defined(tileset)) { + continue; } tileset.show = true; @@ -180,12 +173,12 @@ Cesium3DTilesetVisualizer.prototype.getBoundingSphere = function ( } const primitive = tilesetData.tilesetPrimitive; - if (!defined(primitive) || !primitive.show) { - return BoundingSphereState.FAILED; + if (!defined(primitive)) { + return BoundingSphereState.PENDING; } - if (!primitive.ready) { - return BoundingSphereState.PENDING; + if (!primitive.show) { + return BoundingSphereState.FAILED; } BoundingSphere.clone(primitive.boundingSphere, result); @@ -235,15 +228,33 @@ Cesium3DTilesetVisualizer.prototype._onCollectionChanged = function ( function removeTileset(visualizer, entity, tilesetHash, primitives) { const tilesetData = tilesetHash[entity.id]; if (defined(tilesetData)) { - primitives.removeAndDestroy(tilesetData.tilesetPrimitive); + if (defined(tilesetData.tilesetPrimitive)) { + primitives.removeAndDestroy(tilesetData.tilesetPrimitive); + } delete tilesetHash[entity.id]; } } -function checkLoad(primitive, entity, tilesetHash) { - primitive.readyPromise.catch(function (error) { +async function createTileset(resource, tilesetHash, entity, primitives) { + tilesetHash[entity.id] = { + url: resource.url, + loadFail: false, + }; + + try { + const tileset = await Cesium3DTileset.fromUrl(resource); + tileset.id = entity; + primitives.add(tileset); + + if (!defined(tilesetHash[entity.id])) { + return; + } + + tilesetHash[entity.id].tilesetPrimitive = tileset; + } catch (error) { console.error(error); tilesetHash[entity.id].loadFail = true; - }); + } } + export default Cesium3DTilesetVisualizer; diff --git a/packages/engine/Source/Scene/Cesium3DTileStyleEngine.js b/packages/engine/Source/Scene/Cesium3DTileStyleEngine.js index 91aa8a31364..bd6eac5a113 100644 --- a/packages/engine/Source/Scene/Cesium3DTileStyleEngine.js +++ b/packages/engine/Source/Scene/Cesium3DTileStyleEngine.js @@ -33,7 +33,7 @@ Cesium3DTileStyleEngine.prototype.resetDirty = function () { }; Cesium3DTileStyleEngine.prototype.applyStyle = function (tileset) { - if (!tileset.ready) { + if (!defined(tileset.root)) { return; } diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index d5c7674a03a..3c885a72c8e 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -10,10 +10,10 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; -import DeveloperError from "../Core/DeveloperError.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import Event from "../Core/Event.js"; import ImageBasedLighting from "./ImageBasedLighting.js"; +import IonResource from "../Core/IonResource.js"; import JulianDate from "../Core/JulianDate.js"; import ManagedArray from "../Core/ManagedArray.js"; import CesiumMath from "../Core/Math.js"; @@ -53,113 +53,131 @@ import TileBoundingRegion from "./TileBoundingRegion.js"; import TileBoundingSphere from "./TileBoundingSphere.js"; import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; +/** + * @typedef {Object} Cesium3DTileset.ConstructorOptions + * + * Initialization options for the Cesium3DTileset constructor + * + * @property {boolean} [options.show=true] Determines if the tileset will be shown. + * @property {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. + * @property {Axis} [options.modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. + * @property {Axis} [options.modelForwardAxis=Axis.X] Which axis is considered forward when loading models for tile contents. + * @property {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from light sources. + * @property {number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. + * @property {number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. + * @property {boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. + * @property {boolean} [options.cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. + * @property {number} [options.cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. + * @property {boolean} [options.preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. + * @property {boolean} [options.preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. + * @property {boolean} [options.preferLeaves=false] Optimization option. Prefer loading of leaves first. + * @property {boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. + * @property {number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. + * @property {number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. + * @property {number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. + * @property {number} [options.progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. + * @property {boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. + * @property {number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. + * @property {number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. + * @property {Cesium3DTileset.foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError} + * @property {number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. + * @property {boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. + * @property {number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. + * @property {number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. + * @property {number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. + * @property {boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. + * @property {boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. + * @property {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. + * @property {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. + * @property {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. + * @property {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * @property {Cartesian3} [options.lightColor] The light color when shading models. When <code>undefined</code> the scene's light color is used instead. + * @property {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting for this tileset. + * @property {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. + * @property {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @property {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @property {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. + * @property {boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. + * @property {boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. + * @property {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @property {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @property {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. + * @property {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset. + * @property {boolean} [options.projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. + * @property {string} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. + * @property {boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. + * @property {boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. + * @property {boolean} [options.enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. + * @property {boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. + * @property {boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. + * @property {boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. + * @property {boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. + * @property {boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. + * @property {boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. + * @property {boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. + * @property {boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. + */ + +/** + * @typedef {Cesium3DTileset.ConstructorOptions} Cesium3DTileset.DeprecatedConstructorOptions + * @property {Resource|string|Promise<Resource>|Promise<string>} options.url The url to a tileset JSON file. Deprecated. + */ + /** * A {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles tileset}, * used for streaming massive heterogeneous 3D geospatial datasets. * + * <div class="notice"> + * This object is normally not instantiated directly, use {@link Cesium3DTileset.fromUrl}. + * </div> + * * @alias Cesium3DTileset * @constructor * - * @param {object} options Object with the following properties: - * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The url to a tileset JSON file. - * @param {boolean} [options.show=true] Determines if the tileset will be shown. - * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. - * @param {Axis} [options.modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. - * @param {Axis} [options.modelForwardAxis=Axis.X] Which axis is considered forward when loading models for tile contents. - * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from light sources. - * @param {number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. - * @param {number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. - * @param {boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. - * @param {boolean} [options.cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. - * @param {number} [options.cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. - * @param {boolean} [options.preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. - * @param {boolean} [options.preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. - * @param {boolean} [options.preferLeaves=false] Optimization option. Prefer loading of leaves first. - * @param {boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. - * @param {number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. - * @param {number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. - * @param {number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. - * @param {number} [options.progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. - * @param {boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. - * @param {number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. - * @param {number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. - * @param {Cesium3DTileset.foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError} - * @param {number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. - * @param {boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. - * @param {number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. - * @param {number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. - * @param {number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. - * @param {boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. - * @param {boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. - * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. - * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. - * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. - * @param {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. - * @param {Cartesian3} [options.lightColor] The light color when shading models. When <code>undefined</code> the scene's light color is used instead. - * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting for this tileset. - * @param {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. - * @param {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @param {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. - * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. - * @param {boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. - * @param {boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. - * @param {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. - * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset. - * @param {boolean} [options.projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. - * @param {string} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. - * @param {boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. - * @param {boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. - * @param {boolean} [options.enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. - * @param {boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. - * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. - * @param {boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. - * @param {boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. - * @param {boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. - * @param {boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. - * @param {boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. - * @param {boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. + * @param {Cesium3DTileset.DeprecatedConstructorOptions} options An object describing initialization options * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. * * @example - * const tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle/tileset.json' - * })); + * try { + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json" + * }); + * scene.primitives.add(tileset); + * } catch (error) { + * console.error(`Error creating tileset: ${error}`); + * } * * @example * // Common setting for the skipLevelOfDetail optimization - * const tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle/tileset.json', - * skipLevelOfDetail : true, - * baseScreenSpaceError : 1024, - * skipScreenSpaceErrorFactor : 16, - * skipLevels : 1, - * immediatelyLoadDesiredLevelOfDetail : false, - * loadSiblings : false, - * cullWithChildrenBounds : true - * })); + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json", { + * skipLevelOfDetail: true, + * baseScreenSpaceError: 1024, + * skipScreenSpaceErrorFactor: 16, + * skipLevels: 1, + * immediatelyLoadDesiredLevelOfDetail: false, + * loadSiblings: false, + * cullWithChildrenBounds: true + * }); + * scene.primitives.add(tileset); * * @example * // Common settings for the dynamicScreenSpaceError optimization - * const tileset = scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle/tileset.json', - * dynamicScreenSpaceError : true, - * dynamicScreenSpaceErrorDensity : 0.00278, - * dynamicScreenSpaceErrorFactor : 4.0, - * dynamicScreenSpaceErrorHeightFalloff : 0.25 - * })); + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json", { + * dynamicScreenSpaceError: true, + * dynamicScreenSpaceErrorDensity: 0.00278, + * dynamicScreenSpaceErrorFactor: 4.0, + * dynamicScreenSpaceErrorHeightFalloff: 0.25 + * }); + * scene.primitives.add(tileset); * * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles specification} */ function Cesium3DTileset(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - Check.defined("options.url", options.url); - //>>includeEnd('debug'); - this._url = undefined; this._basePath = undefined; this._root = undefined; @@ -974,114 +992,123 @@ function Cesium3DTileset(options) { } this._instanceFeatureIdLabel = instanceFeatureIdLabel; - this._schemaLoader = undefined; - - const that = this; - let resource; - this._readyPromise = Promise.resolve(options.url) - .then(function (url) { - let basePath; - resource = Resource.createIfNeeded(url); - that._resource = resource; - - // ion resources have a credits property we can use for additional attribution. - that._credits = resource.credits; - - if (resource.extension === "json") { - basePath = resource.getBaseUri(true); - } else if (resource.isDataUri) { - basePath = ""; - } + if (defined(options.url)) { + deprecationWarning( + "Cesium3DTileset options.url", + "Cesium3DTileset constructor parameter options.url was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTileset.fromUrl instead." + ); + const that = this; + let resource; + this._readyPromise = Promise.resolve(options.url) + .then(function (url) { + let basePath; + resource = Resource.createIfNeeded(url); + that._resource = resource; + + // ion resources have a credits property we can use for additional attribution. + that._credits = resource.credits; + + if (resource.extension === "json") { + basePath = resource.getBaseUri(true); + } else if (resource.isDataUri) { + basePath = ""; + } - that._url = resource.url; - that._basePath = basePath; + that._url = resource.url; + that._basePath = basePath; - return Cesium3DTileset.loadJson(resource); - }) - .then(function (tilesetJson) { - if (that.isDestroyed()) { - return; - } - - // This needs to be called before loadTileset() so tile metadata - // can be initialized synchronously in the Cesium3DTile constructor - return processMetadataExtension(that, tilesetJson); - }) - .then(function (tilesetJson) { - if (that.isDestroyed()) { - return; - } + return Cesium3DTileset.loadJson(resource); + }) + .then(function (tilesetJson) { + if (that.isDestroyed()) { + return; + } - // Set these before loading the tileset since _geometricError - // and _scaledGeometricError get accessed during tile creation - that._geometricError = tilesetJson.geometricError; - that._scaledGeometricError = tilesetJson.geometricError; - - that._root = that.loadTileset(resource, tilesetJson); - - // Handle legacy gltfUpAxis option - const gltfUpAxis = defined(tilesetJson.asset.gltfUpAxis) - ? Axis.fromName(tilesetJson.asset.gltfUpAxis) - : Axis.Y; - const modelUpAxis = defaultValue(options.modelUpAxis, gltfUpAxis); - const modelForwardAxis = defaultValue(options.modelForwardAxis, Axis.X); - - const asset = tilesetJson.asset; - that._asset = asset; - that._properties = tilesetJson.properties; - that._extensionsUsed = tilesetJson.extensionsUsed; - that._extensions = tilesetJson.extensions; - that._modelUpAxis = modelUpAxis; - that._modelForwardAxis = modelForwardAxis; - that._extras = tilesetJson.extras; - - const extras = asset.extras; - if ( - defined(extras) && - defined(extras.cesium) && - defined(extras.cesium.credits) - ) { - const extraCredits = extras.cesium.credits; - let credits = that._credits; - if (!defined(credits)) { - credits = []; - that._credits = credits; + // This needs to be called before loadTileset() so tile metadata + // can be initialized synchronously in the Cesium3DTile constructor + return processMetadataExtension(resource, tilesetJson).then( + (metadata) => { + that._metadataExtension = metadata; + return tilesetJson; + } + ); + }) + .then(function (tilesetJson) { + if (that.isDestroyed()) { + return; } - for (let i = 0; i < extraCredits.length; ++i) { - const credit = extraCredits[i]; - credits.push(new Credit(credit.html, that._showCreditsOnScreen)); + + // Set these before loading the tileset since _geometricError + // and _scaledGeometricError get accessed during tile creation + that._geometricError = tilesetJson.geometricError; + that._scaledGeometricError = tilesetJson.geometricError; + + that._root = that.loadTileset(resource, tilesetJson); + + // Handle legacy gltfUpAxis option + const gltfUpAxis = defined(tilesetJson.asset.gltfUpAxis) + ? Axis.fromName(tilesetJson.asset.gltfUpAxis) + : Axis.Y; + const modelUpAxis = defaultValue(options.modelUpAxis, gltfUpAxis); + const modelForwardAxis = defaultValue(options.modelForwardAxis, Axis.X); + + const asset = tilesetJson.asset; + that._asset = asset; + that._properties = tilesetJson.properties; + that._extensionsUsed = tilesetJson.extensionsUsed; + that._extensions = tilesetJson.extensions; + that._modelUpAxis = modelUpAxis; + that._modelForwardAxis = modelForwardAxis; + that._extras = tilesetJson.extras; + + const extras = asset.extras; + if ( + defined(extras) && + defined(extras.cesium) && + defined(extras.cesium.credits) + ) { + const extraCredits = extras.cesium.credits; + let credits = that._credits; + if (!defined(credits)) { + credits = []; + that._credits = credits; + } + for (let i = 0; i < extraCredits.length; ++i) { + const credit = extraCredits[i]; + credits.push(new Credit(credit.html, that._showCreditsOnScreen)); + } } - } - // Save the original, untransformed bounding volume position so we can apply - // the tile transform and model matrix at run time - const boundingVolume = that._root.createBoundingVolume( - tilesetJson.root.boundingVolume, - Matrix4.IDENTITY - ); - const clippingPlanesOrigin = boundingVolume.boundingSphere.center; - // If this origin is above the surface of the earth - // we want to apply an ENU orientation as our best guess of orientation. - // Otherwise, we assume it gets its position/orientation completely from the - // root tile transform and the tileset's model matrix - const originCartographic = that._ellipsoid.cartesianToCartographic( - clippingPlanesOrigin - ); - if ( - defined(originCartographic) && - originCartographic.height > - ApproximateTerrainHeights._defaultMinTerrainHeight - ) { - that._initialClippingPlanesOriginMatrix = Transforms.eastNorthUpToFixedFrame( + // Save the original, untransformed bounding volume position so we can apply + // the tile transform and model matrix at run time + const boundingVolume = that._root.createBoundingVolume( + tilesetJson.root.boundingVolume, + Matrix4.IDENTITY + ); + const clippingPlanesOrigin = boundingVolume.boundingSphere.center; + // If this origin is above the surface of the earth + // we want to apply an ENU orientation as our best guess of orientation. + // Otherwise, we assume it gets its position/orientation completely from the + // root tile transform and the tileset's model matrix + const originCartographic = that._ellipsoid.cartesianToCartographic( clippingPlanesOrigin ); - } - that._clippingPlanesOriginMatrix = Matrix4.clone( - that._initialClippingPlanesOriginMatrix - ); + if ( + defined(originCartographic) && + originCartographic.height > + ApproximateTerrainHeights._defaultMinTerrainHeight + ) { + that._initialClippingPlanesOriginMatrix = Transforms.eastNorthUpToFixedFrame( + clippingPlanesOrigin + ); + } + that._clippingPlanesOriginMatrix = Matrix4.clone( + that._initialClippingPlanesOriginMatrix + ); - return that; - }); + return that; + }); + } } Object.defineProperties(Cesium3DTileset.prototype, { @@ -1108,19 +1135,9 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @type {object} * @readonly - * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. */ asset: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._asset; }, }, @@ -1132,19 +1149,9 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @type {object} * @readonly - * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. */ extensions: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._extensions; }, }, @@ -1177,8 +1184,6 @@ Object.defineProperties(Cesium3DTileset.prototype, { * @type {object} * @readonly * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. - * * @example * console.log(`Maximum building height: ${tileset.properties.height.maximum}`); * console.log(`Minimum building height: ${tileset.properties.height.minimum}`); @@ -1188,21 +1193,12 @@ Object.defineProperties(Cesium3DTileset.prototype, { */ properties: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._properties; }, }, /** * When <code>true</code>, the tileset's root tile is loaded and the tileset is ready to render. - * This is set to <code>true</code> right before {@link Cesium3DTileset#readyPromise} is resolved. * * @memberof Cesium3DTileset.prototype * @@ -1213,6 +1209,10 @@ Object.defineProperties(Cesium3DTileset.prototype, { */ ready: { get: function () { + deprecationWarning( + "Cesium3DTileset.ready", + "Cesium3DTileset.ready was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTileset.fromUrl instead." + ); return defined(this._root); }, }, @@ -1227,6 +1227,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @type {Promise<Cesium3DTileset>} * @readonly + * @deprecated * * @example * tileset.readyPromise.then(function(tileset) { @@ -1241,6 +1242,10 @@ Object.defineProperties(Cesium3DTileset.prototype, { */ readyPromise: { get: function () { + deprecationWarning( + "Cesium3DTileset.readyPromise", + "Cesium3DTileset.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTileset.fromUrl instead." + ); return this._readyPromise; }, }, @@ -1537,19 +1542,9 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @type {Cesium3DTile} * @readonly - * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. */ root: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._root; }, }, @@ -1562,28 +1557,16 @@ Object.defineProperties(Cesium3DTileset.prototype, { * @type {BoundingSphere} * @readonly * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. - * * @example - * const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ - * url : 'http://localhost:8002/tilesets/Seattle/tileset.json' - * })); + * const tileset = await Cesium.Cesium3DTileset.fromUrl("http://localhost:8002/tilesets/Seattle/tileset.json"); * - * tileset.readyPromise.then(function(tileset) { - * // Set the camera to view the newly added tileset - * viewer.camera.viewBoundingSphere(tileset.boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0)); - * }); + * viewer.scene.primitives.add(tileset); + * + * // Set the camera to view the newly added tileset + * viewer.camera.viewBoundingSphere(tileset.boundingSphere, new Cesium.HeadingPitchRange(0, -0.5, 0)); */ boundingSphere: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - this._root.updateTransform(this._modelMatrix); return this._root.boundingSphere; }, @@ -1806,8 +1789,6 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @memberof Cesium3DTileset.prototype * - * @exception {DeveloperError} The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true. - * * @type {*} * @readonly * @@ -1815,14 +1796,6 @@ Object.defineProperties(Cesium3DTileset.prototype, { */ extras: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The tileset is not loaded. Use Cesium3DTileset.readyPromise or wait for Cesium3DTileset.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._extras; }, }, @@ -1978,6 +1951,174 @@ Object.defineProperties(Cesium3DTileset.prototype, { }, }); +/** + * Creates a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles tileset}, + * used for streaming massive heterogeneous 3D geospatial datasets, from a Cesium ion asset ID. + * + * @param {number} assetId The Cesium ion asset id. + * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options + * + * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. + * + * @example + * //Load a Cesium3DTileset with asset ID of 124624234 + * try { + * const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(124624234); + * scene.primitives.add(tileset); + * } catch (error) { + * console.error(`Error creating tileset: ${error}`); + * } + */ +Cesium3DTileset.fromIonAssetId = async function (url, options) { + const resource = await IonResource.fromAssetId(124624234); + return Cesium3DTileset.fromUrl(resource); +}; + +/** + * Creates a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles tileset}, + * used for streaming massive heterogeneous 3D geospatial datasets. + * + * @param {Resource|string} url The url to a tileset JSON file. + * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options + * + * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. + * + * @example + * try { + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json" + * }); + * scene.primitives.add(tileset); + * } catch (error) { + * console.error(`Error creating tileset: ${error}`); + * } + * + * @example + * // Common setting for the skipLevelOfDetail optimization + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json", { + * skipLevelOfDetail: true, + * baseScreenSpaceError: 1024, + * skipScreenSpaceErrorFactor: 16, + * skipLevels: 1, + * immediatelyLoadDesiredLevelOfDetail: false, + * loadSiblings: false, + * cullWithChildrenBounds: true + * }); + * scene.primitives.add(tileset); + * + * @example + * // Common settings for the dynamicScreenSpaceError optimization + * const tileset = await Cesium.Cesium3DTileset.fromUrl( + * "http://localhost:8002/tilesets/Seattle/tileset.json", { + * dynamicScreenSpaceError: true, + * dynamicScreenSpaceErrorDensity: 0.00278, + * dynamicScreenSpaceErrorFactor: 4.0, + * dynamicScreenSpaceErrorHeightFalloff: 0.25 + * }); + * scene.primitives.add(tileset); + */ +Cesium3DTileset.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + const resource = Resource.createIfNeeded(url); + let basePath; + if (resource.extension === "json") { + basePath = resource.getBaseUri(true); + } else if (resource.isDataUri) { + basePath = ""; + } + + const tilesetJson = await Cesium3DTileset.loadJson(resource); + const metadataExtension = await processMetadataExtension( + resource, + tilesetJson + ); + + const tileset = new Cesium3DTileset(options); + tileset._resource = resource; + tileset._url = resource.url; + tileset._basePath = basePath; + tileset._metadataExtension = metadataExtension; + // Set these before loading the tileset since _geometricError + // and _scaledGeometricError get accessed during tile creation + tileset._geometricError = tilesetJson.geometricError; + tileset._scaledGeometricError = tilesetJson.geometricError; + + const asset = tilesetJson.asset; + tileset._asset = asset; + tileset._extras = tilesetJson.extras; + + let credits = resource.credits; + if (!defined(credits)) { + credits = []; + } + + const assetExtras = asset.extras; + if ( + defined(assetExtras) && + defined(assetExtras.cesium) && + defined(assetExtras.cesium.credits) + ) { + const extraCredits = assetExtras.cesium.credits; + for (let i = 0; i < extraCredits.length; ++i) { + const credit = extraCredits[i]; + credits.push(new Credit(credit.html, tileset._showCreditsOnScreen)); + } + } + tileset._credits = credits; + + // Handle legacy gltfUpAxis option + const gltfUpAxis = defined(tilesetJson.asset.gltfUpAxis) + ? Axis.fromName(tilesetJson.asset.gltfUpAxis) + : Axis.Y; + const modelUpAxis = defaultValue(options.modelUpAxis, gltfUpAxis); + const modelForwardAxis = defaultValue(options.modelForwardAxis, Axis.X); + + tileset._properties = tilesetJson.properties; + tileset._extensionsUsed = tilesetJson.extensionsUsed; + tileset._extensions = tilesetJson.extensions; + tileset._modelUpAxis = modelUpAxis; + tileset._modelForwardAxis = modelForwardAxis; + + tileset._root = tileset.loadTileset(resource, tilesetJson); + + // Save the original, untransformed bounding volume position so we can apply + // the tile transform and model matrix at run time + const boundingVolume = tileset._root.createBoundingVolume( + tilesetJson.root.boundingVolume, + Matrix4.IDENTITY + ); + const clippingPlanesOrigin = boundingVolume.boundingSphere.center; + // If this origin is above the surface of the earth + // we want to apply an ENU orientation as our best guess of orientation. + // Otherwise, we assume it gets its position/orientation completely from the + // root tile transform and the tileset's model matrix + const originCartographic = tileset._ellipsoid.cartesianToCartographic( + clippingPlanesOrigin + ); + if ( + defined(originCartographic) && + originCartographic.height > + ApproximateTerrainHeights._defaultMinTerrainHeight + ) { + tileset._initialClippingPlanesOriginMatrix = Transforms.eastNorthUpToFixedFrame( + clippingPlanesOrigin + ); + } + tileset._clippingPlanesOriginMatrix = Matrix4.clone( + tileset._initialClippingPlanesOriginMatrix + ); + + tileset._readyPromise = Promise.resolve(tileset); + tileset._ready = true; + return tileset; +}; + /** * Provides a hook to override the method used to request the tileset json * useful when fetching tilesets from remote servers @@ -2146,17 +2287,17 @@ function makeTile(tileset, baseResource, tileHeader, parentTile) { * * @param {Cesium3DTileset} tileset The tileset * @param {object} tilesetJson The tileset JSON - * @return {Promise<object>} A promise that resolves to tilesetJson for chaining. + * @return {Promise<Cesium3DTilesetMetadata>} The loaded Cesium3DTilesetMetadata * @private */ -function processMetadataExtension(tileset, tilesetJson) { +async function processMetadataExtension(resource, tilesetJson) { const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") ? tilesetJson.extensions["3DTILES_metadata"] : tilesetJson; let schemaLoader; if (defined(metadataJson.schemaUri)) { - const resource = tileset._resource.getDerivedResource({ + resource = resource.getDerivedResource({ url: metadataJson.schemaUri, }); schemaLoader = ResourceCache.getSchemaLoader({ @@ -2167,19 +2308,19 @@ function processMetadataExtension(tileset, tilesetJson) { schema: metadataJson.schema, }); } else { - return Promise.resolve(tilesetJson); + return; } - tileset._schemaLoader = schemaLoader; - - return schemaLoader.load().then(function (schemaLoader) { - tileset._metadataExtension = new Cesium3DTilesetMetadata({ - schema: schemaLoader.schema, - metadataJson: metadataJson, - }); + await schemaLoader.load(); - return tilesetJson; + const metadataExtension = new Cesium3DTilesetMetadata({ + schema: schemaLoader.schema, + metadataJson: metadataJson, }); + + ResourceCache.unload(schemaLoader); + + return metadataExtension; } const scratchPositionNormal = new Cartesian3(); @@ -2340,7 +2481,7 @@ function sortRequestByPriority(a, b) { * @param {FrameState} frameState */ Cesium3DTileset.prototype.postPassesUpdate = function (frameState) { - if (!this.ready) { + if (!defined(this._root)) { return; } @@ -2363,7 +2504,7 @@ Cesium3DTileset.prototype.postPassesUpdate = function (frameState) { * @param {FrameState} frameState */ Cesium3DTileset.prototype.prePassesUpdate = function (frameState) { - if (!this.ready) { + if (!defined(this._root)) { return; } @@ -2927,7 +3068,7 @@ function raiseLoadProgressEvent(tileset, frameState) { // Events are raised (added to the afterRender queue) here since promises // may resolve outside of the update loop that then raise events, e.g., - // model's readyPromise. + // model's readyEvent if (progressChanged && tileset._tilesLoaded) { frameState.afterRender.push(function () { tileset.allTilesLoaded.raiseEvent(); @@ -2998,7 +3139,7 @@ function update(tileset, frameState, passStatistics, passOptions) { return false; } - if (!tileset.ready) { + if (!defined(tileset._root)) { return false; } @@ -3169,10 +3310,6 @@ Cesium3DTileset.prototype.destroy = function () { this._tileDebugLabels && this._tileDebugLabels.destroy(); this._clippingPlanes = this._clippingPlanes && this._clippingPlanes.destroy(); - if (defined(this._schemaLoader)) { - ResourceCache.unload(this._schemaLoader); - } - // Traverse the tree and destroy all tiles if (defined(this._root)) { const stack = scratchStack; diff --git a/packages/engine/Source/Scene/I3SLayer.js b/packages/engine/Source/Scene/I3SLayer.js index a894236b8bf..214e2d3fb90 100644 --- a/packages/engine/Source/Scene/I3SLayer.js +++ b/packages/engine/Source/Scene/I3SLayer.js @@ -1,6 +1,7 @@ import defined from "../Core/defined.js"; import Rectangle from "../Core/Rectangle.js"; import Resource from "../Core/Resource.js"; +import RuntimeError from "../Core/RuntimeError.js"; import Cesium3DTileset from "./Cesium3DTileset.js"; import I3SNode from "./I3SNode.js"; @@ -84,7 +85,7 @@ Object.defineProperties(I3SLayer.prototype, { /** * Gets the Cesium3DTileset for this layer. * @memberof I3SLayer.prototype - * @type {Cesium3DTileset} + * @type {Cesium3DTileset|undefined} * @readonly */ tileset: { @@ -167,28 +168,22 @@ Object.defineProperties(I3SLayer.prototype, { * @returns {Promise} A promise that is resolved when the layer data is loaded * @private */ -I3SLayer.prototype.load = function () { - const that = this; - +I3SLayer.prototype.load = async function () { if (this._data.spatialReference.wkid !== 4326) { - console.log( + throw new RuntimeError( `Unsupported spatial reference: ${this._data.spatialReference.wkid}` ); - return Promise.reject(); } - return this._dataProvider._geoidDataIsReadyPromise.then(function () { - return that._loadRootNode().then(function () { - that._create3DTileset(); - return that._tileset.readyPromise.then(function () { - that._rootNode._tile = that._tileset._root; - that._tileset._root._i3sNode = that._rootNode; - if (that.legacyVersion16) { - return that._rootNode._loadChildren(); - } - }); - }); - }); + await this._dataProvider._geoidDataIsReadyPromise; + await this._loadRootNode(); + await this._create3DTileset(); + + this._rootNode._tile = this._tileset._root; + this._tileset._root._i3sNode = this._rootNode; + if (this.legacyVersion16) { + return this._rootNode._loadChildren(); + } }; /** @@ -378,7 +373,7 @@ I3SLayer.prototype._computeExtent = function () { /** * @private */ -I3SLayer.prototype._create3DTileset = function () { +I3SLayer.prototype._create3DTileset = async function () { const inPlaceTileset = { asset: { version: "1.0", @@ -391,7 +386,7 @@ I3SLayer.prototype._create3DTileset = function () { type: "application/json", }); - const inPlaceTilesetURL = URL.createObjectURL(tilesetBlob); + const tilesetUrl = URL.createObjectURL(tilesetBlob); const tilesetOptions = {}; if (defined(this._dataProvider._cesium3dTilesetOptions)) { @@ -401,26 +396,20 @@ I3SLayer.prototype._create3DTileset = function () { } } } - tilesetOptions.url = inPlaceTilesetURL; - tilesetOptions.show = this._dataProvider.show; - - this._tileset = new Cesium3DTileset(tilesetOptions); + this._tileset = await Cesium3DTileset.fromUrl(tilesetUrl, tilesetOptions); + this._tileset.show = this._dataProvider.show; this._tileset._isI3STileSet = true; + this._tileset.tileUnload.addEventListener(function (tile) { + tile._i3sNode._clearGeometryData(); + URL.revokeObjectURL(tile._contentResource._url); + tile._contentResource = tile._i3sNode.resource; + }); - const that = this; - this._tileset.readyPromise.then(function () { - that._tileset.tileUnload.addEventListener(function (tile) { - tile._i3sNode._clearGeometryData(); - URL.revokeObjectURL(tile._contentResource._url); - tile._contentResource = tile._i3sNode.resource; - }); - - that._tileset.tileVisible.addEventListener(function (tile) { - if (defined(tile._i3sNode)) { - tile._i3sNode._loadChildren(); - } - }); + this._tileset.tileVisible.addEventListener(function (tile) { + if (defined(tile._i3sNode)) { + tile._i3sNode._loadChildren(); + } }); }; diff --git a/packages/engine/Source/Scene/createOsmBuildings.js b/packages/engine/Source/Scene/createOsmBuildings.js index d17e717ba37..5e7f8286ab6 100644 --- a/packages/engine/Source/Scene/createOsmBuildings.js +++ b/packages/engine/Source/Scene/createOsmBuildings.js @@ -2,6 +2,7 @@ import Color from "../Core/Color.js"; import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import IonResource from "../Core/IonResource.js"; import Cesium3DTileset from "./Cesium3DTileset.js"; import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; @@ -49,6 +50,11 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; * })); */ function createOsmBuildings(options) { + deprecationWarning( + "createOsmBuildings", + "createOsmBuildings was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use createOsmBuildingsAsync instead." + ); + options = combine(options, { url: IonResource.fromAssetId(96188), }); diff --git a/packages/engine/Source/Scene/createOsmBuildingsAsync.js b/packages/engine/Source/Scene/createOsmBuildingsAsync.js new file mode 100644 index 00000000000..8206ce5a178 --- /dev/null +++ b/packages/engine/Source/Scene/createOsmBuildingsAsync.js @@ -0,0 +1,84 @@ +import Color from "../Core/Color.js"; +import defaultValue from "../Core/defaultValue.js"; +import defined from "../Core/defined.js"; +import IonResource from "../Core/IonResource.js"; +import Cesium3DTileset from "./Cesium3DTileset.js"; +import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; + +/** + * Creates a {@link Cesium3DTileset} instance for the + * {@link https://cesium.com/content/cesium-osm-buildings/|Cesium OSM Buildings} + * tileset. + * + * @function + * + * @param {object} [options] Construction options. Any options allowed by the {@link Cesium3DTileset} constructor + * may be specified here. In addition to those, the following properties are supported: + * @param {Color} [options.defaultColor=Color.WHITE] The default color to use for buildings + * that do not have a color. This parameter is ignored if <code>options.style</code> is specified. + * @param {Cesium3DTileStyle} [options.style] The style to use with the tileset. If not + * specified, a default style is used which gives each building or building part a + * color inferred from its OpenStreetMap <code>tags</code>. If no color can be inferred, + * <code>options.defaultColor</code> is used. + * @param {boolean} [options.enableShowOutline=true] If true, enable rendering outlines. This can be set to false to avoid the additional processing of geometry at load time. + * @param {boolean} [options.showOutline=true] Whether to show outlines around buildings. When true, + * outlines are displayed. When false, outlines are not displayed. + * @returns {Promise<Cesium3DTileset>} + * + * @see Ion + * + * @example + * // Create Cesium OSM Buildings with default styling + * const viewer = new Cesium.Viewer("cesiumContainer"); + * try { + * const tileset = await Cesium.createOsmBuildingsAsync(); + * viewer.scene.primitives.add(tileset)); + * } catch (error) { + * console.log(`Error creating tileset: ${error}`); + * } + * + * @example + * // Create Cesium OSM Buildings with a custom style highlighting + * // schools and hospitals. + * const viewer = new Cesium.Viewer("cesiumContainer"); + * try { + * const tileset = await Cesium.createOsmBuildingsAsync({ + * style: new Cesium.Cesium3DTileStyle({ + * color: { + * conditions: [ + * ["${feature['building']} === 'hospital'", "color('#0000FF')"], + * ["${feature['building']} === 'school'", "color('#00FF00')"], + * [true, "color('#ffffff')"] + * ] + * } + * }) + * }); + * viewer.scene.primitives.add(tileset)); + * } catch (error) { + * console.log(`Error creating tileset: ${error}`); + * } + */ +async function createOsmBuildingsAsync(options) { + const tileset = await Cesium3DTileset.fromUrl( + IonResource.fromAssetId(96188), + options + ); + + let style = options.style; + + if (!defined(style)) { + const color = defaultValue( + options.defaultColor, + Color.WHITE + ).toCssColorString(); + style = new Cesium3DTileStyle({ + color: `Boolean(\${feature['cesium#color']}) ? color(\${feature['cesium#color']}) : ${color}`, + }); + } + + tileset.style = style; + + return tileset; +} + +export default createOsmBuildingsAsync; diff --git a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js index 5181dad6a3a..054adceae03 100644 --- a/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/Cesium3DTilesetVisualizerSpec.js @@ -6,6 +6,7 @@ import { Matrix4, Resource, BoundingSphereState, + Cesium3DTileset, ConstantPositionProperty, ConstantProperty, EntityCollection, @@ -35,22 +36,10 @@ describe( scene.destroyForSpecs(); }); - function allPrimitivesReady() { - const promises = []; - for (let i = 0; i < scene.primitives.length; ++i) { - promises.push(scene.primitives.get(i).readyPromise); - } - return Promise.all(promises).catch(function (e) { - // 404 errors - }); - } - afterEach(function () { - return allPrimitivesReady().then(function () { - if (defined(visualizer)) { - visualizer = visualizer.destroy(); - } - }); + if (defined(visualizer)) { + visualizer = visualizer.destroy(); + } }); it("constructor throws if no scene is passed.", function () { @@ -85,7 +74,7 @@ describe( visualizer = undefined; }); - it("object with no model does not create one.", function () { + it("object with no tileset does not create one.", function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -97,7 +86,7 @@ describe( expect(scene.primitives.length).toEqual(0); }); - it("object with no position does not set modelMatrix.", function () { + it("object with no position does not set modelMatrix.", async function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -107,11 +96,15 @@ describe( visualizer.update(JulianDate.now()); + await pollToPromise(function () { + return defined(scene.primitives.get(0)); + }); + const tilesetPrimitive = scene.primitives.get(0); expect(tilesetPrimitive.modelMatrix).toEqual(Matrix4.IDENTITY); }); - it("A Cesium3DTilesetGraphics causes a primitive to be created and updated.", function () { + it("A Cesium3DTilesetGraphics causes a primitive to be created and updated.", async function () { const time = JulianDate.now(); const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -129,7 +122,12 @@ describe( visualizer.update(time); + await pollToPromise(function () { + return defined(scene.primitives.get(0)); + }); + expect(scene.primitives.length).toEqual(1); + expect(scene.primitives.get(0)).toBeInstanceOf(Cesium3DTileset); const primitive = scene.primitives.get(0); visualizer.update(time); @@ -137,7 +135,7 @@ describe( expect(primitive.maximumScreenSpaceError).toEqual(24.0); }); - it("A Cesium3DTilesetGraphics with a Resource causes a primitive to be created.", function () { + it("A Cesium3DTilesetGraphics with a Resource causes a primitive to be created.", async function () { const time = JulianDate.now(); const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -158,10 +156,15 @@ describe( visualizer.update(time); + await pollToPromise(function () { + return defined(scene.primitives.get(0)); + }); + expect(scene.primitives.length).toEqual(1); + expect(scene.primitives.get(0)).toBeInstanceOf(Cesium3DTileset); }); - it("removing removes primitives.", function () { + it("removing removes primitives.", async function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -175,16 +178,17 @@ describe( ); testObject.tileset = tileset; visualizer.update(time); - return allPrimitivesReady().then(function () { - expect(scene.primitives.length).toEqual(1); - visualizer.update(time); - entityCollection.removeAll(); - visualizer.update(time); - expect(scene.primitives.length).toEqual(0); + await pollToPromise(function () { + return defined(scene.primitives.get(0)); }); + expect(scene.primitives.length).toEqual(1); + visualizer.update(time); + entityCollection.removeAll(); + visualizer.update(time); + expect(scene.primitives.length).toEqual(0); }); - it("Visualizer sets id property.", function () { + it("Visualizer sets id property.", async function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -199,11 +203,15 @@ describe( tileset.uri = new ConstantProperty(tilesetUrl); visualizer.update(time); + await pollToPromise(function () { + return defined(scene.primitives.get(0)); + }); + const tilesetPrimitive = scene.primitives.get(0); expect(tilesetPrimitive.id).toEqual(testObject); }); - it("Computes bounding sphere.", function () { + it("Computes bounding sphere.", async function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -218,19 +226,18 @@ describe( tileset.uri = new ConstantProperty(tilesetUrl); visualizer.update(time); - const tilesetPrimitive = scene.primitives.get(0); const result = new BoundingSphere(); let state = visualizer.getBoundingSphere(testObject, result); expect(state).toBe(BoundingSphereState.PENDING); - return pollToPromise(function () { - scene.render(); + await pollToPromise(function () { state = visualizer.getBoundingSphere(testObject, result); return state !== BoundingSphereState.PENDING; - }).then(function () { - expect(state).toBe(BoundingSphereState.DONE); - expect(result).toEqual(tilesetPrimitive.boundingSphere); }); + + const tilesetPrimitive = scene.primitives.get(0); + expect(state).toBe(BoundingSphereState.DONE); + expect(result).toEqual(tilesetPrimitive.boundingSphere); }); it("Fails bounding sphere for entity without tileset.", function () { @@ -243,7 +250,7 @@ describe( expect(state).toBe(BoundingSphereState.FAILED); }); - it("Fails bounding sphere when model fails to load.", function () { + it("Fails bounding sphere when tileset fails to load.", async function () { const entityCollection = new EntityCollection(); visualizer = new Cesium3DTilesetVisualizer(scene, entityCollection); @@ -261,14 +268,14 @@ describe( const result = new BoundingSphere(); let state = visualizer.getBoundingSphere(testObject, result); expect(state).toBe(BoundingSphereState.PENDING); - return allPrimitivesReady() - .catch(function (e) { - // 404 error - }) - .finally(function () { - state = visualizer.getBoundingSphere(testObject, result); - expect(state).toBe(BoundingSphereState.FAILED); - }); + + await pollToPromise(function () { + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + + state = visualizer.getBoundingSphere(testObject, result); + expect(state).toBe(BoundingSphereState.FAILED); }); it("Compute bounding sphere throws without entity.", function () { diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 10bef3ed990..92902d24dcf 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -39,6 +39,7 @@ import { RequestScheduler, Resource, ResourceCache, + RuntimeError, Transforms, } from "../../index.js"; import Cesium3DTilesTester from "../../../../Specs/Cesium3DTilesTester.js"; @@ -263,12 +264,6 @@ describe( return tileset._selectedTiles.indexOf(tile) > -1; } - it("throws with undefined url", function () { - expect(function () { - return new Cesium3DTileset(); - }).toThrowDeveloperError(); - }); - it("rejects readyPromise with invalid tileset JSON file", function () { spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( url, @@ -372,7 +367,7 @@ describe( it("rejects readyPromise with invalid tileset version", function () { const tilesetJson = { asset: { - version: 2.0, + version: "2.0", }, }; @@ -392,7 +387,7 @@ describe( it("rejects readyPromise with unsupported extension", function () { const tilesetJson = { asset: { - version: 1.0, + version: "1.0", }, extensionsUsed: ["unsupported_extension"], extensionsRequired: ["unsupported_extension"], @@ -411,27 +406,68 @@ describe( }); }); - it("url and tilesetUrl set up correctly given tileset JSON filepath", function () { - const path = "Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); - return Promise.resolve(tileset).then(function () { - expect(tileset.resource.url).toEqual(path); - return tileset.readyPromise; + it("fromUrl throws without url", async function () { + await expectAsync( + Cesium3DTileset.fromUrl() + ).toBeRejectedWithDeveloperError( + "url is required, actual value was undefined" + ); + }); + + it("fromUrl throws with unsupported version", async function () { + const tilesetJson = { + asset: { + version: "2.0", + }, + }; + + const uri = `data:text/plain;base64,${btoa(JSON.stringify(tilesetJson))}`; + await expectAsync(Cesium3DTileset.fromUrl(uri)).toBeRejectedWithError( + RuntimeError, + "The tileset must be 3D Tiles version 0.0, 1.0, or 1.1" + ); + }); + + it("fromUrl throws with unsupported extension", async function () { + const tilesetJson = { + asset: { + version: "1.0", + }, + extensionsUsed: ["unsupported_extension"], + extensionsRequired: ["unsupported_extension"], + }; + + const uri = `data:text/plain;base64,${btoa(JSON.stringify(tilesetJson))}`; + await expectAsync(Cesium3DTileset.fromUrl(uri)).toBeRejectedWithError( + RuntimeError, + "Unsupported 3D Tiles Extension: unsupported_extension" + ); + }); + + it("fromUrl throws with invalid tileset JSON file", async function () { + await expectAsync(Cesium3DTileset.fromUrl("invalid.json")).toBeRejected(); + }); + + it("fromUrl resolves with file resource", async function () { + const resource = new Resource({ + url: "Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json", }); + + const tileset = await Cesium3DTileset.fromUrl(resource); + expect(tileset).toBeInstanceOf(Cesium3DTileset); }); - it("url and tilesetUrl set up correctly given path with query string", function () { + it("url and tilesetUrl set up correctly given tileset JSON filepath", async function () { + const path = "Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; + const tileset = await Cesium3DTileset.fromUrl(path); + expect(tileset.resource.url).toEqual(path); + }); + + it("url and tilesetUrl set up correctly given path with query string", async function () { const path = "Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; const param = "?param1=1¶m2=2"; - const tileset = new Cesium3DTileset({ - url: path + param, - }); - return Promise.resolve(tileset).then(function () { - expect(tileset.resource.url).toEqual(path + param); - return tileset.readyPromise; - }); + const tileset = await Cesium3DTileset.fromUrl(path + param); + expect(tileset.resource.url).toEqual(path + param); }); it("resolves readyPromise", function () { @@ -487,15 +523,9 @@ describe( }); }); - it("gets root tile", function () { - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - expect(function () { - return tileset.root; - }).toThrowDeveloperError(); - return tileset.readyPromise.then(function () { - expect(tileset.root).toBeDefined(); - }); + it("gets root tile", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + expect(tileset.root).toBeDefined(); }); it("hasExtension returns true if the tileset JSON file uses the specified extension", function () { @@ -551,53 +581,12 @@ describe( }); }); - it("throws when getting asset and tileset is not ready", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - expect(function () { - return tileset.asset; - }).toThrowDeveloperError(); - return tileset.readyPromise; - }); - - it("throws when getting extensions and tileset is not ready", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - expect(function () { - return tileset.extensions; - }).toThrowDeveloperError(); - return tileset.readyPromise; - }); - - it("throws when getting properties and tileset is not ready", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - expect(function () { - return tileset.properties; - }).toThrowDeveloperError(); - return tileset.readyPromise; - }); - - it("throws when getting extras and tileset is not ready", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - expect(function () { - return tileset.extras; - }).toThrowDeveloperError(); - return tileset.readyPromise; - }); - it("requests tile with invalid magic", async function () { const invalidMagicBuffer = Cesium3DTilesTester.generateBatchedTileBuffer({ magic: [120, 120, 120, 120], }); - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - await tileset.readyPromise; + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); const failedSpy = jasmine.createSpy("listenerSpy"); tileset.tileFailed.addEventListener(failedSpy); @@ -624,9 +613,8 @@ describe( it("handles failed tile requests", async function () { viewRootOnly(); - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - await tileset.readyPromise; + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); const failedSpy = jasmine.createSpy("listenerSpy"); tileset.tileFailed.addEventListener(failedSpy); @@ -657,9 +645,8 @@ describe( it("handles failed tile processing", async function () { viewRootOnly(); - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - await tileset.readyPromise; + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); const failedSpy = jasmine.createSpy("listenerSpy"); tileset.tileFailed.addEventListener(failedSpy); @@ -867,34 +854,23 @@ describe( }); }); - it("verify statistics", function () { - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); - // Verify initial values + // Verify initial values after root and children are requested const statistics = tileset._statistics; expect(statistics.visited).toEqual(0); expect(statistics.numberOfCommands).toEqual(0); expect(statistics.numberOfPendingRequests).toEqual(0); expect(statistics.numberOfTilesProcessing).toEqual(0); - return Cesium3DTilesTester.waitForReady(scene, tileset).then(function () { - // Check that root and children are requested - expect(statistics.visited).toEqual(5); - expect(statistics.numberOfCommands).toEqual(0); - expect(statistics.numberOfPendingRequests).toEqual(5); - expect(statistics.numberOfTilesProcessing).toEqual(0); - - // Wait for all tiles to load and check that they are all visited and rendered - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(statistics.visited).toEqual(5); - expect(statistics.numberOfCommands).toEqual(5); - expect(statistics.numberOfPendingRequests).toEqual(0); - expect(statistics.numberOfTilesProcessing).toEqual(0); - } - ); - }); + scene.primitives.add(tileset); + // Wait for all tiles to load and check that they are all visited and rendered + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(statistics.visited).toEqual(5); + expect(statistics.numberOfCommands).toEqual(5); + expect(statistics.numberOfPendingRequests).toEqual(0); + expect(statistics.numberOfTilesProcessing).toEqual(0); }); function checkPointAndFeatureCounts(tileset, features, points, triangles) { @@ -935,62 +911,74 @@ describe( ); } - it("verify batched features statistics", function () { - options.url = withBatchTableUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify batched features statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl(withBatchTableUrl, options); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 10, 0, 120); }); - it("verify no batch table features statistics", function () { - options.url = noBatchIdsUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify no batch table features statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl(noBatchIdsUrl, options); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 0, 0, 120); }); - it("verify instanced features statistics", function () { - options.url = instancedRedMaterialUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify instanced features statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl( + instancedRedMaterialUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 25, 0, 12); }); - it("verify composite features statistics", function () { - options.url = compositeUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify composite features statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl(compositeUrl, options); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 35, 0, 132); }); - it("verify tileset of tilesets features statistics", function () { - options.url = tilesetOfTilesetsUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify tileset of tilesets features statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl( + tilesetOfTilesetsUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 50, 0, 600); }); - it("verify points statistics", function () { + it("verify points statistics", async function () { viewPointCloud(); - options.url = pointCloudUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + const tileset = await Cesium3DTileset.fromUrl(pointCloudUrl, options); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 0, 1000, 0); }); - it("verify triangle statistics", function () { - options.url = tilesetEmptyRootUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify triangle statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl( + tilesetEmptyRootUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 40, 0, 480); }); - it("verify batched points statistics", function () { + it("verify batched points statistics", async function () { viewPointCloud(); - options.url = pointCloudBatchedUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + const tileset = await Cesium3DTileset.fromUrl( + pointCloudBatchedUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 8, 1000, 0); }); @@ -2443,41 +2431,31 @@ describe( }); }); - it("tilesLoaded", function () { - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("tilesLoaded", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); expect(tileset.tilesLoaded).toBe(false); - return tileset.readyPromise.then(function () { - expect(tileset.tilesLoaded).toBe(false); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(tileset.tilesLoaded).toBe(true); - } - ); - }); + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(tileset.tilesLoaded).toBe(true); }); - it("all tiles loaded event is raised", function () { + it("all tiles loaded event is raised", async function () { // Called first when only the root is visible and it becomes loaded, and then again when // the rest of the tileset is visible and all tiles are loaded. const spyUpdate1 = jasmine.createSpy("listener"); const spyUpdate2 = jasmine.createSpy("listener"); viewRootOnly(); - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); tileset.allTilesLoaded.addEventListener(spyUpdate1); tileset.initialTilesLoaded.addEventListener(spyUpdate2); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - viewAllTiles(); - return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( - function () { - expect(spyUpdate1.calls.count()).toEqual(2); - expect(spyUpdate2.calls.count()).toEqual(1); - } - ); - } - ); + scene.primitives.add(tileset); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + viewAllTiles(); + + await Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); + expect(spyUpdate1.calls.count()).toEqual(2); + expect(spyUpdate2.calls.count()).toEqual(1); }); it("tile visible event is raised", function () { @@ -2613,9 +2591,8 @@ describe( it("destroys before tile finishes loading", async function () { viewRootOnly(); - options.url = tilesetUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); - await tileset.readyPromise; + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); const root = tileset.root; scene.renderForSpecs(); // Request root scene.primitives.remove(tileset); @@ -3724,24 +3701,18 @@ describe( }); }); - it("maximumMemoryUsage throws when negative", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); + it("maximumMemoryUsage throws when negative", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); expect(function () { tileset.maximumMemoryUsage = -1; }).toThrowDeveloperError(); - return tileset.readyPromise; }); - it("maximumScreenSpaceError throws when negative", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); + it("maximumScreenSpaceError throws when negative", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); expect(function () { tileset.maximumScreenSpaceError = -1; }).toThrowDeveloperError(); - return tileset.readyPromise; }); it("propagates tile transform down the tree", function () { @@ -3960,10 +3931,10 @@ describe( }); }); - it("does not add commands or stencil clear command with no selected tiles", function () { - options.url = tilesetUrl; + it("does not add commands or stencil clear command with no selected tiles", async function () { options.skipLevelOfDetail = true; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); + scene.primitives.add(tileset); scene.renderForSpecs(); const statistics = tileset._statistics; expect(tileset._selectedTiles.length).toEqual(0); @@ -4655,28 +4626,20 @@ describe( ); }); - it("throws if frameState is undefined", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); + it("throws if frameState is undefined", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); expect(function () { tileset.updateForPass(); }).toThrowDeveloperError(); - - return tileset.readyPromise; }); - it("throws if tilesetPassState is undefined", function () { - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); + it("throws if tilesetPassState is undefined", async function () { + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl, options); expect(function () { tileset.updateForPass(scene.frameState); }).toThrowDeveloperError(); - - return tileset.readyPromise; }); }); @@ -5585,12 +5548,8 @@ describe( viewNothing(); - const tileset = scene.primitives.add( - new Cesium3DTileset({ - url: multipleContentsUrl, - }) - ); - await tileset.readyPromise; + const tileset = await Cesium3DTileset.fromUrl(multipleContentsUrl); + scene.primitives.add(tileset); viewAllTiles(); scene.renderForSpecs(); @@ -5687,9 +5646,12 @@ describe( expect(statistics.numberOfTilesWithContentReady).toBe(1); }); - it("verify multiple content statistics", function () { - options.url = multipleContentsUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify multiple content statistics", async function () { + const tileset = await Cesium3DTileset.fromUrl( + multipleContentsUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 35, 0, 132); }); @@ -5763,11 +5725,8 @@ describe( viewNothing(); let errorCount = 0; - const tileset = scene.primitives.add( - new Cesium3DTileset({ - url: multipleContentsUrl, - }) - ); + + const tileset = await Cesium3DTileset.fromUrl(multipleContentsUrl); tileset.tileFailed.addEventListener(function (event) { errorCount++; expect(endsWith(event.url, ".json")).toBe(true); @@ -5775,7 +5734,7 @@ describe( "External tilesets are disallowed inside multiple contents" ); }); - await tileset.readyPromise; + scene.primitives.add(tileset); spyOn(Resource.prototype, "fetchArrayBuffer").and.callFake(function () { const externalTileset = { @@ -5985,9 +5944,12 @@ describe( expect(statistics.numberOfTilesWithContentReady).toBe(1); }); - it("verify multiple content statistics (legacy)", function () { - options.url = multipleContentsLegacyUrl; - const tileset = scene.primitives.add(new Cesium3DTileset(options)); + it("verify multiple content statistics (legacy)", async function () { + const tileset = await Cesium3DTileset.fromUrl( + multipleContentsLegacyUrl, + options + ); + scene.primitives.add(tileset); return checkPointAndFeatureCounts(tileset, 35, 0, 132); }); diff --git a/packages/engine/Specs/Scene/I3SLayerSpec.js b/packages/engine/Specs/Scene/I3SLayerSpec.js index cbc8bcd5279..4dbf710091a 100644 --- a/packages/engine/Specs/Scene/I3SLayerSpec.js +++ b/packages/engine/Specs/Scene/I3SLayerSpec.js @@ -1,4 +1,9 @@ -import { I3SLayer, I3SDataProvider, Math as CesiumMath } from "../../index.js"; +import { + I3SLayer, + I3SDataProvider, + Math as CesiumMath, + RuntimeError, +} from "../../index.js"; describe("Scene/I3SLayer", function () { const rootNodePageEntry = { @@ -284,7 +289,7 @@ describe("Scene/I3SLayer", function () { }); }); - it("creates 3d tileset", function () { + it("creates 3d tileset", async function () { const mockI3SProvider = createMockI3SProvider(); const testLayer = new I3SLayer(mockI3SProvider, layerData); testLayer._nodePages = [ @@ -293,21 +298,15 @@ describe("Scene/I3SLayer", function () { ]; testLayer._nodePageFetches = [Promise.resolve()]; - return testLayer - ._loadRootNode() - .then(function () { - testLayer._create3DTileset(); - expect(testLayer.tileset).toBeDefined(); + await testLayer._loadRootNode(); + await testLayer._create3DTileset(); - return testLayer.tileset.readyPromise; - }) - .then(function () { - expect(testLayer.tileset.tileUnload._listeners.length).toEqual(1); - expect(testLayer.tileset.tileVisible._listeners.length).toEqual(1); - }); + expect(testLayer.tileset).toBeDefined(); + expect(testLayer.tileset.tileUnload._listeners.length).toEqual(1); + expect(testLayer.tileset.tileVisible._listeners.length).toEqual(1); }); - it("creates 3d tileset with options", function () { + it("creates 3d tileset with options", async function () { const cesium3dTilesetOptions = { debugShowBoundingVolume: true, maximumScreenSpaceError: 8, @@ -326,23 +325,17 @@ describe("Scene/I3SLayer", function () { ]; testLayer._nodePageFetches = [Promise.resolve()]; - return testLayer - ._loadRootNode() - .then(function () { - testLayer._create3DTileset(); - expect(testLayer.tileset).toBeDefined(); - expect(testLayer.tileset.debugShowBoundingVolume).toEqual(true); - expect(testLayer.tileset.maximumScreenSpaceError).toEqual(8); + await testLayer._loadRootNode(); + await testLayer._create3DTileset(); + expect(testLayer.tileset).toBeDefined(); + expect(testLayer.tileset.debugShowBoundingVolume).toEqual(true); + expect(testLayer.tileset.maximumScreenSpaceError).toEqual(8); - return testLayer._tileset.readyPromise; - }) - .then(function () { - expect(testLayer.tileset.tileUnload._listeners.length).toEqual(1); - expect(testLayer.tileset.tileVisible._listeners.length).toEqual(1); - }); + expect(testLayer.tileset.tileUnload._listeners.length).toEqual(1); + expect(testLayer.tileset.tileVisible._listeners.length).toEqual(1); }); - it("loads i3s layer", function () { + it("loads i3s layer", async function () { const mockI3SProvider = createMockI3SProvider(); const testLayer = new I3SLayer(mockI3SProvider, layerData); testLayer._nodePages = [ @@ -351,15 +344,14 @@ describe("Scene/I3SLayer", function () { ]; testLayer._nodePageFetches = [Promise.resolve()]; - return testLayer.load().then(function () { - expect(testLayer.tileset).toBeDefined(); - expect(testLayer._rootNode).toBeDefined(); - expect(testLayer._rootNode._tile).toBe(testLayer.tileset._root); - expect(testLayer._rootNode).toBe(testLayer.tileset._root.i3sNode); - }); + await testLayer.load(); + expect(testLayer.tileset).toBeDefined(); + expect(testLayer._rootNode).toBeDefined(); + expect(testLayer._rootNode._tile).toBe(testLayer.tileset._root); + expect(testLayer._rootNode).toBe(testLayer.tileset._root.i3sNode); }); - it("load i3s layer rejects unsupported spatial reference", function () { + it("load i3s layer rejects unsupported spatial reference", async function () { const invalidLayerData = { nodePages: { lodSelectionMetricType: "maxScreenThresholdSQ", @@ -381,19 +373,9 @@ describe("Scene/I3SLayer", function () { ]; testLayer._nodePageFetches = [Promise.resolve()]; - spyOn(console, "log"); - - return testLayer - .load() - .then(function () { - fail( - "Promise should not be resolved for unsupported spatial reference" - ); - }) - .catch(function () { - expect(console.log).toHaveBeenCalledWith( - `Unsupported spatial reference: ${invalidLayerData.spatialReference.wkid}` - ); - }); + await expectAsync(testLayer.load()).toBeRejectedWithError( + RuntimeError, + `Unsupported spatial reference: ${invalidLayerData.spatialReference.wkid}` + ); }); }); diff --git a/packages/engine/Specs/Scene/Vector3DTileContentSpec.js b/packages/engine/Specs/Scene/Vector3DTileContentSpec.js index 6bdf4724dc7..4106b41aa0e 100644 --- a/packages/engine/Specs/Scene/Vector3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTileContentSpec.js @@ -2219,10 +2219,10 @@ describe( ); }); - it("destroys", function () { - const tileset = new Cesium3DTileset({ - url: vectorTilePolygonsWithBatchTableTileset, - }); + it("destroys", async function () { + const tileset = await Cesium3DTileset.fromUrl( + vectorTilePolygonsWithBatchTableTileset + ); expect(tileset.isDestroyed()).toEqual(false); tileset.destroy(); expect(tileset.isDestroyed()).toEqual(true); diff --git a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js index 60c337fc9b7..8b9f0683dd8 100644 --- a/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js +++ b/packages/widgets/Source/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js @@ -1224,7 +1224,8 @@ Object.defineProperties(Cesium3DTilesInspectorViewModel.prototype, { if (defined(tileset)) { const that = this; - tileset.readyPromise.then(function (t) { + // This is here for backwards compatibility. It can be removed when Cesium3DTileset.readyPromise is fully deprecated. + tileset._readyPromise.then(function (t) { if (!that.isDestroyed()) { that._properties(t.properties); } diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 751b2d0f503..42216d4aa28 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2233,7 +2233,8 @@ function updateZoomTarget(viewer) { // If zoomTarget was Cesium3DTileset if (target instanceof Cesium3DTileset || target instanceof VoxelPrimitive) { - return target.readyPromise + // This is here for backwards compatibility and can be removed once Cesium3DTileset.readyPromise is removed. + return target._readyPromise .then(function () { const boundingSphere = target.boundingSphere; // If offset was originally undefined then give it base value instead of empty object diff --git a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js index 94cc1760c52..b38d5101390 100644 --- a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js +++ b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js @@ -53,36 +53,31 @@ describe( }); describe("tileset options", function () { - it("show properties", function () { + it("show properties", async function () { viewModel = new Cesium3DTilesInspectorViewModel( scene, performanceContainer ); - const tileset = new Cesium3DTileset({ + const tileset = await Cesium3DTileset.fromUrl({ url: tilesetUrl, }); viewModel.tileset = tileset; - return tileset.readyPromise.then(function () { - expect(viewModel.properties.indexOf("id") !== -1).toBe(true); - expect(viewModel.properties.indexOf("Longitude") !== -1).toBe(true); - expect(viewModel.properties.indexOf("Latitude") !== -1).toBe(true); - expect(viewModel.properties.indexOf("Height") !== -1).toBe(true); - viewModel.destroy(); - }); + expect(viewModel.properties.indexOf("id") !== -1).toBe(true); + expect(viewModel.properties.indexOf("Longitude") !== -1).toBe(true); + expect(viewModel.properties.indexOf("Latitude") !== -1).toBe(true); + expect(viewModel.properties.indexOf("Height") !== -1).toBe(true); + viewModel.destroy(); }); }); describe("display options", function () { - beforeAll(function () { + beforeAll(async function () { viewModel = new Cesium3DTilesInspectorViewModel( scene, performanceContainer ); - const tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl); viewModel.tileset = tileset; - return tileset.readyPromise; }); afterAll(function () { @@ -228,15 +223,12 @@ describe( }); describe("update options", function () { - beforeAll(function () { + beforeAll(async function () { viewModel = new Cesium3DTilesInspectorViewModel( scene, performanceContainer ); - viewModel.tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - return viewModel.tileset.readyPromise; + viewModel.tileset = await Cesium3DTileset.fromUrl(tilesetUrl); }); afterAll(function () { @@ -270,7 +262,7 @@ describe( describe("style options", function () { let style; - beforeAll(function () { + beforeAll(async function () { style = new Cesium3DTileStyle({ color: { conditions: [ @@ -292,11 +284,7 @@ describe( scene, performanceContainer ); - viewModel.tileset = new Cesium3DTileset({ - url: tilesetUrl, - }); - - return viewModel.tileset.readyPromise; + viewModel.tileset = await Cesium3DTileset.fromUrl(tilesetUrl); }); afterAll(function () { diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index b626261028e..cfabcc15a8b 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -1240,95 +1240,67 @@ describe( }).toThrowDeveloperError(); }); - it("zoomTo returns false if Cesium3DTileset fails to load", function () { - viewer = createViewer(container); - const tileset = new Cesium3DTileset({ - url: "foo/bar", - }); - - return tileset.readyPromise - .catch(function (e) { - expect(e.toString()).toEqual("Request has failed. Status Code: 404"); - }) - .then(function () { - return viewer.zoomTo(tileset); - }) - .then((result) => { - expect(result).toBe(false); - }); - }); - - it("zoomTo zooms to Cesium3DTileset with default offset when offset not defined", function () { + it("zoomTo zooms to Cesium3DTileset with default offset when offset not defined", async function () { viewer = createViewer(container); const path = "./Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); + const tileset = await Cesium3DTileset.fromUrl(path); - // load the tileset then check tests - return tileset.readyPromise.then(function () { - const expectedBoundingSphere = tileset.boundingSphere; - const expectedOffset = new HeadingPitchRange( - 0.0, - -0.5, - expectedBoundingSphere.radius - ); + const expectedBoundingSphere = tileset.boundingSphere; + const expectedOffset = new HeadingPitchRange( + 0.0, + -0.5, + expectedBoundingSphere.radius + ); - let wasCompleted = false; - spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( - boundingSphere, - offset - ) { - expect(boundingSphere).toEqual(expectedBoundingSphere); - expect(offset).toEqual(expectedOffset); - wasCompleted = true; - }); - const promise = viewer.zoomTo(tileset); + let wasCompleted = false; + spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( + boundingSphere, + offset + ) { + expect(boundingSphere).toEqual(expectedBoundingSphere); + expect(offset).toEqual(expectedOffset); + wasCompleted = true; + }); + const promise = viewer.zoomTo(tileset); - viewer._postRender(); + viewer._postRender(); - return promise.then(function () { - expect(wasCompleted).toEqual(true); - }); + return promise.then(function () { + expect(wasCompleted).toEqual(true); }); }); - it("zoomTo zooms to Cesium3DTileset with offset", function () { + it("zoomTo zooms to Cesium3DTileset with offset", async function () { viewer = createViewer(container); const path = "./Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); + const tileset = await Cesium3DTileset.fromUrl(path); - // load the tileset then check tests - return tileset.readyPromise.then(function () { - const expectedBoundingSphere = tileset.boundingSphere; - const expectedOffset = new HeadingPitchRange( - 0.4, - 1.2, - 4.0 * expectedBoundingSphere.radius - ); + const expectedBoundingSphere = tileset.boundingSphere; + const expectedOffset = new HeadingPitchRange( + 0.4, + 1.2, + 4.0 * expectedBoundingSphere.radius + ); - const promise = viewer.zoomTo(tileset, expectedOffset); - let wasCompleted = false; - spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( - boundingSphere, - offset - ) { - expect(boundingSphere).toEqual(expectedBoundingSphere); - expect(offset).toEqual(expectedOffset); - wasCompleted = true; - }); + const promise = viewer.zoomTo(tileset, expectedOffset); + let wasCompleted = false; + spyOn(viewer.camera, "viewBoundingSphere").and.callFake(function ( + boundingSphere, + offset + ) { + expect(boundingSphere).toEqual(expectedBoundingSphere); + expect(offset).toEqual(expectedOffset); + wasCompleted = true; + }); - viewer._postRender(); + viewer._postRender(); - return promise.then(function () { - expect(wasCompleted).toEqual(true); - }); + return promise.then(function () { + expect(wasCompleted).toEqual(true); }); }); @@ -1587,110 +1559,95 @@ describe( }).toThrowDeveloperError(); }); - it("flyTo flies to Cesium3DTileset with default offset when options not defined", function () { + it("flyTo flies to Cesium3DTileset with default offset when options not defined", async function () { viewer = createViewer(container); const path = "./Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); + const tileset = await Cesium3DTileset.fromUrl(path); - // load tileset to test - return tileset.readyPromise.then(function () { - const promise = viewer.flyTo(tileset); - let wasCompleted = false; + const promise = viewer.flyTo(tileset); + let wasCompleted = false; - spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( - target, - options - ) { - expect(options.offset).toBeDefined(); - expect(options.duration).toBeUndefined(); - expect(options.maximumHeight).toBeUndefined(); - wasCompleted = true; - options.complete(); - }); + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.offset).toBeDefined(); + expect(options.duration).toBeUndefined(); + expect(options.maximumHeight).toBeUndefined(); + wasCompleted = true; + options.complete(); + }); - viewer._postRender(); + viewer._postRender(); - return promise.then(function () { - expect(wasCompleted).toEqual(true); - }); + return promise.then(function () { + expect(wasCompleted).toEqual(true); }); }); - it("flyTo flies to Cesium3DTileset with default offset when offset not defined", function () { + it("flyTo flies to Cesium3DTileset with default offset when offset not defined", async function () { viewer = createViewer(container); const path = "./Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); + const tileset = await Cesium3DTileset.fromUrl(path); const options = {}; - // load tileset to test - return tileset.readyPromise.then(function () { - const promise = viewer.flyTo(tileset, options); - let wasCompleted = false; + const promise = viewer.flyTo(tileset, options); + let wasCompleted = false; - spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( - target, - options - ) { - expect(options.offset).toBeDefined(); - expect(options.duration).toBeUndefined(); - expect(options.maximumHeight).toBeUndefined(); - wasCompleted = true; - options.complete(); - }); + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.offset).toBeDefined(); + expect(options.duration).toBeUndefined(); + expect(options.maximumHeight).toBeUndefined(); + wasCompleted = true; + options.complete(); + }); - viewer._postRender(); + viewer._postRender(); - return promise.then(function () { - expect(wasCompleted).toEqual(true); - }); + return promise.then(function () { + expect(wasCompleted).toEqual(true); }); }); - it("flyTo flies to Cesium3DTileset when options are defined", function () { + it("flyTo flies to Cesium3DTileset when options are defined", async function () { viewer = createViewer(container); const path = "./Data/Cesium3DTiles/Tilesets/TilesetOfTilesets/tileset.json"; - const tileset = new Cesium3DTileset({ - url: path, - }); + const tileset = await Cesium3DTileset.fromUrl(path); - // load tileset to test - return tileset.readyPromise.then(function () { - const offsetVal = new HeadingPitchRange(3.0, 0.2, 2.3); - const options = { - offset: offsetVal, - duration: 3.0, - maximumHeight: 5.0, - }; + const offsetVal = new HeadingPitchRange(3.0, 0.2, 2.3); + const options = { + offset: offsetVal, + duration: 3.0, + maximumHeight: 5.0, + }; - const promise = viewer.flyTo(tileset, options); - let wasCompleted = false; + const promise = viewer.flyTo(tileset, options); + let wasCompleted = false; - spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( - target, - options - ) { - expect(options.duration).toBeDefined(); - expect(options.maximumHeight).toBeDefined(); - wasCompleted = true; - options.complete(); - }); + spyOn(viewer.camera, "flyToBoundingSphere").and.callFake(function ( + target, + options + ) { + expect(options.duration).toBeDefined(); + expect(options.maximumHeight).toBeDefined(); + wasCompleted = true; + options.complete(); + }); - viewer._postRender(); + viewer._postRender(); - return promise.then(function () { - expect(wasCompleted).toEqual(true); - }); + return promise.then(function () { + expect(wasCompleted).toEqual(true); }); }); From 4f8c8cd19b95f42d152210ef69c89c467d24616b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 20 Mar 2023 16:02:37 -0400 Subject: [PATCH 555/679] Update Sandcastles --- Apps/Sandcastle/gallery/3D Tiles BIM.html | 3 +- .../gallery/3D Tiles Clipping Planes.html | 152 +++--- Apps/Sandcastle/gallery/3D Tiles Compare.html | 21 +- .../gallery/3D Tiles Feature Picking.html | 10 +- .../gallery/3D Tiles Feature Styling.html | 2 +- Apps/Sandcastle/gallery/3D Tiles Formats.html | 83 ++-- .../gallery/3D Tiles Inspector.html | 31 +- .../gallery/3D Tiles Interactivity.html | 27 +- .../Sandcastle/gallery/3D Tiles Interior.html | 10 +- .../gallery/3D Tiles Next CDB Yemen.html | 99 ++-- ...es Next Photogrammetry Classification.html | 38 +- .../gallery/3D Tiles Next S2 Globe.html | 15 +- ...D Tiles Photogrammetry Classification.html | 70 +-- .../gallery/3D Tiles Photogrammetry.html | 13 +- .../3D Tiles Point Cloud Classification.html | 55 +-- .../gallery/3D Tiles Point Cloud Shading.html | 126 ++--- .../gallery/3D Tiles Point Cloud Styling.html | 19 +- .../gallery/3D Tiles Point Cloud.html | 14 +- .../3D Tiles Terrain Classification.html | 22 +- .../gallery/Aerometrex San Francisco.html | 20 +- .../Sandcastle/gallery/Ambient Occlusion.html | 20 +- .../Sandcastle/gallery/Clamp to 3D Tiles.html | 21 +- .../gallery/Classification Types.html | 12 +- Apps/Sandcastle/gallery/Classification.html | 10 +- .../gallery/Custom Shaders 3D Tiles.html | 34 +- .../Custom Shaders Property Textures.html | 19 +- Apps/Sandcastle/gallery/FXAA.html | 15 +- Apps/Sandcastle/gallery/Fog Post Process.html | 23 +- Apps/Sandcastle/gallery/MSAA.html | 34 +- .../gallery/Montreal Point Cloud.html | 29 +- .../gallery/Polylines on 3D Tiles.html | 65 ++- .../gallery/Sample Height from 3D Tiles.html | 13 +- .../gallery/Scene Rendering Performance.html | 21 +- .../gallery/Terrain Clipping Planes.html | 84 ++-- .../3D Tiles Performance Testing.html | 3 +- .../gallery/development/3D Tiles Split.html | 79 ++-- .../development/Many Clipping Planes.html | 19 +- .../gallery/development/Pick From Ray.html | 7 +- .../gallery/development/Picking.html | 434 ++++++++---------- .../gallery/development/Shadows.html | 24 +- CHANGES.md | 2 +- Documentation/CustomShaderGuide/README.md | 9 +- Documentation/OfflineGuide/README.md | 13 +- packages/engine/Source/Scene/BufferLoader.js | 2 + .../engine/Source/Scene/Cesium3DTileset.js | 6 +- packages/engine/Source/Scene/GltfLoader.js | 14 + packages/engine/Source/Scene/ResourceCache.js | 2 +- .../Source/Scene/Tileset3DTileContent.js | 4 +- .../Source/Scene/createOsmBuildingsAsync.js | 8 +- 49 files changed, 979 insertions(+), 877 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles BIM.html b/Apps/Sandcastle/gallery/3D Tiles BIM.html index 06df8cba02b..542878ac305 100644 --- a/Apps/Sandcastle/gallery/3D Tiles BIM.html +++ b/Apps/Sandcastle/gallery/3D Tiles BIM.html @@ -209,8 +209,7 @@ }); } catch (error) { console.log(`Error loading tileset: ${error}`); - } - //Sandcastle_End + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index 9547272431f..b6ce63560bf 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -142,7 +142,8 @@ } let tileset; - function loadTileset(url) { + async function loadTileset(resource) { + const currentExampleType = viewModel.currentExampleType; clippingPlanes = new Cesium.ClippingPlaneCollection({ planes: [ new Cesium.ClippingPlane( @@ -153,77 +154,76 @@ edgeWidth: viewModel.edgeStylingEnabled ? 1.0 : 0.0, }); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, + try { + const url = await Promise.resolve(resource); + tileset = await Cesium.Cesium3DTileset.fromUrl(url, { clippingPlanes: clippingPlanes, - }) - ); - - tileset.debugShowBoundingVolume = - viewModel.debugBoundingVolumesEnabled; - return tileset.readyPromise - .then(function () { - const boundingSphere = tileset.boundingSphere; - const radius = boundingSphere.radius; + }); + if (currentExampleType !== viewModel.currentExampleType) { + // Another tileset was loaded, discard the current result + return; + } - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + viewer.scene.primitives.add(tileset); + + tileset.debugShowBoundingVolume = + viewModel.debugBoundingVolumesEnabled; + const boundingSphere = tileset.boundingSphere; + const radius = boundingSphere.radius; + + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + + if ( + !Cesium.Matrix4.equals( + tileset.root.transform, + Cesium.Matrix4.IDENTITY + ) + ) { + // The clipping plane is initially positioned at the tileset's root transform. + // Apply an additional matrix to center the clipping plane on the bounding sphere center. + const transformCenter = Cesium.Matrix4.getTranslation( + tileset.root.transform, + new Cesium.Cartesian3() + ); + const transformCartographic = Cesium.Cartographic.fromCartesian( + transformCenter ); + const boundingSphereCartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const height = + boundingSphereCartographic.height - + transformCartographic.height; + clippingPlanes.modelMatrix = Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(0.0, 0.0, height) + ); + } - if ( - !Cesium.Matrix4.equals( - tileset.root.transform, - Cesium.Matrix4.IDENTITY - ) - ) { - // The clipping plane is initially positioned at the tileset's root transform. - // Apply an additional matrix to center the clipping plane on the bounding sphere center. - const transformCenter = Cesium.Matrix4.getTranslation( - tileset.root.transform, - new Cesium.Cartesian3() - ); - const transformCartographic = Cesium.Cartographic.fromCartesian( - transformCenter - ); - const boundingSphereCartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center - ); - const height = - boundingSphereCartographic.height - - transformCartographic.height; - clippingPlanes.modelMatrix = Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(0.0, 0.0, height) - ); - } - - for (let i = 0; i < clippingPlanes.length; ++i) { - const plane = clippingPlanes.get(i); - const planeEntity = viewer.entities.add({ - position: boundingSphere.center, - plane: { - dimensions: new Cesium.Cartesian2( - radius * 2.5, - radius * 2.5 - ), - material: Cesium.Color.WHITE.withAlpha(0.1), - plane: new Cesium.CallbackProperty( - createPlaneUpdateFunction(plane), - false - ), - outline: true, - outlineColor: Cesium.Color.WHITE, - }, - }); - - planeEntities.push(planeEntity); - } - return tileset; - }) - .catch(function (error) { - console.log(error); - }); + for (let i = 0; i < clippingPlanes.length; ++i) { + const plane = clippingPlanes.get(i); + const planeEntity = viewer.entities.add({ + position: boundingSphere.center, + plane: { + dimensions: new Cesium.Cartesian2(radius * 2.5, radius * 2.5), + material: Cesium.Color.WHITE.withAlpha(0.1), + plane: new Cesium.CallbackProperty( + createPlaneUpdateFunction(plane), + false + ), + outline: true, + outlineColor: Cesium.Color.WHITE, + }, + }); + + planeEntities.push(planeEntity); + } + return tileset; + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } function loadModel(url) { @@ -308,11 +308,12 @@ } else if (newValue === clipObjects[1]) { loadTileset(pointCloudUrl); } else if (newValue === clipObjects[2]) { - loadTileset(instancedUrl); - // Position the instanced tileset above terrain - tileset.modelMatrix = new Cesium.Matrix4.fromTranslation( - new Cesium.Cartesian3(15.0, -58.6, 50.825) - ); + loadTileset(instancedUrl).then(() => { + // Position the instanced tileset above terrain + tileset.modelMatrix = new Cesium.Matrix4.fromTranslation( + new Cesium.Cartesian3(15.0, -58.6, 50.825) + ); + }); } else { loadModel(modelUrl); } @@ -336,7 +337,10 @@ function reset() { viewer.entities.removeAll(); - viewer.scene.primitives.remove(tileset); + if (Cesium.defined(tileset)) { + viewer.scene.primitives.remove(tileset); + } + planeEntities = []; targetY = 0.0; tileset = undefined; diff --git a/Apps/Sandcastle/gallery/3D Tiles Compare.html b/Apps/Sandcastle/gallery/3D Tiles Compare.html index 5f494f9abe7..6e209e819f0 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Compare.html +++ b/Apps/Sandcastle/gallery/3D Tiles Compare.html @@ -54,18 +54,19 @@ //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); - const left = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(69380), - }) - ); + try { + const left = await Cesium.Cesium3DTileset.fromIonAssetId(69380); + viewer.scene.primitives.add(left); + left.splitDirection = Cesium.SplitDirection.LEFT; - left.splitDirection = Cesium.SplitDirection.LEFT; + viewer.zoomTo(left); - const right = viewer.scene.primitives.add(Cesium.createOsmBuildings()); - right.splitDirection = Cesium.SplitDirection.RIGHT; - - viewer.zoomTo(left); + const right = await Cesium.createOsmBuildingsAsync(); + viewer.scene.primitives.add(right); + right.splitDirection = Cesium.SplitDirection.RIGHT; + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } // Sync the position of the slider with the split position const slider = document.getElementById("slider"); diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index 8174e5fdec8..b486801ef7e 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -59,10 +59,12 @@ }); // Load the NYC buildings tileset - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - viewer.scene.primitives.add(tileset); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } // HTML overlay for showing feature name on mouseover const nameOverlay = document.createElement("div"); diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html index c9fe5b050eb..ddadf3af659 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Styling.html @@ -61,7 +61,7 @@ <h1>Loading...</h1> const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); // Add Cesium OSM buildings to the scene as our example 3D Tileset. - const osmBuildingsTileset = Cesium.createOsmBuildings(); + const osmBuildingsTileset = await Cesium.createOsmBuildingsAsync(); viewer.scene.primitives.add(osmBuildingsTileset); // Set the initial camera to look at Seattle diff --git a/Apps/Sandcastle/gallery/3D Tiles Formats.html b/Apps/Sandcastle/gallery/3D Tiles Formats.html index e141b25e538..7c7d1fb50cf 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Formats.html +++ b/Apps/Sandcastle/gallery/3D Tiles Formats.html @@ -140,59 +140,62 @@ viewer.shadows = enabled; }); + let resourceToLoad; Cesium.knockout .getObservable(viewModel, "selectedTileset") - .subscribe(function (options) { + .subscribe(async function (options) { if (Cesium.defined(tileset)) { scene.primitives.remove(tileset); } if (!Cesium.defined(options)) { inspectorViewModel.tileset = undefined; + resourceToLoad = undefined; return; } - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: options.resource, + resourceToLoad = options.resource; + try { + tileset = await Cesium.Cesium3DTileset.fromUrl(resourceToLoad, { enableDebugWireframe: true, - }) - ); + }); + if (options.resource !== resourceToLoad) { + // Another tileset was loaded. Discard the result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.readyPromise - .then(function () { - inspectorViewModel.tileset = tileset; - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0, - -2.0, - Math.max(100.0 - tileset.boundingSphere.radius, 0.0) - ) - ); + inspectorViewModel.tileset = tileset; + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0, + -2.0, + Math.max(100.0 - tileset.boundingSphere.radius, 0.0) + ) + ); - const properties = tileset.properties; - if ( - Cesium.defined(properties) && - Cesium.defined(properties.Height) - ) { - tileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${Height} >= 83", "color('purple', 0.5)"], - ["${Height} >= 80", "color('red')"], - ["${Height} >= 70", "color('orange')"], - ["${Height} >= 12", "color('yellow')"], - ["${Height} >= 7", "color('lime')"], - ["${Height} >= 1", "color('cyan')"], - ["true", "color('blue')"], - ], - }, - }); - } - }) - .catch(function (error) { - throw error; - }); + const properties = tileset.properties; + if ( + Cesium.defined(properties) && + Cesium.defined(properties.Height) + ) { + tileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${Height} >= 83", "color('purple', 0.5)"], + ["${Height} >= 80", "color('red')"], + ["${Height} >= 70", "color('orange')"], + ["${Height} >= 12", "color('yellow')"], + ["${Height} >= 7", "color('lime')"], + ["${Height} >= 1", "color('cyan')"], + ["true", "color('blue')"], + ], + }, + }); + } + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } }); viewModel.selectedTileset = viewModel.tilesets[0]; diff --git a/Apps/Sandcastle/gallery/3D Tiles Inspector.html b/Apps/Sandcastle/gallery/3D Tiles Inspector.html index 736bde4e8f3..1ad857bd51a 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Inspector.html +++ b/Apps/Sandcastle/gallery/3D Tiles Inspector.html @@ -46,22 +46,23 @@ viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin); const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - enableDebugWireframe: true, - }); - viewer.scene.primitives.add(tileset); - - await tileset.readyPromise; + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343, { + enableDebugWireframe: true, + }); + viewer.scene.primitives.add(tileset); - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0.0, - -0.5, - tileset.boundingSphere.radius / 4.0 - ) - ); //Sandcastle_End + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0.0, + -0.5, + tileset.boundingSphere.radius / 4.0 + ) + ); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html index 30426497ff7..a55fae14eb1 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interactivity.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interactivity.html @@ -114,16 +114,20 @@ endTransform: Cesium.Matrix4.IDENTITY, }); + let style; // Load the NYC buildings tileset. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }); - scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - meta: { - description: "'Building ${BIN} has height ${Height}.'", - }, - }); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343); + scene.primitives.add(tileset); + style = new Cesium.Cesium3DTileStyle({ + meta: { + description: "'Building ${BIN} has height ${Height}.'", + }, + }); + tileset.style = style; + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); @@ -185,8 +189,11 @@ } // Evaluate feature description + if (!Cesium.defined(style)) { + return; + } console.log( - `Description : ${tileset.style.meta.description.evaluate(feature)}` + `Description : ${style.meta.description.evaluate(feature)}` ); } diff --git a/Apps/Sandcastle/gallery/3D Tiles Interior.html b/Apps/Sandcastle/gallery/3D Tiles Interior.html index 3fc2975278f..38c63747e69 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Interior.html +++ b/Apps/Sandcastle/gallery/3D Tiles Interior.html @@ -39,10 +39,12 @@ // San Miguel model created by Guillermo M. Leal Llaguno. Cleaned up and hosted by Morgan McGuire: http://graphics.cs.williams.edu/data/meshes.xml const viewer = new Cesium.Viewer("cesiumContainer"); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(125737), - }); - viewer.scene.primitives.add(tileset); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(125737); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const initialPosition = new Cesium.Cartesian3( -1111583.3721328347, diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index 515f30909f2..c69b695c55b 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -52,19 +52,6 @@ const scene = viewer.scene; scene.light.intensity = 7.0; - // 3D Tiles Next converted from CDB of Aden, Yemen (CDB provided by Presagis) - const terrainTileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(667809), - }) - ); - const buildingsTileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(666747), - maximumScreenSpaceError: 12, - }) - ); - const cameraTransforms = { tileset: { destination: new Cesium.Cartesian3( @@ -149,19 +136,6 @@ }); } - buildingsTileset.readyPromise.then(function (tileset) { - const center = Cesium.Cartesian3.fromDegrees( - 45.04192, - 12.753525, - 2000 - ); - const heading = Cesium.Math.toRadians(50.0); - const pitch = Cesium.Math.toRadians(-20.0); - const range = 5000.0; - - flyCameraTo(cameraTransforms.tileset); - }); - // --- Style --- const buildingStyle = new Cesium.Cesium3DTileStyle({ @@ -408,34 +382,61 @@ } } - const modes = [ - { - text: "No style", - onselect: function () { - resetHighlight(); - buildingsTileset.style = undefined; - terrainTileset.style = undefined; + try { + // 3D Tiles Next converted from CDB of Aden, Yemen (CDB provided by Presagis) + const terrainTileset = await Cesium.Cesium3DTileset.fromIonAssetId( + 1240402 + ); + viewer.scene.primitives.add(terrainTileset); + const buildingsTileset = await Cesium.Cesium3DTileset.fromIonAssetId( + 666747, + { + maximumScreenSpaceError: 12, + } + ); + viewer.scene.primitives.add(buildingsTileset); + const center = Cesium.Cartesian3.fromDegrees( + 45.04192, + 12.753525, + 2000 + ); + const heading = Cesium.Math.toRadians(50.0); + const pitch = Cesium.Math.toRadians(-20.0); + const range = 5000.0; + + flyCameraTo(cameraTransforms.tileset); + + const modes = [ + { + text: "No style", + onselect: function () { + resetHighlight(); + buildingsTileset.style = undefined; + terrainTileset.style = undefined; + }, }, - }, - { - text: "Style buildings based on height", - onselect: function () { - resetHighlight(); - buildingsTileset.style = buildingStyle; - terrainTileset.style = undefined; + { + text: "Style buildings based on height", + onselect: function () { + resetHighlight(); + buildingsTileset.style = buildingStyle; + terrainTileset.style = undefined; + }, }, - }, - { - text: "Style terrain based on materials", - onselect: function () { - buildingsTileset.style = undefined; - terrainTileset.style = terrainStyle; + { + text: "Style terrain based on materials", + onselect: function () { + buildingsTileset.style = undefined; + terrainTileset.style = terrainStyle; + }, }, - }, - ]; + ]; + Sandcastle.addToolbarMenu(modes); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } Sandcastle.addToolbarMenu(locations); - Sandcastle.addToolbarMenu(modes); Sandcastle.addToggleButton( "Enable terrain picking", enablePicking, diff --git a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html index 97f23ac0aba..1f024d001d3 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next Photogrammetry Classification.html @@ -48,24 +48,6 @@ const scene = viewer.scene; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(775877), - }); - - const translation = new Cesium.Cartesian3( - -1.398521324920626, - 0.7823052871729486, - 0.7015244410592609 - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - - tileset.maximumScreenSpaceError = 8.0; - scene.pickTranslucentDepth = true; - scene.light.intensity = 7.0; - - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); - // Fly to a nice overview of the city. viewer.camera.flyTo({ destination: new Cesium.Cartesian3( @@ -80,6 +62,26 @@ ), }); + let tileset; + try { + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(775877); + + const translation = new Cesium.Cartesian3( + -1.398521324920626, + 0.7823052871729486, + 0.7015244410592609 + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + + tileset.maximumScreenSpaceError = 8.0; + scene.pickTranslucentDepth = true; + scene.light.intensity = 7.0; + + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } + // Styles ============================================================================= const classificationStyle = new Cesium.Cesium3DTileStyle({ diff --git a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html index f1d18063448..28f1198ab04 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html @@ -74,13 +74,16 @@ easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT, }); - // MAXAR OWT WFF 1.2 Base Globe - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(691510), + let tileset; + try { + // MAXAR OWT WFF 1.2 Base Globe + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(691510, { maximumScreenSpaceError: 4, - }) - ); + }); + scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } // --- Style --- diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html index f59d6b68833..d2cff77c241 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry Classification.html @@ -41,41 +41,47 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - // A normal b3dm tileset containing photogrammetry - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + try { + // A normal b3dm tileset containing photogrammetry + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); - const classificationTilesetUrl = - "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; - // A b3dm tileset used to classify the photogrammetry tileset - const classificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(classificationTileset); + const classificationTilesetUrl = + "../../SampleData/Cesium3DTiles/Classification/Photogrammetry/tileset.json"; + // A b3dm tileset used to classify the photogrammetry tileset + const classificationTileset = await Cesium.Cesium3DTileset.fromUrl( + classificationTilesetUrl, + { + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + } + ); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(classificationTileset); - // The same b3dm tileset used for classification, but rendered normally for comparison. - const nonClassificationTileset = new Cesium.Cesium3DTileset({ - url: classificationTilesetUrl, - show: false, - }); - nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 0, 0, 0.5)", - }); - viewer.scene.primitives.add(nonClassificationTileset); + // The same b3dm tileset used for classification, but rendered normally for comparison. + const nonClassificationTileset = await Cesium.Cesium3DTileset.fromUrl( + classificationTilesetUrl, + { + show: false, + } + ); + nonClassificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 0, 0, 0.5)", + }); + viewer.scene.primitives.add(nonClassificationTileset); - Sandcastle.addToggleButton("Show classification", true, function ( - checked - ) { - classificationTileset.show = checked; - nonClassificationTileset.show = !checked; - }); //Sandcastle_End + Sandcastle.addToggleButton("Show classification", true, function ( + checked + ) { + classificationTileset.show = checked; + nonClassificationTileset.show = !checked; + }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html index ca2b8281520..7bfde7dcc8f 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html +++ b/Apps/Sandcastle/gallery/3D Tiles Photogrammetry.html @@ -40,12 +40,13 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); //Sandcastle_End + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html index d07104ec585..9b472838122 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Classification.html @@ -41,35 +41,38 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - //Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + try { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(16421); + viewer.scene.primitives.add(tileset); - // Geometry Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry - const classificationTileset = new Cesium.Cesium3DTileset({ - url: + // Geometry Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/Geometry + const classificationTileset = await Cesium.Cesium3DTileset.fromUrl( "../../SampleData/Cesium3DTiles/Classification/PointCloud/tileset.json", - classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, - }); - viewer.scene.primitives.add(classificationTileset); + { + classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, + } + ); + viewer.scene.primitives.add(classificationTileset); - classificationTileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${id} === 'roof1'", "color('#004FFF', 0.5)"], - ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], - ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], - ["${id} === 'roof2'", "color('#004FFF', 0.5)"], - ["${id} === 'tower3'", "color('#FF8833', 0.5)"], - ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], - ["true", "color('#FFFF00', 0.5)"], - ], - }, - }); + classificationTileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${id} === 'roof1'", "color('#004FFF', 0.5)"], + ["${id} === 'towerBottom1'", "color('#33BB66', 0.5)"], + ["${id} === 'towerTop1'", "color('#0099AA', 0.5)"], + ["${id} === 'roof2'", "color('#004FFF', 0.5)"], + ["${id} === 'tower3'", "color('#FF8833', 0.5)"], + ["${id} === 'tower4'", "color('#FFAA22', 0.5)"], + ["true", "color('#FFFF00', 0.5)"], + ], + }, + }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } viewer.scene.camera.setView({ destination: new Cesium.Cartesian3( diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html index cdc3ed6fc5d..1beeba7bff9 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Shading.html @@ -207,71 +207,83 @@ pointCloudShading.eyeDomeLightingRadius; } - function loadStHelens() { - // Set the initial camera view to look at Mt. St. Helens - const initialPosition = Cesium.Cartesian3.fromRadians( - -2.1344873183780484, - 0.8071380277370774, - 5743.394497982162 - ); - const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( - 112.99596671210358, - -21.34390550872461, - 0.0716951918898415 - ); - viewer.scene.camera.setView({ - destination: initialPosition, - orientation: initialOrientation, - endTransform: Cesium.Matrix4.IDENTITY, - }); + async function loadStHelens() { + try { + // Set the initial camera view to look at Mt. St. Helens + const initialPosition = Cesium.Cartesian3.fromRadians( + -2.1344873183780484, + 0.8071380277370774, + 5743.394497982162 + ); + const initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees( + 112.99596671210358, + -21.34390550872461, + 0.0716951918898415 + ); + viewer.scene.camera.setView({ + destination: initialPosition, + orientation: initialOrientation, + endTransform: Cesium.Matrix4.IDENTITY, + }); - // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ - // This tileset uses replacement refinement and has geometric error approximately equal to - // the average interpoint distance in each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - viewer.scene.primitives.add(tileset); + // Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/ + // This tileset uses replacement refinement and has geometric error approximately equal to + // the average interpoint distance in each tile. + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(5713); + if (viewModel.currentExampleType !== pointClouds[0]) { + // Scenario has changes. Discards the result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead - tileset.pointCloudShading.baseResolution = undefined; - tileset.pointCloudShading.geometricErrorScale = 1.0; - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = undefined; // Will be based on maximumScreenSpaceError instead + tileset.pointCloudShading.baseResolution = undefined; + tileset.pointCloudShading.geometricErrorScale = 1.0; + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - tilesetToViewModel(tileset); + tilesetToViewModel(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } - function loadChurch() { - // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. - // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); + async function loadChurch() { + try { + // Point Cloud by Prof. Peter Allen, Columbia University Robotics Lab. Scanning by Alejandro Troccoli and Matei Ciocarlie. + // This tileset uses additive refinement and has geometric error based on the bounding box size for each tile. + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(16421); + if (viewModel.currentExampleType !== pointClouds[1]) { + // Scenario has changes. Discards the result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.maximumScreenSpaceError = 16.0; - tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. - tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. - tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. - tileset.pointCloudShading.attenuation = true; - tileset.pointCloudShading.eyeDomeLighting = true; + tileset.maximumScreenSpaceError = 16.0; + tileset.pointCloudShading.maximumAttenuation = 4.0; // Don't allow points larger than 4 pixels. + tileset.pointCloudShading.baseResolution = 0.05; // Assume an original capture resolution of 5 centimeters between neighboring points. + tileset.pointCloudShading.geometricErrorScale = 0.5; // Applies to both geometric error and the base resolution. + tileset.pointCloudShading.attenuation = true; + tileset.pointCloudShading.eyeDomeLighting = true; - viewer.scene.camera.setView({ - destination: new Cesium.Cartesian3( - 4401744.644145314, - 225051.41078911052, - 4595420.374784433 - ), - orientation: new Cesium.HeadingPitchRoll( - 5.646733805039757, - -0.276607153839886, - 6.281110875400085 - ), - }); + viewer.scene.camera.setView({ + destination: new Cesium.Cartesian3( + 4401744.644145314, + 225051.41078911052, + 4595420.374784433 + ), + orientation: new Cesium.HeadingPitchRoll( + 5.646733805039757, + -0.276607153839886, + 6.281110875400085 + ), + }); - tilesetToViewModel(tileset); + tilesetToViewModel(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } function checkZero(newValue) { diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html index c0d8b25038f..0b9882c0948 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud Styling.html @@ -42,12 +42,16 @@ const viewer = new Cesium.Viewer("cesiumContainer"); viewer.clock.currentTime = new Cesium.JulianDate(2457522.154792); - const tileset = new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/PointCloud/PointCloudWithPerPointProperties/tileset.json", - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -1.0, 50.0)); + let tileset; + try { + tileset = await Cesium.Cesium3DTileset.fromUrl( + "../../SampleData/Cesium3DTiles/PointCloud/PointCloudWithPerPointProperties/tileset.json" + ); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -1.0, 50.0)); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const styles = []; function addStyle(name, style) { @@ -219,6 +223,9 @@ function setStyle(style) { return function () { + if (!Cesium.defined(tileset)) { + return; + } tileset.style = new Cesium.Cesium3DTileStyle(style); }; } diff --git a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html index 2d5fa1d21e6..10c52266ef4 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html +++ b/Apps/Sandcastle/gallery/3D Tiles Point Cloud.html @@ -41,11 +41,6 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(16421), - }); - viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ destination: new Cesium.Cartesian3( 4401744.644145314, @@ -57,7 +52,14 @@ -0.276607153839886, 6.281110875400085 ), - }); //Sandcastle_End + }); + + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(16421); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html index ef9ea1301f1..086aeaba8e0 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html +++ b/Apps/Sandcastle/gallery/3D Tiles Terrain Classification.html @@ -45,17 +45,19 @@ geocoder.flightDuration = 0.0; geocoder.search(); - // Vector 3D Tiles are experimental and the format is subject to change in the future. - // For more details, see: - // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5737), - }); - viewer.scene.primitives.add(tileset); + try { + // Vector 3D Tiles are experimental and the format is subject to change in the future. + // For more details, see: + // https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(5737); + viewer.scene.primitives.add(tileset); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgba(255, 255, 255, 0.5)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgba(255, 255, 255, 0.5)", + }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } // Information about the currently highlighted feature const highlighted = { diff --git a/Apps/Sandcastle/gallery/Aerometrex San Francisco.html b/Apps/Sandcastle/gallery/Aerometrex San Francisco.html index ad722934e5e..c90af96ea9e 100755 --- a/Apps/Sandcastle/gallery/Aerometrex San Francisco.html +++ b/Apps/Sandcastle/gallery/Aerometrex San Francisco.html @@ -32,20 +32,18 @@ <div id="loadingOverlay"><h1>Loading...</h1></div> <div id="toolbar"></div> <script id="cesium_sandcastle_script"> - window.startup = function (Cesium) { + window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer", { - terrainProvider: Cesium.createWorldTerrain(), + terrain: Cesium.Terrain.fromWorldTerrain(), }); // Aerometrex San Francisco High Resolution 3D Model with Street Level Enhanced 3D - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1415196), - maximumScreenSpaceError: 4, - }) - ); + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(1415196, { + maximumScreenSpaceError: 4, + }); + viewer.scene.primitives.add(tileset); // Ferry Building – Street Level Enhanced mesh with a resolution of ~6mm per pixel function viewFerryBuilding() { @@ -136,7 +134,11 @@ }; if (typeof Cesium !== "undefined") { window.startupCalled = true; - window.startup(Cesium); + window.startup(Cesium).catch((error) => { + "use strict"; + console.error(error); + }); + Sandcastle.finishedLoading(); } </script> </body> diff --git a/Apps/Sandcastle/gallery/Ambient Occlusion.html b/Apps/Sandcastle/gallery/Ambient Occlusion.html index 93d0363738f..95b5f26543e 100644 --- a/Apps/Sandcastle/gallery/Ambient Occlusion.html +++ b/Apps/Sandcastle/gallery/Ambient Occlusion.html @@ -129,18 +129,6 @@ ); } - // Power Plant design model provided by Bentley Systems - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - }); - tileset.readyPromise - .then(function (tileset) { - viewer.scene.primitives.add(tileset); - }) - .catch(function (error) { - console.log(error); - }); - const viewModel = { show: true, ambientOcclusionOnly: false, @@ -202,7 +190,13 @@ new Cesium.Cartesian3() ); - //Sandcastle_End + try { + // Power Plant design model provided by Bentley Systems + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(1240402); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html index ee38cdbfed9..dadb13795bf 100644 --- a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.html @@ -51,12 +51,6 @@ positionProperty = entity.position; }); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); - viewer.camera.setView({ destination: new Cesium.Cartesian3( 1216403.8845586285, @@ -71,10 +65,17 @@ endTransform: Cesium.Matrix4.IDENTITY, }); - if (scene.clampToHeightSupported) { - tileset.initialTilesLoaded.addEventListener(start); - } else { - window.alert("This browser does not support clampToHeight."); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + viewer.scene.primitives.add(tileset); + + if (scene.clampToHeightSupported) { + tileset.initialTilesLoaded.addEventListener(start); + } else { + window.alert("This browser does not support clampToHeight."); + } + } catch (error) { + console.log(`Error loading tileset: ${error}`); } function start() { diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 2e285c956b3..e7db822b24f 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -39,12 +39,10 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + viewer.scene.primitives.add(tileset); - tileset.readyPromise.then(function () { const boundingSphere = tileset.boundingSphere; viewer.camera.viewBoundingSphere( boundingSphere, @@ -55,7 +53,9 @@ ) ); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const polygon = viewer.entities.add({ polygon: { diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index 092fd125631..ea896e4a2c3 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -311,10 +311,12 @@ scene.invertClassificationColor.alpha = parseFloat(value); } - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - scene.primitives.add(tileset); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const viewModel = { inverted: viewer.scene.invertClassification, diff --git a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html index 6347bd97b1f..41ff38b556e 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Custom Shaders 3D Tiles.html @@ -44,21 +44,25 @@ //Sandcastle_Begin const viewer = new Cesium.Viewer("cesiumContainer"); - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - customShader: new Cesium.CustomShader({ - lightingModel: Cesium.LightingModel.UNLIT, - fragmentShaderText: ` - // Color tiles by distance to the camera - void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) - { - material.diffuse = vec3(0.0, 0.0, 1.0); - material.diffuse.g = -fsInput.attributes.positionEC.z / 1.0e4; - } - `, - }), - }); - viewer.scene.primitives.add(tileset); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343, { + customShader: new Cesium.CustomShader({ + lightingModel: Cesium.LightingModel.UNLIT, + fragmentShaderText: ` + // Color tiles by distance to the camera + void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) + { + material.diffuse = vec3(0.0, 0.0, 1.0); + material.diffuse.g = -fsInput.attributes.positionEC.z / 1.0e4; + } + `, + }), + }); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } + const initialPosition = Cesium.Cartesian3.fromDegrees( -74.01881302800248, 40.69114333714821, diff --git a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html index 0a556bff380..134bef94f81 100644 --- a/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html +++ b/Apps/Sandcastle/gallery/Custom Shaders Property Textures.html @@ -48,15 +48,16 @@ const scene = viewer.scene; scene.globe.depthTestAgainstTerrain = false; - // MAXAR OWT Muscatatuk photogrammetry dataset with property textures - // containing horizontal and vertical uncertainty - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(905848), - }) - ); - - viewer.zoomTo(tileset); + let tileset; + try { + // MAXAR OWT Muscatatuk photogrammetry dataset with property textures + // containing horizontal and vertical uncertainty + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(905848); + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } const shaders = { NO_TEXTURE: undefined, diff --git a/Apps/Sandcastle/gallery/FXAA.html b/Apps/Sandcastle/gallery/FXAA.html index 00e94e1f1b1..628cdcfa726 100644 --- a/Apps/Sandcastle/gallery/FXAA.html +++ b/Apps/Sandcastle/gallery/FXAA.html @@ -50,17 +50,18 @@ endTransform: Cesium.Matrix4.IDENTITY, }); - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); - viewer.scene.postProcessStages.fxaa.enabled = true; Sandcastle.addToggleButton("FXAA", true, function (checked) { viewer.scene.postProcessStages.fxaa.enabled = checked; - }); //Sandcastle_End + }); + + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/Fog Post Process.html b/Apps/Sandcastle/gallery/Fog Post Process.html index e4e2ad87b52..7adaf7be5f8 100644 --- a/Apps/Sandcastle/gallery/Fog Post Process.html +++ b/Apps/Sandcastle/gallery/Fog Post Process.html @@ -34,16 +34,6 @@ shouldAnimate: true, }); - if (!viewer.scene.context.depthTexture) { - window.alert("This browser does not support the fog post process."); - } - - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - - viewer.scene.primitives.add(tileset); - viewer.scene.camera.setView({ destination: new Cesium.Cartesian3( 1216356.033078094, @@ -58,6 +48,10 @@ endTransform: Cesium.Matrix4.IDENTITY, }); + if (!viewer.scene.context.depthTexture) { + window.alert("This browser does not support the fog post process."); + } + const fragmentShaderSource = ` float getDistance(sampler2D depthTexture, vec2 texCoords) { @@ -105,7 +99,14 @@ fogColor: Cesium.Color.BLACK, }, }) - ); //Sandcastle_End + ); + + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/MSAA.html b/Apps/Sandcastle/gallery/MSAA.html index 16a13ca2bd2..d7a635f7010 100644 --- a/Apps/Sandcastle/gallery/MSAA.html +++ b/Apps/Sandcastle/gallery/MSAA.html @@ -79,6 +79,26 @@ viewer.scene.camera.lookAt(target, offset); } + let currentAssetId; + async function createTileset(assetId) { + currentAssetId = assetId; + + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId( + assetId + ); + + if (currentAssetId !== assetId) { + // Another scenario was loaded. Discard the result. + return; + } + + scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } + } + const options = [ { text: "Statue of Liberty", @@ -98,12 +118,7 @@ ), endTransform: Cesium.Matrix4.IDENTITY, }); - - scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), - }) - ); + createTileset(75343); }, }, { @@ -111,11 +126,6 @@ onselect: function () { viewer.entities.removeAll(); scene.primitives.removeAll(); - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - }) - ); viewer.camera.setView({ destination: new Cesium.Cartesian3( 1234138.7804841248, @@ -128,11 +138,13 @@ roll: 6.283184816241989, }, }); + createTileset(1240402); }, }, { text: "Hot Air Balloon", onselect: function () { + currentAssetId = undefined; viewer.entities.removeAll(); scene.primitives.removeAll(); createModel( diff --git a/Apps/Sandcastle/gallery/Montreal Point Cloud.html b/Apps/Sandcastle/gallery/Montreal Point Cloud.html index 77d78a50e7d..56fca3c6e2d 100644 --- a/Apps/Sandcastle/gallery/Montreal Point Cloud.html +++ b/Apps/Sandcastle/gallery/Montreal Point Cloud.html @@ -90,17 +90,6 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(28945), - pointCloudShading: { - attenuation: true, - maximumAttenuation: 2, - }, - }) - ); - // Fly to a nice overview of the city. viewer.camera.flyTo({ destination: new Cesium.Cartesian3( @@ -363,8 +352,22 @@ tileset.style = new Cesium.Cesium3DTileStyle(styleObject); } - // Apply an initial style. - applyStyle(tileset, pointStyles); + let tileset; + try { + // A ~10 billion point 3D Tileset of the city of Montreal, Canada captured in 2015 with a resolution of 20 cm. Tiled and hosted by Cesium ion. + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(28945, { + pointCloudShading: { + attenuation: true, + maximumAttenuation: 2, + }, + }); + viewer.scene.primitives.add(tileset); + + // Apply an initial style. + applyStyle(tileset, pointStyles); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } Cesium.knockout.track(viewModel); diff --git a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html index 304324bbcba..192f4c3ef3b 100644 --- a/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Polylines on 3D Tiles.html @@ -43,12 +43,18 @@ "2022-08-01T00:00:00Z" ); - const powerplant = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(1240402), - show: false, - }) - ); + let powerPlant; + let powerPlantShow = false; + try { + powerPlant = await Cesium.Cesium3DTileset.fromIonAssetId(1240402); + powerPlant.show = powerPlantShow; + scene.primitives.add(powerPlant); + powerPlant.tileLoad.addEventListener(function (tile) { + processTileFeatures(tile, hideDuplicateFloor); + }); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } // Hide duplicate floor geometry to avoid // z-fighting artifacts. @@ -86,9 +92,6 @@ } } - powerplant.tileLoad.addEventListener(function (tile) { - processTileFeatures(tile, hideDuplicateFloor); - }); const pipes = viewer.entities.add({ polyline: { positions: Cesium.Cartesian3.fromDegreesArray([ @@ -110,11 +113,15 @@ }, }); - const building = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); + let building; + try { + building = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + building.show = !powerPlantShow; + scene.primitives.add(building); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } + const route = viewer.entities.add({ polyline: { positions: Cesium.Cartesian3.fromDegreesArray([ @@ -143,10 +150,17 @@ { text: "BIM", onselect: function () { - building.show = false; - route.polyline.show = false; - powerplant.show = true; - pipes.polyline.show = true; + powerPlantShow = true; + + pipes.polyline.show = powerPlantShow; + route.polyline.show = !powerPlantShow; + if (Cesium.defined(powerPlant)) { + powerPlant.show = powerPlantShow; + } + if (Cesium.defined(building)) { + building.show = !powerPlantShow; + } + scene.camera.setView({ destination: new Cesium.Cartesian3( 1234151.4883992162, @@ -164,10 +178,17 @@ { text: "Photogrammetry", onselect: function () { - building.show = true; - route.polyline.show = true; - powerplant.show = false; - pipes.polyline.show = false; + powerPlantShow = false; + + pipes.polyline.show = powerPlantShow; + route.polyline.show = !powerPlantShow; + if (Cesium.defined(powerPlant)) { + powerPlant.show = powerPlantShow; + } + if (Cesium.defined(building)) { + building.show = !powerPlantShow; + } + scene.camera.setView({ destination: new Cesium.Cartesian3( 1216596.5376729995, diff --git a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html index 5e4c6b5d6ae..31a6c0efbd2 100644 --- a/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html +++ b/Apps/Sandcastle/gallery/Sample Height from 3D Tiles.html @@ -46,12 +46,6 @@ ); } - const tileset = scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }) - ); - scene.camera.setView({ destination: new Cesium.Cartesian3( 1216411.0748779264, @@ -66,6 +60,13 @@ endTransform: Cesium.Matrix4.IDENTITY, }); + try { + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } + Sandcastle.addToolbarButton("Sample heights", function () { sampleHeights(); }); diff --git a/Apps/Sandcastle/gallery/Scene Rendering Performance.html b/Apps/Sandcastle/gallery/Scene Rendering Performance.html index bc865eedbe7..028cb0f6ac9 100644 --- a/Apps/Sandcastle/gallery/Scene Rendering Performance.html +++ b/Apps/Sandcastle/gallery/Scene Rendering Performance.html @@ -167,6 +167,7 @@ <h4>Max delta time</h4> // Clear scene and set default view. let handler; + let loadingTileset = false; function resetScene() { viewer.trackedEntity = undefined; viewer.dataSources.removeAll(); @@ -180,18 +181,26 @@ <h4>Max delta time</h4> viewModel.showTimeOptions = false; viewModel.timeChangeEnabled = false; viewModel.maximumRenderTimeChange = 0; + loadingTileset = false; } // Load a tileset and set the view. // No need to call scene.requestRender() - function loadTilesetScenario() { + async function loadTilesetScenario() { resetScene(); - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(40866), - }); - viewer.scene.primitives.add(tileset); - viewer.zoomTo(tileset); + loadingTileset = true; + try { + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(40866); + if (!loadingTileset) { + // Scenario was changed. Discard result. + return; + } + viewer.scene.primitives.add(tileset); + viewer.zoomTo(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } // Load an animated model and set the view. diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index fe9b60f6339..a31336922fa 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -155,7 +155,7 @@ viewer.trackedEntity = entity; } - function loadStHelens() { + async function loadStHelens() { // Create clipping planes for polygon around area to be clipped. const points = [ new Cesium.Cartesian3( @@ -283,51 +283,51 @@ globe.backFaceCulling = true; globe.showSkirts = true; - // Load tileset - tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(5713), - }); - return tileset.readyPromise - .then(function () { - // Adjust height so tileset is in terrain - const cartographic = Cesium.Cartographic.fromCartesian( - tileset.boundingSphere.center - ); - const surface = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - 0.0 - ); - const offset = Cesium.Cartesian3.fromRadians( - cartographic.longitude, - cartographic.latitude, - -20.0 - ); - const translation = Cesium.Cartesian3.subtract( - offset, - surface, - new Cesium.Cartesian3() - ); - tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); + try { + // Load tileset + tileset = await Cesium.Cesium3DTileset.fromIonAssetId(5713); + if (viewModel.currentExampleType !== exampleTypes[1]) { + // Scenario has changed. Discard the result. + return; + } + // Adjust height so tileset is in terrain + const cartographic = Cesium.Cartographic.fromCartesian( + tileset.boundingSphere.center + ); + const surface = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + 0.0 + ); + const offset = Cesium.Cartesian3.fromRadians( + cartographic.longitude, + cartographic.latitude, + -20.0 + ); + const translation = Cesium.Cartesian3.subtract( + offset, + surface, + new Cesium.Cartesian3() + ); + tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); - tileset.style = new Cesium.Cesium3DTileStyle({ - color: "rgb(207, 255, 207)", - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + color: "rgb(207, 255, 207)", + }); - viewer.scene.primitives.add(tileset); + viewer.scene.primitives.add(tileset); - const boundingSphere = tileset.boundingSphere; + const boundingSphere = tileset.boundingSphere; - const radius = boundingSphere.radius; - viewer.camera.viewBoundingSphere( - boundingSphere, - new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) - ); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - }) - .catch(function (error) { - throw error; - }); + const radius = boundingSphere.radius; + viewer.camera.viewBoundingSphere( + boundingSphere, + new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0) + ); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } function loadGrandCanyon() { diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html index 7748ce8edac..4fdd86f97fb 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Performance Testing.html @@ -64,8 +64,7 @@ const referenceMaximum = new Cesium.JulianDate(); const heatmapTileProperty = "_foveatedFactor"; - const tileset = new Cesium.Cesium3DTileset({ - url: Cesium.IonResource.fromAssetId(75343), + const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(75343, { debugHeatmapTilePropertyName: heatmapTileProperty, }); diff --git a/Apps/Sandcastle/gallery/development/3D Tiles Split.html b/Apps/Sandcastle/gallery/development/3D Tiles Split.html index 0eb53386039..0ec89e25de0 100644 --- a/Apps/Sandcastle/gallery/development/3D Tiles Split.html +++ b/Apps/Sandcastle/gallery/development/3D Tiles Split.html @@ -182,63 +182,62 @@ } }); + let loadedResource; Cesium.knockout .getObservable(viewModel, "selectedTileset") - .subscribe(function (options) { + .subscribe(async function (options) { if (Cesium.defined(tileset)) { scene.primitives.remove(tileset); } if (!Cesium.defined(options)) { inspectorViewModel.tileset = undefined; + loadedResource = undefined; return; } - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: options.resource, - enableDebugWireframe: true, - }) - ); + loadedResource = options.resource; + tileset = await Cesium.Cesium3DTileset.fromUrl(options.resource, { + enableDebugWireframe: true, + }); + if (loadedResource !== options.resource) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); if (Cesium.defined(viewModel.selectedSplitDirection)) { tileset.splitDirection = viewModel.selectedSplitDirection.value; } - tileset.readyPromise - .then(function () { - inspectorViewModel.tileset = tileset; - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0, - -2.0, - Math.max(100.0 - tileset.boundingSphere.radius, 0.0) - ) - ); + inspectorViewModel.tileset = tileset; + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0, + -2.0, + Math.max(100.0 - tileset.boundingSphere.radius, 0.0) + ) + ); - const properties = tileset.properties; - if ( - Cesium.defined(properties) && - Cesium.defined(properties.Height) - ) { - tileset.style = new Cesium.Cesium3DTileStyle({ - color: { - conditions: [ - ["${Height} >= 83", "color('purple', 0.5)"], - ["${Height} >= 80", "color('red')"], - ["${Height} >= 70", "color('orange')"], - ["${Height} >= 12", "color('yellow')"], - ["${Height} >= 7", "color('lime')"], - ["${Height} >= 1", "color('cyan')"], - ["true", "color('blue')"], - ], - }, - }); - } - }) - .catch(function (error) { - throw error; + const properties = tileset.properties; + if ( + Cesium.defined(properties) && + Cesium.defined(properties.Height) + ) { + tileset.style = new Cesium.Cesium3DTileStyle({ + color: { + conditions: [ + ["${Height} >= 83", "color('purple', 0.5)"], + ["${Height} >= 80", "color('red')"], + ["${Height} >= 70", "color('orange')"], + ["${Height} >= 12", "color('yellow')"], + ["${Height} >= 7", "color('lime')"], + ["${Height} >= 1", "color('cyan')"], + ["true", "color('blue')"], + ], + }, }); + } }); viewModel.selectedTileset = viewModel.tilesets[0]; diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index e5cc49ba2b9..79ef45f3150 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -217,17 +217,20 @@ } let tileset; + let currentUrl; async function loadTileset(url, height) { + currentUrl = url; createClippingPlanes(); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - clippingPlanes: modelEntityClippingPlanes, - enableDebugWireframe: true, - }) - ); + tileset = await Cesium.Cesium3DTileset.fromUrl(url, { + clippingPlanes: modelEntityClippingPlanes, + enableDebugWireframe: true, + }); + if (currentUrl !== url) { + // Another scenario has been loaded. Discard the result. + return; + } + viewer.scene.primitives.add(tileset); - await tileset.readyPromise; const boundingSphere = tileset.boundingSphere; const cartographic = Cesium.Cartographic.fromCartesian( diff --git a/Apps/Sandcastle/gallery/development/Pick From Ray.html b/Apps/Sandcastle/gallery/development/Pick From Ray.html index a24c5a563f9..98a720f1e53 100644 --- a/Apps/Sandcastle/gallery/development/Pick From Ray.html +++ b/Apps/Sandcastle/gallery/development/Pick From Ray.html @@ -49,11 +49,10 @@ drillPick = checked; }); - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json", - }) + const tileset = await Cesium.Cesium3DTileset.fromUrl( + "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json" ); + viewer.scene.primitives.add(tileset); tileset.style = new Cesium.Cesium3DTileStyle({ defines: { diff --git a/Apps/Sandcastle/gallery/development/Picking.html b/Apps/Sandcastle/gallery/development/Picking.html index 2c8c309193e..740c7a55d9d 100644 --- a/Apps/Sandcastle/gallery/development/Picking.html +++ b/Apps/Sandcastle/gallery/development/Picking.html @@ -53,6 +53,7 @@ const worldTerrain = Cesium.Terrain.fromWorldTerrain(); const ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider(); + let loadedResource; Sandcastle.addToolbarMenu([ { text: "Billboard", @@ -333,274 +334,247 @@ }, { text: "Batched 3D Model", - onselect: function () { - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json", - }) + onselect: async function () { + const url = + "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"; + loadedResource = url; + tileset = await Cesium.Cesium3DTileset.fromUrl(url); + if (loadedResource !== url) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0, + -2.0, + Math.max(100.0 - tileset.boundingSphere.radius, 0.0) + ) ); - tileset.readyPromise - .then(function () { - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0, - -2.0, - Math.max(100.0 - tileset.boundingSphere.radius, 0.0) - ) - ); - - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - const pickedFeature = viewer.scene.pick( - movement.endPosition - ); - if (!Cesium.defined(pickedFeature)) { - return; - } - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }) - .catch(function (error) { - throw error; - }); + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }, }, { text: "Instanced 3D Model", - onselect: function () { - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/Instanced/InstancedWithBatchTable/tileset.json", - }) - ); + onselect: async function () { + const url = + "../../SampleData/Cesium3DTiles/Instanced/InstancedWithBatchTable/tileset.json"; + loadedResource = url; + tileset = await Cesium.Cesium3DTileset.fromUrl(url); + if (loadedResource !== url) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.readyPromise - .then(function () { - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0, - -2.0, - Math.max(100.0 - tileset.boundingSphere.radius, 0.0) - ) - ); + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0, + -2.0, + Math.max(100.0 - tileset.boundingSphere.radius, 0.0) + ) + ); - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - const pickedFeature = viewer.scene.pick( - movement.endPosition - ); - if (!Cesium.defined(pickedFeature)) { - return; - } - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }) - .catch(function (error) { - throw error; - }); + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }, }, { text: "Point cloud", - onselect: function () { - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: - "../../SampleData/Cesium3DTiles/PointCloud/PointCloudRGB/tileset.json", - }) - ); + onselect: async function () { + const url = + "../../SampleData/Cesium3DTiles/PointCloud/PointCloudRGB/tileset.json"; + loadedResource = url; + tileset = await Cesium.Cesium3DTileset.fromUrl(url); + if (loadedResource !== url) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.readyPromise - .then(function () { - viewer.zoomTo( - tileset, - new Cesium.HeadingPitchRange( - 0, - -2.0, - Math.max(100.0 - tileset.boundingSphere.radius, 0.0) - ) - ); + viewer.zoomTo( + tileset, + new Cesium.HeadingPitchRange( + 0, + -2.0, + Math.max(100.0 - tileset.boundingSphere.radius, 0.0) + ) + ); - tileset.style = new Cesium.Cesium3DTileStyle({ - pointSize: 8.0, - }); + tileset.style = new Cesium.Cesium3DTileStyle({ + pointSize: 8.0, + }); - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.primitive.style = new Cesium.Cesium3DTileStyle( - { - pointSize: 10.0, - } - ); - highlighted.feature = undefined; - } - const pickedFeature = viewer.scene.pick( - movement.endPosition - ); - if (!Cesium.defined(pickedFeature)) { - return; + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.primitive.style = new Cesium.Cesium3DTileStyle( + { + pointSize: 10.0, } - highlighted.feature = pickedFeature; - pickedFeature.primitive.style = new Cesium.Cesium3DTileStyle( - { - pointSize: 10.0, - color: 'color("yellow")', - } - ); - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }) - .catch(function (error) { - throw error; + ); + highlighted.feature = undefined; + } + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } + highlighted.feature = pickedFeature; + pickedFeature.primitive.style = new Cesium.Cesium3DTileStyle({ + pointSize: 10.0, + color: 'color("yellow")', }); + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }, }, { text: "Vector tile polygons", - onselect: function () { + onselect: async function () { viewer.scene.setTerrain(worldTerrain); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: - "../../../Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json", - }) - ); + const url = + "../../../Specs/Data/Cesium3DTiles/Vector/VectorTilePolygons/tileset.json"; + loadedResource = url; + tileset = await Cesium.Cesium3DTileset.fromUrl(url); + if (loadedResource !== url) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.readyPromise - .then(function () { - camera.position = new Cesium.Cartesian3( - 6382696.762766026, - 20.61495686957654, - -83.83598213685399 - ); - camera.direction = new Cesium.Cartesian3( - -0.9999999739409788, - 0.00022792812935066512, - 0.000012915478344419502 - ); - camera.up = new Cesium.Cartesian3( - 0.00001291547800893194, - -2.9438010410026854e-9, - 0.9999999999165953 - ); - camera.right = new Cesium.Cartesian3.cross( - camera.direction, - camera.up, - camera.right - ); + camera.position = new Cesium.Cartesian3( + 6382696.762766026, + 20.61495686957654, + -83.83598213685399 + ); + camera.direction = new Cesium.Cartesian3( + -0.9999999739409788, + 0.00022792812935066512, + 0.000012915478344419502 + ); + camera.up = new Cesium.Cartesian3( + 0.00001291547800893194, + -2.9438010410026854e-9, + 0.9999999999165953 + ); + camera.right = new Cesium.Cartesian3.cross( + camera.direction, + camera.up, + camera.right + ); - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - const pickedFeature = viewer.scene.pick( - movement.endPosition - ); - if (!Cesium.defined(pickedFeature)) { - return; - } - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }) - .catch(function (error) { - throw error; - }); + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }, }, { text: "Vector tile polylines", - onselect: function () { + onselect: async function () { viewer.scene.setTerrain(worldTerrain); - tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: - "../../../Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json", - }) - ); + const url = + "../../../Specs/Data/Cesium3DTiles/Vector/VectorTilePolylines/tileset.json"; + loadedResource = url; + tileset = await Cesium.Cesium3DTileset.fromUrl(url); + if (loadedResource !== url) { + // Another scenario was loaded. Discard result. + return; + } + viewer.scene.primitives.add(tileset); - tileset.readyPromise - .then(function () { - camera.position = new Cesium.Cartesian3( - 6382696.762766026, - 20.61495686957654, - -83.83598213685399 - ); - camera.direction = new Cesium.Cartesian3( - -0.9999999739409788, - 0.00022792812935066512, - 0.000012915478344419502 - ); - camera.up = new Cesium.Cartesian3( - 0.00001291547800893194, - -2.9438010410026854e-9, - 0.9999999999165953 - ); - camera.right = new Cesium.Cartesian3.cross( - camera.direction, - camera.up, - camera.right - ); + camera.position = new Cesium.Cartesian3( + 6382696.762766026, + 20.61495686957654, + -83.83598213685399 + ); + camera.direction = new Cesium.Cartesian3( + -0.9999999739409788, + 0.00022792812935066512, + 0.000012915478344419502 + ); + camera.up = new Cesium.Cartesian3( + 0.00001291547800893194, + -2.9438010410026854e-9, + 0.9999999999165953 + ); + camera.right = new Cesium.Cartesian3.cross( + camera.direction, + camera.up, + camera.right + ); - handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); - handler.setInputAction(function (movement) { - if (Cesium.defined(highlighted.feature)) { - highlighted.feature.color = highlighted.originalColor; - highlighted.feature = undefined; - } - const pickedFeature = viewer.scene.pick( - movement.endPosition - ); - if (!Cesium.defined(pickedFeature)) { - return; - } - highlighted.feature = pickedFeature; - Cesium.Color.clone( - pickedFeature.color, - highlighted.originalColor - ); - pickedFeature.color = Cesium.Color.YELLOW; - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - }) - .catch(function (error) { - throw error; - }); + handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); + handler.setInputAction(function (movement) { + if (Cesium.defined(highlighted.feature)) { + highlighted.feature.color = highlighted.originalColor; + highlighted.feature = undefined; + } + const pickedFeature = viewer.scene.pick(movement.endPosition); + if (!Cesium.defined(pickedFeature)) { + return; + } + highlighted.feature = pickedFeature; + Cesium.Color.clone( + pickedFeature.color, + highlighted.originalColor + ); + pickedFeature.color = Cesium.Color.YELLOW; + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }, }, ]); Sandcastle.reset = function () { + loadedResource = undefined; viewer.entities.removeAll(); if (Cesium.defined(polylines)) { scene.primitives.remove(polylines); diff --git a/Apps/Sandcastle/gallery/development/Shadows.html b/Apps/Sandcastle/gallery/development/Shadows.html index f6d39e4adcb..ad840163f0a 100644 --- a/Apps/Sandcastle/gallery/development/Shadows.html +++ b/Apps/Sandcastle/gallery/development/Shadows.html @@ -899,18 +899,18 @@ } } - function createTileset(resource) { - resource - .then(function (url) { - viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: url, - }) - ); - }) - .catch(function (error) { - console.log(error); - }); + async function createTileset(url) { + try { + const tileset = await Cesium.Cesium3DTileset.fromUrl(url); + const location = uiOptions.locations[viewModel.location]; + if (location.tileset !== url) { + // Another option was loaded. Discard the result; + return; + } + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } } async function createModel(url, origin) { diff --git a/CHANGES.md b/CHANGES.md index 9dff17ef164..6b282ba90bf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,7 +19,7 @@ try { ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, , `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `Cesium3DTileset.fromIonAssetId`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. ##### Fixes :wrench: diff --git a/Documentation/CustomShaderGuide/README.md b/Documentation/CustomShaderGuide/README.md index 681559dbdf3..714af960430 100644 --- a/Documentation/CustomShaderGuide/README.md +++ b/Documentation/CustomShaderGuide/README.md @@ -67,10 +67,11 @@ follows: const customShader = new Cesium.CustomShader(/* ... */); // Applying to all tiles in a tileset. -const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ - url: "http://example.com/tileset.json", - customShader: customShader -})); +const tileset = await Cesium.Cesium3DTileset.fromUrl( + "http://example.com/tileset.json", { + customShader: customShader +}); +viewer.scene.primitives.add(tileset); // Applying to a model directly const model = await Cesium.Model.fromGltfAsync({, diff --git a/Documentation/OfflineGuide/README.md b/Documentation/OfflineGuide/README.md index 9d8a23eed78..e50e84fa1ca 100644 --- a/Documentation/OfflineGuide/README.md +++ b/Documentation/OfflineGuide/README.md @@ -57,9 +57,12 @@ Most other files loaded in CesiumJS, such as 3D Tiles or glTF, are static assets For example, a local tileset in an `example` directory can now be loaded with the following url: ```js - const tileset = viewer.scene.primitives.add( - new Cesium.Cesium3DTileset({ - url: "http://localhost:8003/example/tileset.json", - }) - ); + try { + const tileset = await Cesium.Cesium3DTileset.fromUrl( + "http://localhost:8003/example/tileset.json" + ); + viewer.scene.primitives.add(tileset); + } catch (error) { + console.log(`Error loading tileset: ${error}`); + } ``` diff --git a/packages/engine/Source/Scene/BufferLoader.js b/packages/engine/Source/Scene/BufferLoader.js index 6c1eeb33e77..fb5f572abb9 100644 --- a/packages/engine/Source/Scene/BufferLoader.js +++ b/packages/engine/Source/Scene/BufferLoader.js @@ -57,6 +57,7 @@ Object.defineProperties(BufferLoader.prototype, { * * @type {string} * @readonly + * @private */ cacheKey: { get: function () { @@ -70,6 +71,7 @@ Object.defineProperties(BufferLoader.prototype, { * * @type {Uint8Array} * @readonly + * @private */ typedArray: { get: function () { diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 3c885a72c8e..f01a49263e6 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -1969,9 +1969,9 @@ Object.defineProperties(Cesium3DTileset.prototype, { * console.error(`Error creating tileset: ${error}`); * } */ -Cesium3DTileset.fromIonAssetId = async function (url, options) { - const resource = await IonResource.fromAssetId(124624234); - return Cesium3DTileset.fromUrl(resource); +Cesium3DTileset.fromIonAssetId = async function (assetId, options) { + const resource = await IonResource.fromAssetId(assetId); + return Cesium3DTileset.fromUrl(resource, options); }; /** diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index 24db24b33bc..f2aa0cc0ae9 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -89,6 +89,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ LOADED: 2, /** @@ -97,6 +99,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ PROCESSING: 3, /** @@ -109,6 +113,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ POST_PROCESSING: 4, /** @@ -118,6 +124,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ PROCESSED: 5, /** @@ -126,6 +134,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ READY: 6, /** @@ -133,6 +143,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ FAILED: 7, /** @@ -140,6 +152,8 @@ const GltfLoaderState = { * * @type {number} * @constant + * + * @private */ UNLOADED: 8, }; diff --git a/packages/engine/Source/Scene/ResourceCache.js b/packages/engine/Source/Scene/ResourceCache.js index 21d8e8c4a66..086033589d1 100644 --- a/packages/engine/Source/Scene/ResourceCache.js +++ b/packages/engine/Source/Scene/ResourceCache.js @@ -308,7 +308,7 @@ ResourceCache.getGltfJsonLoader = function (options) { * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. * - * @returns {GltfBufferViewLoader>} The cached buffer view loader. + * @returns {GltfBufferViewLoader} The cached buffer view loader. * @private */ ResourceCache.getBufferViewLoader = function (options) { diff --git a/packages/engine/Source/Scene/Tileset3DTileContent.js b/packages/engine/Source/Scene/Tileset3DTileContent.js index e3ea176125b..9d5ba1172c9 100644 --- a/packages/engine/Source/Scene/Tileset3DTileContent.js +++ b/packages/engine/Source/Scene/Tileset3DTileContent.js @@ -119,12 +119,12 @@ Object.defineProperties(Tileset3DTileContent.prototype, { }); /** - * + * Creates an instance of Tileset3DTileContent from a parsed JSON object * @param {Cesium3DTileset} tileset * @param {Cesium3DTile} tile * @param {Resource} resource * @param {object} json - * @returns + * @returns {Tileset3DTileContent} */ Tileset3DTileContent.fromJson = function (tileset, tile, resource, json) { const content = new Tileset3DTileContent(tileset, tile, resource); diff --git a/packages/engine/Source/Scene/createOsmBuildingsAsync.js b/packages/engine/Source/Scene/createOsmBuildingsAsync.js index 8206ce5a178..08b4b019c7a 100644 --- a/packages/engine/Source/Scene/createOsmBuildingsAsync.js +++ b/packages/engine/Source/Scene/createOsmBuildingsAsync.js @@ -1,7 +1,6 @@ import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import IonResource from "../Core/IonResource.js"; import Cesium3DTileset from "./Cesium3DTileset.js"; import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; @@ -59,10 +58,9 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; * } */ async function createOsmBuildingsAsync(options) { - const tileset = await Cesium3DTileset.fromUrl( - IonResource.fromAssetId(96188), - options - ); + const tileset = await Cesium3DTileset.fromIonAssetId(96188, options); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); let style = options.style; From e2ae222efeffaf394a5bc7a63b893e28031300cc Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 20 Mar 2023 17:00:45 -0400 Subject: [PATCH 556/679] Fix specs --- packages/engine/Specs/Scene/Composite3DTileContentSpec.js | 5 +---- .../Cesium3DTilesInspectorViewModelSpec.js | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/engine/Specs/Scene/Composite3DTileContentSpec.js b/packages/engine/Specs/Scene/Composite3DTileContentSpec.js index 2d454a9912d..2dcea78122b 100644 --- a/packages/engine/Specs/Scene/Composite3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Composite3DTileContentSpec.js @@ -135,10 +135,7 @@ describe( await expectAsync( Cesium3DTilesTester.createContentForMockTile(arrayBuffer, "cmpt") - ).toBeRejectedWithError( - RuntimeError, - "Failed to load i3dm\nFailed to load glTF\nFailed to load glTF: http://localhost:8080/Specs/invalid?compositeIndex=0" - ); + ).toBeRejectedWithError(RuntimeError); }); it("renders composite", function () { diff --git a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js index b38d5101390..d681f7cba70 100644 --- a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js +++ b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js @@ -58,9 +58,7 @@ describe( scene, performanceContainer ); - const tileset = await Cesium3DTileset.fromUrl({ - url: tilesetUrl, - }); + const tileset = await Cesium3DTileset.fromUrl(tilesetUrl); viewModel.tileset = tileset; expect(viewModel.properties.indexOf("id") !== -1).toBe(true); expect(viewModel.properties.indexOf("Longitude") !== -1).toBe(true); From c7d0cc2d972402f9dd99b51383ea7b3d8ae6ea95 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 21 Mar 2023 09:25:12 -0400 Subject: [PATCH 557/679] Fix spec --- .../Cesium3DTilesInspectorViewModelSpec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js index d681f7cba70..33bf3e02879 100644 --- a/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js +++ b/packages/widgets/Specs/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModelSpec.js @@ -60,6 +60,8 @@ describe( ); const tileset = await Cesium3DTileset.fromUrl(tilesetUrl); viewModel.tileset = tileset; + // Here to allow backwards compatibility- This immediately resolves for tilesets created with fromUrl(). Can be removed when ready promises are removed. + await tileset.readyPromise; expect(viewModel.properties.indexOf("id") !== -1).toBe(true); expect(viewModel.properties.indexOf("Longitude") !== -1).toBe(true); expect(viewModel.properties.indexOf("Latitude") !== -1).toBe(true); From d4c9a5c9824cf095bd6606ddfbfb5b02e1b9b6ad Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 21 Mar 2023 10:14:46 -0400 Subject: [PATCH 558/679] Update docs to correct error type for requestErrorEvent --- packages/engine/Source/Core/Resource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Core/Resource.js b/packages/engine/Source/Core/Resource.js index a13e79f0e95..4037f852bc7 100644 --- a/packages/engine/Source/Core/Resource.js +++ b/packages/engine/Source/Core/Resource.js @@ -721,7 +721,7 @@ Resource.prototype.getDerivedResource = function (options) { /** * Called when a resource fails to load. This will call the retryCallback function if defined until retryAttempts is reached. * - * @param {Error} [error] The error that was encountered. + * @param {RequestErrorEvent} [error] The error that was encountered. * * @returns {Promise<boolean>} A promise to a boolean, that if true will cause the resource request to be retried. * @@ -2301,7 +2301,7 @@ Resource.DEFAULT = Object.freeze( * @callback Resource.RetryCallback * * @param {Resource} [resource] The resource that failed to load. - * @param {Error} [error] The error that occurred during the loading of the resource. + * @param {RequestErrorEvent} [error] The error that occurred during the loading of the resource. * @returns {boolean|Promise<boolean>} If true or a promise that resolved to true, the resource will be retried. Otherwise the failure will be returned. */ export default Resource; From 71bac958221033204c4178fd5b60d1623227ba3e Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 21 Mar 2023 10:17:38 -0400 Subject: [PATCH 559/679] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index b2e896226f2..bf08a55fbde 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ ##### Fixes :wrench: - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) +- Fixed error type to be `RequestErrorEvent` in `Resource.retryCallback`. [#11177](https://github.com/CesiumGS/cesium/pull/11177) #### @cesium/widgets From 22c4d0f8e5e851ab0e4211b0522a04325202cf62 Mon Sep 17 00:00:00 2001 From: Michael Cabana <mikeyc343@gmail.com> Date: Tue, 21 Mar 2023 11:15:44 -0400 Subject: [PATCH 560/679] Updates Viewer docs to allow false for imageryProvider in ConstructorOptions --- packages/widgets/Source/Viewer/Viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 780af46acb3..0dd341eeede 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -313,7 +313,7 @@ function enableVRUI(viewer, enabled) { * @property {ProviderViewModel[]} [imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel} [selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true. * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true. - * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. + * @property {ImageryProvider|false} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. From b037162a300517c447dd4ec0b96411f3c242aa2a Mon Sep 17 00:00:00 2001 From: Michael Cabana <mikeyc343@gmail.com> Date: Tue, 21 Mar 2023 11:19:50 -0400 Subject: [PATCH 561/679] Updates CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index b2e896226f2..acf1d6edd23 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ ##### Fixes :wrench: - Fixed Cesium.Viewer instantiated inside my lit component: CreditDisplay is missing its styles [#10907](https://github.com/CesiumGS/cesium/issues/10907) +- Fixed allowing `false` for `imageryProvider` in `Viewer.ConstructorOptions`. [#11179](https://github.com/CesiumGS/cesium/pull/11179) ### 1.103 - 2023-03-01 From 70c4eb352417476d31e6dadacd6911e72cec776d Mon Sep 17 00:00:00 2001 From: Michael Cabana <mikeyc343@gmail.com> Date: Tue, 21 Mar 2023 11:22:25 -0400 Subject: [PATCH 562/679] Updates CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 77083950bd9..e973df68a70 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -349,3 +349,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Rudolf Farkas](https://github.com/rudifa) - [Nick Noce](https://github.com/nnoce14) - [Jacob Van Dine](https://github.com/JacobVanDine) +- [Michael Cabana](https://github.com/mikecabana) From c8d6c9032b6787cc47fa4f11ac7118459e707351 Mon Sep 17 00:00:00 2001 From: Marco Hutter <javagl@javagl.de> Date: Tue, 21 Mar 2023 20:21:06 +0100 Subject: [PATCH 563/679] Cleanups for 3D Tiles Feature Picking sandcastle --- .../gallery/3D Tiles Feature Picking.html | 127 +++++++++--------- 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html index be7ff813d68..fb30d61323e 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html +++ b/Apps/Sandcastle/gallery/3D Tiles Feature Picking.html @@ -33,6 +33,7 @@ window.startup = function (Cesium) { "use strict"; //Sandcastle_Begin + // A simple demo of 3D Tiles feature picking with hover and select behavior // Building data courtesy of NYC OpenData portal: http://www1.nyc.gov/site/doitt/initiatives/3d-building.page const viewer = new Cesium.Viewer("cesiumContainer", { @@ -90,6 +91,53 @@ Cesium.ScreenSpaceEventType.LEFT_CLICK ); + // Update the 'nameOverlay' for the given picked feature, + // at the given (screen) position. + function updateNameOverlay(pickedFeature, position) { + if (!Cesium.defined(pickedFeature)) { + nameOverlay.style.display = "none"; + return; + } + // A feature was picked, so show its overlay content + nameOverlay.style.display = "block"; + nameOverlay.style.bottom = `${ + viewer.canvas.clientHeight - position.y + }px`; + nameOverlay.style.left = `${position.x}px`; + const name = pickedFeature.getProperty("BIN"); + nameOverlay.textContent = name; + } + + // Create the HTML that will be put into the info box that shows + // information about the currently selected feature + function createPickedFeatureDescription(pickedFeature) { + const description = + `${ + '<table class="cesium-infoBox-defaultTable"><tbody>' + + "<tr><th>BIN</th><td>" + }${pickedFeature.getProperty("BIN")}</td></tr>` + + `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( + "DOITT_ID" + )}</td></tr>` + + `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( + "SOURCE_ID" + )}</td></tr>` + + `<tr><th>Longitude</th><td>${pickedFeature.getProperty( + "Longitude" + )}</td></tr>` + + `<tr><th>Latitude</th><td>${pickedFeature.getProperty( + "Latitude" + )}</td></tr>` + + `<tr><th>Height</th><td>${pickedFeature.getProperty( + "Height" + )}</td></tr>` + + `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( + "TerrainHeight" + )}</td></tr>` + + `</tbody></table>`; + return description; + } + // If silhouettes are supported, silhouette features in blue on mouse over and silhouette green on mouse click. // If silhouettes are not supported, change the feature color to yellow on mouse over and green on mouse click. if ( @@ -122,20 +170,13 @@ // Pick a new feature const pickedFeature = viewer.scene.pick(movement.endPosition); + + updateNameOverlay(pickedFeature, movement.endPosition); + if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; return; } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - const name = pickedFeature.getProperty("BIN"); - nameOverlay.textContent = name; - // Highlight the feature if it's not already selected. if (pickedFeature !== selected.feature) { silhouetteBlue.selected = [pickedFeature]; @@ -172,23 +213,10 @@ silhouetteGreen.selected = [pickedFeature]; // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `</tbody></table>`; + selectedEntity.description = createPickedFeatureDescription( + pickedFeature + ); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } else { @@ -211,21 +239,12 @@ } // Pick a new feature const pickedFeature = viewer.scene.pick(movement.endPosition); + updateNameOverlay(pickedFeature, movement.endPosition); + if (!Cesium.defined(pickedFeature)) { - nameOverlay.style.display = "none"; return; } - // A feature was picked, so show it's overlay content - nameOverlay.style.display = "block"; - nameOverlay.style.bottom = `${ - viewer.canvas.clientHeight - movement.endPosition.y - }px`; - nameOverlay.style.left = `${movement.endPosition.x}px`; - let name = pickedFeature.getProperty("name"); - if (!Cesium.defined(name)) { - name = pickedFeature.getProperty("id"); - } - nameOverlay.textContent = name; + // Highlight the feature if it's not already selected. if (pickedFeature !== selected.feature) { highlighted.feature = pickedFeature; @@ -270,36 +289,12 @@ } // Highlight newly selected feature pickedFeature.color = Cesium.Color.LIME; + // Set feature infobox description - const featureName = pickedFeature.getProperty("name"); - selectedEntity.name = featureName; - selectedEntity.description = - 'Loading <div class="cesium-infoBox-loading"></div>'; viewer.selectedEntity = selectedEntity; - selectedEntity.description = - `${ - '<table class="cesium-infoBox-defaultTable"><tbody>' + - "<tr><th>BIN</th><td>" - }${pickedFeature.getProperty("BIN")}</td></tr>` + - `<tr><th>DOITT ID</th><td>${pickedFeature.getProperty( - "DOITT_ID" - )}</td></tr>` + - `<tr><th>SOURCE ID</th><td>${pickedFeature.getProperty( - "SOURCE_ID" - )}</td></tr>` + - `<tr><th>Longitude</th><td>${pickedFeature.getProperty( - "longitude" - )}</td></tr>` + - `<tr><th>Latitude</th><td>${pickedFeature.getProperty( - "latitude" - )}</td></tr>` + - `<tr><th>Height</th><td>${pickedFeature.getProperty( - "height" - )}</td></tr>` + - `<tr><th>Terrain Height (Ellipsoid)</th><td>${pickedFeature.getProperty( - "TerrainHeight" - )}</td></tr>` + - `</tbody></table>`; + selectedEntity.description = createPickedFeatureDescription( + pickedFeature + ); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } From eb781ae1d0a1a117a400faa92af43924591ef9e2 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Mar 2023 15:30:44 -0400 Subject: [PATCH 564/679] Fix 3D Tiles clipping planes Sandcastle --- .../gallery/3D Tiles Clipping Planes.html | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index b6ce63560bf..7df0fc46db1 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -142,8 +142,9 @@ } let tileset; - async function loadTileset(resource) { + async function loadTileset(resource, modelMatrix) { const currentExampleType = viewModel.currentExampleType; + clippingPlanes = new Cesium.ClippingPlaneCollection({ planes: [ new Cesium.ClippingPlane( @@ -159,11 +160,16 @@ tileset = await Cesium.Cesium3DTileset.fromUrl(url, { clippingPlanes: clippingPlanes, }); + if (currentExampleType !== viewModel.currentExampleType) { // Another tileset was loaded, discard the current result return; } + if (Cesium.defined(modelMatrix)) { + tileset.modelMatrix = modelMatrix; + } + viewer.scene.primitives.add(tileset); tileset.debugShowBoundingVolume = @@ -308,12 +314,13 @@ } else if (newValue === clipObjects[1]) { loadTileset(pointCloudUrl); } else if (newValue === clipObjects[2]) { - loadTileset(instancedUrl).then(() => { - // Position the instanced tileset above terrain - tileset.modelMatrix = new Cesium.Matrix4.fromTranslation( + // Position the instanced tileset above terrain + loadTileset( + instancedUrl, + Cesium.Matrix4.fromTranslation( new Cesium.Cartesian3(15.0, -58.6, 50.825) - ); - }); + ) + ); } else { loadModel(modelUrl); } From 64f2d61be70e8ee1860c2864426175bbdd39bc5c Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 22 Mar 2023 16:39:11 -0400 Subject: [PATCH 565/679] Fix Sandcastle, docs --- Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html | 2 +- packages/engine/Source/Scene/Cesium3DTileset.js | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index c69b695c55b..6423a6837fc 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -385,7 +385,7 @@ try { // 3D Tiles Next converted from CDB of Aden, Yemen (CDB provided by Presagis) const terrainTileset = await Cesium.Cesium3DTileset.fromIonAssetId( - 1240402 + 667809 ); viewer.scene.primitives.add(terrainTileset); const buildingsTileset = await Cesium.Cesium3DTileset.fromIonAssetId( diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index f01a49263e6..42dfd843cb1 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -1957,11 +1957,14 @@ Object.defineProperties(Cesium3DTileset.prototype, { * * @param {number} assetId The Cesium ion asset id. * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options + * @returns {Promise<Cesium3DTileset>} * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. * + * @see Cesium3DTileset#fromUrl + * * @example - * //Load a Cesium3DTileset with asset ID of 124624234 + * // Load a Cesium3DTileset with a Cesium ion asset ID of 124624234 * try { * const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(124624234); * scene.primitives.add(tileset); @@ -1980,9 +1983,12 @@ Cesium3DTileset.fromIonAssetId = async function (assetId, options) { * * @param {Resource|string} url The url to a tileset JSON file. * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options + * @returns {Promise<Cesium3DTileset>} * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. * + * @see Cesium3DTileset#fromIonAssetId + * * @example * try { * const tileset = await Cesium.Cesium3DTileset.fromUrl( From bc8ee55c40a8e969dece438454006c122d965b0d Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 22 Mar 2023 17:45:43 -0400 Subject: [PATCH 566/679] Fix typos in READMEs --- .../Contributors/PerformanceTestingGuide/README.md | 7 +++++-- Documentation/Contributors/TestingGuide/README.md | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/Contributors/PerformanceTestingGuide/README.md b/Documentation/Contributors/PerformanceTestingGuide/README.md index decea410bfe..ff4a98e9f11 100644 --- a/Documentation/Contributors/PerformanceTestingGuide/README.md +++ b/Documentation/Contributors/PerformanceTestingGuide/README.md @@ -127,7 +127,8 @@ class Timer { To time how long it takes for the tileset.json to be fetched and the `Cesium3DTileset` to be initialized (not including the tile content), start -the timer just before creating the tileset with `Cesium3DTileset.fromUrl`, and stop it after the asynchronous function has completed. +the timer just before creating the tileset with `Cesium3DTileset.fromUrl`, and +stop it after the asynchronous function has completed. ```js tilesetTimer.start(); @@ -139,7 +140,9 @@ tilesetTimer.print(); ### How to measure tile load time To time how long it takes for all the tiles in the current camera view to load -(not including the tileset load time), after the tileset has been created with `Cesium3DTileset.fromUrl` and stop it in the `initialTilesLoaded` event handler. This event is used +(not including the tileset load time), start the timer after the tileset has +been created with `Cesium3DTileset.fromUrl` and stop it in the `initialTilesLoaded` +event handler. This event is used because we only care about our initial fixed camera view. `allTilesLoaded`, in contrast, may trigger multiple times if the camera moves, which is undesireable here. diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index 6b367b69ebd..b8a315f5bb3 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -714,7 +714,7 @@ it("renders glTF model", async function () { }); ``` -Given a model's url and other options, [`loadAndZoomToModelAsync`](https://github.com/CesiumGS/cesium/blob/main/paclages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js) loads a model, configures the camera, and returns a promise that resolves when a model is ready for rendering. +Given a model's url and other options, [`loadAndZoomToModelAsync`](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js) loads a model, configures the camera, and returns a promise that resolves when a model is ready for rendering. Since loading a model requires asynchronous requests and creating WebGL resources that may be spread over several frames, CesiumJS's [`pollToPromise`](https://github.com/CesiumGS/cesium/blob/main/Specs/pollToPromise.js) is used to return a promise that resolves when the model is ready, which occurs by rendering the scene in an implicit loop (hence the name "poll") until `model.ready` is `true` or the `timeout` is reached. @@ -737,7 +737,7 @@ it("can create a billboard using a URL", async function () { Here a billboard is loaded using a url to image. Internally, `Billboard` makes an asynchronous request for the image and then sets its `ready` property to `true`. The function passed to `pollToPromise` just returns the value of `ready`; it does not need to render the scene to progressively complete the request like `Model`. Finally, the test verifies that the billboard is green. -To test if a promises rejects, we use `expectAsync` and provide the expected error type and message. Here is an excerpt from [ArcGISTiledElevationTerrainProviderSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js): +To test if a promise rejects, we use `expectAsync` and provide the expected error type and message. Here is an excerpt from [ArcGISTiledElevationTerrainProviderSpec.js](https://github.com/CesiumGS/cesium/blob/main/packages/engine/Specs/Core/ArcGISTiledElevationTerrainProviderSpec.js): ```javascript it("fromUrl throws if the SRS is not supported", async function () { From def23b0932663e5bfee09b7bc0e5192092179275 Mon Sep 17 00:00:00 2001 From: jiangheng <jiangheng@geoway.com.cn> Date: Thu, 23 Mar 2023 09:25:06 +0800 Subject: [PATCH 567/679] Make both projectionMatrix called --- packages/engine/Source/Core/FrustumGeometry.js | 2 +- packages/engine/Source/Core/OrthographicFrustum.js | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/engine/Source/Core/FrustumGeometry.js b/packages/engine/Source/Core/FrustumGeometry.js index bece354b733..0446378d326 100644 --- a/packages/engine/Source/Core/FrustumGeometry.js +++ b/packages/engine/Source/Core/FrustumGeometry.js @@ -295,8 +295,8 @@ FrustumGeometry._computeNearFarPlanes = function ( let inverseView; let inverseViewProjection; + const projection = frustum.projectionMatrix; if (frustumType === PERSPECTIVE) { - const projection = frustum.projectionMatrix; const viewProjection = Matrix4.multiply( projection, view, diff --git a/packages/engine/Source/Core/OrthographicFrustum.js b/packages/engine/Source/Core/OrthographicFrustum.js index ff629fa1e25..6e45f6b1b19 100644 --- a/packages/engine/Source/Core/OrthographicFrustum.js +++ b/packages/engine/Source/Core/OrthographicFrustum.js @@ -63,15 +63,6 @@ function OrthographicFrustum(options) { */ this.far = defaultValue(options.far, 500000000.0); this._far = this.far; - - if ( - defined(this.width) && - defined(this.aspectRatio) && - defined(this.near) && - defined(this.far) - ) { - update(this); - } } /** From 2290ec24291d9d977492cf2fedbf24e68d81120d Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Thu, 23 Mar 2023 11:27:40 +0300 Subject: [PATCH 568/679] Polished code based on review comments. Note: carefully tested the performance implications of each code change. --- .../Source/Shaders/AtmosphereCommon.glsl | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index d1c9917a761..8220f39a154 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -9,6 +9,14 @@ uniform vec3 u_atmosphereMieCoefficient; const float ATMOSPHERE_THICKNESS = 111e3; // The thickness of the atmosphere in meters. +/** + * Rational approximation to tanh(x) +*/ +float approximateTanh(float x) { + float x2 = x * x; + return max(-1.0, min(+1.0, x * (27.0 + x2) / (27.0 + 9.0 * x2))); +} + /** * This function computes the colors contributed by Rayliegh and Mie scattering on a given ray, as well as * the transmittance value for the ray. @@ -53,18 +61,17 @@ void computeScattering( // // For performance reasons, instead of a if/else branch // a soft choice is implemented through a weight 0.0 <= w_stop_gt_lprl <= 1.0 - float lprl = length(primaryRayLength); - float x = 1e-7 * primaryRayAtmosphereIntersect.stop / lprl; + float x = 1e-7 * primaryRayAtmosphereIntersect.stop / length(primaryRayLength); // w_stop_gt_lprl: similar to (1+tanh)/2 // Value close to 0.0: close to the horizon // Value close to 1.0: above in the sky - float w_stop_gt_lprl = max(0.0,min(1.0,(1.0 + x * ( 27.0 + x * x ) / ( 27.0 + 9.0 * x * x ))/2.0)); - + float w_stop_gt_lprl = 0.5 * (1.0 + approximateTanh(x)); + // The ray should start from the first intersection with the outer atmopshere, or from the camera position, if it is inside the atmosphere. float start_0 = primaryRayAtmosphereIntersect.start; primaryRayAtmosphereIntersect.start = max(primaryRayAtmosphereIntersect.start, 0.0); // The ray should end at the exit from the atmosphere or at the distance to the vertex, whichever is smaller. - primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, lprl); + primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, length(primaryRayLength)); // Distinguish inside or outside atmosphere (outer space) @@ -72,7 +79,7 @@ void computeScattering( // (1) from outer space we have to use the original implementation to get an unmodified/acceptable rendering // (2) within atmosphere we need a speedup float x_o_a = start_0 - ATMOSPHERE_THICKNESS; // ATMOSPHERE_THICKNESS used as an ad-hoc constant, no precise meaning here, only the order of magnitude matters - float w_inside_atmosphere = 1.0 - max(0.0,min(1.0,(1.0 + x_o_a * ( 27.0 + x_o_a * x_o_a ) / ( 27.0 + 9.0 * x_o_a * x_o_a ))/2.0)); // similar to 1.0 - (1+tanh)/2 + float w_inside_atmosphere = 1.0 - 0.5 * (1.0 + approximateTanh(x_o_a)); // (1) Outside of the atmosphere: original (16.0,4.0) values for good rendering // (2) Inside atmosphere: smaller (4.0,2.0) values for a speedup @@ -81,14 +88,13 @@ void computeScattering( // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. float rayPositionLength = primaryRayAtmosphereIntersect.start; - // (1) Outside of the atmosphere: original implementation + // (1) Outside of the atmosphere: constant rayStepLength // (2) Inside atmosphere: variable rayStepLength to compensate the originally rough rendering of the smaller (4.0,2.0) values // Implementation: sky vs horizon: constant step in one case, increasing step in the other case float rayStepLengthIncrease = w_inside_atmosphere * ((1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0)); float rayStepLength = max(1.0-w_inside_atmosphere, w_stop_gt_lprl) * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0*w_inside_atmosphere,float(PRIMARY_STEPS)); - vec3 rayleighAccumulation = vec3(0.0); vec3 mieAccumulation = vec3(0.0); vec2 opticalDepth = vec2(0.0); From 5f94afc5255597b4ef9896b7f9ecbebc821d34d1 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 23 Mar 2023 14:34:52 -0400 Subject: [PATCH 569/679] Small fixes --- Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html | 3 --- packages/engine/Source/Scene/Cesium3DTileContentFactory.js | 1 - packages/engine/Source/Scene/Vector3DTileGeometry.js | 2 +- packages/engine/Source/Scene/Vector3DTilePoints.js | 1 - packages/engine/Source/Scene/Vector3DTilePolygons.js | 4 +--- packages/engine/Source/Scene/Vector3DTilePrimitive.js | 1 - 6 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html index 6423a6837fc..1c17a7059da 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html +++ b/Apps/Sandcastle/gallery/3D Tiles Next CDB Yemen.html @@ -400,9 +400,6 @@ 12.753525, 2000 ); - const heading = Cesium.Math.toRadians(50.0); - const pitch = Cesium.Math.toRadians(-20.0); - const range = 5000.0; flyCameraTo(cameraTransforms.tileset); diff --git a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js index 6e2186c31ca..281235e3777 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContentFactory.js +++ b/packages/engine/Source/Scene/Cesium3DTileContentFactory.js @@ -67,7 +67,6 @@ const Cesium3DTileContentFactory = { tileset, tile, resource, - arrayBuffer, byteOffset ); diff --git a/packages/engine/Source/Scene/Vector3DTileGeometry.js b/packages/engine/Source/Scene/Vector3DTileGeometry.js index 9dd4c3e7138..39ce487b1fc 100644 --- a/packages/engine/Source/Scene/Vector3DTileGeometry.js +++ b/packages/engine/Source/Scene/Vector3DTileGeometry.js @@ -340,7 +340,7 @@ function createPrimitive(geometries) { return; } - this._error = error; + geometries._error = error; }); } } diff --git a/packages/engine/Source/Scene/Vector3DTilePoints.js b/packages/engine/Source/Scene/Vector3DTilePoints.js index 76e151edc6f..42c65633d7f 100644 --- a/packages/engine/Source/Scene/Vector3DTilePoints.js +++ b/packages/engine/Source/Scene/Vector3DTilePoints.js @@ -52,7 +52,6 @@ function Vector3DTilePoints(options) { this._polylineCollection = new PolylineCollection(); this._polylineCollection._useHighlightColor = true; - this._verticesPromise = undefined; this._packedBuffer = undefined; this._ready = false; diff --git a/packages/engine/Source/Scene/Vector3DTilePolygons.js b/packages/engine/Source/Scene/Vector3DTilePolygons.js index a5a37be0fc7..dfc26848fe2 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolygons.js +++ b/packages/engine/Source/Scene/Vector3DTilePolygons.js @@ -40,8 +40,7 @@ import Vector3DTilePrimitive from "./Vector3DTilePrimitive.js"; * @private */ function Vector3DTilePolygons(options) { - // All of the private properties will be released except _readyPromise - // and _primitive after the Vector3DTilePrimitive is created. + // All of the private properties will be released except _primitive after the Vector3DTilePrimitive is created. this._batchTable = options.batchTable; this._batchIds = options.batchIds; @@ -377,7 +376,6 @@ function finishPrimitive(polygons) { polygons._boundingVolume = undefined; polygons._boundingVolumes = undefined; polygons._batchedIndices = undefined; - polygons._verticesPromise = undefined; } } diff --git a/packages/engine/Source/Scene/Vector3DTilePrimitive.js b/packages/engine/Source/Scene/Vector3DTilePrimitive.js index 5ae75ea11d2..0f16df4a98f 100644 --- a/packages/engine/Source/Scene/Vector3DTilePrimitive.js +++ b/packages/engine/Source/Scene/Vector3DTilePrimitive.js @@ -249,7 +249,6 @@ function createVertexArray(primitive, context) { primitive._batchedPositions = undefined; primitive._transferrableBatchIds = undefined; primitive._vertexBatchIds = undefined; - primitive._verticesPromise = undefined; } function createShaders(primitive, context) { From 58e93731f4746af0b7282e5565cfebbee965a325 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 23 Mar 2023 14:45:02 -0400 Subject: [PATCH 570/679] Add specs --- packages/engine/Source/Scene/Cesium3DTileset.js | 4 ++++ packages/engine/Specs/Scene/Cesium3DTilesetSpec.js | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 42dfd843cb1..9f5526d1de7 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -1973,6 +1973,10 @@ Object.defineProperties(Cesium3DTileset.prototype, { * } */ Cesium3DTileset.fromIonAssetId = async function (assetId, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("assetId", assetId); + //>>includeEnd('debug'); + const resource = await IonResource.fromAssetId(assetId); return Cesium3DTileset.fromUrl(resource, options); }; diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 92902d24dcf..e93bdc4c7f2 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -470,6 +470,14 @@ describe( expect(tileset.resource.url).toEqual(path + param); }); + it("fromIonAssetId throws without assetId", async function () { + await expectAsync( + Cesium3DTileset.fromIonAssetId() + ).toBeRejectedWithDeveloperError( + "assetId is required, actual value was undefined" + ); + }); + it("resolves readyPromise", function () { return Cesium3DTilesTester.loadTileset(scene, tilesetUrl).then(function ( tileset From 4a74622a0972f2694e3134715473e88d7b7a4cb9 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 24 Mar 2023 12:26:23 -0400 Subject: [PATCH 571/679] Fix example in CustomShaderGuide --- Documentation/CustomShaderGuide/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/CustomShaderGuide/README.md b/Documentation/CustomShaderGuide/README.md index 7a95e34cac7..81474975518 100644 --- a/Documentation/CustomShaderGuide/README.md +++ b/Documentation/CustomShaderGuide/README.md @@ -143,12 +143,12 @@ The user is responsible for assigning a value to this varying in const customShader = new Cesium.CustomShader({ // Varying is declared here varyings: { - v_selectedColor: VaryingType.VEC3, + v_selectedColor: Cesium.VaryingType.VEC4, }, // User assigns the varying in the vertex shader vertexShaderText: ` void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput) { - float positiveX = step(0.0, positionMC.x); + float positiveX = step(0.0, vsOutput.positionMC.x); v_selectedColor = mix( vsInput.attributes.color_0, vsInput.attributes.color_1, @@ -159,7 +159,7 @@ const customShader = new Cesium.CustomShader({ // User uses the varying in the fragment shader fragmentShaderText: ` void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) { - material.diffuse = v_selectedColor; + material.diffuse = v_selectedColor.rgb; } `, }); From bebcc0fcaf107f0cb82d45b1c9f43584b71dd0f8 Mon Sep 17 00:00:00 2001 From: Marco Hutter <javagl@javagl.de> Date: Sun, 26 Mar 2023 16:55:29 +0200 Subject: [PATCH 572/679] Remove link to WebStorm guide --- Documentation/Contributors/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/Contributors/README.md b/Documentation/Contributors/README.md index f5f2a77d928..d8251192f80 100644 --- a/Documentation/Contributors/README.md +++ b/Documentation/Contributors/README.md @@ -3,7 +3,6 @@ - [CONTRIBUTING.md](../../CONTRIBUTING.md) - Start here. How to find something to work on, submit issues, and open pull requests. - [Build Guide](BuildGuide/README.md) - How to build and run CesiumJS locally. - **IDEs** - use any IDE you want for CesiumJS development. Most contributors use WebStorm (commercial) or VSCode (open source). - - [WebStorm Guide](WebStormGuide/README.md) - How to set up WebStorm. - [VSCode Guide](VSCodeGuide/README.md) - How to set up VSCode. - [Coding Guide](CodingGuide/README.md) - JavaScript and GLSL coding conventions and best practices for design, maintainability, and performance. - [Testing Guide](TestingGuide/README.md) - How to run the CesiumJS tests and write awesome tests. From bc3bafd6d9609a510bf889d5feb2aa1e8f964e72 Mon Sep 17 00:00:00 2001 From: Marco Hutter <javagl@javagl.de> Date: Sun, 26 Mar 2023 16:55:48 +0200 Subject: [PATCH 573/679] Update link to Deprecation Guide --- Documentation/Contributors/CodeReviewGuide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Contributors/CodeReviewGuide/README.md b/Documentation/Contributors/CodeReviewGuide/README.md index d041b813536..03f3185b827 100644 --- a/Documentation/Contributors/CodeReviewGuide/README.md +++ b/Documentation/Contributors/CodeReviewGuide/README.md @@ -40,7 +40,7 @@ This guide describes best practices for code reviewers. - Verify that [CHANGES.md](../../../CHANGES.md) was updated. - Does the change warrant a new Sandcastle example? - Does it warrant a blog post or tweet so users know what to look forward to in the next release? -- Verify that deprecated and breaking changes to the public API were handled correctly. See the [Deprecation Guide](../DeprecationGuide/README.md). +- Verify that deprecated and breaking changes to the public API were handled correctly. See the ["Deprecation and Breaking Changes" section in the Coding Guide](../CodingGuide/README.md#deprecation-and-breaking-changes). ## Testing From 5f62acfb31055fe3091c93833b7131445279555e Mon Sep 17 00:00:00 2001 From: Marco Hutter <javagl@javagl.de> Date: Sun, 26 Mar 2023 17:04:08 +0200 Subject: [PATCH 574/679] Fix lik to documentation guide --- Documentation/Contributors/CodeReviewGuide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Contributors/CodeReviewGuide/README.md b/Documentation/Contributors/CodeReviewGuide/README.md index 03f3185b827..bc7ef0e9fae 100644 --- a/Documentation/Contributors/CodeReviewGuide/README.md +++ b/Documentation/Contributors/CodeReviewGuide/README.md @@ -36,7 +36,7 @@ This guide describes best practices for code reviewers. ## Changes to the Public CesiumJS API - If new identifiers were added to the public CesiumJS API: - - Verify there is new reference doc. See the [Documentation Guide](../CodingGuide/README.md). + - Verify there is new reference doc. See the [Documentation Guide](../DocumentationGuide/README.md). - Verify that [CHANGES.md](../../../CHANGES.md) was updated. - Does the change warrant a new Sandcastle example? - Does it warrant a blog post or tweet so users know what to look forward to in the next release? From dbe0d457ef88329e5d290595234ba83e7bd1842a Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Mar 2023 11:04:18 -0400 Subject: [PATCH 575/679] Fix broken links in CustomShaderGuide --- Documentation/CustomShaderGuide/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/CustomShaderGuide/README.md b/Documentation/CustomShaderGuide/README.md index 81474975518..dcd4bc1186a 100644 --- a/Documentation/CustomShaderGuide/README.md +++ b/Documentation/CustomShaderGuide/README.md @@ -837,7 +837,7 @@ For `ENUM` type metadata, the statistics struct for that property should contain ## `czm_modelVertexOutput` struct -This struct is built-in, see the [documentation comment](../../../Shaders/Builtin/Structs/modelVertexOutput.glsl). +This struct is built-in, see the [documentation comment](../../packages/engine/Source/Shaders/Builtin/Structs/modelVertexOutput.glsl). This struct contains the output of the custom vertex shader. This includes: @@ -855,7 +855,7 @@ This struct contains the output of the custom vertex shader. This includes: ## `czm_modelMaterial` struct -This struct is a built-in, see the [documentation comment](../../Source/Shaders/Builtin/Structs/modelMaterial.glsl). This is similar to `czm_material` from the old Fabric system, but has slightly different fields as this one supports PBR lighting. +This struct is a built-in, see the [documentation comment](../../packages/engine/Source/Shaders/Builtin/Structs/modelMaterial.glsl). This is similar to `czm_material` from the old Fabric system, but has slightly different fields as this one supports PBR lighting. This struct serves as the basic input/output of the fragment shader pipeline stages. For example: From b5a82a4a16bc5aea4307e6d655e9a13ca7614390 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 27 Mar 2023 13:45:17 -0400 Subject: [PATCH 576/679] Update TimeDynamicPointCloud, I3S, and Voxels readyPromise --- .../gallery/I3S 3D Object Layer.html | 66 ++-- .../gallery/I3S Feature Picking.html | 66 ++-- .../gallery/I3S IntegratedMesh Layer.html | 65 ++-- .../gallery/development/Frustum.html | 10 +- .../gallery/development/Voxels.html | 42 +-- CHANGES.md | 5 + packages/engine/Source/Scene/Cesium3DTile.js | 2 +- .../Scene/Cesium3DTilesVoxelProvider.js | 281 ++++++++++------ .../engine/Source/Scene/Cesium3DTileset.js | 8 +- .../Source/Scene/ClassificationPrimitive.js | 7 + .../Source/Scene/GroundPolylinePrimitive.js | 13 +- .../engine/Source/Scene/GroundPrimitive.js | 9 +- .../engine/Source/Scene/I3SDataProvider.js | 316 ++++++++++++------ packages/engine/Source/Scene/I3SFeature.js | 13 +- packages/engine/Source/Scene/I3SLayer.js | 2 +- packages/engine/Source/Scene/I3SNode.js | 125 ++++--- packages/engine/Source/Scene/PointCloud.js | 30 +- packages/engine/Source/Scene/Primitive.js | 20 ++ .../Source/Scene/TimeDynamicPointCloud.js | 17 +- packages/engine/Source/Scene/VoxelContent.js | 124 ++++--- .../engine/Source/Scene/VoxelPrimitive.js | 130 +++---- packages/engine/Source/Scene/VoxelProvider.js | 4 +- .../Scene/Cesium3DTilesVoxelProviderSpec.js | 86 +++-- .../engine/Specs/Scene/I3SDataProviderSpec.js | 115 ++----- packages/engine/Specs/Scene/I3SLayerSpec.js | 4 +- packages/engine/Specs/Scene/I3SNodeSpec.js | 63 ++-- .../Specs/Scene/TimeDynamicPointCloudSpec.js | 22 +- .../engine/Specs/Scene/VoxelPrimitiveSpec.js | 32 +- .../Specs/Scene/buildVoxelDrawCommandsSpec.js | 10 +- .../Specs/Scene/processVoxelPropertiesSpec.js | 12 +- packages/widgets/Source/Viewer/Viewer.js | 5 +- .../VoxelInspector/VoxelInspectorViewModel.js | 3 +- packages/widgets/Specs/Viewer/ViewerSpec.js | 10 +- 33 files changed, 931 insertions(+), 786 deletions(-) diff --git a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html index 778356edb8e..20de32645af 100644 --- a/Apps/Sandcastle/gallery/I3S 3D Object Layer.html +++ b/Apps/Sandcastle/gallery/I3S 3D Object Layer.html @@ -50,38 +50,46 @@ <h1>Loading...</h1> "San Francisco": "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_3DObjects_1_7/SceneServer/layers/0", }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["San Francisco"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + try { + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Create I3S data provider + const i3sProvider = await Cesium.I3SDataProvider.fromUrl( + tours["San Francisco"], + i3sOptions + ); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); + + // Center camera on I3S once it's loaded + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); + } catch (error) { + console.log( + `There was an error creating the I3S Data Provider: ${error}` + ); + } // An entity object which will hold info about the currently selected feature for infobox display const selectedEntity = new Cesium.Entity(); diff --git a/Apps/Sandcastle/gallery/I3S Feature Picking.html b/Apps/Sandcastle/gallery/I3S Feature Picking.html index c8c8348b415..692608b9e5e 100644 --- a/Apps/Sandcastle/gallery/I3S Feature Picking.html +++ b/Apps/Sandcastle/gallery/I3S Feature Picking.html @@ -50,38 +50,46 @@ <h1>Loading...</h1> "New York": "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/NYC_Attributed_v17/SceneServer", }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours["New York"], - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + try { + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Create I3S data provider + const i3sProvider = await Cesium.I3SDataProvider.fromUrl( + tours["New York"], + i3sOptions + ); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); + + // Center camera on I3S once it's loaded + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); + } catch (error) { + console.log( + `There was an error creating the I3S Data Provider: ${error}` + ); + } // An entity object which will hold info about the currently selected feature for infobox display const selectedEntity = new Cesium.Entity(); diff --git a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html index 935b2fc0dd9..50fcdbc32c9 100644 --- a/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html +++ b/Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html @@ -52,39 +52,46 @@ <h1>Loading...</h1> Frankfurt: "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", }; - // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based - // height systems (Cesium World Terrain). - // If this is not specified, or the URL is invalid no geoid conversion will be applied. - // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model - const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - ); + try { + // Initialize a terrain provider which provides geoid conversion between gravity related (typically I3S datasets) and ellipsoidal based + // height systems (Cesium World Terrain). + // If this is not specified, or the URL is invalid no geoid conversion will be applied. + // The source data used in this transcoding service was compiled from https://earth-info.nga.mil/#tab_wgs84-data and is based on EGM2008 Gravity Model + const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + ); - // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing - const cesium3dTilesetOptions = { - skipLevelOfDetail: false, - debugShowBoundingVolume: false, - }; - const i3sOptions = { - url: tours.Frankfurt, - traceFetches: false, // for tracing I3S fetches - geoidTiledTerrainProvider: geoidService, // pass the geoid service - cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset - }; + // Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing + const cesium3dTilesetOptions = { + skipLevelOfDetail: false, + debugShowBoundingVolume: false, + }; + const i3sOptions = { + traceFetches: false, // for tracing I3S fetches + geoidTiledTerrainProvider: geoidService, // pass the geoid service + cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset + }; - // Create I3S data provider - const i3sProvider = new Cesium.I3SDataProvider(i3sOptions); + // Create I3S data provider + const i3sProvider = await Cesium.I3SDataProvider.fromUrl( + tours.Frankfurt, + i3sOptions + ); - // Add the i3s layer provider as a primitive data type - viewer.scene.primitives.add(i3sProvider); + // Add the i3s layer provider as a primitive data type + viewer.scene.primitives.add(i3sProvider); - // Center camera on I3S once it's loaded - await i3sProvider.readyPromise; - const center = Cesium.Rectangle.center(i3sProvider.extent); - center.height = 10000.0; - viewer.camera.setView({ - destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), - }); //Sandcastle_End + // Center camera on I3S once it's loaded + const center = Cesium.Rectangle.center(i3sProvider.extent); + center.height = 10000.0; + viewer.camera.setView({ + destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(center), + }); + } catch (error) { + console.log( + `There was an error creating the I3S Data Provider: ${error}` + ); + } //Sandcastle_End }; if (typeof Cesium !== "undefined") { window.startupCalled = true; diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index ce5e4eee3ac..82ea8dc2d3a 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -106,11 +106,17 @@ }) ); - frustumPrimitive.readyPromise.then(function (primitive) { - const bs = primitive.getGeometryInstanceAttributes("frustum") + const removeListener = scene.postRender.addEventListener(() => { + if (!frustumPrimitive.ready) { + return; + } + + const bs = frustumPrimitive.getGeometryInstanceAttributes("frustum") .boundingSphere; scene.camera.viewBoundingSphere(bs); scene.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + + removeListener(); }); //Sandcastle_End }; diff --git a/Apps/Sandcastle/gallery/development/Voxels.html b/Apps/Sandcastle/gallery/development/Voxels.html index a4d414c95c8..7280815f412 100644 --- a/Apps/Sandcastle/gallery/development/Voxels.html +++ b/Apps/Sandcastle/gallery/development/Voxels.html @@ -78,7 +78,6 @@ this.types = [Cesium.MetadataType.VEC4]; this.componentTypes = [Cesium.MetadataComponentType.FLOAT32]; this.ready = true; - this.readyPromise = Promise.resolve(this); } const scratchColor = new Cesium.Color(); @@ -301,16 +300,10 @@ }) ); - voxelPrimitive.readyPromise - .then(function () { - viewer.voxelInspector.viewModel.voxelPrimitive = voxelPrimitive; - viewer.camera.flyToBoundingSphere(voxelPrimitive.boundingSphere, { - duration: 0.0, - }); - }) - .catch(function (error) { - console.log(error); - }); + viewer.voxelInspector.viewModel.voxelPrimitive = voxelPrimitive; + viewer.camera.flyToBoundingSphere(voxelPrimitive.boundingSphere, { + duration: 0.0, + }); return voxelPrimitive; } @@ -394,11 +387,10 @@ }, { text: "Box - 3D Tiles", - onselect: function () { - const provider = new Cesium.Cesium3DTilesVoxelProvider({ - url: - "../../SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json", - }); + onselect: async function () { + const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl( + "../../SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json" + ); const primitive = createPrimitive( provider, customShaderWhite, @@ -421,11 +413,10 @@ }, { text: "Ellipsoid - 3D Tiles", - onselect: function () { - const provider = new Cesium.Cesium3DTilesVoxelProvider({ - url: - "../../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", - }); + onselect: async function () { + const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl( + "../../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json" + ); const primitive = createPrimitive( provider, customShaderWhite, @@ -448,11 +439,10 @@ }, { text: "Cylinder - 3D Tiles", - onselect: function () { - const provider = new Cesium.Cesium3DTilesVoxelProvider({ - url: - "../../SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json", - }); + onselect: async function () { + const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl( + "../../SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json" + ); const primitive = createPrimitive( provider, customShaderWhite, diff --git a/CHANGES.md b/CHANGES.md index 6b282ba90bf..003796f07eb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -74,6 +74,11 @@ try { console.log(`Failed to load model. ${error}`); } ``` +- `I3SDataProvider` construction parameter `options.url`, `I3SDataProvider.ready`, and `I3SDataProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `I3SDataProvider.fromUrl` instead. +- `TimeDynamicPointCloud.readyPromise` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `TimeDynamicPointCloud.frameFailed` to track any errors. +- `VoxelProvider.ready` and `VoxelProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. +- `Cesium3DTilesVoxelProvider` construction parameter `options.url`, `Cesium3DTilesVoxelProvider.ready`, and `Cesium3DTilesVoxelProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `Cesium3DTilesVoxelProvider.fromUrl` instead. +- `Primitive.readyPromise`, `ClassificationPrimitive.readyPromise`, `GroundPrimitive.readyPromise`, and `GroundPolylinePrimitive.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Wait for `Primitive.ready`, `ClassificationPrimitive.ready`, `GroundPrimitive.ready`, or `GroundPolylinePrimitive.ready` to return true instead. #### @cesium/widgets diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index de95fdc92b4..30087fff82a 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -1046,7 +1046,7 @@ function createPriorityFunction(tile) { * The request may not be made if the Cesium Request Scheduler can't prioritize it. * </p> * - * @return {Promise<void>|undefined} A promise that resolves when the request completes, or undefined if there is no request needed, or the request cannot be scheduled. + * @return {Promise<Cesium3DTileContent>|undefined} A promise that resolves when the request completes, or undefined if there is no request needed, or the request cannot be scheduled. * @private */ Cesium3DTile.prototype.requestContent = function () { diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 02e1904a612..5a84f8f9d99 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -2,7 +2,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import Matrix4 from "../Core/Matrix4.js"; import OrientedBoundingBox from "../Core/OrientedBoundingBox.js"; @@ -28,14 +28,18 @@ import VoxelShapeType from "./VoxelShapeType.js"; * <p> * Implements the {@link VoxelProvider} interface. * </p> + * <div class="notice"> + * This object is normally not instantiated directly, use {@link Cesium3DTilesVoxelProvider.fromUrl}. + * </div> * * @alias Cesium3DTilesVoxelProvider * @constructor * @augments VoxelProvider * * @param {object} options Object with the following properties: - * @param {Resource|string|Promise<Resource>|Promise<string>} options.url The URL to a tileset JSON file. + * @param {Resource|string|Promise<Resource>|Promise<string>} [options.url] The URL to a tileset JSON file. Deprecated. * + * @see Cesium3DTilesVoxelProvider.fromUrl * @see VoxelProvider * @see VoxelPrimitive * @see VoxelShapeType @@ -44,12 +48,7 @@ import VoxelShapeType from "./VoxelShapeType.js"; */ function Cesium3DTilesVoxelProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug) - Check.defined("options.url", options.url); - //>>includeEnd('debug'); - - /** @inheritdoc */ - this.ready = false; + this._ready = false; /** @inheritdoc */ this.shapeTransform = undefined; @@ -99,84 +98,187 @@ function Cesium3DTilesVoxelProvider(options) { const that = this; let tilesetJson; - this._readyPromise = Promise.resolve(options.url).then(function (url) { - const resource = Resource.createIfNeeded(url); - return resource - .fetchJson() - .then(function (tileset) { - tilesetJson = tileset; - validate(tilesetJson); - const schemaLoader = getMetadataSchemaLoader(tilesetJson, resource); - return schemaLoader.load(); - }) - .then(function (schemaLoader) { - const root = tilesetJson.root; - const voxel = root.content.extensions["3DTILES_content_voxels"]; - const className = voxel.class; - - const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") - ? tilesetJson.extensions["3DTILES_metadata"] - : tilesetJson; - - const metadataSchema = schemaLoader.schema; - const metadata = new Cesium3DTilesetMetadata({ - metadataJson: metadataJson, - schema: metadataSchema, + if (defined(options.url)) { + deprecationWarning( + "Cesium3DTilesVoxelProvider options.url", + "Cesium3DTilesVoxelProvider constructor parameter options.url was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTilesVoxelProvider.fromUrl instead." + ); + + this._readyPromise = Promise.resolve(options.url).then(function (url) { + const resource = Resource.createIfNeeded(url); + return resource + .fetchJson() + .then(function (tileset) { + tilesetJson = tileset; + validate(tilesetJson); + const schemaLoader = getMetadataSchemaLoader(tilesetJson, resource); + return schemaLoader.load(); + }) + .then(function (schemaLoader) { + const root = tilesetJson.root; + const voxel = root.content.extensions["3DTILES_content_voxels"]; + const className = voxel.class; + + const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") + ? tilesetJson.extensions["3DTILES_metadata"] + : tilesetJson; + + const metadataSchema = schemaLoader.schema; + const metadata = new Cesium3DTilesetMetadata({ + metadataJson: metadataJson, + schema: metadataSchema, + }); + + addAttributeInfo(that, metadata, className); + + const implicitTileset = new ImplicitTileset( + resource, + root, + metadataSchema + ); + + const { + shape, + minBounds, + maxBounds, + shapeTransform, + globalTransform, + } = getShape(root); + + that.shape = shape; + that.minBounds = minBounds; + that.maxBounds = maxBounds; + that.dimensions = Cartesian3.unpack(voxel.dimensions); + that.shapeTransform = shapeTransform; + that.globalTransform = globalTransform; + that.maximumTileCount = getTileCount(metadata); + + let paddingBefore; + let paddingAfter; + + if (defined(voxel.padding)) { + paddingBefore = Cartesian3.unpack(voxel.padding.before); + paddingAfter = Cartesian3.unpack(voxel.padding.after); + } + + that.paddingBefore = paddingBefore; + that.paddingAfter = paddingAfter; + + that._implicitTileset = implicitTileset; + + ResourceCache.unload(schemaLoader); + + that._ready = true; + return that; }); + }); + } +} - addAttributeInfo(that, metadata, className); +Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, { + /** @inheritdoc */ + readyPromise: { + get: function () { + deprecationWarning( + "Cesium3DTilesVoxelProvider.readyPromise", + "Cesium3DTilesVoxelProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTilesVoxelProvider.fromUrl instead." + ); + return this._readyPromise; + }, + }, + /** @inheritdoc */ + ready: { + get: function () { + deprecationWarning( + "Cesium3DTilesVoxelProvider.ready", + "Cesium3DTilesVoxelProvider.ready was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Cesium3DTilesVoxelProvider.fromUrl instead." + ); + return this._ready; + }, + }, +}); - const implicitTileset = new ImplicitTileset( - resource, - root, - metadataSchema - ); +/** + * Creates a {@link VoxelProvider} that fetches voxel data from a 3D Tiles tileset. + * + * @param {Resource|string} url The URL to a tileset JSON file + * @returns {Promise<Cesium3DTilesVoxelProvider>} The created provider + * + * @exception {RuntimeException} Root must have content + * @exception {RuntimeException} Root tile content must have 3DTILES_content_voxels extension + * @exception {RuntimeException} Root tile must have implicit tiling + * @exception {RuntimeException} Tileset must have a metadata schema + * @exception {RuntimeException} Only box, region and 3DTILES_bounding_volume_cylinder are supported in Cesium3DTilesVoxelProvider + */ +Cesium3DTilesVoxelProvider.fromUrl = async function (url) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); - const { - shape, - minBounds, - maxBounds, - shapeTransform, - globalTransform, - } = getShape(root); + const resource = Resource.createIfNeeded(url); + const tilesetJson = await resource.fetchJson(); - that.shape = shape; - that.minBounds = minBounds; - that.maxBounds = maxBounds; - that.dimensions = Cartesian3.unpack(voxel.dimensions); - that.shapeTransform = shapeTransform; - that.globalTransform = globalTransform; - that.maximumTileCount = getTileCount(metadata); + validate(tilesetJson); - let paddingBefore; - let paddingAfter; + const schemaLoader = getMetadataSchemaLoader(tilesetJson, resource); + await schemaLoader.load(); - if (defined(voxel.padding)) { - paddingBefore = Cartesian3.unpack(voxel.padding.before); - paddingAfter = Cartesian3.unpack(voxel.padding.after); - } + const root = tilesetJson.root; + const voxel = root.content.extensions["3DTILES_content_voxels"]; + const className = voxel.class; - that.paddingBefore = paddingBefore; - that.paddingAfter = paddingAfter; + const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata") + ? tilesetJson.extensions["3DTILES_metadata"] + : tilesetJson; - that._implicitTileset = implicitTileset; + const metadataSchema = schemaLoader.schema; + const metadata = new Cesium3DTilesetMetadata({ + metadataJson: metadataJson, + schema: metadataSchema, + }); - ResourceCache.unload(schemaLoader); + const provider = new Cesium3DTilesVoxelProvider(); - that.ready = true; - return that; - }); - }); -} + addAttributeInfo(provider, metadata, className); -Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, { - /** @inheritdoc */ - readyPromise: { - get: function () { - return this._readyPromise; - }, - }, -}); + const implicitTileset = new ImplicitTileset(resource, root, metadataSchema); + + const { + shape, + minBounds, + maxBounds, + shapeTransform, + globalTransform, + } = getShape(root); + + provider.shape = shape; + provider.minBounds = minBounds; + provider.maxBounds = maxBounds; + provider.dimensions = Cartesian3.unpack(voxel.dimensions); + provider.shapeTransform = shapeTransform; + provider.globalTransform = globalTransform; + provider.maximumTileCount = getTileCount(metadata); + + let paddingBefore; + let paddingAfter; + + if (defined(voxel.padding)) { + paddingBefore = Cartesian3.unpack(voxel.padding.before); + paddingAfter = Cartesian3.unpack(voxel.padding.after); + } + + provider.paddingBefore = paddingBefore; + provider.paddingAfter = paddingAfter; + + provider._implicitTileset = implicitTileset; + + ResourceCache.unload(schemaLoader); + + provider._ready = true; + provider._readyPromise = Promise.resolve(provider); + + return provider; +}; function getTileCount(metadata) { if (!defined(metadata.tileset)) { @@ -357,7 +459,7 @@ function copyArray(values, length) { return Array.from({ length }, (v, i) => valuesArray[i]); } -function getVoxelPromise(implicitTileset, tileCoordinates) { +async function getVoxelContent(implicitTileset, tileCoordinates) { const voxelRelative = implicitTileset.contentUriTemplates[0].getDerivedResource( { templateValues: tileCoordinates.getTemplateValues(), @@ -367,18 +469,17 @@ function getVoxelPromise(implicitTileset, tileCoordinates) { url: voxelRelative.url, }); - return voxelResource.fetchArrayBuffer().then(function (arrayBuffer) { - const preprocessed = preprocess3DTileContent(arrayBuffer); + const arrayBuffer = await voxelResource.fetchArrayBuffer(); + const preprocessed = preprocess3DTileContent(arrayBuffer); - const voxelContent = new VoxelContent( - voxelResource, - preprocessed.jsonPayload, - preprocessed.binaryPayload, - implicitTileset.metadataSchema - ); + const voxelContent = await VoxelContent.fromJson( + voxelResource, + preprocessed.jsonPayload, + preprocessed.binaryPayload, + implicitTileset.metadataSchema + ); - return voxelContent.readyPromise; - }); + return voxelContent; } async function getSubtreePromise(provider, subtreeCoord) { @@ -424,14 +525,6 @@ async function getSubtreePromise(provider, subtreeCoord) { /** @inheritdoc */ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The provider is not ready. Use Cesium3DTilesVoxelProvider.readyPromise or wait for Cesium3DTilesVoxelProvider.ready to be true." - ); - } - //>>includeEnd('debug'); - options = defaultValue(options, defaultValue.EMPTY_OBJECT); const tileLevel = defaultValue(options.tileLevel, 0); const tileX = defaultValue(options.tileX, 0); @@ -482,7 +575,7 @@ Cesium3DTilesVoxelProvider.prototype.requestData = function (options) { return Promise.reject("Tile is not available"); } - return getVoxelPromise(implicitTileset, tileCoordinates); + return getVoxelContent(implicitTileset, tileCoordinates); }) .then(function (voxelContent) { return names.map(function (name) { diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 9f5526d1de7..0f34df03d51 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -58,6 +58,7 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * * Initialization options for the Cesium3DTileset constructor * + * @property {Resource|string|Promise<Resource>|Promise<string>} [options.url] The url to a tileset JSON file. Deprecated. * @property {boolean} [options.show=true] Determines if the tileset will be shown. * @property {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. * @property {Axis} [options.modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. @@ -118,11 +119,6 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * @property {boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. */ -/** - * @typedef {Cesium3DTileset.ConstructorOptions} Cesium3DTileset.DeprecatedConstructorOptions - * @property {Resource|string|Promise<Resource>|Promise<string>} options.url The url to a tileset JSON file. Deprecated. - */ - /** * A {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles tileset}, * used for streaming massive heterogeneous 3D geospatial datasets. @@ -134,7 +130,7 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * @alias Cesium3DTileset * @constructor * - * @param {Cesium3DTileset.DeprecatedConstructorOptions} options An object describing initialization options + * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. * diff --git a/packages/engine/Source/Scene/ClassificationPrimitive.js b/packages/engine/Source/Scene/ClassificationPrimitive.js index b9d1c608bce..b0817890c2f 100644 --- a/packages/engine/Source/Scene/ClassificationPrimitive.js +++ b/packages/engine/Source/Scene/ClassificationPrimitive.js @@ -2,6 +2,7 @@ import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribu import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import GeometryInstance from "../Core/GeometryInstance.js"; @@ -164,6 +165,7 @@ function ClassificationPrimitive(options) { this._ready = false; const classificationPrimitive = this; + // This is here for backwards compatibility. This promise wrapper can be removed once readyPromise is removed. this._readyPromise = new Promise((resolve, reject) => { classificationPrimitive._completeLoad = () => { if (this._ready) { @@ -340,9 +342,14 @@ Object.defineProperties(ClassificationPrimitive.prototype, { * @memberof ClassificationPrimitive.prototype * @type {Promise<ClassificationPrimitive>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "ClassificationPrimitive.readyPromise", + "ClassificationPrimitive.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for ClassificationPrimitive.ready to return true instead." + ); return this._readyPromise; }, }, diff --git a/packages/engine/Source/Scene/GroundPolylinePrimitive.js b/packages/engine/Source/Scene/GroundPolylinePrimitive.js index 77afcbe5b62..648329cac34 100644 --- a/packages/engine/Source/Scene/GroundPolylinePrimitive.js +++ b/packages/engine/Source/Scene/GroundPolylinePrimitive.js @@ -4,6 +4,7 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import GeometryInstance from "../Core/GeometryInstance.js"; import GeometryInstanceAttribute from "../Core/GeometryInstanceAttribute.js"; import GroundPolylineGeometry from "../Core/GroundPolylineGeometry.js"; @@ -193,6 +194,7 @@ function GroundPolylinePrimitive(options) { this._ready = false; const groundPolylinePrimitive = this; + // This is here for backwards compatibility. This promise wrapper can be removed once readyPromise is removed. this._readyPromise = new Promise((resolve, reject) => { groundPolylinePrimitive._completeLoad = () => { this._ready = true; @@ -318,9 +320,14 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, { * @memberof GroundPolylinePrimitive.prototype * @type {Promise<GroundPolylinePrimitive>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "GroundPolylinePrimitive.readyPromise", + "GroundPolylinePrimitive.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for GroundPolylinePrimitive.ready to return true instead." + ); return this._readyPromise; }, }, @@ -825,7 +832,6 @@ GroundPolylinePrimitive.prototype.update = function (frameState) { }; this._primitive = new Primitive(primitiveOptions); - this._primitive.readyPromise.then(this._completeLoad); } if ( @@ -841,6 +847,11 @@ GroundPolylinePrimitive.prototype.update = function (frameState) { this._primitive.show = this.show; this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; this._primitive.update(frameState); + frameState.afterRender.push(() => { + if (!this._ready && defined(this._primitive) && this._primitive.ready) { + this._completeLoad(); + } + }); }; /** diff --git a/packages/engine/Source/Scene/GroundPrimitive.js b/packages/engine/Source/Scene/GroundPrimitive.js index 861bd2b4435..ce39516f303 100644 --- a/packages/engine/Source/Scene/GroundPrimitive.js +++ b/packages/engine/Source/Scene/GroundPrimitive.js @@ -5,6 +5,7 @@ import Cartographic from "../Core/Cartographic.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import GeometryInstance from "../Core/GeometryInstance.js"; @@ -213,6 +214,7 @@ function GroundPrimitive(options) { this._ready = false; const groundPrimitive = this; + // This is here for backwards compatibility. This promise wrapper can be removed once readyPromise is removed. this._readyPromise = new Promise((resolve, reject) => { groundPrimitive._completeLoad = () => { if (this._ready) { @@ -388,9 +390,14 @@ Object.defineProperties(GroundPrimitive.prototype, { * @memberof GroundPrimitive.prototype * @type {Promise<GroundPrimitive>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "GroundPrimitive.readyPromise", + "GroundPrimitive.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for GroundPrimitive.ready to return true instead." + ); return this._readyPromise; }, }, @@ -934,7 +941,7 @@ GroundPrimitive.prototype.update = function (frameState) { this._primitive.update(frameState); frameState.afterRender.push(() => { - if (defined(this._primitive) && this._primitive.ready) { + if (!this._ready && defined(this._primitive) && this._primitive.ready) { this._completeLoad(); } }); diff --git a/packages/engine/Source/Scene/I3SDataProvider.js b/packages/engine/Source/Scene/I3SDataProvider.js index f5b5dddef96..53e55f94a23 100644 --- a/packages/engine/Source/Scene/I3SDataProvider.js +++ b/packages/engine/Source/Scene/I3SDataProvider.js @@ -51,59 +51,77 @@ import Cartographic from "../Core/Cartographic.js"; import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; -import DeveloperError from "../Core/DeveloperError.js"; import HeightmapEncoding from "../Core/HeightmapEncoding.js"; import Resource from "../Core/Resource.js"; +import RuntimeError from "../Core/RuntimeError.js"; import TaskProcessor from "../Core/TaskProcessor.js"; import WebMercatorProjection from "../Core/WebMercatorProjection.js"; import I3SLayer from "./I3SLayer.js"; import Lerc from "lerc"; import Rectangle from "../Core/Rectangle.js"; +/** + * @typedef {Object} I3SDataProvider.ConstructorOptions + * + * Initialization options for the I3SDataProvider constructor + * + * @property {Resource|string} [options.url] The url of the I3S dataset. Deprecated. + * @property {string} [options.name] The name of the I3S dataset. + * @property {boolean} [options.show=true] Determines if the dataset will be shown. + * @property {ArcGISTiledElevationTerrainProvider|Promise<ArcGISTiledElevationTerrainProvider>} [options.geoidTiledTerrainProvider] Tiled elevation provider describing an Earth Gravitational Model. If defined, geometry will be shifted based on the offsets given by this provider. Required to position I3S data sets with gravity-related height at the correct location. + * @property {boolean} [options.traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. + * @property {Cesium3DTileset.ConstructorOptions} [options.cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. + */ + /** * An I3SDataProvider is the main public class for I3S support. The url option * should return a scene object. Currently supported I3S versions are 1.6 and * 1.7/1.8 (OGC I3S 1.2). I3SFeature and I3SNode classes implement the * Object Model for I3S entities, with public interfaces. * + * <div class="notice"> + * This object is normally not instantiated directly, use {@link I3SDataProvider.fromUrl}. + * </div> + * * @alias I3SDataProvider * @constructor * - * @param {Object} options Object with the following properties: - * @param {Resource|string} options.url The url of the I3S dataset. - * @param {string} [options.name] The name of the I3S dataset. - * @param {boolean} [options.show=true] Determines if the dataset will be shown. - * @param {ArcGISTiledElevationTerrainProvider|Promise<ArcGISTiledElevationTerrainProvider>} [options.geoidTiledTerrainProvider] Tiled elevation provider describing an Earth Gravitational Model. If defined, geometry will be shifted based on the offsets given by this provider. Required to position I3S data sets with gravity-related height at the correct location. - * @param {boolean} [options.traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. - * @param {Object} [options.cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. + * @param {I3SDataProvider.ConstructorOptions} options An object describing initialization options + * + * @see I3SDataProvider.fromUrl + * @see ArcGISTiledElevationTerrainProvider * * @example - * const i3sData = new I3SDataProvider({ - * url: 'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0' - * }); - * viewer.scene.primitives.add(i3sData); + * try { + * const i3sData = await I3SDataProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0" + * ); + * viewer.scene.primitives.add(i3sData); + * } catch (error) { + * console.log(`There was an error creating the I3S Data Provider: ${error}`); + * } * * @example - * const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( - * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" - * ); - * let i3sData = new I3SDataProvider({ - * url: 'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0', - * geoidTiledTerrainProvider: geoidService - * }); - * viewer.scene.primitives.add(i3sData); + * try { + * const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + * ); + * const i3sData = await I3SDataProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", { + * geoidTiledTerrainProvider: geoidService + * }); + * viewer.scene.primitives.add(i3sData); + * } catch (error) { + * console.log(`There was an error creating the I3S Data Provider: ${error}`); + * } */ function I3SDataProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - //>>includeStart('debug', pragmas.debug); - Check.defined("options.url", options.url); - //>>includeEnd('debug'); - // All public configuration is defined as ES5 properties // These are just the "private" variables and their defaults. - this._resource = Resource.createIfNeeded(options.url); this._name = options.name; this._show = defaultValue(options.show, true); this._geoidTiledTerrainProvider = options.geoidTiledTerrainProvider; @@ -117,13 +135,22 @@ function I3SDataProvider(options) { this._layers = []; this._data = undefined; this._extent = undefined; - this._geoidDataIsReadyPromise = undefined; + this._geoidDataPromise = undefined; this._geoidDataList = undefined; this._decoderTaskProcessor = undefined; - this._readyPromise = undefined; - this._ready = false; + this._taskProcessorReadyPromise = undefined; + + if (defined(options.url)) { + deprecationWarning( + "I3SDataProvider options.url", + "I3SDataProvider constructor parameter options.url was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use I3SDataProvider.fromUrl instead." + ); + this._readyPromise = undefined; + this._ready = false; - this._load(); + this._resource = Resource.createIfNeeded(options.url); + this._load(); + } } Object.defineProperties(I3SDataProvider.prototype, { @@ -200,14 +227,6 @@ Object.defineProperties(I3SDataProvider.prototype, { */ layers: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The dataset is not loaded. Use I3SDataProvider.readyPromise or wait for I3SDataProvider.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._layers; }, }, @@ -220,14 +239,6 @@ Object.defineProperties(I3SDataProvider.prototype, { */ data: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The dataset is not loaded. Use I3SDataProvider.readyPromise or wait for I3SDataProvider.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._data; }, }, @@ -240,14 +251,6 @@ Object.defineProperties(I3SDataProvider.prototype, { */ extent: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this.ready) { - throw new DeveloperError( - "The dataset is not loaded. Use I3SDataProvider.readyPromise or wait for I3SDataProvider.ready to be true." - ); - } - //>>includeEnd('debug'); - return this._extent; }, }, @@ -257,9 +260,14 @@ Object.defineProperties(I3SDataProvider.prototype, { * @memberof I3SDataProvider.prototype * @type {Promise<I3SDataProvider>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "I3SDataProvider.readyPromise", + "I3SDataProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use I3SDataProvider.fromUrl instead." + ); return this._readyPromise; }, }, @@ -270,9 +278,14 @@ Object.defineProperties(I3SDataProvider.prototype, { * @memberof I3SDataProvider.prototype * @type {boolean} * @readonly + * @deprecated */ ready: { get: function () { + deprecationWarning( + "I3SDataProvider.ready", + "I3SDataProvider.ready was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use I3SDataProvider.fromUrl instead." + ); return this._ready; }, }, @@ -333,9 +346,7 @@ I3SDataProvider.prototype.isDestroyed = function () { */ I3SDataProvider.prototype.update = function (frameState) { for (let i = 0; i < this._layers.length; i++) { - // Reintroducing tileset.ready check to prevent random failures - // when initially loading the tileset - if (defined(this._layers[i]._tileset) && this._layers[i]._tileset.ready) { + if (defined(this._layers[i]._tileset)) { this._layers[i]._tileset.update(frameState); } } @@ -346,7 +357,7 @@ I3SDataProvider.prototype.update = function (frameState) { */ I3SDataProvider.prototype.prePassesUpdate = function (frameState) { for (let i = 0; i < this._layers.length; i++) { - if (defined(this._layers[i]._tileset) && this._layers[i]._tileset.ready) { + if (defined(this._layers[i]._tileset)) { this._layers[i]._tileset.prePassesUpdate(frameState); } } @@ -357,7 +368,7 @@ I3SDataProvider.prototype.prePassesUpdate = function (frameState) { */ I3SDataProvider.prototype.postPassesUpdate = function (frameState) { for (let i = 0; i < this._layers.length; i++) { - if (defined(this._layers[i]._tileset) && this._layers[i]._tileset.ready) { + if (defined(this._layers[i]._tileset)) { this._layers[i]._tileset.postPassesUpdate(frameState); } } @@ -368,40 +379,113 @@ I3SDataProvider.prototype.postPassesUpdate = function (frameState) { */ I3SDataProvider.prototype.updateForPass = function (frameState, passState) { for (let i = 0; i < this._layers.length; i++) { - if (defined(this._layers[i]._tileset) && this._layers[i]._tileset.ready) { + if (defined(this._layers[i]._tileset)) { this._layers[i]._tileset.updateForPass(frameState, passState); } } }; +/** + * Creates an I3SDataProvider. Currently supported I3S versions are 1.6 and + * 1.7/1.8 (OGC I3S 1.2). + * + * @param {string|Resource} url The url of the I3S dataset, which should return an I3S scene object + * @param {I3SDataProvider.ConstructorOptions} options An object describing initialization options + * @returns {Promise<I3SDataProvider>} + * + * @example + * try { + * const i3sData = await I3SDataProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0" + * ); + * viewer.scene.primitives.add(i3sData); + * } catch (error) { + * console.log(`There was an error creating the I3S Data Provider: ${error}`); + * } + * + * @example + * try { + * const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer" + * ); + * const i3sData = await I3SDataProvider.fromUrl( + * "https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/Frankfurt2017_vi3s_18/SceneServer/layers/0", { + * geoidTiledTerrainProvider: geoidService + * }); + * viewer.scene.primitives.add(i3sData); + * } catch (error) { + * console.log(`There was an error creating the I3S Data Provider: ${error}`); + * } + */ +I3SDataProvider.fromUrl = async function (url, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("url", url); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + const resource = Resource.createIfNeeded(url); + const data = await I3SDataProvider.loadJson(resource); + + const provider = new I3SDataProvider(options); + provider._resource = resource; + provider._data = data; + + // Success + if (defined(data.layers)) { + for (let layerIndex = 0; layerIndex < data.layers.length; layerIndex++) { + const newLayer = new I3SLayer( + provider, + data.layers[layerIndex], + layerIndex + ); + provider._layers.push(newLayer); + } + } else { + const newLayer = new I3SLayer(provider, data, data.id); + provider._layers.push(newLayer); + } + + provider._computeExtent(); + + // Start loading all of the tiles + const layerPromises = []; + for (let i = 0; i < provider._layers.length; i++) { + layerPromises.push(provider._layers[i].load()); + } + + await Promise.all(layerPromises); + provider._ready = true; + provider._readyPromise = Promise.resolve(provider); + return provider; +}; + /** * @private */ I3SDataProvider.prototype._load = function () { const that = this; - this._readyPromise = this._loadJson(this._resource).then(function (data) { + this._readyPromise = I3SDataProvider.loadJson( + this._resource, + this._traceFetches + ).then(function (data) { // Success that._data = data; - if (defined(that._data.layers)) { - for ( - let layerIndex = 0; - layerIndex < that._data.layers.length; - layerIndex++ - ) { + if (defined(data.layers)) { + for (let layerIndex = 0; layerIndex < data.layers.length; layerIndex++) { const newLayer = new I3SLayer( that, - that._data.layers[layerIndex], + data.layers[layerIndex], layerIndex ); that._layers.push(newLayer); } } else { - const newLayer = new I3SLayer(that, that._data, that._data.id); + const newLayer = new I3SLayer(that, data, data.id); that._layers.push(newLayer); } that._computeExtent(); - that._geoidDataIsReadyPromise = that._loadGeoidData(); // Start loading all of the tiles const layerPromises = []; @@ -427,27 +511,32 @@ I3SDataProvider._fetchJson = function (resource) { /** * @private + * + * @param {Resource} resource The JSON resource to request + * @param {bool=false} trace Log the resource + * @returns {Promise<object>} The fetched data */ -I3SDataProvider.prototype._loadJson = function (resource) { - if (this._traceFetches) { +I3SDataProvider.loadJson = async function (resource, trace) { + if (trace) { console.log("I3S FETCH:", resource.url); } - return I3SDataProvider._fetchJson(resource).then(function (data) { - if (defined(data.error)) { - console.error("Failed to fetch I3S ", resource.url); - if (defined(data.error.message)) { - console.error(data.error.message); - } - if (defined(data.error.details)) { - for (let i = 0; i < data.error.details.length; i++) { - console.log(data.error.details[i]); - } + const data = await I3SDataProvider._fetchJson(resource); + if (defined(data.error)) { + console.error("Failed to fetch I3S ", resource.url); + if (defined(data.error.message)) { + console.error(data.error.message); + } + if (defined(data.error.details)) { + for (let i = 0; i < data.error.details.length; i++) { + console.log(data.error.details[i]); } - return Promise.reject(data.error); } - return data; - }); + + throw new RuntimeError(data.error); + } + + return data; }; /** @@ -496,19 +585,28 @@ I3SDataProvider.prototype._binarizeGltf = function (rawGltf) { /** * @private + * @returns {Promise<TaskProcessor>} */ -I3SDataProvider.prototype._getDecoderTaskProcessor = function () { +I3SDataProvider.prototype.getDecoderTaskProcessor = function () { + if (defined(this._taskProcessorReadyPromise)) { + return this._taskProcessorReadyPromise; + } + if (!defined(this._decoderTaskProcessor)) { const processor = new TaskProcessor("decodeI3S"); - this._taskProcessorReadyPromise = processor.initWebAssemblyModule({ - modulePath: "ThirdParty/Workers/draco_decoder_nodejs.js", - wasmBinaryFile: "ThirdParty/draco_decoder.wasm", - }); + this._taskProcessorReadyPromise = processor + .initWebAssemblyModule({ + modulePath: "ThirdParty/Workers/draco_decoder_nodejs.js", + wasmBinaryFile: "ThirdParty/draco_decoder.wasm", + }) + .then(() => { + return processor; + }); this._decoderTaskProcessor = processor; } - return this._decoderTaskProcessor; + return this._taskProcessorReadyPromise; }; function getCoveredTiles(terrainProvider, extent) { @@ -615,20 +713,34 @@ function getTiles(terrainProvider, extent) { /** * @private */ -I3SDataProvider.prototype._loadGeoidData = async function () { - // Load tiles from arcgis - const that = this; - const geoidTerrainProvider = this._geoidTiledTerrainProvider; - - if (!defined(geoidTerrainProvider)) { - console.log( - "No Geoid Terrain service provided - no geoid conversion will be performed." - ); - return; +I3SDataProvider.prototype.loadGeoidData = async function () { + if (defined(this._geoidDataPromise)) { + return this._geoidDataPromise; } + this._geoidDataPromise = (async () => { + // Load tiles from arcgis + const geoidTerrainProvider = this._geoidTiledTerrainProvider; + + if (!defined(geoidTerrainProvider)) { + console.log( + "No Geoid Terrain service provided - no geoid conversion will be performed." + ); + return; + } - const heightMaps = await getCoveredTiles(geoidTerrainProvider, that._extent); - that._geoidDataList = heightMaps; + try { + const heightMaps = await getCoveredTiles( + geoidTerrainProvider, + this._extent + ); + this._geoidDataList = heightMaps; + } catch (error) { + console.log( + "Error retrieving Geoid Terrain tiles - no geoid conversion will be performed." + ); + } + })(); + return this._geoidDataPromise; }; /** diff --git a/packages/engine/Source/Scene/I3SFeature.js b/packages/engine/Source/Scene/I3SFeature.js index d911a75acaa..e9c2b492666 100644 --- a/packages/engine/Source/Scene/I3SFeature.js +++ b/packages/engine/Source/Scene/I3SFeature.js @@ -1,4 +1,5 @@ import defined from "../Core/defined.js"; +import I3SDataProvider from "./I3SDataProvider.js"; /** * This class implements an I3S Feature. @@ -52,12 +53,12 @@ Object.defineProperties(I3SFeature.prototype, { * @returns {Promise} A promise that is resolved when the data of the I3S feature is loaded * @private */ -I3SFeature.prototype.load = function () { - const that = this; - return this._dataProvider._loadJson(this._resource).then(function (data) { - that._data = data; - return data; - }); +I3SFeature.prototype.load = async function () { + this._data = await I3SDataProvider.loadJson( + this._resource, + this._dataProvider._traceFetches + ); + return this._data; }; export default I3SFeature; diff --git a/packages/engine/Source/Scene/I3SLayer.js b/packages/engine/Source/Scene/I3SLayer.js index 214e2d3fb90..05828d8617a 100644 --- a/packages/engine/Source/Scene/I3SLayer.js +++ b/packages/engine/Source/Scene/I3SLayer.js @@ -175,7 +175,7 @@ I3SLayer.prototype.load = async function () { ); } - await this._dataProvider._geoidDataIsReadyPromise; + await this._dataProvider.loadGeoidData(); await this._loadRootNode(); await this._create3DTileset(); diff --git a/packages/engine/Source/Scene/I3SNode.js b/packages/engine/Source/Scene/I3SNode.js index 839b0517a68..222f79ce7e5 100644 --- a/packages/engine/Source/Scene/I3SNode.js +++ b/packages/engine/Source/Scene/I3SNode.js @@ -1,6 +1,5 @@ import Cartographic from "../Core/Cartographic.js"; import defaultValue from "../Core/defaultValue.js"; -import defer from "../Core/defer.js"; import defined from "../Core/defined.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import HeadingPitchRoll from "../Core/HeadingPitchRoll.js"; @@ -11,6 +10,7 @@ import Resource from "../Core/Resource.js"; import Quaternion from "../Core/Quaternion.js"; import Transforms from "../Core/Transforms.js"; import Cesium3DTile from "./Cesium3DTile.js"; +import I3SDataProvider from "./I3SDataProvider.js"; import I3SFeature from "./I3SFeature.js"; import I3SField from "./I3SField.js"; import I3SGeometry from "./I3SGeometry.js"; @@ -52,6 +52,7 @@ function I3SNode(parent, ref, isRoot) { this._layer = layer; this._nodeIndex = nodeIndex; this._resource = resource; + this._isLoading = false; this._tile = undefined; this._data = undefined; @@ -170,7 +171,7 @@ Object.defineProperties(I3SNode.prototype, { /** * @private */ -I3SNode.prototype.load = function () { +I3SNode.prototype.load = async function () { const that = this; function processData() { @@ -191,28 +192,29 @@ I3SNode.prototype.load = function () { // If we don't have a nodepage index load from json if (!defined(this._nodeIndex)) { - return this._dataProvider._loadJson(this._resource).then(function (data) { - // Success - that._data = data; - processData(); - }); + const data = await I3SDataProvider.loadJson( + this._resource, + this._dataProvider._traceFetches + ); + that._data = data; + processData(); + return; } - return this._layer._getNodeInNodePages(this._nodeIndex).then(function (node) { - that._data = node; - let uri; - if (that._isRoot) { - uri = "nodes/root/"; - } else if (defined(node.mesh)) { - const uriIndex = node.mesh.geometry.resource; - uri = `../${uriIndex}/`; - } - if (defined(uri)) { - that._resource = that._parent.resource.getDerivedResource({ url: uri }); - } + const node = await this._layer._getNodeInNodePages(this._nodeIndex); + that._data = node; + let uri; + if (that._isRoot) { + uri = "nodes/root/"; + } else if (defined(node.mesh)) { + const uriIndex = node.mesh.geometry.resource; + uri = `../${uriIndex}/`; + } + if (defined(uri)) { + that._resource = that._parent.resource.getDerivedResource({ url: uri }); + } - processData(); - }); + processData(); }; /** @@ -609,7 +611,10 @@ I3SNode.prototype._create3DTileDefinition = function () { /** * @private */ -I3SNode.prototype._createI3SDecoderTask = function (dataProvider, data) { +I3SNode.prototype._createI3SDecoderTask = async function ( + decodeI3STaskProcessor, + data +) { // Prepare the data to send to the worker const parentData = data.geometryData._parent._data; const parentRotationInverseMatrix = @@ -664,18 +669,14 @@ I3SNode.prototype._createI3SDecoderTask = function (dataProvider, data) { parentRotation: parentRotation, }; - const decodeI3STaskProcessor = dataProvider._getDecoderTaskProcessor(); - const transferrableObjects = []; - return dataProvider._taskProcessorReadyPromise.then(function () { - return decodeI3STaskProcessor.scheduleTask(payload, transferrableObjects); - }); + return decodeI3STaskProcessor.scheduleTask(payload, transferrableObjects); }; /** * @private */ -I3SNode.prototype._createContentURL = function () { +I3SNode.prototype._createContentURL = async function () { let rawGltf = { scene: 0, scenes: [ @@ -701,6 +702,8 @@ I3SNode.prototype._createContentURL = function () { }, }; + const decodeI3STaskProcessor = await this._dataProvider.getDecoderTaskProcessor(); + // Load the geometry data const dataPromises = [this._loadGeometryData()]; if (this._dataProvider.legacyVersion16) { @@ -720,13 +723,16 @@ I3SNode.prototype._createContentURL = function () { tile: that._tile, }; - const task = that._createI3SDecoderTask(that._dataProvider, parameters); - if (!defined(task)) { + const promise = that._createI3SDecoderTask( + decodeI3STaskProcessor, + parameters + ); + if (!defined(promise)) { // Postponed return; } - generateGltfPromise = task.then(function (result) { + generateGltfPromise = promise.then(function (result) { rawGltf = parameters.geometryData._generateGltf( result.meshData.nodesInScene, result.meshData.nodes, @@ -746,7 +752,7 @@ I3SNode.prototype._createContentURL = function () { const glbDataBlob = new Blob([binaryGltfData], { type: "application/binary", }); - that._glbURL = URL.createObjectURL(glbDataBlob); + return URL.createObjectURL(glbDataBlob); }); }); }; @@ -757,50 +763,37 @@ Cesium3DTile.prototype._hookedRequestContent = Cesium3DTile.prototype.requestContent; /** + * Requests the tile's content. + * <p> + * The request may not be made if the Cesium Request Scheduler can't prioritize it. + * </p> + * + * @return {Promise<Cesium3DTileContent>|undefined} A promise that resolves when the request completes, or undefined if there is no request needed, or the request cannot be scheduled. * @private */ -Cesium3DTile.prototype._resolveHookedObject = function () { - const that = this; - // Keep a handle on the early promises - // Call the real requestContent function - this._hookedRequestContent(); - - // Fulfill the promises - this._contentReadyToProcessPromise.then(function () { - that._contentReadyToProcessDefer.resolve(); - }); - - this._contentReadyPromise.then(function (content) { - that._isLoading = false; - that._contentReadyDefer.resolve(content); - }); -}; - Cesium3DTile.prototype.requestContent = function () { - const that = this; if (!this.tileset._isI3STileSet) { return this._hookedRequestContent(); } if (!this._isLoading) { this._isLoading = true; - - // Create early promises that will be fulfilled later - this._contentReadyToProcessDefer = defer(); - this._contentReadyDefer = defer(); - this._contentReadyToProcessPromise = this._contentReadyToProcessDefer.promise; - this._contentReadyPromise = this._contentReadyDefer.promise; - - this._i3sNode._createContentURL().then(function () { - that._contentResource = new Resource({ url: that._i3sNode._glbURL }); - that._resolveHookedObject(); - }); - - // Returns the number of requests - return 0; + return this._i3sNode + ._createContentURL() + .then((url) => { + if (!defined(url)) { + this._isLoading = false; + return; + } + + this._contentResource = new Resource({ url: url }); + return this._hookedRequestContent(); + }) + .then((content) => { + this._isLoading = false; + return content; + }); } - - return 1; }; function bilinearInterpolate(tx, ty, h00, h10, h01, h11) { diff --git a/packages/engine/Source/Scene/PointCloud.js b/packages/engine/Source/Scene/PointCloud.js index a5e94aad2fb..c2a0d363cd3 100644 --- a/packages/engine/Source/Scene/PointCloud.js +++ b/packages/engine/Source/Scene/PointCloud.js @@ -156,9 +156,8 @@ function PointCloud(options) { ); this._splittingEnabled = false; - this._resolveReadyPromise = undefined; - this._rejectReadyPromise = undefined; - this._readyPromise = initialize(this, options); + this._error = undefined; + initialize(this, options); } Object.defineProperties(PointCloud.prototype, { @@ -180,12 +179,6 @@ Object.defineProperties(PointCloud.prototype, { }, }, - readyPromise: { - get: function () { - return this._readyPromise; - }, - }, - color: { get: function () { return Color.clone(this._highlightColor); @@ -283,14 +276,6 @@ function initialize(pointCloud, options) { } pointCloud._pointsLength = parsedContent.pointsLength; - - return new Promise(function (resolve, reject) { - pointCloud._resolveReadyPromise = function () { - pointCloud._ready = true; - resolve(pointCloud); - }; - pointCloud._rejectReadyPromise = reject; - }); } const scratchMin = new Cartesian3(); @@ -1280,7 +1265,7 @@ function decodeDraco(pointCloud, context) { }) .catch(function (error) { pointCloud._decodingState = DecodingState.FAILED; - pointCloud._rejectReadyPromise(error); + pointCloud._error = error; }); } } @@ -1292,6 +1277,13 @@ const scratchScale = new Cartesian3(); PointCloud.prototype.update = function (frameState) { const context = frameState.context; + + if (defined(this._error)) { + const error = this._error; + this._error = undefined; + throw error; + } + const decoding = decodeDraco(this, context); if (decoding) { return; @@ -1309,7 +1301,7 @@ PointCloud.prototype.update = function (frameState) { createResources(this, frameState); modelMatrixDirty = true; shadersDirty = true; - this._resolveReadyPromise(); + this._ready = true; this._parsedContent = undefined; // Unload } diff --git a/packages/engine/Source/Scene/Primitive.js b/packages/engine/Source/Scene/Primitive.js index a431decf52b..3dabc034a1c 100644 --- a/packages/engine/Source/Scene/Primitive.js +++ b/packages/engine/Source/Scene/Primitive.js @@ -9,6 +9,7 @@ import combine from "../Core/combine.js"; import ComponentDatatype from "../Core/ComponentDatatype.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import EncodedCartesian3 from "../Core/EncodedCartesian3.js"; @@ -350,6 +351,7 @@ function Primitive(options) { this._ready = false; const primitive = this; + // This is here for backwards compatibility. This promise wrapper can be removed once readyPromise is removed. this._readyPromise = new Promise((resolve, reject) => { primitive._completeLoad = (frameState, state, error) => { this._error = error; @@ -486,6 +488,19 @@ Object.defineProperties(Primitive.prototype, { * * @type {boolean} * @readonly + * + * @example + * // Wait for a primitive to become ready before accessing attributes + * const removeListener = scene.postRender.addEventListener(() => { + * if (!frustumPrimitive.ready) { + * return; + * } + * + * const attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); + * + * removeListener(); + * }); */ ready: { get: function () { @@ -498,9 +513,14 @@ Object.defineProperties(Primitive.prototype, { * @memberof Primitive.prototype * @type {Promise<Primitive>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "Primitive.readyPromise", + "Primitive.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Primitive.ready to return true instead." + ); return this._readyPromise; }, }, diff --git a/packages/engine/Source/Scene/TimeDynamicPointCloud.js b/packages/engine/Source/Scene/TimeDynamicPointCloud.js index 04b3f77cab5..6d6d1b87acf 100644 --- a/packages/engine/Source/Scene/TimeDynamicPointCloud.js +++ b/packages/engine/Source/Scene/TimeDynamicPointCloud.js @@ -3,6 +3,7 @@ import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import Event from "../Core/Event.js"; import getTimestamp from "../Core/getTimestamp.js"; import JulianDate from "../Core/JulianDate.js"; @@ -183,6 +184,7 @@ function TimeDynamicPointCloud(options) { this._clockMultiplier = 0.0; this._resolveReadyPromise = undefined; const that = this; + // This is here for backwards compatibility and can be removed when readyPromise is removed. this._readyPromise = new Promise(function (resolve) { that._resolveReadyPromise = resolve; }); @@ -252,9 +254,14 @@ Object.defineProperties(TimeDynamicPointCloud.prototype, { * * @type {Promise<TimeDynamicPointCloud>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "TimeDynamicPointCloud.readyPromise", + "TimeDynamicPointCloud.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use TimeDynamicPointCloud.frameFailed instead." + ); return this._readyPromise; }, }, @@ -395,6 +402,7 @@ function requestFrame(that, interval, frameState) { sequential: true, ready: false, touchedFrameNumber: frameState.frameNumber, + uri: uri, }; frames[index] = frame; Resource.fetchArrayBuffer({ @@ -410,7 +418,6 @@ function requestFrame(that, interval, frameState) { uniformMapLoaded: getUniformMapLoaded(that), pickIdLoaded: getPickIdLoaded, }); - return frame.pointCloud.readyPromise; }) .catch(handleFrameFailure(that, uri)); } @@ -507,7 +514,12 @@ function renderFrame(that, frame, updateState, frameState) { pointCloud.geometricErrorScale = shading.geometricErrorScale; pointCloud.maximumAttenuation = getMaximumAttenuation(that); - pointCloud.update(frameState); + try { + pointCloud.update(frameState); + } catch (error) { + handleFrameFailure(that, frame.uri)(error); + } + frame.touchedFrameNumber = frameState.frameNumber; } @@ -738,6 +750,7 @@ TimeDynamicPointCloud.prototype.update = function (frameState) { const that = this; if (defined(frame) && !defined(this._lastRenderedFrame)) { frameState.afterRender.push(function () { + // This is here for backwards compatibility and can be removed when readyPromise is removed. that._resolveReadyPromise(that); return true; }); diff --git a/packages/engine/Source/Scene/VoxelContent.js b/packages/engine/Source/Scene/VoxelContent.js index eead3e8f72d..4d566c89d0d 100644 --- a/packages/engine/Source/Scene/VoxelContent.js +++ b/packages/engine/Source/Scene/VoxelContent.js @@ -11,58 +11,20 @@ import MetadataTable from "./MetadataTable.js"; * @constructor * * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed. - * @param {object} [json] Voxel JSON contents. Mutually exclusive with binary. - * @param {Uint8Array} [binary] Voxel binary contents. Mutually exclusive with json. - * @param {MetadataSchema} metadataSchema The metadata schema used by property tables in the voxel content - * - * @exception {DeveloperError} One of json and binary must be defined. * * @private * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy. */ -function VoxelContent(resource, json, binary, metadataSchema) { +function VoxelContent(resource) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("resource", resource); - if (defined(json) === defined(binary)) { - throw new DeveloperError("One of json and binary must be defined."); - } //>>includeEnd('debug'); this._resource = resource; this._metadataTable = undefined; - - let chunks; - if (defined(json)) { - chunks = { - json: json, - binary: undefined, - }; - } else { - chunks = parseVoxelChunks(binary); - } - - this._readyPromise = initialize( - this, - chunks.json, - chunks.binary, - metadataSchema - ); } Object.defineProperties(VoxelContent.prototype, { - /** - * A promise that resolves once all buffers are loaded. - * - * @type {Promise} - * @readonly - * @private - */ - readyPromise: { - get: function () { - return this._readyPromise; - }, - }, - /** * The {@link MetadataTable} storing voxel property values. * @@ -77,38 +39,74 @@ Object.defineProperties(VoxelContent.prototype, { }, }); -function initialize(content, json, binary, metadataSchema) { - return requestBuffers(content, json, binary).then(function (buffersU8) { - const bufferViewsU8 = {}; - const bufferViewsLength = json.bufferViews.length; - for (let i = 0; i < bufferViewsLength; ++i) { - const bufferViewJson = json.bufferViews[i]; - const start = bufferViewJson.byteOffset; - const end = start + bufferViewJson.byteLength; - const buffer = buffersU8[bufferViewJson.buffer]; - const bufferView = buffer.subarray(start, end); - bufferViewsU8[i] = bufferView; - } +/** + * Creates an object representing voxel content for a {@link Cesium3DTilesVoxelProvider}. + * + * @param {Resource} resource The resource for this voxel content. This is used for fetching external buffers as needed. + * @param {object} [json] Voxel JSON contents. Mutually exclusive with binary. + * @param {Uint8Array} [binary] Voxel binary contents. Mutually exclusive with json. + * @param {MetadataSchema} metadataSchema The metadata schema used by property tables in the voxel content + * @returns {Promise<VoxelContent>} + * + * @exception {DeveloperError} One of json and binary must be defined. + */ +VoxelContent.fromJson = async function ( + resource, + json, + binary, + metadataSchema +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("resource", resource); + if (defined(json) === defined(binary)) { + throw new DeveloperError("One of json and binary must be defined."); + } + //>>includeEnd('debug'); + + let chunks; + if (defined(json)) { + chunks = { + json: json, + binary: undefined, + }; + } else { + chunks = parseVoxelChunks(binary); + } + + const buffersU8 = await requestBuffers(resource, chunks.json, chunks.binary); + const bufferViewsU8 = {}; + const bufferViewsLength = chunks.json.bufferViews.length; + for (let i = 0; i < bufferViewsLength; ++i) { + const bufferViewJson = chunks.json.bufferViews[i]; + const start = bufferViewJson.byteOffset; + const end = start + bufferViewJson.byteLength; + const buffer = buffersU8[bufferViewJson.buffer]; + const bufferView = buffer.subarray(start, end); + bufferViewsU8[i] = bufferView; + } + + const propertyTableIndex = chunks.json.voxelTable; + const propertyTableJson = chunks.json.propertyTables[propertyTableIndex]; - const propertyTableIndex = json.voxelTable; - const propertyTableJson = json.propertyTables[propertyTableIndex]; - content._metadataTable = new MetadataTable({ - count: propertyTableJson.count, - properties: propertyTableJson.properties, - class: metadataSchema.classes[propertyTableJson.class], - bufferViews: bufferViewsU8, - }); - return content; + const content = new VoxelContent(resource); + + content._metadataTable = new MetadataTable({ + count: propertyTableJson.count, + properties: propertyTableJson.properties, + class: metadataSchema.classes[propertyTableJson.class], + bufferViews: bufferViewsU8, }); -} -function requestBuffers(content, json, binary) { + return content; +}; + +function requestBuffers(resource, json, binary) { const buffersLength = json.buffers.length; const bufferPromises = new Array(buffersLength); for (let i = 0; i < buffersLength; i++) { const buffer = json.buffers[i]; if (defined(buffer.uri)) { - const baseResource = content._resource; + const baseResource = resource; const bufferResource = baseResource.getDerivedResource({ url: buffer.uri, }); diff --git a/packages/engine/Source/Scene/VoxelPrimitive.js b/packages/engine/Source/Scene/VoxelPrimitive.js index cd862874da0..833d764142c 100644 --- a/packages/engine/Source/Scene/VoxelPrimitive.js +++ b/packages/engine/Source/Scene/VoxelPrimitive.js @@ -8,8 +8,8 @@ import clone from "../Core/clone.js"; import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; -import DeveloperError from "../Core/DeveloperError.js"; import Event from "../Core/Event.js"; import JulianDate from "../Core/JulianDate.js"; import Matrix3 from "../Core/Matrix3.js"; @@ -426,7 +426,7 @@ function VoxelPrimitive(options) { this._readyPromise = initialize(this, provider); } -function initialize(primitive, provider) { +async function initialize(primitive, provider) { const promise = new Promise(function (resolve) { primitive._completeLoad = function (primitive, frameState) { // Set the primitive as ready after the first frame render since the user might set up events subscribed to @@ -439,9 +439,35 @@ function initialize(primitive, provider) { }; }); - return provider.readyPromise.then(function () { - return promise; - }); + // This is here for backwards compatibility. It can be removed when readyPromise is removed. + if (defined(provider._readyPromise) && !provider._ready) { + await provider._readyPromise; + } + + // Set the bounds + const { + shape: shapeType, + minBounds = VoxelShapeType.getMinBounds(shapeType), + maxBounds = VoxelShapeType.getMaxBounds(shapeType), + } = provider; + + primitive.minBounds = minBounds; + primitive.maxBounds = maxBounds; + primitive.minClippingBounds = VoxelShapeType.getMinBounds(shapeType); + primitive.maxClippingBounds = VoxelShapeType.getMaxBounds(shapeType); + + checkTransformAndBounds(primitive, provider); + + // Create the shape object, and update it so it is valid for VoxelTraversal + const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); + primitive._shape = new ShapeConstructor(); + primitive._shapeVisible = updateShapeAndTransforms( + primitive, + primitive._shape, + provider + ); + + return promise; } Object.defineProperties(VoxelPrimitive.prototype, { @@ -464,9 +490,14 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {Promise<VoxelPrimitive>} * @readonly + * @deprecated */ readyPromise: { get: function () { + deprecationWarning( + "VoxelPrimitive.readyPromise", + "VoxelPrimitive.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for VoxelPrimitive.ready to return true instead." + ); return this._readyPromise; }, }, @@ -490,19 +521,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {BoundingSphere} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ boundingSphere: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "boundingSphere must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._shape.boundingSphere; }, }, @@ -513,20 +534,10 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {OrientedBoundingBox} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ orientedBoundingBox: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "orientedBoundingBox must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - - return this._shape.orientedBoundingBox; + return this.shape.orientedBoundingBox; }, }, @@ -556,19 +567,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {VoxelShapeType} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ shape: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "shape must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._provider.shape; }, }, @@ -579,19 +580,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {Cartesian3} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ dimensions: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "dimensions must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._provider.dimensions; }, }, @@ -602,19 +593,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {number[][]} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ minimumValues: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "minimumValues must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._provider.minimumValues; }, }, @@ -625,19 +606,9 @@ Object.defineProperties(VoxelPrimitive.prototype, { * @memberof VoxelPrimitive.prototype * @type {number[][]} * @readonly - * - * @exception {DeveloperError} If the primitive is not ready. */ maximumValues: { get: function () { - //>>includeStart('debug', pragmas.debug); - if (!this._ready) { - throw new DeveloperError( - "maximumValues must not be called before the primitive is ready." - ); - } - //>>includeEnd('debug'); - return this._provider.maximumValues; }, }, @@ -1018,7 +989,8 @@ VoxelPrimitive.prototype.update = function (frameState) { this._customShader.update(frameState); // Exit early if it's not ready yet. - if (!this._ready && !provider.ready) { + // This is here for backward compatibility. It can be removed when readyPromise is removed. + if ((defined(provider._ready) && !provider._ready) || !defined(this._shape)) { return; } @@ -1188,29 +1160,6 @@ function initFromProvider(primitive, provider, context) { primitive._pickId = context.createPickId({ primitive }); uniforms.pickColor = Color.clone(primitive._pickId.color, uniforms.pickColor); - // Set the bounds - const { - shape: shapeType, - minBounds = VoxelShapeType.getMinBounds(shapeType), - maxBounds = VoxelShapeType.getMaxBounds(shapeType), - } = provider; - - primitive.minBounds = minBounds; - primitive.maxBounds = maxBounds; - primitive.minClippingBounds = VoxelShapeType.getMinBounds(shapeType); - primitive.maxClippingBounds = VoxelShapeType.getMaxBounds(shapeType); - - checkTransformAndBounds(primitive, provider); - - // Create the shape object, and update it so it is valid for VoxelTraversal - const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType); - primitive._shape = new ShapeConstructor(); - primitive._shapeVisible = updateShapeAndTransforms( - primitive, - primitive._shape, - provider - ); - const { shaderDefines, shaderUniforms: shapeUniforms } = primitive._shape; primitive._shapeDefinesOld = clone(shaderDefines, true); @@ -1896,7 +1845,6 @@ VoxelPrimitive.DefaultCustomShader = new CustomShader({ function DefaultVoxelProvider() { this.ready = true; - this.readyPromise = Promise.resolve(this); this.shape = VoxelShapeType.BOX; this.dimensions = new Cartesian3(1, 1, 1); this.names = ["data"]; diff --git a/packages/engine/Source/Scene/VoxelProvider.js b/packages/engine/Source/Scene/VoxelProvider.js index 48a20b1e9d2..0f48173c924 100644 --- a/packages/engine/Source/Scene/VoxelProvider.js +++ b/packages/engine/Source/Scene/VoxelProvider.js @@ -24,6 +24,7 @@ Object.defineProperties(VoxelProvider.prototype, { * @memberof VoxelProvider.prototype * @type {boolean} * @readonly + * @deprecated */ ready: { get: DeveloperError.throwInstantiationError, @@ -35,6 +36,7 @@ Object.defineProperties(VoxelProvider.prototype, { * @memberof VoxelProvider.prototype * @type {Promise<VoxelProvider>} * @readonly + * @deprecated */ readyPromise: { get: DeveloperError.throwInstantiationError, @@ -247,8 +249,6 @@ Object.defineProperties(VoxelProvider.prototype, { * @param {number} [options.tileZ=0] The tile's Z coordinate. * @privateparam {number} [options.keyframe=0] The requested keyframe. * @returns {Promise<Array[]>|undefined} A promise to an array of typed arrays containing the requested voxel data or undefined if there was a problem loading the data. - * - * @exception {DeveloperError} The provider must be ready. */ VoxelProvider.prototype.requestData = DeveloperError.throwInstantiationError; diff --git a/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js index bea961f4e89..ccb33d20733 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesVoxelProviderSpec.js @@ -26,9 +26,10 @@ describe("Scene/Cesium3DTilesVoxelProvider", function () { url: url, }); + expect(provider).toBeDefined(); + return provider.readyPromise.then(function () { expect(provider).toBeDefined(); - expect(provider.ready).toBeTrue(); expect(provider.globalTransform).toEqual(Matrix4.IDENTITY); expect(provider.shapeTransform).toEqualEpsilon( Matrix4.fromScale(Ellipsoid.WGS84.radii), @@ -48,61 +49,52 @@ describe("Scene/Cesium3DTilesVoxelProvider", function () { }); }); - it("constructor throws when url option is missing", function () { - expect(function () { - return new Cesium3DTilesVoxelProvider({ - url: undefined, - }); - }).toThrowDeveloperError(); - }); - - it("requestData works for root tile", function () { + it("fromUrl creates a voxel provider", async function () { const url = "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; - const provider = new Cesium3DTilesVoxelProvider({ - url: url, - }); + const provider = await Cesium3DTilesVoxelProvider.fromUrl(url); - return provider.readyPromise - .then(function () { - return provider.requestData(); - }) - .then(function (data) { - expect(data.length).toEqual(1); - - const dimensions = provider.dimensions; - const voxelCount = dimensions.x * dimensions.y * dimensions.z; - const componentCount = MetadataType.getComponentCount( - provider.types[0] - ); - const expectedLength = voxelCount * componentCount; - expect(data[0].length).toEqual(expectedLength); - }); + expect(provider).toBeInstanceOf(Cesium3DTilesVoxelProvider); + expect(provider.globalTransform).toEqual(Matrix4.IDENTITY); + expect(provider.shapeTransform).toEqualEpsilon( + Matrix4.fromScale(Ellipsoid.WGS84.radii), + CesiumMath.EPSILON10 + ); + expect(provider.shape).toEqual(VoxelShapeType.ELLIPSOID); + expect(provider.minBounds).toEqual(new Cartesian3(0.0, 0.0, -1.0)); + expect(provider.maxBounds).toEqual(new Cartesian3(1.0, 1.0, 0.0)); + expect(provider.dimensions).toEqual(new Cartesian3(2, 2, 2)); + expect(provider.paddingBefore).toBeUndefined(); + expect(provider.paddingAfter).toBeUndefined(); + expect(provider.names).toEqual(["a"]); + expect(provider.types).toEqual([MetadataType.SCALAR]); + expect(provider.componentTypes).toEqual([MetadataComponentType.FLOAT32]); + expect(provider.minimumValues).toEqual([[0]]); + expect(provider.maximumValues).toEqual([[1]]); }); - it("requestData throws if the provider is not ready", function () { + it("requestData works for root tile", async function () { const url = "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json"; - const provider = new Cesium3DTilesVoxelProvider({ - url: url, - }); - expect(function () { - return provider.requestData(); - }).toThrowDeveloperError(); + const provider = await Cesium3DTilesVoxelProvider.fromUrl(url); + + const data = await provider.requestData(); + expect(data.length).toEqual(1); + + const dimensions = provider.dimensions; + const voxelCount = dimensions.x * dimensions.y * dimensions.z; + const componentCount = MetadataType.getComponentCount(provider.types[0]); + const expectedLength = voxelCount * componentCount; + expect(data[0].length).toEqual(expectedLength); }); - it("requestData loads multiple attributes correctly", function () { + it("requestData loads multiple attributes correctly", async function () { const url = "./Data/Cesium3DTiles/Voxel/VoxelMultiAttribute3DTiles/tileset.json"; - const provider = new Cesium3DTilesVoxelProvider({ url }); + const provider = await Cesium3DTilesVoxelProvider.fromUrl(url); - return provider.readyPromise - .then(function () { - return provider.requestData(); - }) - .then(function (data) { - expect(data.length).toBe(3); - expect(data[0][0]).toBe(0.0); - expect(data[1][0]).toBe(0.5); - expect(data[2][0]).toBe(1.0); - }); + const data = await provider.requestData(); + expect(data.length).toBe(3); + expect(data[0][0]).toBe(0.0); + expect(data[1][0]).toBe(0.5); + expect(data[2][0]).toBe(1.0); }); }); diff --git a/packages/engine/Specs/Scene/I3SDataProviderSpec.js b/packages/engine/Specs/Scene/I3SDataProviderSpec.js index 50a7999be80..780ff4b9834 100644 --- a/packages/engine/Specs/Scene/I3SDataProviderSpec.js +++ b/packages/engine/Specs/Scene/I3SDataProviderSpec.js @@ -1,9 +1,11 @@ import { + Cesium3DTileset, GeographicTilingScheme, I3SDataProvider, Math as CesiumMath, Rectangle, Resource, + RuntimeError, } from "../../index.js"; describe("Scene/I3SDataProvider", function () { @@ -182,8 +184,9 @@ describe("Scene/I3SDataProvider", function () { const frameState = {}; testProvider.update(frameState); - // Function should not be called for tilesets that are not yet ready - expect(testProvider._layers[0]._tileset.update).not.toHaveBeenCalled(); + expect(testProvider._layers[0]._tileset.update).toHaveBeenCalledWith( + frameState + ); expect(testProvider._layers[1]._tileset.update).toHaveBeenCalledWith( frameState ); @@ -203,10 +206,9 @@ describe("Scene/I3SDataProvider", function () { const frameState = {}; testProvider.prePassesUpdate(frameState); - // Function should not be called for tilesets that are not yet ready expect( testProvider._layers[0]._tileset.prePassesUpdate - ).not.toHaveBeenCalled(); + ).toHaveBeenCalledWith(frameState); expect( testProvider._layers[1]._tileset.prePassesUpdate ).toHaveBeenCalledWith(frameState); @@ -226,10 +228,9 @@ describe("Scene/I3SDataProvider", function () { const frameState = {}; testProvider.postPassesUpdate(frameState); - // Function should not be called for tilesets that are not yet ready expect( testProvider._layers[0]._tileset.postPassesUpdate - ).not.toHaveBeenCalled(); + ).toHaveBeenCalledWith(frameState); expect( testProvider._layers[1]._tileset.postPassesUpdate ).toHaveBeenCalledWith(frameState); @@ -250,10 +251,10 @@ describe("Scene/I3SDataProvider", function () { const passState = { test: "test" }; testProvider.updateForPass(frameState, passState); - // Function should not be called for tilesets that are not yet ready - expect( - testProvider._layers[0]._tileset.updateForPass - ).not.toHaveBeenCalled(); + expect(testProvider._layers[0]._tileset.updateForPass).toHaveBeenCalledWith( + frameState, + passState + ); expect(testProvider._layers[1]._tileset.updateForPass).toHaveBeenCalledWith( frameState, passState @@ -342,12 +343,9 @@ describe("Scene/I3SDataProvider", function () { Promise.resolve(mockBinaryResponse) ); - spyOn(console, "log"); - const resource = Resource.createIfNeeded("mockBinaryUri"); return testProvider._loadBinary(resource).then(function (result) { expect(Resource.prototype.fetchArrayBuffer).toHaveBeenCalled(); - expect(console.log).toHaveBeenCalledWith("I3S FETCH:", resource.url); expect(result).toBe(mockBinaryResponse); }); }); @@ -370,69 +368,38 @@ describe("Scene/I3SDataProvider", function () { }); }); - it("loads json", function () { - const mockJsonResponse = { test: 1 }; - - spyOn(I3SDataProvider.prototype, "_load"); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl", - name: "testProvider", - }); + it("fromUrl throws without url ", async function () { + await expectAsync( + I3SDataProvider.fromUrl() + ).toBeRejectedWithDeveloperError(); + }); + it("loads json", async function () { spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(mockJsonResponse) + Promise.resolve(mockProviderData) ); - - const resource = Resource.createIfNeeded("mockJsonUri"); - return testProvider._loadJson(resource).then(function (result) { - expect(Resource.prototype.fetchJson).toHaveBeenCalled(); - expect(result).toBe(mockJsonResponse); + spyOn(Cesium3DTileset, "fromUrl").and.callFake(async () => { + const tileset = new Cesium3DTileset(); + tileset._root = {}; // Mock the root tile so that i3s property can be appended + return tileset; }); - }); - it("loads json with traceFetches enabled", function () { - const mockJsonResponse = { test: 1 }; - - spyOn(I3SDataProvider.prototype, "_load"); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl", + const testProvider = await I3SDataProvider.fromUrl("mockProviderUrl", { name: "testProvider", - traceFetches: true, }); - spyOn(Resource.prototype, "fetchJson").and.returnValue( - Promise.resolve(mockJsonResponse) - ); - - spyOn(console, "log"); - - const resource = Resource.createIfNeeded("mockJsonUri"); - return testProvider._loadJson(resource).then(function (result) { - expect(Resource.prototype.fetchJson).toHaveBeenCalled(); - expect(console.log).toHaveBeenCalledWith("I3S FETCH:", resource.url); - expect(result).toBe(mockJsonResponse); - }); + expect(Resource.prototype.fetchJson).toHaveBeenCalled(); + expect(testProvider).toBeInstanceOf(I3SDataProvider); + expect(testProvider.data).toEqual(mockProviderData); + expect(Cesium3DTileset.fromUrl).toHaveBeenCalled(); }); - it("loadJson rejects invalid uri", function () { - spyOn(I3SDataProvider.prototype, "_load"); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl", - name: "testProvider", - }); - + it("loadJson rejects invalid uri", async function () { const resource = Resource.createIfNeeded("mockJsonUri"); - return testProvider - ._loadJson(resource) - .then(function () { - fail("Promise should not be resolved for invalid uri"); - }) - .catch(function (error) { - expect(error.statusCode).toEqual(404); - }); + await expectAsync(I3SDataProvider.loadJson(resource)).toBeRejected(); }); - it("loadJson rejects error response", function () { + it("loadJson rejects error response", async function () { const mockErrorResponse = { error: { code: 498, @@ -444,25 +411,15 @@ describe("Scene/I3SDataProvider", function () { }, }; - spyOn(I3SDataProvider.prototype, "_load"); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl", - name: "testProvider", - }); - spyOn(Resource.prototype, "fetchJson").and.returnValue( Promise.resolve(mockErrorResponse) ); const resource = Resource.createIfNeeded("mockJsonUri"); - return testProvider - ._loadJson(resource) - .then(function () { - fail("Promise should not be resolved for error response"); - }) - .catch(function (error) { - expect(error).toBe(mockErrorResponse.error); - }); + await expectAsync(I3SDataProvider.loadJson(resource)).toBeRejectedWithError( + RuntimeError, + mockErrorResponse.error + ); }); it("loads geoid data", function () { @@ -475,7 +432,7 @@ describe("Scene/I3SDataProvider", function () { testProvider._extent = Rectangle.fromDegrees(-1, 0, 1, 2); - return testProvider._loadGeoidData().then(function () { + return testProvider.loadGeoidData().then(function () { expect(testProvider._geoidDataList.length).toEqual(2); expect(testProvider._geoidDataList[0].height).toEqual(2); expect(testProvider._geoidDataList[0].width).toEqual(2); @@ -499,7 +456,7 @@ describe("Scene/I3SDataProvider", function () { }); testProvider._extent = Rectangle.fromDegrees(-1, 0, 1, 2); - return testProvider._loadGeoidData().then(function () { + return testProvider.loadGeoidData().then(function () { expect(testProvider._geoidDataList).toBeUndefined(); }); }); diff --git a/packages/engine/Specs/Scene/I3SLayerSpec.js b/packages/engine/Specs/Scene/I3SLayerSpec.js index 4dbf710091a..4bc6b24ab3a 100644 --- a/packages/engine/Specs/Scene/I3SLayerSpec.js +++ b/packages/engine/Specs/Scene/I3SLayerSpec.js @@ -107,7 +107,9 @@ describe("Scene/I3SLayer", function () { const mockI3SProvider = new I3SDataProvider({ url: "mockProviderUrl?testQuery=test", }); - mockI3SProvider._geoidDataIsReadyPromise = Promise.resolve(); + spyOn(I3SDataProvider.prototype, "loadGeoidData").and.returnValue( + Promise.resolve() + ); return mockI3SProvider; } diff --git a/packages/engine/Specs/Scene/I3SNodeSpec.js b/packages/engine/Specs/Scene/I3SNodeSpec.js index 6e6941b374a..5e7e25beab0 100644 --- a/packages/engine/Specs/Scene/I3SNodeSpec.js +++ b/packages/engine/Specs/Scene/I3SNodeSpec.js @@ -654,14 +654,12 @@ describe("Scene/I3SNode", function () { it("loads root node from uri", function () { const rootNode = new I3SNode(mockI3SLayerWithoutNodePages, "mockUrl", true); - spyOn(rootNode._dataProvider, "_loadJson").and.returnValue( + const spy = spyOn(I3SDataProvider, "loadJson").and.returnValue( Promise.resolve(rootNodeWithChildren) ); return rootNode.load().then(function () { - expect(rootNode._dataProvider._loadJson).toHaveBeenCalledWith( - rootNode.resource - ); + expect(spy).toHaveBeenCalledWith(rootNode.resource, false); expect(rootNode.data.children.length).toEqual(2); }); }); @@ -669,7 +667,7 @@ describe("Scene/I3SNode", function () { it("loads child node from uri", function () { const rootNode = new I3SNode(mockI3SLayerWithoutNodePages, "mockUrl", true); const childNode = new I3SNode(rootNode, "mockUrlChild", false); - spyOn(childNode._dataProvider, "_loadJson").and.returnValue( + const spy = spyOn(I3SDataProvider, "loadJson").and.returnValue( Promise.resolve(nodeWithContent) ); @@ -679,9 +677,7 @@ describe("Scene/I3SNode", function () { return childNode.load(); }) .then(function () { - expect(childNode._dataProvider._loadJson).toHaveBeenCalledWith( - childNode.resource - ); + expect(spy).toHaveBeenCalledWith(childNode.resource, false); expect(childNode.data.children.length).toEqual(0); expect(childNode.tile).toBeDefined(); expect(childNode.tile.i3sNode).toBe(childNode); @@ -951,7 +947,7 @@ describe("Scene/I3SNode", function () { true ); - spyOn(nodeWithMesh._dataProvider, "_loadJson").and.returnValue( + spyOn(I3SDataProvider, "loadJson").and.returnValue( Promise.resolve(nodeWithContent) ); spyOn(nodeWithMesh._dataProvider, "_loadBinary").and.returnValue( @@ -1070,7 +1066,7 @@ describe("Scene/I3SNode", function () { true ); - spyOn(nodeWithTexturedMesh._dataProvider, "_loadJson").and.returnValue( + spyOn(I3SDataProvider, "loadJson").and.returnValue( Promise.resolve(nodeWithTexturedContent) ); spyOn(nodeWithTexturedMesh._dataProvider, "_loadBinary").and.returnValue( @@ -1131,7 +1127,7 @@ describe("Scene/I3SNode", function () { true ); - spyOn(nodeWithMesh._dataProvider, "_loadJson").and.callFake(function ( + const spy = spyOn(I3SDataProvider, "loadJson").and.callFake(function ( resource ) { if ( @@ -1167,8 +1163,9 @@ describe("Scene/I3SNode", function () { expect(nodeWithMesh.featureData[0].data.featureData).toEqual([]); expect(nodeWithMesh.featureData[0].data.geometryData).toEqual([]); - expect(nodeWithMesh._dataProvider._loadJson).toHaveBeenCalledWith( - nodeWithMesh.featureData[0].resource + expect(spy).toHaveBeenCalledWith( + nodeWithMesh.featureData[0].resource, + false ); }); }); @@ -1188,16 +1185,14 @@ describe("Scene/I3SNode", function () { }); }); - it("load feature data rejects invalid url", function () { + it("load feature data rejects invalid url", async function () { const nodeWithMesh = new I3SNode( mockI3SLayerWithoutNodePages, "mockNodeUrl", true ); - spyOn(nodeWithMesh._dataProvider, "_loadJson").and.callFake(function ( - resource - ) { + spyOn(I3SDataProvider, "loadJson").and.callFake(function (resource) { if ( resource .getUrlComponent() @@ -1218,17 +1213,8 @@ describe("Scene/I3SNode", function () { return Promise.reject(); }); - return nodeWithMesh - .load() - .then(function () { - return nodeWithMesh._loadFeatureData(); - }) - .then(function () { - fail("Promise should not be resolved for invalid uri"); - }) - .catch(function (error) { - expect(error.statusCode).toEqual(404); - }); + await nodeWithMesh.load(); + await expectAsync(nodeWithMesh._loadFeatureData()).toBeRejected(); }); it("creates 3d tile content", function () { @@ -1270,8 +1256,8 @@ describe("Scene/I3SNode", function () { }; spyOn( nodeWithMesh._dataProvider, - "_getDecoderTaskProcessor" - ).and.returnValue(mockProcessor); + "getDecoderTaskProcessor" + ).and.returnValue(Promise.resolve(mockProcessor)); return rootNode .load() @@ -1282,11 +1268,11 @@ describe("Scene/I3SNode", function () { return nodeWithMesh._createContentURL(); }) .then(function (result) { - expect(nodeWithMesh._glbURL).toBeDefined(); + expect(result).toBeDefined(); expect(nodeWithMesh.tile).toBeDefined(); //Test fetching the blob url that was created - return Resource.fetchArrayBuffer(nodeWithMesh._glbURL); + return Resource.fetchArrayBuffer(result); }) .then(function (data) { expect(data.error).toBeUndefined(); @@ -1419,18 +1405,11 @@ describe("Scene/I3SNode", function () { }) .then(function (result) { spyOn(childNode, "_createContentURL").and.callFake(function () { - childNode._glbURL = "mockGlbUrl"; - return Promise.resolve(); + return Promise.resolve("mockGlbUrl"); }); - spyOn(childNode.tile, "_hookedRequestContent").and.callFake( - function () { - childNode.tile._contentReadyToProcessPromise = Promise.resolve(); - } - ); + spyOn(childNode.tile, "_hookedRequestContent"); - childNode.tile._contentResource = { _url: "mockOriginalContentUrl" }; - childNode.tile.requestContent(); - return Promise.all([childNode.tile._contentReadyToProcessPromise]); + return childNode.tile.requestContent(); }) .then(function () { expect(childNode.tile._contentResource._url).toEqual("mockGlbUrl"); diff --git a/packages/engine/Specs/Scene/TimeDynamicPointCloudSpec.js b/packages/engine/Specs/Scene/TimeDynamicPointCloudSpec.js index ef2a07c4449..db47c849004 100644 --- a/packages/engine/Specs/Scene/TimeDynamicPointCloudSpec.js +++ b/packages/engine/Specs/Scene/TimeDynamicPointCloudSpec.js @@ -828,29 +828,21 @@ describe( }); return loadFrame(pointCloud).then(function () { const decoder = DracoLoader._getDecoderTaskProcessor(); + let frameFailed = false; spyOn(decoder, "scheduleTask").and.callFake(function () { return Promise.reject({ message: "my error" }); }); - const spyUpdate = jasmine.createSpy("listener"); - pointCloud.frameFailed.addEventListener(spyUpdate); + pointCloud.frameFailed.addEventListener((error) => { + frameFailed = true; + expect(error).toBeDefined(); + expect(error.uri).toContain("1.pnts"); + expect(error.message).toBe("my error"); + }); goToFrame(1); scene.renderForSpecs(); - let failedPromise; - let frameFailed = false; return pollToPromise(function () { - const contents = pointCloud._frames[1].pointCloud; - if (defined(contents) && !defined(failedPromise)) { - failedPromise = contents.readyPromise.catch(function () { - frameFailed = true; - }); - } scene.renderForSpecs(); return frameFailed; - }).then(function () { - const arg = spyUpdate.calls.argsFor(0)[0]; - expect(arg).toBeDefined(); - expect(arg.uri).toContain("1.pnts"); - expect(arg.message).toBe("my error"); }); }); }); diff --git a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js index 68cc557ab41..971de1e19d6 100644 --- a/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js +++ b/packages/engine/Specs/Scene/VoxelPrimitiveSpec.js @@ -14,18 +14,17 @@ describe( let scene; let provider; - beforeEach(function () { + beforeEach(async function () { scene = createScene(); const camera = scene.camera; camera.position = Cartesian3.fromElements(-10, -10, -10); camera.direction = Cartesian3.fromElements(1, 1, 1); - provider = new Cesium3DTilesVoxelProvider({ - url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", - }); - - return provider.readyPromise; + provider = await Cesium3DTilesVoxelProvider.fromUrl( + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json" + ); + return provider; }); afterEach(function () { @@ -44,10 +43,12 @@ describe( it("constructs with options", async function () { const primitive = new VoxelPrimitive({ provider }); scene.primitives.add(primitive); - scene.renderForSpecs(); expect(primitive.provider).toBe(provider); - await primitive.readyPromise; + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; + }); expect(primitive.shape._type).toBe(provider.shape._type); expect(primitive.dimensions.equals(provider.dimensions)).toBe(true); @@ -134,7 +135,10 @@ describe( const shape = primitive._shape; shape.translation = new Cartesian3(2.382, -3.643, 1.084); - await primitive.readyPromise; + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; + }); primitive.update(scene.frameState); const stepSizeUv = shape.computeApproximateStepSize(primitive.dimensions); @@ -146,7 +150,10 @@ describe( scene.primitives.add(primitive); scene.renderForSpecs(); - await primitive.readyPromise; + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; + }); expect(primitive.customShader).toBe(VoxelPrimitive.DefaultCustomShader); @@ -173,7 +180,10 @@ describe( scene.renderForSpecs(); expect(primitive.isDestroyed()).toBe(false); - await primitive.readyPromise; + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; + }); primitive.update(scene.frameState); expect(primitive.isDestroyed()).toBe(false); diff --git a/packages/engine/Specs/Scene/buildVoxelDrawCommandsSpec.js b/packages/engine/Specs/Scene/buildVoxelDrawCommandsSpec.js index 1835f16b738..7ba353984ca 100644 --- a/packages/engine/Specs/Scene/buildVoxelDrawCommandsSpec.js +++ b/packages/engine/Specs/Scene/buildVoxelDrawCommandsSpec.js @@ -12,14 +12,12 @@ describe("Scene/buildVoxelDrawCommands", function () { let scene; let provider; - beforeAll(function () { + beforeAll(async function () { scene = createScene(); - provider = new Cesium3DTilesVoxelProvider({ - url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", - }); - - return provider._readyPromise; + provider = await Cesium3DTilesVoxelProvider.fromUrl( + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json" + ); }); afterAll(function () { diff --git a/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js b/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js index 808586fe14e..b885ab52e4f 100644 --- a/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js +++ b/packages/engine/Specs/Scene/processVoxelPropertiesSpec.js @@ -11,21 +11,19 @@ describe("Scene/processVoxelProperties", function () { let scene; let provider; - beforeAll(function () { + beforeAll(async function () { scene = createScene(); - provider = new Cesium3DTilesVoxelProvider({ - url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", - }); - - return provider.readyPromise; + provider = await Cesium3DTilesVoxelProvider.fromUrl( + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json" + ); }); afterAll(function () { scene.destroyForSpecs(); }); - it("adds shader defines and structs", function () { + it("adds shader defines and structs", async function () { const primitive = new VoxelPrimitive({ provider }); primitive.update(scene.frameState); diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 42216d4aa28..ab404d8a009 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2233,7 +2233,7 @@ function updateZoomTarget(viewer) { // If zoomTarget was Cesium3DTileset if (target instanceof Cesium3DTileset || target instanceof VoxelPrimitive) { - // This is here for backwards compatibility and can be removed once Cesium3DTileset.readyPromise is removed. + // This is here for backwards compatibility and can be removed once Cesium3DTileset.readyPromise and VoxelPrimitive.readyPromise is removed. return target._readyPromise .then(function () { const boundingSphere = target.boundingSphere; @@ -2277,7 +2277,8 @@ function updateZoomTarget(viewer) { // If zoomTarget was TimeDynamicPointCloud if (target instanceof TimeDynamicPointCloud) { - return target.readyPromise.then(function () { + // This is here for backwards compatibility and can be removed once TimeDynamicPointCloud.readyPromise is removed. + return target._readyPromise.then(function () { const boundingSphere = target.boundingSphere; // If offset was originally undefined then give it base value instead of empty object if (!defined(zoomOptions.offset)) { diff --git a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js index af391c97aad..265ef89468a 100644 --- a/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js +++ b/packages/widgets/Source/VoxelInspector/VoxelInspectorViewModel.js @@ -720,7 +720,8 @@ Object.defineProperties(VoxelInspectorViewModel.prototype, { this._voxelPrimitive = voxelPrimitive; const that = this; - that._voxelPrimitive.readyPromise.then(function () { + // This is here for backwards compatibility. This can be done immediately once readyPromise is removed. + that._voxelPrimitive._readyPromise.then(function () { that._customShaderCompilationRemoveCallback = that._voxelPrimitive.customShaderCompilationEvent.addEventListener( function (error) { const shaderString = diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index cfabcc15a8b..443d94001a5 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -1406,14 +1406,14 @@ describe( }); }); - function loadVoxelPrimitive(viewer) { + async function loadVoxelPrimitive(viewer) { const voxelPrimitive = new VoxelPrimitive({ - provider: new Cesium3DTilesVoxelProvider({ - url: "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json", - }), + provider: await Cesium3DTilesVoxelProvider.fromUrl( + "./Data/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json" + ), }); viewer.scene.primitives.add(voxelPrimitive); - return voxelPrimitive.readyPromise; + return voxelPrimitive; } it("zoomTo zooms to VoxelPrimitive with default offset when offset not defined", function () { From 0b177166a1705d106677fd5956141b47cb38005b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 27 Mar 2023 14:16:23 -0400 Subject: [PATCH 577/679] Fix specs, ensure listeners are removed when objcet is destroyed --- .../Source/Scene/GlobeSurfaceTileProvider.js | 20 +++++++++++++++---- .../Core/GoogleEarthEnterpriseMetadataSpec.js | 2 +- .../TileMapServiceImageryProviderSpec.js | 6 ++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index fb3dcd2adb2..3b068cd95a2 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -127,19 +127,19 @@ function GlobeSurfaceTileProvider(options) { this._errorEvent = new Event(); - this._imageryLayers.layerAdded.addEventListener( + this._removeLayerAddedListener = this._imageryLayers.layerAdded.addEventListener( GlobeSurfaceTileProvider.prototype._onLayerAdded, this ); - this._imageryLayers.layerRemoved.addEventListener( + this._removeLayerRemovedListener = this._imageryLayers.layerRemoved.addEventListener( GlobeSurfaceTileProvider.prototype._onLayerRemoved, this ); - this._imageryLayers.layerMoved.addEventListener( + this._removeLayerMovedListener = this._imageryLayers.layerMoved.addEventListener( GlobeSurfaceTileProvider.prototype._onLayerMoved, this ); - this._imageryLayers.layerShownOrHidden.addEventListener( + this._removeLayerShownListener = this._imageryLayers.layerShownOrHidden.addEventListener( GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden, this ); @@ -1389,6 +1389,14 @@ GlobeSurfaceTileProvider.prototype.isDestroyed = function () { GlobeSurfaceTileProvider.prototype.destroy = function () { this._tileProvider = this._tileProvider && this._tileProvider.destroy(); this._clippingPlanes = this._clippingPlanes && this._clippingPlanes.destroy(); + this._removeLayerAddedListener = + this._removeLayerAddedListener && this._removeLayerAddedListener(); + this._removeLayerRemovedListener = + this._removeLayerRemovedListener && this._removeLayerRemovedListener(); + this._removeLayerMovedListener = + this._removeLayerMovedListener && this._removeLayerMovedListener(); + this._removeLayerShownListener = + this._removeLayerShownListener && this._removeLayerShownListener(); return destroyObject(this); }; @@ -1441,6 +1449,10 @@ function getTileReadyCallback(tileImageriesToFree, layer, terrainProvider) { } GlobeSurfaceTileProvider.prototype._onLayerAdded = function (layer, index) { + if (this.isDestroyed()) { + return; + } + if (layer.show) { const terrainProvider = this._terrainProvider; diff --git a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js index 2af772c023b..2a3b2b0fcd0 100644 --- a/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js +++ b/packages/engine/Specs/Core/GoogleEarthEnterpriseMetadataSpec.js @@ -395,7 +395,7 @@ describe("Core/GoogleEarthEnterpriseMetadata", function () { GoogleEarthEnterpriseMetadata.fromUrl(url) ).toBeRejectedWithError( RuntimeError, - "An error occurred while accessing http://localhost:9876/host.invalid/flatfile?q2-0-q.1: Request has failed. Status Code: 404" + new RegExp("Request has failed. Status Code: 404") ); }); }); diff --git a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js index 3ffa7be62b4..4b4f3d98e7b 100644 --- a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js @@ -252,7 +252,9 @@ describe("Scene/TileMapServiceImageryProvider", function () { TileMapServiceImageryProvider.fromUrl("made/up/tms/server") ).toBeRejectedWithError( RuntimeError, - "http://localhost:9876/made/up/tms/server/tilemapresource.xml specifies an unsupported profile attribute, foobar." + new RegExp( + "made/up/tms/server/tilemapresource.xml specifies an unsupported profile attribute, foobar." + ) ); }); @@ -274,7 +276,7 @@ describe("Scene/TileMapServiceImageryProvider", function () { TileMapServiceImageryProvider.fromUrl("made/up/tms/server") ).toBeRejectedWithError( RuntimeError, - "Unable to find expected tilesets or bbox attributes in http://localhost:9876/made/up/tms/server/tilemapresource.xml." + new RegExp("Unable to find expected tilesets or bbox attributes") ); }); From 63f720d45e2964cfa79a0aaebd5ed5bb0cd03feb Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Mar 2023 14:33:22 -0400 Subject: [PATCH 578/679] PR feedback phase 1 --- .../Source/Scene/Cesium3DTilesetBaseTraversal.js | 9 +++++++++ .../Scene/Cesium3DTilesetMostDetailedTraversal.js | 11 +++++++++++ .../Source/Scene/Cesium3DTilesetSkipTraversal.js | 8 ++++++++ .../engine/Source/Scene/Cesium3DTilesetTraversal.js | 9 +++++---- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js index 57b776b6b08..8f5227e0106 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js @@ -4,6 +4,13 @@ import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; /** + * Depth-first traversal that traverses all visible tiles and marks tiles for selection. + * A tile does not refine until all children are loaded. + * This is the traditional replacement refinement approach and is called the base traversal. + * + * @alias Cesium3DTilesetBaseTraversal + * @constructor + * * @private */ function Cesium3DTilesetBaseTraversal() {} @@ -19,6 +26,8 @@ const emptyTraversal = { }; /** + * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render. + * * @private * @param {Cesium3DTileset} tileset * @param {FrameState} frameState diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js index f8a66b2f551..98b95009611 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js @@ -7,6 +7,9 @@ import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; * Traversal that loads all leaves that intersect the camera frustum. * Used to determine ray-tileset intersections during a pickFromRayMostDetailed call. * + * @alias Cesium3DTilesetMostDetailedTraversal + * @constructor + * * @private */ function Cesium3DTilesetMostDetailedTraversal() {} @@ -16,6 +19,14 @@ const traversal = { stackMaximumLength: 0, }; +/** + * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render. + * + * @private + * @param {Cesium3DTileset} tileset + * @param {FrameState} frameState + * @returns {boolean} Whether the appropriate tile is ready for picking + */ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( tileset, frameState diff --git a/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js index a74e04481de..b4dbdc6b3ac 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js @@ -4,6 +4,12 @@ import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js"; /** + * Depth-first traversal that traverses all visible tiles and marks tiles for selection. + * Allows for skipping levels of the tree and rendering children and parent tiles simultaneously. + * + * @alias Cesium3DTilesetSkipTraversal + * @constructor + * * @private */ function Cesium3DTilesetSkipTraversal() {} @@ -28,6 +34,8 @@ const selectionTraversal = { const descendantSelectionDepth = 2; /** + * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render. + * * @private * @param {Cesium3DTileset} tileset * @param {FrameState} frameState diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js index 2c32ced7721..fc30a1eca82 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js @@ -10,6 +10,7 @@ import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; * * @alias Cesium3DTilesetTraversal * @constructor + * @abstract * * @see Cesium3DTilesetBaseTraversal * @see Cesium3DTilesetSkipTraversal @@ -20,6 +21,8 @@ import Cesium3DTileRefine from "./Cesium3DTileRefine.js"; function Cesium3DTilesetTraversal() {} /** + * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render. + * * @private * @param {Cesium3DTileset} tileset * @param {FrameState} frameState @@ -283,10 +286,8 @@ function anyChildrenVisible(tile, frameState) { * @param {Cesium3DTile} tile */ function updateMinimumMaximumPriority(tile) { - const { - _maximumPriority: maximumPriority, - _minimumPriority: minimumPriority, - } = tile.tileset; + const minimumPriority = tile.tileset._minimumPriority; + const maximumPriority = tile.tileset._maximumPriority; const priorityHolder = tile._priorityHolder; maximumPriority.distance = Math.max( From b14765558c4c71853321c47951349ff7dce493b9 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 27 Mar 2023 15:28:49 -0400 Subject: [PATCH 579/679] Fix vector tile example --- packages/engine/Source/Scene/Vector3DTileContent.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/Vector3DTileContent.js b/packages/engine/Source/Scene/Vector3DTileContent.js index 56d7e750b5f..396e1a9e52f 100644 --- a/packages/engine/Source/Scene/Vector3DTileContent.js +++ b/packages/engine/Source/Scene/Vector3DTileContent.js @@ -25,7 +25,6 @@ import decodeVectorPolylinePositions from "../Core/decodeVectorPolylinePositions * <p> * Implements the {@link Cesium3DTileContent} interface. * </p> - * This object is normally not instantiated directly, use {@link Vector3DTileContent.fromTile}. * * @alias Vector3DTileContent * @constructor @@ -298,6 +297,7 @@ function initialize(content, arrayBuffer, byteOffset) { byteOffset += sizeOfUint32; if (byteLength === 0) { + content._ready = true; return; } @@ -622,8 +622,6 @@ function initialize(content, arrayBuffer, byteOffset) { batchTable: batchTable, }); } - - return; } function createFeatures(content) { From fbfcc66caff29cebf640cc1cd0c5df4231c2ee32 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 27 Mar 2023 15:33:53 -0400 Subject: [PATCH 580/679] Fix docs --- packages/engine/Source/Scene/I3SDataProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/I3SDataProvider.js b/packages/engine/Source/Scene/I3SDataProvider.js index 53e55f94a23..d284e00bf5c 100644 --- a/packages/engine/Source/Scene/I3SDataProvider.js +++ b/packages/engine/Source/Scene/I3SDataProvider.js @@ -513,7 +513,7 @@ I3SDataProvider._fetchJson = function (resource) { * @private * * @param {Resource} resource The JSON resource to request - * @param {bool=false} trace Log the resource + * @param {boolean} [trace=false] Log the resource * @returns {Promise<object>} The fetched data */ I3SDataProvider.loadJson = async function (resource, trace) { From 83afbc4e2ef8782d319988649a173165f93f53d6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Mar 2023 17:15:35 -0400 Subject: [PATCH 581/679] Add getter for tileset.isSkippingLevelOfDetail --- packages/engine/Source/Scene/Cesium3DTile.js | 7 ++-- .../Source/Scene/Cesium3DTileBatchTable.js | 2 +- .../engine/Source/Scene/Cesium3DTileset.js | 41 +++++++++++-------- packages/engine/Source/Scene/Model/Model.js | 7 +--- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index f3de7ee3fb0..acdc5c83db2 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -879,7 +879,7 @@ function isPriorityDeferred(tile, frameState) { // Skip this feature if: non-skipLevelOfDetail and replace refine, if the foveated settings are turned off, if tile is progressive resolution and replace refine and skipLevelOfDetail (will help get rid of ancestor artifacts faster) // Or if the tile is a preload of any kind const replace = tile.refine === Cesium3DTileRefine.REPLACE; - const skipLevelOfDetail = tileset._skipLevelOfDetail; + const skipLevelOfDetail = tileset.isSkippingLevelOfDetail; if ( (replace && !skipLevelOfDetail) || !tileset.foveatedScreenSpaceError || @@ -1023,7 +1023,7 @@ function getPriorityReverseScreenSpaceError(tileset, tile) { const parent = tile.parent; const useParentScreenSpaceError = defined(parent) && - (!tileset._skipLevelOfDetail || + (!tileset.isSkippingLevelOfDetail || tile._screenSpaceError === 0.0 || parent.hasTilesetContent || parent.hasImplicitContent); @@ -2214,7 +2214,8 @@ Cesium3DTile.prototype.updatePriority = function () { // Map 0-1 then convert to digit. Include a distance sort when doing non-skipLOD and replacement refinement, helps things like non-skipLOD photogrammetry const useDistance = - !tileset._skipLevelOfDetail && this.refine === Cesium3DTileRefine.REPLACE; + !tileset.isSkippingLevelOfDetail && + this.refine === Cesium3DTileRefine.REPLACE; const normalizedPreferredSorting = useDistance ? priorityNormalizeAndClamp( this._priorityHolder._distanceToCamera, diff --git a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js index a892b0f9494..29517ea70a1 100644 --- a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js +++ b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js @@ -896,7 +896,7 @@ Cesium3DTileBatchTable.prototype.addDerivedCommands = function ( const finalResolution = tile._finalResolution; const tileset = tile.tileset; const bivariateVisibilityTest = - tileset._skipLevelOfDetail && + tileset.isSkippingLevelOfDetail && tileset._hasMixedContent && frameState.context.stencilBuffer; const styleCommandsNeeded = getStyleCommandsNeeded(this); diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 181f63ec81f..dd3697e9e73 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -658,15 +658,6 @@ function Cesium3DTileset(options) { */ this.skipLevelOfDetail = defaultValue(options.skipLevelOfDetail, false); - /** - * Whether this tileset is actually skipping levels of detail. - * The user option may have been disabled if all tiles are using additive refinement, - * or if some tiles have a content type for which rendering does not support skipping - * - * @private - * @type {boolean} - */ - this._skipLevelOfDetail = this.skipLevelOfDetail; this._disableSkipLevelOfDetail = false; /** @@ -1385,6 +1376,28 @@ Object.defineProperties(Cesium3DTileset.prototype, { }, }, + /** + * Whether this tileset is actually skipping levels of detail. + * The user option may have been disabled if all tiles are using additive refinement, + * or if some tiles have a content type for which rendering does not support skipping + * + * @memberof Cesium3DTileset.prototype + * + * @type {boolean} + * @private + * @readonly + */ + isSkippingLevelOfDetail: { + get: function () { + return ( + this.skipLevelOfDetail && + !defined(this._classificationType) && + !this._disableSkipLevelOfDetail && + !this._allTilesAdditive + ); + }, + }, + /** * The tileset's schema, groups, tileset metadata and other details from the * 3DTILES_metadata extension or a 3D Tiles 1.1 tileset JSON. This getter is @@ -2393,12 +2406,6 @@ Cesium3DTileset.prototype.prePassesUpdate = function (frameState) { 0.0 ); - this._skipLevelOfDetail = - this.skipLevelOfDetail && - !defined(this._classificationType) && - !this._disableSkipLevelOfDetail && - !this._allTilesAdditive; - if (this.dynamicScreenSpaceError) { updateDynamicScreenSpaceError(this, frameState); } @@ -2730,7 +2737,7 @@ function updateTiles(tileset, frameState, passOptions) { const selectedTiles = tileset._selectedTiles; const bivariateVisibilityTest = - tileset._skipLevelOfDetail && + tileset.isSkippingLevelOfDetail && tileset._hasMixedContent && context.stencilBuffer && selectedTiles.length > 0; @@ -3081,7 +3088,7 @@ Cesium3DTileset.prototype.getTraversal = function (passOptions) { ) { return Cesium3DTilesetMostDetailedTraversal; } - return this._skipLevelOfDetail + return this.isSkippingLevelOfDetail ? Cesium3DTilesetSkipTraversal : Cesium3DTilesetBaseTraversal; }; diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index da958787bf2..538363a1580 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -2430,10 +2430,6 @@ Model.prototype.hasSilhouette = function (frameState) { ); }; -function supportsSkipLevelOfDetail(frameState) { - return frameState.context.stencilBuffer; -} - /** * Gets whether or not the model is part of a tileset that uses the * skipLevelOfDetail optimization. This accounts for whether skipLevelOfDetail @@ -2448,8 +2444,9 @@ Model.prototype.hasSkipLevelOfDetail = function (frameState) { return false; } + const supportsSkipLevelOfDetail = frameState.context.stencilBuffer; const tileset = this._content.tileset; - return supportsSkipLevelOfDetail(frameState) && tileset._skipLevelOfDetail; + return supportsSkipLevelOfDetail && tileset.isSkippingLevelOfDetail; }; /** From 841b9612846d476a9c3001b2b94326a2f8f9fced Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 27 Mar 2023 17:49:09 -0400 Subject: [PATCH 582/679] Expose and document private property Cesium3DTileset.prototype.hasMixedContent --- .../Source/Scene/Cesium3DTileBatchTable.js | 2 +- .../engine/Source/Scene/Cesium3DTileset.js | 22 +++++++++++++++++++ .../Scene/Cesium3DTilesetBaseTraversal.js | 2 +- .../Cesium3DTilesetMostDetailedTraversal.js | 2 +- .../Scene/Cesium3DTilesetSkipTraversal.js | 4 ++-- .../Source/Scene/Model/ModelDrawCommand.js | 2 +- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js index 29517ea70a1..6631d6c1962 100644 --- a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js +++ b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js @@ -897,7 +897,7 @@ Cesium3DTileBatchTable.prototype.addDerivedCommands = function ( const tileset = tile.tileset; const bivariateVisibilityTest = tileset.isSkippingLevelOfDetail && - tileset._hasMixedContent && + tileset.hasMixedContent && frameState.context.stencilBuffer; const styleCommandsNeeded = getStyleCommandsNeeded(this); diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index dd3697e9e73..5a7c916fa4f 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -1376,6 +1376,28 @@ Object.defineProperties(Cesium3DTileset.prototype, { }, }, + /** + * Whether the tileset is rendering different levels of detail in the same view. + * Only relevant if {@link Cesium3DTileset.isSkippingLevelOfDetail} is true. + * + * @memberof Cesium3DTileset.prototype + * + * @type {boolean} + * @private + */ + hasMixedContent: { + get: function () { + return this._hasMixedContent; + }, + set: function (value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.bool(value); + //>>includeEnd('debug'); + + this._hasMixedContent = value; + }, + }, + /** * Whether this tileset is actually skipping levels of detail. * The user option may have been disabled if all tiles are using additive refinement, diff --git a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js index 8f5227e0106..a85ddcc4013 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetBaseTraversal.js @@ -42,7 +42,7 @@ Cesium3DTilesetBaseTraversal.selectTiles = function (tileset, frameState) { tileset._selectedTiles.length = 0; tileset._selectedTilesToStyle.length = 0; tileset._emptyTiles.length = 0; - tileset._hasMixedContent = false; + tileset.hasMixedContent = false; const root = tileset.root; Cesium3DTilesetTraversal.updateTile(root, frameState); diff --git a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js index 98b95009611..8645642a852 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js @@ -33,7 +33,7 @@ Cesium3DTilesetMostDetailedTraversal.selectTiles = function ( ) { tileset._selectedTiles.length = 0; tileset._requestedTiles.length = 0; - tileset._hasMixedContent = false; + tileset.hasMixedContent = false; let ready = true; diff --git a/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js index b4dbdc6b3ac..aea34eee3fc 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js +++ b/packages/engine/Source/Scene/Cesium3DTilesetSkipTraversal.js @@ -50,7 +50,7 @@ Cesium3DTilesetSkipTraversal.selectTiles = function (tileset, frameState) { tileset._selectedTiles.length = 0; tileset._selectedTilesToStyle.length = 0; tileset._emptyTiles.length = 0; - tileset._hasMixedContent = false; + tileset.hasMixedContent = false; const root = tileset.root; Cesium3DTilesetTraversal.updateTile(root, frameState); @@ -394,7 +394,7 @@ function traverseAndSelect(root, frameState) { } else { tile._selectionDepth = ancestorStack.length; if (tile._selectionDepth > 0) { - tile.tileset._hasMixedContent = true; + tile.tileset.hasMixedContent = true; } lastAncestor = tile; if (!traverse) { diff --git a/packages/engine/Source/Scene/Model/ModelDrawCommand.js b/packages/engine/Source/Scene/Model/ModelDrawCommand.js index d24adea9cf1..83323fc1ec7 100644 --- a/packages/engine/Source/Scene/Model/ModelDrawCommand.js +++ b/packages/engine/Source/Scene/Model/ModelDrawCommand.js @@ -532,7 +532,7 @@ ModelDrawCommand.prototype.pushCommands = function (frameState, result) { if (this._needsSkipLevelOfDetailCommands) { const { tileset, tile } = this._model.content; - if (tileset._hasMixedContent) { + if (tileset.hasMixedContent) { if (!tile._finalResolution) { pushCommand( tileset._backfaceCommands, From 9f59a400ebfc2f93bb9d6669899f93d356672bee Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 28 Mar 2023 12:59:28 -0400 Subject: [PATCH 583/679] Fix specs to use tileset.hasMixedContent accessor --- packages/engine/Specs/Scene/Cesium3DTilesetSpec.js | 12 ++++++------ .../engine/Specs/Scene/Model/ModelDrawCommandSpec.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js index 624d3b7a2f0..d0c1807dd03 100644 --- a/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js +++ b/packages/engine/Specs/Scene/Cesium3DTilesetSpec.js @@ -3827,12 +3827,12 @@ describe( const statistics = tileset._statistics; expect(statistics.numberOfTilesWithContentReady).toEqual(1); expect(tileset._selectedTiles[0]._selectionDepth).toEqual(0); - expect(tileset._hasMixedContent).toBe(false); + expect(tileset.hasMixedContent).toBe(false); return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( function (tileset) { expect(statistics.numberOfTilesWithContentReady).toEqual(5); - expect(tileset._hasMixedContent).toBe(false); + expect(tileset.hasMixedContent).toBe(false); } ); }); @@ -3853,7 +3853,7 @@ describe( scene.renderForSpecs(); - expect(tileset._hasMixedContent).toBe(true); + expect(tileset.hasMixedContent).toBe(true); expect(statistics.numberOfTilesWithContentReady).toEqual(2); expect( tileset.root.children[0].children[0].children[3]._selectionDepth @@ -3863,7 +3863,7 @@ describe( return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then( function (tileset) { expect(statistics.numberOfTilesWithContentReady).toEqual(5); - expect(tileset._hasMixedContent).toBe(false); + expect(tileset.hasMixedContent).toBe(false); } ); }); @@ -3914,7 +3914,7 @@ describe( expect(root.children[0].children[0].children[3]._finalResolution).toBe( true ); - expect(tileset._hasMixedContent).toBe(true); + expect(tileset.hasMixedContent).toBe(true); const commandList = scene.frameState.commandList; const rs = commandList[1].renderState; @@ -3958,7 +3958,7 @@ describe( expect( isSelected(tileset, root.children[0].children[0].children[3]) ).toBe(false); - expect(tileset._hasMixedContent).toBe(false); + expect(tileset.hasMixedContent).toBe(false); return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset); }); diff --git a/packages/engine/Specs/Scene/Model/ModelDrawCommandSpec.js b/packages/engine/Specs/Scene/Model/ModelDrawCommandSpec.js index 99a5fb9a7fe..6e86f1b0f1b 100644 --- a/packages/engine/Specs/Scene/Model/ModelDrawCommandSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelDrawCommandSpec.js @@ -88,7 +88,7 @@ describe( _projectTo2D: false, content: { tileset: { - _hasMixedContent: true, + hasMixedContent: true, _backfaceCommands: [], }, tile: { From 66d76da116354710120a16556bd1efb263d843f9 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 28 Mar 2023 13:18:52 -0400 Subject: [PATCH 584/679] Fix Check.typeOf signature in tileset.hasMixedContent --- packages/engine/Source/Scene/Cesium3DTileset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 5a7c916fa4f..601bfb2393a 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -1391,7 +1391,7 @@ Object.defineProperties(Cesium3DTileset.prototype, { }, set: function (value) { //>>includeStart('debug', pragmas.debug); - Check.typeOf.bool(value); + Check.typeOf.bool("value", value); //>>includeEnd('debug'); this._hasMixedContent = value; From dee5f0d18a6237e3d18067b69a1af9ee357dfee1 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 28 Mar 2023 13:40:22 -0400 Subject: [PATCH 585/679] Cleanup --- CHANGES.md | 2 +- .../Source/DataSources/ModelVisualizer.js | 95 ++++++------ packages/engine/Source/Scene/Cesium3DTile.js | 146 +++++++++--------- .../Source/Scene/Cesium3DTileContent.js | 2 +- .../engine/Source/Scene/Cesium3DTileset.js | 130 +++++++--------- .../Source/Scene/Composite3DTileContent.js | 30 ++-- .../Source/Scene/GltfBufferViewLoader.js | 103 ++++++------ .../engine/Source/Scene/GltfDracoLoader.js | 109 ++++++------- .../Source/Scene/GltfIndexBufferLoader.js | 9 +- packages/engine/Source/Scene/GltfLoader.js | 47 +++--- .../Scene/GltfStructuralMetadataLoader.js | 56 +++---- .../engine/Source/Scene/GltfTextureLoader.js | 69 +++++---- .../engine/Source/Scene/I3SDataProvider.js | 59 +++---- .../engine/Source/Scene/Model/ModelUtility.js | 6 +- .../Source/Scene/Multiple3DTileContent.js | 131 +++++++--------- .../Specs/Scene/Empty3DTileContentSpec.js | 1 - packages/engine/Specs/Scene/GltfLoaderSpec.js | 28 ---- .../Scene/GroundPolylinePrimitiveSpec.js | 47 +++--- .../engine/Specs/Scene/GroundPrimitiveSpec.js | 68 ++++---- .../Scene/Model/loadAndZoomToModelAsync.js | 45 +----- packages/widgets/Specs/Viewer/ViewerSpec.js | 8 +- 21 files changed, 566 insertions(+), 625 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7cdb5a5e191..4c935d4b0b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,7 +19,7 @@ try { ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `Cesium3DTileset.fromIonAssetId`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`, and `Model.texturesReadyEvent` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `Cesium3DTileset.fromIonAssetId`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`,`Model.texturesReadyEvent`, `I3SDataProvider.fromUrl`, and `Cesium3DTilesVoxelProvider.fromUrl` for better async flow and error handling. ##### Fixes :wrench: diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 337e8012822..1297ad74707 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -66,6 +66,52 @@ function ModelVisualizer(scene, entityCollection) { this._onCollectionChanged(entityCollection, entityCollection.values, [], []); } +async function createModelPrimitive( + visualizer, + entity, + resource, + incrementallyLoadTextures +) { + const primitives = visualizer._primitives; + const modelHash = visualizer._modelHash; + + try { + const model = await Model.fromGltfAsync({ + url: resource, + incrementallyLoadTextures: incrementallyLoadTextures, + scene: visualizer._scene, + }); + + if (visualizer.isDestroyed() || !defined(modelHash[entity.id])) { + return; + } + + model.id = entity; + primitives.add(model); + modelHash[entity.id].modelPrimitive = model; + model.errorEvent.addEventListener((error) => { + if (!defined(modelHash[entity.id])) { + return; + } + + console.log(error); + + // Texture failures when incrementallyLoadTextures + // will not affect the ability to compute the bounding sphere + if (error.name !== "TextureError" && model.incrementallyLoadTextures) { + modelHash[entity.id].loadFailed = true; + } + }); + } catch (error) { + if (visualizer.isDestroyed() || !defined(modelHash[entity.id])) { + return; + } + + console.log(error); + modelHash[entity.id].loadFailed = true; + } +} + /** * Updates models created this visualizer to match their * Entity counterpart at the given time. @@ -131,50 +177,13 @@ ModelVisualizer.prototype.update = function (time) { }; modelHash[entity.id] = modelData; - (async () => { - try { - const model = await Model.fromGltfAsync({ - url: resource, - incrementallyLoadTextures: Property.getValueOrDefault( - modelGraphics._incrementallyLoadTextures, - time, - defaultIncrementallyLoadTextures - ), - scene: this._scene, - }); - - if (this.isDestroyed() || !defined(modelHash[entity.id])) { - return; - } - - model.id = entity; - primitives.add(model); - modelHash[entity.id].modelPrimitive = model; - model.errorEvent.addEventListener((error) => { - if (!defined(modelHash[entity.id])) { - return; - } - - console.log(error); - - // Texture failures when incrementallyLoadTextures - // will not affect the ability to compute the bounding sphere - if ( - error.name !== "TextureError" && - model.incrementallyLoadTextures - ) { - modelHash[entity.id].loadFailed = true; - } - }); - } catch (error) { - if (this.isDestroyed() || !defined(modelHash[entity.id])) { - return; - } + const incrementallyLoadTextures = Property.getValueOrDefault( + modelGraphics._incrementallyLoadTextures, + time, + defaultIncrementallyLoadTextures + ); - console.log(error); - modelHash[entity.id].loadFailed = true; - } - })(); + createModelPrimitive(this, entity, resource, incrementallyLoadTextures); } const model = modelData.modelPrimitive; diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 30087fff82a..eb056f4d706 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -1105,7 +1105,7 @@ function requestMultipleContents(tile) { tile._contentState = Cesium3DTileContentState.LOADING; return promise - .then(async (content) => { + .then((content) => { if (tile.isDestroyed()) { // Tile is unloaded before the content can process return; @@ -1130,6 +1130,81 @@ function requestMultipleContents(tile) { }); } +async function processArrayBuffer( + tile, + tileset, + request, + expired, + requestPromise +) { + const previousState = tile._contentState; + tile._contentState = Cesium3DTileContentState.LOADING; + ++tileset.statistics.numberOfPendingRequests; + + let arrayBuffer; + try { + arrayBuffer = await requestPromise; + } catch (error) { + --tileset.statistics.numberOfPendingRequests; + if (tile.isDestroyed()) { + // Tile is unloaded before the content can process + return; + } + + if (request.cancelled || request.state === RequestState.CANCELLED) { + // Cancelled due to low priority - try again later. + tile._contentState = previousState; + ++tileset.statistics.numberOfAttemptedRequests; + return; + } + + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; + } + + if (tile.isDestroyed()) { + --tileset.statistics.numberOfPendingRequests; + // Tile is unloaded before the content can process + return; + } + + if (request.cancelled || request.state === RequestState.CANCELLED) { + // Cancelled due to low priority - try again later. + tile._contentState = previousState; + --tileset.statistics.numberOfPendingRequests; + ++tileset.statistics.numberOfAttemptedRequests; + return; + } + + try { + const content = await makeContent(tile, arrayBuffer); + --tileset.statistics.numberOfPendingRequests; + + if (tile.isDestroyed()) { + // Tile is unloaded before the content can process + return; + } + + if (expired) { + tile.expireDate = undefined; + } + + tile._content = content; + tile._contentState = Cesium3DTileContentState.PROCESSING; + + return content; + } catch (error) { + --tileset.statistics.numberOfPendingRequests; + if (tile.isDestroyed()) { + // Tile is unloaded before the content can process + return; + } + + tile._contentState = Cesium3DTileContentState.FAILED; + throw error; + } +} + /** * @private * @param {Cesium3DTile} tile @@ -1164,74 +1239,7 @@ function requestSingleContent(tile) { return; } - const previousState = tile._contentState; - tile._contentState = Cesium3DTileContentState.LOADING; - ++tileset.statistics.numberOfPendingRequests; - - return (async () => { - let arrayBuffer; - try { - arrayBuffer = await promise; - } catch (error) { - --tileset.statistics.numberOfPendingRequests; - if (tile.isDestroyed()) { - // Tile is unloaded before the content can process - return; - } - - if (request.cancelled || request.state === RequestState.CANCELLED) { - // Cancelled due to low priority - try again later. - tile._contentState = previousState; - ++tileset.statistics.numberOfAttemptedRequests; - return; - } - - tile._contentState = Cesium3DTileContentState.FAILED; - throw error; - } - - if (tile.isDestroyed()) { - --tileset.statistics.numberOfPendingRequests; - // Tile is unloaded before the content can process - return; - } - - if (request.cancelled || request.state === RequestState.CANCELLED) { - // Cancelled due to low priority - try again later. - tile._contentState = previousState; - --tileset.statistics.numberOfPendingRequests; - ++tileset.statistics.numberOfAttemptedRequests; - return; - } - - try { - const content = await makeContent(tile, arrayBuffer); - --tileset.statistics.numberOfPendingRequests; - - if (tile.isDestroyed()) { - // Tile is unloaded before the content can process - return; - } - - if (expired) { - tile.expireDate = undefined; - } - - tile._content = content; - tile._contentState = Cesium3DTileContentState.PROCESSING; - - return content; - } catch (error) { - --tileset.statistics.numberOfPendingRequests; - if (tile.isDestroyed()) { - // Tile is unloaded before the content can process - return; - } - - tile._contentState = Cesium3DTileContentState.FAILED; - throw error; - } - })(); + return processArrayBuffer(tile, tileset, request, expired, promise); } /** diff --git a/packages/engine/Source/Scene/Cesium3DTileContent.js b/packages/engine/Source/Scene/Cesium3DTileContent.js index 714cd0adc3e..ba6222f2866 100644 --- a/packages/engine/Source/Scene/Cesium3DTileContent.js +++ b/packages/engine/Source/Scene/Cesium3DTileContent.js @@ -161,7 +161,7 @@ Object.defineProperties(Cesium3DTileContent.prototype, { }, /** - * Returns true when the tile's content is ready to render; otherwise false + * Gets the promise that will be resolved when the tile's content is ready to render. * * @memberof Cesium3DTileContent.prototype * diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 0f34df03d51..7ddd6a3da9a 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -58,65 +58,65 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * * Initialization options for the Cesium3DTileset constructor * - * @property {Resource|string|Promise<Resource>|Promise<string>} [options.url] The url to a tileset JSON file. Deprecated. - * @property {boolean} [options.show=true] Determines if the tileset will be shown. - * @property {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. - * @property {Axis} [options.modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. - * @property {Axis} [options.modelForwardAxis=Axis.X] Which axis is considered forward when loading models for tile contents. - * @property {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from light sources. - * @property {number} [options.maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. - * @property {number} [options.maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. - * @property {boolean} [options.cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. - * @property {boolean} [options.cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. - * @property {number} [options.cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. - * @property {boolean} [options.preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. - * @property {boolean} [options.preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. - * @property {boolean} [options.preferLeaves=false] Optimization option. Prefer loading of leaves first. - * @property {boolean} [options.dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. - * @property {number} [options.dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. - * @property {number} [options.dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. - * @property {number} [options.dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. - * @property {number} [options.progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. - * @property {boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. - * @property {number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. - * @property {number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. - * @property {Cesium3DTileset.foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError} - * @property {number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. - * @property {boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. - * @property {number} [options.baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. - * @property {number} [options.skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. - * @property {number} [options.skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. - * @property {boolean} [options.immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. - * @property {boolean} [options.loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. - * @property {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. - * @property {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. - * @property {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. - * @property {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. - * @property {Cartesian3} [options.lightColor] The light color when shading models. When <code>undefined</code> the scene's light color is used instead. - * @property {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting for this tileset. - * @property {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. - * @property {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @property {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. - * @property {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. - * @property {boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. - * @property {boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. - * @property {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @property {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @property {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. - * @property {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset. - * @property {boolean} [options.projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. - * @property {string} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. - * @property {boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. - * @property {boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. - * @property {boolean} [options.enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. - * @property {boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. - * @property {boolean} [options.debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. - * @property {boolean} [options.debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. - * @property {boolean} [options.debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. - * @property {boolean} [options.debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. - * @property {boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. - * @property {boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. - * @property {boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. + * @property {Resource|string|Promise<Resource>|Promise<string>} [.url] The url to a tileset JSON file. Deprecated. + * @property {boolean} [show=true] Determines if the tileset will be shown. + * @property {Matrix4} [modelMatrix=Matrix4.IDENTITY] A 4x4 transformation matrix that transforms the tileset's root tile. + * @property {Axis} [modelUpAxis=Axis.Y] Which axis is considered up when loading models for tile contents. + * @property {Axis} [modelForwardAxis=Axis.X] Which axis is considered forward when loading models for tile contents. + * @property {ShadowMode} [shadows=ShadowMode.ENABLED] Determines whether the tileset casts or receives shadows from light sources. + * @property {number} [maximumScreenSpaceError=16] The maximum screen space error used to drive level of detail refinement. + * @property {number} [maximumMemoryUsage=512] The maximum amount of memory in MB that can be used by the tileset. + * @property {boolean} [cullWithChildrenBounds=true] Optimization option. Whether to cull tiles using the union of their children bounding volumes. + * @property {boolean} [cullRequestsWhileMoving=true] Optimization option. Don't request tiles that will likely be unused when they come back because of the camera's movement. This optimization only applies to stationary tilesets. + * @property {number} [cullRequestsWhileMovingMultiplier=60.0] Optimization option. Multiplier used in culling requests while moving. Larger is more aggressive culling, smaller less aggressive culling. + * @property {boolean} [preloadWhenHidden=false] Preload tiles when <code>tileset.show</code> is <code>false</code>. Loads tiles as if the tileset is visible but does not render them. + * @property {boolean} [preloadFlightDestinations=true] Optimization option. Preload tiles at the camera's flight destination while the camera is in flight. + * @property {boolean} [preferLeaves=false] Optimization option. Prefer loading of leaves first. + * @property {boolean} [dynamicScreenSpaceError=false] Optimization option. Reduce the screen space error for tiles that are further away from the camera. + * @property {number} [dynamicScreenSpaceErrorDensity=0.00278] Density used to adjust the dynamic screen space error, similar to fog density. + * @property {number} [dynamicScreenSpaceErrorFactor=4.0] A factor used to increase the computed dynamic screen space error. + * @property {number} [dynamicScreenSpaceErrorHeightFalloff=0.25] A ratio of the tileset's height at which the density starts to falloff. + * @property {number} [progressiveResolutionHeightFraction=0.3] Optimization option. If between (0.0, 0.5], tiles at or above the screen space error for the reduced screen resolution of <code>progressiveResolutionHeightFraction*screenHeight</code> will be prioritized first. This can help get a quick layer of tiles down while full resolution tiles continue to load. + * @property {boolean} [foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded. + * @property {number} [foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect. + * @property {number} [foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}. + * @property {Cesium3DTileset.foveatedInterpolationCallback} [foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError} + * @property {number} [foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view. + * @property {boolean} [skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal. + * @property {number} [baseScreenSpaceError=1024] When <code>skipLevelOfDetail</code> is <code>true</code>, the screen space error that must be reached before skipping levels of detail. + * @property {number} [skipScreenSpaceErrorFactor=16] When <code>skipLevelOfDetail</code> is <code>true</code>, a multiplier defining the minimum screen space error to skip. Used in conjunction with <code>skipLevels</code> to determine which tiles to load. + * @property {number} [skipLevels=1] When <code>skipLevelOfDetail</code> is <code>true</code>, a constant defining the minimum number of levels to skip when loading tiles. When it is 0, no levels are skipped. Used in conjunction with <code>skipScreenSpaceErrorFactor</code> to determine which tiles to load. + * @property {boolean} [immediatelyLoadDesiredLevelOfDetail=false] When <code>skipLevelOfDetail</code> is <code>true</code>, only tiles that meet the maximum screen space error will ever be downloaded. Skipping factors are ignored and just the desired tiles are loaded. + * @property {boolean} [loadSiblings=false] When <code>skipLevelOfDetail</code> is <code>true</code>, determines whether siblings of visible tiles are always downloaded during traversal. + * @property {ClippingPlaneCollection} [clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the tileset. + * @property {ClassificationType} [classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. + * @property {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. + * @property {object} [pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * @property {Cartesian3} [lightColor] The light color when shading models. When <code>undefined</code> the scene's light color is used instead. + * @property {ImageBasedLighting} [imageBasedLighting] The properties for managing image-based lighting for this tileset. + * @property {boolean} [backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. + * @property {boolean} [enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set to false to avoid the additional processing of geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @property {boolean} [showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @property {Color} [outlineColor=Color.BLACK] The color to use when rendering outlines. + * @property {boolean} [vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. + * @property {boolean} [vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}. + * @property {string|number} [featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @property {string|number} [instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @property {boolean} [showCreditsOnScreen=false] Whether to display the credits of this tileset on screen. + * @property {SplitDirection} [splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset. + * @property {boolean} [projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded. + * @property {string} [debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value. + * @property {boolean} [debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. + * @property {boolean} [debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. + * @property {boolean} [enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded. + * @property {boolean} [debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. + * @property {boolean} [debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile. + * @property {boolean} [debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content. + * @property {boolean} [debugShowViewerRequestVolume=false] For debugging only. When true, renders the viewer request volume for each tile. + * @property {boolean} [debugShowGeometricError=false] For debugging only. When true, draws labels to indicate the geometric error of each tile. + * @property {boolean} [debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile. + * @property {boolean} [debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile. + * @property {boolean} [debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile. */ /** @@ -2620,16 +2620,6 @@ function handleTileFailure(error, tileset, tile) { } } -/** - * @private - * @param {Cesium3DTileset} tileset - * @param {Cesium3DTile} tile - * @returns {Function} - */ -function handleTileSuccess(tileset, tile) { - tileset.tileLoad.raiseEvent(tile); -} - /** * @private * @param {Cesium3DTileset} tileset @@ -2672,7 +2662,7 @@ function processTiles(tileset, frameState) { if (tile.contentReady) { --statistics.numberOfTilesProcessing; - handleTileSuccess(tileset, tile, tile.content); + tileset.tileLoad.raiseEvent(tile); } } catch (error) { --statistics.numberOfTilesProcessing; diff --git a/packages/engine/Source/Scene/Composite3DTileContent.js b/packages/engine/Source/Scene/Composite3DTileContent.js index 0c224a38cfa..e61d10e819a 100644 --- a/packages/engine/Source/Scene/Composite3DTileContent.js +++ b/packages/engine/Source/Scene/Composite3DTileContent.js @@ -17,11 +17,15 @@ import RuntimeError from "../Core/RuntimeError.js"; * * @private */ -function Composite3DTileContent(tileset, tile, resource) { +function Composite3DTileContent(tileset, tile, resource, contents) { this._tileset = tileset; this._tile = tile; this._resource = resource; - this._contents = []; + + if (!defined(contents)) { + contents = []; + } + this._contents = contents; this._metadata = undefined; this._group = undefined; @@ -230,8 +234,6 @@ Composite3DTileContent.fromTileType = async function ( const tilesLength = view.getUint32(byteOffset, true); byteOffset += sizeOfUint32; - const content = new Composite3DTileContent(tileset, tile, resource); - // For caching purposes, models within the composite tile must be // distinguished. To do this, add a query parameter ?compositeIndex=i. // Since composite tiles may contain other composite tiles, check for an @@ -246,6 +248,8 @@ Composite3DTileContent.fromTileType = async function ( prefix = ""; } + const promises = []; + promises.length = tilesLength; for (let i = 0; i < tilesLength; ++i) { const tileType = getMagic(uint8Array, byteOffset); @@ -263,16 +267,9 @@ Composite3DTileContent.fromTileType = async function ( }); if (defined(contentFactory)) { - const innerContent = await Promise.resolve( - contentFactory( - content._tileset, - content._tile, - childResource, - arrayBuffer, - byteOffset - ) + promises[i] = Promise.resolve( + contentFactory(tileset, tile, childResource, arrayBuffer, byteOffset) ); - content._contents.push(innerContent); } else { throw new RuntimeError( `Unknown tile content type, ${tileType}, inside Composite tile` @@ -282,6 +279,13 @@ Composite3DTileContent.fromTileType = async function ( byteOffset += tileByteLength; } + const innerContents = await Promise.all(promises); + const content = new Composite3DTileContent( + tileset, + tile, + resource, + innerContents + ); return content; }; diff --git a/packages/engine/Source/Scene/GltfBufferViewLoader.js b/packages/engine/Source/Scene/GltfBufferViewLoader.js index a0bb01d6d37..714d3166bae 100644 --- a/packages/engine/Source/Scene/GltfBufferViewLoader.js +++ b/packages/engine/Source/Scene/GltfBufferViewLoader.js @@ -125,6 +125,56 @@ Object.defineProperties(GltfBufferViewLoader.prototype, { }, }); +async function loadResources(loader) { + try { + const bufferLoader = getBufferLoader(loader); + loader._bufferLoader = bufferLoader; + await bufferLoader.load(); + + if (loader.isDestroyed()) { + return; + } + + const bufferTypedArray = bufferLoader.typedArray; + const bufferViewTypedArray = new Uint8Array( + bufferTypedArray.buffer, + bufferTypedArray.byteOffset + loader._byteOffset, + loader._byteLength + ); + + // Unload the buffer + loader.unload(); + + loader._typedArray = bufferViewTypedArray; + if (loader._hasMeshopt) { + const count = loader._meshoptCount; + const byteStride = loader._meshoptByteStride; + const result = new Uint8Array(count * byteStride); + MeshoptDecoder.decodeGltfBuffer( + result, + count, + byteStride, + loader._typedArray, + loader._meshoptMode, + loader._meshoptFilter + ); + loader._typedArray = result; + } + + loader._state = ResourceLoaderState.READY; + return loader; + } catch (error) { + if (loader.isDestroyed()) { + return; + } + + loader.unload(); + loader._state = ResourceLoaderState.FAILED; + const errorMessage = "Failed to load buffer view"; + throw loader.getError(errorMessage, error); + } +} + /** * Loads the resource. * @returns {Promise<GltfBufferViewLoader>} A promise which resolves to the loader when the resource loading is completed. @@ -135,57 +185,8 @@ GltfBufferViewLoader.prototype.load = async function () { return this._promise; } - this._promise = (async () => { - this._state = ResourceLoaderState.LOADING; - try { - const bufferLoader = getBufferLoader(this); - this._bufferLoader = bufferLoader; - await bufferLoader.load(); - - if (this.isDestroyed()) { - return; - } - - const bufferTypedArray = bufferLoader.typedArray; - const bufferViewTypedArray = new Uint8Array( - bufferTypedArray.buffer, - bufferTypedArray.byteOffset + this._byteOffset, - this._byteLength - ); - - // Unload the buffer - this.unload(); - - this._typedArray = bufferViewTypedArray; - if (this._hasMeshopt) { - const count = this._meshoptCount; - const byteStride = this._meshoptByteStride; - const result = new Uint8Array(count * byteStride); - MeshoptDecoder.decodeGltfBuffer( - result, - count, - byteStride, - this._typedArray, - this._meshoptMode, - this._meshoptFilter - ); - this._typedArray = result; - } - - this._state = ResourceLoaderState.READY; - return this; - } catch (error) { - if (this.isDestroyed()) { - return; - } - - this.unload(); - this._state = ResourceLoaderState.FAILED; - const errorMessage = "Failed to load buffer view"; - throw this.getError(errorMessage, error); - } - })(); - + this._state = ResourceLoaderState.LOADING; + this._promise = loadResources(this); return this._promise; }; diff --git a/packages/engine/Source/Scene/GltfDracoLoader.js b/packages/engine/Source/Scene/GltfDracoLoader.js index 18648d869fc..a1902e0ba84 100644 --- a/packages/engine/Source/Scene/GltfDracoLoader.js +++ b/packages/engine/Source/Scene/GltfDracoLoader.js @@ -93,6 +93,34 @@ Object.defineProperties(GltfDracoLoader.prototype, { }, }); +async function loadResources(loader) { + const resourceCache = loader._resourceCache; + try { + const bufferViewLoader = resourceCache.getBufferViewLoader({ + gltf: loader._gltf, + bufferViewId: loader._draco.bufferView, + gltfResource: loader._gltfResource, + baseResource: loader._baseResource, + }); + loader._bufferViewLoader = bufferViewLoader; + await bufferViewLoader.load(); + + if (loader.isDestroyed()) { + return; + } + + loader._bufferViewTypedArray = bufferViewLoader.typedArray; + loader._state = ResourceLoaderState.PROCESSING; + return loader; + } catch (error) { + if (loader.isDestroyed()) { + return; + } + + handleError(loader, error); + } +} + /** * Loads the resource. * @returns {Promise<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. @@ -104,34 +132,7 @@ GltfDracoLoader.prototype.load = async function () { } this._state = ResourceLoaderState.LOADING; - const resourceCache = this._resourceCache; - this._promise = (async () => { - try { - const bufferViewLoader = resourceCache.getBufferViewLoader({ - gltf: this._gltf, - bufferViewId: this._draco.bufferView, - gltfResource: this._gltfResource, - baseResource: this._baseResource, - }); - this._bufferViewLoader = bufferViewLoader; - await bufferViewLoader.load(); - - if (this.isDestroyed()) { - return; - } - - this._bufferViewTypedArray = bufferViewLoader.typedArray; - this._state = ResourceLoaderState.PROCESSING; - return this; - } catch (error) { - if (this.isDestroyed()) { - return; - } - - handleError(this, error); - } - })(); - + this._promise = loadResources(this); return this._promise; }; @@ -142,6 +143,32 @@ function handleError(dracoLoader, error) { throw dracoLoader.getError(errorMessage, error); } +async function processDecode(loader, decodePromise) { + try { + const results = await decodePromise; + if (loader.isDestroyed()) { + return; + } + + // Unload everything except the decoded data + loader.unload(); + + loader._decodedData = { + indices: results.indexArray, + vertexAttributes: results.attributeData, + }; + loader._state = ResourceLoaderState.READY; + return loader._baseResource; + } catch (error) { + if (loader.isDestroyed()) { + return; + } + + // Capture this error so it can be thrown on the next `process` call + loader._dracoError = error; + } +} + /** * Processes the resource until it becomes ready. * @@ -200,31 +227,7 @@ GltfDracoLoader.prototype.process = function (frameState) { return false; } - this._decodePromise = (async () => { - try { - const results = await decodePromise; - if (this.isDestroyed()) { - return; - } - - // Unload everything except the decoded data - this.unload(); - - this._decodedData = { - indices: results.indexArray, - vertexAttributes: results.attributeData, - }; - this._state = ResourceLoaderState.READY; - return this._baseResource; - } catch (error) { - if (this.isDestroyed()) { - return; - } - - // Capture this error so it can be thrown on the next `process` call - this._dracoError = error; - } - })(); + this._decodePromise = processDecode(this, decodePromise); }; /** diff --git a/packages/engine/Source/Scene/GltfIndexBufferLoader.js b/packages/engine/Source/Scene/GltfIndexBufferLoader.js index ca6ace4e053..de52c841209 100644 --- a/packages/engine/Source/Scene/GltfIndexBufferLoader.js +++ b/packages/engine/Source/Scene/GltfIndexBufferLoader.js @@ -335,18 +335,19 @@ GltfIndexBufferLoader.prototype.process = function (frameState) { return false; } - const typedArray = this._typedArray; - const indexDatatype = this._indexDatatype; + let typedArray = this._typedArray; + let indexDatatype = this._indexDatatype; if (defined(this._dracoLoader)) { try { const ready = this._dracoLoader.process(frameState); if (ready) { const dracoLoader = this._dracoLoader; - const typedArray = dracoLoader.decodedData.indices.typedArray; + typedArray = dracoLoader.decodedData.indices.typedArray; this._typedArray = typedArray; // The index datatype may be a smaller datatype after draco decode - this._indexDatatype = ComponentDatatype.fromTypedArray(typedArray); + indexDatatype = ComponentDatatype.fromTypedArray(typedArray); + this._indexDatatype = indexDatatype; } } catch (error) { handleError(this, error); diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index f2aa0cc0ae9..7d31ff1f09d 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -268,7 +268,7 @@ function GltfLoader(options) { this._loaderPromises = []; this._textureLoaders = []; this._texturesPromises = []; - this._textureCallbacks = {}; + this._textureCallbacks = []; this._bufferViewLoaders = []; this._geometryLoaders = []; this._geometryCallbacks = []; @@ -849,6 +849,26 @@ function loadAccessorValues(accessor, typedArray, values, useQuaternion) { return values; } +async function loadAccessorBufferView( + loader, + bufferViewLoader, + gltf, + accessor, + useQuaternion, + values +) { + await bufferViewLoader.load(); + if (loader.isDestroyed()) { + return; + } + + const bufferViewTypedArray = bufferViewLoader.typedArray; + const typedArray = getPackedTypedArray(gltf, accessor, bufferViewTypedArray); + + useQuaternion = defaultValue(useQuaternion, false); + loadAccessorValues(accessor, typedArray, values, useQuaternion); +} + function loadAccessor(loader, gltf, accessorId, useQuaternion) { const accessor = gltf.accessors[accessorId]; const accessorCount = accessor.count; @@ -857,23 +877,14 @@ function loadAccessor(loader, gltf, accessorId, useQuaternion) { const bufferViewId = accessor.bufferView; if (defined(bufferViewId)) { const bufferViewLoader = getBufferViewLoader(loader, gltf, bufferViewId); - const promise = (async () => { - await bufferViewLoader.load(); - if (loader.isDestroyed()) { - return; - } - - const bufferViewTypedArray = bufferViewLoader.typedArray; - const typedArray = getPackedTypedArray( - gltf, - accessor, - bufferViewTypedArray - ); - - useQuaternion = defaultValue(useQuaternion, false); - loadAccessorValues(accessor, typedArray, values, useQuaternion); - })(); - + const promise = loadAccessorBufferView( + loader, + bufferViewLoader, + gltf, + accessor, + useQuaternion, + values + ); loader._loaderPromises.push(promise); return values; diff --git a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js index ee10c33b4b7..7bd6129a086 100644 --- a/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js +++ b/packages/engine/Source/Scene/GltfStructuralMetadataLoader.js @@ -115,6 +115,34 @@ Object.defineProperties(GltfStructuralMetadataLoader.prototype, { }, }); +async function loadResources(loader) { + try { + const bufferViewsPromise = loadBufferViews(loader); + const texturesPromise = loadTextures(loader); + const schemaPromise = loadSchema(loader); + + await Promise.all([bufferViewsPromise, texturesPromise, schemaPromise]); + + if (loader.isDestroyed()) { + return; + } + + loader._gltf = undefined; // No longer need to hold onto the glTF + + loader._state = ResourceLoaderState.LOADED; + return loader; + } catch (error) { + if (loader.isDestroyed()) { + return; + } + + loader.unload(); + loader._state = ResourceLoaderState.FAILED; + const errorMessage = "Failed to load structural metadata"; + throw loader.getError(errorMessage, error); + } +} + /** * Loads the resource. * @returns {Promise<GltfStructuralMetadataLoader>} A promise which resolves to the loader when the resource loading is completed. @@ -126,33 +154,7 @@ GltfStructuralMetadataLoader.prototype.load = function () { } this._state = ResourceLoaderState.LOADING; - this._promise = (async () => { - try { - const bufferViewsPromise = loadBufferViews(this); - const texturesPromise = loadTextures(this); - const schemaPromise = loadSchema(this); - - await Promise.all([bufferViewsPromise, texturesPromise, schemaPromise]); - - if (this.isDestroyed()) { - return; - } - - this._gltf = undefined; // No longer need to hold onto the glTF - - this._state = ResourceLoaderState.LOADED; - return this; - } catch (error) { - if (this.isDestroyed()) { - return; - } - - this.unload(); - this._state = ResourceLoaderState.FAILED; - const errorMessage = "Failed to load structural metadata"; - throw this.getError(errorMessage, error); - } - })(); + this._promise = loadResources(this); return this._promise; }; diff --git a/packages/engine/Source/Scene/GltfTextureLoader.js b/packages/engine/Source/Scene/GltfTextureLoader.js index 277c077bb42..ce02ace4495 100644 --- a/packages/engine/Source/Scene/GltfTextureLoader.js +++ b/packages/engine/Source/Scene/GltfTextureLoader.js @@ -118,6 +118,40 @@ Object.defineProperties(GltfTextureLoader.prototype, { const scratchTextureJob = new CreateTextureJob(); +async function loadResources(loader) { + const resourceCache = loader._resourceCache; + try { + const imageLoader = resourceCache.getImageLoader({ + gltf: loader._gltf, + imageId: loader._imageId, + gltfResource: loader._gltfResource, + baseResource: loader._baseResource, + }); + loader._imageLoader = imageLoader; + await imageLoader.load(); + + if (loader.isDestroyed()) { + return; + } + + // Now wait for process() to run to finish loading + loader._image = imageLoader.image; + loader._mipLevels = imageLoader.mipLevels; + loader._state = ResourceLoaderState.LOADED; + + return loader; + } catch (error) { + if (loader.isDestroyed()) { + return; + } + + loader.unload(); + loader._state = ResourceLoaderState.FAILED; + const errorMessage = "Failed to load texture"; + throw loader.getError(errorMessage, error); + } +} + /** * Loads the resource. * @returns {Promise<GltfDracoLoader>} A promise which resolves to the loader when the resource loading is completed. @@ -129,40 +163,7 @@ GltfTextureLoader.prototype.load = async function () { } this._state = ResourceLoaderState.LOADING; - const resourceCache = this._resourceCache; - this._promise = (async () => { - try { - const imageLoader = resourceCache.getImageLoader({ - gltf: this._gltf, - imageId: this._imageId, - gltfResource: this._gltfResource, - baseResource: this._baseResource, - }); - this._imageLoader = imageLoader; - await imageLoader.load(); - - if (this.isDestroyed()) { - return; - } - - // Now wait for process() to run to finish loading - this._image = imageLoader.image; - this._mipLevels = imageLoader.mipLevels; - this._state = ResourceLoaderState.LOADED; - - return this; - } catch (error) { - if (this.isDestroyed()) { - return; - } - - this.unload(); - this._state = ResourceLoaderState.FAILED; - const errorMessage = "Failed to load texture"; - throw this.getError(errorMessage, error); - } - })(); - + this._promise = loadResources(this); return this._promise; }; diff --git a/packages/engine/Source/Scene/I3SDataProvider.js b/packages/engine/Source/Scene/I3SDataProvider.js index d284e00bf5c..5b1d4527348 100644 --- a/packages/engine/Source/Scene/I3SDataProvider.js +++ b/packages/engine/Source/Scene/I3SDataProvider.js @@ -67,12 +67,12 @@ import Rectangle from "../Core/Rectangle.js"; * * Initialization options for the I3SDataProvider constructor * - * @property {Resource|string} [options.url] The url of the I3S dataset. Deprecated. - * @property {string} [options.name] The name of the I3S dataset. - * @property {boolean} [options.show=true] Determines if the dataset will be shown. - * @property {ArcGISTiledElevationTerrainProvider|Promise<ArcGISTiledElevationTerrainProvider>} [options.geoidTiledTerrainProvider] Tiled elevation provider describing an Earth Gravitational Model. If defined, geometry will be shifted based on the offsets given by this provider. Required to position I3S data sets with gravity-related height at the correct location. - * @property {boolean} [options.traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. - * @property {Cesium3DTileset.ConstructorOptions} [options.cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. + * @property {Resource|string} [url] The url of the I3S dataset. Deprecated. + * @property {string} [name] The name of the I3S dataset. + * @property {boolean} [show=true] Determines if the dataset will be shown. + * @property {ArcGISTiledElevationTerrainProvider|Promise<ArcGISTiledElevationTerrainProvider>} [geoidTiledTerrainProvider] Tiled elevation provider describing an Earth Gravitational Model. If defined, geometry will be shifted based on the offsets given by this provider. Required to position I3S data sets with gravity-related height at the correct location. + * @property {boolean} [traceFetches=false] Debug option. When true, log a message whenever an I3S tile is fetched. + * @property {Cesium3DTileset.ConstructorOptions} [cesium3dTilesetOptions] Object containing options to pass to an internally created {@link Cesium3DTileset}. See {@link Cesium3DTileset} for list of valid properties. All options can be used with the exception of <code>url</code> and <code>show</code> which are overridden by values from I3SDataProvider. */ /** @@ -710,6 +710,30 @@ function getTiles(terrainProvider, extent) { }); } +async function loadGeoidData(provider) { + // Load tiles from arcgis + const geoidTerrainProvider = provider._geoidTiledTerrainProvider; + + if (!defined(geoidTerrainProvider)) { + console.log( + "No Geoid Terrain service provided - no geoid conversion will be performed." + ); + return; + } + + try { + const heightMaps = await getCoveredTiles( + geoidTerrainProvider, + provider._extent + ); + provider._geoidDataList = heightMaps; + } catch (error) { + console.log( + "Error retrieving Geoid Terrain tiles - no geoid conversion will be performed." + ); + } +} + /** * @private */ @@ -717,29 +741,8 @@ I3SDataProvider.prototype.loadGeoidData = async function () { if (defined(this._geoidDataPromise)) { return this._geoidDataPromise; } - this._geoidDataPromise = (async () => { - // Load tiles from arcgis - const geoidTerrainProvider = this._geoidTiledTerrainProvider; - - if (!defined(geoidTerrainProvider)) { - console.log( - "No Geoid Terrain service provided - no geoid conversion will be performed." - ); - return; - } - try { - const heightMaps = await getCoveredTiles( - geoidTerrainProvider, - this._extent - ); - this._geoidDataList = heightMaps; - } catch (error) { - console.log( - "Error retrieving Geoid Terrain tiles - no geoid conversion will be performed." - ); - } - })(); + this._geoidDataPromise = loadGeoidData(this); return this._geoidDataPromise; }; diff --git a/packages/engine/Source/Scene/Model/ModelUtility.js b/packages/engine/Source/Scene/Model/ModelUtility.js index af90b10e490..877be6bdb24 100644 --- a/packages/engine/Source/Scene/Model/ModelUtility.js +++ b/packages/engine/Source/Scene/Model/ModelUtility.js @@ -369,13 +369,9 @@ ModelUtility.supportedExtensions = { * supported. If an unsupported extension is found, this throws * a {@link RuntimeError} with the extension name. * -<<<<<<< HEAD - * @param {Array<String>} extensionsRequired The extensionsRequired array in the glTF. + * @param {string[]} extensionsRequired The extensionsRequired array in the glTF. * * @exception {RuntimeError} Unsupported glTF Extension -======= - * @param {string[]} extensionsRequired The extensionsRequired array in the glTF. ->>>>>>> no-ready-promises */ ModelUtility.checkSupportedExtensions = function (extensionsRequired) { const length = extensionsRequired.length; diff --git a/packages/engine/Source/Scene/Multiple3DTileContent.js b/packages/engine/Source/Scene/Multiple3DTileContent.js index c5ebb7e8a81..65578e43444 100644 --- a/packages/engine/Source/Scene/Multiple3DTileContent.js +++ b/packages/engine/Source/Scene/Multiple3DTileContent.js @@ -485,32 +485,11 @@ async function createInnerContents(multipleContents) { return; } - const createPromise = async (arrayBuffer, i) => { - if (!defined(arrayBuffer)) { - // Content was not fetched. The error was handled in - // the fetch promise. Return undefined to indicate partial failure. - return; - } - - try { - const contents = await createInnerContent( - multipleContents, - arrayBuffer, - i - ); - return contents; - } catch (error) { - handleInnerContentFailed(multipleContents, i, error); - } - }; - - const promises = []; - for (let i = 0; i < arrayBuffers.length; ++i) { - const arrayBuffer = arrayBuffers[i]; - promises.push(createPromise(arrayBuffer, i)); - } + const promises = arrayBuffers.map((arrayBuffer, i) => + createInnerContent(multipleContents, arrayBuffer, i) + ); - // Even if we had a partial success, mark that we finished creating + // Even if we had a partial success (in which case the inner promise will be handled, but the content will nit be returned), mark that we finished creating // contents const contents = await Promise.all(promises); multipleContents._contentsCreated = true; @@ -519,59 +498,69 @@ async function createInnerContents(multipleContents) { } async function createInnerContent(multipleContents, arrayBuffer, index) { - const preprocessed = preprocess3DTileContent(arrayBuffer); - - if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) { - throw new RuntimeError( - "External tilesets are disallowed inside multiple contents" - ); + if (!defined(arrayBuffer)) { + // Content was not fetched. The error was handled in + // the fetch promise. Return undefined to indicate partial failure. + return; } - multipleContents._disableSkipLevelOfDetail = - multipleContents._disableSkipLevelOfDetail || - preprocessed.contentType === Cesium3DTileContentType.GEOMETRY || - preprocessed.contentType === Cesium3DTileContentType.VECTOR; + try { + const preprocessed = preprocess3DTileContent(arrayBuffer); - const tileset = multipleContents._tileset; - const resource = multipleContents._innerContentResources[index]; - const tile = multipleContents._tile; - - let content; - const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType]; - if (defined(preprocessed.binaryPayload)) { - content = await Promise.resolve( - contentFactory( - tileset, - tile, - resource, - preprocessed.binaryPayload.buffer, - 0 - ) - ); - } else { - // JSON formats - content = await Promise.resolve( - contentFactory(tileset, tile, resource, preprocessed.jsonPayload) - ); - } + if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) { + throw new RuntimeError( + "External tilesets are disallowed inside multiple contents" + ); + } - const contentHeader = multipleContents._innerContentHeaders[index]; + multipleContents._disableSkipLevelOfDetail = + multipleContents._disableSkipLevelOfDetail || + preprocessed.contentType === Cesium3DTileContentType.GEOMETRY || + preprocessed.contentType === Cesium3DTileContentType.VECTOR; + + const tileset = multipleContents._tileset; + const resource = multipleContents._innerContentResources[index]; + const tile = multipleContents._tile; + + let content; + const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType]; + if (defined(preprocessed.binaryPayload)) { + content = await Promise.resolve( + contentFactory( + tileset, + tile, + resource, + preprocessed.binaryPayload.buffer, + 0 + ) + ); + } else { + // JSON formats + content = await Promise.resolve( + contentFactory(tileset, tile, resource, preprocessed.jsonPayload) + ); + } - if (tile.hasImplicitContentMetadata) { - const subtree = tile.implicitSubtree; - const coordinates = tile.implicitCoordinates; - content.metadata = subtree.getContentMetadataView(coordinates, index); - } else if (!tile.hasImplicitContent) { - content.metadata = findContentMetadata(tileset, contentHeader); - } + const contentHeader = multipleContents._innerContentHeaders[index]; - const groupMetadata = findGroupMetadata(tileset, contentHeader); - if (defined(groupMetadata)) { - content.group = new Cesium3DContentGroup({ - metadata: groupMetadata, - }); + if (tile.hasImplicitContentMetadata) { + const subtree = tile.implicitSubtree; + const coordinates = tile.implicitCoordinates; + content.metadata = subtree.getContentMetadataView(coordinates, index); + } else if (!tile.hasImplicitContent) { + content.metadata = findContentMetadata(tileset, contentHeader); + } + + const groupMetadata = findGroupMetadata(tileset, contentHeader); + if (defined(groupMetadata)) { + content.group = new Cesium3DContentGroup({ + metadata: groupMetadata, + }); + } + return content; + } catch (error) { + handleInnerContentFailed(multipleContents, index, error); } - return content; } function handleInnerContentFailed(multipleContents, index, error) { diff --git a/packages/engine/Specs/Scene/Empty3DTileContentSpec.js b/packages/engine/Specs/Scene/Empty3DTileContentSpec.js index e20fa68da1d..9cb79921e44 100644 --- a/packages/engine/Specs/Scene/Empty3DTileContentSpec.js +++ b/packages/engine/Specs/Scene/Empty3DTileContentSpec.js @@ -19,7 +19,6 @@ describe("Scene/Empty3DTileContent", function () { expect(content.texturesByteLength).toBe(0); expect(content.batchTableByteLength).toBe(0); expect(content.innerContents).toBeUndefined(); - expect(content.readyPromise).toBeUndefined(); expect(content.tileset).toBe(mockTileset); expect(content.tile).toBe(mockTile); expect(content.url).toBeUndefined(); diff --git a/packages/engine/Specs/Scene/GltfLoaderSpec.js b/packages/engine/Specs/Scene/GltfLoaderSpec.js index 8b868906184..53c2d9c2dbd 100644 --- a/packages/engine/Specs/Scene/GltfLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfLoaderSpec.js @@ -176,34 +176,6 @@ describe( ); }); - // This cannot actually ever happen due to gltfPipeline's updateVersion - xit("load throws if the gltf specifies an unknown version", async function () { - spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( - Promise.resolve( - generateJsonBuffer({ - asset: { - version: "3.0", - }, - }).buffer - ) - ); - - const gltfResource = new Resource({ - url: "https://example.com/model.glb", - }); - - const gltfLoader = new GltfLoader({ - gltfResource: gltfResource, - releaseGltfJson: true, - }); - gltfLoaders.push(gltfLoader); - - await expectAsync(gltfLoader.load()).toBeRejectedWithError( - RuntimeError, - "Failed to load glTF\nUnsupported glTF version: 0.1" - ); - }); - it("load throws if an unsupported extension is required", async function () { function modifyGltf(gltf) { gltf.extensionsRequired = ["NOT_supported_extension"]; diff --git a/packages/engine/Specs/Scene/GroundPolylinePrimitiveSpec.js b/packages/engine/Specs/Scene/GroundPolylinePrimitiveSpec.js index 6ea779e687c..ef37af8f385 100644 --- a/packages/engine/Specs/Scene/GroundPolylinePrimitiveSpec.js +++ b/packages/engine/Specs/Scene/GroundPolylinePrimitiveSpec.js @@ -202,7 +202,7 @@ describe( expect(groundPolylinePrimitive.debugShowShadowVolume).toEqual(true); }); - it("releases geometry instances when releaseGeometryInstances is true", function () { + it("releases geometry instances when releaseGeometryInstances is true", async function () { if (!GroundPolylinePrimitive.isSupported(scene)) { return; } @@ -215,13 +215,16 @@ describe( expect(groundPolylinePrimitive.geometryInstances).toBeDefined(); scene.groundPrimitives.add(groundPolylinePrimitive); - scene.renderForSpecs(); - return groundPolylinePrimitive.readyPromise.then(function () { - expect(groundPolylinePrimitive.geometryInstances).not.toBeDefined(); + + await pollToPromise(() => { + scene.renderForSpecs(); + return groundPolylinePrimitive.ready; }); + + expect(groundPolylinePrimitive.geometryInstances).not.toBeDefined(); }); - it("does not release geometry instances when releaseGeometryInstances is false", function () { + it("does not release geometry instances when releaseGeometryInstances is false", async function () { if (!GroundPolylinePrimitive.isSupported(scene)) { return; } @@ -234,13 +237,15 @@ describe( expect(groundPolylinePrimitive.geometryInstances).toBeDefined(); scene.groundPrimitives.add(groundPolylinePrimitive); - scene.renderForSpecs(); - return groundPolylinePrimitive.readyPromise.then(function () { - expect(groundPolylinePrimitive.geometryInstances).toBeDefined(); + await pollToPromise(() => { + scene.renderForSpecs(); + return groundPolylinePrimitive.ready; }); + + expect(groundPolylinePrimitive.geometryInstances).toBeDefined(); }); - it("adds afterRender promise to frame state", function () { + it("becomes ready", async function () { if (!GroundPolylinePrimitive.isSupported(scene)) { return; } @@ -252,11 +257,12 @@ describe( }); scene.groundPrimitives.add(groundPolylinePrimitive); - scene.renderForSpecs(); - - return groundPolylinePrimitive.readyPromise.then(function (param) { - expect(param.ready).toBe(true); + await pollToPromise(() => { + scene.renderForSpecs(); + return groundPolylinePrimitive.ready; }); + + expect(groundPolylinePrimitive.ready).toBe(true); }); it("does not render when geometryInstances is undefined", function () { @@ -293,7 +299,7 @@ describe( expect(scene.frameState.commandList.length).toEqual(0); }); - it("becomes ready when show is false", function () { + it("becomes ready when show is false", async function () { if (!GroundPolylinePrimitive.isSupported(scene)) { return; } @@ -305,17 +311,12 @@ describe( ); groundPolylinePrimitive.show = false; - let ready = false; - groundPolylinePrimitive.readyPromise.then(function () { - ready = true; - }); - - return pollToPromise(function () { + await pollToPromise(() => { scene.renderForSpecs(); - return ready; - }).then(function () { - expect(ready).toEqual(true); + return groundPolylinePrimitive.ready; }); + + expect(groundPolylinePrimitive.ready).toBeTrue(); }); it("does not render other than for the color or pick pass", function () { diff --git a/packages/engine/Specs/Scene/GroundPrimitiveSpec.js b/packages/engine/Specs/Scene/GroundPrimitiveSpec.js index 18d1b30ad38..20a453354b2 100644 --- a/packages/engine/Specs/Scene/GroundPrimitiveSpec.js +++ b/packages/engine/Specs/Scene/GroundPrimitiveSpec.js @@ -229,7 +229,7 @@ describe( expect(primitive.debugShowShadowVolume).toEqual(true); }); - it("releases geometry instances when releaseGeometryInstances is true", function () { + it("releases geometry instances when releaseGeometryInstances is true", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -242,13 +242,15 @@ describe( expect(primitive.geometryInstances).toBeDefined(); scene.groundPrimitives.add(primitive); - scene.renderForSpecs(); - return primitive.readyPromise.then(function () { - expect(primitive.geometryInstances).not.toBeDefined(); + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; }); + + expect(primitive.geometryInstances).not.toBeDefined(); }); - it("does not release geometry instances when releaseGeometryInstances is false", function () { + it("does not release geometry instances when releaseGeometryInstances is false", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -261,13 +263,15 @@ describe( expect(primitive.geometryInstances).toBeDefined(); scene.groundPrimitives.add(primitive); - scene.renderForSpecs(); - return primitive.readyPromise.then(function () { - expect(primitive.geometryInstances).toBeDefined(); + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; }); + + expect(primitive.geometryInstances).toBeDefined(); }); - it("adds afterRender promise to frame state", function () { + it("becomes ready", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -279,11 +283,12 @@ describe( }); scene.groundPrimitives.add(primitive); - scene.renderForSpecs(); - - return primitive.readyPromise.then(function (param) { - expect(param.ready).toBe(true); + await pollToPromise(() => { + scene.renderForSpecs(); + return primitive.ready; }); + + expect(primitive.ready).toBe(true); }); it("does not render when geometryInstances is undefined", function () { @@ -321,7 +326,7 @@ describe( expect(scene.frameState.commandList.length).toEqual(0); }); - it("becomes ready when show is false", function () { + it("becomes ready when show is false", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -334,17 +339,12 @@ describe( }) ); - let ready = false; - primitive.readyPromise.then(function () { - ready = true; - }); - - return pollToPromise(function () { + await pollToPromise(() => { scene.renderForSpecs(); - return ready; - }).then(function () { - expect(ready).toEqual(true); + return primitive.ready; }); + + expect(primitive.ready).toBe(true); }); it("does not render other than for the color or pick pass", function () { @@ -1191,7 +1191,7 @@ describe( expect(scene).notToPick(); }); - it("internally invalid asynchronous geometry resolves promise and sets ready", function () { + it("internally invalid asynchronous geometry becomes ready", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -1210,18 +1210,15 @@ describe( scene.groundPrimitives.add(primitive); - return pollToPromise(function () { + await pollToPromise(() => { scene.renderForSpecs(); return primitive.ready; - }).then(function () { - return primitive.readyPromise.then(function (arg) { - expect(arg).toBe(primitive); - expect(primitive.ready).toBe(true); - }); }); + + expect(primitive.ready).toBe(true); }); - it("internally invalid synchronous geometry resolves promise and sets ready", function () { + it("internally invalid synchronous geometry becomes ready", async function () { if (!GroundPrimitive.isSupported(scene)) { return; } @@ -1241,15 +1238,12 @@ describe( scene.groundPrimitives.add(primitive); - return pollToPromise(function () { + await pollToPromise(() => { scene.renderForSpecs(); return primitive.ready; - }).then(function () { - return primitive.readyPromise.then(function (arg) { - expect(arg).toBe(primitive); - expect(primitive.ready).toBe(true); - }); }); + + expect(primitive.ready).toBe(true); }); it("update throws when batched instance colors are different and materials on GroundPrimitives are not supported", function () { diff --git a/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js b/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js index 1c645260b02..2c80710f8a4 100644 --- a/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js +++ b/packages/engine/Specs/Scene/Model/loadAndZoomToModelAsync.js @@ -2,50 +2,7 @@ import { Model } from "../../../index.js"; import pollToPromise from "../../../../../Specs/pollToPromise.js"; async function loadAndZoomToModelAsync(options, scene) { - const model = await Model.fromGltfAsync({ - url: options.url, - gltf: options.gltf, - basePath: options.basePath, - show: options.show, - modelMatrix: options.modelMatrix, - scale: options.scale, - minimumPixelSize: options.minimumPixelSize, - maximumScale: options.maximumScale, - id: options.id, - allowPicking: options.allowPicking, - incrementallyLoadTextures: options.incrementallyLoadTextures, - asynchronous: options.asynchronous, - clampAnimations: options.clampAnimations, - shadows: options.shadows, - debugShowBoundingVolume: options.debugShowBoundingVolume, - enableDebugWireframe: options.enableDebugWireframe, - debugWireframe: options.debugWireframe, - cull: options.cull, - opaquePass: options.opaquePass, - upAxis: options.upAxis, - forwardAxis: options.forwardAxis, - customShader: options.customShader, - content: options.content, - heightReference: options.heightReference, - scene: options.scene, - distanceDisplayCondition: options.distanceDisplayCondition, - color: options.color, - colorBlendAmount: options.colorBlendAmount, - colorBlendMode: options.colorBlendMode, - silhouetteColor: options.silhouetteColor, - silhouetteSize: options.silhouetteSize, - clippingPlanes: options.clippingPlanes, - lightColor: options.lightColor, - imageBasedLighting: options.imageBasedLighting, - backFaceCulling: options.backFaceCulling, - credit: options.credit, - showCreditsOnScreen: options.showCreditsOnScreen, - projectTo2D: options.projectTo2D, - featureIdLabel: options.featureIdLabel, - instanceFeatureIdLabel: options.instanceFeatureIdLabel, - classificationType: options.classificationType, - }); - + const model = await Model.fromGltfAsync(options); scene.primitives.add(model); await pollToPromise( diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index 443d94001a5..e2cdec48edd 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -1304,7 +1304,7 @@ describe( }); }); - function loadTimeDynamicPointCloud(viewer) { + async function loadTimeDynamicPointCloud(viewer) { const scene = viewer.scene; const clock = viewer.clock; @@ -1338,12 +1338,12 @@ describe( scene.primitives.add(pointCloud); - return pollToPromise(function () { + await pollToPromise(function () { scene.render(); return defined(pointCloud.boundingSphere); - }).then(function () { - return pointCloud.readyPromise; }); + + return pointCloud; } it("zoomTo zooms to TimeDynamicPointCloud with default offset when offset not defined", function () { From 76defbae4bf832bd13a70b21f5412ea2e0d2e6db Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 28 Mar 2023 14:39:20 -0400 Subject: [PATCH 586/679] Deprecation & documentation cleanup --- .../Scene/Cesium3DTilesVoxelProvider.js | 19 +++++- .../Source/Scene/Composite3DTileContent.js | 40 ++++++++++++- .../engine/Source/Scene/Empty3DTileContent.js | 30 ++++++++++ .../Source/Scene/Geometry3DTileContent.js | 41 ++++++++++++- .../Source/Scene/Implicit3DTileContent.js | 33 +++++++++++ .../Source/Scene/Model/Model3DTileContent.js | 59 +++++++++++++++++++ .../Source/Scene/Multiple3DTileContent.js | 40 ++++++++++++- .../Source/Scene/Tileset3DTileContent.js | 32 ++++++++++ .../Source/Scene/Vector3DTileContent.js | 39 ++++++++++++ .../Source/Scene/Vector3DTileGeometry.js | 3 + .../engine/Source/Scene/Vector3DTilePoints.js | 3 + .../Source/Scene/Vector3DTilePolygons.js | 3 + .../Source/Scene/Vector3DTilePolylines.js | 3 + 13 files changed, 340 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js index 5a84f8f9d99..c319710e159 100644 --- a/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js +++ b/packages/engine/Source/Scene/Cesium3DTilesVoxelProvider.js @@ -176,7 +176,14 @@ function Cesium3DTilesVoxelProvider(options) { } Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, { - /** @inheritdoc */ + /** + * Gets the promise that will be resolved when the provider is ready for use. + * + * @memberof Cesium3DTilesVoxelProvider.prototype + * @type {Promise<Cesium3DTilesVoxelProvider>} + * @readonly + * @deprecated + */ readyPromise: { get: function () { deprecationWarning( @@ -186,7 +193,15 @@ Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, { return this._readyPromise; }, }, - /** @inheritdoc */ + + /** + * Gets a value indicating whether or not the provider is ready for use. + * + * @memberof Cesium3DTilesVoxelProvider.prototype + * @type {boolean} + * @readonly + * @deprecated + */ ready: { get: function () { deprecationWarning( diff --git a/packages/engine/Source/Scene/Composite3DTileContent.js b/packages/engine/Source/Scene/Composite3DTileContent.js index e61d10e819a..824b0118695 100644 --- a/packages/engine/Source/Scene/Composite3DTileContent.js +++ b/packages/engine/Source/Scene/Composite3DTileContent.js @@ -1,5 +1,6 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import getMagic from "../Core/getMagic.js"; import RuntimeError from "../Core/RuntimeError.js"; @@ -30,6 +31,11 @@ function Composite3DTileContent(tileset, tile, resource, contents) { this._metadata = undefined; this._group = undefined; this._ready = false; + + this._resolveContent = undefined; + this._readyPromise = new Promise((resolve) => { + this._resolveContent = resolve; + }); } Object.defineProperties(Composite3DTileContent.prototype, { @@ -126,12 +132,41 @@ Object.defineProperties(Composite3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Composite3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Composite3DTileContent.prototype + * + * @type {Promise<Composite3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Composite3DTileContent.readyPromise", + "Composite3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Composite3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -333,7 +368,10 @@ Composite3DTileContent.prototype.update = function (tileset, frameState) { ready = ready && contents[i].ready; } - this._ready = ready; + if (!this._ready && ready) { + this._ready = true; + this._resolveContent(this); + } }; Composite3DTileContent.prototype.isDestroyed = function () { diff --git a/packages/engine/Source/Scene/Empty3DTileContent.js b/packages/engine/Source/Scene/Empty3DTileContent.js index 13f427b0e02..b9aa4f82144 100644 --- a/packages/engine/Source/Scene/Empty3DTileContent.js +++ b/packages/engine/Source/Scene/Empty3DTileContent.js @@ -1,3 +1,4 @@ +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; @@ -64,12 +65,41 @@ Object.defineProperties(Empty3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Empty3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return true; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Empty3DTileContent.prototype + * + * @type {Promise<Empty3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Empty3DTileContent.readyPromise", + "Empty3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Empty3DTileContent.ready to return true instead." + ); + return Promise.resolve(this); + }, + }, + tileset: { get: function () { return this._tileset; diff --git a/packages/engine/Source/Scene/Geometry3DTileContent.js b/packages/engine/Source/Scene/Geometry3DTileContent.js index f9ea775d910..4486ffbb8bf 100644 --- a/packages/engine/Source/Scene/Geometry3DTileContent.js +++ b/packages/engine/Source/Scene/Geometry3DTileContent.js @@ -1,6 +1,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js"; @@ -43,6 +44,13 @@ function Geometry3DTileContent( this._group = undefined; this._ready = false; + + // This is for backwards compatibility. It can be removed once readyPromise is removed. + this._resolveContent = undefined; + this._readyPromise = new Promise((resolve) => { + this._resolveContent = resolve; + }); + initialize(this, arrayBuffer, byteOffset); } @@ -97,12 +105,41 @@ Object.defineProperties(Geometry3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Geometry3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Geometry3DTileContent.prototype + * + * @type {Promise<Geometry3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Geometry3DTileContent.readyPromise", + "Geometry3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Geometry3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -291,7 +328,8 @@ function initialize(content, arrayBuffer, byteOffset) { byteOffset += sizeOfUint32; if (byteLength === 0) { - this._ready = true; + content._ready = true; + content._resolveContent(content); return; } @@ -512,6 +550,7 @@ Geometry3DTileContent.prototype.update = function (tileset, frameState) { if (defined(this._batchTable) && this._geometries.ready) { this._batchTable.update(tileset, frameState); this._ready = true; + this._resolveContent(this); } }; diff --git a/packages/engine/Source/Scene/Implicit3DTileContent.js b/packages/engine/Source/Scene/Implicit3DTileContent.js index 8f93e9dc5de..7f6a8314afb 100644 --- a/packages/engine/Source/Scene/Implicit3DTileContent.js +++ b/packages/engine/Source/Scene/Implicit3DTileContent.js @@ -4,6 +4,7 @@ import clone from "../Core/clone.js"; import combine from "../Core/combine.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import CesiumMath from "../Core/Math.js"; @@ -73,6 +74,7 @@ function Implicit3DTileContent(tileset, tile, resource) { this._url = subtreeResource.getUrlComponent(true); this._ready = false; + this._readyPromise = undefined; } Object.defineProperties(Implicit3DTileContent.prototype, { @@ -118,12 +120,41 @@ Object.defineProperties(Implicit3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Implicit3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Implicit3DTileContent.prototype + * + * @type {Promise<Implicit3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Implicit3DTileContent.readyPromise", + "Implicit3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Implicit3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -229,6 +260,8 @@ Implicit3DTileContent.fromSubtreeJson = async function ( content._implicitSubtree = subtree; expandSubtree(content, subtree); content._ready = true; + content._readyPromise = Promise.resolve(content); + return content; }; diff --git a/packages/engine/Source/Scene/Model/Model3DTileContent.js b/packages/engine/Source/Scene/Model/Model3DTileContent.js index 52c51879f4b..cd222a39c47 100644 --- a/packages/engine/Source/Scene/Model/Model3DTileContent.js +++ b/packages/engine/Source/Scene/Model/Model3DTileContent.js @@ -2,6 +2,7 @@ import Color from "../../Core/Color.js"; import combine from "../../Core/combine.js"; import defined from "../../Core/defined.js"; import destroyObject from "../../Core/destroyObject.js"; +import deprecationWarning from "../../Core/deprecationWarning.js"; import DeveloperError from "../../Core/DeveloperError.js"; import Pass from "../../Renderer/Pass.js"; import ModelAnimationLoop from "../ModelAnimationLoop.js"; @@ -29,6 +30,9 @@ function Model3DTileContent(tileset, tile, resource) { this._metadata = undefined; this._group = undefined; this._ready = false; + + this._resolveContent = undefined; + this._readyPromise = undefined; } Object.defineProperties(Model3DTileContent.prototype, { @@ -85,12 +89,41 @@ Object.defineProperties(Model3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Model3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Model3DTileContent.prototype + * + * @type {Promise<Model3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Model3DTileContent.readyPromise", + "Model3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Model3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -254,6 +287,7 @@ Model3DTileContent.prototype.update = function (tileset, frameState) { }); this._ready = true; + this._resolveContent = this._resolveContent && this._resolveContent(this); } }; @@ -290,6 +324,11 @@ Model3DTileContent.fromGltf = async function (tileset, tile, resource, gltf) { const model = await Model.fromGltfAsync(modelOptions); content._model = model; + // This is for backwards compatibility. It can be removed once readyPromise is removed. + content._readyPromise = new Promise((resolve) => { + content._resolveContent = resolve; + }); + return content; }; @@ -324,6 +363,11 @@ Model3DTileContent.fromB3dm = async function ( const model = await Model.fromB3dm(modelOptions); content._model = model; + // This is for backwards compatibility. It can be removed once readyPromise is removed. + content._readyPromise = new Promise((resolve) => { + content._resolveContent = resolve; + }); + return content; }; @@ -352,6 +396,11 @@ Model3DTileContent.fromI3dm = async function ( const model = await Model.fromI3dm(modelOptions); content._model = model; + // This is for backwards compatibility. It can be removed once readyPromise is removed. + content._readyPromise = new Promise((resolve) => { + content._resolveContent = resolve; + }); + return content; }; @@ -379,6 +428,11 @@ Model3DTileContent.fromPnts = async function ( const model = await Model.fromPnts(modelOptions); content._model = model; + // This is for backwards compatibility. It can be removed once readyPromise is removed. + content._readyPromise = new Promise((resolve) => { + content._resolveContent = resolve; + }); + return content; }; @@ -404,6 +458,11 @@ Model3DTileContent.fromGeoJson = async function ( const model = await Model.fromGeoJson(modelOptions); content._model = model; + // This is for backwards compatibility. It can be removed once readyPromise is removed. + content._readyPromise = new Promise((resolve) => { + content._resolveContent = resolve; + }); + return content; }; diff --git a/packages/engine/Source/Scene/Multiple3DTileContent.js b/packages/engine/Source/Scene/Multiple3DTileContent.js index 65578e43444..10de75a5c2f 100644 --- a/packages/engine/Source/Scene/Multiple3DTileContent.js +++ b/packages/engine/Source/Scene/Multiple3DTileContent.js @@ -1,4 +1,5 @@ import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import Request from "../Core/Request.js"; @@ -56,6 +57,11 @@ function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) { this._requests = new Array(contentCount); this._ready = false; + this._resolveContent = undefined; + this._readyPromise = new Promise((resolve) => { + this._resolveContent = resolve; + }); + this._innerContentResources = new Array(contentCount); this._serverKeys = new Array(contentCount); @@ -211,6 +217,15 @@ Object.defineProperties(Multiple3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Multiple3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { if (!this._contentsCreated) { @@ -221,6 +236,26 @@ Object.defineProperties(Multiple3DTileContent.prototype, { }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Multiple3DTileContent.prototype + * + * @type {Promise<Multiple3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Multiple3DTileContent.readyPromise", + "Multiple3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Multiple3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -636,7 +671,10 @@ Multiple3DTileContent.prototype.update = function (tileset, frameState) { ready = ready && contents[i].ready; } - this._ready = ready; + if (!this._ready && ready) { + this._ready = true; + this._resolveContent(this); + } }; Multiple3DTileContent.prototype.isDestroyed = function () { diff --git a/packages/engine/Source/Scene/Tileset3DTileContent.js b/packages/engine/Source/Scene/Tileset3DTileContent.js index 9d5ba1172c9..34559190b62 100644 --- a/packages/engine/Source/Scene/Tileset3DTileContent.js +++ b/packages/engine/Source/Scene/Tileset3DTileContent.js @@ -1,4 +1,5 @@ import destroyObject from "../Core/destroyObject.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; /** * Represents content for a tile in a @@ -24,6 +25,7 @@ function Tileset3DTileContent(tileset, tile, resource) { this._group = undefined; this._ready = false; + this._readyPromise = Promise.resolve(this); } Object.defineProperties(Tileset3DTileContent.prototype, { @@ -69,12 +71,41 @@ Object.defineProperties(Tileset3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Tileset3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Tileset3DTileContent.prototype + * + * @type {Promise<Tileset3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Tileset3DTileContent.readyPromise", + "Tileset3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Tileset3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -130,6 +161,7 @@ Tileset3DTileContent.fromJson = function (tileset, tile, resource, json) { const content = new Tileset3DTileContent(tileset, tile, resource); content._tileset.loadTileset(content._resource, json, content._tile); content._ready = true; + return content; }; diff --git a/packages/engine/Source/Scene/Vector3DTileContent.js b/packages/engine/Source/Scene/Vector3DTileContent.js index 396e1a9e52f..565e8839aaa 100644 --- a/packages/engine/Source/Scene/Vector3DTileContent.js +++ b/packages/engine/Source/Scene/Vector3DTileContent.js @@ -1,6 +1,7 @@ import Cartesian3 from "../Core/Cartesian3.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import Ellipsoid from "../Core/Ellipsoid.js"; @@ -52,6 +53,13 @@ function Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) { this._group = undefined; this._ready = false; + + // This is here for backwards compatibility and can be removed when readyPromise is removed. + this._resolveContent = undefined; + this._readyPromise = new Promise((resolve) => { + this._resolveContent = resolve; + }); + initialize(this, arrayBuffer, byteOffset); } @@ -120,12 +128,41 @@ Object.defineProperties(Vector3DTileContent.prototype, { }, }, + /** + * Returns true when the tile's content is ready to render; otherwise false + * + * @memberof Vector3DTileContent.prototype + * + * @type {boolean} + * @readonly + * @private + */ ready: { get: function () { return this._ready; }, }, + /** + * Gets the promise that will be resolved when the tile's content is ready to render. + * + * @memberof Vector3DTileContent.prototype + * + * @type {Promise<Vector3DTileContent>} + * @readonly + * @deprecated + * @private + */ + readyPromise: { + get: function () { + deprecationWarning( + "Vector3DTileContent.readyPromise", + "Vector3DTileContent.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Wait for Vector3DTileContent.ready to return true instead." + ); + return this._readyPromise; + }, + }, + tileset: { get: function () { return this._tileset; @@ -298,6 +335,7 @@ function initialize(content, arrayBuffer, byteOffset) { if (byteLength === 0) { content._ready = true; + content._resolveContent(content); return; } @@ -714,6 +752,7 @@ Vector3DTileContent.prototype.update = function (tileset, frameState) { } this._batchTable.update(tileset, frameState); this._ready = true; + this._resolveContent(this); } }; diff --git a/packages/engine/Source/Scene/Vector3DTileGeometry.js b/packages/engine/Source/Scene/Vector3DTileGeometry.js index 39ce487b1fc..c6e4c768807 100644 --- a/packages/engine/Source/Scene/Vector3DTileGeometry.js +++ b/packages/engine/Source/Scene/Vector3DTileGeometry.js @@ -108,6 +108,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { * * @type {number} * @readonly + * @private */ trianglesLength: { get: function () { @@ -125,6 +126,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { * * @type {number} * @readonly + * @private */ geometryByteLength: { get: function () { @@ -140,6 +142,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, { * @memberof Vector3DTileGeometry.prototype * @type {boolean} * @readonly + * @private */ ready: { get: function () { diff --git a/packages/engine/Source/Scene/Vector3DTilePoints.js b/packages/engine/Source/Scene/Vector3DTilePoints.js index 42c65633d7f..f66fc7901a0 100644 --- a/packages/engine/Source/Scene/Vector3DTilePoints.js +++ b/packages/engine/Source/Scene/Vector3DTilePoints.js @@ -67,6 +67,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, { * * @type {boolean} * @readonly + * @private */ ready: { get: function () { @@ -81,6 +82,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, { * * @type {number} * @readonly + * @private */ pointsLength: { get: function () { @@ -95,6 +97,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, { * * @type {number} * @readonly + * @private */ texturesByteLength: { get: function () { diff --git a/packages/engine/Source/Scene/Vector3DTilePolygons.js b/packages/engine/Source/Scene/Vector3DTilePolygons.js index dfc26848fe2..06a6d3de907 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolygons.js +++ b/packages/engine/Source/Scene/Vector3DTilePolygons.js @@ -108,6 +108,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { * * @type {number} * @readonly + * @private */ trianglesLength: { get: function () { @@ -125,6 +126,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { * * @type {number} * @readonly + * @private */ geometryByteLength: { get: function () { @@ -140,6 +142,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, { * @memberof Vector3DTilePolygons.prototype * @type {boolean} * @readonly + * @private */ ready: { get: function () { diff --git a/packages/engine/Source/Scene/Vector3DTilePolylines.js b/packages/engine/Source/Scene/Vector3DTilePolylines.js index 70baacb6d69..781f568b511 100644 --- a/packages/engine/Source/Scene/Vector3DTilePolylines.js +++ b/packages/engine/Source/Scene/Vector3DTilePolylines.js @@ -99,6 +99,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { * * @type {number} * @readonly + * @private */ trianglesLength: { get: function () { @@ -113,6 +114,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { * * @type {number} * @readonly + * @private */ geometryByteLength: { get: function () { @@ -125,6 +127,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, { * @memberof Vector3DTilePolylines.prototype * @type {boolean} * @readonly + * @private */ ready: { get: function () { From 18025ca3aaa6552d620c23b0496ff44cdfc4b9b2 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 28 Mar 2023 15:00:48 -0400 Subject: [PATCH 587/679] Cleanup --- .../Specs/Scene/BillboardCollectionSpec.js | 12 ++++--- packages/engine/Specs/Scene/GlobeSpec.js | 34 +++++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/packages/engine/Specs/Scene/BillboardCollectionSpec.js b/packages/engine/Specs/Scene/BillboardCollectionSpec.js index 2e605eb15d3..529ff904953 100644 --- a/packages/engine/Specs/Scene/BillboardCollectionSpec.js +++ b/packages/engine/Specs/Scene/BillboardCollectionSpec.js @@ -2503,7 +2503,7 @@ describe( expect(b._clampedPosition).toBeUndefined(); }); - it("changing the terrain provider", function () { + it("changing the terrain provider", async function () { const b = billboardsWithHeight.add({ heightReference: HeightReference.CLAMP_TO_GROUND, position: Cartesian3.fromDegrees(-72.0, 40.0), @@ -2512,10 +2512,12 @@ describe( spyOn(b, "_updateClamping").and.callThrough(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - requestVertexNormals: true, - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { + requestVertexNormals: true, + } + ); scene.terrainProvider = terrainProvider; diff --git a/packages/engine/Specs/Scene/GlobeSpec.js b/packages/engine/Specs/Scene/GlobeSpec.js index cfc2b6a5f68..af2863a7a40 100644 --- a/packages/engine/Specs/Scene/GlobeSpec.js +++ b/packages/engine/Specs/Scene/GlobeSpec.js @@ -227,11 +227,13 @@ describe( }); }); - it("terrainProviderChanged event fires", function () { - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - requestVertexNormals: true, - }); + it("terrainProviderChanged event fires", async function () { + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { + requestVertexNormals: true, + } + ); const spyListener = jasmine.createSpy("listener"); globe.terrainProviderChanged.addEventListener(spyListener); @@ -241,7 +243,7 @@ describe( expect(spyListener).toHaveBeenCalledWith(terrainProvider); }); - it("tilesLoaded return true when tile load queue is empty", function () { + it("tilesLoaded return true when tile load queue is empty", async function () { expect(globe.tilesLoaded).toBe(true); globe._surface._tileLoadQueueHigh.length = 2; @@ -262,10 +264,12 @@ describe( globe._surface._tileLoadQueueLow.length = 0; expect(globe.tilesLoaded).toBe(true); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - requestVertexNormals: true, - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { + requestVertexNormals: true, + } + ); globe.terrainProvider = terrainProvider; scene.render(); @@ -306,10 +310,12 @@ describe( returnVertexNormalTileJson(); - const terrainProvider = new CesiumTerrainProvider({ - url: "made/up/url", - requestVertexNormals: true, - }); + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url", + { + requestVertexNormals: true, + } + ); globe.terrainProvider = terrainProvider; scene.camera.setView({ From ba022f70d5dae3f01da24d33a0b9f3fc4099b3cb Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 28 Mar 2023 16:19:44 -0400 Subject: [PATCH 588/679] Add CesiumTerrainProvider.fromIonAssetId --- Apps/Sandcastle/gallery/ArcticDEM.html | 4 +- Apps/Sandcastle/gallery/PAMAP Terrain.html | 4 +- CHANGES.md | 4 +- .../Source/Core/CesiumTerrainProvider.js | 54 ++++++++++++++++--- .../Source/Core/VRTheWorldTerrainProvider.js | 2 +- .../Source/Core/createWorldTerrainAsync.js | 3 +- .../Specs/Core/CesiumTerrainProviderSpec.js | 8 +++ 7 files changed, 63 insertions(+), 16 deletions(-) diff --git a/Apps/Sandcastle/gallery/ArcticDEM.html b/Apps/Sandcastle/gallery/ArcticDEM.html index 8d6d3509b59..63286fc2296 100644 --- a/Apps/Sandcastle/gallery/ArcticDEM.html +++ b/Apps/Sandcastle/gallery/ArcticDEM.html @@ -40,8 +40,8 @@ try { // High-resolution arctic terrain from the Arctic DEM project (Release 4), tiled and hosted by Cesium ion. // https://www.pgc.umn.edu/data/arcticdem/ - viewer.scene.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3956) + viewer.scene.terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId( + 3956 ); } catch (error) { window.alert(`Failed to load terrain. ${error}`); diff --git a/Apps/Sandcastle/gallery/PAMAP Terrain.html b/Apps/Sandcastle/gallery/PAMAP Terrain.html index 4d3d07e1fa4..5c8ab22a00b 100644 --- a/Apps/Sandcastle/gallery/PAMAP Terrain.html +++ b/Apps/Sandcastle/gallery/PAMAP Terrain.html @@ -40,8 +40,8 @@ try { // High resolution terrain of Pennsylvania curated by Pennsylvania Spatial Data Access (PASDA) // http://www.pasda.psu.edu/ - viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromUrl( - Cesium.IonResource.fromAssetId(3957) + viewer.terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId( + 3957 ); } catch (error) { window.alert(`Failed to load terrain. ${error}`); diff --git a/CHANGES.md b/CHANGES.md index 07e46740653..500fee77e16 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromIonAssetId`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. ##### Fixes :wrench: @@ -39,7 +39,7 @@ - `TerrainProvider.ready` and `TerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. - `createWorldImagery` was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `createWorldImageryAsync` instead. - `ArcGISTiledElevationTerrainProvider` constructor parameter `options.url`, `ArcGISTiledElevationTerrainProvider.ready`, and `ArcGISTiledElevationTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `ArcGISTiledElevationTerrainProvider.fromUrl` instead. -- `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `CesiumTerrainProvider.fromUrl` instead. +- `CesiumTerrainProvider` constructor parameter `options.url`, `CesiumTerrainProvider.ready`, and `CesiumTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `CesiumTerrainProvider.fromIonAssetId` or `CesiumTerrainProvider.fromUrl` instead. - `CustomHeightmapTerrainProvider.ready`, and `CustomHeightmapTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. - `EllipsoidTerrainProvider.ready`, and `EllipsoidTerrainProvider.readyPromise` were deprecated in CesiumJS 1.104. - `GoogleEarthEnterpriseMetadata` constructor parameter `options.url` and `GoogleEarthEnterpriseMetadata.readyPromise` were deprecated in CesiumJS 1.104. They will be removed in 1.107. Use `GoogleEarthEnterpriseMetadata.fromUrl` instead. diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index 61bc5d98b68..26da3ade269 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -12,6 +12,7 @@ import WebMercatorTilingScheme from "./WebMercatorTilingScheme.js"; import getJsonFromTypedArray from "./getJsonFromTypedArray.js"; import HeightmapTerrainData from "./HeightmapTerrainData.js"; import IndexDatatype from "./IndexDatatype.js"; +import IonResource from "./IonResource.js"; import OrientedBoundingBox from "./OrientedBoundingBox.js"; import QuantizedMeshTerrainData from "./QuantizedMeshTerrainData.js"; import Request from "./Request.js"; @@ -444,7 +445,7 @@ async function requestLayerJson(terrainProviderBuilder, provider) { /** * <div class="notice"> - * To construct a CesiumTerrainProvider, call {@link CesiumTerrainProvider.fromUrl}. Do not call the constructor directly. + * To construct a CesiumTerrainProvider, call {@link CesiumTerrainProvider.fromIonAssetId} or {@link CesiumTerrainProvider.fromUrl}. Do not call the constructor directly. * </div> * * A {@link TerrainProvider} that accesses terrain data in a Cesium terrain format. @@ -463,9 +464,8 @@ async function requestLayerJson(terrainProviderBuilder, provider) { * // Create Arctic DEM terrain with normals. * try { * const viewer = new Cesium.Viewer("cesiumContainer", { - * terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( - * Cesium.IonResource.fromAssetId(3956), { - * requestVertexNormals: true + * terrainProvider: await Cesium.CesiumTerrainProvider.fromIonAssetId(3956, { + * requestVertexNormals: true * }) * }); * } catch (error) { @@ -474,6 +474,7 @@ async function requestLayerJson(terrainProviderBuilder, provider) { * * @see createWorldTerrain * @see CesiumTerrainProvider.fromUrl + * @see CesiumTerrainProvider.fromIonAssetId * @see TerrainProvider */ function CesiumTerrainProvider(options) { @@ -534,7 +535,7 @@ function CesiumTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "CesiumTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); this._readyPromise = CesiumTerrainProvider._initializeReadyPromise( options, @@ -1061,7 +1062,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.ready", - "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -1078,7 +1079,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.readyPromise", - "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); return this._readyPromise; }, @@ -1196,6 +1197,45 @@ CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function ( return this._levelZeroMaximumGeometricError / (1 << level); }; +/** + * Creates a {@link TerrainProvider} from a Cesium ion asset ID that accesses terrain data in a Cesium terrain format + * Terrain formats can be one of the following: + * <ul> + * <li> {@link https://github.com/AnalyticalGraphicsInc/quantized-mesh Quantized Mesh} </li> + * <li> {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/heightmap-1.0 Height Map} </li> + * </ul> + * + * @param {Resource|String|Promise<Resource>|Promise<String>} url The URL of the Cesium terrain server. + * @param {CesiumTerrainProvider.ConstructorOptions} [options] An object describing initialization options. + * @returns {Promise<CesiumTerrainProvider>} + * + * @example + * // Create Arctic DEM terrain with normals. + * try { + * const viewer = new Cesium.Viewer("cesiumContainer", { + * terrainProvider: await Cesium.CesiumTerrainProvider.fromIonAssetId(3956, { + * requestVertexNormals: true + * }) + * }); + * } catch (error) { + * console.log(error); + * } + * + * @exception {RuntimeError} layer.json does not specify a format + * @exception {RuntimeError} layer.json specifies an unknown format + * @exception {RuntimeError} layer.json specifies an unsupported quantized-mesh version + * @exception {RuntimeError} layer.json does not specify a tiles property, or specifies an empty array + * @exception {RuntimeError} layer.json does not specify any tile URL templates + */ +CesiumTerrainProvider.fromIonAssetId = async function (assetId, options) { + //>>includeStart('debug', pragmas.debug); + Check.defined("assetId", assetId); + //>>includeEnd('debug'); + + const resource = await IonResource.fromAssetId(assetId); + return CesiumTerrainProvider.fromUrl(resource, options); +}; + /** * Creates a {@link TerrainProvider} that accesses terrain data in a Cesium terrain format. * Terrain formats can be one of the following: diff --git a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js index 73a66d669ae..5db5f33c2c8 100644 --- a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js +++ b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js @@ -137,7 +137,7 @@ async function requestMetadata(terrainProviderBuilder, resource, provider) { /** * <div class="notice"> - * To construct a CesiumTerrainProvider, call {@link CesiumTerrainProvider.fromUrl}. Do not call the constructor directly. + * To construct a VRTheWorldTerrainProvider, call {@link VRTheWorldTerrainProvider.fromUrl}. Do not call the constructor directly. * </div> * * A {@link TerrainProvider} that produces terrain geometry by tessellating height maps diff --git a/packages/engine/Source/Core/createWorldTerrainAsync.js b/packages/engine/Source/Core/createWorldTerrainAsync.js index 983b7e89ba3..ec931a8ed4e 100644 --- a/packages/engine/Source/Core/createWorldTerrainAsync.js +++ b/packages/engine/Source/Core/createWorldTerrainAsync.js @@ -1,6 +1,5 @@ import CesiumTerrainProvider from "./CesiumTerrainProvider.js"; import defaultValue from "./defaultValue.js"; -import IonResource from "./IonResource.js"; /** * Creates a {@link CesiumTerrainProvider} instance for the {@link https://cesium.com/content/#cesium-world-terrain|Cesium World Terrain}. @@ -41,7 +40,7 @@ import IonResource from "./IonResource.js"; function createWorldTerrainAsync(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); - return CesiumTerrainProvider.fromUrl(IonResource.fromAssetId(1), { + return CesiumTerrainProvider.fromIonAssetId(1, { requestVertexNormals: defaultValue(options.requestVertexNormals, false), requestWaterMask: defaultValue(options.requestWaterMask, false), }); diff --git a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js index 28a533b5412..c4d6a6c5a29 100644 --- a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js @@ -152,6 +152,14 @@ describe("Core/CesiumTerrainProvider", function () { expect(CesiumTerrainProvider).toConformToInterface(TerrainProvider); }); + it("fromIonAssetId throws without assetId", async function () { + await expectAsync( + CesiumTerrainProvider.fromIonAssetId() + ).toBeRejectedWithDeveloperError( + "assetId is required, actual value was undefined" + ); + }); + it("fromUrl throws without url", async function () { await expectAsync( CesiumTerrainProvider.fromUrl() From d3af1ba2bd2aca4bbb626411550d97eb690dc6f4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 28 Mar 2023 16:27:52 -0400 Subject: [PATCH 589/679] Fix typo in comment --- packages/engine/Source/Scene/Multiple3DTileContent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Multiple3DTileContent.js b/packages/engine/Source/Scene/Multiple3DTileContent.js index 10de75a5c2f..10b8998d3e7 100644 --- a/packages/engine/Source/Scene/Multiple3DTileContent.js +++ b/packages/engine/Source/Scene/Multiple3DTileContent.js @@ -524,7 +524,7 @@ async function createInnerContents(multipleContents) { createInnerContent(multipleContents, arrayBuffer, i) ); - // Even if we had a partial success (in which case the inner promise will be handled, but the content will nit be returned), mark that we finished creating + // Even if we had a partial success (in which case the inner promise will be handled, but the content will not be returned), mark that we finished creating // contents const contents = await Promise.all(promises); multipleContents._contentsCreated = true; From 2dd4240e5840cf1438c4a40a93bd9db1dcb793e4 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 28 Mar 2023 16:32:51 -0400 Subject: [PATCH 590/679] fix sandcastle warning --- Apps/Sandcastle/Sandcastle-helpers.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Apps/Sandcastle/Sandcastle-helpers.js b/Apps/Sandcastle/Sandcastle-helpers.js index cdb6b971625..06d1834429e 100644 --- a/Apps/Sandcastle/Sandcastle-helpers.js +++ b/Apps/Sandcastle/Sandcastle-helpers.js @@ -12,7 +12,8 @@ `};\n` + `if (typeof Cesium !== 'undefined') {\n` + ` window.startupCalled = true;\n` + - ` window.startup(Cesium).catch((error) => {\n` + + ` window.startup(Cesium).catch((error) => {\n` + + ` "use strict";\n` + ` console.error(error);\n` + ` });\n` + `}\n` From a5cc2b055d8d0628742c39f11064d508d0f4fb03 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Tue, 28 Mar 2023 19:27:13 -0400 Subject: [PATCH 591/679] Standardize whitespace, clarify comments in AtmosphereCommon.glsl --- .../Source/Shaders/AtmosphereCommon.glsl | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 8220f39a154..8be332abcb6 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -58,11 +58,9 @@ void computeScattering( // To deal with smaller values of PRIMARY_STEPS (e.g. 4) // we implement a split strategy: sky or horizon. - // // For performance reasons, instead of a if/else branch // a soft choice is implemented through a weight 0.0 <= w_stop_gt_lprl <= 1.0 float x = 1e-7 * primaryRayAtmosphereIntersect.stop / length(primaryRayLength); - // w_stop_gt_lprl: similar to (1+tanh)/2 // Value close to 0.0: close to the horizon // Value close to 1.0: above in the sky float w_stop_gt_lprl = 0.5 * (1.0 + approximateTanh(x)); @@ -73,27 +71,21 @@ void computeScattering( // The ray should end at the exit from the atmosphere or at the distance to the vertex, whichever is smaller. primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, length(primaryRayLength)); - - // Distinguish inside or outside atmosphere (outer space) - // Reasons: - // (1) from outer space we have to use the original implementation to get an unmodified/acceptable rendering - // (2) within atmosphere we need a speedup + // For the number of ray steps, distinguish inside or outside atmosphere (outer space) + // (1) from outer space we have to use more ray steps to get a realistic rendering + // (2) within atmosphere we need fewer steps for faster rendering float x_o_a = start_0 - ATMOSPHERE_THICKNESS; // ATMOSPHERE_THICKNESS used as an ad-hoc constant, no precise meaning here, only the order of magnitude matters float w_inside_atmosphere = 1.0 - 0.5 * (1.0 + approximateTanh(x_o_a)); - - // (1) Outside of the atmosphere: original (16.0,4.0) values for good rendering - // (2) Inside atmosphere: smaller (4.0,2.0) values for a speedup int PRIMARY_STEPS = int(16.0 - w_inside_atmosphere * 12.0); // Number of times the ray from the camera to the world position (primary ray) is sampled. - int LIGHT_STEPS = int(4.0 - w_inside_atmosphere * 2.0); // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. + int LIGHT_STEPS = int(4.0 - w_inside_atmosphere * 2.0); // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. float rayPositionLength = primaryRayAtmosphereIntersect.start; - // (1) Outside of the atmosphere: constant rayStepLength - // (2) Inside atmosphere: variable rayStepLength to compensate the originally rough rendering of the smaller (4.0,2.0) values - // Implementation: sky vs horizon: constant step in one case, increasing step in the other case - float rayStepLengthIncrease = w_inside_atmosphere * ((1.0 - w_stop_gt_lprl)*(primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / (float(PRIMARY_STEPS*(PRIMARY_STEPS+1))/2.0)); - float rayStepLength = max(1.0-w_inside_atmosphere, w_stop_gt_lprl) * (primaryRayAtmosphereIntersect.stop - primaryRayAtmosphereIntersect.start) / max(7.0*w_inside_atmosphere,float(PRIMARY_STEPS)); - + // (1) Outside the atmosphere: constant rayStepLength + // (2) Inside atmosphere: variable rayStepLength to compensate the rough rendering of the smaller number of ray steps + float totalRayLength = primaryRayAtmosphereIntersect.stop - rayPositionLength; + float rayStepLengthIncrease = w_inside_atmosphere * ((1.0 - w_stop_gt_lprl) * totalRayLength / (float(PRIMARY_STEPS * (PRIMARY_STEPS + 1)) / 2.0)); + float rayStepLength = max(1.0 - w_inside_atmosphere, w_stop_gt_lprl) * totalRayLength / max(7.0 * w_inside_atmosphere, float(PRIMARY_STEPS)); vec3 rayleighAccumulation = vec3(0.0); vec3 mieAccumulation = vec3(0.0); @@ -104,7 +96,7 @@ void computeScattering( for (int i = 0; i < PRIMARY_STEPS; i++) { // Calculate sample position along viewpoint ray. vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength); - + // Calculate height of sample position above ellipsoid. float sampleHeight = length(samplePosition) - atmosphereInnerRadius; @@ -115,7 +107,7 @@ void computeScattering( // Generate ray from the sample position segment to the light source, up to the outer ring of the atmosphere. czm_ray lightRay = czm_ray(samplePosition, lightDirection); czm_raySegment lightRayAtmosphereIntersect = czm_raySphereIntersectionInterval(lightRay, origin, atmosphereOuterRadius); - + float lightStepLength = lightRayAtmosphereIntersect.stop / float(LIGHT_STEPS); float lightPositionLength = 0.0; @@ -145,9 +137,7 @@ void computeScattering( mieAccumulation += sampleDensity.y * attenuation; // Increment distance on primary ray. - - // --- Modified: increasing step length - rayPositionLength += (rayStepLength+=rayStepLengthIncrease); + rayPositionLength += (rayStepLength += rayStepLengthIncrease); } // Compute the scattering amount. From 7a35fa9624d405540a295a3affb1e43611e0f73c Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Wed, 29 Mar 2023 07:41:41 +0300 Subject: [PATCH 592/679] Add WebGL1 support to AtmosphereCommon.glsl --- .../engine/Source/Shaders/AtmosphereCommon.glsl | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 8be332abcb6..8cdde711964 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -93,7 +93,13 @@ void computeScattering( vec2 heightScale = vec2(u_atmosphereRayleighScaleHeight, u_atmosphereMieScaleHeight); // Sample positions on the primary ray. - for (int i = 0; i < PRIMARY_STEPS; i++) { + for (int i = 0; i < 999999999; ++i) { + + // The loop should be: for (int i = 0; i < PRIMARY_STEPS; ++i) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (i >= PRIMARY_STEPS) + break; + // Calculate sample position along viewpoint ray. vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength); @@ -114,7 +120,12 @@ void computeScattering( vec2 lightOpticalDepth = vec2(0.0); // Sample positions along the light ray, to accumulate incidence of light on the latest sample segment. - for (int j = 0; j < LIGHT_STEPS; j++) { + for (int j = 0; j < 999999999; ++j) { + + // The loop should be: for (int j = 0; i < LIGHT_STEPS; ++j) {...} but WebGL1 cannot + // loop with non-constant condition, so it has to break early instead + if (j >= LIGHT_STEPS) + break; // Calculate sample position along light ray. vec3 lightPosition = samplePosition + lightDirection * (lightPositionLength + lightStepLength * 0.5); From a121a0a1459d35ea4b6313873cd8a7bd5b4e4b10 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 10:21:19 -0400 Subject: [PATCH 593/679] Fix built viewer --- Apps/CesiumViewer/CesiumViewer.js | 7 ++++--- Apps/CesiumViewer/index.js | 1 - gulpfile.js | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 Apps/CesiumViewer/index.js diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 2226c85e8fa..f2d303300b6 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -1,6 +1,7 @@ -if (window.CESIUM_BASE_URL === undefined) { - window.CESIUM_BASE_URL = "../../Build/CesiumUnminified/"; -} +// eslint-disable-next-line no-undef +window.CESIUM_BASE_URL = window.CESIUM_BASE_URL + ? window.CESIUM_BASE_URL + : "../../Build/CesiumUnminified/"; import { Cartesian3, diff --git a/Apps/CesiumViewer/index.js b/Apps/CesiumViewer/index.js deleted file mode 100644 index f4e3e3d56f2..00000000000 --- a/Apps/CesiumViewer/index.js +++ /dev/null @@ -1 +0,0 @@ -window.CESIUM_BASE_URL = "."; diff --git a/gulpfile.js b/gulpfile.js index ef228912e4f..51a36176f10 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2230,7 +2230,8 @@ async function buildCesiumViewer() { ".png": "text", }; config.format = "iife"; - config.inject = ["Apps/CesiumViewer/index.js"]; + // Configure Cesium base path to use built + config.define = { CESIUM_BASE_URL: `"."` }; config.external = ["https", "http", "url", "zlib"]; config.outdir = cesiumViewerOutputDirectory; config.outbase = "Apps/CesiumViewer"; @@ -2247,7 +2248,7 @@ async function buildCesiumViewer() { ".gif": "text", ".png": "text", }, - outdir: cesiumViewerOutputDirectory, + outdir: join(cesiumViewerOutputDirectory, "Widgets"), outbase: "packages/widgets/Source/", }); From 0cabc3be7af9d3e97d593998ce0cf8b916a30454 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 11:10:16 -0400 Subject: [PATCH 594/679] Update CHANGES.md --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 500fee77e16..ef4b13f8183 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,13 +6,14 @@ ##### Additions :tada: -- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromIonAssetId`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. +- Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromIonAssetId`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, and `createWorldTerrainAsync` for better async flow and error handling. [#11059](https://github.com/CesiumGS/cesium/pull/11059) ##### Fixes :wrench: - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) - Fixed error type to be `RequestErrorEvent` in `Resource.retryCallback`. [#11177](https://github.com/CesiumGS/cesium/pull/11177) - Fixed `SingleTileImageryProvider` fetching image when `show` is `false` by allowing lazy-loading for `SingleTileImageryProvider` if `tileWidth` and `tileHeight` are provided to the constructor. [#9529](https://github.com/CesiumGS/cesium/issues/9529) +- Fixed various race conditions from async operations. [#10909](https://github.com/CesiumGS/cesium/issues/10909) ##### Deprecated :hourglass_flowing_sand: From 12a2f2899e15969895a59ff9ae34eed46d2ec255 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 29 Mar 2023 11:15:05 -0400 Subject: [PATCH 595/679] Update ion URL in RequestScheduler --- packages/engine/Source/Core/RequestScheduler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index a0e4b63c8e4..43542ad80cc 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -76,7 +76,7 @@ RequestScheduler.maximumRequestsPerServer = 6; */ RequestScheduler.requestsByServer = { "api.cesium.com:443": 18, - "assets.cesium.com:443": 18, + "assets.ion.cesium.com:443": 18, }; /** From f4bc9c40df37e6ad5679212e09c2b933ec32693b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 10:46:25 -0400 Subject: [PATCH 596/679] Update dev dependencies --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f755bdb9a61..5122b730fd4 100644 --- a/package.json +++ b/package.json @@ -97,14 +97,14 @@ "karma-jasmine": "^5.1.0", "karma-longest-reporter": "^1.1.0", "karma-safari-launcher": "^1.0.0", - "karma-sourcemap-loader": "^0.3.8", + "karma-sourcemap-loader": "^0.4.0", "karma-spec-reporter": "^0.0.36", "markdownlint-cli": "^0.33.0", "merge-stream": "^2.0.0", "mime": "^3.0.0", "mkdirp": "^2.1.3", "node-fetch": "^3.2.10", - "open": "^8.2.1", + "open": "^9.1.0", "p-limit": "^4.0.0", "prettier": "2.1.2", "prismjs": "^1.28.0", @@ -114,7 +114,7 @@ "rollup-plugin-strip-pragma": "^1.0.0", "stream-to-promise": "^3.0.0", "tsd-jsdoc": "^2.5.0", - "typescript": "^4.9.4", + "typescript": "^5.0.2", "yargs": "^17.0.1" }, "scripts": { @@ -167,4 +167,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} From 14bfce8648a412cd4272a379443c3bcb49423c38 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 12:27:04 -0400 Subject: [PATCH 597/679] Tweaked travis scripts to ensure encrypted variables are available for internal tasks --- travis/coverage.sh | 2 +- travis/deploy.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/coverage.sh b/travis/coverage.sh index d718e9a5d6b..f4c929ec6cf 100755 --- a/travis/coverage.sh +++ b/travis/coverage.sh @@ -4,7 +4,7 @@ if [ $TRAVIS_BRANCH != "cesium.com" ]; then npm --silent run build npm --silent run coverage -- --browsers FirefoxHeadless --webgl-stub --failTaskOnError --suppressPassed - if [ $TRAVIS_REPO_SLUG == "CesiumGS/cesium" ]; then + if [ $TRAVIS_SECURE_ENV_VARS ]; then aws s3 sync ./Build/Coverage s3://cesium-dev/cesium/$TRAVIS_BRANCH/Build/Coverage --delete --color on fi fi diff --git a/travis/deploy.sh b/travis/deploy.sh index b1ec01abbaf..26cab879a9f 100755 --- a/travis/deploy.sh +++ b/travis/deploy.sh @@ -1,6 +1,6 @@ #!/bin/bash set -ev -if [ $TRAVIS_REPO_SLUG == "CesiumGS/cesium" ]; then +if [ $TRAVIS_SECURE_ENV_VARS ]; then # Files deployed to cesium.com are "production", and should be cached at edge locations for # better performance. Otherwise, this is a development deploy and nothing should be cached if [ $TRAVIS_BRANCH == "cesium.com" ]; then From f593afa79b03994833e8f4ea4c46bd6b068a546c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Wed, 29 Mar 2023 12:37:23 -0400 Subject: [PATCH 598/679] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 65b98282d57..c0141480942 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - Fixed issue where passing `children` in the Entity constructor options will override children. [#11101](https://github.com/CesiumGS/cesium/issues/11101) - Fixed error type to be `RequestErrorEvent` in `Resource.retryCallback`. [#11177](https://github.com/CesiumGS/cesium/pull/11177) +- Fixed ion URL in `RequestScheduler` throttling overrides. [#11193](https://github.com/CesiumGS/cesium/pull/11193) #### @cesium/widgets From 36b4c39bd2b05f1c5650f16fccb26f03441f1b75 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 12:39:12 -0400 Subject: [PATCH 599/679] Fix documentation type --- packages/engine/Source/Core/CesiumTerrainProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index 26da3ade269..c1cb21357ce 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -1205,7 +1205,7 @@ CesiumTerrainProvider.prototype.getLevelMaximumGeometricError = function ( * <li> {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/heightmap-1.0 Height Map} </li> * </ul> * - * @param {Resource|String|Promise<Resource>|Promise<String>} url The URL of the Cesium terrain server. + * @param {number} assetId The Cesium ion asset id. * @param {CesiumTerrainProvider.ConstructorOptions} [options] An object describing initialization options. * @returns {Promise<CesiumTerrainProvider>} * From 601943527080dc943335c78f2816bc0ed15cb8a1 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 14:00:50 -0400 Subject: [PATCH 600/679] Remove readyPromise from i3s spec --- .../Specs/DataSources/ModelVisualizerSpec.js | 2 +- .../engine/Specs/Scene/I3SDataProviderSpec.js | 83 +++++++++---------- packages/engine/Specs/Scene/I3SNodeSpec.js | 4 +- .../Specs/Scene/ImageryLayerCollectionSpec.js | 2 +- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index afd6cef84f3..e58b15b04c2 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -694,7 +694,7 @@ describe( ModelVisualizer, "_sampleTerrainMostDetailed" ).and.callFake(() => { - return Promise.reject(); + return Promise.reject(404); }); // Initialize the Entity and the ModelGraphics. diff --git a/packages/engine/Specs/Scene/I3SDataProviderSpec.js b/packages/engine/Specs/Scene/I3SDataProviderSpec.js index 780ff4b9834..5bd98270246 100644 --- a/packages/engine/Specs/Scene/I3SDataProviderSpec.js +++ b/packages/engine/Specs/Scene/I3SDataProviderSpec.js @@ -483,7 +483,7 @@ describe("Scene/I3SDataProvider", function () { expect(testProvider._extent.north).toEqual(CesiumMath.toRadians(3)); }); - it("loads i3s provider", function () { + it("loads i3s provider", async function () { spyOn(I3SDataProvider, "_fetchJson").and.callFake(function (resource) { if (resource.url.endsWith("mockProviderUrl/layers/0/mockRootNodeUrl/")) { return Promise.resolve(mockRootNodeData); @@ -491,36 +491,33 @@ describe("Scene/I3SDataProvider", function () { return Promise.resolve(mockProviderData); } - return Promise.reject(); + return Promise.reject("invalid i3s request"); }); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl", + const testProvider = await I3SDataProvider.fromUrl("mockProviderUrl", { name: "testProvider", geoidTiledTerrainProvider: mockGeoidProvider, }); - return testProvider.readyPromise.then(function () { - expect(testProvider.ready).toBe(true); + expect(testProvider.ready).toBe(true); - // Layers have been populated and root node is loaded - expect(testProvider.layers.length).toEqual(1); - expect(testProvider.layers[0].rootNode.tile).toBeDefined(); - expect(testProvider.layers[0].rootNode.tile.i3sNode).toEqual( - testProvider.layers[0].rootNode - ); + // Layers have been populated and root node is loaded + expect(testProvider.layers.length).toEqual(1); + expect(testProvider.layers[0].rootNode.tile).toBeDefined(); + expect(testProvider.layers[0].rootNode.tile.i3sNode).toEqual( + testProvider.layers[0].rootNode + ); - // Expect geoid data to have been loaded - expect(testProvider._geoidDataList.length).toEqual(1); - expect(testProvider._geoidDataList[0].height).toEqual(2); - expect(testProvider._geoidDataList[0].width).toEqual(2); - expect(testProvider._geoidDataList[0].buffer).toEqual( - new Float32Array([4, 5, 6, 7]) - ); - }); + // Expect geoid data to have been loaded + expect(testProvider._geoidDataList.length).toEqual(1); + expect(testProvider._geoidDataList[0].height).toEqual(2); + expect(testProvider._geoidDataList[0].width).toEqual(2); + expect(testProvider._geoidDataList[0].buffer).toEqual( + new Float32Array([4, 5, 6, 7]) + ); }); - it("loads i3s provider from single layer url", function () { + it("loads i3s provider from single layer url", async function () { spyOn(I3SDataProvider, "_fetchJson").and.callFake(function (resource) { if (resource.url.endsWith("mockProviderUrl/layers/0/mockRootNodeUrl/")) { return Promise.resolve(mockRootNodeData); @@ -528,32 +525,32 @@ describe("Scene/I3SDataProvider", function () { return Promise.resolve(mockLayerData); } - return Promise.reject(); + return Promise.reject("invalid i3s request"); }); - const testProvider = new I3SDataProvider({ - url: "mockProviderUrl/layers/0/", - name: "testProvider", - geoidTiledTerrainProvider: mockGeoidProvider, - }); + const testProvider = await I3SDataProvider.fromUrl( + "mockProviderUrl/layers/0/", + { + name: "testProvider", + geoidTiledTerrainProvider: mockGeoidProvider, + } + ); - return testProvider.readyPromise.then(function () { - expect(testProvider.ready).toBe(true); + expect(testProvider.ready).toBe(true); - // Layers have been populated and root node is loaded - expect(testProvider.layers.length).toEqual(1); - expect(testProvider.layers[0].rootNode.tile).toBeDefined(); - expect(testProvider.layers[0].rootNode.tile.i3sNode).toEqual( - testProvider.layers[0].rootNode - ); + // Layers have been populated and root node is loaded + expect(testProvider.layers.length).toEqual(1); + expect(testProvider.layers[0].rootNode.tile).toBeDefined(); + expect(testProvider.layers[0].rootNode.tile.i3sNode).toEqual( + testProvider.layers[0].rootNode + ); - // Expect geoid data to have been loaded - expect(testProvider._geoidDataList.length).toEqual(1); - expect(testProvider._geoidDataList[0].height).toEqual(2); - expect(testProvider._geoidDataList[0].width).toEqual(2); - expect(testProvider._geoidDataList[0].buffer).toEqual( - new Float32Array([4, 5, 6, 7]) - ); - }); + // Expect geoid data to have been loaded + expect(testProvider._geoidDataList.length).toEqual(1); + expect(testProvider._geoidDataList[0].height).toEqual(2); + expect(testProvider._geoidDataList[0].width).toEqual(2); + expect(testProvider._geoidDataList[0].buffer).toEqual( + new Float32Array([4, 5, 6, 7]) + ); }); }); diff --git a/packages/engine/Specs/Scene/I3SNodeSpec.js b/packages/engine/Specs/Scene/I3SNodeSpec.js index 5e7e25beab0..4b22bbfa9e0 100644 --- a/packages/engine/Specs/Scene/I3SNodeSpec.js +++ b/packages/engine/Specs/Scene/I3SNodeSpec.js @@ -1147,7 +1147,7 @@ describe("Scene/I3SNode", function () { return Promise.resolve(nodeWithContent); } - return Promise.reject(); + return Promise.reject("invalid i3s node"); }); return nodeWithMesh @@ -1210,7 +1210,7 @@ describe("Scene/I3SNode", function () { return Promise.resolve(nodeWithContent); } - return Promise.reject(); + return Promise.reject("invalid i3s node"); }); await nodeWithMesh.load(); diff --git a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js index 6558c5d1991..d37f669aa22 100644 --- a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js @@ -746,7 +746,7 @@ describe( if (level !== 1 || (x === 0 && y === 0)) { return ImageryProvider.loadImage(this, "Data/Images/Blue.png"); } - return Promise.reject(); + return Promise.reject("invalid tile"); }, }; From dfc4eb87037c7ef594aa865ab0d5c3e25ec87276 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 29 Mar 2023 16:32:07 -0400 Subject: [PATCH 601/679] Send X-Cesium-Client header in ion requests --- packages/engine/Source/Core/IonResource.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/engine/Source/Core/IonResource.js b/packages/engine/Source/Core/IonResource.js index 137be3899ee..8c4c24cff1d 100644 --- a/packages/engine/Source/Core/IonResource.js +++ b/packages/engine/Source/Core/IonResource.js @@ -197,6 +197,7 @@ IonResource.prototype._makeRequest = function (options) { options.headers = {}; } options.headers.Authorization = `Bearer ${this._ionEndpoint.accessToken}`; + options.headers["X-Cesium-Client"] = "CesiumJS"; return Resource.prototype._makeRequest.call(this, options); }; From bbff4e6b57b02ba7ef94badc3a6754699966b0ed Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 30 Mar 2023 09:20:41 -0400 Subject: [PATCH 602/679] Set cesium client version headers for ion requests --- build.js | 2 +- packages/engine/Source/Core/IonResource.js | 4 ++++ packages/engine/Specs/Core/IonResourceSpec.js | 24 +++++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/build.js b/build.js index ba6f6f545be..447ca315cd7 100644 --- a/build.js +++ b/build.js @@ -853,7 +853,7 @@ export function bundleCombinedSpecs(options) { * @returns */ export async function createIndexJs(workspace) { - let contents = ""; + let contents = `globalThis.CESIUM_VERSION = "${version}";\n`; // Iterate over all provided source files for the workspace and export the assignment based on file name. const workspaceSources = workspaceSourceFiles[workspace]; diff --git a/packages/engine/Source/Core/IonResource.js b/packages/engine/Source/Core/IonResource.js index 8c4c24cff1d..383b924f945 100644 --- a/packages/engine/Source/Core/IonResource.js +++ b/packages/engine/Source/Core/IonResource.js @@ -198,6 +198,10 @@ IonResource.prototype._makeRequest = function (options) { } options.headers.Authorization = `Bearer ${this._ionEndpoint.accessToken}`; options.headers["X-Cesium-Client"] = "CesiumJS"; + /* global CESIUM_VERSION */ + if (typeof CESIUM_VERSION !== "undefined") { + options.headers["X-Cesium-Client-Version"] = CESIUM_VERSION; + } return Resource.prototype._makeRequest.call(this, options); }; diff --git a/packages/engine/Specs/Core/IonResourceSpec.js b/packages/engine/Specs/Core/IonResourceSpec.js index b9e785322fb..754bbbb030c 100644 --- a/packages/engine/Specs/Core/IonResourceSpec.js +++ b/packages/engine/Specs/Core/IonResourceSpec.js @@ -175,9 +175,9 @@ describe("Core/IonResource", function () { it("Calls base _makeRequest with expected options when resource no Authorization header is defined", function () { const originalOptions = {}; const expectedOptions = { - headers: { + headers: jasmine.objectContaining({ Authorization: `Bearer ${endpoint.accessToken}`, - }, + }), }; const _makeRequest = spyOn(Resource.prototype, "_makeRequest"); @@ -190,9 +190,9 @@ describe("Core/IonResource", function () { it("Calls base _makeRequest with expected options when resource Authorization header is already defined", function () { const originalOptions = {}; const expectedOptions = { - headers: { + headers: jasmine.objectContaining({ Authorization: `Bearer ${endpoint.accessToken}`, - }, + }), }; const _makeRequest = spyOn(Resource.prototype, "_makeRequest"); @@ -203,6 +203,22 @@ describe("Core/IonResource", function () { expect(_makeRequest).toHaveBeenCalledWith(expectedOptions); }); + it("Calls base _makeRequest including X-Cesium-* headers", function () { + const originalOptions = {}; + const expectedOptions = { + headers: jasmine.objectContaining({ + "X-Cesium-Client": "CesiumJS", + "X-Cesium-Client-Version": jasmine.stringContaining("1."), + }), + }; + + const _makeRequest = spyOn(Resource.prototype, "_makeRequest"); + const endpointResource = IonResource._createEndpointResource(assetId); + const resource = new IonResource(endpoint, endpointResource); + resource._makeRequest(originalOptions); + expect(_makeRequest).toHaveBeenCalledWith(expectedOptions); + }); + it("Calls base _makeRequest with no changes for external assets", function () { const externalEndpoint = { type: "3DTILES", From 1a6e14544da408bef9f8711be2283218b613548f Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 30 Mar 2023 09:28:24 -0400 Subject: [PATCH 603/679] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 06888e445cd..e7f06044755 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ try { ##### Additions :tada: - Added `ArcGisMapServerImageryProvider.fromUrl`, `ArcGISTiledElevationTerrainProvider.fromUrl`, `BingMapsImageryProvider.fromUrl`, `CesiumTerrainProvider.fromUrl`, `CesiumTerrainProvider.fromIonAssetId`, `GoogleEarthEnterpriseMetadata.fromUrl`, `GoogleEarthEnterpriseImageryProvider.fromMetadata`, `GoogleEarthEnterpriseMapsProvider.fromUrl`, `GoogleEarthEnterpriseTerrainProvider.fromMetadata`, `ImageryLayer.fromProviderAsync`, `IonImageryProvider.fromAssetId`, `SingleTileImageryProvider.fromUrl`, `Terrain`, `TileMapServiceImageryProvider.fromUrl`, `VRTheWorldTerrainProvider.fromUrl`, `createWorldTerrainAsync`, `Cesium3DTileset.fromUrl`, `Cesium3DTileset.fromIonAssetId`, `createOsmBuildingsAsync`, `Model.fromGltfAsync`, `Model.readyEvent`, `Model.errorEvent`,`Model.texturesReadyEvent`, `I3SDataProvider.fromUrl`, and `Cesium3DTilesVoxelProvider.fromUrl` for better async flow and error handling. [#11059](https://github.com/CesiumGS/cesium/pull/11059) +- Send `X-Cesium-*` headers to requests to cesium ion. [#11200](https://github.com/CesiumGS/cesium/pull/11200) ##### Fixes :wrench: From b80a4bfc1a639434da378ed5ad65f7bb7474fe96 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 30 Mar 2023 11:01:32 -0400 Subject: [PATCH 604/679] Fix doc --- packages/engine/Source/Scene/Model/ModelAnimationCollection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js index eb104751032..6953a928069 100644 --- a/packages/engine/Source/Scene/Model/ModelAnimationCollection.js +++ b/packages/engine/Source/Scene/Model/ModelAnimationCollection.js @@ -123,7 +123,7 @@ function addAnimation(collection, animation, options) { * @param {ModelAnimation.AnimationTimeCallback} [options.animationTime=undefined] If defined, computes the local animation time for this animation. * @returns {ModelAnimation} The animation that was added to the collection. * - * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#readyPromise} to resolve. + * @exception {DeveloperError} Animations are not loaded. Wait for the {@link Model#ready} to return trues. * @exception {DeveloperError} options.name must be a valid animation name. * @exception {DeveloperError} options.index must be a valid animation index. * @exception {DeveloperError} Either options.name or options.index must be defined. From 084194467bad739af6a65e40f32ed290dae9f0e6 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 31 Mar 2023 13:12:29 -0400 Subject: [PATCH 605/679] Don't create contexts in global scope in specs --- .../Contributors/TestingGuide/README.md | 36 +++++++ packages/engine/Specs/Renderer/BufferSpec.js | 94 +++++++++---------- .../Specs/Scene/Vector3DTileGeometrySpec.js | 42 ++++----- .../Specs/Scene/Vector3DTilePolygonsSpec.js | 23 ++--- .../engine/Specs/createWebglVersionHelper.js | 25 +++++ 5 files changed, 128 insertions(+), 92 deletions(-) create mode 100644 packages/engine/Specs/createWebglVersionHelper.js diff --git a/Documentation/Contributors/TestingGuide/README.md b/Documentation/Contributors/TestingGuide/README.md index b8a315f5bb3..b7ccdb1e527 100644 --- a/Documentation/Contributors/TestingGuide/README.md +++ b/Documentation/Contributors/TestingGuide/README.md @@ -383,6 +383,8 @@ We strive to write isolated isolated tests so that a test can be run individuall The tests in the `'WebGL'` category do not strictly follow this pattern. Creating a WebGL context (which is implicit, for example, in `createScene`) is slow. Because it creates a lot of contexts, e.g., one per test, it is not well supported in browsers. So the tests use the pattern in the code example below where a `scene` (or `viewer` or `context`) has the lifetime of the suite using `beforeAll` and `afterAll`. +Due to side-effects, a WebGL context should never be created in the global scope, that is, outside of a `it`, `beforeAll`, `afterAll`, `beforeEach`, or `afterEach` block. Since they create a context, this applies to helper functions `createContext`, `createScene`, and `createViewer`. + ### Rendering Tests Unlike the `Cartesian3` tests we first saw, many tests need to construct the main CesiumJS `Viewer` widget or one of its major components. Low-level renderer tests construct just `Context` (which, itself, has a canvas and WebGL context), and primitive tests construct a `Scene` (which contains a `Context`). @@ -503,6 +505,40 @@ it("can declare automatic uniforms", function () { }); ``` +#### Test in WebGL 1 and WebGL 2 + +Sometimes, it's helpful to run rendering test in both WebGL 1 and WebGL 2 contexts to verify code works in either case. `createWebglVersionHelper` is a helper function that duplicates a block of specs in each context, and only runs WebGL 2 if supported by the environment. + +For example, the following code will execute the spec `"can create a vertex buffer from a size in bytes"` twice, once in a WebGL 1 context and once in a WebGL 2 context. + +```js +createWebglVersionHelper(createBufferSpecs); + +function createBufferSpecs(contextOptions) { + let buffer; + let buffer2; + let context; + + beforeAll(function () { + context = createContext(contextOptions); + }); + + afterAll(function () { + context.destroyForSpecs(); + }); + + it("can create a vertex buffer from a size in bytes", function () { + buffer = Buffer.createVertexBuffer({ + context: context, + sizeInBytes: 4, + usage: BufferUsage.STATIC_DRAW, + }); + expect(buffer.sizeInBytes).toEqual(4); + expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); + }); +} +``` + #### Debugging Rendering Tests Rendering tests typically render to a 1x1 pixel canvas. This is so each test runs as diff --git a/packages/engine/Specs/Renderer/BufferSpec.js b/packages/engine/Specs/Renderer/BufferSpec.js index 18bbbd0cc9b..666cdd8e3b1 100644 --- a/packages/engine/Specs/Renderer/BufferSpec.js +++ b/packages/engine/Specs/Renderer/BufferSpec.js @@ -1,23 +1,17 @@ import { IndexDatatype, Buffer, BufferUsage } from "../../index.js"; +import createWebglVersionHelper from "../createWebglVersionHelper.js"; import createContext from "../../../../Specs/createContext.js"; describe( "Renderer/Buffer", function () { - createBufferSpecs({}); - const c = createContext({}); - // Don't repeat WebGL 1 tests when WebGL 2 is not supported - if (c.webgl2) { - createBufferSpecs({}); - } - c.destroyForSpecs(); + createWebglVersionHelper(createBufferSpecs); function createBufferSpecs(contextOptions) { - let context; let buffer; let buffer2; - const webglMessage = contextOptions.requestWebgl1 ? "" : ": WebGL 2"; + let context; beforeAll(function () { context = createContext(contextOptions); @@ -36,7 +30,7 @@ describe( } }); - it(`throws when creating a vertex buffer with no context${webglMessage}`, function () { + it(`throws when creating a vertex buffer with no context`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ sizeInBytes: 4, @@ -45,7 +39,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating a vertex buffer with an invalid typed array${webglMessage}`, function () { + it(`throws when creating a vertex buffer with an invalid typed array`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, @@ -55,7 +49,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating a vertex buffer with both a typed array and size in bytes${webglMessage}`, function () { + it(`throws when creating a vertex buffer with both a typed array and size in bytes`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, @@ -66,7 +60,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating a vertex buffer without a typed array or size in bytes${webglMessage}`, function () { + it(`throws when creating a vertex buffer without a typed array or size in bytes`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, @@ -75,7 +69,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating a vertex buffer with invalid usage${webglMessage}`, function () { + it(`throws when creating a vertex buffer with invalid usage`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, @@ -85,7 +79,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating a vertex buffer with size of zero${webglMessage}`, function () { + it(`throws when creating a vertex buffer with size of zero`, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, @@ -95,7 +89,7 @@ describe( }).toThrowDeveloperError(); }); - it(`creates vertex buffer${webglMessage}`, function () { + it(`creates vertex buffer`, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 16, @@ -106,7 +100,7 @@ describe( expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); }); - it(`copies array to a vertex buffer${webglMessage}`, function () { + it(`copies array to a vertex buffer`, function () { const sizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; const vertices = new ArrayBuffer(sizeInBytes); const positions = new Float32Array(vertices); @@ -122,7 +116,7 @@ describe( buffer.copyFromArrayView(vertices); }); - it(`can create a vertex buffer from a typed array${webglMessage}`, function () { + it(`can create a vertex buffer from a typed array`, function () { const typedArray = new Float32Array(3); typedArray[0] = 1.0; typedArray[1] = 2.0; @@ -137,7 +131,7 @@ describe( expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); }); - it(`can create a vertex buffer from a size in bytes${webglMessage}`, function () { + it(`can create a vertex buffer from a size in bytes`, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, @@ -147,7 +141,7 @@ describe( expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); }); - it(`throws when creating an index buffer with no context${webglMessage}`, function () { + it(`throws when creating an index buffer with no context`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ sizeInBytes: 4, @@ -157,7 +151,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer with an invalid typed array${webglMessage}`, function () { + it(`throws when creating an index buffer with an invalid typed array`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -168,7 +162,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer with both a typed array and size in bytes${webglMessage}`, function () { + it(`throws when creating an index buffer with both a typed array and size in bytes`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -180,7 +174,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer without a typed array or size in bytes${webglMessage}`, function () { + it(`throws when creating an index buffer without a typed array or size in bytes`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -190,7 +184,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer with invalid usage${webglMessage}`, function () { + it(`throws when creating an index buffer with invalid usage`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -201,7 +195,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer with invalid index data type${webglMessage}`, function () { + it(`throws when creating an index buffer with invalid index data type`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -212,7 +206,7 @@ describe( }).toThrowDeveloperError(); }); - it(`throws when creating an index buffer with size of zero${webglMessage}`, function () { + it(`throws when creating an index buffer with size of zero`, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, @@ -223,7 +217,7 @@ describe( }).toThrowDeveloperError(); }); - it(`creates index buffer${webglMessage}`, function () { + it(`creates index buffer`, function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 6, @@ -239,7 +233,7 @@ describe( expect(buffer.numberOfIndices).toEqual(3); }); - it(`copies array to an index buffer${webglMessage}`, function () { + it(`copies array to an index buffer`, function () { const sizeInBytes = 3 * Uint16Array.BYTES_PER_ELEMENT; const elements = new ArrayBuffer(sizeInBytes); const indices = new Uint16Array(elements); @@ -256,7 +250,7 @@ describe( buffer.copyFromArrayView(elements); }); - it(`can create an index buffer from a typed array${webglMessage}`, function () { + it(`can create an index buffer from a typed array`, function () { const typedArray = new Uint16Array(3); typedArray[0] = 1; typedArray[1] = 2; @@ -273,7 +267,7 @@ describe( expect(buffer.indexDatatype).toEqual(IndexDatatype.UNSIGNED_SHORT); }); - it(`can create an index buffer from a size in bytes${webglMessage}`, function () { + it(`can create an index buffer from a size in bytes`, function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 6, @@ -285,7 +279,7 @@ describe( expect(buffer.indexDatatype).toEqual(IndexDatatype.UNSIGNED_SHORT); }); - it(`getBufferData throws without WebGL 2${webglMessage}`, function () { + it(`getBufferData throws without WebGL 2`, function () { if (context.webgl2) { return; } @@ -302,7 +296,7 @@ describe( }).toThrowDeveloperError(); }); - it(`getBufferData throws without arrayView${webglMessage}`, function () { + it(`getBufferData throws without arrayView`, function () { if (!context.webgl2) { return; } @@ -318,7 +312,7 @@ describe( }).toThrowDeveloperError(); }); - it(`getBufferData throws with invalid sourceOffset${webglMessage}`, function () { + it(`getBufferData throws with invalid sourceOffset`, function () { if (!context.webgl2) { return; } @@ -338,7 +332,7 @@ describe( }).toThrowDeveloperError(); }); - it(`getBufferData throws with invalid destinationOffset${webglMessage}`, function () { + it(`getBufferData throws with invalid destinationOffset`, function () { if (!context.webgl2) { return; } @@ -358,7 +352,7 @@ describe( }).toThrowDeveloperError(); }); - it(`getBufferData throws with invalid length${webglMessage}`, function () { + it(`getBufferData throws with invalid length`, function () { if (!context.webgl2) { return; } @@ -378,7 +372,7 @@ describe( }).toThrowDeveloperError(); }); - it(`getBufferData reads from vertex buffer${webglMessage}`, function () { + it(`getBufferData reads from vertex buffer`, function () { if (!context.webgl2) { return; } @@ -401,7 +395,7 @@ describe( expect(destArray).toEqual(typedArray); }); - it(`getBufferData reads from index buffer${webglMessage}`, function () { + it(`getBufferData reads from index buffer`, function () { if (!context.webgl2) { return; } @@ -423,7 +417,7 @@ describe( expect(destArray).toEqual(typedArray); }); - it(`copyFromBuffer throws without WebGL 2${webglMessage}`, function () { + it(`copyFromBuffer throws without WebGL 2`, function () { if (context.webgl2) { return; } @@ -444,7 +438,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws without readBuffer${webglMessage}`, function () { + it(`copyFromBuffer throws without readBuffer`, function () { if (!context.webgl2) { return; } @@ -460,7 +454,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws with invalid readOffset${webglMessage}`, function () { + it(`copyFromBuffer throws with invalid readOffset`, function () { if (!context.webgl2) { return; } @@ -487,7 +481,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws with invalid writeOffset${webglMessage}`, function () { + it(`copyFromBuffer throws with invalid writeOffset`, function () { if (!context.webgl2) { return; } @@ -514,7 +508,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws with invalid sizeInBytes${webglMessage}`, function () { + it(`copyFromBuffer throws with invalid sizeInBytes`, function () { if (!context.webgl2) { return; } @@ -544,7 +538,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws with one index buffer and the other is not an index buffer${webglMessage}`, function () { + it(`copyFromBuffer throws with one index buffer and the other is not an index buffer`, function () { if (!context.webgl2) { return; } @@ -568,7 +562,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer throws when readBuffer is the same buffer and copy range overlaps${webglMessage}`, function () { + it(`copyFromBuffer throws when readBuffer is the same buffer and copy range overlaps`, function () { if (!context.webgl2) { return; } @@ -587,7 +581,7 @@ describe( }).toThrowDeveloperError(); }); - it(`copyFromBuffer with vertex buffers${webglMessage}`, function () { + it(`copyFromBuffer with vertex buffers`, function () { if (!context.webgl2) { return; } @@ -616,7 +610,7 @@ describe( expect(destArray).toEqual(typedArray); }); - it(`copyFromBuffer with index buffers${webglMessage}`, function () { + it(`copyFromBuffer with index buffers`, function () { if (!context.webgl2) { return; } @@ -647,7 +641,7 @@ describe( expect(destArray).toEqual(typedArray); }); - it(`destroys${webglMessage}`, function () { + it(`destroys`, function () { const b = Buffer.createIndexBuffer({ context: context, sizeInBytes: 3, @@ -659,7 +653,7 @@ describe( expect(b.isDestroyed()).toEqual(true); }); - it(`fails to provide an array view${webglMessage}`, function () { + it(`fails to provide an array view`, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 3, @@ -670,7 +664,7 @@ describe( }).toThrowDeveloperError(); }); - it(`fails to copy a large array view${webglMessage}`, function () { + it(`fails to copy a large array view`, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 3, @@ -683,7 +677,7 @@ describe( }).toThrowDeveloperError(); }); - it(`fails to destroy${webglMessage}`, function () { + it(`fails to destroy`, function () { const b = Buffer.createIndexBuffer({ context: context, sizeInBytes: 3, diff --git a/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js b/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js index f5c9d67609b..32d9365f8e1 100644 --- a/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js +++ b/packages/engine/Specs/Scene/Vector3DTileGeometrySpec.js @@ -22,24 +22,16 @@ import { Vector3DTileGeometry, } from "../../index.js"; -import createContext from "../../../../Specs/createContext.js"; +import createWebglVersionHelper from "../createWebglVersionHelper.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; describe( "Scene/Vector3DTileGeometry", function () { - createGeometrySpecs({}); - const c = createContext({}); - // Don't repeat WebGL 1 tests when WebGL 2 is not supported - if (c.webgl2) { - createGeometrySpecs({}); - } - c.destroyForSpecs(); + createWebglVersionHelper(createGeometrySpecs); function createGeometrySpecs(contextOptions) { - const webglMessage = contextOptions.requestWebgl1 ? "" : "WebGL 2"; - let scene; let rectangle; let geometry; @@ -330,7 +322,7 @@ describe( }); } - it(`renders a single box${webglMessage}`, function () { + it(`renders a single box`, function () { const dimensions = new Cartesian3(1000000.0, 1000000.0, 1000000.0); const boxes = packBoxes([ { @@ -350,7 +342,7 @@ describe( }); }); - it(`renders multiple boxes${webglMessage}`, function () { + it(`renders multiple boxes`, function () { const dimensions = new Cartesian3(500000.0, 500000.0, 500000.0); const modelMatrices = [ Matrix4.fromTranslation(new Cartesian3(dimensions.x, 0.0, 0.0)), @@ -378,7 +370,7 @@ describe( }); }); - it(`renders a single cylinder${webglMessage}`, function () { + it(`renders a single cylinder`, function () { const radius = 1000000.0; const length = 1000000.0; const cylinders = packCylinders([ @@ -400,7 +392,7 @@ describe( }); }); - it(`renders multiple cylinders${webglMessage}`, function () { + it(`renders multiple cylinders`, function () { const radius = 500000.0; const length = 500000.0; const modelMatrices = [ @@ -431,7 +423,7 @@ describe( }); }); - it(`renders a single ellipsoid${webglMessage}`, function () { + it(`renders a single ellipsoid`, function () { const radii = new Cartesian3(500000.0, 500000.0, 500000.0); const ellipsoid = packEllipsoids([ { @@ -451,7 +443,7 @@ describe( }); }); - it(`renders multiple ellipsoids${webglMessage}`, function () { + it(`renders multiple ellipsoids`, function () { const radii = new Cartesian3(500000.0, 500000.0, 500000.0); const modelMatrices = [ Matrix4.fromTranslation(new Cartesian3(radii.x, 0.0, 0.0)), @@ -479,7 +471,7 @@ describe( }); }); - it(`renders a single sphere${webglMessage}`, function () { + it(`renders a single sphere`, function () { const radius = 500000.0; const sphere = packSpheres([ { @@ -496,7 +488,7 @@ describe( }); }); - it(`renders multiple spheres${webglMessage}`, function () { + it(`renders multiple spheres`, function () { const radius = 500000.0; const modelMatrices = [ Matrix4.fromTranslation(new Cartesian3(radius, 0.0, 0.0)), @@ -521,7 +513,7 @@ describe( }); }); - it(`renders with multiple types of each geometry${webglMessage}`, function () { + it(`renders with multiple types of each geometry`, function () { const dimensions = new Cartesian3(125000.0, 125000.0, 125000.0); const modelMatrices = [ Matrix4.fromTranslation(new Cartesian3(dimensions.x, 0.0, 0.0)), @@ -607,7 +599,7 @@ describe( }); }); - it(`renders multiple geometries after a re-batch${webglMessage}`, function () { + it(`renders multiple geometries after a re-batch`, function () { const dimensions = new Cartesian3(125000.0, 125000.0, 125000.0); const modelMatrices = [ Matrix4.fromTranslation(new Cartesian3(dimensions.x, 0.0, 0.0)), @@ -701,7 +693,7 @@ describe( }); }); - it(`renders with inverted classification${webglMessage}`, function () { + it(`renders with inverted classification`, function () { const radii = new Cartesian3(100.0, 100.0, 1000.0); const ellipsoids = packEllipsoids([ { @@ -756,7 +748,7 @@ describe( }); }); - it(`renders wireframe${webglMessage}`, function () { + it(`renders wireframe`, function () { const origin = Rectangle.center(rectangle); const center = ellipsoid.cartographicToCartesian(origin); const modelMatrix = Transforms.eastNorthUpToFixedFrame(center); @@ -796,7 +788,7 @@ describe( }); }); - it(`renders based on classificationType${webglMessage}`, function () { + it(`renders based on classificationType`, function () { const radii = new Cartesian3(100.0, 100.0, 1000.0); const ellipsoids = packEllipsoids([ { @@ -866,7 +858,7 @@ describe( }); }); - it(`picks geometry${webglMessage}`, function () { + it(`picks geometry`, function () { const origin = Rectangle.center(rectangle); const center = ellipsoid.cartographicToCartesian(origin); const modelMatrix = Transforms.eastNorthUpToFixedFrame(center); @@ -914,7 +906,7 @@ describe( }); }); - it(`isDestroyed${webglMessage}`, function () { + it(`isDestroyed`, function () { geometry = new Vector3DTileGeometry({}); expect(geometry.isDestroyed()).toEqual(false); geometry.destroy(); diff --git a/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js b/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js index 0388cf89f10..ef14b4d4b60 100644 --- a/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTilePolygonsSpec.js @@ -6,6 +6,7 @@ import { destroyObject, Ellipsoid, GeometryInstance, + Math as CesiumMath, Rectangle, RectangleGeometry, Pass, @@ -19,31 +20,19 @@ import { Vector3DTilePolygons, } from "../../index.js"; -import { Math as CesiumMath } from "../../index.js"; - -import createContext from "../../../../Specs/createContext.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; -// Testing of this feature in WebGL is currently disabled due to test -// failures that started in https://github.com/CesiumGS/cesium/pull/8600. -// Classification does NOT work reliably in WebGL2 anyway, see -// https://github.com/CesiumGS/cesium/issues/8629 -const testInWebGL2 = false; - describe( "Scene/Vector3DTilePolygons", function () { createPolygonSpecs({}); - if (testInWebGL2) { - const c = createContext({}); - // Don't repeat WebGL 1 tests when WebGL 2 is not supported - if (c.webgl2) { - createPolygonSpecs({}); - } - c.destroyForSpecs(); - } + // Testing of this feature in WebGL is currently disabled due to test + // failures that started in https://github.com/CesiumGS/cesium/pull/8600. + // Classification does NOT work reliably in WebGL2 anyway, see + // https://github.com/CesiumGS/cesium/issues/8629 + //createWebglVersionHelper(createPolygonSpecs); function createPolygonSpecs(contextOptions) { const webglMessage = contextOptions.requestWebgl1 ? "" : "WebGL 2"; diff --git a/packages/engine/Specs/createWebglVersionHelper.js b/packages/engine/Specs/createWebglVersionHelper.js new file mode 100644 index 00000000000..c08b5ee688e --- /dev/null +++ b/packages/engine/Specs/createWebglVersionHelper.js @@ -0,0 +1,25 @@ +/** + * Repeats a block of specs in Webgl1 and Webgl2, if supported + * @param {createSpecCallback} createSpecs + */ +export default function createWebglVersionHelper(createSpecs) { + describe("with WebGL 1", function () { + createSpecs({ + requestWebgl1: true, + }); + }); + + describe("with WebGL 2", function () { + // Don't repeat tests unless WebGL 2 is supported + if (typeof WebGL2RenderingContext !== "undefined") { + createSpecs(); + } + }); +} + +/** + * @callback createSpecCallback + * + * @param {ContextOptions} [contextOptions] options used to initialize context + * + */ From 3e3a965114998273ce885431a2cdb2b1c49d4542 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 3 Apr 2023 13:05:46 -0400 Subject: [PATCH 606/679] Fix bug with orthographic zoom --- packages/engine/Source/Scene/ScreenSpaceCameraController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index d3a00212e3a..c08c3c298aa 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -592,7 +592,7 @@ function handleZoom( if (camera.frustum instanceof OrthographicFrustum) { if (Math.abs(distance) > 0.0) { camera.zoomIn(distance); - camera._adjustOrthographicFrustum(); + camera._adjustOrthographicFrustum(true); } return; } From 1db5c0483171d3c16347dd070525a2f48b871062 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 3 Apr 2023 13:10:57 -0400 Subject: [PATCH 607/679] Update CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e7f06044755..0be912062aa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.105 - 2023-05-01 + +#### @cesium/engine + +##### Fixes :wrench: + +- Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) + ### 1.104 - 2023-04-03 #### Major Announcements :loudspeaker: From 1e59b4c4614d3d211d05541a22d3924521ef3714 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 3 Apr 2023 14:28:55 -0400 Subject: [PATCH 608/679] Set depthTestAgainstTerrain when using the viewer with baseLayerPicker enabled --- packages/engine/Source/Scene/DepthPlane.js | 2 +- packages/widgets/Source/Viewer/Viewer.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/DepthPlane.js b/packages/engine/Source/Scene/DepthPlane.js index 75cf1465a75..234ae355b31 100644 --- a/packages/engine/Source/Scene/DepthPlane.js +++ b/packages/engine/Source/Scene/DepthPlane.js @@ -125,7 +125,7 @@ DepthPlane.prototype.update = function (frameState) { const context = frameState.context; - // Allow offsetting the ellipsoid radius to address rendering artefacts below ellipsoid zero elevation. + // Allow offsetting the ellipsoid radius to address rendering artifacts below ellipsoid zero elevation. const radii = frameState.mapProjection.ellipsoid.radii; const ellipsoid = new Ellipsoid( radii.x + this._ellipsoidOffset, diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index ab404d8a009..995bbe1ac12 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -720,6 +720,8 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to if (createBaseLayerPicker) { baseLayerPicker.viewModel.selectedTerrain = undefined; + // Required as this is otherwise set by the baseLayerPicker + scene.globe.depthTestAgainstTerrain = true; } scene.setTerrain(options.terrain); From f0ed0c60c9f4ce7c6ff791d373a7a63e446f2499 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 3 Apr 2023 15:54:32 -0400 Subject: [PATCH 609/679] Replace calls to deprecated methods in Sandcastles --- Apps/Sandcastle/gallery/Cesium OSM Buildings.html | 3 ++- Apps/Sandcastle/gallery/Clouds.html | 3 ++- packages/engine/Source/Scene/ImageryLayer.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html index 6c1d6d635b5..f2d56ece3eb 100755 --- a/Apps/Sandcastle/gallery/Cesium OSM Buildings.html +++ b/Apps/Sandcastle/gallery/Cesium OSM Buildings.html @@ -42,7 +42,8 @@ terrain: Cesium.Terrain.fromWorldTerrain(), }); - viewer.scene.primitives.add(Cesium.createOsmBuildings()); + const osmBuildingsTileset = await Cesium.createOsmBuildingsAsync(); + viewer.scene.primitives.add(osmBuildingsTileset); viewer.scene.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(-74.019, 40.6912, 750), diff --git a/Apps/Sandcastle/gallery/Clouds.html b/Apps/Sandcastle/gallery/Clouds.html index 356a94f9c7f..9a71daad41a 100644 --- a/Apps/Sandcastle/gallery/Clouds.html +++ b/Apps/Sandcastle/gallery/Clouds.html @@ -39,7 +39,8 @@ }); const scene = viewer.scene; - scene.primitives.add(Cesium.createOsmBuildings()); + const osmBuildingsTileset = await Cesium.createOsmBuildingsAsync(); + scene.primitives.add(osmBuildingsTileset); /////////////////////////// // Create clouds diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 15af84c1537..0e41bf62b0e 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -684,7 +684,7 @@ const terrainRectangleScratch = new Rectangle(); ImageryLayer.prototype.getViewableRectangle = async function () { deprecationWarning( "ImageryLayer.getViewableRectangle", - "ImageryLayer.getViewableRectangle was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.getImageryRectangle instead." + "ImageryLayer.getViewableRectangle was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.getImageryRectangle instead." ); const imageryProvider = this._imageryProvider; From e5fc2cbe85ca24fd8c877e1bfdba346eea4f9b74 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 3 Apr 2023 16:05:31 -0400 Subject: [PATCH 610/679] Ensure flyTo is not using deprecated API --- packages/widgets/Source/Viewer/Viewer.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 995bbe1ac12..151cae40ce5 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2137,8 +2137,22 @@ function zoomToOrFly(that, zoomTarget, options, isFlight) { //If the zoom target is a rectangular imagery in an ImageLayer if (zoomTarget instanceof ImageryLayer) { - zoomTarget - .getViewableRectangle() + let rectanglePromise; + + if (defined(zoomTarget.imageryProvider)) { + // This is here for backward compatibility. It can be removed when readyPromise is removed. + rectanglePromise = zoomTarget.imageryProvider._readyPromise.then(() => { + return zoomTarget.getImageryRectangle(); + }); + } else { + rectanglePromise = new Promise((resolve) => { + const removeListener = zoomTarget.readyEvent.addEventListener(() => { + removeListener(); + resolve(zoomTarget.getImageryRectangle()); + }); + }); + } + rectanglePromise .then(function (rectangle) { return computeFlyToLocationForRectangle(rectangle, that.scene); }) From 372175a458ca61fc7c907e82a7637e55d4b19596 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Mon, 3 Apr 2023 16:22:06 -0400 Subject: [PATCH 611/679] Updates for 1.104 release --- CHANGES.md | 2 +- ThirdParty.json | 2 +- package.json | 6 +++--- packages/engine/Source/Core/Ion.js | 2 +- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e7f06044755..98a39b76df1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -94,7 +94,7 @@ try { ##### Deprecated :hourglass_flowing_sand: -- `Viewer` constructor option `options.imageryProvider` haw been deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `options.baseLayer` instead. +- `Viewer` constructor option `options.imageryProvider` has been deprecated in CesiumJS 1.104. It will be removed in 1.107. Use `options.baseLayer` instead. ### 1.103 - 2023-03-01 diff --git a/ThirdParty.json b/ThirdParty.json index 24aa6825dc1..799d0c9ed08 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -150,7 +150,7 @@ "license": [ "BSD-3-Clause" ], - "version": "7.2.2", + "version": "7.2.3", "url": "https://www.npmjs.com/package/protobufjs" }, { diff --git a/package.json b/package.json index 5122b730fd4..2d396870654 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.103.0", + "version": "1.104.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.1.0", - "@cesium/widgets": "2.1.0" + "@cesium/engine": "2.2.0", + "@cesium/widgets": "2.1.1" }, "devDependencies": { "@aws-sdk/client-s3": "^3.276.0", diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index 30ccb28c53d..874652dbe41 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,7 +4,7 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4ZTMwYjM0Yy1lYTdkLTQ5YjEtOTUyYS01Y2YxMjE5OWJjMmEiLCJpZCI6MjU5LCJpYXQiOjE2Nzc2Nzk3MTZ9.OGOiqPh0He1XDVU6azp_c5w3jJcmPXcA1briVUcyrvQ"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYjk1OWEzOS0wM2UzLTQ1MmItYjVhNi0xOGE2NDAyNDc4ZjYiLCJpZCI6MjU5LCJpYXQiOjE2ODA1MzgxNTl9.ANfifMhFxb5agKqgDghPl1R__jvaz6dcEbkoNFM-txE"; /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/package.json b/packages/engine/package.json index b69507f5fa0..7fb12468fc1 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "2.1.0", + "version": "2.2.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 9dc62ba1b8d..eb17b13a769 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "2.1.0", + "version": "2.1.1", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "2.1.0", + "@cesium/engine": "2.2.0", "nosleep.js": "^0.12.0" }, "type": "module", From 62d1091f6a6f9a86c1cccb244bb0b1059737f36d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 4 Apr 2023 09:14:18 -0400 Subject: [PATCH 612/679] Update release schedule --- .slackbot.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.slackbot.yml b/.slackbot.yml index 21e55140377..f1b54f977c8 100644 --- a/.slackbot.yml +++ b/.slackbot.yml @@ -1,6 +1,8 @@ -# List of Slack usernames (not GitHub) for the Cesium Concierge Slackbot to send release reminders for. releaseSchedule: - ggetz, 1/2/2023 - jjhembd, 2/1/2023 - ggetz, 3/1/2023 - jjhembd, 4/3/2023 + - ggetz, 5/1/2023 + -jjhembd, 6/1/2023 + - ggetz, 7/1/2023 From 5789679b2a5051ac270052201241f29bc0bdebca Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 4 Apr 2023 10:45:47 -0400 Subject: [PATCH 613/679] Ensure offcenterFrustum's values are updated --- packages/engine/Source/Core/FrustumGeometry.js | 5 +++-- .../engine/Source/Core/OrthographicFrustum.js | 13 +++++++++++++ packages/engine/Source/Core/PerspectiveFrustum.js | 14 ++++++++++++++ packages/engine/Source/Renderer/UniformState.js | 5 +++-- packages/engine/Source/Scene/Camera.js | 15 ++++++++------- packages/engine/Source/Scene/Cesium3DTile.js | 5 +++-- packages/engine/Source/Scene/Picking.js | 5 +++-- packages/engine/Source/Scene/QuadtreePrimitive.js | 5 +++-- packages/engine/Source/Scene/SceneTransforms.js | 5 +++-- .../engine/Specs/Core/OrthographicFrustumSpec.js | 8 ++++---- .../engine/Specs/Core/PerspectiveFrustumSpec.js | 4 ++-- 11 files changed, 59 insertions(+), 25 deletions(-) diff --git a/packages/engine/Source/Core/FrustumGeometry.js b/packages/engine/Source/Core/FrustumGeometry.js index 0446378d326..46fcb8cfb78 100644 --- a/packages/engine/Source/Core/FrustumGeometry.js +++ b/packages/engine/Source/Core/FrustumGeometry.js @@ -327,8 +327,9 @@ FrustumGeometry._computeNearFarPlanes = function ( ); if (!defined(inverseViewProjection)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } const near = frustumSplits[i]; diff --git a/packages/engine/Source/Core/OrthographicFrustum.js b/packages/engine/Source/Core/OrthographicFrustum.js index 6e45f6b1b19..e94dcb86810 100644 --- a/packages/engine/Source/Core/OrthographicFrustum.js +++ b/packages/engine/Source/Core/OrthographicFrustum.js @@ -184,6 +184,19 @@ Object.defineProperties(OrthographicFrustum.prototype, { return this._offCenterFrustum.projectionMatrix; }, }, + /** + * Gets the orthographic projection matrix computed from the view frustum. + * @memberof OrthographicFrustum.prototype + * @type {OrthographicOffCenterFrustum} + * @readonly + * @private + */ + offCenterFrustum: { + get: function () { + update(this); + return this._offCenterFrustum; + }, + }, }); /** diff --git a/packages/engine/Source/Core/PerspectiveFrustum.js b/packages/engine/Source/Core/PerspectiveFrustum.js index 2290af9c9c0..0442961c533 100644 --- a/packages/engine/Source/Core/PerspectiveFrustum.js +++ b/packages/engine/Source/Core/PerspectiveFrustum.js @@ -274,6 +274,20 @@ Object.defineProperties(PerspectiveFrustum.prototype, { return this._sseDenominator; }, }, + + /** + * Gets the orthographic projection matrix computed from the view frustum. + * @memberof PerspectiveFrustum.prototype + * @type {PerspectiveOffCenterFrustum} + * @readonly + * @private + */ + offCenterFrustum: { + get: function () { + update(this); + return this._offCenterFrustum; + }, + }, }); /** diff --git a/packages/engine/Source/Renderer/UniformState.js b/packages/engine/Source/Renderer/UniformState.js index 75e55c25da0..4447269e10d 100644 --- a/packages/engine/Source/Renderer/UniformState.js +++ b/packages/engine/Source/Renderer/UniformState.js @@ -1173,8 +1173,9 @@ UniformState.prototype.updateFrustum = function (frustum) { this._oneOverLog2FarDepthFromNearPlusOne = 1.0 / this._log2FarDepthFromNearPlusOne; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } this._frustumPlanes.x = frustum.top; diff --git a/packages/engine/Source/Scene/Camera.js b/packages/engine/Source/Scene/Camera.js index caab469d1b3..0ecb9179283 100644 --- a/packages/engine/Source/Scene/Camera.js +++ b/packages/engine/Source/Scene/Camera.js @@ -2602,9 +2602,8 @@ function rectangleCameraPosition3D(camera, rectangle, result, updateCamera) { let rightScalar; let topScalar; - const ratio = - camera.frustum._offCenterFrustum.right / - camera.frustum._offCenterFrustum.top; + const offCenterFrustum = camera.frustum._offCenterFrustum; + const ratio = offCenterFrustum.right / offCenterFrustum.top; const heightRatio = height * ratio; if (width > heightRatio) { rightScalar = width; @@ -2950,8 +2949,9 @@ function getPickRayOrthographic(camera, windowPosition, result) { const height = canvas.clientHeight; let frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } let x = (2.0 / width) * windowPosition.x - 1.0; x *= (frustum.right - frustum.left) * 0.5; @@ -3440,8 +3440,9 @@ function distanceToBoundingSphere3D(camera, radius) { function distanceToBoundingSphere2D(camera, radius) { let frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } let right, top; diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 713472c0ee4..f2a3da5163a 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -917,8 +917,9 @@ Cesium3DTile.prototype.getScreenSpaceError = function ( frameState.mode === SceneMode.SCENE2D || frustum instanceof OrthographicFrustum ) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } const pixelSize = Math.max(frustum.top - frustum.bottom, frustum.right - frustum.left) / diff --git a/packages/engine/Source/Scene/Picking.js b/packages/engine/Source/Scene/Picking.js index 22c18426f0d..780659f5411 100644 --- a/packages/engine/Source/Scene/Picking.js +++ b/packages/engine/Source/Scene/Picking.js @@ -92,8 +92,9 @@ function getPickOrthographicCullingVolume( ) { const camera = scene.camera; let frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } let x = (2.0 * (drawingBufferPosition.x - viewport.x)) / viewport.width - 1.0; diff --git a/packages/engine/Source/Scene/QuadtreePrimitive.js b/packages/engine/Source/Scene/QuadtreePrimitive.js index 37ba1b3bd0d..19ffded98cb 100644 --- a/packages/engine/Source/Scene/QuadtreePrimitive.js +++ b/packages/engine/Source/Scene/QuadtreePrimitive.js @@ -1275,8 +1275,9 @@ function screenSpaceError(primitive, frameState, tile) { function screenSpaceError2D(primitive, frameState, tile) { const camera = frameState.camera; let frustum = camera.frustum; - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } const context = frameState.context; diff --git a/packages/engine/Source/Scene/SceneTransforms.js b/packages/engine/Source/Scene/SceneTransforms.js index 7110adbfcf6..ec23eb92498 100644 --- a/packages/engine/Source/Scene/SceneTransforms.js +++ b/packages/engine/Source/Scene/SceneTransforms.js @@ -432,8 +432,9 @@ SceneTransforms.drawingBufferToWgs84Coordinates = function ( let worldCoords; let frustum = scene.camera.frustum; if (!defined(frustum.fovy)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; + const offCenterFrustum = frustum.offCenterFrustum; + if (defined(offCenterFrustum)) { + frustum = offCenterFrustum; } worldCoords = scratchWorldCoords; worldCoords.x = diff --git a/packages/engine/Specs/Core/OrthographicFrustumSpec.js b/packages/engine/Specs/Core/OrthographicFrustumSpec.js index 82b904a00f9..1a65cbaba34 100644 --- a/packages/engine/Specs/Core/OrthographicFrustumSpec.js +++ b/packages/engine/Specs/Core/OrthographicFrustumSpec.js @@ -138,8 +138,7 @@ describe("Core/OrthographicFrustum", function () { }); it("get orthographic projection matrix", function () { - const projectionMatrix = frustum.projectionMatrix; - frustum = frustum._offCenterFrustum; + frustum = frustum.offCenterFrustum; const expected = Matrix4.computeOrthographicOffCenter( frustum.left, frustum.right, @@ -149,6 +148,7 @@ describe("Core/OrthographicFrustum", function () { frustum.far, new Matrix4() ); + const projectionMatrix = frustum.projectionMatrix; expect(projectionMatrix).toEqualEpsilon(expected, CesiumMath.EPSILON6); }); @@ -217,7 +217,7 @@ describe("Core/OrthographicFrustum", function () { pixelRatio, new Cartesian2() ); - const expected = frustum._offCenterFrustum.getPixelDimensions( + const expected = frustum.offCenterFrustum.getPixelDimensions( dimensions.x, dimensions.y, distance, @@ -239,7 +239,7 @@ describe("Core/OrthographicFrustum", function () { pixelRatio, new Cartesian2() ); - const expected = frustum._offCenterFrustum.getPixelDimensions( + const expected = frustum.offCenterFrustum.getPixelDimensions( dimensions.x, dimensions.y, distance, diff --git a/packages/engine/Specs/Core/PerspectiveFrustumSpec.js b/packages/engine/Specs/Core/PerspectiveFrustumSpec.js index e8bbfb002e8..afea2402bfd 100644 --- a/packages/engine/Specs/Core/PerspectiveFrustumSpec.js +++ b/packages/engine/Specs/Core/PerspectiveFrustumSpec.js @@ -250,7 +250,7 @@ describe("Core/PerspectiveFrustum", function () { pixelRatio, new Cartesian2() ); - const expected = frustum._offCenterFrustum.getPixelDimensions( + const expected = frustum.offCenterFrustum.getPixelDimensions( dimensions.x, dimensions.y, distance, @@ -272,7 +272,7 @@ describe("Core/PerspectiveFrustum", function () { pixelRatio, new Cartesian2() ); - const expected = frustum._offCenterFrustum.getPixelDimensions( + const expected = frustum.offCenterFrustum.getPixelDimensions( dimensions.x, dimensions.y, distance, From 477960715b5cdbe42b06c9f31a7013974708049d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 4 Apr 2023 11:03:31 -0400 Subject: [PATCH 614/679] Update CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 98a39b76df1..9a8512b9cb2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.105 - 2023-05-01 + +#### @cesium/engine + +##### Fixes :wrench: + +- Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) + ### 1.104 - 2023-04-03 #### Major Announcements :loudspeaker: From 6201846987e80681779f7f7238849ab221ce7c1b Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Tue, 4 Apr 2023 18:43:06 +0300 Subject: [PATCH 615/679] Update CHANGES.md for atmosphere rendering performance fix --- CHANGES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index b2e896226f2..a4c019b4137 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log +#### @cesium/engine + +##### Fixes :wrench: + +- Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) + ### 1.104 - 2023-04-03 #### @cesium/engine From c2b7a86a7ba0e6f6d878633ef71150f8ef999230 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Thu, 16 Mar 2023 19:36:54 -0400 Subject: [PATCH 616/679] Use Matrix4.multiplyTransformation to update tile transforms --- packages/engine/Source/Scene/Cesium3DTile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Cesium3DTile.js b/packages/engine/Source/Scene/Cesium3DTile.js index 713472c0ee4..59fb5db8d9f 100644 --- a/packages/engine/Source/Scene/Cesium3DTile.js +++ b/packages/engine/Source/Scene/Cesium3DTile.js @@ -1796,7 +1796,7 @@ Cesium3DTile.prototype.createBoundingVolume = function ( */ Cesium3DTile.prototype.updateTransform = function (parentTransform) { parentTransform = defaultValue(parentTransform, Matrix4.IDENTITY); - const computedTransform = Matrix4.multiply( + const computedTransform = Matrix4.multiplyTransformation( parentTransform, this.transform, scratchTransform From 390e0b91f37d2d17ba8d9597a869e79f85baa46a Mon Sep 17 00:00:00 2001 From: Guillaume Lathoud <glat@glat.info> Date: Wed, 5 Apr 2023 07:12:30 +0300 Subject: [PATCH 617/679] Update AtmosphereCommon.glsl: syntax adjustments --- .../engine/Source/Shaders/AtmosphereCommon.glsl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/engine/Source/Shaders/AtmosphereCommon.glsl b/packages/engine/Source/Shaders/AtmosphereCommon.glsl index 8cdde711964..84acc525565 100644 --- a/packages/engine/Source/Shaders/AtmosphereCommon.glsl +++ b/packages/engine/Source/Shaders/AtmosphereCommon.glsl @@ -8,6 +8,8 @@ uniform vec3 u_atmosphereRayleighCoefficient; uniform vec3 u_atmosphereMieCoefficient; const float ATMOSPHERE_THICKNESS = 111e3; // The thickness of the atmosphere in meters. +const int PRIMARY_STEPS_MAX = 16; // Maximum number of times the ray from the camera to the world position (primary ray) is sampled. +const int LIGHT_STEPS_MAX = 4; // Maximum number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. /** * Rational approximation to tanh(x) @@ -76,8 +78,8 @@ void computeScattering( // (2) within atmosphere we need fewer steps for faster rendering float x_o_a = start_0 - ATMOSPHERE_THICKNESS; // ATMOSPHERE_THICKNESS used as an ad-hoc constant, no precise meaning here, only the order of magnitude matters float w_inside_atmosphere = 1.0 - 0.5 * (1.0 + approximateTanh(x_o_a)); - int PRIMARY_STEPS = int(16.0 - w_inside_atmosphere * 12.0); // Number of times the ray from the camera to the world position (primary ray) is sampled. - int LIGHT_STEPS = int(4.0 - w_inside_atmosphere * 2.0); // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. + int PRIMARY_STEPS = PRIMARY_STEPS_MAX - int(w_inside_atmosphere * 12.0); // Number of times the ray from the camera to the world position (primary ray) is sampled. + int LIGHT_STEPS = LIGHT_STEPS_MAX - int(w_inside_atmosphere * 2.0); // Number of times the light is sampled from the light source's intersection with the atmosphere to a sample position on the primary ray. // Setup for sampling positions along the ray - starting from the intersection with the outer ring of the atmosphere. float rayPositionLength = primaryRayAtmosphereIntersect.start; @@ -93,12 +95,13 @@ void computeScattering( vec2 heightScale = vec2(u_atmosphereRayleighScaleHeight, u_atmosphereMieScaleHeight); // Sample positions on the primary ray. - for (int i = 0; i < 999999999; ++i) { + for (int i = 0; i < PRIMARY_STEPS_MAX; ++i) { // The loop should be: for (int i = 0; i < PRIMARY_STEPS; ++i) {...} but WebGL1 cannot // loop with non-constant condition, so it has to break early instead - if (i >= PRIMARY_STEPS) + if (i >= PRIMARY_STEPS) { break; + } // Calculate sample position along viewpoint ray. vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength); @@ -120,12 +123,13 @@ void computeScattering( vec2 lightOpticalDepth = vec2(0.0); // Sample positions along the light ray, to accumulate incidence of light on the latest sample segment. - for (int j = 0; j < 999999999; ++j) { + for (int j = 0; j < LIGHT_STEPS_MAX; ++j) { // The loop should be: for (int j = 0; i < LIGHT_STEPS; ++j) {...} but WebGL1 cannot // loop with non-constant condition, so it has to break early instead - if (j >= LIGHT_STEPS) + if (j >= LIGHT_STEPS) { break; + } // Calculate sample position along light ray. vec3 lightPosition = samplePosition + lightDirection * (lightPositionLength + lightStepLength * 0.5); From 91cde95783d8ca1ac1a87f54104fbe390196f806 Mon Sep 17 00:00:00 2001 From: Joe Stanton <jsromejoe@gmail.com> Date: Wed, 5 Apr 2023 12:47:28 -0400 Subject: [PATCH 618/679] Updated tsd config to include ContextOptions in the widgets typescript definitions --- packages/widgets/tsd-conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/widgets/tsd-conf.json b/packages/widgets/tsd-conf.json index 135bf4d652b..020f98fbd69 100644 --- a/packages/widgets/tsd-conf.json +++ b/packages/widgets/tsd-conf.json @@ -4,6 +4,7 @@ }, "source": { "include": [ + "packages/engine/Source/Renderer/Context.js", "packages/widgets/Source" ], "exclude": [ @@ -29,4 +30,4 @@ "outFile": "index.d.ts", "recurse": true } -} \ No newline at end of file +} From d6183e7e6cd0b36be6840efeb79298bd0a20a3ad Mon Sep 17 00:00:00 2001 From: Joe Stanton <jsromejoe@gmail.com> Date: Wed, 5 Apr 2023 14:27:03 -0400 Subject: [PATCH 619/679] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6d3b2d22a42..41b51a46a92 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -351,3 +351,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [L](https://github.com/L-hikari) - [Jacob Van Dine](https://github.com/JacobVanDine) - [Michael Cabana](https://github.com/mikecabana) +- [Joseph Stanton](https://github.com/romejoe) From 45c5ad5e56b5b2cae84ea2920ce64ae34aa9e887 Mon Sep 17 00:00:00 2001 From: Marco Hutter <javagl@javagl.de> Date: Fri, 7 Apr 2023 17:52:31 +0200 Subject: [PATCH 620/679] Fix scope of proxy definition --- .../engine/Source/Scene/IonImageryProvider.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index e17f6554362..52bc8491510 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -296,18 +296,18 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { return this._imageryProvider.hasAlphaChannel; }, + }, - /** - * Gets the proxy used by this provider. - * @memberof IonImageryProvider.prototype - * @type {Proxy} - * @readonly - * @default undefined - */ - proxy: { - get: function () { - return undefined; - }, + /** + * Gets the proxy used by this provider. + * @memberof IonImageryProvider.prototype + * @type {Proxy} + * @readonly + * @default undefined + */ + proxy: { + get: function () { + return undefined; }, }, From 4503f09f6e5759feb82498c3b15dbffd1f391683 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 7 Apr 2023 13:45:20 -0400 Subject: [PATCH 621/679] Skip coverage deploys for forks --- travis/coverage.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/travis/coverage.sh b/travis/coverage.sh index f4c929ec6cf..c35d714cabc 100755 --- a/travis/coverage.sh +++ b/travis/coverage.sh @@ -4,7 +4,9 @@ if [ $TRAVIS_BRANCH != "cesium.com" ]; then npm --silent run build npm --silent run coverage -- --browsers FirefoxHeadless --webgl-stub --failTaskOnError --suppressPassed - if [ $TRAVIS_SECURE_ENV_VARS ]; then - aws s3 sync ./Build/Coverage s3://cesium-dev/cesium/$TRAVIS_BRANCH/Build/Coverage --delete --color on - fi + # Exit early if AWS credentials are not defined + [ -z "${AWS_ACCESS_KEY_ID}" ] && exit 0; + + # Deploy results + aws s3 sync ./Build/Coverage s3://cesium-dev/cesium/$TRAVIS_BRANCH/Build/Coverage --delete --color on fi From 5064f1093fd9b2d63c3a52997902c3c25e6ab5a5 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 7 Apr 2023 14:03:00 -0400 Subject: [PATCH 622/679] Fix CHANGES.md header --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 20e50af4db9..9e9fd68f7e0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,7 @@ # Change Log +### 1.105 - 2023-05-01 + #### @cesium/engine ##### Fixes :wrench: From e4d0525f3610b295960dfc13897b2eae6b4ecc44 Mon Sep 17 00:00:00 2001 From: Joe Stanton <jsromejoe@gmail.com> Date: Fri, 7 Apr 2023 14:12:40 -0400 Subject: [PATCH 623/679] Updated Changes.md indicating 10963 was fixed --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 9e9fd68f7e0..94f168d6114 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,13 @@ - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) +#### @cesium/widgets + +##### Fixes :wrench: + +- Fixed missing `ContextOptions` in generated TypeScript definitions. [10963](https://github.com/CesiumGS/cesium/issues/10963) + + ### 1.104 - 2023-04-03 #### Major Announcements :loudspeaker: From 91585ff6606168eed4b9e316d0c012ca684312ad Mon Sep 17 00:00:00 2001 From: Joe Stanton <jsromejoe@gmail.com> Date: Fri, 7 Apr 2023 19:25:32 +0000 Subject: [PATCH 624/679] Ran prettier to fix formatting --- CHANGES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 94f168d6114..290f3d15f45 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,7 +14,6 @@ - Fixed missing `ContextOptions` in generated TypeScript definitions. [10963](https://github.com/CesiumGS/cesium/issues/10963) - ### 1.104 - 2023-04-03 #### Major Announcements :loudspeaker: From 7c692f710fc7e44e974b5e0ecaa20450b3c5ff10 Mon Sep 17 00:00:00 2001 From: HuZehua <hzh@bimquan.com> Date: Mon, 10 Apr 2023 14:26:58 +0800 Subject: [PATCH 625/679] Fix some comments of Cesium3DTileset and Viewer --- CONTRIBUTORS.md | 1 + packages/engine/Source/Scene/Cesium3DTileset.js | 6 +++--- packages/widgets/Source/Viewer/Viewer.js | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 87ca3d55980..3a3190dabf2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -353,3 +353,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Jacob Van Dine](https://github.com/JacobVanDine) - [Michael Cabana](https://github.com/mikecabana) - [Joseph Stanton](https://github.com/romejoe) +- [Zehua Hu](https://github.com/lanvada) diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index b36f2c91a06..0f9aad6abf2 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -141,7 +141,7 @@ import Cesium3DTilesetSkipTraversal from "./Cesium3DTilesetSkipTraversal.js"; * try { * const tileset = await Cesium.Cesium3DTileset.fromUrl( * "http://localhost:8002/tilesets/Seattle/tileset.json" - * }); + * ); * scene.primitives.add(tileset); * } catch (error) { * console.error(`Error creating tileset: ${error}`); @@ -2029,7 +2029,7 @@ Cesium3DTileset.fromIonAssetId = async function (assetId, options) { * used for streaming massive heterogeneous 3D geospatial datasets. * * @param {Resource|string} url The url to a tileset JSON file. - * @param {Cesium3DTileset.ConstructorOptions} options An object describing initialization options + * @param {Cesium3DTileset.ConstructorOptions} [options] An object describing initialization options * @returns {Promise<Cesium3DTileset>} * * @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. @@ -2040,7 +2040,7 @@ Cesium3DTileset.fromIonAssetId = async function (assetId, options) { * try { * const tileset = await Cesium.Cesium3DTileset.fromUrl( * "http://localhost:8002/tilesets/Seattle/tileset.json" - * }); + * ); * scene.primitives.add(tileset); * } catch (error) { * console.error(`Error creating tileset: ${error}`); diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 151cae40ce5..ffd43da6c79 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -317,7 +317,7 @@ function enableVRUI(viewer, enabled) { * @property {ImageryProvider|false} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false. Deprecated. * @property {ImageryLayer|false} [baseLayer=ImageryLayer.fromWorldImagery()] The bottommost imagery layer applied to the globe. If set to <code>false</code>, no imagery provider will be added. This value is only valid if `baseLayerPicker` is set to false. * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use - * @property {Terrain} [options.terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. + * @property {Terrain} [terrain] A terrain object which handles asynchronous terrain provider. Can only specify if options.terrainProvider is undefined. * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. * @property {Element|string} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed. From 6f1083e6ceff86ff9adb4a4f111c563e00998a4d Mon Sep 17 00:00:00 2001 From: bbbbx <venus@venusworld.cn> Date: Tue, 11 Apr 2023 20:37:46 +0800 Subject: [PATCH 626/679] Fix rendering of emissive model --- CHANGES.md | 1 + .../Scene/Model/MaterialPipelineStage.js | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 290f3d15f45..b27e93e2d17 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -44,6 +44,7 @@ try { - Fixed ion URL in `RequestScheduler` throttling overrides. [#11193](https://github.com/CesiumGS/cesium/pull/11193) - Fixed `SingleTileImageryProvider` fetching image when `show` is `false` by allowing lazy-loading for `SingleTileImageryProvider` if `tileWidth` and `tileHeight` are provided to the constructor. [#9529](https://github.com/CesiumGS/cesium/issues/9529) - Fixed various race conditions from async operations. [#10909](https://github.com/CesiumGS/cesium/issues/10909) +- Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) ##### Deprecated :hourglass_flowing_sand: diff --git a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js index d049899380d..0d2f200d53b 100644 --- a/packages/engine/Source/Scene/Model/MaterialPipelineStage.js +++ b/packages/engine/Source/Scene/Model/MaterialPipelineStage.js @@ -245,18 +245,6 @@ function processMaterialUniforms( defaultEmissiveTexture, disableTextures ) { - const emissiveTexture = material.emissiveTexture; - if (defined(emissiveTexture) && !disableTextures) { - processTexture( - shaderBuilder, - uniformMap, - emissiveTexture, - "u_emissiveTexture", - "EMISSIVE", - defaultEmissiveTexture - ); - } - const emissiveFactor = material.emissiveFactor; if ( defined(emissiveFactor) && @@ -275,6 +263,18 @@ function processMaterialUniforms( undefined, ShaderDestination.FRAGMENT ); + + const emissiveTexture = material.emissiveTexture; + if (defined(emissiveTexture) && !disableTextures) { + processTexture( + shaderBuilder, + uniformMap, + emissiveTexture, + "u_emissiveTexture", + "EMISSIVE", + defaultEmissiveTexture + ); + } } const normalTexture = material.normalTexture; From 05a6ae1ca48e2b3656e0ef7fb61a10395dbc78c8 Mon Sep 17 00:00:00 2001 From: bbbbx <venus@venusworld.cn> Date: Tue, 11 Apr 2023 21:01:06 +0800 Subject: [PATCH 627/679] Update changelog --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b27e93e2d17..2e6ecce5e10 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ ##### Fixes :wrench: - Fixed missing `ContextOptions` in generated TypeScript definitions. [10963](https://github.com/CesiumGS/cesium/issues/10963) +- Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) ### 1.104 - 2023-04-03 @@ -44,7 +45,6 @@ try { - Fixed ion URL in `RequestScheduler` throttling overrides. [#11193](https://github.com/CesiumGS/cesium/pull/11193) - Fixed `SingleTileImageryProvider` fetching image when `show` is `false` by allowing lazy-loading for `SingleTileImageryProvider` if `tileWidth` and `tileHeight` are provided to the constructor. [#9529](https://github.com/CesiumGS/cesium/issues/9529) - Fixed various race conditions from async operations. [#10909](https://github.com/CesiumGS/cesium/issues/10909) -- Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) ##### Deprecated :hourglass_flowing_sand: From 05c225561a6149d3f41df018edb092ac73909380 Mon Sep 17 00:00:00 2001 From: bbbbx <venus@venusworld.cn> Date: Wed, 12 Apr 2023 00:41:13 +0800 Subject: [PATCH 628/679] Add unit test --- .../Scene/Model/MaterialPipelineStageSpec.js | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js b/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js index c5b9cd0edd5..9c6f090d70a 100644 --- a/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js +++ b/packages/engine/Specs/Scene/Model/MaterialPipelineStageSpec.js @@ -12,6 +12,7 @@ import { ModelAlphaOptions, ModelStatistics, ModelLightingOptions, + ModelComponents, Pass, RenderState, Resource, @@ -257,6 +258,59 @@ describe( }); }); + it("doesn't add emissive uniforms when emissive factor is default", function () { + return loadGltf(boomBox).then(function (gltfLoader) { + const components = gltfLoader.components; + const primitive = components.nodes[0].primitives[0]; + + const material = primitive.material; + material.emissiveFactor = Cartesian3.clone( + ModelComponents.Material.DEFAULT_EMISSIVE_FACTOR + ); + const metallicRoughness = material.metallicRoughness; + + const renderResources = mockRenderResources(); + const shaderBuilder = renderResources.shaderBuilder; + const uniformMap = renderResources.uniformMap; + + MaterialPipelineStage.process( + renderResources, + primitive, + mockFrameState + ); + + ShaderBuilderTester.expectHasVertexUniforms(shaderBuilder, []); + ShaderBuilderTester.expectHasFragmentUniforms(shaderBuilder, [ + "uniform sampler2D u_baseColorTexture;", + "uniform sampler2D u_metallicRoughnessTexture;", + "uniform sampler2D u_normalTexture;", + "uniform sampler2D u_occlusionTexture;", + ]); + + ShaderBuilderTester.expectHasVertexDefines(shaderBuilder, []); + ShaderBuilderTester.expectHasFragmentDefines(shaderBuilder, [ + "HAS_BASE_COLOR_TEXTURE", + "HAS_METALLIC_ROUGHNESS_TEXTURE", + "HAS_NORMAL_TEXTURE", + "HAS_OCCLUSION_TEXTURE", + "TEXCOORD_BASE_COLOR v_texCoord_0", + "TEXCOORD_METALLIC_ROUGHNESS v_texCoord_0", + "TEXCOORD_NORMAL v_texCoord_0", + "TEXCOORD_OCCLUSION v_texCoord_0", + "USE_METALLIC_ROUGHNESS", + ]); + + const expectedUniforms = { + u_normalTexture: material.normalTexture.texture, + u_occlusionTexture: material.occlusionTexture.texture, + u_baseColorTexture: metallicRoughness.baseColorTexture.texture, + u_metallicRoughnessTexture: + metallicRoughness.metallicRoughnessTexture.texture, + }; + expectUniformMap(uniformMap, expectedUniforms); + }); + }); + it("adds specular glossiness uniforms", function () { return loadGltf(boomBoxSpecularGlossiness).then(function (gltfLoader) { const components = gltfLoader.components; From 002002c8e5788c0a3f7c183819b2c70a72e1bce5 Mon Sep 17 00:00:00 2001 From: Jason Summercamp <bbetancova@gmail.com> Date: Tue, 18 Apr 2023 07:50:10 -0600 Subject: [PATCH 629/679] 10957 zoom to entities without globe fix (#11226) * fixed modelvisualizer.js * updated contributors file * added test case and refactored based on feedback * updated CHANGES.md * updated test case * updated test case * updated test case * updated test case * updated test case * updated test case * updated test case * updated test case * updated test case * refactored test case * Move createViewer, move zoomTo test * defined --------- Co-authored-by: Gabby Getz <gabby@cesium.com> --- CHANGES.md | 1 + CONTRIBUTORS.md | 1 + .../Source/DataSources/ModelVisualizer.js | 8 ++-- .../Specs/DataSources/ModelVisualizerSpec.js | 43 +++++++++++++++++-- packages/widgets/Specs/Viewer/ViewerSpec.js | 30 ++++++++++++- .../Specs/Viewer/viewerDragDropMixinSpec.js | 2 +- .../viewerPerformanceWatchdogMixinSpec.js | 2 +- .../widgets/Specs}/createViewer.js | 4 +- 8 files changed, 79 insertions(+), 12 deletions(-) rename {Specs => packages/widgets/Specs}/createViewer.js (82%) diff --git a/CHANGES.md b/CHANGES.md index e7f8741c1e6..4cdd2f46dc1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ - Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) - Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) +- Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) #### @cesium/widgets diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3a3190dabf2..0c8e36eca36 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -354,3 +354,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Michael Cabana](https://github.com/mikecabana) - [Joseph Stanton](https://github.com/romejoe) - [Zehua Hu](https://github.com/lanvada) +- [Jason Summercamp](https://github.com/fullstacc) diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index 1297ad74707..ce216060dd9 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -63,6 +63,7 @@ function ModelVisualizer(scene, entityCollection) { this._entityCollection = entityCollection; this._modelHash = {}; this._entitiesToVisualize = new AssociativeArray(); + this._onCollectionChanged(entityCollection, entityCollection.values, [], []); } @@ -444,11 +445,12 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { const scene = this._scene; const globe = scene.globe; - const ellipsoid = globe.ellipsoid; - const terrainProvider = globe.terrainProvider; + // cannot access a terrain provider if there is no globe; formally set to undefined + const terrainProvider = defined(globe) ? globe.terrainProvider : undefined; const hasHeightReference = model.heightReference !== HeightReference.NONE; - if (hasHeightReference) { + if (defined(globe) && hasHeightReference) { + const ellipsoid = globe.ellipsoid; // We cannot query the availability of the terrain provider till its ready, so the // bounding sphere state will remain pending till the terrain provider is ready. // ready is deprecated. This is here for backwards compatibility diff --git a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js index e58b15b04c2..4c12504069d 100644 --- a/packages/engine/Specs/DataSources/ModelVisualizerSpec.js +++ b/packages/engine/Specs/DataSources/ModelVisualizerSpec.js @@ -39,15 +39,13 @@ describe( let scene; let entityCollection; let visualizer; - let originalTerrainProvider; beforeAll(function () { scene = createScene(); - scene.globe = new Globe(); - originalTerrainProvider = scene.globe.terrainProvider; }); beforeEach(function () { + scene.globe = new Globe(); entityCollection = new EntityCollection(); visualizer = new ModelVisualizer(scene, entityCollection); }); @@ -55,7 +53,6 @@ describe( afterEach(function () { visualizer = visualizer && visualizer.destroy(); entityCollection.removeAll(); - scene.globe.terrainProvider = originalTerrainProvider; }); afterAll(function () { @@ -648,6 +645,44 @@ describe( }); }); + it("computes bounding sphere where globe is undefined", async function () { + scene.globe = undefined; + + const time = JulianDate.now(); + const testObject = entityCollection.getOrCreateEntity("test"); + const model = new ModelGraphics(); + testObject.model = model; + + testObject.position = new ConstantProperty( + new Cartesian3(5678, 1234, 1101112) + ); + model.uri = new ConstantProperty(boxUrl); + visualizer.update(time); + + let primitive; + await pollToPromise(function () { + primitive = scene.primitives.get(0); + return defined(primitive); + }); + + const result = new BoundingSphere(); + let state = visualizer.getBoundingSphere(testObject, result); + expect(state).toBe(BoundingSphereState.PENDING); + + await pollToPromise(function () { + scene.render(); + visualizer.update(time); + state = visualizer.getBoundingSphere(testObject, result); + return state !== BoundingSphereState.PENDING; + }); + expect(state).toBe(BoundingSphereState.DONE); + const expected = BoundingSphere.clone( + primitive.boundingSphere, + new BoundingSphere() + ); + expect(result).toEqual(expected); + }); + it("fails bounding sphere for entity without ModelGraphics", function () { const testObject = entityCollection.getOrCreateEntity("test"); visualizer.update(JulianDate.now()); diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index e2cdec48edd..691d7025d15 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -47,7 +47,7 @@ import { Timeline, } from "../../index.js"; -import createViewer from "../../../../Specs/createViewer.js"; +import createViewer from "../createViewer.js"; import DomEventSimulator from "../../../../Specs/DomEventSimulator.js"; import MockDataSource from "../../../../Specs/MockDataSource.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; @@ -1551,6 +1551,34 @@ describe( }); }); + it("zoomTo zooms to entity when globe is disabled", async function () { + // Create viewer with globe disabled + const viewer = createViewer(container, { + globe: false, + infoBox: false, + selectionIndicator: false, + shadows: true, + shouldAnimate: true, + }); + + // Create position variable + const position = Cartesian3.fromDegrees(-123.0744619, 44.0503706, 1000.0); + + // Add entity to viewer + const entity = viewer.entities.add({ + position: position, + model: { + uri: "../SampleData/models/CesiumAir/Cesium_Air.glb", + }, + }); + + await viewer.zoomTo(entity); + + // Verify that no errors occurred + expect(viewer.scene).toBeDefined(); + expect(viewer.scene.errorEvent).toBeUndefined(); + }); + it("flyTo throws if target is not defined", function () { viewer = createViewer(container); diff --git a/packages/widgets/Specs/Viewer/viewerDragDropMixinSpec.js b/packages/widgets/Specs/Viewer/viewerDragDropMixinSpec.js index c5ca1f8d912..d730ac1f413 100644 --- a/packages/widgets/Specs/Viewer/viewerDragDropMixinSpec.js +++ b/packages/widgets/Specs/Viewer/viewerDragDropMixinSpec.js @@ -2,7 +2,7 @@ import { defined, TimeInterval } from "@cesium/engine"; import { viewerDragDropMixin } from "../../index.js"; -import createViewer from "../../../../Specs/createViewer.js"; +import createViewer from "../createViewer.js"; import DomEventSimulator from "../../../../Specs/DomEventSimulator.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; diff --git a/packages/widgets/Specs/Viewer/viewerPerformanceWatchdogMixinSpec.js b/packages/widgets/Specs/Viewer/viewerPerformanceWatchdogMixinSpec.js index 0590bc95bc0..3526b0304dc 100644 --- a/packages/widgets/Specs/Viewer/viewerPerformanceWatchdogMixinSpec.js +++ b/packages/widgets/Specs/Viewer/viewerPerformanceWatchdogMixinSpec.js @@ -2,7 +2,7 @@ import { PerformanceWatchdog, viewerPerformanceWatchdogMixin, } from "../../index.js"; -import createViewer from "../../../../Specs/createViewer.js"; +import createViewer from "../createViewer.js"; describe( "Widgets/Viewer/viewerPerformanceWatchdogMixin", diff --git a/Specs/createViewer.js b/packages/widgets/Specs/createViewer.js similarity index 82% rename from Specs/createViewer.js rename to packages/widgets/Specs/createViewer.js index 2be7c2a00e3..6a55487f99a 100644 --- a/Specs/createViewer.js +++ b/packages/widgets/Specs/createViewer.js @@ -1,7 +1,7 @@ import { defaultValue } from "@cesium/engine"; -import { Viewer } from "@cesium/widgets"; +import { Viewer } from "../index.js"; -import getWebGLStub from "./getWebGLStub.js"; +import getWebGLStub from "../../../Specs/getWebGLStub.js"; function createViewer(container, options) { options = defaultValue(options, {}); From bf7d09204d194dd30a9e32a0696375c2b34fecd9 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 18 Apr 2023 14:19:35 -0400 Subject: [PATCH 630/679] Allow grabbing gltf through the API --- .../engine/Source/Scene/GltfJsonLoader.js | 12 ++ packages/engine/Source/Scene/GltfLoader.js | 43 +----- packages/engine/Source/Scene/Model/Model.js | 127 ++++++++++++------ .../engine/Specs/Scene/GltfJsonLoaderSpec.js | 26 ++++ packages/engine/Specs/Scene/GltfLoaderSpec.js | 14 -- .../engine/Specs/Scene/Model/ModelSpec.js | 24 ++++ 6 files changed, 152 insertions(+), 94 deletions(-) diff --git a/packages/engine/Source/Scene/GltfJsonLoader.js b/packages/engine/Source/Scene/GltfJsonLoader.js index 616c28a4265..97405b1deda 100644 --- a/packages/engine/Source/Scene/GltfJsonLoader.js +++ b/packages/engine/Source/Scene/GltfJsonLoader.js @@ -5,6 +5,7 @@ import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js"; import getMagic from "../Core/getMagic.js"; import isDataUri from "../Core/isDataUri.js"; import Resource from "../Core/Resource.js"; +import RuntimeError from "../Core/RuntimeError.js"; import addDefaults from "./GltfPipeline/addDefaults.js"; import addPipelineExtras from "./GltfPipeline/addPipelineExtras.js"; import ForEach from "./GltfPipeline/ForEach.js"; @@ -14,6 +15,7 @@ import updateVersion from "./GltfPipeline/updateVersion.js"; import usesExtension from "./GltfPipeline/usesExtension.js"; import ResourceLoader from "./ResourceLoader.js"; import ResourceLoaderState from "./ResourceLoaderState.js"; +import ModelUtility from "./Model/ModelUtility.js"; /** * Loads a glTF JSON from a glTF or glb. @@ -242,6 +244,16 @@ async function processGltfJson(gltfJsonLoader, gltf) { await loadEmbeddedBuffers(gltfJsonLoader, gltf); removePipelineExtras(gltf); + const version = gltf.asset.version; + if (version !== "1.0" && version !== "2.0") { + throw new RuntimeError(`Unsupported glTF version: ${version}`); + } + + const extensionsRequired = gltf.extensionsRequired; + if (defined(extensionsRequired)) { + ModelUtility.checkSupportedExtensions(extensionsRequired); + } + gltfJsonLoader._gltf = gltf; gltfJsonLoader._state = ResourceLoaderState.READY; return gltfJsonLoader; diff --git a/packages/engine/Source/Scene/GltfLoader.js b/packages/engine/Source/Scene/GltfLoader.js index 7d31ff1f09d..42077c0234d 100644 --- a/packages/engine/Source/Scene/GltfLoader.js +++ b/packages/engine/Source/Scene/GltfLoader.js @@ -18,7 +18,6 @@ import getAccessorByteStride from "./GltfPipeline/getAccessorByteStride.js"; import getComponentReader from "./GltfPipeline/getComponentReader.js"; import numberOfComponentsForType from "./GltfPipeline/numberOfComponentsForType.js"; import GltfStructuralMetadataLoader from "./GltfStructuralMetadataLoader.js"; -import ModelUtility from "./Model/ModelUtility.js"; import AttributeType from "./AttributeType.js"; import Axis from "./Axis.js"; import GltfLoaderUtil from "./GltfLoaderUtil.js"; @@ -240,12 +239,6 @@ function GltfLoader(options) { this._loadForClassification = loadForClassification; this._renameBatchIdSemantic = renameBatchIdSemantic; - // This flag will be set in parse() if the KHR_mesh_quantization extension is - // present in extensionsRequired. This flag is used later when parsing - // attributes. When the extension is present, attributes may be stored as - // quantized integer values instead of floats. - this._hasKhrMeshQuantization = false; - // When loading EXT_feature_metadata, the feature tables and textures // are now stored as arrays like the newer EXT_structural_metadata extension. // This requires sorting the dictionary keys for a consistent ordering. @@ -392,26 +385,6 @@ async function loadGltfJson(loader) { return; } - const gltf = gltfJsonLoader.gltf; - const version = gltf.asset.version; - if (version !== "1.0" && version !== "2.0") { - const url = loader._gltfResource.url; - throw new RuntimeError( - `Failed to load ${url}: \nUnsupported glTF version: ${version}` - ); - } - - const extensionsRequired = gltf.extensionsRequired; - if (defined(extensionsRequired)) { - ModelUtility.checkSupportedExtensions(extensionsRequired); - - // Check for the KHR_mesh_quantization extension here, it will be used later - // in loadAttribute(). - loader._hasKhrMeshQuantization = extensionsRequired.includes( - "KHR_mesh_quantization" - ); - } - loader._state = GltfLoaderState.LOADED; loader._textureState = GltfLoaderState.LOADED; @@ -1014,14 +987,7 @@ function setQuantizationFromWeb3dQuantizedAttributes( attribute.quantization = quantization; } -function createAttribute( - gltf, - accessorId, - name, - semantic, - setIndex, - hasKhrMeshQuantization -) { +function createAttribute(gltf, accessorId, name, semantic, setIndex) { const accessor = gltf.accessors[accessorId]; const MathType = AttributeType.getMathType(accessor.type); const normalized = defaultValue(accessor.normalized, false); @@ -1057,6 +1023,10 @@ function createAttribute( // In the glTF 2.0 spec, min and max are not affected by the normalized flag. // However, for KHR_mesh_quantization, min and max must be dequantized for // normalized values, else the bounding sphere will be computed incorrectly. + const hasKhrMeshQuantization = gltf.extensionsRequired?.includes( + "KHR_mesh_quantization" + ); + if (hasKhrMeshQuantization && normalized && isQuantizable) { dequantizeMinMax(attribute, MathType); } @@ -1197,8 +1167,7 @@ function loadAttribute( accessorId, name, modelSemantic, - setIndex, - loader._hasKhrMeshQuantization + setIndex ); if (!defined(draco) && !defined(bufferViewId)) { diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 4b53df8e374..6dd51e324f1 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -112,7 +112,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * @alias Model * @internalConstructor * - * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model. + * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model. Deprecated. * @privateParam {ModelType} options.type Type of this model, to distinguish individual glTF files from 3D Tiles internally. * @privateParam {object} options Object with the following properties: * @privateParam {Resource} options.resource The Resource to the 3D model. @@ -464,7 +464,7 @@ function Model(options) { this._completeTexturesLoad = undefined; this._rejectTexturesLoad = undefined; - // This is for backward compatibility. When readyPromise is removed, this block can be too + // This is for backward compatibility. When readyPromise is removed, _loader and this block can be removed too if (!defined(this._loader._promise)) { this._readyPromise = new Promise((resolve, reject) => { this._completeLoad = () => { @@ -2841,26 +2841,26 @@ Model.fromGltf = function (options) { * <p> * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the .glb extension. * - * @param {Object} options Object with the following properties: - * @param {String|Resource} options.url The url to the .gltf or .glb file. - * @param {String|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to. - * @param {Boolean} [options.show=true] Whether or not to render the model. + * @param {object} options Object with the following properties: + * @param {string|Resource} options.url The url to the .gltf or .glb file. + * @param {string|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to. + * @param {boolean} [options.show=true] Whether or not to render the model. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates. - * @param {Number} [options.scale=1.0] A uniform scale applied to this model. - * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. - * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. - * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. - * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. - * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. - * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. + * @param {number} [options.scale=1.0] A uniform scale applied to this model. + * @param {number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom. + * @param {number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize. + * @param {object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}. + * @param {boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}. + * @param {boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. + * @param {boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. + * @param {boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified. * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from light sources. - * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. - * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. - * @param {Boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. - * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. - * @param {Boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. - * @param {Boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. + * @param {boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective. + * @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. + * @param {boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded. + * @param {boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true. + * @param {boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used. + * @param {boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model. * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model. * @param {Axis} [options.forwardAxis=Axis.Z] The forward-axis of the glTF model. * @param {CustomShader} [options.customShader] A custom shader. This will add user-defined GLSL code to the vertex and fragment shaders. Using custom shaders with a {@link Cesium3DTileStyle} may lead to undefined behavior. @@ -2870,28 +2870,31 @@ Model.fromGltf = function (options) { * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed. * @param {Color} [options.color] A color that blends with the model's rendered color. * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model. - * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. + * @param {number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts. - * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. - * @param {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored. - * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. + * @param {number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. + * @param {boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored. + * @param {boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Cartesian3} [options.lightColor] The light color when shading the model. When <code>undefined</code> the scene's light color is used instead. * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting on this model. - * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. - * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. - * @param {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. + * @param {boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent. + * @param {Credit|string} [options.credit] A credit for the data source, which is displayed on the canvas. + * @param {boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen. * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this model. - * @param {Boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. - * @param {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. - * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting. + * @param {boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded. + * @param {string|number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {string|number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority. + * @param {object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting. * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded. + * @param {Model.GltfCallback} [options.gltfCallback] A function that is called with the loaded gltf object once loaded. * * @returns {Promise<Model>} A promise that resolves to the created model when it is ready to render. * * @exception {RuntimeError} The model failed to load. + * @exception {RuntimeError} Unsupported glTF version. + * @exception {RuntimeError} Unsupported glTF Extension * * @example * // Load a model and add it to the scene @@ -2931,6 +2934,28 @@ Model.fromGltf = function (options) { * } catch (error) { * console.log(`Failed to load model. ${error}`); * } + * + * @example + * // Load a model and play the last animation at half speed + * let animations; + * try { + * const model = await Cesium.Model.fromGltfAsync({ + * url: "../../SampleData/models/CesiumMan/Cesium_Man.glb", + * gltfCallback: gltf => { + * animations = gltf.animations + * } + * }); + * viewer.scene.primitives.add(model); + * model.readyEvent.addEventListener(() => { + * model.activeAnimations.add({ + * index: animations.length - 1, + * loop: Cesium.ModelAnimationLoop.REPEAT, + * multiplier: 0.5, + * }); + * }); + * } catch (error) { + * console.log(`Failed to load model. ${error}`); + * } */ Model.fromGltfAsync = async function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -2988,22 +3013,31 @@ Model.fromGltfAsync = async function (options) { // Further resource loading is handled synchronously in loader.process(), and requires // hooking into model's update() as the frameState is needed await loader.load(); - - const model = new Model(modelOptions); - - const resourceCredits = model._resource.credits; - if (defined(resourceCredits)) { - const length = resourceCredits.length; - for (let i = 0; i < length; i++) { - model._resourceCredits.push(resourceCredits[i]); - } - } - - return model; } catch (error) { loader.destroy(); throw ModelUtility.getError("model", resource, error); } + + const gltfCallback = options.gltfCallback; + if (defined(gltfCallback)) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.func("options.gltfCallback", gltfCallback); + //>>includeEnd('debug'); + + gltfCallback(loader.gltfJson); + } + + const model = new Model(modelOptions); + + const resourceCredits = model._resource.credits; + if (defined(resourceCredits)) { + const length = resourceCredits.length; + for (let i = 0; i < length; i++) { + model._resourceCredits.push(resourceCredits[i]); + } + } + + return model; }; /* @@ -3214,4 +3248,11 @@ function makeModelOptions(loader, modelType, options) { }; } +/** + * Interface for the function that is called with the loaded gltf object once loaded. + * @callback Model.GltfCallback + * + * @param {object} gltf The gltf object + */ + export default Model; diff --git a/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js b/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js index 96561ba3c9a..84549d70126 100644 --- a/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfJsonLoaderSpec.js @@ -598,6 +598,32 @@ describe("Scene/GltfJsonLoader", function () { ); }); + it("load throws if an unsupported extension is required", async function () { + const arrayBuffer = generateJsonBuffer({ + ...gltf1, + extensionsRequired: ["NOT_supported_extension"], + }).buffer; + + spyOn(GltfJsonLoader.prototype, "_fetchGltf").and.returnValue( + Promise.resolve(arrayBuffer) + ); + + spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( + Promise.resolve(new Float32Array([0.0, 0.0, 0.0]).buffer) + ); + + const gltfJsonLoader = new GltfJsonLoader({ + resourceCache: ResourceCache, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + + await expectAsync(gltfJsonLoader.load()).toBeRejectedWithError( + RuntimeError, + "Failed to load glTF: https://example.com/model.glb\nUnsupported glTF Extension: NOT_supported_extension" + ); + }); + it("load throws if glTF fails to process", async function () { const arrayBuffer = generateJsonBuffer(gltf1).buffer; diff --git a/packages/engine/Specs/Scene/GltfLoaderSpec.js b/packages/engine/Specs/Scene/GltfLoaderSpec.js index 53c2d9c2dbd..24a7f780784 100644 --- a/packages/engine/Specs/Scene/GltfLoaderSpec.js +++ b/packages/engine/Specs/Scene/GltfLoaderSpec.js @@ -176,20 +176,6 @@ describe( ); }); - it("load throws if an unsupported extension is required", async function () { - function modifyGltf(gltf) { - gltf.extensionsRequired = ["NOT_supported_extension"]; - return gltf; - } - - await expectAsync( - loadModifiedGltfAndTest(boxTextured, undefined, modifyGltf) - ).toBeRejectedWithError( - RuntimeError, - "Failed to load glTF\nUnsupported glTF Extension: NOT_supported_extension" - ); - }); - function getOptions(gltfPath, options) { const resource = new Resource({ url: gltfPath, diff --git a/packages/engine/Specs/Scene/Model/ModelSpec.js b/packages/engine/Specs/Scene/Model/ModelSpec.js index ee3c3260f58..b454031927a 100644 --- a/packages/engine/Specs/Scene/Model/ModelSpec.js +++ b/packages/engine/Specs/Scene/Model/ModelSpec.js @@ -331,6 +331,30 @@ describe( }); }); + it("calls gltfCallback", function () { + let wasCalled = false; + return loadAndZoomToModelAsync( + { + url: boxTexturedGltfUrl, + gltfCallback: (gltf) => { + wasCalled = true; + expect(gltf).toEqual( + jasmine.objectContaining({ + asset: { generator: "COLLADA2GLTF", version: "2.0" }, + }) + ); + }, + }, + scene + ).then(function (model) { + expect(model.ready).toEqual(true); + expect(model._sceneGraph).toBeDefined(); + expect(model._resourcesLoaded).toEqual(true); + expect(wasCalled).toBeTrue(); + verifyRender(model, true); + }); + }); + it("raises errorEvent when a texture fails to load and incrementallyLoadTextures is true", async function () { const resource = Resource.createIfNeeded(boxTexturedGltfUrl); const gltf = await resource.fetchJson(); From 7210197822772d88b769db66b7ac620d5e06acb1 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 18 Apr 2023 14:25:10 -0400 Subject: [PATCH 631/679] Update CHANGES.md --- CHANGES.md | 4 ++++ packages/engine/Source/Scene/Model/Model.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4cdd2f46dc1..b72acabb278 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,10 @@ #### @cesium/engine +##### Additions :tada: + +- Added `options.gltfCallback` to `Model.loadGltfAsync` to allow apps to access the loaded glTF JSON. [#11240](https://github.com/CesiumGS/cesium/pull/11240) + ##### Fixes :wrench: - Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 6dd51e324f1..b8dfa8bf300 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -112,7 +112,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js"; * @alias Model * @internalConstructor * - * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model. Deprecated. + * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model. * @privateParam {ModelType} options.type Type of this model, to distinguish individual glTF files from 3D Tiles internally. * @privateParam {object} options Object with the following properties: * @privateParam {Resource} options.resource The Resource to the 3D model. @@ -464,7 +464,7 @@ function Model(options) { this._completeTexturesLoad = undefined; this._rejectTexturesLoad = undefined; - // This is for backward compatibility. When readyPromise is removed, _loader and this block can be removed too + // This is for backward compatibility. When readyPromise is removed, this block can be too if (!defined(this._loader._promise)) { this._readyPromise = new Promise((resolve, reject) => { this._completeLoad = () => { From 45a2007b51289464f43b6933e1c8417ae1dd0ca8 Mon Sep 17 00:00:00 2001 From: Tamrat Belayneh <Tamrat-B@users.noreply.github.com> Date: Wed, 19 Apr 2023 07:29:19 -0700 Subject: [PATCH 632/679] Add support for Access Token when creating an ArcGISMapServerImageryProvider (#11098) * Implemented secure arcgis services access. * updated arcgsis icons * changes based on code review * doc language revisions * updates based on review and fixed failing tests * clean up * Cleanup * Cleanup Documentation * Cleanup test * Simplify ArcGIS Developer key storage * Update API key, fix casing, update release guide * Fix changes.md * File case fix --------- Co-authored-by: George Owen <gowen@esri.com> Co-authored-by: Gabby Getz <gabby@cesium.com> --- Apps/Sandcastle/gallery/ArcGIS MapServer.html | 22 +- CHANGES.md | 4 + .../Contributors/ReleaseGuide/README.md | 51 +- .../engine/Source/Scene/ArcGisBaseMapType.js | 12 + .../Scene/ArcGisMapServerImageryProvider.js | 165 ++++- .../engine/Source/Scene/ArcGisMapService.js | 83 +++ .../ArcGisMapServerImageryProviderSpec.js | 587 +++++++++--------- .../Specs/Scene/IonImageryProviderSpec.js | 24 +- .../createDefaultImageryProviderViewModels.js | 60 +- .../ArcGISMapServiceWorldHillshade.png | Bin 0 -> 8624 bytes .../ArcGISMapServiceWorldImagery.png | Bin 0 -> 12290 bytes .../ArcGISMapServiceWorldOcean.png | Bin 0 -> 9905 bytes .../esriNationalGeographic.png | Bin 11555 -> 0 bytes .../ImageryProviders/esriWorldImagery.png | Bin 11575 -> 0 bytes .../ImageryProviders/esriWorldStreetMap.png | Bin 8501 -> 0 bytes 15 files changed, 642 insertions(+), 366 deletions(-) create mode 100644 packages/engine/Source/Scene/ArcGisBaseMapType.js create mode 100644 packages/engine/Source/Scene/ArcGisMapService.js create mode 100644 packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldHillshade.png create mode 100644 packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldImagery.png create mode 100644 packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldOcean.png delete mode 100644 packages/widgets/Source/Images/ImageryProviders/esriNationalGeographic.png delete mode 100644 packages/widgets/Source/Images/ImageryProviders/esriWorldImagery.png delete mode 100644 packages/widgets/Source/Images/ImageryProviders/esriWorldStreetMap.png diff --git a/Apps/Sandcastle/gallery/ArcGIS MapServer.html b/Apps/Sandcastle/gallery/ArcGIS MapServer.html index 007aa861425..327eecd6bf1 100644 --- a/Apps/Sandcastle/gallery/ArcGIS MapServer.html +++ b/Apps/Sandcastle/gallery/ArcGIS MapServer.html @@ -32,13 +32,31 @@ window.startup = async function (Cesium) { "use strict"; //Sandcastle_Begin + // An ArcGIS Access Token is required to authenticate requests to an ArcGIS Image Tile service. + // To access secure ArcGIS resources, you need to create an ArcGIS developer account at https://developers.arcgis.com/, + // then implement an authentication method to obtain an access token. See https://developers.arcgis.com/documentation/mapping-apis-and-services/security + + // The access token can be assigned globally: + // Cesium.ArcGisMapService.defaultAccessToken = <token>; + // or as a token parameter when creating the ArcGisMapServeImageryProvider. + // const viewer = new Cesium.Viewer("cesiumContainer", { + // baseLayer: Cesium.ImageryLayer.fromProviderAsync( + // Cesium.ArcGisMapServerImageryProvider.fromBasemapType( + // Cesium.ArcGisBaseMapType.SATELLITE, { + // token: "<token>" + // })), + // }); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayer: Cesium.ImageryLayer.fromProviderAsync( - Cesium.ArcGisMapServerImageryProvider.fromUrl( - "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/" + Cesium.ArcGisMapServerImageryProvider.fromBasemapType( + Cesium.ArcGisBaseMapType.SATELLITE + // other supported styles include: + // Cesium.ArcGisMapServerImageryProvider.HILLSHADE + // Cesium.ArcGisMapServerImageryProvider.OCEANS ) ), }); + //Sandcastle_End }; if (typeof Cesium !== "undefined") { diff --git a/CHANGES.md b/CHANGES.md index 4cdd2f46dc1..ad1c6640aac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,10 @@ #### @cesium/engine +##### Additions :tada: + +- Added `ArcGisMapServerImagery.fromBasemapType`, and `ArcGisBaseMapType`, and `ArcGisMapService` for ease of use with the latest ArcGIS Imagery API.[#11098](https://github.com/CesiumGS/cesium/pull/11098) + ##### Fixes :wrench: - Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) diff --git a/Documentation/Contributors/ReleaseGuide/README.md b/Documentation/Contributors/ReleaseGuide/README.md index ad81aee8263..971e2b9f15e 100644 --- a/Documentation/Contributors/ReleaseGuide/README.md +++ b/Documentation/Contributors/ReleaseGuide/README.md @@ -21,30 +21,31 @@ There is no release manager; instead, our community shares the responsibility. A 3. Make sure you are using the latest drivers for your video card. 4. Pull down the latest `main` branch and run `npm install`. 5. Update the Cesium ion demo token in `Ion.js` with a new token from the CesiumJS ion team account with read and geocode permissions. These tokens are named like this: `1.85 Release - Delete on November 1st, 2021`. Delete the token from 2 releases ago. -6. Proofread [`CHANGES.md`](../../../CHANGES.md) with the date of the release. Adjust the order of changes so that prominent/popular changes come first. Ensure each change is in the section for the relevant workspace. -7. Based on `CHANGES.md`, update each workspace version following the rules of [semantic versioning](https://semver.org/), e.g., +6. Update the ArcGIS Developer API key in `ArcGisMapService.js` with a new API key from the CesiumJS ArcGIS Developer account. These API keys are named like this: `1.85 Release - Delete on November 1st, 2021`. Delete the API key from 2 releases ago. +7. Proofread [`CHANGES.md`](../../../CHANGES.md) with the date of the release. Adjust the order of changes so that prominent/popular changes come first. Ensure each change is in the section for the relevant workspace. +8. Based on `CHANGES.md`, update each workspace version following the rules of [semantic versioning](https://semver.org/), e.g., - `npm version minor -w @cesium/engine --no-git-tag-version` - If there are no changes, skip updating the workspace version. -8. Update the version in `package.json` to match, e.g. `1.14.0` -> `1.15.0`. -9. Commit these changes. -10. Make sure the repository is clean `git clean -d -x -f`. **This will delete all files not already in the repository.** -11. Run `npm install`. -12. Make sure `ThirdParty.json` is up to date by running `npm run build-third-party`. If there are any changes, verify and commit them. -13. Create the release zip `npm run make-zip`. -14. Run tests against the release `npm run test -- --failTaskOnError --release`. Test **in all browsers** with the `--browsers` flag (i.e. `--browsers Firefox,Chrome`). Alternatively, test with the browser Spec Runner by starting a local server (`npm start`) and browsing to http://localhost:8080/Specs/SpecRunner.html?built=true&release=true. -15. Unpack the release zip to the directory of your choice and start the server by running `npm install` and then `npm start` -16. Browse to http://localhost:8080 and confirm that the home page loads as expected and all links work. -17. Verify that the [documentation](http://localhost:8080/Build/Documentation/index.html) built correctly -18. Make sure [Hello World](http://localhost:8080/Apps/HelloWorld.html) loads. -19. Make sure [Cesium Viewer](http://localhost:8080/Apps/CesiumViewer/index.html) loads. -20. Run [Sandcastle](http://localhost:8080/Apps/Sandcastle/index.html) on the browser of your choice (or multiple browsers if you are up for it). Switch to the `All` tab and run through every demo to make sure they all work. Actually play with each of the buttons and sliders on each demo to ensure everything works as expected. -21. If any of the above steps fail, post a message to the `#cesiumjs` channel in Slack to figure out what needs to be fixed before we can release. **Do NOT proceed to the next step until issues are resolved.** -22. Push your commits to main +9. Update the version in `package.json` to match, e.g. `1.14.0` -> `1.15.0`. +10. Commit these changes. +11. Make sure the repository is clean `git clean -d -x -f`. **This will delete all files not already in the repository.** +12. Run `npm install`. +13. Make sure `ThirdParty.json` is up to date by running `npm run build-third-party`. If there are any changes, verify and commit them. +14. Create the release zip `npm run make-zip`. +15. Run tests against the release `npm run test -- --failTaskOnError --release`. Test **in all browsers** with the `--browsers` flag (i.e. `--browsers Firefox,Chrome`). Alternatively, test with the browser Spec Runner by starting a local server (`npm start`) and browsing to http://localhost:8080/Specs/SpecRunner.html?built=true&release=true. +16. Unpack the release zip to the directory of your choice and start the server by running `npm install` and then `npm start` +17. Browse to http://localhost:8080 and confirm that the home page loads as expected and all links work. +18. Verify that the [documentation](http://localhost:8080/Build/Documentation/index.html) built correctly +19. Make sure [Hello World](http://localhost:8080/Apps/HelloWorld.html) loads. +20. Make sure [Cesium Viewer](http://localhost:8080/Apps/CesiumViewer/index.html) loads. +21. Run [Sandcastle](http://localhost:8080/Apps/Sandcastle/index.html) on the browser of your choice (or multiple browsers if you are up for it). Switch to the `All` tab and run through every demo to make sure they all work. Actually play with each of the buttons and sliders on each demo to ensure everything works as expected. +22. If any of the above steps fail, post a message to the `#cesiumjs` channel in Slack to figure out what needs to be fixed before we can release. **Do NOT proceed to the next step until issues are resolved.** +23. Push your commits to main - `git push` -23. Create and push a [tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging), e.g., +24. Create and push a [tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging), e.g., - `git tag -a 1.1 -m "1.1 release"` - `git push origin 1.1` (this assumes origin is the primary cesium repository, do not use `git push --tags` as it pushes all tags from all remotes you have on your system.) -24. Publish the release zip file to GitHub +25. Publish the release zip file to GitHub - https://github.com/CesiumGS/cesium/releases/new - Select the tag you use pushed - Enter 'CesiumJS 1.xx' for the title @@ -52,12 +53,12 @@ There is no release manager; instead, our community shares the responsibility. A - Look at a [previous release](https://github.com/CesiumGS/cesium/releases/tag/1.79) for an example. Don't use emoji, headings, or other formatting - Attach the `Cesium-1.xx` release zip file - Publish the release -25. Publish to npm by running `npm publish` in the repository root (not the unzipped file directory) (the first time you do this, you will need to authorize the machine using `npm adduser`) -26. Use `npm publish -w <WORKSPACE>` in the repository root (not the unzipped file directory) to publish the workspace. Repeat this step for each **updated** workspace, in the following order: +26. Publish to npm by running `npm publish` in the repository root (not the unzipped file directory) (the first time you do this, you will need to authorize the machine using `npm adduser`) +27. Use `npm publish -w <WORKSPACE>` in the repository root (not the unzipped file directory) to publish the workspace. Repeat this step for each **updated** workspace, in the following order: - `npm publish -w @cesium/engine` - `npm publish -w @cesium/widgets` -27. Check out the `cesium.com` branch. Merge the new release tag into the `cesium.com` branch `git merge origin <tag-name>`. CI will deploy the hosted release, Sandcastle, and the updated doc when you push the branch up. -28. After the `cesium.com` branch is live on cesium.com, comment in the `#comms-chat` slack channel to notify comms that the release is done so they can add these highlights and publish the monthly blog post +28. Check out the `cesium.com` branch. Merge the new release tag into the `cesium.com` branch `git merge origin <tag-name>`. CI will deploy the hosted release, Sandcastle, and the updated doc when you push the branch up. +29. After the `cesium.com` branch is live on cesium.com, comment in the `#comms-chat` slack channel to notify comms that the release is done so they can add these highlights and publish the monthly blog post - Note, it may take a little while for the new version of CesiumJS to be live on cesium.com (~30 minutes after the branch builds). You can check the version of Cesium in [sandcastle](https://sandcastle.cesium.com/) by looking at the tab above the cesium pane. -29. Update the version of CesiumJS used in the Cesium Workshop: https://github.com/CesiumGS/cesium-workshop/blob/main/index.html#L13-L14 -30. Continue to the [Cesium Analytics release](https://github.com/CesiumGS/cesium-analytics/blob/main/Documentation/Contributors/AnalyticsReleaseGuide/README.md) +30. Update the version of CesiumJS used in the Cesium Workshop: https://github.com/CesiumGS/cesium-workshop/blob/main/index.html#L13-L14 +31. Continue to the [Cesium Analytics release](https://github.com/CesiumGS/cesium-analytics/blob/main/Documentation/Contributors/AnalyticsReleaseGuide/README.md) diff --git a/packages/engine/Source/Scene/ArcGisBaseMapType.js b/packages/engine/Source/Scene/ArcGisBaseMapType.js new file mode 100644 index 00000000000..cced8ec1d7b --- /dev/null +++ b/packages/engine/Source/Scene/ArcGisBaseMapType.js @@ -0,0 +1,12 @@ +/** + * ArcGisBaseMapType enumerates the ArcGIS image tile layers that are supported by default. + * + * @enum {number} + * @see ArcGisMapServerImageryProvider + */ +const ArcGisBaseMapType = { + SATELLITE: 1, + OCEANS: 2, + HILLSHADE: 3, +}; +export default Object.freeze(ArcGisBaseMapType); diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index 2ba117078e3..c278359b783 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -16,9 +16,12 @@ import RuntimeError from "../Core/RuntimeError.js"; import TileProviderError from "../Core/TileProviderError.js"; import WebMercatorProjection from "../Core/WebMercatorProjection.js"; import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js"; +import ArcGisMapService from "./ArcGisMapService.js"; import DiscardMissingTileImagePolicy from "./DiscardMissingTileImagePolicy.js"; import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js"; import ImageryProvider from "./ImageryProvider.js"; +import ArcGisBaseMapType from "./ArcGisBaseMapType.js"; +import DeveloperError from "../Core/DeveloperError.js"; /** * @typedef {object} ArcGisMapServerImageryProvider.ConstructorOptions @@ -39,8 +42,7 @@ import ImageryProvider from "./ImageryProvider.js"; * that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this * parameter. * @property {boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached - * tiles are used if they are available. If false, any pre-cached tiles are ignored and the - * 'export' service is used. + * tiles are used if they are available. Exporting Tiles is only supported with deprecated APIs. * @property {string} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown. * @property {boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke * the Identify service on the MapServer and return the features included in the response. If false, @@ -59,6 +61,8 @@ import ImageryProvider from "./ImageryProvider.js"; * @property {number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server. * @property {number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing * a tiled server. + * + * */ /** @@ -85,6 +89,7 @@ function ImageryProviderBuilder(options) { credit = new Credit(credit); } this.credit = credit; + this.tileCredits = undefined; this.tileDiscardPolicy = options.tileDiscardPolicy; this.tileWidth = defaultValue(options.tileWidth, 256); @@ -104,6 +109,7 @@ ImageryProviderBuilder.prototype.build = function (provider) { provider._tilingScheme = this.tilingScheme; provider._rectangle = this.rectangle; provider._credit = this.credit; + provider._tileCredits = this.tileCredits; provider._tileDiscardPolicy = this.tileDiscardPolicy; provider._tileWidth = this.tileWidth; provider._tileHeight = this.tileHeight; @@ -221,7 +227,11 @@ function metadataSuccess(data, imageryProviderBuilder) { } if (defined(data.copyrightText) && data.copyrightText.length > 0) { - imageryProviderBuilder.credit = new Credit(data.copyrightText); + if (defined(imageryProviderBuilder.credit)) { + imageryProviderBuilder.tileCredits = [new Credit(data.copyrightText)]; + } else { + imageryProviderBuilder.credit = new Credit(data.copyrightText); + } } } @@ -255,7 +265,7 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { }); try { - const data = await jsonResource.fetchJsonp(); + const data = await jsonResource.fetchJson(); metadataSuccess(data, imageryProviderBuilder); } catch (error) { metadataFailure(resource, error, provider); @@ -264,7 +274,7 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { /** * <div class="notice"> - * To construct a ArcGisMapServerImageryProvider call {@link ArcGisMapServerImageryProvider.fromUrl}. Do not call the constructor directly. + * This object is normally not instantiated directly, use {@link ArcGisMapServerImageryProvider.fromBasemapType} or {@link ArcGisMapServerImageryProvider.fromUrl}. * </div> * * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are @@ -275,6 +285,7 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { * * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options * + * @see ArcGisMapServerImagery.fromBasemapType * @see ArcGisMapServerImagery.fromUrl * @see BingMapsImageryProvider * @see GoogleEarthEnterpriseMapsProvider @@ -286,12 +297,29 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { * @see UrlTemplateImageryProvider * * @example + * // Add a base layer from a default ArcGIS Basemap + * const viewer = new Cesium.Viewer("cesiumContainer", { + * baseLayer: Cesium.ImageryLayer.fromProviderAsync( + * Cesium.ArcGisMapServerImageryProvider.fromBasemapType( + * Cesium.ArcGisBaseMapType.SATELLITE, { + * token: "<ArcGIS Access Token>" + * } + * ) + * ), + * }); + * + * @example + * // Create an imagery provider from the url directly * const esri = await Cesium.ArcGisMapServerImageryProvider.fromUrl( - * "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" - * ); + * "https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer", { + * token: "<ArcGIS Access Token>" + * }); * * @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security| ArcGIS Access Token } + * is required to authenticate requests to an ArcGIS Image Tile service. + * To access secure ArcGIS resources, you need to create an ArcGIS developer + * account or an ArcGIS online account, then implement an authentication method to obtain an access token. */ function ArcGisMapServerImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -321,7 +349,13 @@ function ArcGisMapServerImageryProvider(options) { this._tilingScheme.rectangle ); this._layers = options.layers; - this._credit = undefined; + this._credit = options.credit; + this._tileCredits = undefined; + + let credit = options.credit; + if (typeof credit === "string") { + credit = new Credit(credit); + } /** * Gets or sets a value indicating whether feature picking is enabled. If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will @@ -371,6 +405,115 @@ function ArcGisMapServerImageryProvider(options) { } } +/** + * Creates an {@link ImageryProvider} which provides tiled imagery from an ArcGIS base map. + * @param {ArcGisBaseMapType} style The style of the ArcGIS base map imagery. Valid options are {@link ArcGisBaseMapType.SATELLITE}, {@link ArcGisBaseMapType.OCEANS}, and {@link ArcGisBaseMapType.HILLSHADE}. + * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options. + * @returns {Promise<ArcGisMapServerImageryProvider>} A promise that resolves to the created ArcGisMapServerImageryProvider. + * + * @example + * const provider = await Cesium.ArcGisMapServerImageryProvider.fromBasemapType( + * Cesium.ArcGisBaseMapType.SATELLITE, { + * token: "<ArcGIS Access Token>" + * }); + * + * @example + * // Add a base layer from a default ArcGIS Basemap + * const viewer = new Cesium.Viewer("cesiumContainer", { + * baseLayer: Cesium.ImageryLayer.fromProviderAsync( + * Cesium.ArcGisMapServerImageryProvider.fromBasemapType( + * Cesium.ArcGisBaseMapType.HILLSHADE, { + * token: "<ArcGIS Access Token>" + * } + * ) + * ), + * }); + */ + +ArcGisMapServerImageryProvider.fromBasemapType = async function ( + style, + options +) { + //>>includeStart('debug', pragmas.debug); + Check.defined("style", style); + //>>includeEnd('debug'); + + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + let accessToken; + let server; + let warningCredit; + switch (style) { + case ArcGisBaseMapType.SATELLITE: + { + accessToken = defaultValue( + options.token, + ArcGisMapService.defaultAccessToken + ); + server = Resource.createIfNeeded( + defaultValue(options.url, ArcGisMapService.defaultWorldImageryServer) + ); + server.appendForwardSlash(); + const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit( + accessToken + ); + if (defined(defaultTokenCredit)) { + warningCredit = Credit.clone(defaultTokenCredit); + } + } + break; + case ArcGisBaseMapType.OCEANS: + { + accessToken = defaultValue( + options.token, + ArcGisMapService.defaultAccessToken + ); + server = Resource.createIfNeeded( + defaultValue(options.url, ArcGisMapService.defaultWorldOceanServer) + ); + server.appendForwardSlash(); + const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit( + accessToken + ); + if (defined(defaultTokenCredit)) { + warningCredit = Credit.clone(defaultTokenCredit); + } + } + break; + case ArcGisBaseMapType.HILLSHADE: + { + accessToken = defaultValue( + options.token, + ArcGisMapService.defaultAccessToken + ); + server = Resource.createIfNeeded( + defaultValue( + options.url, + ArcGisMapService.defaultWorldHillshadeServer + ) + ); + server.appendForwardSlash(); + const defaultTokenCredit = ArcGisMapService.getDefaultTokenCredit( + accessToken + ); + if (defined(defaultTokenCredit)) { + warningCredit = Credit.clone(defaultTokenCredit); + } + } + break; + default: + //>>includeStart('debug', pragmas.debug); + throw new DeveloperError(`Unsupported basemap type: ${style}`); + //>>includeEnd('debug'); + } + + return ArcGisMapServerImageryProvider.fromUrl(server, { + ...options, + token: accessToken, + credit: warningCredit, + usePreCachedTilesIfAvailable: true, // ArcGIS Base Map Service Layers only support Tiled views + }); +}; + function buildImageResource(imageryProvider, x, y, level, request) { let resource; if (imageryProvider._useTiles) { @@ -413,7 +556,6 @@ function buildImageResource(imageryProvider, x, y, level, request) { queryParameters: query, }); } - return resource; } @@ -941,7 +1083,7 @@ ArcGisMapServerImageryProvider.prototype.getTileCredits = function ( y, level ) { - return undefined; + return this._tileCredits; }; /** @@ -1078,4 +1220,5 @@ ArcGisMapServerImageryProvider.prototype.pickFeatures = function ( return result; }); }; +ArcGisMapServerImageryProvider._metadataCache = {}; export default ArcGisMapServerImageryProvider; diff --git a/packages/engine/Source/Scene/ArcGisMapService.js b/packages/engine/Source/Scene/ArcGisMapService.js new file mode 100644 index 00000000000..4656f58cb24 --- /dev/null +++ b/packages/engine/Source/Scene/ArcGisMapService.js @@ -0,0 +1,83 @@ +import Credit from "../Core/Credit.js"; +import defined from "../Core/defined.js"; +import Resource from "../Core/Resource.js"; + +let defaultTokenCredit; +const defaultAccessToken = + "AAPKd815e334cb774973b7245e23a67f4d08Js7A8e8xvfBpgnZIzp1jbL3FWJTmx7AKG8wa87OwDcWEu4CxQCNiydpPbGpALiTf"; +/** + * Default options for accessing the ArcGIS image tile service. + * + * An ArcGIS access token is required to access ArcGIS image tile layers. + * A default token is provided for evaluation purposes only. + * To obtain an access token, go to {@link https://developers.arcgis.com} and create a free account. + * More info can be found in the {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security/ | ArcGIS developer guide}. + * + * @see ArcGisMapServerImageryProvider + * @namespace ArcGisMapService + */ + +const ArcGisMapService = {}; +/** + * Gets or sets the default ArcGIS access token. + * + * @type {string} + */ +ArcGisMapService.defaultAccessToken = defaultAccessToken; + +/** + * Gets or sets the URL of the ArcGIS World Imagery tile service. + * + * @type {string|Resource} + * @default https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer + */ +ArcGisMapService.defaultWorldImageryServer = new Resource({ + url: + "https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer", +}); + +/** + * Gets or sets the URL of the ArcGIS World Hillshade tile service. + * + * @type {string|Resource} + * @default https://ibasemaps-api.arcgis.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer + */ +ArcGisMapService.defaultWorldHillshadeServer = new Resource({ + url: + "https://ibasemaps-api.arcgis.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer", +}); + +/** + * Gets or sets the URL of the ArcGIS World Oceans tile service. + * + * @type {string|Resource} + * @default https://ibasemaps-api.arcgis.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer + */ +ArcGisMapService.defaultWorldOceanServer = new Resource({ + url: + "https://ibasemaps-api.arcgis.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer", +}); + +/** + * + * @param {string} providedKey + * @return {string|undefined} + */ +ArcGisMapService.getDefaultTokenCredit = function (providedKey) { + if (providedKey !== defaultAccessToken) { + return undefined; + } + + if (!defined(defaultTokenCredit)) { + const defaultTokenMessage = + '<b> \ + This application is using a default ArcGIS access token. Please assign <i>Cesium.ArcGisMapService.defaultAccessToken</i> \ + with an API key from your ArcGIS Developer account before using the ArcGIS tile services. \ + You can sign up for a free ArcGIS Developer account at <a href="https://developers.arcgis.com/">https://developers.arcgis.com/</a>.</b>'; + + defaultTokenCredit = new Credit(defaultTokenMessage, true); + } + + return defaultTokenCredit; +}; +export default ArcGisMapService; diff --git a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js index b0717a912ed..3be3fa7863c 100644 --- a/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/ArcGisMapServerImageryProviderSpec.js @@ -1,11 +1,11 @@ import Uri from "urijs"; import { - appendForwardSlash, ArcGisMapServerImageryProvider, + ArcGisBaseMapType, + ArcGisMapService, Cartesian2, Cartesian3, Cartographic, - defined, DiscardMissingTileImagePolicy, GeographicTilingScheme, getAbsoluteUri, @@ -50,49 +50,18 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { Resource._DefaultImplementations.loadWithXhr; }); - function expectCorrectUrl( - expectedBaseUrl, - actualUrl, - functionName, - withProxy, - token - ) { - let uri = new Uri(actualUrl); - - if (withProxy) { - uri = new Uri(decodeURIComponent(uri.query())); - } - - const params = queryToObject(uri.query()); - - const uriWithoutQuery = new Uri(uri); - uriWithoutQuery.query(""); - - expect(uriWithoutQuery.toString()).toEqual( - appendForwardSlash(expectedBaseUrl) - ); - - const expectedParams = { - callback: functionName, - f: "json", - }; - if (defined(token)) { - expectedParams.token = token; - } - expect(params).toEqual(expectedParams); - } - - function stubJSONPCall(baseUrl, result, withProxy, token) { - Resource._Implementations.loadAndExecuteScript = function ( + function stubJSONCall(baseUrl, result, withProxy, token) { + spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( url, - functionName, - deferred + responseType, + method, + data, + headers, + deferred, + overrideMimeType ) { - expectCorrectUrl(baseUrl, url, functionName, withProxy, token); - setTimeout(function () { - window[functionName](result); - }, 1); - }; + deferred.resolve(JSON.stringify(result)); + }); } it("conforms to ImageryProvider interface", function () { @@ -137,7 +106,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("resolves readyPromise", function () { const baseUrl = "//tiledArcGisMapServer.invalid"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -152,7 +121,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("resolves readyPromise with Resource", function () { const baseUrl = "//tiledArcGisMapServer.invalid"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); const resource = new Resource({ url: baseUrl, @@ -196,7 +165,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("fromUrl resolves with created provider", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider).toBeInstanceOf(ArcGisMapServerImageryProvider); @@ -206,7 +175,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("fromUrl resolves with created provider with Resource parameter", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); const resource = new Resource({ url: baseUrl, @@ -264,7 +233,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, unsupportedWKIDResult); + stubJSONCall(baseUrl, unsupportedWKIDResult); await expectAsync( ArcGisMapServerImageryProvider.fromUrl(baseUrl) @@ -319,7 +288,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, unsupportedFullExtentWKIDResult); + stubJSONCall(baseUrl, unsupportedFullExtentWKIDResult); await expectAsync( ArcGisMapServerImageryProvider.fromUrl(baseUrl) @@ -332,7 +301,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("fromUrl creates provider for tiled servers in web mercator projection", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider.tileWidth).toEqual(128); @@ -348,81 +317,122 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { expect(provider.hasAlphaChannel).toBeDefined(); }); - it("supports tiled servers in web mercator projection", function () { + it("fromBasemapType throws without style", async function () { + await expectAsync( + ArcGisMapServerImageryProvider.fromBasemapType() + ).toBeRejectedWithDeveloperError( + "style is required, actual value was undefined" + ); + }); + + it("fromBasemapType throws with unknown style", async function () { + await expectAsync( + ArcGisMapServerImageryProvider.fromBasemapType("unknown") + ).toBeRejectedWithDeveloperError("Unsupported basemap type: unknown"); + }); + + it("fromBasemapType creates an ImageryProvider with expected values", async function () { + const expectedUrl = ArcGisMapService.defaultWorldImageryServer; + stubJSONCall(expectedUrl, webMercatorResult); + const provider = await ArcGisMapServerImageryProvider.fromBasemapType( + ArcGisBaseMapType.SATELLITE, + { + token: "myToken", + } + ); + + expect(provider.url).toContain(expectedUrl); + expect(provider.token).toEqual("myToken"); + expect(provider.credit.html).toEqual("Test copyright text"); + expect(provider.usingPrecachedTiles).toBeTrue(); + }); + + it("fromBasemapType displays default Credit if default token is used", async function () { + const expectedUrl = ArcGisMapService.defaultWorldImageryServer; + stubJSONCall(expectedUrl, webMercatorResult); + const provider = await ArcGisMapServerImageryProvider.fromBasemapType( + ArcGisBaseMapType.SATELLITE + ); + + expect(provider.url).toContain(expectedUrl); + expect(provider.token).toBeDefined(); + expect(provider.credit.html).toContain( + "This application is using a default ArcGIS access token." + ); + expect(provider.getTileCredits(0, 0, 0)[0].html).toEqual( + "Test copyright text" + ); + }); + + it("supports tiled servers in web mercator projection", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, webMercatorResult); + stubJSONCall(baseUrl, webMercatorResult); - const provider = new ArcGisMapServerImageryProvider({ - url: baseUrl, - }); + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider.url).toEqual(baseUrl); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(128); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toEqual(2); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.credit).toBeDefined(); - expect(provider.tileDiscardPolicy).toBeInstanceOf( - DiscardMissingTileImagePolicy - ); - expect(provider.rectangle).toEqual( - new WebMercatorTilingScheme().rectangle - ); - expect(provider.usingPrecachedTiles).toEqual(true); - expect(provider.hasAlphaChannel).toBeDefined(); + expect(provider.tileWidth).toEqual(128); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(2); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeInstanceOf( + DiscardMissingTileImagePolicy + ); + expect(provider.rectangle).toEqual(new WebMercatorTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(true); + expect(provider.hasAlphaChannel).toBeDefined(); - Resource._Implementations.createImage = function ( - request, - crossOrigin, - deferred - ) { - const url = request.url; - if (/^blob:/.test(url)) { - Resource._DefaultImplementations.createImage( - request, - crossOrigin, - deferred - ); - } else { - expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); + Resource._Implementations.createImage = function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + if (/^blob:/.test(url)) { + Resource._DefaultImplementations.createImage( + request, + crossOrigin, + deferred + ); + } else { + expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - } - }; + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + } + }; - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); + + // Just return any old image. + Resource._DefaultImplementations.loadWithXhr( + "Data/Images/Red16x16.png", responseType, method, data, headers, - deferred, - overrideMimeType - ) { - expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); - - // Just return any old image. - Resource._DefaultImplementations.loadWithXhr( - "Data/Images/Red16x16.png", - responseType, - method, - data, - headers, - deferred - ); - }; + deferred + ); + }; - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(image).toBeImageOrImageBitmap(); }); }); @@ -459,91 +469,85 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - it("supports tiled servers in geographic projection", function () { + it("supports tiled servers in geographic projection", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, geographicResult); + stubJSONCall(baseUrl, geographicResult); - const provider = new ArcGisMapServerImageryProvider({ - url: baseUrl, - }); + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider.url).toEqual(baseUrl); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(128); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toEqual(2); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.credit).toBeDefined(); - expect(provider.tileDiscardPolicy).toBeInstanceOf( - DiscardMissingTileImagePolicy - ); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle - ); - expect(provider.usingPrecachedTiles).toEqual(true); + expect(provider.tileWidth).toEqual(128); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toEqual(2); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeInstanceOf( + DiscardMissingTileImagePolicy + ); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(true); - Resource._Implementations.createImage = function ( - request, - crossOrigin, - deferred - ) { - const url = request.url; - if (/^blob:/.test(url) || supportsImageBitmapOptions) { - // If ImageBitmap is supported, we expect a loadWithXhr request to fetch it as a blob. - Resource._DefaultImplementations.createImage( - request, - crossOrigin, - deferred, - true, - false, - true - ); - } else { - expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); + Resource._Implementations.createImage = function ( + request, + crossOrigin, + deferred + ) { + const url = request.url; + if (/^blob:/.test(url) || supportsImageBitmapOptions) { + // If ImageBitmap is supported, we expect a loadWithXhr request to fetch it as a blob. + Resource._DefaultImplementations.createImage( + request, + crossOrigin, + deferred, + true, + false, + true + ); + } else { + expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - } - }; + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + } + }; - Resource._Implementations.loadWithXhr = function ( - url, + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); + + // Just return any old image. + Resource._DefaultImplementations.loadWithXhr( + "Data/Images/Red16x16.png", responseType, method, data, headers, - deferred, - overrideMimeType - ) { - expect(url).toEqual(getAbsoluteUri(`${baseUrl}tile/0/0/0`)); - - // Just return any old image. - Resource._DefaultImplementations.loadWithXhr( - "Data/Images/Red16x16.png", - responseType, - method, - data, - headers, - deferred - ); - }; + deferred + ); + }; - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(image).toBeImageOrImageBitmap(); }); }); it("fromUrl creates provider for tiled servers in geographic projection", async function () { const baseUrl = "//tiledArcGisMapServer.invalid"; - stubJSONPCall(baseUrl, geographicResult); + stubJSONCall(baseUrl, geographicResult); const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider.tileWidth).toEqual(128); @@ -558,73 +562,67 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { expect(provider.usingPrecachedTiles).toEqual(true); }); - it("supports non-tiled servers", function () { + it("supports non-tiled servers", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, { + stubJSONCall(baseUrl, { currentVersion: 10.01, copyrightText: "Test copyright text", }); - const provider = new ArcGisMapServerImageryProvider({ - url: baseUrl, - }); + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl); expect(provider.url).toEqual(baseUrl); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(256); - expect(provider.tileHeight).toEqual(256); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); - expect(provider.credit).toBeDefined(); - expect(provider.tileDiscardPolicy).toBeUndefined(); - expect(provider.rectangle).toEqual( - new GeographicTilingScheme().rectangle - ); - expect(provider.usingPrecachedTiles).toEqual(false); - expect(provider.enablePickFeatures).toBe(true); + expect(provider.tileWidth).toEqual(256); + expect(provider.tileHeight).toEqual(256); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(GeographicTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeUndefined(); + expect(provider.rectangle).toEqual(new GeographicTilingScheme().rectangle); + expect(provider.usingPrecachedTiles).toEqual(false); + expect(provider.enablePickFeatures).toBe(true); - Resource._Implementations.createImage = function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); + Resource._Implementations.createImage = function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); - const uriWithoutQuery = new Uri(uri); - uriWithoutQuery.query(""); + const uriWithoutQuery = new Uri(uri); + uriWithoutQuery.query(""); - expect(uriWithoutQuery.toString()).toEqual( - getAbsoluteUri(`${baseUrl}export`) - ); + expect(uriWithoutQuery.toString()).toEqual( + getAbsoluteUri(`${baseUrl}export`) + ); - expect(params.f).toEqual("image"); - expect(params.bboxSR).toEqual("4326"); - expect(params.imageSR).toEqual("4326"); - expect(params.format).toEqual("png32"); - expect(params.transparent).toEqual("true"); - expect(params.size).toEqual("256,256"); + expect(params.f).toEqual("image"); + expect(params.bboxSR).toEqual("4326"); + expect(params.imageSR).toEqual("4326"); + expect(params.format).toEqual("png32"); + expect(params.transparent).toEqual("true"); + expect(params.size).toEqual("256,256"); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }; + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + }; - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(image).toBeImageOrImageBitmap(); }); }); it("fromUrl creates provider for non-tiled servers", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, { + stubJSONCall(baseUrl, { currentVersion: 10.01, copyrightText: "Test copyright text", }); @@ -641,11 +639,11 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { expect(provider.enablePickFeatures).toBe(true); }); - it("supports non-tiled servers with various constructor parameters", function () { + it("supports non-tiled servers with various constructor parameters", async function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; const token = "5e(u|2!7Y"; - stubJSONPCall( + stubJSONCall( baseUrl, { currentVersion: 10.01, @@ -655,8 +653,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { token ); - const provider = new ArcGisMapServerImageryProvider({ - url: baseUrl, + const provider = await ArcGisMapServerImageryProvider.fromUrl(baseUrl, { token: token, tileWidth: 128, tileHeight: 512, @@ -668,55 +665,53 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { expect(provider.url).toEqual(baseUrl); - return provider.readyPromise.then(function () { - expect(provider.tileWidth).toEqual(128); - expect(provider.tileHeight).toEqual(512); - expect(provider.maximumLevel).toBeUndefined(); - expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); - expect(provider.credit).toBeDefined(); - expect(provider.tileDiscardPolicy).toBeUndefined(); - expect(provider.rectangle).toEqual( - Rectangle.fromDegrees(1.0, 2.0, 3.0, 4.0) - ); - expect(provider.usingPrecachedTiles).toBe(false); - expect(provider.enablePickFeatures).toBe(false); - expect(provider.layers).toEqual("foo,bar"); - - Resource._Implementations.createImage = function ( - request, - crossOrigin, - deferred - ) { - const uri = new Uri(request.url); - const params = queryToObject(uri.query()); + expect(provider.tileWidth).toEqual(128); + expect(provider.tileHeight).toEqual(512); + expect(provider.maximumLevel).toBeUndefined(); + expect(provider.tilingScheme).toBeInstanceOf(WebMercatorTilingScheme); + expect(provider.credit).toBeDefined(); + expect(provider.tileDiscardPolicy).toBeUndefined(); + expect(provider.rectangle).toEqual( + Rectangle.fromDegrees(1.0, 2.0, 3.0, 4.0) + ); + expect(provider.usingPrecachedTiles).toBe(false); + expect(provider.enablePickFeatures).toBe(false); + expect(provider.layers).toEqual("foo,bar"); - const uriWithoutQuery = new Uri(uri); - uriWithoutQuery.query(""); + Resource._Implementations.createImage = function ( + request, + crossOrigin, + deferred + ) { + const uri = new Uri(request.url); + const params = queryToObject(uri.query()); - expect(uriWithoutQuery.toString()).toEqual( - getAbsoluteUri(`${baseUrl}export`) - ); + const uriWithoutQuery = new Uri(uri); + uriWithoutQuery.query(""); - expect(params.f).toEqual("image"); - expect(params.bboxSR).toEqual("3857"); - expect(params.imageSR).toEqual("3857"); - expect(params.format).toEqual("png32"); - expect(params.transparent).toEqual("true"); - expect(params.size).toEqual("128,512"); - expect(params.layers).toEqual("show:foo,bar"); - expect(params.token).toEqual(token); + expect(uriWithoutQuery.toString()).toEqual( + getAbsoluteUri(`${baseUrl}export`) + ); - // Just return any old image. - Resource._DefaultImplementations.createImage( - new Request({ url: "Data/Images/Red16x16.png" }), - crossOrigin, - deferred - ); - }; + expect(params.f).toEqual("image"); + expect(params.bboxSR).toEqual("3857"); + expect(params.imageSR).toEqual("3857"); + expect(params.format).toEqual("png32"); + expect(params.transparent).toEqual("true"); + expect(params.size).toEqual("128,512"); + expect(params.layers).toEqual("show:foo,bar"); + expect(params.token).toEqual(token); + + // Just return any old image. + Resource._DefaultImplementations.createImage( + new Request({ url: "Data/Images/Red16x16.png" }), + crossOrigin, + deferred + ); + }; - return provider.requestImage(0, 0, 0).then(function (image) { - expect(image).toBeImageOrImageBitmap(); - }); + return provider.requestImage(0, 0, 0).then(function (image) { + expect(image).toBeImageOrImageBitmap(); }); }); @@ -724,7 +719,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { const baseUrl = "//tiledArcGisMapServer.invalid/", token = "5e(u|2!7Y"; - stubJSONPCall(baseUrl, webMercatorResult, false, token); + stubJSONCall(baseUrl, webMercatorResult, false, token); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -847,7 +842,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, unsupportedWKIDResult); + stubJSONCall(baseUrl, unsupportedWKIDResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -900,7 +895,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { it("raises error event when image cannot be loaded", function () { const baseUrl = "//tiledArcGisMapServer.invalid/"; - stubJSONPCall(baseUrl, { + stubJSONCall(baseUrl, { currentVersion: 10.01, copyrightText: "Test copyright text", }); @@ -1004,7 +999,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, webMercatorFullExtentResult); + stubJSONCall(baseUrl, webMercatorFullExtentResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -1075,7 +1070,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, webMercatorOutsideBoundsResult); + stubJSONCall(baseUrl, webMercatorOutsideBoundsResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -1140,7 +1135,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, geographicFullExtentResult); + stubJSONCall(baseUrl, geographicFullExtentResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -1200,7 +1195,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }, }; - stubJSONPCall(baseUrl, unknownSpatialReferenceResult); + stubJSONCall(baseUrl, unknownSpatialReferenceResult); const provider = new ArcGisMapServerImageryProvider({ url: baseUrl, @@ -1227,6 +1222,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { describe("pickFeatures", function () { it("works with WebMercator geometry", async function () { + stubJSONCall("made/up/map/server", webMercatorResult); const provider = await ArcGisMapServerImageryProvider.fromUrl( "made/up/map/server", { @@ -1269,10 +1265,13 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); it("works with Geographic geometry", async function () { - const provider = new ArcGisMapServerImageryProvider({ - url: "made/up/map/server", - usePreCachedTilesIfAvailable: false, - }); + stubJSONCall("made/up/map/server", geographicResult); + const provider = await ArcGisMapServerImageryProvider.fromUrl( + "made/up/map/server", + { + usePreCachedTilesIfAvailable: false, + } + ); Resource._Implementations.loadWithXhr = function ( url, @@ -1294,19 +1293,22 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { overrideMimeType ); }; - - const pickResult = await provider.pickFeatures(0, 0, 0, 0.5, 0.5); - expect(pickResult.length).toBe(1); - - const firstResult = pickResult[0]; - expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); - expect(firstResult.description).toContain("Hummock Grasses"); - expect(firstResult.position).toEqual( - Cartographic.fromDegrees(123.45, -34.2) - ); + return provider + .pickFeatures(0, 0, 0, 0.5, 0.5) + .then(function (pickResult) { + expect(pickResult.length).toBe(1); + + const firstResult = pickResult[0]; + expect(firstResult).toBeInstanceOf(ImageryLayerFeatureInfo); + expect(firstResult.description).toContain("Hummock Grasses"); + expect(firstResult.position).toEqual( + Cartographic.fromDegrees(123.45, -34.2) + ); + }); }); it("returns undefined if enablePickFeatures is false", async function () { + stubJSONCall("made/up/map/server", webMercatorResult); const provider = await ArcGisMapServerImageryProvider.fromUrl( "made/up/map/server", { @@ -1319,6 +1321,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); it("returns undefined if enablePickFeatures is dynamically set to false", async function () { + stubJSONCall("made/up/map/server", geographicResult); const provider = await ArcGisMapServerImageryProvider.fromUrl( "made/up/map/server", { @@ -1332,6 +1335,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); it("does not return undefined if enablePickFeatures is dynamically set to true", async function () { + stubJSONCall("made/up/map/server", webMercatorResult); const provider = await ArcGisMapServerImageryProvider.fromUrl( "made/up/map/server", { @@ -1368,6 +1372,7 @@ describe("Scene/ArcGisMapServerImageryProvider", function () { }); it("picks from individual layers", async function () { + stubJSONCall("made/up/map/server", webMercatorResult); Resource._Implementations.loadWithXhr = function ( url, responseType, diff --git a/packages/engine/Specs/Scene/IonImageryProviderSpec.js b/packages/engine/Specs/Scene/IonImageryProviderSpec.js index 60cf3b780a5..bfeb3b25ce0 100644 --- a/packages/engine/Specs/Scene/IonImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/IonImageryProviderSpec.js @@ -290,17 +290,19 @@ describe("Scene/IonImageryProvider", function () { } it("createImageryProvider works with ARCGIS_MAPSERVER", function () { - spyOn(Resource._Implementations, "loadAndExecuteScript").and.callFake( - function (url, name, deffered) { - deffered.resolve({ - resourceSets: [ - { - resources: [{ imageUrl: "", imageUrlSubdomains: [], zoomMax: 0 }], - }, - ], - }); - } - ); + spyOn(Resource._Implementations, "loadWithXhr").and.callFake(function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + deferred.resolve( + JSON.stringify({ imageUrl: "", imageUrlSubdomains: [], zoomMax: 0 }) + ); + }); return testExternalImagery( "ARCGIS_MAPSERVER", { url: "http://test.invalid" }, diff --git a/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js b/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js index 05702413171..361f11bc9a8 100644 --- a/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js +++ b/packages/widgets/Source/BaseLayerPicker/createDefaultImageryProviderViewModels.js @@ -6,6 +6,7 @@ import { IonWorldImageryStyle, OpenStreetMapImageryProvider, TileMapServiceImageryProvider, + ArcGisBaseMapType, } from "@cesium/engine"; import ProviderViewModel from "./ProviderViewModel.js"; @@ -60,23 +61,24 @@ function createDefaultImageryProviderViewModels() { providerViewModels.push( new ProviderViewModel({ - name: "ESRI World Imagery", + name: "ArcGIS World Imagery", iconUrl: buildModuleUrl( - "Widgets/Images/ImageryProviders/esriWorldImagery.png" + "Widgets/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png" ), tooltip: "\ -World Imagery provides one meter or better satellite and aerial imagery in many parts of the world and lower resolution \ -satellite imagery worldwide. The map includes NASA Blue Marble: Next Generation 500m resolution imagery at small scales \ -(above 1:1,000,000), i-cubed 15m eSAT imagery at medium-to-large scales (down to 1:70,000) for the world, and USGS 15m Landsat \ -imagery for Antarctica. The map features 0.3m resolution imagery in the continental United States and 0.6m resolution imagery in \ -parts of Western Europe from DigitalGlobe. In other parts of the world, 1 meter resolution imagery is available from GeoEye IKONOS, \ -i-cubed Nationwide Prime, Getmapping, AeroGRID, IGN Spain, and IGP Portugal. Additionally, imagery at different resolutions has been \ -contributed by the GIS User Community.\nhttp://www.esri.com", +ArcGIS World Imagery provides one meter or better satellite and aerial imagery in many parts of the world and lower \ +resolution satellite imagery worldwide. The map includes 15m TerraColor imagery at small and mid-scales (~1:591M down to ~1:288k) \ +for the world. The map features Maxar imagery at 0.3m resolution for select metropolitan areas around the world, 0.5m \ +resolution across the United States and parts of Western Europe, and 1m resolution imagery across the rest of the world. \ +In addition to commercial sources, the World Imagery map features high-resolution aerial photography contributed by the \ +GIS User Community. This imagery ranges from 0.3m to 0.03m resolution (down to ~1:280 nin select communities). \ +For more information on this map, including the terms of use, visit us online at \n\ +https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9", category: "Other", creationFunction: function () { - return ArcGisMapServerImageryProvider.fromUrl( - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", + return ArcGisMapServerImageryProvider.fromBasemapType( + ArcGisBaseMapType.SATELLITE, { enablePickFeatures: false, } @@ -87,20 +89,21 @@ contributed by the GIS User Community.\nhttp://www.esri.com", providerViewModels.push( new ProviderViewModel({ - name: "ESRI World Street Map", + name: "ArcGIS World Hillshade", iconUrl: buildModuleUrl( - "Widgets/Images/ImageryProviders/esriWorldStreetMap.png" + "Widgets/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png" ), tooltip: "\ -This worldwide street map presents highway-level data for the world. Street-level data includes the United States; much of \ -Canada; Japan; most countries in Europe; Australia and New Zealand; India; parts of South America including Argentina, Brazil, \ -Chile, Colombia, and Venezuela; Ghana; and parts of southern Africa including Botswana, Lesotho, Namibia, South Africa, and Swaziland.\n\ -http://www.esri.com", +ArcGIS World Hillshade map portrays elevation as an artistic hillshade. This map is designed to be used as a backdrop for topographical, soil, hydro, \ +landcover or other outdoor recreational maps. The map was compiled from a variety of sources from several data providers. \ +The basemap has global coverage down to a scale of ~1:72k. In select areas of the United States and Europe, coverage is available \ +down to ~1:9k. For more information on this map, including the terms of use, visit us online at \n\ +https://www.arcgis.com/home/item.html?id=1b243539f4514b6ba35e7d995890db1d", category: "Other", creationFunction: function () { - return ArcGisMapServerImageryProvider.fromUrl( - "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", + return ArcGisMapServerImageryProvider.fromBasemapType( + ArcGisBaseMapType.HILLSHADE, { enablePickFeatures: false, } @@ -111,19 +114,24 @@ http://www.esri.com", providerViewModels.push( new ProviderViewModel({ - name: "ESRI National Geographic", + name: "Esri World Ocean", iconUrl: buildModuleUrl( - "Widgets/Images/ImageryProviders/esriNationalGeographic.png" + "Widgets/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png" ), tooltip: "\ -This web map contains the National Geographic World Map service. This map service is designed to be used as a general reference map \ -for informational and educational purposes as well as a basemap by GIS professionals and other users for creating web maps and web \ -mapping applications.\nhttp://www.esri.com", +ArcGIS World Ocean map is designed to be used as a base map by marine GIS professionals and as a reference map by anyone interested in ocean data. \ +The base map features marine bathymetry. Land features include inland waters and roads overlaid on land cover and shaded relief imagery. \ +The map was compiled from a variety of best available sources from several data providers, including General Bathymetric Chart of the Oceans GEBCO_08 Grid, \ +National Oceanic and Atmospheric Administration (NOAA), and National Geographic, Garmin, HERE, Geonames.org, and Esri, and various other contributors. \ +The base map currently provides coverage for the world down to a scale of ~1:577k, and coverage down to 1:72k in US coastal areas, and various other areas. \ +Coverage down to ~ 1:9k is available limited areas based on regional hydrographic survey data. The base map was designed and developed by Esri. \ +For more information on this map, including our terms of use, visit us online at \n\ +https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500", category: "Other", creationFunction: function () { - return ArcGisMapServerImageryProvider.fromUrl( - "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/", + return ArcGisMapServerImageryProvider.fromBasemapType( + ArcGisBaseMapType.OCEANS, { enablePickFeatures: false, } diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldHillshade.png b/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldHillshade.png new file mode 100644 index 0000000000000000000000000000000000000000..bd5976d24d5687ad29a2760511656d4158c63016 GIT binary patch literal 8624 zcmZ{K1yCH_67FKboe&%r4+*YIu*Kb-;2u~OSUkA96FflhV8KHmI7<i)!2<-B;J)Z1 z|9{`T|GRbHnL5)w-Tn2~M{4R!)kLYQ%Hd*BU;zLCTm^Y)%||Kmr(-;MynnQJS$Y(x zwqO-708pENeQS>P_)KRhuc-n6_%H(ifuR7v^`j|p8vt<U0swZ+007|(0N|N(&KC`l zM~9cSzJiU43V`iV#{i%r5dlyhHKfN2fJ6cKlkHIhh#^t_TbGTn2cZ7TuKFndH2KH= zC+=^Fl8^MCEcwX)j+V$r`H%hwRzA9i{wOe=<qco}05<WTjs(ccAp-!AQ|-0&-SkzI zg)N~F4s$E0g*As4#Q6^jAmSzbs6wpW%;~%!j!rOPFH!oxB7`6HKW0vPy1zo)97O5$ zRn+OEpsv<*0vuc%T=ZgCbaZqgu2wd}n$oiWf<Hcq(%ZSYISX@gdU|?tc=B>UU2QqJ zK_Cz(7Y`>75Bp;TJIve3&D@LK3C8eulK-1W+8So*YVYi34|SsZlh@n=>h2~=PydJL z-|g=@-Ry1t!{h|}*RUQ3$oa>^$<4vV`M+S+UiSYV*dNc|u)oIjH=W3zWWolT)-b4} z`=7GJ1bIaMV)%cI|Ece9fd2mi{L}c~05w;8>&Geii-G%J1pl=CBmPgF!s_;3){gqp z_7H0)*q^F+xVS_(|EK4_ky21csH>K<xuvz(Bhg=wf0+I|`Y#@X|L}10^8S<OAD(|9 zML7Sg+dtOv?@jWT^>LSoVTo}5d&h}ksqibM0RS|}3esS0FQl}Eh-9i6_b0!WGUswo zNX?N5P%#vBi0nF2EB2a?80Oium<SnH=^-Pas|QsmO1`o|aW%z|>Lo7AEz1&o?EHMg zy?XQHq;76jAF8T0n)S-_fRBNpu*Gxy%;&3(on2YWmp8ku0~^i1udhFfZEbDwKO7x> zBB!CTXJ#(R8Xr#*X&q^+h!ylHn|7`7-&pEH7{rm&klV*6#Jk>nnOj(>a^W;>AEGE6 z4nfDK_}vQc@Bf|2&%#`q{oA*2)ZN2FcNtDYODovg+B&?q=g7;;8}iFAz{29g&gBjH zj02uz#q!tO+}td?f}NdA8!ocY$glL3Mn41NcPMVB#Nk(7@xS~75=&?Jm$^o(Ya(_% z`$Y&}n-C4D6S@(8xck}>V5Z0`EHFJZJUr#&op^I|o|8NlK4((%wCs5LydZFRc$kQ6 z6JzKLssKO#(+wQKkQFe@$HNfo#TQSHrfNbb7nGkOqN0%a4@pUOHXa@v*spCUV_(k% zlR`MZwUntmPDl(n77b3g!`E!Ej07hvTv30s>2!2d^$lJX@MQa{jQs2^u5@Kh)ziYu zgGC1p4vsg_H9LZ@g@tP}4CeW7+1KKJH#mK*#i%Qs6FJ5FG(*XE$2y;Z6#4pf&WsHi zbKt;0xkaEfyG2hd`{t_>U!$M&larHSRF{=9g&_noWp`Ytgm?GOex~8yDqc{uVu4E$ zSAKI;R8*<c`ylF7VMEoP{0{E9(dAN>sxdBAjSF<|dD-9V>sF{juNyQ%&!fjNI<Jy4 zm{%Z>eZJFE*znlYlngnOh0*6GXA3NrIh>SxX8zHRc0<~6$#Gv=Lm?1&Oj>}#UbW6X zploLEz;O$qQ~$YvELhDV1-N%z*MQuVfog=2g`FjPO4-$5vl!Obx5*fLy}xRk5$?VC z6Au^~wqug9G|-+DaI7vl^cA00Jgr5`KXI;`5O#kcMppajh7<+3Y-+m58!U`niy<a7 zi{Hkxbxj`{a-g$m%x6n3g~7sIRnIjcJTMaVo*%!%TU~nEWR7@}x@~`8#XRF(Tu{a_ z#?awT<_?8J0N=Q<`IS2Ad}f+Abh({9RXM`@EspW)9OD2&Nr$}jp!KB#6Onx@$2wC1 zF@An63VO0gp;v3414{uv_9E!&x&2(c-`VC^#>7{|%o@ITlAhF?J7Y!u?Dw{XoQBq^ zsku33tkv^SfVMExNU2%rh^3SzlUp0-1HM*2Shr)Qrcs76o~Xx;{w3B;cgziaw}PlC zPVi9krgn~K5uyCyYH)~@9VLwj#tsu`s9Dvv2ywO}#pj#TH?r!Bm$hQ&EktuJ-2Ks6 zb^-C$>+^D@?Du})70<;T+sYnSnGn``Y3W*&WnM%CIxa9FK2~teGG)%8ZZ2MBWMnAK z!|s5`&Bd-ER6#&Yl;5~}b-e46t=A+R)8@MxE`91s=wZ@$?I#lHen<2Wj5q$kGOCf= zx%@D#t$-1S#e!RxIED1E*G1aNvEkxvrf~$}-)$svsS!=)pf-7$r0#MmdZe1}41@)D zY3~gu`^zWfL#uUsI?6V$R1-b&(Nf0xSj^(Hu5g2&xKjww=HTOpgpciueKDf(-!F_# z-^0y>=MOZiRS}y!DOxbjLzj`13h{@LuwzA-ad6Xv)YlclQU)brEkDGSmk-$R2zXNr zjBE;yzRcv_nx3d)E|<82a3+e1fgtao%b1gvPm{m<@=Wvc<=V7&aFc$?_B>ols};S! zSlATV+_E@*ul0TTE0^ynLBOK*`*ZZ7)e!agFdI^2^7ODd=6y#91g*rV7-%So+C3|> zY8PQ6%hTV@*w)te+75(sYrAQ~Ftip+S$&5QM`v6oVTkS>-1zL~V9#)<Net53|KNs4 zz#zu4@|1INiu?9lbo9$|doje_Pn1lGH)=oXgb-siOCf2=oQMCylV(3tgc~%Tvo$w+ z{>;mRH7K>XxY+Kx$U?A$%f|tsQBTVp#<Ig2o?kqT9c-7^`6^*VWO`=i1+xCAQ1GvM zt|j1SDQJHJ)Y8xY_b&X|{oRpy4XFse2F9<lP#V<Ny}A*FQ6aYiszYKi!}$FzWA9?* z9*$O|AXuWC1Aqc7pxS#81=gSC=Wks!;ioJOgQc^RZBbDJ*TZWa-lru5LDhNw*X1%Y ziIby;@t`bd4d>83!zPs37Ywi`Lf%<2GI-uS`oWKa4GC=`+ktX;G41WJe1`0;_9`b3 zNT%GCKHB*SI=@zoDc^L(JZ=uNEac-@$T8Aql_ms$^?QVvNe;4VF|1d8KitM|iD{bL z;DRMS2Y$vwqt<#Dx_pN3#T&y?V!!l^&puS$%5AXOiQm#C+_!7h0$Z+p_x|1lBsH|u z?$?T;Ln$vX!~*E`+%|vsP5HaHizDu!e@Awr*xT;c>*0dHezo@kN^|(T>*(s?F2V6d z_vHQ$qqC#P`5SneJS~G2^>*I%JR;troE;}e{=D3x<Bo@pGD-vJ@%Y(@uofFnXzAR5 zt(#*}ga2>c<eZi9&5fA!;jSg5c13wAwpX%OAvc%V<GuU2bPDqeTHN8~cwd;#Fgo>- z!%zIxT}b7=&_1~M_>iDc+w3=~OFqo#6<k0M+(%!DIn>D4*?1tEMaV_Gbup0}p9K>N z(Uu7)*lt`I>v)ReR377|-5%Xy1{|+O+(eB^VI|a4dNtv(Gn+bhL_R;}CRWgRmP|RD z0Jo>Wk_{HPTqhXo*@;FBS-kOW@V=ik&0ZnVZ>Ft8HLs5nE(C8&d!+>V9%ED2x4#PS zXrH;eBS(7Tx8K#Dtb*_(#SPrsoc8c%S&5vssjKZ!Bf`C{Lg&hSA`>oWi5XNpP=dJk z400NR3+EO#kY;bdxY*7-N@NL0fH^$41*#=%Oo9<dp=OpBmlrAKG;kJa%oeqn4r`nT z+SAY@0|4pMR)}=Uch%mwxVUr=QWWE;LCxf>K8ag8^)|mPC)C6rCnsMt=fH|41hfgH zKr5If@5Ev8UQP`^#;UhS3qd5Pz}3^X`JyYZEf*G6_r}hO8g^CmQJmhH&!y?a=R4x) z-f!`SeUtktp?cIiFsMP(SwzPxC-szp?2>C5oHo<m?Aqbjbbig#1O~ysPpqzh+VpBn z`r75P-v(9q{2C3ohn)@!E=zZwTvZT##>0&Z5rRKaNTrivuenGJV)JFS7T-9nr}ekH z-|Bd%fD;snB-E+O602%$!Guz0?P>0+4?OQaBl_!!0MC^?q40Nf7!37Tx*3OIU}q6E zYr!8{moI|n4gIXFDqD2a)5$me_YnPDFLdkIJfV7n8YfJlpHmd;mtQ#wObgaI)igj} zp32*6#n;GKlJGF2&FJswS*^zA`Cb~=69=*RZ*Gw)IfuHr`k07G(NB^0LNNomzTA90 zNQn1FJ(MMGt9hf2Hlr{qI=}KOR6KqV{j{wKIefE|jOa_~&f+UH9r1W*n`AaWes`c! z?id0Yge;wDyJ*3PWyK~IdU<jF+efT}D~}CYJq@A!{Jfqw{Z~7qY-1nve)5=)4v-jx z?2;}e99MNbHg6!nq|&4e*oZ}*$z%kR^^v7Gd&31hSG#EaZpz3~ek%7Bq^ZaO$h3%4 zBl2?WFD%%0BTkSqUy&|%k`UObEr%+}Z<^r^*NqkAe_B?ON#8c7GCW$D1Sz?BUo`8L zdfhW)M|T{z*Y-~`QarxI)qE3%OLb{+SPl=G_n#9n)1jJ6`V0veGkts6)YzCQV$N%@ zYK4_wE+H(<Ttf$#=}(}|Zd7w%Qs(dyFw8MEtgIwD-7;64wbbpV)av==CHc$4a8pa+ z<Lbx3V-r;C!UE6;tE4h>wtC!swQ=68@z6sRU~C?fZpzG|`AO92$5)10E{%SjO%wBq zWT6-ojK<xa+AJ=tW4&X08CjVh88K5q&vj_K+;vQV%s0c~<U4gfJwgz~pmb{OtSH1a zcAGx%^EOt^P#L~UOAYHQYEV@ptbJU$Xk|Qps#2x(g{82m#MR;yX8trhkTO!;3&WI5 z`cuQ_)>uo2NM!e+ouj&z0wL<$_k}%$l~a6bG~!<~J#sHDWL>Y1Z8%q)nC+5q*`jiv zp4E-+?!J*Bb9h4$$vlL&j)}ysY{4@E<v3-MS3c%i855iYhg=7`GRjfCv3=6P1n6z- zj+)DIB#s%kOKU~6TG9|!-8J%q_FMXC?2&3M`gGo)ceLW#>wWkU-rr~QGA==e+`4+k z#fqRPCe*HbGawd>4fJHTY|}X>+Ak)nYd-&NaG_1{YL9D1Xh?$%DE*QD;P8%^smM4J z^GUt!GT9!Z6|lR&@6yV@I(k_!n1Mv{gMZen(tS+^vhBV@uEFo4b#;Mv%eEj=SXI%< zUMg3zx-1uJpu)}65;qW8)0@<IMWLY2myW*2kQZxznqGU^i+kC}|6y8(8rbVj!9qYw zES!)4{<Og`Tl&Jah67JUh4Gl%<Q<&k$90`#?c97Qi!^;GW@Yb?GyxO4h5frcF52;F z<hTBI9JxixFJ$2<X}di8ETO9WDNLxr{Z`gB1`cc!bawJ3^3l!)Ghu>!?s{Qh%|7}5 z2BeHj2qE@KCAHzaE#w}8=Tb%%m-mD68&#-+Cn8FiYQTrg@94;!8?yI0ei7@-Mdaob zt+Dd617>FU;4y?{t-iTPUZo4C@+}n{7>0>pK6<w^_}%Kbn9ZFqlz-fa^<(QXk_BXk zcRsPVft01BzU}rqJzs=b44G++Oe73;+5%106t1cbmFq^D8DTV}Cs9gqAI+o<$|@`W z*t@7Gu6|)Bce=OrtM~O<?#sAvu=1c72o$@E?beX_+bYv^T%KDu`XyQf!5QL;lHzDB zh3*Yo_=2;ZIAf7Fs~~}@tQ>V#Q$!Tp`^l!_e4=K2zvx|0y%58U{%TX5-d4Zg&Dc_@ z8t7JjQ@(J7c$TX~G=<uv7pkpDMW2aj6@C7ed@BdcN4QI34<}^)VYcVTGcs`YTu!bu z#wPkhUi}Xe5-tC}-26<wX#C#$uQ9!JUF*6j`#an_&B>0IO}4J+mm+IwBvJzU%lZ!f z2t>N$LeoMlWmLFtK(vRrub1i6sv8z#I-=pD(w<1ya(6{=lp5<d7R<GjFY+td<nnQt zq{s^iDfvyfqdO;p)2~LCsj>WZa7ocRuH}U1G4sQW71%>-nF8vK6uv3MH-WfK7W<+Q zaY;BBhV!b``qhi)0>`EyshfhDC<O4`g{jT)X0@!fPUCd>=$AS=Kv!R~Tt#XZn#rBI z2{bfaWvHiTX?)wy^mHmY`EBCpv^jc=hu#9-{@nc>>AtReMF6we=T_n8U<q`;(YX2@ zcRCNM{UY1<Ibu<&bUWYIC>TyB3Cug7CLM}-W^IuHX*>oAfYYi;*e};aMn@)RQTxr1 zCl{2KP!Cvur{^n6Ch-38#k$oJ2_`i}ap{AUx5^+D2Z;pMbunDoTLe!#X0-i1ug+Uv zr${&DW}F5*WGWCm-adHStd~$B8^RW<vhfq|rRY|yFqr-asI8Gikw?|=XcrqPvDrJ4 z|8m-5<oE;FHY##?{%4t=-Njlzei%goX%i56Lc40veqzjd@XQ_&&LJGh+z&1@>~Dre zfqmz6G%pJzTF%!rD2K0|d2*I-+>8ibz$F2Yq%2IGf(<BnzQk%}fZx8>Z*+Qda&pdL z#^}sW8e-I=y}9~^*`|-#r)M{ZgQf%=Ht#+Fo0bs-Y3pW;_p6irirrM5Z<2PT_e*Nb z@Eas3#Dg*tT38fT(YcI=7o;ok2(RDaDavH+qMLo8Qey*^@-x>NdyGic>v^n;ZEZkd z82#4OTC^jhBJA8>!IC|Jg&zB^3W@P!qv8)#33t_R0N>Ps6Yt7gNWSICDlHVqFt&dY zfxZ`iD0iGKKa<bLaUm$_a((~RDB_tl<4DA(&1|`Z@2H)|C}_wT+cMMh@t{mKFq~x} zsDu$G=vsSXy1X+IMH3M;D@lQWSt!$+dO0M`?gAV<Y_m*mxw8>B-xX5%{sJ`&iBn3s zPq)UB8BYZ><(=<MBw0+1(v<rJ4T0?wgX>sLYiicaReKTf<>Tv(-x=`yxdHC$2+u<) zsc8*1xxf(~(Ccm^Bh!kWXXYoY(GwXh@`w3y0^}Wh&569>h|OCbv0r=ga%?=2cYdl| zCky;hk@DodaY;||`dzkrMoY+7t(k`oY4=Jt&PxnpNOP&hUMqBnn~&%ZL|zS#bWOcQ zQ4V~5gtWL|2v=JwsxHl}Pr3>am)E$UIoTZ7E-gyoI(Itvo4e}IKx3E6=QxQ;7f-LR z@C>Ni@iw#y6@Qx2h3+p+_qDgc1TO^tw3}qg!!YS*Vx_0U`aw5Z!hi=sIY2me#<pf} zcrN!KX)i{>5$Y8792y}HUPv$M)FOWgUMaZqFi?}z8+l(29y7`Ok#~PqiWPI=p%7Aa zxi^R3h<6h~ikXV?^YMs3X5k)5!#w;BiW5w;Sr$6YV=BJ@d1>=0moZv^QJ$s0H0%PL z3zx>|d2S+~JbnF4)nB2is;pC~TFpm<ztpahF)H)NjX=;DIAd&vQh`(+kV7$if>|fL zzb`z4O&F?3mXSiugDHvVp}klC>K|-J?ab3#33G4Mu#sa$<w}1?Z8NrB{Lyq(k7iwz zVbQVwm^eyN+0k!b>bZ+ILUsE+XVxCOluiW>9{$4Q()0~B%*C$O9N8?T0fM~RjBG3_ zf)_VA@skn5kP7cj(MR;!o;ObLOjn;1G>jBtd8369=Nq=z)Y)seyXsUs{PvtPAPVlG znAp}BBXvPq!By7iPqeU!n#=x;W51_78jB9!fSNX)yKqiA_?VKm^nO+~y@Dl#hcLxh zJg&5ve4ma2S#~my!5A7Kgc#pW%$lf7L?b6Eh^RG|cJbOIO5Ba}DCq8Ddt222x*-4r z1EX5{E_UCm5BQJwjaYkTtcl~TI-WDyo1PhbY5egshG0C<<{4VSLMzxOTW?1IS38{h zbgeVMk?#(EDl~ot|M?9p-{2IodoNqZ^FnD{2+pB7=4Ea3{P<~)qw<9=x!&!Qtp)-~ z{QCG2e4ur+p;WoU()G10pI0kYfe?F+Mb<@HT}1`dfpd%{wNx!{+CiY3F;BwIchV`e z%sbjd@2fKTist5R+o>$OdlIu~ABHMl?R&o~p)C?A!n2bTNVijVfdEr&^YITV{BOx( zaSr0+%n^Faf+Nc7iNgvxohQa8XsUK>uq*s37|t83`5cBKu;Jxfdh_IxHhGPa7s_pl zSvcH8If&3^xda+CQPc^Vd^UIQ^MghTjp7%zU#A`X&LXLN)6RP=j0xyZgtj%bV#BJt z?D&D<*t(3k@72w<Txbf~!x}4k&jxQFKPpxkFy5$2hP&htV|>ThvV>NX)?tyyMO`Fn z&%dnaefMkhWaQ}JK-V>Rm`8Lo_^Pq8hfkK_HA^=y(6GJhHh;@wtoMOS#@xrtPUvRj z=_If$llDCXUjI&)Qd+U0+fexf<gjH1<?yceaBDO#-L@?kMZGLBPsv<RV7j854%XV( zps$de!KuZduTeNe7vpVf$I$Y2YX|tTf@wM>Us+AbytHSwp9e^wyD_(xz9lY$3F(uw zBjUba+Ztm+aceqK>CSn-4!^dUdO9WpNU}6e1{L2+|H5NJ_pSl#VhE%8A%G?71wt_R zX=VRhBaPpe{DMxP-vzS>Hwuer12Q!noA&7;inX&1hmZSrLz^J3F*o^OLTSaAL&ia) zn+BS2)vOzZP>I`@16TpSHsGad9nki-*Tx`gXq@g$MrL1gn|G@rq(1EipN-lHySzYg zF|)W$+G&hbqg2NsP~;)x856$(x7-;4Dla<{oxWFBesF~BTm+b4wOO6%$7eN(&2J}E z8ri?k_3*yy7;MBz70YCWV=Ync(TMv~)q_4-{8pWQngZfbO_9h|`J|;0@g%#=85l+M zy)EKu&-A`g83krX=M_)x%Brlr5NYb-AE|(Rf{VFbAl(hjc#kPbZsb-A!f}vIOik$E z2fnmIBF{OSrJ8$Yl&FqiEy+h4;&PhY=cDDyto+c%mvHz#yjUav0%4HM9li9C!9pV` z@V{L2OoL%qU+U8E6$<iqTky1|rQKj!Lnw1UkqCqpjY%gF32Jn{lGzT&yT`&h+FJYG zB5^~c-I#we2FT)*C@bVfCPET=WlSZB<gF0S9W(HqK;<KWlu=Fvf2c-)nzGl8l3iL; z$xh~FD6QCS$vw@;O`E6Fa@@OW#nX%9lg36mS75uX2y$h{`@4KICg!vKH5S2b#c@(z z4XWqCjHVOo9gLa57LobxipRRIh-F`)orgZ-f5ll1Df%KDCwFdCf-cN4&ulQChDn5~ zhFvE{QG|-VYq-6L0Q0|~f61waZH_9-wHf&&Ifuw*QxvX#K>WGenq6$WpEe+tnR8O! znB#O!>2?b{EziAeqJNHKYaf<H3Yz!t)Z{i&6>{)6$6_Lsyf*ApN(cvQYK{q)S$1NC zW`v6U%5TYbeY#Rb-E@fS7p<2UD=`a%JeSV^z{WV16@1v<zo--{OByo8t7HkLVb!7| zM7E9EiOI;=3~ScL%(662fN;vqPMn^sn=gIwjpZXPtdkjKR1COXF?g;jls@H}8a5jX zq@q={yt$T8JkV~8hqvW&8^yq6F#zPyC~jQrxX{nlu-0mor#Aid<vuq;*~25l(n_a@ zcw2mu1m1v+t{$NeB<xAi!R7Hk)})wE0`M7M&`!Wf-Rba89Z5p%wFP%QJ0AS(4VclN zqPBkCrd~ZArO7Kq-FU`nLXx{gvx0-E>2~_%b`e92v#qqaeNnl;oTtJ>xr5DgsST!^ zKWwA?LkErf!el_XXiMg~Dsj+#IMsy>`0^<?*}34>>{AfrHB`$)Ra-7xYt@;bca}pO z%&<grsk~h;zQX;g4EXXX^ZxgTOuST(ZiM=2i4>>pc28{amDy;y;t-}u7N?dQE;TK6 zL%;^QJcTk{I|x7f2KR$;ULx$o(cHY8YI0oT-pGh_ada?Qa=MC9%M611Od&zGK8K(L z!<&~iE6Nh3|Ba(8;Vt~;_5t<Ouw>q3xnc&2m3Glf60jDKGoUq;7DObXm6*X@!|}}f zZr45eL;3nMwTf=WhFZ7wZbwA^Z2}=W+CJvT4iL{&exGAF;$pI$J_OidKdNs~C@8}y zdlE92LDX+6W_7iRQaJ_uP62<OenrsI>x{aen1&$aQmKX6B|pm;#ThHZsHd%JO)wbN zj8BnBU7K+GZMWqTs9OA-n4&<ks9bP`khKN;nw@mj-9Hm72o`y23z44Z17qw>3vRh4 z@=dRfT=nqNz#5U)skkQyaqL$c=6xBz9cfhLg_a+sxIj4SQg&4fc#}M%@}E?hsUA&# zK&7>rFJ8_m_<F^Gr%N&xxq-9XZ|@T>em-Q4D&84ONw%{`E7fhnvZ$KP2+gr2Giw$& zZe6CdU#e*zIP7V=tXJ=r%s9923()TV%wJ`jTTyZ0hl0~gy_o-eZ3?@hqQZKOYHNJO zq<A>-`-8UKh_L?)e?zU)yn^{V))8MxqBrB<g0VuiAd`(7r_^_>eeFgIAHYK~fZTVu z9?_Dnq#mZrG(&xFM=?i)DS&1-2Y0RX5<-$i$JD3lU_dTHe?})b4wf2n#D9W<6G^~n z(pLFZVqQ2S$))c6c64h(fR>563GdoHYyVt~di~&KG99at=b(K`o7EWiAP1cu8S4IS zZiEnp!?WR9t-7vXt&(}pVT7ml`r~V_M`H-P8SQVpMo=rqO?G%>V(vZl#L;QUuIY2y z5J_47tPaYmTMtad{j6soiK#t;k9YW7cJ|9}29fMT8GqM@*BQr+3&<1gI&CwM)m(QZ z@UWt3o^f6T2i^zV-gMlR-cwM*y>48nrfCd7n_0(HKTy1JlcNdDql+tQt!<OEsAgXy z09nN0vzFM1hB00VtX+Mq==^f2C#wtU<irD6S-)=amZhEbp6&k@ObM#zzj`6SPAQGO z+&hk$GA5<Y!eV=@w;wZ4(%bT8O!CTL8lIotKws1rk|!haG>83(#Q{UR7}{j-7(s}> zx+a}L>{frQ%f5q0x=c|bI#R~QxZi2pgnB$S67}sc6Q4$*T_pW$c+lg~F-#U?{iriT z6C?I$NJ{YfifP%7^$I<=7%?{7z*=w;dUW2g&@PofE2t3h=br=x8CB_ONweVp1A+GV A0RR91 literal 0 HcmV?d00001 diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldImagery.png b/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldImagery.png new file mode 100644 index 0000000000000000000000000000000000000000..46ffe9c6f21dcf1ce2ac0de44b62bbb59ed89c35 GIT binary patch literal 12290 zcmZ{KbyOY8((lII-QC@t;O_3h-GVzCclY4#?ht%Ka1FNc1a}D*0=%4a&%5`o?|rXl z^;At&{Ytv)kC|Q*qoyK@f=Gx6002<r<)k$JP_e%zJnWx)joqhh005EPPEt}$UQ&`= z&CSKy&d~}0kc-L4gww-X$NhRWU4~~Mag1(%+y{*gAI?Y~?LkCQED2N_jg0PsbP$(@ z#*xOA#x_DCcMz9qZlY&2-64+ywy@$#NzbTQp84<iU-{eg-{tR!a6N7cJx)K)kOAB% z*{G;+GNH(ovsn;tZcJrlq`7WXAqeP8@UYN*f7c;D?(PDBV6vOS2WND#MW3%q24_20 z@49JtAgdb)V5qtZp5@Jw+NIQbS|P<GEMTmtE;lQm!b&pzgwi97elE>zm{{>>(c(z& z`aWkKoptgVfKD%5Ko0@X;P`BFc#AbJSmu|`5)n#GG3l-DbwGDJ?`tVISz%{)qH$Q{ zi2u?li11!T@M5D(%C@Ik;Gfl4F|MqtjK=}hRiMPm#>1ckno7j_U1)RnfrW+VDCxe8 zqzHsCf-C=+&?C4T>X97V1Ak!-5WJP5!n>X~!i<(~6;4L^4kQ<1{a|PS%q?h^NKa4B zp7D_F#sB&f>vl#tXC+g|5m2@R+T?V>|EL>^zxqCjBLX`}qd=LG_sWFV1ORIOIPO+@ z%dp^q5EDTgTt@j#tbS>v0yY7{P?IAai^14J8hboi4-&3H*$hIMn2N$f7Ly|~Lj@$m zFU|)Zg=m|S&_h_6GOZ!hh_mp+qlQ`RLfb;w3`x7fYyvt50Y2~`Q|vDQ&0Ui02y%Ed zbqc~VNIUUg$q1Gx%@n%hNQgj*B6@mQ1z@-uY8#>fT821|8jlCSKD<9_Rt&G$LG6PF z8DS)C(dxV`eh33Q$qEp~6e$~}cjV2L{tLDWkZTXJ3x69~cgXWvy$h!weg_C=%JCbr zKn5TogCEUn9@&J!iWx3NbrTJ*AC^v;AxE+p??EmyP9hbrL`lZZkBl+`$~Md6=+9<H zCQFOa4`cYMWr1p8z_FDrlx;SReTbA9tNrz}X?|1Cnw%pfFPdR!J&4y-)q>3euBmj* zo1Zu_#A1)wwZDtrh|`&-fw&WIHS`R0|3k)g$w$}(#wFBy2yV~!$uR&Si0_U54f2gQ z2>ZQ2jMf&T4q-doHZ)mHs*0MJB9Cs9HXg$|#!V`)1dAh@p1gtFnPLS?D4H*(6r`Uj z93$;U5s{iIe<r70X1!>&NVQ1BnNug}Ma@P{mx45*z5ipscHit4E*5e$d$^prcwdcI z6IET1;gP|mN~;DULo%VlT9Z$cs5+}kwd%^smh+G^h!ZlWos);Np0m@+WD?Wr-fGJ# zYXWy%XR;u@k3on*Hk~W^$K=ia%J}klehN`)Zf50#;RM`7<wVvLS;_$IhX$Z7yV|t| zIz2WMu~t_ZyM&}|4>xOqs-bFarEx{V;wKN>t)v1awo<av$AwC49Be0?5u7_52kbe9 zSOWMF;NDj`D@U_DQ)Et2Mmzd$rcnkb4SSuQdhXJ?ifQ#kO;&AZbyBsrs$s1g4SDtT zip7dsJ)Bbex*jziRnNjxt7Unfp3kj>AM3R)!og6UdRuxTQi0{a#P3b+?NF3a$P$nf zwg|JhX?X}f6VF)AkbFMkp=+}>XfTjB5Ncz!6|rID+{&q*X0+yWS1>f*&=rz>0eTfa z)S)WUDOJi<N*^_|%4gLRHTFt&DtarZDzd4$WSFFFLj{(I8h%g@&I(F;i-(vZA2ux& z&mH1d%sKeVXv)(}N}z$Vh0KL=hI~c17r!RMAmg9lOfWL$H5N0*GsdTEishe1oz_SD zTA`;Yt66N9f09fvI=#ibS~uaimS;w4YGS!<{kAAEM+r91l};MPQxuxgn(~{9(m~X@ ztB<V{tTQnrGQ6vIsJjBIIel?j0k>^@Y2j&3Xx*~$pG&mHv+Z1Hn7VB33+o&2Uk@4< zpQ9KvOBzAXokg|IYHbuWClMiD6)f=ly=!@ue&I2EqHDu-gndLc`{PdU?)%~L9MPwR zPkY_Ot{A<X#ui48y|G(uTRzU7&Z+`E#1NGsT!+s41?NHEUdyA(qsD)<eMMf4>HWNM z665pBC)4l2m%%5(SKD9YX5~iZ+WEHNw)sx~Wa%XC{{C_6P-wq$@9U$(&)m;f?7{cH zor7cFDc|kiD<Q@pN`Q%C{H{T}4}-EuKk?x4+F(M+2Z}Dllfv|ea)v%IgIJJF^jfd= zqqWCtk_)8Uq^Iym^nbE`qw-KZ9$_D8%4=$HUB9N;OW5PWD8RtM_%0VWzMR5WqE(t& z0xrE-*jqqZSc>bzy)qK+0XfT0qz;wWl|L&svS=D-_MC6Jtsi_jptES=z~GQI7rhDf z@%(b4H?StstQo)>jQ1V^q*|lMj&_f!jV6loj%kc0Q+1VJD_~DK&eY4{&jBgdsQ6`^ z=Njb-r(veM(MzWirhrpr<l^LosI<^4;Cq*NmhP5bxRf{*I6*loIYL~OQg0=Z%=8X+ zI{v&Qug?#M_=k?;1hbwq^%H@Gcm>{^A4NZA@AMA)j8@=Sz-+_p)Pw5w8_x~O`|P)B z_LeVe(dt50Kn*7bwY?oa7q-Q!dwZT`o(yL}%q`3{^nSgf=7F-!GM~(D#$gLllxa9= zN>YmxW{DgIh62)lD(}$dD);gQGT@|}u(dMRGQVievJJe|FL!G1DDZxDx!f=xu-eht z)Y)4Za&q24)g9Nx){1vT+uZI6>n`>9x{*KSZBpA-U$-R<&S+IM!ckl9H*|Si*($8T zs)e%`wl{dFx>|3uv2HZIx(Lh*oM|U)w`wPQq`MgK9y}6r$QL(05Z@fy44XS0IrHzg z2wq()0;{cDKPO)&Ke>+YUCKm_jZvM-c5n|V3n*jBW)b&!PT%SIx9Z=8;L0eje{vN* zdb+!^=qD523obdMezCk`c-8b*SyIXBkf>)es03qffG*T8UTqEwPflGg`Cr4H(V}MU z3+n|ceVnI!7oWf1r6R%LRS0nj(y`GR5uX@r-(PF&m-lWV^}evaeC+odeVHsLeJnuI zHEt;AJM_4i_I$YSAbQ|4@W1d=eYbu5aU%NCzmki}x8WkNeR^ED8vNF=aS`V&d}Y*q z=KVM}7#i|6)HLKTsTc`*gnk^ms@x8~Cx09|9~qWilPym=Ak`IB57u~0TTo>&_rK{j zo7>y2j4Kc&-b?!OBye`5S~@ycHOKh1ZH(}1{nt4aAJt92{-@{TxOlwQG@60&_m-pb zy(!HBx1fvs*gV2O8b2Ce<2RXunc~h4m)?r7%EB*-{(M53zf2BZ_t4JKM98Q_6K4(s zhl6W=IsWYa5%-=Yo5~$S9Y*&(Far|))HOgD(1=znNP!3dvuJ%_E?9CLa3DT*u|N87 zo!9VU{{Y}FrI4y|7KGqW>=CChAR<wuv7m<=<mC<ib(M+ZVj-d%M=4Q0;UBY~01J3R z1&GE`r>^&5PS|LDpnQZlp3Yl})fg#8^!p&I05usp9K38d01-Yu5=X1~jp5HLW2Tj! zytT42fbkCx4}gKd1VH`aApTqc2tokN-#h@I073L`UIT*u9~(#jAj%E^{f~{oANtow z{xkoe|DjN+kpQ?qPndsZcoF2kt;LF<{=@�mL;W<>miSO$#?GD`$6G7mrvZ)W$yo z1XnqIcK`sF=C27MuR(nc06?zWY3X_BDJuzDxHz$zS-O~8vHCc<{^bWC>?8Pxb+Ym> zBlmG~baof?5uyCsLhuj&mza%`{BIKv2N6m=Wi@h17dI<%URHKic1lr1a&mHEH%n_l z4Jny_;D4S(C~ZAFTm{+KyuH0yy}4Lj+-%r51Ox=w*g4raIa&T#u(<m=dzksKIJ;B* z%gO)sBW2}o;b!ORVdvsZ{+C}fa~Dq!5lYIx0{wgZD^DvQyZ=OTcK@fWKLxV=rD5Y> zWoP@}U><hX{~y?2nt#FmuIpdng#U6TsAlJ5<)|lR=k#Z(|D-0$#lz1n{CAxHNA;gf z{{_`{w{nwoar%Sw5dF_){R94Q<^Kf!9aH~5F*!N-`2RcRf2sZp`d1Nx8dmNuj-G!l zqPDZ0hbX5o+y5s1pD6wRz(hH?|J3(4=)a}^6QTFNBK}+YKM|^Kc7GPa?61^BIsS?8 z-?D$~h1vev{Qqi(e|6g5(m$;xiYUzX@3s|1{Fr>f1OQM%$V-W9`9SpL>Q`B<`|b?1 zMsdv@&GL9_d$w=ccU!f~SYpzlL;51@4<UpDom`_oLgJ#*qAzk#n%<g*Qo()Qr+}~_ zPnpnM9M6ogM9H+A$Xq@ZU*=iu^E~28^5=hkUG4Aeso7jU&D=ltf807c?|U#f%YEBv zTA9gNPrVZ%>o%IroO-;U^uK(0_m*5pwU{4pvlpIYz7|1(+zDtXs5BE%BoLjrQR9-+ zG~_Jij$ui#P)rS<`>^?KJ1IGI0I@+b3Z~fQdA>D|OoCm?%~-<2Ip?#u$LymrnP)VK zs1x@Mw=#1GK}cKtoE>+kB}XU!;fp5sm3-(<QskQ+&mfvG6E-9gja^yZzJ%h|#F5qP z_fbg56px;8J$UcnmfGyHtDZ=9x`;LC6`!UVRqIR;QXFpcD2CGBE7|Ieg&7bpQis)= zk@b?xO7ROMh|0I$YFLR}7^~ZXiqOa~B~@Ox6Y>}1!QCNOtA4nEt7iO7Rx@&>=sfx~ zRjh`h&s!<!2TZ84v1f%*g%J38P;x_-H%O>2QcPa>pr0!9O68an0Trczh*EA9_<|q# zBAn3ubuWfV(5Jy0il6Fd@+-CJs5$OJ@CvWP)7#tIJTklj4U!_x1US@k5;{=E#2}r? zIu-9GPvtiyW~fvg96X{w%`!1Go5;@O^B~3oV^-ZH14*pi4q0NI5UC+DKB82)_^@=2 ze6k|TzLHuBf2^Zu{)Y^=gnMoypB?1+GNcU5aML5DZ=Guk$6RvpeX@CIF<7tWNWs)p z7>THWM2KwslFN|xxZ?V64!oiB%NaOKBWp0wqjUwPyt(Ur7fu^Q@x&tm96AOt75hWP z0@z2|-*c2@mdK*fR5^bHa*#*0g=*-NqaNh|PVtLMPo>iIplPBGDOD1zTO&xX7i>xd zkeV;ts%@tLMN%bJgDs$!e1mms`B|OM%7zzhs_;f&?C(@SchSQ2y}gtRGH<6~eqJ<P zgc5L`z<j+$7d}N3HddL))xD1()VEeCZ?}D6VQW1gegZwn!~ninAeuo;DVqBxKnI~o z{--&1hm&xex^^41)6FCf6Xh1_7YH^drQA?_Id6yd&z_~_7x!=-1`MSX#l`}yX3E@D zGT@~NkR51yyWn-`vBB``M*~rUjT`FrXUZ1hL3&`iozDp|5Sr;$n#e1O#J!;6jq>8; z(_ks+g&T>y06{ULEc97oD3p>Pus14f0!S5RYnSNXb?h;QcM6W-wxa(sP@w8KS_mEt zt0MjkphA)x&`11~3xgkZCEN5-;IzBw_|4W_cZ0|O@;i)>|3jW~C04CYZ3h?rhEqGo z*lh9b_Vg&yjf5^Y>K-<tKqU|5wH>JNb7=CJ6;Hs=`4M!;h=u|x(ZcF(V05H3Jlo2d zPRO_n{|IsgJDvEb)kZX)49=Zm?V$+MaIbl@sY$c-z1za9w#cJNDw`oz3Dtn91J2Iy zdUJlY?s@mUr^CYAHgkJm+xNHG#QbWUi}UU~RI-O&5&wFjePb;KOOr*`S-=<)I*%lT zRWy61BDulgE$i1_c7S&z%YhorC-vhCt|H%JZ9^xd8WaZ{jc9$n-gf5%nKZqkqCJW> zDWT%K`CH!h8Oq04t5%7bTT(0q8(z5__60Lm38vqSyds@c&|Mk`b!n<j`EQKb!)<CE zTU&5m9mbtVc&vI*?$5XP8#>8lzL#N48aiZ=$41{1GKDpNqXSYI_=~T9O-M?t+$16= zvmgWrQ(sW(?z53IQQiAhT4+1AYDqZd*!F9*>iB2uMpU^FaQIAvARQKX=lWo<@RjGI zH_^$J>fut5D)mhPm#v6gZo`<gTueL{*#LV1l0P4ga8y$(s=|tsC@*(JosLLN0dL?| zFH*Lj5r!Kpp--A9$@Yv{$+*$KqSvSj*y^;V!^rq`T)*ch4uAmFnx$JEa%|mpLp0Q6 z*sg&9vwpocg;Hm$vOEjOPrfsx@tVDUhw&nh)7l$B*NnWE`e8>_Z8o?p*#LLUU6x9n zNfze9xVl3wfoVw%WZW=h{ySwbj^lFfnz?H-j9^5h@`4@0P2B3$`WJso3o#A}A-w4Y z8a+-J>PCJ|XE2B4)nK$jG7teq7<0S|PL;UpYIBMXyh|#-g$LSHEEc^8bW}9Wl8rck z)I3)(q5UoxCp<{o{KM|t@%N<8*F-dLyENZu-#oz&#>~%6oUO`Mz{SjGVJ|88zNo2G z9$mgV1u21$c@ts-<UO%ymS`qg(a+IL%n*4W!2&I-iIJvg_=EhjJa_t`VFBJaSZ?s* zmA8?cufG5n#GRiR-ZqS$6bZ?NZu7RnCgu1+uy>=e5$qJeG>V34q(Ml*O5G#aTH8_h z#MKe_4Q?XTr2TYLjr~;0>I(PL&+&seV=5EZnV`qxuzLgDdNM8FC{siuJ!O9#mB^KQ zBHl<06j!R*EM|#v-KI0bA2L2A06b<&t2@*S0@(%uU}QXk0Ju1?O0^rftAS=@a6P-> zC^qdv=C>;u5Z?Fn^c%hUEFCtQfN~Qn4Bk}OCYS(<o4$YgFfC=7yb1Yd)K4yh_!J?| zRbX{0K`6~{FNN(QfAhgA-*rs<yz2nxR7+DTYh#j4Sj!|k|Dn$l06xQ}{D;pov|M*K z;oEB&+%p_vVl-ysuusICveG%uv+-O6^Qd3!R%$zh%v9`y-Gs*gFlecnQP|X;l@FAp z2tqUHUpY`<KG>&G-3rV+27dGVf^SBonOnS#H2<*(zmk*2h?>^`Zn}iJ<;Ft>8=+uu z9NtlnUL#za6bnl|&3wu&tR@3P$|4~D8r&+3>7rDjQ`cYs)*I?$saN&DXFyN2E7cKw zWkyJ`^7iGEW#ESkOq5krqHm!kty>il#sEq@r}2yBA=4nxYS3%5sFq-v-%;#VW)DhI z1<+npTZqXrG<|^y=JphZ)M=*PA#>Uwc8!HsJYdMK)D*%X!n%~v@Rw+3PwFX|J@EL> zDc8NKH<Za8Hiv9E^aN2*cHU+Id-=35c)R2zmL^u!VRm3Wg)yk8;*MS9J5Ryl)(vaH z$|EZr+9Y96wN}0(tA@&Xa+eMP6CEW%w?Nsz@-Y%&_LA%5CAA-aFsIZas)Lmob_<8X zoH3sh!^|xnVFm#h+lIkWM3|P%f=M*jda6<Yw3}!Zz$}!;LX!2aCq!ex<`<I+?a=zw zDfSlAKdgr?9U75|Pr2w3o#vuvV6P9MTP<9+Jr*Wr8!AK3>sl>nki%wK7_sTz(-@1E zERvg;|18W65wZ!H!IVj{T^)=;#Av;^GA^M{duUyJg{o?`yiV6P{e2yz13ro#by*~y z845#AlVs9G+>~t3F$(>d)q`0npsA0EMV}=n^P=<l98+A!sqNv@u+0Q4EPJM`8qe25 zGm)!O=~}iFwp|IAR~JLapwL0bghc{y<)AVlP^L@2Sej<DxmIOn90Pv|4qoUY?>_PI z7==$kF<DbX#tBdind-e;=}%X~I#DaR2i0e#d&%!%BNo+#zC1dk^&<spK0*ng?F?(> zuyiDx1&FouMyJH<QfelEVIubc?N@Su_RLN}h@(Twxqeb<rgEvLMm-(^owwpp6Von^ z-^u(BSLafG?}l=e!xP0+p$lN8zE~Bg_=jtwE-B~$#jh82qV-&o)8x`XhgnRXVzT2g zTUj+yt`cvMguwh>EuBSltfo?8lBvTyKX>g4ykTJ+UPRNew)enVO}zM$oP<NF-mVVo zeEYZ~MlVkNu0(XsL5aSo9|VXHH%ilhYV7LKI8lmQ06ER?$fFv37B`;A{2_L={_atc zrm{~lc~z)mW44CdxIl-{YI&&52_wlIAh+)8lIn2ly+QN?Mlf<B7Ye<YtJ04WDp5^i z`H!h{V)ERIP~3s2ftfhRrPJaaiILFTdGN_qu0QHTj;}Tn`uwSB_J0G9DXYQXk^r)d za?^A=Ettc|@JbM4>7qwi!+QtNY4k<kQ^^lLK{miZ`wivwkbCtWe-3W6Q9p@)E|0t? zJr`W9x;7d{m;_WSLF8hqaf#FQn%7Uht|bnANFug&D76rJ+%adZk_9wJ8eq%w-Dw0m zu67GxFo!JVFu5=ktekhV(eFW#MwY>C%&tZs{tgjYGAL%kkwb{bzL^>G0{+Un^K2PO zonptT;X}gVHiJ|X7eK-x^H~uw!i@ZiEp5uBlp`KZ8G{>>rAp34Oq>!fqFSZ=(D|z_ z!4K+;bP)Z}UHG$EzYik<bV4cuy<m8wbAc<IX``OF_5piydqyVd?)RxRY~*Y89Y`_! z;lM(mY`@81MZ9TD>5N&F;=E4`l48X9X`Uv4>QU!rOeb%<Wp)JzF=LHm#nbbGIbM=5 zT3~p~Hx{mpL5Y?IVG&R~Hs+L>`$clNOG*>9*KO?S6}Kp!$izHwiD5JWteVsLAZ|i6 zG@L==_`#K*a+OU}=@9gS-ryrvpx_LKQTSO=5+ke!LrCXST~EjcLxgzCxF)(+|6A0H z43Qfe#e*ESE4D#UEt@7X8Y7QEERAX*8lsVyT=&MWBNjv?r?_{i{tom?*&0LE5j<nf z`fz+Hl!2BLUB*iXlUc7b*`<p}{G<3bvAms0y0%1J^geVunLV3q4xl^y-Kg1q!N<1O z`%=iIWcS33p815!|5eas6s}tikC-EIx(k^$9#1RP$Lr>IY^pE-%}^ZYI)^<p<^ZID zx?V1ritX7|B%!;jZ4>Jdx2w@C)sI$!`{$^>Q&&!s?i;*Lv-=$DaC)50LhSRmp0JU+ zQz6=?;zAf8?<lLbbShI`8X_J?ew>YimoP{>!M}@RGneoMkA-3P?4)uaIC{N$bIeF8 zn_4=_c_<<mwdh1>DfoCV2VcbsFr*Pua-Ub%wqm<`Y6esiqbJ0?jeRN)vmE*?sAEhv z`~AbQ!AF8KOEGZl5!I%Fe?2M`5Hqw&UAW^8FKF?XCawP$Cz#D|TQ5RVp41Z1l34iE z0}V|*I#L_Q(u&qIJzo$343QRIzGNuk?`P~*-+~rox+77poWt<acT_4Us;xnBrr{9+ z0#%s<76rdBPE?v8Jq>D2nxQviO(CBl?dNjnzRgI6Fw!eN+kMI+GiMT=7x23DP{i}L zB-5(cu8jEz*heh#RciR?z&QbxTUv9(JG<`S5;SEp@Z8h)bEt5rE1U#G)Sp@^eJFu( z1IoCoh(F!{n%h9@N&nO?w#GkDu*CJH4mQ=S8CI0X`&E>Mb<3{Hm#euaCu$zwAp8l3 zrC&&`tiDb8n6)zr3J5WKbd-V)gUZ>Aomkr_l{ycA#977J+RJp);5wlhq(qP-DJ?_x zYh=gY)ppvLoi%LOT__8`zj#Z@-}z#FA%m2t>X-(sisdCP{_fu96w-@ytVt@TZPML$ z*)$jJgE008amqhRf;oebw*Q!)qo8o9+lnQtVv`f-NeBcAtB7E#)%>D1QiD9eW9-t6 z*2$1<Q1c9O!zQenr>DV+>n=`<u`C=-jz3d~Z~M|0Gv()Wyg|*dHl`4z65<3~AIc;R zxQ!_MjqgRQAIwgUl_yv-`Q&Sr9jhL>*6zbH;TNP(ZUezzosHO~AzQ~Ri<{sFXwZp6 zuqB}%pJNgzMWrW~vf!?;2=6T#01;oha$Cw{1{L0Lv=dKcF8V7|vi&?_<eMX*g{@SB z7@v*y1f)J|FGJ?p$JDY*aQKIey_9ypZW{{pwn_@mfhb*n_;)&QTwFMD549>n%PKA& zK-RG_ehDi~4M@862I{ouqBMz@JC%2`o9DoxtE=CJ$p5HJ7z7_erIO1A&|=%XQyOqI zYU$_(u3F4&8N<ZRQ=LdgK?U?59Ry)uH>932I;-tDCa#Gv`B-8U%`fLy8Wb@Z_a3WC z9(Rwy7$H{O6P1pm%5s?EuVpA^IeEUu|2Y!D4VfJ#yszNVmn%P>iZO=LN$t@I{I-)f zXshrftVNHcl2wg<;7*mRWzuAKPdPk+NrJ$a8wo&5NKW_E4Biaj`tJFaBjTl?)-W1D zKYrKZ9VWct6I8V(#3Nn2J4EbVu6|J|KqTta`sb3E(IGlrJ7*ajB)%`w^0o}K+9fI5 zMVt!>_&|^mIWyq9B-zMTTi$8qUCq6p>`MMQh6{9uh7))Qy}D;G`WwD^<^(Uti0>&< zu{u#l)qNffwLaJoUE`ykTSo4WRgCj8);t?l6?Ove76FMO#XTCM!!xDa?kOpppETK; z=zE#r5C-#zO-NQIEoXI2fUF2`Vk@JK_2x44J^%;F@(~~bs2-NOQgPs2r$a3wO>XKD zDh}PSZ`34CDXfI#uAppNtLQ^4;>t~Q0UHED!7}L6(AoxsB78=v5W<Zp>z13!s^`*x zhR20p*VJvpVdg-a5ZCSIhd;z)f*r9OQ@MCPKUP<lA{0}#4F?7b66&*`-sd4%j$&vW zgsY2FQ=n_XpQ(IW&EE_&|K*OEoSQz7&aH92^0kv}R`X@UruN}5tiTvx2@8Vop5m)( z4VsO#9mntzj+nrnx`8jKH+hZ%A;c@;p7@3z)UvgR0{I~Ebss;dQXGuSlzR?hXDkm2 zN;QdcdC|HyY`Pa;Rrkc%X477HG@5$(vF;+fK2o@!wXEQuZ+1yb)}i*&@J$eYbyZd> z@_xkB7{6g(`sJwh)u~_#I-Q<j)5t95jLoa(;g`wM<s+@vU>{x$dr0|JM;pvS&8vN_ z8DFAEFPTxR-CB#NX|k4{tY!Yy^^mBU>*#467xcp2O2KxAoiB_s9VLjmJw)No?ey}n zR>0asQOOk?dTq3)1HGhU=nefKT5(t`9>K`8S%%^g^mukS^F6RLR6~l!k_eTcTq3Wg zRzMk@FQP29A2tho67`}ogD;2HJ|dZYJDE^mY^UoOwPxC4nUVR;hy57iE~|dFB-Y;h zEFZ}$J-yERD)GL<dmOrV9}>$ZYYS@fG+U+d(@c-}QVo;M`68T2TfNO(7)d<LUOzXg z-OIP9Y{Utw_>>j<L}zEZ;WPrdPBWEg>w|e<%PH<TANi=nPvTPNEDc_YW~~Jdh(rO_ z5}Yn1jxoDo1X(V3bf`@=XHyZ~=3+_tFRE33t*VE3su!w}4l7aF#*n4r-dQC#(fk80 zQCb~G0Mn$1S&DG97mLoL%I4u7s%H5tpWwu}ya+8|3`B(@_1ap~eVpM+Pn#9PLIq~C zEhKC5u2wZR1HT4zo#T8&KPQe7I6u3U+gORQdF9h|NiFK`*!isCPA3!DFLY7N@N)G* z!hweuTZ>eH`m$;97fMF`bjcvkMCxVK(r|gY!$C0v;^*7^g7%?|6x!8p$L=3|cG4M1 zM_7aBqPs%nsN~Do*Svx(h9bd<px7eh#{Hzny43jTkv`U|{uo0`U)K7Klx8`wm?jgF z5OHa{$%s`8%_+M3bzSf@Vc9p5G@bep?dbb0gax`TNJUq-)qxih>yhcW<<EU@7ay8n zkWg`cw{bz41Snxy8q!%8qk0M=C+ENmfsoIqitD(eUU))DGzheE5|Cr2Qt_3iaky!8 z%72%SW}y3@)-|qm*W%TuoEZjP2cEmfk0GCrd6}=uD)$QXj$fj)e2L$hoKpx2_ey{t z9><sueKVC29;(4!TL2rhCVPNczO$>^r6s)}o7P<yD_9Dipj|Ax^hx-0nvr=+v)lW7 zU#+>5y|OFnJQ+%Wq3wiN#9H9NFs2FtmOy8#h}>T(r*Z5Du)j-410oPujb((~fG2N3 zbACk3&U$E&lN}-NNwR2;3DEX!pCW6V!xWTvPT}6aCT7{x1&4!?n#L6~)1b<fw;ESy z>FrI=ssk@j88bh?l}4+>7saB_lB_A<=%r*H4!#(~B}Yb}HyYEKD`fPWyvoqNa$0%* zE_ifPI1dcqZ!Ub>pS#XbiYMhXP;;nqD^BbhWWVeetx4#I_uSNee5%Xol3`C~tAS)$ z6ZCFXrAWm$m2Y06>Z(EaoW+A<ZqKUE5Na9TM~zTjL36XYsFz%MpUg4lTjguM!UdO< z`zcsrs~ayKe!+gryJ>UNh7lt4Ax3*qxi&~xPFxPB6K0YO7$#oX@Byy1?mVv!B*?DY z)MI2yw_-508m4ExZIW*GTO0*_=d3;nDX&VLgd88#{-lL#*usx69NlLd1uqK+g0X|j zs{2J5IYe>E1k~^=HZsk8dbn3d@@xRFQ`))N*?MwQ%j@&$ZFYznSDLKj{=6Heal?w7 z@a|CR-8uXb!c<v{eCQRW?(TCb>?vWNfE|C$>T77|oXfX$FvXSWoJUmvu~u2f>}k^0 zztdLlv)ZtH^ib|147}E@@9Vev>Myhi@E3@i!t-hpYReM6U&WU?sh3+tYm=+daG#CR zILgHTM3^@Yr}+C8Sp^9?u?>&(n(`6}fJx;B<BzWE<ZsYks=xJX6lv|KV(LkUzOwT? z@xY>Fa8LJUbu}7RUz6NCw}qAdd_r^7*G$BQ>^#2CjM|`1%IUD9US8h0An}I&5jerR z{KH>I@4+eUX9seJu;FIMr+|sK<$+hS%(I=cZ9t&H2+u}1bA7khn3wZw%vR73l-^(8 z;lxf~((4(L#hTT2FjNQ(k&9Q#2UKnmlR?preDwLTL2p$maJ`!^Zi*C6>9dSWRN12k zA@F5Q6MZBbRHAyd#;q*i3`P(1Ei*cTja@x0g8MNaB&Qcf!<fZ~C@@^+$IX@zQbqHL zVcr{jcUo^TAEW!Y25N7qdi56w$Z0bLmQOPyAV#td-ToFQuSc|$Hv%E>53VSXj6RBC zIbmMYXDY<EgR9?c_SWvOC%qBV0yP7s_hU|`&>n3u>L6-#s-kILR<}`BvQw0~a5D3v zP<n+rRJ|>KdpbZ^ZjI=fWW0ag2=@iF(2{t0sSB8Vz0E?%AtBY?52JxSBD<43@ss#F zDp8|WQTK-vFtVMAZG-wx=5+|BZ#amo6kW}+aBGe{7c0B^FF)CWK1=615rMvaZ|}_* z$pMPWk(}l$Yphb-h%Jd;FUmH3&|%C@M?`YgpN{!hFJSpIwL{Zaw96(N$OXeQKQirT z1nG7gd%Z-X%ZWB9pHgPj_<)rmP)?G@QQnSO5t87IXuNojD2-_!dE#vf{gQgzGr0H} zvN14}IfHphss&8WBg0OU@if>(JG7-kK#^Y9`Tn%iZ~nOR8<MsyWNMYS_uOY35SWiu z-p*k3<)Jdza!&XWLn!!}023b)Y4n<X2!o;Ln;tY5#9nB$mu_GbIh{U7q@LIZ^8!W= zeV#}P2n}5ibx_4aER$&_yCe)!XFV!qg<S-rX2c@D5=EVf1w^kx0=WwOw5y#6x4IH~ zvu`Y&!Sn)S`U4~V&JJj#Q&9H;Y3F$TDCm)^qrcniD;%Kw(97+3NwV8oN{u4ap>=Qg z?b+so&8Rjn-Q{H}o0Kzx!hH|?{qk5ierFlIiapyw7DLyS#-|Yaxd=km*l@kIV<ib8 zwY*2y!C~w&24PKgnG{oq_WYzZ>V$5b@l9OE7ILj7rahvvB>-h3x>=Vrj#HX?+35>A z#5Cevzqao{1W`BiV(`^lY~ZiL-(Tu^XHa2XrI0w2h?6*We+H$L96EY9-Y?!g%)O1c z7=XOGUX4>}fik&S5ikY^%aaYbOjuvx@duMep!I5gK4C*W0irprvJXzZE1^E2l)<36 zqr;0MX;tZ=Gb*mOflTVv%@_x)sd!CC#S=Ex---gpFLAb|f3l;Iq1~V?9>QYm2+(hn zd~Eyp1Xmbw^N}aX(Vasy$a4SuhXrl&mPUrReL@BcXIE~A_t~ImyaVz&Bqx=ERy1?g zE@rW;Hd(t{4cg5t_0y$<r46ONTY0<^G2L$uXLXRmLHRJu=;hCgTV(J!H)7odTv-E~ zhgThEzfG?@FkxKQKXsF^0+R=<t@cQ$(O4p4kPkL8yZRKc9(2I<zEt5~*eTc+KOr|d zPnYCv3IyAgXI@m*U2OH<IQhF)I<R5TWS)Yy<!I+qx$?Y~iZqX;$;YhXHEa%`%%h{d zb<M;&=*ABYlmrzu#;JT*OPCz%XC%XE85)a`RdZ~i>bDTR&wa$o!UOTh)kcx;(~g*j zzqB)6CMmC2jfu2wcZ`g3JxmR}y{x>%%{804N5W`X1zlC0yZDFD2~g2aM-PIDjxH`A z2h4<4y)Q<S0w+H+DR(q$f+NXwJ@_ej6+fuv05EF4h*dp6oCG5fUztS%)Hy=iKrHPy z#=D(GmyPdmlP!wda9CP)Z~HpSth!?>xx^TUE9$<t!DB0K1_@vKe_--oSn7ih5A`=r zT)-b*@86wAuHO3V0mrwGn8Q?RkNDN9!ITAdEpoD-=QjqDSd5!LzC6B<8Q^s|KH4Vv z?R<OoV)1l%&(ECL8tA=AZ1prsZE)T=jk)qh_Hjg9n?^t`Y+_g<9n+!IHa9y+(<SsW zd$RIx<!edd)rWHBXbz027e?VOsX|$su{r;hkoS7Z_R8BAykwC2J4oh>tq=I70oj!; z#@~Znh>+M?Iz0F{+grZK<4qDc8AV0*e8PJOg;cCSJc9raUA*h9(gqa+6<_~Q;TaB5 zS(>Pf+SA+C?J_;}c7)1?_ZT>W9OBe!5quW9elS{?!sG*N^{T^N_*^`*E`$%4b^ac7 z((t-s6O_@pCN^gDGJUTFTo+4v7oj*~h`jMJoEcYcQM0y-%isC&Bjojd;O_2$FX-~h zFe4v#%WMu-3n+b!>6HAkq>_A|ZZmj+p<LltQ7B8`%9$C<M91uUiZ(B#44>S@F01&2 z7tpcPly`qKyVh|V)j`y-afTM~(m3!a{c_4QFjWCpx<4y=G=cUeiy)h7Ay6hFe<c(g zg}}Z1UEaoh3bpg9%liFTH)zD<=^GtOQP(_K^H1p<MMDGahn2<d7dAC{GWT(FD5Dbm z!D7=z6xH4+(r}^F5`Z?3{KbuW{X&?yrdM)c8_v3FbIy0a)$@$Tt(N!SxdY;7DfKQ+ z;BBbQO-}d1tB5+KrENvUNPZEO<(d`RviKzZ27~0ekL?4G4g-!^9|IO*>w640h?<?e zzMI3sXX%RpH*||OLp1Fh3*&K4MKptT_YQJv_%5N@?}KG{noPOA77Sl@yxw?UuG<8k z-8s_#vcMxB-G+T9ZGCBA3>JK+Ys}Fr{PGgkUzi;(`*T^(xbyO|FOBc^!8>?w=>dza z&yvZ8SKaUdP6K@*^I0Ib6i1w~#~q&{QVuFRq&2Wj!irDYt7h94qO9n3Qp{!gvhlKS z!|N{hW9$2E;ahT+2^XZ0S64D~vn;(f=A$I(2Vy7{SfORuq<oV41WzGwUoHMJ$q`%7 zrpd3|4-R+@#y{3!IizNm4^%qWW4!csf2!hA&>pKzD83)FThVk+p*Hop^g9Rtdj8NN z<UMd%fCXn@<-X+gs4uFTUT5XfPqf&JS9p6QYc95Ov|$_$(5lwawY2XO;bj+b%M*FQ z=zaR#3c|_NacCaZeo4JPqBP!EKeF^JHCat06>bu0>^FP#>c1b~pyoLva$dHVsuup7 lq*~A?@?ep$^EK-oE-u`LO4F>Y?63ct<fT=l8YE0Z{}0x}yx9N% literal 0 HcmV?d00001 diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldOcean.png b/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldOcean.png new file mode 100644 index 0000000000000000000000000000000000000000..286f3a0574bae93ff2d8a0d6c578dce0c3a904f7 GIT binary patch literal 9905 zcmY*<1yCJb67I#_U4y&3I~NG<8r)qj7Mu{=or^oc-Q8V-B)Ge~1YZ8#eY@|Ssh<8$ z&(~j{K2uXQH8l|`N-`*jgopqD07Xt#O6{)~`^Vs6|DMZjTsHnX2sbqu2|)EU@$uhD zh=q=vrJ^E$;V*^<z(8OEp#Gu!Jpd4d0GNMa0N^tO(SNZT1l@l)kN`lK4FLK-9KFB( zpCS9#{$~HjL*+sIPcaYjzihEQsQ=-A(wgj88~!>3XIWi0000T=AA<mZv+)0_>Dp-M zfOHfU1k9WqSWL{FOf6Wv9Gw5j0tk5t{Dlq{AQLh#2YW|10WV>Se=!99;(x-d6lDLR zfb4`RbQD#{B%NF>$aq-TSlB2;5Xs2Mgj~%n1=OT~|4IKl6Q-~Rft&?cSv@^HSv)ye zoLsF~+4=eTS=l&PIXIaAGML@G9YH2u%#Lo9{}%bbI#L#HX0A5QAR8w~vVU|<Or6|8 z!W0z$6#DP@_c}o~mjA2d==Pts{x-<^&lOg77B<%ZYX40Y`X?%&>}q52xAH&wBJ4u{ zV*Y=z|I`s;{ipc<vzUK(`mgBURz(nnSpU0iB8UWr+i(B?m5H2`xP}*md*)aJ)v|l8 zvZm#dP*)us7a;}w0_qs512(z$VT{&$E`i~K3BP>=jchpr*X%&1T@G!)=9D&cS#5)A z*;m~R-kB%Cg{tuu(f0$da0<d0!!xbS(T7)S6vJUt?wDN@l0`FW!X~XVv`jwI$GTO= z0#`m@A)V=r=i+Bl-Bf7}iW{alKMOq7ss^oZKC!CI2MO9Os>0apx~!({88Y0fGIQ2L zQ?216Cd>@d%u5p%LhDlnOAhsx-2VP+8!`Oa$}<zT-ak(k%Ou=Xf0}U+jDQ4U2DZ`R ztocMXb$*EHHz7`C`G`C(v{4?8CwaSn_>Nqlb358{6RL_+)na>Bk*-d$JiJO0GwKp= z)m!smK%(t#XWk1Cy1yU%W_V;V;Y0OF|1z9^;-`OMM422;BX!6Gb|Wdej{Z#S$@cZi zjeF@-Q=>d(v|LxVOhen)xMQ8%c%yj0ryP9-QFlMRd$q6@(&EfRFhqqzox|TWu_-66 zktJ7o(np|1np6<JY`_@mfM~XHKL-)X$=ib9chELUNTWa({>*aLjH#etuQByB#-JC6 zIGsNH^scQ+oMm_PzT;7$aT!4-3S^Zdx<t$jBYt1-jn>b43IvH;xo8UVh`amB#zEid z=ONP}3uy%z9l0*C5CS^~6*0;iiZnc?W=uirB|>vG@nji#Xz35PgFh@aI3$y85gsS$ z40y!NLR@i>b4=vTk=_$;UhT2RwwQ&_JWDc6yWt22DfrdH)=o*JdSkIVL+pk|T&CRw ze{aTvyaDvK7W!wX^X5|>)KhX8op_XJF-MEFL&>L^h&zJ@%`}bl0X647tp<|UbrIX9 zexiI{Ndi3y=H?FRm#jlXYUat;+k9d^O~etaI@`iW#M^1Jy1|w<`iVI9uza(nXjn86 zQ;%~GYE<1QH*4dTL8CaGYLRXzw1>Li;V{xa?P9#LE(*kMrZ%`GbcT;0Zk;S$)}`o> z!bcDd+@O~E4<-ZPl}pg%2IO8vvHCF_aHVl|J1|6jTP2lzf#S9cc8krE3?VR%8XTm@ zPU{5*tYf@#eWw$J$-sA;aF4?U^NVatX2YDvU6cB)VLy;ylh}{edk8kWLDLFnKx1XX z71@C8gU+Nczg()?k458J0%iF?Y>Go91x!0#X0$n-9aD#NIE6>_{3h&QxWR3(@+$Ds z^S?R$W}I>k?E;nL^<^5?6_;O{kZlk2*H|Ig4}CXx2=xYM(3&pzYqaS~eQrfJrp#ja zzusU_brXG?*F^X-!Wek)b+*s4nceV4;u~ZmS;X?rw^w{&VH1yzqej6xL#D!w375Dp zOb0$ogTc1(LC2`2BYY!?aVx&C)>9GiF_yH?w~&GAZZB8IblkLGvbMR6m<nQFHTp83 zmc8GhJ!}_G|M;|EMM-@m(mHHh8tj4mjv<T5Tp?yzeZx!I#K5gzBn~^aVUMQ^>(@u1 zd-b<Gr?hA<LKpBwrc8PCOW?j38A+p%-E6y6$}RucYVaK!z<}1tyI+guRqYrJ=kofn zjreFFmFTmZB?d$Y2I0;ON@9kvYKQDZFX~V-geZtaJpi%oDZf-KaeA#>MBuL(ae?KG z^`@1B6_f^qsfWEpbfI12vYv7p%HGrS|4^ZrK7;fJALBZn{25mE(RBueCj*{9XmpNd z?crtIaC2u_FhLZ$BdCL$5G(P6V2q(y&;IS$A<?PpKVL8i4&kaG@^oU9kn;AQ7m1yt zn>ggdN^;-y#bD3M<p8sh6Xq}bxA`}|$6D3;H!9Sg32|zGnKZ~|QR%S4>LK!&2%}A* z<oG3(@w7Oh6;V7StaMwUSYU{dBnneOD4``i@XVz!`x#24K)JjwIPIVWt8``Nw;)9? zuKYNJ!m{0UHZD8)*Rn#8^Tb#P_p8}=_qK;X=a2Jz8XOG{yWB7w!bF@%5cYRSO7Ve@ zu970SZnj$rR+abT{A#AUF{AMj*;q8TG1afiag^vrpCqHCVu_`cX(E3tire00bCDNZ znsWq!b$VeU$)2^I)3FDL+$FBq^|%doWcPwF;)<X*<fmLkTRKvmGr9w47NX}ao9Uzk zk^tT_txNX{{4BC!FP$55wIUOHQC8``$@FG8a?hTNtyBE!x-KSdRB-82>aCT_f=r_Y zwh_{P!a}ItF=SFj``^iU={Y&SF*SihdWX6U(K_h{PBA9vlc#V+t*C1fj<FIV$S<x9 z3J!InI1ci0VT3-G5Haf;fGjjuYA$MYmdSR`!iV#mPs5$$X|qWshf+b3h&Z~5v6c;e z(OlHNK}2@PFhe2Y?&TILe;)@Kz|pn|ag`QEmp><hvU*L>)3D>hG478h0+NKp%7!uF zqWRXjyrdB{<tXz&TCDpoB}L?tpWQ2&87ioVlQ^p;FYT!8i7IIkzL%xo%g}8cK9+27 zoVj40*__|~`7;1TfO9nd9Z4bv$?MhzVkR@vmISW<m#c+Rj&zqe?r;+v7mGN-yGA@- z<?;f^DW>svH0v`PSt+cdr&WWyLHtjuWl1lb#2+4AB+?f2-x2UQmXv40#s={Ra}&W> zoM6NGBFBmC`+6I$c=j*7PX4aaH4G^wQEk=Bnq5YpGG^q+z0*|wDBi}ii%+M$^N=db zig&@H)TaAuNb}*Wg~k~eNmZ;LZ0ji;`}~OCF|Cq@;L@4c8M2~LAhW6k*xmHYvTYLQ zCu~yAg788v>R4dN0zbDB3fbtDyj}G2S80nanI?JU8_DzAh#+9OJvyPmr1KJzkVdmE zeQx*_pL{0vBt>>yYr!-|3eF5#W3C>+W<Q5wrIZpkz}<~Y{{$SfO2YWmpL8{M?hmCy zL6xH#l!t(`1vX`X`^6X(|AXFE%%uX=4SgmNUWn3fICxax@K$qjl*x+G0HZ%CxR#D! z>BB-J6ubO_p_ckxB`}hMFq>)U^sTaqu9s>MhemNvEHiywiJ9b^8h~6!0ey$eS*Unr z+YJXR%(l_YG!e_LDLMq&ph5#9uv)^E8;VPg0ONwkZ@?nC9>eoiaSO&*+6iKc)Dys} zH46tf_}rC2oME-KT!l+kEQNlMb2d|6L$TZWFtbwZKALRs$>eL81wwzY6T%L4>ge0C zyK4n?x)ql~vO`2&CU+fX2%dAa4i5gxc|7dklAo7pjwdBdNL##``8g<yirKRAS{z}S zyOD-fRmZ21YcNG^8hBfzmXGj_doN^(5_8@Hlxx}Wo#TQ1=yA6`icEIOu5AtuYvjeZ z8hl4>_M_YQ4;69_wS(yQ^~C1|Ps~%{F-V>wXQZ1q?nx{DDfD?oM`ff8u}WEK3l-SU zmTjsLZbx>(F$Z1(=D2k#;%bt;vi*Q=DUZ%p)PA5&AEITPX1a8%WiX!;X0UcuYWg1# zZd{!5SS9o9S1twxS91lJqS{emIpfMIMk*$i9b($e$A;+A*Vg4zp}iq(kv<K1MYT*x z3vt&1o1AtgL#D)6UOXCcIt;uU5$a=Igc}vyoR)890^r6tl|(lrSp!bpb2C{J_r>pk zj6*}GP1kG;n>O&!n@vBVR`fj|R4MAbR6ElEWPROwP9U!FeW?ZUm3OORKg%sq2n=(n zq@J+3(0Ul8o8qrYIjP*K<4uzj3rGx|Awp4mnu26gNK#zc%NeB7{V&?N-Xe*zm^10z zCQ9$Z*cvzLU*VLI#vR6YVO7i|8VqL4Qu=A0A<|U}A4}y?bAfXd+1cveVDEBKcEI#J z_}!_{;)=D<(#v1t<znzH;(FnA%wdn-sW~?@zEXR2S&fA(-ezOnk@tIV(y)3tnAD&> zJjX$moc?&o)1R4L>R>O;wm?X!=$d3~Vj$#qH=mT#EKK7lnwB{@kde{MMKQ!O;!E5! z2uE}cwQ!>=9OJPuVMQ*UBTw)*Zc-bx|NIT-wvgx>>xR;%kMezBXln|dE{@tK<ga6U zin>#9Qu<SWG~`m$n7H%kOQ_(JK1YdgvJ$li(w*KjoE6oXlcb+Kq^oPym_j^V=vo2W z6$4O3hpDNe-FB3LA{^9eUkrQt1t7EqmPO?IIx1O@h5WSWK6-WsTbG}Hy_O&BQ#gNT zbEB$|XN8wl5QPdwl0akTBsJ?oC>-{)gN>pPr~gheb2}3%7u(|~2R@siTZ8`0q}C4i zNATq1Pd*OX;F?eWj=iMCu-<ESl^1%h*2}^bIZe@Y!0o+${YbdeMoxm)oCU0qw*Z#} z=VTrQ^mvjpH9=Be03&=#-m%YH2JcZy0f_1cVe{U#m6}k{7d>oP%#~|&@j6sv`pZVP zs0fq@-Cuip1L=7w1QHA1sMg?8`QLG29Ydp@c3;Er=Rj3-2Dl1wv;khXHxw+jqqqLN z2T8PF;qH&vd37qSrOK%AF-y;IsqGIvj+v{lgZ(|kIJi<a<(=w7Z(OLMj-@ExSe=;g zc7Y9o?Gg_z;?qB0C+O8`{nNjZH~cVXuPi6?qHmO882Xhg>oy;|PNKkC3SIpZ&?1fd zh_(tHNRV!9w+=Z0eUw>aDAmy(i?Ai6U%C4y?o%(d0k-x^l8KhuyNV*215A1)8jE}j zBaG^ed!kfE3qFhxHg2F1IGUDPN9FoUu%9T-=lY8ZgDlsyAeq9Pq*@*56oRZJ=XPx* zx>DdY<Piyn;EE}Vr4?iUQsgUMr?NIE^9T>O=$9fQ(-$cR@ZcSw(?jXdra5oen!M5* zF$~WNieiwWY1^FGX%NRR2a!JGRespwuiBTv8QKY+O-0^puJcWfZBaC*8$l~rmhNI! zCx$gKAA;^O(WP2w3civy*tS&!<z_0K*lKVU?4tu<5CJ1p7vgsdT|a+f2MI4Ir!TJ} zN+du2bE2wdj2*7j_smS0P+A@6B=E)-6YPSVkjUD|>9W(Y4zF4WrhY18rQ&e@&>&L~ zk<bwZZMV{7?z@r@jfjbwP5S5e9#p5R{q$2Yy|p}*V-JOBp%#Ta>Yq&}*aSnE0c&Jb zv|OQLs(uQk{1XmE*iTH$Og2&CcR~HKJw5*3qz*twIHn={>Hbs^7a^C;{Y7q@Ch57v zvqV#5p^O=tPIWdDa%QI4<W=h?t4`XgfF+Uf+xTBe-(R1p^6s*G_oFmHmYNsdBJZGv zC`%s7Igr!r0ZD4y<PBL$J%XIRKO_@V-D7sc^b=Ed+#Nb`^)xLfSAfDKW4PYjP}=I; zId5LPA>e3pOfGm3vk+0$9Oi)7y5AnKFyr|MpN9lbA&c)Yr@|f*H(~~6Tw(!!=MYSh z<5X$8YLHR8X^{4sPV?Qj)GSp%x067Ai}Q(o<uH-ZC_SlwQu*9znhI1kjYNc{E<qz} zmYn52^7ZzH30yQ)>SV!htW4*ac=C-|WMgAy(|ko*dR1gE5@+Th8uFFF1vjaW+371X zU(BBUaRv^rKvRO+%<g<9F{kxiKBV@@g896xZG?S42Ct}S)9QlC?YzpADH9-P5tVfF zCRc}Nu)N5aU`h@;uX?|sTh~X^e3K0$^`2!hV>&RG+yvSWn%B$pn~aaKzY<D;#x{Uh z>Ewd?>V3@kVat(*jk1*|BLp_*xWN?&QZv`PWCz;E=%QkKn2;xpyS#g_=Rg8JhZZA{ z3oCZ*z<!o4E}OT<FJrxs?JdvP7344)SAsc<t^!uHZx*<=M=aO!CBl1iGyb_^Z0vtH zZ|Pa<1uDp{d3aUoDbPoDPzZ4>iibEc4R@Ig4o{Ku1hkq%D#^9nVMy(FPu@6K=#W=Y zXvM2q`Rw4Zcwh1umzs))XU(Tp>^se0_V(Jg1QSVsF5HG*cv7i^3VPy-n}3cw%JgNp z@*JG3(xR?<aJ?gTZ-t}JHOzxu#ox?PM5Q6>Xdp@^8S*vGh2_I~AqR?iNF+3VtUf38 zm)+YNzWBG5J+2b-|6T(2Ho!P=8WaS77_lk!l!(8y-{Pl{Os3$o#5Rh*Anx8!@lE>5 zqudNhbBb)l?1bgdb&d~*VSpWXAED+An?hmPwqbUk>Am|RA&}hlI-kpxK?J*&*wTT; z$F6C|i<oO{6&q}MFc@B1$G7tpAE&6@i7?@jq<X=@TfUH~G*C!B*X@$yQ0U1WQpt37 zMZN}tbc&N}>j~&hFpl$<2lv4yThGSPWIRRnR@anOd1#(3bCw1?Wi`7m!TqI6R!$Nm zQ4vo=Q9RM?+Ej#h0^eG_)8};wM+kxiA+v-cn!(_d6`@6#Y3diNsn!nNp-gSo-S_K! z`^`Eii_aTmtg#D9VI={dBQ)v0nAN@|6S}6%Cmf^Fc;q=K%75#*Cg_&;>%K#v(4iw2 z-r7DYkM*gPRay#ZIp?9&GwzR}{+uflR6e}w-}!Ne5pNbc6WP_k8F<O=!DS5o`RbyR zFiE_7s%<6Ih4;8iALxzyNmO*WbX6L1Nvm{b;nwT^h1-NHj$ZvtK+Dy~O%h@mHc25g z93B26ut0CJi@5VdinMsMf}cIsQ(HYVHFwydfuVT5NZfm{Wt_e?2igz)P*jARiW(6T z{bmi%c*WIo?9T#vk7#_gUgMQ<PUil%r}K`PLC4>ldp86zG0aELF42A*iiS*1qt~U^ zm)-4w#%q<Kp<Y_3^N-e{)j%9*&rjLY{AOMu3XR^k2RLFjU$cj%N)ZNh9yrhuKb}fO zF=$q=hwxa@r`ZT~%tTLzrm*J3)#G2R03gG>i9}Z@cCy-DsOSP=c!wPoj?!e1XGcbQ z0;fQBAAvC@{_oxTJyaaM9pJaDdocR#ZrEj^Wa7=S5obSEL;Hcl+j79uBfL9FKx^*c z+2~TnfW?~nu4s3Mh1n3_`?gb0<OPNUrBOdtG`owxJLx4*A(!-E4=Y|0|NZJ&rp$O( zdKW3MO&V07mEIr|WIa!U3_lk2G?Y1!9`|WyJ$p`0fTV9Vug-y`MEDSbpo>R;`)<Sq zhNBfK1*hpNYW$CNX6o|m4oG6F@Jc}M$<sC?L(}An;8$}|bV|qgw?K<o6Y+`(FJJIT zvhP;?2LqUjbz#xLmo)fh4<`2_w9b@r@v99|_9Qar`+Mp-NsmvYks&8bvFghS_}ImQ z#3-2Z<0;p0uqNP^1z0pVwM5Wf8*$Q{#SEFBSD<ChnecLRZsGd^!qRuP2VQIubEdq6 zPXNy?qckbkA&2-<p;Re&wY0OQ++0!&+GE8~Wk(|95IxsgMJEf@&mgMYJp5<JO+#m4 z$j}yX7QUoI4*C-(t~TU}aTms<XgU{bWjeUrJzA=x(7msU`sL-(cXUkY*_glxhXPB# z&6Zz#OFZJ4oHr}0g3zv;m38!EcNKYeK7HJ-KAn$fuEl7;&RNFvTy3Tz*DH^`4I%M- zAx}qZUW!#I)-04A@Wcx}4Vj!vcY{9<@6cZ;G7Nu(XujJ(wh;L4@{8I2xEJQ^n7`-s zMKMYzcEMNzLPTLrJ=`cCiHAkgRKQRQi_HMbzY+!(OmSIK#D6ij)q!m>8=V0rqOfmH zCCZMq`PppjHgvU(Zgm*r1+Ik8R)~(o)myDqF9xE_M_#|6U;4L31iV|*SQ#q+Mpmpb zdNA{v@t1g{!<4&lax&{}_<b%cr%p@iDATyS%1*$%a#SZb)9hh<8LYbe!0n$8fL27^ zo*t;>JyKn?pkirmovo!Widmq<^r-30iRUtX)jK1sqqqajmP!56nz6B_puPoaF}^+n zbNmD1bB^6$*uv<)HAHz)wJ5(LuNZoA>S2oXC4b@7HOzh57AYv+cV^mojZ>~W$dLDX zx~~aHI?7)T>0N1;8BJ-)igpzWpi)~@FKDFxrB~XB*PaJO%uQsb0C97HuU=y<ew`r6 zxCMDuMYd4hdxvp_4mUNOg`a|z&J<I9qBy+q6Hd$G04D&KELfHZ<4S%{e*A<9ViP(Z zxyP^~uaaVl@+D*hreoR>q6_UY>M3`#JMPl>XAGE+@<6#1EPLHj!*Km*q)u!>2Sc@? zK^P8a2ip>B|H?Q@nS)=kK5O6RSEK-xW3H@^aR2ptRXmI@zG5o)>6ayP6XaSYN@7M- z;y3_FY^F6LiM08L8l3eD4rwDfZ*JY}<z~W5^M*4~l&iXJNuJAYbqt1QqP?6>*5gz! zl==$2zJbG-9rNR(r*U9r-j(LjEapK--7}4qxd*{{1ykx!B-NNO|7`qaA(ZgqEh)~p z_gjtUqiSEaz~BeYA#>?^vbWAJYDf*$$;h9tyX#hZM^UY<t-XsSMOzc2_Y1fK@dj-5 zOHPm1x?HHU_z>=}SDZs%GqcLlpZ%HTW({wMMSabetuwLjwj*F+rQ>nTGf2}A!Yu5d z$jZfk#x}M9`*!HMSI^a_>-S-)4YHtWry(Im_>=N2qp<O!T7^#Q#6h2W{%ogm`2d5L z!bxi^mf}1w!>$MZpgQXhMrofvowDjTZqj8(h#huObQh#_11dt11I|QP<qFg2&fcgM z!Q)&s(MLBdQB6OTQuh`VF$?-Hlo({>QNYxzHw9bNL48wlQY!|*MDf%Ga;pZ?g+!il zSj6iN_92>LB|t%aB<G@aHW76V-PGSBnQHIND;nE|ySQSD$DsVaOYLjt4}yYY^aggf zj;x`*ZJKvD_rBZ}*)G$WZRr-ALlmaOdM_^8(?a8y{md4&tP!Ix@xw+rLwM=W3Gwe> zErAGk->+T;xwSAtzd}?A1_utwp*At}{Yf#zkd#Mi5GQ|*&AUcL%oqH|`W<{L9GMTx zIk0#EQ7c*a^bsi)ZYX^x$1TVvWbu=m8s&llo}?>?-gd*{l_?4pDiz_J=@1&yIO*mk zxVtYgo-Q(OMfc|Ufz#qH*`bw7rD*?3N&*xP_qN*A*VS<Q1Q~<*gT!)B^8;M%l5Ly9 zl&bQ2@#=Z~REPPof9a3Y)1K-fFg#*{c<xk9)T$=<z5kJyAGgkujnka>v>0C_6lG2` ztNPXvaWa4kBkahm-RA|+JP2Kfyy;2WJBrPiM--xqeZlSFWDt?_RdK$WzF~nn!-Fwa zw(>hZ#pT5Xo8QByc_tFnb(r>odubF`50o%(P&%R@kW-ic^byn2psUq*-NLo_Jug?! z>`^0rU>l3v6&-2G5W)j)<dj}xm8Y~mPi79PWy7%UIoSRt%tv5O8N+F_n+loqN)U{! z>8Q4&*-t1ZFj;7_!<J1u>z(T1MTn!867yiEgJ3rjKegZypzPz7()m4nw1#R8qaNm7 z{|*v_Fm;iNUnNMVGQ(Ym@Aj?5$gs#3bZ`e(OT8FPuBA${8>$f_|G;Vvifxf9o_oQF z>WjW4%`OM_EXJg<j`AHA>Le=c6J++TVp}44G|y?;f;c?N=L63Z3qdtodys&Z42gD| z3qNQQxhq-AQA9SM0Q@;}@3GovVb;0M$=gcE2&A8f>RcXqzr3k>l!<UpbYPHwDcL1~ z@KF@}TL~OK&AvE5%8uwYx2+@YK2koA=H%uUd;CtW^QzE=z$-hd?M&0QpUPJ{3gmUb zFAHYAQ2+h+ZIQQ|++t(ZgVM}Em1JY`;rgB$7eQUdqwV302P#+{%$1hBs2%v0e<Tw% z^KlojA+s@FYVIZ7Xp#j2heiEVusmM&9DTC~ogu%6@`56XWgXMERc}sS(F$=gK4lOO zI*7YP<-<0$Qa+#v&bq@n5u?hae}dmQP0DV{co8YSU;AmTJTqvG(t7}KA=;^d^Y(RH zjD;PV6AtbspU|)K6Mg97>ow2h>Hx0zc`xN(26ouXgskM%pXG~5Y(Y%qCvgv0$Uxs% zo@)BO8s=G67zRkRE03eH>~D73vh9=0+a|^bW)Qtx3#u*quYckKIJz}P4`=;pGm}c< zo?v{+?n_pA*!Ca4M6~w8?0@r)k<@G`rp4!~W2gH1^D02*vgAkiny~}p2FndU`K%&_ z``bD4rq=DmFZISUXrnpq3yklEUlx>~TBDsl?jgdj4uz$t%X<U7U&!k}o(R83_tvsp zdcSS2Ubc4Q7<JnZU2bj;UW!ib)>QWt8IbM*C%oJcaM>!nhzo035opVg0r|k7MkH(? zV)_)>^xet<c>>0;$wq+hWh$5e*V+8ElL$`_<TV7D;4g5$OhL-UC>JO+`H*vjS8H&x z*NPNVN>S?;Zn?mv<suiUe>F)EGRZjgwE1Zi!#Wnf#437hkuV;IKv5HpQFDAv`P1X| z-KJ<UGk@kjZ3sNRsaFp^hUv`a@TVT5;qx*Kteh{jEqsZWYid^E?)vSs&n~A2vgzF1 z#W=-XdQq#v&2*m$e||g*4vCO<Zj*v74MsK~+dChS-u&jgLPBy|es%=SO(|R9S#3dC z&%_rZ@!7mvhJ=1*9tW+26vge^uZSzfCR2>KC<ZqXjMRKQ`@P+qaCE<3hswA*c?ROj zFN0NKmpjsQ=w^Zs{H+jp=6?2pO9Njn{Xq*ufpoL6>`4doJ&yc4ONxLjFad;G#afMs zj0+V3Vn5<R56tYzu!}@wVR5z+n(3z_C>@{W>%***vp|HyJw)bltAL><Dyr#qNGHC1 zU-77NMYYAe%S+r29y&kqM2g>;&x=w9(0eTL;<=G%l`bdxFyGn(S=vY;O=;!?qc%6$ z^j4b+B=tIq2|<GE(SAUDr0TMpS(@g=c}E;6#_nm<hs~}`3iO^Z7E3}JCw-63jGsU5 zU}JK9<(gA4ZkM<u)-alB;c^mdN`rwu-%SJ=LWLQJAbpJ$t7)6fHZ*bP`53I*5Y2pE zkc9D1+{1HcR@d9N2A=or<~PWtIJ5(wVWCOdWFB2!&u{}dr9J9Mxc%{}+=H20=uAE@ zEfp|eN1+z&hAt-CBo<$cDvukLnk-co2c9E*?tw}bNGaL+U6AZ}=J2xBT)ErPx&Ivo z^<9_pb-b+0sxiSKVLOk$My`srw*s(^qAxEok=$<)^-FLQuQL|j3W((vOK)V9Eh*$J z`iGB~rQ{D#=;-=g-L(+u02;Hc>1J?8ud&uGvKGds&QDrL0s>hBcb{|@!CNdwYNE^( z=9pWVO2l>*LN;5#vX5mM@u{%jpmB0a=p)Mry>1+~j8Ef%Wr#9}uW86Z=2?*VPZ!`U zH3Zd-oO(}QyEY)yf|?Ec&6#v9f4C$Rfhgt29lSaY+g7I0pD;dJrZySpex_N4YNdf2 zvDB5z107iSID#K0ob7i?d=9E{m4F#$X2#dpcP7hmHjs496jwnkwOkYy{i5YJ3%Pm? z$DIP&BTu$Vw^#ER#r|>=?ZGO@ukQ}m`-Fc#iG5t9;AN*-XY=5oRqsxau<%5;wN5h1 zW#ST`sCb&Tiop`beLAc&?;{=UDuU+TwKMsh$-ESV-eI)`keq|jUnfq>ZkoeaSS9HL z$hI1kW{B~)sbdHKFzJUOC>%ihzU9UYR)YZSBDIgo8<Nhu124q{7He;T0kRaMk^HtR z*lRWko2%y!q%&=gqnE-@i}=ix4E6V4lNGq26n)ZX)1zW`Q9sX@*sOl}0bc+fVES}P zS^Z-~Ul<S{TITnM20LAr8KPN0p~krs^3l3}n3R0L6Vnz)blJhaU1=oFcnoXRn58$B zQWix;JTnGM#zruH+A#Q_T!ID}n)_ZLVbF~hc>YsxKttAIQBGSoE!ZR@6)p7;fbBA) z1^`8Gh`#hXbPh|&gdheyED6w(4%7;Als~-$8Dw@5>>*t2Kn4P8(`pP$k?X;8W9*oO z6A{>c%}v!jtuS={=AttpQntZyT7TB_>Ba?o(M`#s-yq2vYqo~11A@Mec!0%ot@DeI z6Q4j>=QMyp^98TzPUurNqe8tDRrwP_d~&n-GHN~~XMJWl6pXw#oAogi4M#A_MMm9v zj00yvY;$$ORh)S+4+lWlcN#{07qj=a0osTI+P%lHaLcK@8ih>DfecVM7WsuNz4}L_ zXu8ly@jF{#2NcEYf_6evIkh;Rt=#iBl1zeC_fG`zsIX}W#Z|=AD!?;fMqHV+%q92^ z(Nm)V2*oTO#DHG$nK>^KupZe!#>GgsJa<?nMsn2Z(a(DZE@#=rBMNCc(dDv6Pd{lM zJyfUbM?MuQlK8cnxBI*JaaoG5X+T(nSK=1E9_mUq_CTI1m>G8|%lbvOT#qvC;|9jv zC#(o@xJ4(TJC9vws_hv<!}tS$Rm@q=RoNedPT~JT&lDX8p<gQc&I3^i3xH8+xxFC{ z$+KAv`pu~G?o8Bk_$Q-ELXE66tsfIgXt3cV7#K>ktMDF6l9Bz8;ut(QVN;XHjiZF1 zq_=XpW*{dq&~H0*mF^K=NPzc!IQg(f%$Bl`n&m!N*92<QQxf(=`P3$KtmYW)W%drr z9$rfjT)z2>n<2oxAM06v_O=^(*f!_>ZDZhyc_#{k!?A(dy{v5*dwsyY>ku^c0VAe( W7%D<lzVpw2TXND$Qq>a1!T$%Pri0@E literal 0 HcmV?d00001 diff --git a/packages/widgets/Source/Images/ImageryProviders/esriNationalGeographic.png b/packages/widgets/Source/Images/ImageryProviders/esriNationalGeographic.png deleted file mode 100644 index bcfdd0b28d3ebd7fd4df1e8fe632d6ce2c8c38be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11555 zcmV+;E!@(HP)<h;3K|Lk000e1NJLTq002M$002M;0ssI2B@5<>00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D03>upSad^gZEa<4 zbO206K|~-_Wn*Y=Z)|U8X=QUDNp52<AXYIhFfo46gAD)x02*{fSaefwW^{L9a%BKe zVQFr3E>1;MAa*k@H7+qQF!XYv001mvNkl<ZXhUsyXKZ8HnWYB1KL?AQ*<E`)!5+tM zce1;?y1Tk^E~!){l~l?(2P#mJqC`p}6)5JMbIv*EoHHd=&N+1`x5wk1g$J{*QGj=0 z3~+Gq9tnZpx#yhkepgj|Sql<%c@;iNCSkWW*H++QDjg+|P=OVTUt@Cd3_hMMBJdOh zy_3h1Ziuvareu>P-4bcB0C>tRi5_ckGo5}TPr?A8&`E@HE}22(2w5_<M5JaZbONE2 zE&;w}W5~EAJ_9CX!Km^!ym*l9=+vebG3@P&jnynRgo1@$tUb4a=!v8xQ?r93pe|RG z>kJE8I-7_LNadP)V`rSfhQZeQ`})o_H-9M+Z&gY4H9T1dm%oI=udS^?wouDxEPM;S zf<mnUl*l9;nSz(f1auZ&q37~sc#Ty;<)P^Utkx#fIRs)YMQLW)g9^1)z!Q);JhDi_ zBoI+V(hiGF6^b|lF-s_7QHa|-7EZw26wshv11@OB;2C2C&aB8iDhZ5`#EAZhMpuB4 z&l$Q}o3OZvP*{jSER2kFID9N$MAY2UK<6!|i~1Qzlhw)Cz2?~19IUSSHJ7teCDeV1 zp&cbsh6qGBg|b7YZm%Kc*EbhY$Tb0njo#crtZnkSJjl{4j)33_2?Pd~!XdK7G_I5; z)p1>6gC}Z|=~;3qjmyTc7$}8|iABTFs1*!ql}<rZDR>r>LL;FR0<w&~A)?Ot4O>CO zx=hJn3GsZ(B-PYRRlz4=jYcmt6lH)0dMQM3p`dYC6eB~eOUq3}>g+&&*9Lab6<{sG zniZO@bY2xtN|fqNE*DZIlOB{vj?$Qiw=iF#2p1^aK_UwTLv>*Y3)|TFE&LLeyg{a6 zDP$Z4kD;P>P$)Q)LE~^4LMctAV$0N0g-!+V;mMdJ5=qSBOK2z_zF))b)d@jL<{TF{ zDPw}%nrW|oIBXcR^ZWK)xQu$ora%kC^El-o-ZjjM&&nfft`IRB5i874XBeL>ijq00 z+e<Z?Hto*sSd8Qf;Q@Ffgm9di&In2c<zCseU$Ry?+?NdI^E~kp9Q89S^(cjN5yz-o z$DBbE8&Sk7C{hQC)Q2IB6Nq3cah^$BVpBI5lx+$D$z*J@IXf&Cjwhh<1SB>e$zh{d z1f+xp(eOu|`ca>0UQ8ddD^|qR{<s4kvCIec(-Hkr$%PBb*Jac-9uq?1jbmg3Wb>#Z z1odSx=>jcvos-z-B`Ts!S)MDaiX}z4B&n1{*|IcS7U#>tTuG2Gii&wzIj^eZ^;J4+ ztwMiRqCP2ApHb+}11n2(h{*hyD?Y{+9jEe76PRbwq#7K)k%a4{6Z%Dr6((VthMi&% zpiCl+f}1B{W~sPkGGRc(nqw0|8o`uRHELA$c&)QK>4cKiMM9iUI*=*HW>CMDw4;JL zgjq1BV{V$o7>yXoWKGcc!%`dAoPgT0(AX`eze08;3BCj^nHQGI%1Tj@&j<@8RcTjI z*^`$l;$lHi$P0nb_siNUuIw^HRKt~B(3mfqU6*y1vr6q@x#lyi@u)&~RH!)0;2)<j zs>$R=5~dxu(N5bMW@0;plwmezj!%FpII}#`D1CdHPa33dx0AP;l)Pb|Wg*~La+nsa zx<!|I*e)NBSP(%y%B9*iil9o)q>48h&~7A6grtGw5F=H*d5LmH;+z$SW(}EjM+qI+ zrG!h&c%GBV1DmZVX62cTtWcDfcVz&9LV=gh@c?D6?yIZlf*~TilfrEU`l(oXnI}Fa zk{{C<&+2t2m6}t0@o@(4EQ5W8M(NvG>s^{?UKl=yUOP$0G%O6(uY%gOf-yCJfQ14v zQA10h6Z7K-=RjZbXhZP;MZ%q4o;zn#j72P~8}k=XkY*`uj*T5u^2c4q`G9#cZh{od zTO}hds6eSiP`(-}bgi*$<JveZuuo20=Op)d>7p=|6~*HGd_hsJsCM@i#a&UR$WG<h z*&@HRE2~;X_n}BbG#-dApWur7sO-yh-X)Q|(PnNi=<6l&S|;}rh0%sZ_s@*Cv|Kz5 z0W~tnbpl3f*Tv)g^(T#r0he)5PM<^0c3{>!0hNXZJ{j&mBIdwp*olj$|B<}i25fM1 z^)DC4&Z&5dV#cUhG3C@x2kfIE<5<Qrzw6ve8Mh6h6|rDNqT0sFdU@7KeFW~#VPbpq z)IL9uVi;ZMaFQL%a1wcTyugg*8PPl|Sr%sZ<W=jKArf~^q(w-L2(EmFCLH0&#}t<N zNU%E)>aw_6rP?O8s1rx%nFiI@*Bo8~4@jhaHp{|9cgIv;Yb-pUOU*d7ThoK}HWMb6 zBnc$by}gH*7dtF!%=GXf_(CrgI}Zh4)=E}__DzR&&Z(O+Nc*DR<(M0ibj@Ymkd%En zpj)=e;07^*EFb1uX4C<wIl1Pq;1jnv;eC!ZLG(lko;co@#QQSDK%N#XaUvCIY)@IG zv|^1uvcXH@so_}GI7u+6a&HAoylA{Vmgx?ry3GC#g{7Ax8Afb$jttkFJaTXeencW2 z8SCkt8Sah8<|EM|tpr+s;eb*Fa|GA@N$kW-b#Kp!TtdRcx1T!tMMu*)1gt0I##=RW zKFfSA0MCbD5f3&QKqdT3VHYUn16M-pMfXlrgT!+Bc)BUMYf<i<Qw1UR+>U3L;x5zU zyR2xL7AjHvMXJBd2$XofqS%|4R;m09x)#LHfKZG{JY&S_8_QP~lgYIk#m+*qv6OH3 z`mQ+rBP33D)4=f!${KN_ac1<GfDP;Isp;*%==BQaQn*IBe7f#e6LXjKCaP9LSe~z^ zV4FfNutn3-aN&!dmg52{By1%a#PcR4I33%J1YthUTF}4lcSF-L<ego@UU)5`pR8CG z)FP-+jn*i4)P^m08e>dBq+yWnF2<k0=dTOm`^@Zpt~G-+#&AkI*Bc90;g}GrbjTEh z`4eP!2p-E0<SU)o>{u~1<*~N;9Nl(9SHQ6#=1g?A92xI#n(8~Sz1$!bEDaAF9~n6X zWMd9|%BWo-F~)~Sk55jWCE*8o^bxymAsayi?Ni9*AqEb}E|`fPUZ1O80DVcrH{ZI- z^LUZr2s#wribb}{S^RE%CuM^q^|M|JL@At7%a&yd2!Ykf(T<qnNVyjts%%@+>*n;D zwTKk^XI1`9rUI>Zn5z^zup>B}DuS<G!xr+(*=$=n)sRbqa@iS+sm*Ecb(s1?&c&c* zm9^bZUmudwXGGL7pKU{@oMtmSC87}#chG5qmGc52dxU~-GHa*(PN+=_HY%o#(rLK> zsgrKgQR6K1C<=Ooywyb~^oIR}(luH6x-3)X$I{e%j&ZHTE`%|D-F(C`ZjcVxG!VZN zB^6JJWz$wSS|D5HSh}g&E?Hnf6@hXs<0{WOPl}W&*j3@=$hG?e=|X)bF^~ujW)d9{ zUuVz`u{x_2x|8l;kHOI^QFZI|Gcp-iDxL|Mh-x0#sh`b6SHj-um>-hxBY{F4DrmsE zk_y7|aahzhZ&ZMkylI1Ym5A!6><n%!HqH&5{LN3RKz&DqoO!1epD2n#X^t~QwfPDD zC>3b!l`JzG#Ci<FG5d1diAnoNUh_Je(#<6G>y!wU1FH9IY8=~2Gn_3RR;j^37cO9; zR^bUXrQL~W^m544?svAN5-ko#gH}1>^z^vHQ<Zz1#7()(PnY@x5}%l5V$o0|F728| zG+@>Aq=EpGVS{YUAOVX>{SM`n+c<95_1X19I_bECF(qa!Yb0|@-V_1R1Q|d6`MZAw z1y>t1oAD^Wa#NezR|S$hqmv+2!v&%ly#|s9qQh3Ck~PEL8RuX|U7D3*3>R@CJO<eI z`Y>*5c6DJ`CD`(t(N@XSwGgggT(7D<e<m0p`Mon<=cLKd;t1BL?A3Dfkj6|=SOmsM zK$|FY+<8G@R~Em@a6}n|akC1pmrU3-<37WrMKSKsEXvp*HD_AG1E~Z9CgreQKds=6 zF))LS9gtQsVvvFe8y6{Cm$8U?4sDQ59Wa`afe0y*;%H4M9C-|~TsPSN@!Zts3jQEr zyT7yH^W~{lP}fNyZxQ=y*aF4Ft6`v)$&SnQM-E~k69qRXtX#bAUN0Nwt3E$;+8yNE zTyVDsp)*e#ykjCeSQnO9Qu~_d4Qc41BK}63`kk}%P2$G$U}0CKT;VXrM65Bpa!JJj z>4mc%!zKyU%_NMlh{F=jgh>UpD4{AoSjGaY`4Ek`+iRJ28>ZX_uwFJM6%4A>)42-6 z@7YSmX%g`Q7TqhCK-AJ1y$p0ck0+2uM@P=Ptb8&CJk;?yFn6#pT|0~Qdugg&y|D&v z>#0AaV9aM++Z7-3MsTz0v$OA8;#(@mSTI2f#Ch(dRO+yqqF?Lxp6K?zQslojRDN&G zKedDtF0aaJ#Bl}Fa@i7_JT9V48-=S9>MV;eE@aN~7_(gZ46w4vlT`GOfHJP+&PW;K zF4Krf(UT4?m6OPjdm$A^7RyAfWjYnvNrv$|n@y0}^C36(W{Def!OD>}sSa|g=ATDK zE)4XXW{|+w@|rbp<9vT@EIztd#`xWsrn>i7<dGNmbomfEYJpW<sQJw4cblSRL*~9P zP+{u)T(MIr3F+NwhTbbq+|b|ncS+(8-ok4Z56`A`8t98=4w%2w=$1`O@!by5jGES= zV>ihe(*pXGLb4#`PN<j@N;<r={>sI3eOleP!wOFLm(#wbxMR*|1jW2dx#UJHG!hSP zZNvIH8V{2(-Esd~*s<u=%-~52z;$s4HFo9l$4v4}J|>ki76+O?<<dL$i*(@Zn;Q5a z<wa%PsJ#g3MvPt+2-1^9m%`&U=5B9FoxeWO_`w%7zj)`+U;XueuNxdwrg!D}XYO17 zZckm)nV2TsG!QJcU^M1g^I6t_ipkrfaz50mTUQCM*i2(a(|Eu;?=p-DX`S`8?>4oa zuasFq4>IOmH%NwEn#q85A>@LDyil)cDdd8Z@%5c8A9OSx2M;x(5e;f_D;(a|*794O z3b{CQuKD6m-G=p>1;KFZyTe_d?ZBFu*dfAd`^}Wh%wJMdr(y<lmDw`oi_v|BK;Y(6 zOX($5p9ohTllY3?96ErYkv!LKZOR=p1kpN?qBD}*wq+i>e{%A-n_CyAXV1tKgeBM% z0<|&)8MbOV1l%iN@Nc#@&T^?udgbJm)?e25e1XIEY$KaA(gmG(4ro?JIoP0@^4OMa ziUpt-YvdpTW@v7*4>Z`hxz?wUPLOf^BfX!p$pd;Rcx(AI0eRje83KS<szWSXq;7Xw zq)T^lA{}Q!PU<UraaDR<d#*yOJWOh%d1d&qv-C$@<VN!tc$>6ijYeF>Ybdelv)Z<% zzMeJ27y;dLvHIuW=~IJ4hd%u6-w^4jPYxe!=xztEFWOY=a}#wJYd#<BzO*{mlM2W$ z)*bxC$Nw}3zC6%-VrJr!NrM5j;!wv#oN=caXvA$i;(&;@sT9+>Tm+r5$YLUCWQ>%( z=r`ew(v^UDGh{(HRWn*%U(UB~)hz&<0vs;^+hW4I;x~YzmdQK0?JA?DO`{(*`<aeZ zF0%h8d**+4OyO!eht*bFymCw9Eh1^U#-X{|=9UwuzL*$my?Fe~a>|X_n)&3nKh^3K zzy8gKT_ZiwQcxu(AN=g2!-tQaKYixh;m>Ru!IkFo7uznDi;fM%_~!?HqES&Lf-Nos z3Its(gXzQ|I%b@X+u*TD49<o?f)YvSSTuo0gxORSH5Z{5BB`4LMlsANSt24^#k@t8 zbVaX#nN-U<5!kDTh0Uu$<4RRBIPY*wxFXwok4l9*zo$vkry9mM8clrnYI5%}mhCuo zd14LEYU=6z`yc<)$jDgZ`TG5Qc5!y(qxXN7&u7oqUKp7ki~^G+cIlTN{&;MDm?y+A z$TRyzZCCfv`u1bltaTYW_{pa~w>i{Woj@rga~N<A6(VL5`0RD18Yx#3m~0wfAXO;E zZ0?53AXf|N3LeF8lQRi$9u1)sVnnPBDgjF);`nrmj7=BQ2wEQ9C}1e)_$s5a)9LKf z+Ivj?9j1hHyt?%lAAYjDwXm?WxkZ;Ci0Tvd18YR$)XMCK2M?@n;ZL4E23ekN?Ya1q zcmB@iaUD8!rf*_cWm8BEs<yG7p~b<4wJ!8dyT`iK((=jCQ|~V?cei(*or8=9<6gB+ zu2u`#3>1%!WYf584o<Ga8k{_>Nv+cx^?I>FfsqIqKDWtYR0w%g0hc0`vS~DoKtPkr zr2;-zA{I*de6>id7K#iKnVik8vg*2n!7h!p#+`sTf}-=6YL1;bSl9gd2WP(Mor4;J zy8w;mkuJ#2!pJ-*lHbJ(Q4K@YUEqfI4!`S6guBMU6rtRcO1a~AB-ZH6#ztMoIpkV* zIw0cHcaZA{7`$r&+~NtF?LHfoMUyK;LM}-yrg{A)nOw;es!UE(vSiNf>BCXI(_%E3 zq=AstAF^u=Qk&CYvKy!@iclty8}SM~&S+yO)HsKOXSZ^kR*qD#Q)RXdc*1b8dDBzz zS&I3{{a2YMf3OuF`ffaP?maXYZUb=bKl0yv?$~{xO<h$vg3ffhdv5CZl}3FaUb^!{ z@3LhoadqyYqjbj^4NB!ig&3-p&f1KS+c(AWAU_&{N(4Qtv$GPqS;!ag6=a1)g=cKc z!^cf7soKorNU-jJ%48P+;3-iw!InF0F**$1u-_SQs?7?cQ)O|QWEzoJ$=2Is7PnfV z6Nr_3K)NcUWys`$n}VXq^{eLGJyqhNKKo3cejo|mRK)ITQV(^R$ELz_0II}&f$!?E zD{b!{J94tKk))7%@@1XJFE^>YF|(=iie(9F-EQz)|I9=!cC)>|^L@E^#-d##Vry3* zUxLT#u3V^HhAt53TeI+q>BYhMl`$%3M``5rk2elaH9JG{XwD4Z83thVaEu<FC#JUe z#2Oph8`q#o>#&U(*yglYO^#-*7LS}GCd#zjDu-uEZ$}360e9h%rSJz$`d?Lv*Rtq+ zW$KkS_YDBxL7sS_NWKIhi$CYPqAN@e-{;Icd*m+c8Ux{IArUWl?R($K{AFh%+tJ;0 zsrnP}SZ(8lUpWkDyAh5?UXk)f#k|3uj?dbg>fo!;!HJfMxdAE%<M3-W7Jm2er3+UM z*0mnuD^N&02#)SkJGYgNHD>~Ej}i=CVjv^gAwla}jxDYYIzv*En`iNgLMfA2O{vnG zyL47~;Z|82x}%K#i!S#keew6I%p-07TSMtPeerjy%vZ|vYfbJOUEvJ?bMcw`<_p{Y zU1hwa371Xbvcc_FSv1nfU3cZVA(-y$@4Z}i5;Rmd-g{0f-d<fgKiYZPYbJzz3&13I z=ICeO$;FK=$eHs;y8Evnw&v;lZ3Jc-&su8eI<&Oe3tH%0#SA**B#j4Z3a?lq8wMZR zo#3KLs~4M&Le@qUMjDE=AW#tU`vJ2{QKi&g)R@3~5AwG3ZAIjzF!Vx^eqz{tB#PaY zryr?uPu2Nn+Tsg+`IV;dT$Xw$kH0pS-iRW%B;h;$Ykzd-zt;Qr!o}-=_uS<d3Rj|M zWPEtIdt((e&~|*R>(s_db6?|mvjh)J5O(8CZ*wgYg4$SHU0Yuo9PVgptKrKDP~;F> zh7_C7=bGO;aP&RUVyidBQMs1o_IbSzq4#1e0Y>*=bI)*dOHWN(U(MXgAep_Xvq~c= zPgN}3Z*@$^OQ!hsyMY_OH{@R{(+^d-+m`)T=DnA?;uA&so;-CI$fzd&NR@qHDgQ~C z{7R920VpF5y%u?&YQhh!>HGHGZ?y5-*2LcM%-rBeClSBc)BO2x=RpZ;VW9aGbgZ7T zeFZZ0`RZKDHf;IgsS7h;&^Tyd0W!uBq9>PH*(yY|qGYI+8ahu;K|93yEi`kOr&(~s zs3t#IX4+|NuK{{@UCZ%H%|~aTeE@B{Pvei-syxQ7pm)XTXS-5yRb<zYdv2|~kw@;o zO*8PSPCin`A81mKjrkYm;wyRhsUrT+e&dbf)*ofbZxqRIHQAS3Pf?qAz<1^K(E^H2 zUs{`{Q5Vpgojme@Qm}x6T|zEgU~KmT96aVli+X2yYIeB4XMKH1uH>)<J8PJ6qF@22 z-j!pr<!~Ge%vU2eNJ9ecnms~O+BezC#kC#K6r>f28zZvkQRE4YjhxxFS$)DP$k<Oq z&Q(u<&sB+sma#k1Ffa}o62BWo$~OgJssFyM@WxU4&XW5^pM0r~KD8E~X|lJ4@ropS zPqX_*mibzmdT74>OdY?Yj$M;^;>l}!K&G8;S~<@TI@YMzcAdP(qyQ-x3%LN%W9^sn z`*>u$fWuTO#K8Cvj2TQ`HdC?UEATi*h{C=qGOUF1Vx<)eK&V@#h{svV35k9~W5>8+ zG*^tGacnBB8)hHb5oT6Z*Zfo_2bqi$_wHyqIxl_lWi8*F1MUW+>l~aiX3TwUDE>|y zex^!12e#jseyqto|4$)|Tvwz3gMAge{<SBWkA$=ZKe1q6*pHDa0fbA~8B>iFEbDd& zL@AtM()$_2H31hV6j2-=wb3n7*$9pZ#o$Ib^LT|Hstqq`g7XYzA6eKhP%eqp>k7w` z*gUKAL#?rOrDH{9M_B_r;18>2=X-`n5855GZZ~usbO8jOJ6<=;HRQk;F2xX4ChtoV zkL9VShVobX(o<Rdx;p#pKZUXUS`xc2@ZU71?g9kTDciM-An%41{mi`(q2fl|@ME8( zCA&d^P6z|0S`m}rv1;`?r9v(7glzt}!RldqB3y+N>&mc{E`-XnY6<TsEJ(AD7SCzj zDYDuH*ZWr$4v4|OX^&ErR-!wqsyciAP<Q_kr+Zl}>4rehM-z7F`c6&5(24fGO_5HQ zzYlaFW$}fw_*|B`qb%I{i@N^|eE~Q$zS3u2szTRsTnT)Ann#=DlR6M{Z9?LtOS*)c zzqHtOY-_p&x7w$Zt)bxa<9(g|-Cccs13UpgS4c~hY$yygFx}P-svBKwRM~Jq_rx(~ zz|i*Yk(yO(m&Uba450YBIf-dS@4;CDEN?<qwSn#L9sUBoc2OjloS8b~adYlHNN=FP zU)0uM#7ax?o;v$fk$)}DJQt)M=&yaH$~^r~0kkGv{##r5jo4kDT0?aVv}$$ud`i^Y zdTI;SWtOfk4WAsla*(+(&cTfZZ7A~geC^54)|TfdK@**w-E1}+hy)BaJGV0R{(+x& zjnv5vL_BkTd9!Z`+0!|EdJ@_w)FBAmNj!IagWQWC^xMO1Ymi$NDl9g3{cvLP1a^C@ ztN9?EJQ$5`1wsouRHQBHb7rqf{nvrwl$mcuiI?iiw|`Oh|3m5<W&DM?@U=F23r677 zceVo~1BnK2Y&eSE8jS_n$c2W<?qf>kqJ}qJj^S0@l`AzLF^KSmxslonXEEr_pwDWz zD#3H3t(_O8DhiPWZSFlpV9yvmB))1@YQPb>kZsBY(4*F{16yQ}+>8fYROL)mi&Ym) zre(Pp#$}FsoU;yFS0K>ou%ioQOLjl+O5d<#U#OF>#E~b;%*(%U&Yz*leyxZ-b?klX zEImaq<zHTCm|R(D9qg^Xcoc=5_Xh+MBj@T)|B{U8F$$+1?b6lU`TDaz0}a$RH=bOD zfgLuL*Qu5Ai5KfmvbdPiZeV($?R?#bLJd-8+=Og2(M78>uyz1H|LCv(;aC3^g6yXW z*K9#ymB#w1&D|iDG^jP5Zg-Dbd)8>I^E&!%x{hdIwY+QCy|bUZ_SBJktWDn2Wgh-T z-G7F@@RdCF0BExM#O)Q5xVjT$OYDVrAM}ilkXU%DL%IwZgwAxkR7AG|7Szn>`70CM zCs44_k-nz&l?4Ht%B5i@hTBI+yR}-e%cEb0Pqg=(-^7C{yyfok(`Oq#MBv6Le0Xik z!PfqBTsaPa(#)#z_-h=_x=6g!6RZxWPVe39E*543j-|BslE>Wa^Q@KjyjLII&p&t_ zy7t7Bx%L;`^Uu%~UP`04ErrM0*!4LK@6+mTo+%}96fZP(ZxcvzjcjbJul;fjdTA67 zZKW*Nuy>{!PJFO3J#hK_sUrtI8SHG|UR^o-$@{HWE`NW<tu5;fis`wb(-#h|Y)rHd zR!=Nl(K+co<F%JNj<4>37gooZBCIQ{tKv!8O|HgB<!~T%!D60qIfsIg%P#w<*FToZ zf>r8TnX*0-Lq-zP*KfWGC9aZGSH+>*s@zR!`Ytf`S&IM4G^g6<AYYt3HMR&7Sptsy zJ>V0PA)(6NqdBvK(!{pb&vr%x@vB6oQbL`GNXLCzh>APNKwZ-F`x#qxX3@Nqwm?Hc z2%9S$3Tg{Br<QPldzss#Llc&Urs@<H978yp+gGtA3sl|=L$o5*k%380q~KJwx1FAx zIcD{D$yA-4O{Z`>{T}xsXz0xN@QFxbB$Di#p7?wR)#8fIE6s2$K|G6)9H|@VSX`5a zN|x+PmG9n{7rF-L=Y<v*MxZ8Xyq>FHb3Ir2!RshZ2q3`Cek1ngM2^^|Dk2S}Jr=H# zJSyTW#T{a|mX!1Jyjqk?g9_Q1eEKRd0<tMPN)byV7n)2eok1+o(D_Onk+Zx_7(rtC z!fBC6h0vHucE8*iFfe$OD)7|Y&~URWv}Lwp&z-D>FOLO6#EzCr=T01$n*JaZU8E7m zmZ8-W{blIpF_BCfj_uCDw(9%F5Hz_v^E8lq@!7FU^-ZlTlgC!NTmJSxSe|{dt#oE& z{hv=ZwLmuEEbB)H&m663?^qRx0#{dHi)W6$Hwl^Gkl2-EmQCFL{QVzo!Ut%C`GNkk zO|3_^H<nwjTmbx*&O~Z1o^0!_mmAo<lZ|I;-#c*l?-_iU&CAP{+%BJ1BIi&UMBpSI zTiY1ly(5Zb*e$IMtH>^QWNmz+83O63KKJ1kVvtE6VlbMyqTZIyPkce$vu7_VH}3UJ z!<s-yNB*@Z`wWQ}Ujjzvk*QYjGR+)iI<orQgNbcsP4~!qM@|fYp(l<U#*vv!&sBBd z1(w0;9qxSR`0-1Zn%}(nu9!<6Jn$}$i#mGz*9X4*S!-|gfdlUikMuNNsnr_fXKRmd zVpexZh$CkYgyIG!Z|ijR$2v1VnQ;q5R5ThPmkF!RR)4y<+;jVh&L3l4tUHawc82m> z1EZG(vQ?1;GuU_O*r6XX=$&>4?Bt1`K^NxJ#pv}%Puiw8yH@zXr3aW>Ls!3cChyY4 z!rvS_**G$ry!-X(j<M?Yeh6ayM?e1I==A7kAN`ogV;S~djF8nw>+7dhX5Kw_=J>_K z_K*=pfc^6?{s)!-|M@#Vy4+R^D6_i0pj7kPJL@{TFAtA(hhy$7EaJW2yc<ZE>Fk~V z_P75<qZ1~RezjVNL$A}wJ5?*t@t)oWtr4d;vg_-vpox>o3a5W?fXsnky)P4pXD?qk zM#A?e^Pq*rPtPB2z|ohb7UL+AOLE*%lz*?tzeFpeJab8=mDV(0>7H5g?>#)$Jb1Z( zOsZ49_u<bvhr7<4{0Ml~?7ciavva)hGDps=2Mr&n{^0ua0$)x2?U(POi5r8UfmIYz zZqn)WLKYj{)qUw7{_(G;ru(c`HJe2}b@C{KkA<vG^$oT;oJNI0pqBF#5~fT*smi9* zYw%GzecE7PY;GU~a#$cqKp;0sym?=G^ZFg7-OSKwM`ML*Z>SBnFf=lL2+P=}YeS~J zKg#m2l=+9vvpa|C#!uIsTio6@r1zxJ>*E;V;nu;qZOrl7^W#w1$<xPx>B#luKj4~l zL*L-Qa7X9F*uje@QrGiBjpUc_zoRqj?Otb7ciV~Dv*RPpRui8_fgd^aOTC7jj=S}8 z2^P6={M_eF9T$ZXb}SmuC`DSOKp~>&<n*fDU23_^-`!^v%c5-7T)0L{?jh|ixh@1X z`3U8GOE!<q?skS!N0WulKyb$Af#*uj%<Y%z)H6=#nkskQRe7NE?Yh$mXJJnq*=GcA z(L%R4p?yuNqKU-J$$g7E?91PyhF-GcuTz!V7QNcy@dZma9kHU$7X14kzr*263VRi! z+Z4`*?%zsQ^3IS?8V{@d4ylYswrLe1hZDGe#WFsJ+hj5800J5*8yLvlW<gb<Bra8? zyZeg0tIEAydATGh7DR=-FqR`lGE8TXV010GqXX&kU?MT-F!nesqrs@iU%siYd?PA6 z7ZvVm3lFUM=d9Q>0L<u9M&t=S{1{l-@#mbx3qs@>HTsO3cnVy#joAnG%pFH!-w`PR zBl;v-c&N6yYoO0&Q{BCj-MtzuRKmcP#r@v>L@*mbC%tR9wduu)c@k;I=%8EOLX%An zUtMIeNIDf?%-JEM=c}S|Ml#LG6@=wo+4nSd<)xxHpA*>qo8MRO+>z)(8hcwH-VqLW z*^O;BYhO4e2v)AEvafjQm$K3eb^eJYbd&7A{}v?QJpjN1HTaMgdW81g#rf~jL-$4T zhuZ98OYV^)d*6||P4`^elKYT!DPN@tCqmJLUt>{n<vgB>qEwpW!LZMc)hlL++Y19- zJ*Q3`WYTw(GA<kjX}VGm#8)K5FGIUlmYS+U5h}nTmEji45`aKuPoB*SVhN_rhxJ97 zRv%uhost<^-J!Nfw9DseF&dkKDXPCzP{yAL;@>JO|DwvjWVm)Ifd_B#w(dWJ6n;nv zJ*0&na-xsKiAS=;Lq+_7B6gn<xg(6;vgGfED!2Wal0BNxdV)N?&6LSnA~%AGtDd0R zV8R--oO$r%!7o3a8X6X}xb^31E}lC_z#>=SV@t3OI&Zcro#g=v00goHVZJ2J<OP8k z&F;kp6TC!G7EEzfR;WbZXY+Q3V;!MjgT{El8G^erE`9Q@GWDIh@Ne?mSKQFex6XNM zp8wxY?8Gx>><K;c2;jg7KVn9nFoTa6frsDQFZ0k)eqt#;&_#Ehh5M1~Us-bx)y1ds z*dwWTH&`wwb|e0{V;(x!+1qpa=uuGrz+gxBl?$~St4kxJ?advhC0bk+V3<sf4{(U5 z*wHi_sNU+uXst+Jj2q4f-Eq3wx+>9*>n*)bUz0CbW3^tkxj?QM&r>Mc@~>5?H`3$_ zMfUsZfxUk#0<iJGE3g93^vDBh=m9x!?|X5=0FxK=$gA%WyHAVU7N;Lc68E|O>)OmS z+wSkA;YWhZSMtJZnxmo!U9)A&5{G^UvC2`|o4Oj#oIk<iGOyIt&QDKlAmLve`gmz| zwhG8=Hp7c2S<wVD7^k};B(oQ-wr^PcRHGNGb8o602$gwRYX(_eSA3y!VPCJ)+2{1b z!v&MSbWIn3B#k}N6kh;&1&V$fgSRdMR^XWxf6RzJ2DTq~1qe_>&nUs?<iInW`z9rL z7YH{i{DADd#qizdhM%&$57^-+n%x(?@NJxK7pIFa&}pp;D|mSl!DY>%wpMpg4Gj%* z(-TD8*4*3}aNbqrvV0)2K!{TXK{U(pC1|z~!RW`Byd<e<MPgnu`7n+E(PV>KoNa+v zP0A1Q*xMbBZhssdEd|`gJNoPsRqnB*@P?aw`Bn#Ded`~91~>Hra1p@at;cAgCzQY= zlJ5aE@PHkA2D}nH_lVy6ME5<4`#w-T+j9f>ZKl7%54=(4{y_Fcmn5cj=?#o6M|b6F zdnUn4D@f!rc6*l3hOMl$Q~^zMw<6oWrULp(ZciG{b6p9lB}xPi0iJf2ub&3^_~SgY zW8GkF^F_|5-BVsmli66~@Pc9mZR+M-_x>wo=Dw`-9Y6gVsQ9e{K)G)T0OtALKf(Jz z060MI6EFDj=e*c6PWU-D{tEBDk9R%frM{tso^2WT(Y9;L48xBOAN|4M+RxibBgDw6 z!AFhWAiDmI82t`qxjjcvJHr{RPGB+O)>kh?qo}I#KEmOe4EWY^DRw?BO(vz@FxMU9 zsD1tJ2sNJ3`J$v)3ZKmgyzU*hds<`t*l0azw0&x|G+XreaE6?@tqCRnk0f=+a_x8G z<ZD6f4KwsL&iO!;|C->xu@SgW$$Yirxg*Sf!vK^CJfV3XD+~WBO1<JnpVEO&6?_ON zfN|WyIPVg?4;u-LpMLNQ5|h7-r5~#~j1Wm+>I8*v9U}8k{A*~QUzJL3Xp-XiJ&a(3 z#TclHq=ucIzE~W(Tc+)nzxR?q&aelF#_$4Dyf!^IxUkY9SFK#X=6-P3YcfOhrZdq{ zPd?L>jStwgvvPHlC%#y$Tnj(?is{V?Lbue}Z{?|P8NLT-OG%V@#7sTsXI}%3XU85h z0NVgLaoz^L1*G77-;o{y1jzn}c=uhr2gv%9D`@7S6GyV8t4yWs!!JHsq_c*|x=+5W zJv%cp2$THdN2fNWeEaP`Z7Pe0FV}W;ovHH2n*-6VTyFN-{!XPrDeZEy6+s}yi0rY3 zr#t`W-~I4X<B_59nu*DtaLAC!$?{o5Dhy3Whi;W;i?Ml)>V(tRoJtEl`=!FmSEk%` z=k5#V{u{^soA|T;P~{#n-4#jfo;Y@2nR@}8Wzx(GR`4#ve_ND%{+7U75daQAHW-m- z^Ah*p{@{PrHFln98R{D!(WXir8@yk<^AX<7(ggQ@^3kVTVyY<dvU);td34$8^i&06 zt+8ZpG&UTKfCK*JM3S&~Q<tr%wZ5(Hv9@!yb=U4?Y<|(%>Z2kF(-q)t<9fS$e~Z~Z zx0_uLx<-(QUu^9h?CJY>5HhIonMPsDwY?))iOIeDm}&^OL(othpQaADDla@Yzx)0_ z^`%#e>{9^J%qxEE2|M(?CV;g74%8qJ^k+*#-w%H9cWvE+^C*VF?GM~~ad`oM=Javb zy$D+y{+pltjAfO$ZvXqb^6nBvJunHWa(FuYfj*O=MW=38N(U^K_1!&7wrDd3Hl~*b zPF9~xSL_1S#)&hZ+FWX-0oOiWPvs-~htAH-9Em339o@e=apu<w1GBmJ+&iECMC;UU z(a1mj^b3l@yv5TD!7$^q@O1*$nY#yMU6Xra-2F;ddZ{ZsQ|G^uB%X33j{pEt06GAD z30S8nmP3aQr7C-=hu>*^32pkp5L#Sw{;>1*9#>sBR^6lw7&!hLIQt`cyhN2s|1Vtr Vu;WKwORfL_002ovPDHLkV1hsqiJAZa diff --git a/packages/widgets/Source/Images/ImageryProviders/esriWorldImagery.png b/packages/widgets/Source/Images/ImageryProviders/esriWorldImagery.png deleted file mode 100644 index a9429daf31d7ddbef690cca8388521bd04294713..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11575 zcmV-7Ey&V|P)<h;3K|Lk000e1NJLTq002M$002M;0ssI2B@5<>00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv001neNkl<ZXhSV}2XvEH)~zt^-Ex&=Nw$jB zd+)vXUTjOU+`A1nrW;cY*al-Tz4ru20_i;@Ap}x@gpiN`36NgrpPB!E^VWLny~E5~ z>#VyzeU|*4eb2f3>@6E{>fDj}gVXD$#@26MJimYanWyJZp4qi$|CX~C56|pcw|IHa z$kOhOTUPGaxoK)<-T1_k)e}oLO;3!B4+ql$iAgLqOH4ikLrhiZ1cRfUeM9M<zU1(5 z`;w8a?Nbvwr`N4pw`|w0t=qS+pPE{8^w`d)p5A}-*p5Sox9yytfY?4ezH#%ClV^4x zKEC7V$@!ya_MCp^$fBh^-9xFZ+txgF;ozkgPo6qEf8zAco%3sE=T^<_8sB$d<Dny4 z4j<im^!W7gliLtSPwbuFH#Ir6V$;;py@w`GJ~cnTZ|ll6i^exCZR=~c`HZ1PPgifc zyRW^kzq6yWrMItRcIWi)(jk>iqqM3+Es;n|lqcnCOp;*SDN?XhI>Dlm&WVZ9o}Pro zB(qrc8#b=qvv+pO)WqDbE&C5{-*;f!$<zDhcCJ5gaC+_fC4B>_U3<6gJv?{p%z-1P z_HCWpDA8~^5^5~v-7+(N^6Vbi&3y-_4jkFM_u$53r?#CqGkfZ(IauN4!J}IcCr%$Y zac1A)<2w%=fuHS$ZCJHt)E{!1y%w24PUTQkMwP{BRclo?hu!XU*ld;+tCo90zB&e3 zZ8P|q!WyfA%BEX9Mo+}a6*Ku#c29rX%JC(MmZ(B43WmJ1JEr&U+qG)-()An0XLoGb zvUT02&8wd}cl6wa<4czI2P5tcTh{H`H@9Q&j-jz3okL&GsAGxfOd-YQF>K$t@%ZVz z`wne8a(w&T{5n_<9G=>HU^86o**|&o#4KX>-kH;94?OeS@$=6ed*;#!*oKj1i*#nK zM5~Y+)GV>U<gl3>4uM2!b9sIKutuwoG&V7W0t|($u$Z_?IhsVoHjsHz9$&^M(uqs~ zGnR^V4|O~I4vv^Zp;4uB8H2?nk_m3FW7&!&%U3Pw8|<2%nOwJV+~zP#l;Y*%E9Um@ z+OcOo(%i@pa;os?IvR=0Buh2YH5*o+d+w=IXOHaKyJcd-l2cFZKlkj>6KD2bdg;u6 z5=IORbj-}Ghnk*#`bjBv?3qb+BxxL0J%i4cO6q7-zFf)Ti_utuLT%C+9U_^MBaxxV zWGsV0;Pc9fglZxYMI^yTu*7<F9j<}HG`j48rkKWRq6@e}k&Hs6qcPZeB0(aP>I_=3 zRMbEvwso||8l!A3i_PbyIy#2O#x~E+B|5tJN>v%Awxk+G7w{E2P4D2qvD3#796i|H z)$DK^Hcw3)Iy%37Zt|(~$IhNR3jL4h?QNZ#+kEl)(-&VnbL#A&E!!sDK`*kVioj&S z@4{1POreBK=a$#t<SMhy=&B>r$}rec9KMo5K_HPiC=^8`F0UsvFxVBS+A<WTv<6*{ z!4g?)wp1q8>c})^K?yQDzo@jLvZ$=I7+FSR(@l1>$LBSgP4#3F246>{GSGN}%@<S} zEl5mV6`oX$BjFlo)wOuD!@X^8=Zf()dW*KU9^IU799}Zm(vgHb_a554bMFp>KjhxD zW#Zh$QxLlk?;IE%P@433Dg{fU5!h@zjb4t$Rbuh=GzN{$Bhy(6@^eZss1h6|v!c8R zi=~L9e3gO5l~TB(^4j{W;_|{uG@3}Qr*rCPY#fD|S6PNA$U$T+$So_as;#X=W2sDz z*B4&4dcx-RmDgZuuyv3<+~<j9e2E;k0Fj#y72wGf@KAWP7|x%`g08D$3xy;)ox)-< z`TS&idwXv$tO%Zv)za3uX5;cz>&AK(wOjo*GMj<KpbM&MN-@}C6lP&j2_hp4u`oL` zuPC>uEUTnAr@Snyyc|(hhA2g5l~)y`@JI}y<lhfQEX>L(DXVRulGt2Wk+rxoEUE}q zT~Jw3fy1Nfi3Oz<S^32k)wRfKOkOb(k&#_oUJa35P*Pq~3qOL7!|%yORuGu%3S8ZS zf}$q{N7v?+l|yY|1xOG8PoPi%HUt`vGT9Bytr1_$sWeJRY;t*RbqTtv1Y1{Fjmbe) zEi5cU<P;(@auGR2d8Jj^rDcfxd_-w!er;`5H42eifXFW`Mb#}VDn{hyA@U0ftE$l? zGL}MxwW_Y3$mihb)M7L`ue_qT2AxxaL@dlhWac9l<RG#OGYiU!D$v<Q<qPvm3y?Mc z{!tzxuNa~XjW4dQMdTJ`79rtfaTO}N7&6H(t--)`CAO{_PoQ!Ih)Q&Y)}#(K`^|10 zOG?MladiwLTP7fI1%+rVBEJYxPy)YVL4FB50{|4()MS*F<)Kj340<Jvnp;zoQ(09_ zAVHrL)l{HJb!c*ZIS!4)qOepFUBqK4Wn>|*5RG0?R0Q>`swbA9aru=fNUop)m4~d( zEvteoAw{^zC@6);<(5|?vhx=dmcrYzN-JQ6J5Yqo;!;FjK|v+d^GQH?i7XDHs<uXF z)y2~hN7yRV@@XQPNH6s?1=MaANhm1A;qoCxXqdeGjKZSg8Wf4kt)Y^U<oYT`Lp769 z-atSS@F+4dt2DQofTr;2WG)p=##Ys%U?Z3k4vs~w<IpRJxMCazSc|Dt;MnY991ch< zyP^VGu?T}HuB|P>V&S3yh03d}gmNKrbD_@JNaVtj5_oz>adAc=R5%|x3R)T(EV~q$ zS6&G)5Oglv8S*B(Q{E=G+$?3t=mM?S9&uZue!0WMP>SL4B{)=0c}ZnGmLcYgO=`MA zfaWxmGjP=$LY<gKk+G;!7Lh|_NEiZ*K&TaRm0Y@*UdODfCRUddYf$t$BoS3cuB9mW z0;`Uq6rtEOu1-;mM?q9m33x8OLBfNzj>pKYM&_d`GRg`IF;(zfxGu)lEJPM%BTMtE zDyj%|<#=o@wE>B%EvT+UWM?7_PDf)~OKX2yFy+^Kb$l&s5=UZDitQSfPD~avv20Qe z6^EhXsUoJ-q?FmzES-p?U=S4yik8JPa)ox0(j}LfBr2Oi<4{4U?Miq_6H#hNRrLZQ zK}ag6qKXLR7#@kFWaGp%l%RnmWfj#|Rnl-3R4j@`psDycKBbmRE+?W2YmsI3)f5Sf zD4^lkB$|warq|W68gL8}UBaaZSt7lHz@b)?uo)$}2yZN!=xj^&q$8~nZ^8o@#Acb? zu2K07OdTJ~sfS=F*l<%}Q_3uIu~p8}^VlYV$fpo`Wo$E>V`j=+LcWHruu8NprP?8f z3#CmeGm8XTj?f|ym<2>Bxr&9U=3<d_^g>(_0+W|hTa=3}Zcs1@5-L$j6WJAYq6Q?T zra?-tqM~tJg2bj^s=4q|YFE+}ET)o&Wf4e1T0O5pV35`_>nlj8?5YApxXB%B33v3j zC%RI$fWsDYIHOLvRf6HwGIUJ7T}Y6VsA`(f#20GV&VYfdqVcsfnUyECvN`$&ftf0H z&{_I=Lr9@@iwqu#Cu;D;Ek>_WY~V3fbhTTj^%^u@t;{YLnT31<mnNs+x!4*;rO?9r zcL*$Tvo@dsocfTSrJ?ck9HmF0@~YSdF2^X4dDY5*p+P|}CL*h8D3L{?bg6iHK2y%1 zOKFI7S5s44EY+DzcC|)Znxbv-R9~uPFlCOJE9un@Dw@ozq-&TGlhESVyMtzxU8;7- zG)^gC5Ls9%k4WJWFtsF&M`VxcyiI0z$N=GOw0oND*04$LP(VQTVv9&%<O_^Eu|+6z zh!}FR#x0YWc|0w{7*JcnI*nW5Y_ysp8ih-wbW2rUrPM8xxfK$(oN3@JtjR)DW|Wc2 zh+-l`Nf#RhTDJ-U(b?b9*4GkEMm^C$yfx81(zj&ol8J3=WKLN*wGt<&gX+U)95HLM zGYSBFO-@JD0!>1fHE`4nl}85IP-H}on&yg|6P>|8+zxMxrhIUy%t6zC!WJ>xqZX}4 zDKhe8R)Hy~QCI}NW}7Q!vIJDoHg~Mu0~dO?)Y+srMO08vsZ&6f)zwStpb=OGHinI< z6Vx@x8tQm>Gy}zy)0B3Z+#*Kw4tK8JuxfPWXj^|z-{_*wMLqVgQ*4wF1Vo04RWByz z<BLh+21mr^3|fK_rzh^T_>D9n@IYxD8xPGUvrA!1I7)^yVrl7)x3tBYlEFwaXmlGG z5*F|>PsK5KblzsCIiTljSR5r?X_I&(resGj-s15^&4~_Qx+mm~>hyMjJE5~glv=Nd zt|XKYbIZtu6g5fW5=-o2u7LyXhi23iWAiHsrKpCAlG=R4p%eS2cTRWob-5!!kdW4Z zOQe+wbV7+$DzV9+;UIgmxPc-7MMrXaj4-X`dQmL}RZx{n<kYJiYPC}Xhr5AKVhU+O zIai}s=!`19gomz2!*IyR%Rr*a!0|W&RtS|z3Ssl<2Zq|gyM-clgGu7{Y1=x(gNu?w zi&NottKKW->nUUr2F*m0q<FENCwECyZUt4=KoSwS8YWl8po)l?hRWRX48-L0#@3!z ze>B`VG}ymnRO_&yNVU}@w8SI@@-c)gT)i;ArT|C9iWEE^pRO<p^mYYH)PSR*_$m&J z4&eSL6=M>MD~odSGAk-eVN4em7a=kbh=mXt1trCJB7rC73#39OkHHqOBubIPY0+rq zEH<^CfTlC?W~;olJ+f%DP4AT`?L38zD>N`EVmw1d0gl!MwWf#;jtw+wAmvQ<MWOdN z3Q9Gx1Obl0;dAk&VvW_Jv)d?qHWFK%S5;VwE2|(?b2R))GH8c|B8|}Fw*df0Kpkqb zYi(kloF+90*m5R`OAzTq0+pz~fq<?>)z{bK@%W<R(v0k!%);V~g}GVT1-W^}dHKcJ zfG;a&VOC~lb{1SC0Aj|1g;|Kq97I_~9*u>UD%nCUU1{ap!g{?&#gJ2|G60~kH`?H! zQzZnJlHyC)Tl!;xq(fyEP<c3n!K%lR>hepA^N|(R_<D|9%vFex_$ov`BC{+ft1^E< zSvHZ|U~(GGHhnPQhE9#99C`-;pa8Kp@ahTdI=x#fl#5}HMG~=0BBfIq#U<s41({C* zk)M%K2rB}SgFs{fo&_1%2t?)r5N!)G0c3u0(SmG5Mh=J?B!yLP_N%oHIb;tbMP%U1 ztukZCWC~ezUKveV&y*7_A$7dN+uRM5<Mzgk2!}U7pwKf4@-vHzDoJ>{LPS@K&}?!> zd0sKLDyOO>yS$LZqu9gNP}&_xS`1E>Gb9Zq48bOo*)3BV1UichXosU>t86N8`gmGB zn6l!E3Pe^eWc=^Ea~5Xg=jE2>=9DZzz|EW|Yi<@4ps2hIgU8j>Vz77|t`4tMDvchE z+$7RE6b83iX_1(`T3gTvr50I*WHAxX#$f2x1P<2dQAbi96VRwormVu?06<PzDFC3# zcmSZ5O925>NyaQh7Az>vsUc&yO18=_wg#2S9;Z91a)gxOlr@~Rd!m*=qZ1g`=r^!r zES8KzWRWo>JR&0_Gq121S(%lYp9v!Q36dv~u^{LF-}yIyYAl8$;0q*Tp;!d&8QM?p z(rD~Tol^|~7iOQq9dm%t<mtIINdsHSfRRsNVJquO(S&kbLp1`NPHr*i@7x?@F|xiE z00^xbu2Cj1$q0OEKDsowvbd5^QwtK4Une!P<83x)SQSoL+WMp6q!aeQA9r*Qr-SJL zyr-U3FVcuv5)Qhqww^++s6k~c%*n|ugn)}IaF)f$g2GbhqRgV){L(^9Jyxcc8>~i) z%`8{Sii!%zOp-_`ROscfvV=?;mnx9+EpBtNuQ8DF02lk4T~HQ|gj!ES6R2n?VtFPQ zl)P*Z^qJ*_7$yO-7ujG$aX@vH)>XlIz|!kMS^@x(j-_=9A)pJpMiP#QL7-;Ii~=aP z&ZDiULxP@LJ2kQQ_`au}d+Nl~Cp!DOpvA!lmsM6kAgd}XYN}y{JGsdG%Gyc{0V9+N zRC=W^;7+6(sWcLnP%GESOm?GErvSdHt;dk*B%9khysQtRtuG12%i_@+?P{f7%$G93 z73F6Y<Yku>E-1`~la_}r#c+st0i}vsgQC?U3Dp(#H6$Jt6tdXB*SnNDmqg<bh12e2 zZ^Yu)N%TCXqydR7L{X|rv4!b@)YZ@4|K^9UfBpMU-~D|5{H3!atCuWVIRXI}!z&gK zE*l;lA6vC)e8q<4YqyLqn^-b9+Up59!ZGi_aF<Rmmn+0po6+tt!)h|?#1g(jDQRqq zEL}0QdSc1=+Ohtjc9^FQpUD-lIQ`})RF+kcgTz#o<EjcUWfcu*9KQk0CXgf~nw(A) zP|186Un5pnR63W&6}38|W>?(WIg)N)l+rlmLLCQ&Yc&a3O|BqtaHDI7zkKxB7vJ6d z`1Tcun|D5Z@au!`e*f<AUymUk{rTwO9}i*u{%_y^@vmQh`^S$z{q^Ye%P)5Hf$*@k zbv8NOhUTV--{-X3jIhRI!BEfx>)=55%9SI@WTdAjy>9)=rOSrfIup@GzsaG4bG4wj zqO_h)1~UacLsx<T6oJYW+r%)8#b$-UYjMWBCLah)W4I*%jTmh4LZTxRgFtow09L6< zAhU=;NVg0$Uwq@-M|ZA#^Zn-!e!BCo|NGZ>e}4PpKYzIQ>o?cGx_0CKr{Dkm@z4MB z)7L-W{rJnPfbh3}eE;r;uO-^T7KbX`5$zvL_jV-{jsCWlXn#*jOCl8XSz#R+?&@hz zQb<@PjnLd2>h4K*cBPyiGqSP}QC3}!CE}T4HcQHF5HmP1lB_bSip|n8LE%U&@<>}_ zda%PC_gVs$WKUCSpc#Z+`{MNIx<$T}%NWqQnrt8>U5$2NZi<l5*bzE<ZvWShZ+>+9 z^3_k@`0mg9_ka8PrT3qooZqnH$hHsfT!A|`AAEB5`4eZJJ^JlWU%mO>i=jrB-YjkF zif^1;;dW~MUgKbY%gCY*lR?rzs!_;Tk&tasPbZH_6>u3rpEDZq_w{!+CL)DkXb^>n z+^W1XJhGBlg=5#V)jUWVLTHl`Bn|c^XJRlJ>x}vnUaeCNGR`0O=<TZRk&gbQU7jX~ z$*&dYIUtESa+=02E5{Y_Rm`pP8{WV1)|(%`45fJdkGl{4ynX()6KiJ1=8w&Ma`(!; zA8x<;?!_Gkw>|Ufx$l3!|MHv9!Wbb^YWfFTR*esbA~s*ZG&tPa)0d#qYlUK}&7oR6 z+SwF$d);~thb$Jemn|QOL<5mnkV>Z@DhQRuwIu+co<k7oMGA)+LTXh&h)hy*(Bh1{ zV(l?c%*_(f`Ergk;IMiup=N)gyD{0@Yz-Mn{Q5dJ7V=hEC6#q0YMb=<g@cd(ynp-K zPwzau2>?ESeC?SxPVGK9^V$cOzWe2?hriza`M<vV_{(dz?tS|EKYzON(VPCL9fL26 zH+hyU?QQLhK|6K#CkGa_d4p!NT^Ub!m#rG~`>i&ImdPSBISrjXt)8Ge*_KcnG>8Tv zr370F!Bz9@Q3qrU)=_R%D9vh<#{yyV+S+>C8dGtuhy#=dt25wq1znMrXk&X5N5QEg zRMfNZK&CpUqK<(!c{R{N0N~~~*CBrW*TaW@eRc8evzz9|4?Q*i{wHsIa_7od4{m;X z=h`=q@BH}Z!*@P-O>LBB=OL(!I=PCUZjUR}0ubcMbi^OBOXQqHOL*(dy2eBZ$co9Q zR$(i}DiMrJxlu{xP!Jee?ShgF=ps;*?zmfNRkEclkZv$v<Qj$EV(<mLiBz*c=u@cV zDvgrPW?5Y}yT{Sg+T?Evk~s||ZUex8?Y9Q>A}z-gx9vN*^Zw6YLiTsR|NP#spTGIh z3nOd#f+?rJ(LOxZ{o?Bv-ud8_!zcHC@y(4t{_)F|k1i{9^1R}ll8U07!mR4rN))cz z6Lht8r)_QvrVhmwv4b&xs3~ao*+^_MXsd#%;_UK#Jm_Bx5|LX|0K%jYU8Jxm>_Hnx z#wN1}0tJ`LWrM7g%cY@6P@_}x1YD(BA(99=JT9F{qp|5QT$Bc79lf3-<C54!*nR*2 zYrH*p?EHb>{^tkC9$?)6<%^fzeP-9u>8~E%y!6V`Bg^|<eC5LNQ~Q^VkG}Q(Yma~V z_R975Kv3qF6hPz@<fHKz3X`hPDr1Sb&a7t(I8+u5ba*%!xA|Q(J_}K>a6xfaA*!^N zNyw=#LV#v2#+8xyWNXk0jV{xOcoLS*s9-QDwb&ZDQW9$nL+7ygOn1Nq8S?}%Bk+77 z2eyYTU}A_hJQ<TMW7tDRIK*Nd*B!I&Ju&zFUk~26`qI-cp8WCe58nRp<z0uSKmP3f zUHhkFO}>+74sMxVJGOlI@UgvbU4HGE=Pwv-rhkv40z8Q#QYgp_21u#0>S`1o&k_i5 zBvMIbr9!6>$Ru^Nh9?@NvV<w)s_Z(Lun4|h1k3|X?~QxHiGbZ}Hd@p+yIvq<N)>#w zO&g4Rbv8H;#@7BcfVA2SW{WPFj<t6+TitrLn8KGcd@;K%_(WFFMI`8@4co`Re01xX zSI<H(y>smq;GF#@=8l}&vue#K7|zMf6N^Xs#@8&}wtdUV)5qrb?{<1U;0cPWPz`Jz zS0rs<ut5k`*W&;4eKm;Xg}DWYg_#SovOzQ;7A`2MDR)IY?L%GOCO^U$v?!e#aE4aD z#TRpX19q!TXD}$#I&r+&?+#i)cz`4X8cp>jR1Re@<njk?aIl(E{&>o-F^h4ODwA8G zw1^pEG6VqFIJ@TOe>?&fx^?fPU;h5^?xS08z5mjg3rDukP4*77wxr`@ONV;<+E%Sz zx?|_IrK^@%9L_9|c~z*wa#U7PX>Mux6OXenyQCV8$jJK7ce-F97G~z=6%~UA$}P^f zxGk~PM!nO3P<j+NPAyGHw7AuFx7O-Z19<^4Yt3?tOXrU|Jt3RXqO>`6pg>^YTb(MY zoT*ZCV-b5I>9aVLVhvkr;A`zXdr-j;VJ%+8%<lC!zPft(`m1le|KgP!@87<6>)!Ww zq2qV#nVH?Wb>;YyqsR6gJHCI@mWj<%8<wpe>*#Gyb*3P#+_FMMb_NLhtl}al!otkF ztjt1W3A&;fonKH=UQv^qS5Qz?NT!g`wbe$m4jK<Z6ccM2DmikxKWy~{tZuI<5OzSK zT7%r`&<7)KU(jK(YTX`7b0VBbMquE3d`7ohpH2n4yPFfKfG=XRhfG3sgTln(D;i>H z*YR_EZ{Gdz+Gm$REPVC&i`(~ZT>tFKxr?W^Y+pY!yK!i7*OsY?;l*8RH!Ppry5{i7 z{V%-s-02Iav=&WXc|j4nyr8Ny4_Q)HU5PBOEGjHRRbd<IsTgdnOd*dq#Ri85EH<Ot zXE&Ht1ad8+j!VQ)FcOV09Pzl_X0uuSq=n21r^D>^*g;4|!alh6c^%0_tR>wPYxH`( z=2+O(*PU8A+BZ7Z*VdD8hi$3upewA?*+p&r@mDTC1LOAlKkohZ&&Lmce{lEVZD9RN zubkhxZ)Vq?>EV&?O`BIAJUn~g$n5B{p1p@>fmKhOJN!f~540wFQcWGr$?g;kpZ3ml zDwTlf>}Z4G)za2Hw774_t|`4q3C9VVT&Cn9SaL3oikB!wAd-?zp;*|HOor0wXtF8N z91o?F@kDbp;CDepV}W4E0{|isS9?0PXrO(`;+{2YmW(YQ3^jXYdJct)6{#7$Bdxc- zz6PlS0H_0q)7$qxxpwQ_)8`Mbm{`1Ge7K{hX=-L-)tdgT+gGk$H+b=t)BpW{et-1a z*Kc2a<@y&_uH1a*y-(kPioJL3&C6F`zxMIvtJmJT{_*8cZ+)=;&>U26dUhRn|Lr?B z1|qg-lN$l^j7TR)r2Ir<u%$T|54#dgUWm42V`DUsXbh*4@mM?<iTVR!kJVvJrNT`y zZ)-A~ZVbSi2M60hsW-NS%x;a^ECF{mva0WmD=%FC{M~mydhPVHhj$#D-m!1%&I8ly zHm_K;v}bPj=A$QffBW$ECpTYz_~Xs1AHQ<!sa?0e`r!Bf{vHJEPk(>-;KwgNy!Fm! zAYQ+{ap(RgpMUw`$2Twk^xM5(|NQpN%a=x$cCXvCj4!4Rk9I;c_YI{HTnUHDCIRiF zngXe~I}x?FG&;foeKh2BxeTB{;!VC#qsJe2ficxORCb5T<xqFFgg_3qCHza5bdOIg zj-|ZLpv4g|!`nO&YdGPFrG4!K&7DKZBTw(!cYMd5quXb8ZCJBuY}ei`)3a+|d*hh{ zho>O>ukK$v|NODnE?)$;egES(fBO5Q4?cbi2>0y|Ui#tpdk=p29O^TFX!H9Yzx?3Q z=P$ncv@c}w1Wa|r8js%sObD(3JaGkRkIwekP*0*e?O(I3b9QR!nicI1m&Rz8+T9v& z!~)Js=T?GdmfFNx4a;GbtQc+Iy?xEL&CB-e-Y~UoWu(bkQCkKhTy2(lB6f*}%ahae z4tb(8IDd5ej{REz!2H4KEwd8<VAaH;!$;@VZW!5rc;?87T>xy`u1$-U_Z~dC=i2QL zE<Ar`dT!IJZ(scO$2)hw`}EnDPHx|`?wt>x|M~a(&%JOO_MSjSqp=mSrckQ2skJ?Y z0ACDDvSo6`aBpMSrCc%)o0%LM8H(6F3X@%I^C@j1jm*MjX(((x4MMMDTFty=BdI;J zt7kTkZr`?i<(h7dk@e(DxEw@jO%YehK%xsOu!VdDy<@QH*oA$E&+GzTI≥%k22x zgHzk)*1q}9vlpH{_SA*Ly@M@*n4@Q?E#1?6@Z`R^gF7bHuK?3HvvYF(z|8JLGY3yV z^`@@geEsoHcQ0H#!QoS?P^C4Piga5t91XO#LklUXuutP_2isb_PK$7HUu=4EWbr^; zYvM@FES{A~x6$kMM7$D5(~@L1&J()S(g*ruJEoU!+c<h)Ztc#k%ac*FMA^U=5vc+q zij1lzqUsq0san|G*8+Qd^yK`r&!60Xc>BgJE9UoY9bDWtIkoE1k6(Uq_xeXSE^pYp z;?U9gBggj~J+c4vQ%76dqv5Dy`RbuB?tTR04`9q6+V=W;FTiL&_S8XzT9Tiii^J6h z!-4j`_8kZ25L$=4YdEoWX4OD%+@#^8o9*kz`-TQ$F27P{Vo}rts)@pJbNEgU&qU{H z8^l_w+Q3@8D6xCT_~tc(lj8%E6N5diK8IK74Cq2BFGyNf%;N|-L6vlLCm`=V2d2-Q zI|vt3+a~}(vNhN@)bj2JFaHMvkkaBMy`YYE@0*?9yM5KF;dSfAh8K5$H(0c!3yi_U zre$C|K^i{$^3xi<0svsKm~>l9YftNvHDidX`Z9rxk!}mOwghcvNq<jl9{O|rB4{3+ zOQLXzq+YSaCl<Q|avNW57iz5nlT|dfr0vk2Ntmir8%80<hFijMTOe*XxV1=J1tJTP zS)9cdQlS}O@1X*xpFXhf(6*T!>);GT8l8!B;N;moH$H#=lUwhunpk|`$PS>$1BZ8> zI(uk%uoe8|@}+%~lPeD#nw{RZcKzh?$*I*}J^t+Fw=c<6;=H^ZGMTu3<GOWQ)~%n} zfB=<da%eibnui9`@vx(}yJ_jNUVqT+i<$#XHebr&PT8%ECQDdn59_@#v)iw8`?SLY z$+@kocTSB%Y?@fyo(@nLwF;fU;xkkD^!&=A?9!YX9MWi&pE$F3ZujKDqdWE<oY^tI z3D%~Rud}!5=I!@>`QzS4H{M#gW_b7h>9re|PH*4v!prAR9owBw1eT5UE?v^&^O=lh z+1mAEhmOqM`1;y&ubgA^=uiO?i7>WoN%v59Gq4byN2_nZD^(J|-yZbYdwW~PmJP(3 zJ?XA^ti|tbboi6*rp`!9cRZH#flTV?YV7Szu3Xx`an;C{iKV+{)=#cq){+d6D7EOi zs#0_rB5y%<SssR5OXCo2E)AqUyKCdIQ@alxn*##fJiXfOH>5iv?_YcIx4+%H_Q@M# zD|(<T+vYYrbLr&mudZKy`}zLf<m|R}=g%KKacb|5otuuG+H>T@{I|c}edV3!p#lU# z9e5Rw&&`!^@w7Tbc46+q+)O00v<{D9(8(67KAH%6qb`tf!MHmRb9uvdP)DJtD;Rco zd}fcw)ExJ9BqPbNCl&FI^tTTWw1+|tu7HjuU`o-*JWyU_Jh&W<Nd~h9x*wY7<k@|& z_v<z-h2z`ZpV+;B>gPZ1{{CP0FMn`pX2-;(mrm{6vl)*2#TU=)oZmb<xACP{&b{>7 z`Ile6@bq)X&s{w6&Ewl(uMeHtOKiYbR+a+*fr!uGGw4DFBB!V*x3C~93-n(Bht2f* zUEmd=G~fYz5f?boK+tKiXh0)@QVNIN&GA5cD&C!L>P|H-?rEP`J~B4apGbs3y4N?< zRpL;E)#XTRHOLdOlG`(ogzRDC;RHj98#XWh&zXj)bnDJL?|pdb$jRBs>1EG8e;nHE zrPt2E+`WGD-OE>B1^zkr{K<>2KK=If*Peat>2H7k=9hmyK6(C#P{L&}Xe}+trbOfL z(%}^wRw8H|4v|7FDk>=}Db;G#sdO@uh=5%HZxCq?#Nz&7&>8YO;t_9S)E5c5nqvN- z$L4pKTB3o`zRtx1UC?`69!)A2Vd`p;m>LwRjxOS`r5vH0-I(-33qk5<&mV%LylLx7 z0JD1S;<w&?e&^nGH*UXm|Iw$<zHk%(>^ZO%B*VS$Ze6|c&dYB<clZ0-kN&v-%9R)1 zyZQFZS6+DV`#0bG_{F|syF^kRo6YR+?*$qKwb#;{Mws0`u|i!`UY?bo%@)#KJ_9Iz zgIQ#@%AIbl-Kn<N6p@%?U?>gIob;vA!9>arRM_4fPj|<HjSih%CQ`FFLRMK-Nlwwi zlFEXdq6K&|3Qw+f`i%!q&F($6?c60e#hZafr?#(My1f6;kzG^UR^R&K{o7w%J92tA z$cN`&KmYZkFCPE--OvB}?YqA{zW>|3kM3Uo{JR?$-@5SDwO1be^3@N2-aYp8K3BlD zV%5@QODYtD?F@Ad^dNFd%D@dFvNKC7ON4SR0C0MBR)<`p6FOX4AIO`ar8(*E8))h7 zO~ji#k(krwP%E{3v7E^gkQ>-|mZ(9d<A<9=0y)2?u9C_ngE$5Cwq|nKvWZ0}&hMF? zUw7jCzU{j=jjiZ|3AK3ii60nU+6hwP{By^id-=@0N4Ia?{rIo{_3MBC-@iZj^WoiJ z?tS~mcMt#i?x%k~zWwbD7-8V=9{>L3E0>>JJGpvjbkObh)zo4LRFYIJfAU8-L}n(s zu2!Ly!{`B?aryK{i`Z&c#TwnfIX!*Jp+)Uu%lcrrv~|RsUcJU3lBu9Wm{fKhhFC%6 z)<5}!ibKnnb7;H<Z`5)4^uFK!`NI!?Jh=bk7Y}~Dz5m4Q+=0y?gjTH|**rZC;|X+F z|6t3|Nc;N9WpBRs;*Y;S`0VRXKtf;p{KIQ^KECzsXHVk(jcZ?A{pQCzUp@XDjM44; z*Png)Y}Zh`Kn^yaupnn)J%#A-I}jNKxrNALiCU6?v)dYrG`fOO8+4A@sse-7lnAu6 zMmxI`z5VI-&L&W%R)<z=km{{UyVs~PNhy31SHS|Is<J3~3a&uS?HF!-=GCWwG+^g` z_}jMt;Lf8@zy0k?u=cArjP?wr$5!;i%sPE`Kd>ig<Couj_LI-Ap1N>+U`g-D>cvgn z$#827Y|ZK|tA|$(teIS~eC^`VRRc@M2UA@!Gzn8psI4JlaTG!YrUGmXVnM;eywW_L zlnX~Tn()UH-j?<-ba^Trf%s4MgToz*M|)uH?oB!UX5dG)QEGH*WJWPvL=ou(-X=F- zkeehNIWyhg{KDJMd~oZX*RMVg@%7KQu7CO7k#l=iO^!{@t^r-p(U%xmJ^<YaNMOX? zymS3;|MUBcZ(ec+9PX$G=3rK7E{1{~T0RVr;^|Ph$qVmq?`<|X)H&sOndOD$1Pq=| zs3l^cWe_MLnn0@uO9?yb3Rr?sd$Kju(G>^#3ntSaaKH-JE$MiwC6-J@LybPW-(vNe z?BJX2nkRqw(2H$g{JnaUUnjSSJ4e!2Z@>G^&$n+s{N(EGcfS1L)5m|icj2|uYo}Mv z9h#onxdD{(`Yo$LBh2re**rC|bKmyu^HUxD?F>FWlniqf0t^{TVmE}Ef~n4AqAlLq zog7;=3<f};;0krpY6gL8RG=w1rjP~$3IR!YB2H*r0ATm(-F_orXlV_1cBLR=NWHbK zsiQO5*52ISk?8J8NB;e91hJNIFcHwXbZj}BE@cRGLdf18F&n&^k%>V_{fkGR-ueC$ z$o|v&AN=~izrXU?TeF9zHt$@wab|pC^YSe_Hf)>SxNhSLkPqV<R@mGY5`&0uz(-nQ zdWTu2R|!-ixlZ1ginaBm`iDA)7Weo=P71q$B%~t>GAd|wHB_9+B#*>B2$NUe+#Zdl z0v4Cf>ej*;1=o{qi=<i_n-fu3J33oh+Y(L95qR0&k%El@!tpiwbq+m6K&z~;t|Zjp znFN_dOcoH(w5sl<?O*?L``TCUUBCP8*S~!B#rL25@Xv3r-Ff%G+1=B7Htjh+cl7MO z>0OgE+c%7i^_@I(c=y3MXyxpptXg8NBjh5nsF_8%MHNL-jdXa)pfBuk`>dTkEwDCl zDHtZ9oQkJw#Lk3Yq8E~=Xhb*}_caEfD|9xwT*p%z#o?G6KzH=E4~-7AcC~c$rF(}v zTRIzCyPI3P8{_SfVA2<B3&ZD&YVz|cvTKNyJSAIWSJqOhAqJOsKl<a|EAKzI|Mc8P zUta$Bo3}ps=JNit+s8HxY&)>!-5YNKx9mE)YxCUXz7zYu`QhHnmtPgC#fZGj1`gdD z3s>N(vPyE`fNIQ|crq4kj(~R=TQ*_~IvG+9UCyZ&P#6lX)~V-6n0X~x2&G9YGbs2< z9?&^UNCI+v@|}vu3~IY;urm&Q-`SMzNdmPeI%1uJDV<X-)(Jp10{|4M3W+Vj(`%I$ znbaUEt1T=+=Z9Oomp^_T0GxRCz@@j&e*Wmn!@s_G{_@$?Q={u=$6x>O<$FJW{q{$1 zUwY%>hHV>9KX>Nzb7zfi^TNWMDm>cgvNJ_oB9kK3DTDFw@RCKHeO>*7z~DoXbleg3 pSRyX9*C;kC^lm*k*y4)({|D4;?Wka2O~?QM002ovPDHLkV1nlV;mH61 diff --git a/packages/widgets/Source/Images/ImageryProviders/esriWorldStreetMap.png b/packages/widgets/Source/Images/ImageryProviders/esriWorldStreetMap.png deleted file mode 100644 index dfbc1f42d3add0290b2a1a85ff54aa58e305af31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8501 zcmV-5A<Eu~P)<h;3K|Lk000e1NJLTq002M$002M;0ssI2B@5<>00004XF*Lt006O% z3;baP00009a7bBm000ib000ib0l1NC?EnA(8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^4L^m3s903fkRL_t(&Lyda*lU&u6X8jfO!$fpUOtfQSCL9wp-R*Wa(?Q!9 zW4GO6F*ZmDFf`C0gR#LF3}!J%Ds4ytp&jidRaRx?zVBI;wP#jtFPFFPTdtM0?-DcT zzE>)h1a?ov7cXwUtjzkpd(S=RJNISRty}c^I=;GsEiL30W;1is6P?D$bS>4=k_|ag z6Jt6b)!2wihZH)fZiCK+bv{xTV}P0zs!P#^FxcRebs<(0BdQdwR=ff?xwbSTiK7_S zBXHvzt8)bD)3htI`nl%BzPkU!dU=rTKden&l}W!!_$AUS5^jKiyUc+^dSucE?|vN$ z6##UtuUCNm@?w5rZfb6Na;7=ft_?TUWK)heq<Bq;>0DH0LWndIP-y^SuQ4H=i`)?) z!XN_F>q5LCCSah8VNDDXpn=V-uIh@0Ei5$K4UQykv>Ruaq%*wdqoqm5{IE@M9n)|t zP?vGPN%|g0+XP6&oiWfr0#;YC<)!@MTz0-QHPf1$u8*ohf~f}BidSJ_j$<ktHc6|D zAK{w>7>L3;=u)JH1PnHWL_>^fLWHPzIDT?vZFc?U0#Qu~bpK54{A}SE=RCAtjcEg) z=|h(kY5;LH1i;*zFz%r1HwpmiCX=p}rTp@IW^p##Y2_4UgdjsSHQKDPnpCV}0f~+& zF#TxmjVRhKfWJ$C4v-?c1Tx~Fp(esLrps_YR4sd}^!VIDbEYlg<$#P|6GMAD<JVWF zoRaNG9kVLHlJJPQN36QUiW4Bfwd#^^fVmD3NM2xX0t9T)=vtb`mggaOCTJo~)1%WJ za&@&fH=`~tsG5QirGU(s!DB?x?GV!0aP4jZK-a{bmk>yNyun8mK2)x_iBe>~!!0hU zGM*sZN7tyZ>OQGN&uJvE^nd^XN7V0u1d@zEG6k5^za;=@bS=(R7iKb=6lbW^%1Uc? zM&#%bEaxNe!PTV}jzxLOt1v;04(OoRkb$QEYXa^;O^70}(K-`Wxq!-g#ImE5bE;Bt zy`!(PldGiw*Z*lPXM+e4Aabe>uIk`Rb`wI`aYq1-;%fVD-ijY2U}3I2H<M<mV5d#B zTT(F}V~DWKM~X#Hr!CdBYNg<iS-;MPYD`F@Zco3l0RX`A9_l9GzRrhr)?XvhKhx=u zP6as9OH5dm5#KElYsD{#ffIVwE8qbRg1&46-W+B#v0Ve~1anK60?g!dN5K5-)ZEO3 zz{cB6s@-PrN?4cUx)@>UAcYUFE;TBp5KsFwE>dTsunzYK__N@`DjS47qrq~ML79w* zR9I%ba^ke^Kf8_(vHjh(smp4`C6#>)1U+UGiks}WG;9}OtiWB<zbRm@GcnU1*5s5d zW|vo#O2w~=z#yy$kqYK+)`?D=#tKfANBLCeLJ&Uy5MYLo2^gb0pvnX!E+(kZAqhys zghBXHUY_ylWgBbVzmm4jrmpkOLu&PgT(-+a7gKWZMH^ojV2cALdl=kV1atZ+uT0&= z-i+j~*=BmCnQG`sqMF!PZ_#8*L>VTm3lWxbm9XI2N*gZ^v6Nrq!`khX`i%nM>r8p@ z2WX+ug!wqiFB4vcaLS~$HhPJ-eRhio3${a2>XL{9#R0JhbnSGppDpyUMXRadZUII) zgRS^A_Qnd-GSjt0vlgpX!VB}drr=C9R72q#Qh0Y6vp4GOOj|AH><R~UAPCz)LjpE8 z@g|@uvzydSAOVQCgQHM_S1R6GsgHLY?u<JY3Lb8tTgRMy#m$the8I}*2gss@E?AiS z09&vDxT1Y5dcHa}P?;JSiC?BG-oj)bQ}QTOury(<PPup@G(OnF;i0aX+HgltwAB%Y z3e{@mg}GX_7|<YEV6u6S$a}Fucx`E#C&tK<U8OxbiPDkI1`O&6or~$Lk!Nq02t=I< znDHuAy>b;o*(H_&+W1w`(!D_>_`qo~a;8>xuoW9!vT}JVm+hyr{bbHc<p!8M2(YsS z_pAT**o89(y7#{GoxlB`@#w%ayZ&`7IRIgK;=o&f`onJrtf&6^um36(vUW{tgVSof zsf<W`lwn5JR@-C+yhF6XLePg5K8h8+qL^M<6mnBuk&0+^M4_Ox1!V?|##mb$Qz20z z>UVgX1Cj7?B;-e{h}pHQUGRTikDR?(4ocS#H75Gyf`i6vWMP1rvN9Pfm9^seKD=;) zD)cf~KT~v_IriSm&+mNx=_ekz|Gv+T?tS`+huKO}r2<js*<FwQ_`P@b+;`u1j~qGF z)lw2|1<L-QD#k12$l7XCV8?heTw^1Ud8mpnp9@HGY2)Ucsu5V;CjvPprVA5IrSfU_ zyF<~d5)+Z>AZ%8Xy^-voUV<(2as;IIKCx(5C$F-W{VQdECwf719+R^DG}d3m`l`7b z#MBLZ>P9)=OXMuf)D1RwgDt|lZom7&{r~)ryLRt7daV1058VIG?_Sr$w9JIDv~$Og zzxTw?9=`hJsh>Xh!>*<hYl?9&VY(C}Dxr3Zo^DaqlAk8rm6A^pbE`|ujkVe7w!E_3 z)|7m;<P_+r&wlOFxl@nt_+iL%MHNOw3KC8LvIJ~3*l+;k3viE6aqwtI+R4P{vgh-g zWSqBjOG9V4d>@hPt>&)dnI1BI4NqUKWP9*z9|RJehv~O6m@7MK|6l*(TQ5BKbST*O zt^fL07tWqg#ZiTeaCq>^pFMQnKm1(*8~*mU|9e+W0vDNV7#^6VA|gMvw5V4rgQApK zTB@(F%+^($s6>ld4_zHzTW*nfa&+X{L*M_-Pk(q{Jk&E3bFtJ^O&kRQBFsGqK*q)` zgNLcO#iB#bJLGgfYwcbbw=Jf9!i7Kao?~3(G#5Q5#?K3pvmzjRMo63!lNY7IOY-nV zZSsnq>s7M03kTmA^Iu`JuCoW<qjRwa?Q4>b7Ugwb+3&i3szr}nJ@zpO2-k(7CQ5}N ziHlatiM6$vwbhx`)rESEB`Qgx<P+JDDn!b8d#lE@8r;ZekH>j>e8fRjBX7R`{PVka z;l-Fh_(6bCGMzGxEPzmQahOvCvyeQmT0gx>r<SKYi?K_(>$qY&EL*yjKEMGOpt0qE z+}ADk?HBs@(Uy-1%g1>Ce%yALa2%to2dKU;n1L^7>t5FS3EQ`y?*Ejs!JWfY-;pj| z4%dXC21<)Tkqebek@fZYR*T0ggLv5|fr$`8x)4*iD98BArP%Uvvsw*jCI<fa`(ITG z35g&5@ZC3#9(;?#{XB#X0RkK#0P?qhIR!NRy|ne?&d}9`v}bPU+U(@D)q;Jk=w2)N zSIhpDN^qqTS}BKCvCwMCw_0*8m)r|E=UmP;mvsZ?v#y0H`+UYXpYbeY2Np80jGl#z zXFltkpRzAx?Oo7$=zOxq#Xx|>`9Q$N`XXLQF@#4GAXoa03Kdg@xX6d{1y7^NHd{n0 z)%W5rcTNt+2cvyEessUB_o#@rFEk}CfpCDY<jW2YgKXH(CeI4}pR5*K+V$ho<-Nr9 zeVk=K)4P|p?5F!+Y7YYFzJsjgFk?AH^&MvVKGodk>fQ@A|HYaQu3y#zXY2lRwE*B$ zJ$Sb6gFEN-z?quwT*H5+3l&`+Ji;L4b%F5;3^abT6g~+19qvFyLj{YA%4`%bxv`=j z1gvgM6V%AHOP{{{%g3L6;wKkQf5cQ^<9am$34lcqs!krWLzWcMJ=8#VCwX}uiq4IF zZ0Z6rag7@~&kdeq6KBN4IR&C?@Jnszf<AmnAH7@~zgi!?q9(pn!Dh$KBgD_^iF5VD zxkl2!;CVnjd9I#3TT7g+$IpU*h%N+?20lht0!^J<oY#md7zddCu*OHgK?t<Jm~#ni zc6mYXOjE5E-I*5P4mM>e<@$IUQhpG;8e~`=Y(3#pFoz5Uwb(C2&Io-6VER?dA;EW| zI&m3GUm_=Zs#Dj=TrZuoaQS||XcbB}v22$Jr$o49!le=J8sVvv-a6&0(_n;w9>h5~ zU&uFbg_#X$;L5m&%0@r{PzUo91g=y$*ib9;b7C3uYC;g8@L{s-!E)YagIHZ@i(H|Y zb(XR4@<NlRM@cBLOrR#GTT-qer*(Cdqk}@#r4(&)zF&mN?maL&bbWT{D%;!5r7l;} zmrI$;_+&4cwL-<^iVmslkt(omKAA9Uh+hHwO+m2_>0lWdRE`isNRkE&wo#yNASTlw zfCD?QsX?HF3=v;l)+*Q_PX{G7R4zDaa%gE@Sz6KwGF2}4VWy!~Z`H}A*#?OvP96W? z!#})rVDI~f_P;wgXc3vHQgZX<0ikG7f~QpLk(IoUhj5RbBFB2jiOW?;{Fy!`XX7y^ zP*(_Gyy-C&sD?}k8gUh@IDn6sfQfIQLj%Z`;DUp?0T|T4t5aSO5U+uy5g?EP3Lh*N zZS5A>(Ai?nUCjGsKD)lwY}D~W-bdm-s3Qs;WhpPq46Q75@IvCt(;x2r;H}FSPxkkm z86UQD)v$s&!J={59^P_rZltFfy+jTiDyJ_{<2}s8H9XscyaQ(Et8S5kEEkZtpbX$c zDi;E~Zp1Bu4xu8T$f-lm#7B*-7&f6H;~3N_AHWPDSQ_|bROOQ}@zqKcawW@7wp-l# z+B8e2i+Q)e1~dVMox(z`aP!>Q%A!tIf~9=l2Y-0wt+!sga^XZxE{H?~`f&m4<Kt(< zflnc0iZ}Mt@pD-A3N_I~Pl8|Q<#JZYQ8MX4M+7KzLjWL9<G=-nAjE5s7)78Su8WZd z3i`Ol$Dttsz(9e>VZpp?8ha1`p9!hF51VvcJaurO_h@!%pr%(gHWn8a^&%E6Lp4AO zBX!tGTv(*Ng{%j<enref$K$dcdwj?DU)%G-V~_k;<uc&*7}{0OTKK+0vtzxD#FxCa zn;XA^XTb2l^joN$jlrx!#idYwXxY$AqeK_3Lm@&ZWvCC)rKl#NmbwApqp$+74qGb& z3#Bjt8N4IohXE3x3BGvf!b9Kx$KU^U&z=`|Ls*v!k(JdBL5-Ko5LdA}8>=%h4a}(! z057D7g@rk-kn@j^4g@^c4*co;Up%(s#b54{nGuQhOQfq7Jk@lZSjjmc*{iWLY~~t~ zwcxp4GS^4v?R42L;$Db&NE^D@`x`K_HaaD!0eca6#}IfV10^5OX2h6=+&frz6M-&` z2}`W^!}s=_IeEO*AV&s0zyI}frL4PFtIjV-SP}Z#XoHE=nJBcH4C5;n1Ivp#O^lR_ zp5MOy?EU}eZ^uTWiHM^(5fQnhPI(*HfOuoy@`POroaJ1{)N~J#y<RQ!QMrBwk`MHa zWrsxgVD+K-ymJU38N3Y{CQMbE?{2#f^QeNgVK#e@E|rR?T+rTk^6fYGc-`j<*}!1r znn(xBh0xNXTGuO8%%?&FDMS?^T*$i`4RX3kfw$wRsHNxlZ(e)hsa=o0_R2F1o>G*- zX(m#OomSmPm!a+IJ)n+VW%Iq&qNP%R;OS$t{T%d)h5%^a%=z9X;4Y#7Q^WQ<TL2km z184|fgDpLG_0rMPC*CdPgOejR7WdN?A4?9et=3t3lqQ3U2)%)y#7CEx>eW(&#{CiB zxm}O{<iNfUB4I}~Xi<cuF2(06ezEtX#jLF!JgIn2N_i`ZSt~^gUg)E<eO#`O!>oJ- zb}*DDNQ-xlWK02Q@Mjp`1L)3g3xK^0A;l&;jS^i=y!P_$7oU6bvm@_7N-pPZ&3XwK z=Zhhn^b@7n!mO&ug;LR3Dcb+==F`@m^T!VD{o}j8(d8*kiZx-cBi=`sA#2_Eq%nF! zDA=ijmCS?Dw=h`?n+E{{eANj{f3E-ocV2GW7!Yab4B^gs$DPg_2~c1wz;>p?GMx;2 zFTL~To~g;<U%dn&5fE8_DeqlbZi+I7RiaA^@^pj2avqKe7W1w@zP;zAUp^J_+a)$z z6H*Yt(*@xD(Q?tF1-{U{C-l6HFW5O~bF(o0$T%?2zn5%6)olu>L54BtqGNC=RtJ1d z0|?k;Zybog2REypF#v#ofNC6`DRe}jhTePo)#sksdGf^J%NO^R^KKmT3*6-DdS`jH z4Hl@94+>P+a=rV-7al)<?xfdk`S|@;6?Pb?wCJ$zKV1u*TAXx{{rl?aegOlsU}N%D z2p%feOBMPU*Z@#~tLT8_KNJAiS^<;236uBj_SN5|P*BoB8pwj$CJeV5m5H&)>#x7O zW5@ST9Q}a9V_4qZnUPjjma^FhG?Pr(|NL`1e)qfA-gx89Sk$FSBQ-=NGz|&<`o5Kt zziIna2%Qm1PPRBe7j0D0O5`m>!9qf-j@d-arBr?Q2tZu#4xud=0ye|lWWRMljX?Nd z1>g<iZ6<*HoiNgK@zb6wXH%)jBRd|91g-_WXGT+whAwd&=CYkW_1OpSy!)$%e)NOq zo_S_$INDUxO~zZNol@ZQM&RON+AduGNKFrLn42&5vqdXi0Q94)abhJ_Trv~^Dgd1B zO`~#r3+8HUuE4hG-<o&?uz)xSKnWEI(7+@?o#T_!b<BF>%SRsm$?22(|LGt8=Czl1 zUcPYH>*;kmt#7>k>h7ISbRYQ0F>oR5xu8fX2^=C7YG!(w-UDluux2|ZMotK27Y*%L z!3s$e)&YgS!JaSKq18kOb+-io#cvdFS4INkX{-Qz%EWdVn*!i3APk@fPz7kdhNs4S zcx56Sv^@LN&tk#;(UF0tc0Cr4MSt=0C(=_B|Nio`WGT^-Qi>1~`9Pfts?N`564#dt zZnk%yoVQR_J5>e&1Ezp2_5xIZKO>;NjlF(%N;P+|slmi{4M>2(fJ-xd2r{IakZ9={ zO&tH#OHW=rbG%*0L?QXmgZE*@{MoaoPn<l$2@{$)Sm%=}lwLa0&fDdl?sYuY37zM{ zpNmx|Q?*g(Km{Gy0(BGSX|s&GO##4TO8{(Q5KvbV-zWgs!(ZODk8ckEs188r8=e$4 zKo9}BaHzX6ycj5^L$FOHF?68&jWcIHZ8hYXPK^`Nm9m#-A_^C86M<Ufd_8z(jY<gD z_bd4xx#X7116<k8lw2%^j{KqYqDMx?(+cS?3fR)HeM7_Fm`XNH#BIQu0J@B0T6jCI z3Z?+mNg_R9r<7<*pV0V0T@I=6U22*oN7@Z)b+z4Wa5OVsE_u1B8<hR<Qo-3t-C!L@ zY88i4ajRvUT(+|nFI#bPuoPA2=0m&9$EM$~iMOu+V0%h6MZ(nx6C?vI%WZU_wq1xp z*ubo-0(v%TxbQ?>fNu%ZK?Zz_1lAnBA}(>EeBL1mnfZ>gvOK-I(VT6U+gRu(JuLPg z(8ez5Wz-W3ghPg|pz7z1r$Z)t^Tf_L=0|Dt9sys=Lh-G)wy?Dh+ckilHe^AsfFAC` z#KV^&E87s^D~vH>50VBOQWTa#mZKcyB@6CSA;L1*8I8PIXP44pwtsJ}WYd5&?cyl( z)KSL$65)jb0_jDEE+)1M*vdlaA?F<pNC0};d2eyp;%xw!hr6JGFxTk+6VPoK{}tSI zOt1K8>%oPBe>QYpjGa=5fPzjJJ<#S#keX13ekb2;!Q22K0C@!H6^#&wZ$=snpw%$2 z`O^5m=AYdy0P;TU0kej0VpDoU1|;r4N^HI*q7;ET3|K1|RK23@;CeNz_8n|aT$9P5 zik<>_psq_$TY%{8%)K3E_AmvY^kT62%aiyu>gGovG@@PT(e&2B8F>KEP?HU1a69U9 zvW8?NwhL(DNWexVB=>fM02TGAU`f0hI$sFG)#Un(*j$0z0t`Z%t8ovu{@@;%+PXFw zD<)&Onz)O-3D8iN6R=_pl=zVBO##)gWa(~AZVJ#CpN>vPB5(zkfP1KK!LUR3(%OQ# zSy8&Yd)ICOr5O;=Q12!B7XcdLO)=J#V<5Xl_$9j`ps%}~zOJ!RjfJi0udz@`Vs&GJ zH>Y`98QKD9+X^9oad2XEDyU;Lnnv`f6Pov+(ZWN$x}yYE2I3hBXexvM0o1{kfu@oK zG!#=n9Kx&(o7E5?_I0;1*L8G43|}3nqnc=pA<w`z{WAgpKzB>PcGtNDv~3Lb+n2&% zZ*GrhS4$b(LR%X$F%4H0FbIIL2^hCPfC?@s(K7Z)n+$BN00=;j22oWB0Amn<{?lJv z0R)5DCjLyYp^gO>_V&bYV{Zt6z^E(9nv&GjWL-}*^ms!{w6tU!U@*STJ_)4jDr}gc zrj%+yYJ$ZfgYv+Uo7IS7+25Y(MdwpoxXu{`5ly_Awo$f*``h@1731eq2n?ECcnLQ( zqb<>BKfuUfkjIRVu;BB9M!_}ehOo&V84xMfRnA9B`6yP17K)J~7R0bXsTe93B3Qwf z%{a4ZXLiz=%eZoA>_|@yWYW&5v^$rv<}$XzNN?GGe3eM3u!%F4x)4Nh&n7_t$f$7% zR3A~5L^6zr<d8#A8btz-i3Ij$Rt2sRl?o%?v=1QDewhkNkj+@*^iBvvg*ECdlm#eo z(7{1MPiRuS>(<8nt@S0q%?-f9*2|5J#hbU5Zr)r(xV3l-@D*U*7%XpmHMardwa!;7 z`d1n$T8_8U*V<gT!Np|}#Z1FERW_-cn_-&(06LSpy&woii3p;{gp6NeLRii<HQ~%m zx-*lm%%pv4(l(X0BfvOqj5C0NOvct#DEJHcpowB3P%J>h9xmpi)l!0`Mmc7jM;HTe z^f*tC3sjn?rWhteF&UPc5GDi5)l_GsU+^EDr6VmdDM|hY7ljo-(}qqwjmP?E8$di5 z&%+s?MnkO#pojiYuqnge19jsWAtW4;i7hP%|M%AXt(z;iZmxcHYx%2NOJChw1l&Sc zxCL+Bn)?c2zN@CCYU*Gepd}#sYig3EA_JBqRLLW=VTBFLu+|)0LoySQ&@*kQP-x7v z5g6$4i?Z+dO)|{&?rj&{;0smJS3|qm*a;wmjT*=I=!bU-<5O6V!nie5>;f7I2r8t} zoq$0ieH!6YDIfetmW(mv5KRqJ^e{z@QRFy9!gZ9UU@&Tep++fUwCnWe@8>35b!h~$ zP*a9PIeO~&2jBj0|HWlLL*fw<57A_}f_chCU(c0pycDddLk%s~)RN#VX2kd`?&EFH zOa?lEbIRc5rVwuM0d$6pLLbbzUll_#7ZK?gS@M^2?sDEkU>+VCa}tbGz<fRc(=Smz zmGEnXU#CDDSXwtncsR<#Qci|;vy_LUeH`OwX)jzk+Rww4@(E0!>&54GfAG$0O*zw2 zh9Kt%RATp&55N7p-@g9qf45jJzW(|P@4x@%*>gvJ^3w-?^P5+H^~%$Nn5yZCx|VFo z@o6v@YEllLYA3ENrQNjsNQdz@Vcqzs3>KXa@tnI_v6qV;h8%9_<ie~zGp(soIhS!T zcu;~ZOTxs1MFkD$*DVU+(?AIgh6+k}+<f=~n^@s}(5omyP-Oi)tQ8Nv6l^dE(LmSV zf9G!=efUQ;WvZbLfjjWJPJQqG@BaK}k396?_u^6S>#x4}i^qSesnidDaR0NrcXogB zZmU*ksi~$s1O=|C4Aqt44(1XDj@`r)to2Z<&?}NKJyD(;V(=J=ryBLj!kjQSBQ4G; zttLG)%P%ZQje5CS3b6$EYL5#24f;hCECOr;C|iC6^wY4g&O%NLq2IwE8Bv}N;+Rin zM`bpJ7d&H$>vevpE8w>jvhl@PvM!I+q`}OXMHVJ!+e9|)rO8ya9LFoknQ44t)Ex=+ z@^oshnQf{g4X6eh0M+SfDOt0BwwSiJM;%1?B2C3w9dT)OesyK0(-CPZQ7Jlzyi>vh z660k_cOmbYn-`~N_(H)e5S}_7tl<&#h@VD3DnoS_vMSna$W4GFY)}!M4hgicP;gF9 zb90?qB_A6Z?0NjrpZ4{9*`>;pb!DQV0(-CtP^Sjl`eaj^Y-r={db+7kH1)~43fFWC z{jw<2RL4vK$V4I2nrun&_UJ{`dt!sjthd##Ru(!Pjitx%qQ6@3F;&R=;1R+)aDuGQ z1{vI2E{0c@I*l4rg8q(lD3n*E!!ndD0)on~QGT5c)R=%yqX8@kPdkeRyQ-F#mYdmJ z@V$3m{Mn=b5(s*B@BBp<MTBZH@Qyc>7{HiRAUD+1Qw<F$4mLE{wL>j^q@fKrHK0Dy zREL{tYEu9Jd=ceh`}c1!kwrX3B|LOKoJwBtdrrzgi-_^nh|0!zJb3l&pQxf&VM0XF zOI0)LtMiJKFXS9V#l_K3w!#V#QqksyxbmP>OQGK&k%WC}%Bjlu>Po9p8Ghr<=lAY? z|Bvs!bLilQ5?kmZD?tq$GO(AUU=~_PKoXJ+xQQm%9&OOP)7DdMeaP^3DFd(vHWvZe zQgKl7d@((Gak}97;_Vl+G0U%C+2!}$;K{*XzqIR_Cm->7E_qxR9=QLzdtP|z%DE3k z+FLHz1%7N}qccBW7kR9VMGI4|?BoEJvsW=2S#^>XCsA=1vbItsIMb2Vmgi`EEHggv z;d^^_KK|&lJ9ie-gAHLE`hg-xMPU2FL>h_6BnQq1j1as;CJ(IWw3Y&U2LcRJy$zs2 zPIS1zcDi459bacg-hXlTOS>Nbmj}K_R13Y=Pu=(3|NY9#FYNDr|H++?`UCF$`#yQ| zw=bPM{(CInixvB;c(T<N)>db3t<SBkw3e3i>1jq$ixfRZlA|n}nVEri+w-$Rr4Yi4 z9-j2ExckJB-#z$Gf1e$P=47~QV|}(-22+tl9!>$51_c3WK;umewN&tPskWAafe|)$ z34rixOYsixWBNW>EqS9Cj(qDs|EFK>-uc+icUT85{OeDC0Fm0g?~kF-Kx!!Pg9pC< z#v5-v`_xnKzV&Ye7U=ESKR(`@%Q<i?#?x6<!Kd5O@^TBx?aiA|iRb2KRhAelPPyr_ zPk?g4cxA>V5H5HB@!soS)YS2=n;R>Vh=~HE_872f$-@Y+N0rnTT0kA30|p_wAoJWK zpr%Bp#h^ZPP7R%@=Od3k_|Ftsym<ETzK`E1X2ONZ$XuP8trcNUzxU3b{rkEfeq@K; z`sHA-_t=5A%LOm0Q-qf+J1a$NF>B4GZP^L?)VMV_*$*$-swX>YJ$~Trr=R%I#8AIP jMWISagqNqi3LX7_oJkR9e-^w+00000NkvXXu0mjfQDIA= From 7a337e280066b1e4a680e3d3493ad87986230183 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Wed, 19 Apr 2023 10:53:13 -0400 Subject: [PATCH 633/679] Reduce URI parsing (#11202) * Add serverKey property to Request constructor options * Avoid repeated calls to Resource.prototype.url * Clean up url parsing in Resource.js * Fix bugs in Resource.prototype.parseUrl * Avoid re-parsing url in RequestScheduler.getServerKey * Avoid re-parsing url in Resource.prototype.clone * Move Resource constructor to top of file * Avoid re-parsing url in Resource.prototype.getUrlComponent * Restore placeholders in Resource.prototype.getUrlComponent * Add specs for Request, incorporate PR feedback * Fix Request.prototype.clone spec * Clean up defaultClone helper in Resource * Update CHANGES.md --------- Co-authored-by: Jeshurun Hembd <jeshurun@cesium.com> Co-authored-by: Gabby Getz <gabby@cesium.com> --- CHANGES.md | 1 + packages/engine/Source/Core/Request.js | 5 +- .../engine/Source/Core/RequestScheduler.js | 2 +- packages/engine/Source/Core/Resource.js | 462 +++++++++--------- packages/engine/Specs/Core/RequestSpec.js | 105 ++++ packages/engine/Specs/Core/ResourceSpec.js | 14 + .../TileMapServiceImageryProviderSpec.js | 2 +- 7 files changed, 353 insertions(+), 238 deletions(-) create mode 100644 packages/engine/Specs/Core/RequestSpec.js diff --git a/CHANGES.md b/CHANGES.md index ad1c6640aac..cecdbf60742 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ ##### Fixes :wrench: +- Fixed Repeated URI parsing slows 3D Tiles performance [#11197](https://github.com/CesiumGS/cesium/issues/11197). Together with [#11211](https://github.com/CesiumGS/cesium/pull/11211), this can reduce tile parsing time by as much as 25% on large tilesets - Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) - Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) diff --git a/packages/engine/Source/Core/Request.js b/packages/engine/Source/Core/Request.js index 9988f54c6cc..0274ab3e4d5 100644 --- a/packages/engine/Source/Core/Request.js +++ b/packages/engine/Source/Core/Request.js @@ -18,6 +18,7 @@ import RequestType from "./RequestType.js"; * @param {boolean} [options.throttle=false] Whether to throttle and prioritize the request. If false, the request will be sent immediately. If true, the request will be throttled and sent based on priority. * @param {boolean} [options.throttleByServer=false] Whether to throttle the request by server. * @param {RequestType} [options.type=RequestType.OTHER] The type of request. + * @param {string} [options.serverKey] A key used to identify the server that a request is going to. */ function Request(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -105,7 +106,7 @@ function Request(options) { * * @private */ - this.serverKey = undefined; + this.serverKey = options.serverKey; /** * The current state of the request. @@ -166,7 +167,7 @@ Request.prototype.clone = function (result) { result.serverKey = this.serverKey; // These get defaulted because the cloned request hasn't been issued - result.state = this.RequestState.UNISSUED; + result.state = RequestState.UNISSUED; result.deferred = undefined; result.cancelled = false; diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index 43542ad80cc..66ad7d211bd 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -352,7 +352,7 @@ RequestScheduler.getServerKey = function (url) { let uri = new Uri(url); if (uri.scheme() === "") { - uri = new Uri(url).absoluteTo(pageUri); + uri = uri.absoluteTo(pageUri); uri.normalize(); } diff --git a/packages/engine/Source/Core/Resource.js b/packages/engine/Source/Core/Resource.js index 4037f852bc7..cf4c0dfce01 100644 --- a/packages/engine/Source/Core/Resource.js +++ b/packages/engine/Source/Core/Resource.js @@ -36,184 +36,6 @@ const xhrBlobSupported = (function () { } })(); -/** - * Parses a query string and returns the object equivalent. - * - * @param {Uri} uri The Uri with a query object. - * @param {Resource} resource The Resource that will be assigned queryParameters. - * @param {boolean} merge If true, we'll merge with the resource's existing queryParameters. Otherwise they will be replaced. - * @param {boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in uri will take precedence. - * - * @private - */ -function parseQuery(uri, resource, merge, preserveQueryParameters) { - const queryString = uri.query(); - if (queryString.length === 0) { - return {}; - } - - let query; - // Special case we run into where the querystring is just a string, not key/value pairs - if (queryString.indexOf("=") === -1) { - const result = {}; - result[queryString] = undefined; - query = result; - } else { - query = queryToObject(queryString); - } - - if (merge) { - resource._queryParameters = combineQueryParameters( - query, - resource._queryParameters, - preserveQueryParameters - ); - } else { - resource._queryParameters = query; - } - uri.search(""); -} - -/** - * Converts a query object into a string. - * - * @param {Uri} uri The Uri object that will have the query object set. - * @param {Resource} resource The resource that has queryParameters - * - * @private - */ -function stringifyQuery(uri, resource) { - const queryObject = resource._queryParameters; - - const keys = Object.keys(queryObject); - - // We have 1 key with an undefined value, so this is just a string, not key/value pairs - if (keys.length === 1 && !defined(queryObject[keys[0]])) { - uri.search(keys[0]); - } else { - uri.search(objectToQuery(queryObject)); - } -} - -/** - * Clones a value if it is defined, otherwise returns the default value - * - * @param {*} [val] The value to clone. - * @param {*} [defaultVal] The default value. - * - * @returns {*} A clone of val or the defaultVal. - * - * @private - */ -function defaultClone(val, defaultVal) { - if (!defined(val)) { - return defaultVal; - } - - return defined(val.clone) ? val.clone() : clone(val); -} - -/** - * Checks to make sure the Resource isn't already being requested. - * - * @param {Request} request The request to check. - * - * @private - */ -function checkAndResetRequest(request) { - if ( - request.state === RequestState.ISSUED || - request.state === RequestState.ACTIVE - ) { - throw new RuntimeError("The Resource is already being fetched."); - } - - request.state = RequestState.UNISSUED; - request.deferred = undefined; -} - -/** - * This combines a map of query parameters. - * - * @param {object} q1 The first map of query parameters. Values in this map will take precedence if preserveQueryParameters is false. - * @param {object} q2 The second map of query parameters. - * @param {boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in q1 will take precedence. - * - * @returns {object} The combined map of query parameters. - * - * @example - * const q1 = { - * a: 1, - * b: 2 - * }; - * const q2 = { - * a: 3, - * c: 4 - * }; - * const q3 = { - * b: [5, 6], - * d: 7 - * } - * - * // Returns - * // { - * // a: [1, 3], - * // b: 2, - * // c: 4 - * // }; - * combineQueryParameters(q1, q2, true); - * - * // Returns - * // { - * // a: 1, - * // b: 2, - * // c: 4 - * // }; - * combineQueryParameters(q1, q2, false); - * - * // Returns - * // { - * // a: 1, - * // b: [2, 5, 6], - * // d: 7 - * // }; - * combineQueryParameters(q1, q3, true); - * - * // Returns - * // { - * // a: 1, - * // b: 2, - * // d: 7 - * // }; - * combineQueryParameters(q1, q3, false); - * - * @private - */ -function combineQueryParameters(q1, q2, preserveQueryParameters) { - if (!preserveQueryParameters) { - return combine(q1, q2); - } - - const result = clone(q1, true); - for (const param in q2) { - if (q2.hasOwnProperty(param)) { - let value = result[param]; - const q2Value = q2[param]; - if (defined(value)) { - if (!Array.isArray(value)) { - value = result[param] = [value]; - } - - result[param] = value.concat(q2Value); - } else { - result[param] = Array.isArray(q2Value) ? q2Value.slice() : q2Value; - } - } - } - - return result; -} - /** * @typedef {object} Resource.ConstructorOptions * @@ -227,6 +49,7 @@ function combineQueryParameters(q1, q2, preserveQueryParameters) { * @property {Resource.RetryCallback} [retryCallback] The Function to call when a request for this resource fails. If it returns true, the request will be retried. * @property {number} [retryAttempts=0] The number of times the retryCallback should be called before giving up. * @property {Request} [request] A Request object that will be used. Intended for internal use only. + * @property {boolean} [parseUrl=true] If true, parse the url for query parameters; otherwise store the url without change */ /** @@ -319,13 +142,26 @@ function Resource(options) { this.retryAttempts = defaultValue(options.retryAttempts, 0); this._retryCount = 0; - const uri = new Uri(options.url); - parseQuery(uri, this, true, true); - - // Remove the fragment as it's not sent with a request - uri.fragment(""); + const parseUrl = defaultValue(options.parseUrl, true); + if (parseUrl) { + this.parseUrl(options.url, true, true); + } else { + this._url = options.url; + } +} - this._url = uri.toString(); +/** + * Clones a value if it is defined, otherwise returns the default value + * + * @param {object} [value] The value to clone. + * @param {object} [defaultValue] The default value. + * + * @returns {object} A clone of value or the defaultValue. + * + * @private + */ +function defaultClone(value, defaultValue) { + return defined(value) ? clone(value) : defaultValue; } /** @@ -471,14 +307,7 @@ Object.defineProperties(Resource.prototype, { return this.getUrlComponent(true, true); }, set: function (value) { - const uri = new Uri(value); - - parseQuery(uri, this, false); - - // Remove the fragment as it's not sent with a request - uri.fragment(""); - - this._url = uri.toString(); + this.parseUrl(value, false, false); }, }, @@ -555,6 +384,138 @@ Resource.prototype.toString = function () { return this.getUrlComponent(true, true); }; +/** + * Parse a url string, and store its info + * + * @param {string} url The input url string. + * @param {boolean} merge If true, we'll merge with the resource's existing queryParameters. Otherwise they will be replaced. + * @param {boolean} preserveQuery If true duplicate parameters will be concatenated into an array. If false, keys in url will take precedence. + * @param {string} [baseUrl] If supplied, and input url is a relative url, it will be made absolute relative to baseUrl + * + * @private + */ +Resource.prototype.parseUrl = function (url, merge, preserveQuery, baseUrl) { + let uri = new Uri(url); + const query = parseQueryString(uri.query()); + + this._queryParameters = merge + ? combineQueryParameters(query, this.queryParameters, preserveQuery) + : query; + + // Remove unneeded info from the Uri + uri.search(""); + uri.fragment(""); + + if (defined(baseUrl) && uri.scheme() === "") { + uri = uri.absoluteTo(getAbsoluteUri(baseUrl)); + } + + this._url = uri.toString(); +}; + +/** + * Parses a query string and returns the object equivalent. + * + * @param {string} queryString The query string + * @returns {object} + * + * @private + */ +function parseQueryString(queryString) { + if (queryString.length === 0) { + return {}; + } + + // Special case where the querystring is just a string, not key/value pairs + if (queryString.indexOf("=") === -1) { + return { [queryString]: undefined }; + } + + return queryToObject(queryString); +} + +/** + * This combines a map of query parameters. + * + * @param {object} q1 The first map of query parameters. Values in this map will take precedence if preserveQueryParameters is false. + * @param {object} q2 The second map of query parameters. + * @param {boolean} preserveQueryParameters If true duplicate parameters will be concatenated into an array. If false, keys in q1 will take precedence. + * + * @returns {object} The combined map of query parameters. + * + * @example + * const q1 = { + * a: 1, + * b: 2 + * }; + * const q2 = { + * a: 3, + * c: 4 + * }; + * const q3 = { + * b: [5, 6], + * d: 7 + * } + * + * // Returns + * // { + * // a: [1, 3], + * // b: 2, + * // c: 4 + * // }; + * combineQueryParameters(q1, q2, true); + * + * // Returns + * // { + * // a: 1, + * // b: 2, + * // c: 4 + * // }; + * combineQueryParameters(q1, q2, false); + * + * // Returns + * // { + * // a: 1, + * // b: [2, 5, 6], + * // d: 7 + * // }; + * combineQueryParameters(q1, q3, true); + * + * // Returns + * // { + * // a: 1, + * // b: 2, + * // d: 7 + * // }; + * combineQueryParameters(q1, q3, false); + * + * @private + */ +function combineQueryParameters(q1, q2, preserveQueryParameters) { + if (!preserveQueryParameters) { + return combine(q1, q2); + } + + const result = clone(q1, true); + for (const param in q2) { + if (q2.hasOwnProperty(param)) { + let value = result[param]; + const q2Value = q2[param]; + if (defined(value)) { + if (!Array.isArray(value)) { + value = result[param] = [value]; + } + + result[param] = value.concat(q2Value); + } else { + result[param] = Array.isArray(q2Value) ? q2Value.slice() : q2Value; + } + } + } + + return result; +} + /** * Returns the url, optional with the query string and processed by a proxy. * @@ -568,32 +529,56 @@ Resource.prototype.getUrlComponent = function (query, proxy) { return this._url; } - const uri = new Uri(this._url); - + let url = this._url; if (query) { - stringifyQuery(uri, this); + url = `${url}${stringifyQuery(this.queryParameters)}`; } - // objectToQuery escapes the placeholders. Undo that. - let url = uri.toString().replace(/%7B/g, "{").replace(/%7D/g, "}"); + // Restore the placeholders, which may have been escaped in objectToQuery or elsewhere + url = url.replace(/%7B/g, "{").replace(/%7D/g, "}"); const templateValues = this._templateValues; - url = url.replace(/{(.*?)}/g, function (match, key) { - const replacement = templateValues[key]; - if (defined(replacement)) { - // use the replacement value from templateValues if there is one... - return encodeURIComponent(replacement); - } - // otherwise leave it unchanged - return match; - }); + if (Object.keys(templateValues).length > 0) { + url = url.replace(/{(.*?)}/g, function (match, key) { + const replacement = templateValues[key]; + if (defined(replacement)) { + // use the replacement value from templateValues if there is one... + return encodeURIComponent(replacement); + } + // otherwise leave it unchanged + return match; + }); + } if (proxy && defined(this.proxy)) { url = this.proxy.getURL(url); } + return url; }; +/** + * Converts a query object into a string. + * + * @param {object} queryObject The object with query parameters + * @returns {string} + * + * @private + */ +function stringifyQuery(queryObject) { + const keys = Object.keys(queryObject); + + if (keys.length === 0) { + return ""; + } + if (keys.length === 1 && !defined(queryObject[keys[0]])) { + // We have 1 key with an undefined value, so this is just a string, not key/value pairs + return `?${keys[0]}`; + } + + return `?${objectToQuery(queryObject)}`; +} + /** * Combines the specified object and the existing query parameters. This allows you to add many parameters at once, * as opposed to adding them one at a time to the queryParameters property. If a value is already set, it will be replaced with the new value. @@ -667,30 +652,14 @@ Resource.prototype.getDerivedResource = function (options) { resource._retryCount = 0; if (defined(options.url)) { - const uri = new Uri(options.url); - - const preserveQueryParameters = defaultValue( - options.preserveQueryParameters, - false - ); - parseQuery(uri, resource, true, preserveQueryParameters); - - // Remove the fragment as it's not sent with a request - uri.fragment(""); - - if (uri.scheme() !== "") { - resource._url = uri.toString(); - } else { - resource._url = uri - .absoluteTo(new Uri(getAbsoluteUri(this._url))) - .toString(); - } + const preserveQuery = defaultValue(options.preserveQueryParameters, false); + resource.parseUrl(options.url, true, preserveQuery, this._url); } if (defined(options.queryParameters)) { resource._queryParameters = combine( options.queryParameters, - resource._queryParameters + resource.queryParameters ); } if (defined(options.templateValues)) { @@ -753,8 +722,16 @@ Resource.prototype.retryOnError = function (error) { */ Resource.prototype.clone = function (result) { if (!defined(result)) { - result = new Resource({ + return new Resource({ url: this._url, + queryParameters: this.queryParameters, + templateValues: this.templateValues, + headers: this.headers, + proxy: this.proxy, + retryCallback: this.retryCallback, + retryAttempts: this.retryAttempts, + request: this.request.clone(), + parseUrl: false, }); } @@ -1301,7 +1278,8 @@ function fetchJsonp(resource, callbackParameterName, functionName) { resource.setQueryParameters(callbackQuery); const request = resource.request; - request.url = resource.url; + const url = resource.url; + request.url = url; request.requestFunction = function () { const deferred = defer(); @@ -1316,11 +1294,7 @@ function fetchJsonp(resource, callbackParameterName, functionName) { } }; - Resource._Implementations.loadAndExecuteScript( - resource.url, - functionName, - deferred - ); + Resource._Implementations.loadAndExecuteScript(url, functionName, deferred); return deferred.promise; }; @@ -1376,7 +1350,8 @@ Resource.prototype._makeRequest = function (options) { checkAndResetRequest(resource.request); const request = resource.request; - request.url = resource.url; + const url = resource.url; + request.url = url; request.requestFunction = function () { const responseType = options.responseType; @@ -1386,7 +1361,7 @@ Resource.prototype._makeRequest = function (options) { const data = options.data; const deferred = defer(); const xhr = Resource._Implementations.loadWithXhr( - resource.url, + url, responseType, method, data, @@ -1433,6 +1408,25 @@ Resource.prototype._makeRequest = function (options) { }); }; +/** + * Checks to make sure the Resource isn't already being requested. + * + * @param {Request} request The request to check. + * + * @private + */ +function checkAndResetRequest(request) { + if ( + request.state === RequestState.ISSUED || + request.state === RequestState.ACTIVE + ) { + throw new RuntimeError("The Resource is already being fetched."); + } + + request.state = RequestState.UNISSUED; + request.deferred = undefined; +} + const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; function decodeDataUriText(isBase64, data) { diff --git a/packages/engine/Specs/Core/RequestSpec.js b/packages/engine/Specs/Core/RequestSpec.js new file mode 100644 index 00000000000..8ff12753244 --- /dev/null +++ b/packages/engine/Specs/Core/RequestSpec.js @@ -0,0 +1,105 @@ +import { Request, RequestState, RequestType } from "../../index.js"; + +describe("Core/Request", function () { + it("sets correct properties in constructor", function () { + const options = Object.freeze({ + url: "https://www.example.com", + requestFunction: Promise.resolve(), + cancelFunction: () => undefined, + priorityFunction: () => 1, + priority: 1, + throttle: true, + throttleByServer: true, + type: RequestType.IMAGERY, + serverKey: "customKey", + }); + + const request = new Request(options); + + expect(request.url).toBe(options.url); + expect(request.requestFunction).toBe(options.requestFunction); + expect(request.cancelFunction).toBe(options.cancelFunction); + expect(request.priorityFunction).toBe(options.priorityFunction); + expect(request.priority).toBe(options.priority); + expect(request.throttle).toBe(options.throttle); + expect(request.throttleByServer).toBe(options.throttleByServer); + expect(request.type).toBe(options.type); + expect(request.serverKey).toBe(options.serverKey); + + expect(request.state).toBe(RequestState.UNISSUED); + }); + + it("cancels", function () { + const request = new Request(); + expect(request.cancelled).toBe(false); + request.cancel(); + expect(request.cancelled).toBe(true); + }); + + it("cloning without options creates a request with the same properties", function () { + const initialOptions = Object.freeze({ + url: "https://www.example.com", + requestFunction: Promise.resolve(), + cancelFunction: () => undefined, + priorityFunction: () => 1, + priority: 1, + throttle: true, + throttleByServer: true, + type: RequestType.IMAGERY, + serverKey: "customKey", + }); + + const request = new Request(initialOptions); + const clone = request.clone(); + + expect(clone.url).toBe(initialOptions.url); + expect(clone.requestFunction).toBe(initialOptions.requestFunction); + expect(clone.cancelFunction).toBe(initialOptions.cancelFunction); + expect(clone.priorityFunction).toBe(initialOptions.priorityFunction); + expect(clone.priority).toBe(initialOptions.priority); + expect(clone.throttle).toBe(initialOptions.throttle); + expect(clone.throttleByServer).toBe(initialOptions.throttleByServer); + expect(clone.type).toBe(initialOptions.type); + expect(clone.serverKey).toBe(initialOptions.serverKey); + }); + + it("cloning with a result parameter updates the properties of the result", function () { + const options1 = Object.freeze({ + url: "https://www.example.com", + requestFunction: Promise.resolve(), + cancelFunction: () => undefined, + priorityFunction: () => 1, + priority: 1, + throttle: true, + throttleByServer: true, + type: RequestType.IMAGERY, + serverKey: "customKey", + }); + + const options2 = Object.freeze({ + url: "http://example.com", + requestFunction: fetch, + cancelFunction: () => "cancelled", + priorityFunction: () => 2, + priority: 2, + throttle: false, + throttleByServer: false, + type: RequestType.TERRAIN, + serverKey: "updatedKey", + }); + + const request1 = new Request(options1); + const request2 = new Request(options2); + const clone = request2.clone(request1); + + expect(clone.url).toBe(options2.url); + expect(clone.requestFunction).toBe(options2.requestFunction); + expect(clone.cancelFunction).toBe(options2.cancelFunction); + expect(clone.priorityFunction).toBe(options2.priorityFunction); + expect(clone.priority).toBe(options2.priority); + expect(clone.throttle).toBe(options2.throttle); + expect(clone.throttleByServer).toBe(options2.throttleByServer); + expect(clone.type).toBe(options2.type); + expect(clone.serverKey).toBe(options2.serverKey); + }); +}); diff --git a/packages/engine/Specs/Core/ResourceSpec.js b/packages/engine/Specs/Core/ResourceSpec.js index 93d5da2daf3..8ce027c2b09 100644 --- a/packages/engine/Specs/Core/ResourceSpec.js +++ b/packages/engine/Specs/Core/ResourceSpec.js @@ -139,6 +139,20 @@ describe("Core/Resource", function () { }); }); + it("Constructing with parseUrl false does not strip query parameters from url", function () { + const resource = new Resource({ + url: "http://test.com/tileset?foo=bar&baz=foo", + parseUrl: false, + }); + expect(resource.getUrlComponent()).toEqual( + "http://test.com/tileset?foo=bar&baz=foo" + ); + expect(resource.getUrlComponent(true)).toEqual( + "http://test.com/tileset?foo=bar&baz=foo" + ); + expect(resource.queryParameters).toEqual({}); + }); + it("createIfNeeded returns undefined, if parameter is undefined", function () { expect(Resource.createIfNeeded()).toBeUndefined(); }); diff --git a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js index 4b4f3d98e7b..db45f53f009 100644 --- a/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js +++ b/packages/engine/Specs/Scene/TileMapServiceImageryProviderSpec.js @@ -373,7 +373,7 @@ describe("Scene/TileMapServiceImageryProvider", function () { "made/up/tms/server/" ); - // check some details about the tilemapresourcel.xml so we know we got parsed/configured properly + // check some details about the tilemapresource.xml so we know we got parsed/configured properly let url = getAbsoluteUri("made/up/tms/server/{z}/{x}/{reverseY}.jpg"); // Uri.absoluteTo() escapes the placeholders. Undo that. url = url.replace(/%7B/g, "{").replace(/%7D/g, "}"); From 0426baa38915c36c54b47a77b8c93bfde606b426 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 19 Apr 2023 15:46:22 -0400 Subject: [PATCH 634/679] CreditDisplay.addCreditToNextFrame and CreditDisplay.addStaticCredit --- CHANGES.md | 10 + packages/engine/Source/Core/Credit.js | 2 +- .../engine/Source/Core/IonGeocoderService.js | 2 +- .../Source/DataSources/DataSourceDisplay.js | 4 +- .../engine/Source/Scene/Cesium3DTileset.js | 2 +- packages/engine/Source/Scene/CreditDisplay.js | 102 ++++++++- .../Source/Scene/GlobeSurfaceTileProvider.js | 8 +- packages/engine/Source/Scene/Model/Model.js | 6 +- packages/engine/Source/Widget/CesiumWidget.js | 12 ++ .../engine/Specs/Scene/CreditDisplaySpec.js | 202 ++++++++++++++---- .../engine/Specs/Widget/CesiumWidgetSpec.js | 2 + packages/widgets/Source/Viewer/Viewer.js | 12 ++ packages/widgets/Specs/Viewer/ViewerSpec.js | 2 + 13 files changed, 300 insertions(+), 66 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cecdbf60742..f67075e2e9c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,8 @@ ##### Additions :tada: - Added `ArcGisMapServerImagery.fromBasemapType`, and `ArcGisBaseMapType`, and `ArcGisMapService` for ease of use with the latest ArcGIS Imagery API.[#11098](https://github.com/CesiumGS/cesium/pull/11098) +- Added `CesiumWidget.creditDisplay` to access the onscreen and lightbox credits. +- Added `CreditDisplay.addStaticCredit` and `CreditDisplay.removeStaticCredit` such that `Credit.showOnScreen` value is taken into account. [#6215](https://github.com/CesiumGS/cesium/issues/6215) ##### Fixes :wrench: @@ -17,8 +19,16 @@ - Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) - Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) +##### Deprecated :hourglass_flowing_sand: + +- `CreditDisplay.addCredit`, `CreditDisplay.addDefaultCredit`, and `CreditDisplay.removeDefaultCredit` have been deprecated in CesiumJS 1.105. They will be removed in 1.107. Use `CreditDisplay.addCreditToNextFrame`, `CreditDisplay.addStaticCredit`, and `CreditDisplay.removeStaticCredit` respectively instead. + #### @cesium/widgets +##### Additions :tada: + +- Added `Viewer.creditDisplay` to access the onscreen and lightbox credits. + ##### Fixes :wrench: - Fixed missing `ContextOptions` in generated TypeScript definitions. [10963](https://github.com/CesiumGS/cesium/issues/10963) diff --git a/packages/engine/Source/Core/Credit.js b/packages/engine/Source/Core/Credit.js index 807a79ff1c0..2dbe1cbb3ad 100644 --- a/packages/engine/Source/Core/Credit.js +++ b/packages/engine/Source/Core/Credit.js @@ -17,7 +17,7 @@ const creditToId = {}; * @exception {DeveloperError} html is required. * * @example - * //Create a credit with a tooltip, image and link + * // Create a credit with a tooltip, image and link * const credit = new Cesium.Credit('<a href="https://cesium.com/" target="_blank"><img src="/images/cesium_logo.png" title="Cesium"/></a>'); */ function Credit(html, showOnScreen) { diff --git a/packages/engine/Source/Core/IonGeocoderService.js b/packages/engine/Source/Core/IonGeocoderService.js index 8d73ff089cf..674c3ca47c9 100644 --- a/packages/engine/Source/Core/IonGeocoderService.js +++ b/packages/engine/Source/Core/IonGeocoderService.js @@ -33,7 +33,7 @@ function IonGeocoderService(options) { const defaultTokenCredit = Ion.getDefaultTokenCredit(accessToken); if (defined(defaultTokenCredit)) { - options.scene.frameState.creditDisplay.addDefaultCredit( + options.scene.frameState.creditDisplay.addStaticCredit( Credit.clone(defaultTokenCredit) ); } diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index 691855fff52..e71989ea47b 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -313,7 +313,7 @@ DataSourceDisplay.prototype._postRender = function () { const credit = dataSource.credit; if (defined(credit)) { - frameState.creditDisplay.addCredit(credit); + frameState.creditDisplay.addCreditToNextFrame(credit); } // Credits from the resource that the user can't remove @@ -321,7 +321,7 @@ DataSourceDisplay.prototype._postRender = function () { if (defined(credits)) { const creditCount = credits.length; for (let c = 0; c < creditCount; c++) { - frameState.creditDisplay.addCredit(credits[c]); + frameState.creditDisplay.addCreditToNextFrame(credits[c]); } } } diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index 0f9aad6abf2..ac848668623 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -3212,7 +3212,7 @@ function update(tileset, frameState, passStatistics, passOptions) { for (let i = 0; i < credits.length; ++i) { const credit = credits[i]; credit.showOnScreen = tileset._showCreditsOnScreen; - frameState.creditDisplay.addCredit(credit); + frameState.creditDisplay.addCreditToNextFrame(credit); } } } diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 6752fda1fca..c8df048177f 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -4,6 +4,7 @@ import Check from "../Core/Check.js"; import Credit from "../Core/Credit.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import deprecationWarning from "../Core/deprecationWarning.js"; import destroyObject from "../Core/destroyObject.js"; import Uri from "urijs"; @@ -303,7 +304,14 @@ function appendCss(container) { * @constructor * * @example - * const creditDisplay = new Cesium.CreditDisplay(creditContainer); + * // Add a credit with a tooltip, image and link to display onscreen + * const credit = new Cesium.Credit(`<a href="https://cesium.com/" target="_blank"><img src="/images/cesium_logo.png" title="Cesium"/></a>`, true); + * viewer.creditDisplay.addStaticCredit(credit); + * + * @example + * // Add a credit with a plaintext link to display in the lightbox + * const credit = new Cesium.Credit('<a href="https://cesium.com/" target="_blank">Cesium</a>'); + * viewer.creditDisplay.addStaticCredit(credit); */ function CreditDisplay(container, delimiter, viewport) { //>>includeStart('debug', pragmas.debug); @@ -418,17 +426,36 @@ function setCredit(creditDisplay, credits, credit, count) { } /** * Adds a credit to the list of current credits to be displayed in the credit container + * for the next frame * * @param {Credit} credit The credit to display + * @deprecated */ CreditDisplay.prototype.addCredit = function (credit) { + deprecationWarning( + "CreditDisplay.addCredit", + "CreditDisplay.addCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addCreditToNextFrame instead." + ); + + this.addCreditToNextFrame(credit); +}; + +/** + * Adds a {@link Credit} that will show on screen or in the lightbox until + * the next frame. This is mostly for internal use. Use {@link CreditDisplay.addStaticCredit} to add a persistent credit to the screen. + * + * @see CreditDisplay.addStaticCredit + * + * @param {Credit} credit The credit to display in the next frame. + */ +CreditDisplay.prototype.addCreditToNextFrame = function (credit) { //>>includeStart('debug', pragmas.debug); Check.defined("credit", credit); //>>includeEnd('debug'); if (credit._isIon) { // If this is the an ion logo credit from the ion server - // Juse use the default credit (which is identical) to avoid blinking + // Just use the default credit (which is identical) to avoid blinking if (!defined(this._defaultCredit)) { this._defaultCredit = Credit.clone(getDefaultCredit()); } @@ -450,24 +477,58 @@ CreditDisplay.prototype.addCredit = function (credit) { * Adds credits that will persist until they are removed * * @param {Credit} credit The credit to added to defaults + * + * @deprecated */ CreditDisplay.prototype.addDefaultCredit = function (credit) { //>>includeStart('debug', pragmas.debug); Check.defined("credit", credit); //>>includeEnd('debug'); + deprecationWarning( + "CreditDisplay.addDefaultCredit", + "CreditDisplay.addDefaultCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." + ); + const defaultCredits = this._defaultCredits; if (!contains(defaultCredits, credit)) { + credit.showOnScreen = true; defaultCredits.push(credit); } }; /** - * Removes a default credit + * Adds a {@link Credit} that will show on screen or in the lightbox until removed with {@link CreditDisplay.removeStaticCredit}. * - * @param {Credit} credit The credit to be removed from defaults + * @param {Credit} credit The credit to added + * + * @example + * // Add a credit with a tooltip, image and link to display onscreen + * const credit = new Cesium.Credit(`<a href="https://cesium.com/" target="_blank"><img src="/images/cesium_logo.png" title="Cesium"/></a>`, true); + * viewer.creditDisplay.addStaticCredit(credit); + * + * @example + * // Add a credit with a plaintext link to display in the lightbox + * const credit = new Cesium.Credit('<a href="https://cesium.com/" target="_blank">Cesium</a>'); + * viewer.creditDisplay.addStaticCredit(credit); */ -CreditDisplay.prototype.removeDefaultCredit = function (credit) { +CreditDisplay.prototype.addStaticCredit = function (credit) { + //>>includeStart('debug', pragmas.debug); + Check.defined("credit", credit); + //>>includeEnd('debug'); + + const defaultCredits = this._defaultCredits; + if (!contains(defaultCredits, credit)) { + defaultCredits.push(credit); + } +}; + +/** + * Removes a static credit shown on screen or in the lightbox. + * + * @param {Credit} credit The credit to be removed. + */ +CreditDisplay.prototype.removeStaticCredit = function (credit) { //>>includeStart('debug', pragmas.debug); Check.defined("credit", credit); //>>includeEnd('debug'); @@ -479,11 +540,31 @@ CreditDisplay.prototype.removeDefaultCredit = function (credit) { } }; +/** + * Removes a default credit. + * + * @param {Credit} credit The credit to be removed from defaults + */ +CreditDisplay.prototype.removeDefaultCredit = function (credit) { + deprecationWarning( + "CreditDisplay.removeDefaultCredit", + "CreditDisplay.removeDefaultCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." + ); + + this.removeStaticCredit(credit); +}; + +/** + * @private + */ CreditDisplay.prototype.showLightbox = function () { this._lightbox.style.display = "block"; this._expanded = true; }; +/** + * @private + */ CreditDisplay.prototype.hideLightbox = function () { this._lightbox.style.display = "none"; this._expanded = false; @@ -506,15 +587,20 @@ CreditDisplay.prototype.beginFrame = function () { this._creditDisplayElementPoolIndex = 0; const screenCredits = currentFrameCredits.screenCredits; + const lightboxCredits = currentFrameCredits.lightboxCredits; + screenCredits.removeAll(); + lightboxCredits.removeAll(); + const defaultCredits = this._defaultCredits; for (let i = 0; i < defaultCredits.length; ++i) { const defaultCredit = defaultCredits[i]; - setCredit(this, screenCredits, defaultCredit, Number.MAX_VALUE); + const creditCollection = defaultCredit.showOnScreen + ? screenCredits + : lightboxCredits; + setCredit(this, creditCollection, defaultCredit, Number.MAX_VALUE); } - currentFrameCredits.lightboxCredits.removeAll(); - if (!Credit.equals(CreditDisplay.cesiumCredit, this._cesiumCredit)) { this._cesiumCredit = Credit.clone(CreditDisplay.cesiumCredit); } diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index 3b068cd95a2..ab54cb9002a 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -352,7 +352,7 @@ function updateCredits(surface, frameState) { surface._terrainProvider._ready && defined(surface._terrainProvider.credit) ) { - creditDisplay.addCredit(surface._terrainProvider.credit); + creditDisplay.addCreditToNextFrame(surface._terrainProvider.credit); } const imageryLayers = surface._imageryLayers; @@ -364,7 +364,7 @@ function updateCredits(surface, frameState) { layer.imageryProvider._ready && defined(layer.imageryProvider.credit) ) { - creditDisplay.addCredit(layer.imageryProvider.credit); + creditDisplay.addCreditToNextFrame(layer.imageryProvider.credit); } } } @@ -2098,7 +2098,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { tileCreditIndex < tileCreditLength; ++tileCreditIndex ) { - creditDisplay.addCredit(tileCredits[tileCreditIndex]); + creditDisplay.addCreditToNextFrame(tileCredits[tileCreditIndex]); } } @@ -2719,7 +2719,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { creditIndex < creditLength; ++creditIndex ) { - creditDisplay.addCredit(credits[creditIndex]); + creditDisplay.addCreditToNextFrame(credits[creditIndex]); } } diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index 4b53df8e374..9a493d94bb3 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -2509,19 +2509,19 @@ function addCreditsToCreditDisplay(model, frameState) { // Add all credits to the credit display. const credit = model._credit; if (defined(credit)) { - creditDisplay.addCredit(credit); + creditDisplay.addCreditToNextFrame(credit); } const resourceCredits = model._resourceCredits; const resourceCreditsLength = resourceCredits.length; for (let c = 0; c < resourceCreditsLength; c++) { - creditDisplay.addCredit(resourceCredits[c]); + creditDisplay.addCreditToNextFrame(resourceCredits[c]); } const gltfCredits = model._gltfCredits; const gltfCreditsLength = gltfCredits.length; for (let c = 0; c < gltfCreditsLength; c++) { - creditDisplay.addCredit(gltfCredits[c]); + creditDisplay.addCreditToNextFrame(gltfCredits[c]); } } diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 779117804ba..994857c2674 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -520,6 +520,18 @@ Object.defineProperties(CesiumWidget.prototype, { }, }, + /** + * Manages the list of credits to display on screen and in the lightbox. + * @memberof CesiumWidget.prototype + * + * @type {CreditDisplay} + */ + creditDisplay: { + get: function () { + return this._scene.frameState.creditDisplay; + }, + }, + /** * Gets the camera. * @memberof CesiumWidget.prototype diff --git a/packages/engine/Specs/Scene/CreditDisplaySpec.js b/packages/engine/Specs/Scene/CreditDisplaySpec.js index 45621f576e2..e628770c9a6 100644 --- a/packages/engine/Specs/Scene/CreditDisplaySpec.js +++ b/packages/engine/Specs/Scene/CreditDisplaySpec.js @@ -87,27 +87,48 @@ describe("Scene/CreditDisplay", function () { creditDisplay.beginFrame(); } - it("credit display addCredit throws when credit is undefined", function () { + it("addCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); creditDisplay.addCredit(); }).toThrowDeveloperError(); }); - it("credit display addDefaultCredit throws when credit is undefined", function () { + it("addCreditToNextFrame throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.addCreditToNextFrame(); + }).toThrowDeveloperError(); + }); + + it("addDefaultCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); creditDisplay.addDefaultCredit(); }).toThrowDeveloperError(); }); - it("credit display removeDefaultCredit throws when credit is undefined", function () { + it("addStaticCredit throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.addStaticCredit(); + }).toThrowDeveloperError(); + }); + + it("removeDefaultCredit throws when credit is undefined", function () { expect(function () { creditDisplay = new CreditDisplay(container); creditDisplay.removeDefaultCredit(); }).toThrowDeveloperError(); }); + it("removeStaticCredit throws when credit is undefined", function () { + expect(function () { + creditDisplay = new CreditDisplay(container); + creditDisplay.removeStaticCredit(); + }).toThrowDeveloperError(); + }); + it("credit display displays a credit", function () { creditDisplay = new CreditDisplay(container); const credit = new Credit( @@ -115,7 +136,7 @@ describe("Scene/CreditDisplay", function () { true ); beginFrame(creditDisplay); - creditDisplay.addCredit(credit); + creditDisplay.addCreditToNextFrame(credit); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; @@ -132,7 +153,7 @@ describe("Scene/CreditDisplay", function () { // add only credit1 during the frame beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); + creditDisplay.addCreditToNextFrame(credit1); creditDisplay.endFrame(); const innerHTMLWithCredit1 = container.innerHTML; const creditContainer = container.childNodes[1]; @@ -141,7 +162,7 @@ describe("Scene/CreditDisplay", function () { // add only credit2 during the frame beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); const innerHTMLWithCredit2 = container.innerHTML; expect(innerHTMLWithCredit2).not.toEqual(innerHTMLWithCredit1); @@ -150,8 +171,8 @@ describe("Scene/CreditDisplay", function () { // add both credit1 and credit2 during the frame beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); const innerHTMLWithCredit1AndCredit2 = container.innerHTML; expect(innerHTMLWithCredit1AndCredit2).not.toEqual(innerHTMLWithCredit1); @@ -175,8 +196,8 @@ describe("Scene/CreditDisplay", function () { const delimiter = ", "; creditDisplay = new CreditDisplay(container, ", "); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; @@ -193,9 +214,9 @@ describe("Scene/CreditDisplay", function () { const delimiter = ", "; creditDisplay = new CreditDisplay(container, delimiter); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.addCreditToNextFrame(credit3); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; expect(creditContainer.childNodes.length).toEqual(5); @@ -206,8 +227,8 @@ describe("Scene/CreditDisplay", function () { expect(creditContainer.childNodes[4]).toEqual(credit3.element); beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.addCreditToNextFrame(credit3); creditDisplay.endFrame(); expect(creditContainer.childNodes.length).toEqual(3); expect(creditContainer.childNodes[0]).toEqual(credit2.element); @@ -221,8 +242,8 @@ describe("Scene/CreditDisplay", function () { expect(creditContainer.childNodes[0]).toEqual(credit2.element); beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); - creditDisplay.addCredit(credit3); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.addCreditToNextFrame(credit3); creditDisplay.endFrame(); expect(creditContainer.childNodes.length).toEqual(3); expect(creditContainer.childNodes[0]).toEqual(credit2.element); @@ -237,7 +258,7 @@ describe("Scene/CreditDisplay", function () { creditDisplay = new CreditDisplay(container, ", "); creditDisplay.addDefaultCredit(defaultCredit); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); + creditDisplay.addCreditToNextFrame(credit1); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; @@ -252,14 +273,36 @@ describe("Scene/CreditDisplay", function () { expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); }); - it("credit display displays credits when default is removed", function () { + it("credit display displays a static credit", function () { const defaultCredit = new Credit("default credit", true); const credit1 = new Credit("credit1", true); creditDisplay = new CreditDisplay(container, ", "); - creditDisplay.addDefaultCredit(defaultCredit); + creditDisplay.addStaticCredit(defaultCredit); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.endFrame(); + + const creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(", "); + expect(creditContainer.childNodes[2]).toEqual(credit1.element); + + beginFrame(creditDisplay); + creditDisplay.endFrame(); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + }); + + it("credit display displays credits when a static credit is removed", function () { + const defaultCredit = new Credit("default credit", true); + const credit1 = new Credit("credit1", true); + + creditDisplay = new CreditDisplay(container, ", "); + creditDisplay.addStaticCredit(defaultCredit); + beginFrame(creditDisplay); + creditDisplay.addCreditToNextFrame(credit1); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; expect(creditContainer.childNodes.length).toEqual(3); @@ -269,7 +312,7 @@ describe("Scene/CreditDisplay", function () { creditDisplay.removeDefaultCredit(defaultCredit); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); + creditDisplay.addCreditToNextFrame(credit1); creditDisplay.endFrame(); expect(creditContainer.childNodes.length).toEqual(1); expect(creditContainer.childNodes[0]).toEqual(credit1.element); @@ -280,8 +323,8 @@ describe("Scene/CreditDisplay", function () { const credit2 = new Credit("credit1", true); creditDisplay = new CreditDisplay(container); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); const creditContainer = container.childNodes[1]; expect(creditContainer.childNodes.length).toEqual(1); @@ -294,9 +337,9 @@ describe("Scene/CreditDisplay", function () { beginFrame(creditDisplay); for (let i = 0; i < repeatedCreditCount; i++) { - creditDisplay.addCredit(new Credit("credit1", true)); + creditDisplay.addCreditToNextFrame(new Credit("credit1", true)); } - creditDisplay.addCredit(new Credit("credit2", true)); + creditDisplay.addCreditToNextFrame(new Credit("credit2", true)); const credits = creditDisplay._currentFrameCredits.screenCredits.values; expect(credits.length).toEqual(2); @@ -324,7 +367,7 @@ describe("Scene/CreditDisplay", function () { const creditString = "credit".concat((i + 1).toString()); const count = creditCounts[i]; for (let j = 0; j < count; j++) { - creditDisplay.addCredit(new Credit(creditString, true)); + creditDisplay.addCreditToNextFrame(new Credit(creditString, true)); } } creditDisplay.endFrame(); @@ -337,7 +380,7 @@ describe("Scene/CreditDisplay", function () { expect(creditContainer.childNodes[6]).toEqual(credit4.element); }); - it("credit display sorts credits by frequency with default credit", function () { + it("credit display sorts credits by frequency with static credit", function () { const defaultCredit = new Credit("default credit", true); const creditCounts = [2, 10, 6, 1]; const credit1 = new Credit("credit1", true); @@ -346,14 +389,14 @@ describe("Scene/CreditDisplay", function () { const credit4 = new Credit("credit4", true); creditDisplay = new CreditDisplay(container); - creditDisplay.addDefaultCredit(defaultCredit); + creditDisplay.addStaticCredit(defaultCredit); beginFrame(creditDisplay); for (let i = 0; i < creditCounts.length; i++) { const creditString = "credit".concat((i + 1).toString()); const count = creditCounts[i]; for (let j = 0; j < count; j++) { - creditDisplay.addCredit(new Credit(creditString, true)); + creditDisplay.addCreditToNextFrame(new Credit(creditString, true)); } } creditDisplay.endFrame(); @@ -377,7 +420,7 @@ describe("Scene/CreditDisplay", function () { creditDisplay.showLightbox(); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); + creditDisplay.addCreditToNextFrame(credit1); creditDisplay.endFrame(); creditDisplay.update(); @@ -386,7 +429,7 @@ describe("Scene/CreditDisplay", function () { expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); beginFrame(creditDisplay); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); creditDisplay.update(); @@ -396,8 +439,8 @@ describe("Scene/CreditDisplay", function () { expect(creditList.childNodes[0].childNodes[0]).toEqual(credit2.element); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); creditDisplay.update(); @@ -415,16 +458,84 @@ describe("Scene/CreditDisplay", function () { creditDisplay.hideLightbox(); }); + it("displays static credits in a lightbox", function () { + const credit1 = new Credit("credit1"); + const credit2 = new Credit(`<img src="${imageUrl}"/>`); + + creditDisplay = new CreditDisplay(container); + const creditList = creditDisplay._creditList; + creditDisplay.addStaticCredit(credit1); + + creditDisplay.showLightbox(); + + beginFrame(creditDisplay); + creditDisplay.endFrame(); + creditDisplay.update(); + + let innerHTML = creditList.innerHTML; + expect(creditList.childNodes.length).toEqual(1); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); + + beginFrame(creditDisplay); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); + + expect(creditList.innerHTML).not.toEqual(innerHTML); + innerHTML = creditList.innerHTML; + expect(creditList.childNodes.length).toEqual(2); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); + expect(creditList.childNodes[1].childNodes[0]).toEqual(credit2.element); + + beginFrame(creditDisplay); + creditDisplay.endFrame(); + expect(creditList.childNodes.length).toEqual(1); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); + + creditDisplay.hideLightbox(); + }); + + it("credit display displays credits when a static credit is removed from the lightbox", function () { + const credit1 = new Credit("credit1"); + const credit2 = new Credit(`<img src="${imageUrl}"/>`); + + creditDisplay = new CreditDisplay(container, ", "); + const creditList = creditDisplay._creditList; + + creditDisplay.showLightbox(); + + creditDisplay.addStaticCredit(credit1); + beginFrame(creditDisplay); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); + + expect(creditList.childNodes.length).toEqual(2); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit1.element); + expect(creditList.childNodes[1].childNodes[0]).toEqual(credit2.element); + + creditDisplay.removeStaticCredit(credit1); + beginFrame(creditDisplay); + creditDisplay.addCreditToNextFrame(credit2); + creditDisplay.endFrame(); + creditDisplay.update(); + + expect(creditList.childNodes.length).toEqual(1); + expect(creditList.childNodes[0].childNodes[0]).toEqual(credit2.element); + }); + it("handles showOnScreen toggles at runtime", function () { // Credits are constructed to show on screen const credit1 = new Credit("credit1", true); const credit2 = new Credit("credit2", true); creditDisplay = new CreditDisplay(container); + creditDisplay.addStaticCredit(credit1); + beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); + creditDisplay.update(); const screenCreditContainer = container.childNodes[1]; expect(screenCreditContainer.childNodes.length).toEqual(3); @@ -436,9 +547,9 @@ describe("Scene/CreditDisplay", function () { credit2.showOnScreen = false; creditDisplay.showLightbox(); + beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); const lightboxCreditList = creditDisplay._creditList; @@ -456,8 +567,7 @@ describe("Scene/CreditDisplay", function () { creditDisplay.hideLightbox(); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); expect(screenCreditContainer.childNodes.length).toEqual(3); @@ -473,8 +583,8 @@ describe("Scene/CreditDisplay", function () { const creditList = creditDisplay._creditList; beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); creditDisplay.update(); @@ -483,8 +593,8 @@ describe("Scene/CreditDisplay", function () { creditDisplay.showLightbox(); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); creditDisplay.update(); @@ -505,8 +615,8 @@ describe("Scene/CreditDisplay", function () { expect(creditList.childNodes.length).toEqual(0); beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); + creditDisplay.addCreditToNextFrame(credit1); + creditDisplay.addCreditToNextFrame(credit2); creditDisplay.endFrame(); creditDisplay.update(); diff --git a/packages/engine/Specs/Widget/CesiumWidgetSpec.js b/packages/engine/Specs/Widget/CesiumWidgetSpec.js index 3982b31914a..a2a52138937 100644 --- a/packages/engine/Specs/Widget/CesiumWidgetSpec.js +++ b/packages/engine/Specs/Widget/CesiumWidgetSpec.js @@ -1,6 +1,7 @@ import { CesiumWidget, Clock, + CreditDisplay, defaultValue, EllipsoidTerrainProvider, ScreenSpaceEventHandler, @@ -59,6 +60,7 @@ describe( expect(widget.isDestroyed()).toEqual(false); expect(widget.container).toBeInstanceOf(HTMLElement); expect(widget.canvas).toBeInstanceOf(HTMLElement); + expect(widget.creditDisplay).toBeInstanceOf(CreditDisplay); expect(widget.creditContainer).toBeInstanceOf(HTMLElement); expect(widget.creditViewport).toBeInstanceOf(HTMLElement); expect(widget.scene).toBeInstanceOf(Scene); diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index ffd43da6c79..00c320b3a99 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -986,6 +986,18 @@ Object.defineProperties(Viewer.prototype, { }, }, + /** + * Manages the list of credits to display on screen and in the lightbox. + * @memberof Viewer.prototype + * + * @type {CreditDisplay} + */ + creditDisplay: { + get: function () { + return this._cesiumWidget.creditDisplay; + }, + }, + /** * Gets the DOM element for the area at the bottom of the window containing the * {@link CreditDisplay} and potentially other things. diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index 691d7025d15..35546b38641 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -7,6 +7,7 @@ import { ClockRange, ClockStep, Color, + CreditDisplay, defined, EllipsoidTerrainProvider, HeadingPitchRange, @@ -119,6 +120,7 @@ describe( expect(viewer.selectionIndicator).toBeInstanceOf(SelectionIndicator); expect(viewer.imageryLayers).toBeInstanceOf(ImageryLayerCollection); expect(viewer.terrainProvider).toBeInstanceOf(EllipsoidTerrainProvider); + expect(viewer.creditDisplay).toBeInstanceOf(CreditDisplay); expect(viewer.camera).toBeInstanceOf(Camera); expect(viewer.dataSourceDisplay).toBeInstanceOf(DataSourceDisplay); expect(viewer.dataSources).toBeInstanceOf(DataSourceCollection); From bed30771dd758cd922a588a6efd8787dbd31add2 Mon Sep 17 00:00:00 2001 From: Kirill Shapovalov <52831380+ShapovalovKL@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:57:41 +0400 Subject: [PATCH 635/679] Allow Cesium3DTileStyle with conditionally undefined scaleByDistance, translucencyByDistance and distanceDisplayCondition (#11228) * Allow per feature undefined values in Cesium3DTileStyle Allow to use StyleExpression for scaleByDistance. translucencyByDistance, distanceDisplayCondition which returns undefined for some objects * update CONTRIBUTORS * fix code style * fix code style * Update CHANGES.md * Update CHANGES.md * Update CHANGES.md * Add test for style options witch can be evaluated to undefined * Add test for style options witch can be evaluated to undefined * Add test for style options witch can be evaluated to undefined --- CHANGES.md | 2 + CONTRIBUTORS.md | 1 + .../engine/Source/Scene/Vector3DTilePoints.js | 38 +++-- .../Specs/Scene/Vector3DTilePointsSpec.js | 142 ++++++++++++++++++ 4 files changed, 170 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cecdbf60742..808a55ae381 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,8 @@ - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) - Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) - Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) +- Fixed a crash when Cesium3DTileStyle's scaleByDistance, translucencyByDistance or distanceDisplayCondition set to StyleExpression + which returns `undefined`. [#11228](https://github.com/CesiumGS/cesium/pull/11228) #### @cesium/widgets diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0c8e36eca36..0a27401ca74 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -355,3 +355,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Joseph Stanton](https://github.com/romejoe) - [Zehua Hu](https://github.com/lanvada) - [Jason Summercamp](https://github.com/fullstacc) +- [Shapovalov Kirill](https://github.com/ShapovalovKL) diff --git a/packages/engine/Source/Scene/Vector3DTilePoints.js b/packages/engine/Source/Scene/Vector3DTilePoints.js index f66fc7901a0..7bea9c2c902 100644 --- a/packages/engine/Source/Scene/Vector3DTilePoints.js +++ b/packages/engine/Source/Scene/Vector3DTilePoints.js @@ -394,11 +394,15 @@ Vector3DTilePoints.prototype.applyStyle = function (style, features) { if (defined(style.scaleByDistance)) { const scaleByDistanceCart4 = style.scaleByDistance.evaluate(feature); - scratchScaleByDistance.near = scaleByDistanceCart4.x; - scratchScaleByDistance.nearValue = scaleByDistanceCart4.y; - scratchScaleByDistance.far = scaleByDistanceCart4.z; - scratchScaleByDistance.farValue = scaleByDistanceCart4.w; - feature.scaleByDistance = scratchScaleByDistance; + if (defined(scaleByDistanceCart4)) { + scratchScaleByDistance.near = scaleByDistanceCart4.x; + scratchScaleByDistance.nearValue = scaleByDistanceCart4.y; + scratchScaleByDistance.far = scaleByDistanceCart4.z; + scratchScaleByDistance.farValue = scaleByDistanceCart4.w; + feature.scaleByDistance = scratchScaleByDistance; + } else { + feature.scaleByDistance = undefined; + } } else { feature.scaleByDistance = undefined; } @@ -407,11 +411,15 @@ Vector3DTilePoints.prototype.applyStyle = function (style, features) { const translucencyByDistanceCart4 = style.translucencyByDistance.evaluate( feature ); - scratchTranslucencyByDistance.near = translucencyByDistanceCart4.x; - scratchTranslucencyByDistance.nearValue = translucencyByDistanceCart4.y; - scratchTranslucencyByDistance.far = translucencyByDistanceCart4.z; - scratchTranslucencyByDistance.farValue = translucencyByDistanceCart4.w; - feature.translucencyByDistance = scratchTranslucencyByDistance; + if (defined(translucencyByDistanceCart4)) { + scratchTranslucencyByDistance.near = translucencyByDistanceCart4.x; + scratchTranslucencyByDistance.nearValue = translucencyByDistanceCart4.y; + scratchTranslucencyByDistance.far = translucencyByDistanceCart4.z; + scratchTranslucencyByDistance.farValue = translucencyByDistanceCart4.w; + feature.translucencyByDistance = scratchTranslucencyByDistance; + } else { + feature.translucencyByDistance = undefined; + } } else { feature.translucencyByDistance = undefined; } @@ -420,9 +428,13 @@ Vector3DTilePoints.prototype.applyStyle = function (style, features) { const distanceDisplayConditionCart2 = style.distanceDisplayCondition.evaluate( feature ); - scratchDistanceDisplayCondition.near = distanceDisplayConditionCart2.x; - scratchDistanceDisplayCondition.far = distanceDisplayConditionCart2.y; - feature.distanceDisplayCondition = scratchDistanceDisplayCondition; + if (defined(distanceDisplayConditionCart2)) { + scratchDistanceDisplayCondition.near = distanceDisplayConditionCart2.x; + scratchDistanceDisplayCondition.far = distanceDisplayConditionCart2.y; + feature.distanceDisplayCondition = scratchDistanceDisplayCondition; + } else { + feature.distanceDisplayCondition = undefined; + } } else { feature.distanceDisplayCondition = undefined; } diff --git a/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js b/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js index 9aef5e30df9..c1a22dfedf6 100644 --- a/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js +++ b/packages/engine/Specs/Scene/Vector3DTilePointsSpec.js @@ -1,6 +1,7 @@ import { Cartesian2, Cartesian3, + Cartesian4, Cartographic, clone, Color, @@ -427,6 +428,147 @@ describe( }); }); + it("renders multiple points and test style options witch can be evaluated to undefined", function () { + const testOptions = + /*[ + Cesium3DTileStyle option, + Cesium3DTileStyle default value, + Cesium3DTileFeature property, + expected Cesium3DTileFeature value, + expected undefined Cesium3DTileFeature value + ]*/ + [ + [ + "scaleByDistance", + new Cartesian4(1.0e4, 1.0, 1.0e6, 0.0), + "scaleByDistance", + new NearFarScalar(1.0e4, 1.0, 1.0e6, 0.0), + undefined, + ], + [ + "translucencyByDistance", + new Cartesian4(1.0e4, 1.0, 1.0e6, 0.0), + "translucencyByDistance", + new NearFarScalar(1.0e4, 1.0, 1.0e6, 0.0), + undefined, + ], + [ + "distanceDisplayCondition", + new Cartesian2(0.1, 1.0e6), + "distanceDisplayCondition", + new DistanceDisplayCondition(0.1, 1.0e6), + undefined, + ], + [ + "disableDepthTestDistance", + 1.0e6, + "disableDepthTestDistance", + 1.0e6, + undefined, + ], + ]; + const minHeight = 0.0; + const maxHeight = 100.0; + const cartoPositions = []; + for (let i = 0; i < testOptions.length; ++i) { + cartoPositions.push(Cartographic.fromDegrees(0.1 * i, 0.0, 10.0)); + } + + const positions = encodePositions( + rectangle, + minHeight, + maxHeight, + cartoPositions + ); + + const mockTilesetClone = clone(mockTileset); + const batchTable = new Cesium3DTileBatchTable( + mockTilesetClone, + testOptions.length + ); + mockTilesetClone.batchTable = batchTable; + + const batchIds = []; + for (let i = 0; i < testOptions.length; ++i) { + batchTable.setProperty(i, "pointIndex", i); + batchIds.push(i); + } + batchTable.update(mockTilesetClone, scene.frameState); + + points = scene.primitives.add( + new Vector3DTilePoints({ + positions: positions, + batchTable: batchTable, + batchIds: new Uint16Array(batchIds), + rectangle: rectangle, + minimumHeight: minHeight, + maximumHeight: maxHeight, + }) + ); + + const styleOptions = {}; + // Creating style which returns undefined for a single option for every feature. Undefined option index equal pointIndex + for ( + let testOptionIndex = 0; + testOptionIndex < testOptions.length; + ++testOptionIndex + ) { + const testOption = testOptions[testOptionIndex]; + const cesium3DTileStyleOptionName = testOption[0]; + const cesium3DTileStyleOptionDefaultValue = testOption[1]; + styleOptions[cesium3DTileStyleOptionName] = { + evaluate: function (feature) { + if (feature.getProperty("pointIndex") === testOptionIndex) { + return undefined; + } + return cesium3DTileStyleOptionDefaultValue; + }, + }; + } + + const style = new Cesium3DTileStyle(styleOptions); + + return loadPoints(points).then(function () { + const features = []; + points.createFeatures(mockTilesetClone, features); + points.applyStyle(style, features); + + let i; + for (i = 0; i < features.length; ++i) { + const feature = features[i]; + // Checking feature properties. Undefined option index equal pointIndex + for ( + let testOptionIndex = 0; + testOptionIndex < testOptions.length; + ++testOptionIndex + ) { + const testOption = testOptions[testOptionIndex]; + const cesium3DTileFeaturePropertyName = testOption[2]; + const expectedCesium3DTileFeaturePropertyDefaultValue = + testOption[3]; + const expectedCesium3DTileFeaturePropertyUndefinedValue = + testOption[4]; + const expectedCesium3DTileFeaturePropertyValue = + i === testOptionIndex + ? expectedCesium3DTileFeaturePropertyUndefinedValue + : expectedCesium3DTileFeaturePropertyDefaultValue; + if (defined(expectedCesium3DTileFeaturePropertyValue)) { + expect(feature[cesium3DTileFeaturePropertyName]).toBeDefined(); + expect(feature[cesium3DTileFeaturePropertyName]).toEqual( + expectedCesium3DTileFeaturePropertyValue + ); + } else { + expect(feature[cesium3DTileFeaturePropertyName]).toBeUndefined(); + } + } + } + // Look at first feature to load all primitives + const position = ellipsoid.cartographicToCartesian(cartoPositions[0]); + scene.camera.lookAt(position, new Cartesian3(0.0, 0.0, 50.0)); + return allPrimitivesReady(points); + }); + }); + it("renders a point with an image", function () { const minHeight = 0.0; const maxHeight = 100.0; From 65b6944f9fea904ca7a36987444c28e1ec78d8c2 Mon Sep 17 00:00:00 2001 From: qiuyan_wang <37433156+wqy224488@users.noreply.github.com> Date: Thu, 20 Apr 2023 21:58:44 +0800 Subject: [PATCH 636/679] update the UniformType : mat3 (#11235) * update the UniformType : mat3 * add CONTRIBUTORS.md * Update CHANGES.md with adding a summary about this change. --------- Co-authored-by: Gabby Getz <gabby@cesium.com> --- CHANGES.md | 1 + CONTRIBUTORS.md | 1 + packages/engine/Source/Scene/Model/UniformType.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 808a55ae381..b913faa9b3a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ - Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) - Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) +- Fixed UniformType.MAT3 value for custom shaders. [#11235](https://github.com/CesiumGS/cesium/pull/11235). - Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) - Fixed a crash when Cesium3DTileStyle's scaleByDistance, translucencyByDistance or distanceDisplayCondition set to StyleExpression which returns `undefined`. [#11228](https://github.com/CesiumGS/cesium/pull/11228) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0a27401ca74..5d0fb7a9053 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -354,5 +354,6 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Michael Cabana](https://github.com/mikecabana) - [Joseph Stanton](https://github.com/romejoe) - [Zehua Hu](https://github.com/lanvada) +- [王秋艳](https://github.com/wqy224488) - [Jason Summercamp](https://github.com/fullstacc) - [Shapovalov Kirill](https://github.com/ShapovalovKL) diff --git a/packages/engine/Source/Scene/Model/UniformType.js b/packages/engine/Source/Scene/Model/UniformType.js index d8cd20aee2c..880df862b1f 100644 --- a/packages/engine/Source/Scene/Model/UniformType.js +++ b/packages/engine/Source/Scene/Model/UniformType.js @@ -104,7 +104,7 @@ const UniformType = { * @type {string} * @constant */ - MAT3: "mat2", + MAT3: "mat3", /** * A 3x3 matrix of floating point values. * From c529d8d876c7d8d23333cb1aed8ce90ef3716ab4 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:13:31 -0400 Subject: [PATCH 637/679] Fix icons in base layer picker widget (#11244) * Fix iconUrls in createDefaultImageryProviderViewModel * Rename ArcGis baselayer icons --------- Co-authored-by: Jeshurun Hembd <jeshurun@cesium.com> --- ...shade.png => ArcGisMapServiceWorldHillshade.png} | Bin ...Imagery.png => ArcGisMapServiceWorldImagery.png} | Bin ...orldOcean.png => ArcGisMapServiceWorldOcean.png} | Bin 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/widgets/Source/Images/ImageryProviders/{ArcGISMapServiceWorldHillshade.png => ArcGisMapServiceWorldHillshade.png} (100%) rename packages/widgets/Source/Images/ImageryProviders/{ArcGISMapServiceWorldImagery.png => ArcGisMapServiceWorldImagery.png} (100%) rename packages/widgets/Source/Images/ImageryProviders/{ArcGISMapServiceWorldOcean.png => ArcGisMapServiceWorldOcean.png} (100%) diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldHillshade.png b/packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png similarity index 100% rename from packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldHillshade.png rename to packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldImagery.png b/packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png similarity index 100% rename from packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldImagery.png rename to packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png diff --git a/packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldOcean.png b/packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png similarity index 100% rename from packages/widgets/Source/Images/ImageryProviders/ArcGISMapServiceWorldOcean.png rename to packages/widgets/Source/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png From f61767e016fa8a3553dfba02a0f412b35f71c4b5 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Fri, 21 Apr 2023 11:26:24 -0400 Subject: [PATCH 638/679] Fix out_FragColor handling in demodernizeShader (#11230) * Fix out_FragColor regexes in demodernizeShader * Update CHANGES.md --------- Co-authored-by: Jeshurun Hembd <jeshurun@cesium.com> --- CHANGES.md | 1 + packages/engine/Source/Renderer/demodernizeShader.js | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2732cafb643..af75a76ed66 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ - Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) - Fixed a crash when Cesium3DTileStyle's scaleByDistance, translucencyByDistance or distanceDisplayCondition set to StyleExpression which returns `undefined`. [#11228](https://github.com/CesiumGS/cesium/pull/11228) +- Fixed handling of `out_FragColor` layout declarations when translating shaders to WebGL1. [#11230](https://github.com/CesiumGS/cesium/pull/11230) #### @cesium/widgets diff --git a/packages/engine/Source/Renderer/demodernizeShader.js b/packages/engine/Source/Renderer/demodernizeShader.js index 357ed8de644..ac984761ed0 100644 --- a/packages/engine/Source/Renderer/demodernizeShader.js +++ b/packages/engine/Source/Renderer/demodernizeShader.js @@ -41,16 +41,16 @@ function demodernizeShader(input, isFragmentShader) { output = output.replaceAll(/out_FragData_(\d+)/g, `gl_FragData[$1]`); } - // Replace out_FragColor with gl_FragColor. - output = output.replaceAll(/out_FragColor/g, `gl_FragColor`); - output = output.replaceAll(/out_FragColor\[(\d+)\]/g, `gl_FragColor[$1]`); - // Remove all layout declarations for out_FragColor. output = output.replaceAll( - /layout\s+\(location\s*=\s*0\)\s*out\s+vec4\s+out_FragColor/g, + /layout\s+\(location\s*=\s*0\)\s*out\s+vec4\s+out_FragColor;/g, `` ); + // Replace out_FragColor with gl_FragColor. + output = output.replaceAll(/out_FragColor/g, `gl_FragColor`); + output = output.replaceAll(/out_FragColor\[(\d+)\]/g, `gl_FragColor[$1]`); + if (/gl_FragDepth/.test(output)) { output = `#extension GL_EXT_frag_depth : enable\n${output}`; // Replace gl_FragDepth with gl_FragDepthEXT. From 781d7ac9219a35e3067409b3643430d463e106aa Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 21 Apr 2023 18:45:38 -0400 Subject: [PATCH 639/679] Fix typo in deprecation messages --- packages/engine/Source/Scene/CreditDisplay.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index c8df048177f..f5bcefe7f26 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -434,7 +434,7 @@ function setCredit(creditDisplay, credits, credit, count) { CreditDisplay.prototype.addCredit = function (credit) { deprecationWarning( "CreditDisplay.addCredit", - "CreditDisplay.addCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addCreditToNextFrame instead." + "CreditDisplay.addCredit was deprecated in CesiumJS 1.105. It will be removed in CesiumJS 1.107. Use CreditDisplay.addCreditToNextFrame instead." ); this.addCreditToNextFrame(credit); @@ -487,7 +487,7 @@ CreditDisplay.prototype.addDefaultCredit = function (credit) { deprecationWarning( "CreditDisplay.addDefaultCredit", - "CreditDisplay.addDefaultCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." + "CreditDisplay.addDefaultCredit was deprecated in CesiumJS 1.105. It will be removed in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." ); const defaultCredits = this._defaultCredits; @@ -548,7 +548,7 @@ CreditDisplay.prototype.removeStaticCredit = function (credit) { CreditDisplay.prototype.removeDefaultCredit = function (credit) { deprecationWarning( "CreditDisplay.removeDefaultCredit", - "CreditDisplay.removeDefaultCredit was deprecated in CesiumJS 1.105. It will be in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." + "CreditDisplay.removeDefaultCredit was deprecated in CesiumJS 1.105. It will be removed in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." ); this.removeStaticCredit(credit); From e868a33d2a21d47d4bb31995eba563024494159e Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 24 Apr 2023 11:27:18 -0400 Subject: [PATCH 640/679] Cleanup property names --- packages/engine/Source/Scene/CreditDisplay.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index f5bcefe7f26..02aae3dbb0a 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -381,7 +381,7 @@ function CreditDisplay(container, delimiter, viewport) { this._hideLightbox = hideLightbox; this._expandLink = expandLink; this._expanded = false; - this._defaultCredits = []; + this._staticCredits = []; this._cesiumCredit = cesiumCredit; this._previousCesiumCredit = undefined; this._currentCesiumCredit = cesiumCredit; @@ -490,7 +490,7 @@ CreditDisplay.prototype.addDefaultCredit = function (credit) { "CreditDisplay.addDefaultCredit was deprecated in CesiumJS 1.105. It will be removed in CesiumJS 1.107. Use CreditDisplay.addStaticCredit instead." ); - const defaultCredits = this._defaultCredits; + const defaultCredits = this._staticCredits; if (!contains(defaultCredits, credit)) { credit.showOnScreen = true; defaultCredits.push(credit); @@ -517,9 +517,9 @@ CreditDisplay.prototype.addStaticCredit = function (credit) { Check.defined("credit", credit); //>>includeEnd('debug'); - const defaultCredits = this._defaultCredits; - if (!contains(defaultCredits, credit)) { - defaultCredits.push(credit); + const staticCredits = this._staticCredits; + if (!contains(staticCredits, credit)) { + staticCredits.push(credit); } }; @@ -533,10 +533,10 @@ CreditDisplay.prototype.removeStaticCredit = function (credit) { Check.defined("credit", credit); //>>includeEnd('debug'); - const defaultCredits = this._defaultCredits; - const index = defaultCredits.indexOf(credit); + const staticCredits = this._staticCredits; + const index = staticCredits.indexOf(credit); if (index !== -1) { - defaultCredits.splice(index, 1); + staticCredits.splice(index, 1); } }; @@ -592,13 +592,13 @@ CreditDisplay.prototype.beginFrame = function () { screenCredits.removeAll(); lightboxCredits.removeAll(); - const defaultCredits = this._defaultCredits; - for (let i = 0; i < defaultCredits.length; ++i) { - const defaultCredit = defaultCredits[i]; - const creditCollection = defaultCredit.showOnScreen + const staticCredits = this._staticCredits; + for (let i = 0; i < staticCredits.length; ++i) { + const staticCredit = staticCredits[i]; + const creditCollection = staticCredit.showOnScreen ? screenCredits : lightboxCredits; - setCredit(this, creditCollection, defaultCredit, Number.MAX_VALUE); + setCredit(this, creditCollection, staticCredit, Number.MAX_VALUE); } if (!Credit.equals(CreditDisplay.cesiumCredit, this._cesiumCredit)) { From c740db38483f685324dd0bb9f58c528711a5f070 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 24 Apr 2023 15:55:20 -0400 Subject: [PATCH 641/679] Update dependencies --- .../Source/DataSources/EntityCluster.js | 254 +++++++++--------- packages/engine/package.json | 6 +- 2 files changed, 129 insertions(+), 131 deletions(-) diff --git a/packages/engine/Source/DataSources/EntityCluster.js b/packages/engine/Source/DataSources/EntityCluster.js index 164aa48ca8e..3edf4fedc8b 100644 --- a/packages/engine/Source/DataSources/EntityCluster.js +++ b/packages/engine/Source/DataSources/EntityCluster.js @@ -76,14 +76,6 @@ function EntityCluster(options) { this.show = defaultValue(options.show, true); } -function getX(point) { - return point.coord.x; -} - -function getY(point) { - return point.coord.y; -} - function expandBoundingBox(bbox, pixelRange) { bbox.x -= pixelRange; bbox.y -= pixelRange; @@ -335,153 +327,159 @@ function createDeclutterCallback(entityCluster) { let collection; let collectionIndex; - const index = new KDBush(points, getX, getY, 64, Int32Array); + if (points.length > 0) { + const index = new KDBush(points.length, 64, Uint32Array); + for (let p = 0; p < points.length; ++p) { + index.add(points[p].coord.x, points[p].coord.y); + } + index.finish(); - if (currentHeight < previousHeight) { - length = clusters.length; - for (i = 0; i < length; ++i) { - const cluster = clusters[i]; + if (currentHeight < previousHeight) { + length = clusters.length; + for (i = 0; i < length; ++i) { + const cluster = clusters[i]; - if (!occluder.isPointVisible(cluster.position)) { - continue; + if (!occluder.isPointVisible(cluster.position)) { + continue; + } + + const coord = Billboard._computeScreenSpacePosition( + Matrix4.IDENTITY, + cluster.position, + Cartesian3.ZERO, + Cartesian2.ZERO, + scene + ); + if (!defined(coord)) { + continue; + } + + const factor = 1.0 - currentHeight / previousHeight; + let width = (cluster.width = cluster.width * factor); + let height = (cluster.height = cluster.height * factor); + + width = Math.max(width, cluster.minimumWidth); + height = Math.max(height, cluster.minimumHeight); + + const minX = coord.x - width * 0.5; + const minY = coord.y - height * 0.5; + const maxX = coord.x + width; + const maxY = coord.y + height; + + neighbors = index.range(minX, minY, maxX, maxY); + neighborLength = neighbors.length; + numPoints = 0; + ids = []; + + for (j = 0; j < neighborLength; ++j) { + neighborIndex = neighbors[j]; + neighborPoint = points[neighborIndex]; + if (!neighborPoint.clustered) { + ++numPoints; + + collection = neighborPoint.collection; + collectionIndex = neighborPoint.index; + ids.push(collection.get(collectionIndex).id); + } + } + + if (numPoints >= minimumClusterSize) { + addCluster(cluster.position, numPoints, ids, entityCluster); + newClusters.push(cluster); + + for (j = 0; j < neighborLength; ++j) { + points[neighbors[j]].clustered = true; + } + } } + } - const coord = Billboard._computeScreenSpacePosition( - Matrix4.IDENTITY, - cluster.position, - Cartesian3.ZERO, - Cartesian2.ZERO, - scene - ); - if (!defined(coord)) { + length = points.length; + for (i = 0; i < length; ++i) { + const point = points[i]; + if (point.clustered) { continue; } - const factor = 1.0 - currentHeight / previousHeight; - let width = (cluster.width = cluster.width * factor); - let height = (cluster.height = cluster.height * factor); + point.clustered = true; - width = Math.max(width, cluster.minimumWidth); - height = Math.max(height, cluster.minimumHeight); + collection = point.collection; + collectionIndex = point.index; - const minX = coord.x - width * 0.5; - const minY = coord.y - height * 0.5; - const maxX = coord.x + width; - const maxY = coord.y + height; + const item = collection.get(collectionIndex); + bbox = getBoundingBox( + item, + point.coord, + pixelRange, + entityCluster, + pointBoundinRectangleScratch + ); + const totalBBox = BoundingRectangle.clone( + bbox, + totalBoundingRectangleScratch + ); - neighbors = index.range(minX, minY, maxX, maxY); + neighbors = index.range( + bbox.x, + bbox.y, + bbox.x + bbox.width, + bbox.y + bbox.height + ); neighborLength = neighbors.length; - numPoints = 0; - ids = []; + + const clusterPosition = Cartesian3.clone(item.position); + numPoints = 1; + ids = [item.id]; for (j = 0; j < neighborLength; ++j) { neighborIndex = neighbors[j]; neighborPoint = points[neighborIndex]; if (!neighborPoint.clustered) { + const neighborItem = neighborPoint.collection.get( + neighborPoint.index + ); + const neighborBBox = getBoundingBox( + neighborItem, + neighborPoint.coord, + pixelRange, + entityCluster, + neighborBoundingRectangleScratch + ); + + Cartesian3.add( + neighborItem.position, + clusterPosition, + clusterPosition + ); + + BoundingRectangle.union(totalBBox, neighborBBox, totalBBox); ++numPoints; - collection = neighborPoint.collection; - collectionIndex = neighborPoint.index; - ids.push(collection.get(collectionIndex).id); + ids.push(neighborItem.id); } } if (numPoints >= minimumClusterSize) { - addCluster(cluster.position, numPoints, ids, entityCluster); - newClusters.push(cluster); - - for (j = 0; j < neighborLength; ++j) { - points[neighbors[j]].clustered = true; - } - } - } - } - - length = points.length; - for (i = 0; i < length; ++i) { - const point = points[i]; - if (point.clustered) { - continue; - } - - point.clustered = true; - - collection = point.collection; - collectionIndex = point.index; - - const item = collection.get(collectionIndex); - bbox = getBoundingBox( - item, - point.coord, - pixelRange, - entityCluster, - pointBoundinRectangleScratch - ); - const totalBBox = BoundingRectangle.clone( - bbox, - totalBoundingRectangleScratch - ); - - neighbors = index.range( - bbox.x, - bbox.y, - bbox.x + bbox.width, - bbox.y + bbox.height - ); - neighborLength = neighbors.length; - - const clusterPosition = Cartesian3.clone(item.position); - numPoints = 1; - ids = [item.id]; - - for (j = 0; j < neighborLength; ++j) { - neighborIndex = neighbors[j]; - neighborPoint = points[neighborIndex]; - if (!neighborPoint.clustered) { - const neighborItem = neighborPoint.collection.get( - neighborPoint.index - ); - const neighborBBox = getBoundingBox( - neighborItem, - neighborPoint.coord, - pixelRange, - entityCluster, - neighborBoundingRectangleScratch - ); - - Cartesian3.add( - neighborItem.position, + const position = Cartesian3.multiplyByScalar( clusterPosition, + 1.0 / numPoints, clusterPosition ); + addCluster(position, numPoints, ids, entityCluster); + newClusters.push({ + position: position, + width: totalBBox.width, + height: totalBBox.height, + minimumWidth: bbox.width, + minimumHeight: bbox.height, + }); - BoundingRectangle.union(totalBBox, neighborBBox, totalBBox); - ++numPoints; - - ids.push(neighborItem.id); - } - } - - if (numPoints >= minimumClusterSize) { - const position = Cartesian3.multiplyByScalar( - clusterPosition, - 1.0 / numPoints, - clusterPosition - ); - addCluster(position, numPoints, ids, entityCluster); - newClusters.push({ - position: position, - width: totalBBox.width, - height: totalBBox.height, - minimumWidth: bbox.width, - minimumHeight: bbox.height, - }); - - for (j = 0; j < neighborLength; ++j) { - points[neighbors[j]].clustered = true; + for (j = 0; j < neighborLength; ++j) { + points[neighbors[j]].clustered = true; + } + } else { + addNonClusteredItem(item, entityCluster); } - } else { - addNonClusteredItem(item, entityCluster); } } diff --git a/packages/engine/package.json b/packages/engine/package.json index 7fb12468fc1..e36d29a700d 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -36,12 +36,12 @@ "@zip.js/zip.js": "2.4.x", "autolinker": "^4.0.0", "bitmap-sdf": "^1.0.3", - "dompurify": "^2.2.2", + "dompurify": "^3.0.2", "earcut": "^2.2.4", "grapheme-splitter": "^1.0.4", "jsep": "^1.3.8", - "kdbush": "^3.0.0", - "ktx-parse": "^0.4.5", + "kdbush": "^4.0.1", + "ktx-parse": "^0.5.0", "lerc": "^2.0.0", "mersenne-twister": "^1.1.0", "meshoptimizer": "^0.18.1", From b9a09aef23a0b9f9de103c6d392344afff671181 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 24 Apr 2023 16:01:09 -0400 Subject: [PATCH 642/679] Update dev dependencies --- build.js | 4 ++-- gulpfile.js | 4 ++-- package.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.js b/build.js index 447ca315cd7..91e7882900d 100644 --- a/build.js +++ b/build.js @@ -10,7 +10,7 @@ import esbuild from "esbuild"; import { globby } from "globby"; import glslStripComments from "glsl-strip-comments"; import gulp from "gulp"; -import rimraf from "rimraf"; +import { rimraf } from "rimraf"; import { rollup } from "rollup"; import rollupPluginStripPragma from "rollup-plugin-strip-pragma"; import terser from "@rollup/plugin-terser"; @@ -18,7 +18,7 @@ import rollupCommonjs from "@rollup/plugin-commonjs"; import rollupResolve from "@rollup/plugin-node-resolve"; import streamToPromise from "stream-to-promise"; -import mkdirp from "mkdirp"; +import { mkdirp } from "mkdirp"; // Determines the scope of the workspace packages. If the scope is set to cesium, the workspaces should be @cesium/engine. // This should match the scope of the dependencies of the root level package.json. diff --git a/gulpfile.js b/gulpfile.js index 51a36176f10..a55506e6e6c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -16,8 +16,8 @@ import gulpRename from "gulp-rename"; import gulpReplace from "gulp-replace"; import { globby } from "globby"; import open from "open"; -import rimraf from "rimraf"; -import mkdirp from "mkdirp"; +import { rimraf } from "rimraf"; +import { mkdirp } from "mkdirp"; import mergeStream from "merge-stream"; import streamToPromise from "stream-to-promise"; import karma from "karma"; diff --git a/package.json b/package.json index 2d396870654..766a0b1ab96 100644 --- a/package.json +++ b/package.json @@ -102,14 +102,14 @@ "markdownlint-cli": "^0.33.0", "merge-stream": "^2.0.0", "mime": "^3.0.0", - "mkdirp": "^2.1.3", + "mkdirp": "^3.0.1", "node-fetch": "^3.2.10", "open": "^9.1.0", "p-limit": "^4.0.0", "prettier": "2.1.2", "prismjs": "^1.28.0", "request": "^2.79.0", - "rimraf": "^4.1.2", + "rimraf": "^5.0.0", "rollup": "^3.17.2", "rollup-plugin-strip-pragma": "^1.0.0", "stream-to-promise": "^3.0.0", From c9ace662cc19d4f996939f7e956ee917ec088949 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Mon, 24 Apr 2023 16:10:38 -0400 Subject: [PATCH 643/679] Use alpha from rendered scene in AmbientOcclusionModulate (#11247) * Use alpha from rendered scene in AmbientOcclusionModulate * Update CHANGES.md * Fix coordinates for random texture sampling --------- Co-authored-by: Jeshurun Hembd <jeshurun@cesium.com> --- CHANGES.md | 1 + .../Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl | 2 +- .../Shaders/PostProcessStages/AmbientOcclusionModulate.glsl | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index af75a76ed66..5abfb8faabd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ - Fixed a crash when Cesium3DTileStyle's scaleByDistance, translucencyByDistance or distanceDisplayCondition set to StyleExpression which returns `undefined`. [#11228](https://github.com/CesiumGS/cesium/pull/11228) - Fixed handling of `out_FragColor` layout declarations when translating shaders to WebGL1. [#11230](https://github.com/CesiumGS/cesium/pull/11230) +- Fixed a problem with Ambient Occlusion that affected some MacOS hardware. [#10106](https://github.com/CesiumGS/cesium/issues/10106) #### @cesium/widgets diff --git a/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl b/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl index d5db2034e6c..0aecd38e231 100644 --- a/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl +++ b/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl @@ -58,7 +58,7 @@ void main(void) float gapAngle = 90.0 * czm_radiansPerDegree; // RandomNoise - float randomVal = texture(randomTexture, v_textureCoordinates).x; + float randomVal = texture(randomTexture, v_textureCoordinates / pixelSize / 255.0).x; //Loop for each direction for (int i = 0; i < 4; i++) diff --git a/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionModulate.glsl b/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionModulate.glsl index 694672fc70d..44b26074613 100644 --- a/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionModulate.glsl +++ b/packages/engine/Source/Shaders/PostProcessStages/AmbientOcclusionModulate.glsl @@ -5,7 +5,7 @@ in vec2 v_textureCoordinates; void main(void) { - vec3 color = texture(colorTexture, v_textureCoordinates).rgb; - vec3 ao = texture(ambientOcclusionTexture, v_textureCoordinates).rgb; - out_FragColor.rgb = ambientOcclusionOnly ? ao : ao * color; + vec4 color = texture(colorTexture, v_textureCoordinates); + vec4 ao = texture(ambientOcclusionTexture, v_textureCoordinates); + out_FragColor = ambientOcclusionOnly ? ao : ao * color; } From 0700f49879ea0e56842023ecaa90ad078d2987fc Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 25 Apr 2023 09:23:39 -0400 Subject: [PATCH 644/679] Update requestsByServer defaults --- packages/engine/Source/Core/RequestScheduler.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index 66ad7d211bd..1b185a3a7e3 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -65,18 +65,23 @@ RequestScheduler.maximumRequests = 50; RequestScheduler.maximumRequestsPerServer = 6; /** - * A per server key list of overrides to use for throttling instead of <code>maximumRequestsPerServer</code> + * A per server key list of overrides to use for throttling instead of <code>maximumRequestsPerServer</code>. + * Useful when streaming data from a known HTTP/2 or HTTP/3 server. * @type {object} * * @example + * RequestScheduler.requestsByServer["myserver.com:443"] = 18; + * + * @example * RequestScheduler.requestsByServer = { - * 'api.cesium.com:443': 18, - * 'assets.cesium.com:443': 18 + * "api.cesium.com:443": 18, + * "assets.cesium.com:443": 18, * }; */ RequestScheduler.requestsByServer = { "api.cesium.com:443": 18, "assets.ion.cesium.com:443": 18, + "ibasemaps-api.arcgis.com:443": 18, }; /** From 80920cb240757e57d06f5bff80e7ab102f54d286 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 27 Apr 2023 12:28:43 -0400 Subject: [PATCH 645/679] Add geocoder credits --- CHANGES.md | 2 + .../Source/Core/BingMapsGeocoderService.js | 20 +- .../engine/Source/Core/GeocoderService.js | 33 +- .../engine/Source/Core/IonGeocoderService.js | 21 +- .../Source/Core/OpenCageGeocoderService.js | 19 +- .../Source/Core/PeliasGeocoderService.js | 14 +- .../Specs/Core/BingMapsGeocoderServiceSpec.js | 58 +-- .../Specs/Core/IonGeocoderServiceSpec.js | 38 +- .../Specs/Core/OpenCageGeocoderServiceSpec.js | 39 ++- .../Specs/Core/PeliasGeocoderServiceSpec.js | 31 +- .../Source/Geocoder/GeocoderViewModel.js | 191 ++++++---- .../Specs/Geocoder/GeocoderViewModelSpec.js | 330 +++++++++++------- 12 files changed, 552 insertions(+), 244 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bcb7e2ef85f..bf8d308967a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ - Added `CesiumWidget.creditDisplay` to access the onscreen and lightbox credits. - Added `CreditDisplay.addStaticCredit` and `CreditDisplay.removeStaticCredit` such that `Credit.showOnScreen` value is taken into account. [#6215](https://github.com/CesiumGS/cesium/issues/6215) - Added `options.gltfCallback` to `Model.loadGltfAsync` to allow apps to access the loaded glTF JSON. [#11240](https://github.com/CesiumGS/cesium/pull/11240) +- Added `GeocoderService.credit` and and `attributions` property to `GeocoderService.Result` to allow for geocoder services to attribute results. ##### Fixes :wrench: @@ -34,6 +35,7 @@ ##### Additions :tada: - Added `Viewer.creditDisplay` to access the onscreen and lightbox credits. +- The `Geocoder` widget will now display attributions onscreen or in the lightbox for geocoder results if present, otherwise a default credit from a geocoder service if one is provided. ##### Fixes :wrench: diff --git a/packages/engine/Source/Core/BingMapsGeocoderService.js b/packages/engine/Source/Core/BingMapsGeocoderService.js index 9be3c977180..a9292e57015 100644 --- a/packages/engine/Source/Core/BingMapsGeocoderService.js +++ b/packages/engine/Source/Core/BingMapsGeocoderService.js @@ -1,4 +1,5 @@ import Check from "./Check.js"; +import Credit from "./Credit.js"; import defaultValue from "./defaultValue.js"; import Rectangle from "./Rectangle.js"; import Resource from "./Resource.js"; @@ -39,6 +40,11 @@ function BingMapsGeocoderService(options) { url: url, queryParameters: queryParameters, }); + + this._credit = new Credit( + `<img src="http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png"\/>`, + false + ); } Object.defineProperties(BingMapsGeocoderService.prototype, { @@ -65,6 +71,18 @@ Object.defineProperties(BingMapsGeocoderService.prototype, { return this._key; }, }, + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof BingMapsGeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: function () { + return this._credit; + }, + }, }); /** @@ -73,7 +91,7 @@ Object.defineProperties(BingMapsGeocoderService.prototype, { * @param {string} query The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ -BingMapsGeocoderService.prototype.geocode = function (query) { +BingMapsGeocoderService.prototype.geocode = async function (query) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("query", query); //>>includeEnd('debug'); diff --git a/packages/engine/Source/Core/GeocoderService.js b/packages/engine/Source/Core/GeocoderService.js index 9d5f026c37c..5c02ec2bdff 100644 --- a/packages/engine/Source/Core/GeocoderService.js +++ b/packages/engine/Source/Core/GeocoderService.js @@ -1,9 +1,12 @@ +import Credit from "./Credit.js"; +import defined from "./defined.js"; import DeveloperError from "./DeveloperError.js"; /** * @typedef {object} GeocoderService.Result * @property {string} displayName The display name for a location * @property {Rectangle|Cartesian3} destination The bounding box for a location + * @property {object[]} [attributions] */ /** @@ -16,7 +19,35 @@ import DeveloperError from "./DeveloperError.js"; * @see PeliasGeocoderService * @see OpenCageGeocoderService */ -function GeocoderService() {} +function GeocoderService() { + DeveloperError.throwInstantiationError(); +} + +Object.defineProperties(GeocoderService.prototype, { + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof GeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: DeveloperError.throwInstantiationError, + }, +}); + +/** + * Parses credits from the geocoder result attributions, if present. + * @param {GeocoderService.Result} geocoderResult The geocoder result + * @returns {Credit[]|undefined} A list of credits if present in the result, otherwise undefined + */ +GeocoderService.getCreditsFromResult = function (geocoderResult) { + if (defined(geocoderResult.attributions)) { + return geocoderResult.attributions.map(Credit.getIonCredit); + } + + return undefined; +}; /** * @function diff --git a/packages/engine/Source/Core/IonGeocoderService.js b/packages/engine/Source/Core/IonGeocoderService.js index 674c3ca47c9..0f7eba7732a 100644 --- a/packages/engine/Source/Core/IonGeocoderService.js +++ b/packages/engine/Source/Core/IonGeocoderService.js @@ -49,8 +49,27 @@ function IonGeocoderService(options) { this._accessToken = accessToken; this._server = server; this._pelias = new PeliasGeocoderService(searchEndpoint); + this._credit = new Credit( + `<img src="https:\/\/ion.cesium.com\/Images\/attributes\/geocoder.png"\/>`, + false + ); } +Object.defineProperties(IonGeocoderService.prototype, { + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof IonGeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: function () { + return this._credit; + }, + }, +}); + /** * @function * @@ -58,7 +77,7 @@ function IonGeocoderService(options) { * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. * @returns {Promise<GeocoderService.Result[]>} */ -IonGeocoderService.prototype.geocode = function (query, geocodeType) { +IonGeocoderService.prototype.geocode = async function (query, geocodeType) { return this._pelias.geocode(query, geocodeType); }; export default IonGeocoderService; diff --git a/packages/engine/Source/Core/OpenCageGeocoderService.js b/packages/engine/Source/Core/OpenCageGeocoderService.js index f49342b73f2..593285a9707 100644 --- a/packages/engine/Source/Core/OpenCageGeocoderService.js +++ b/packages/engine/Source/Core/OpenCageGeocoderService.js @@ -1,6 +1,7 @@ import Cartesian3 from "./Cartesian3.js"; import Check from "./Check.js"; import combine from "./combine.js"; +import Credit from "./Credit.js"; import defaultValue from "./defaultValue.js"; import defined from "./defined.js"; import Rectangle from "./Rectangle.js"; @@ -48,6 +49,10 @@ function OpenCageGeocoderService(url, apiKey, params) { url.setQueryParameters({ key: apiKey }); this._url = url; this._params = defaultValue(params, {}); + this._credit = new Credit( + `Geodata copyright <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors`, + false + ); } Object.defineProperties(OpenCageGeocoderService.prototype, { @@ -73,6 +78,18 @@ Object.defineProperties(OpenCageGeocoderService.prototype, { return this._params; }, }, + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof PeliasGeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: function () { + return this._credit; + }, + }, }); /** @@ -81,7 +98,7 @@ Object.defineProperties(OpenCageGeocoderService.prototype, { * @param {string} query The query to be sent to the geocoder service * @returns {Promise<GeocoderService.Result[]>} */ -OpenCageGeocoderService.prototype.geocode = function (query) { +OpenCageGeocoderService.prototype.geocode = async function (query) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("query", query); //>>includeEnd('debug'); diff --git a/packages/engine/Source/Core/PeliasGeocoderService.js b/packages/engine/Source/Core/PeliasGeocoderService.js index f859d8c0723..fd63305eddf 100644 --- a/packages/engine/Source/Core/PeliasGeocoderService.js +++ b/packages/engine/Source/Core/PeliasGeocoderService.js @@ -44,6 +44,18 @@ Object.defineProperties(PeliasGeocoderService.prototype, { return this._url; }, }, + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof PeliasGeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: function () { + return undefined; + }, + }, }); /** @@ -53,7 +65,7 @@ Object.defineProperties(PeliasGeocoderService.prototype, { * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. * @returns {Promise<GeocoderService.Result[]>} */ -PeliasGeocoderService.prototype.geocode = function (query, type) { +PeliasGeocoderService.prototype.geocode = async function (query, type) { //>>includeStart('debug', pragmas.debug); Check.typeOf.string("query", query); //>>includeEnd('debug'); diff --git a/packages/engine/Specs/Core/BingMapsGeocoderServiceSpec.js b/packages/engine/Specs/Core/BingMapsGeocoderServiceSpec.js index b153fc089c5..9d5dbccfda0 100644 --- a/packages/engine/Specs/Core/BingMapsGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/BingMapsGeocoderServiceSpec.js @@ -1,4 +1,10 @@ -import { BingMapsGeocoderService, Rectangle, Resource } from "../../index.js"; +import { + BingMapsGeocoderService, + Credit, + GeocoderService, + Rectangle, + Resource, +} from "../../index.js"; describe("Core/BingMapsGeocoderService", function () { afterAll(function () { @@ -6,7 +12,11 @@ describe("Core/BingMapsGeocoderService", function () { Resource._DefaultImplementations.loadAndExecuteScript; }); - it("returns geocoder results", function () { + it("conforms to GeocoderService interface", function () { + expect(BingMapsGeocoderService).toConformToInterface(GeocoderService); + }); + + it("returns geocoder results", async function () { const query = "some query"; const key = "not_the_real_key;"; const data = { @@ -33,14 +43,13 @@ describe("Core/BingMapsGeocoderService", function () { deferred.resolve(data); }; const service = new BingMapsGeocoderService({ key: key }); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(1); - expect(results[0].displayName).toEqual("a"); - expect(results[0].destination).toBeInstanceOf(Rectangle); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(1); + expect(results[0].displayName).toEqual("a"); + expect(results[0].destination).toBeInstanceOf(Rectangle); }); - it("uses supplied culture", function () { + it("uses supplied culture", async function () { const query = "some query"; const key = "not_the_real_key;"; const data = { @@ -67,14 +76,13 @@ describe("Core/BingMapsGeocoderService", function () { deferred.resolve(data); }; const service = new BingMapsGeocoderService({ key: key, culture: "ja" }); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(1); - expect(results[0].displayName).toEqual("a"); - expect(results[0].destination).toBeInstanceOf(Rectangle); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(1); + expect(results[0].displayName).toEqual("a"); + expect(results[0].destination).toBeInstanceOf(Rectangle); }); - it("returns no geocoder results if Bing has no results", function () { + it("returns no geocoder results if Bing has no results", async function () { const query = "some query"; const data = { resourceSets: [], @@ -87,12 +95,11 @@ describe("Core/BingMapsGeocoderService", function () { deferred.resolve(data); }; const service = new BingMapsGeocoderService({ key: "" }); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(0); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(0); }); - it("returns no geocoder results if Bing has results but no resources", function () { + it("returns no geocoder results if Bing has results but no resources", async function () { const query = "some query"; const data = { resourceSets: [ @@ -109,8 +116,17 @@ describe("Core/BingMapsGeocoderService", function () { deferred.resolve(data); }; const service = new BingMapsGeocoderService({ key: "" }); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(0); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(0); + }); + + it("credit returns expected value", async function () { + const service = new BingMapsGeocoderService({ key: "" }); + + expect(service.credit).toBeInstanceOf(Credit); + expect(service.credit.html).toEqual( + `<img src="http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png"/>` + ); + expect(service.credit.showOnScreen).toBe(false); }); }); diff --git a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js index d1337006984..a35e1249b33 100644 --- a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js @@ -1,4 +1,10 @@ -import { GeocodeType, Ion, IonGeocoderService } from "../../index.js"; +import { + Credit, + GeocoderService, + GeocodeType, + Ion, + IonGeocoderService, +} from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; @@ -12,14 +18,18 @@ describe("Core/IonGeocoderService", function () { scene.destroyForSpecs(); }); - it("Creates with default parameters", function () { + it("conforms to GeocoderService interface", function () { + expect(IonGeocoderService).toConformToInterface(GeocoderService); + }); + + it("creates with default parameters", function () { const service = new IonGeocoderService({ scene: scene }); expect(service._accessToken).toEqual(Ion.defaultAccessToken); expect(service._server.url).toEqual(Ion.defaultServer.url); }); - it("Creates with specified parameters", function () { + it("creates with specified parameters", function () { const accessToken = "123456"; const server = "http://not.ion.invalid/"; @@ -33,18 +43,30 @@ describe("Core/IonGeocoderService", function () { expect(service._server.url).toEqual(server); }); - it("calls inner geocoder and returns result", function () { + it("calls inner geocoder and returns result", async function () { const service = new IonGeocoderService({ scene: scene }); - const expectedResult = Promise.resolve(); - spyOn(service._pelias, "geocode").and.returnValue(expectedResult); + const expectedResult = ["results"]; + spyOn(service._pelias, "geocode").and.returnValue( + Promise.resolve(expectedResult) + ); const query = "some query"; - const result = service.geocode(query, GeocodeType.SEARCH); - expect(result).toBe(expectedResult); + const result = await service.geocode(query, GeocodeType.SEARCH); + expect(result).toEqual(expectedResult); expect(service._pelias.geocode).toHaveBeenCalledWith( query, GeocodeType.SEARCH ); }); + + it("credit returns expected value", async function () { + const service = new IonGeocoderService({ scene: scene }); + + expect(service.credit).toBeInstanceOf(Credit); + expect(service.credit.html).toEqual( + `<img src="http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png"/>` + ); + expect(service.credit.showOnScreen).toBe(false); + }); }); diff --git a/packages/engine/Specs/Core/OpenCageGeocoderServiceSpec.js b/packages/engine/Specs/Core/OpenCageGeocoderServiceSpec.js index b88ee4b889c..50ab7610234 100644 --- a/packages/engine/Specs/Core/OpenCageGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/OpenCageGeocoderServiceSpec.js @@ -1,9 +1,18 @@ -import { OpenCageGeocoderService, Resource } from "../../index.js"; +import { + Credit, + GeocoderService, + OpenCageGeocoderService, + Resource, +} from "../../index.js"; describe("Core/OpenCageGeocoderService", function () { const endpoint = "https://api.opencagedata.com/geocode/v1/"; const apiKey = "c2a490d593b14612aefa6ec2e6b77c47"; + it("conforms to GeocoderService interface", function () { + expect(OpenCageGeocoderService).toConformToInterface(GeocoderService); + }); + it("constructor throws without url", function () { expect(function () { return new OpenCageGeocoderService(undefined); @@ -16,7 +25,7 @@ describe("Core/OpenCageGeocoderService", function () { }).toThrowDeveloperError(); }); - it("returns geocoder results", function () { + it("returns geocoder results", async function () { const service = new OpenCageGeocoderService(endpoint, apiKey); const query = "-22.6792,+14.5272"; @@ -45,14 +54,13 @@ describe("Core/OpenCageGeocoderService", function () { Promise.resolve(data) ); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(1); - expect(results[0].displayName).toEqual(data.results[0].formatted); - expect(results[0].destination).toBeDefined(); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(1); + expect(results[0].displayName).toEqual(data.results[0].formatted); + expect(results[0].destination).toBeDefined(); }); - it("returns no geocoder results if OpenCage has no results", function () { + it("returns no geocoder results if OpenCage has no results", async function () { const service = new OpenCageGeocoderService(endpoint, apiKey); const query = ""; @@ -61,8 +69,17 @@ describe("Core/OpenCageGeocoderService", function () { Promise.resolve(data) ); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(0); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(0); + }); + + it("credit returns expected value", async function () { + const service = new OpenCageGeocoderService(endpoint, apiKey); + + expect(service.credit).toBeInstanceOf(Credit); + expect(service.credit.html).toEqual( + `Geodata copyright <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors` + ); + expect(service.credit.showOnScreen).toBe(false); }); }); diff --git a/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js b/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js index 174b3fc9326..2dc01182261 100644 --- a/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js @@ -1,18 +1,23 @@ import { Cartesian3, + GeocoderService, GeocodeType, PeliasGeocoderService, Resource, } from "../../index.js"; describe("Core/PeliasGeocoderService", function () { + it("conforms to GeocoderService interface", function () { + expect(PeliasGeocoderService).toConformToInterface(GeocoderService); + }); + it("constructor throws without url", function () { expect(function () { return new PeliasGeocoderService(undefined); }).toThrowDeveloperError(); }); - it("returns geocoder results", function () { + it("returns geocoder results", async function () { const service = new PeliasGeocoderService("http://test.invalid/v1/"); const query = "some query"; @@ -34,14 +39,13 @@ describe("Core/PeliasGeocoderService", function () { Promise.resolve(data) ); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(1); - expect(results[0].displayName).toEqual(data.features[0].properties.label); - expect(results[0].destination).toBeInstanceOf(Cartesian3); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(1); + expect(results[0].displayName).toEqual(data.features[0].properties.label); + expect(results[0].destination).toBeInstanceOf(Cartesian3); }); - it("returns no geocoder results if Pelias has no results", function () { + it("returns no geocoder results if Pelias has no results", async function () { const service = new PeliasGeocoderService("http://test.invalid/v1/"); const query = "some query"; @@ -50,12 +54,11 @@ describe("Core/PeliasGeocoderService", function () { Promise.resolve(data) ); - return service.geocode(query).then(function (results) { - expect(results.length).toEqual(0); - }); + const results = await service.geocode(query); + expect(results.length).toEqual(0); }); - it("calls search endpoint if specified", function () { + it("calls search endpoint if specified", async function () { const service = new PeliasGeocoderService("http://test.invalid/v1/"); const query = "some query"; @@ -68,7 +71,7 @@ describe("Core/PeliasGeocoderService", function () { "getDerivedResource" ).and.callThrough(); - service.geocode(query, GeocodeType.SEARCH); + await service.geocode(query, GeocodeType.SEARCH); expect(getDerivedResource).toHaveBeenCalledWith({ url: "search", queryParameters: { @@ -77,7 +80,7 @@ describe("Core/PeliasGeocoderService", function () { }); }); - it("calls autocomplete endpoint if specified", function () { + it("calls autocomplete endpoint if specified", async function () { const service = new PeliasGeocoderService("http://test.invalid/v1/"); const query = "some query"; @@ -90,7 +93,7 @@ describe("Core/PeliasGeocoderService", function () { "getDerivedResource" ).and.callThrough(); - service.geocode(query, GeocodeType.AUTOCOMPLETE); + await service.geocode(query, GeocodeType.AUTOCOMPLETE); expect(getDerivedResource).toHaveBeenCalledWith({ url: "autocomplete", queryParameters: { diff --git a/packages/widgets/Source/Geocoder/GeocoderViewModel.js b/packages/widgets/Source/Geocoder/GeocoderViewModel.js index 23cdc521cfd..3f8709d6ba3 100644 --- a/packages/widgets/Source/Geocoder/GeocoderViewModel.js +++ b/packages/widgets/Source/Geocoder/GeocoderViewModel.js @@ -4,7 +4,9 @@ import { defaultValue, defined, DeveloperError, + destroyObject, Event, + GeocoderService, GeocodeType, getElement, IonGeocoderService, @@ -53,7 +55,8 @@ function GeocoderViewModel(options) { this._flightDuration = options.flightDuration; this._searchText = ""; this._isSearchInProgress = false; - this._geocodePromise = undefined; + this._wasGeocodeCancelled = false; + this._previousCredits = []; this._complete = new Event(); this._suggestions = []; this._selectedSuggestion = undefined; @@ -82,7 +85,7 @@ function GeocoderViewModel(options) { if (that.isSearchInProgress) { cancelGeocode(that); } else { - geocode(that, that._geocoderServices, geocodeType); + return geocode(that, that._geocoderServices, geocodeType); } }); @@ -418,29 +421,20 @@ function flyToDestination(viewModel, destination) { }); } -function chainPromise(promise, geocoderService, query, geocodeType) { - return promise.then(function (result) { - if ( - defined(result) && - result.state === "fulfilled" && - result.value.length > 0 - ) { - return result; - } - const nextPromise = geocoderService - .geocode(query, geocodeType) - .then(function (result) { - return { state: "fulfilled", value: result }; - }) - .catch(function (err) { - return { state: "rejected", reason: err }; - }); - - return nextPromise; - }); +async function attemptGeocode(geocoderService, query, geocodeType) { + try { + const result = await geocoderService.geocode(query, geocodeType); + return { + state: "fulfilled", + value: result, + credits: geocoderService.credit, + }; + } catch (error) { + return { state: "rejected", reason: error }; + } } -function geocode(viewModel, geocoderServices, geocodeType) { +async function geocode(viewModel, geocoderServices, geocodeType) { const query = viewModel._searchText; if (hasOnlyWhitespace(query)) { @@ -449,31 +443,84 @@ function geocode(viewModel, geocoderServices, geocodeType) { } viewModel._isSearchInProgress = true; + viewModel._wasGeocodeCancelled = false; - let promise = Promise.resolve(); - for (let i = 0; i < geocoderServices.length; i++) { - promise = chainPromise(promise, geocoderServices[i], query, geocodeType); - } - - viewModel._geocodePromise = promise; - promise.then(function (result) { - if (promise.cancel) { + let i; + let result; + for (i = 0; i < geocoderServices.length; i++) { + if (viewModel._wasGeocodeCancelled) { return; } - viewModel._isSearchInProgress = false; - const geocoderResults = result.value; + result = await attemptGeocode(geocoderServices[i], query, geocodeType); if ( + defined(result) && result.state === "fulfilled" && - defined(geocoderResults) && - geocoderResults.length > 0 + result.value.length > 0 ) { - viewModel._searchText = geocoderResults[0].displayName; - viewModel.destinationFound(viewModel, geocoderResults[0].destination); - return; + break; } - viewModel._searchText = `${query} (not found)`; - }); + } + + if (viewModel._wasGeocodeCancelled) { + return; + } + + viewModel._isSearchInProgress = false; + clearCredits(viewModel); + + const geocoderResults = result.value; + if ( + result.state === "fulfilled" && + defined(geocoderResults) && + geocoderResults.length > 0 + ) { + viewModel._searchText = geocoderResults[0].displayName; + viewModel.destinationFound(viewModel, geocoderResults[0].destination); + const credits = updateCredits( + viewModel, + GeocoderService.getCreditsFromResult(geocoderResults[0]) + ); + // If the result does not contain any credits, default to the service credit. + if (!defined(credits)) { + updateCredit(viewModel, geocoderServices[i].credit); + } + return; + } + + viewModel._searchText = `${query} (not found)`; +} + +function updateCredit(viewModel, credit) { + if ( + defined(credit) && + !viewModel._scene.isDestroyed() && + !viewModel._scene.frameState.creditDisplay.isDestroyed() + ) { + viewModel._scene.frameState.creditDisplay.addStaticCredit(credit); + viewModel._previousCredits.push(credit); + } +} + +function updateCredits(viewModel, credits) { + if (defined(credits)) { + credits.forEach((credit) => updateCredit(viewModel, credit)); + } + + return credits; +} + +function clearCredits(viewModel) { + if ( + !viewModel._scene.isDestroyed() && + !viewModel._scene.frameState.creditDisplay.isDestroyed() + ) { + viewModel._previousCredits.forEach((credit) => { + viewModel._scene.frameState.creditDisplay.removeStaticCredit(credit); + }); + } + + viewModel._previousCredits.length = 0; } function adjustSuggestionsScroll(viewModel, focusedItemIndex) { @@ -496,10 +543,9 @@ function adjustSuggestionsScroll(viewModel, focusedItemIndex) { } function cancelGeocode(viewModel) { - viewModel._isSearchInProgress = false; - if (defined(viewModel._geocodePromise)) { - viewModel._geocodePromise.cancel = true; - viewModel._geocodePromise = undefined; + if (viewModel._isSearchInProgress) { + viewModel._isSearchInProgress = false; + viewModel._wasGeocodeCancelled = true; } } @@ -511,7 +557,7 @@ function clearSuggestions(viewModel) { knockout.getObservable(viewModel, "_suggestions").removeAll(); } -function updateSearchSuggestions(viewModel) { +async function updateSearchSuggestions(viewModel) { if (!viewModel.autoComplete) { return; } @@ -523,26 +569,29 @@ function updateSearchSuggestions(viewModel) { return; } - let promise = Promise.resolve([]); - viewModel._geocoderServices.forEach(function (service) { - promise = promise.then(function (results) { - if (results.length >= 5) { - return results; + clearCredits(viewModel); + + for (const service of viewModel._geocoderServices) { + const newResults = await service.geocode(query, GeocodeType.AUTOCOMPLETE); + viewModel._suggestions = viewModel._suggestions.concat(newResults); + if (newResults.length > 0) { + let useDefaultCredit = true; + newResults.forEach((result) => { + const credits = GeocoderService.getCreditsFromResult(result); + useDefaultCredit = useDefaultCredit && !defined(credits); + updateCredits(viewModel, credits); + }); + + // Use the service credit if there were no attributions in the results + if (useDefaultCredit) { + updateCredit(viewModel, service.credit); } - return service - .geocode(query, GeocodeType.AUTOCOMPLETE) - .then(function (newResults) { - results = results.concat(newResults); - return results; - }); - }); - }); - return promise.then(function (results) { - const suggestions = viewModel._suggestions; - for (let i = 0; i < results.length; i++) { - suggestions.push(results[i]); } - }); + + if (viewModel._suggestions.length >= 5) { + return; + } + } } /** @@ -554,4 +603,20 @@ GeocoderViewModel.flyToDestination = flyToDestination; //exposed for testing GeocoderViewModel._updateSearchSuggestions = updateSearchSuggestions; GeocoderViewModel._adjustSuggestionsScroll = adjustSuggestionsScroll; + +/** + * @returns {boolean} true if the object has been destroyed, false otherwise. + */ +GeocoderViewModel.prototype.isDestroyed = function () { + return false; +}; + +/** + * Destroys the widget. Should be called if permanently + * removing the widget from layout. + */ +GeocoderViewModel.prototype.destroy = function () { + clearCredits(this); + return destroyObject(this); +}; export default GeocoderViewModel; diff --git a/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js b/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js index 033491f365d..60985592782 100644 --- a/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js +++ b/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js @@ -1,4 +1,4 @@ -import { Cartesian3, Rectangle } from "@cesium/engine"; +import { Cartesian3, Credit, Rectangle } from "@cesium/engine"; import { GeocoderViewModel } from "../../index.js"; import createScene from "../../../../Specs/createScene.js"; import pollToPromise from "../../../../Specs/pollToPromise.js"; @@ -62,56 +62,71 @@ describe( scene.destroyForSpecs(); }); + let geocoderViewModel; + afterEach(function () { + geocoderViewModel = geocoderViewModel && geocoderViewModel.destroy(); + }); + it("constructor sets expected properties", function () { const flightDuration = 1234; - const viewModel = new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, flightDuration: flightDuration, }); - expect(viewModel.scene).toBe(scene); - expect(viewModel.flightDuration).toBe(flightDuration); - expect(viewModel.keepExpanded).toBe(false); + expect(geocoderViewModel.scene).toBe(scene); + expect(geocoderViewModel.flightDuration).toBe(flightDuration); + expect(geocoderViewModel.keepExpanded).toBe(false); }); it("can get and set flight duration", function () { - const viewModel = new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, }); - viewModel.flightDuration = 324; - expect(viewModel.flightDuration).toEqual(324); + geocoderViewModel.flightDuration = 324; + expect(geocoderViewModel.flightDuration).toEqual(324); expect(function () { - viewModel.flightDuration = -123; + geocoderViewModel.flightDuration = -123; }).toThrowDeveloperError(); }); it("throws is searchText is not a string", function () { - const viewModel = new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); expect(function () { - viewModel.searchText = undefined; + geocoderViewModel.searchText = undefined; }).toThrowDeveloperError(); }); - it("moves camera when search command invoked", function () { - const viewModel = new GeocoderViewModel({ + it("moves camera when search command invoked", async function () { + let destinationFoundCallback; + + const promise = new Promise((resolve) => { + destinationFoundCallback = async function (viewModel, destination) { + await GeocoderViewModel.flyToDestination(viewModel, destination); + resolve(); + }; + }); + + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], + destinationFound: destinationFoundCallback, }); const cameraPosition = Cartesian3.clone(scene.camera.position); - viewModel.searchText = "220 Valley Creek Blvd, Exton, PA"; - viewModel.search(); - - return pollToPromise(function () { + geocoderViewModel.searchText = "220 Valley Creek Blvd, Exton, PA"; + await geocoderViewModel.search(); + await pollToPromise(function () { scene.tweens.update(); return !Cartesian3.equals(cameraPosition, scene.camera.position); }); + await expectAsync(promise).toBeResolved(); }); it("constructor throws without scene", function () { @@ -120,7 +135,7 @@ describe( }).toThrowDeveloperError(); }); - it("raises the complete event camera finished", function () { + it("raises the complete event camera finished", async function () { let destinationFoundCallback; const promise = new Promise((resolve) => { @@ -130,7 +145,7 @@ describe( ); }; }); - const viewModel = new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, flightDuration: 0, geocoderServices: [customGeocoderOptions], @@ -138,169 +153,240 @@ describe( }); const spyListener = jasmine.createSpy("listener"); - viewModel.complete.addEventListener(spyListener); - - viewModel.searchText = "-1.0, -2.0"; - viewModel.search(); + geocoderViewModel.complete.addEventListener(spyListener); - return promise.then(function () { - expect(spyListener.calls.count()).toBe(1); - - viewModel.flightDuration = 1.5; - viewModel.searchText = "2.0, 2.0"; - viewModel.search(); - - return pollToPromise(function () { - scene.tweens.update(); - return spyListener.calls.count() === 2; - }); - }); + geocoderViewModel.searchText = "-1.0, -2.0"; + await geocoderViewModel.search(); + await promise; + expect(spyListener.calls.count()).toBe(1); }); it("can be created with a custom geocoder", function () { expect(function () { - return new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], }); }).not.toThrowDeveloperError(); }); - it("automatic suggestions can be retrieved", function () { - const geocoder = new GeocoderViewModel({ + it("automatic suggestions can be retrieved", async function () { + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); - geocoder._searchText = "some_text"; - GeocoderViewModel._updateSearchSuggestions(geocoder).then(function () { - expect(geocoder._suggestions.length).toEqual(3); - }); + geocoderViewModel._searchText = "some_text"; + await GeocoderViewModel._updateSearchSuggestions(geocoderViewModel); + expect(geocoderViewModel._suggestions.length).toEqual(3); + expect(destinationFoundCallback).not.toHaveBeenCalled(); }); - it("update search suggestions results in empty list if the query is empty", function () { - const geocoder = new GeocoderViewModel({ + it("update search suggestions results in empty list if the query is empty", async function () { + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); - geocoder._searchText = ""; + geocoderViewModel._searchText = ""; - GeocoderViewModel._updateSearchSuggestions(geocoder); - expect(geocoder._suggestions.length).toEqual(0); + await GeocoderViewModel._updateSearchSuggestions(geocoderViewModel); + expect(geocoderViewModel._suggestions.length).toEqual(0); + expect(destinationFoundCallback).not.toHaveBeenCalled(); }); it("can activate selected search suggestion", function () { - spyOn(GeocoderViewModel, "flyToDestination"); + const destinationFoundCallback = jasmine.createSpy(); const destination = new Rectangle(0.0, -0.1, 0.1, 0.1); - const geocoder = new GeocoderViewModel({ + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); const suggestion = { displayName: "a", destination: destination }; - geocoder._selectedSuggestion = suggestion; - geocoder.activateSuggestion(suggestion); - expect(geocoder._searchText).toEqual("a"); - expect(GeocoderViewModel.flyToDestination).toHaveBeenCalledWith( - geocoder, + geocoderViewModel._selectedSuggestion = suggestion; + geocoderViewModel.activateSuggestion(suggestion); + expect(geocoderViewModel._searchText).toEqual("a"); + expect(destinationFoundCallback).toHaveBeenCalledWith( + geocoderViewModel, destination ); }); - it("if more than one geocoder service is provided, use first result from first geocode in array order", function () { - spyOn(GeocoderViewModel, "flyToDestination"); - - let destinationFoundCallback; - - const promise = new Promise((resolve) => { - destinationFoundCallback = function (viewModel, destination) { - resolve(); - GeocoderViewModel.flyToDestination(viewModel, destination); - }; - }); - const geocoder = new GeocoderViewModel({ + it("if more than one geocoder service is provided, use first result from first geocode in array order", async function () { + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [noResultsGeocoder, customGeocoderOptions2], - destinationFound: destinationFoundCallback, - }); - geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding - - geocoder.search(); - return promise.then(function () { - expect(geocoder._searchText).toEqual(geocoderResults2[0].displayName); - expect(GeocoderViewModel.flyToDestination).toHaveBeenCalledWith( - geocoder, - mockDestination - ); + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); + geocoderViewModel._searchText = "sthsnth"; // an empty query will prevent geocoding + + await geocoderViewModel.search(); + expect(geocoderViewModel._searchText).toEqual( + geocoderResults2[0].displayName + ); + expect(destinationFoundCallback).toHaveBeenCalledWith( + geocoderViewModel, + mockDestination + ); }); - it("can update autoComplete suggestions list using multiple geocoders", function () { - const geocoder = new GeocoderViewModel({ + it("can update autoComplete suggestions list using multiple geocoders", async function () { + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions, customGeocoderOptions2], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); - geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding - GeocoderViewModel._updateSearchSuggestions(geocoder).then(function () { - expect(geocoder._suggestions.length).toEqual( - geocoderResults1.length + geocoderResults2.length - ); - }); + geocoderViewModel._searchText = "sthsnth"; // an empty query will prevent geocoding + await GeocoderViewModel._updateSearchSuggestions(geocoderViewModel); + expect(geocoderViewModel._suggestions.length).toEqual( + geocoderResults1.length + geocoderResults2.length + ); + expect(destinationFoundCallback).not.toHaveBeenCalled(); }); - it("uses custom destination found callback", function () { + it("uses custom destination found callback", async function () { spyOn(GeocoderViewModel, "flyToDestination"); - let destinationFoundCallback; - - const promise = new Promise((resolve) => { - destinationFoundCallback = jasmine - .createSpy() - .and.callFake(function () { - resolve(); - }); - }); - const geocoder = new GeocoderViewModel({ + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [noResultsGeocoder, customGeocoderOptions2], destinationFound: destinationFoundCallback, }); - geocoder._searchText = "sthsnth"; // an empty query will prevent geocoding - geocoder.search(); - return promise.then(function () { - expect(geocoder._searchText).toEqual(geocoderResults2[0].displayName); - expect(GeocoderViewModel.flyToDestination).not.toHaveBeenCalled(); - expect(destinationFoundCallback).toHaveBeenCalledWith( - geocoder, - mockDestination - ); - }); + geocoderViewModel._searchText = "sthsnth"; // an empty query will prevent geocoding + await geocoderViewModel.search(); + // await promise; + expect(geocoderViewModel._searchText).toEqual( + geocoderResults2[0].displayName + ); + expect(GeocoderViewModel.flyToDestination).not.toHaveBeenCalled(); + expect(destinationFoundCallback).toHaveBeenCalledWith( + geocoderViewModel, + mockDestination + ); }); it("automatic suggestions can be navigated by arrow up/down keys", function () { spyOn(GeocoderViewModel, "_adjustSuggestionsScroll"); - const viewModel = new GeocoderViewModel({ + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode }); - viewModel._searchText = "some_text"; - return GeocoderViewModel._updateSearchSuggestions(viewModel).then( + geocoderViewModel._searchText = "some_text"; + return GeocoderViewModel._updateSearchSuggestions(geocoderViewModel).then( function () { - expect(viewModel._selectedSuggestion).toEqual(undefined); - viewModel._handleArrowDown(viewModel); - expect(viewModel._selectedSuggestion.displayName).toEqual("a"); - viewModel._handleArrowDown(viewModel); - viewModel._handleArrowDown(viewModel); - expect(viewModel._selectedSuggestion.displayName).toEqual("c"); - viewModel._handleArrowDown(viewModel); - expect(viewModel._selectedSuggestion.displayName).toEqual("a"); - viewModel._handleArrowDown(viewModel); - viewModel._handleArrowUp(viewModel); - expect(viewModel._selectedSuggestion.displayName).toEqual("a"); - viewModel._handleArrowUp(viewModel); - expect(viewModel._selectedSuggestion).toBeUndefined(); + expect(geocoderViewModel._selectedSuggestion).toEqual(undefined); + geocoderViewModel._handleArrowDown(geocoderViewModel); + expect(geocoderViewModel._selectedSuggestion.displayName).toEqual( + "a" + ); + geocoderViewModel._handleArrowDown(geocoderViewModel); + geocoderViewModel._handleArrowDown(geocoderViewModel); + expect(geocoderViewModel._selectedSuggestion.displayName).toEqual( + "c" + ); + geocoderViewModel._handleArrowDown(geocoderViewModel); + expect(geocoderViewModel._selectedSuggestion.displayName).toEqual( + "a" + ); + geocoderViewModel._handleArrowDown(geocoderViewModel); + geocoderViewModel._handleArrowUp(geocoderViewModel); + expect(geocoderViewModel._selectedSuggestion.displayName).toEqual( + "a" + ); + geocoderViewModel._handleArrowUp(geocoderViewModel); + expect(geocoderViewModel._selectedSuggestion).toBeUndefined(); + expect(destinationFoundCallback).not.toHaveBeenCalled(); } ); }); + + it("updates credits based on returned results", async function () { + const geocoderResults = [ + { + displayName: "a", + destination: mockDestination, + attributions: [ + { + html: "attribution", + }, + ], + }, + { + displayName: "b", + destination: mockDestination, + }, + { + displayName: "c", + destination: mockDestination, + }, + ]; + const geocoderOptions = { + autoComplete: true, + geocode: function (input) { + return Promise.resolve(geocoderResults); + }, + credit: new Credit("custom credit", false), + }; + + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ + scene: scene, + geocoderServices: [geocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode + }); + geocoderViewModel._searchText = "sthsnth"; // an empty query will prevent geocoding + + await geocoderViewModel.search(); + + scene.frameState.creditDisplay.beginFrame(); + scene.frameState.creditDisplay.endFrame(); + + const credits = scene.frameState.creditDisplay._staticCredits; + expect(credits.length).toBe(2); // first credit will be default ion credit + expect(credits[1]).toBeInstanceOf(Credit); + expect(credits[1].html).toEqual("attribution"); + expect(credits[1].showOnScreen).toBeFalse(); + expect(destinationFoundCallback).toHaveBeenCalled(); + }); + + it("uses default geocoder service credit if not present in results", async function () { + const geocoderOptions = { + autoComplete: true, + geocode: function (input) { + return Promise.resolve(geocoderResults1); + }, + credit: new Credit("custom credit", false), + }; + + const destinationFoundCallback = jasmine.createSpy(); + geocoderViewModel = new GeocoderViewModel({ + scene: scene, + geocoderServices: [geocoderOptions], + destinationFound: destinationFoundCallback, // Don't move the camera after a successful geocode + }); + geocoderViewModel._searchText = "sthsnth"; // an empty query will prevent geocoding + + await geocoderViewModel.search(); + + scene.frameState.creditDisplay.beginFrame(); + scene.frameState.creditDisplay.endFrame(); + + const credits = scene.frameState.creditDisplay._staticCredits; + expect(credits.length).toBe(2); // first credit will be default ion credit + expect(credits[1]).toBeInstanceOf(Credit); + expect(credits[1].html).toEqual("custom credit"); + expect(credits[1].showOnScreen).toBeFalse(); + expect(destinationFoundCallback).toHaveBeenCalled(); + }); }, "WebGL" ); From 8aaf8ba1584af25b4d0964b700c113209b79bf06 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 27 Apr 2023 13:24:34 -0400 Subject: [PATCH 646/679] Cleanup geocoder services, update CHANGES.md --- CHANGES.md | 10 +++++----- .../Source/Core/CartographicGeocoderService.js | 15 +++++++++++++++ .../engine/Source/Core/OpenCageGeocoderService.js | 2 +- .../Specs/Core/CartographicGeocoderServiceSpec.js | 10 +++++++++- .../engine/Specs/Core/IonGeocoderServiceSpec.js | 2 +- .../widgets/Source/Geocoder/GeocoderViewModel.js | 4 ++-- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bf8d308967a..dad73a5d0a6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,10 +7,10 @@ ##### Additions :tada: - Added `ArcGisMapServerImagery.fromBasemapType`, and `ArcGisBaseMapType`, and `ArcGisMapService` for ease of use with the latest ArcGIS Imagery API.[#11098](https://github.com/CesiumGS/cesium/pull/11098) -- Added `CesiumWidget.creditDisplay` to access the onscreen and lightbox credits. +- Added `CesiumWidget.creditDisplay` to access the onscreen and lightbox credits. [#11241](https://github.com/CesiumGS/cesium/pull/11241) - Added `CreditDisplay.addStaticCredit` and `CreditDisplay.removeStaticCredit` such that `Credit.showOnScreen` value is taken into account. [#6215](https://github.com/CesiumGS/cesium/issues/6215) - Added `options.gltfCallback` to `Model.loadGltfAsync` to allow apps to access the loaded glTF JSON. [#11240](https://github.com/CesiumGS/cesium/pull/11240) -- Added `GeocoderService.credit` and and `attributions` property to `GeocoderService.Result` to allow for geocoder services to attribute results. +- Added `GeocoderService.credit` and and `attributions` property to `GeocoderService.Result` to allow for geocoder services to attribute results. [#11256](https://github.com/CesiumGS/cesium/pull/11256) ##### Fixes :wrench: @@ -28,14 +28,14 @@ ##### Deprecated :hourglass_flowing_sand: -- `CreditDisplay.addCredit`, `CreditDisplay.addDefaultCredit`, and `CreditDisplay.removeDefaultCredit` have been deprecated in CesiumJS 1.105. They will be removed in 1.107. Use `CreditDisplay.addCreditToNextFrame`, `CreditDisplay.addStaticCredit`, and `CreditDisplay.removeStaticCredit` respectively instead. +- `CreditDisplay.addCredit`, `CreditDisplay.addDefaultCredit`, and `CreditDisplay.removeDefaultCredit` have been deprecated in CesiumJS 1.105. They will be removed in 1.107. Use `CreditDisplay.addCreditToNextFrame`, `CreditDisplay.addStaticCredit`, and `CreditDisplay.removeStaticCredit` respectively instead. [#11241](https://github.com/CesiumGS/cesium/pull/11241) #### @cesium/widgets ##### Additions :tada: -- Added `Viewer.creditDisplay` to access the onscreen and lightbox credits. -- The `Geocoder` widget will now display attributions onscreen or in the lightbox for geocoder results if present, otherwise a default credit from a geocoder service if one is provided. +- Added `Viewer.creditDisplay` to access the onscreen and lightbox credits. [#11241](https://github.com/CesiumGS/cesium/pull/11241) +- The `Geocoder` widget will now display attributions onscreen or in the lightbox for geocoder results if present, otherwise a default credit from a geocoder service if one is provided. [#11256](https://github.com/CesiumGS/cesium/pull/11256) ##### Fixes :wrench: diff --git a/packages/engine/Source/Core/CartographicGeocoderService.js b/packages/engine/Source/Core/CartographicGeocoderService.js index 35a6ebd0b10..149edc6270c 100644 --- a/packages/engine/Source/Core/CartographicGeocoderService.js +++ b/packages/engine/Source/Core/CartographicGeocoderService.js @@ -10,6 +10,21 @@ import Check from "./Check.js"; */ function CartographicGeocoderService() {} +Object.defineProperties(CartographicGeocoderService.prototype, { + /** + * Gets the credit to display after a geocode is performed. Typically this is used to credit + * the geocoder service. + * @memberof CartographicGeocoderService.prototype + * @type {Credit|undefined} + * @readonly + */ + credit: { + get: function () { + return undefined; + }, + }, +}); + /** * @function * diff --git a/packages/engine/Source/Core/OpenCageGeocoderService.js b/packages/engine/Source/Core/OpenCageGeocoderService.js index 593285a9707..139a7f194f2 100644 --- a/packages/engine/Source/Core/OpenCageGeocoderService.js +++ b/packages/engine/Source/Core/OpenCageGeocoderService.js @@ -81,7 +81,7 @@ Object.defineProperties(OpenCageGeocoderService.prototype, { /** * Gets the credit to display after a geocode is performed. Typically this is used to credit * the geocoder service. - * @memberof PeliasGeocoderService.prototype + * @memberof OpenCageGeocoderService.prototype * @type {Credit|undefined} * @readonly */ diff --git a/packages/engine/Specs/Core/CartographicGeocoderServiceSpec.js b/packages/engine/Specs/Core/CartographicGeocoderServiceSpec.js index fed7eeeb8fa..98fb8ae1802 100644 --- a/packages/engine/Specs/Core/CartographicGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/CartographicGeocoderServiceSpec.js @@ -1,8 +1,16 @@ -import { Cartesian3, CartographicGeocoderService } from "../../index.js"; +import { + Cartesian3, + CartographicGeocoderService, + GeocoderService, +} from "../../index.js"; describe("Core/CartographicGeocoderService", function () { const service = new CartographicGeocoderService(); + it("conforms to GeocoderService interface", function () { + expect(CartographicGeocoderService).toConformToInterface(GeocoderService); + }); + it("returns cartesian with matching coordinates for NS/EW input", function () { const query = "35N 75W"; return service.geocode(query).then(function (results) { diff --git a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js index a35e1249b33..e5bb50e8e53 100644 --- a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js @@ -65,7 +65,7 @@ describe("Core/IonGeocoderService", function () { expect(service.credit).toBeInstanceOf(Credit); expect(service.credit.html).toEqual( - `<img src="http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png"/>` + `<img src="https:\/\/ion.cesium.com\/Images\/attributes\/geocoder.png"\/>` ); expect(service.credit.showOnScreen).toBe(false); }); diff --git a/packages/widgets/Source/Geocoder/GeocoderViewModel.js b/packages/widgets/Source/Geocoder/GeocoderViewModel.js index 3f8709d6ba3..7d0912a7bc4 100644 --- a/packages/widgets/Source/Geocoder/GeocoderViewModel.js +++ b/packages/widgets/Source/Geocoder/GeocoderViewModel.js @@ -565,12 +565,12 @@ async function updateSearchSuggestions(viewModel) { const query = viewModel._searchText; clearSuggestions(viewModel); + clearCredits(viewModel); + if (hasOnlyWhitespace(query)) { return; } - clearCredits(viewModel); - for (const service of viewModel._geocoderServices) { const newResults = await service.geocode(query, GeocodeType.AUTOCOMPLETE); viewModel._suggestions = viewModel._suggestions.concat(newResults); From 2bd8dadacc8f429ff0e286d3cd688d197449e96e Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Thu, 27 Apr 2023 14:26:55 -0400 Subject: [PATCH 647/679] Remove default ion geocoder credit --- .../engine/Source/Core/IonGeocoderService.js | 6 +--- .../Source/Core/PeliasGeocoderService.js | 1 + .../Specs/Core/IonGeocoderServiceSpec.js | 7 +--- .../Specs/Core/PeliasGeocoderServiceSpec.js | 36 +++++++++++++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Core/IonGeocoderService.js b/packages/engine/Source/Core/IonGeocoderService.js index 0f7eba7732a..7ff6f6260d2 100644 --- a/packages/engine/Source/Core/IonGeocoderService.js +++ b/packages/engine/Source/Core/IonGeocoderService.js @@ -49,10 +49,6 @@ function IonGeocoderService(options) { this._accessToken = accessToken; this._server = server; this._pelias = new PeliasGeocoderService(searchEndpoint); - this._credit = new Credit( - `<img src="https:\/\/ion.cesium.com\/Images\/attributes\/geocoder.png"\/>`, - false - ); } Object.defineProperties(IonGeocoderService.prototype, { @@ -65,7 +61,7 @@ Object.defineProperties(IonGeocoderService.prototype, { */ credit: { get: function () { - return this._credit; + return undefined; }, }, }); diff --git a/packages/engine/Source/Core/PeliasGeocoderService.js b/packages/engine/Source/Core/PeliasGeocoderService.js index fd63305eddf..30da8c2c43c 100644 --- a/packages/engine/Source/Core/PeliasGeocoderService.js +++ b/packages/engine/Source/Core/PeliasGeocoderService.js @@ -98,6 +98,7 @@ PeliasGeocoderService.prototype.geocode = async function (query, type) { return { displayName: resultObject.properties.label, destination: destination, + attributions: results.attributions, }; }); }); diff --git a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js index e5bb50e8e53..43b490eab0a 100644 --- a/packages/engine/Specs/Core/IonGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/IonGeocoderServiceSpec.js @@ -1,5 +1,4 @@ import { - Credit, GeocoderService, GeocodeType, Ion, @@ -63,10 +62,6 @@ describe("Core/IonGeocoderService", function () { it("credit returns expected value", async function () { const service = new IonGeocoderService({ scene: scene }); - expect(service.credit).toBeInstanceOf(Credit); - expect(service.credit.html).toEqual( - `<img src="https:\/\/ion.cesium.com\/Images\/attributes\/geocoder.png"\/>` - ); - expect(service.credit.showOnScreen).toBe(false); + expect(service.credit).toBeUndefined(); }); }); diff --git a/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js b/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js index 2dc01182261..a12b2cc1899 100644 --- a/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js +++ b/packages/engine/Specs/Core/PeliasGeocoderServiceSpec.js @@ -45,6 +45,42 @@ describe("Core/PeliasGeocoderService", function () { expect(results[0].destination).toBeInstanceOf(Cartesian3); }); + it("returns geocoder results with attributions", async function () { + const service = new PeliasGeocoderService("http://test.invalid/v1/"); + + const query = "some query"; + const data = { + attributions: [ + { + html: `Credit`, + collapsible: true, + }, + ], + features: [ + { + type: "Feature", + geometry: { + type: "Point", + coordinates: [-75.172489, 39.927828], + }, + properties: { + label: "1826 S 16th St, Philadelphia, PA, USA", + }, + }, + ], + }; + spyOn(Resource.prototype, "fetchJson").and.returnValue( + Promise.resolve(data) + ); + + const results = await service.geocode(query); + expect(results.length).toEqual(1); + expect(results[0].displayName).toEqual(data.features[0].properties.label); + expect(results[0].destination).toBeInstanceOf(Cartesian3); + expect(results[0].attributions.length).toBe(1); + expect(results[0].attributions[0].html).toEqual("Credit"); + }); + it("returns no geocoder results if Pelias has no results", async function () { const service = new PeliasGeocoderService("http://test.invalid/v1/"); From e9abc4105c24f7f796fdcc356415a1c613f5188d Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 28 Apr 2023 10:42:22 -0400 Subject: [PATCH 648/679] De-dupe static credits --- packages/engine/Source/Scene/CreditDisplay.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 02aae3dbb0a..91260d7aa0e 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -598,6 +598,16 @@ CreditDisplay.prototype.beginFrame = function () { const creditCollection = staticCredit.showOnScreen ? screenCredits : lightboxCredits; + + if ( + staticCredit._isIon && + Credit.equals(CreditDisplay.cesiumCredit, this._cesiumCredit) + ) { + // If this is the an ion logo credit from the ion server, + // make sure to remove de-duplicate with the default ion credit + continue; + } + setCredit(this, creditCollection, staticCredit, Number.MAX_VALUE); } From 55ccd4459f347de1d11376d7527a6d417d586e04 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <jeshurun@cesium.com> Date: Fri, 28 Apr 2023 15:07:55 -0400 Subject: [PATCH 649/679] Fix typos in comments --- packages/engine/Source/Scene/CreditDisplay.js | 4 ++-- packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/Scene/CreditDisplay.js b/packages/engine/Source/Scene/CreditDisplay.js index 91260d7aa0e..4dda7c57ac6 100644 --- a/packages/engine/Source/Scene/CreditDisplay.js +++ b/packages/engine/Source/Scene/CreditDisplay.js @@ -603,8 +603,8 @@ CreditDisplay.prototype.beginFrame = function () { staticCredit._isIon && Credit.equals(CreditDisplay.cesiumCredit, this._cesiumCredit) ) { - // If this is the an ion logo credit from the ion server, - // make sure to remove de-duplicate with the default ion credit + // If this is an ion logo credit from the ion server, + // make sure to de-duplicate with the default ion credit continue; } diff --git a/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js b/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js index 60985592782..25976391640 100644 --- a/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js +++ b/packages/widgets/Specs/Geocoder/GeocoderViewModelSpec.js @@ -92,7 +92,7 @@ describe( }).toThrowDeveloperError(); }); - it("throws is searchText is not a string", function () { + it("throws if searchText is not a string", function () { geocoderViewModel = new GeocoderViewModel({ scene: scene, geocoderServices: [customGeocoderOptions], From 787a86a636e3c599744792c62bf169cb8783b1e3 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 1 May 2023 09:34:16 -0400 Subject: [PATCH 650/679] Changes for 1.105 release --- CHANGES.md | 8 ++++---- ThirdParty.json | 6 +++--- package.json | 8 ++++---- packages/engine/Source/Core/Ion.js | 2 +- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index dad73a5d0a6..0cd0a34efc7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,16 +15,16 @@ ##### Fixes :wrench: - Fixed Repeated URI parsing slows 3D Tiles performance [#11197](https://github.com/CesiumGS/cesium/issues/11197). Together with [#11211](https://github.com/CesiumGS/cesium/pull/11211), this can reduce tile parsing time by as much as 25% on large tilesets -- Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) -- Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) - Fixed atmosphere rendering performance issue. [10510](https://github.com/CesiumGS/cesium/issues/10510) -- Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) -- Fixed UniformType.MAT3 value for custom shaders. [#11235](https://github.com/CesiumGS/cesium/pull/11235). - Fixed crashing when zooming to an entity without globe present. [#10957](https://github.com/CesiumGS/cesium/pull/11226) +- Fixed model rendering when emissiveTexture is defined and emissiveFactor is not. [#11215](https://github.com/CesiumGS/cesium/pull/11215) +- Fixed issue with calling `switchToOrthographicFunction` and `camera.flyTo` in immediate succession. [#11210](https://github.com/CesiumGS/cesium/pull/11210) +- Fixed an issue when zooming in an orthographic frustum. [#11206](https://github.com/CesiumGS/cesium/pull/11206) - Fixed a crash when Cesium3DTileStyle's scaleByDistance, translucencyByDistance or distanceDisplayCondition set to StyleExpression which returns `undefined`. [#11228](https://github.com/CesiumGS/cesium/pull/11228) - Fixed handling of `out_FragColor` layout declarations when translating shaders to WebGL1. [#11230](https://github.com/CesiumGS/cesium/pull/11230) - Fixed a problem with Ambient Occlusion that affected some MacOS hardware. [#10106](https://github.com/CesiumGS/cesium/issues/10106) +- Fixed UniformType.MAT3 value for custom shaders. [#11235](https://github.com/CesiumGS/cesium/pull/11235). ##### Deprecated :hourglass_flowing_sand: diff --git a/ThirdParty.json b/ThirdParty.json index 799d0c9ed08..a3c3deaacb0 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -36,7 +36,7 @@ "license": [ "Apache-2.0" ], - "version": "2.4.5", + "version": "3.0.2", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -77,7 +77,7 @@ "license": [ "ISC" ], - "version": "3.0.0", + "version": "4.0.2", "url": "https://www.npmjs.com/package/kdbush" }, { @@ -101,7 +101,7 @@ "license": [ "MIT" ], - "version": "0.4.5", + "version": "0.5.0", "url": "https://www.npmjs.com/package/ktx-parse" }, { diff --git a/package.json b/package.json index 766a0b1ab96..ac0ad100e08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.104.0", + "version": "1.105.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.2.0", - "@cesium/widgets": "2.1.1" + "@cesium/engine": "2.3.0", + "@cesium/widgets": "2.2.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.276.0", @@ -167,4 +167,4 @@ "packages/engine", "packages/widgets" ] -} +} \ No newline at end of file diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index 874652dbe41..31536200251 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,7 +4,7 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYjk1OWEzOS0wM2UzLTQ1MmItYjVhNi0xOGE2NDAyNDc4ZjYiLCJpZCI6MjU5LCJpYXQiOjE2ODA1MzgxNTl9.ANfifMhFxb5agKqgDghPl1R__jvaz6dcEbkoNFM-txE"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwZWQ3OWFlZC1kOTg3LTRlZjctYTAyYy0xNjFmODE1MWE2NGUiLCJpZCI6MjU5LCJpYXQiOjE2ODI5NDYzODh9.DEH4GpqliH-xsDE7h-ZCICtHgnGu32wdSjt4hFqw7lU"; /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/package.json b/packages/engine/package.json index e36d29a700d..ef127fc219e 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "2.2.0", + "version": "2.3.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index eb17b13a769..9395cc18574 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "2.1.1", + "version": "2.2.0", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "2.2.0", + "@cesium/engine": "2.3.0", "nosleep.js": "^0.12.0" }, "type": "module", From a1b0da48e14ef76abfabfaf4a8a2d6ff26b17559 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 1 May 2023 10:33:58 -0400 Subject: [PATCH 651/679] Tweak doc formatting --- .../Scene/ArcGisMapServerImageryProvider.js | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index c278359b783..92d6aa3ce82 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -279,31 +279,30 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { * * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are * used, if available. + * + * <br/> + * + * An {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security| ArcGIS Access Token } is required to authenticate requests to an ArcGIS Image Tile service. + * To access secure ArcGIS resources, it's required to create an ArcGIS developer + * account or an ArcGIS online account, then implement an authentication method to obtain an access token. * * @alias ArcGisMapServerImageryProvider * @constructor * * @param {ArcGisMapServerImageryProvider.ConstructorOptions} [options] Object describing initialization options * - * @see ArcGisMapServerImagery.fromBasemapType - * @see ArcGisMapServerImagery.fromUrl - * @see BingMapsImageryProvider - * @see GoogleEarthEnterpriseMapsProvider - * @see OpenStreetMapImageryProvider - * @see SingleTileImageryProvider - * @see TileMapServiceImageryProvider - * @see WebMapServiceImageryProvider - * @see WebMapTileServiceImageryProvider - * @see UrlTemplateImageryProvider + * @see ArcGisMapServerImageryProvider.fromBasemapType + * @see ArcGisMapServerImageryProvider.fromUrl * * @example - * // Add a base layer from a default ArcGIS Basemap + * // Set the default access token for accessing ArcGIS Image Tile service + * Cesium.ArcGisMapService.defaultAccessToken = "<ArcGIS Access Token>"; + * + * // Add a base layer from a default ArcGIS basemap * const viewer = new Cesium.Viewer("cesiumContainer", { * baseLayer: Cesium.ImageryLayer.fromProviderAsync( * Cesium.ArcGisMapServerImageryProvider.fromBasemapType( - * Cesium.ArcGisBaseMapType.SATELLITE, { - * token: "<ArcGIS Access Token>" - * } + * Cesium.ArcGisBaseMapType.SATELLITE * ) * ), * }); @@ -317,9 +316,7 @@ async function requestMetadata(resource, imageryProviderBuilder, provider) { * * @see {@link https://developers.arcgis.com/rest/|ArcGIS Server REST API} * @see {@link https://developers.arcgis.com/documentation/mapping-apis-and-services/security| ArcGIS Access Token } - * is required to authenticate requests to an ArcGIS Image Tile service. - * To access secure ArcGIS resources, you need to create an ArcGIS developer - * account or an ArcGIS online account, then implement an authentication method to obtain an access token. + */ function ArcGisMapServerImageryProvider(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -412,10 +409,12 @@ function ArcGisMapServerImageryProvider(options) { * @returns {Promise<ArcGisMapServerImageryProvider>} A promise that resolves to the created ArcGisMapServerImageryProvider. * * @example + * // Set the default access token for accessing ArcGIS Image Tile service + * Cesium.ArcGisMapService.defaultAccessToken = "<ArcGIS Access Token>"; + * + * // Add a base layer from a default ArcGIS basemap * const provider = await Cesium.ArcGisMapServerImageryProvider.fromBasemapType( - * Cesium.ArcGisBaseMapType.SATELLITE, { - * token: "<ArcGIS Access Token>" - * }); + * Cesium.ArcGisBaseMapType.SATELLITE); * * @example * // Add a base layer from a default ArcGIS Basemap From 92049b8092e190b0dfc114dadba279e67f5085e6 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 3 May 2023 14:21:20 -0400 Subject: [PATCH 652/679] Adjust camera controls for 3D --- CHANGES.md | 8 ++ .../Scene/ScreenSpaceCameraController.js | 132 ++++++++++++++---- 2 files changed, 111 insertions(+), 29 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0cd0a34efc7..ae332b41f27 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.106 - 2023-06-01 + +#### @cesium/engine + +##### Fixes :wrench: + +- Improved camera controls for panning on 3D Tiles and fixed camera controls when globe is off. [#7171](https://github.com/CesiumGS/cesium/issues/7171) + ### 1.105 - 2023-05-01 #### @cesium/engine diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index c08c3c298aa..e95bf0cd457 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -217,7 +217,7 @@ function ScreenSpaceCameraController(scene) { modifier: KeyboardEventModifier.SHIFT, }; /** - * The minimum height the camera must be before picking the terrain instead of the ellipsoid. + * The minimum height the camera must be before picking the terrain or scene content instead of the ellipsoid. * @type {number} * @default 150000.0 */ @@ -611,19 +611,22 @@ function handleZoom( object._zoomMouseStart ); - if (defined(object._globe)) { - if (mode === SceneMode.SCENE2D) { - pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay) - .origin; - pickedPosition = Cartesian3.fromElements( - pickedPosition.y, - pickedPosition.z, - pickedPosition.x - ); - } else { - pickedPosition = pickGlobe(object, startPosition, scratchPickCartesian); - } + if (defined(object._globe) && mode === SceneMode.SCENE2D) { + pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay) + .origin; + pickedPosition = Cartesian3.fromElements( + pickedPosition.y, + pickedPosition.z, + pickedPosition.x + ); + } else { + pickedPosition = pickPosition( + object, + startPosition, + scratchPickCartesian + ); } + if (defined(pickedPosition)) { object._useZoomWorldPosition = true; object._zoomWorldPosition = Cartesian3.clone( @@ -709,7 +712,7 @@ function handleZoom( const centerPixel = scratchCenterPixel; centerPixel.x = canvas.clientWidth / 2; centerPixel.y = canvas.clientHeight / 2; - const centerPosition = pickGlobe( + const centerPosition = pickPosition( object, centerPixel, scratchCenterPosition @@ -1107,17 +1110,11 @@ const pickGlobeScratchRay = new Ray(); const scratchDepthIntersection = new Cartesian3(); const scratchRayIntersection = new Cartesian3(); -function pickGlobe(controller, mousePosition, result) { +function pickPosition(controller, mousePosition, result) { const scene = controller._scene; const globe = controller._globe; const camera = scene.camera; - if (!defined(globe)) { - return undefined; - } - - const cullBackFaces = !controller._cameraUnderground; - let depthIntersection; if (scene.pickPositionSupported) { depthIntersection = scene.pickPositionWorldCoordinates( @@ -1126,6 +1123,14 @@ function pickGlobe(controller, mousePosition, result) { ); } + if ( + !defined(globe) || + (defined(depthIntersection) && !globe.translucency.enabled) + ) { + return Cartesian3.clone(depthIntersection, result); + } + + const cullBackFaces = !controller._cameraUnderground; const ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); const rayIntersection = globe.pickWorldCoordinates( ray, @@ -1289,7 +1294,8 @@ function translateCV(controller, startPosition, movement) { let globePos; if (camera.position.z < controller._minimumPickingTerrainHeight) { - globePos = pickGlobe(controller, startMouse, translateCVStartPos); + globePos = pickPosition(controller, startMouse, translateCVStartPos); + if (defined(globePos)) { origin.x = globePos.x; } @@ -1476,7 +1482,7 @@ function rotateCVOnTerrain(controller, startPosition, movement) { center = Cartesian3.clone(controller._tiltCenter, rotateCVCenter); } else { if (camera.position.z < controller._minimumPickingTerrainHeight) { - center = pickGlobe(controller, startPosition, rotateCVCenter); + center = pickPosition(controller, startPosition, rotateCVCenter); } if (!defined(center)) { @@ -1711,7 +1717,7 @@ function zoomCV(controller, startPosition, movement) { let intersection; if (height < controller._minimumPickingTerrainHeight) { - intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); + intersection = pickPosition(controller, windowPosition, zoomCVIntersection); } let distance; @@ -1918,7 +1924,7 @@ function spin3D(controller, startPosition, movement) { const globe = controller._globe; if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - const mousePos = pickGlobe( + const mousePos = pickPosition( controller, movement.startPosition, scratchMousePos @@ -2051,6 +2057,7 @@ const pan3DTemp2 = new Cartesian3(); const pan3DTemp3 = new Cartesian3(); const pan3DStartMousePosition = new Cartesian2(); const pan3DEndMousePosition = new Cartesian2(); +const pan3DDiffMousePosition = new Cartesian2(); function pan3D(controller, startPosition, movement, ellipsoid) { const scene = controller._scene; @@ -2064,9 +2071,76 @@ function pan3D(controller, startPosition, movement, ellipsoid) { movement.endPosition, pan3DEndMousePosition ); + const height = ellipsoid.cartesianToCartographic( + camera.positionWC, + scratchCartographic + ).height; - let p0 = camera.pickEllipsoid(startMousePosition, ellipsoid, pan3DP0); - let p1 = camera.pickEllipsoid(endMousePosition, ellipsoid, pan3DP1); + let p0, p1; + + if ( + !movement.inertiaEnabled && + height < controller._minimumPickingTerrainHeight + ) { + p0 = pickPosition(controller, startMousePosition, pan3DP0); + + if (defined(p0)) { + let tanPhi = 1.0; + let tanTheta = 1.0; + + if (defined(camera.frustum.fovy)) { + tanPhi *= 2 * Math.tan(camera.frustum.fovy * 0.5); + tanTheta *= camera.frustum.aspectRatio * tanPhi; + } + + const distance = Math.abs(Cartesian3.distance(camera.positionWC, p0)); + const dragDelta = Cartesian2.subtract( + endMousePosition, + startMousePosition, + pan3DDiffMousePosition + ); + const x = (dragDelta.x * scene.pixelRatio) / scene.drawingBufferWidth; + const y = (-dragDelta.y * scene.pixelRatio) / scene.drawingBufferHeight; + + // Move the camera to the the distance the cursor moved in worldspace + const right = Cartesian3.multiplyByScalar( + camera.rightWC, + x * distance * tanTheta, + pan3DTemp1 + ); + + // Move the camera forward the distance the cursor moved in worldspace as the camera is pointed tangent to the ellipsoid + const cameraPositionNormal = Cartesian3.normalize( + camera.positionWC, + scratchCameraPositionNormal + ); + let dot = Math.abs( + Cartesian3.dot(camera.directionWC, cameraPositionNormal) + ); + const direction = Cartesian3.multiplyByScalar( + camera.directionWC, + y * (1.0 - dot) * 2 * distance, + pan3DTemp2 + ); + + // Move the camera up the distance the cursor moved in worldspace as the camera is pointed towards the center + dot = Math.abs(Cartesian3.dot(camera.upWC, cameraPositionNormal)); + const up = Cartesian3.multiplyByScalar( + camera.upWC, + y * (1.0 - dot) * distance * tanPhi, + pan3DTemp3 + ); + + p1 = Cartesian3.add(p0, right, pan3DP1); + p1 = Cartesian3.add(p1, direction, p1); + p1 = Cartesian3.add(p1, up, p1); + } + } + + if (!defined(p0)) { + p0 = camera.pickEllipsoid(startMousePosition, ellipsoid, pan3DP0); + p1 = camera.pickEllipsoid(endMousePosition, ellipsoid, pan3DP1); + } if (!defined(p0) || !defined(p1)) { controller._rotating = true; @@ -2205,7 +2279,7 @@ function zoom3D(controller, startPosition, movement) { ? approachingCollision : height < controller._minimumPickingTerrainHeight; if (needPickGlobe) { - intersection = pickGlobe(controller, windowPosition, zoomCVIntersection); + intersection = pickPosition(controller, windowPosition, zoomCVIntersection); } let distance; @@ -2397,7 +2471,7 @@ function tilt3DOnTerrain(controller, startPosition, movement) { if (Cartesian2.equals(startPosition, controller._tiltCenterMousePosition)) { center = Cartesian3.clone(controller._tiltCenter, tilt3DCenter); } else { - center = pickGlobe(controller, startPosition, tilt3DCenter); + center = pickPosition(controller, startPosition, tilt3DCenter); if (!defined(center)) { ray = camera.getPickRay(startPosition, tilt3DRay); From 8f6e3ec7c516f2d199cd6b9a1000480d10b19602 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Fri, 5 May 2023 11:18:06 -0400 Subject: [PATCH 653/679] Use first picked position in drag when possible --- .../Source/Scene/ScreenSpaceCameraController.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index e95bf0cd457..09a736d4f2e 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -291,6 +291,8 @@ function ScreenSpaceCameraController(scene) { this._zoomMouseStart = new Cartesian2(-1.0, -1.0); this._zoomWorldPosition = new Cartesian3(); this._useZoomWorldPosition = false; + this._panLastMousePosition = new Cartesian2(); + this._panLastWorldPosition = new Cartesian3(); this._tiltCVOffMap = false; this._looking = false; this._rotating = false; @@ -2082,7 +2084,17 @@ function pan3D(controller, startPosition, movement, ellipsoid) { !movement.inertiaEnabled && height < controller._minimumPickingTerrainHeight ) { - p0 = pickPosition(controller, startMousePosition, pan3DP0); + p0 = Cartesian3.clone(controller._panLastWorldPosition, pan3DP0); + + // Use the last picked world position unless we're starting a new drag + if ( + !Cartesian2.equalsEpsilon( + startMousePosition, + controller._panLastMousePosition + ) + ) { + p0 = pickPosition(controller, startMousePosition, pan3DP0); + } if (defined(p0)) { let tanPhi = 1.0; @@ -2134,6 +2146,9 @@ function pan3D(controller, startPosition, movement, ellipsoid) { p1 = Cartesian3.add(p0, right, pan3DP1); p1 = Cartesian3.add(p1, direction, p1); p1 = Cartesian3.add(p1, up, p1); + + Cartesian3.clone(p1, controller._panLastWorldPosition); + Cartesian2.clone(endMousePosition, controller._panLastMousePosition); } } From b35ac36855e3dc1534985bfd75628b3d60e0cb4b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Mon, 8 May 2023 14:54:10 -0400 Subject: [PATCH 654/679] Make sure availability tiles are loaded before deciding there is no terrain at that x, y, level --- .../Source/Core/CesiumTerrainProvider.js | 28 ++++++++++++++++ .../engine/Source/Core/TileAvailability.js | 32 +++++++++---------- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index c1cb21357ce..d0fe20a8a5a 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -915,6 +915,34 @@ CesiumTerrainProvider.prototype.requestTileGeometry = function ( layerToUse = layer; break; } + + if (!defined(layer.availabilityLevels)) { + // This layer doesn't use cutout terrain, so we don't need to do the following check + continue; + } + + const tile = getAvailabilityTile(layer, x, y, level); + if ( + !defined(tile) || + !layer.availability.isTileAvailable(tile.level, tile.x, tile.y) || + layer.availabilityTilesLoaded.isTileAvailable( + tile.level, + tile.x, + tile.y + ) + ) { + continue; + } + + // There are some cases where availability tiles are not completely loaded at this point. Request them now. + return requestTileGeometry( + this, + tile.x, + tile.y, + tile.level, + layer, + request + ); } } diff --git a/packages/engine/Source/Core/TileAvailability.js b/packages/engine/Source/Core/TileAvailability.js index 0a6a74a3eed..2a4bec88d07 100644 --- a/packages/engine/Source/Core/TileAvailability.js +++ b/packages/engine/Source/Core/TileAvailability.js @@ -396,10 +396,10 @@ function findMaxLevelFromNode(stopNode, node, position) { // Find the deepest quadtree node containing this point. let found = false; while (!found) { - const nw = node._nw && rectangleContainsPosition(node._nw.extent, position); - const ne = node._ne && rectangleContainsPosition(node._ne.extent, position); - const sw = node._sw && rectangleContainsPosition(node._sw.extent, position); - const se = node._se && rectangleContainsPosition(node._se.extent, position); + const nw = node.nw && rectangleContainsPosition(node.nw.extent, position); + const ne = node.ne && rectangleContainsPosition(node.ne.extent, position); + const sw = node.sw && rectangleContainsPosition(node.sw.extent, position); + const se = node.se && rectangleContainsPosition(node.se.extent, position); // The common scenario is that the point is in only one quadrant and we can simply // iterate down the tree. But if the point is on a boundary between tiles, it is @@ -408,36 +408,36 @@ function findMaxLevelFromNode(stopNode, node, position) { if (nw) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node._nw, position) + findMaxLevelFromNode(node, node.nw, position) ); } if (ne) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node._ne, position) + findMaxLevelFromNode(node, node.ne, position) ); } if (sw) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node._sw, position) + findMaxLevelFromNode(node, node.sw, position) ); } if (se) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node._se, position) + findMaxLevelFromNode(node, node.se, position) ); } break; } else if (nw) { - node = node._nw; + node = node.nw; } else if (ne) { - node = node._ne; + node = node.ne; } else if (sw) { - node = node._sw; + node = node.sw; } else if (se) { - node = node._se; + node = node.se; } else { found = true; } @@ -501,10 +501,10 @@ function updateCoverageWithNode( } // Update with child nodes. - updateCoverageWithNode(remainingToCoverByLevel, node._nw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._ne, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._sw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node._se, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node.nw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node.ne, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node.sw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node.se, rectanglesToCover); } function subtractRectangle(rectangleList, rectangleToSubtract) { From 6a4e6fa925b131f4097c38b0439cca9b19100091 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Tue, 9 May 2023 17:40:07 -0400 Subject: [PATCH 655/679] Use pick position direction for panning --- .../Scene/ScreenSpaceCameraController.js | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 09a736d4f2e..47d28e501eb 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2060,6 +2060,8 @@ const pan3DTemp3 = new Cartesian3(); const pan3DStartMousePosition = new Cartesian2(); const pan3DEndMousePosition = new Cartesian2(); const pan3DDiffMousePosition = new Cartesian2(); +const pan3DPixelDimensions = new Cartesian2(); +const panRay = new Ray(); function pan3D(controller, startPosition, movement, ellipsoid) { const scene = controller._scene; @@ -2097,41 +2099,41 @@ function pan3D(controller, startPosition, movement, ellipsoid) { } if (defined(p0)) { - let tanPhi = 1.0; - let tanTheta = 1.0; - - if (defined(camera.frustum.fovy)) { - tanPhi *= 2 * Math.tan(camera.frustum.fovy * 0.5); - tanTheta *= camera.frustum.aspectRatio * tanPhi; - } - const distance = Math.abs(Cartesian3.distance(camera.positionWC, p0)); + const pixelDimensions = camera.frustum.getPixelDimensions( + scene.drawingBufferWidth, + scene.drawingBufferHeight, + distance - camera.frustum.near, + scene.pixelRatio, + pan3DPixelDimensions + ); const dragDelta = Cartesian2.subtract( endMousePosition, startMousePosition, pan3DDiffMousePosition ); - const x = (dragDelta.x * scene.pixelRatio) / scene.drawingBufferWidth; - const y = (-dragDelta.y * scene.pixelRatio) / scene.drawingBufferHeight; // Move the camera to the the distance the cursor moved in worldspace const right = Cartesian3.multiplyByScalar( camera.rightWC, - x * distance * tanTheta, + dragDelta.x * pixelDimensions.x, pan3DTemp1 ); - // Move the camera forward the distance the cursor moved in worldspace as the camera is pointed tangent to the ellipsoid + // Move the camera towards the picked position in worldspace as the camera is pointed towards a horizon view const cameraPositionNormal = Cartesian3.normalize( camera.positionWC, scratchCameraPositionNormal ); - let dot = Math.abs( - Cartesian3.dot(camera.directionWC, cameraPositionNormal) - ); + const pickDirection = camera.getPickRay(startMousePosition, panRay) + .direction; + let dot = Math.abs(Cartesian3.dot(pickDirection, cameraPositionNormal)); + let magnitude = -dragDelta.y * (1.0 - dot) * pixelDimensions.y * 2.0; + dot = Math.abs(Cartesian3.dot(camera.directionWC, cameraPositionNormal)); + magnitude += -dragDelta.y * (1.0 - dot) * pixelDimensions.y * 2.0; const direction = Cartesian3.multiplyByScalar( - camera.directionWC, - y * (1.0 - dot) * 2 * distance, + pickDirection, + magnitude, pan3DTemp2 ); @@ -2139,7 +2141,7 @@ function pan3D(controller, startPosition, movement, ellipsoid) { dot = Math.abs(Cartesian3.dot(camera.upWC, cameraPositionNormal)); const up = Cartesian3.multiplyByScalar( camera.upWC, - y * (1.0 - dot) * distance * tanPhi, + -dragDelta.y * (1.0 - dot) * pixelDimensions.y, pan3DTemp3 ); From 1b5c133d5fcfe3e98b5cf54456080d3bca121469 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 10 May 2023 09:47:16 -0400 Subject: [PATCH 656/679] Only use new camera controls when globe is false --- CHANGES.md | 2 +- .../Scene/ScreenSpaceCameraController.js | 38 ++++++++++++++----- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ae332b41f27..3510b99f7e6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ ##### Fixes :wrench: -- Improved camera controls for panning on 3D Tiles and fixed camera controls when globe is off. [#7171](https://github.com/CesiumGS/cesium/issues/7171) +- Improved camera controls when globe is off. [#7171](https://github.com/CesiumGS/cesium/issues/7171) ### 1.105 - 2023-05-01 diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 47d28e501eb..a17aeca252c 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -2090,6 +2090,7 @@ function pan3D(controller, startPosition, movement, ellipsoid) { // Use the last picked world position unless we're starting a new drag if ( + !scene.globe && !Cartesian2.equalsEpsilon( startMousePosition, controller._panLastMousePosition @@ -2098,15 +2099,22 @@ function pan3D(controller, startPosition, movement, ellipsoid) { p0 = pickPosition(controller, startMousePosition, pan3DP0); } - if (defined(p0)) { - const distance = Math.abs(Cartesian3.distance(camera.positionWC, p0)); + if (!scene.globe && defined(p0)) { + const toCenter = Cartesian3.subtract(p0, camera.positionWC, pan3DTemp1); + const toCenterProj = Cartesian3.multiplyByScalar( + camera.directionWC, + Cartesian3.dot(camera.directionWC, toCenter), + pan3DTemp1 + ); + const distanceToNearPlane = Cartesian3.magnitude(toCenterProj); const pixelDimensions = camera.frustum.getPixelDimensions( scene.drawingBufferWidth, scene.drawingBufferHeight, - distance - camera.frustum.near, + distanceToNearPlane, scene.pixelRatio, pan3DPixelDimensions ); + const dragDelta = Cartesian2.subtract( endMousePosition, startMousePosition, @@ -2125,14 +2133,24 @@ function pan3D(controller, startPosition, movement, ellipsoid) { camera.positionWC, scratchCameraPositionNormal ); - const pickDirection = camera.getPickRay(startMousePosition, panRay) + const endPickDirection = camera.getPickRay(endMousePosition, panRay) .direction; - let dot = Math.abs(Cartesian3.dot(pickDirection, cameraPositionNormal)); - let magnitude = -dragDelta.y * (1.0 - dot) * pixelDimensions.y * 2.0; - dot = Math.abs(Cartesian3.dot(camera.directionWC, cameraPositionNormal)); - magnitude += -dragDelta.y * (1.0 - dot) * pixelDimensions.y * 2.0; + const endPickProj = Cartesian3.subtract( + endPickDirection, + Cartesian3.projectVector(endPickDirection, camera.rightWC, pan3DTemp2), + pan3DTemp2 + ); + const angle = Cartesian3.angleBetween(endPickProj, camera.directionWC); + const forward = Math.max(Math.tan(angle), 0.1); // Clamp so we don't make this value infinitely large when the angle is small + let dot = Math.abs( + Cartesian3.dot(camera.directionWC, cameraPositionNormal) + ); + const magnitude = + ((-dragDelta.y * pixelDimensions.y) / Math.sqrt(forward)) * + 2 * + (1.0 - dot); const direction = Cartesian3.multiplyByScalar( - pickDirection, + endPickDirection, magnitude, pan3DTemp2 ); @@ -2154,7 +2172,7 @@ function pan3D(controller, startPosition, movement, ellipsoid) { } } - if (!defined(p0)) { + if (!defined(p0) || !defined(p1)) { p0 = camera.pickEllipsoid(startMousePosition, ellipsoid, pan3DP0); p1 = camera.pickEllipsoid(endMousePosition, ellipsoid, pan3DP1); } From 46042ef2ec2a4fc8e9a2e4e75e92c8d9739a94ec Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 10 May 2023 11:47:48 -0400 Subject: [PATCH 657/679] Spin3d should fallback to old behavior when globe is defined --- .../Source/Scene/ScreenSpaceCameraController.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index a17aeca252c..5878c5492ab 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -1926,9 +1926,9 @@ function spin3D(controller, startPosition, movement) { const globe = controller._globe; if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - const mousePos = pickPosition( - controller, + const mousePos = camera.pickEllipsoid( movement.startPosition, + controller._ellipsoid, scratchMousePos ); if (defined(mousePos)) { @@ -2090,7 +2090,7 @@ function pan3D(controller, startPosition, movement, ellipsoid) { // Use the last picked world position unless we're starting a new drag if ( - !scene.globe && + !defined(controller._globe) && !Cartesian2.equalsEpsilon( startMousePosition, controller._panLastMousePosition @@ -2099,7 +2099,7 @@ function pan3D(controller, startPosition, movement, ellipsoid) { p0 = pickPosition(controller, startMousePosition, pan3DP0); } - if (!scene.globe && defined(p0)) { + if (!defined(controller._globe) && defined(p0)) { const toCenter = Cartesian3.subtract(p0, camera.positionWC, pan3DTemp1); const toCenterProj = Cartesian3.multiplyByScalar( camera.directionWC, @@ -2141,13 +2141,15 @@ function pan3D(controller, startPosition, movement, ellipsoid) { pan3DTemp2 ); const angle = Cartesian3.angleBetween(endPickProj, camera.directionWC); - const forward = Math.max(Math.tan(angle), 0.1); // Clamp so we don't make this value infinitely large when the angle is small + let forward = 1.0; + if (defined(camera.frustum.fov)) { + forward = Math.max(Math.tan(angle), 0.1); // Clamp so we don't make the magnitude infinitely large when the angle is small + } let dot = Math.abs( Cartesian3.dot(camera.directionWC, cameraPositionNormal) ); const magnitude = - ((-dragDelta.y * pixelDimensions.y) / Math.sqrt(forward)) * - 2 * + ((-dragDelta.y * pixelDimensions.y * 2.0) / Math.sqrt(forward)) * (1.0 - dot); const direction = Cartesian3.multiplyByScalar( endPickDirection, From f33188bba950b650532921f2b6d742bf8ca00deb Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 10 May 2023 12:06:51 -0400 Subject: [PATCH 658/679] pick globe on spin3d --- .../Source/Scene/ScreenSpaceCameraController.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 5878c5492ab..7aecb7cbc9b 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -1834,7 +1834,6 @@ const scratchStrafeRay = new Ray(); const scratchStrafePlane = new Plane(Cartesian3.UNIT_X, 0.0); const scratchStrafeIntersection = new Cartesian3(); const scratchStrafeDirection = new Cartesian3(); -const scratchMousePos = new Cartesian3(); function strafe(controller, movement, strafeStartPosition) { const scene = controller._scene; @@ -1926,10 +1925,13 @@ function spin3D(controller, startPosition, movement) { const globe = controller._globe; if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - const mousePos = camera.pickEllipsoid( - movement.startPosition, - controller._ellipsoid, - scratchMousePos + const ray = camera.getPickRay(startPosition, pickGlobeScratchRay); + const cullBackFaces = !controller._cameraUnderground; + const mousePos = globe.pickWorldCoordinates( + ray, + scene, + cullBackFaces, + scratchRayIntersection ); if (defined(mousePos)) { let strafing = false; From 3206a789576c9675a4dd3a56a8bc3678dd33169b Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 10 May 2023 13:40:03 -0400 Subject: [PATCH 659/679] Fallback to old behavior for spin3d --- .../Source/Scene/ScreenSpaceCameraController.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index 7aecb7cbc9b..d83065068c2 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -1125,10 +1125,7 @@ function pickPosition(controller, mousePosition, result) { ); } - if ( - !defined(globe) || - (defined(depthIntersection) && !globe.translucency.enabled) - ) { + if (!defined(globe)) { return Cartesian3.clone(depthIntersection, result); } @@ -1874,6 +1871,7 @@ const scratchRadii = new Cartesian3(); const scratchEllipsoid = new Ellipsoid(); const scratchLookUp = new Cartesian3(); const scratchNormal = new Cartesian3(); +const scratchMousePosition = new Cartesian3(); function spin3D(controller, startPosition, movement) { const scene = controller._scene; @@ -1925,13 +1923,10 @@ function spin3D(controller, startPosition, movement) { const globe = controller._globe; if (defined(globe) && height < controller._minimumPickingTerrainHeight) { - const ray = camera.getPickRay(startPosition, pickGlobeScratchRay); - const cullBackFaces = !controller._cameraUnderground; - const mousePos = globe.pickWorldCoordinates( - ray, - scene, - cullBackFaces, - scratchRayIntersection + const mousePos = pickPosition( + controller, + movement.startPosition, + scratchMousePosition ); if (defined(mousePos)) { let strafing = false; From 8e3861e23d9562c3381edd0dfc944e3ca5e28369 Mon Sep 17 00:00:00 2001 From: Gabby Getz <gabby@cesium.com> Date: Wed, 10 May 2023 14:08:59 -0400 Subject: [PATCH 660/679] Updates for Google Photorealistic 3D Tiles --- ...alistic 3D Tiles with Building Insert.html | 127 ++++++++++++++++++ ...ealistic 3D Tiles with Building Insert.jpg | Bin 0 -> 81604 bytes .../Google Photorealistic 3D Tiles.html | 77 +++++++++++ .../Google Photorealistic 3D Tiles.jpg | Bin 0 -> 76182 bytes CHANGES.md | 7 +- .../Contributors/ReleaseGuide/README.md | 51 +++---- packages/engine/Source/Core/GoogleMaps.js | 56 ++++++++ packages/engine/Source/Core/Ion.js | 1 + .../engine/Source/Core/RequestScheduler.js | 1 + packages/engine/Source/Core/Resource.js | 13 ++ .../engine/Source/Scene/ArcGisMapService.js | 1 + .../engine/Source/Scene/Cesium3DTileset.js | 3 +- packages/engine/Source/Scene/Model/Model.js | 8 +- .../createGooglePhotorealistic3DTileset.js | 53 ++++++++ 14 files changed, 368 insertions(+), 30 deletions(-) create mode 100644 Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.html create mode 100644 Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.jpg create mode 100644 Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.html create mode 100644 Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.jpg create mode 100644 packages/engine/Source/Core/GoogleMaps.js create mode 100644 packages/engine/Source/Scene/createGooglePhotorealistic3DTileset.js diff --git a/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.html b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.html new file mode 100644 index 00000000000..5cd69c623b2 --- /dev/null +++ b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.html @@ -0,0 +1,127 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta + name="viewport" + content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" + /> + <meta + name="description" + content="Use Viewer to start building new applications or easily embed Cesium into existing applications." + /> + <meta name="cesium-sandcastle-labels" content="Beginner, Showcases" /> + <title>Cesium Demo + + + + + +
+

Loading...

+
+ + + diff --git a/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.jpg b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles with Building Insert.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c8e5a1de9d438994abab4662d00d848cc84d89be GIT binary patch literal 81604 zcmbTcbx@o?7%sZFLxEz&*~O)}yHlLvP^7rCEKVs_92Qs#6o&%Ein|tyJH=U?MT#sg zr4%^)&N*|=%>C=$n{P7n%_NiLdGaQC^X7S4dfEiMc%!VQ3_w9a0h~R5fTt}0my*Ae zJpiDo3E%(#0NBrEd;rwvKiud1>Nx{cyzK1UA&ws2fTtCJ0sspG0}}%s3ljqq8w(2? zmlzKh2M3po=mkD8CD|(~N-|0cYC2X%YFcJm3Q8s(CT2EvPA<+@46g-VbMUiraB}?D z2nrT9HZBhCOFX=n95j?P9RHuwQxAX`8^sru9}R^GfJ%&lMvU^*51us7m;7NV zh1fv(x?VE9UuPhJ_g>*Rxa1U+RIiv>SlQS)1cih}M8(7v6qS@!RMpDPJ`3D3>e2R>Uj){$frG8FJ&-jv=^|h$DohT`X%bDHDGf_DlJc!n$4@pn%>P*?X^Fxa1(g zE#~w8p#4u||L=f>|Nlbve}Mg8TyOwB8p`wJp%DXQ0Ozk`o&Xp6|BRjh*4a}JG}ozw zDSnciAl<|Sei2@(+nV5WXr>KTyid%j;5(kTQpXq3K}t@PRFp7d{GHS5gDc9*U=79g z+@6+L#u%~XS3L8&zp);hItxj1J2Bx(9kb9tG1juI9jw1 zDDRCgy{;ucI~r|VPK2D+X^GRGd^G;Alc0BteL-T!FirmR&8)3CGw%K|K}Zt&DiS8N ze?mi!H;duiNssGsV&}Ly@0wYZJn))Om_LnZJ^-)Pi!*Cr^}ObobJJhx3D7;jK3$U} zK_PP*cXf59i0G#P+{ogm~_ngxeM@hYIB97=GHocjva{dv_$P`=&&pdW72j zPDAZiNbKhaEK@FtJeh~c;D`SI-CV=Z*AF+Gi~E19gWO&wNtfGyUEt&1A7i|DStR}O zbmC{qP?O9fnO3py_rSCSm|#VRej7Y-*!S+EE;L}M)Pk+n{Cu|1l791Z16ZE`s_hXIEu1Vb z$#ELRKTk^Az=*b#ruyP_OG+l1%L++QByaiMmjIXQZnD|!$`XICC*`co&r=IGNchX2 z0Ksv_SDKo(+6^m`^(S|RM46YzSTbpW)kSBAmm0NQt*vuzCPb*35@LPF#pWm2iM$gR4;w%RA?9E&p-RyT@_j z?Y2az5ChlveEsaLim)R*RwZ+8{^GkzGHm~D~g0Q5m z6Uc7@a@r||$G+~B(0C}qzrfLGd6(kxp6saZgHV=oB4&d|K74TLbN#g!GV}zft@+XV<94Y;oa_XX7_zZX zc9efs^Xf=_*8SMSMy0!HgGOK{lNopN5Zjy$jwwRdcpnmZn<3(5rc$wdmm-qJ$T#{@ z{b6DNAQSfQKf8Yd97`Yz0-Ubb*~AHMZ;hS@c-&%1$Yl1iwPntLN#7`M+pV9+Cb5?I zt&}aze(7w^L`aXwN4nYlyuHT-6SvL=LE`Aq$_9>P)!tpAm&QB+mN$gO#$3WR67*Z2 zJUoUWdP(>$C1^ac<-~{FpeF$C$p_)31;o!v0bm8Ew>^g}ee8hm%$Fj5?1XKl!M&-I z*}cI)Isj`PmhMc+M!|d%RsESvtjBG@E1^;3(BJD9CzIgBKWnqiP8(+t{>cb&o6yyS z;RxUgOIQ6ct^B%&_#SUvX(oNv#Qk(gM-HJlWJr?K;G259u`bCvQ^`l$wLI0+ks*(% zqqnC-3PX!M7AzSO-m9BdPk>^TC%}O269Ah&RtwcBLAxwnTIT!|Y|%jD$2!qkpIq$R zVU7|txn7J9&HM9PK#vla= zL3`AhNK9Hx5QZUbV!y%@z`n*py-g#LM4Ms~5NTv1fDcIsEk=l42};&Cd@1oY=Sx(m zV6@_kh`dXp&5*IUs$rPE5ZHW8jNtrc>%Hy&N9J~3^n>KNDCZM^goIfK)gyLc{Zl|Nyi!zp-F+JXlBo3DrVPvvK4 z70>DOkUz4LZ}d}2s|6O3x*_KV)czFx>Wf;Ex0i?~z;@-*UT)SlJ8MVO?!UDIO8cF# zWY5lo)QGEZ>YS5DUKziDisOQPfqw`3H%c!36IkH=aUhIN7isH7v`s-K@{eQ9Tv=r8 zpkg2nDNxIBzw604EgbxHo6}4plWH_6XDsr=YrNc|eD^;>Qq^$;c}saaKfY**0rFNc zrd&ygO3Ox0F{8gEMFrM^f`4diZf^S`5}p9Q+0O>MV#0T7a=gs1U*8x_d6dKY<8C0Z z815QRx;J{Q=x`g)$Wam)Ue$<@eq7CSE`+YR7sZVa+cLlg^;8tX5(}Wwz~;cf%38@~ zY3d`AovMjAq=e^1JuEoP!U^~XQYoHeVT>^-=VVUwfZ0V*z2BJlHGSS>2R#-)pLgVF z_V4r}+VQ!j;7}l{#p>$jSky80&jc$!F{&GCt(?v35lw-~#jVL|s8_(;b z82JR~f8d<4YOt?^eQc9qQ*wm{0YWA@azxkzjgEVZ;yv{z?@*|AYAN@z7SB$s2f@D9 z-k$Vl-`ZO@Gdv&(FmAC3~byLuAhtUm$%X-h7a7aw`Nw`s+2up9hS9Y%DC|1Z}IAYFWK zUmibVsN~YzmFg=jmJQYo5A;3_yY&6-xMvlx`h!r&;61@fPQRz{=)R=y&mcOd)3ZLa z3;kZdl2yAKWZZ95tlJm{@X$gRrh0kA>)ar&IE4qq?!I$gn7TVUw7{lD%ClfVDCU)0 z{{$V?n8&+ROL#l@N^?w(VY_dTMR3)TPZ`ZYo_FJSp8K`M%_gEI09X0I$uW zzroa09pdKX>1Aq%1~`*QT?)p~cfZA);%xmB9OCf4#ZPxb!F7!pHjt*hZCc*9<+%4n zh3tS|3?4VV>Cmi&_*V&+WJGL`xmd_VXv{MQ9htRhh>-Iu<8naqGw69ZW9E;mjywJQ z?5q^b1_FQetBC0=k@=EM@@Qjgx`>zT?r>mFTI>D$DEjFA1o)%$)koUkxF#I%1WC5?JWj3Ps;(7$L?TStRIi@)f|e|f(q{9SHsQ($3^VGV+f;JZ#D zis-ZAaXRRkm;A*?50MP{23h1bN$KOlL=QI{>OU~dRxI)SeZ+WZU*DxpPR(6=dhb63Av+S4dPT4Yb z=}?A-wVu{Qd)2mc_7DBsZlJK;%q;f{I%Xsq@#6ukZQx8)Q|Wtk&9|mDd9MZ&1Ue*K z#AuO@d(Njzz;c#UbX7#r}RelD&N0DZvI(-a(0w9!pJRG`~zs`RDNT>rGifLLPh76t>rO8dEw37~&`d%zJ`9AgojMw*NuVloWO$!4=N4wYzH~@OlW0Qf+1SeaR5mp!2 z@l-w39?OHgqc^EIxEFp{AN)8exwJ%k5QqyO+E$e^FjE8W7&m*0@yIM9v3i3lSwT6%uf@()ut?+n0wKg3pFw zh+WdsX?zvK;xB@cw?t5eg0?p@M%NX^Pe^HB-{vbCL_~7f?t|Ptrbwk88`j`oZA`H3 zwF5;>LN1`rZ2#oG_j$Q9&es&>RQGYLw!ZI(w-KA_-l?lEBQb^Z##!7BCnY81&{V6IWQO9^BM9ltT^k+OyYjH!b{k9)`kyUDQ zCx!PQH5z%UHF@N_j`oLbfz%C_LJv}x@m4nvU0_INgdgkrq@T~xGfgRVktX{sP0jg% z$-jQa9e!8ccbc4SB*fXw`MYbeqL~L5wP}p$uU61@JuGRiL&yjp?^6xm7m4nqjZ4s& zob$B*)PXO2RqS&uSd*FLOP~utK%GT})-2#N5@v3OH`M;w-kw9AhcS>2M!6ob{i6v# zzTQ&!yHT53)^P^D7uq8*;s)#ciHCCcK(9%#MkZz1lyz=~B@ux4B`u9vRPXHTo1m-J`uxgmUV&Iv z#+wcoM@l_?9yBi6TWyU_4wsDiOlr1%PBi5Ba$|0iVUq$-fw<8b{0PIauWGsT_2`^! ze`sY--%TwYv;1Q0vaAONMDP!g@L~~!4eIYe_i66&Ww|!<2H8)Lp|DkwA9nQ^=BQd; z0bVFWHpBY~zdY+k{S$MW$~8ixdXD~n%-^{#^G>wbSL~+nHB&6~#B+ek4fkS+p|+m^ z(?~yPi?zk?Vscke+vJdTNf+l z^^_;(n>%Gw)fm3fYC$8H1WiQ@gs|lDR_Sen3}*zjmKd63pzZAA_`OCDG=rvRE0d9= z{1cKxO%mVx&NyPD+quFp*94-u7RRe=sM^2K=~Q);kz%eLz(w~42^D2Y=6Kl3&x{2{ zTf-m`&@|yh1TshoW)z1!v5*D0WZHUt0i8$DF6Gcf9GDRgpqUOyRaHA+kJp;_mv`V} zV#={n9*l@>{ww}c95*>A8sbLedG;sGG(BUJ9aVBPN`9v>~k zZX8~OZ{vIHcSBj;&oK=ur%a&;Eq^5-O(-1Eg8rcGJOvNH-PL3rdbN;*0XLi48}Yf_ z%UsK`#wGLvEWHh-!)RP8$rQA(V=Aiw|j>KtCW{ zuqW6Vq6FYyRO5yd&3tQf5e4!K6?m}t5BurtK<}H6(L;KIyZQ{?;uYm4Su8L$3D-Hd zjJUrY5cx9GJ)$LTTl zDrXLxcV$W|iA7;yQ)pp#20@8tx*bMlmG|WfvS_g^_V_3u2i6=C)mxT!_2r>u{os7f z7E)O&<3jIM;hfAj$^A5(_^@CvzO1H#5PK>>7F+SB?+NPtC&QI3VhpJL)!L(2Ypg)Q zcW}haK5L00Yxl)?az7QN$CoV?x*ucf?HKiKB1GJ^S)yx6pUZwKd6v2m^trDhKYEG# z?#!jGc4zy5F&ceS8ok0O;J_47dM;ygf?$iaALvt9 zf(jeDZ65Ndhw}R_J5RXSRZGB*ozvdKPBstfptQ2<8KegkDs|U0#L~a;)NA>Ig!s>O4`yi{142Ax*K9V#8&dFrWFNFBSoV zO7F4YudwtWk%qlPXBSwa(wP-rpM4w!ITZZB*6ts2Rw~_@BtE}wO@7Hs0*RQ^Ql*si zuEJsMdSQPts5b895ddmgX4JR9BUnPPhD+e1&Dop2GiUh{-<77{2wt-`)!5wfMN%j4 zG!vB%y!o}ZqMC9#oA{MzT}7~BKselfkzl0sDaJ5+(KMPRD82d;K_m;~TNNY_yZy9)~s?Tn2yz#C2eQ~-aO;`C$lC|KDG-#Odg^P zXk~;O&xb@uG?ESv3ZzauV10{|{*>A@m!83|1>jJ_mOjBn@+Her(d^eOinw1TKDr&P ztQz0JB3t7AAnjQzm=GJ1R^U)V(bm58B{RxI@y2K_0CGsQ{MDLmefZ`fr+d}wG^P*7 zn`mPMMY~&30+Rs<&x+gHFEyZeKejiyrQvcyHkz{xKCQ4Fce78#JZR)3FL;lpX{@8y z4@;-_-;AxHuE$lBgWG*F&pvJP0Z$3ltze$o3|2M^`Tl+5L%Rdy4MVi$`tc(+EOfkK zZ-{%*t^B6;bu<*jK-bq~B|?tLw>%r5A4}k3k(3p3&JN$xd`ToaJHwS2qL6AIi%_k` z#vxj_(I<}i;$K89uNZ*t&is~=hVZ(roK}w-&+wP2!55Zy5gcEWv9SE8fS$CR!xv%MTk3W55#K5eKn182a%>2D@&gb+2GTF?601D%rtT$R=FUWL<(*am z<$Qff)W-wh9&3)*kf>B!xv65?=jUjutaYe;CQRfmwud|I5NDri%2Goj-p3_7fV;H8 zNin4R^Kc=`5G6sLHY9cG`3lid&h6FJyTz|RCZHz0Cw9A+rOA&Qlf zuz8ZFz*j z0SZ}!&WT_j_IPvC?$9~iGxDXqzcA-jSv3jy0mTLa^TZcrc*^~X{uDTin?LHGb=$yL z?dfvJcOp)g7T`;?$_v{PK`W|R{p=qUQ_^|V%rW%LP_(7w?2s^i_@oJQx?q$`M+~M$ zZ8x%Q(75cbmFiFh$go`{y2=BsUPRc}xOue@|Aw1t8B>))QR#G7N%I6ux<$LsCQGV} zU8E^53tKxLkZWan=-PSxet-1^ocyv}-LrDD;MyE0R3rl3sQotZLk#g#yfMy?j9^1b8w=ji z1=*&L&d_R=rph;ry1CSeJKP*D)MuOAH5bu#-ZcZaWX;D=)D?bKVeY>DVr7N2T0-W$ zkbv?l@@xE3YRbd2dtbG~rCPY`M{~-o{$U79@`_g6;5(774}sQ(<)2KRQWp=1RO79* zM|uT%q?Q^VE*QFJHl61Eo$Njn!^r3%Bg0!N)|09|qghz$ z^zunm{(5^i1g`#Z^Y7y@lSba7edwn_P&W+8S?D4*V$>0qWJ|`s`P7-yQYF{{(V1sn zDx0F!Oou0v>n0z6k%pz?U^JkTic%5YpS5j{FRvFctZAgAu8G&5RGom_eEs>9%vcVdFMwcP z3beDY4L24_Yjly@`({5VoaH5OO4^|hlLyW9$@RR{{%}l8@GUgh1>Z!mWrlTGUWxVZ zK)M>m#{foOcKheJG{b|7jm7-8{6TnE)l@2%a7zXz+n${cAp0ceGJIks&r2X@o;rKQ z(FX@K#|6ag+eJN(i@DiHQ4IQ7vFUR<^0h~LYfqb*i2{|mN2w(gpel+xXqiLbmwKqF zMv#@yqaKfWfp=HP5}P2G1SoqKAqoAnnX@@B=Tm%0v2YO|?{Ca7wOo|OTa?D?PP6|_ zIrz^=RmXEISST^8F=JrM;9_E+6F(*zE37S4iWfJ@!#UUED_uIjYXSK!KKC|MEK7hI z+w*q>7Iic6$WXWc-ZxdQnra~F;fsC)4eNFJul7619e$`E&1shp#W%N`I>suLoVbyF z8F28Z6+(_*vCbE%dbU+0+w0WCvsd^PHKX6Xj zHUp-3{;p4Cipmbpql3DuApr`G9HIgDe4FCsU8U}L&7DOsXtH;a%*O!Z#U8Tgga%!j z;(eX4A0g{cEL8qz=Tv1%--N)IFLsG&JfA+F1TU1Q6SWZVAL%z`O3!V9f-eTBMp$>P z3NA#4sCq~C;&~bGHRn6lyQ+3O>jW~`s;T5J6N^Jt?~-(gWYSz$)R`JAOQ+C>78V2(UXnZgniR9;G@eUk_%D4DTsVT(qr;Unep%u014Y*0eQ_Z zxu{a+&tOHvi_Ow>^9lz4hD)z%94yfx2BJVSHz}n~uQ+a@>F#NnTg=Q_)@H#0FRWvb9Xc z4=s0fpV~=?m#EfEoszRcQI^g;K5<6X|GsiM5VdF}t6)Lb%u-^Nc`XzhpG3v2HFatf z$AZW`B4PuzO2x@vdTyfFWNi0qqw`D;NQ_>Vi=hQ;8ZBqzOKpdKJAp(LZY8$ z*)jP`Oq2;_F|^l#EgG-#Ro_XUV8if?_4LLgalbbRqugn$pr`yy0H}_6IoEa8N9bj1 z=2o*nSBdJI8j~N7kt4$x^KGoje)u+0k!)&lzuQQ=j;-B5P)@hRn9lG>t>aKFGBYS@ zwYKS`=BpD+4z?ct3YZ-9y*|-42tVu+pFSfLGibKT!~1vj?u)}QDt8g{6^VUThVbGX zLda|l-90BmgOkInV#olb zwyAqr^)fa`MA^B54;DeMiptj1z3roq!4;~Zog%_^W_|=eJke?<@;@hpL2;M@EUm9Z z2ofloTTq$Y?bEbYVvP9QhA52&RmHGc$RY)enu)V*{674!XYOq9F2hC>1+rgFGx zkso^@Ah#d;Ymp!T&dJaZ)P_z4yO&wZ5n6o9tEHzU1C{6+Ck$k8O1@svoy!iXXtm() z1LY<^QnuAA-NNMYeEnZGOEk}blf`}ZOCas3CWksrEjM2$r2A2g9uN{yJFs!pO#soH zl}=IF@v@oH*%JV^$X%{F^D|UACUuDX(cikOVaOu5eKW4Z#X~sP!D~@qa$zgerlqOl z)99y7VJfm^FHFj?Z~(d|_O`q0R!e&;$>>JASDVu0F=^^Te6Zo+`aqR6aFm})6}KaH zQ2J5CW<~VWtW{(#qJx55ILj4ukO5P<3EKm%Q$Qkjp>viQ07Cyw+@|tQ-y8Cq_TU|- z*iWz~#40^!($-HeZ7KhotIcY67GrB}!AucsqVYh|;lGAGDegdnu9PfR&!R~O26}TK zs&7PIOrR!!=ovI0?_uUXMUweRgXnKSMA86|CI#32amel*&sSDze$ zHsC`Z9;~9+)!H#{!~C9gBv1J@J3J)b#wIT(Az5YYwqh^av7|22&)akg*BA9@WWUR3 zW-~ole$B0OtZlxJOIM|{c|DNG`t7%ja%bV#hwRd|4c6?&>>yuo$_N$OY}Nr`(l*s` z75BHg`EO>b5i0KI0`Z<9?ZqEDpQR_=+9hJ9H|WBziPt6BokG6JrbKgPH{Sc~Gr&;d z(F%Uclu*2I%4#aUXwIe4+L2eZFn0iyZ~m+3l9B?Ch?R3c7TKPXs!27*4S9ZkA%{ha zf`GY%^qU5MCMJ7L+o;v&N#e!^?q$?RBn!+f@bAtDuU5a~v6aphN*t3)TpI~jf*Tqc z4s*y^CMO5_Fc9YKljWAGNQJgWZNFyj5xt8Ml@c9lvS>1PNH@;gjOSD}x-C!00if*o z9pxCTeWVqiRZ-*O=^IUr8OP)A)-QO!361bo7W@16l+4avF2j9Bb;eM%^7xeV1qEd)Y@VPb?i7p0*0%476hbGU^hzFD%eAq?*$dF8XmYWu)#W6b%KY zE$IMlTu&h`DxdNxcWUVK34nlKf1c@gFC}qPq+WrEIPA*gBaGYABblRME#&Jy{l%P; z-EY|<-@t4J!J++^VX4pI|MfaAh8cG{-f6a&Z*%yC5d^KnAmRxy`LSJhtZiSk6{W~H zrLEp4j~XinO{_1t-#3D+UH2uu0)2iH(fU^r$SCISxh2r|oY%!9CJ*!6YaSlWvgK|yb=UWO8{IOKPCs3pGzCIWTBvopJ&UZSv~LF- zC|Rm|8{Xc(m4BS<@cA`@!*u*`HPbnP0BP`;;g! zj5w3DeI(=53hz6fQK9Bg261*GMD>Uk_a&bIiS%&c>GHJ3#(;PHZ&cr-fOD+hBzUrU zFUsz{Q-5J{P^Ugn-jPM6M`fqP{qh3#QHOFLNGZCOI*p)W>Z)()gmGs3MhT}OI4C@^ zDfjW%8Qg4jd(p9gd1*pBEw|0hm&@kag8oA%Zf)x(%6nYJbe^J8V%HT}^w~Ds{)#Q7 z)^~~1Tsu6^d+YvU*xTbPdOq%NF$<8x(1Qx@rN&CTpj2?<<_SJ=I3nCjg^G$bi;;NM zHIW8V>ZGDTvWaYN3TC)Y4oJ%dAP#xZT|vg}_Nxla70xD6`i6tLPmad*LIk zxt~zxRsU(q*w41(6}>k6)p#>g4eHE$%F>#b4}&_K>$Z6n@PnhYXEg8Zn(e}j-a%U5R(!I3s zbV8FZyPY2Pz=C_v3&J07o06Kd{(?5?n>9WAEnBU&I|`#&zl|@}!5(8L;X`$Nex}^p zoWxSJg{Ivkp6vK?bePAlu)zH@%NK=iZYaBd28Oh-!ej6j%P zhA}dtp)TW_Y@9k!0f-|OQ_QB<4@8&@?wOQ)agp6|0q7&cK=e9*l})MkWaavXQb47- zd3ry;QnRt$TLv`7FQ*<~!gYjkSjEKlN|z-ff4x11`((PXyLm9qF(#Tswxzn-qHh&} zJAfT%2fZ}uD@R0x*+MO&4yn6uJFqbHJ+T>~%6xfF>5r@}ak4^qBHc}i@&oR-u&b$@%g4Uf?$Vj0uBYoZ52*eOBVd(B783@Ewx=`{xx41p%E>m$Hv9vx7|Oqq7n4}cT2h*1P9LoK+03#l`FJUl)riKayFXgAeND2ze+0IR=aZ

Pz#b4a`O=o?+d3G&n-t|!naFvsp!q8r z{^6@)IfU@`bEslI@4L2P*85QvEw+px`d&O@aJ6oPTCNJO%UwO?CO!$NutOHYiJZKY zN1=|`(|(=Tw#17`7&J5An0c)&E@?=IlLW!Zr%ysMuldK3YZJ2Gz1a{epz3;Os7 z7d^4G{?wUBftEH%L@9}Y7I+V^mDJOhWu4TNt*t82c)VUZNy_@>(!@NkJVTjKGu9%B z_~s&V{Pjk47s|5S2MYIW;72&(Vk!$jJ=K8a)lr-)Uj&yU4t(8H69QrkA zd;5pl=3t$}EM&<#Z04OX4;jL?qxQ?Gj@K*629gStt(O=htXK^5%w=&|79}1f9c!B2 zBi6s3JTlRNEC!aIMtR-= z;Om2w;pZsxCIY?QH1aP&t$*XaXirD5x~6LG#OCZxaAqnlj7L6`aBrWW6&y~)l4F|c ztlQYq!qrkKNma*dnG>(}`wAiB$~d)qgPabe);@bq(Ij0y_DKo!B?u3zG{FxsWDh>ZldTm!_JIL21~%j)MD|S%m!&o65wfegDKIsLy|T^PDnvwFj=;G z*)CZYA1PykZL@(97Qk%?V0%M@l4*@F>tdmL-#o`dvOYh`0CfOdC?8{@<%#1qQ7{)& zr_On|vlN!3xip6Vs%GLqeFO5P#>&Aw=ENt3p$zJi?~uB$Uu+4fNwyZZ=Gg+rVTUXq zX`)ue_QSEX#P{P4{|QyD9Kg9CO*x$SvCT>eAe8o;hDffSh+p-hw44A7Q-RJ$s_;eC zHh%JU$5I}<=Q~KPM&algnSrMXiW7Gq$S zSlAz&QoV{{08u(R?+%aHh?GlKzVAFLqFoRPMX8Rb6{ zXg2Xr9)W}4cZQi;x$?nMN|W(^sN{AjZYzvMaAj1a7%Rl5XK0}~+?dpe^iV!X{bgt$ z4f(HTIPla@O>yRFFzIt`lq6sY~DwxL+&NppM=gzhzIpZk0=KX z`C&-(oI{iEi^Eq{8QDRC&R@5v;(5_YWPA8n8C&W7Q2`8)0TSO|9pNY7za?uAm6XS? zh4B3G$n&*1&Qy=hPBC^!v<-oOf^HV0A4!}VXHr%bf(TZ1&8an2biy)cfe8{QVadv} zy|>%x@6a^onqpoHnWW8-sqV>Fq>Sp@oaT2-3M4q>-F@#eTwp9;U6xE%?_So-&Y9X# zu5L321TY9=>wyQgSxU1Ghi&8F>8Z4hsRJ0R%@>^6P9E~}5_^k(L!~-uE$(ofj zx78uirDea{wF=$whR7m|6ApQey=>7Wpx|&(N>S0Wf7~H%6;1-H#seH*=((}dzw!5B zsA6&X4}Dz4-EOkvKHbY(fIu=$npNm7Ft_DE_SHG&*&3N{g})8O$&)JN&kx(P)c2(o zRIFLy*jN#*m^-1Jm_Qnzk!rsI3zC*!MO|}^5Av*a(PPW_bt5k)a?mb519JQG+J;zD z%|B=}WcS0%WvK*Iw@p?oRW|QCJ?H) zH_oR17Aj&};U8{oPjQG7A=vr;Nq}x?2eSAhutBhaisfE1(SazPaBT3FRv=I2@4VK8 zEGb!i05y>CyH`$L@Dt$gyw@KJ{8@UW+)gM{(k`E;c-sEu)%TLNilx!qFC%=CTT@yp zrVTblQdcQd%x0p@@`g?*c8H{Qv1_Ehoo7XVc!ZR|Y*velfC@f-2A;=7P91gF&fl!H zOdpACDNJ-#y6qvYIb=%xMXbGEwAgCjxLmS0AwQOMlbPwPt6-NVu+Aa5m@ZJwhh(^V z>kqRUiZUjzpC2L*ILq4hPS_G?gy!9;EWBrdg_Z-&t%&}@BNX7b($!wy{61|2xJ#?H z-|Q?N+fX{&qzN%-5?AzR#w&!!atr9UKI|V%_@wqafeR#2$sC#6n+bo7s%D7b z5)%5$D6F^EC8cw0Owd2DlhJAm&wB@R{0o>W4~{z>(Y^7g1%dP5wu(ybjUZm6Oe zfQUy1slNKK@B|pFRRe=cGQ-~YVNp@SgAiF6gGOTysV>fV5}n8UTt)WtgTgf$>8Dd< zxdmn{BO-S$xRyOgplztI#^``ZL^+PAH3j9-2ea0usjel9&QFChdpWL-z5ui7N`~-ATqcIw zc8+Ud4dldc+nNB7aM(knNdr!Gf*EOjl(ES&rB%DzUBcXCmZwvR& zsshr6f7_@~Y6^2k4vu`(AZ$Z{{Q2_R?;{igHMF7%^M( z$B3*{UaQE}HpMF5Yfl-7i$jxN;zRMO-%|w)0ik-$xF){htE&%5q8x^c2j1Hn3Ca95 zEU4Knw%&EPKu{YdG)vjAg%=1d_@%8tJAXU@$h1VjIPS*3kSEpN ziPkgQ>oS6Foq~x5Vam7X+!w zRrPY|GW}>FJvCb=8qrE^x#r*|8yKUdRhwBG#`-Mac znQjPYkgT4B8^DBPij+TU_BjEmb_nIJ#fF?WlKR9;j)~vFn@Tp|z)K5>fFA!OG%ji^ zO5h$9-M0pxE(*OF>lbUw!(sZWCv8>*up$VmtQfl0Ws1DZ`-Gj&uqqAGgXY^8gO5)4 ziZHHXlwtf(n}jnp+H6_sGR}TkKRvSJ!S|)Zi(FxkhVKcgiDPBj=03ect~0*SA|rbZ3O<$Es1$RS zNz7G9&aUce$oiD^G(hmUbjF?M>*L%UYxs-4J>xNylfH7QLD_wD#7tXpoM(aSRQHx4 zBgKogUZ!Yel5dNKy>DBs&S##N+R{XonQ0HwrN+b}O%zJG-D;Ff`Z(uYv{>T`F|ZtZ z72%|Ja4T|hbCDxRVK~C_HoO9_P(sG8Wl5>8#UVWHs zvhs(x+Nz~V4O+U3llO~RLb7W`RtgKV-lLsk@Z}>*L)N@OW43XM_DMhgs4&_RYCn-h z^pOe0-*E~*jKbz1pP##onQ=9)|CWz5%$A-2je5*+OjK!dyagkO9F(M)rYm+*^978? z^md=F_9(yH?_n3osOn^vU12M215Q3xMB7i~7dgf#oZH&KuU9n#^*Ykv#wLr!j z|F&w1)M=e6+hFliZChFsPO%6DX)7MjHkB;)OSZ%RLJB|{Nb1Xb={51u0JrbpSMQV< zR;b&0FXqUZwJ4*wM9|$4WI4W^3Wn@(JYdH?pB+rrlMccxL38Gg@&*706kKGA%@EViv>wNADP;T zXQ#462e5!3K~?sxZ}{mX|l=j^yv40+Es|c^5NJTR*>OzUufFYI86B6wAB{L30`4#R=*awO zF_A@-G{}(?7emem@q%9%e%m&>+E{bq00*R$I_xdMY?f|_Z*|tMZ}uT zm+CLwrR_(**5Ctn(od5#EIZFx;(dbI@`yb=n@i#YzHYBV636nti4#UI&AnmwW`B3A zPqE?AlC`kF*+H4*V+`tOyIcUmlqo>3XIaq-e=GL~e#lB|JU`MK;H@`bc}V-x)tf3Y z@@`p!j-N<|ueX|H{cliqsmn5Q*GNLK$DLu5&(O`Wb4ZsN8_2` zj>qP8AKIX@=zY)iX?B9)!2Ot4kPOl9<`!Zz`C?Ee)NCaJe+&hs;WI<+7$N2~_It?E z{;EI8tX?N%$jX1GL;d zPKYVx2>Au6iXpG{s1UuWeDU(u1}NCE9{B0FFN%W z>STP-O_#M+)O7E&Q)W<{uBy9b01O3^00JFY=lm*64gUuKl|X90hoWioMI2XpZN$lw zE8otM1`fOt8?!5A7-Ky$2+0Q>J)eR#?H=CZeGcD5zZa4D_(>&=kD^9L?#kedG25Kv z;*;fD2E9zX>(3E*Yfl#b7>VW6G9`5-_YzJvfRZz)!mlbvewj7T-)eKc@Ait@UR$$F z1k=fM@=Ic8i60?dRf97e;NXA(!L56( zL&NuW<4&JTY4p(o%M;70HM_U~e9sCEqZmAljyev2isgEty-pJ2SrTd%wvV`4D-{?6 zW9}fF`tmB~hpsJ+&ZKmvXo4|y5x3o6n*%xY9V$4jJU1q-=4y#~V{N?1ww61k3Wp4; zURDJBrv!kfIjUDS8U!l<9x$G5$&1DeATv- zPVkL(aDL znu;@`x}ZCQVR8guU@;nSdFf#Ohw-EFsg7{aoEm4!ec(T z=xfg>(y#3A7T($9xMn1IapW!l9FxsK8c7eYwxVON zJd=pVS-NypIOjZc5UreInw<)F^Vtbb)fjeC_-vJY$YA-1D&(mwvkC+z6<% zPi_?;^Fq4~<;ftP2T_7^?NjPcEvJMoZLZa!X|(?Uk~vpyTl+kPb_fzu&v}c_9@mtGdE~leumijbW zgtko*xVLcSHv=NJareGlegph#Tf}}4v$Ok6-HQPwlpF42l6QT<_bOv>Vo4((cmM}Z zYmc#JPaJ9>fD%Q?Z1lrdrTB&hnS4tibBQ$TRtiRPRpepczA^aLb5?1fPeX?A)z!7G zw;jaOtWl!MWW;9(HoqtN*IRcqHy#zcxznD`IIZ^Wo;ep`JJqsAFbU~{&o#x`Vp#7| z;xt^@+;9c~A~(lBTGP@L4}==2Mp6632OT=c{x#?37g2?}$}9f>CPtL(Wa=gjagy^- z5Xo@q9_TGlu0Or<6O;TsIN+L-OGZr$i3m{~#jr+Lbo{&5IdX*BSVe%rwu~wJ*k0As z>a)oP_*qD7fJpuzBVL*JHPtJmqCQn?nKoBb-1vgsNK(>Fj8rdTdIQjQ9qR((B#Tv; zK!!A1o0VA3a*B!w2RS@vy>xaKPP(${HyVbYVQ&(qe$hYAxlVS7({!2VsZcoUQ(bsM z*HD(@QMK`gg|+3nozmuKhELu`zjX?hZ<}^F$rw1vDk*5mDQGtfKB;G?Gi+P=W7~nj zAUXrV9AxudK9S)`d_!vbj+=b~LS->18;6$57|Rok^SQk?;BwinI?7bhHCro^Mak0? z=19vT$@9BqO8~$XVS+#-Cyan=dHx`#nc;ibd^>LXG|3=%(a)cmOCq*Rfb+Bwj8OTu zT|m^=uI1I{x*9#?W(f*!^5s@(6o42gQpa&2RC?zf4ONR-wD9e_S!!)M&a+1A1VIRV zI=BV5Wlq&RfPVM3E0NKDBH!s2wsw%%+j&;umoUpb4+|kIn`=cM9QcW}d6PQ{4l~o*P z)3<)LEuu#@k2^GkGRQF!$m-I9Mnd6A@s4*9$4vCB?Ny>S_KR-hg%N;BD_NAov@T&j_tf5NJ3cOF%qKshd>KG`0$FxYmd z4YYck-(#Qc7Llq)6qx|9!8ylXGC?>UJ?j^Gwr&8y1U7O0@A#S`%UU}|${7&xjDz3$ zQ*F@wo6C?c^0+uWe-QqHgtR95m*>%KhlXUhzP)zTE!sDVGWb>wk>jr{!AqPD22ZAI zCc;L6CY1>#Sx3wGpXpnEC)F%&bUQ$>2=xf0F}~5jR7`i|edX=W52rYG@|4g^bu-*; z#!qDb0PEIEL}+$)T3ObXF%~VPwndxFaKT$FzbPZ986%FP9^#LPEhCQF2P_AdAbgNH z`B;u~p4}^<@Vh*EwbKcP)*mo+2V$TEFdn&a-?eRcmrSy61YDRbtxVGs3fvSC?aLGl zJu%ml(>0uC_F|lM(DRQD;`(X)(lX2rM+2#@<5y^=@E)k*L=uIywLq8y}u)R`y6qbum`a{?d^Wq+Cd`vZqnsui;&#lHI<&18Ne<3=1-Dc^e#ao=+WD z2fcHC9-hNZn%__t(6o^`K3&8L3O+HC2|36ooE&Gd9BkieGTdBCc`=gVNd(TXykHJ@ z9tg%e`**8rnd&8`##Q7xPOIVznPgpR19dydIY0?4PeQzP^*@az#fFazamlCN&n3dJ zZMQO}!GoXSQciF<;CCkjo%>5Eo_Uq+-dQ4vq$nG1+z-6oi^%7X=~C*RAJSm(>=!?0 zx4FEyW0-AZD$tTkACv*PKpTAr0B~wrY3Rn9>T}jN4RL&tw2*n5)FOG9E=kABk%P(l zSEAo|V^_5Bt%Ua0_EOzjhIu2BRNt8n2}W<1AO!v(4jZo-^81Z0*hv^`D~o6986V~& z(+4BHPjBJNy-MkAbk(~uIx!>4XZd|_pd5DZ)KZdcX`@OH3SL}k>wgZNCK$0rGN9eC z43OE|k+=*J3FiQSNV! zr^6+swg6;~Tn8hed>-Ai%}CeQ_cJ}rPNFEr&o1>$eq#cDe8-&UBd$pOYF*xz2)U)+~oXa ztGkdLK6UCmnR&I^cm(2jpx>_?3uuA!$e|%h&e@)PCK7Nk3pK_r?9sWDq2~f8U7~uvCkX6xcn=k zv9;99D<$Td*9y{xi5?c20yY7`$?3`Oz|TS`RUqTckmGrEGiSWitYZc}X7w$Mn|{=q zXkNMHTRG1Mq3usuEVUmHLYCJW)#b4yvb4C8Uz8H0C{u&;4i0h8Q;Mf?bZ#yt8yW_% zaS^o_MWbLFfOibzBkul!tVetzxv{&B2y9`F;eXUA2PdyRNWdfUKBlXgUdVi|*JjPM zJ|3{tyw|aK%wxesUeVq%mZE5lZ!sLf`4mtt%K+j{}nn2=6^zBmiZ`|7}#sTvHK%k5Q zKpa-BnX~ZpGhW1xa&V9m#3F=|RzPuso|x)78o5hL8KmxLjZeczQMV;xvP)(XO!EmY ze$W*E0IN_2(VX?iZoag2i!C=>ytkL_mU>0I?|9yInWS_wk&qP_akStT1D@I9t(;bJ zwXu%XBzdH^R^H5ZtcpuxX&ng1HG104-&dB(4NenjZ?Ur0Xfqj7>J*X*#zsizB=b|H z?vYoQR&`oeg*0mo78vC5$DbX>WmQ`?eV~EC3nKu2UWcAWMRWR;HWr?Ax&{9L+OEFW zv`KdgTL{AADVK7jm0V={U=DI2(=4a9X|3aUN9D!?2#fm#`2^=6fhq!ViW*)+b18xR&@Pt=S}d3 zmv5@dEmC&4ww#$*TC)wSADA)134a z!?2Wie^f7XX!p8tKfKEnWjHth=cp&HFc*1Gh4?gJv_+Ow(w6G1dqbItE~>pTGsx>s`!%UPMyvqxANX#z@coYA1Kd!wsLw` zH>mhh+Ro%Ylc`)wZx}A~T-%7iQOaNIiJ3|+_C`g`tU$HIWW+%`lmNr8 zLC}u%b{J!35=V6Cj6uUGVh-H(ACGSIk?0zo?w{saMfQbe7?jKqFgy+$9Z!7L--rAW zeX04MZILa6Oky5ViO%o=Dt5jXjPk^D#cR(M)QdApT{mWp3PW=9BrzBBS|R~lw;-PQ z<&#yJz*!X1K=?!WwrL}u?Wp})>+F5c* zA@>#jF2}Wb&DMu`Z=}y~g4$azEyg)50qEG>_2-ξ37b2lrEDRCN8*XvrT6dIM>F|p+mc2UnA0rnLpi)b}nLhUZ)knFLz zpKxw-9BkvRc*>0XRjoI{9wpUc5?bkwQHJ#MB}mJz2h0O7C4OPZjV{GjQxmBOGyF@P!-MtU`d4Z`5JP!yax9&6<|io8A(wanjBRO-)6WNYbCH~F z%YOvPrCcxew!aO5Rz7MJFCq+r2vlb4k<^NdsXLDLDz%2AE}YidpM;*`HAPi>Z9`(P z&n>W%$v8a$AFXhDp|;dD9O*hG)tqRgwX#ZQbs(IQNZ<^CkMXYiP`tIWjZ(+O7kZjV zpLyVTk}z^O4B5}%KD9$Z@icltac!hoNqEdLa^U+PnR}eCUcB|KAs1_+B-P4smy5+( zi_95Mmlz7e95joA&teXKhP_9`lBm*rO3pG)lWm+HNIq?2-Rjr6o`rJ+_OLa*n2?8$ zEgpITqX!HL^*9+h70zlO5Ypxw#ktc|$9)V?N(6@+BP6I8$56x*pUQ^Z#cL4R%OqMQ z*217QmB$z){{X9MwWChy@QYCr_rrWo{+mw%UMHRKgiqF-&wss$?it_VG`zTXy`Q!e7p`|@; zdGSs1X{xHE4ugfx7xb?B-tr-++*@7CZw;rJ=1kHRR)5{5(2@n-q%hA1k?GES{t1-N zr;#C6!6OaO?c?>W{{RwRC6vu^8V7GZKn4|YkT?fCc0ED*9^I3_GDfjijE+NCyh%Js zsJtw@8tOv0B!Iil0QSXKnnj8inYze02crSkAIi4IgA1c-+U}jITdnJ~w(AF$sD5lV zNd%zFEqZn zjzLa%{{U{Kpt+S{G>sI=xZ|hS5C=~6-rhl|{em=}+fURk zA|;}d<}m8&SMG&kRFYKlj-YeJa*{(Xn5HSL)*K;LEf9`QAFA<&QU-gDy>VGa&qGa7 z-FSaXwu4l-yVP|JDHJNUQ&ElB;F58*i7nF$j2@Y({8@3QU+Fq!mA0{KG;vKF;%_=6 za{EZ;CU8^|`N`>zO7ktz$WM|`G3)bW(@l=0f2c^-mKT>X!iW)~g^H#Sbo@c%)}_-? zceuH(bUKyAifRn$dkiaX2y<_69p~Tk0Ir+VayjIT^&s@O5VX057Sg;$EKh=3Jw*Wo z=Z~8JFB$dE9`wE)(yZXp;J4Q8HG3=RX5Vc*2=U1Q&erMd0pxc$s?vCV$r%3tXXzqFPMzdFUP z;%RgCmurNO$__XLMz}n8&q3)@je6cosXY6eh#}pOUd&0bXMjj`-P@B^Z#1(JXdcmG znIsCABH&Dy2c5(yjYz@AQ{TT@mTfLwKT2s@?@p3gRDYs0Xu?IvBPTp_&IsxULr(pG ztN#EAEv>o}HN~9bIR@3+B1tM_cH6a2{0q6{(~h}icfR7rNEK57A-I$Y4@{7D1?qd_ zk6apqOR%}POQ|h19Xj!W-6RGzm5Aj0skonCxI24Qh`dO;q<`7hmKII+U`pG9!6I1H zlk#>T1NmdU4o{#cram=>;#as4T0?Or=^8<(K$5X1l24ckC$BX;vRpxav4Ix zVz>%e0g$P0pN30ub}Xy-P~g48=F}Se>C=}1Sc8801JIM9eRLsSRN)#6HSgd z^zBAzZk9q1m`NJ~a2TqH`FV=aM|O7L<-ia_a{ zj)OH`;^NBp%(=I`v$uaR$WZ{=+m8cj&jURd9{B@~F4M#}w&QiZ{d z?kwSXk&d1bNd4ulwZRLVAGsuoNd6ue9{hofa$oS3>QdbOqUc-QPI|S~x=WGoxOG6L^CnF$&C)eF62T}HQ- zHoK5SOA;W0Ty)?K%0_Y2S314!Yke$pdZ&kO?`~$)EoEko2-@aJAIx;wut>gHF{m9# z$G0G3Cl5%v)GlqL5#C#*gaypZ%HW=I7nsCNZxI{?oI~*SpxvWki_oKYTg~05<5L6;`YkeB(9RH z1|Wlw80RdEdCq(K_BodDRoI66oHmjP^KBkaM}CJLvT8ioKta8cP8zt8*xLX z%V}@++lhBXs0tPZ@}YPPKs;bz6QXZ4M7gvmDrN=fIYznu)#R=HLt7qXGLucG}p#a8n^C9 z7XY@>LkSQlUIFLk?fBv8z5&Z&&cHrxxykoA90OSzrlOZxJ-(mfiEgYWk-pTkEtXN! z<^uq@{w(qbV^wbTPZH_6r;*}ivlFyn$0J8?Cr2xQ>5#m80pf8=G4>dxAyWA4A$0h6hXHgI_LA}2i#oMEWAD9 zD-?Y*SBPqR_e(9{FsiQXv15&{a7n_F#PiQJqH<4CT19OSzO&ZB6wZt2ljxxh>J3#}W zidfy|*Cg^Ut&yPz2a_ZZJk2|sz%ho$U;bC{6ld(id zK)tmx=z3!S5XTe|K(RRF?gbMI)8-ggI6RPY2b>EHWZlg6dN!F8GHjYDE~A?dl1m>p zR$$!V@;;S&QqnXyOC2TdEQ-p+Y(Q1PJGyRDk(>`;K7$=Kj}j)IZ>ip`5>^_eYOQ_^$|F47BNO!rpsM;QPN;FoNkfbcWYsB4;L zm#KKzO1C$gFWs6IlVB>r0U(jvJvcqH@15dHX!L2|wbNy3CX@YQ?%r}Sx6=oc$J2^w zsaniZi%s2F>Gd5m#B->Ue-O!OWi8h4GB=d8BPWJml&%im2Tr}Kl<^6)Rh6@#7L{sVkmPb2&U)_Qol#%!GkG;tw z6^G)#2kY}{5#L#9@m&*cH^rw~zGGlpA(Spd4my%~9kEUlYF3dlisiZ}=@#s^^QpK| zGpIyWA;&F~kPl8Vo`W@WP%}nRE#pU9j7Ar5%7DPOc?5fPu5wd7mDsh^Z6vjtJZ3wD zDIh1NLFTo-&}4@Yra%e`0iF&B#{}fy{&lRPw=+$b^vyp;ywj%s*w)g@bpkkJ5lVVD z%u6Z}fHD9ao->a9^|1JV9kS173<2R&5i4%qJvPq7+FWUNKVgPdWR@gnWDGmy%N(4Z_~U>% zt;@UNABintks2o!k0~I9+!@h8&-?|tj`ecR+Sgx_dogq$X7qRAR?@zcvavEtB6;wANvU%vFbU%=t1&*C zv7Nkq+~eB1EhERei&@1EudeYB`5`t@EGRRaaExC(9AR;T&r0`XwYw!Y)sc;-SnJwc z=^nfGl(v>2k-{z#O}XJ%rtIwlJqCR%6Iio}HTizTiy&gmBN7zYan3W?6UKQUbB>kh zu<9^fTkN*EhT#+mUB1$#q!_~}50(HQPzm)N4HVIIo9n0_Qa2X>s^&;tBMZkT1UV9;d2HsU&)h&BB>Lj28rz*gjl(0qQz+_pQA)&ht>XX0g$mP?^RV zt}Pblqa2)&LX5T!G0k)fs4s_f+nMx_5Xl#kCUXR2Y zjmDb-YF;VR?pHgcwl^Xr3$TKR%RZe3=$f*d%`%s^_n!dF$&+6%=%3IJq25kg~?|0~pEq zwv)j*JZI@yR@ZUCb@MnOPD?IuYt-ZL&xR8~j`H^U>fFq(V-ZTD&SiXIRnvEHGoO4d zX6br%l&~nclK9GJJ7s87c#B{JQ{n|`Waac^Lx`ifDrkGvOaV*2aXmWd*)geX?pSs6kz z@w=~In4J3aO4oATcpm0UmRDhLu@5w|?E?gD1mNRy4lqDt*pO;nXnLi!h2sm2GVTD_ zj(Be349mNx%*x#cdQ~*kO88n>w_(~=UoSj{E4Mgo0CA8{UW4f^#`i(5Q$NmVRPD$NU9D29+bEkG`9OI@aMKislXyam5mhZE+^k8LH@-EEWR$MAu=|ZsdH)3R+1YmI%qiHwOm; z7#)8KlfpWO*|jM@v~L2&@e~GQwMi_$hfLQ=CxvvI7P+4FrE4o0ekj$JUl4t! z%J$+#kx&N#kz*r2D(45TPEI)|in*ou_r)4!8rxjGWCIwvaVmlIY~zZ|lSlCVw9ys0 zyRu11Uov)Cf#Q8GzqH%m=@aF5h-SHESpghw9AJ$7(m}}YMy;mZ%PEH1O)?um zIEElVCmi#KB$J#H$G0_4m!N82i%5@G(OTofR@1By-E31RjSB`qSQ5C-)*bsd*A_Kj z3|ie-+1csZJ6vB(%Y;+=PK2A3>}d6$AYHhHMX@5w(g895(9 zdiAVau@}(`-8kv|34a?r)~*bGY1pixH+md`K>B8q+u`4c-I75Nc-cz^GLotX1eV4> z5nYRFdP2!=blb;u$ucF_5d+5^B#iE@8RC@Cf9taB+-) zd)Co-i)&$82P6Lg2!6Bu+fTynD6YWxi$P{Abs2I_PHm(9hKjCg{$Gf#6L(fC2aYf8 znUdE6?2^%&c4o1&HT7{++8*$HOt*-+9(LwW~nT`O#UcH1fni7#yf#r{?Op zz!(jlIFA{4${TMN>lV;ywrM;Xg~IvfIb<$Gj51Wd!|V5P$EOvO7mnth2x3cRhUy6e zL33=W2trRJqOK1B0niW6I&v!t=c8&q7`v6EH?Fqo=yu)38$$7w&H!dX7zY4yLC+qQ z%ltsoy#D|Q{k98h>u9Z67zrX)jh8zI?^htV%sR0r9P^V>=zcZvMa8_(9Z}o~K65&( z+kqSmI5-&{y=r|!SJbDs^4k98ZRBntM`ery$Qwb&9)M7jQU|f*^GuCx44FIFZ6j}> z#(zpBJF(D!-+R>Y{vWMqFNXDIwOe>?M8|pAwSXs{4haVwp55z0-@slfni58o*gR}$ zV+@{zg4rLB^{x4lHW{VqcRHkr6{;rUS38_9-t-+$et_4a>0b!7F=zIP?ycgG4tMaS zbCJl-e;gX&bqyZ>06=IVyeel{Rz@)rRy^nBEsSm)XBixhPDN_zUM{${k&<{Iz6tZN zx*+3lJ=@o5bO+9rhn`5}=w$qT}$W7LkmwN~ct@=q`Q zC(DeLB}n1%Ay&zA=sOQjTF02H9XyxzgH4V*Qw^=aZ~5u=p^kn~8=p?z)yM0$G3vTZ znq0cG#S`Zd`C$=2ZNvo(Ffudvccw*gb>+iw+04?UE9A4fmMqA32*4Q09q@5g+7Ozo z*2YcqM-U*p#~$V}n9ebm>-Fj~JDKJS85)0uEOcA%Dh*!V(&1u}gp)v3Mo@)daC6Rh zJaN?L12AdrcdHihRqXPlE40O8v9zuS04{!9<+4r>0Q1ti`P)ZJICVWr)mBLrV_7e+ zq(KoMGY>6)c_8_*xqea>*c$N#8d_g>Vh2PtzWlh&owpsYcEtBX+ zC!ADz74&fF@@|*+er9&D0HML;ejb(RQ(O2l;^R(8o(*#PNfITB803j!-~s~`CQP^8 z1Pnw;IW`*L)qU->lQKCEV>Tx04uLDiMW4jAuC>fqDa%;_U-b(shkRbWH~S z+enB499qais8Cp$4o(5wbGrk#6+EiksBUSyvxJV`?(IXt9I^rq8Db<6)3@baHi6;o zLMfxUx=56Bgm!JmBaVQKaysDktUHZfR)!}cSngGc46@;P#xkT5G4pgIJG*!3wC@*P zSZQj_wb-s@y?6mkSB#yQXAAP)PZDv`vC~~+8NnTqd=dO6; zk4oCQ@rI>me42izs$1I$T*$AyBCI2hPBXZi3=hMAYn9S`SFP$cR?)$yTp0{S-s`EhR`EPXtX^&Y&$zvUCTNyqgD9<#7;aEN9^{TNPAi|07V1gb>`IzFi->`Gik9kUXk zoPu%l0m$bSw-$%vO+Mnz-Yqrdje&7u@+xf`h$95&k&?vmCO)D6@Z z10-3mmp_o%$Ub2*Z9bVeIX;*dvRy$liA^)a7Z$Q=ZFJUlc9EGLAtw8WI6p4XHv$hI zIT!@U>Q{5yM>#=R*IPI*W4uTZA1)hKciW8M1yVhE&-hi! zDf~dB)`+jH=#t!O(A-#BOEh;GE$2F88QL(!0oOe`S9jsdyFE9s*0^d}yJ zxu$$G)HKE^d*db1p>dRERZ%ZE$X_&NcjIcQ^LR zLaop5Vc(BXM`BNN+}AALD%EujIy)QNyPKFi!6L^e&UXQ~IXOKzuIY6-CXk5W#AxiU zman!&;}}-?hh9fh*N&B`srVO2)#ERr-NkB<4a*`}C^BSy(8?4yAZO6zVxo27Mm*J8 zNPMrM=lV9Ms_r^Xh4l8xeCiehD+t4uU!1Q@{GewUABB5Pn<}I)ZrrJ18*_t<5rBG% z^F1rTI@BH@vbwlPq_&Dc=2&I{kf_RrQ_tQ3Nawx|Ij>98+x;Q7ws{Q92;&*g`S-7q z&v8(xI7XC{OI;sd=^N8espgtDi#5xgL`SFTzi5Mb5~8R8fTtUsi2#tk*(27qJVRxn z*;xg=(X55iC?m?aC>S>bJ5>i?{DJ(D9b-d+5U54Wg||nvf>bPQ4sr+> z1p1r`_hDL{PkNibrlhwdxmoA7Hr^Atfo*1r;tQDD5=kBEqR4T`9%7tefDaw&8=nTv z^R=DY$s=Z{W8|fhYt*q+oUE|!6Y4^61;gp zvzpVy7P`qYksL(r7am+J#aS`|4bBdI3GL1+sZX()%){XC6+n_+L8r+V*%7D9{nN9a zJ$i9bTzHZlUKFy{Es{Hkoo9HQv}~kgan5n`9F99ze>SUs9I-*HYU2%$AquHk2ss() zzdU@WkIt&BRc$jyN0>FWq|?S^Ge-k1&nqJsEx7L54l++YX|d`T z&}g%U&~Wet^AT@UImiKjb^yi+;BC)5R6Z8hX4d4LEW;}(3h)_O%dT_6f(HbiaC-Kr zy~ea=hA8@hnBG$Ra~jg zaj+Hx>Id?x@<(+At1Xt0001I}lglys;Yx#!p0!5lwR@YQvgnaSjr+3KEG1ONL1hDP zI6l2SjZ2bR0hz98wmP)Xomw$!;1H2pv+dkS!m6C9@5m$H6@M)all`To+Q? zG^T6Io!@Cl9zeOlCwi&cyb?x0_UT76O2{pJ&Q<5pq_>+&wDYZ|QmRDEvdQx2oVuze zaz++GoOi;CmM?}=YH0UTYDy%YVn{aZBj?j$Bd-|90~Om@*;r}z@|`Ln3rb6uiQP#g ze|QjBanm^TCy`ZkeP8TxD4dpQI7@VGxft#`1^Ig88T_ep^#+m7!{MDXO1O?F;rmR{ zx9@La-xwb*cBp3{@ILn3X9GFnqP@0=-ixJH5lJeGd9NWElZ-dcP5~GLjPchP#an|~ zyOLvZYcz1OagVPK-Kd<3h5cr@@qAUF>4Mld4j8F-IJqTbuGtdLmo;m0CwAW%9v)O7E;j9wQc;#O<@TihEJYbT$fdKT!t`2)_YBTHCa_+K{-swbsV$814sRfGQ ze(VGHdBNa&5nJ)-dUfrLSC@JO+IvW#dGo#(YiEt`+Xwi7{A-QYv`-k?EJiIKQ5MYz zAld%BNSD(YK-A5r;xL{P^t92iiKb37m zuFl$#z`!ac%V&g*5wHq_3-QQm6bF(=}Ws}TU#t0xQBJCYN zh@4iYkM?xa*(@*2k_8D4Vu8j$#&?m)Bb;F4ILYfvW8=6ry;eE=Pc^7?0aET=CL4#0 zXR+Ck26Nx(T|80vXHaX2>^xPc`HX<=l$%8@w~YMjfKOejahk%UTvm$ZMcn280I@En zytTKVRJ(aD=3=7Wb}YPdO2i2OW3u2A)2(z9_-n$xACC5B@fU5yx8L_3Ov5)|KqF80Of_7JDh=DyO3;W&oa}k&r$d=IQlxyuoB{_< zI3$){B)YP=iYs~Mv6O-&oi0fSoQx|IOC>ytQ|{gk!mgMc_3-=k>)D{krTP&PO%ltp5PQ!SM(kKeaA;f7e#5OLs9`Ba^^9irVqh5BOMKBf-Ws zOP-zo0D9HC;r{>;YBqjF^tyhHGZhotGU+fYM#}8HRTPHGgPi&r+o750w%!hpP0>xz zdj*DA)zPApY;3(l2~Oh22S0nKLDHfB0EBU(R!bWTyQLo|n$~W);E+IJ$RrMSp0z;y zUhxY|KhZSJ*$cpMaoZ<;KczD3;ufQKc!{iQt7~Y>zjcgzSxz&9zZgA#z0-`=E;B1Z zEi?&+v8dZ?H&fYK$Tp;2Ne21)CVdBu3WwbBFo*qDi- z3{+!3DI9;}#=WaR@y(Q$R?+L)y~(>!If;-5=OF#!PXuSBvknMu03c&KYdJ>Rm2snD%`i!~gjpJ4E4;Bb7&jQ&p|PF@3HPe=#%%8F zVVS*7uToMtKV6!nK z@Ol1qjik7>$y-ZSxkk#(JU(dvj1Wi;<*%>7+CqtRa_oPJfFipwY)V%OJk-_8hD3Ex0c^cy0)~6Z}q7Tn{10A z#tuM_o+_evyTx}((OX=@%KXL+Is{-na;OOFSaV$4+rnF}$}Lib6vwuIpX-&QGtm>s2o2 zxOFBgdotU&A7)?(%XPx_#y>MmOZ{Hf)y1`~vW%aSJA7pPqoxO|enOp)i`PCIv{JEI z>q7C#$PH@Ir{YWn^ zer8=zl~ql|0LQOAfjo4_BWBXlOIano)^A>W27}E;x|yWG-JD^zkGp~ZkB)g9XE{pF z#iVhUTE45KP2^o$M{4n?WrP%(6a?Vzj0RjD2HaqA$4cw;uZ~)*y4Y*|D$ZDnV5PM3 zMo$^YS7I}gKZic`!fP;ngIIWkj@zxiMhwKLCnF!bOmyh0f%$<(!%%1@c_WS)OAJ4s z0!j`}Ny9H6Pyy}V6trtpQcU^+@8Tu-)C3mRP{NGL6`YrTOY#ExtYnOgaslsNYpeLn z#eNS$x^&9|G_j*xFy8Lla#fYf43Fub;^jWyHT8rR%Pf%wQ!G)&(g3+a>1VI{G6(&eOWkh?NFkGje_bA@b;%fbAw6}Z1k+gnJiFzPMll19w2k@B2u zBn*&x_4PGMFPg}F(MZG6EG~5mvpuekx`B&x6=Y(pahwteB!QEFbH;mDb2r0(5X&R4 zmvGTbxt0Z*7^72+50o&;JdwfRVDzIz@u!LOq>A3flJ3?$#S_U{5r@@4WA}jraO2oh z?0zBKU3iP_nzVPYOsp1YEUwIG85nhrLVd>3fO1b#YWZB54p!98x6yU43=g(zo*$OX z+ZAYLvXKs0^Zw6SjPDy)+q*YlTklPFGD7hQ9^%x^KIIh1?v+!?-qqtowPMPI{XqHPR z`#f8)4nA%N1N*$!A!DoSdM2UvO*d7NIOUMrs+pDe$KK^xMmF$q=sVP@CF(mnT-4IE zeMd~y-0M0Fnq2V(k{P0z*q@AS38|B@Py_U{88tA6FX@YG;gsx6w&RZuul1Vkm z_+IAn?_9T@^77+UmRkpQ`&`CNr_8}o&jXC$9>0+3U0Dv+7&z%)6P>p4Z8y;!6#f#( zxS8Tm^2ot{?p*Qor^Rt3SrIuv*bTG+oPS?>uOIrcPv~pJv7sW$%lBI!N}eybG2d_I zeB5qV{{ZXNQBDO@Y>jRl2K)P)1ogog$LTUfK^A7;C^lVL*|J7*u?1Lx{`=hS;Q!&h2Cv(zqi zZ9)j{KGh@JOLK1|vaoD&cnW_L*Et7_^|9!_4Y$-(&#TRRwu)!E7P2u#Y!)s1sImY! zBj*_WFn;SrrHmzWo1WiVds!~D3u_Bm+x=2UX$mAjE;xjrBTvj)-@RwJVS3R z%l@uKp8RhHWD*7l@Mbv z`vtHCcCL6TuE6!`dCmnUn`XWqiN=uzp>UEv@BUE?t%bn*zjzLMjtM<0KUurfXVdO< z?H)Mej#mBj21as#5XrQL+5x}=Dy+Z^F48SFNo7S)yBg&-sK-sL*dE^0 zwAigKZzqcN2!xaUp>B#2sIse^b;biaf_|g1^u=pfc*so|8m*Gsd5+3jGOmcEjimh9 z?sJb$obdZ!3~EygkN8Suf$docjyPZLKH-J{j1DqBho_|pG%Y?Gh@-ceXN<7(%jLH( zLc2n!Z2IJ5r!+e?pt_v`Lk;t9vbcc5jK1b? zKx6JWGjSc#8CA*)U9aYl7bX7g&Aoq%Iqi;X*z_-n`d+W4>Dph3 zbjQ_in5=3|tWu#GKujV1R1-MXKsLTHM;|Hd=L?lPr^H;6ko@mUcPFN2R<){AWtMHtB#R3m94Imp}8`r@_jJ{;)R*LKhZ7PlpLOKiLR z(s}^QfsqG)x_-3%r!L~L=1n}-(iE05l3)_D0TeQz`6(W8iLk0E&DB%hS?fIppDPlwu8qS7vd z;_G>)$uYw`4Ii!s?DBhLFTN`lZDz*$^;sv_@)Nsq?HMPYF^=b@N{MNIAO-fnSvHVH zc=a6r02OD=G#5h6@YluB+&#UEGAjwA+ghHmIUPbf!ErwZtU)??<8C6ORE`7 zd06ff%NfQOk_I#WKZf*ge_<{xuO)<)0F;rFgVb@4Ls~DaYnIljX*2z*1z~{rB}g4r zvIyu;80lHxTikjxmC^h+d#}u~*$asR5FSAf$QX=~zjg=XjPYF({3zC@W_P-`xA_jm zen}*byK{~SIRx@Lcc)qF4H~pM&)Tjakl~lipe+mRBAUkS)sT^CTn(mfV3aJPpg8z@Mf$sy5y(vz6Ff z#P-=B249>J>U)pC8tA+|q{n!XHqhv!Y^q6K4h9L}{{R*^HJbW-Hkx}uapC)DkyM11 zIZTe;h{Go%b_fA_X3{eY3)BRYwRGt4 zJ-LdCIpf)v?POK)$OqyVh&bo_R_mYpY~SNqv1?P<+lzIEHdW5nBc4yc9qVhy8fKur zKJgT>K<k(ByAR|@HEzQ0=HZ!91dWbaV+FDG#%M|+)avc-BeV|sU)y)is?!-~55H;W zkf8TH`OR61_f`^ww=EvrEUj*(f((I{C-D3;>scCf*P(o?WGyNWFl9Foah~Agq2y8- zT4>&T%k*G)Ah~vYj+hxEgN|{{8X;+_=GDxePl2+a|eXCigW-BPvJ|Iih>(R+PlgE6ETfTe`@u zq%?&`@e{zw?T`&eJ5MUGl~V8-K|q;vaH}pDGN=FyF&vURoKt>H&aruxvD^@XX^^W) zxdd}|mq>8HvB*UOaU}Dcjxmm=mDh&iz1Cy2T{aym-^&rk@z{w2o<<7{ zlfceg`{zA%rc93`p2gyCkjIt*a3x&vk?T@u_VYK|Ba%h(Tm^6nwtC~LuwI9A_?J^S9Vz?ML8JY;Z=YfgN?-f2*x=*Z{cXL2sG>c&m$IecS7D+Vn!F_B=DSr zoP&Yst7(vxj!y6Ft7zY52gxYR83}Et4oJv+bzXzl@}(91w~+}hP5?WbYMvMla{mDA z3bUxBnr-Zweaz^xMi+2qEPi08A2RdD`(KYkP_2s_Sml=Z*u?q5v|Bo7w(h6f{{XL5 zdmykzAXV6oLKQzQV#Z2=(J> zwzFB^M$_s7AGAqybv#E3sZvhRqXVXMk%OJw)lFML{>Fvw?S9Z1K#zXOJhsRuD$F?` zsLnll^`*|6u=!cFp!jQ6(sc2t-A!Mk47n_d5tj-H0J@Wr*yMUGrh%tk z!kUCL-Mn{U5J?j(O@ojVaZSUMo*$0Ku6SDy9qMph8%zC8?noLJAUx#b3L9@dauklI zuN_TrR=Ta!-aPwUT8+(&v&zhFqWPXR2R|-Y6M!*{k52UxjozS{>OMdCSsnG`>Y6sG zYxbS{XSBPW6Mn=42*-`U0g%}Br-*@{l<>U`ZtN$i-g~d_>WFJ*=eH_ZRc|o0dPb z+sByjbG&bUbHM01&q6U$uCyxWC#QG|P<=YWOY5sUHfB|g8JWwt*@3wOMn2){3H9TF z*r$OlEG>iHU4Nzpa~MG3 zN?@{v;~D5d9=z8buIlz$UyPx+zmUS05J`ev*eryoATt6~5CQpIV+SLZtoe1&wRRX$+@oq~s2T19xqEk0^9Eo^ z&Ph2L>;4sDFAcW0cRc!jsTJJFihp?%Myv?HA&VTG9;|Y4oStz?Z4&!Wl0UcITE(z3 zqDtd)1D-;FOAM391aN%~bgo-j?q#n-Y6AcRPPI$TLV2VTE6l!96#xPl47*@poDq;a zV>NQ~S-;gL7W$Khe zs4btbO1ERILT_Se%gG`((Bd@C;yC1kj&a+!Zlb06mg7>8*ff(N3HMhx0atWdZL%`!1?B=Fzax74@;VV(UF=JWwaus0Ae+U>Fa=fPEWo%t;fHqPjB%0EIIRtK z;z;GO@?|QIa+@TGpPf$~Z~@5ALCEipD-zY(FBCyCNU|1;xnU?61zU~49@VQQrN#W( ze0CPnT(q~!(WGjnhy#W=CA%J6^zFrS%i=bTxekZG@>@-N*;nWfaN?UkHZ=`5sMfOddF07=VrFP=|KfPVMdE`|>5;2dqZ2<)OcA8Iim0yBfj z_s=~&@y&Ps7qHXy4La!DtY{K#w)Zyb-gN1nOO6Al-2))woPcV5AH$lZrke3tY4-NQ zMImErw%pECk1>aq_~5U~7;?GjY8_tJQ1F(Q7OQo9WV?CMBvczgP!Gxo0kCj0jCS-D zla!^UgtR&dZQyHY4#^`q2=8-EiX zuLGVl&1)Dwpm#no@q5K^ZERss@<5E24U))r^TEgv6@gQb!;ZN3;<1w1A<8Ks zKeTmJ)}XMQqTIrpNQ_|-b`}btagRZadsnAuw-%lt(_)@TmF0kiaOyIxj1mW7*B;-E zarWLF(G{(AYpd&@IG`&Kg)K`k8OUXRLBScqj+n};+%Ska@ zslyHvxXuSsIl-v*a#Ff8Ji}k`7N@27j9h3D%_`+)ibaf_j1F*cFfc}HJ!;QMwvGv{ zwA+n7{zM|?7h++^$NHkgxd*A;(||ayS@AxRt(!Zg(_*xm4=AgBrhhMfM>qg+^(;9C zyeC|})+V@D)%72?lx7N6;blcQ87itsT>QBp0CC>B;NMbN?4B0!Mw8+X2EnFlvf4#? zrZj#}+h_8kodMtsW00d5Iq0XHkT!fx;B7C&(pu|b?u3gHptrYl32--V>m~^VG2}Nu zF<(8U(J?1D$myE3W2)V0*9&uDb2Y5!4%s1)qYR979@(N)`lbn}Et#!ysJc2mw?e78*c>sizV7JjhBaVCd z<*&t`7F*sd(%(gJqn3(WWL1-nHxvrq{d*3*;C{1>`OR}jiM=LwIw7B!0jZR zqacRH2*)1vn}b`7?(cjhZ5`Y;v1>OebgZ(fUdCjnxM$mM{x|Y*Kj>IwsFhMy%BQFZ7s+b3p zo`b18_2G5@03Y06Yo2a}XKkcQHc?X15vF~>XD$FFo_`vc-3^xK@D#SC?X+!nOEq>4 zJ*J@hBg&kOzyhzx?!BuD>%!hBPcnb(v40$r7B6c7DoM{O5C8`~hAXS^-kYn9H|<)z zn3XOjc92hQOv*UM-i)Upobm`G-mJrK_B~amSegrYC*yva#meOqfT-`2PE)w;N}h*(DrwWMe^%7^5}F}Sh(ITz3*vIh?Z?EZDw->rD zg(34N{??R$Q6eECUtP_TN&f&itefu~>X$-T?OiOb*>EF;KqHQRY-c{;io#W67pu8v zbN-%rI&As>0IsY50L9T>N@Y{Y0F&3{6jpy(U&)`<5~vs^~MFm3tUgU{(*{{V{4o2B@}SQc7x!+j$F7()WtwM$CU&yD=4COT0(h_F2m38H{;^ zepMl{cnUeoxIPP)22gt}iT8?{lZVpG?=tcpmtnv90IEFWL2Mp*Ko-^&~ z>)y1yJ+C}+{`ujS1Sj`v6la_qU~X>xMhD^4XDjp?OR3qV+OC|IwpMo+QQO8Nav{h7 z1sp3d2OM=H9Q)S3iE5gSyUJ4L)+wd)7AK6vMlsG1btIk` zVtm5x&{;GoD{+js&cOSt4^LXXqj-UJ7{kZmmRCm$CCr+JS=D&}ou#Dv$K_*=MPbVN zm43$kw})(_NzKt0PaxSLMcP-Bj1WtM&t2K$j8>xQ8gxrihuI?aSOuD2SDdzMu`ZMtuC10N|LH&Pp@gt=2aIA+|#hNSGXLA1V95^Uu)Kc9QwG zkxqwrh6YJk6Tv$eWE^84AK)K`dFAdWnkanDHB8SVgm~AD%5rkYKBx6HWyypA%>|y6&`YG}|Y>5rQA=gUl>^#vrg?Vyn-f z`cbF&PgIry_fz=_K5r#kcSDX;9Al;rBj)z4__W)<_(x{c{{XVipEL*N)Gh7~)0qGS z6&Ys8RqFW8P7h8~Th?9+qiZef(gX@511iMlxIe{=9{iejaoD7jH0(s074^m5Et=7x zF-a^EEM*7o$<78x-Npy^hfXU;#x}7gn-#_VOFrPcm=X{uJm(x^7_N31 zw5w~#V7%90lGbD^CBU?ptT|G4?Z_|5z$Ja~D@#w%w9EZ2E10imx)7f&qBCc99Ahd% zl}vHebLpN|t=vr|q0Qahxy;e-b#MS9Bmi^3#}%IhH%qBUcM=o`uHQHx+&ztU7ycZy zOHn77G|1y2a!F{}hVB47g4oXooE#1bs`@{Hd{M3$Ke8;^YbRt_?=Eo^Z5w26Qr~zE z;dc?!891%EqR6u@>JonBeU;rLX5(QwJZC(8KhH|%{84*(uil>`-f88=1aYZ$037rK zwRLy?4Dnrz5w4-3+yvXTOa*5rvqvVqrdn!p$%ZP(idc+o zC6g*f4;*J4XRdj>%iD&!g^k3FS$waZw*bDt{{Tw9x{jciA>*B*bCqU+*-I~>`LoY{ zwLGaJtnO~fcd7Z%Lv#|t!bFVC_FHv^I7t~)O~1TjyZfYdBZ`m18ik&f<141r0(l>4 zZz}fgJSsPuqb2Z2INUPN-;vbRX{kpql^K|%cE#Y4q;f$a2_=r~9Dlrf^4$)!o)B$f zb%RZ7o5`VQrFd-ATgMr3xc>RGyNr-P+IkEVT<&pWU=ezM>0!{NxmU$jb zmg-9u-QTa?J^3T9+*TIyX+cHQziqjdlv*qdNCc3qGI7by08^eh0~PGPANX^nX)NtW@!fD?Iob45*ci_Jc+`MwWk#4OHN(h(B89u5o4^z}0r_|Sp zQ$NE-rz%aZ{{Zmis#3Aww*D5?=9oQ%7#w+TB*Hwe80ClufyOh(=Tu zYw7Q9WWHUOL4;{*5k)FVIC5FH1IBT*93DC2Ri0ra^_9L%Udf(yqUjn=hjR+uX;&!o z+vHv4r&kQ1wstTG0M7+n@^jL)qw#DK-%D+vJ*q}V+@qubaNLD;Qe0phe8Yj0n%Ex- zuWgs?)*7sq_P;X`Y|Rc>kOA7H4DA`o?~bE2qyGR1az@B5tcAlaaPnJ5>~f$Jm0T%1 zc_3%#Fz{wdr(-X%9(!#vANuL{x_7UX&A;BCqBf4h z;y=0+^HIb8s8jy{!n~5e4_cNaAG;;b%_z#?^!2Eyl1;X&wqKhh?ZE|o^GFKTL*`ZB zXY)M%m4)L-CpNK574MTAamdeXytLyAayc9*$t}(^oDs!zHh_rt1;Gjk=acXBtnGJ3 zgH^oKu4XK)WX@9(6;qX5^uge$Ach#nIUHA~mTQcM&+=qTW0g9#jsE}${f?sc^2vPi zNgM|5W|%@Y0?wf22mr1D0CUjdt9X825Y2rX8+)juS$x?gF$CV3!ByNb$YMb0z$esp zR+>GHj3QGSNh3Qkl3*Fh=zg8YVb-R7{(N%BJH`;7-Gx$&G29S;$R73f>LvwP_03aD zwRXJwJKg;5E#s0kSmGs!W4I~c3}+-941>#3UQchT{{W=TrrQ<4GRo1S$`@%3`@xKH z+%e;(bDE#Zi_SALD@oUJKu&RjLwe%_uRtmWwNbMZPN6@ABp`L?-2Q%*NhC8eEf2$% z$L&(sM3AWk9#!*WWgr!0ir-f@a3v zjpA_keiENc(pqg^?mJ7QAx)NdKO~dMBd{NLcMX$_RSWCsZ#Nd%8Ev;dZ{E^J9Djmlh71@!D6Wr&D$cp7A03VURx<_Bf{C#U$aY$+mPc zT--EqLH3qtAyQ(Du_}a&oB~f=5B|Mt>Ap4BbXzlJVScvIE@v&}t1-v}8DKyhXQx`_ zfR!hoes-&D&s<}-=~cBEe$jlf24xPTrx+aZpTdbmq|wx0>pHiJce~xS>?AwWP$7(=V0P_X z0y=f%Q3*yj1(u1glB{8T>k)wr_e<9!Yw{IJm?Z;^59q*17L-2 zSxXh}6#yh05ydrFj$0gjbF)snesPR(>(;d_Y_6|w#l5|y%+4d}6}vNIyJH)$oG=HbM^Rlh$BDkcV>Vi1eV%3pSt4-G z$GiUkb;$<0Knx3UC`2JlmA`ZQM8I!(8S<&IG1@h_#D%v?9hBX>J`f=OU_#}$81 z(7ZFCqP3lZU*9+1oueUF1mvlG+j^h7l6dy3nFmw4)Dr4jh@CbYb-E6b8~_<(VY@sY z0m0{y)DLd*Te!20ts_F)C6$+)j1QBLFiuCz+1ddB99CD8F3AgXsLkax-)N4~+j1dk zWZ0-!{JC~NE`JV{LJeKzvo{WndGf5WTM3ROX79L$3&H0jJ+{@GKMrdXMk8yho46WA zkTu20F`+!=P@E|CRRf+W_e-H^a~D@ zHt%%#acyb~vS5W*+7y$<&`t+Fm3gMpbomNgM;@L>%1lr$-V0|(|TGC{@h}c;?&g~}Sa$N=yw(di)qi3!+0tam85%|VqsM@02>QY-1f%Y~+ zJi)y|Y>o~$4!jQJ4rwke?rkJdYi_p@gu%n@Z~y=Sk%8&>bgq4`3d14s0J^hBkQa}1 zk|boZko`FzsvM_G4_bcgm99;iGVc64t=i6G7Ut`pm95ms2=)0xW4B*X>N7$>-*^m+ zXF2WpS5s>)>Erta_WOC)e0KM4VrKank@vB{Ioq6(obYLN2=(h7VQ#OqsHT+RPuir& zWH`uR$i(1`f-rD!2T@o{3ckw~&PVN5y~Nr70Ci}t-ft4=aa>6l@T^jWVxmalhihQ< z86e>MjL}i`c?^HWOG}+z9abxMxR&DH?WBe@ezlW6JaV$I8 zTmuwO=DsoahTMWXaC7ZmtKvg1JON?{x=xmf^m4svi+x(s@7MrzidE{N8V zMW{z|cOwZuc-~kXoT*=*IL0~ddEgrKVR%PUWYn4A$z?Q<8-o}r8!|o{EgwL4sO3T2 z04D&P<2W@Toz;&1oj5#KxN7t0X3p7jLbuI>Aq1h$Pa`=UPYYq8 z#S~~9${J|F*%V<0NgWvEFvfWuPXpgb&9$jEIH7XuCm@Zzhdt_ZsjFiJ!C&uJd2OcK zyKS)2{?slbHs)U|%>yJ1hQU>SNyx?kJm-TJui#YEENrfzx@(lUXC_WIqTzOcR{@Sg zo;|%XU$jUpaq()%zG*CQ-1MRK$flJQOp1&)o)`h14@Lv@t>5@YmQ{ZuWtBqYyy#Tt z(-{7>NO(?Z94s$oD8MFElVY#b4s-ZX&VtOXX@6~PmXXkvIr&r)4*>JDdJgsJeh0rv z>~2sxlvdmi=zpbhT5o|P#{0K|Mj(x`+>z#xI9xE}pMS!w*x6iYPaL{lgR3l!pE07e zd60a^AnrKro}7X`aZx#@tWrl`s$GkCuP1n(SQP_;7!E-9&JP@Xr<&vE)OG!O$~$c? zD`fXD^GK51R_=i zV?QVe2`7$E81KbmYOL^FEKoZt#_pNy_~;K~(DC&8)EdW&bsbw*x4JFmCA#d2E#!bQ zPjYg40(i(!IKZk`dYHInFBX1cTO4OO{C`^Qr)a~KnM-@4agfa=tBIa6NCc?+!2Vf2 z#w zTF$#J0e>x#Lku?nb^iCD=~s0kbw{oEn!@J$;q8k}EP@#A7tL_TaLH1q8RX#gE$e_Y z$Di6uZ>MV)8dQ3GB*_4{jI>Hxd?1i^+ITEE?lHm6dST*AGw`+$2+C`gqQWROi!P=#FjP%GP93I@)D|U7?NwsqHvRcm^ zQHX6tjqz7|Z!4DEyT(BILB=`j!1NVYPQB1=E)wSc!r*DwQI*+j>a3Cjm%^|rR}P>6 zM^0)3Yc7#(X9tM26_VM=^5WBgc@Y4>UT`yl!#N{^&3deV3iMq;nQmG^q_m55Z}wLh z=R4J;F2#Y)cvZm1CYLeNYb{Rc|b)7Qe@3~cG^r`fC_k~Ow-Jo0ZL-AfiF zvR4^lz`z7n7OU|B6ZYw}k0vY0WHAWtt1 zrNy9ffL&bdk~PTe2K=ZT=RUd3d8de`I_|R!TGX~zs}GsvMQ*Iv&?NEaxlI+`5j4?Zy1Ds?W0=hI>ZJm|7iE(i5 zH#M_@>5>Y0n}MG|^MlHUAN!-l0_;asEsKXwiZ46eT>13GCatla`*(!}2 z6Ot5z$T>e#UbPmxDsBDLTL(~}gZbvLEhe*y-Bw4ESuxA7T<6yV8SVL1ks3Y!3s*?XE5|bb z0MjQ8gY@f7o+g2hnUARH*Vep_R9)G>1Xgm4!#?I_-cAPN&Uwi7sHL%6K_veGJg!N@ zkG#H|laE2~Sef}j9+Zo4V~{d4D-JTJ7^9RfZQ1Gq8zJW`-fJA3k-+DWPaVHMYKH20 zuV(W6%vvZXY$Wbs&~7J>z%NEQkoD$Bt1o4ktbDCVN zEBI7=LZZ5}+m+E+^ZAR@ugCn*<7*4tNsqR&l zav#jx0MD8*-8<;G(RmIUWG2LyZI*Qb@;V&d0J{zOY-9@0C= z-63%tvN*_a#hI9#;4fTya!*Q;?)F_QOtLDlC(P=k`EHFU%farP74&l?k z*{YqRO1Sg%#jQ)Jpdy9DHLefSVnYRfURFK%)yOE8+ds0N( zkzOe`#(53c)rDeLX+!gHaCjew&JgYX^PnWk)IKXH{fGChyZ8P{{XL02P7}f2*-Z( z)SB253$@R(2a}sz`+*&ih!Vocyr>{Q!st@=|UKt`p znf}jo9iauB79#{4;a7GD=t$@2Yt41Eiq}+FM6k$2U^t112*8}FC#m{mdQ)K4?;un} zx{(v^<#`}rjx+2|2TIZ~vanj`ucwN1%V{H9`EHg+=;1dZKAen$(~fI$E6pb6(j7uO z>19ar;Z;sS_2o|>{#otTyjxE3M3%FOE}B`H2r8iy2d7Y1r~sdS^}h|)m#NsxarUpX z79f>r2r#!f$mBLcjC$jyP6W8gJq7A_I`mh*FoELJu8Kn%rsZiIMKH-YIAWlT1A@DO z+tRUh8w>3sYkOk3f>F%(IFrk6%B+AhoCO%#InS>gQP*#6<&rHS!&~R(FKrMmdIAX< z>5iaPy&uP#?bfAd9qUPX95*WMBUK4!tT=E<|x^G)!wS><-QIx z$6RtNGg7giLAth2?G$J(lWn0wFbd!k^PYb2&&&Zmc8X0q#8*o!##Dv;r`Q~jK3sL& zNsM&qzqbUM&8~&>E~eGig>Q5fWsO!)q#-T48RQ&;oM)a0=BitGeCgJ*L2Y`<8L}gq zMr9|QF#iB+1cTRujN+G0)u6l!E6w&nD`qyCJf)EFpPjfZ*N(M*_}g7spR!#^b2^Wk z$szHa;1B`Fza1&3BqwHM;_tqu0rXYl@S?I!wTNN{jj9ozzC=g)u>L}du6dJVOT~AD zc&k)vYpB!WFwszhnae;z60rHLCt^`^pk#VZs-rPjj7O_U^S#E=F8~6oO4*2c| zUNAajUg}q{d{Eas&n+Q3&BSZF<;wZ4rHL3lF@x8S#uMQwvtD6-M7pvw9mmME7op=P#%GNh8Qz;*|KJN%=spseNBZ?wx4wYvLC-FfXJNpYNo zGVRQMUfh$A03?i-#{?h7i0_~jZu~i=UE0Atnlwg6@|HGd21exZo(~77Obqi_ zpYV&9n24G8o_2Y7Ab+1~?6%7d>$ z-QjwXzbo^74+oBvE^CICIolrrz4De(08z#oUzxqaGp8-dxM zY!QRgoc?vR*7q{W=Q{%v{{RF@x66FtNPm|g_Xj-s(!;3U%AaSlmPt{tFy{&Z&s_Uw zfzJohl$4J15pZXwVurF(twBCvJ}?D;ss`A=Wh@T!k>{{RU!=bANJSY)?zvJ0%C zkPvz)Ad)%cV;DZ9RrzO)B$*_IWmJ>OdEspR(~ZEcK;(D)Ya3tFV86Ey8>5^If}}bA z=m+R}XPn@66_VF-+U#?lAk@f}Ak?gO-l_$T>vqNn8yG8(n>aq5eK@Ng8P<)H%`-w~ z#B9bja=U=X1de-tH52%9Lpe95;_g1iKK{kW!N=H?{xVtt`#6sgZC)gh{s%xz5f9E)tw%R zsCbUTf9&*l-Z|N2d6R51lE-OMK?jg};~ZCKCZFN&59#*~_V(|xHhChM$ug0^19nRe z2Rx2f1m`tI=f$=+9uar3yG=6YPznvD%tSFzS7-rPNDA*`LBB&thw1D5G7s|V1v1a2?Ud# za(Tudq3K$^{kzR)5teyC^R8rE25gd8vG3QOefsmb-V_kptLt|nSz!U$T0#;Lj==ry z4mezK)2OVu<#E|q^XAszpHh3h14_HFxI`xqPR>;HC+W^Gc=jDDv#`{4Ek{tdk6V!? zm`J5&HtHlQ58UAJxjE_DtU1taE+TtKq`8oC(MC*B5=s6dxzA3(d+|wcZE+?qb;oTA z)JDPxtR!zTaM&!W+%X3Lh9#69J*p~HbBlr@Sv#BLo!>Dy&l{7iI0eRjT%SWma{Od- z+4K5R54^cOPePcl&yKMHaB-LXMrwO|`-nJ>f0xkz0EbF}PhdYMqXhCx00;3Ve_8;% zHG76*=ORkD$0`r<#wqKmTM!mYRziBV-OU*pz}(wO{3{Ot9A!@&g1D(ISS0b1Hma~JL+A9R$|BSu8vg*w zj2XhI;~RG$YFU?TgluT|A1ienReKPo^oLbt+HyDJx38^PoBd}(I$##v+t!YtK0ozh zoM?xHr??wxK#rm;LVK!`ILH40uB52uVdVk1ACUIJ6vh!oV+SYqhvq7IBkFy9yH`2l zf9)$<@pGijD0w1SWP}mr%DH|UJRiJzr)v>iiV((UBaZQ^4*#I!OJ#zk_f zKnTDo0AOSb>tp%?OL&1=o(G$_EoS2)NWxK7u>_1NXd2?&-ulDUDfp1 zftt3V_B(aHgqvVnm0^J(_6Ort9*J4(Xh(IOMPpl6ZBP#>6XB$Lfh!?D3XcLX0%*13HzLtReZYp5?E)I$i`=gN(3rHJ|n zl^IVR$smw@Ggvydv#)8eM=NVk=4t465L_k3sWQtRrDb6kKWn(PEE8@*?$}7@1D{fO?@6in zqwH;L7g4vlX$I*fglBeGjzcQ2ILG10>&?v%#FqL$hWy*eqn74U1KO1`7ea6dJ4%7n zkWX)-jV(i8@cpcES;=K#Yc#Pi^X(#zWkA^hvYm11fmtM&?n9z9hy4-;H-aP#O{)2u zOECF(^yfUD^%2)rZBAQDOF8Cfq}cf2=eWnOwPbjF!kX3M-WIyjqm6{K2;>{n9e`cR zcMy8|@<&|-T{6z?qp^FteKzN8FnJdZ6oJSL0Nlfn$AZIxPw{h2b8H@E%`WRu)pgl4 z_%zFe5Xh@6j=%`=!~(}4a(ehdEs`UNX9eF;qSPlzV_#@#xM$oRG9NJyR>D`6ToHc)go-fj1Go`h@q8FXE zGP6E5vmOeJ;3hHDmQXTD#Sag7PV(namJM1+G?`SYm^A>=%;Oo%aq!N-6*%va>x%k( zx%%RvytKB|ATZuUvLWo89c-0O2Ee>_QI;1 zfq+g4$nG=Ju8pNzS=`I1zLd6JSRyHkzT8P;OiEKSJM;7xFwwf zNX9+gh7NYGpiltMPSxlBFYv~-rb62twN1+yl20#eYq`K&M8LnaU^&M>c%GOf@^Vfp^fu`>o-No~UMhX*B2n_Ldx4cFslZ=Q zbJnu&{2nf>T`lhx-g#K7I>4wTOoj-+W0l8jbY3{AalYf#7BycL#j9%&+*|3tV-Tq? zbs5~v)DyU4E9ubI#+hSjb*g>0NYtR+v-f!_$j{R|cx>bn3kE!nPfEeld_HvBc;dQ= z?%|F6(jk*!ZU_Sz8OAfoIV5w`Q1;e$dW3f}MA}4ltQttCOe?QbhEsyv0C@f$yjE^H z+!H+=bghUHHT_{#MgSLqKp#K=AC(o!oqQ+D7l^ImMd46iGVL9PH}Q{3Dy)L#JyGDg z@#l#w8p01XuP#Yx6Ng_lvT`s%$sPIpDbv~5X_nTOVkRMp4#AOkt1kfHV*s{0a&ygW zYY;N{vss@0%!C*72t3#GRD$P_7p8Cy55IBFex;@B7hY0Y#U1cQNh2syFsp?)&OiVW z#tU|>r8KNci+dDw=xyzF7K-0whGYQTKqJ525#!vb%5n0MwMPN6GuU8b0<<+rT+0L7 z2mJWmh8X3&)$A5SZUK(w-a{m*yMQv|JoP6ab>p>Y zq*{KZs3xgxbu0>F%CbzslNkhMfyX2a1CD(LYV6dxmcqT`V~@J9EOo`US$7etMW=5is*USHloScsT{L*S7+>YrS3= zbuHg4f;ChGBLblg7X*w0++!RA^r@`%?J@2cT+bv@7hR=}-1_B-{E0OAT;ryM=$N`L ztu6GI5F}zWhT26);9{yu;BL+UVs`_aeJZx7ntkK_vs8*pc-ewRjK>Ys;O*pcdBz6< zv=(WbP@To9$DHD1bD0KkH)oy1U~n;kSFPg_GRT9?5Tj;7q^~6W%mL#7;{;=XPc-2N z9a|ivnn@!vU$7*j$i%N^QG%oeat|R?Fd5IF!9KM^Q-b;Q>AuSxnT^?^!)5kzI~?Z+ z-0_aRcjAgoLTKZ)GDuahBu*3@WN>kj!OlPfuQfHtm7>TR`UxeHWhOr$sS%ODCnOHI z=ub@Z(w*bF6Xww~h|_#WER2IywHGr-Acrz25-1%;NbAY#-#qhOycXBi<*s#s_G@@l zJ0ba+LD&PFW8Vj-2fca5zZKnIvFg2R`JS6Zq1VM3uvm?^1vGNM27W>FnNkrDGa1PEO2{K3%+yopLe9Oa`kr zTC959vuW~M%M><+6vmR^POp+n1;%|adme(bZ9F;RTTOD}NMKWMDI_bOl;;Pgcpx6W z-j&$<%Hnb^ATVyd|TI%%^;jZpz@U3hltd0yz!OTwT<>S*FW# zaO(nGLywYI$XCEQ-U!PtOkjh7la57kN5eXvt#b3|w%g#9uoe(PT_3geH&HMrn-w!xYMp1agQEhk(IKfOXdVWE;29+CV&XAOlCVi*`&)Q;^d1-9|aBZCVK=g%sed;S`L9 z{{U3M#|L=I5yw1oPMp3FjA}8?`-Qm6J*uW79-MQ5l6k@D$6Qs|*G|4y78h$OM=GP6 zMhLr!J9h`dwtchs^&2Z^CAE#M!D%f}2Kzvfm0%-+g(ErW56l-FslcJT>V}dt4aT#l zz+utEai^F<#EeiUBxGf@~=Gj=ad{PHgLs$@aG-Q4u2Z#Z#7#B zgp zc4mH)rORO@x@)B(hTbyqiDNA8!|tm`*BQn^DUf&|9M*$s*7w&*aeHFdQyAlo=9*&1 zyw(!w77!tJnKZby^9RbEO?D~gZB$QK4Lk_hWd4@5yg8dEK=M@2b2yz zzzP>986}uxfH>R0J$UI>sm3BV!=#&CHjvzmj2eDeH%7*I!Om(JQ_HtRP{C0^0AzuI z@6YGWIfyO%InU77=T#C_B$sooY$_GV8C?6WDHJzV4UhI-q)>6r;rQm5alj!n-;7pZ z3cxYker$APq*0dnRDD&knotfhH;C@h&obHg72nS$;kJhE`1d)BpbB-yn{my+U&x~eDlx03$=yvx!4Xo>7&U-*%3;Y84-5??X~TTP!a-Ow=y z103<5$I`X59}nKgBI+I>zWYV%rqdL02+}p+gy53E5KkwZjySI>@e6An9g!{cWtUBO zBV9(~e=&T?H!zH4hu=_K3<3N^k%Px;;NOb2TI8|m`r@sIq~wKR#1izt1d>#op1g6_ zCl&Sz9ZVZLOWh96{{TC~#7k!}zB9%;aytsgo51n2vqPvzqpBmOMt#ml@~)fn6rqo; zR)W;vuDmm=E4enJK%*t#aCdj$aL4le>mFS;-YMis;Eg6z^ZAkGgL{u!^*fI|TFPxa zvp&P+d70U}9A_NkK9v*;JhnSEHG!mc0!ZTo#(jGG{{Tu>A2H<5;hiz2S8F)S^#(Ds zpHa4|=>8HB>rU6Vtk$wP9m8WiKe`2a)y|KnPNd0e8ekl{e3%_iPCpY~bFJRm!FlEB z%_quE!zj*jxcP^04?JM-IULe(x*C$X+R3MAx_+3*nq{j;5)!cpl<)Q#9FzFhmH6aE ztm+zMNRipBak!Q%cpoU+vC05B85!rNeDE#mUL?7i&h8caMZ9vamlBD~smg#sBWUZ# zKn8j1T$kImIJILWZHZ9gL`;>CE_q>|dbWKzHB_lMK4v*i>d5rp4|ulj-qC-xJb`;> z3~)-4Orz~_gMlECm<471;}G1i>4RR0Z*v{Ryi-NH%asGJ!#k(zqa6eSs{gGnoyXJ48?a~7AgP%o2sB;m*CdeZ1q2psS#v9 zvHU7P-#0v(syc8$z~eOV#4jf&9MS^7Z%(xE+;f_)tPceKH0yiNB9u6&LsP~N zG=P~{=Zbzo>Tyu3dehauY;iytI`4$E-FnqwxrqmqghDm~sM|3+v^NT<&E?GM35=fj&H>|b9Q3bI)x14psz)cA z3K>dBs@*yDuNiKK63OO* zq#v1%Nyzuz`3gucQ22)4OO!;moG|j-s;CSLbvXd!S5Y>NX{c&8(Q6Rg8D20}TW0eY zXCp0=F_WKfb4&h%7l&t#D`;F=Hspyu`P$(N5J4l8(C5D=snKm=Us9met?%THSS}bn zyvnBGWM}>yZBv|Q9q>n|pwx#(wVOlxRn_9eBtpv^j*TjToRF#;ACIq5RdvSIH9I?9 zHWr3h!z;%tGRCqtSae=9f=|<_qRd^`>Ea)>#~GUrR#-QbAH|QGZ#;F+1e|rGmVn*P zXHu|vp_tmNmra#eyuKNR4P~p+T-?%MTFk#{wwm4E6_GsXnG142WzSK;=hPoc z^=&R20Al{mu{PSO{G$FR;gLxy#xuu7P;r5r_N?C+NBya%top>N(@&2kXwgCWPdk9` zl0Y2wKZzN*t1-By^dr)>tvcbcG^N2n(Z)ydWM}cldU0I`i8X^~;or09i*FEkjF%)G z#C(pW0)gmr+nV4s&kO3%U&Qg+Ozj`cv4MsoxGF(8{{ZXPXQ$|Tp1Y&n8@o2MSr^Gx z-SaL7E<%6^9Q7dc^fad{HDHR5Q)sXP`i zy`*u*V~RU}pKtfroO0O5JXThn4UNU^v)@lCNy&F8xyL8vVo1YqG6r}(b5m(O2IRLk zH6I%57rMQ?mS4L_-!|$Z$&;w(Ja;4I1EA&HX})aFh*KR7bJ+TK zuFCFxJHxPDTiaNDlkF-9d*>+ZxauPZBS?%hd_>upHd;=htXNGdU0Ye~oP;J)T&4jS3LNK=oD6lVmik7Z zB!g10o5-A~S6hcFv8X2{LXF<}EWLVnu8&opNYJD5C)BNNu2ljgCoE$fu#1!Hfsbm( z(yuiy6AA3+(Fdd?Els z6;17s08OV2!5)VPAm9^ITX?Hau-7BIhR!zACWxYkl}*f2DwDV=IU$1u02b&7Amkca zy#t}C57_m)d#P@&Ev#g-e~EG3){3mxmTVm zf{J+9k#M^}$><2=*O?g>^xa&@l1p`QF)!r;BzGjU5TG1)>^}o-wlC|21f7VILR34d@bQ~VdPwD5-hiACPS#f^zFqZ&x7nG)h@5?!uj*u zNi)d9e=Nk~uNcla^ro9%5YoQHdR4>SX*PEf?J`XQNXMroK|ju}GZGIC`D9a4&P!O< z77W`4G65o-$e{8UI34j{p5hlRX|Ff=ohxBM0kBH&an_e{JvU=MnWhriKYJPe?r8vC z56Vt>!N=)X0DuGi&&-OH0;|DppHWOw*#U!N+-LQv00Xf64FE=f7thFlFloz@#9_W; z*yU+{VED^z_gs(8nwx!7uVR0d08d~_Y8g=30Puh@{c6nr0P9;4d7VCNV?26MX=)>p z8C_atVm3to05BNpFny@FZPyHP=cg_(-8@Y`($9^gVnK*8 zi93BgsT=N}r6j4fcw8=kd*S+p)$QJ$`Pr%WD1*x4hMFFJyLU=f?=&bO0BEI3(cp z$mYGgoBiRhC;6f$vC`i7Pfpa|?F(yfcW-g?%E5?{vN9PQ9;EF!KPkXG9FyiADDW$3 zt0ekltu?!5PqNIVZXjO!lc`bDc*^lx8h?p(9Wz;X)in*G7ZDkzedI<40+2J4k6dKr z=RDGB9wmKyRE{Yin&dP7`ZdlBwsjwex&__9lv8(SfsnnV4ahul$8i|vmBFkHV?@{8&F$JteI$f$kh@Cf00Fr2dT=x8UW(Sby~Uf{ ze`TeThgjR~6FHE4`$<$)>5lmWy%P8WIU~8A^83y>4HyyfeL*KIe?GL;OKgW^a{dwV zF12x;9!vR6q)-7DyC34C#Y{lJm=GoO0#ipvjZybiKAR@1c@N*H)HQ7qjkkox`i*|7dH6ckC{(X z{{YwGptjUn9g*D@Pb)rDpk<*w`2Hd6YW4%Q@NbL{gY_wA)lz$lS;z(L9aT6CbF%0`md78FT&c zbGPz6YPHXjvC1wqdA#{#1Wf=k?(3bToM7^M_N@651K#gEUEur66prs%u#zjpz=*gk zz^-sqa;F0T930?vAXgQ4 z1WPK)-fh*3q>Ai1lOA?4X2~q9x!sY|nC0vTvxmv41LKeKYmU-@Jpst0mU z09Fp6eQ)9$8R1EU8aYrdFXYT=C}zgU$;RyQ^A0{?wCA8bPaW}Yl)6T!BZBed({(7t z-J+Hth-4&y+2??`$tTx>aanq4ON+>2BPMqU6+tAk9ixHI3&G>PbRQF~X4dtis?7pJ z9lTM)3P&-JnD-K@<6!d68HqcH&d@WQ)+dJa`-t^RJF>rMlFft5ZwBU-*fv9z18^Hk zjsf-NmqBve?Ee6=yiFg;4V{|Cyef&Gf!K0S^E6jg_M5-@0qSGu@PF~zE1K-y$mV=N zlUn$%Uo+guH0f{T2>2_PW;>MQusm)V>CZe>RJD5>i)ATsduKYNuL7AEAYGv4a9RFr zk&p>IR*#4*%=+%IBQb4lLUxibFA_E+Y%n|WoHgNpGmiZSG{Yl;z~!`<1r# zAmn6YjCZc9s~Oq0YZ#~1ucn^K+GU4yGF!G{b>xspZN0$bAp2GXI+dW-9xID?gxyLQ zK$E(mkg&(yI3pvdt(PUVxn|UEcF#X8CK=h2?7$TuRRiuG1~7hO&JKF=J*ot|wXwTPX(t+_ zZa1pL$%x9HnFo7hdY&rQm*IUvdls8m)UIvVWXbk>g4zE7XE`IF9ORxldTiKf7Obs3 zmYE4qNs?QIL9u&t{{Yq?|iutuL68f`kkWy?TOjy*G23 z)YJSFhfs;HXNu-c?Jga81cAbU-2u-aFK(4*Qt>5*lLUg^=-k}Ofp&#E5&L6|;FHhu z70BQC%U;zaiq6Iswk9#S*#-?D2N*qByLaw=>n>-|9j~d}%_g5?YQpN`3n@%NW}U#1 zoEFYDt~mbydl>vH7W2nT5B~D? zL2T0P?tW2@diDC`n(DOA58CPCL8=9ga0wD!NUjJcIP#Q$r=RbG-@PY(q3CnEt9<<)GPYh2mIWx%^+W!V zN2=%+>f$TNE@W~Wy1Z>Tn!wK^q*eB5YXUXH1ODUAd&at^rO8^M=#&eF@ z#dI-P>sN3q*x91NBH)=H1aqE!M;$TRqm|yl%yqgZtEJm`mV2vkktBo^SHPC6IKW6*RUaC;n9#qZh$ zoMze=d1r^rNR)y=+72_*I3oj&qOrUkVXDEaT-{#6@HXN+sgr}8^}}CWGozJzi3)OL2W3#m$@NfQ0ZTy19_q=SKuJMu?vmC(J7ot!S| z8pzJsZTLS^j+v+f#_}tnb_IAFfeVj8kJ7$-5uQc=017wtHjO)OWk@zmGlzT}o#Y;; zzj{YP!zVpEjlh02e&W(+oCJ*URsvo?d z?aw%Dfj|;isB6_8Uhr4$hU@s%%Yx>1^8;@0xwjwAsM;?3t)LerPs#=jZH+4O<}q;; zPUy-AGBDhKTA6MIMEio2jw$UFko>a7%15ZCLQV8Dt=pAo8ak`QX)kJ3^a9)Eef+eEzD52oaQ1lY{HnWPV-5AKDRV-gvbA z*3>S`v;fbK_LLm)`t&us9;)R*nN59uNl?`v8dk3cX?!u5c!psZTm0>%A^z5 z2l#70O7T3F7t#ptFEqWZq#+yBf!T&sAIsORN~X6=ZfCw26oLrIJ#sUet8=E=%oXQC z7CuHKV59H{73X%J73G3tj{EG_QDbkN3cO5vZXk>k>@X|6x7YN$tvp?=%sy9_=19gt z@(h8<&Opf=`}*-s#i3mu6|0E9w=M;wo@KJkRw6+kCU_k4j8jy^9h=FEBy)rV`3h#W zsM|idc`ltEU}>D8ZkQzW=~>@xe=iC5zuK<&*&`CehqJgdLhkUlRBWFw{QA<}MQwLz zW?U=xBfm9Suk#y6JbM|J0E4(1idn>D#+!&FWC4H(rZYy$TkSX~4%ZgNaARSfJv~7B zaauFq*yO~ry2{MoyGCHG?lH%2YN=^DvH&{@j`Aoxz}`%G$0um#G^`A#q)3-q+<_S zZ>JtqK699n!z^X8fam+CkJ7K&X=|-nw9PDb@+__#r9SJ^$O4w$A4aVu7Un8pX~Luw9_taHlnDSJwarU0giJlPm)0DbDa9t zOG1q%?;~UFDjqU8`i_SkvJE?OM{nigHk1B(O#-m|Km+-T$*FcOKFRz?M;FB_K&b`3 zt9&1K&2g#evB;oc@I(?Pd<=p3bDG-Iz9VT77XH)mO_ckG${^A%BH8(~XSez3!dr`W zQYVJST;m>HuwUlJr}8xYrxuo_v61_L0W}`?@|W!BzqEDJd_uG`69T=& zeF^hN^8BkgJ}mE=)5`wSymj0z1Xj^Pt~UY*Q|7VbBZgnsj77K8BT#&cbz%nKEmx0G zoYZY|BtsVSK#hz7kYn-t=9j(vp~*pgufWy5@zvg-?C|LeVJyrS&D3=_xQ-`XtQl?J z2(GwRA1?<6sLy$Ot}qu`lU`g~#L=bJ!4g{nF@#mX1mmdZfyv-hCP??Q#Ii{laO({0 z9TB^*7y~&Z_v=e7#J4I{-={@h0REIXH@QC2F<#;}^!+9q>p390)JQW(7D;iwOO3cB z+qhC6dyv%8Tgq>p5ct>ukmieEA} z0hQ1KtPesDaYcE&eka$gBU?D^(j>P6C6CE(kS`eI=ZsNU+^%F;@fM+_L*p%9?aMN> zT8+UuMrAmYBZVFE-Ayb|YdWr#D+jW*g^u+7+4+xmC#O~I>+f9_p{7R(dscR*u4%ecN#;&2uNUrij{~o{2aXgkPQ49uIVGVwy+Xsmu$x$= z)(4+BJMgkHE4BtW2RYz$$7-?S9aB!yELAS9&9UC95o0aAutqSw7!2^({cD@P*L+8K z(c4(*w@`_)aAIiHh5-aNa!32exb>>m{vOmWbr^=ett=5U1w?->QTCi=xB!fkgZlI{ z?=aZdx$&)<-8$(ut9f%K5k#m90zk$O-Clcq-;QuO{Zmxe?kyuayUA+|yhe=dWH>m$ z2P9|I4*vDg{{X@{qQb8uqM)8V|bL@fCRMtlH96R{+5-=XVRUK{Y0{q4ld zeQ6D>d-BNAy5M6WNIdb7c>eIBS6eX}i>uyQTrhLy+X=||V!{wfi1<1INXZKRU%16?NcEP%E$K;Z$w2ZNsA^TDq$*E~pd*}=NDQEeOI z0)dGw>zwjVI%gG|Kic&R=uVYqGM4`UTF)NX*BAp0_;cfTwtTz63#hg zU%F58BmDbSxMC1TvwJztSh1&r^!%&9t(xL$t6s~<)kPwiwv@iqjws*^Nkq!-&#pMD ziwtT2SjQa?dQg3741q`ojGPMc+il&JR+CMJR@}?U>S{miyJ!`eOAVuq&A_Q|=P^Ps z8M1p;Yuwx%G-GeJ-c2=j1*>U7$jk@_9sB!Kv9ZgXZwzuqdU5{%)~v;n<(o1i5&;+y z`~Lu+%+iDp^C>X$HiYJA2e2TUHn%A+yO69DlMj)W1@=}W0v zPPa`q!;U!}M+3D_B&ZlN$P0{cPpPXB08(OdR|P=e_2-O=gUOV9-deKtEHH6emhzCr zhu$ht$M=-=AE2h~l{X}6rY)p^TR7w2r{PNAWhhZ5)3{{xCaljC1nz})j_N=JeQ;0m z6=oDKY!Q^mz+`c_0J9OIMx^#p|7EEbO;nno_+M$n1QGJSK8)}nn-J-IgCNqwPWU84wi!5>b)g==Zr zc(II@k>!=ScVnJ<)Hl_Pvl117QbWAs3{N?#)7sg(znyG@Z}DscKZvVr!A42P)}tu1 z#CNG-{oM7a8It-noyEIIqG;PV!i?u0gB5|R+WngA_jn3fN)_kSe=uvOz0?}g2>^^J z3IZu?5`8}+KgW?=eeKM%-3N9q>;`!6&-m7mxS3VPT`<3iizGjK=WlU6+#MPF35H<;S;{BzG9}Kgy}Ug!K63R%3A<^TMG7 z6W@jhkHpta7PF{ZTcC2z2L)6I1a!t52lf2wXtkSm!McVx&g}9^FykL}xc*|D*jV#j zTf zjMGe#75?zXe;n6KdEt4Y`K%{m0QrQNKamxYa~=J$D=ac79bHo+^QuxzTA4=7?c9#L zSaF^WYglUX+o*x#NfI%)bVRERbk2A+M+j7i*`ssQJg@lFLK)yYLae#!@$x@Pu4@xx zse@Xynn0dr*#{eBTp!Fb>Lj+B+VAYw4FpqU4=tTT0(xW?&AYZQBJ`V)a;5R$;Zx5^r?65JDoGh0w~0yML5CQPCo;W(=~5N)sb~*ZM4fq zxxRD=@wiu2^5@X8bJMnY!mUWbYEn(?b+^klv8G*F=~ruSd2H<%K_ONl2ph52pQpDK>f=&015He&Bmpr#pK<~8jFpwCTBtsZl+jyj1AG1en@Y@L0V~EIP z3Zp!2J$U+nKRSx<#9Do%#y2ugGhmH_BG{=7Ld#f!;yEquE$wZt7%WoU&ZVD^x&dsHoa7UpKMKoz z$~i3$#*d)*s`p2_mu;I|Gz!>IVo>BSI0WON@BMH!tLc|izfC^=JCwP(mPPU;ZiJD@ z$6PTViTrw&@Fl(F`dnRINvU1jNb*c#v=FFZagQ*ba!>Gv=zg_-MDRRvY6e1=5XKi^ z5M~f@o=XB5y}BO#=(Ki1vpo73Z)DU3gsME&{{WUmV5!D%-uzclqdBTHnP$lr9JhPawS?%!PT?Z6yWJy%nM$doV7AyNPYX0_$g z+7%ZQnXl!~5h%d?g(jbAadiyKt7+EuF-es`0+tKU1Z4KdVMn%0;X~x^c>UsA+}@e4 zj@CfH0Lppo&p!NOu%1~G>&~<#SzF~`PDj0aulyli8TrAqj7Y~S?oUrlX1Tpzz!At^ zO*R&V7nWd!kp8??DP7%@%WaIG4g62kv{+(>`ZIHGtV<}`4?Tw*eSP{G_5BCN8cw`` z>GvumARj5nRyoMvcjO=Q#dtdChB=vM+E`-<4(yJ8Y>tB?AK_GGyOT)(P2B^f&)O{40Cbz_$6-j~S?S-xBz3Bf<5cz1?=E?wG6mips0)Fb8l zOMI=4#PQej{}sp&&(C+#-q2@%RbA$s6989jRAf;!houC4)60j9irh8cM8-nr`1 zr&>I<712vgj(!gj+f8uR%#8)osAh)Xd1Q3;`i{8kT5#`;-buo!lNbQ!6&2=@Z*s`q zQai`WZy76&!_)bCgINy-rKH9@qa?BJVs|Jzer$!uLODFIJvi@P4kIN`S`OY%{LK{m zof`};MhL40P4k7TY>=jhv8URfx8Tek(I$c2&*pZ6lLUWDC$jS*#i4t_7uBBZ;2eBE=RedhmqbQ+}7RkeZjanP`0>^>d1N

C~doj zPhxqd250s|#zBr%W1d4UIQ?lPwUr1VLyn%H{vMrb{Ii8)7{P3G&1T-*TqIJM@|aR` zr#-2yMPlue!1H;NIz$khBQOU)jb>{t=CMf1%Mc)j9e5ZWfc|xvYk15ywwaARH2GR$Ak*--B)(T@-N_%;w$QW+9w+jF;1TlY^TlN=TFOBTnLJ}S&*4^83}X?< zz#gC+1NczHYC(N8lN7j>ilM;)M<9Xzb5`M!!YE`|I3(sP|c2d2YbmSZbRS1Ko2V8OWJl0f$ZXA)8 z2d!Pc%3PL{02~lM&(f(y8{N#2Mlx9A>F-)ZMcqEv?MkYvh}4FWk2~A2_TZ7n*V3+C zCB??r(Lx0z0uOJ?j+LivZxy^Msf9!sB=tD%Y3Lwk`3jT%$*I1#D5Iun!Ys)#1%qW+ zderyLbu#SQh9E(~IW7JbVWx=z%!)8^jPv>{%_wIks zO6)$$uQv7G8`Lo$%C9J7i~@2+dNi}FOg=kH@cf0yk1A~ut>$SV;ezsGY!H1h(;rZ3 zDBAwVdrU(exWg{O0rwx!el_Vci)kI3P_jsq_+(%=6Q5DivY$YQSF&fbk*p>22M_z@ z!0W-sT=lPBmUoAilTJU1{=P(VGm#qX>o=EnvK#;#bYXxWQONwNM0*?NkQu`%U~?W0 z&ON`V{OfN20K+S9Dk~}~H%V2ogZ}BPtFH=`DJ8qBw(puiHn15SlboNxkH)({v@nUK z&b9u&Uov@HC`+Wm{{SpIZcv^|%Da_w!Q_nd@7wUIkk}=~#PKq`AqgrZiMn78Nyl<~ z^sCy2mvN?C#BJ`3kd!-GMIC)Jox_ZGG+OJoiy`x)bW%x7{`h@xK43o&$F+9Ts~WIV zgSuq6na4qvH6{l;K%VYiiQ!#z4yu+Rno=B*sz? zxIE+h@m3>+Zz4P183`ML?&Oa7$m5^sSIuEroP7Fao!bF+fgJw;&t)l}qg5l}t2QoS z4;e<*e>Um1l$4i!5|;byXJyn!Bn~d zbG-mZ1O4AxYQ&M@Ov@C6;Kw47oc8CB&a0R#ad!S4u)c@w7CQZeN=_Opyui!&4cY6| zWP8)*@X}gg&by?@8G@*W^;qPb4mcoWjGn`j(z1Yxz9fRXy<*yl;&-GA*kQQC-!yDpMKHf%u8#4?3wAv&+kO(RmixHDO5w-8D|8)T8# z9Atn_NyjIydY@Y5Bk?AsrrMBXY0Uf93xs?+o-)CPdK1P7=}Ve#sB*`t(b@P0`pu(v zF}%UbwY)&I$$|!2JOhuIax=lt1Dfc(KAJ3dhCO0Wv))EdA-;{G*gG)|*n$YoI@g+M zo+s90p57}f>!}$PA%Y^GXea{$s~R?O$Q&*`Iua{;Q_(Lkqz|J(eAjXFdiQPn-Ni>P z3Hc8VoS$ygN|bMQP2H@IY}5RWLLWBX;wfRtUFbt{J?g%<;hQZ^&?~vOWMLsBZjAAQ zSqZ`8zg`D8;=GeX*EQV^)@(G0O{6WVOXuGl@0FHJlu!U52G7*0@-bN2e}`aM8flhGr(Bs{ zMGOW`Gqm^Tp(me8>~-5IC-JVS5=PR=CG6#5MBGRc9!T`*$>3yrReOfhbUi3d;z;Fz z-Q33lNDlTuaHIl3{t=PFmS9N8tvR|PEGC&bieh_0<0S@Enp-Yp8(X!As$ zX^;S000IC26&WAGSAszt)oTwIO|D(r==$^#&1h~xj!4*}z|Ps-&Orll;EvsEtknJ+ z>DST!0K}917DOE+W3|6b*EW0|V`btN-ay9UFfgr!86@C-b#4SlxEI$_+*t8}639oIIs(Jj1dJT< z*PLS-&_!hgHnwVfn`UDJxE^5LoRUU51-c66v8BaWX*4 z`sK6v0($kMlw8EnTHI;(morbPn~3BfM-xZ1!lQA(A+h{jNXYd#))X*5d|g}%iSSjgDjEwb!p z0OtgbpyLF35;)CYEroKXopf*P<$Jq-BW^H6zGx$^NdRX)*{w@S8|;ha$V@UQBLv}r z6;|HBTU+^a#U;eqBHPIWVs0ah9v7hP&Q5cIf(uQAUL-SI&odMI#~-;E&fJ_~bLbCW z$=D1iz8cz3s5Qs-tk$Ui0D3T?!*kOlE;NWC?^r!7y$+4s1Z;T4FrLMBMi~t43TRj26&r&`A06x|0I)1Zn zsM`sxU(Jb|XnYaRrVk>%X}<7gpt1u=?}|3lT$?>)$8T|+p`#f?^&Ps3 z^cy`&+V%vJ8CFQ&qXWULnrOSGWa>U0w7bhP6@CiHga=-GHb0(gk=FD*b4+Ep(B&Id zyvZPp6;sX*xjFr$HNu&7IYng;P zzMjyK32EUBz;_=e3jvPcpUCmqY2aT&6~(fNAdqESpdtS(%7u zAZ{e!1pIg(x=j)MViMRJvIZ&ACU+(4V|; zGrRu)tyHf!eX0Dzm(Mk9$g2cV#!f&Rfc2xLfZ4gZg(49%I*j$lTFZ`qF6$`Ul}=QZ z#%gX4;=?sKe+Xe*23wI<6oqlJ+jG9&2=L%T<6=oQOXnK}C%^(&u*a+|3 z;-twx{;ELO`|HQ9?9*C6h|GF=VDU%-Skgtqs9~J^)eO_eXb2+!b^^0+wQ$jtggPAO zDu2SGj{H5UTe=r*!(;X1`hSI0n2LIir1ws{SwKQc@qn`X zu`f;9y{JR9Xwua+5khJiLHZoScvI#d zZdqCoT0n8Qf*f(!=O?$dLW^+|ks^|CuCE|Fhs}%^TpaQ+FnZ&j-i+4qY8a08(NACA z05hK5>ZRX?_ZE9;Jj{=|H$Rd803+*PK|?sh)zW_J^V{zs!K09eQYsN{SVpYimAN@n z$vE7-57cqj7^?!}D}ZEGcnLmQl^cO193Gu``e0{~oLRckrDjWMgwc5b;SlacCz1f` z&t3;7@HLJ!i>pH$Te%1h()R2Sw^5u7f=96J>0ZKVtD+4?u|+`T4sy)_6+7z0=EfAa zBaCMQ*b-0ms#h?^LdCKW=6(GF4Nh4_$az~bh4#z8=nI~yH z6M%m(NjBz^&i?8t+Ih>`?_wd4#N~(Zx}TJSN47DH@@d_nSjyCF)u8(d31N=u-Wf8) zs)HE{!1Vs;_sQ-ms)=4;ggZKGHV63F**->A=UW zHKUH=-R;rZCX}C;HrDyNo!C7GLyjnx6%z(%=C_b^mId#~2Lm|kpZ@?+s4iue($vj# zk;`ium-C`OF<*YU$KK98M__2O9mt_J`XZ&I%`_)_6%&%|;GFK>>(2LA{4loHkVC91;q!1UD9yPOLu33rQhtkrwTOOoBF%z~nZ5p4HNL zf4~}jw1V$eva@THjQMd#2z3MyLHUMR`08=r>Sj~r+zf9G_#z0kNVT0k6%=3$MvtGE z0#qDqVT|rlq;r6Ciu5f%PPVg-NbH(4DU!_40p_;e81M<_o-vXL%}alM29c)8eRC)< z+iu!fuo&bf-%d^dKbHreDe;HIiS=9QY;;?hE$pMrL9kTK^W~d^!1-_nIu^<2Xqc(h zb`!EY%l%3@E|%Lw(&W3p^H~}rh|zYRnTwVAha3^tKDwF6Zgt($O$y%JO>b(;7T+PnxZLCdaCQtgJP<}WHO^^&3~kn9bK(oRFDGX#;x{`O zobp(W&7Qg9yWK)2gTz;pvGeX8=3x;d{Zf|fz5eLr`g(Cz5+draGiA2?$NS#&Dvc{5 z`BkoD*;=i%3k|3GDnv0Fs$d^~{=Hp-{>`r5(IuOxWLhr0Un++(ok-m|W* zqqMf)b#WcMI0pd#0GyxBv~`_A=T40#xVnnk+sptQ66|xpei9~sW#U?-XC}C z>GwSnTigXZa@0fmv3gaQIP|yM4xq3V6Wv%B8QN(V1jrfKE1_6V`7RPFPbZj7(=B- z-)Ss2Z)|5A@q?P;w3zix|=AZS)- zfca7S1M8l&xOKxkxKf&uBx zdQXY`TMnD2;wxz+l$?Cn!r*7|&0}fWbUrS!ntRxceqbI&%%f_P$RrSX0|SrGy;n7r zniaLs>bxiMM^4t^D{}GLT*kR8BLIh{eqw%K#Qrth-Rf4h7BXFGQ!FsXGR#f@!Re0tR`2{JudfkdeqwdIZ{AGqvG53B zq>N+cRs8BD9ds!^=djyf!K!KT-&k&v2{Jl+SCsyw!ktmz~M*vIjQV*%UxqozqW-)Ycu7E*PN0t zdvSsfT;~}c(4_hl(U~QUzJ;VRSi>Qh$G(*ZCF9`W;-x zClL+u7DJE_@OUGUo}8W!*R2ptt0IGu(>e97Le|^FIyAA5K1=w5l5KB5j#3Hgu5ws| z>(m|xOi4G7tP<^Qjijk}44W<$nL$E6_CLHq>~WuJ@att*m^(#tF6gB+cE>VA{Rzef z-u2H{Rb?2KGa+R$NH-%w`2-QvAJ(W#;lei~(ylBqp#>2^0|0?g#T1v9Qlvv@R|T8Xh6L2Nagu4)9&Pj7ILvYIGu^T2 z?fw4<7#jnW(tHuml1&@t&P2qD4t^ zJDOz{jAh=D3jD`B(~b+wQFZZmNQu9GqlxKt^Z6XD8B|Z7}lE zE&ItB<2WbrtDaJ-V;rADNMfWx7m?3%&-JA((xXIF+`~CMb>gV%kX%Tr&@sk&80kQY z@#`|nFeD!7G8Z}U$1yR!&q%2$89R2M707{XP zsRUCTpl_JqW}}wl$%x4!lB2HPaac26o9o^b1jq_b0R!vl-kL%>HDwtDpU#}vE5%{S zd?Af(t=W~klHCtd2jg0{#f%}OZOp?t{3rq34*2IB5mJ8-C#5ie8;tYDDPm&W^N)H% zAa%99%o1UldxQ6KKgq27y(yz{D2=WJWR*M0u;UoW?bjVZ>x$N$t>IHN)pAv?awel9$8qPtKm}DMaQsJ0wmIBX1pXjt72y zF|Ry3A(yC4rW1dG4t;{m8xJB|A)j~Ts+}Ic-KOws==Fh0kaZ~8u5p?}t?KHm;TDFUO zwZC~J#whX>5tcaHo_IMN4!Pr?)V{`=J6%1z(jdblM4_3>s3T}UG=qXT2Y?C3Z%N0w z3P(1NcW7iq+2tw?u47{3p1V|#M+9+$(-;D@^uG^HsmUjk149#GW+yKj4D!5;58(Ts|_*}a3by4n zy{YT|H)*aMTU$XIvz1gRtPai1(>)R~$>^gTRb30hrdh3i+}CRq!HXMU8Qf*C$gH3h zAP#bSoc11@rfBg+XB4&<4RLH=ERp={oDG9-3^ytHuzF`84l1?YnhVEruuLSLFbwu+ z+oA+E$6!}$5=$@6rGOl5I4z>9(k70QO5~b#rjOxg*`-A>ylA#P#nSJWZtU&s032`! zJ4Q(&q*MK+JW#VbODly_l2n#G@<|-y)~o5U-Nyj(wF_I6NC}Xs@}!u9l8TB5VaUJ@ z$vh?qG{`j=?&oP_jt1xgslXXfMndhu=cnh*C9bTC+e4uL0EAX?!JYs|{WL$}MKpMV zQZioqJ@GVu{A!ANi$hycYrCC$P!W%_Ah?lam2etG3~|q}{C(<%p>X06YXsfLtkO6O;jGy*v25OAEjSkZ9_m_75Zqf3I4(-1| z(xrn>(uJ9|xUq)TJ)>>Z2o(AZ;B)xYI+nR@Vp@^OmI)Js80qi#txUk%(Zn09TE@1dM;1e1 zmvX0hBy<4dA6|I?Wyj(@Lf+Z!^sB^{)N*SsA1+7)^Nf4fk2i^K?PRjk^x<&;v6ad0mx7|9e6q6j{_#XZqvl}aa-xp z>Q^wuJ>9ZPvv&*ff<}1&WbvN8t7OpbKF;cRt!>usB?~%+Xl58Aj+=QY&)0+NOuw*; zQ-RK!e2d16g;&9N@}OiK@}QMGA6|1>*LLfDZLtQ|#su3zXwR@cd;SFA=CdsH8_PHq zr@w3Iqf!;{V+7}nE=U9n^T*-cS*=lCOy#Wf+s_U~9mVdV8+`k&M6$AMQtZvKNh2%@ zomRf#-s91eQ^xb0n*qi1iez>sQg@Ce^=c+hSne+vdv zkVbnCZ(7fb!8&G+=H|#typZW2IQ1Lxsg1hZf@RRl@+7G!6bA40M@F> zxnn+YXcU3Gc7kaIv#R9z!H1_EKJf=2bs!vP6p>#40A<}pc;+&(9PD)6liT(G z0QJ`y;{N~^4Odn{Y}=&=mkY2HfHsW#C?9~MppJ%ZPwcm{LAQFVe6Nzb#&M7c2Ogfa zehEv)uZCVSI~wKuHzYTD^pW4l=460L3`rK%EwP8pz!1AnmPX~|@H=O#i6sg?&|~um z3`9Wf9CpbkA74>YuYE>IwPa8LQO0r?r?=Cmr+SW6Mc{_c2TsG#{$KrSdW zr?kx)GvuNV?vhPV8TS^@1$LPgl|kIhxgPviKdS1t%P~k%g`PqO3G$wKIl=CIx>I~t z;%$(uaHB^VIc=?i++!W^4}9dDR#?^r<&1H~8An9igK-DvKauvRlNHMo=!<&R?|F71 zM(Grb$YaL@@&Ul>#sylu@D`UWK5m_I);B6L2GZ*Oqpu(RYNKs*bqzr+;*K?V6aqmY zI}qEqa(D-hKb9-7i*zc88Mej%QX3sQAFVXl(ZO1Hj`K{D?B`RF4Y*vwgoJ!xvhp$s zJQBQTBp#LM9uVy;O#3?RJpKb((VGduo;nT)9AKV#=eZhBa9SNNiM(iFfi&G7UpG{e zXw_O57*0cHC*?WdV>smG`t^Eq8@)amZlf00E`g;H8cuMYL_G0 zc`jp&UP#*`afS@-yKYG1xW-0KI6POREHOCDf4U@NX#2f$)7O*zX(k65sCatreGTkw zwHZs0HoS*%UcJfnKHUde^Qrs+C62EIuXc4gMaFI|Rh3!!$@#aFlhYs^a%p zr2hcCz}yA_Y>ozhL(dfN2l%Y&{%UG6dB_PS=O8TBV}l_O->$tT!?wS2oTAdDbtL7(X{&xa4z=mEhtsYOsI0 zeBXhjW|`3#Af7gOeq4KFpTyF`3R}WaH*&>^Cp?;h&gwZ~{{V?}>hbZs^SiHcoQ&eF zox2bw0Rsma{Qj+|x|Tncm8vb)+%CxA5d2VM3|?Fh+fQ)E3u5SOk&~ zhbIf1_p1bkOpbY=0G`}_H5p=$!Rt@Pr`HFGl;{2_D?F?AtpL(=|a{3(55m}0(ZeiCQsEl9| zdJezm6ab_iznvKhz>fXBDZ^<{alz@xtoPMmWjl8exc1|m@P3p5dVk(P>ZD|@0V6p4 zDzr#qj3>*-Qj4?`>xz=rWw^Euyq@45p48bJ%8jI8N{*m*pbFZSscEF!CB~sVR`IiJ zMv=nqKG~|4diIyB%Qdy7)xE%uF!Jq?I8l;2WOlDD__g8~q+4w|84QlHd9sFl`9lN+ zJY$f=`v5&^ufu;L&fe<&{#j!e3FKRjc1m{x*VGa8``zp4aCuL*qN>TX-rweA>RH&* z@$Z84k#3hBA4$^U73XTZf~ql+?0M)gdHUcA;H2>{i7f2Rgqo$!QC^s>kkoL+CrXqTj*me65HPoF$NTc11BqhMmCY!x$Q&4+SiAmhwYI%H0;4)EF1uv zdHGo5?|zk9T~1gn++D!Y0ygbrJaLc2{cEP_?m_C_9lyTTJS_|wUCq6OB(!Z6tbglS zW96OLkRi%!6*+t0vG6)NX^GK;&bn&Q`f(z2j8u zap`$_w~*ZEw-MVJxRTiHJKQ#L=u|oRha3^khz0`^${{TyZMM+SCq&m3ZkQuND0P&J}C2EzCI$u((z6hPB zcKcqYGQ{9t#-sA`#y*%7R_jk5adU&A_m+j$V$iwm+$X!gN_#&Ok@oq zHDis0HxWE(FO|3+P>iVVPCMr(@~nM7OxA5R2@Jvr?IZc6o=3@5&tf{99-oDD7QPel z99pc_QCdSR*6<{j1!aTQ`~q%Shs~EzPAz}M!L**3dqR_%MexZ z@`KYk>FrS%N(rZ`3!|F*Oc3fXcWhR8e+04tdZE0)eV&**(CXzAy`-W`2UThm_Z z*75wb!BPtXM$v)}c*zH@-VYV5ZuSDti2P@Hq3QZm+B7RHGe?J(^yT^v%E7k|cN}9R z4EC-l!#ytiBM&bO||q-wT$Wy~6N>an(I7;Yz% zouIZC0CGl8xW#nQc#BN%mxlbSdsdNPlWL?Ja#*fI7SB#FPdMX>*32$<*EUez6%(de ze(C5}ka#_PIQA8pe}DahY$cjpMw}e5IRy7n$v;6^o*D5_*6flyf+M-wOp&TE8*|hj z#CP?q{{RvAGJRS{78g>-1C!<>K1n3?&NJ#xPp7>#6)nep$DV2CIQ&g;x;rh-`>^)q zkVdb$zEO-WJq`koPBC7hZRLyiQ#@wnBM&5T`e0;?^%*^VK9x_y{{Rkuu%nV>y^`v4 z_YkoPoMZ4fBv$lthhMX6HqtOw+z*$?J&(BS`BHxC&~e*S8hdt{GNpVw@GdSn~Q9*6GihC!2TiF0uEd8HI|ZF&de=tqPP+D^5h3@ zdS?f}rCOE2p@R;kS>#4+lIp}2Z1ouY^X*ciEO6{B&44h(jDzp~bHy~rmD~Zwe&X9WHgLMM2!lfvg6J0DDbKIe|r&g<7#P~=;!z>^#uz#@a|gP&eKt8_>M5-^`G z-Na`jjz7<>MAnw~5^i${7!i2c>QQVc|H1S(ah~IWfG}grvv~2Hh%PgE(f~0Kg@2j1D^Y>&H`8qy5w&WKs&89@szRQ=h(wI@5ajFNND)~m?jS8AQh z)UGfOIO+Lx^d6i|tTLpGu`nUP-O!VYdR&xWpDX}4!Nw_YvNAMyJnqX3Tq5bH}lEA zq`Ob2TSAWNQ16T$y}9T)>UsTZOlkT({OfeleUAAEDKtc?j(YCSvwyN&M3ST6lEAW}`t=#*aeG92N9lYW>JlK|a!m=>v!x_gv z#lacl+37Z7Z#X55JUXTE8# zai|!!+LXSDPGnMXGNwOL4n2DHq9&ir^K7Fryn}+Sxs+p$yaGFJ-QSU%)OWWc5p{j2 zSl+^ssK|{YB5rz)PFtMtM^Fzn%UcglvgN58mY-pfOZK@0QQR?*F5wvjF!t$;;Py3c zHj-(UHQyjp#!fn)O5*h&9Gy>6jtx6c5~eWH&4!aCXBbxP^*oyF?B$%|O*Z50Pyx(0 z2lu0#o_qazcI{pkCnkH*e<%KBa~)zYmZ36EILSFCh~`JQF@hP?jl$^~bO2Uq4obN-vh8vouXTjZMHP%7A{A47Tyie|U<+ z+)_bz6tA%fE!bd;{*^E}KjT=8uGWyUY*gC5)hsbb3KWYVdx~&CJMuvkftMu%F7ea@ z$e;zt3UNq!XCjPa>DHJXWZVO*Z9O-1pa%oJc^Mg_jB$(}ze)xRV<0v&jMA0kiU4T< zHsQv4Q^6yVP|YI80~rs3`Jc7MGl~w}G)7-s?SO-k25_;$BRO~En48d*_ z2s-ne*0}pMlv`zyS9kZ1-p8P>UsTrh+ucoc?+sg`=lx~J3?n(l8>kq^IR`oE#dYDZ zb+IncT6cRAVKSN& zJ?Z<>{66C;O|uGb2tz&c$8D!U_G$MSWR-S>P)HjW9G%0j9D3%o^-l+B+J>7QhR-3O zIEkV_xFg_Px)!m;nVLIz%K^FA4ac4VJ@KDzDkyYlu4G@bGb%~*`KWge#Bx)}19jFMe?t^i(sY@SXldt9@#v$c}$_^q;AC(S&3fUL>^ zyik_$9&XjaTHe# zG?v45;Te%s5TF5^LFNat~e=0NDH*bD$iPvYI*Jo8xl zQtsm7+FMJlI_e^>Aee10gUc^JFv!N?*QO3DH6&e%EvZ1RRW5Y(P;eGV7_c6Pp0rhi zqT0wy%GS*za>vPxWcTaO=S5Y;W3#(6L3OO@){Yu^H4B*)p8d81+?RWuE3`A%K0yaB>^(a(%vC zjNB7vV=s;L&lBjfY5J@>outBfu@!_-%+9V9mBX^I`@Op!c+DDD#0?8U)2Fc6t4m=l zcI$6E_K@5%nD>Va9fAOIHsg1Gdsi!{CX{W`**w{9WLJ@{f|2GG19~uFmOLJ~!RMNO zi=t{?C1}#!Siw9vl0uT-F&I5?k7)ij+0 zOpeCd`L#BU!pPRZtZ1#yLyitV-umLS?lg-HdrXi)9B~;3&LdUe`-8_HLTKjHEJY8B z^xMx6+uq3*sFw-$a`th-2}vZ46@U(3J^eHHvEH2)w_&PAH0?$iE-YTy$8~EHuJ({j zWLY9@*y}Fda86I9ar%ylb>XR?xDuAPj$Es`P|%(R;n2v$X9on2!!*q@Z?-HZ+A#4) z$eHECMi+S-nRpvgG~^Dgl2<0Qvg#vO#J)4su5{lf!LBSXpuc(JhiF*hw+Im-$DrBi zf_}A$ABs}y@nS^0hDEtn0yu&DV8V|ts2L}Y{B-oLgUOFqnn?8+m(6^vH;^G^<90?D zmd*zx{{RZ)a!qsB+8gP&QAv6PizXfiw^N2B0x$egI(OM- zyoTo15e#ugj;yPdATbI+&qIUP2j08eK=)BcJ(w~qiq3^F+kiVxG3a>3d9;2vzB*LN ztXapXLR9^oZb01u90x2g$FD)pA9#1Ir1-~I)4t5Mw_D)11O#PL2rs#pIPSwa{Jkp) zRg|6NR8o$J^|aosttv|&%d~Hdg~|LsAxyZomgYa2+GW_?e5O490=Ru&;+&D_Q8*F5 znJ&`|j-aG~5E}u0bsKPb9fx}A{6FIxoqI@%`KOJi$P$-G!iKT zBq=!ndh{ob+3D#P-f275FG8yj2q)7B>Q zS#60z%e!zVrbf}!@r?a-^gVaQV)1T#L3uxuB%kV@(kR+fo;Nz6+*b+tV~paU@gImM z@SThnx;~@~I-^Qwh2cUK4jMpM{KIi0rZ@+l1sArA9=elwZpTxTPYord*aVHB!bl^r z2OSS;+cr1lR~A2-_Mx}M>7D_poPiwd%X(;zTAaq2m!?|gHqSVjfb zp(YGMG5eU$$~$C?e_FjjuRXQw6QE5p{zAuT5L>fs>C}Df9Q*e56#I=f<Ngo4ml@49E3}vEh;SB~)XKvSGX6V>t)q>4DG=xU3CceQWGb z7MG%Gt9s`!ma=Rd5tGo5LG?YjrfVK7@hjcNj}qO)TsTFJJgFJM2WZFMHL;}Xn(X_f z)-N_l&%a=|hdo08Sy!B4dgmXd4?xwK9v{-RA*Ut6+TDKpl}{mv`h9r)D`nGAfdf93 zsJ`aqBer(Q?oS`*HEJDiQMI*_)(fqc=2nzO(W~UPbCSU4uS3UdRXd*&-ssSaGH%SaURyO=N-Vn+>tIrjzEoS>zaEkv?)q@eV*Bb{uuZU4brILV;g$sXJujXao#%)9-YstSC zzmjQO`HrSEA2}E&fzJomuQgv&*5J}(d#y_5DCU_8?JA+2ax=n=wh0}-Ax=9EPU^;G z?}v2=ZvhsQNs)}A7g5OsWMl)!N@Th|p!W#E(&UWiY;iGfslfCN>s#7qiRG712T#=l zLI`2BMU=qY6_EGj5;8jjj8m*+> zU8KzgxR=aRvNvfPJRU(loMY0Vi^N)qXp3E}ff%qxjX=rd=Kvm0y(@)`nKUzPws*0b z5xXxbiNFB+9y7@F9Q)F?m8bxrto-*Qb4P6=%IG?R$UbG`2a#J7>eAmX$9UCQe7_|l zR9tb>jy~$=r?nu}br@swEpL2>f03PFk1fC)ow+>#$vNVU$Eqp9b(rE~b!BmLZmJk0 z@v=S+a6=K2I`hvJe%0@UOv2Xo&LqKawOg=@+y^5V$;V=9w3^Pc8|R%}RRXIl5s|b4 zF}H6$Ph(Kesb9}*(X`~dE(tLsDe0ZcSD(5#r=+kOwO=HD>{FyQiV)?{%ntz@vl3ZQ1NNh3PY>MKAr#~GiwqyF^?=Z z+<*tT_3K?})8-}w|7&=9e%&9MJI^v1DlyOiJ@`|mX_Ibj9~u& z4l5g1@wfJEpPLr51hOI9<;e(6gE+`T&j54z@mYUi($n5!_KfK6u5MQlt&FpI%EeU% z;>a<$;dvcLUr|);mipQ$B})s%Rb9az7x{tj)2F?8oBT=F?>yP0y^dHAk@k5aibPc` z08y3p9WZ?{SFJuHc!>F!y+P)c5+d6~Jit4)7nAC1Ib^hx_?UY}dPbXVbhmR)J*~t$ z&nqlt0_YytSde!+V`qiB`2>l{=Px&7?Nps z^IM`a&az;Z{mUJ|ejL$lr8E}cGdzW`eprq>{&i9x6&uT2b8UNjcLxC$J3JKUjDn!` z9r{yZ*XDrzh8tUjjaWDr4kG6vv&!?&IM4H?{fAHa*!kJ5HMy{jUTb*(BkvKy@G+lG zqw}g-kM^9Fj@o1k1nYykc%Nd7^O9EsjQaGd66<=EQ(LI_IkUEBOdh9rT%O%H!5+1%;r{>&-ovLX_fTIUkmM^{Fm>eh1Yl(J>-06% zCFSgze0H}Jqgo<)X%w)=%eOv-PI(=9JXFc5UZirY7Xf_YJj_KHGUKK|UQgytdXB_u zijl$gdv^1z=8oB&SSq7#EaP6COZ9B=X4lxK)pKG6!A;I`*g74Q}jP-e~vtT7H^H32!x=Xy`-alb%~AC%8Ey zrxcS?Lf4^CuZVm{_INc958c_!l0I%cnKnW@hU0@mbr)HN=Xg znn$ZuWn|I(rLG&@Kna5KT-xyLEfWV`>2t2Tm?kJsn~?5+b8jLBB=p^kgM;Z_pZ%MAX=?$xN8HPe%)586;f_0V+O)={c#!#i zYN~;^3k+Zm1_1efQGhrY993EGXSqZ&o!d_YqJjbL02w^?IHW5aUFVK$>~$G!Ue@X5 zwv%ZnfPg{jIjYh8Q%P>6v!6~kI!v%MZU$CzNaXRxIV0D;dscKlG`R4Wi?#m%A`dk$ zrr9uA3O2yUAy{&!2ZjeAfmr?<@l2i;)-JUTHXD|>X4?muaBzUPCBOhk*x+PiIXFBD zZ6~;MHL*FHz-5URdcx_cBpxs=(<;2mmS&uA<0py%W0o+*R;2&J}!%a`&?zuFVFX79GWQEo;k#39;@{S73 z02x-u1Dxj|(M2z_a5Uu8yc477R{G*-_fbc02scp2GdOpYDh<1zpeHAh_|>}~8u(LE zvLbCV`Zxh&6cGRrs*(!0^9W#2sM>Ne4HQ!8arGZ>W8pkHTj^57U76Poz$hSb!}4?L zIrQyQYSx-Rhdf26-Y~mOIU|*Bt?i_6(l~4(8IuPD9=$>7MHMmJu7=i`aisWy%(7a{ zs$*s)oU0I{)HkRjj>fQNw9xGCEuP{ze9Ku~r&w*G25hh_-f8{fwm1Y3PjktliqR0v z?JHgI9lr9pGUFm#lh04P`0`jhPvFU*SeHt^nh61u5(1kyAK_J( z3PP)LJDm44QBgN-0MF6&Zwc6FQQKYVQ{54C(=^h>9E1(S5n+x>>>u9i*!8SSKN$FS zcD1q8v^0sVt{mJojk3k&z^S!)3<+$Ek&r#;qO*pnf!S!y;LSoiNq@2$d#|5&n{GUo zO|6gJys}}jjGU9lUQKOjx~7S#+xdD0z0Is};a(|GLYE-6Kn!p={LK_rt4jf}x`vnz z_qKEkfEFd&p1Zm*$2s-m1ByqJPoFY{k&|FpjFIOJo=H&Suh;ORil#JSc#r-OXfGD~ z`#$Zi%xxmc=CInzn8*RZ=j0yXAIFx{?z|1+?Qci1y3y}m`Li5`M`eUdki>-&atK!K zlabJ41r=Mwo~K;}hllKLrO|YYIjyFQ3523Y#!9YwyATM#$35!x&-NnPvqc2vQ#gef zf-uai%lu>jFuyhqanqV8ta_RiWV_HrQ6<%biDQiw{E$F=V<$Vt4_?PU)sv`0q21}X zme+QY{jOKtXi$?JXmD`AvB~Sy9=}W!R-z}j{{Vz08}*&MG?9FmFKn9_I0^v+egNUJ zMh`veXT0$7yMjwg8>rxpA}2#3++^bgPVPDH$I^-@5R%{cepn@2D?5acMoLK80ZGOV z42|o_=lWG0Tf{yS(_`|5jrZCXJ+8$|sd4wPJk=l`$DDdmMF3aRweJZ{sLHEhc+Apn zKoO7xz+eyW+mNRO9ntR${UYmD~Y8GT`+X zKGacH&=}jjAHdUJK{T2?vB7kvSB~5?dr-840}|kJ7k~g5Je=aTbUiyu(e&t|`!dLg z<&=auMJG4~n4ExHoQ$5B>`_n!^Qh=hM;W}gyOKi3bH$YfdtpnQerCDdMh^^X*U(9+ zS>4M#aeu2aHj);0QyVdpo;n@} zUNOxSRI!-SM{aK=`#d5fR=@xcL7YjG#c7=ezSzVuN@q*iH7yuhP6mf)2*{#BK# z==K+1HQZuN%o)Bx&u+a>Us@=pghc)x(&f`;f(RBM%2#&Gl|G}NY}Y2*Yw7p?L(RNz zD6FFy8*|9~XriV|K^?A*Dz2E3G*GgpS1$^&IppM@t!u+_%M%zI$Xt@^67Aj4XM#DR ziX-rhf_+MOEo7cqB$fa$(Fq93p2IoE*PMIPE#yhN+_q)1{;RPNXZ_jH10%b&CWq!GJ12zwG>kj_-)M0n|6Zj zwMRjm_w*lyd3LYjtzzF&zA;bbn|YZPRnEWz^v8d%=|vSEX?la$>pTmhT6r^T*O4n; zt-~rLd?I9Xf=2G`)SfZln(A&YT5F_v4$w#dC)9DzYAB)nMyp6&6T}cOE4u)WKQWKc z)A7ks>DG!XLlGMa*vCC;CMS2z&*8-sQUV#38ZwU>zTSw#E1&69?Js7QY3=US8_F1G zQ}@1Xbm{*9>i43GU|Nn8o62KMnY& zUi)U6*Y7mL$dk=gXdOwzjmp50oQ#4p0ml`U;a?S7=vuYq&ZTE@saoBS-rF_60#mzi sE=m$eJcb)cJm!ijjLa+hp?j%Z-7I1uJkKDE9PHdl$KjeNqJf|P*;W~Fga7~l literal 0 HcmV?d00001 diff --git a/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.html b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.html new file mode 100644 index 00000000000..df403ed08f7 --- /dev/null +++ b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.html @@ -0,0 +1,77 @@ + + + + + + + + + Cesium Demo + + + + + +

+

Loading...

+
+ + + diff --git a/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.jpg b/Apps/Sandcastle/gallery/Google Photorealistic 3D Tiles.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f6887c2cc98eaf23310db767f8ffef051ae02304 GIT binary patch literal 76182 zcmbTdWl&r}*DgA^yE_3AG&qF8A;E*Y6C}91ThQPWAOSK!@Zb<&AVBcJ2X}%DFhK@) zJ-qLC>)fjQ>z=cxx@uSL-o5&HmhA4edY%@Z)&az-iYkf#6ciM|@$(Pxv;p8z2ypxe z0H~`2xBvhE_VY6V0P6D{?sKDkZU7}OJ3BXT2X`O9(=y;K01E>H69XL!69W?)3kw^U z1P>Pn2bY3~7@vfif|iDwf|`nsk^Kc7!%GG#Y8GCWmmHkjJlwR*d_sI&g6v$}T>lva z1q&M+7YCOd509LSo|>NP|M+_90+3*%_@N4;p|Ai@Nl?&8P@eh#OaK51#xu76!25qL z6jU^H3`{I+99+ET4o$=WR1`EcRCF{940QD8-l5OW0q7(cq%Q>IFv+w(V6k|T3r40F zVzbKEcT?z09+fF% zlRdG*&)VN~gvt1E3q%2E5f~p*U~g^$^E+%mz2stI3LMC9CLfnmr*@<%A50X zA*5OU3r{dMOcjOh(OPy~u9USzhWOrzKYT-I9`?}x>Itw}@#na{-HkjNP7n^Ei-pFTUf46W_ZaVM!P3;;Vhr zao~8_nn8xDct6Asb2^{;I(q-1LWb%2h2lUr!`NH;MD^l2njt7T$`n!jU(pqr&H58eiF_pR&-G9D zd!BH*%V(T2$Br`pq2o~6vg1gWF2M5~>IC@r1lX{-ULKJ-F}jYRKY0R>{g;a8m)z-| z02AArMEA7+F&9JWKnoeNg=r#sEi9!c03Or86X0CzI{FEK`Cnx{EBW4ic|iP8=796R zQWj{$N-U(E0J~VvDA!Y;QN9JQoe1SVb5NQZ|M+GVniL}U1c?5xxE&Y+CkI;Tv+6u> zU`f9BPk;rT@JFub6S{$Wn`c!%0lJHy0QdUdz%fqh0>bP^O1|W7#6TGH?h`=nzaz+O z*aWQP-_VE1${haB1g1b^5;Oy1R|SOWVXOhmGH;UFH28rZw3CV<`4XX-GX0O>GGSjhkQM0gMM zWB~9yb*KgW&t=}TNqE}@(nx8_&E>O&=|OaVmug5n&uWsd&yt>(`nuQh1>^~kR=g4p zpLOD+3)l;|?>{MROVr@MEnY_?JprgXy!dDobo??F*Xh$Q&TH~}XocGzkl=6RLwM@k zhZ*lTC=9*n{kyPI&QY8n$(R^Gu;hzc7pKN2Kr;LND`|;mq-&Zy7r(KO>;s;xC; z4*o7@Q_VE~zFV}+!G#>PTNi&+yO+|;)n-18i|^W?^Q8gyWgSm6qtC}Zsk!yo7sWI; zdY^1SyRtNDa6Sg)O}lF~qs%{U&qv{+0cr8>XAaj)x|z<&^MUvKMKU;&@2r|dNARbI z+6O;#xg^WVf08~BJ>vJ-O-xzd_}IDsqD^^|(`_mqo^G2alVwiwMO3eON-#(ZOH$GX z-T{B)4s~}Azs`Z>Bi;t|Laj17-^|r7i~kn@=$`jPp}m&=a_;0y{OER#79i1MEbm-* zewuZzK18Olv`K0M(k7afC0gz4DcHXwIw9Lrqo~4z#YPkaaDV1QQszuz-{N}qS-G@W zNg)9O&konw5E{Pe?D_0O29LSN_s)JM{g(+9xg)07Z@ZoVcDBxO3+6>!n!{b3hrMFm zz#85N5zV9!AJgrV&X$(Pp8rsdHeex1@C0D3X;3Phb(0xrND-P!1k6YaoFE>8L{liy`|Nj}5L5l>sTCq-30Dl$8C%)Q*ww{QX<4!E~dV`To_Uh}ILod(W(%=;J@~T*siRzc|T) z3>UGxRm-5w9~n+Dk{+{1`lyqNHHEVpbf#w*m*rsE;TIE^;~uwLJplsjCFzNXuhUE9 zimpM1iNnE;uEm1t#4U91R2N_1uDh~|K}$L6zSMYUbqb$cEK$Y{&|XeroE3TK{%T-9z?tTul%QE%!%4$tp2Bq?6{H&ZWRfYv!j3m1~ zt{&Yd3z3-T zc@%GuE}Rk2Yr$2vgZC4b{sc%hoDbtUp={lFFx7N+IA1*AJ+y8%{m6G&@hyeAR9gF& z_jthh(e~Oe|4%Me=Y#huHrTOhv7%RUR4B`iTu%TqPOSMv9@X^Wdy$j4gxdBuo-eQB zo1DK1|sy)G3mWD<2h{^TJ{K;s0?lbub=uZPK0+XJg#VT>J)WTPJggL6?j zpu#mcF0KonT^H3h%OQNlMuE!#;G(zd#4@no6~CJQ1%ApiUw zrq*A{xk0|&Fq4>kpWLWCdp623m#?lC3~C6W(oco< zVH7r+6KpfQ>g_tBb3;Q~mJ!NOX1_zFQ}Wgf#vN=wTx?+XeTDqC+@1>b{h4`A0Gbak zonC?pGmd1QqLko4?~OlWYY7ukbD>pVRnbOS`gWo_V(J32XxM-6@9PwQmSPy(a)9Zh*HF(NynB@W+ugI z4$GANI57F?MXa(*L?~yKxZD03Yl-7`+_Mo!VkKq^<+m`+vJOFYR_z4ICqRR;^**TU zHt#HDaaVQSzD-aGHvHDAqCB20I!&dTeX4kwb%aH}@+zcjG3^!~Efq>ZJuR5~sW);Q zAl3QH%usteRwUm0^f6(+n{QbGf%OY@x| zKD*J$W7O;uQ^`^(?^1t7PH@8DdD=cy3S2nswN4Z20&E1$@XQ0%@AEf=F_He!x zrCFtUNH7vj%(-8RT(e&>yY8RWUQf@xR-C1dt$&{pFsQ+cdqj0 zdt{W9^r|&_LuW`m^81;HEu3`J?S%dO`naGDuAAw^ zfao@>{MCwo0^|H*<+Wk20-}6lTxuwXY?@POBq27doJPY`uUjOeJS6NB&o(N|Vt}C6 z3$B*OrO7(``G3)NPx-F3u!5gg*>wGwjxX;*?Aa6C zU42D6rZ;~z__t6_DNr;}7poUA40cu8(*PL)YmA)U1km{Ig7w3D()OtAgm!G04)|nB z0Dj5vBQoLU2HsMeJJzEZmRPY#!ifS`eOyIyf?}KH9K`p}zkz5xULFNRgC5)>zI0K7 zXEtC@+9yEFiMReQQ_>0GLN4m364 z%KO$b4qnIZEu3W{c|NnGCsZ{tF?r2WZn-mU_>4}|j(@SH=0?YVeofi;De=)GU z%v@>_M0)}NERPF)xjR-yBGp{yz~&t65t0sTCzJWwVE!cia)m?9=-esBPcZ*VUmllaCZU;xYT}9}Y#i z8I8)tX!etIAvvx4YZM3fz?Xd{Pk>kvwr{>Mfjf}$^JR| zhEPUT#TTyvE}$Y&=U#vwJn8w;rs3NE=kl)G+7ijHX75HN!6-Q>I-?Xe)^V*FtwCye z^=uz);oZxF^x;ziRbi66?btc<-h3NN(dAVbfCa}`Xa-G}w<0+DG5wXmzQVxd?ixu` zE?%WXuGH%s1)ga$Ra+jKF0KNyMMKGTd+FKmb@r6k?Q~(2dr7*QGgKp4T0+}`^;~^H zA$?5M0S8OTqmy5^GFLUtz`x{zrD};)wM{b$JUAexYD~eBekQR^A2zWMeQpk_UAL7H zyef*J?M0YNC}>!$Qovfg>zflajgyxd4sGHGgVP3nGH)u%GM`9?eivdf;3T@0{%!6oaZII z^bo$H%1Q1V&?^tghtggQ41P#xl89gjd0-^f$Zy%RMLq%cssck^wkRe#>Wseg{>JKM z-U?$2sk})I3#d8kdqd>8x$2o?MlFJKso?2fFJIZLO1gr{iV-lx8i6HQO#3aCCg*et zXFWQ6h%HHQ)Kr2hTz%D}8hkzOOcZv>#G?^5ub5CX#Z5w!-a>Also{4)!(Q7`IL>u; zZKdSP(6N*E?@TeIfNFJ(n;~c|E*ICY1{V%dgrU(Ru>Nvw2co{bJ@h|KEnHp=D-)W zj@I3SBNTY)8DSPU43KK!IYyX)B~mX-Y%4iS47u5@k0lX%)h$V}J4EoXLIe8Q^ja}r z7ySHjraZhvRsSs~*gSx82KLYZ4qyWj(z8YZCP$hOMjtQbk*^a-`<1W{jhXam)lm5| zDFPpR{YJ9Pj9F?`?x#;b(6-2hu%->$h%hN!Ykf{h8zhLCWx!C#7mLLXr|MrS${TcOl z$OxaChD^0jPS_uYT;twqlcB)!nDEAt9S%L+6b-|QZkqMZTU&g1`6*Nu_dvN))g!ns4oENZQUgPEM6kbnc|uxFk3o7eQl!y zVu@8a6tzcmv22m2Nwz50XAwfC6LK5NzjHsSt7)8OE@n9AODcESI4)>Y)7zJ>69IBm z$v!tlmX8>~Bq&vB)S(%cFL7tBK{?8n~&O0*rzawy2^9J-ZPAA(rkqkM5b;D3N86G@|(zH@{j>#m|wHg z-116X-OlSIm+bR5%|0&F5Gxap2o4l;E){>;3d5W6AK>D)BsLjkX=$d?8I*o!8bA}N z)yh5M=0bR_6N(`*6N)v$h@i9ri$!zGleZY5!2Znds<;=Kt;pLa>Oeo(>RXvcW-*iH z?*$A5Lc^si2=cgjN*~FsZ20*X4B7JAs?%0b=I6z_e)@x%jcR$b#8@);1Z)zOw-=@u ziX67+^S@rvGg-@DW=aq(LR*KI9juM+n;XE6qTi=570i4O%j)Uv(}MJ5juV9j7JjAu zvPU?4r*lWcYpexg&DckHCnA%#vaYPDk;S6hC;9x1MD3=Y!>QR0JSr$}F{RH$`gEQ6 zaP-nyNkxxO>TDJ4ZCdTb)=AN<@`!=uh>Fm-Av~vXMt5xUtaqjk$ii_v6=v5WDGl-U zV85T$8==Ph?*;0X)0-kM9>T>h(8?Cni}9{6%wMwFDlaN@e>9f1*832F9@Xxh+z~it zhqufy(JdgFp%Jg_HCj)}7WZPRs`R`*n+yAb(x zuC$l`ntvBnzzCVaNV+%|(;ePX@aO-IUnbd@IL7(}TsXBnQ-|hH=E;ktuOfL=MlAyJ^eb z(CJ+Z&?SLFlVX#p-JPUB)k#H$;4q=wXb9C!HUOXhlI>%2S*hkuPuqA5!DkhgY_K)v ztj#Yhb>eF}N}6QG#fAh~+s)kD=! zh?X7#JSz3GHT#2CAXu08E75Ze#6C@tUn*$!PRzQg!B&0zG!zL1z{SwXlUR)b^mGM;Do=9#Ky}K@n8BqR4dm#&oD#iD_~+P zLNhu$f8@NDD~5!FLGIba4A^?~T6Kb=+sexff@QZP=E5c#c|WWD$w$ymYuHwQ*>1rB zb;IdtM8NY(!GGdTrYa)2W-wHRottzfAqV&o?@H7gKJ>(IqPV&C>?~wpa+^HFy~7Z0 z?RL_+m3QjMY0bcq#`Npb)|TcOO3Z}j<}i1DVj?tPm}w{0u;-D9E2|1AGST@8^d=TdA7HM~cH7&LMhfT|<;^{-_6CvbFHR|*OG3w0fzBpqUpo(ImP3-J3p`JL~O+lyk^>T-58nv$8yF187jyJ4nM~WhR8Cj*|Sd zWhCjCS<*ZhQT%lxYkE>DvK@_kq!>X;tuGME)NR{9*cFsY5V8b~-aV6pW9Z)x}BCTv-B z-SHh-Z(hBmhqM0R2eL~A+$c%TtXWOu>>qI3`|tezK=%7+=)w%RNtG!H-pM~c>k~8;Zg9{xVNT9#T#@HT z83e?!`-#!jNn0ov$90*sH-4@1fqOEmgT&fDBXk71*SctsF!H>$4~zLS1b8|!r$?DX z)P_3YJTsi7Yeyd#iebOfR0otFxc||uVejQAEiOII&8_A&|J#{)UARC_2n5m9y`{H5 z;(MPn*xC52`A=KJ@8$?|#lBR@7e36*hFM#vW$bCdE!~~aC}`|gJ5m=PUtcWd==79d z5hT%3iUCr8U?K;Xm$cGl;->F(;BIp~@hStGG<8_Rtrx82V{g4Tmg%as7UW@<{UGaj zfb9y_@xd08c3z6u0Jf8Cz~QE8`i&00_xv)${?y0gxzCj6{9WS(hkeOks0Z)LXv8Gx zFRQs_;%FU~rcDwUzL2*#4gqBj(=ONFt*AR>|b+8e7 zxq+){lMeR7P+i=1+kVLxZ`T{UD(&W(jDsgZ89Dj|bczDimL1)P%4-{&^~FU`4J z#&53l4NC)~qRG{qbYCL+Q0c&8`_t)Ty!HzslDj_6@S(Wl6~Wc(^0Al^)gCdrZ87E~ z!+M1xccoO#g?Z7tNaD1yR;5*LaKWW?eqJtLscnk!mXId7Gnv8}J*n#bSGq>fG;_+g ze)^+2qZ54MK9a%xe%>i6KaZew!}^la?>r|xQ$y5#s0xCSX#7$}napU=@-BE2Wt(U& zxxMG2KV8INDUFt`ogP0-Y-sS-mmb%D0XH9aP@1w8djHt+81cnWtM-I*u%gvkWJ{WdQ_S~=YKs7=cTe^O`;MC8KjFmNKzRhf+-e%;GKwc; zP&*F`4mRJ|$EEXudT#vt7((T};tYY`kfCz-j5i-zzq$Whb@U$LeFCry8{>~lA~3G- z?YA#(yweZ4R;%aAivB(U`t~H6Q#MzI-%qPyC!`KCw4o|a@CQg_PgMzr(a+fO<6ULQ z?xj^#^&95hS78z!Mr1cb3*`=3Aq-(~Hfv?pK2%*FZU6XMQXD z@j2gqnw!FQM~$fG$eQ@xRlkJrYGI?qm33La&2UE32OA+b&Xk=aKEJ?A{o?oDZ~aud zvx%{26L{fRD4uzr?Npe}g^GPPE}!J38UA6{=nd7BCDJgYty%57T8}O$p<(uKk?>^^ zJF4i7tc9V>L(oJ6MBT|AGUJQ00ZBG|y?x{;09Inoz!?&OslUKpwoIR)+?si0{L|1h zS4i94ddIkFCpyTe#UFsHOn(A%gGg~JX-rP!ez*Hn@90lOC2n@w%hI#Q&T6lFrMgvv zGC+5#4b&~;bF!;wZZbz;s1r43m@yX!TTJQ& zs`o|7QjhbiJMX?}d8?PJI92Uh(+kX5;zVwQjJ08|&RF`3v~#q{pfsSj%NCRL+2aq3 zJE>Kf@JTjs)i0VAHs|6F&CS?BD5~^`Nl{pHD0Wp|C*5V7s*dCIRM zCf8V5T+#Orzh;XAw)9Z78d9ijt@zn&nw79bOR`^gXAGygu!G-bFHtnmrOaN zXSs$vMvYuqOEtv(k)|dF+3+uu>uTmNOPX^8-~E_F-Fc%!$kuI>=_Qo64qvKx1rJW# z%F&D|m{TabR4k+DKd-;3a2Jn}tfWfz0(`W>S)7agX9 zSKnc|O=;|0><pf=HA@#Lq89A)*?GwJ3f1=0IHgD) zK}jP>T+U`v0cX)w^8|KcC%GU- z!yyA$?306Szv@QV`z5(KMXzog6N^0p!sc2UVA|iZ`~+}}rHixt#rA%(-tt?3 z-L?ipU6B8PYl|^4ez`Qc6RA@-AQ8kA3^|J5j>a%l4CiQRZU(LWI%DRU}XhtFG#E?yI`l z52nr^xRh{d;>TzFu)v`~Cs2x#aspWk(>2E{I!4anc8@xI!j-gMnKxrI-V?X93FgQ; z{MkN`W0V>s=dZ)o!=~a5irjAc0vvd&zp7_q;&@d-nJ=_Q(p8_ZKoHH;CwfXqR^+zD zC$?_qYT;;j>yrC%w8*M^p$k9nYz8gW)m5qIb}qNH zQc_n@>&HB+R{ii-$7P8oLhI0KC&lnc7$s(K;{3X{8Qt$p%{K|h7wyE zmR0~ztQ9l+($ukY@N}g=_0>z?8`H+ESac4%b+{**m|0@h=D%E{QZUd4f-YYHDYt`v z|J!;YJxfr%`&rePZRLn8Uy#`!6$Q(m6|Ed;+*7>bN5-{xb>!$PZmf9Od=!(RT&TZ} zw10ueP+TWG`}2LLg(Zy;$zXC{_JX zU+&2`|C^Se+Kp5)VeJ(zV>9y@R-d{)SOhuPZ!6^*o@a3EW@4(Vq?ySnYTbPdzE{;- zU0OCBgACR;4mCBeGZYgnu5@js5HajsT*W;XqzoizM2LXL=C;AaPk>jrH@3pRm5;8x zVP>A@Ue}dsr|y4MRBQ6N6g=cbDRLB(gCg_45xt*NN~qavg*1R?s_Ms_8j8?*xk=^j z>y5cG`6?z4cF%#8;RKGL`v#|K$7aPexCXV$rJ2mod;v8;7b_0^5@{D+rS1zjll&vt zZB*{MLbh`jb*L!E+-O5@EhW@PX{ZI2Y;9?}lZ`UAWp;gDyQW|PB?*Phd5bEql{A%$ z)e61w2mRC-*5nC^xT=b6nYK+iMu+a$U^3yTtHno`!R2;w)Oaj6F897-tI^=#%W49d zo`#!kH`~~87B36xB|j_&Cf~%A0`O{B=Cs15Chp)0UaU;-V;Z7U;;n`yd4SoQ`{2Q@ zs0At=pC`Z{sXC`tCs2?QrQ}OLyz2fwuOdqBs9wi)%z^1V?*XN`+V4!-Mi%6)1bC)5 zPE`dFkC4S-cyjC2&|T9E-{*TePW?Lp8ZrENud^Ek`Rn;^)!)f^3UUKyp#n7btng|= z3dT!{-N3I)ywRnLOFzvOS<{pma>Uds3Bz>Cw&6f}U)b}}5Y11oARuJDrl7$1L`{T; zcOFw%mvvz_RGQ!npvFOmwZmDi8lI!K4`;%nL}+Sts5rOQ@6L~0m5pfmm+ZVA0Igru zL1GtQMefkOFZt+)m%exZT+(N$F>&l<5=~oXv3QHi`U_*M_Z5PMukIegUe088W(>N9 zb%*JtKV+<$=E1cyRUaKqmiRvVbm$&rwfPYDVq=Qvw+TMXuCg``uzk}#z zR4Kb;C?qCT&8X~^alY+q>xppHtY#tQM22^`$2u#Zd7|kO>nSg z^q}a-6#*OsB3QxBv>7?G=s(hR28NeTteWS}?>>JH4q(e#dLQ>EPgLw~MdmcjdhBMajCshWOk-Hn`Wr z6m^7re%bR9Y38trPxNwH)1U*ANr8-}?q+%U&um)}Gw|_8{BTHKH+KKX|2bM-@%6 zq}+EhfNkb~q`jo}ae>OD>gD%N_2xUV-Ep(&WvvO&k@Fnq2Cl|o){pJ8b)c|+g)U-Ca z6CEx|DwPT`Mwsyi!RO~9151a^6n-uMb-Rqa?;kkNW|p&0s9wwLNRIFK6wN>JHgNsLX+^(fIWu^v%a5odnqCPY^z3G;QQ!y1kJkVMfq~ilFm{* zAA4JJTAgx#feS(Z7yLosZa2dTEd0ao2orIYGpB4txJWr@*(AMVI#c zCME;hohmGEs{!3$9d2Pk;)G&|CeFlU2G1Q#z~Qx&(!f`?^8G zW74&}NoU-vv>!a1Tx?q6(=6V;SgIU)nLzDgn^(UHmSlfjlx>teg<+35z9ylE_Q{Q3 zFGCD556)cMGcd?soK`%6!wAXhhq_l1zt*RT|`2xw0~PtA}p? zJjJa)^pH505{HXqge-$>sNI|GahGkvzh(ZmrN5A5#H!nD5++dX0V*V4en!u@>Di;? z=~4d5m0S`lhysAqlLnrH59j{6V(v&Rhja9U$YTZhvDeerFyayAs0A5ntOy42(PC$2 zD@J)$4*)Z0zGA=wNAjw;V;M9&W-eqEs~;;suEvQ&dM+0Utu+IOI+QuqoEr0FD6;qg z?FfEjm09*A{)=|wtj}&&J9gHcl{Bw%!U@yiuDn4gw>NPWZrMCMw%_8Kdv}|F6E=+8 z-D_A|Q`MSCWU^h*1W{$JQCK5-*%_$VE<~oCpO5ZhX2TPZuay5Z{%FnMY<}T5uoBhf zHh>1NXJgE?>tqe^*OGH#$vMS?#4lOvWK^tI;0MCXSxR-i4eGpV5U@8b#LIzIDQt!t z$B?B@_kZ3PY&{AH8ad;%rtu$<9>0FHXMz-W&@I-3-y7{s{Ip` z+)8;20^P(S z{cR=?XM^QU)IK{g@YvOmn{M14fiG-UjD5b9x**4x6vcr7?lDiFn;Lk+`=nSOOJQ4k zj377k)VU5a<>P^5dxvFhcRPZ7aicHIn*e51F@|IBqxc(f-Y+RW2{Ec@6vy_ZcG-yRu^j9jcR6`hO?~6K$Ha z_s*Rud3(xS>Ls6+eQCvLzF3mL_fGQNA2VxgYMdx;2;j2|zQcLHx%Z0WG;h5SCaZ^J z_JvAkPAMIGzimp>boca?tjMUh_~J0Gmqbj=cms3s`6&*IxOmf;`9gVhiM0L!tX{>2 z%vhicl)ezmaAjLCnru5sM$Ue1r}F22p|g-^pydg5`%-qm8f9EG?v%-3#qTGcOO=_S# z-cJLy$pCg;?5A*=6dA@ls8s~WXf!k>BM%S1-W0Z1cxKY)*`gq!9X=k{KP?FtmlPaX zM%)Tn4S4*9B9lD$aiG)3Rd`4pIh;GaNp)_f%n{U1%NChn=0|YmXa7&x(8D`S#w8o zdS&(t=r6a$+D+o?Arb*EJoxukn5Orhvmd-W>_zPOqUiF^&HKOc8sj22tjwF)LC0iqv*D7;11Cot1ak0XsKTjD>?hVd>H0~X(hFbLX22r+#JlP zm>zj2Ne|*z!mq9aD_|j~BjM=fc!Aa`-x9{fTngc-2oo+{XFcvBP;;7e+4f>H^32T- zID&!fKIaKwZ1Ot%;9QmPm-A(;da0s=1`Gs<=(9S+4Gr=}&V=_sey3a-SM%|FSR>^C zh83U;;y~XcWX7AIy$@2q^qV@{18YLsdFpG2AkpnX4C>$+V$rCK={<=m1wuxDh0C!a4gwcFnv`$(4J3jMj!op~abI9twRfP-La+=V2 zp>~E@ZP{0E-ZY3lRIn?mXFZ_>`(r$_cb7>V_xhfsQq4|KP9#yC&6Saz==%cw{m+0QnXG_yz3CDi$_ba<^Xt)kJOhqQ zxkW+6pOAltGDFY#s6S{zuF?C>jhZwo#k)Q5(})3g&Qo*_Hy#VOJk6BINgXMNeK$U}y-^ zpGx|&IytGMwpg29^r~#*?zg#}J!nKNIKHUkBSzN;kKsIi?$LK z<)q^z_BUBTsi`9XAdWJDV$NIU?)b8LyJ;uiPwVTFK@^#I=b|7sfS--&Ymx_HuqX67 zac3+^rA&MX*I14=QwxGp+{Fx_YN4h+r}zRo6N#zu>}2{qjXY#gD>rw6hfdQZ)*;x% zfELjZXtiG$-{iRpm8QD*(j;=!W!NTWQO|8pGC$2rQ}yftO=oJF6yuvK>l4774GP3C zBNSA!K|)2=0zgW~v&Yk~8r5Vte^^PzpXLX%ey#hi=0mZP0;EoJn8U6KDaYQr&v!QS zzF;!>>eyyQ7iCm4W4GLhCcSzGvbDEOM61JyW7!Gg}g?#h{>EHN@?oBL~Xly79p?nEcU$x z5fEiX;j&p-CcebbhU&r}sa8BK21_{=xl_}tqRCEUiJXpdy9POuCuy(Qa-%_>lnfcCrYBSi z(f5{#{s^(nLbgb3#83CoKjI~-l-5K{=j$IAdr4d4-ygjuXbw6{&ApjRN$@XIm+F{H zMNjW{dX;&$^|1c=0jA}dUv2d>;KheCiwip%=7bMlNCO5pl#dL3mXU;uwyx}`>@BSc zMfPcjUWp4g5mMwt6^z&44xBYTT|~_JN6J1md6kO}F#2z&tT0C01_x_zq*CnWP!x!- zh|Z%F+gkpr@IZ}WM{|V!tvERP5o!So%XY-i_<#%tvp*n|l7Ea}@}tdOvldphyx6h2 zot$^z=~h1&S;S=|a3crRvj~mx%y7DDZgFO-S8yAG6nio&4=6vPoWi#mT90zhUk7b+ z-t#%WZZ9<|_Tf12GIC|l4}zx@TvA=RVzlH-^+%h&`|(Z|ubB|pXXk;<>*~jF57qYdd2nX?@c?+10j*@kXpAfA6aa`g-*)K2OMP5WN6Vr1Ydm zGx1-QEbAURu@#E(%{6f!c(r13r@o!{1ZduC>o38v`HDwq%H|YmFRsnqTcHr>lzh{> z06Yz~(8{V6>?=Y;^>1y6yEQ~&i|Z2r+odIaz+{t?1dsju>tbr^*Z+uAAz;i25og&p zi4o87ojb`9W;4P!6q!n4m|lTh>+A2xU*9toFO8>!==;(Y;sY8PbB4;d>c@QXFJd-=mp|+4ucX?0 z(`LDKo$`yH!Q6=KKcc7YQdQD((k(h^(%gK^H*jPN$veC23_2gPAKHKslS!Bb1Z#fH z|6TtDk$;&A*If;8H=(L(@o$?QE?=4qJZ+E}mPt^?stJ$^r>$iAv_4%`2AOr?%b{ro zT`rdBr=p+I7zJIu`eHMRyan0Xb+6}>)Z{dmF4_8~=Z&&7d5^CdUOqTC{+cRnG15`z z^3M>_vORTubRle4LF(Vrg#K_gF`wQud6mOv8s7y8HtGQ^thCoq(VracX9VljA0K#B zzO|?4oDs$Wv83;{vUy*WaX|j{%u6mCHq7z1tGItaeOC!wbjRom7{ElZ9kNo>3_eHh z6=~||UZ=K_{!z~{YTtCLcYQy%JR#{3M6BtioLI3(?Pm2oOF8DoiyhD-{3zycxEgE- z8UB9)CfQ(;`k61WfBwk!dYN>9`9HW15j}*N7+~drvlj%;(=EZm-cvWO_+2#S!wo5& z@WsgzC5t|-_z=UZ+y&f!r1&g+)gr#42=gHBTh26fqp54py90j@>=OAm_Xm4t@{le4 z==^3gU9woMAxulz+KcMQ7M~<3)Uh#uqWWXTB3}p}IjPd!V2Lj&#yHyHVrwq@kpNKo ze$FWuu~RR(L{EX7$aVW3$aAMLL}^E-i0KiO_gs?d5T9Pv&T^AoQ>*ovsHTGIl?yTR~Ti*u?02kO~Or@^k0$|Ah5(4GME*OTujKN=T6xTFuZRbc2bX7Gvd+q+3q z=!UGEwoHYa-Cl5#w%wRbp(89}RW0k`6r-f#(#{2h;CX{#ni9%;cF=eR#uA z!m^s`i-<-VVwQX^4-Xlil-~B&*AKB_uWk13w<#$t$d>=RgqgDW@y4cW5dD{ z#5}VmwU|yqv-#$=&^uDumy*NeZg39-5T4RBrrkpXnH_iAdvtH=^_iEWiC__w9YjwN zyOc3mf&6*FVDxh^9>;Krq3vX@injK$ zgn`tGH1M^gS(WZeX2bWlMEz$=4kmhS?fn^Iup@m#iL)-~opIMWBG2$U^n`NR@J}L4 zb-H8$O5p9uk)$Y*1^`M&OF5^^G&!G@LCda#ramTG)qQ$1-B7?zy)bU*&KBO4s-bST zT-@xTQ5Qewv7@lcLhyNwE`CJ`fHHLdlitL@GD!>mu4v(^ zMQko)GJQU8v+cfkV{WX$NeqA4;~nb)Z7Jcm0i=c0rs$+(ZP7m`9dUwl*F8x9S5jGC z(7YE`(_Ey5u+qmYc{%77MQn47o_XoiQ52T3+OdZ2-Q+U-k$s_eVD;PO08|XORyf8v z$gY}nCbtWt&a}AZy1Piy-r{o{f>u~myLIP|**N_=*GrKG?$Q^u zAY?Nk1=+rf)OF8I2%`HMhhWV!0(|R~5=w+|_n$1hcg3f#*P+!Qt;jdqTp50|FkJM+yR z)?LNP6FXb8p5oTm$-c6Nf0<^tH^|J&a6#OM&~)#b>-;5S_L$^(E}&*xW{KpqkUK== z<0Ek3ovqG2xvo=G(@dI_P{n6$8cWvm$$1x!0_;KxoRRZ01;9UtOQdRcI$wkD^r$6U z%b{;8%Pev!+~p232MgF>^v5|lH43jmxS75k)TGt4({X8d&#<%`)^g=N{;b-&Cx)zf`lo^T<}OBAE+biUUTECg}U(#ys08c4WfL?!H3^|IPdLU>?6(a zS~{JZtZ)g=7x#F{$3K@f&z!|NbZokvcu8q1_AgufNVqG<+LRUl0G5oBl79tUejdHC z&FwehG|71%_Kmof+y>pTTYvjM$B(UWz8cVe%`~sCTuXfmfY#4%cKf3}y%gt;ppG$u z4Rk|Fws|CWxxAH}<~Nm-_hW7X?Fa@vN9B&S+Udt`QMwkEr0SObOxkqPGPY7S zkjAgb9PMs@5m#<5>?|%V&}kAGofNBYU=Bu4@f@6y$LrHPdiZ)KhjL#`(qw#}WC4HL z`M3IK9CO86gG|;Ar3CG%`GPl4C6P>%+ukb0gn2hyd%Er)xW`mcx=O1kp2=u%?Y z+-?KyLBI;DkN?pt}GXzbn};)Xnz&H)F0?l|Z%&pn1Sd|0x@t)oqh z%L1|5Ivzp(S*)04`M}O9;|R5JIW%^b{xH_zC8WDsmBu#93S;Z?fNLjHxqHnb>I=CG zLx#9jRa}Pv?Z+Gr*c@W2$A*j$!#Tz~{c7!ur6!S@1t)p(&g_u6<2++MGen^qG?3Jq zce&-defrvL8gNUbw_seccM1+i&CUnj$Dys=SN;)UV`+5OF{xlgvBfUH4&pf5w0{UZ z0r$SOK9At|yc49|KA>JGhQlQEpnN~yBkV!csB;(k6)2oG0r=GRnl6{6>G7?Mj)NS@=I`@Z;1WULAErM_tu?Io%2qkz8$spRf=)X0 z_O3@YCf`9=<|MbYhs3gop^9DZpQ=>j*LFFO7~EfFSGvgYo%^Smvb)Sp!3La zii+0e&sNu?(yZcSGq|;yXCR zOoccg4a`($0CS$zq&eWOfaUFn+H_lGePZQgxC=M$BzFo3;SOBj1E0^FU{>|MlNI&1 z*zKcxr)dj_m3OyH{GfUcoOG;>PeHhr7%oKU#DWi&%J=~F45We&Vh#^#_1_CzTi^Ig zOP<_`5L%>rg5%~vwYvWRw5F~p*LJwCW66!ywI-=L*lE`jpjCuiFksm4oG%~}d;T=( zpT;-(M0VGDRlF%YF2%`&%A+F$p>#2xoROd9Ue_!FYgsMiE?|`mZh^=Q2*DhEYb^Lv zNqFIjtr)BsG5+=bT=nNQ)f!48buO%Uj9P`}pKS58>Z+TFg5Km|NZ>9>ZUYP+PC)C< zYo^n+{VQLyv$BUulHTN8q<51%hENaxtPGS zaszH+qsx*!2F?Ie(XcyKpM+-A?r$xhTN5nrc#alWyuLm_2mk?&02mnKj+NU@Yv`Zk zbJTW&XzBbxrP^rvEO2Sjc~MJqy_a!sn`s&3`wHSU8_6xN9Tmt|h%2V=mB4I_j{JaY zzwwec+3iU0Ix3A}+mriCl zX@puzMy5>& z9$lFnVDA8)LH7M>88w(ub0XbfZeR7_40;YaaZue~PVXn!A9Pz(#2pce?%;#?gG$!d zHzGo|+&)hhWbvG^Or+~tzz1mB z*9J^{p!$mCrM8yd2?JX;@)?79WC7b8W73n(w`t|wYYQY{*+G%U7!E&*i)aUBYvZf? zds!CO#5b~Jq5l9#g(TaY@sdgHQzyiIYB)^CTaDFoxgH3{dF_S%wZbjsxkn#mAc6oX zHZjI~gWjT@VhDmEA{m0SF_17DiO=x%=|?IHv(hE;_lRe?cwb$$7R=1PLqZDV0&sp$ zYPY9+Lf7o0Wjdada!wgUyVqbO@HXunp4H`mqfYF1swinQvvD~)aohXU7~$Gw-6LVb z;3r@+{qJ!}#aJ%SUw?`|DMVI@w0QeX3a0t;|r1v`12)lfMIC9rphKvqDHYne1ute^WPpL+BDP z%MIcAYP3Tb{p`2SHvUVwt29#dQ-H)rtM)+-~Fe zvFlF)lW;0QB{!uKZD^ z#c?EXO>k5AT3cd-k8lacIq&IQ?ca#}L2GK!O?!42K!7an*#scZ2j3!_f8xv8W4O$A zk05=DWVeX8q$0e)Z&!~8+*)6Ar zIK`Nz7V%VUOl5%#2!Q^0(RTAE9E=IO?wo8vM5?si@u#W{yK@{O+&r!8cQ@@N>FvCSV z+;=(sE5e$LYbDLWk_(+a0Pk-EK4FjMV!~6A<(;G*pfSS?;|8qXXm<*ext~{*4-Rb5VAR5{<+xTQu0CzUJ6FnO4UkAU$?3Zt2%+K)9@5&>U0T@x0HhWX zTq=VjqlL>CO{dEwjsZM^KMsy-c{KezUHyyf=J{SYWV?NVVP!ufAza~ib0CSCxEq&( zVwwXH8hip*3aTw5Xuz7>WO<6qwTO>9@WcgPa6@DnRMM9+W9ehg%lT2Oy_AC)!8XKy z?6nDaS>!)uI4W3?2|vT1PAk>#ZEZ%d(1nvuT{JbdqDK##aFP?j5By4g_6(Wif$d6I z*Hve@)Zsdux_n3i-Z`2VkRPARY_329b0%Ca)1LLeF%~?-5p4iiu_Gh>OMit;7nQsN zW(Xrc>WI%DO7s~t%_1M)PiJR5?-&y;wXAVR6O>}57=;Xae7;!?&JQCjUk>P6WyBAt zX;DiUi_3Wa(IU7wAQnZFa?A)Dl&YW|4tS@`g2$ejAZST@E#EN4=-Z|be0x&vv2QG! zIF;Cpvmea7W`-qP~jiNYXha z4TH2T%k#ios#kBD$5=71slZ^Ah&-CX!)@sI!8U~I;1zr}hraM-~qpxZ-j^fii z6Q^EZThAntZci~}+;(mt3~_)!HP36G5%fJ~)Z4JTvjCDjxPy!y#BUvsT+}x6SJECBIRT*VCXv(am|?m_ za*S15AcjzL`Jc*`4;grpUy|ERiLoOnQw)q)cE=*J5MFAN`F8PbEh~_yzy|1Z&N(sqasK$OCw+;sM^v6C@iy2B=_*5zf8*9uk%QCb^{qQ?f5da7 zgZn?re!EuL$x)8Hn&sf|uBR@W43|<|MIty*qidYw8R5?zv+vItBYRHp?yT~CibxtH zec8K~c$ldm0CuaBjt4?W^ga3H-OEVZ@pRv4xw4#$Z?^}pxvqC{M%~lix?dJst+ZAV zs|WJcmw3-TG1r_|GTrM+e+Zh?+Oe2P7(IU)w&(XRw8_&rjNy(sz~pjzR!)^6+*7Zm zYx1lJs<@6LRPjOAY^^P9gP75!MoDf9ylNFnNJ;szhH;LW&pZmk)Nhpp5a}{16=EEQ zIdvc%-1O&+S6QTZJ4~NMp52y2o#l0sa1o_Z(4bW9AFZ?O5?HV=}wl*NV@V~NHpM)HuYHJiZpIV z-U|PKoVV6$u@GQeC_A7i3!)^!v0IIzYN4-ni z0_h@5fwn6yFhB#+rWBPuP+sSb3$KgTcgV4}nXEvdNg=jHOpNk`FhK@ha}+c z>{X6^u5_$0MoFY*q%HHR6A2YEs#KwjDk& zr7k3q)i-5SlntNZ13deq{oZ)`!p32D#c zBmV$}XXyiWvtkvt7P*Z<&#MaSrGuqHPEbcYDMk+H^p6bPt-}SH18pt|BP;^(7D8t2Uv`yhzGIA>^oF`4xd)LU)|k3@&v$ix(>teCpFM&_F9$AsfjLH zC)(=3-4B-|8OH9THRW|W4IK|bv0Wz8=Tp+O=b52G$}J>?^S2{+&yB#7o(6rZ3s^dR ziMhD3(=DvRLh*))q{!zxzGgh}k4}AXM4Io!t1Ac!L1l4pQ-XIY1CLIoywAiR5GB>@ zZmi?6`!JO4FXwJ$!vcE_y+0b-Dw?||-e$^bGb=^ChV_vP5pgKaaC<+!A8L)11-Fzt zF5LaBzCj@LAo^BDpEUROrK7nr$Rpl2%mF1=807lalyTmpK5aLRz>nMq#sSYk{?Mof zEQ1g!f&eqUoV0N}bt*BG9+cpb{jCz_Oh$}H7E$sMbIAmHcBZZI^E|n&qEZS2n2MYd z49%9O3dMB+8UjfZ^tA4*^(I($tWn4W%ip#K0vW(1B;LVwApK94QEj`KWq^$tL%Zqr|VsRyo5C)M^CHeQ{x|ZneCcEZl;A%{k^U z-13K>D$TO$`i`M*B;!)KMc&wDkb%L$=chQRmi9p;L7=gaG;hb*VqB6j)j&Apik?_4 z+S+CsMUu*>p&d-QIX^f2w8y7G(u)C@wpSKFm4V{h8xmd|g<>(12=}bJo4+<=BCJct zI908CmNxd%Fy+6i&aeFa_y`iknZ!MNwvp~YUpxuq;xedOP1y|YV+ zx!t-5n}4QT0G>Fg4UUsEurzvHmZsl6RM4L-mnS3!M%~t;S8koEW!?NHro+24?mRJ| zJ;v#c%YxOa~u=PWc$^& z-^o#f?MTu(MofesK}CY*5Bwo_aOxLR>Cr(PPOORc#`88QB<E9swa~O;<+d~{DaLWPHEJj!(_>j~?pDbe zhzm8#BC+%tY*Dc8auN7jTl*c1ca{tU7e;BCDHWPA)JUH(+tvP9(0bv!RFh12VY!m; z?E>+c-9jvi#47H{k(9Hu5!FO*lff0yYaTcjVtZXW&S__a0_}4VL{uXsir_Ke_Y3Qs zb-_0p-m^UBONkcV>J^!cNYOyc{m|rYVUnPj#DJ56dQwGdHtnUhhDaoMEM$@>giI0R zki<}pvVoT+Lo02QIl%#rO<0hb{>1{!^WD9-mt&_~M6>2SpERa5B~e@o9*|4*%YnP zE?O2OXLx2-EKYI)9QUo85#Z|uzP+=S3yb?GztYUkeDsPumjMn8XKp~+sy8t8uNt-S z5^6p?I+m!y6_Q4gP@k3@E+b6!!hjTd@k?FTLRnM97dKP*uTZqvc_aCt&f=Qq=a9c zcAwpYgSe57r$3m@ZhUX?MAx1rw9za!l+(z0cjIJ|I))v1I9zr9^HxyvB-CRLz}w8K zToP9-F|!|2`TBLQ9~md2Y#E%=+H00m7q(FuljICIknB>$vz|HY*YOo-N*J}2E+=%z z3QF$za507(LBi)C05UP!opp5tlclQ6vPjS6uGSl!)Tv@ur>9KxJq1_RE^cGDmTP%T z62k)#ESL)*!6(a;2Lyr8_RmhEfqTxvF>md3sI8CKtgT~DDp?CeHvmA|`vE+V2yx$m z^sKwz3f);V&2KbUaVT~SgsU5{@=bk$7G4G1@F!;)tc_{PUb-toAv>6O{ zu)6gJztGoanvsnfNrEaa0br5qt(q&^lKH>#BbMyH7l>n6Re;EpfQ3=WB;bxfz~F<; zI`_qwR#3+^fI7Yi(g`XAJX86}*{bk(ekTD|vbCkV*Wx;}x3% z+zmEUAQuY^#iWKNA>0MwzEjRJ!_%b{@zp0K&9HK$cF(EZYZ?u$-SS5q?C-fFQlJ3L z2LzMQ4)vbE;u%FVTgJ1`hOoo#AXIn)KzOvYH^Qc!Xm2h-P@b>-4s+ssXhyC7VWg<0@H7(ICF zTn`;p`_^CA%%t=ma{@Pnbc+ksk{NBLn6on|+|sh`0FBw?bvWuPE^QXt(q((8RiYbq zl7Q~d9>g9;Y;@#jiC%Koit|Qef)!USA=(+6pvmjV!20^t$gS;XXylc$`@xNPWGpaS z7|H3*exHsK#MZwx!tAG_`4T}S(WGjlD~zh2#P;W};mvD{i!7=cWSv|Ong9xpqXg%U z^vhB%V2D6r^42i9L<*|pgMdAUzkc;r!fBdW*ad@3SKhLHor^nQo(SY{N6qbzT5-kC zR>3nzQq?WSlVQCj*lk;G91<}!p!VyE&s*zT%c$al+TuwVHUM>BPf&d+sT_83!s>1z z`%|PM2c4M^6M=#VCp~#4r@L`%Ch~6bu%F%~#H`AM41B()AQPPPkz2fEd30L-1@mY+ zOL(1CNx|kuUqi`scEEmM@urXXr#AOy;wFI9FE<=9=YQc zX0?L~L{Gb!JD}^IJE>3cPl~>VjCcB1vf`Mh&j^)^m(iH%btAUJUbk7UZ z2BH|ci8mygC9|h_QbjUG<6{y-G3(AMjnXaCz>vs=nnljm?05#VF6Ed*Jhtl0-e&m2 z9J#>TmR$7tamV+0ryGY`N9G9Gmy(A8fx+h=G5S`K#Ywewp!td(BhyyW7PQr8 z`#iCaI@aTR6@``15<;%-kDQL2@JXv0bRetbcgY?b&X~oTrw2S5i`#ea3MhwALHBbov z1Hc^MXV6#D<+qgFpJO@M9M6e2F0#b-i2%=WxBmdIRJ8U3P_-?)3n*i^t_M6-?-gA6 z+QO$FxPmm}>AU{`W~!Pun)-+OIy92U46-6B?krUpfsXw;SEW(fEQ7A_Z-*hC_Tt}6 zxM^VtyB87RlN@IwaK||OtJ356dvPv@c@z@IHRNg;BaMeFK43Q-4oZw3ooj^nbFS)| zM~L3zRMY4C0foHawm~!85O6uqsm2NV*SlEiHad#^r$@Yo;Ksx;jl&e=f*5rif;sg3 zYv!du62?0F|WL z+T6f$5Xy?I%yzG0yl3*y<6Q=sJ^8bHE1NN5%NEG@LQ*l2g;1<=agN+^>()p_aKL9k z(zI}dl3)Rq{_?TsrwTd%MpuRDUR_LeXw+`obpHS{c~Q+BBT=`G;zMkf%M4}8$2$T* zUN-#4>+}cOptZSS6T>{0%#Y>$+ps_bc6cl51$Ii8*9B0laiAMrP=Z+-g&6K~FmaB) z_04L*rJ1Id2qYe6$9<}DK=$X4PI1R-=)z-XT6~j8PCbZi?ZxDR-%gI=;!=#jJP|kX zdXhacTTy5}W!IT-){;UtvZ};VL%<+$?TV+N+1pL3rYs?d!5YdPC6#bN7|$dgbH+Kv zY-l$vsA+*O-DH`SogFf(B9pW~BLt6Oj)SoRG1#h<<;w^DVo0e6!;OC85pic{4EF2{ zXhqP4h~3UoL-PIJhu4gbYK`}T^-VEmlKV-%M2zm1Ws*0IKmY<;0C)ALf5KU+cq_z= zwkOW8nE8eY*<{MO%V3UIka#~{_37GAigX_sT19Vg@kcHLwXCvjJu)!B@%Wy4XPj4~ zN>X&=Chu^u<5TGp2#Z@mc_H%m1db6S5=l54Ny)+ds+3lnu8pMg$85_kH%=T96!jn} z>_1BPomWWJT^jEQm-B4k0w;)6(|*hDF>lbT)X&FL^q9bCY?IY?(Hm=Vrb!s z*uGQ%q^JXE0|%-5pjMp0%6WW{MzO+RxrS*ryxZds&j-{F{C+h(owVxi_Oc{$7)q%Z zF{=Vudv4D_e@gV*y*kb-AG1!kO>8!ZwHtY)xk597jI*$hll(vo6~;NL4dBfV^7db} zUR+;UfU+~#!)s_kAe9`BNgKXi4t|vRgO!|A@#`~L+@;{ur$#X#+$51UjFW@N#|!#a zWPV+`6psMOF(j1-?ty`W>AU{`9ze?8p9D?*um-V>#odNCn*sm7L}E;vE7;xVM0x zIFQlC5S}mr#s)Ln99JtP=rRCew^4!jkhXez*LmVQ3x%|`gxKCmGDnwCt2tA(vN8rU zoQ{>3H-&s&(yH6|XI=}B`SNrFpJ@H4Wvz~fz$MRzQE-h4sv587^L*t(qIOmK-CZN{J*q3e z1YFxqW;B^^<+-?TDgM`|m=Y#&@@^rYp;jan=&jck?xF|Kb-hA+O*-E0N4U6=rh?ba zpAtyVhT5Y5WUtKp`vF?|9lob_MeXIay^OnXfZM2-%gNdZ8QXwyjP=g~wRKw9l#es; z_riTr*7a|0{6%A7BwE9<9TD$A#_#Ak=+(FJ;Qv( zvyVkRMQ`0{_RBL%s_J(+xI02M%fTN5qNl{iT)N=a`V#UL=vs5VZ06QL<<6hGH0ucH5ls$6D824p>!;^Tdh= z2R-xOBkM+?;#+GKV|95AsQ@sKJEX>NK2ymbLHw(a)qWtX5Xf}9cDRlb6|XLw?Twi6 z!R&FyO7!W)SH8ue)=dD7oFLp37BT=zjCIa&#yi#>{{V?}i))Xw#3a7C*vw;fPBVZGaa?uP-m|DPO{>o`K_sZn1k#wHc){h=bz#84jbA4uk&M)FN2EY+rF)p< zNcPDblKId@1{<+W(h-bu&Y+*+9D_*(jmxhX-aVVHm1{EGLX6m*V*3r%OtDC5&nm1vYe$jChWk=soLausmCB{0ZO3#t?6tr$cFi5~ON}|#k zR2=!7C=vp3hE#mxoMR%(!)b4(&vy;=rS8}B7swJt_C^EmjtjDY0n0E=$CToj$wMr+ z`}Dm!=-n#pk{AGaZP|z*?!gd)jGQb(rb+5*-80(UPit{^CDp@C=1m>Dd8TYQVy}`_ zPX{?!Mtg!YQ3y2yZWXqRC72&16}7f?UapuM8-xDHF%HK|dqxTu zC0pfDmB$FBv-g7atMJ98q!Yyj^}WOH+>b0WB1Q-SfJH`W7a#M{v66m4#V{n(Ad*XF zgTvC+D9Nf`HV8T$zhQ0_!-79D|**J)AfmNPl&ul9;s;*VZO%=*=S-_ z}YbE&{A4%EmTaJc1u&vkjSWHDdBw?0g6lB_m+e(@_O2p6f^fVW;0*8ZE}O#<6b zcJU6g2Dl>u<&HL3;Y0+p6B3`F9RYpECmqEPVHuwk{6}eJ;X7>`M4AI_e2V560R7x3 zL607yMgf5xRTro=;+F4nH3a(vhAHsbko1fYLH!9IjcRzKSC3Wk1?Annw05@MVGuzQ zg;kqj)=8)o(2=rFr6>#@0D*?|j52RaGSUOM`=+6c)$d9dU~B zdod`1RoejL<;Tm9LOOnR?D`~W;r{@Jv8Cg>Pj%*B-N?fRI1rUck6pmBmd712ic*$} zG0;}(&pFoh3)|lj3pSCTQ+fQ^rez$v^PF%GUYvFUx+x@EJvw_y;%N*~#~uomGP@k) z5%10hcs0lBS1EVmTYJe^+j;VaFA*hx0BsAw=NRqD^sW6u`b+IKW`aV~j7$dcoM$R{ z>GFVh>FwXf#>bv9vkoFBdISd*!kNjaBj^LOL@{G5J<=J!*ZNDMV(ji+Enj%v-SnL@Yec0X|{=5XYP^2Pcz^P?pK9w5>Gp7;P~kNgDm- zB$I+U=m^gunxP||YYr&#GKp>oQv0Mjj^;G)>AZN0&HZ{>VHWjN|K9 zq+0>)Ir??+vA!y}^lr zVQ9uz-)nnanx~EB!*~NCRbxKu-)aRah&4=xW;=` z-3r@I)2$h92ohR8*$G@0$OIJ!IbLu_Bp+fkhpPCx!u661RxuPmD~3NY?0s{^V4*2H zMQDY}O6oKnO5aX+zqFoNw?`uqrZ!O681);nJN`AeBaZ6%9{mf&_C^gG@x94IpKdZS z+%X*qtjk?y*H*o2sl2e(aVhgY@eH7R{W4Dk)%z>x?xS{>59T&d0102Z0Uh`}UM&&!TEJkjUNbtD$|Hwzhw*zHrbmx4FBC*>z6o}7X!gwt0M-6)}eK(D#1K+Td)fLWM>kNer$DKy*<9QwD9sz zK^n%`&3Y~@Np|~KiB>$y(*T`DJ(vzS!0*uXP-!wGO4b^Dw==^g_q$7fGtFU=s)roo zIQ8}FF$ae{A1<46`irEN*FIE`q!LB7gA8I(^Kf!HW1$B;)4VSVYIpHNF0FZ|nJ^LU zt{HZ@?nvr!hUAX5>0vPOgngv9CwF5(HSZinr~Rt>3yU~WH#vJa$cT5`c5#mR=hm(b zTf~xSX?q@{8>zzpZ6X*L&U3fhAB}A4k?T5ju9>E#-HxvWl7yb>ST1LIL&ysfBWxn6 zJO*aS0C9s>wcR?)L$|kz+eE+AN0!58l8%tzsZymkFv#7w0y^M>kzJnAZDI00=PPsK zy<*KqhvaEC?Tu3MLcu`;sm}u-Wbg%4xbRiu>e1h6 z7P_vTs94YTh?~!W(HMnOfOeJ)skiSDf_+YIXj-m}w+{!gwKJ?Ea zX$ZHsMi~(%{*sIN%O?`&FVlXbKYFx-&H zsu_@QNK!I-kIu4|9*nh=KM>UOYi|WxYe}hr;(5c}xORZqB0ND@va1g;_S$*Ia1LqE z{3wOa2E8mzE=orwh6%@Azr5$D$r%UMxj%?eYF8dG)O9Znd8*M(wka%Fq?lOIALU#e z21Xh0^yJd;_r?u>N08e1f-|YYt~QAPjpN7s2Ml=XMt$nzN-+3P_d7jPM6~edmm4gy z#EJ_gsj8TRUBmyunKZteX(4J{v z=+9Ss`i1Oy<+sCM_)7c*VXSF#M{lXOoMl(e+4jiF2eH5dfm}YJqTOk;2=2pL-&?r~ z2rAhf!LOojbSn))!(l)lV|jBkv$-dsW+a#G*S7-|#Opp4({%5jS%!Or!Q17;v7=|O zeauw;0RI3w^dmcHEzVcMe--aEc|OJBINIvh%q$)?#?Czl(>WRXcdu1=G=CY{nImPm zTo8`~VqiM(LF98>1&4sNeQQJW62#bC+acXFl1#}s10~(t2^q#uTpoH3u}7xfct6dG z&MS)xrW@m#CUOHFH*7DogO0m$K_D>TgzVmdW^~s+9KX@_MHKLzHfI7^A+$+lPPt+T zBmfI?3B^#O-tq88+Uh};C~7?`uLw>%NF@z$233v;C3>E=yV zNUlu5)Wc}SSF2}mDp!N@;X4D|VBXF2Ff`hF?zAeQZW8l3KQ=yK7cKL0uBE^Laahf9 zYHpN66dpk>D@O@;jHq=+m5`F?56Chw*dPv|RF>9>aTA+uM$u$dC5(llLy^&Z%oE>( z>IO;93kszHs6iAX;v~tIm8@V6_8Oo5O7ze4y!>^{4-37O} zI^Bj0vdO@9!NF%4EHS_Z#xvNCpcF6EhlSs0X=4%jgnbi{P|sN?aLj_A&e;J zBz(@!xa0s0VO#$IYj~c`uO@q|_#tO+w5VSp26^SX5<12t?ehBR$gC^A=T&**Jqtz~ zbhr)0%KqoP%Q5c?E&5|J3QQuDHd)C}$*a5n&; z@-x&{Yb?VHDgXfUfr_W77Om`c1=VJ{)LLk6 zWMq;CQzWy<2UPOaw*?@83%a*Mj-sGfT_)c0d93ZEn<7~t))m>KIXs{#9BIaIPFRum ziN#0#jV+@=EyG*eOAh09m)9{o%n3L#z)xMIH}4n`$IG57rubrlNwnb0YXkiHjr583 zhymv+PSuDuI90|^%acmLTzIdqBWZOj+3obZ#aBzK$s~{~W99wO!^l7cWQAUwo+?DS z)BgapWt!#|)nU4Ijc)E`Z?nS41{@>CKq#afvbz9!k%3e#d_Q%n*_-#0IAXXeQ&7K~ z$%Tsz#GU^Dy=LpcQJm*@7&lh_(I<}2O1Aq<(wvztkx5B0f#j$=LBJSpT$9%{XfT#( zZ)_~4mf~r&`;y5m#-%ZmB|ESTYE&^HMMe012Ydmvva_q_<{6AhfTufZq<6NlUfZy@ zj`mgoXE$s6his3SCP8j_-6J1hy(!p5n|W_8;CGJd=6ycS;h?xO-R*%8V`_%l4^ntV zIrLm}JQn(0&Fm3ez;&x=?f%TjT|{y!<+!(I+}|+V3m;$xX_3vS&#R(aU20b^YJ<;; z3507BVBvhjHqg8r{J?-g0E1HKwwfc_rQeD5C7w9)jbQ{*n^z=;%%zhuK0rL+WC9d( zKoD9stF2ngWunO@t!&N`X4@Pv+kipk@XPX(kg?u>Ls@-#?x}_5;$BN7CiJm0^fu zKQp=h5nE14D+z0<+x#%_ou`TQ#g6g`JLnG1oK@Fk2NLNEo6&M z&7$fK;@uP-s~l;yMgZUwhd!L2uE4Uj@Q1_DwkAlgbtzKCWX{qu6`1r5j4K2F_dRP1 zR*CNI*1{`vF{=WLv=ta{x?X_>SMR2;L&uaTd*kwk_ zjzKC0axyxM)sa8i?%|(kF)X)F|9*7q8OR&c^$h%Avs0UMKe<*|=Yc?THJYO^Mx zDYp+{wm^vKA;~)*B;&R~2aYN&N%Z^M*;>Z%{{U$O4dpuEl?RYW>;2$8KsC)7%1tM* ztYYe#syByiBh!EiX9>A7tQ;on{XTLkCXl9sYX!rWSzKhEMisNj^!dL^qbw4|44QP0 z0!SqDT1R|^1wjXZPIv|y&qKjD>6~%JP`i>Fg?QvuBWjJPPp?tOuebQs8LpEW*@T9hn!bQB+wbUUif_&SRkz3mf82)0i=CZqKN#bTbSU!I|)$KRI+WxQ! z)3oy{41oCoeu0U`dFhTlUbO!J z32XXPcjnyK$2t?{vADW$u0oQ$Z7MKH9*}ZSY^j z@(2WB{Il?NPpRz9QROKW){ z8a1tykz7Vb_A<;>uz4O}033nAQ~2i;mR|-n%NX6G)GR~ia4KA2f8RBuZSdDwxn+`j zn`@g%7l9=1A8$}f>?1y-C+cgKT+FNAq303m=^I@`szb7SbR@@|mLWj^V0Rqn-nqLG zrE51T#YL6K{{UAM0PJSS11ePDbN%Y|#rQX?*lK@k(=IgFa&T0aA6#L5x^$-MKLqZz zJI}OU+*`NzjBS?3f8ZHEQa-hCN)JT!BFysL2HtBw5KUzxNRdkNeBrtU4}w0tR@^2y zS)q#NSw~OaKJ1R4(yi;i2s~OR38z}U!bSvfkurc#aJk&W2OMMARVy!rzBAJqWz_WP zkvDD&8wt(;!N@|`d3vI#qeqQ}?+t#}q zFAqT-m)atTG|?|*8=IlVc=r5jj;68YL$S%j2{KC*%_q#ka_ENSM%e6sDwP!CMw@vd%NCgE=G zu5Rav)VA-Ce4w7A*S;$nUhcOf6tMF4h|W-{Qe$(RAD|f?wbH6ibt0P)a7jJy#G99rNtJZVaS)Gl1!rxpSdRU1&UypX zQ*3l*u<=HnXB1A>1W6=!4C+`islt)QFiQPF9)#8OnQisWapn?kj_@HQ7AG*ozzhzb zFdv0!`2u*E2_QO<9UBgrQa3677Qr|^=Dn!9p*)G-}4~*#fA$WI`VyM zhwL7gIz6-uL@a2HB0+bcZ^B)beCpx z#y2K`MGfCwDc6#g34 zblY;d*RILo=q@c|p29+*kTQon5stNqHMPZ?0WuXn zpw~yaQ$*~?%TgNdjz_{$YSub)>RN4_S617PnQrZtQaX^_dU{sudiREPn~5dW=2)$m zMiRnE8Ka58ZN-5F4&qk_865QF)E*$!8%xpzvBVZjsmAGImEm?Fagx!MW57|@paZpX zC&kmo#J-85+>_Pr;g)tkQt}$XVQOCSX1>}IUh+4!j|*wK#;x{$4z$+Opb{CZ09b95 zoP)QIz38pR4i~jyOW^Cd?B$13OMBxCf+=pAA2vY6Hv_m7bzFuUq!=V|)MW>cb<1=k zOoK|(dU0!Fi|dZL>6&u2Qim4sxF`9l03k&mybXY92T6Q>^wEa$VUfe1)a+p(EQ3mFe3UuF}`V z8iU&0z45i4CK5Zu)~FUj+0N~t5(zwldCxWH7k5{dI;_)avKtm=$xB9LLEolN9^F3* z%B3eA%8R+^`X9$TE9q9-#8!t)lOev-8y61UIl}sShUx4p(`{z9*EE=3+C6aSB(F;rcJ+)g^ zIYqc)th{imA>~&%;N*G?^IZ0u@jt|#9C#DQ+Hzj$%%jV>fGndU8%{TEIN;=MKVB=o z(0o~;Yu0D}5&cYG%!hNubu5DmfHr_e{x~~|wt8orhklI)rdFrn)SrC%R+k7x+6;)Y zZi%*r=pD0+^-@NA=Za+0!!4Dyw}~Z&StHvY+L9}eJdT^B-yiRAF`t+mXQ|@75gFDl z85-TV8zaag@ITVIFA;cC`$u)oo0OTp^a~y%ATRKpqylg~2PFMw{l{~dxYF))n|GGY z7FaLhks!K?SrD=iLB`U!JoIl)YWv-!raa-Bx_n@;#jVnAZp?4NWKPqDn zkj;PqAe`V^8En~VHp*>ptgRtg5WFoTqU_5S%KXFlixL6GOJrx7Nnli$%+hZXDT&x3 zdE*j%$7obx!?@;dthf5hVKuCBh>IhCy;v~Rl6!x=@$@3$la^uYF_pxty` z#q&thA=rGv+m`?U4(>)VjCREp%`b?fTf}89JYlF^SiPfO+1*acE;lgX5c1y1HwXlJ#z+ zlG!+pJ@onLaq`BfCm}IcOJl;vE!O(24hds=6J59^AQ}UfC zt}mvB+T!}{^!VaFWTtD0MDySg8^sGg?Dq`Y0M9CU6w5n}3AKoB?JTb6)DaaUd91|j zHjY^$SrrgA2_PvMEJ5_teK%Q#7@@Sa*G0|DgtSYkZcuZb(-5E_Zbs~}&p7qBAAzpr zkNzh%*1C)mFlW=DxM*Qgrz_?-1*dGBlGqthfkumPIr+5>LteSL7MC(#Sk9(bnpxT_ zSXqt~JMVN;$RS4a(Qq@64CbR*_td$95fxUOU^a%%kgOcoYbjeRw#XD^*D z*7;FD$r~nTJMsobBf-W%1dEM(KPeLG9C(%2Btt;~hwBpkE8L1IZf9y#P1 z$%DaKfr(>|&IOqmkw2Q~iJ#(brMC7|+I>%(N6MY#RDu;%;gc7VN_!!&$tT5@TBF~N1JQ< zMvqA4#01AR&9GSQp(pRlA=*B; z8;Kr(*ClE5K2&QJ)Z%ZO`)XTB?wV<1w3IwVX9bw1;<*DW@{HphI}^=m=6LUJt|S6j z7Td@x*NmKx#~-MwmU_*!-W`TJbn>Tx77R0F61e9*vr$>ye&*m^D<3N04a~eu=egXuF`*-AAn-Uj{b;h)7s+oogmSx`PJGTz z++^|3Z+gh_W~HcUy6x?}Q=hY6M!SNjU^T#IDP~(I-AJ5vGgHJ{b z=I*RKiJfGQM3N`lGCC5(af8k}jQVr%;b z9rX7N3PRs26=_f01bg@G#cyf;5P?8z=~`ADRSwbg^{%%;hT2UI8POv9Ns*dj6ts*( zoC0(5@H=vIM7CEKmvcHnGW_L~1U~+PyJNN3?8_P@!O;+ZXF~*Q(6NPBpJGp6#=CtZ z#u}DDlHYp)fYCw$#(I4#p3`)FT@(~(;sLS)u5s^-S9#&JySIqNaM8&tw=P%m;<@Td zJ&hunv7=vH-R*f1wiDHt82rAKw$gwJd#f79i+l2)8%uTIAt zamIZ)%kfu8dLkYBT!xW0PW5P83(Osqc-eK(X*-O`hKr#_H9DeJBWeG ztBzOP9-#dyx@gI17nfxtBtVbd$lJ%@dgPwun&4N*H+t2(&uih`LsE-*UD57!Q-E>u zsQ}{~R=M7zX^87Z7_0meIlk6QCP?L$(!jg7sX(T%r;ltgx(I3wR6kF9$Tk9D)B_;T@4 zA|_~BA-(x+%a4^YmLrZh`ilAARq+-5--j)psSs13+GAHCEZ{RbyF5eg~F z;+2rw4P#SDE|i!1I!L~J#y^%blB!ta1Cx)fb=H11mfKB&?#lYbZ^%O*n<9;^v}Zk( zWRcGR^}xxmG(j+sIbzv}T@$4qWXL{;@tusiX1w?4;yWElRtZWcDRa>ro`4nka(nC@>aDklt!?h~ zyIZGNrPL&71Z;7!(Qpt}Gt1Y@J9Zbu`W@-thekTr8}#*=KavyA{gY^44|xo6WgC%0Mc z0?y1hj5gEw?!f(fR+ha5#F`eD6He_sFv_Mz$&rWwRgQ8?bSK|6lV##*uPiPsbrfiI z0E~gvwg<@j>)d?@Ls~gWMRJmozN8S}dG_&78*W!n%5jW>GAbD_8+Z6r7Mf+gG`B(2KEzz_-g9<{X@r+X7Py$?Xq12>24 zgsZi@g&6k60sOFPIZ!-hU3U*dQlzs-@}J%g-nAK!XAB5$LtI^Mda#R*ho5{;($re% zmiB~3yWQK8eFym0oW7NCqwk@wQ22)+d&@M>+_wkwX8!;R;||u3J^NRsMsnmttUWnu z(aYT1%WB9ZWjnLLKj+q?55-*8$oo`E58Yhx{(Y-Ipv`v2SlymwXsA?iT?wU`g}&a^ z)p(ELew`|%*N1#ZVmHUU!+Ug}IXw!n>z_;yt#QVEt|P!Z`uhshk6OF1(o;@p8Wjzb zAp`_gZdi`sXEnu$i<8hG^f-&{GWx{>Tw62Sw<6*tEfaCshXH;^@Y|qLYYbt@k zDY%fw*OKG@1CG_zMWo$Yw6~rfz4FSS5;P}zo=$VrAG!}dwVkQU6KDH-LpKh?0{YfN z8!tI6w;Nloam8`zV@sIYR=26>OwXiVG#+5XuF&e=RbWA@5$hUl)zUV%q^kb_dh1Vf z6xsE`B@fU6NgjlngiR)isYf#*$Jp;N1;OWyi;^GkIrgmEm}az}$i9MGX;+4hR4T)q zbTo#0MuFo!TF=AwQ)ri|s!878QehnOL%qJ~2bSO{CvfAXcKTPv4-RTqa>c47`W?(` z_cbsr$Ek0+gOSzE}J zL!nZ*=z4M+r8fljAo?y_C~uY7~kl%N+DF+9GoRDxm1#?=ak>ZU;@>6fD zPj74(h~P`vv$s5M4z15_4mhtQ()C$%o8rD0zqrsOm2)Im6Wd60-B|pc`2e1KSE5*a zQn|PLHMfa$$B;JI#rB-ubS~X8+yfaW>(|<&mBeYA+HRGvM!_|6X{bW0u^wdxNQO{l zOG3cyR5)A!OB|l!4QEQ#p;s_i+Fsi`Y*7}Q2$@H?2srm1-7|{W(>y_<_=OPZTBI_a zo7y#-B{=AIoUh_L){--(Op%!rs!yUw^-(`ty$YAn)@`G^Qyf>*M;L64 zsw8X<52qDgKOgGM%EUtKr<}_!58=A9d}Xu#6Mb)ipX~|%0Q6&47o3R4oCDIjlp|s; zdJKORHJIWc+1N1kVMa!uk3 zDXrmmNG>9hMp443VY~FrdShxP;9 zb-5!3UkU1jj0_~;E^*HW6UWw|m*PIYyf1_`MqY$8uLPcF*kuD93&;Ne#Zm0y9L9Z*#5?~0x0jQ``m;qK z@gDK@g|_w{6(qi`ZSgiTiw`PT?My}O{O)8Hv;YJxTq_fjyM>}&frZ-Px$w= zg?)VKi2W5!WO&xoU$XFh#q)icL|a3=Wx+sL4m0)Z#Y==x)SEox#=6`wK^>-^>X52! zjT3;Wf(gby3gPq}GUHsD3`HgMxYi z>IQrC>t2uHj|9u5TBWuY>rs%Fk)cw+V>~WKa0jn?&aG6Hkx_}QrojXj7TRu}pSia| z8n<@img&@-lkRJY_{*qyb7^`c6NX!O&DG1qPY&P(MjZ)NT>E*1eSL$&{vMXnMYz4Q zbdE4x%ck7m5(W=YPw80K9|yFr5Z&D0>w1o-adCMwPVWN87!2ItZr#A?^v4y+1$|kg zJeNoTG{bLk42vYCBocGBMZgMFcO2)Ad9B7MV7d=1ZmK-uR|EhDCy##h>9G7B@a?s- z!)%(G?Fze^<}g?&z{%Ksx_VSo{2tNdnIs=?B~Zl0ua!iKPJUn_!T$j33gVU;ZcUM6 z!ZjOnsoLq+i7%R5NM%?40;f19zaOS6Yr|s3Z4N8D$;9(REQvS+EQ-Z~4mlX?duNPd zy@uc5{)-$-Z!AwOvbN=k?hY3{e&VlV+}6gQ@WaCza6e_zEmc_Ml$lsJra_Q{)Yk5V zoD^FNA3a&8l{Dm*n$?+^GC2qMPI)=V9`%)clR9~WzL+)XvSGAUL?1(ikyPko~R ze4$1=W1890?KRI5DlM*^bA9EVo^&?tBQLH<>UkU=Km~nMb>M#v-rTj#{*R~2G@mJw zYdA|c7y~78dRB}cQ%v@eJ>+5mgP7z<)B%hu5EPH0HLi&VDf0!tfjnPlaAmU7b(o8s zvn8C%xciKAT~3HRYhfdyQO*EWzcZDOa+w|HATAG+Wid*j-w{{X^4qivhYiZ^spRy9>t zkb#|`oGwpHk_Wh~yU!R;0Z*}bSI$mz=3PRV^!vN1I&E+H70h))MC5NDogQ=q?P+7r zy9&tD{8gt1`m~ya7lgYo zE56*4g9H)x#&e$I>58f1zX3(!qirS2{`%QSMv?_}T%Jm)ehKx@VV;#*KN;##+K5U= zGJrvnULCskO{4Mxxz#t@KY6a}gp-`Ephi8qRXPUV+H#&q~mT;h%?4vAEOboHsd^{$H2=`69C{yitFrS}nb(^F}^tZzhs?8L$C4 zX5*%C03C2DX#8ERPa`U{BtOa!MV?RBCac*@Inldw;9Un$5q+}3u6&gXADwqQ?HqS6 z>^bjLCiqX_>F*x$eH2MM{pWkBj_;`7&*RdwCGifs8*P&1qCTEbAEqj-n(nUqRO&M* z?XkB104hGN_d(8$(eR_fXw1-Q5XQ{gnS_$IPvZQ4k2R~O_&Z6{Vv;CrA#XY_Dql5B zhD5;|TX8#w%-wVMo7C41HEm5g>X(G$9M0e4Q4L2?z(3k|fd2s3!}0pneO_CO+9TEc zhvVn>`+~Ez&kkGbntYb`EYZodm?mBgyqF+JxFZZR{KrCT&7S)7xGkt%XCL#~zs8`N z=5|)!b2IV$QW~{~eZ}n&w=RKxkfpYv8{NISglmcC7K?n;C9W zSGQf{e6KX5C?8fhtfmFjWRu1@IpT&y-GVX#jy)^F0QW&XGhui>eah&9Js@@3r(JiwsmE+Ly$s06Hs62aFTpVnYHBq#VK|b7$rm0I5 zepHOoTSK-sZTB*W;}`_sw`}7T<{lvzHeM{hw7=7vPm|10*3w{{Z680&$IZ)dPu?RZ ztrDc8qk5GYwy$I8zlb_7hx|q1A3dXnI!Wcz&TkD1HO69b(Tt6`T)Ir z#XqffVd2Y4=2LvrQ9FBNm2Iv5)sHwL`GkLa9R9SoQLDm8T((9CsFGO(VNcEVrzG2* z6pp8nTpdqQMWf69AzV1|7`I+_LW}gyPxY>U?D8Hnfm>cbk!11Z$Oj=jwa5GcYJhwW znXgKp!j10IRyh4-OnR%Q_f=}C=sBx;+wa$|N#h$vKj0#%{{RrK`0S4gtG!7-GQ1nE zJVdZWp_wD)Sl}M~{uSRng}00^KF4EqV`VRv3B8ydj_b#je|8vd;FSOdIX{m>kOn-u^Sfyp zMmrSl^c`cvtL1AteddD2_O<*9WVW4{ZVP}+XOHfaj1i7FifgGLvGOmp^LJ>mF5CNj zKGIYlnFlM+t~jqr@Mn(hbsap~YCc?z<@s~lI4=yUaxt~D!5wM$9vbk!h+(}pa~}`h z&ie$AZZLul2vDR1lRTkU6+U@!0m_o>M?`zk=DHjU-)CK=~1lrHkOSHag~Emv$+=XOiw^a zQl}#rEElQEcdlyBQMi)cOA83?{6z}JT4U)S*_v$4A45rj@^2xJwKTvwMumN z)AXG--sUET;b3zlEI}v?jLV#N!yY?vRP?o%Pl3|XX(B5l1F^A@yKn?|7(MFAAe>`R zwL7u6x)nXf-2VXVqOUF7)+!`P-6KayBvmKoRbWWR&=E~r`)x;AlxlWruWSM&*4R=5 z0816KC64iu6K><7Ck=KyoZTyabW+g`LcYdn!E&Y*!jAGno% zk|r9upA39M)GcB8?v3PZNDy2R6o^5`-vev^0KkS%t#VQ@l6e>np`4ICIjZ*Yk22wU zZI_NcR3GL|ONwJm^$llMi&?pf<`rez5Jn9a!=1$R>D+QSqPedRmj2Ih>{}9$GIN1} z#TCUhX*6oKI!_Zeklrx9fcR?Kd1t?tKQ?VzD7?u$!VVBIW0Tv1+Z8p>hm2^WOwe=~ z$wl1P4>K@0C#dH~CqhpWZ zpJ^V(v(4f(wKn&6+HRRH?5Vb~V%+o?X9M)BD+asvOK9ftObf9|mO=JtA59I}6t`WLqQmFx)W3CN9t9NWYuaT(p%*^H=6kR|`;Z;2s@(7EG zb=`VE%0Ss`YJ)h&bGM$k^y83f7riV>rm3z-qoYgBrD5DAXQU(WX#gXft`KlM1KAV3E+uZ6p?ZgOt#WG70${cV$ zWn68+JZ;Z8&p}T6JaFt5@$8Lw+mghS)RK85oRUu@)sUqWmRx;!rR*VK_Kb?s&q=ep zTZ>H`dGX{VmlsmGPf|oxt?XD~>T$>}mE6 zc^b{)OP02l5}QT9Wq%~9;5VjJ@;eireQ9j`LvyEFM{8qm62zlwnM*rh06OG)Rz3*_ zKg0S{B)qbN2IBVGEMp=`)qT5~Udo#29P(!G{3P1JZYNy&2$%dSR@e3Nq5R}kJphSw z^~YM~#=oRMPVG+A@tiD~{#6W~GSS5TU)w_+omE)>07_0U8s<89_5FHgA#ZuX{{WUq zKlWOU_045T5?-FYlz)YDcD^mqo@Q0N*l~=?g-7RA^*ZAG9bH>8uk?8W-#}r$Yj{NjEy&6cO7T{{Wv#^F3qY)zlZ0T3Tqf;o)|OOEtqcAmcaydVij^gK_aM#S+Mk z6t;HVak32m0O(nz&V!Y++AZLOlG5}XU>q8Cx?6HcBMs}puNGg3-YjJ!?RLy@*X*b$ zhvEl{aND&ohj-muNWb`+J)&aeXSGgYU@;IYo;fvD(+$G$?OtJN;e|vCH_lIREiE(dR7mZc=V|i8);&Mf$d&cHSKC? zW;5$IM{dvpzR$}Qk*eHJcN?3FsihhIDcJMt){kxE9EZ8f8_LR35;lx<>r9!Q{#FQt zDb6sX@vomIRpc|X1M23HmNwGj%H(bhl+V|A%n$AEY{4|62n$5Z6_*L8aDX$=o8(pN9MB}-u0WFagH-;GF6grX)M0%rm=fgXf8nQM= z@Y_s#{{XpKdTzg@-({_Dqi(!1vJ?4=@gpUww$>-6K+iSOXqu(6Tv}V9+Q#8Cp7~+Y zrPPs12=zHND+N_DUPYGl%OB8HC)RYcaM7EfSwPMsZs(41TqIhImukLLFCku~6r6rl zYBar`bF)vmkT6hj3moTA(P{HG(Z=aQlloUE*3!vs7BBR*KRYWu{2@s=7|!f=sOHn> zFt^%u-3AiNf(7!(N8p>Px#!$mu{AC}B;6{XvFO(S054BIR&L(ds)OQAzFhfQc9N%n zcSj+|AMe&QmR7K-3E~YtR$@QZ#XDpF03qV3n}3;#>d-I;CvCik1JwMqb3WtcM&_&I zjaymM?<}rtbioLKGZ^AIiE z7zS1t!N~40oY#A$KFv-NduRC?;r9I$(?Jizo%05b8J0|X;-nD=ojJ!nYc!)rC(3c{R;}(B z%z=mh09w5B*_3UnJbT1aJ>QIV35ovzmitD1fFIJJ8}Y+ce>=?7rI$GpJ2&QP$J#dJ zo&|bvR*9oWC3^m5rEur|dLPq|=}?n{pGrw&^Dd@w$Y~j~_|q8tryWgqbUt=Y@@(z= zKk$kh)lE*~?TnX$&I=rbU^oqqp7q+<{3Fs}KxCTzpBqkR!v0t_=Q`)be-_zmS9(U1 ze+{**i~XH;+NN@YY2<_7HHCZQPZwYO_nQ6FJCMIA2tOqPyjfkdWv5f!ZN407R>8?gt?$E|$#aj0sS zIQvGWcI2G@0Iq7r)F5e}_p(a-9PV;+S;`HRq>rp@{3&Z=aNytXj&qqUWRf!z`eha{ z59MBS@l)a6lcEVcd0@#bkX^$i)s&7NBM~Aqlo4qxOcJxJYB?cG6p>MpPeC0QIR*anz>MCDipR z%`vYbzf`}DEzTBWxPjDdZmY&P=rhu)!Kc|3ShU-TeAZ%FZwL(RPxprh&}SS0TAnV_ zH4Q6LnCdo73;+dRlL`{h07|*1UtL*ge`Hn@TP%(Y6Aj8pW5_*M*X1KM zX3ccF`Gv$2HJ#nNyh$Cy;w}3|=H2PFurum<@qh}y@?wTyia z)X~%|b=p0&*0zrw$`pSvoF7aIDm@2x*klaEfhh}<&}|>rG*=w{CTg}lGsk-Ehli5x zYv%#vo<)iSRH z6UR(Zb=)<$)bY%((?pL4*5$MR0HD=PN8&Z*mCRAYq1)nA;I!^>j=jC=ynkhl0h)Vg zy?oi#arv67sljD&HKg$BI%BMC!SQ_wAQ9=iJ#kX)+@-$7xV&+#+_rwnYXawhu@m}} zTUL7Rqdlx|BgY%KCAP*o?jyc?0ay@TXs{{swS6=J)C-g+KR|O+9}wtJ+Q&NTkTeY= zCzz=C+yb0^-$VM;rk7A@zK2Ksr>K~iiPeiK#^{v)07{!nzP`KCZKa;z`K=o7^3)*R zj(8sRgKy$r56asYT(d*BKfGe2^B@nytv(+V=vp*CXT8;+ZdycWQRFVH#fCPnIuYNs zK4|w9q;waJbn%5tnUvu29Q|rITJ;-0Y`8fY$&j4>b%dV~yg7Gy4YX6;vq<3-n^F{# za5*iJS;yj5m=qXN@?r;g)jydvJncpV@HoZ5`SNVZ342TU6{&u?|CO>W947Y7(WT6U(QOQbsiZz2)E z^hF=it({Wn6R~Ya($*pTmY;Qdc!_T+xQ(QXIYd?H#C9Ikv>vxGE^TgRw`7jWT!sfK zgy)g%Oq)c#IL(dprGVlKW^507*tpeokFv?PR=rXNaF-6F@&>BT*MdPL8jQ)0;Az`$ z<(yXZd0KtQoz8mi!}_}2G-;*k5^Y_N5Gs1oy8ac}==dZ~;EU&{bVCRJGBs?d7|1cA`QZ#&<-lF}Zu>XFr8SX*gX+ zQ+jmNq0J{^-lO3iWa_uKQvHr7Ww~-Cn({SVmg$mnQ7?q<*_h3#=`pM=^XBhA`Uo{7 zx0X6ZjoqD|r*W*$sY`D+?_+4hAxMxhEu5DJ{A#hajTZV{ldD`IEF=dCPhflg6{ZzB z&~93O9S&;Gk)(-lG)QgcW`|hQ*-P#6qw|X=*C~(Is))4vd1Q`#SdyooCe@#}zS^>} zUf*0w*1Bcnt0V7I94yDDu%-V1gj-!=@BaV@{-zYRGS+f)$Eg*RZ`9ew3Y={9>Px1b zAl$f%QNMQbB^Yfz6muJY(^{s|X*(1RLsBFhabX&d{T=-(_LrkwL3z4+V;M2O4I(QH zsq9TvT^8tqS?r@3{{WVku&>jC)upsDD+`M#=iEi~$(-YQL{I)Y)n+|QM@*Tt8>zcC z{Zo_qL@Gb*;w328)(W^EKiZM7dF&2PPSiG^V2H*|cFhiZB#t@n@~QWv1%s_<%@9TK zym`-AFXbftagWm#6xyw!)9w6?2Fg9t%%w}rzT*7lAK`qX&<ytiI0Cm#8mL=ch>5rB(Yo$ zNw9^_{yc`IlxRsCd3Sn*qiNvVB4hsmA2g9&X-TvjYx#i#{#&YN{{S5{tTJ!-OLgR# ze5=Ug3cVw=g){jetqmi^THV&SVz(Nl%!+4?S$AL&xB@u!s z?>FxY6N7?kD@D}ZP($G6L5!(3_XPf}TNW{DtuvG1(-|OV{T@to_cfHF%S{>AknXdS ze%>mC@hAlC&UopX?Bur9=CxrKnG|it16rp%{{XZqy~dH^gBcd_Mv8kX!lY7)eMH(g z%bQsq-o`bFocS)}YLb7}H($!48YZVIua&1=KI4E^7CHSZu$MsbT#Ib6PS(vFc#y2& zNp0+N@}EK~MeuKlZgSWDDY-(#2L1f4k?Ge4x8-DWBal8B)>T8kpK^mF10-cZ$6mga z+f5$rWGyw_g{v_;ME7y2KZbMqS7rYI3fN4<-Rrj(0ghWSa^Hz#S8aY9_@92JkJQ+w)Y-!R1zU1gbjcQUQei{j@!f@1=W`J z)_YlHmMmeEk6?bSml8HkI4j2$+2|Qd*&i8SEQ9!w{uRdfO6FnV__Vq0 z*?+U1NaMIg{nf&>jQK|HLl;szV0XwJ$A=U#xZHob2kTwR%Mbl`6)kZJ=E}M=;QDb* zmk=zIH$;t_@)XG;WO7$OLEflqH-1ltH3o822nfz`jPdz;vbN8=~71P5w;gzG1DV)l@o7oqJqct72hXlv*u23T)K*H7Hc;Vk+y9{cU*cI8x<|`Nw^X?NrjarXh*8KDXR=bTr$q~v^pZE?d#y1}omHgN+ zSlr9$<-*OA_zH*q5$_RAF6g{Js>nASk!2<^p1nF%xqL&e15}gGq8eZLOjSv-2~&P@0@n(b6M1sly4HFtJLrG{{V>EZmkn(emT=Wv!&Qe zO)(44ay=#&)XxXIB16I&=Z360O^{Y7` z1^AO;^7;Y85#Nu_vw@7v@kXFvtjy#1i>@*Fd4H{a1*iDaLGd+!v++%pv~MUWB2MwJ zJweFM;rM}Az99HPVQ~xHcv*(mZTk@J&U*}=o`az0rF6!sdNVf@$1g4>^C7TFb7y%m zj^Y<>OSb?VAi_*g8o1vVPhfb9ET_|#shzdsC9hYhl85K1KC2J-a!TVmJF^nMl&AfsSF?gU zqaK7dP@4YyX)(9j=2lsqSgYeB3PyighCNSIXv|Bg-fhly{h`4Ab+Z-$gs%dt26C>QsI8`f{;#_?}KjBv5#H?p-owNRtAj#+FJk*+f!&+*Vv&k%* zVVxbmZoz@6)_oc#%Gh39lh93Y6n;Baw5_~FX$owI!WvwMplO7zasL2))_l5*$kr`Z z9eVmO-zwZb)9tw8t9cRggW9_}wflj6x*rMX)4Z|AAunj}%OE6j{fWonR!*s|&k+gW z%@r3Mgwm98^(QpkUB%3B@k0*dyBvDf>NC~6$X2Ju3q?@gl|aax*; zcJHHTvY;EvOA|IZJ747o@UF@~5Bx(!%=(m}M^iSX$LeZ(ST(4MM|nPvbtFNz8;JbU z3loEtL(}{yP!o~EXqsL2qkJ1kwvyrP+%p92f;!fk_%l{(%ZQ=V=8m!^|FOkZ^sm?^nu_C!14{i@{zY zirz^VNVo`!Ngxd4>D1PoJ_gn!xV5>kvAMbOrdMS#Y`_OUc=6h$y|~lmw7IlhPAisZ z*kT)Y$4^s%Tc_czw95i&8l}vJ097`sj04mR(&fIzb21An4M$D5)0R^9S^LP+uQhCLy9F;)8ilve8rFTtAE(KLIuW~Y;Z<5Mi29- z_H3?nd8wYk7>_FILH_!o{zkN}t~AxtwB~yordNTskF}^Pi61#WUq7XH-`U!D>0xRQ zsDVfHsS-G%U?YhT0mjt>6ni0ao?Ruyl##N>VIUYFi6`Cslu)+=3R6Y5n{XK3B|pi< zda!f!p&R#OJ#j~|^DEkU9#ZpPtbkegJ57|8IA*evQaXQm$f}n*PmT2$%E95g3vt+{ znQI^F%bNB181af}Jawy7*K&E;jo&D1})O5y$yo|$pn3Bn@pjbp1-X%P9o=L8Ex>@Z6@$}f)6{XBKTWis0^B&!#)N|#;QN9b?-8jBsM_g)1%!k0xK~+fUD$%iRNb_ zJ{ahNb~0SwJ~5A-fB2fPpANh|3~iY1T>k*IDE@-F#Ie1RoPqRV?1#QrON?F!el=+(! zuT6J34Wuz_ z`gEq;>5FQ{Des~Zj1q_o5WUSqoEK5@v8yrlrCAAMo@++SN3*&ru-&t_ehB_zsLgxf z>rXUEc{HyZ71;t3TbyJPHv9FgECPf^PPx zUwjPaxXnxAtlw;x76?RR0}}00eKEGBO)|Mo@tX|Y>b$e%lw{{Q9M%Vez9L#{7s&Q?-4}GK%dxM@Uf5!S<>iBm}yYn~LK@u00rOER!qaYrq=Nti? zF+BkzA5HNco~5FV7hYz7tW1_Vw%yGEAcclw$uI(Qz$H&kE1ptq+|fs|>h}`CIf7eB zeCv0%hDfFI#C~XK)x6EUi*DVIdY?_c7Lzi#`D7y}(;2KAD=7RkWoM(aZg?SIJ%Pv) zo@BxP?(+Ed#b_f3T&c)BiuEA{DoQW0&Zj6;=0|I8-gII>*$0qoBgRp${2^L`k%HR* zIR5}`O=s!aoVs)1eDN{)l=k{m-YnE1pTe&sWSHJnQ`qONaY~G#FC*5aT~+lwsR560 z=BR4S%V2O%%-|Z>j#${90O!4D_=-e2bZVt?We1O;uGlYm8{#EuQaSNjz8t(u4Pr~l zMpE9&=1hBt9|QBitd45jO+BxMHT_D`c`fI)wuxevH!8}{JZr%m{oU2mRoa_pfVVlD zD|^}DjbO2!PCte+f2DL5o*D5K)WpN0UcW#w3Fq{#ZcS@ml~hl!>M{&+uXiH@`I@w| z+`6})cPzz^JLF@Z%-4@|dmSyug8WV87dl~t073Jnjy`|jOfytJ;TY6yW?!}3X}04y z$<$$PeK>Q^xBmcMvNn07sXp1O%LS}Sk_!+!j z7}fTn0OtkWGwsi6!|B*yreLUMQ?1kThB@nyjZGjkqKqT++3S z6G&uBNKuY6<&C%=!>9iMuDGQ_OH^vACS>Y9AG6j#X0?~jC;fC#{KxotI5{0ZE)FWT zopG#qXSbr9BK;Y*c z20*1@rRu1ut6O<)fzf1#bZn~IcLjC%(2}dr{{RT>SnCr)O&7%)KaDM$riE>x)RHJbH=bgNe8I+C1yni4c<4?5 z??tzZZgdw#m^8NJHqR`XGmfAWfdJq@AHSYCUZCgeT1IUNq|ZIE(X}lP&$rg?{?Bdmu(%v#V}GK`YlB(`~h@a!7b#M+dIn zKb>BVBR#A#+u?>e=ku%?v^R=!k2Gj9d2I1ZRj}2Wy#}Wr+7ZxNm2tO~>F-*yc*9e+ zwlUjkF~_xjRDw0g{Bc|?dTH}nV!F3(4$>s+T`rMm-`KHl!GD-LgOSwGn{L8sBU&#N z>no?&G1S@zxDFm!22Mkf$@*fa8n&e}kp3!wus_0j{*{|znr@?R&`)n9!qP%FEW3AZ z{12sGhfB~m;p7H9 z4ZXqrYPOSQpxmv=Ix~+hcaLejayZ952d!xvO)lGG+39e?%HuB1&T*e}NnA8We3NOg zM5YUyiKHj)$UzwOsjc-Gl1R2N8^Z!Uae_asY}=$UaRs%!c;ed0-2VXe>#aAJJ5D539k76Z zAywnJW5lG(hHf03AM=_`HmnJx?r|C(m426T%@&t?HMC3`SytV)01i*hjC8MB9wE?f z90c(OkkU3jPq)RmpG9vou0i=Z^R%t{Bd4M;5fH!Z zynq158@!ev{*{Me7WjjAUWXJwI;L^Xw4-K;Z z=SHSRLkxytxOW1LdykbK#RtYO4!nhKw7pi{c*CfULHLY= zkEVW=wtQ{j_R#J%t9!<|w6rKESXVM3bA<&?Fi9A%4iH5oVWZB|)7rPZK7f2S@#>y7 zKAPjcb2${Q(40}w+mPs`_V&*4$c@ncX+A#gXwuaOXFqYUTR5P0=Hxa(2gd?VH6iSJFl ztSc0GTX>z_q$9C70D5<>8uvujA5aloSx%C%3Ij$!9)qP}8n@~WK1W`^7`0zB1{XWJ zgpn1G(1`1IP4TX&bOpuCH%JQnqT>CZ>6HjQyVgI4{vTdNW^SZ`nr0lGgzc>n;hXrU zMR3sv8CNLVSbH2+sjcM9^?Mrf_`_0}Hn)w%0fp5M+hq zedX(pq>+>84Rf}h7uIhl%G%7(Zo<1pR50v8IM1(I>h%8rhqs&5T|xo_z$XOM%Cbtx zsKM^dtyfvKI-L4tv=AYP?o*7M0yE#X{tOZJ<Scuhz2?Dg55t+U0$E@ zBf@F+tBK^22A<>0jTSw{6e6g|&tH_E#8qua;*W;Q2ep#wR|mDYO#Z&rY0NodaoVP< zs9Wlm&@GMPE6TCVr3O@zFjsF-bI&AJ>{l@|MfQkpqh};z$Zp-w9R3-s$^Ihg*FGkT zQM%Jw|h+@L33{TNhELp9SYzB)K#n7VK}F;wFTGM zl-x&Yce5KGd_@Ki9OoJ52aNJ7o3qz`*QjcH3B+1-vW|Kc$N1B){w!STRukIW=`lkj z$XCrW@7Q}B73^!D&_CDfM5zI^nZQ3%w9?m930WQ2hOT4QH2Ef;=3Is`#|&T=H~^E5 zOLZ9I^X$jaXTNVU(Pl9;gggDR0A#3ImbOZ zpGs=@uU<>0mRUnIq;4$=6ZPa)Qj2>P)ama$4{$Xh5sGXWw}vR(ocjvGzW8CRUPyk; zXCZuJE%M}kIHmspgpXa4Ln7TujN@r&)mMSjpcM?4n!V8iYs-lU{``dEp+9pWbCT$~ zjrY#JYrm)j_E#B&Uo04#$CBhv?`Pi56SMW=Ya;^NZ6CK5?(@ho#E%`_x@>M(gDB<&pG zNzYI`>%*ya;lCEequc>~rs|gwTisj8PS*^;2M7Dho*S=GL?z6wgGO~a{AL|yXvn}u zC<*U^YR;TU@Siq{{Ysa*JF!m=yAmxl1VxDrnUu0 z?~W=4Y_)E*9mm!G04DD1z`DJignQ(=yR}Biz}miJpKhwPoH!Lz#WCZ;`e&r~*8rdQ z5-!%c5DpKWc^Y8;CbeyR9d_9>Y8pgbpPEfVFh4xk4;{LP zQcf|?TGF+PE9=HHURBPE9eQ{|7$c45@jip|xZJ6BT!1;~pwy3N;rJLuHnt}$NIzzQ zpYqNt0WE;?!;YYw{$Jx-wpP(C%yBe3=tPO zJ3v1-2jw4~c6xMe4U93d%OWUmt}D#n%hbGAZ)GarqepH(+49#cewkBIP4N%JGRC6L zXsr)YQYCNw2pZ8(m1<_=ccJWY{KRou8hjsUyx0gB89dj3OXI&482){7RmXISG$-;= zP4MT6wJ!{Kf-P#&;(MlJi-_(eG8yB}N@cURr%_QUT@6OtpHID)?n0wy6v?b&zfhWj z66!FsCkzLtq5lBu)^CKoX{30^O^WAFm0-A#eAaU~60SP&o<|3tPfF;3!Q^7O+D~&$ zjxK#WP|=iJ%jJ|sc6+E>_h_2IOGfwyP-8TR{q#Vk5G+dj!68bKsX~g`sY3S zcCPrxf*B4CW!~tv*KE!|(dA~`&VwO|>y`ZZ80+4$lsgopc`mdZUe)5G{{R(+vOnqmfBhKMz}rV{r%nBtqLD0VA^z04 zkaDr@X4$j#L9oX0jG(zFR}SH z(p-6axmC_Nr_XhA$OxKM9+|6pSeEiB5_z3faB`;^sJ5jSJS z*PnXchg{LvF_%=gi*7pP=kgWLLuqXt!9`umB9PhVI2jd-s@p{z;6^xX)m_C|5z3_X zJqtoMligj59YWsXDI7>jGXkWH5J3aeHPH(zZy~(<&zKDDjy7-Cit`@`-ovEdO4m*0 z#VlFfw4QQ32cfS;vevY@)BPTED`y*4CeQMurS9quI+vk}DE@7YE_nnn6l#-01)AIq zK3OD%gDQ!!{SU241;I$w653fZIQc;QIj7FIQ^fFpXS#0(=8{wxJ$h$9g+rPeiGyw9 zojvxhr>EU%>c;`MtfP*<-S6#A{{V!p(qPhQ+D+xs#&-~3%MK54aDBf&YRb9rrPb`t zw-0R?jgHW>p*;Hon(OpuvePt_v{`J6TOy+sSNV@}-!FU`g;DioI3t)p5-uggb{-$M zwa)@crD;#}70URQ*sqE1ibWi2AV~tmp;wg|z#Lb2`UZ;LWyRLAkvkH>E$rR<^!c`m z<~6vj?zQ6_GC4(o6c$hkILGvk<7csPL|xE}!D)x8V&p*n#xPBk&66}sES(u;tWJPH= z!re~M1e&zbY4C&0mkx-aeM^?ciAK+9bDmE==EflrAG4`?2bJXQ8Xwb&rR1bE?|vdf$^h&A-`-rJS#~I46+2 z^r>|sw-ea&yM<+jG20a`i>SVhtXk?2#~iP0`_&~~%1#LWwbsv~_)%j20Fjwk0mkbI z^Z0zV)mZ!smQ_h^FB&yq7$ZVMejuJchmlL#QL4;%f04$hBpn3s< ze_D|E;_h8aE31oSmN>p>;$Wu_{o+dUM>x++*KZHOm?KaP_A%H(G5-LeRh0NgWV}gy zSbIVSKk?&J%|;}?c^q8d6!mn7$7Kv~F&q?8*Vh0Fz`OBIzj_^Bc{aZV7lHo()~`a> zJQ?BN3|g74E+&!jy}o41j&a5_$pjAE9G)wP)x1}sXjZ~WEg{q=nZI=kZ(Xb3aXWL5 zUgx)5Wa`s;C38gvkzM><;z4GyJ?zU0UT397Mb?jre${go)Z{|>np~22^*wznI`6}J#AfN{vz`c+MvysOp+F?=-Ozg0kBPij z;tdy0f=y3FOEY?mBUx@Yvhm$;FmOTk@6B=$d`8wIVI{7arN&$MgipBrPX7R{Xs1!> zVC9N?o3Lm)wakc*eKBc3G5M1b<^l=%NjPqV@!FdH3%gC`X|2Ii^D54c+4?CbHIFyM zEqZQV3mBMmbc-Z^-$d4B?~QfI(2J|d3}>J~5Ds|8&?vo7w0a#U{3Di#&m6jhNhlc# zM{JRjG7nLYtx5ffU?Yu^>0}If$SMfuJ5F#;0rvGGxHGEV-O2Kaq-=KFPCv=3v1tAv zn=(P6>TSk%Ev%o<6`S_E^O4H?o%M%@blb>UXocHG2^+*wU}NhjrrvmeNw-qbY8EHt z1SIpUP8%m6fLU>jbDv&4d3`_O{{V?^nUD50++!I6TtuhwVg+a)h8`s(5A2W!a&DsI z{{SAVyqfrnyjMe}x6}L|Z4*1|7IzXaAW3+Ny*gn@C-eNPJ}(t$wsFcW+fRthhB-jB zo%lUREx5Pyl}uRxSPt z!yM?>8uZSJa?2gCLV4^<9DYWv_?tw34rx|4{vD3$wxWHK|s5D}bkyPJ{i$^1=yAWlj7v(FWcPH6QXQnJ}vr_1(e_8toC7$dl^ z9oBT+Bf{6$dS<(#TwdC%8Lh74yOP*T8QYZs6qaQ#jAtj4j0*OX*S%u+i$$}$wvy^t zb11M%%*I zw-#b}u5cYePyh^a0r`2y=il3t*hk^rA|hRM%P{PBZu>gqpROwRkOKAV?N=HK{L<9t zlp}o(FH_Q5*F(3u-r82J5DybV#5)|2SqN<7?;P`wyPkQurs}Zk_J3?!7~jM?Sr-p# zk$}aM1Y9NtHl8wrIO~p;Z^U7Ik!`EG!=pFMFH#cnSxw0dRC37K3Rl+$Adj1n(`|2b ze;??A{wK23A-{qdq7sMRrIhD-@Kuq(#(%=QArzI7O2>S|X&`fhN;wqX#)TwT(HsMX zdH(>!2FHmY8T*#1G3m=!f7sWUc*@|<;%khP`>+rXpr;+ij7b}DBvd)%(zD@kDlj|N zr4na~x2ag@_j*o~2C=P;Ft43(srG3mG6yQT8+ae;yVWt$toX*=2BVq+9|&8(41OlPnV9jjNnkP4g3=G=Rt>j?Eu+Y| z)TRLNJd}?k{`xqo7k_2j3{XxaW$T6gb5iU^WdvuQ;=Ie97B*wK&Y_H5X z^ckeL2eG9Vr3L%mYId4ZTg$%bM8ZdREww;6Cj&lV=s2uD_(%2Q0yG*m<3)f3f)>I3 zD)Oz)nczF7ktMa4CRCA0R?9qNkEj*MUTQa&2W0oxQmXKG%*XkfskE$2dYY2yH}=fO zP(-v&xw(~7BiIv@^ck%ft!yUJZojgpYxIsYy5K2XaDRmIzmHnuBaIGZIdPsz{#9#7 z*7Y9^YLZ^*ixiPM6u7pXcSUfY-DUp(J!&u5s~vWeB(|~IU0BT}yy+U0mL}T3>TdvArjcV*%TEaB8q zG|gV(1(?{GJirzCOgI5aDpj%6ZpUL#(?zDFu8vFMQta_1xF7TAzxo@|Pxzh+_@3WC z^X9+$8_`*oaNa9#_^h>``u_l*{{Tica9Y@V71l1BXh%eT4=fCA2p@rbpJFSz@mpiY zTG#!AC;tG^ja-JgXp^*8S8^)ZTg2w#GH_)XMpYm1Bo*qfg&h4%yF19|Te)Y2V=}mz zcCQV%1Db*0k8?>O-tFtoD;Dcpy1Tl0l&ok^?$K0yi`afucHCSTft8rEdk!ib%26el z4lxQhAH*q<`LU@H+rYW}Gga>IOlM?77Vb}Ks4s2@@&5qhqx>r;QCzDVDJ|ESrIOqL zc_4E_wa6}7D=B&TOp*QH(y@*8(*nL{9>5A=l1Dj_%O6%G()NL5ZAO}eYOI>1vFsgD z*lixwuch6!+&eXY5zgN^8%UYS9=Qrf>sWAHh@)RAtrG+9Ob9vr4OogvrI0&Zd87M~ z!bl&91pc**=GxGuq1X*K!;ch6KCdY&kO+-|Y@Fwm_o-#k^ou_&Mr zGb7qfa^<$B8>sJ`_vyt;Z{n>O6_WGAmhfAaCnDh;+a31p8SCp<_dXZZbr^#U8sQsg z0!xXM5%_K1B(ei+rX{{XhwT0;^nhB79A zDOMf1>%j+%^{q3Y=$A8j$4s(mareH?gpuxXUPSt4v!QBJYBsiJ;u~m-UQST7CJ-`L z1YjJD=dT@cUY+3EO;Xpx_R;FHGO%AW%PF+wiDC~NV>keGsCP>DElEqEt8b%e_Ob_p z#t5B%jUx(wF;iTH!l*^d9CWKaxu{)t+#&wx%_Q4*V9pETUxU0!;yr6llSR{(=T5e@ zVY|`7bbWd508i%#_|q%13uk)el_M=w~zc?r(KlNt+iXL)?nD0 zCXzVU1YjbbdXK&7S!*V0trR!KelL>V-%wego9!_Z6iCgrQNso0djW!R#(lC)a27ru z)OGn~p&i?>xjbk#HXDm^ie7V3Q*A>$aN^0waj%A9_cn4b_dg9=G- zUequItjvLiMtTN0`V9JYr^n*!Tc~B4*e{X@@}zCUc*i*e40rB(XB{YV?oTT&R$-YD4|lYj{PJJQxmVW_jV*R|Vy7W(*F#d>e8)pHE47TtOh zH=y&m>TMXGV3vkBVw!-9e^O=rhGAN;6kXe5mz1 zzZ&Uwmv+|IG2KHw!zfhp!+r0&_etxKio(3{GNt76&Po`iatx6W3ZcLX4sn&ndSsK^ zkEt=v1^)*p_6PU?e|v%D*Vh@1`h+!kOAqAE7+7{ z93GwP%{~`sE2ob$hG+)IZa^)J9DXDJ03EMQQV&r@Pm0KB4PyA0ShCaX{HvKl$uIi2 z`?>TTvyunnTSmP4{{X>KT-_$4so#}Y&V9$=7=SGux4oSeVX6L zXK`(H43bJ?LcunkcsbqQBezW=Pkba`8>V6CGybhNV z>l)O~%mH|%v`~W_yL^Lzf$Dy|(=@+?o)nhkUg=tnsXxq1G?z%(ZVxy>M_m3?+nugv zqG;P|c3Sq4EzXkh+(8qFZsVOBau;30D9S!Ury1lD7z~UP!uWO+m&Ddy9MzISEGBFH zBK{R6ibe~)yD|R&mU&XZ4u>Q7xaj<61;2)TM`v~6yGC1sZuXadY2N8|0dJWZPbUNe zxk&4ro+`z?_MRis^?fSR^6J`CEwb!iHfwfhWL8;EJ3{0+=kDP2IIg-nrF3U2#g;** zp~$E~rv|{yeF?-#oCBKjU1_&#mxTA3vHt*l8ug9eCQqe#1>Bxx{LX)giT!DzqLZ9{ z6waJtrI2Ex>r_zW8OR-LzVJQGtiK+-Ic_ba7f=R@NsHx3TM3tLKQGF-ix`ahjkG!9 zNs&5wuocyOKP>+Mw561U5Ur@*?Hzy?(}DU5;Ks|{NYfFyg}iu63X*Q zE@is4ky|z%u7ODX&vHM5uiW7{#PJ-ETZfB5(IY4LzRXyU#Idid$jHI3ojxx7CYQtB zZ-_i44s>!$-dLdj0FN(MLH__ey+`nMA1B=NBQA#aILZ85syi7X`z5(!$%fe!({1(r zZfnU}O;+H=9lWizWMBdE$Oi-82B<;deOaxdX`)MAz@PMq1bzMMO54NoN2gyr`nHm# zk~oz8u}D%}b;nKt6{<{4px<$SqDYrlWgqzuJo%$k<07aYGJ>G z%5nK6YU&m?mez1Xd#S+0Jdz_@W!2XTqZ|+Jn#-B|IU66d+v-;`6M|)AjZfv1RV2EJ zc@4E~8%QkEU4LrHoRo=5!biUF3H$|L*7TOW@YH(tkb-?YlC#E(hqrEi^7AAdW#EqP;&r_=}@!7LnR~MOU}f5+Mz)y9^#BOHd;HDQ4j!y168uMvvq!xE+sIS>>tmMO6 z%nCko6^0Kv2dMhg=)s=TtLT@SByq`i<;!V02_UZ%Rs>dDu2NqZYp)r|8lBP~s>;Cs04m|NIU-pLa39*eC!`E|mNdE1<8+SR zIE;81MFT(Q6;oE#UvpbP{{T1fu@}j2Rzj8KjZ-Z3B#P#Z4TZUmyX;JX9iwq(M2^xQ^s-DtN8g+vXpoR%zT|a=?&C zBc*Fw-&-<_w$sPUf^k-w25pOwyjRrJMl(P|!X$bW9Nz#UQ$-B@#g zc>e$#)~=1IN@R$648{IzdA$esx^h2CiOvz-lV*0&%<)DS7*IF^wO-M#_UcIg05KUI z1!LLCE!E736`fE6za#_3c;M&gaZ&0Th5nRdySFe)Z@UhLHVmG`=k>*L{cen<$eyM9 zIVE$|QbQ_aAp`4BO{iO2&X%&=!5s1cQYMfFU`_@HQ_mIVx4t^LlR`k(GC*CFGsE)d z87B<9jzahETqd`1cO#|jlE~BCFvZa%nLb=#w|)TQ(wc4b3m-viW_dKtD@lSxL8)p8 z*CCES(bFvd0GLp}@H*-pvUd)Kyc5Fm>pIr0XARq2Y7)mEluNO52rbKc3=C)WHSX57 z(ArwZZw5qhj19*mn#!zf&WLPE4pijQTCbTibN7e>mA0xLIRd4yU91Tn^$|eH@3lB= z?jg4+B-2dTSm9m7d!9xI6)26R&zMHun^2s7d}sXisrPOlKLh#FZuIG0CL-gE4h1x} z4^P&RzoDiU_pIeBXf&=lUAf2u@vPll+S)d|iV1EAP=+{{aqGdyQaR_^ukQA$nuY8( zv2B!{&HM`3Vmb8WeQP~gXNqf9OCtIA5(zGyxpGty$KE5RH~?T*AFJ!Px*h0(-%x?s zmn6iBMhN5P$3KO3emv9WveW0gw=$reJf&cM>tNt#*8;KpAq#33f-ewh_7kiTpjmFL z!${kBRopu8JLk1k2+cupeC37m6fE z8b#2MPGp(ox$;X&4_pk601c8oap)`2ZuHB0ix!9MknJc@BUpkWgV-qGb^6zm$7SLj z7sXdL_V!m_WtLNz;kYp?s4cVxPe8+tymrlJPYwImQvU!UITZXm;Z0v%yAoSz*V3Xm z^Bl(HW2sW!;QH5FKZmTXtrpqu;nUU2D*%QL? z=3GgF2?2@@UMjR zWDYfLA`Lzj&o6MZNXG!=BJNPRN4C=>2uUO6 zUGlEc(~tlab6JyG(ql8j;N3#z+_+X>J|-*QJ7O}BI5}c4JN2h2LHY&R<~k;=7OSf@ zzlg0DS&HeC%^qV!sBi}T$^l$p@zbAb^lPsLcsBDymK`5X)AWXvs!OQLsLLusrH1|- z;F7z5>B$%%*F9(B9}6=)(fA_V%6MjvQA}t40|=(y`0`7;Ike=_w2ON=!BCP3UDwkD zNTVZ<;qB71l;E_2u{`M?L3yomzIqU2la+9C2tJtL)Dm0AF6{957;bZs&u*jJy?p0m zscU`|vWELZzr3}Droti?Fi6CALzHefo;uQxy|Gt4r&zJDxY93U@eD@ePKp+qWMu?w3P~z@f(Cg65nL~W!+3_$-%zu( zk!>{zPnZif;F;QYZQyt3jN?34m+GE1@kXa-Db;*Obt+F2#Uv=gINexnBVqtK9CYtX z@WOf9$C@pi7nd-?*9GK_WMonmN#th)aYJ21rK$BDv@zRSLv3uEA%z5SC?xGrFa}Lb z2^2GKJYbLKO(%-P*l}ztG3cWvyuVZUyP)cNRn4WfrmT-FWJNZ`jYEG4BuTq&agl?O zkU<T?k(tb!!^skw0bp2CM(x$r7>{{(@f%CSyub0Mhaz|m?G;4hf zs!6Sm{>JVnnmFaeVS>pfTdL!6Z1))FHLs=Wt2U+fn<-2(GJ>3pjHt*ecsS#zuPD>M zw4Om{r={J*z%#ry$j(Ma80}o~jt{j}@e~^9MNMW4+go{LI~IFqi_Bry83Q=ukEM0S zYn7&qQ$332b-!lt_3!VcC}*{}nolg5Njsw_AYqS85r!aRoDNIE8i$qQtz|94*)8q7 zX!eaRFk?7xllYt8f(Gsg$*hkL>b7mAM5ka|Uy?{Aa{EaD79B`ajAMX0_O7jT5ABUb zwVg@lx4F~j0(?ND?PP-JOZFgOHyLFLcrB6DMOsONcZ)WhV15*U@z149-~v~2u?GaJ z0zWauM!*i8Yuh;p?pw>Xk-ZR_@%MexG4(a-y3B?>CTw*pit_0r+bQCiQ6Q7<{xr-~ zt+Wn#9VwX|2lArj7qkKgi8SV6l}nU%=Nu^n{{SlA_+8?CS6cYZ;pi{!jF$fZYPyvo z^3`^qvd@l#(3-;0$NFT<3Wko#<&c&OhVol!$>4L2YKMX~89WW+O)JC~t!HvA8dVnY zU&O?-+sKMosXJG544e`Ma0$RZZZWpfHl}@-KBr-8s9M-u-rK`@dAsb^@=B{D+eTYr zla|2bp|4C?Ox{Q*-*&#(8Oc;lrR9iicbtXWAd+_uY6B+f8&Jl zexu^sd39@fR(KIDrt;Te%EG*SsmWgd0CRD5bWlfD+{YthUQ43 z-oaRIgs{lQ7_t-BB}Z!W`E2zyJg>$#z7^DbNN;=-VSlGtTxI37yN)DFc|Ylv$s6Q6 z{J0xWP6!JeQT?C8@aOK{T=VWDAL8GoR1N+!NnpL`J zaz5pek~h6<#kqh7fzEN7)+mE+C+zrbil4 zR=A1_TT!rt`Jq?F20MzWCaK@qlzcqVXH zar7DMS{@hiDADiHR(6JDBV^bd5PA{m_4KSWs^8k*MSmT{lE{sclR0qs>_I-2(BF7^ z!^IFutavZxxKZX_Xl?$s1;;FepWY5L@{Ti5>^ofUuLZx2t>v=Qr;f*0LlnCueUaZW zU{99gqZ}SRPAiz#bx6ELsY~I%i5fno2BByByA56#OHBkzfOp68`N@?hc1h&*u2W0a zu57Oo-bZ$Y90IMwLxYj;!*lJ5^vHZcrfXJd7mIgXLaVahT8tLBumpY9+BZm~81NU)|kxGCarG!ttErYeZ)zO1GhXMQT44$b=;9ijL9O9 z%F1v-9WhpP8+}9JZ-cLHbqNQF^gHcBJ4+jQZ!rXsy0K}2UE2@Kw;XcZ*0j1ko}uSl z_&(?D@WMZTXOZXHp5c=@Ba!m~j%!FuxfNpC(5CwR_lPepWYt+@xV4a5nL>bM8&$y| z05kLB=miy0$zu~<7|7hyg5%M=v>(U{D>-kWac!k@oAK1CXX8&0s^D(bE}I9`%EbQw zI`iA^ zCZ1xEmwTM=Bk}h%C{74zLP@?}zCw1C*@w>c+~*8|_Rd;b82ejjMQ8?%ZwvxfTS zIaXA-yoDX&WdH#mA0QaW$2laEn({A${w>h_H7(?xA=JLgonVB+B$<8&@0CdDp82mp ze~%suj`+gkRFydY07;J2d4G{$+<&{;xMg{CG*&xgw3Nd&tg=UQf&mgK8-{W+dC%qA zpwx6o^=}T|=$8=r7L&yBD=G$9ne+R^QP74vvw_IXb2^8{p90z2wcVZd&Zjc~qT1fp zL~QedT0p7?t_eLjHRgJ+#l3%BxiiT+>DCdk31@1>ccDB7Y~|Y+&q3D!R5-P*wH?vV zYH~@XEzXH>zH?d5*78cd35|#?kM_FPU*J};lEy17W*b}B7UwqJa+WIWpaHb5G4Gn< zU&KxJndVz7DNM4og{4>Aa&yiY4xCp>;H`3fXT)m(vayOQXj*4zmG^&i09lWAAC+~t z%@r59o$Pzxg?t~RXc}|m-5ve~)dPb|sQS<_Z8+!GpWYV$|VVY@f-RNe( z_o&Nr%}k|WO5=?sASSc*t#02$v)?uv=0zsn9Dl4M*U$`%`*f@yc50RML$$4H*Fv-t zU6wBS^5aFxd}BV`WOX9A1LG)eBWt_3KG0f27-4*lF1DeEZb@00q1jnm&amh&5{=9sTctU+TJFDG6^tKK2 z!E+NcgYB>|BmA6J2CMP=!q#!jx>bgwsmh<~+^WM1@z*R%kNe_{%eoih?v3HiJHjul z$!BeEtx0mC+2D;(-N?_E^H&5&HiAy@eKYfO!|Hz$ZNK3SO(#sy?Ce_NPxPINrX|M1 zxl?cPHsQDUKpdR$mE*sNy6+ZN+eSaXA>;H7UV-sj!q%fqm&K9W{{W?1qQ!Q~Gv^^8Rfz7( zz|Z${=qbMfkjB8Rz$5iOBx|wv?wg*v&6|^w7R`So}v?VSOvK4G+AP{>F z^)HJ&SAF8!Yj`y)Ya4X8kh&X4nGYibe9Yg5Q| z)q;Z~nC|3d%8};<+S%`u>B+9*F|Rkn`Rujp7Sr_$D8!P8!1Cu^@syK#l8j1%gaSy} z&N2YRz0mJ2ylVG1meIu&_QZ)Y&k&d8V~lMl2XMm$&nF(e)c5k->2cdZBM5FZxh+4-qZmOhc(y__uI*Q4ZVb33hYBK_OuRDuUHkXL|zFgqqyIVVzxVMf} zISit`_)6y_m4<6froq*}ioDlQLmbb8$Gv+G_DzM&p8alF;fV692?4R{au2r^WBwH% zhjk3e9p}RP4nI6rZQsJZeW56thMREM&cYrh>5v9N1fHCgqw6%DmmegLF!J_z zYh9S|W3&sO_uW_d6I?V_@sabkIOC4B>$lzt)^z<7QPcIE3sh&jmJ$}p7F?$Cq_;v9q3X0{;Mr_$|7Fxh#8M5M8N?Hm)hk_pZ;#wy$ztoF#FKMd&Pw<_|&>`(pmCOzsqj}Yn! zAb9lsBHh%1h^%66pHM|}7G$%dun_WntERVxYn^jVkH~F_4X`*I45)AGSyuif*5$m7 zS5cnW$skkqVj?`B_Hka>;a?wkX6D3cUNh5RgUnG9-zK6n&OjP|i?Z-;AZm#t0O5ak`PnB_Q>gxQ3 zBpl%SgWPwnhg8umyk|6*-VKMy)e#Jr+DwH|1p|hQ*QX<{SWw133w=N0JdD;)7MtS$ z2}?9hunaZz6QKJL{d@yEg~UiF#=Ci=zX z+cm!5nS*jX#NZrYgP#2=mZ9M}ybJKxSYH#}LT>d*qK{67+=-H1j;<~g_60YnZn$zW z&MTYI^{qok)F8gn?&X4bPD87Zz+_|}Rp4>bgs!w3({s=?FBFd$+D)rImu;rqG~Qjx zTI5G0imUU5KX)s%V<(VLdMfp{zhmNP&ZlLk!(lXsZRAiONX)~H$~$E?b?=|86%TMZ z{ZB*F^)HAXF1gg&8+%J#QtCdeZ;R4Lqg zKDekEg=OJu>%RynL@$UBR^2qU=U^1W3)y3F`tZC@lCETdj>7^Y?+T0eB+&dwYgNzZ$ z!Nx%5q&60>;cNSe;gTEicNm7;9g7OLEHK2g0m$_j6<0{M)F63AovQh3Ds7M+HxEwu z?_RI)*TSR7lf*iShUZav3^30x%q^pd6qz!5Hy~#j8+hc?ji)h~7z_jfY7M&xj@3}Au&_U?X_+g{m?R^6<%miu+9k2RWi zEf9>4^@_)pK7@1IuNA$c+FNM)9j==Ufnu>yXsofb84PLxViX>{9(`!57Y4oS+=_DM zG+35yIj4cQ>rq7_NRqTn&ang}#}m0bv&PUeF^+hpNkho!qEC`PFy`Js#Ah5P-N*11 ziK#Fdpz%-}r4j^P`?j-T;dt@2N&X-`C|S4cM7u&!m>QEs4N31I4O`w&!$H>_pI#AE{YoFr6!G}NqH8Zd4D(E ziW^IInTufHki6~VlUx`4BmO4Wl{){3D5m9$QbuM>swFJwFY=#wa~RVtyVuT%WXbn*n6Gss&S4u$>zOyUEM4E*GlWu ze&`I-hNm)ot>v=}=OBv3(T%Nf`(18$)}!G$#i_Rb%Dt0Kwq^&}0k?3(4@My1`&YD^yOFrFl^Npz59eI>ihdwk_(I)H z^pa0?Da3ZLsA&fr794F{r#R_?yfE25KSYn4#&-pYh<=^K^e)%CZC_=?%!hTavkvjPpN3=5rz7y-MfM2DXiMm5JtOEfQQ@U0A6!&9Uhco0606LuVe=dMt+j@;;rVVnHE%SxkR!`;YjWx& zL|lBqM-V!RCWP zPD75_9@#wm)l!sVtjcmvp@RvIVh}MxPb8i{I`_|nGHd!ij~0_WJ1nlQeA{2O#_Hip z<(W?aqi{!2oz>;u4e%m(hs9ccl=teXJeiko4Y5IH+Iji5smB=3Ghac+q(`85n%@lO z+64(|1W~iNjUvE7$tMZ`&r)zb>qpBcbW}~9M_JPJ-B7`QbseOBSDEHWc+Tu#pL~pc z4P$Cw5qu-0+1y>Ovu}RUsUq6Z_sJu61GYWujrhqPqGK27X(>WL;C<9PvAfff2h{bi zA<*sGNZKW~+QnIG&50#B5!l0fNS zMEpGsqWDinOLX~K(l(U<<%npthyqJG6=uF^6pGr#Z^DPBH$@MQ40H@iX|BOR$<%Q9KIJ zvW7cU`Rd!bCnp7Z_1b+a$@N)$N8*W_P}gr}l_J22Wcd@GKt%up`F=esy71+})AT!* zmM4zlONm!vf?9bEzWfaHlm7tf&0Jlja+A5n%?nGa&1Gt=@fo&q8_0ysG+@&wnnrjMzeJl$KytZ*4(-}A`49FEz?KuGD@ zpt11{!CkIcfN=24m|^uDMQo}+w29^He8xOEf2V74{{U#Gknl*X&`ymTkT7`!ai8m2 z&YR;XM&XQPiuzLG<4D$Re#xoYM$tLtCs872*Pe%-wa4rK00p#tP9ZmkE>4>#%udp0 ziO+0;*4ehO_}As7x6!cJQH%$Xjg;m?%Sobm3PGbdvzUq5njKh_?y9>7%gJc zHQRr(YOsybsgufllzZGZ;lVUYUhwsnrt(pn^%rG>c$3GL#{@h%BrGAf1IIr+y< z?KLeX;iA;+{&bc$`GXFCk6tT#z`q-Hj|@hdez^nc+G?C6szS{Qlah0fpBXp=kF9z= z&xQOk@daPR9s|`atTkB(dy<395)5D@v2OVZAbi6IuTp7AwuX4$lc)IpcCyr!bdMUj z+i!APWv-@hFs=ysBp_gIz$AgzxXo6=_fDF9H(IrOOUrh_j%6y!LB@IN4m$U*P4S0< zH8>gUyhEoLvVV7|TdO_0vBog?9=?w34I_ zdFHuq5qMB(@I|cnR%tbV4o(Kkv|Z0`_{ol7KI0C!J&5(IzZdO)v;0e@+S=*T+iA8s zWL9>!P0V+pS)9s^k~Wg(-?{5t--f(NsCZXWd+i~WmU#TDt7#N8cQBGSM!@vW0LbKa zHKcEApl5O5S6MVUod!2twtddkqO`OttqS_iTfYm%acyZdrJmB`mbQ~<1vg~w90D7T z8>bXhN!@|wzCTkh#V-^BcpAmtPoVRjsary}_Tu{CGJx%dKF)u@R=15Un&aZ9iD8fL z&8}S_{{X-3{(lP1)*F7NEUm}xt&fo!`}8O3O;co&X*zYzyL{W2h0bJ@_WuCu*IM^> zJ|Bnd+I%YWe-ZchKhmL4x)zF-@PDsy%X{}Vui@{9)A)l#OX%-oisosLmkW?f#t01f z2XVt3a1B7tZe33L?T?u|DE{glqPH8ux`cLLY=Z77;#)+!m4u~sD;5BAf=*W)cOtac z;q~Q&XM`slLeZ1$1IQY%0ds z1Yn-{1kl+SJ z$@MkccxS>Ihluqkn8DIcuTL2ew0Nlp|Cm-Qgn&vfJvkY|H4n=fRrm4or*((ssZ!D3>j+U;H zgbx`<3-aWH!(^ULNhYhEF-mPV)@5=2tfQ6BuinT%ja>U&82ew_zX=+)K6To9vF%bKTu0@F7SH8`+Rl%Yw;M^rV4eqRd733s=0plP zB)3Y$`(?(XvU%ETD+hIW0u7SLpdMr-je&_$5MhSVzwb0+F4*0W=x=4ang!B4yXdw$ zNp{Pa1a1rDoPi)L!|ognrz8=BAd$q9eWpk*R$08~I~l%xyL;dPj@5NjPmK}n8W`3P zBUTc|6$fPlkiNhH_*637Nj#~xV<8+CWcgd4R3`_eRm_~5GQZ&;aVFHcXpD#E4G9~) z03Vf0Z=tLa#uf5ooJ*bwAaov|m24!CBmrP5nFDwXNc@<3(uY@JhR-<4_T&8VTKieG zt25<5j^&qb)n^RfFeCySAFVm9=_@^i6zgkl3}qhhw&m@=zDf zoUo1nz~S(yLmocs5DrJuxg9Ivw8r@^^_j)x$DFNj^P@A|;{`$9G6y)@j)RV)9M+ij z&t{gE0kr#AWb+S@K>5Zw9Ps2Hz0NDEhgndpmbz>)Mxe;sRB#E&W7u+eKBl$haoDX9 z+({M0u4ms=ExYMmMjIwz@cd!DYT~h7w zv6WT7i+(CO7;_`CYdEhXlg@=Fj4K%uXoD#OuLNM$Z~P)Y9lM2Mi^AGbj&;Cj?IVbu z4shz65rfDh99JaQGu^h~(!Wh8XYy%If>)= zYv86>_UIWdGOPWka!KTWwf@kiFT+0vE6k@ro@P=DMz?d4pp5bJsQ`P|Nu%fsWwqyf ze>b<65~&C4&0d}uiz@kpApD>*{{V$&%Ny)FBaSvf5I^v5g3!5O5wl<*tQSS zu0`N|0uB?x`aa#*25Wub_TZ3xYi*j|6x>!vWAiA>WcK48{8oJT@WF7!qJ>x=xia-0 zy!G!*M*Rj+m%(}z@X5QwI!?&fd-+y~oDsnU0DqT1on?=Nz8ttQNfw0(4%uaE`-s3y zWRZh{azMc2uQ}qn1-$!wZ6&Beh;n?T!m0Jo(x8&s?sRpuhBtEHNh`O=fd2q{Y01Fn zXgT*82CI@H4J*Pn9vFi1=ffIY5Zz9z408$OkhcM`^W=}igMpuIZ51bo$#Hx`PyVh? zyhtFna858d9AJCrjB;Kmx{f#g%Cd;x>ep&xc|vXSSNoB#@G0rn7|A5^YTtyk-ETth z<=hvLY1R!ijOOOzuYFm`f5 zValElaBCvh;l-84nC{v_2;JH?4Ls{6M^S)sbB;Tjt!-te*j^i5Dq*bM%m^|xKt#FY z0SHl6Vzy;6;o`-cu5L9@+P*QKx&NB(C*5ufzWU25zF(jmECfqQrLFM+~e% zkOFeV0l>f`AcLQ%r|aGb)ivl8=+Q$0!#TIO7ZJQ(W8?)Z@_fLP_lFhgYvl}q<@D#L zN|B_um;o|DCI|6=YhrAVAielytR|%s$u*!yk+uev@sL0x8+}jXTK*pJP0pRGTa8dz z&2J2m%8<&kyDX#S+&2Nv$v_113J#;EU8s0d!@8SWvf0ODacT#VJ&OolATiT#9R>zL zz$X}@Zw|pTqQ|PpyEd|!5IZZ50|E#GA4<+iwwU%Xwcm!(>bjA>(C%i_H3u0J62>;b z;1Ed;2d3Y~p|SAih%GI|IhA6%YzsWtxqhCUwF<`)oWPQ2Z{F07eSML$vfbJn?CLqYLZhHaF#{wOfDzR0WE##z`%XFg=cQTt1iLEhkmD`#dgSzKmu|JE;7*Q}8?r+F>T81!SCx+LknEmt;9(ekWSw|X9$bveMtHPLf2#?&>^4qP31(YAyJjX zE(dM7QJ=$)ddt_eD76+h2nD6$NT}Blsc$omgd7IrzH{3(M#D|C(dB`b@6VP&ors?+ z0y^{b>s=kJ){`kHBMgUW8*oQ|>syj%>DE@UStydyDW+VnnKWiFxi#33a!XR^)TQ0g2!f z+Pt?^@a^WG@jCld)2(*c>hYwr+cwd%Y+;uf%N_YUfFSScI?}e61J+AgT*KzT6~X(G zBad%SsQl}Y@khhm8(g=M?(}%>u9#(Hv;rCP$2*Auy7Xh)*07cXB)hGmXyoUJfl@ts zRl7|~RnzVPhW_bFbxBE)ese>T&79`q`!15t-y<7zJ7-jf-PPNGwGK>!#<&=NP=kwHtljy?id5ENXGuW25l3$BCuU z?zHb4MPaE!2vnWOk$lkP;|S3xVaVl42d7-tFN!)s8w{pGXmn@^GV`HXsn zW+#HAg1rdH9eJ^#cthcyi}rG+S>7&&`5B2g#~>&k_143v_-@Jqbdzk0jBSQ782(f_ zBr7xLOB>s*BTjuE#`<06vEdOW!j7lS(9-&q$Bwzf)czal_Lo9`2_?^p zbV=7X`i7ls(r48j7bO@T2sp2)p@AOY>l!4>9QYzwj(oYYKZp!-)8_tlsiXL!%T$!w zNLtfSj2|}AZ@j$rJs5Q4Q&P65Z(YxvJSU*)dIpMO)^z#w`L1PY(kq167wx8hg!@@=E4|TF?Igah`4dnXwC^edW>Lm*PDiMzhs!?F;GGkfhPv#7iI!0RfNjo_qcottrc%Hz`W$=5LAB1+-GH zRc)mEAO8SVarQF(o5V0M#ys^ufg}8DYf!#x%K{jWzA=i+vD2RGTZbToG9Vc4c&fIg zbUOb43wUzhRQQuFov2(jrG%`_B#Lm%Ht*V}wt8o^eGzYQV`XUtrIp33R@Uevia#`+ zsyYw7&*S|0uMM+hi{dl8qB=zxW>@>I`?106$7 z^2?2H!}95q!i{VuYndHO!y=uYYY;N4kTzo+`T{%E#_Jsq_ej|+WnzT!ikgm-Uq?d?!Lsci#4`enBH51154r0{ZZGn1TwUSK>! zph08gEcQQY@;1YpSsi1W5@p!K?R7s7ol4?Hni!-0(H9w#2X8hIq-{_X z;AbBxz@wG-9nV`$S`z@8JF8zYSLIn`XxVykmSdiSlh3_FWvNEVvTNvAf_QU}{Cy4& zPUD{S=0EV0>62J2YbBMn(YEhP9kLY~-uPh9y7l zu6Q2Q`FzOK_c5#(r4#+4+D|OuVBV~*4td?XI0M@iD&O0*J6hu1G62HdH%#ZV06KR3 zb6-A-=|AVApQ)w$e82P2{{Zi*Ief*b^f&gDJZ`(RZ%oK|JdBT<-0{=ep}*E_EcD6l zwF~IhC~+jdTNh?II0^yD<*|X9`R;vK+ehY0EB^qp100&^qSX8+tJ;X>of-7oeazA% zu_XD~xw4-#5OM%GJoF$_ zjpAFVa6`0+$PV4fR&DmV|BJ=7A;WMkBA zU_frb?ZD*o#b|5V?}zSE!}~5E`h1h!Q!o2 zOY7V8OK2s$+8<&v1=^)X&<=Vr>z+WZNPK6gtY$AR!~)F4{I=cm9Fda#=N^^K$>Ki? zG8p5#({}(znrvU^Z&PH*Z;1P;i1(~hlPZVmBXj4NQAfDz`0$9s_?L!tL9G-X`dH^d| zPSpHaZKjLscyyVrOl4XbZgA4@0AspMs(w+xz{w{Z*DDUI;p3@Y$uzbfXLe1XTFAwe zDGmaa!V+9CMN;a~p%uU=CQxujZK zEwagNIF37IX@15Dl!yKC49FXm?s4r{y8fij(fyX@*5$XzN7(I*0Z_Nf8zFZbdvWS& zltpvWwXYFgtiDa0FixId-d9vHsUv{E_4z^M6I`9AjMf0BFklg|t@lEOC|lpa$R$22Mv>@Ypp;<(F)3 z$ci(J*HNPC+A8VqX{yXk)$E%U%w@cQ2g}bma&mHc#s_-8FNi!gmyn1qH1~|iUBR(% zRXDkVUAG^xVVye zp>|N-JYV3N#m1QApORCAV7)Ow;fAm^!EmG3eOG z8*2Gbu6s&ri##bhPiuhL0J#Jlp4s;`D{Deo0}G2d&Pgf@W08z-zk}uSnIefzB(DC?&(PL38k&-dS@ta-zwLXP^9R20vqv5E#Ht~>F5w57u8cN(n^)xv%YK-uS_ZwM z#bzH?me3ZTKW8@X%^Kt!?<(2pfVt_MOpf68UE3- z85rhFexZT=Ysg~p28$NCaXhznqSV5KEViu5@?(`;NAisIZJ?gjq5l907lxV_Xl}If zR2`8uo8^YU0+!fu^KK;adUHy^dX2=3bq2|AG`1K39E`3GLHpfnp48^oEMfDsD~%rI zm*#bn;nkl3ar{^xa0~zkU#)rV?z5-Osc7QI$+=~Hw+jusD!y1_PGjM;QQcF-3yrf_VN|B%U2lOp?b@kx@y+jnsl`{e)%-ncWQgX-Tr5CF!qP`nlMT6;l_iwra1Kw>izF92l+~lS z(BrrU1-i49k)wCuf-%QA@7krC#0_tC0FFymhIqp(0)AHMwDZ8PI<(e2IyDJP$rMqG z_nlHm9lYpDU?}-W`@=g<0H%)->6bQsNS@N#;Vj}JSv2)1lJ7odLdJ4R9)luxKlHLT`HnnSVCOln4Z zE_fc*8tPIv{Iq}j=+Vj-JtM^4GVuq8Zk7XUZE+ias-D(XaUy^^^N@bL{Y7EF#l3hd zIngbglk;XK=k@lkQcJd#3P|kA-A3bB*Ku4#*@kv8p6=MetFjB8v*9gT+r~O=+uuhX zk*nL~#k#3TWsDB1xbWHIui;Pgf;SQ_LH_k%*v;X$i9mmwO}7Ev;F2+N36FE-K4u{9 zz&JlJ;{!ET+fvYNyh$0ing}$pZ};wDl4h1nf>eSSDeaxO13h@Gr3CgJ&b}={R{}zW z4{=tK^4xMIjdvb$Ym3&ky$a>D^QKR211#!gA7)~RxEqUnftYUXlac9K6L^EeOi>}b z)7J`Bq-{OU=iHlQz>IN#`BBF>=dDk(^BR%aA0K!xLzY`ht!$f!&dF9gc?jL#2W|+g zUl9CI@XYq{+-aBb%Xb5Up{=9^)4JrYKAhK{Y2GE#v|kbHM*7A*M&9w&VV$kxW{EO? zc#7+^HV7aU#~32Ayfdxong+3Tdv$KQlwj?G-fKvTOP2f28#_Q8?Ovw?a1}~67c)Dp zf5rMHvwoLaeC!j-3gE`r4U$M4biou?o}|%S+}+P@5QZ6U9pj7uHYqs+1C9q2QDI!z z)$WqhPTBPvh}aI~yAS38t|IwAv;0$Y2sshlG7KKsAW=nb{t{QjT#{D}8>19> z+bYU%LF18Kb?3z$Z&vU<--flax5+n`w6(8_~+y4O9 zbpHU*UbpYOeHGp2voh)Kqf*l&uux?mCeQ}s$2~fJv{771wJBSckHm_W%-hhwySVW_qWxpH!g{Xhlz$*aJ4<76 z;>|8uNp_m@HgZo>=FvqtH_7u7OPI=?6f}f?&q690O0CC|qvvHMN$4?-znv6TC69{T z7Hf54#LI&1+??b20ZFhJ8T*F-dU6T=luc!AH)oY6%9 zH)8#m$a9_e{V6VXTSsv#0#+`7bw4l^QA`X&{+V|ROiA-2W+T%Zx_{pym&u8IK9jO# z{?t&OhZ_OM=S3A`66s@Et`Keu5F1CQBAFUQ^T3#FNT8q0kLg7e2zQkq*pgm%G>oU{ z0RI3QntOQSn&nU&MEh4K-xN_m8n^HxO{R+{h%p=6*8*xf|);-XrhqG?I6j3vCip0KTaxpi+#5jVNL=_LV?@n#S~Hk z6A|+^?&D_f$8KsEwD|n62|1QbF&>Z9m)e}xoN0c1poow?#5!|Fi)02*vI z_*mJGE>3avqKZIYaEHP-m>+jhfq(KG)e1m2>|PW_xP5kK`O!rnE6j_wH8~~D3I70r zVzRFwREAvgREAURbDz{vMKlH2tdcvZ%I9f_t}~8tnqylkwTyWnNS{7CpD~B>6j4F~ z&75l1c_oQb2Pf+U263PJK7b1!&0T_ZW+~t1$bNSS9qO#|oy^g-diYNm@_Rba5 zFA*1N#>Z$KzHC)*vM27p+EP#Ef5M6=0tSQ#cX!>2g{%=8c8HO&K~bLh1NzZL0Brba zK=D?Nr;#M_me2e6{*{wu3#(qLE`P7RN`OvA(8FFZ%fFfw)c-5JH zZO5NXWBh4~k&CO}m+mG9{r0Q;jTBG=V75h&KypAp$DXGI)0GrJuZ~OY{4qro0Vq|> zqo0?j=TeAQ&I)=M_kKHbMHGOgd8bDnl??EFjrN9D `1.15.0`. -10. Commit these changes. -11. Make sure the repository is clean `git clean -d -x -f`. **This will delete all files not already in the repository.** -12. Run `npm install`. -13. Make sure `ThirdParty.json` is up to date by running `npm run build-third-party`. If there are any changes, verify and commit them. -14. Create the release zip `npm run make-zip`. -15. Run tests against the release `npm run test -- --failTaskOnError --release`. Test **in all browsers** with the `--browsers` flag (i.e. `--browsers Firefox,Chrome`). Alternatively, test with the browser Spec Runner by starting a local server (`npm start`) and browsing to http://localhost:8080/Specs/SpecRunner.html?built=true&release=true. -16. Unpack the release zip to the directory of your choice and start the server by running `npm install` and then `npm start` -17. Browse to http://localhost:8080 and confirm that the home page loads as expected and all links work. -18. Verify that the [documentation](http://localhost:8080/Build/Documentation/index.html) built correctly -19. Make sure [Hello World](http://localhost:8080/Apps/HelloWorld.html) loads. -20. Make sure [Cesium Viewer](http://localhost:8080/Apps/CesiumViewer/index.html) loads. -21. Run [Sandcastle](http://localhost:8080/Apps/Sandcastle/index.html) on the browser of your choice (or multiple browsers if you are up for it). Switch to the `All` tab and run through every demo to make sure they all work. Actually play with each of the buttons and sliders on each demo to ensure everything works as expected. -22. If any of the above steps fail, post a message to the `#cesiumjs` channel in Slack to figure out what needs to be fixed before we can release. **Do NOT proceed to the next step until issues are resolved.** -23. Push your commits to main +10. Update the version in `package.json` to match, e.g. `1.14.0` -> `1.15.0`. +11. Commit these changes. +12. Make sure the repository is clean `git clean -d -x -f`. **This will delete all files not already in the repository.** +13. Run `npm install`. +14. Make sure `ThirdParty.json` is up to date by running `npm run build-third-party`. If there are any changes, verify and commit them. +15. Create the release zip `npm run make-zip`. +16. Run tests against the release `npm run test -- --failTaskOnError --release`. Test **in all browsers** with the `--browsers` flag (i.e. `--browsers Firefox,Chrome`). Alternatively, test with the browser Spec Runner by starting a local server (`npm start`) and browsing to http://localhost:8080/Specs/SpecRunner.html?built=true&release=true. +17. Unpack the release zip to the directory of your choice and start the server by running `npm install` and then `npm start` +18. Browse to http://localhost:8080 and confirm that the home page loads as expected and all links work. +19. Verify that the [documentation](http://localhost:8080/Build/Documentation/index.html) built correctly +20. Make sure [Hello World](http://localhost:8080/Apps/HelloWorld.html) loads. +21. Make sure [Cesium Viewer](http://localhost:8080/Apps/CesiumViewer/index.html) loads. +22. Run [Sandcastle](http://localhost:8080/Apps/Sandcastle/index.html) on the browser of your choice (or multiple browsers if you are up for it). Switch to the `All` tab and run through every demo to make sure they all work. Actually play with each of the buttons and sliders on each demo to ensure everything works as expected. +23. If any of the above steps fail, post a message to the `#cesiumjs` channel in Slack to figure out what needs to be fixed before we can release. **Do NOT proceed to the next step until issues are resolved.** +24. Push your commits to main - `git push` -24. Create and push a [tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging), e.g., +25. Create and push a [tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging), e.g., - `git tag -a 1.1 -m "1.1 release"` - `git push origin 1.1` (this assumes origin is the primary cesium repository, do not use `git push --tags` as it pushes all tags from all remotes you have on your system.) -25. Publish the release zip file to GitHub +26. Publish the release zip file to GitHub - https://github.com/CesiumGS/cesium/releases/new - Select the tag you use pushed - Enter 'CesiumJS 1.xx' for the title @@ -53,12 +54,12 @@ There is no release manager; instead, our community shares the responsibility. A - Look at a [previous release](https://github.com/CesiumGS/cesium/releases/tag/1.79) for an example. Don't use emoji, headings, or other formatting - Attach the `Cesium-1.xx` release zip file - Publish the release -26. Publish to npm by running `npm publish` in the repository root (not the unzipped file directory) (the first time you do this, you will need to authorize the machine using `npm adduser`) -27. Use `npm publish -w ` in the repository root (not the unzipped file directory) to publish the workspace. Repeat this step for each **updated** workspace, in the following order: +27. Publish to npm by running `npm publish` in the repository root (not the unzipped file directory) (the first time you do this, you will need to authorize the machine using `npm adduser`) +28. Use `npm publish -w ` in the repository root (not the unzipped file directory) to publish the workspace. Repeat this step for each **updated** workspace, in the following order: - `npm publish -w @cesium/engine` - `npm publish -w @cesium/widgets` -28. Check out the `cesium.com` branch. Merge the new release tag into the `cesium.com` branch `git merge origin `. CI will deploy the hosted release, Sandcastle, and the updated doc when you push the branch up. -29. After the `cesium.com` branch is live on cesium.com, comment in the `#comms-chat` slack channel to notify comms that the release is done so they can add these highlights and publish the monthly blog post +29. Check out the `cesium.com` branch. Merge the new release tag into the `cesium.com` branch `git merge origin `. CI will deploy the hosted release, Sandcastle, and the updated doc when you push the branch up. +30. After the `cesium.com` branch is live on cesium.com, comment in the `#comms-chat` slack channel to notify comms that the release is done so they can add these highlights and publish the monthly blog post - Note, it may take a little while for the new version of CesiumJS to be live on cesium.com (~30 minutes after the branch builds). You can check the version of Cesium in [sandcastle](https://sandcastle.cesium.com/) by looking at the tab above the cesium pane. -30. Update the version of CesiumJS used in the Cesium Workshop: https://github.com/CesiumGS/cesium-workshop/blob/main/index.html#L13-L14 -31. Continue to the [Cesium Analytics release](https://github.com/CesiumGS/cesium-analytics/blob/main/Documentation/Contributors/AnalyticsReleaseGuide/README.md) +31. Update the version of CesiumJS used in the Cesium Workshop: https://github.com/CesiumGS/cesium-workshop/blob/main/index.html#L13-L14 +32. Continue to the [Cesium Analytics release](https://github.com/CesiumGS/cesium-analytics/blob/main/Documentation/Contributors/AnalyticsReleaseGuide/README.md) diff --git a/packages/engine/Source/Core/GoogleMaps.js b/packages/engine/Source/Core/GoogleMaps.js new file mode 100644 index 00000000000..e5ae75f2068 --- /dev/null +++ b/packages/engine/Source/Core/GoogleMaps.js @@ -0,0 +1,56 @@ +import Credit from "./Credit.js"; +import defined from "./defined.js"; +import Resource from "./Resource.js"; + +let defaultKeyCredit; +const defaultKey = "AIzaSyBESBYnp1EcqtlAcjMTJ65GjUsJtaCWVXA"; + +/** + * Default settings for accessing the Google Maps API. + *
+ * An API key is only required if you are using any Google Maps APIs, such as {@link createGooglePhotorealistic3DTileset}. + * A default key is provided for evaluation purposes only. + * Follow instructions for managing API keys for the Google Maps Platform at {@link https://developers.google.com/maps/documentation/embed/get-api-key} + * + * @see createGooglePhotorealistic3DTileset + * @see https://developers.google.com/maps/documentation/embed/get-api-key + * + * @namespace GoogleMaps + */ +const GoogleMaps = {}; + +/** + * Gets or sets the default Google Maps API key. + * + * @type {string} + */ +GoogleMaps.defaultApiKey = defaultKey; + +/** + * Gets or sets the default Google Map Tiles API endpoint. + * + * @type {string|Resource} + * @default https://tile.googleapis.com/v1/ + */ +GoogleMaps.mapTilesApiEndpoint = new Resource({ + url: "https://tile.googleapis.com/v1/", +}); + +GoogleMaps.getDefaultApiKeyCredit = function (providedKey) { + if (providedKey !== defaultKey) { + return undefined; + } + + if (!defined(defaultKeyCredit)) { + const defaultKeyMessage = + ' \ + This application is using CesiumJS\'s default Google Maps API key. Please assign Cesium.GoogleMaps.defaultApiKey \ + with
your API key for the Google Maps Platform.'; + + defaultKeyCredit = new Credit(defaultKeyMessage, true); + defaultKeyCredit._isDefaultToken = true; + } + + return defaultKeyCredit; +}; +export default GoogleMaps; diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index 31536200251..db3e3ff4b96 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -49,6 +49,7 @@ Ion.getDefaultTokenCredit = function (providedKey) { You can sign up for a free ion account at https://cesium.com.
'; defaultTokenCredit = new Credit(defaultTokenMessage, true); + defaultTokenCredit._isDefaultToken = true; } return defaultTokenCredit; diff --git a/packages/engine/Source/Core/RequestScheduler.js b/packages/engine/Source/Core/RequestScheduler.js index 1b185a3a7e3..46fa4e3d130 100644 --- a/packages/engine/Source/Core/RequestScheduler.js +++ b/packages/engine/Source/Core/RequestScheduler.js @@ -82,6 +82,7 @@ RequestScheduler.requestsByServer = { "api.cesium.com:443": 18, "assets.ion.cesium.com:443": 18, "ibasemaps-api.arcgis.com:443": 18, + "tile.googleapis.com:443": 18, }; /** diff --git a/packages/engine/Source/Core/Resource.js b/packages/engine/Source/Core/Resource.js index cf4c0dfce01..276ed0a4c49 100644 --- a/packages/engine/Source/Core/Resource.js +++ b/packages/engine/Source/Core/Resource.js @@ -148,6 +148,8 @@ function Resource(options) { } else { this._url = options.url; } + + this._credits = options.credits; } /** @@ -372,6 +374,16 @@ Object.defineProperties(Resource.prototype, { return Object.keys(this.headers).length > 0; }, }, + + /** + * Gets the credits required for attribution of an asset. + * @private + */ + credits: { + get: function () { + return this._credits; + }, + }, }); /** @@ -732,6 +744,7 @@ Resource.prototype.clone = function (result) { retryAttempts: this.retryAttempts, request: this.request.clone(), parseUrl: false, + credits: defined(this.credits) ? this.credits.slice() : undefined, }); } diff --git a/packages/engine/Source/Scene/ArcGisMapService.js b/packages/engine/Source/Scene/ArcGisMapService.js index 4656f58cb24..8beb63a0a6c 100644 --- a/packages/engine/Source/Scene/ArcGisMapService.js +++ b/packages/engine/Source/Scene/ArcGisMapService.js @@ -76,6 +76,7 @@ ArcGisMapService.getDefaultTokenCredit = function (providedKey) { You can sign up for a free ArcGIS Developer account at https://developers.arcgis.com/.
'; defaultTokenCredit = new Credit(defaultTokenMessage, true); + defaultTokenCredit._isDefaultToken = true; } return defaultTokenCredit; diff --git a/packages/engine/Source/Scene/Cesium3DTileset.js b/packages/engine/Source/Scene/Cesium3DTileset.js index ac848668623..7d7466bf4b6 100644 --- a/packages/engine/Source/Scene/Cesium3DTileset.js +++ b/packages/engine/Source/Scene/Cesium3DTileset.js @@ -3211,7 +3211,8 @@ function update(tileset, frameState, passStatistics, passOptions) { if (defined(credits) && statistics.selected !== 0) { for (let i = 0; i < credits.length; ++i) { const credit = credits[i]; - credit.showOnScreen = tileset._showCreditsOnScreen; + credit.showOnScreen = + tileset._showCreditsOnScreen || credit._isDefaultToken; frameState.creditDisplay.addCreditToNextFrame(credit); } } diff --git a/packages/engine/Source/Scene/Model/Model.js b/packages/engine/Source/Scene/Model/Model.js index e2755e6c461..3b64dd296bc 100644 --- a/packages/engine/Source/Scene/Model/Model.js +++ b/packages/engine/Source/Scene/Model/Model.js @@ -2384,19 +2384,21 @@ function updateShowCreditsOnScreen(model) { const showOnScreen = model._showCreditsOnScreen; if (defined(model._credit)) { - model._credit.showOnScreen = showOnScreen; + model._credit.showOnScreen = showOnScreen || model._credit._isDefaultToken; } const resourceCredits = model._resourceCredits; const resourceCreditsLength = resourceCredits.length; for (let i = 0; i < resourceCreditsLength; i++) { - resourceCredits[i].showOnScreen = showOnScreen; + resourceCredits[i].showOnScreen = + showOnScreen || resourceCredits[i]._isDefaultToken; } const gltfCredits = model._gltfCredits; const gltfCreditsLength = gltfCredits.length; for (let i = 0; i < gltfCreditsLength; i++) { - gltfCredits[i].showOnScreen = showOnScreen; + gltfCredits[i].showOnScreen = + showOnScreen || gltfCredits[i]._isDefaultToken; } } diff --git a/packages/engine/Source/Scene/createGooglePhotorealistic3DTileset.js b/packages/engine/Source/Scene/createGooglePhotorealistic3DTileset.js new file mode 100644 index 00000000000..d644f3988ef --- /dev/null +++ b/packages/engine/Source/Scene/createGooglePhotorealistic3DTileset.js @@ -0,0 +1,53 @@ +import Cesium3DTileset from "./Cesium3DTileset.js"; +import defaultValue from "../Core/defaultValue.js"; +import defined from "../Core/defined.js"; +import GoogleMaps from "../Core/GoogleMaps.js"; +import Resource from "../Core/Resource.js"; + +/** + * Creates a {@link Cesium3DTileset} instance for the Google Photorealistic 3D Tiles tileset. + * + * @function + * + * @param {string} [key=GoogleMaps.defaultApiKey] Your API key to access Google Photorealistic 3D Tiles. See {@link https://developers.google.com/maps/documentation/javascript/get-api-key} for instructions on how to create your own key. + * @param {Cesium3DTileset.ConstructorOptions} [options] An object describing initialization options. + * @returns {Promise} + * + * @see GoogleMaps + * + * @example + * Cesium.GoogleMaps.defaultApiKey = "your-api-key"; + * + * const viewer = new Cesium.Viewer("cesiumContainer"); + * + * try { + * const tileset = await Cesium.createGooglePhotorealistic3DTileset(); + * viewer.scene.primitives.add(tileset)); + * } catch (error) { + * console.log(`Error creating tileset: ${error}`); + * } + */ +async function createGooglePhotorealistic3DTileset(key, options) { + key = defaultValue(key, GoogleMaps.defaultApiKey); + + let credits; + const credit = GoogleMaps.getDefaultApiKeyCredit(key); + if (defined(credit)) { + credits = [credit]; + } + + options = defaultValue(options, {}); + options.showCreditsOnScreen = true; + + const resource = new Resource({ + url: `${GoogleMaps.mapTilesApiEndpoint}3dtiles/root.json`, + queryParameters: { + key: key, + }, + credits: credits, + }); + + return Cesium3DTileset.fromUrl(resource, options); +} + +export default createGooglePhotorealistic3DTileset; From 633f5153b48ec83eaeeaaa5e1e1a0bc09c78f22c Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Wed, 10 May 2023 14:45:23 -0400 Subject: [PATCH 661/679] Updates for 1.105.1 release --- package.json | 4 ++-- packages/engine/package.json | 2 +- packages/widgets/package.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ac0ad100e08..b16001f21f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.105.0", + "version": "1.105.1", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.3.0", + "@cesium/engine": "2.4.0", "@cesium/widgets": "2.2.0" }, "devDependencies": { diff --git a/packages/engine/package.json b/packages/engine/package.json index ef127fc219e..fa18c9a2f23 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "2.3.0", + "version": "2.4.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 9395cc18574..404d33870d1 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "2.3.0", + "@cesium/engine": "2.4.0", "nosleep.js": "^0.12.0" }, "type": "module", @@ -52,4 +52,4 @@ "bugs": { "url": "https://github.com/CesiumGS/cesium/issues" } -} +} \ No newline at end of file From d35385f4f96084bc7daf27f5e4a473213a2cb0d2 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Thu, 11 May 2023 13:59:54 -0500 Subject: [PATCH 662/679] Fix doc for Entity.prototype.computeModelMatrix (#11277) Co-authored-by: Jeshurun Hembd --- packages/engine/Source/DataSources/Entity.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/engine/Source/DataSources/Entity.js b/packages/engine/Source/DataSources/Entity.js index 774103a8298..35241758178 100644 --- a/packages/engine/Source/DataSources/Entity.js +++ b/packages/engine/Source/DataSources/Entity.js @@ -637,13 +637,12 @@ const positionScratch = new Cartesian3(); const orientationScratch = new Quaternion(); /** - * Computes the model matrix for the entity's transform at specified time. Returns undefined if orientation or position - * are undefined. + * Computes the model matrix for the entity's transform at specified time. Returns undefined if position is undefined * * @param {JulianDate} time The time to retrieve model matrix for. * @param {Matrix4} [result] The object onto which to store the result. * - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position or orientation are undefined. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position is undefined. */ Entity.prototype.computeModelMatrix = function (time, result) { //>>includeStart('debug', pragmas.debug); From f573f11e039f5f61a7b47da1a44dff9dbacf18cf Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Mon, 15 May 2023 09:24:17 -0400 Subject: [PATCH 663/679] Update widgets version --- CHANGES.md | 4 ++++ Documentation/Contributors/ReleaseGuide/README.md | 1 - package.json | 4 ++-- packages/widgets/package.json | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1fac1760035..116a34f6d15 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Change Log +### 1.105.2 - 2023-05-15 + +- This is an npm-only release to fix a dependency issue published in 1.105.1. + ### 1.105.1 - 2023-05-10 #### @cesium/engine diff --git a/Documentation/Contributors/ReleaseGuide/README.md b/Documentation/Contributors/ReleaseGuide/README.md index d7ad90411e8..79c663ce916 100644 --- a/Documentation/Contributors/ReleaseGuide/README.md +++ b/Documentation/Contributors/ReleaseGuide/README.md @@ -26,7 +26,6 @@ There is no release manager; instead, our community shares the responsibility. A 8. Proofread [`CHANGES.md`](../../../CHANGES.md) with the date of the release. Adjust the order of changes so that prominent/popular changes come first. Ensure each change is in the section for the relevant workspace. 9. Based on `CHANGES.md`, update each workspace version following the rules of [semantic versioning](https://semver.org/), e.g., - `npm version minor -w @cesium/engine --no-git-tag-version` - - If there are no changes, skip updating the workspace version. 10. Update the version in `package.json` to match, e.g. `1.14.0` -> `1.15.0`. 11. Commit these changes. 12. Make sure the repository is clean `git clean -d -x -f`. **This will delete all files not already in the repository.** diff --git a/package.json b/package.json index b16001f21f6..dc2bc145676 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.105.1", + "version": "1.105.2", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -52,7 +52,7 @@ ], "dependencies": { "@cesium/engine": "2.4.0", - "@cesium/widgets": "2.2.0" + "@cesium/widgets": "2.3.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.276.0", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 404d33870d1..afe58b13172 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "2.2.0", + "version": "2.3.0", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", @@ -52,4 +52,4 @@ "bugs": { "url": "https://github.com/CesiumGS/cesium/issues" } -} \ No newline at end of file +} From afab16dfe1b2676daa766f1a2d31e7d52f51138d Mon Sep 17 00:00:00 2001 From: Ben Kuster Date: Thu, 18 May 2023 17:17:08 +0200 Subject: [PATCH 664/679] fixed datasource display visualizer callback typedef (#11294) --- packages/engine/Source/DataSources/DataSourceDisplay.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/engine/Source/DataSources/DataSourceDisplay.js b/packages/engine/Source/DataSources/DataSourceDisplay.js index e71989ea47b..6ea22ddf41b 100644 --- a/packages/engine/Source/DataSources/DataSourceDisplay.js +++ b/packages/engine/Source/DataSources/DataSourceDisplay.js @@ -499,12 +499,13 @@ DataSourceDisplay.prototype._onDataSourceMoved = function ( * @callback DataSourceDisplay.VisualizersCallback * * @param {Scene} scene The scene to create visualizers for. + * @param {EntityCluster} entityCluster The entity cluster to create visualizers for. * @param {DataSource} dataSource The data source to create visualizers for. * @returns {Visualizer[]} An array of visualizers used for visualization. * * @example - * function createVisualizers(scene, dataSource) { - * return [new Cesium.BillboardVisualizer(scene, dataSource.entities)]; + * function createVisualizers(scene, entityCluster, dataSource) { + * return [new Cesium.BillboardVisualizer(entityCluster, dataSource.entities)]; * } */ export default DataSourceDisplay; From c60dd09dbd10580058dbe0b64b039c88a8b88479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Junod?= Date: Thu, 18 May 2023 17:18:53 +0200 Subject: [PATCH 665/679] Add TextureUniform type for setUniform value type (#11284) --- packages/engine/Source/Scene/Model/CustomShader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/Source/Scene/Model/CustomShader.js b/packages/engine/Source/Scene/Model/CustomShader.js index f3cb58ac413..eef3163b7d6 100644 --- a/packages/engine/Source/Scene/Model/CustomShader.js +++ b/packages/engine/Source/Scene/Model/CustomShader.js @@ -405,7 +405,7 @@ function validateBuiltinVariables(customShader) { /** * Update the value of a uniform declared in the shader * @param {string} uniformName The GLSL name of the uniform. This must match one of the uniforms declared in the constructor - * @param {boolean|number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|string|Resource} value The new value of the uniform. + * @param {boolean|number|Cartesian2|Cartesian3|Cartesian4|Matrix2|Matrix3|Matrix4|string|Resource|TextureUniform} value The new value of the uniform. */ CustomShader.prototype.setUniform = function (uniformName, value) { //>>includeStart('debug', pragmas.debug); From 0c69d1bcf4c3c77ba8a00629fd7d3328a6c35375 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 18 May 2023 16:50:51 -0400 Subject: [PATCH 666/679] Return the correct promise --- .../Source/Core/CesiumTerrainProvider.js | 45 +++++++++---------- .../engine/Source/Core/TileAvailability.js | 32 ++++++------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index d0fe20a8a5a..ba7645d5e03 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -901,6 +901,8 @@ CesiumTerrainProvider.prototype.requestTileGeometry = function ( const layers = this._layers; let layerToUse; const layerCount = layers.length; + let unknownAvailability = false; + let availabilityPromise = Promise.resolve(); if (layerCount === 1) { // Optimized path for single layers @@ -916,36 +918,31 @@ CesiumTerrainProvider.prototype.requestTileGeometry = function ( break; } - if (!defined(layer.availabilityLevels)) { - // This layer doesn't use cutout terrain, so we don't need to do the following check - continue; - } - - const tile = getAvailabilityTile(layer, x, y, level); - if ( - !defined(tile) || - !layer.availability.isTileAvailable(tile.level, tile.x, tile.y) || - layer.availabilityTilesLoaded.isTileAvailable( - tile.level, - tile.x, - tile.y - ) - ) { - continue; - } - - // There are some cases where availability tiles are not completely loaded at this point. Request them now. - return requestTileGeometry( + const availabilityUnloaded = checkLayer( this, - tile.x, - tile.y, - tile.level, + x, + y, + level, layer, - request + i === 0 ); + if (availabilityUnloaded.result) { + // We can't know yet since the availability is not yet loaded + unknownAvailability = true; + availabilityPromise = availabilityPromise.then( + () => availabilityUnloaded.promise + ); + } } } + if (!defined(layerToUse) && unknownAvailability) { + // Try again when availability data is ready– Otherwise the tile will be marked as failed and never re-requested + return availabilityPromise.then(() => + this.requestTileGeometry(x, y, level, request) + ); + } + return requestTileGeometry(this, x, y, level, layerToUse, request); }; diff --git a/packages/engine/Source/Core/TileAvailability.js b/packages/engine/Source/Core/TileAvailability.js index 2a4bec88d07..0a6a74a3eed 100644 --- a/packages/engine/Source/Core/TileAvailability.js +++ b/packages/engine/Source/Core/TileAvailability.js @@ -396,10 +396,10 @@ function findMaxLevelFromNode(stopNode, node, position) { // Find the deepest quadtree node containing this point. let found = false; while (!found) { - const nw = node.nw && rectangleContainsPosition(node.nw.extent, position); - const ne = node.ne && rectangleContainsPosition(node.ne.extent, position); - const sw = node.sw && rectangleContainsPosition(node.sw.extent, position); - const se = node.se && rectangleContainsPosition(node.se.extent, position); + const nw = node._nw && rectangleContainsPosition(node._nw.extent, position); + const ne = node._ne && rectangleContainsPosition(node._ne.extent, position); + const sw = node._sw && rectangleContainsPosition(node._sw.extent, position); + const se = node._se && rectangleContainsPosition(node._se.extent, position); // The common scenario is that the point is in only one quadrant and we can simply // iterate down the tree. But if the point is on a boundary between tiles, it is @@ -408,36 +408,36 @@ function findMaxLevelFromNode(stopNode, node, position) { if (nw) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node.nw, position) + findMaxLevelFromNode(node, node._nw, position) ); } if (ne) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node.ne, position) + findMaxLevelFromNode(node, node._ne, position) ); } if (sw) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node.sw, position) + findMaxLevelFromNode(node, node._sw, position) ); } if (se) { maxLevel = Math.max( maxLevel, - findMaxLevelFromNode(node, node.se, position) + findMaxLevelFromNode(node, node._se, position) ); } break; } else if (nw) { - node = node.nw; + node = node._nw; } else if (ne) { - node = node.ne; + node = node._ne; } else if (sw) { - node = node.sw; + node = node._sw; } else if (se) { - node = node.se; + node = node._se; } else { found = true; } @@ -501,10 +501,10 @@ function updateCoverageWithNode( } // Update with child nodes. - updateCoverageWithNode(remainingToCoverByLevel, node.nw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node.ne, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node.sw, rectanglesToCover); - updateCoverageWithNode(remainingToCoverByLevel, node.se, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._nw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._ne, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._sw, rectanglesToCover); + updateCoverageWithNode(remainingToCoverByLevel, node._se, rectanglesToCover); } function subtractRectangle(rectangleList, rectangleToSubtract) { From 04a03d64026d397d86c6cd48dcf4f13af9a94e6d Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 18 May 2023 17:05:52 -0400 Subject: [PATCH 667/679] Update CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 0cd0a34efc7..084a547b2ed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Change Log +### 1.106 - 2023-06-01 + +#### @cesium/engine + +##### Fixes :wrench: + +- Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) + ### 1.105 - 2023-05-01 #### @cesium/engine From 0b1619661b0ac9fd42d8acc0455b8be7ea421ef4 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 18 May 2023 17:31:20 -0400 Subject: [PATCH 668/679] prettier --- CHANGES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index fb447a6164d..6cb270d52e3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,5 @@ # Change Log - ### 1.106 - 2023-06-01 #### @cesium/engine From fa78047931bb73cbdad2f777705b7c2025eb9648 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 19 May 2023 14:11:32 -0400 Subject: [PATCH 669/679] Add unit test --- .../ParentAvailability.tile.json | 36 +++++++++ .../ParentUrlAvailability.tile.json | 38 ++++++++++ .../Specs/Core/CesiumTerrainProviderSpec.js | 76 +++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 Specs/Data/CesiumTerrainTileJson/ParentAvailability.tile.json create mode 100644 Specs/Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json diff --git a/Specs/Data/CesiumTerrainTileJson/ParentAvailability.tile.json b/Specs/Data/CesiumTerrainTileJson/ParentAvailability.tile.json new file mode 100644 index 00000000000..83d7f33ce4f --- /dev/null +++ b/Specs/Data/CesiumTerrainTileJson/ParentAvailability.tile.json @@ -0,0 +1,36 @@ +{ + "tilejson": "2.1.0", + "format" : "quantized-mesh-1.0", + "version" : "1.0.0", + "scheme" : "tms", + "attribution" : "This amazing data is courtesy The Amazing Data Source!", + "tiles" : [ + "{z}/{x}/{y}.terrain?v={version}" + ], + "extensions": [ + "watermask", + "metadata", + "octvertexnormals" + ], + "metadataAvailability": 10, + "minzoom": 0, + "maxzoom": 13, + "available" : [ + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 1, + "endY" : 0 + } + ], + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 3, + "endY" : 1 + } + ] + ] +} diff --git a/Specs/Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json b/Specs/Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json new file mode 100644 index 00000000000..3b1c3c0d333 --- /dev/null +++ b/Specs/Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json @@ -0,0 +1,38 @@ +{ + "tilejson": "2.1.0", + "format" : "quantized-mesh-1.0", + "version" : "1.0.0", + "scheme" : "tms", + "attribution" : "This is a child tileset!", + "tiles" : [ + "{z}/{x}/{y}.terrain?v={version}" + ], + "extensions" : [ + "watermask", + "metadata", + "octvertexnormals" + ], + "metadataAvailability": 10, + "minzoom": 0, + "maxzoom": 13, + "available" : [ + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 1, + "endY" : 0 + } + ], + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 2, + "endY" : 1 + } + ] + ], + "parentUrl": "./" +} + diff --git a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js index c4d6a6c5a29..822547b1b8a 100644 --- a/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js +++ b/packages/engine/Specs/Core/CesiumTerrainProviderSpec.js @@ -133,6 +133,45 @@ describe("Core/CesiumTerrainProvider", function () { ); } + function returnParentUrlTileJsonWithMetadataAvailability() { + const paths = [ + "Data/CesiumTerrainTileJson/ParentUrlAvailability.tile.json", + "Data/CesiumTerrainTileJson/ParentAvailability.tile.json", + ]; + let i = 0; + const oldLoad = Resource._Implementations.loadWithXhr; + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + if (url.indexOf("layer.json") >= 0) { + Resource._DefaultImplementations.loadWithXhr( + paths[i++], + responseType, + method, + data, + headers, + deferred + ); + } else { + return oldLoad( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ); + } + }; + } + async function waitForTile(level, x, y, requestNormals, requestWaterMask, f) { const terrainProvider = await CesiumTerrainProvider.fromUrl("made/up/url", { requestVertexNormals: requestNormals, @@ -899,6 +938,43 @@ describe("Core/CesiumTerrainProvider", function () { expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true); }); + it("provides QuantizedMeshTerrainData with multiple layers and with Metadata availability ", async function () { + Resource._Implementations.loadWithXhr = function ( + url, + responseType, + method, + data, + headers, + deferred, + overrideMimeType + ) { + Resource._DefaultImplementations.loadWithXhr( + "Data/CesiumTerrainTileJson/tile.metadataavailability.terrain", + responseType, + method, + data, + headers, + deferred + ); + }; + + returnParentUrlTileJsonWithMetadataAvailability(); + + const terrainProvider = await CesiumTerrainProvider.fromUrl( + "made/up/url" + ); + + expect(terrainProvider.hasMetadata).toBe(true); + const layers = terrainProvider._layers; + expect(layers.length).toBe(2); + + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(false); + + const loadedData = await terrainProvider.requestTileGeometry(0, 0, 1); + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(terrainProvider.availability.isTileAvailable(1, 0, 0)).toBe(true); + }); + it("returns undefined if too many requests are already in progress", async function () { const baseUrl = "made/up/url"; From 95c5e60a27987a0620fdff210d505fc4d5a6d3f6 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 24 May 2023 01:25:24 -0400 Subject: [PATCH 670/679] Enable standard derivatives extension in demodernizeShader --- packages/engine/Source/Renderer/demodernizeShader.js | 3 +++ packages/engine/Source/Scene/Cesium3DTileBatchTable.js | 3 --- packages/engine/Source/Shaders/BillboardCollectionFS.glsl | 4 ---- .../Source/Shaders/Builtin/Functions/writeLogDepth.glsl | 3 --- .../Source/Shaders/Materials/ElevationContourMaterial.glsl | 4 ---- packages/engine/Source/Shaders/Materials/GridMaterial.glsl | 4 ---- .../Source/Shaders/Materials/PolylineArrowMaterial.glsl | 4 ---- packages/engine/Source/Shaders/Model/ModelFS.glsl | 6 ------ 8 files changed, 3 insertions(+), 28 deletions(-) diff --git a/packages/engine/Source/Renderer/demodernizeShader.js b/packages/engine/Source/Renderer/demodernizeShader.js index ac984761ed0..85446533efa 100644 --- a/packages/engine/Source/Renderer/demodernizeShader.js +++ b/packages/engine/Source/Renderer/demodernizeShader.js @@ -56,6 +56,9 @@ function demodernizeShader(input, isFragmentShader) { // Replace gl_FragDepth with gl_FragDepthEXT. output = output.replaceAll(/gl_FragDepth/g, `gl_FragDepthEXT`); } + + // Enable the OES_standard_derivatives extension + output = `#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\n${output}`; } else { // Replace the in with attribute. output = output.replaceAll(/(in)\s+(vec\d|mat\d|float)/g, `attribute $2`); diff --git a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js index 6631d6c1962..b9a678cdd8c 100644 --- a/packages/engine/Source/Scene/Cesium3DTileBatchTable.js +++ b/packages/engine/Source/Scene/Cesium3DTileBatchTable.js @@ -1050,9 +1050,6 @@ function getLogDepthPolygonOffsetFragmentShaderProgram(context, shaderProgram) { fs.defines = defined(fs.defines) ? fs.defines.slice(0) : []; fs.defines.push("POLYGON_OFFSET"); - fs.sources.unshift( - "#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\n" - ); shader = context.shaderCache.createDerivedShaderProgram( shaderProgram, "zBackfaceLogDepth", diff --git a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl index 916731d9277..d4c72d2c3bb 100644 --- a/packages/engine/Source/Shaders/BillboardCollectionFS.glsl +++ b/packages/engine/Source/Shaders/BillboardCollectionFS.glsl @@ -1,7 +1,3 @@ -#ifdef GL_OES_standard_derivatives -#extension GL_OES_standard_derivatives : enable -#endif - uniform sampler2D u_atlas; #ifdef VECTOR_TILE diff --git a/packages/engine/Source/Shaders/Builtin/Functions/writeLogDepth.glsl b/packages/engine/Source/Shaders/Builtin/Functions/writeLogDepth.glsl index d0501b07245..36a745469d3 100644 --- a/packages/engine/Source/Shaders/Builtin/Functions/writeLogDepth.glsl +++ b/packages/engine/Source/Shaders/Builtin/Functions/writeLogDepth.glsl @@ -3,9 +3,6 @@ in float v_depthFromNearPlusOne; #ifdef POLYGON_OFFSET uniform vec2 u_polygonOffset; -#ifdef GL_OES_standard_derivatives -#extension GL_OES_standard_derivatives : enable -#endif #endif #endif diff --git a/packages/engine/Source/Shaders/Materials/ElevationContourMaterial.glsl b/packages/engine/Source/Shaders/Materials/ElevationContourMaterial.glsl index 23c50dea533..ca96ba10829 100644 --- a/packages/engine/Source/Shaders/Materials/ElevationContourMaterial.glsl +++ b/packages/engine/Source/Shaders/Materials/ElevationContourMaterial.glsl @@ -1,7 +1,3 @@ -#ifdef GL_OES_standard_derivatives - #extension GL_OES_standard_derivatives : enable -#endif - uniform vec4 color; uniform float spacing; uniform float width; diff --git a/packages/engine/Source/Shaders/Materials/GridMaterial.glsl b/packages/engine/Source/Shaders/Materials/GridMaterial.glsl index a56f6e74e83..de0bde48918 100644 --- a/packages/engine/Source/Shaders/Materials/GridMaterial.glsl +++ b/packages/engine/Source/Shaders/Materials/GridMaterial.glsl @@ -1,7 +1,3 @@ -#ifdef GL_OES_standard_derivatives - #extension GL_OES_standard_derivatives : enable -#endif - uniform vec4 color; uniform float cellAlpha; uniform vec2 lineCount; diff --git a/packages/engine/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/packages/engine/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 760ac458021..30740251ac5 100644 --- a/packages/engine/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/packages/engine/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,7 +1,3 @@ -#ifdef GL_OES_standard_derivatives -#extension GL_OES_standard_derivatives : enable -#endif - uniform vec4 color; float getPointOnLine(vec2 p0, vec2 p1, float x) diff --git a/packages/engine/Source/Shaders/Model/ModelFS.glsl b/packages/engine/Source/Shaders/Model/ModelFS.glsl index a7cde606497..f56da251646 100644 --- a/packages/engine/Source/Shaders/Model/ModelFS.glsl +++ b/packages/engine/Source/Shaders/Model/ModelFS.glsl @@ -1,9 +1,3 @@ -#if defined(HAS_NORMALS) && !defined(HAS_TANGENTS) && !defined(LIGHTING_UNLIT) - #ifdef GL_OES_standard_derivatives - #extension GL_OES_standard_derivatives : enable - #endif -#endif - czm_modelMaterial defaultModelMaterial() { czm_modelMaterial material; From 2f409a4b4b4cb044fb97ee5f94fa823d457fa7bd Mon Sep 17 00:00:00 2001 From: Alexander Popoff <32072831+aerialist7@users.noreply.github.com> Date: Thu, 25 May 2023 17:45:45 +0300 Subject: [PATCH 671/679] Fixed color creation from CSS color string with modern "space-separated" syntax (#11271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix `Color.fromCssColorString` in case of parsing `rgb(a)`/`hsl(a)` CSS colors with modern "space-separated" syntax * Add `Alexander Popoff` (@aerialist7) to the list of contributors * Escaping * Disable `/` parsing * Fix regexps * Only remove surrounding whitespace from color strings * Enable `/` parsing * Formatting * Make sure availability tiles are loaded before deciding there is no terrain at that x, y, level * Return the correct promise * Update CHANGES.md * Adjust camera controls for 3D * Use first picked position in drag when possible * Use pick position direction for panning * Only use new camera controls when globe is false * Spin3d should fallback to old behavior when globe is defined * pick globe on spin3d * Fallback to old behavior for spin3d * Updates for Google Photorealistic 3D Tiles * Updates for 1.105.1 release * Fix doc for Entity.prototype.computeModelMatrix (#11277) Co-authored-by: Jeshurun Hembd * Update widgets version * fixed datasource display visualizer callback typedef (#11294) * Add TextureUniform type for setUniform value type (#11284) * Add unit test * Enable standard derivatives extension in demodernizeShader * Update CHANGES.md --------- Co-authored-by: Gabby Getz Co-authored-by: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Co-authored-by: Jeshurun Hembd Co-authored-by: Ben Kuster Co-authored-by: Frédéric Junod --- CHANGES.md | 1 + CONTRIBUTORS.md | 1 + packages/engine/Source/Core/Color.js | 8 +-- packages/engine/Specs/Core/ColorSpec.js | 67 +++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6cb270d52e3..a4325e82ecf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ ##### Fixes :wrench: +- Fixed color creation from CSS color string with modern "space-separated" syntax. [#11271](https://github.com/CesiumGS/cesium/pull/11271) - Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) ### 1.105.2 - 2023-05-15 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5d0fb7a9053..d3ec9028d35 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -357,3 +357,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [王秋艳](https://github.com/wqy224488) - [Jason Summercamp](https://github.com/fullstacc) - [Shapovalov Kirill](https://github.com/ShapovalovKL) +- [Alexander Popoff](https://github.com/aerialist7) diff --git a/packages/engine/Source/Core/Color.js b/packages/engine/Source/Core/Color.js index 9dfa7b959fd..23683732133 100644 --- a/packages/engine/Source/Core/Color.js +++ b/packages/engine/Source/Core/Color.js @@ -352,9 +352,9 @@ const rgbaMatcher = /^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i; //#rrggbbaa const rrggbbaaMatcher = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i; //rgb(), rgba(), or rgb%() -const rgbParenthesesMatcher = /^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i; +const rgbParenthesesMatcher = /^rgba?\s*\(\s*([0-9.]+%?)\s*[,\s]+\s*([0-9.]+%?)\s*[,\s]+\s*([0-9.]+%?)(?:\s*[,\s/]+\s*([0-9.]+))?\s*\)$/i; //hsl() or hsla() -const hslParenthesesMatcher = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i; +const hslParenthesesMatcher = /^hsla?\s*\(\s*([0-9.]+)\s*[,\s]+\s*([0-9.]+%)\s*[,\s]+\s*([0-9.]+%)(?:\s*[,\s/]+\s*([0-9.]+))?\s*\)$/i; /** * Creates a Color instance from a CSS color value. @@ -379,8 +379,8 @@ Color.fromCssColorString = function (color, result) { result = new Color(); } - // Remove all whitespaces from the color string - color = color.replace(/\s/g, ""); + // Remove all surrounding whitespaces from the color string + color = color.trim(); const namedColor = Color[color.toUpperCase()]; if (defined(namedColor)) { diff --git a/packages/engine/Specs/Core/ColorSpec.js b/packages/engine/Specs/Core/ColorSpec.js index b2d6cc2bea5..11cb942a722 100644 --- a/packages/engine/Specs/Core/ColorSpec.js +++ b/packages/engine/Specs/Core/ColorSpec.js @@ -244,6 +244,15 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the rgb() format with absolute values (space-separated)", function () { + expect(Color.fromCssColorString("rgb(255 0 0)")).toEqual(Color.RED); + expect(Color.fromCssColorString("rgb(0 255 0)")).toEqual(Color.LIME); + expect(Color.fromCssColorString("rgb(0 0 255)")).toEqual(Color.BLUE); + expect(Color.fromCssColorString("rgb(51 102 204)")).toEqual( + new Color(0.2, 0.4, 0.8, 1.0) + ); + }); + it("fromCssColorString supports the rgb() format with percentages", function () { expect(Color.fromCssColorString("rgb(100%, 0, 0)")).toEqual(Color.RED); expect(Color.fromCssColorString("rgb(0, 100%, 0)")).toEqual(Color.LIME); @@ -253,6 +262,15 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the rgb() format with percentages (space-separated)", function () { + expect(Color.fromCssColorString("rgb(100% 0 0)")).toEqual(Color.RED); + expect(Color.fromCssColorString("rgb(0 100% 0)")).toEqual(Color.LIME); + expect(Color.fromCssColorString("rgb(0 0 100%)")).toEqual(Color.BLUE); + expect(Color.fromCssColorString("rgb(20% 40% 80%)")).toEqual( + new Color(0.2, 0.4, 0.8, 1.0) + ); + }); + it("fromCssColorString supports the rgba() format with absolute values", function () { expect(Color.fromCssColorString("rgba(255, 0, 0, 1.0)")).toEqual(Color.RED); expect(Color.fromCssColorString("rgba(0, 255, 0, 1.0)")).toEqual( @@ -266,6 +284,15 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the rgba() format with absolute values (space-separated)", function () { + expect(Color.fromCssColorString("rgba(255 0 0 / 1.0)")).toEqual(Color.RED); + expect(Color.fromCssColorString("rgba(0 255 0 / 1.0)")).toEqual(Color.LIME); + expect(Color.fromCssColorString("rgba(0 0 255 / 1.0)")).toEqual(Color.BLUE); + expect(Color.fromCssColorString("rgba(51 102 204 / 0.6)")).toEqual( + new Color(0.2, 0.4, 0.8, 0.6) + ); + }); + it("fromCssColorString supports the rgba() format with percentages", function () { expect(Color.fromCssColorString("rgba(100%, 0, 0, 1.0)")).toEqual( Color.RED @@ -281,6 +308,19 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the rgba() format with percentages (space-separated)", function () { + expect(Color.fromCssColorString("rgba(100% 0 0 / 1.0)")).toEqual(Color.RED); + expect(Color.fromCssColorString("rgba(0 100% 0 / 1.0)")).toEqual( + Color.LIME + ); + expect(Color.fromCssColorString("rgba(0 0 100% / 1.0)")).toEqual( + Color.BLUE + ); + expect(Color.fromCssColorString("rgba(20% 40% 80% / 0.6)")).toEqual( + new Color(0.2, 0.4, 0.8, 0.6) + ); + }); + it("fromCssColorString supports named colors regardless of case", function () { expect(Color.fromCssColorString("red")).toEqual(Color.RED); expect(Color.fromCssColorString("GREEN")).toEqual(Color.GREEN); @@ -297,6 +337,16 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the hsl() format (space-separated)", function () { + expect(Color.fromCssColorString("hsl(0 100% 50%)")).toEqual(Color.RED); + expect(Color.fromCssColorString("hsl(120 100% 50%)")).toEqual(Color.LIME); + expect(Color.fromCssColorString("hsl(240 100% 50%)")).toEqual(Color.BLUE); + expect(Color.fromCssColorString("hsl(220 60% 50%)")).toEqualEpsilon( + new Color(0.2, 0.4, 0.8), + CesiumMath.EPSILON15 + ); + }); + it("fromCssColorString supports the hsla() format", function () { expect(Color.fromCssColorString("hsla(0, 100%, 50%, 1.0)")).toEqual( Color.RED @@ -313,6 +363,22 @@ describe("Core/Color", function () { ); }); + it("fromCssColorString supports the hsla() format (space-separated)", function () { + expect(Color.fromCssColorString("hsla(0 100% 50% / 1.0)")).toEqual( + Color.RED + ); + expect(Color.fromCssColorString("hsla(120 100% 50% / 1.0)")).toEqual( + Color.LIME + ); + expect(Color.fromCssColorString("hsla(240 100% 50% / 1.0)")).toEqual( + Color.BLUE + ); + expect(Color.fromCssColorString("hsla(220 60% 50% / 0.6)")).toEqualEpsilon( + new Color(0.2, 0.4, 0.8, 0.6), + CesiumMath.EPSILON15 + ); + }); + it("fromCssColorString wraps hue into valid range for hsl() format", function () { expect(Color.fromCssColorString("hsl(720, 100%, 50%)")).toEqual(Color.RED); expect(Color.fromCssColorString("hsla(720, 100%, 50%, 1.0)")).toEqual( @@ -363,6 +429,7 @@ describe("Core/Color", function () { expect(Color.fromCssColorString("rgb( 255, 255, 255) ")).toEqual( Color.WHITE ); + expect(Color.fromCssColorString("rgb (0 0 255) ")).toEqual(Color.BLUE); expect(Color.fromCssColorString(" #FF0000")).toEqual(Color.RED); expect(Color.fromCssColorString("#FF0 ")).toEqual(Color.YELLOW); expect(Color.fromCssColorString(" hsla(720, 100%, 50%, 1.0) ")).toEqual( From 3b58c726cd8d0b349cd9e2d5db5b02b2c1ce99c5 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Thu, 25 May 2023 14:00:05 -0400 Subject: [PATCH 672/679] Terrain deprecation fixes --- CHANGES.md | 1 + .../ArcGISTiledElevationTerrainProvider.js | 6 +- .../Source/Core/CesiumTerrainProvider.js | 6 +- .../Core/CustomHeightmapTerrainProvider.js | 4 +- .../Source/Core/EllipsoidTerrainProvider.js | 4 +- .../Core/GoogleEarthEnterpriseMetadata.js | 4 +- .../GoogleEarthEnterpriseTerrainProvider.js | 8 +-- .../Source/Core/VRTheWorldTerrainProvider.js | 6 +- .../engine/Source/Core/createWorldTerrain.js | 3 +- packages/engine/Source/Core/sampleTerrain.js | 6 +- .../Source/Core/sampleTerrainMostDetailed.js | 6 +- .../Source/DataSources/ModelVisualizer.js | 7 +- .../Scene/ArcGisMapServerImageryProvider.js | 46 ++++++------- .../Source/Scene/BingMapsImageryProvider.js | 46 ++++++------- packages/engine/Source/Scene/Globe.js | 10 ++- .../engine/Source/Scene/GlobeSurfaceTile.js | 8 ++- .../Source/Scene/GlobeSurfaceTileProvider.js | 67 +++++++++++++------ .../GoogleEarthEnterpriseImageryProvider.js | 48 ++++++------- .../GoogleEarthEnterpriseMapsProvider.js | 44 ++++++------ .../Source/Scene/GridImageryProvider.js | 44 ++++++------ packages/engine/Source/Scene/Imagery.js | 7 +- packages/engine/Source/Scene/ImageryLayer.js | 16 ++++- .../engine/Source/Scene/IonImageryProvider.js | 46 ++++++------- .../Source/Scene/MapboxImageryProvider.js | 44 ++++++------ .../Scene/MapboxStyleImageryProvider.js | 44 ++++++------ .../Source/Scene/SingleTileImageryProvider.js | 44 ++++++------ .../Scene/TileCoordinatesImageryProvider.js | 44 ++++++------ .../Scene/TileMapServiceImageryProvider.js | 2 +- .../Scene/UrlTemplateImageryProvider.js | 46 ++++++------- .../Scene/WebMapServiceImageryProvider.js | 44 ++++++------ .../Scene/WebMapTileServiceImageryProvider.js | 44 ++++++------ .../Scene/computeFlyToLocationForRectangle.js | 6 +- .../engine/Source/Scene/createOsmBuildings.js | 3 +- .../engine/Source/Scene/createWorldImagery.js | 2 +- packages/engine/Source/Widget/CesiumWidget.js | 2 +- .../Specs/Scene/ImageryLayerCollectionSpec.js | 4 +- packages/widgets/Source/Viewer/Viewer.js | 8 ++- .../BaseLayerPickerViewModelSpec.js | 12 +++- packages/widgets/Specs/Viewer/ViewerSpec.js | 5 -- 39 files changed, 435 insertions(+), 362 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6cb270d52e3..9c6c7e4079f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ ##### Fixes :wrench: - Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) +- Fixed async behavior for custom terrain and imagery providers. [#11274](https://github.com/CesiumGS/cesium/issues/11274) ### 1.105.2 - 2023-05-15 diff --git a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js index 8e45da5f752..b17f5832146 100644 --- a/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js +++ b/packages/engine/Source/Core/ArcGISTiledElevationTerrainProvider.js @@ -261,7 +261,7 @@ function ArcGISTiledElevationTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "ArcGISTiledElevationTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); const that = this; @@ -345,7 +345,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { get: function () { deprecationWarning( "ArcGISTiledElevationTerrainProvider.ready", - "ArcGISTiledElevationTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "ArcGISTiledElevationTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -362,7 +362,7 @@ Object.defineProperties(ArcGISTiledElevationTerrainProvider.prototype, { get: function () { deprecationWarning( "ArcGISTiledElevationTerrainProvider.readyPromise", - "ArcGISTiledElevationTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." + "ArcGISTiledElevationTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGISTiledElevationTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/CesiumTerrainProvider.js b/packages/engine/Source/Core/CesiumTerrainProvider.js index ba7645d5e03..51f22fab750 100644 --- a/packages/engine/Source/Core/CesiumTerrainProvider.js +++ b/packages/engine/Source/Core/CesiumTerrainProvider.js @@ -535,7 +535,7 @@ function CesiumTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "CesiumTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); this._readyPromise = CesiumTerrainProvider._initializeReadyPromise( options, @@ -1087,7 +1087,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.ready", - "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -1104,7 +1104,7 @@ Object.defineProperties(CesiumTerrainProvider.prototype, { get: function () { deprecationWarning( "CesiumTerrainProvider.readyPromise", - "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." + "CesiumTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use CesiumTerrainProvider.fromIonAssetId or CesiumTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js index f6879b82abb..2836a38bb20 100644 --- a/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js +++ b/packages/engine/Source/Core/CustomHeightmapTerrainProvider.js @@ -145,7 +145,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { get: function () { deprecationWarning( "CustomHeightmapTerrainProvider.ready", - "CustomHeightmapTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "CustomHeightmapTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return true; }, @@ -162,7 +162,7 @@ Object.defineProperties(CustomHeightmapTerrainProvider.prototype, { get: function () { deprecationWarning( "CustomHeightmapTerrainProvider.readyPromise", - "CustomHeightmapTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "CustomHeightmapTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/EllipsoidTerrainProvider.js b/packages/engine/Source/Core/EllipsoidTerrainProvider.js index b9aa2ba5142..8f289c65759 100644 --- a/packages/engine/Source/Core/EllipsoidTerrainProvider.js +++ b/packages/engine/Source/Core/EllipsoidTerrainProvider.js @@ -98,7 +98,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { get: function () { deprecationWarning( "EllipsoidTerrainProvider.ready", - "EllipsoidTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "EllipsoidTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return true; }, @@ -115,7 +115,7 @@ Object.defineProperties(EllipsoidTerrainProvider.prototype, { get: function () { deprecationWarning( "EllipsoidTerrainProvider.readyPromise", - "EllipsoidTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "EllipsoidTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js index 100abc63ec1..6ac349aef1b 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseMetadata.js @@ -105,7 +105,7 @@ function GoogleEarthEnterpriseMetadata(resourceOrUrl) { if (defined(resourceOrUrl)) { deprecationWarning( "GoogleEarthEnterpriseMetadata options.url", - "GoogleEarthEnterpriseMetadata constructor parmeter resourceOrUrl was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." + "GoogleEarthEnterpriseMetadata constructor parmeter resourceOrUrl was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." ); let url = resourceOrUrl; @@ -183,7 +183,7 @@ Object.defineProperties(GoogleEarthEnterpriseMetadata.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMetadata.readyPromise", - "GoogleEarthEnterpriseMetadata.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." + "GoogleEarthEnterpriseMetadata.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseMetadata.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index ce5c3a0a4b1..f6df5b8c172 100644 --- a/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/packages/engine/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -135,7 +135,7 @@ function GoogleEarthEnterpriseTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." ); const resource = Resource.createIfNeeded(options.url); const that = this; @@ -172,7 +172,7 @@ function GoogleEarthEnterpriseTerrainProvider(options) { } else if (defined(options.metadata)) { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider options.metadata", - "options.metadata was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." + "options.metadata was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseTerrainProvider.fromMetadata instead." ); const metadata = options.metadata; this._metadata = metadata; @@ -253,7 +253,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider.ready", - "GoogleEarthEnterpriseTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "GoogleEarthEnterpriseTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._ready; }, @@ -270,7 +270,7 @@ Object.defineProperties(GoogleEarthEnterpriseTerrainProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseTerrainProvider.readyPromise", - "GoogleEarthEnterpriseTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "GoogleEarthEnterpriseTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js index 5db5f33c2c8..173ce531feb 100644 --- a/packages/engine/Source/Core/VRTheWorldTerrainProvider.js +++ b/packages/engine/Source/Core/VRTheWorldTerrainProvider.js @@ -185,7 +185,7 @@ function VRTheWorldTerrainProvider(options) { if (defined(options.url)) { deprecationWarning( "VRTheWorldTerrainProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. VRTheWorldTerrainProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. VRTheWorldTerrainProvider.fromUrl instead." ); const that = this; const terrainProviderBuilder = new TerrainProviderBuilder(options); @@ -255,7 +255,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { get: function () { deprecationWarning( "VRTheWorldTerrainProvider.ready", - "VRTheWorldTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." + "VRTheWorldTerrainProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." ); return this._ready; }, @@ -272,7 +272,7 @@ Object.defineProperties(VRTheWorldTerrainProvider.prototype, { get: function () { deprecationWarning( "VRTheWorldTerrainProvider.readyPromise", - "VRTheWorldTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." + "VRTheWorldTerrainProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use VRTheWorldTerrainProvider.fromUrl instead." ); return this._readyPromise; }, diff --git a/packages/engine/Source/Core/createWorldTerrain.js b/packages/engine/Source/Core/createWorldTerrain.js index 54790e3474a..a83733d4d01 100644 --- a/packages/engine/Source/Core/createWorldTerrain.js +++ b/packages/engine/Source/Core/createWorldTerrain.js @@ -7,6 +7,7 @@ import IonResource from "./IonResource.js"; * Creates a {@link CesiumTerrainProvider} instance for the {@link https://cesium.com/content/#cesium-world-terrain|Cesium World Terrain}. * * @function + * @deprecated * * @param {object} [options] Object with the following properties: * @param {boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. @@ -34,7 +35,7 @@ import IonResource from "./IonResource.js"; function createWorldTerrain(options) { deprecationWarning( "createWorldTerrain", - "createWorldTerrain was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use createWorldTerrainAsync instead." + "createWorldTerrain was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use createWorldTerrainAsync instead." ); options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/packages/engine/Source/Core/sampleTerrain.js b/packages/engine/Source/Core/sampleTerrain.js index 8a14cf70563..d0f46d8d01f 100644 --- a/packages/engine/Source/Core/sampleTerrain.js +++ b/packages/engine/Source/Core/sampleTerrain.js @@ -43,7 +43,11 @@ async function sampleTerrain(terrainProvider, level, positions) { //>>includeEnd('debug'); // readyPromise has been deprecated; This is here for backwards compatibility - await terrainProvider._readyPromise; + if (defined(terrainProvider._readyPromise)) { + await terrainProvider._readyPromise; + } else if (defined(terrainProvider.readyPromise)) { + await terrainProvider.readyPromise; + } return doSampling(terrainProvider, level, positions); } diff --git a/packages/engine/Source/Core/sampleTerrainMostDetailed.js b/packages/engine/Source/Core/sampleTerrainMostDetailed.js index 99146a24e1e..e99be10c51e 100644 --- a/packages/engine/Source/Core/sampleTerrainMostDetailed.js +++ b/packages/engine/Source/Core/sampleTerrainMostDetailed.js @@ -40,7 +40,11 @@ async function sampleTerrainMostDetailed(terrainProvider, positions) { const maxLevels = []; // readyPromise has been deprecated; This is here for backwards compatibility - await terrainProvider._readyPromise; + if (defined(terrainProvider._readyPromise)) { + await terrainProvider._readyPromise; + } else if (defined(terrainProvider.readyPromise)) { + await terrainProvider.readyPromise; + } const availability = terrainProvider.availability; diff --git a/packages/engine/Source/DataSources/ModelVisualizer.js b/packages/engine/Source/DataSources/ModelVisualizer.js index ce216060dd9..bf329dfb114 100644 --- a/packages/engine/Source/DataSources/ModelVisualizer.js +++ b/packages/engine/Source/DataSources/ModelVisualizer.js @@ -454,7 +454,12 @@ ModelVisualizer.prototype.getBoundingSphere = function (entity, result) { // We cannot query the availability of the terrain provider till its ready, so the // bounding sphere state will remain pending till the terrain provider is ready. // ready is deprecated. This is here for backwards compatibility - if (!terrainProvider._ready) { + if ( + defined(terrainProvider) && + (defined(terrainProvider._ready) + ? !terrainProvider._ready + : defined(terrainProvider.ready) && !terrainProvider.ready) + ) { return BoundingSphereState.PENDING; } diff --git a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js index 92d6aa3ce82..d00eb048005 100644 --- a/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/packages/engine/Source/Scene/ArcGisMapServerImageryProvider.js @@ -371,7 +371,7 @@ function ArcGisMapServerImageryProvider(options) { if (defined(options.url)) { deprecationWarning( "ArcGisMapServerImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." ); const resource = Resource.createIfNeeded(options.url); resource.appendForwardSlash(); @@ -706,7 +706,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.ready", - "ArcGisMapServerImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." + "ArcGisMapServerImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." ); return this._ready; }, @@ -723,7 +723,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.readyPromise", - "ArcGisMapServerImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." + "ArcGisMapServerImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ArcGisMapServerImageryProvider.fromUrl instead." ); return this._readyPromise; }, @@ -798,14 +798,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultAlpha", - "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultAlpha", - "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "ArcGisMapServerImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -822,14 +822,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultNightAlpha", - "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultNightAlpha", - "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "ArcGisMapServerImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -846,14 +846,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultDayAlpha", - "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultDayAlpha", - "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "ArcGisMapServerImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -870,14 +870,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultBrightness", - "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultBrightness", - "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "ArcGisMapServerImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -894,14 +894,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultContrast", - "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultContrast", - "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "ArcGisMapServerImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -917,14 +917,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultHue", - "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultHue", - "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "ArcGisMapServerImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -941,14 +941,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultSaturation", - "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultSaturation", - "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "ArcGisMapServerImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -964,14 +964,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultGamma", - "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultGamma", - "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "ArcGisMapServerImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -987,14 +987,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultMinificationFilter", - "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultMinificationFilter", - "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "ArcGisMapServerImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -1010,14 +1010,14 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, { get: function () { deprecationWarning( "ArcGisMapServerImageryProvider.defaultMagnificationFilter", - "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "ArcGisMapServerImageryProvider.defaultMagnificationFilter", - "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "ArcGisMapServerImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/BingMapsImageryProvider.js b/packages/engine/Source/Scene/BingMapsImageryProvider.js index a7236aedf47..841b8d8e850 100644 --- a/packages/engine/Source/Scene/BingMapsImageryProvider.js +++ b/packages/engine/Source/Scene/BingMapsImageryProvider.js @@ -245,7 +245,7 @@ function BingMapsImageryProvider(options) { if (defined(options.url)) { deprecationWarning( "BingMapsImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." ); //>>includeStart('debug', pragmas.debug); @@ -467,7 +467,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.ready", - "BingMapsImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." + "BingMapsImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." ); return this._ready; }, @@ -484,7 +484,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.readyPromise", - "BingMapsImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." + "BingMapsImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use BingMapsImageryProvider.fromUrl instead." ); return this._readyPromise; }, @@ -530,14 +530,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultAlpha", - "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultAlpha", - "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "BingMapsImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -554,14 +554,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultNightAlpha", - "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultNightAlpha", - "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "BingMapsImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -578,14 +578,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultDayAlpha", - "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultDayAlpha", - "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "BingMapsImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -602,14 +602,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultBrightness", - "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultBrightness", - "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "BingMapsImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -626,14 +626,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultContrast", - "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultContrast", - "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "BingMapsImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -649,14 +649,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultHue", - "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultHue", - "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "BingMapsImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -673,14 +673,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultSaturation", - "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultSaturation", - "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "BingMapsImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -696,14 +696,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultGamma", - "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultGamma", - "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "BingMapsImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -719,14 +719,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultMinificationFilter", - "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultMinificationFilter", - "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "BingMapsImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -742,14 +742,14 @@ Object.defineProperties(BingMapsImageryProvider.prototype, { get: function () { deprecationWarning( "BingMapsImageryProvider.defaultMagnificationFilter", - "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "BingMapsImageryProvider.defaultMagnificationFilter", - "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "BingMapsImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/Globe.js b/packages/engine/Source/Scene/Globe.js index 7e5007c5162..99ffc972e48 100644 --- a/packages/engine/Source/Scene/Globe.js +++ b/packages/engine/Source/Scene/Globe.js @@ -983,12 +983,16 @@ Globe.prototype.beginFrame = function (frameState) { const surface = this._surface; const tileProvider = surface.tileProvider; const terrainProvider = this.terrainProvider; + // ready is deprecated; This is here for backwards compatibility + const terrainReady = + defined(terrainProvider) && + (defined(terrainProvider._ready) + ? terrainProvider._ready + : !defined(terrainProvider.ready) || terrainProvider.ready); const hasWaterMask = this.showWaterEffect && - defined(terrainProvider) && + terrainReady && terrainProvider.hasWaterMask && - // ready is deprecated; This is here for backwards compatibility - terrainProvider._ready && terrainProvider.hasWaterMask; if (hasWaterMask && this._oceanNormalMapResourceDirty) { diff --git a/packages/engine/Source/Scene/GlobeSurfaceTile.js b/packages/engine/Source/Scene/GlobeSurfaceTile.js index 1f18d7aea76..2c718ba5deb 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTile.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTile.js @@ -346,7 +346,13 @@ GlobeSurfaceTile.prototype.processImagery = function ( if (tileImagery.loadingImagery.state === ImageryState.PLACEHOLDER) { const imageryLayer = tileImagery.loadingImagery.imageryLayer; // ImageryProvider.ready is deprecated. This is here for backwards compatibility - if (imageryLayer.ready && imageryLayer.imageryProvider._ready) { + const imageryProvider = imageryLayer.imageryProvider; + if ( + imageryLayer.ready && + (defined(imageryProvider._ready) + ? imageryProvider._ready + : !defined(imageryProvider.ready) || imageryProvider.ready) + ) { // Remove the placeholder and add the actual skeletons (if any) // at the same position. Then continue the loop at the same index. tileImagery.freeResources(); diff --git a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js index ab54cb9002a..b89933ea17b 100644 --- a/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js +++ b/packages/engine/Source/Scene/GlobeSurfaceTileProvider.js @@ -237,15 +237,32 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, { */ ready: { get: function () { - return ( - defined(this._terrainProvider) && + const terrainProvider = this._terrainProvider; + if ( + !defined(terrainProvider) || // TerrainProvider.ready is deprecated; This is here for backwards compatibility - this._terrainProvider._ready && - (this._imageryLayers.length === 0 || - // ImageryProvider.ready is deprecated; This is here for backwards compatibility - (this._imageryLayers.get(0).ready && - this._imageryLayers.get(0).imageryProvider._ready)) - ); + (defined(terrainProvider._ready) + ? !terrainProvider._ready + : defined(terrainProvider.ready) && !terrainProvider.ready) + ) { + return false; + } + + if (this._imageryLayers.length === 0) { + return true; + } + + const imageryLayer = this._imageryLayers.get(0); + if (!imageryLayer.ready) { + return false; + } + + // ImageryProvider.ready is deprecated; This is here for backwards compatibility + const imageryProvider = imageryLayer.imageryProvider; + const imageryProviderReady = defined(imageryProvider._ready) + ? imageryProvider._ready + : !defined(imageryProvider.ready) || imageryProvider.ready; + return imageryProviderReady; }, }, @@ -346,25 +363,30 @@ GlobeSurfaceTileProvider.prototype.update = function (frameState) { function updateCredits(surface, frameState) { const creditDisplay = frameState.creditDisplay; + const terrainProvider = surface._terrainProvider; if ( - defined(surface._terrainProvider) && + defined(terrainProvider) && // ready is deprecated; This is here for backwards compatibility - surface._terrainProvider._ready && - defined(surface._terrainProvider.credit) + (defined(terrainProvider._ready) + ? terrainProvider._ready + : !defined(terrainProvider.ready) || terrainProvider.ready) && + defined(terrainProvider.credit) ) { - creditDisplay.addCreditToNextFrame(surface._terrainProvider.credit); + creditDisplay.addCreditToNextFrame(terrainProvider.credit); } const imageryLayers = surface._imageryLayers; for (let i = 0, len = imageryLayers.length; i < len; ++i) { const layer = imageryLayers.get(i); - // ImageryProvider.ready is deprecated; This is here for backwards compatibility - if ( - layer.ready && - layer.imageryProvider._ready && - defined(layer.imageryProvider.credit) - ) { - creditDisplay.addCreditToNextFrame(layer.imageryProvider.credit); + if (layer.ready) { + // ImageryProvider.ready is deprecated; This is here for backwards compatibility + const imageryProvider = layer.imageryProvider; + const imageryProviderReady = defined(imageryProvider._ready) + ? imageryProvider._ready + : !defined(imageryProvider.ready) || imageryProvider.ready; + if (imageryProviderReady && defined(layer.imageryProvider.credit)) { + creditDisplay.addCreditToNextFrame(layer.imageryProvider.credit); + } } } } @@ -2144,10 +2166,13 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) { tileProvider.hasWaterMask && defined(waterMaskTexture); const oceanNormalMap = tileProvider.oceanNormalMap; const showOceanWaves = showReflectiveOcean && defined(oceanNormalMap); + const terrainProvider = tileProvider.terrainProvider; const hasVertexNormals = - defined(tileProvider.terrainProvider) && + defined(terrainProvider) && // ready is deprecated; This is here for backwards compatibility - tileProvider.terrainProvider._ready && + (defined(terrainProvider._ready) + ? terrainProvider._ready + : !defined(terrainProvider.ready) || terrainProvider.ready) && tileProvider.terrainProvider.hasVertexNormals; const enableFog = frameState.fog.enabled && frameState.fog.renderable && !cameraUnderground; diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index c0309516c3d..d1db22baaef 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -141,7 +141,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { if (defined(options.url)) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." ); const resource = Resource.createIfNeeded(options.url); metadata = new GoogleEarthEnterpriseMetadata(resource); @@ -150,7 +150,7 @@ function GoogleEarthEnterpriseImageryProvider(options) { if (defined(options.metadata)) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider options.metadata", - "options.metadata was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + "options.metadata was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." ); metadata = options.metadata; } @@ -332,7 +332,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.ready", - "GoogleEarthEnterpriseImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + "GoogleEarthEnterpriseImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." ); return this._ready; }, @@ -349,7 +349,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.readyPromise", - "GoogleEarthEnterpriseImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." + "GoogleEarthEnterpriseImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseImageryProvider.fromMetadata instead." ); return this._readyPromise; }, @@ -395,14 +395,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -419,14 +419,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -443,14 +443,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha", - "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GoogleEarthEnterpriseImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -467,14 +467,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultBrightness", - "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultBrightness", - "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GoogleEarthEnterpriseImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -491,14 +491,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultContrast", - "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultContrast", - "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GoogleEarthEnterpriseImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -514,14 +514,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultHue", - "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultHue", - "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GoogleEarthEnterpriseImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -538,14 +538,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultSaturation", - "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultSaturation", - "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GoogleEarthEnterpriseImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -561,14 +561,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultGamma", - "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultGamma", - "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GoogleEarthEnterpriseImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -584,14 +584,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter", - "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter", - "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GoogleEarthEnterpriseImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -607,14 +607,14 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter", - "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter", - "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GoogleEarthEnterpriseImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js index 06b36d5fc59..a5ac96fb485 100644 --- a/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +++ b/packages/engine/Source/Scene/GoogleEarthEnterpriseMapsProvider.js @@ -469,7 +469,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.ready", - "GoogleEarthEnterpriseMapsProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." + "GoogleEarthEnterpriseMapsProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." ); return this._ready; }, @@ -486,7 +486,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.readyPromise", - "GoogleEarthEnterpriseMapsProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." + "GoogleEarthEnterpriseMapsProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use GoogleEarthEnterpriseMapsProvider.fromUrl instead." ); return this._readyPromise; }, @@ -532,14 +532,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -556,14 +556,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -580,14 +580,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha", - "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GoogleEarthEnterpriseMapsProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -604,14 +604,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultBrightness", - "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultBrightness", - "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GoogleEarthEnterpriseMapsProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -628,14 +628,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultContrast", - "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultContrast", - "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GoogleEarthEnterpriseMapsProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -651,14 +651,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultHue", - "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultHue", - "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GoogleEarthEnterpriseMapsProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -675,14 +675,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultSaturation", - "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultSaturation", - "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GoogleEarthEnterpriseMapsProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -698,14 +698,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultGamma", - "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultGamma", - "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GoogleEarthEnterpriseMapsProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -721,14 +721,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter", - "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter", - "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GoogleEarthEnterpriseMapsProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -744,14 +744,14 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, { get: function () { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter", - "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter", - "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GoogleEarthEnterpriseMapsProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/GridImageryProvider.js b/packages/engine/Source/Scene/GridImageryProvider.js index 47388322d72..c6a8d565a4a 100644 --- a/packages/engine/Source/Scene/GridImageryProvider.js +++ b/packages/engine/Source/Scene/GridImageryProvider.js @@ -202,7 +202,7 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.ready", - "GridImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "GridImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return true; }, @@ -219,7 +219,7 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.readyPromise", - "GridImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "GridImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, @@ -265,14 +265,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultAlpha", - "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultAlpha", - "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "GridImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -289,14 +289,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultNightAlpha", - "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultNightAlpha", - "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "GridImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -313,14 +313,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultDayAlpha", - "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultDayAlpha", - "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "GridImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -337,14 +337,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultBrightness", - "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultBrightness", - "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "GridImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -361,14 +361,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultContrast", - "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultContrast", - "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "GridImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -384,14 +384,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultHue", - "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultHue", - "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "GridImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -408,14 +408,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultSaturation", - "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultSaturation", - "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "GridImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -431,14 +431,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultGamma", - "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultGamma", - "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "GridImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -454,14 +454,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultMinificationFilter", - "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultMinificationFilter", - "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "GridImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -477,14 +477,14 @@ Object.defineProperties(GridImageryProvider.prototype, { get: function () { deprecationWarning( "GridImageryProvider.defaultMagnificationFilter", - "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "GridImageryProvider.defaultMagnificationFilter", - "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "GridImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/Imagery.js b/packages/engine/Source/Scene/Imagery.js index bdcf5407f81..35c61d8f6e4 100644 --- a/packages/engine/Source/Scene/Imagery.js +++ b/packages/engine/Source/Scene/Imagery.js @@ -34,11 +34,14 @@ function Imagery(imageryLayer, x, y, level, rectangle) { this.credits = undefined; this.referenceCount = 0; - // imageryProvider._ready is deprecated; This is here for backward compatibility + const imageryProvider = imageryLayer.imageryProvider; if ( !defined(rectangle) && imageryLayer.ready && - imageryLayer.imageryProvider._ready + // imageryProvider._ready is deprecated; This is here for backward compatibility + (defined(imageryProvider._ready) + ? imageryProvider._ready + : !defined(imageryProvider.ready) || imageryProvider.ready) ) { const tilingScheme = imageryLayer.imageryProvider.tilingScheme; rectangle = tilingScheme.tileXYToRectangle(x, y, level); diff --git a/packages/engine/Source/Scene/ImageryLayer.js b/packages/engine/Source/Scene/ImageryLayer.js index 0e41bf62b0e..a97809beee1 100644 --- a/packages/engine/Source/Scene/ImageryLayer.js +++ b/packages/engine/Source/Scene/ImageryLayer.js @@ -690,7 +690,12 @@ ImageryLayer.prototype.getViewableRectangle = async function () { const imageryProvider = this._imageryProvider; const rectangle = this._rectangle; // readyPromise has been deprecated. This is here for backward compatibility and can be removed with readyPromise. - await imageryProvider._readyPromise; + if (defined(imageryProvider._readyPromise)) { + await imageryProvider._readyPromise; + } else if (defined(imageryProvider.readyPromise)) { + await imageryProvider.readyPromise; + } + return Rectangle.intersection(imageryProvider.rectangle, rectangle); }; @@ -751,8 +756,13 @@ ImageryLayer.prototype._createTileImagerySkeletons = function ( } const imageryProvider = this._imageryProvider; - // ready is deprecated. This is here for backwards compatibility - if (!this.ready || !imageryProvider._ready) { + if ( + !this.ready || + // ready is deprecated. This is here for backwards compatibility + (defined(imageryProvider._ready) + ? !imageryProvider._ready + : defined(imageryProvider.ready) && !imageryProvider.ready) + ) { // The imagery provider is not ready, so we can't create skeletons, yet. // Instead, add a placeholder so that we'll know to create // the skeletons once the provider is ready. diff --git a/packages/engine/Source/Scene/IonImageryProvider.js b/packages/engine/Source/Scene/IonImageryProvider.js index 52bc8491510..959c6a95f6f 100644 --- a/packages/engine/Source/Scene/IonImageryProvider.js +++ b/packages/engine/Source/Scene/IonImageryProvider.js @@ -123,7 +123,7 @@ function IonImageryProvider(options) { if (defined(assetId)) { deprecationWarning( "IonImageryProvider options.assetId", - "options.assetId was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." + "options.assetId was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." ); IonImageryProvider._initialize(this, assetId, options); @@ -142,7 +142,7 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.ready", - "IonImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." + "IonImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." ); return this._ready; }, @@ -159,7 +159,7 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.readyPromise", - "IonImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." + "IonImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use IonImageryProvider.fromAssetId instead." ); return this._readyPromise; }, @@ -322,14 +322,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultAlpha", - "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultAlpha", - "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "IonImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -346,14 +346,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultNightAlpha", - "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultNightAlpha", - "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "IonImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -370,14 +370,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultDayAlpha", - "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultDayAlpha", - "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "IonImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -394,14 +394,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultBrightness", - "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultBrightness", - "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "IonImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -418,14 +418,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultContrast", - "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultContrast", - "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "IonImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -441,14 +441,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultHue", - "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultHue", - "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "IonImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -465,14 +465,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultSaturation", - "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultSaturation", - "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "IonImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -488,14 +488,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultGamma", - "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultGamma", - "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "IonImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -511,14 +511,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultMinificationFilter", - "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultMinificationFilter", - "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "IonImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -534,14 +534,14 @@ Object.defineProperties(IonImageryProvider.prototype, { get: function () { deprecationWarning( "IonImageryProvider.defaultMagnificationFilter", - "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "IonImageryProvider.defaultMagnificationFilter", - "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "IonImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/MapboxImageryProvider.js b/packages/engine/Source/Scene/MapboxImageryProvider.js index 22de51aa1ec..ab96e97eb67 100644 --- a/packages/engine/Source/Scene/MapboxImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxImageryProvider.js @@ -146,7 +146,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.ready", - "MapboxImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "MapboxImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._imageryProvider.ready; }, @@ -163,7 +163,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.readyPromise", - "MapboxImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "MapboxImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._imageryProvider._readyPromise; }, @@ -325,14 +325,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultAlpha", - "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultAlpha", - "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "MapboxImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -349,14 +349,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultNightAlpha", - "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this.defaultNightAlpha; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultNightAlpha", - "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "MapboxImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this.defaultNightAlpha = value; }, @@ -373,14 +373,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultDayAlpha", - "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultDayAlpha", - "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "MapboxImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -397,14 +397,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultBrightness", - "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultBrightness", - "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "MapboxImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -421,14 +421,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultContrast", - "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultContrast", - "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "MapboxImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -444,14 +444,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultHue", - "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultHue", - "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "MapboxImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -468,14 +468,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultSaturation", - "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultSaturation", - "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "MapboxImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -491,14 +491,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultGamma", - "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultGamma", - "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "MapboxImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -514,14 +514,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultMinificationFilter", - "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultMinificationFilter", - "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "MapboxImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -537,14 +537,14 @@ Object.defineProperties(MapboxImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxImageryProvider.defaultMagnificationFilter", - "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "MapboxImageryProvider.defaultMagnificationFilter", - "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "MapboxImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js index 41100453e90..08ddc1339c0 100644 --- a/packages/engine/Source/Scene/MapboxStyleImageryProvider.js +++ b/packages/engine/Source/Scene/MapboxStyleImageryProvider.js @@ -150,7 +150,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.ready", - "MapboxStyleImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "MapboxStyleImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._imageryProvider.ready; }, @@ -167,7 +167,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.readyPromise", - "MapboxStyleImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "MapboxStyleImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._imageryProvider.readyPromise; }, @@ -329,14 +329,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultAlpha", - "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultAlpha", - "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "MapboxStyleImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -353,14 +353,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultNightAlpha", - "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultNightAlpha", - "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "MapboxStyleImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -377,14 +377,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultDayAlpha", - "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultDayAlpha", - "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "MapboxStyleImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -401,14 +401,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultBrightness", - "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultBrightness", - "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "MapboxStyleImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -425,14 +425,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultContrast", - "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultContrast", - "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "MapboxStyleImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -448,14 +448,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultHue", - "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultHue", - "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "MapboxStyleImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -472,14 +472,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultSaturation", - "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultSaturation", - "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "MapboxStyleImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -495,14 +495,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultGamma", - "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultGamma", - "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "MapboxStyleImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -518,14 +518,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultMinificationFilter", - "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultMinificationFilter", - "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "MapboxStyleImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -541,14 +541,14 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, { get: function () { deprecationWarning( "MapboxStyleImageryProvider.defaultMagnificationFilter", - "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "MapboxStyleImageryProvider.defaultMagnificationFilter", - "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "MapboxStyleImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/SingleTileImageryProvider.js b/packages/engine/Source/Scene/SingleTileImageryProvider.js index b2096be5724..4b5e3cf3d42 100644 --- a/packages/engine/Source/Scene/SingleTileImageryProvider.js +++ b/packages/engine/Source/Scene/SingleTileImageryProvider.js @@ -253,7 +253,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.ready", - "SingleTileImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use SingleTileImageryProvider.fromUrl instead." + "SingleTileImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use SingleTileImageryProvider.fromUrl instead." ); return this._ready; }, @@ -270,7 +270,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.readyPromise", - "SingleTileImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use SingleTileImageryProvider.fromUrl instead." + "SingleTileImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use SingleTileImageryProvider.fromUrl instead." ); return this._readyPromise; }, @@ -316,14 +316,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultAlpha", - "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultAlpha", - "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "SingleTileImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -340,14 +340,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultNightAlpha", - "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultNightAlpha", - "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "SingleTileImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -364,14 +364,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultDayAlpha", - "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultDayAlpha", - "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "SingleTileImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -388,14 +388,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultBrightness", - "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultBrightness", - "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "SingleTileImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -412,14 +412,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultContrast", - "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultContrast", - "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "SingleTileImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -435,14 +435,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultHue", - "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultHue", - "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "SingleTileImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -459,14 +459,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultSaturation", - "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultSaturation", - "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "SingleTileImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -482,14 +482,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultGamma", - "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultGamma", - "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "SingleTileImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -505,14 +505,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultMinificationFilter", - "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultMinificationFilter", - "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "SingleTileImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -528,14 +528,14 @@ Object.defineProperties(SingleTileImageryProvider.prototype, { get: function () { deprecationWarning( "SingleTileImageryProvider.defaultMagnificationFilter", - "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "SingleTileImageryProvider.defaultMagnificationFilter", - "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "SingleTileImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js index e12542af893..641c80aaed3 100644 --- a/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js +++ b/packages/engine/Source/Scene/TileCoordinatesImageryProvider.js @@ -178,7 +178,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.ready", - "TileCoordinatesImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "TileCoordinatesImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return true; }, @@ -195,7 +195,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.readyPromise", - "TileCoordinatesImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "TileCoordinatesImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, @@ -241,14 +241,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultAlpha", - "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultAlpha", - "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "TileCoordinatesImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -265,14 +265,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultNightAlpha", - "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultNightAlpha", - "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "TileCoordinatesImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -289,14 +289,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultDayAlpha", - "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultDayAlpha", - "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "TileCoordinatesImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -313,14 +313,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultBrightness", - "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultBrightness", - "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "TileCoordinatesImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -337,14 +337,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultContrast", - "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultContrast", - "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "TileCoordinatesImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -360,14 +360,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultHue", - "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultHue", - "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "TileCoordinatesImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -384,14 +384,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultSaturation", - "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultSaturation", - "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "TileCoordinatesImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -407,14 +407,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultGamma", - "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultGamma", - "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "TileCoordinatesImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -430,14 +430,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultMinificationFilter", - "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultMinificationFilter", - "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "TileCoordinatesImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -453,14 +453,14 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, { get: function () { deprecationWarning( "TileCoordinatesImageryProvider.defaultMagnificationFilter", - "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "TileCoordinatesImageryProvider.defaultMagnificationFilter", - "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "TileCoordinatesImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js index e4db25f32ad..37e2fe49376 100644 --- a/packages/engine/Source/Scene/TileMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/TileMapServiceImageryProvider.js @@ -81,7 +81,7 @@ function TileMapServiceImageryProvider(options) { if (defined(options.url)) { deprecationWarning( "TileMapServiceImageryProvider options.url", - "options.url was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use TileMapServiceImageryProvider.fromUrl instead." + "options.url was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use TileMapServiceImageryProvider.fromUrl instead." ); this._metadataError = undefined; diff --git a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js index 8c6a67ca6c7..5c654f21a45 100644 --- a/packages/engine/Source/Scene/UrlTemplateImageryProvider.js +++ b/packages/engine/Source/Scene/UrlTemplateImageryProvider.js @@ -493,7 +493,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.ready", - "UrlTemplateImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "UrlTemplateImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._ready && defined(this._resource); }, @@ -510,7 +510,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.readyPromise", - "UrlTemplateImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "UrlTemplateImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, @@ -558,14 +558,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultAlpha", - "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultAlpha", - "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "UrlTemplateImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -582,14 +582,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultNightAlpha", - "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultNightAlpha", - "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "UrlTemplateImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -606,14 +606,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultDayAlpha", - "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultDayAlpha", - "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "UrlTemplateImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -630,14 +630,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultBrightness", - "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultBrightness", - "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "UrlTemplateImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -654,14 +654,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultContrast", - "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultContrast", - "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "UrlTemplateImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -677,14 +677,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultHue", - "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultHue", - "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "UrlTemplateImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -701,14 +701,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultSaturation", - "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultSaturation", - "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "UrlTemplateImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -724,14 +724,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultGamma", - "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultGamma", - "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "UrlTemplateImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -747,14 +747,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultMinificationFilter", - "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultMinificationFilter", - "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "UrlTemplateImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -770,14 +770,14 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { get: function () { deprecationWarning( "UrlTemplateImageryProvider.defaultMagnificationFilter", - "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "UrlTemplateImageryProvider.defaultMagnificationFilter", - "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "UrlTemplateImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, @@ -794,7 +794,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, { UrlTemplateImageryProvider.prototype.reinitialize = function (options) { deprecationWarning( "UrlTemplateImageryProvider.reinitialize", - "UrlTemplateImageryProvider.reinitialize was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "UrlTemplateImageryProvider.reinitialize was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._reinitialize(options); diff --git a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js index 04e1a284034..949357a5e58 100644 --- a/packages/engine/Source/Scene/WebMapServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapServiceImageryProvider.js @@ -449,7 +449,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.ready", - "WebMapServiceImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "WebMapServiceImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._tileProvider.ready; }, @@ -466,7 +466,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.readyPromise", - "WebMapServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "WebMapServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._tileProvider.readyPromise; }, @@ -572,14 +572,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultAlpha", - "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultAlpha", - "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "WebMapServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -596,14 +596,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultNightAlpha", - "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultNightAlpha", - "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "WebMapServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -620,14 +620,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultDayAlpha", - "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultDayAlpha", - "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "WebMapServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -644,14 +644,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultBrightness", - "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultBrightness", - "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "WebMapServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -668,14 +668,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultContrast", - "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultContrast", - "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "WebMapServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -691,14 +691,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultHue", - "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultHue", - "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "WebMapServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -715,14 +715,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultSaturation", - "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultSaturation", - "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "WebMapServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -738,14 +738,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultGamma", - "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultGamma", - "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "WebMapServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -761,14 +761,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultMinificationFilter", - "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultMinificationFilter", - "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "WebMapServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -784,14 +784,14 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapServiceImageryProvider.defaultMagnificationFilter", - "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "WebMapServiceImageryProvider.defaultMagnificationFilter", - "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "WebMapServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js index 28a4cd3f6dd..8e12a61069e 100644 --- a/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js +++ b/packages/engine/Source/Scene/WebMapTileServiceImageryProvider.js @@ -461,7 +461,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.ready", - "WebMapTileServiceImageryProvider.ready was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "WebMapTileServiceImageryProvider.ready was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return true; }, @@ -478,7 +478,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.readyPromise", - "WebMapTileServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107." + "WebMapTileServiceImageryProvider.readyPromise was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107." ); return this._readyPromise; }, @@ -570,14 +570,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultAlpha", - "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); return this._defaultAlpha; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultAlpha", - "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.alpha instead." + "WebMapTileServiceImageryProvider.defaultAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.alpha instead." ); this._defaultAlpha = value; }, @@ -594,14 +594,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultNightAlpha", - "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); return this._defaultNightAlpha; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultNightAlpha", - "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." + "WebMapTileServiceImageryProvider.defaultNightAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.nightAlpha instead." ); this._defaultNightAlpha = value; }, @@ -618,14 +618,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultDayAlpha", - "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); return this._defaultDayAlpha; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultDayAlpha", - "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." + "WebMapTileServiceImageryProvider.defaultDayAlpha was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.dayAlpha instead." ); this._defaultDayAlpha = value; }, @@ -642,14 +642,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultBrightness", - "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); return this._defaultBrightness; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultBrightness", - "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.brightness instead." + "WebMapTileServiceImageryProvider.defaultBrightness was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.brightness instead." ); this._defaultBrightness = value; }, @@ -666,14 +666,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultContrast", - "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); return this._defaultContrast; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultContrast", - "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.contrast instead." + "WebMapTileServiceImageryProvider.defaultContrast was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.contrast instead." ); this._defaultContrast = value; }, @@ -689,14 +689,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultHue", - "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); return this._defaultHue; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultHue", - "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.hue instead." + "WebMapTileServiceImageryProvider.defaultHue was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.hue instead." ); this._defaultHue = value; }, @@ -713,14 +713,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultSaturation", - "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); return this._defaultSaturation; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultSaturation", - "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.saturation instead." + "WebMapTileServiceImageryProvider.defaultSaturation was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.saturation instead." ); this._defaultSaturation = value; }, @@ -736,14 +736,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultGamma", - "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); return this._defaultGamma; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultGamma", - "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.gamma instead." + "WebMapTileServiceImageryProvider.defaultGamma was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.gamma instead." ); this._defaultGamma = value; }, @@ -759,14 +759,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultMinificationFilter", - "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); return this._defaultMinificationFilter; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultMinificationFilter", - "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." + "WebMapTileServiceImageryProvider.defaultMinificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.minificationFilter instead." ); this._defaultMinificationFilter = value; }, @@ -782,14 +782,14 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, { get: function () { deprecationWarning( "WebMapTileServiceImageryProvider.defaultMagnificationFilter", - "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); return this._defaultMagnificationFilter; }, set: function (value) { deprecationWarning( "WebMapTileServiceImageryProvider.defaultMagnificationFilter", - "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." + "WebMapTileServiceImageryProvider.defaultMagnificationFilter was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use ImageryLayer.magnificationFilter instead." ); this._defaultMagnificationFilter = value; }, diff --git a/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js b/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js index 9fec202c25c..0df36de079e 100644 --- a/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js +++ b/packages/engine/Source/Scene/computeFlyToLocationForRectangle.js @@ -32,7 +32,11 @@ async function computeFlyToLocationForRectangle(rectangle, scene) { } // readyPromise has been deprecated; This is here for backwards compatibility - await terrainProvider._readyPromise; + if (defined(terrainProvider._readyPromise)) { + await terrainProvider._readyPromise; + } else if (defined(terrainProvider.readyPromise)) { + await terrainProvider.readyPromise; + } const availability = terrainProvider.availability; if (!defined(availability) || scene.mode === SceneMode.SCENE2D) { diff --git a/packages/engine/Source/Scene/createOsmBuildings.js b/packages/engine/Source/Scene/createOsmBuildings.js index 5e7f8286ab6..a4943c58725 100644 --- a/packages/engine/Source/Scene/createOsmBuildings.js +++ b/packages/engine/Source/Scene/createOsmBuildings.js @@ -13,6 +13,7 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; * tileset. * * @function + * @deprecated * * @param {object} [options] Construction options. Any options allowed by the {@link Cesium3DTileset} constructor * may be specified here. In addition to those, the following properties are supported: @@ -52,7 +53,7 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js"; function createOsmBuildings(options) { deprecationWarning( "createOsmBuildings", - "createOsmBuildings was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use createOsmBuildingsAsync instead." + "createOsmBuildings was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use createOsmBuildingsAsync instead." ); options = combine(options, { diff --git a/packages/engine/Source/Scene/createWorldImagery.js b/packages/engine/Source/Scene/createWorldImagery.js index 54af66b8c23..2494a88f081 100644 --- a/packages/engine/Source/Scene/createWorldImagery.js +++ b/packages/engine/Source/Scene/createWorldImagery.js @@ -33,7 +33,7 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js"; function createWorldImagery(options) { deprecationWarning( "createWorldImagery", - "createWorldImagery was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use createWorldImageryAsync instead." + "createWorldImagery was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use createWorldImageryAsync instead." ); options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/packages/engine/Source/Widget/CesiumWidget.js b/packages/engine/Source/Widget/CesiumWidget.js index 994857c2674..8d3f2f71774 100644 --- a/packages/engine/Source/Widget/CesiumWidget.js +++ b/packages/engine/Source/Widget/CesiumWidget.js @@ -346,7 +346,7 @@ function CesiumWidget(container, options) { if (defined(options.imageryProvider)) { deprecationWarning( "CesiumWidget options.imageryProvider", - "options.imageryProvider was deprecated in CesiumJS 1.104. It will be in CesiumJS 1.107. Use options.baseLayer instead." + "options.imageryProvider was deprecated in CesiumJS 1.104. It will be removed in CesiumJS 1.107. Use options.baseLayer instead." ); } diff --git a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js index d37f669aa22..ef2318dea35 100644 --- a/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js +++ b/packages/engine/Specs/Scene/ImageryLayerCollectionSpec.js @@ -22,9 +22,7 @@ describe( "Scene/ImageryLayerCollection", function () { const fakeProvider = { - isReady: function () { - return false; - }, + ready: false, }; it("tracks the base layer on add", function () { diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index 00c320b3a99..f9c2c7ba12a 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2153,7 +2153,13 @@ function zoomToOrFly(that, zoomTarget, options, isFlight) { if (defined(zoomTarget.imageryProvider)) { // This is here for backward compatibility. It can be removed when readyPromise is removed. - rectanglePromise = zoomTarget.imageryProvider._readyPromise.then(() => { + let promise = Promise.resolve(); + if (defined(zoomTarget.imageryProvider)) { + promise = zoomTarget.imageryProvider._readyPromise; + } else if (defined(zoomTarget.imageryProvider.readyPromise)) { + promise = zoomTarget.imageryProvider.readyPromise; + } + rectanglePromise = promise.then(() => { return zoomTarget.getImageryRectangle(); }); } else { diff --git a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js index 2c02225b836..3a3ea3dc8b1 100644 --- a/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js +++ b/packages/widgets/Specs/BaseLayerPicker/BaseLayerPickerViewModelSpec.js @@ -15,9 +15,15 @@ describe("Widgets/BaseLayerPicker/BaseLayerPickerViewModel", function () { } MockGlobe.prototype.isDestroyed = () => false; - const testProvider = {}; - const testProvider2 = {}; - const testProvider3 = {}; + const testProvider = { + ready: false, + }; + const testProvider2 = { + ready: false, + }; + const testProvider3 = { + ready: false, + }; const testProviderViewModel = new ProviderViewModel({ name: "name", diff --git a/packages/widgets/Specs/Viewer/ViewerSpec.js b/packages/widgets/Specs/Viewer/ViewerSpec.js index 35546b38641..53475eb2d0a 100644 --- a/packages/widgets/Specs/Viewer/ViewerSpec.js +++ b/packages/widgets/Specs/Viewer/ViewerSpec.js @@ -58,12 +58,7 @@ describe( function () { const readyPromise = Promise.resolve(true); const testProvider = { - isReady: function () { - return false; - }, - _ready: true, ready: true, - _readyPromise: readyPromise, readyPromise: readyPromise, tilingScheme: { tileXYToRectangle: function () { From 6418099880a6ebe79befd5a1fa49edee890735bd Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Fri, 26 May 2023 10:38:20 -0400 Subject: [PATCH 673/679] Fix readyPromise condition --- packages/widgets/Source/Viewer/Viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/widgets/Source/Viewer/Viewer.js b/packages/widgets/Source/Viewer/Viewer.js index f9c2c7ba12a..5d9c10003d8 100644 --- a/packages/widgets/Source/Viewer/Viewer.js +++ b/packages/widgets/Source/Viewer/Viewer.js @@ -2154,7 +2154,7 @@ function zoomToOrFly(that, zoomTarget, options, isFlight) { if (defined(zoomTarget.imageryProvider)) { // This is here for backward compatibility. It can be removed when readyPromise is removed. let promise = Promise.resolve(); - if (defined(zoomTarget.imageryProvider)) { + if (defined(zoomTarget.imageryProvider._readyPromise)) { promise = zoomTarget.imageryProvider._readyPromise; } else if (defined(zoomTarget.imageryProvider.readyPromise)) { promise = zoomTarget.imageryProvider.readyPromise; From c2f7e64ef8a3539a740ede97e5173fba2297f167 Mon Sep 17 00:00:00 2001 From: Gabby Getz Date: Tue, 30 May 2023 14:53:36 -0400 Subject: [PATCH 674/679] Fix for zoom on tracked entity --- CHANGES.md | 1 + .../Scene/ScreenSpaceCameraController.js | 3 +- .../Scene/ScreenSpaceCameraControllerSpec.js | 68 ++++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6e8e01a1515..21f3524b280 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ ##### Fixes :wrench: +- Fixed tracked entity camera controls. [#11286](https://github.com/CesiumGS/cesium/issues/11286) - Fixed color creation from CSS color string with modern "space-separated" syntax. [#11271](https://github.com/CesiumGS/cesium/pull/11271) - Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) - Fixed async behavior for custom terrain and imagery providers. [#11274](https://github.com/CesiumGS/cesium/issues/11274) diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index d83065068c2..38fda58fde8 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -613,6 +613,7 @@ function handleZoom( object._zoomMouseStart ); + // When camera transform is set, such as tracking an entity, object._globe will be undefined, and no position should be picked if (defined(object._globe) && mode === SceneMode.SCENE2D) { pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay) .origin; @@ -621,7 +622,7 @@ function handleZoom( pickedPosition.z, pickedPosition.x ); - } else { + } else if (defined(object._globe)) { pickedPosition = pickPosition( object, startPosition, diff --git a/packages/engine/Specs/Scene/ScreenSpaceCameraControllerSpec.js b/packages/engine/Specs/Scene/ScreenSpaceCameraControllerSpec.js index 4e784b06d7e..f4d3fadca56 100644 --- a/packages/engine/Specs/Scene/ScreenSpaceCameraControllerSpec.js +++ b/packages/engine/Specs/Scene/ScreenSpaceCameraControllerSpec.js @@ -929,7 +929,7 @@ describe("Scene/ScreenSpaceCameraController", function () { ); }); - it("rotates in Columus view with camera transform set", function () { + it("rotates in Columbus view with camera transform set", function () { setUpCV(); const origin = Cartesian3.fromDegrees(-72.0, 40.0); @@ -983,7 +983,7 @@ describe("Scene/ScreenSpaceCameraController", function () { expect(camera.position).not.toEqual(position); }); - it("zooms in Columus view with camera transform set", function () { + it("zooms in Columbus view with camera transform set", function () { setUpCV(); const origin = Cartesian3.fromDegrees(-72.0, 40.0); @@ -1198,6 +1198,70 @@ describe("Scene/ScreenSpaceCameraController", function () { ); }); + it("zooms in on an object in 3D", function () { + setUp3D(); + + scene.globe = new MockGlobe(scene.mapProjection.ellipsoid); + + updateController(); + + const origin = Cartesian3.fromDegrees(-72.0, 40.0, 1.0); + camera.setView({ + destination: origin, + }); + + updateController(); + + scene.pickPositionSupported = true; + scene.pickPositionWorldCoordinates = () => + Cartesian3.fromDegrees(-72.0, 40.0, -10.0); + + const position = Cartesian3.clone(camera.position); + const startPosition = new Cartesian2(0, 0); + const endPosition = new Cartesian2(0, canvas.clientHeight / 2); + + moveMouse(MouseButtons.RIGHT, startPosition, endPosition); + + updateController(); + + expect(Cartesian3.magnitude(position)).toBeGreaterThan( + Cartesian3.magnitude(camera.position) + ); + }); + + it("zooms in on an object in 3D when transform is set", function () { + setUp3D(); + + scene.globe = new MockGlobe(scene.mapProjection.ellipsoid); + + updateController(); + + const origin = Cartesian3.fromDegrees(-72.0, 40.0, 1.0); + camera.lookAtTransform(Transforms.eastNorthUpToFixedFrame(origin), { + heading: 0, + pitch: 0, + range: 10, + }); + + updateController(); + + scene.pickPositionSupported = true; + scene.pickPositionWorldCoordinates = () => + Cartesian3.fromDegrees(-72.0, 40.0, -10.0); + + const position = Cartesian3.clone(camera.position); + const startPosition = new Cartesian2(0, 0); + const endPosition = new Cartesian2(0, canvas.clientHeight / 2); + + moveMouse(MouseButtons.RIGHT, startPosition, endPosition); + + updateController(); + + expect(Cartesian3.magnitude(position)).toBeGreaterThan( + Cartesian3.magnitude(camera.position) + ); + }); + it("zoom in 3D to point 0,0", function () { setUp3D(); scene.globe = new MockGlobe(scene.mapProjection.ellipsoid); From b741605f4eda735e03471b35b086dc89ef501fe7 Mon Sep 17 00:00:00 2001 From: IKangXu Date: Wed, 31 May 2023 22:03:25 +0800 Subject: [PATCH 675/679] Fixed label background rendering. (#11293) * Fixed label background rendering. * Add IKangXu (@IKangXu) to the list of contributors and update changes.md * Update CHANGES.md * Fix background image for label --------- Co-authored-by: IKangXu --- CHANGES.md | 1 + CONTRIBUTORS.md | 1 + packages/engine/Source/Scene/Billboard.js | 7 ------- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6e8e01a1515..b959e2604ee 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ - Fixed color creation from CSS color string with modern "space-separated" syntax. [#11271](https://github.com/CesiumGS/cesium/pull/11271) - Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) - Fixed async behavior for custom terrain and imagery providers. [#11274](https://github.com/CesiumGS/cesium/issues/11274) +- Fixed label background rendering. [#11293](https://github.com/CesiumGS/cesium/pull/11293) ### 1.105.2 - 2023-05-15 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d3ec9028d35..95d2c34a366 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -358,3 +358,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu - [Jason Summercamp](https://github.com/fullstacc) - [Shapovalov Kirill](https://github.com/ShapovalovKL) - [Alexander Popoff](https://github.com/aerialist7) +- [IKangXu](https://github.com/IKangXu) diff --git a/packages/engine/Source/Scene/Billboard.js b/packages/engine/Source/Scene/Billboard.js index 4035cda8d00..45e005cd41a 100644 --- a/packages/engine/Source/Scene/Billboard.js +++ b/packages/engine/Source/Scene/Billboard.js @@ -1169,13 +1169,6 @@ Billboard.prototype._loadImage = function () { } if (defined(image)) { - // No need to wait on imageIndexPromise since these have already been added to the atlas - const index = atlas.getImageIndex(imageId); - if (defined(index)) { - completeImageLoad(index); - return; - } - imageIndexPromise = atlas.addImage(imageId, image); } if (defined(imageSubRegion)) { From b2d169d75e8c9e5cf6cda018f802cc18a860ebc1 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd <41167620+jjhembd@users.noreply.github.com> Date: Thu, 1 Jun 2023 11:33:17 -0500 Subject: [PATCH 676/679] dependency updates (#11325) * Update dependencies * Update tween.js * Revert tween.js version (see #11324) * Revert dependency changes that only affected patch versions --------- Co-authored-by: Jeshurun Hembd --- package.json | 16 ++++++++-------- packages/engine/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index dc2bc145676..b9f2d3bc071 100644 --- a/package.json +++ b/package.json @@ -55,10 +55,10 @@ "@cesium/widgets": "2.3.0" }, "devDependencies": { - "@aws-sdk/client-s3": "^3.276.0", - "@aws-sdk/lib-storage": "^3.276.0", - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.0.1", + "@aws-sdk/client-s3": "^3.342.0", + "@aws-sdk/lib-storage": "^3.342.0", + "@rollup/plugin-commonjs": "^25.0.0", + "@rollup/plugin-node-resolve": "^15.1.0", "@rollup/plugin-terser": "^0.4.0", "chokidar": "^3.5.3", "cloc": "^2.8.0", @@ -67,7 +67,7 @@ "download": "^8.0.0", "draco3d": "^1.5.1", "esbuild": "^0.17.10", - "eslint": "^8.29.0", + "eslint": "^8.41.0", "eslint-config-cesium": "^9.0.1", "eslint-config-prettier": "^8.3.0", "eslint-plugin-es": "^4.1.0", @@ -99,7 +99,7 @@ "karma-safari-launcher": "^1.0.0", "karma-sourcemap-loader": "^0.4.0", "karma-spec-reporter": "^0.0.36", - "markdownlint-cli": "^0.33.0", + "markdownlint-cli": "^0.34.0", "merge-stream": "^2.0.0", "mime": "^3.0.0", "mkdirp": "^3.0.1", @@ -110,7 +110,7 @@ "prismjs": "^1.28.0", "request": "^2.79.0", "rimraf": "^5.0.0", - "rollup": "^3.17.2", + "rollup": "^3.23.0", "rollup-plugin-strip-pragma": "^1.0.0", "stream-to-promise": "^3.0.0", "tsd-jsdoc": "^2.5.0", @@ -167,4 +167,4 @@ "packages/engine", "packages/widgets" ] -} \ No newline at end of file +} diff --git a/packages/engine/package.json b/packages/engine/package.json index fa18c9a2f23..83cd4178fe7 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -44,7 +44,7 @@ "ktx-parse": "^0.5.0", "lerc": "^2.0.0", "mersenne-twister": "^1.1.0", - "meshoptimizer": "^0.18.1", + "meshoptimizer": "^0.19.0", "pako": "^2.0.4", "protobufjs": "^7.1.0", "rbush": "^3.0.1", From d11b746e5809ac115fcff65b7b0c6bdfe81dcf1c Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Wed, 31 May 2023 18:08:12 -0400 Subject: [PATCH 677/679] Updates for 1.106 release --- CHANGES.md | 4 ++-- ThirdParty.json | 4 ++-- package.json | 4 ++-- packages/engine/Source/Core/GoogleMaps.js | 2 +- packages/engine/Source/Core/Ion.js | 3 ++- packages/engine/Source/Scene/ArcGisMapService.js | 2 +- packages/engine/package.json | 2 +- packages/widgets/package.json | 2 +- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 102247f3bd6..61d4f0d2f5a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,11 +6,11 @@ ##### Fixes :wrench: -- Fixed tracked entity camera controls. [#11286](https://github.com/CesiumGS/cesium/issues/11286) +- Fixed label background rendering. [#11293](https://github.com/CesiumGS/cesium/pull/11293) - Fixed color creation from CSS color string with modern "space-separated" syntax. [#11271](https://github.com/CesiumGS/cesium/pull/11271) +- Fixed tracked entity camera controls. [#11286](https://github.com/CesiumGS/cesium/issues/11286) - Fixed a race condition when loading cut-out terrain. [#11296](https://github.com/CesiumGS/cesium/pull/11296) - Fixed async behavior for custom terrain and imagery providers. [#11274](https://github.com/CesiumGS/cesium/issues/11274) -- Fixed label background rendering. [#11293](https://github.com/CesiumGS/cesium/pull/11293) ### 1.105.2 - 2023-05-15 diff --git a/ThirdParty.json b/ThirdParty.json index a3c3deaacb0..b24426296e4 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -36,7 +36,7 @@ "license": [ "Apache-2.0" ], - "version": "3.0.2", + "version": "3.0.3", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -125,7 +125,7 @@ "license": [ "MIT" ], - "version": "0.18.1", + "version": "0.19.0", "url": "https://www.npmjs.com/package/meshoptimizer" }, { diff --git a/package.json b/package.json index b9f2d3bc071..cff8250c992 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.105.2", + "version": "1.106.0", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.4.0", + "@cesium/engine": "2.4.1", "@cesium/widgets": "2.3.0" }, "devDependencies": { diff --git a/packages/engine/Source/Core/GoogleMaps.js b/packages/engine/Source/Core/GoogleMaps.js index e5ae75f2068..4e4258ef511 100644 --- a/packages/engine/Source/Core/GoogleMaps.js +++ b/packages/engine/Source/Core/GoogleMaps.js @@ -3,7 +3,7 @@ import defined from "./defined.js"; import Resource from "./Resource.js"; let defaultKeyCredit; -const defaultKey = "AIzaSyBESBYnp1EcqtlAcjMTJ65GjUsJtaCWVXA"; +const defaultKey = "AIzaSyBqCv5lozjjhtIQ_pZuj2obyAL9bTJdY28"; /** * Default settings for accessing the Google Maps API. diff --git a/packages/engine/Source/Core/Ion.js b/packages/engine/Source/Core/Ion.js index db3e3ff4b96..27af813acfb 100644 --- a/packages/engine/Source/Core/Ion.js +++ b/packages/engine/Source/Core/Ion.js @@ -4,7 +4,8 @@ import Resource from "./Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwZWQ3OWFlZC1kOTg3LTRlZjctYTAyYy0xNjFmODE1MWE2NGUiLCJpZCI6MjU5LCJpYXQiOjE2ODI5NDYzODh9.DEH4GpqliH-xsDE7h-ZCICtHgnGu32wdSjt4hFqw7lU"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmYmE2YWEzOS1lZDUyLTQ0YWMtOTlkNS0wN2VhZWI3NTc4MmEiLCJpZCI6MjU5LCJpYXQiOjE2ODU2MzQ0Njl9.AswCMxsN03WYwuZL-r183OZicN64Ks9aPExWhA3fuLY"; + /** * Default settings for accessing the Cesium ion API. * diff --git a/packages/engine/Source/Scene/ArcGisMapService.js b/packages/engine/Source/Scene/ArcGisMapService.js index 8beb63a0a6c..de42dcb11b1 100644 --- a/packages/engine/Source/Scene/ArcGisMapService.js +++ b/packages/engine/Source/Scene/ArcGisMapService.js @@ -4,7 +4,7 @@ import Resource from "../Core/Resource.js"; let defaultTokenCredit; const defaultAccessToken = - "AAPKd815e334cb774973b7245e23a67f4d08Js7A8e8xvfBpgnZIzp1jbL3FWJTmx7AKG8wa87OwDcWEu4CxQCNiydpPbGpALiTf"; + "AAPKac82a6d80f1340a4aa9587f789d07e96a_Jj1a4fbA59cggYHArDizxxA2U4QDofLUm36VivpUsSRyK7O1JjRPwy916Y-7ld"; /** * Default options for accessing the ArcGIS image tile service. * diff --git a/packages/engine/package.json b/packages/engine/package.json index 83cd4178fe7..9b2228e14ef 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/engine", - "version": "2.4.0", + "version": "2.4.1", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index afe58b13172..74b125559b9 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -28,7 +28,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@cesium/engine": "2.4.0", + "@cesium/engine": "2.4.1", "nosleep.js": "^0.12.0" }, "type": "module", From ea8ba5eadd08dcf4c23fcc7f3c34c549af01eee2 Mon Sep 17 00:00:00 2001 From: Jeshurun Hembd Date: Fri, 2 Jun 2023 14:12:46 -0400 Subject: [PATCH 678/679] Update widgets version --- CHANGES.md | 4 ++++ package.json | 4 ++-- packages/widgets/package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 61d4f0d2f5a..1db5fa562d0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Change Log +### 1.106.1 - 2023-06-02 + +This is an npm-only release to fix a dependency issue published in 1.106 + ### 1.106 - 2023-06-01 #### @cesium/engine diff --git a/package.json b/package.json index cff8250c992..c9b69d2fb96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.106.0", + "version": "1.106.1", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", "license": "Apache-2.0", @@ -52,7 +52,7 @@ ], "dependencies": { "@cesium/engine": "2.4.1", - "@cesium/widgets": "2.3.0" + "@cesium/widgets": "2.3.1" }, "devDependencies": { "@aws-sdk/client-s3": "^3.342.0", diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 74b125559b9..62ed777d78f 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,6 +1,6 @@ { "name": "@cesium/widgets", - "version": "2.3.0", + "version": "2.3.1", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ "3D", From 8282de5d7f0555a86cfd362e1a625c9753512f04 Mon Sep 17 00:00:00 2001 From: Chris Cooper Date: Wed, 2 Dec 2020 14:20:50 +1100 Subject: [PATCH 679/679] All propeller changes in a single commit types --- .github/dependabot.yml | 24 + .github/workflows/dependabot-auto-merge.yml | 32 + .github/workflows/production-release-pr.yml | 23 + .gitignore | 10 +- .npmignore | 2 +- README-PROPELLER.md | 44 + Specs/BadGeometry.js | 2 +- Specs/Cesium3DTilesTester.js | 2 +- Specs/DomEventSimulator.js | 2 +- Specs/ImplicitTilingTester.js | 2 +- Specs/MetadataTester.js | 2 +- Specs/MockDataSource.js | 6 +- Specs/MockImageryProvider.js | 2 +- Specs/MockTerrainProvider.js | 2 +- Specs/TerrainTileProcessor.js | 2 +- Specs/TypeScript/index.ts | 3 +- Specs/ViewportPrimitive.js | 7 +- Specs/addDefaultMatchers.js | 2 +- Specs/createCamera.js | 2 +- Specs/createCanvas.js | 2 +- Specs/createContext.js | 2 +- Specs/createDynamicGeometryUpdaterSpecs.js | 2 +- Specs/createDynamicProperty.js | 2 +- Specs/createFrameState.js | 2 +- ...reateGeometryUpdaterGroundGeometrySpecs.js | 2 +- Specs/createGeometryUpdaterSpecs.js | 2 +- Specs/createGlobe.js | 2 +- Specs/createPackableArraySpecs.js | 2 +- Specs/createPackableSpecs.js | 6 +- Specs/createScene.js | 2 +- Specs/createTileKey.js | 2 +- Specs/equals.js | 2 +- Specs/equalsMethodEqualityTester.js | 2 +- Specs/generateJsonBuffer.js | 2 +- Specs/getWebGLStub.js | 2 +- Specs/pick.js | 2 +- Specs/pollToPromise.js | 2 +- Specs/render.js | 7 +- Specs/runLater.js | 2 +- Specs/test.mjs | 2 +- Specs/testDefinitionChanged.js | 2 +- Specs/testMaterialDefinitionChanged.js | 2 +- ThirdParty.json | 4 +- build.js | 24 +- codeship-services.yml | 22 + codeship-steps.yml | 30 + deployment/Dockerfile | 26 + deployment/crypto.sh | 83 + deployment/encrypted/build_args.sec | 2 + .../encrypted/deploy_creds_production.sec | 2 + deployment/encrypted/dockerhub_dockercfg.sec | 2 + gulpfile.js | 18 +- index.cjs | 20 +- package.json | 8 +- .../Source/Core/ApproximateTerrainHeights.js | 5 + .../Source/Core/GroundPolylineGeometry.js | 3 +- packages/engine/Source/Core/sampleTerrain.js | 60 +- packages/engine/Source/Scene/Camera.js | 45 +- .../Source/Scene/PrimitiveCollection.js | 34 + packages/engine/node_modules/.bin/rimraf | 1 + packages/engine/node_modules/.bin/topo2geo | 1 + packages/engine/node_modules/.bin/topomerge | 1 + .../engine/node_modules/.bin/topoquantize | 1 + packages/engine/package.json | 13 +- packages/engine/yarn-error.log | 8101 +++++++++++++++++ packages/widgets/package.json | 7 +- yarn-error.log | 8061 ++++++++++++++++ yarn.lock | 7712 ++++++++++++++++ 68 files changed, 24439 insertions(+), 73 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/dependabot-auto-merge.yml create mode 100644 .github/workflows/production-release-pr.yml create mode 100644 README-PROPELLER.md create mode 100644 codeship-services.yml create mode 100644 codeship-steps.yml create mode 100644 deployment/Dockerfile create mode 100755 deployment/crypto.sh create mode 100644 deployment/encrypted/build_args.sec create mode 100644 deployment/encrypted/deploy_creds_production.sec create mode 100644 deployment/encrypted/dockerhub_dockercfg.sec create mode 120000 packages/engine/node_modules/.bin/rimraf create mode 120000 packages/engine/node_modules/.bin/topo2geo create mode 120000 packages/engine/node_modules/.bin/topomerge create mode 120000 packages/engine/node_modules/.bin/topoquantize create mode 100644 packages/engine/yarn-error.log create mode 100644 yarn-error.log create mode 100644 yarn.lock diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..86a34d468a3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +# Dependabot config file. Enables updates for internal packages and schedules checks outside of office hours. +# https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates + +version: 2 +registries: + npm-npmjs: # Define registry for private access + type: npm-registry + url: https://registry.npmjs.org + token: ${{secrets.NPM_TOKEN}} + +updates: + # Keep npm dependencies up to date + - package-ecosystem: "npm" + directory: "/" + # Allow version updates for dependencies in these registries + registries: + - npm-npmjs + # Check the npm registry for updates on Sunday 7pm UTC / Monday 5am AEST. This should be out of + # office hours so as to not block CI but not too long before people wake up, in case the updates + # cause issues. + schedule: + interval: "weekly" + day: "sunday" + time: "19:00" diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 00000000000..0f734a60084 --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,32 @@ +# Automatically merge dependabot PRs that upgrade to patch or minor versions. Adapted from: +# https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/automating-dependabot-with-github-actions#enable-auto-merge-on-a-pull-request +name: dependabot-auto-merge +on: pull_request + +permissions: + pull-requests: write + contents: write + +jobs: + auto-merge-dependabot-pr: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Get Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v1.3.3 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Approve PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Auto-merge Dependabot PR + if: ${{steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'}} + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/production-release-pr.yml b/.github/workflows/production-release-pr.yml new file mode 100644 index 00000000000..c1d6f2ccedd --- /dev/null +++ b/.github/workflows/production-release-pr.yml @@ -0,0 +1,23 @@ +# Automatically creates a Product Release PR when anything is committed to main. +name: production-release-pr + +on: + push: + branches: [main] + +jobs: + create-draft-release-pr: + runs-on: ubuntu-latest + + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: auto-create-pr-action + uses: PropellerAero/auto-create-pr-action@master + env: + BRANCH_PREFIX: "main" + BASE_BRANCH: "main" + PULL_REQUEST_TITLE: "[Production Release]" + PULL_REQUEST_DRAFT: "false" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 0baab6ee4ae..629f6d2933b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ .DS_Store Thumbs.db .eslintcache +.env /Apps/CesiumViewer/Gallery/gallery-index.js @@ -27,12 +28,19 @@ Thumbs.db /Tools/jsdoc/cesium_template/static/styles/prism.css /node_modules +/engine/node_modules/ +/widgets/node_modules/ +/packages/engine/node_modules +/packages/widgets/node_modules npm-debug.log npm-debug.log.* package-lock.json -yarn.lock # WebStorm user-specific .idea/workspace.xml .idea/tasks.xml .idea/shelf + +# Codeship +deployment/secrets +*.aes diff --git a/.npmignore b/.npmignore index 1998d4bf545..12d5128b43e 100644 --- a/.npmignore +++ b/.npmignore @@ -36,5 +36,5 @@ /ThirdParty /Tools /web.config - +/deployment Thumbs.db diff --git a/README-PROPELLER.md b/README-PROPELLER.md new file mode 100644 index 00000000000..ae8bf8c2e8e --- /dev/null +++ b/README-PROPELLER.md @@ -0,0 +1,44 @@ +git add # Updating the Propeller fork of Cesium + +"The best way in my eyes is, to rebase because that fetches the latest changes of the upstream branch and replay your work on top of that." - [Stefan Bauer](https://stefanbauer.me/articles/how-to-keep-your-git-fork-up-to-date) + +The ideal git history should have all Propeller modifications in a single most recent commit, followed by the full history from upstream CesiumGS. + +e.g. + +``` +commit c6fc9cb205e387781c5269b95e350f61a8815d08 +Author: Chris Cooper +Date: Mon Sep 21 15:19:02 2020 +1000 + + All the Propeller mods in a single commit + +commit da4ddc58830606d89f762dc7d79b3dfe4103c6d1 +Merge: 9c61508 6c0a0f8 +Author: Kevin Ring +Date: Tue Sep 1 15:47:38 2020 +1000 + + Updates for 1.73 release + +... +``` + +To maintain this going forward, use a `git rebase`. + +``` +# Make sure your main branch is up to date +git checkout main +git pull + +# Fetch the upstream tags +git fetch upstream --tags + +# Interactive rebase to the CesiumGS release tag +# Squash all propeller commits into a single commit +git rebase -i 1.74 + +# Fix all the broken stuff :) + +# You've just re-written the history so you'll have to force +git push origin main --force +``` diff --git a/Specs/BadGeometry.js b/Specs/BadGeometry.js index 7119e214cc5..89cb4092e59 100644 --- a/Specs/BadGeometry.js +++ b/Specs/BadGeometry.js @@ -1,4 +1,4 @@ -import { queryToObject, RuntimeError } from "@cesium/engine"; +import { queryToObject, RuntimeError } from "@propelleraero/cesium-engine"; // PROPELLER HACK function BadGeometry() { this._workerName = "../../Specs/TestWorkers/createBadGeometry"; diff --git a/Specs/Cesium3DTilesTester.js b/Specs/Cesium3DTilesTester.js index b52d0e73cea..0755c9aec07 100644 --- a/Specs/Cesium3DTilesTester.js +++ b/Specs/Cesium3DTilesTester.js @@ -7,7 +7,7 @@ import { Cesium3DTileContentFactory, Cesium3DTileset, TileBoundingSphere, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK import pollToPromise from "./pollToPromise.js"; diff --git a/Specs/DomEventSimulator.js b/Specs/DomEventSimulator.js index bbff151ae5c..336827e074b 100644 --- a/Specs/DomEventSimulator.js +++ b/Specs/DomEventSimulator.js @@ -1,4 +1,4 @@ -import { defaultValue, FeatureDetection } from "@cesium/engine"; +import { defaultValue, FeatureDetection } from "@propelleraero/cesium-engine"; // PROPELLER HACK function createMouseEvent(type, options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/Specs/ImplicitTilingTester.js b/Specs/ImplicitTilingTester.js index 7513a4b497d..d495b415749 100644 --- a/Specs/ImplicitTilingTester.js +++ b/Specs/ImplicitTilingTester.js @@ -1,4 +1,4 @@ -import { defined, defaultValue } from "@cesium/engine"; +import { defined, defaultValue } from "@propelleraero/cesium-engine"; // PROPELLER HACK import concatTypedArrays from "./concatTypedArrays.js"; import MetadataTester from "./MetadataTester.js"; diff --git a/Specs/MetadataTester.js b/Specs/MetadataTester.js index 119015be69d..c93868a4101 100644 --- a/Specs/MetadataTester.js +++ b/Specs/MetadataTester.js @@ -9,7 +9,7 @@ import { MetadataEnum, MetadataTable, MetadataType, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function MetadataTester() {} diff --git a/Specs/MockDataSource.js b/Specs/MockDataSource.js index 80f4a5644ae..70be8c9a96f 100644 --- a/Specs/MockDataSource.js +++ b/Specs/MockDataSource.js @@ -1,4 +1,8 @@ -import { Event, EntityCluster, EntityCollection } from "@cesium/engine"; +import { + Event, + EntityCluster, + EntityCollection, +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function MockDataSource() { //Values to be fiddled with by the test diff --git a/Specs/MockImageryProvider.js b/Specs/MockImageryProvider.js index f90c072834e..cd0c64800a1 100644 --- a/Specs/MockImageryProvider.js +++ b/Specs/MockImageryProvider.js @@ -5,7 +5,7 @@ import { GeographicTilingScheme, Resource, RuntimeError, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function MockImageryProvider() { this.tilingScheme = new GeographicTilingScheme(); diff --git a/Specs/MockTerrainProvider.js b/Specs/MockTerrainProvider.js index 84af4db14e9..c676168dfc9 100644 --- a/Specs/MockTerrainProvider.js +++ b/Specs/MockTerrainProvider.js @@ -7,7 +7,7 @@ import { HeightmapTerrainData, RuntimeError, TerrainProvider, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function MockTerrainProvider() { this.tilingScheme = new GeographicTilingScheme(); diff --git a/Specs/TerrainTileProcessor.js b/Specs/TerrainTileProcessor.js index 4e77bb3c2fe..d27b2a7ecbb 100644 --- a/Specs/TerrainTileProcessor.js +++ b/Specs/TerrainTileProcessor.js @@ -4,7 +4,7 @@ import { GlobeSurfaceTile, TerrainState, Texture, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function TerrainTileProcessor( frameState, diff --git a/Specs/TypeScript/index.ts b/Specs/TypeScript/index.ts index 764ccdeae04..26b9d0f630c 100644 --- a/Specs/TypeScript/index.ts +++ b/Specs/TypeScript/index.ts @@ -99,7 +99,8 @@ import { WebMapServiceImageryProvider, WebMapTileServiceImageryProvider, writeTextToCanvas, -} from "cesium"; +} from "@propelleraero/cesium-engine"; +//PROPELLER HACK // Verify ImageryProvider instances conform to the expected interface let imageryProvider: ImageryProvider; diff --git a/Specs/ViewportPrimitive.js b/Specs/ViewportPrimitive.js index 1f3aa2ce326..c9114660cf1 100644 --- a/Specs/ViewportPrimitive.js +++ b/Specs/ViewportPrimitive.js @@ -1,4 +1,9 @@ -import { defined, destroyObject, Pass, RenderState } from "@cesium/engine"; +import { + defined, + destroyObject, + Pass, + RenderState, +} from "@propelleraero/cesium-engine"; // PROPELLER HACK const ViewportPrimitive = function (fragmentShader) { this._fs = fragmentShader; diff --git a/Specs/addDefaultMatchers.js b/Specs/addDefaultMatchers.js index a072b202042..3425d470f08 100644 --- a/Specs/addDefaultMatchers.js +++ b/Specs/addDefaultMatchers.js @@ -12,7 +12,7 @@ import { ShaderProgram, VertexArray, Math as CesiumMath, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK import equals from "./equals.js"; function createMissingFunctionMessageFunction( diff --git a/Specs/createCamera.js b/Specs/createCamera.js index 2feb6bdb55f..eb044262513 100644 --- a/Specs/createCamera.js +++ b/Specs/createCamera.js @@ -5,7 +5,7 @@ import { GeographicProjection, Matrix4, Camera, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function MockScene(canvas) { canvas = defaultValue(canvas, { diff --git a/Specs/createCanvas.js b/Specs/createCanvas.js index eed0cb7af87..91e9066411f 100644 --- a/Specs/createCanvas.js +++ b/Specs/createCanvas.js @@ -1,4 +1,4 @@ -import { defaultValue } from "@cesium/engine"; +import { defaultValue } from "@propelleraero/cesium-engine"; // PROPELLER HACK let canvasCount = 0; diff --git a/Specs/createContext.js b/Specs/createContext.js index fca62cd01cb..a34d4583f99 100644 --- a/Specs/createContext.js +++ b/Specs/createContext.js @@ -1,4 +1,4 @@ -import { clone, defaultValue, Context } from "@cesium/engine"; +import { clone, defaultValue, Context } from "@propelleraero/cesium-engine"; // PROPELLER HACK import createCanvas from "./createCanvas.js"; import createFrameState from "./createFrameState.js"; diff --git a/Specs/createDynamicGeometryUpdaterSpecs.js b/Specs/createDynamicGeometryUpdaterSpecs.js index b7567a7e434..a70ff1d785f 100644 --- a/Specs/createDynamicGeometryUpdaterSpecs.js +++ b/Specs/createDynamicGeometryUpdaterSpecs.js @@ -5,7 +5,7 @@ import { EllipsoidGeometryUpdater, PrimitiveCollection, Math as CesiumMath, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK import createDynamicProperty from "./createDynamicProperty.js"; import pollToPromise from "./pollToPromise.js"; diff --git a/Specs/createDynamicProperty.js b/Specs/createDynamicProperty.js index 31f16490561..83b1bf380e0 100644 --- a/Specs/createDynamicProperty.js +++ b/Specs/createDynamicProperty.js @@ -1,4 +1,4 @@ -import { ConstantProperty } from "@cesium/engine"; +import { ConstantProperty } from "@propelleraero/cesium-engine"; // PROPELLER HACK function createDynamicProperty(value) { const property = new ConstantProperty(value); diff --git a/Specs/createFrameState.js b/Specs/createFrameState.js index eb07cff2190..a4378b4dcb6 100644 --- a/Specs/createFrameState.js +++ b/Specs/createFrameState.js @@ -6,7 +6,7 @@ import { CreditDisplay, FrameState, JobScheduler, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function createFrameState(context, camera, frameNumber, time) { // Mock frame-state for testing. diff --git a/Specs/createGeometryUpdaterGroundGeometrySpecs.js b/Specs/createGeometryUpdaterGroundGeometrySpecs.js index e91f6b743cc..cfdcbf01533 100644 --- a/Specs/createGeometryUpdaterGroundGeometrySpecs.js +++ b/Specs/createGeometryUpdaterGroundGeometrySpecs.js @@ -9,7 +9,7 @@ import { GroundPrimitive, HeightReference, PrimitiveCollection, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function createGeometryUpdaterGroundGeometrySpecs( Updater, diff --git a/Specs/createGeometryUpdaterSpecs.js b/Specs/createGeometryUpdaterSpecs.js index bfd85501ee9..d02ab5c5d59 100644 --- a/Specs/createGeometryUpdaterSpecs.js +++ b/Specs/createGeometryUpdaterSpecs.js @@ -14,7 +14,7 @@ import { SampledProperty, TimeIntervalCollectionProperty, ShadowMode, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function createGeometryUpdaterSpecs( Updater, diff --git a/Specs/createGlobe.js b/Specs/createGlobe.js index 200419f4288..24680427ef4 100644 --- a/Specs/createGlobe.js +++ b/Specs/createGlobe.js @@ -1,4 +1,4 @@ -import { defaultValue, Ellipsoid, Event } from "@cesium/engine"; +import { defaultValue, Ellipsoid, Event } from "@propelleraero/cesium-engine"; // PROPELLER HACK function createGlobe(ellipsoid) { ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); diff --git a/Specs/createPackableArraySpecs.js b/Specs/createPackableArraySpecs.js index 8d77067e94c..7a48300cbac 100644 --- a/Specs/createPackableArraySpecs.js +++ b/Specs/createPackableArraySpecs.js @@ -1,4 +1,4 @@ -import { defaultValue } from "@cesium/engine"; +import { defaultValue } from "@propelleraero/cesium-engine"; // PROPELLER HACK function createPackableArraySpecs( packable, diff --git a/Specs/createPackableSpecs.js b/Specs/createPackableSpecs.js index bd1ee9e98a1..7c5b1fb607d 100644 --- a/Specs/createPackableSpecs.js +++ b/Specs/createPackableSpecs.js @@ -1,4 +1,8 @@ -import { defaultValue, defined, Math as CesiumMath } from "@cesium/engine"; +import { + defaultValue, + defined, + Math as CesiumMath, +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function createPackableSpecs(packable, instance, packedInstance, namePrefix) { namePrefix = defaultValue(namePrefix, ""); diff --git a/Specs/createScene.js b/Specs/createScene.js index 93e87b42406..7b8245b4266 100644 --- a/Specs/createScene.js +++ b/Specs/createScene.js @@ -4,7 +4,7 @@ import { defaultValue, defined, Scene, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK import createCanvas from "./createCanvas.js"; import getWebGLStub from "./getWebGLStub.js"; diff --git a/Specs/createTileKey.js b/Specs/createTileKey.js index 876c5e37cae..3b5e7c6462f 100644 --- a/Specs/createTileKey.js +++ b/Specs/createTileKey.js @@ -1,4 +1,4 @@ -import { defined, DeveloperError } from "@cesium/engine"; +import { defined, DeveloperError } from "@propelleraero/cesium-engine"; // PROPELLER HACK function createTileKey(xOrTile, y, level) { if (!defined(xOrTile)) { diff --git a/Specs/equals.js b/Specs/equals.js index 16cbafbdf02..50850264a6e 100644 --- a/Specs/equals.js +++ b/Specs/equals.js @@ -1,4 +1,4 @@ -import { FeatureDetection } from "@cesium/engine"; +import { FeatureDetection } from "@propelleraero/cesium-engine"; // PROPELLER HACK function isTypedArray(o) { return FeatureDetection.typedArrayTypes.some(function (type) { diff --git a/Specs/equalsMethodEqualityTester.js b/Specs/equalsMethodEqualityTester.js index 074841499f5..fdc3a6bf88f 100644 --- a/Specs/equalsMethodEqualityTester.js +++ b/Specs/equalsMethodEqualityTester.js @@ -1,4 +1,4 @@ -import { defined } from "@cesium/engine"; +import { defined } from "@propelleraero/cesium-engine"; // PROPELLER HACK function equalsMethodEqualityTester(a, b) { let to_run; diff --git a/Specs/generateJsonBuffer.js b/Specs/generateJsonBuffer.js index e3de112ca3d..97ee18ff947 100644 --- a/Specs/generateJsonBuffer.js +++ b/Specs/generateJsonBuffer.js @@ -1,4 +1,4 @@ -import { defaultValue } from "@cesium/engine"; +import { defaultValue } from "@propelleraero/cesium-engine"; // PROPELLER HACK function generateJsonBuffer(json, byteOffset, boundary) { let i; diff --git a/Specs/getWebGLStub.js b/Specs/getWebGLStub.js index 6d355a5c229..1c872ce99c0 100644 --- a/Specs/getWebGLStub.js +++ b/Specs/getWebGLStub.js @@ -4,7 +4,7 @@ import { defined, DeveloperError, WebGLConstants, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function getWebGLStub(canvas, options) { const stub = clone(WebGLConstants); diff --git a/Specs/pick.js b/Specs/pick.js index 0745c53a34f..ce27b127b9c 100644 --- a/Specs/pick.js +++ b/Specs/pick.js @@ -8,7 +8,7 @@ import { FrameState, JobScheduler, PickFramebuffer, -} from "@cesium/engine"; +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function executeCommands(context, passState, commands) { const length = commands.length; diff --git a/Specs/pollToPromise.js b/Specs/pollToPromise.js index 0e6c3eead36..b243d950c78 100644 --- a/Specs/pollToPromise.js +++ b/Specs/pollToPromise.js @@ -1,4 +1,4 @@ -import { defaultValue, getTimestamp } from "@cesium/engine"; +import { defaultValue, getTimestamp } from "@propelleraero/cesium-engine"; // PROPELLER HACK function pollToPromise(f, options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); diff --git a/Specs/render.js b/Specs/render.js index 860f4a29057..17cdfb0add6 100644 --- a/Specs/render.js +++ b/Specs/render.js @@ -1,4 +1,9 @@ -import { defined, Intersect, Pass, SceneMode } from "@cesium/engine"; +import { + defined, + Intersect, + Pass, + SceneMode, +} from "@propelleraero/cesium-engine"; // PROPELLER HACK function executeCommands(frameState, commands) { let commandsExecuted = 0; diff --git a/Specs/runLater.js b/Specs/runLater.js index b0a33de78a4..332681a415b 100644 --- a/Specs/runLater.js +++ b/Specs/runLater.js @@ -1,4 +1,4 @@ -import { defaultValue } from "@cesium/engine"; +import { defaultValue } from "@propelleraero/cesium-engine"; // PROPELLER HACK function runLater(functionToRunLater, milliseconds) { milliseconds = defaultValue(milliseconds, 0); diff --git a/Specs/test.mjs b/Specs/test.mjs index 13ba4c1162e..5587561f250 100644 --- a/Specs/test.mjs +++ b/Specs/test.mjs @@ -1,4 +1,4 @@ -import { Cartographic, CesiumTerrainProvider, sampleTerrain } from "cesium"; +import { Cartographic, CesiumTerrainProvider, sampleTerrain } from "@propelleraero/cesium"; // PROPELLER HACK import assert from "node:assert"; // NodeJS smoke screen test diff --git a/Specs/testDefinitionChanged.js b/Specs/testDefinitionChanged.js index 37d696d730f..a5658dc7717 100644 --- a/Specs/testDefinitionChanged.js +++ b/Specs/testDefinitionChanged.js @@ -1,4 +1,4 @@ -import { ConstantProperty } from "@cesium/engine"; +import { ConstantProperty } from "@propelleraero/cesium-engine"; // PROPELLER HACK function testDefinitionChanged(property, name, value1, value2) { const listener = jasmine.createSpy("listener"); diff --git a/Specs/testMaterialDefinitionChanged.js b/Specs/testMaterialDefinitionChanged.js index c9d4219ba91..a1e67fbcf6a 100644 --- a/Specs/testMaterialDefinitionChanged.js +++ b/Specs/testMaterialDefinitionChanged.js @@ -1,4 +1,4 @@ -import { ColorMaterialProperty } from "@cesium/engine"; +import { ColorMaterialProperty } from "@propelleraero/cesium-engine"; // PROPELLER HACK function testMaterialDefinitionChanged(property, name, value1, value2) { const listener = jasmine.createSpy("listener"); diff --git a/ThirdParty.json b/ThirdParty.json index b24426296e4..281adfa4493 100644 --- a/ThirdParty.json +++ b/ThirdParty.json @@ -36,7 +36,7 @@ "license": [ "Apache-2.0" ], - "version": "3.0.3", + "version": "2.3.10", "url": "https://www.npmjs.com/package/dompurify", "notes": "dompurify is available as both MPL-2.0 OR Apache-2.0" }, @@ -45,7 +45,7 @@ "license": [ "Apache-2.0" ], - "version": "1.5.6", + "version": "1.5.3", "url": "https://www.npmjs.com/package/draco3d" }, { diff --git a/build.js b/build.js index 91e7882900d..275af8485f0 100644 --- a/build.js +++ b/build.js @@ -22,7 +22,8 @@ import { mkdirp } from "mkdirp"; // Determines the scope of the workspace packages. If the scope is set to cesium, the workspaces should be @cesium/engine. // This should match the scope of the dependencies of the root level package.json. -const scope = "cesium"; +//PROPELLER HACK +const scope = "propelleraero"; const require = createRequire(import.meta.url); const packageJson = require("./package.json"); @@ -262,7 +263,6 @@ const workspaceSourceFiles = { */ function generateDeclaration(workspace, file) { let assignmentName = path.basename(file, path.extname(file)); - let moduleId = file; moduleId = filePathToModuleId(moduleId); @@ -270,6 +270,11 @@ function generateDeclaration(workspace, file) { assignmentName = `_shaders${assignmentName}`; } assignmentName = assignmentName.replace(/(\.|-)/g, "_"); + //PROPELLER HACK + if (workspace === "engine" || workspace === "widgets") { + return `export { ${assignmentName} } from '@${scope}/cesium-${workspace}';`; + } + return `export { ${assignmentName} } from '@${scope}/${workspace}';`; } @@ -283,6 +288,7 @@ export async function createCesiumJs() { // Iterate over each workspace and generate declarations for each file. for (const workspace of Object.keys(workspaceSourceFiles)) { const files = await globby(workspaceSourceFiles[workspace]); + //PROPELLER HACK const declarations = files.map((file) => generateDeclaration(workspace, file) ); @@ -305,7 +311,6 @@ const workspaceSpecFiles = { */ export async function createCombinedSpecList() { let contents = `export const VERSION = '${version}';\n`; - for (const workspace of Object.keys(workspaceSpecFiles)) { const files = await globby(workspaceSpecFiles[workspace]); for (const file of files) { @@ -608,7 +613,8 @@ const externalResolvePlugin = { }; }); - build.onResolve({ filter: /@cesium/ }, () => { + // PROPELLER HACK + build.onResolve({ filter: /@propelleraero/ }, () => { return { path: "Cesium", namespace: "external-cesium", @@ -621,7 +627,10 @@ const externalResolvePlugin = { namespace: "external-cesium", }, () => { - const contents = `module.exports = Cesium`; + //PROPELLER HACK + //const contents = `module.exports = Cesium`; + const contents = `module.exports = "@propelleraero/cesium"`; + return { contents, }; @@ -864,6 +873,7 @@ export async function createIndexJs(workspace) { const files = await globby(workspaceSources); files.forEach(function (file) { + //PROPELLER HACK file = path.relative(`packages/${workspace}`, file); let moduleId = file; @@ -879,6 +889,7 @@ export async function createIndexJs(workspace) { contents += `export { default as ${assignmentName} } from './${moduleId}.js';${EOL}`; }); + //PROPELLER HACK await writeFile(`packages/${workspace}/index.js`, contents, { encoding: "utf-8", }); @@ -1048,7 +1059,7 @@ export const buildWidgets = async (options) => { // Generate Build folder to place build artifacts. mkdirp.sync("packages/widgets/Build"); - // Create index.js + //PROPELLER HACK await createIndexJs("widgets"); // Create SpecList.js @@ -1168,7 +1179,6 @@ export async function buildCesium(options) { await copyWidgetsAssets(path.join(outputDirectory, "Widgets")); // Copy static assets to Source folder. - await copyEngineAssets("Source"); await copyFiles( ["packages/engine/Source/ThirdParty/**/*.js"], diff --git a/codeship-services.yml b/codeship-services.yml new file mode 100644 index 00000000000..3fa7eed13c1 --- /dev/null +++ b/codeship-services.yml @@ -0,0 +1,22 @@ +builder: + encrypted_env_file: deployment/encrypted/build_args.sec + volumes: + - ./Build:/build/Build + - ./Source:/build/Source + build: + dockerfile: deployment/Dockerfile + encrypted_args_file: deployment/encrypted/build_args.sec + + +dockercfg-production: + image: codeship/aws-ecr-dockercfg-generator + add_docker: true + encrypted_dockercfg_path: deployment/encrypted/dockerhub_dockercfg.sec + encrypted_env_file: deployment/encrypted/deploy_creds_production.sec + +publisher: + image: 621673481476.dkr.ecr.us-east-1.amazonaws.com/deploy-tools + volumes: + - .:/code-to-deploy + cached: true + encrypted_env_file: deployment/encrypted/deploy_creds_production.sec diff --git a/codeship-steps.yml b/codeship-steps.yml new file mode 100644 index 00000000000..b373050143e --- /dev/null +++ b/codeship-steps.yml @@ -0,0 +1,30 @@ +- name: Test + service: builder + encrypted_dockercfg_path: deployment/encrypted/dockerhub_dockercfg.sec + command: yarn test + +- name: Build + service: builder + encrypted_dockercfg_path: deployment/encrypted/dockerhub_dockercfg.sec + command: yarn release + +- name: Publish/Deploy + type: parallel + steps: + - name: Publish top level + tag: main + service: publisher + dockercfg_service: dockercfg-production + command: publish-javascript-package --code-dir . --git-tag-prefix propeller + + - name: Publish engine + tag: main + service: publisher + dockercfg_service: dockercfg-production + command: publish-javascript-package --code-dir /packages/engine + + - name: Publish widget + tag: main + service: publisher + dockercfg_service: dockercfg-production + command: publish-javascript-package --code-dir /packages/widgets diff --git a/deployment/Dockerfile b/deployment/Dockerfile new file mode 100644 index 00000000000..97e110dd3aa --- /dev/null +++ b/deployment/Dockerfile @@ -0,0 +1,26 @@ +FROM node:14 AS Builder + +ARG NPM_TOKEN + +# Configure git to use our custom credential helper that can use the $GITHUB_KEY env var +# This allows us to use the github token without writing it to disk. The sleep is required +# to avoid a race condition on some systems. +# https://git-scm.com/docs/api-credentials#_credential_helpers + +ARG GITHUB_KEY + +RUN git config --global credential.helper "!f() { sleep 0.1; echo 'username=${GITHUB_KEY}\npassword=x-oauth-basic'; }; f" && git config --global url."https://github.com/".insteadOf "git@github.com:" + +WORKDIR /build + +# Move the package into the container +COPY . /build + +# Configure yarn to use NPM registry +RUN yarn config set registry "https://registry.npmjs.org" + +# Set authToken for access to @propelleraero/* packages. +RUN npm config set "//registry.npmjs.org/:_authToken" ${NPM_TOKEN} + +# Dependencies +RUN yarn install diff --git a/deployment/crypto.sh b/deployment/crypto.sh new file mode 100755 index 00000000000..9f500526ee5 --- /dev/null +++ b/deployment/crypto.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# +# CRYPTO.SH +# +# Encrypts/decrypts contents of a folder using Codeship's jet cli. +# +# Usage: +# ./crypto encrypt folder destination +# ./crypto decrypt folder destination +# + +set -e + +usage() { + echo $"Usage: `basename $0` [output]" + exit 1 +} + +KEY_PATH="codeship.aes" # todo: getopts --key-path + +ARGC=$# +CMD=$1 +IN_DIR=$2 +OUT_DIR=$3 + +# Do we have at least the input directory +if [ ! "$ARGC" -gt 1 ]; then usage; fi + +# output directory exists or create it +if [ -z "$OUT_DIR" ]; then OUT_DIR=$(pwd); fi +if [ ! -e "$OUT_DIR" ]; then mkdir -p "$OUT_DIR"; fi + +# output is a directory +if [ ! -d "$OUT_DIR" ] +then + echo "ERROR: is not a directory." + usage +fi + +# input is a directory +if [ ! -d "$IN_DIR" ] +then + echo "ERROR: is not a directory or doesn't exist." + usage +fi + +# Check if codeship jet is installed +if ! (hash jet 2>/dev/null) +then + echo "ERROR: jet is not installed. https://documentation.codeship.com/pro/jet-cli/installation/" + exit 1 +fi + +# Check if we have the key +if [ ! -f "$KEY_PATH" ] +then + echo "Key file missing. Download the project's AES key from Codeship and copy it to the project's root directory." + exit 1 +fi + +# encrypt/decrypt +case "$CMD" in + encrypt) + for file in $IN_DIR/* + do + out="$OUT_DIR/$(basename $file).sec" + jet encrypt --key-path $KEY_PATH $file $out + echo "[encrypted] $file > $out" + done + ;; + decrypt) + for file in $IN_DIR/*.sec + do + out="$OUT_DIR/$(basename -s .sec $file)" + jet decrypt --key-path $KEY_PATH $file $out + echo "[decrypted] $file > $out" + done + ;; + *) + usage + exit 1 +esac diff --git a/deployment/encrypted/build_args.sec b/deployment/encrypted/build_args.sec new file mode 100644 index 00000000000..6fccd03f64a --- /dev/null +++ b/deployment/encrypted/build_args.sec @@ -0,0 +1,2 @@ +cloudbees:v1 +b8JaPlhqKjqBtwIiCzJl2ukW2awQFsAu2pBLTpDpgDkko0fjJrVho7FsmyC5rCPLUTPtvDD1ww/u+YhvOO7RS9LaGrtkRY24RTYqy2ENtAevySV5h//bFElAHuUuW3iw92EY0QqJyWAD0q/Tg8ASl5Skyz9+Slj0r21eN9ORgJwwx/goLb8YfN7B4U47bE2wuTbQcW4= \ No newline at end of file diff --git a/deployment/encrypted/deploy_creds_production.sec b/deployment/encrypted/deploy_creds_production.sec new file mode 100644 index 00000000000..1cd43ce605f --- /dev/null +++ b/deployment/encrypted/deploy_creds_production.sec @@ -0,0 +1,2 @@ +cloudbees:v1 +VGavCCRDnL92GUHfHe1WXu2D0YlWJ50oAqVDhnXUEyJ5W06M3k8Pp2bOKRK/Jkab6+yLSzCtBWmnUqYAwOscwt91Ej5YWVN1zh5TwTpovssnddlF3W+Qj9PJAssEqepaWJPdUJ1yGucPP85QiHQH0tb50YR54N80JGXkkaI3qwisn+g9kNxVr9gHTaAlgSqHWeDTIUgQOqNXEMgmu0RkBh1swcr8Ziim1hqV/kMQ+HUTsLXxFGP7dHjdZRWIyDNtav4btoNvch/rKohtJDK/jZjYMz4+2CbyKcmdDvq/pY2Bqt5/cTwpuYox877jh3Y2KlE7jHKCoacDnwY/5p1Jt4iOIZWJHULT/33cRdKxUGE1r+7Z \ No newline at end of file diff --git a/deployment/encrypted/dockerhub_dockercfg.sec b/deployment/encrypted/dockerhub_dockercfg.sec new file mode 100644 index 00000000000..d340916df9b --- /dev/null +++ b/deployment/encrypted/dockerhub_dockercfg.sec @@ -0,0 +1,2 @@ +cloudbees:v1 +gYum6XoxNzooGsGmyKVxf0gSROBJtQ6uHl62w9HUS9Yu7z70u+uzNftvqiNBucIg90jq3y1iYi8ecZ3QjZ5blNCpyOzrGdND+yZsislNLCSrlXP/u9jVy552kiL+2pGFJQOVVVcyVL5GwwkqzpkVCIsL1tObA8PG8i9ehF9yKMpKK+sl16dzB6jI3SRCJ6trBFV4jXxyc99PK26uxx0u76YDDgRBQhTz84hARYV75+QSDXYKUqJHejbGyR1QGfVgPbLFiQ+G7PUV+xioT+1mpe4SiHfRc6vl \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index a55506e6e6c..858251a6659 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -52,7 +52,8 @@ import { // Determines the scope of the workspace packages. If the scope is set to cesium, the workspaces should be @cesium/engine. // This should match the scope of the dependencies of the root level package.json. -const scope = "cesium"; +//PROPELLER HACK +const scope = "propelleraero"; const require = createRequire(import.meta.url); const packageJson = require("./package.json"); @@ -276,10 +277,16 @@ export async function buildTs() { // Generate types for passed packages in order. const importModules = {}; + console.error("workspaces: ", workspaces); + // ["packages/engine", "packages/widgets"]; + for (const workspace of workspaces) { const directory = workspace .replace(`@${scope}/`, "") .replace(`packages/`, ""); + + //PROPELLER HACK + const workspaceModules = await generateTypeScriptDefinitions( directory, `packages/${directory}/index.d.ts`, @@ -1450,6 +1457,7 @@ export async function runCoverage(options) { }, { promiseConfig: true, throwErrors: true } ); + console.error("config:", config); return new Promise((resolve, reject) => { const server = new karma.Server(config, function doneCallback(e) { @@ -1650,6 +1658,8 @@ export async function test() { { promiseConfig: true, throwErrors: true } ); + console.log(workspace, "____config:", config); + return new Promise((resolve, reject) => { const server = new karma.Server(config, function doneCallback(exitCode) { if (failTaskOnError && exitCode) { @@ -1734,7 +1744,8 @@ function generateTypeScriptDefinitions( // Wrap the source to actually be inside of a declared cesium module // and add any workaround and private utility types. - source = `declare module "@${scope}/${workspaceName}" { + //PROPELLER HACK + source = `declare module "@${scope}/cesium-${workspaceName}" { ${source} } `; @@ -1927,7 +1938,8 @@ function createTypeScriptDefinitions() { // Wrap the source to actually be inside of a declared cesium module // and add any workaround and private utility types. - source = `declare module "cesium" { + // PROPELLER HACK + source = `declare module "@propelleraero/cesium" { ${source} } diff --git a/index.cjs b/index.cjs index a0dde5dee5d..b9364e6ca83 100644 --- a/index.cjs +++ b/index.cjs @@ -4,13 +4,19 @@ const path = require("path"); // If in 'production' mode, use the combined/minified/optimized version of Cesium -if (process.env.NODE_ENV === "production") { +if ( + process.env.NODE_ENV === "production" || + process.env.NODE_ENV === "staging" || + process.env.NODE_ENV === "dev" +) { // eslint-disable-next-line global-require module.exports = require(path.join(__dirname, "Build/Cesium/index.cjs")); - return; + //PROPELLER HACK + //return; +} else { + // eslint-disable-next-line global-require + module.exports = require(path.join( + __dirname, + "Build/CesiumUnminified/index.cjs" + )); } - -module.exports = require(path.join( - __dirname, - "Build/CesiumUnminified/index.cjs" -)); diff --git a/package.json b/package.json index c9b69d2fb96..415e90a805b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "cesium", + "name": "@propelleraero/cesium", "version": "1.106.1", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesium.com/cesiumjs/", @@ -51,8 +51,8 @@ "./Specs/**/*" ], "dependencies": { - "@cesium/engine": "2.4.1", - "@cesium/widgets": "2.3.1" + "@propelleraero/cesium-engine": "2.4.1test", + "@propelleraero/cesium-widgets": "2.3.1test" }, "devDependencies": { "@aws-sdk/client-s3": "^3.342.0", @@ -129,6 +129,8 @@ "build-apps": "gulp buildApps", "clean": "gulp clean", "cloc": "gulp cloc", + "codeship:decrypt": "./deployment/crypto.sh decrypt ./deployment/encrypted ./deployment/secrets", + "codeship:encrypt": "./deployment/crypto.sh encrypt ./deployment/secrets ./deployment/encrypted", "coverage": "gulp coverage", "build-docs": "gulp buildDocs", "build-docs-watch": "gulp buildDocsWatch", diff --git a/packages/engine/Source/Core/ApproximateTerrainHeights.js b/packages/engine/Source/Core/ApproximateTerrainHeights.js index 6b1891ddc82..98e3e310df5 100644 --- a/packages/engine/Source/Core/ApproximateTerrainHeights.js +++ b/packages/engine/Source/Core/ApproximateTerrainHeights.js @@ -46,6 +46,11 @@ ApproximateTerrainHeights.initialize = function () { initPromise = Resource.fetchJson( buildModuleUrl("Assets/approximateTerrainHeights.json") ).then(function (json) { + // PROPELLER HACK: Allow rendering of ground primitives with negative WGS84 elevation + const MAX_HOLE_DEPTH = 250; + Object.keys(json).map(function (key) { + json[key][0] -= MAX_HOLE_DEPTH; + }); ApproximateTerrainHeights._terrainHeights = json; }); ApproximateTerrainHeights._initPromise = initPromise; diff --git a/packages/engine/Source/Core/GroundPolylineGeometry.js b/packages/engine/Source/Core/GroundPolylineGeometry.js index 877874c2f5a..ec2837999f5 100644 --- a/packages/engine/Source/Core/GroundPolylineGeometry.js +++ b/packages/engine/Source/Core/GroundPolylineGeometry.js @@ -40,7 +40,8 @@ const MITER_BREAK_LARGE = Math.cos(CesiumMath.toRadians(150.0)); // Ellipsoid height is generally much closer. // The initial max height is arbitrary. // Both heights are corrected using ApproximateTerrainHeights for computing the actual volume geometry. -const WALL_INITIAL_MIN_HEIGHT = 0.0; +// PROPELLER HACK: Allow rendering of ground primitives with negative WGS84 elevation +const WALL_INITIAL_MIN_HEIGHT = -250; const WALL_INITIAL_MAX_HEIGHT = 1000.0; /** diff --git a/packages/engine/Source/Core/sampleTerrain.js b/packages/engine/Source/Core/sampleTerrain.js index d0f46d8d01f..d8318012db0 100644 --- a/packages/engine/Source/Core/sampleTerrain.js +++ b/packages/engine/Source/Core/sampleTerrain.js @@ -34,7 +34,6 @@ import defined from "./defined.js"; * const updatedPositions = await Cesium.sampleTerrain(terrainProvider, 11, positions); * // positions[0].height and positions[1].height have been updated. * // updatedPositions is just a reference to positions. - */ async function sampleTerrain(terrainProvider, level, positions) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object("terrainProvider", terrainProvider); @@ -51,6 +50,30 @@ async function sampleTerrain(terrainProvider, level, positions) { return doSampling(terrainProvider, level, positions); } +*/ +// PROPELLER HACK +async function sampleTerrain( + terrainProvider, + level, + positions, + failResultOnTileFail +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("terrainProvider", terrainProvider); + Check.typeOf.number("level", level); + Check.defined("positions", positions); + //>>includeEnd('debug'); + + // readyPromise has been deprecated; This is here for backwards compatibility + if (defined(terrainProvider._readyPromise)) { + await terrainProvider._readyPromise; + } else if (defined(terrainProvider.readyPromise)) { + await terrainProvider.readyPromise; + } + + // PROPELLER HACK + return doSampling(terrainProvider, level, positions, failResultOnTileFail); +} /** * @param {object[]} tileRequests The mutated list of requests, the first one will be attempted @@ -60,7 +83,11 @@ async function sampleTerrain(terrainProvider, level, positions) { * * @private */ -function attemptConsumeNextQueueItem(tileRequests, results) { +function attemptConsumeNextQueueItem( + tileRequests, + results, + failResultOnTileFail +) { const tileRequest = tileRequests[0]; const requestPromise = tileRequest.terrainProvider.requestTileGeometry( tileRequest.x, @@ -73,9 +100,16 @@ function attemptConsumeNextQueueItem(tileRequests, results) { return false; } - const promise = requestPromise - .then(createInterpolateFunction(tileRequest)) - .catch(createMarkFailedFunction(tileRequest)); + let promise; + // PROPELLER HACK + if (failResultOnTileFail) { + promise = requestPromise.then(createInterpolateFunction(tileRequest)); + } else { + promise = requestPromise + .then(createInterpolateFunction(tileRequest)) + .catch(createMarkFailedFunction(tileRequest)); + } + // END PROPELLER HACK // remove the request we've just done from the queue // and add its promise result to the result list @@ -106,7 +140,7 @@ function delay(ms) { * * @private */ -function drainTileRequestQueue(tileRequests, results) { +function drainTileRequestQueue(tileRequests, results, failResultOnTileFail) { // nothing left to do if (!tileRequests.length) { return Promise.resolve(); @@ -115,7 +149,11 @@ function drainTileRequestQueue(tileRequests, results) { // consume an item from the queue, which will // mutate the request and result lists, and return true if we should // immediately attempt to consume the next item as well - const success = attemptConsumeNextQueueItem(tileRequests, results); + const success = attemptConsumeNextQueueItem( + tileRequests, + results, + failResultOnTileFail + ); if (success) { return drainTileRequestQueue(tileRequests, results); } @@ -126,7 +164,7 @@ function drainTileRequestQueue(tileRequests, results) { }); } -function doSampling(terrainProvider, level, positions) { +function doSampling(terrainProvider, level, positions, failResultOnTileFail) { const tilingScheme = terrainProvider.tilingScheme; let i; @@ -162,7 +200,11 @@ function doSampling(terrainProvider, level, positions) { // create our list of result promises to be filled const tilePromises = []; - return drainTileRequestQueue(tileRequests, tilePromises).then(function () { + return drainTileRequestQueue( + tileRequests, + tilePromises, + failResultOnTileFail + ).then(function () { // now all the required requests have been started // we just wait for them all to finish return Promise.all(tilePromises).then(function () { diff --git a/packages/engine/Source/Scene/Camera.js b/packages/engine/Source/Scene/Camera.js index 0ecb9179283..7069ea49f86 100644 --- a/packages/engine/Source/Scene/Camera.js +++ b/packages/engine/Source/Scene/Camera.js @@ -29,6 +29,34 @@ import CameraFlightPath from "./CameraFlightPath.js"; import MapMode2D from "./MapMode2D.js"; import SceneMode from "./SceneMode.js"; +//PROPELLER HACK +function clampSphere(sphere, position, result) { + if ( + !defined(sphere) || + !defined(position) || + !position || + Cartesian3.equals(position, Cartesian3.ZERO) + ) { + return position; + } + + result = Cartesian3.clone(position, result); + if (Cartesian3.distance(result, sphere.center) <= sphere.radius) { + return result; + } + let directionVector = new Cartesian3(); + directionVector = Cartesian3.normalize( + Cartesian3.subtract(result, sphere.center, directionVector), + directionVector + ); + directionVector = Cartesian3.multiplyByScalar( + directionVector, + sphere.radius, + directionVector + ); + return Cartesian3.add(sphere.center, directionVector, result); +} + /** * @typedef {object} DirectionUp * @@ -85,6 +113,8 @@ function Camera(scene) { } //>>includeEnd('debug'); this._scene = scene; + //PROPELLER HACK + this.boundingSphere = undefined; this._transform = Matrix4.clone(Matrix4.IDENTITY); this._invTransform = Matrix4.clone(Matrix4.IDENTITY); @@ -700,6 +730,14 @@ function updateMembers(camera) { // Compute the Cartographic position of the camera. if (mode === SceneMode.SCENE3D || mode === SceneMode.MORPHING) { + //PROPELLER HACK + if (camera.boundingSphere) { + clampSphere( + camera.boundingSphere, + camera._positionWC, + camera._positionWC + ); + } camera._positionCartographic = camera._projection.ellipsoid.cartesianToCartographic( camera._positionWC, camera._positionCartographic @@ -1475,7 +1513,12 @@ Camera.prototype.setView = function (options) { ); convert = false; } - + //PROPELLER HACK + if (typeof destination !== "undefined") { + if (this.boundingSphere) { + clampSphere(this.boundingSphere, destination, destination); + } + } if (defined(orientation.direction)) { orientation = directionUpToHeadingPitchRoll( this, diff --git a/packages/engine/Source/Scene/PrimitiveCollection.js b/packages/engine/Source/Scene/PrimitiveCollection.js index 89591993dfe..f74f0a9f742 100644 --- a/packages/engine/Source/Scene/PrimitiveCollection.js +++ b/packages/engine/Source/Scene/PrimitiveCollection.js @@ -3,6 +3,7 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; +import Event from "../Core/Event.js"; /** * A collection of primitives. This is most often used with {@link Scene#primitives}, @@ -31,6 +32,8 @@ function PrimitiveCollection(options) { this._primitives = []; this._guid = createGuid(); + this._primitiveAdded = new Event(); + this._primitiveRemoved = new Event(); // Used by the OrderedGroundPrimitiveCollection this._zIndex = undefined; @@ -84,6 +87,32 @@ Object.defineProperties(PrimitiveCollection.prototype, { return this._primitives.length; }, }, + + /** + * An event that is raised when a primitive is added to the collection. + * Event handlers are passed the primitive that was added. + * @memberof PrimitiveCollection.prototype + * @type {Event} + * @readonly + */ + primitiveAdded: { + get: function () { + return this._primitiveAdded; + }, + }, + + /** + * An event that is raised when a primitive is removed from the collection. + * Event handlers are passed the primitive that was removed. + * @memberof PrimitiveCollection.prototype + * @type {Event} + * @readonly + */ + primitiveRemoved: { + get: function () { + return this._primitiveRemoved; + }, + }, }); /** @@ -128,6 +157,8 @@ PrimitiveCollection.prototype.add = function (primitive, index) { this._primitives.splice(index, 0, primitive); } + this._primitiveAdded.raiseEvent(primitive); + return primitive; }; @@ -159,6 +190,8 @@ PrimitiveCollection.prototype.remove = function (primitive) { primitive.destroy(); } + this._primitiveRemoved.raiseEvent(primitive); + return true; } // else ... this is not possible, I swear. @@ -191,6 +224,7 @@ PrimitiveCollection.prototype.removeAll = function () { const length = primitives.length; for (let i = 0; i < length; ++i) { delete primitives[i]._external._composites[this._guid]; + this._primitiveRemoved.raiseEvent(primitives[i]); if (this.destroyPrimitives) { primitives[i].destroy(); } diff --git a/packages/engine/node_modules/.bin/rimraf b/packages/engine/node_modules/.bin/rimraf new file mode 120000 index 00000000000..a3fa24f3547 --- /dev/null +++ b/packages/engine/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../../../../node_modules/rimraf/dist/cjs/src/bin.js \ No newline at end of file diff --git a/packages/engine/node_modules/.bin/topo2geo b/packages/engine/node_modules/.bin/topo2geo new file mode 120000 index 00000000000..2f5761279d9 --- /dev/null +++ b/packages/engine/node_modules/.bin/topo2geo @@ -0,0 +1 @@ +../../../../node_modules/topojson-client/bin/topo2geo \ No newline at end of file diff --git a/packages/engine/node_modules/.bin/topomerge b/packages/engine/node_modules/.bin/topomerge new file mode 120000 index 00000000000..b4f87d93a11 --- /dev/null +++ b/packages/engine/node_modules/.bin/topomerge @@ -0,0 +1 @@ +../../../../node_modules/topojson-client/bin/topomerge \ No newline at end of file diff --git a/packages/engine/node_modules/.bin/topoquantize b/packages/engine/node_modules/.bin/topoquantize new file mode 120000 index 00000000000..e758bd86ef8 --- /dev/null +++ b/packages/engine/node_modules/.bin/topoquantize @@ -0,0 +1 @@ +../../../../node_modules/topojson-client/bin/topoquantize \ No newline at end of file diff --git a/packages/engine/package.json b/packages/engine/package.json index 9b2228e14ef..9dc7ae47e9d 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,5 +1,5 @@ { - "name": "@cesium/engine", + "name": "@propelleraero/cesium-engine", "version": "2.4.1", "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ @@ -22,6 +22,12 @@ "README.md", "LICENSE.md" ], + "exports": { + ".": { + "import": "./index.js" + }, + "./Source/Scene/CameraFlightPath": "./Source/Scene/CameraFlightPath.js" + }, "engines": { "node": ">=14.0.0" }, @@ -32,6 +38,9 @@ "./Specs/**/*" ], "dependencies": { + "@aws-sdk/client-s3": "^3.362.0", + "@aws-sdk/lib-storage": "^3.362.0", + "@rollup/plugin-terser": "^0.4.3", "@tweenjs/tween.js": "^18.6.4", "@zip.js/zip.js": "2.4.x", "autolinker": "^4.0.0", @@ -48,6 +57,8 @@ "pako": "^2.0.4", "protobufjs": "^7.1.0", "rbush": "^3.0.1", + "rimraf": "^5.0.1", + "rollup-plugin-terser": "^7.0.2", "topojson-client": "^3.1.0", "urijs": "^1.19.7" }, diff --git a/packages/engine/yarn-error.log b/packages/engine/yarn-error.log new file mode 100644 index 00000000000..ceea222035f --- /dev/null +++ b/packages/engine/yarn-error.log @@ -0,0 +1,8101 @@ +Arguments: + /home/katrin/.nvm/versions/node/v14.21.2/bin/node /usr/local/bin/yarn add rollup-plugin-terser + ; + ; + +PATH: + /home/katrin/.nvm/versions/node/v14.21.2/bin:/home/katrin/.local/bin:/home/katrin/anaconda3/bin:/home/katrin/anaconda3/condabin:/home/katrin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + +Yarn version: + 1.22.19 + +Node version: + 14.21.2 + +Platform: + linux x64 + +Trace: + Error: https://registry.yarnpkg.com/rollup-plugin-terser%0A;%0A;: Not found + at Request.params.callback [as _callback] (/usr/local/lib/node_modules/yarn/lib/cli.js:66145:18) + at Request.self.callback (/usr/local/lib/node_modules/yarn/lib/cli.js:140890:22) + at Request.emit (events.js:400:28) + at Request. (/usr/local/lib/node_modules/yarn/lib/cli.js:141862:10) + at Request.emit (events.js:400:28) + at IncomingMessage. (/usr/local/lib/node_modules/yarn/lib/cli.js:141784:12) + at Object.onceWrapper (events.js:519:28) + at IncomingMessage.emit (events.js:412:35) + at endReadableNT (internal/streams/readable.js:1333:12) + at processTicksAndRejections (internal/process/task_queues.js:82:21) + +npm manifest: + { + "name": "@cesium/engine", + "version": "2.4.1", + "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", + "keywords": [ + "3D", + "webgl", + "geospatial", + "map", + "globe" + ], + "main": "index.js", + "module": "index.js", + "types": "index.d.ts", + "files": [ + "index.js", + "index.d.ts", + "Source", + "Build/**", + "!Build/Specs/**", + "!Build/minifyShaders.state", + "README.md", + "LICENSE.md" + ], + "engines": { + "node": ">=14.0.0" + }, + "sideEffects": [ + "./Source/ThirdParty/**/*", + "./Source/Widget/*.css", + "./Source/Workers/*", + "./Specs/**/*" + ], + "dependencies": { + "@aws-sdk/client-s3": "^3.362.0", + "@aws-sdk/lib-storage": "^3.362.0", + "@rollup/plugin-terser": "^0.4.3", + "@tweenjs/tween.js": "^18.6.4", + "@zip.js/zip.js": "2.4.x", + "autolinker": "^4.0.0", + "bitmap-sdf": "^1.0.3", + "dompurify": "^3.0.2", + "earcut": "^2.2.4", + "grapheme-splitter": "^1.0.4", + "jsep": "^1.3.8", + "kdbush": "^4.0.1", + "ktx-parse": "^0.5.0", + "lerc": "^2.0.0", + "mersenne-twister": "^1.1.0", + "meshoptimizer": "^0.19.0", + "pako": "^2.0.4", + "protobufjs": "^7.1.0", + "rbush": "^3.0.1", + "rimraf": "^5.0.1", + "topojson-client": "^3.1.0", + "urijs": "^1.19.7" + }, + "type": "module", + "scripts": { + "build": "gulp build --workspace @cesium/engine", + "build-ts": "gulp buildTs --workspace @cesium/engine", + "coverage": "gulp coverage --workspace @cesium/engine", + "test": "gulp test --workspace @cesium/engine", + "postversion": "gulp postversion --workspace @cesium/engine" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CesiumGS/cesium.git" + }, + "homepage": "https://cesium.com/cesiumjs/", + "license": "Apache-2.0", + "author": { + "name": "Cesium GS, Inc.", + "url": "https://cesium.com" + }, + "bugs": { + "url": "https://github.com/CesiumGS/cesium/issues" + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + + "@aws-crypto/crc32@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" + integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/crc32c@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz#016c92da559ef638a84a245eecb75c3e97cb664f" + integrity sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/ie11-detection@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" + integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== + dependencies: + tslib "^1.11.1" + + "@aws-crypto/sha1-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz#f9083c00782b24714f528b1a1fef2174002266a3" + integrity sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-crypto/sha256-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" + integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/sha256-js" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" + integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/supports-web-crypto@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" + integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== + dependencies: + tslib "^1.11.1" + + "@aws-crypto/util@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" + integrity sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-sdk/abort-controller@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.357.0.tgz#5c5336d18b97781d0b940700375d825f9e20d9be" + integrity sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/chunked-blob-reader@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.310.0.tgz#2ada1b024a2745c2fe7e869606fab781325f981e" + integrity sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/client-s3@^3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.362.0.tgz#3cee09ac6ed6d11e39bf9ef3b0ce327d21337f54" + integrity sha512-ZDQqfZ67ni/FVTGsGLELq2Y7Hq3lMUHf9SxVQn0v6Q8IIJwtmstUFxYPkiJMNAO1Lv93GdPkef1guoECRze70A== + dependencies: + "@aws-crypto/sha1-browser" "3.0.0" + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.362.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/eventstream-serde-browser" "3.357.0" + "@aws-sdk/eventstream-serde-config-resolver" "3.357.0" + "@aws-sdk/eventstream-serde-node" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-blob-browser" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/hash-stream-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/md5-js" "3.357.0" + "@aws-sdk/middleware-bucket-endpoint" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-expect-continue" "3.357.0" + "@aws-sdk/middleware-flexible-checksums" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-location-constraint" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-s3" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-ssec" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/signature-v4-multi-region" "3.357.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-stream" "3.360.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@aws-sdk/util-waiter" "3.357.0" + "@aws-sdk/xml-builder" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + + "@aws-sdk/client-sso-oidc@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.362.0.tgz#a2daad47e44c5cd902079467e9e0ac20bd8d90af" + integrity sha512-/urfavz0BjyeWSahp6oh9DjzV8oM5EPmza7iIZXJaPyK03enjse9A52vse4/EfKWaSHtapIgV3ZUKvYDk8AcKA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/client-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.362.0.tgz#5635380fa552d76cf039076e41611d01e00c31ab" + integrity sha512-11M+S7mlr8MBE8NB2yPZWOeb7BV4pcfQ+2p9EE9jVDbcq7VW21chvnf4F+L11aNV1yNtswsnHOSHLKM6YBMM7w== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/client-sts@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.362.0.tgz#f04ad1b9f0060d9b87aca74cc7199393f9d4064b" + integrity sha512-4Kh6oM2hfJbckuMb9O5eRIG66s/eA0wazXYvCbxSiSi3XgkX9L4m5OSNxlzLPe7uVgkEx8ykuk8Xz6qZrZWJcQ== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-sts" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + + "@aws-sdk/config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.357.0.tgz#7672b3f446ed64025d1763efea0289f7f49833a1" + integrity sha512-cukfg0nX7Tzx/xFyH5F4Eyb8DA1ITCGtSQv4vnEjgUop+bkzckuGLKEeBcBhyZY+aw+2C9CVwIHwIMhRm0ul5w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-config-provider" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-env@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.357.0.tgz#9746b9f958f490db5b1502d36cba7da43da460cb" + integrity sha512-UOecwfqvXgJVqhfWSZ2S44v2Nq2oceW0PQVQp0JAa9opc2rxSVIfyOhPr0yMoPmpyNcP22rgeg6ce70KULYwiA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-imds@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.357.0.tgz#6b5317c79e15a059a2f71623ec673bea03af04f6" + integrity sha512-upw/bfsl7/WydT6gM0lBuR4Ipp4fzYm/E3ObFr0Mg5OkgVPt5ZJE+eeFTvwCpDdBSTKs4JfrK6/iEK8A23Q1jQ== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-ini@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.362.0.tgz#e1f328616d0e4d3e32b109e81969058b3e95c47d" + integrity sha512-56gOo0XrqfEXTYrpWwZEYqrKEyNNpyNNvagfuP29d4aqok7ON5CkL1ymmKhNuDGHbbHXVGOIGdLNJBkGBgwE1g== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-node@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.362.0.tgz#0b5b6b4ed520a519bc5660a2f687ebf697a5db06" + integrity sha512-G/oCGTdN3Gx1HgSX6KlGC71q9EQw9luSgGGIgZHAw9u3IllLEARqxVQ5PUPlhEM4FkNNMpzicUbWeI5NeMRuyA== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-ini" "3.362.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-process@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.357.0.tgz#5e661bd4431a171ee862bb60ff0054d11dea150a" + integrity sha512-qFWWilFPsc2hR7O0KIhwcE78w+pVIK+uQR6MQMfdRyxUndgiuCorJwVjedc3yZtmnoELHF34j+m8whTBXv9E7Q== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.362.0.tgz#655ebe1a7f7f6a6ffc76698c4b7172b78cf8aa25" + integrity sha512-jf5jG8IQXNSTuOPMT0SMOpBi+Tlct+3Ik5njpEECFzo5POzU8DgJkc2ALMNW5j+XojuchwgeqWZclPRoacKjVw== + dependencies: + "@aws-sdk/client-sso" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/token-providers" "3.362.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-web-identity@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.357.0.tgz#32765fc53779d84c078d20e4e1585b8fedfcf61f" + integrity sha512-0KRRAFrXy5HJe2vqnCWCoCS+fQw7IoIj3KQsuURJMW4F+ifisxCgEsh3brJ2LQlN4ElWTRJhlrDHNZ/pd61D4w== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-codec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.357.0.tgz#32b6f0d97f3ea6e479e0d59c0a9b625faf3f887b" + integrity sha512-bqenTHG6GH6aCk/Il+ooWXVVAZuc8lOgVEy9bE2hI49oVqT8zSuXxQB+w1WWyZoAOPcelsjayB1wfPub8VDBxQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.357.0.tgz#fc2074bb7a9d8a358b9e0fb601924094af33c133" + integrity sha512-hBabtmwuspVHGSKnUccDiSIbg+IVoBThx6wYt6i4edbWAITHF3ADVKXy7icV400CAyG0XTZgxjE6FKpiDxj9rQ== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.357.0.tgz#d5db248a17fb22bc95d3088b7d840a065f015251" + integrity sha512-E6rwk+1KFXhKmJ+v7JW5Uyyda1yN5XRVupCnCrtFsHFmhVGQxFacoUZIee3bfuCpC58dLSyESggxGpUd3XOSsw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.357.0.tgz#4fc79eea9eb85c173f44ad8e37550231e81cf144" + integrity sha512-boXDy+JWcPfHc9OIKV6I4Bh2XrLcg+eac+/LldNZFcDIB33/gHIM2CJw8u565Iebdz1NKEkP/QPPZbk2y+abPA== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-universal@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.357.0.tgz#b83fb0bbc9623eb3e5a698cb3bfd1b8c502fd351" + integrity sha512-9/Wcdxx38XQAturqOAGYNCaLOzFVnW+xwxd4af9eNOfZfZ5PP5PRKBIpvKDsN26e3l4f3GodHx7MS1WB7BBc2w== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/fetch-http-handler@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.357.0.tgz#8b33b8cefe036fd932b694242893ef3db1a74f02" + integrity sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/hash-blob-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.357.0.tgz#e507929499fe0fe128664b67cd26f63f16ed4d25" + integrity sha512-RDd6UgrGHDmleTnXM9LRSSVa69euSAG2mlNhZMEDWk3OFseXVYqBDaqroVbQ01rM2UAe8MeBFchlV9OmxuVgvw== + dependencies: + "@aws-sdk/chunked-blob-reader" "3.310.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/hash-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.357.0.tgz#70666b0d6a49191cf33ef32b235c33b242de36ce" + integrity sha512-fq3LS9AxHKb7dTZkm6iM1TrGk6XOTZz96iEZPME1+vjiSEXGWuebHt87q92n+KozVGRypn9MId3lHOPBBjygNQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/hash-stream-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.357.0.tgz#a78c6d1ae1c78cb52854311bad50988e8fc12142" + integrity sha512-KZjN1VAw1KHNp+xKVOWBGS+MpaYQTjZFD5f+7QQqW4TfbAkFFwIAEYIHq5Q8Gw+jVh0h61OrV/LyW3J2PVzc+w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/invalid-dependency@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.357.0.tgz#4e86c689a6b0c4d0fe43ba335218d67e9aa652a6" + integrity sha512-HnCYZczf0VdyxMVMMxmA3QJAyyPSFbcMtZzgKbxVTWTG7GKpQe0psWZu/7O2Nk31mKg6vEUdiP1FylqLBsgMOA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/is-array-buffer@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz#f87a79f1b858c88744f07e8d8d0a791df204017e" + integrity sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/lib-storage@^3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.362.0.tgz#734f046cc5ee7727da089efe49c1de6f8f922dc2" + integrity sha512-r3KUIEPLAiZdnxbK+9fgAnxKEjsyeB7wFd0rKuOL+TZouaBSGz2ctni2/tAwN0Om3y8boKWmcUrbUWndN5vjHA== + dependencies: + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/smithy-client" "3.360.0" + buffer "5.6.0" + events "3.3.0" + stream-browserify "3.0.0" + tslib "^2.5.0" + + "@aws-sdk/md5-js@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.357.0.tgz#61853f562e71af0ec58aeede7883de122177ed55" + integrity sha512-to42sFAL7KgV/X9X40LLfEaNMHMGQL6/7mPMVCL/W2BZf3zw5OTl3lAaNyjXA+gO5Uo4lFEiQKAQVKNbr8b8Nw== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-bucket-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.357.0.tgz#9d19ba4a7971c5302e32d024e477755a1f6185ff" + integrity sha512-ep2T0FJXRDl6nffLqiVZUYfDocZ3B72wvHeozckkLVRX0TK91WEpzv4Zz2vdeBp6CGkM3g8oGjbb6ZqllUZ6TA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + "@aws-sdk/util-config-provider" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-content-length@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.357.0.tgz#eafad2db1816cb5d91cd1e090211f040f29bbdaa" + integrity sha512-zQOFEyzOXAgN4M54tYNWGxKxnyzY0WwYDTFzh9riJRmxN1hTEKHUKmze4nILIf5rkQmOG4kTf1qmfazjkvZAhw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.357.0.tgz#bc94bbf55339aa5220011f4ae8e03a7966ce28be" + integrity sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg== + dependencies: + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-expect-continue@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.357.0.tgz#c392c4f31300695158070223f1e337c7503aca92" + integrity sha512-KeizuiiDmdLeAbiNsJt/rZENY5iJo4wCTl7h81htDC60wSwVwFG03IdgvZlFH6jktYRh4mUDD/6Oljme6yPNxw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-flexible-checksums@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.357.0.tgz#957a383dc66942e63493d2ba182ee775e8139507" + integrity sha512-NNQ/iPN6YyzqgVaV8AeYQMZ8y1OmUW27vmt0R66UUw5H5THGc6X9QXoKfie7OHn80Qv1S8P5jw8z5MpvDtjSnQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-crypto/crc32c" "3.0.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-host-header@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.357.0.tgz#9d4f803fc7d9b1f5582a62844b1d841b3c849fe0" + integrity sha512-HuGLcP7JP1qJ5wGT9GSlEknDaTSnOzHY4T6IPFuvFjAy3PvY5siQNm6+VRqdVS+n6/kzpL3JP5sAVM3aoxHT6Q== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-location-constraint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.357.0.tgz#b147973f70c82cf06d3bafcf32b6b826203bcb69" + integrity sha512-4IsIHhwZ2/o7yjLI1XtGMkJ442cbIN5/NtI/Ml0G5UHYviUm8sqvH2vldFBMK5bPuVdk6GpqXpy6wYc9rLJj2w== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-logger@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.357.0.tgz#851a44a934ad8f33465ae4665a6c07ac967a8bbb" + integrity sha512-dncT3tr+lZ9+duZo52rASgO6AKVwRcsc2/T93gmaYVrJqI6WWAwQ7yML5s72l9ZjQ5LZ+4jjrgtlufavAS0eCg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-recursion-detection@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.357.0.tgz#2d7a8cf43f1299c1ff1e113988bd801e7f527401" + integrity sha512-AXC54IeDS3jC1dbbkYHML4STvBPcKZ4IJTWdjEK1RCOgqXd0Ze1cE1e21wyj1tM6prF03zLyvpBd+3TS++nqfA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.362.0.tgz#0d886a18a4560a05267d841545e64b4ca360c06e" + integrity sha512-ZFsty5fXIdvTTm+GnTtCPre89b2QFZYQmD0L5nhJULDFoU5Fz/bsI5C3b98/wb4YCAIfXBZpx4Kh2RAEKnxkyg== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/service-error-classification" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + tslib "^2.5.0" + uuid "^8.3.2" + + "@aws-sdk/middleware-sdk-s3@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.357.0.tgz#3962e60183930b497599357f42f531578544eb18" + integrity sha512-EFQaPD8SoXcK7RiEOZz0zIX9owQW6txu8vrOOVva9xMts36z/3E7b4FVsgEJ53Ixa1x38ddPJxp4U8EIaf+pvQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-sdk-sts@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.357.0.tgz#8f9be3db8f4fd8563baf66925ee326f579b6ae4d" + integrity sha512-Ng2VjLrPiL02QOcs1qs9jG2boO4Gn+v3VIbOJLG4zXcfbSq55iIWtlmr2ljfw9vP5aLhWtcODfmKHS5Bp+019Q== + dependencies: + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-serde@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.357.0.tgz#2614031c81981580bce4bee502985e28e51dadb2" + integrity sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-signing@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.357.0.tgz#9aee1ad571b092ad0bbd63e0b551ffb575220688" + integrity sha512-yB9ewEqI6Fw1OrmKFrUypbCqN5ijk06UGPochybamMuPxxkwMT3bnrm7eezsCA+TZbJyKhpffpyobwuv+xGNrA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-ssec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.357.0.tgz#c99b9b457cfaee32796110b324d2d5056c86b4df" + integrity sha512-uE3nNvJclcY7SgGoOgDCUgfc7ElXQmWVpks8AZzAjJj7bG5j6Bv3FOOYtGtvtxUzTHaOdn+yQwjssV1cZ6GTQw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-stack@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.357.0.tgz#51f181691e8c76694b6583561ba0a0a14472506c" + integrity sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/middleware-user-agent@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.357.0.tgz#d4d27549bbcfdc03f5a8db74435a345b05b40373" + integrity sha512-M/CsAXjGblZS4rEbMb0Dn9IXbfq4EjVaTHBfvuILU/dKRppWvjnm2lRtqCZ+LIT3ATbAjA3/dY7dWsjxQWwijA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-endpoints" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/node-config-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.357.0.tgz#2e47aa36e5efae89b65c79b8c27180d3d8a2d901" + integrity sha512-kwBIzKCaW3UWqLdELhy7TcN8itNMOjbzga530nalFILMvn2IxrkdKQhNgxGBXy6QK6kCOtH6OmcrG3/oZkLwig== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/node-http-handler@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.360.0.tgz#6f762b57f98887b5173886f890669e6a60bf792c" + integrity sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/property-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.357.0.tgz#4c1639c2d52aefab4040c2247c126c11b19d8be9" + integrity sha512-im4W0u8WaYxG7J7ko4Xl3OEzK3Mrm1Rz6/txTGe6hTIHlyUISu1ekOQJXK6XYPqNMn8v1G3BiQREoRXUEJFbHg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/protocol-http@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.357.0.tgz#cd47413d6c1ed2d27bc30c7e9da3b262c8804cf4" + integrity sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/querystring-builder@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.357.0.tgz#0d4627620eba4d3cc523c2e1da88dfa561617599" + integrity sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/querystring-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.357.0.tgz#6dfeb42930b2241cda43646d7c1d16ca886c78af" + integrity sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/service-error-classification@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.357.0.tgz#1c6f6e436997a1886d55cfec6d4796129b789076" + integrity sha512-VuXeL4g5vKO9HjgCZlxmH8Uv1FcqUSjmbPpQkbNtYIDck6u0qzM0rG+n0/1EjyQbPSr3MhW/pkWs5nx2Nljlyg== + + "@aws-sdk/shared-ini-file-loader@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.357.0.tgz#af503df79e05bb9ee0e5d689319c9b52cefe1801" + integrity sha512-ceyqM4XxQe0Plb/oQAD2t1UOV2Iy4PFe1oAGM8dfJzYrRKu7zvMwru7/WaB3NYq+/mIY6RU+jjhRmjQ3GySVqA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/signature-v4-multi-region@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.357.0.tgz#100c573029e2b30a65634090e55be4beb50e16a1" + integrity sha512-eyO3GibYLNCPZ/YxM/ZVDh1fTMKvIUj4fpVo0bxQTKNlqNkVumAIOVLoH5um1A9FN7nDdz+40a7jwYSPlkxW6A== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/signature-v4@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.357.0.tgz#31093e87fda10bee92b6b2784cdba9af9af89e7d" + integrity sha512-itt4/Jh9FqnzK30qIjXFBvM4J7zN4S/AAqsRMnaX7U4f/MV+1YxQHmzimpdMnsCXXs2jqFqKVRu6DewxJ3nbxg== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/smithy-client@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.360.0.tgz#59d55eb41eccc22ca2d3d32c11b60135f882e66d" + integrity sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw== + dependencies: + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-stream" "3.360.0" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/token-providers@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.362.0.tgz#bd0ad974d7a96a06e6f1b574258e63e749e7cbb2" + integrity sha512-w7NTeB2j1CRdvDa7m08KQr12HN6qrOknXhGEMmf67bfdfAdmPWsJXIbxcKH8eze+acOzoimbqv8KyCVmyX/pCQ== + dependencies: + "@aws-sdk/client-sso-oidc" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/types@3.357.0", "@aws-sdk/types@^3.222.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.357.0.tgz#8491da71a4291cc2661c26a75089e86532b6a3b5" + integrity sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/url-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.357.0.tgz#1b197f252d008e201d1e301c8024bed770ef0b2c" + integrity sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg== + dependencies: + "@aws-sdk/querystring-parser" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-arn-parser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz#861ff8810851be52a320ec9e4786f15b5fc74fba" + integrity sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-base64@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz#d0fd49aff358c5a6e771d0001c63b1f97acbe34c" + integrity sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-body-length-browser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz#3fca9d2f73c058edf1907e4a1d99a392fdd23eca" + integrity sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-body-length-node@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz#4846ae72834ab0636f29f89fc1878520f6543fed" + integrity sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-buffer-from@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz#7a72cb965984d3c6a7e256ae6cf1621f52e54a57" + integrity sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw== + dependencies: + "@aws-sdk/is-array-buffer" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-config-provider@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz#ff21f73d4774cfd7bd16ae56f905828600dda95f" + integrity sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-defaults-mode-browser@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.360.0.tgz#fced018e4990220dc31881a5b2b3e425fe08e970" + integrity sha512-/GR8VlK9xo1Q5WbVYuNaZ+XfoCFdWNb4z4mpoEgvEgBH4R0GjqiAqLftUA8Ykq1tJuDAKPYVzUNzK8DC0pt7/g== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + + "@aws-sdk/util-defaults-mode-node@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.360.0.tgz#83e2812474d8807d6d220c5064576e63e4ea8306" + integrity sha512-gR3Ctqpyl7SgStDJ1Jlq6qQDuw/rS9AgbAXx+s3wsmm3fm8lHKkXkDPYVvNDqd6dVXRO6q8MRx00lwkGI4qrpQ== + dependencies: + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-endpoints@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.357.0.tgz#eaa7b4481bbd9fc8f13412b308ba4129d8fa2004" + integrity sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-hex-encoding@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz#19294c78986c90ae33f04491487863dc1d33bd87" + integrity sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-locate-window@^3.0.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz#b071baf050301adee89051032bd4139bba32cc40" + integrity sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-middleware@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.357.0.tgz#1ba478dde5df4e53b231ec6651b8d44c9187f66d" + integrity sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-retry/-/util-retry-3.362.0.tgz#ab4a2bef4fef528cfa58e0840ba28fb5f1c3ca11" + integrity sha512-LDRGKaF2EMcFEa6AlS+ilLiDEeHWyR5FN2+RHdfGQjcqn+Zdd5H6Vc0vUF5Z4PH3hXr5LPZcDh+zM7DlG22KJg== + dependencies: + "@aws-sdk/service-error-classification" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-stream@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream/-/util-stream-3.360.0.tgz#a6cf43cf594540e9d1a4e19b9acbc5c34b3a1225" + integrity sha512-t3naBfNesXwLis29pzSfLx2ifCn2180GiPjRaIsQP14IiVCBOeT1xaU6Dpyk7WeR/jW4cu7wGl+kbeyfNF6QmQ== + dependencies: + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-uri-escape@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz#9f942f09a715d8278875013a416295746b6085ba" + integrity sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-user-agent-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.357.0.tgz#21c3e6c1a3d610dd279952d3ce00909775019be5" + integrity sha512-JHaWlNIUkPNvXkqeDOrqFzAlAgdwZK5mZw7FQnCRvf8tdSogpGZSkuyb9Z6rLD9gC40Srbc2nepO1cFpeMsDkA== + dependencies: + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + + "@aws-sdk/util-user-agent-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.357.0.tgz#a656cebce558b602e753e45a3b8174dc7c0f1fcf" + integrity sha512-RdpQoaJWQvcS99TVgSbT451iGrlH4qpWUWFA9U1IRhxOSsmC1hz8ME7xc8nci9SREx/ZlfT3ai6LpoAzAtIEMA== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + + "@aws-sdk/util-utf8@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz#4a7b9dcebb88e830d3811aeb21e9a6df4273afb4" + integrity sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-waiter@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.357.0.tgz#31fdaf289ed60a633178b39e3b258f9b42a1cbe3" + integrity sha512-jQQGA5G8bm0JP5C4U85VzMpkFHdeeT7fOSUncXLG9Sh8Ambzi4XTud8m5/dA7aNJkvPwZeIF9QdgWCOzpkp1xA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/xml-builder@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz#f0236f2103b438d16117e0939a6305ad69b7ff76" + integrity sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw== + dependencies: + tslib "^2.5.0" + + "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + + "@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + + "@babel/core@^7.12.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + + "@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + + "@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + + "@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + + "@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + + "@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + + "@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + + "@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + + "@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + + "@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + + "@babel/parser@^7.14.7", "@babel/parser@^7.18.6", "@babel/parser@^7.18.9", "@babel/parser@^7.9.4": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== + + "@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + + "@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + + "@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + + "@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + + "@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + + "@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + + "@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + + "@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + + "@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + + "@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + + "@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + + "@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + + "@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + + "@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + + "@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + + "@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + + "@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + + "@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + + "@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + + "@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + + "@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + + "@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + + "@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + + "@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + + "@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + + "@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + + "@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + + "@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + + "@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + + "@eslint/js@8.43.0": + version "8.43.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" + integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== + + "@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + + "@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + + "@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + + "@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + + "@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + + "@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + + "@jridgewell/gen-mapping@^0.3.0": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + + "@jridgewell/source-map@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + + "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + + "@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + + "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + + "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + + "@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + + "@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + + "@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + + "@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + + "@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + + "@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + + "@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + + "@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + + "@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + + "@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + + "@rollup/plugin-commonjs@^22.0.2": + version "22.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz#ee8ca8415cda30d383b4096aad5222435b4b69b6" + integrity sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + + "@rollup/plugin-node-resolve@^15.0.1": + version "15.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz#72be449b8e06f6367168d5b3cd5e2802e0248971" + integrity sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-builtin-module "^3.2.0" + is-module "^1.0.0" + resolve "^1.22.1" + + "@rollup/plugin-terser@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz#c2bde2fe3a85e45fa68a454d48f4e73e57f98b30" + integrity sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA== + dependencies: + serialize-javascript "^6.0.1" + smob "^1.0.0" + terser "^5.17.4" + + "@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + + "@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + + "@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + + "@smithy/protocol-http@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-1.1.0.tgz#caf22e01cb825d7490a4915e03d6fa64954ff535" + integrity sha512-H5y/kZOqfJSqRkwtcAoVbqONmhdXwSgYNJ1Glk5Ry8qlhVVy5qUzD9EklaCH8/XLnoCsLO/F/Giee8MIvaBRkg== + dependencies: + "@smithy/types" "^1.1.0" + tslib "^2.5.0" + + "@smithy/types@^1.0.0", "@smithy/types@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.1.0.tgz#f30a23202c97634cca5c1ac955a9bf149c955226" + integrity sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw== + dependencies: + tslib "^2.5.0" + + "@tweenjs/tween.js@^18.6.4": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-18.6.4.tgz#40a3d0a93647124872dec8e0fd1bd5926695b6ca" + integrity sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ== + + "@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + + "@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + + "@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + + "@types/estree@*", "@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + + "@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + + "@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + + "@types/linkify-it@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" + integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== + + "@types/markdown-it@^12.2.3": + version "12.2.3" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" + integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== + dependencies: + "@types/linkify-it" "*" + "@types/mdurl" "*" + + "@types/mdurl@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" + integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== + + "@types/node@*", "@types/node@>=10.0.0": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" + integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== + + "@types/node@>=13.7.0": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39" + integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg== + + "@types/node@^14.14.41": + version "14.18.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.22.tgz#fd2a15dca290fc9ad565b672fde746191cd0c6e6" + integrity sha512-qzaYbXVzin6EPjghf/hTdIbnVW1ErMx8rPzwRNJhlbyJhu2SyqlvjGOY/tbUt6VFyzg56lROcOeSQRInpt63Yw== + + "@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + + "@types/vinyl@^2.0.4": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.6.tgz#b2d134603557a7c3d2b5d3dc23863ea2b5eb29b0" + integrity sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g== + dependencies: + "@types/expect" "^1.20.4" + "@types/node" "*" + + "@zip.js/zip.js@2.4.x": + version "2.4.26" + resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.4.26.tgz#b79bb2055dc6e185890ee01cdb710caba505d5b2" + integrity sha512-I9HBO3BHIxEMQmltmHM3iqUW6IHqi3gsL9wTSXvHTRpOrA6q2OxtR58EDSaOGjHhDVJ+wIOAxZyKq2x00AVmqw== + + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + + acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + + acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + + acorn@^8.8.2: + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + + ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + + ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + + ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + + ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + + ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + + ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + + ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + + ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + + ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + + any-promise@^1.1.0, any-promise@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + + anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + + anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + + append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA== + dependencies: + buffer-equal "^1.0.0" + + archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA== + dependencies: + file-type "^4.2.0" + + archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + + argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + + arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + + arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA== + dependencies: + make-iterator "^1.0.0" + + arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + + arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw== + dependencies: + make-iterator "^1.0.0" + + arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + + array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA== + + array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + + array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw== + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + + array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + + array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + + array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + + array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + + asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + + assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + + assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + + async-done@^1.2.0, async-done@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" + integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^2.0.0" + stream-exhaust "^1.0.1" + + async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + + async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw== + dependencies: + async-done "^1.2.2" + + asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + + atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + + autolinker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-4.0.0.tgz#aa1f9a52786b727b0ecee8cd7d4a97e0e3ef59f1" + integrity sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw== + dependencies: + tslib "^2.3.0" + + available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + + aws-sdk@^2.1210.0: + version "2.1346.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1346.0.tgz#b259748135daec9252ee9f65f0387b32e9b94c9d" + integrity sha512-sLN7DUQ4KGkVCRN9uU5amz+k5qj5HFdwq0itH7WLtFGG63/vG/HnrqHj1G0PyMij0Zz6CGlRBACstWRm0niYhQ== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.16.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + util "^0.12.4" + uuid "8.0.0" + xml2js "0.4.19" + + aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + + aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + + bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg== + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + + balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + + base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + + base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + + base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + + bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + + big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + + binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + + binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + + binaryextensions@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" + integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== + + bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + + bitmap-sdf@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz#e87b8b1d84ee846567cfbb29d60eedd34bca5b6f" + integrity sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg== + + bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + + bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + + body-parser@1.20.0, body-parser@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + + bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + + bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + + brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + + brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + + braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + + braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + + browserslist@^4.20.2: + version "4.21.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + + buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + + buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + + buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + + buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== + + buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + + buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + + buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + + buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + + buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + + builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + + bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + + bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + + bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + + cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + + cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ== + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + + call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + + callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + + camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + + caniuse-lite@^1.0.30001366: + version "1.0.30001368" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001368.tgz#c5c06381c6051cd863c45021475434e81936f713" + integrity sha512-wgfRYa9DenEomLG/SdWgQxpIyvdtH3NW8Vq+tB6AwR9e56iOIcu1im5F/wNdDf04XlKHXqIx4N8Jo0PemeBenQ== + + caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + + catharsis@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== + dependencies: + lodash "^4.17.15" + + chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + + chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + + chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + + chokidar@^3.5.1, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + + class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + + clean-css@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + + cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + + cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + + cloc@^2.8.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/cloc/-/cloc-2.10.0.tgz#1dbd3755a9ca8d426e9222b2e8a4feaecf855837" + integrity sha512-iHYXbhKNF+Wy6TNxHozD8WkW0qbZ7WKecyFntyFron4BF4SOX6hp7HEuNJ8iVnjimnf3xpLd81kMwoRj2WiCoA== + + clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== + + clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q== + dependencies: + mimic-response "^1.0.0" + + clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== + + clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + + cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + + code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + + collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA== + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + + collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + + color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + + color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + + color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + + color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + + color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + + colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + + combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + + commander@2, commander@^2.20.0, commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + + commander@~10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + + commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + + component-emitter@^1.2.1, component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + + compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + + compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + + concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + + concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + + connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + + content-disposition@0.5.4, content-disposition@^0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + + content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + + convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + + cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + + cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + + cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + + copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + + copy-props@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== + dependencies: + each-props "^1.3.2" + is-plain-object "^5.0.0" + + core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + + core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + + cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + + custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + + d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + + dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + + data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + + date-format@^4.0.10, date-format@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.12.tgz#82c3607e33f8d25fa25b3415b565fe726a34574d" + integrity sha512-L018twW1B6J49/vmoxFSWTwKfUaKJI42cJ2xz1WeNSKaS4uVN5D44f3KfEuYUlZvFybWDJt6YuqVDPZp+IIF/g== + + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + + debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + + decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + + decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + + decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + + decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + + decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + + decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + + decompress@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + + deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + + deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + + deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + + default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + + default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + + default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + + default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ== + + define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + + define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + + define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + + define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + + define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + + delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + + depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + + destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + + detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== + + di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + + dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + + doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + + dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + + dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + + domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + + domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + + dompurify@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.3.tgz#4b115d15a091ddc96f232bcef668550a2f6f1430" + integrity sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ== + + domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + + download@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" + integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== + dependencies: + archive-type "^4.0.0" + content-disposition "^0.5.2" + decompress "^4.2.1" + ext-name "^5.0.0" + file-type "^11.1.0" + filenamify "^3.0.0" + get-stream "^4.1.0" + got "^8.3.1" + make-dir "^2.1.0" + p-event "^2.1.0" + pify "^4.0.1" + + draco3d@^1.5.1: + version "1.5.3" + resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.3.tgz#75dfb3da7d1420571b1ab999191c49fdc2a74571" + integrity sha512-Ahum6SewAd1oVMm6Fk8T/zCE0qbzjohhO5pl1Xp5Outl4JKv7jYicfd5vNtkzImx94XE35fhNXVqHk9ajt+6Tg== + + duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + + duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + + each-props@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + + earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== + + eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + + ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + + edge-launcher@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/edge-launcher/-/edge-launcher-1.2.2.tgz#eb40aafbd067a6ea76efffab0647bcd5509b37b2" + integrity sha512-JcD5WBi3BHZXXVSSeEhl6sYO8g5cuynk/hifBzds2Bp4JdzCGLNMHgMCKu5DvrO1yatMgF0goFsxXRGus0yh1g== + + ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + + electron-to-chromium@^1.4.188: + version "1.4.197" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.197.tgz#172054244cca16320ebc19459bd03d8a9018ff73" + integrity sha512-7EZCIDDraA2NUaHewLaAh6T63cZzgBmgDx/iiaeZ/pjSs36bOFEJ3hLIrn1TKCFhV0PEZZKu6qFPrxa/LGAzLg== + + emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + + emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + + encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@~1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + + engine.io-parser@~5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" + integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== + + engine.io@~6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0" + integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + + ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + + entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + + entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + + entities@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + + error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + + es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0: + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + + es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + + es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + + es6-iterator@^2.0.1, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + + es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + + es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + + esbuild@^0.17.10: + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + + escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + + escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + + escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + + escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + + escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + + eslint-config-cesium@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-cesium/-/eslint-config-cesium-9.0.1.tgz#0104862809cb519d8f275fb4c657e876489e484b" + integrity sha512-9UR1YIdz44bzfXU0cZAH9oUEJ6pZj8CQPFMcMJsg1R9fH1SwSzK+mQSytt6VkvAfURGgb/nrZmncDZEeJ7YV2g== + + eslint-config-prettier@^8.3.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + + eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + + eslint-plugin-es@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" + integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + + eslint-plugin-html@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz#aec2a3772b40ccf51a5be4f972f07600539d3b3e" + integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== + dependencies: + htmlparser2 "^8.0.1" + + eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + + eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + + eslint-utils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + + eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + + eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + + eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + + eslint@^8.41.0: + version "8.43.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" + integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.43.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + + espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + + esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + + esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + + estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + + estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + + estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + + estree-walker@^2.0.1, estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + + esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + + etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + + eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + + events@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== + + events@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + + execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + + execa@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + + expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== + dependencies: + homedir-polyfill "^1.0.1" + + express@^4.17.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + + ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + + ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + + ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + + extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + + extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + + extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + + extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + + extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + + fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + + fast-glob@^3.2.11: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + + fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + + fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw== + + fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + + fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + + fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + + fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + + fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + + file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + + file-type@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" + integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== + + file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + + file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ== + + file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + + file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + + file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + + filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + + filenamify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" + integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + + fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + + fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + + finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + + finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + + find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + + find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + + findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g== + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + + findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + + fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + + flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + + flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + + flatted@^3.1.0, flatted@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== + + flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + + follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + + for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + + for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + + for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== + dependencies: + for-in "^1.0.1" + + foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + + forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + + form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + + formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + + forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + + fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + + fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + + from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + + fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + + fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + + fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ== + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + + fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + + fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + + fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + + function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + + function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + + functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + + gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + + get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + + get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + + get-stdin@~9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" + integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== + + get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + + get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + + get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + + get-stream@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + + get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + + get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + + get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + + getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + + glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + + glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + + glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + + glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw== + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + + glob-watcher@^5.0.3: + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + normalize-path "^3.0.0" + object.defaults "^1.1.0" + + glob@^10.2.5: + version "10.3.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.1.tgz#9789cb1b994515bedb811a6deca735b5c37d2bf4" + integrity sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.10.0" + + glob@^7.1.1, glob@^7.1.3, glob@^7.1.6, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@~10.2.2: + version "10.2.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" + integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.7.0" + + global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + + global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + + globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + + globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + + globby@^13.1.3: + version "13.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.0.tgz#7dd5678d765c4680c2e6d106230d86cb727cb1af" + integrity sha512-jWsQfayf13NvqKUIL3Ta+CIqMnvlaIDFveWE/dpOZ9+3AMEJozsxDvKA02zync9UuvOM8rOXzsD5GqKP4OnWPQ== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + + glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + + glsl-strip-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-strip-comments/-/glsl-strip-comments-1.0.0.tgz#bf8d121edb7482c965d24b8da6080310e55a51a5" + integrity sha512-hDzztQDaa/3YIUZVFlrfaCPnll6gdJntgUDj9ohKtPsoRVxQeNd580qW6PxVROPwD/6WAbqUiiLdRfB1NLDbFQ== + dependencies: + glsl-tokenizer "^2.1.2" + + glsl-tokenizer@^2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a" + integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA== + dependencies: + through2 "^0.6.3" + + got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + + graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.6: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + + graceful-fs@^4.1.10, graceful-fs@^4.2.10: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + + grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + + graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + + gulp-clean-css@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz#5b1e73f2fca46703eb636014cdd4553cea65146d" + integrity sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg== + dependencies: + clean-css "4.2.3" + plugin-error "1.0.1" + through2 "3.0.1" + vinyl-sourcemaps-apply "0.2.1" + + gulp-cli@^2.2.0, gulp-cli@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.4.0" + isobject "^3.0.1" + liftoff "^3.1.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.2.0" + yargs "^7.1.0" + + gulp-insert@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/gulp-insert/-/gulp-insert-0.5.0.tgz#32313f13e4a23cf5acca5ce5f0c080923c778602" + integrity sha512-SDKCWmjomAo0N0Bzj9qEKIfURORJR/72p6AbDBIK9yKZw794ROTrQHliBem+NJzS2GsTWSm8dGWJ5L7KtjnMRA== + dependencies: + readable-stream "^1.0.26-4" + streamqueue "0.0.6" + + gulp-rename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-2.0.0.tgz#9bbc3962b0c0f52fc67cd5eaff6c223ec5b9cf6c" + integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ== + + gulp-replace@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-1.1.3.tgz#8641cdca78e683e8573ca4a012e7e4ebb7e4db60" + integrity sha512-HcPHpWY4XdF8zxYkDODHnG2+7a3nD/Y8Mfu3aBgMiCFDW3X2GiOKXllsAmILcxe3KZT2BXoN18WrpEFm48KfLQ== + dependencies: + "@types/node" "^14.14.41" + "@types/vinyl" "^2.0.4" + istextorbinary "^3.0.0" + replacestream "^4.0.3" + yargs-parser ">=5.0.0-security.0" + + gulp-tap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-tap/-/gulp-tap-2.0.0.tgz#6f66b79870dcbfc364cf4ebe0735b6008473200f" + integrity sha512-U5/v1bTozx672QHzrvzPe6fPl2io7Wqyrx2y30AG53eMU/idH4BrY/b2yikOkdyhjDqGgPoMUMnpBg9e9LK8Nw== + dependencies: + through2 "^3.0.1" + + gulp-zip@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-5.1.0.tgz#38cc1d4c61bc2ab06b452ce463cbe2adc52b935e" + integrity sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw== + dependencies: + get-stream "^5.2.0" + plugin-error "^1.0.1" + through2 "^3.0.1" + vinyl "^2.1.0" + yazl "^2.5.1" + + gulp@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" + integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== + dependencies: + glob-watcher "^5.0.3" + gulp-cli "^2.2.0" + undertaker "^1.2.1" + vinyl-fs "^3.0.0" + + gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw== + dependencies: + glogg "^1.0.0" + + har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + + har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + + has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + + has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + + has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + + has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + + has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + + has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + + has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + + has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + + has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + + has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + + has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + + has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + + homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + + hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + + html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + + htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + + http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + + http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + + http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + + http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + + human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + + human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + + husky@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" + integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== + + iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + + ieee754@1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + + ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + + ignore@^5.1.1, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + + ignore@~5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + + import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + + imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + + inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + + inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + + ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + + ini@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.0.tgz#2f6de95006923aa75feed8894f5686165adc08f1" + integrity sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw== + + install@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/install/-/install-0.13.0.tgz#6af6e9da9dd0987de2ab420f78e60d9c17260776" + integrity sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA== + + internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + + interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + + into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ== + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + + invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + + ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + + is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + + is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + + is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + + is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + + is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + + is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + + is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + + is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + + is-builtin-module@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + + is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + + is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + + is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + + is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + + is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + + is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + + is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + + is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + + is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + + is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + + is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + + is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + + is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + + is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + + is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + + is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + + is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + + is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + + is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug== + + is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + + is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + + is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + + is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + + is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + + is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + + is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + + is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + + is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + + is-reference@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + + is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + + is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + + is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + + is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + + is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + + is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + + is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + + is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + + is-typed-array@^1.1.3, is-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67" + integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + + is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + + is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + + is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + + is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA== + + is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + + is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + + is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + + isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + + isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + + isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + + isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + + isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + + isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + + istanbul-lib-instrument@^5.1.0, istanbul-lib-instrument@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + + istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + + istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + + istanbul-reports@^3.0.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + + istextorbinary@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-3.3.0.tgz#06b1c57d948da11461bd237c00ce09e9902964f2" + integrity sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ== + dependencies: + binaryextensions "^2.2.0" + textextensions "^3.2.0" + + isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + + jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + + jasmine-core@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.2.0.tgz#0605bea284d6d78276f43c47de2532ecd4a73b00" + integrity sha512-OcFpBrIhnbmb9wfI8cqPSJ50pv3Wg4/NSgoZIqHzIwO/2a9qivJWzv8hUvaREIMYYJBas6AvfXATFdVuzzCqVw== + + jasmine-core@^4.1.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.6.0.tgz#6884fc3d5b66bf293e422751eed6d6da217c38f5" + integrity sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ== + + jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== + + js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + + js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + + js2xmlparser@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz#2a1fdf01e90585ef2ae872a01bc169c6a8d5e60a" + integrity sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA== + dependencies: + xmlcreate "^2.0.4" + + jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + + jsdoc@^3.6.7: + version "3.6.11" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.11.tgz#8bbb5747e6f579f141a5238cbad4e95e004458ce" + integrity sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg== + dependencies: + "@babel/parser" "^7.9.4" + "@types/markdown-it" "^12.2.3" + bluebird "^3.7.2" + catharsis "^0.9.0" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.2" + klaw "^3.0.0" + markdown-it "^12.3.2" + markdown-it-anchor "^8.4.1" + marked "^4.0.10" + mkdirp "^1.0.4" + requizzle "^0.2.3" + strip-json-comments "^3.1.0" + taffydb "2.6.2" + underscore "~1.13.2" + + jsep@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/jsep/-/jsep-1.3.8.tgz#facb6eb908d085d71d950bd2b24b757c7b8a46d7" + integrity sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ== + + jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + + json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + + json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + + json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + + json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + + json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + + json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + + jsonc-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + + jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + + jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + + just-debounce@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" + integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== + + karma-chrome-launcher@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" + integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== + dependencies: + which "^1.2.1" + + karma-coverage@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.2.0.tgz#64f838b66b71327802e7f6f6c39d569b7024e40c" + integrity sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + + karma-detect-browsers@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/karma-detect-browsers/-/karma-detect-browsers-2.3.3.tgz#e0d8f9c1a1b0cc58d8668c245441eaf9d832c6ee" + integrity sha512-ltFVyA3ijThv9l9TQ+TKnccoMk6YAWn8OMaccL+n8pO2LGwMOcy6tUWy3Mnv9If29jqvVHDCWntj7wBQpPtv7Q== + dependencies: + which "^1.2.4" + + karma-edge-launcher@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz#3d9529b09b13c909c5f3ceee12d00e7f9a989b3d" + integrity sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw== + dependencies: + edge-launcher "1.2.2" + + karma-firefox-launcher@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz#9a38cc783c579a50f3ed2a82b7386186385cfc2d" + integrity sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA== + dependencies: + is-wsl "^2.2.0" + which "^2.0.1" + + karma-ie-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz#497986842c490190346cd89f5494ca9830c6d59c" + integrity sha512-ts71ke8pHvw6qdRtq0+7VY3ANLoZuUNNkA8abRaWV13QRPNm7TtSOqyszjHUtuwOWKcsSz4tbUtrNICrQC+SXQ== + dependencies: + lodash "^4.6.1" + + karma-jasmine@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-5.1.0.tgz#3af4558a6502fa16856a0f346ec2193d4b884b2f" + integrity sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ== + dependencies: + jasmine-core "^4.1.0" + + karma-longest-reporter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/karma-longest-reporter/-/karma-longest-reporter-1.1.0.tgz#37ba11e421334a0d0d5117e24dace8f2caec9919" + integrity sha512-c34tJbZUntkXMWK6S44NHLsYwF6Nu76+57ZGZvGLlbeltYanlKg/cgs1JqxwEdPz3m0Z2WSMhxBW6pcv0ycn1g== + + karma-safari-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz#96982a2cc47d066aae71c553babb28319115a2ce" + integrity sha512-qmypLWd6F2qrDJfAETvXDfxHvKDk+nyIjpH9xIeI3/hENr0U3nuqkxaftq73PfXZ4aOuOChA6SnLW4m4AxfRjQ== + + karma-sourcemap-loader@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + + karma-spec-reporter@^0.0.36: + version "0.0.36" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz#c54dc155dec2ded1f92ea68dbbdd67fcedbef350" + integrity sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w== + dependencies: + colors "1.4.0" + + karma@^6.3.20: + version "6.4.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" + integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + + kdbush@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + + keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + + kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + + kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + + kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + + klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + + ktx-parse@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ktx-parse/-/ktx-parse-0.5.0.tgz#b4025bbc73ac5386ac37e869de455eab915261bc" + integrity sha512-5IZrv5s1byUeDTIee1jjJQBiD5LPDB0w9pJJ0oT9BCKKJf16Tuj123vm1Ps0GOHSHmeWPgKM0zuViCVuTRpqaA== + + last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ== + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + + lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + + lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + + lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow== + dependencies: + flush-write-stream "^1.0.2" + + lerc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lerc/-/lerc-2.0.0.tgz#82feca29ea6202799a815ca38f7b66a370e8cf9b" + integrity sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg== + + levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + + liftoff@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + + linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + + linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + + load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + + locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + + lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + + lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.6.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + + log4js@^6.4.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.6.0.tgz#e8fd00143d1e0ecf1d10959bb69b90b1b30137f3" + integrity sha512-3v8R7fd45UB6THucSht6wN2/7AZEruQbXdjygPZcxt5TA/msO6si9CN5MefUuKXbYnJHTBnYcx4famwcyQd+sA== + dependencies: + date-format "^4.0.11" + debug "^4.3.4" + flatted "^3.2.5" + rfdc "^1.3.0" + streamroller "^3.1.1" + + long@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + + lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A== + + lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + + "lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + + magic-string@^0.25.3, magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + + make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + + make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + + make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + + make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + + map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + + map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + + markdown-it-anchor@^8.4.1: + version "8.6.4" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz#affb8aa0910a504c114e9fcad53ac3a5b907b0e6" + integrity sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img== + + markdown-it@13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" + integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + + markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + + markdownlint-cli@^0.34.0: + version "0.34.0" + resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.34.0.tgz#d7a4ae8e59911de6dfb01782a7cd554e8a245947" + integrity sha512-4G9I++VBTZkaye6Yfc/7dU6HQHcyldZEVB+bYyQJLcpJOHKk/q5ZpGqK80oKMIdlxzsA3aWOJLZ4DkoaoUWXbQ== + dependencies: + commander "~10.0.1" + get-stdin "~9.0.0" + glob "~10.2.2" + ignore "~5.2.4" + js-yaml "^4.1.0" + jsonc-parser "~3.2.0" + markdownlint "~0.28.2" + minimatch "~9.0.0" + run-con "~1.2.11" + + markdownlint-micromark@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz#5520e04febffa46741875a2f297509ffdb561f5c" + integrity sha512-jRxlQg8KpOfM2IbCL9RXM8ZiYWz2rv6DlZAnGv8ASJQpUh6byTBnEsbuMZ6T2/uIgntyf7SKg/mEaEBo1164fQ== + + markdownlint@~0.28.2: + version "0.28.2" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.28.2.tgz#ea31586a02fe3a06403ecafbbe22d77e363c8ed5" + integrity sha512-yYaQXoKKPV1zgrFsyAuZPEQoe+JrY9GDag9ObKpk09twx4OCU5lut+0/kZPrQ3W7w82SmgKhd7D8m34aG1unVw== + dependencies: + markdown-it "13.0.1" + markdownlint-micromark "0.1.2" + + marked@^4.0.10: + version "4.0.18" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" + integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== + + matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA== + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + + mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + + media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + + merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + + merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + + merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + + mersenne-twister@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" + integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA== + + meshoptimizer@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/meshoptimizer/-/meshoptimizer-0.19.0.tgz#1669e6d788ad3ffd238a65184e478355642ca979" + integrity sha512-58qz5Qc/6Geu8Ib3bBWERE5R7pM5ErrJVo16fAtu6ryxVaE3VAtM/u2vurDxaq8AGZ3yWxuM/DnylTga5a4XCQ== + + methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + + micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + + mime-db@1.52.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.28.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + + mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + + mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + + mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + + mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + + mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + + mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + + mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + + minimatch@^9.0.1, minimatch@~9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" + integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== + dependencies: + brace-expansion "^2.0.1" + + minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + + minimist@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + + "minipass@^5.0.0 || ^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" + integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== + + mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + + mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + + mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + + mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + + ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + + ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + + ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + + mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + + nan@^2.12.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + + nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + + negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + + next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + + node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + + node-fetch@^3.2.10: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + + node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + + normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + + normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + + normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + + normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + + nosleep.js@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/nosleep.js/-/nosleep.js-0.12.0.tgz#a01fddab2c13af357d673928b1f40a9013a4dc08" + integrity sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA== + + now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + + npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + + npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + + number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + + oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + + object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + + object-inspect@^1.12.0, object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + + object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + + object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + + object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + + object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA== + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + + object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + + object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + + object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + + on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + + on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + + on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + + once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + + onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + + onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + + open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + + optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + + ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw== + dependencies: + readable-stream "^2.0.1" + + os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + + p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + + p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + + p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + + p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg== + + p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + + p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + + p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + + p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + + pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + + parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + + parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q== + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + + parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + + parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + + parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== + + parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + + pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + + path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + + path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + + path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + + path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + + path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + + path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + + path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + + path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== + + path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== + dependencies: + path-root-regex "^0.1.0" + + path-scurry@^1.10.0, path-scurry@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.0.tgz#0ffbd4c1f7de9600f98a1405507d9f9acb438ab3" + integrity sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2" + + path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + + path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + + path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + + pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + + performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + + picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + + pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + + pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + + pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + + pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + + pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + + plugin-error@1.0.1, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + + posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + + prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + + prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + + prettier@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" + integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== + + pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + + prismjs@^1.28.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + + protobufjs@^7.1.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2" + integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + + proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + + psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + + pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + + punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + + punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + + qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + + qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + + qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + + query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + + querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + + queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + + quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + + randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + + range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + + raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + + rbush@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf" + integrity sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w== + dependencies: + quickselect "^2.0.0" + + read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + + read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + + "readable-stream@2 || 3": + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + + "readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + + readable-stream@^1.0.26-2, readable-stream@^1.0.26-4: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + + readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readable-stream@^2.3.0: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readable-stream@^3.5.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + + readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + + readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + + rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + + regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + + regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + + regexpp@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + + remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + + remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA== + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + + remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + + repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + + repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + + replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + + replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg== + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + + replacestream@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" + integrity sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA== + dependencies: + escape-string-regexp "^1.0.3" + object-assign "^4.0.1" + readable-stream "^2.0.2" + + request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + + require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + + require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + + requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + + requizzle@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" + integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== + dependencies: + lodash "^4.17.14" + + resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + + resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + + resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A== + dependencies: + value-or-function "^3.0.0" + + resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + + resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.22.1, resolve@^1.4.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + + responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + + ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + + reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + + rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + + rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + + rimraf@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" + integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== + dependencies: + glob "^10.2.5" + + rollup-plugin-strip-pragma@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-strip-pragma/-/rollup-plugin-strip-pragma-1.0.0.tgz#dd6d8c76788af460b16f7f1ca0e90a6e672236f7" + integrity sha512-ydv83CoA07wls7ZWwd4HtjjsoR9vM65SFR/B2tR8D2ppXyZajiQlx5cTJadAXMl9NADnXjUTMHW+kFzOkLoNdA== + dependencies: + magic-string "^0.25.3" + rollup-pluginutils "^2.8.2" + + rollup-pluginutils@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + + rollup@^2.78.0: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + + run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + + run-con@~1.2.11: + version "1.2.12" + resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.12.tgz#51c319910e45a3bd71ee773564a89d96635c8c64" + integrity sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg== + dependencies: + deep-extend "^0.6.0" + ini "~3.0.0" + minimist "^1.2.8" + strip-json-comments "~3.1.1" + + run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + + safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + + safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + + "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + + sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== + + sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + + seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + + semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ== + dependencies: + sver-compat "^1.5.0" + + "semver@2 || 3 || 4 || 5", semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + + semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + + send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + + serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + + serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + + set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + + set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + + setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + + shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + + shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + + side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + + signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + + signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + + slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + + smob@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/smob/-/smob-1.4.0.tgz#ac9751fe54b1fc1fc8286a628d4e7f824273b95a" + integrity sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg== + + snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + + snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + + snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + + socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== + + socket.io-parser@~4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.5.tgz#cb404382c32324cc962f27f3a44058cf6e0552df" + integrity sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + + socket.io@^4.4.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029" + integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.2.0" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.0.4" + + sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + + sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + + sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== + dependencies: + is-plain-obj "^1.0.0" + + source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + + source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + + source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + + source-map@^0.5.1, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + + source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + + sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + + sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + + spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + + spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + + spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + + spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + + split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + + sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + + stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + + static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + + statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + + statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + + stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + + stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + + stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + + stream-to-array@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" + integrity sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA== + dependencies: + any-promise "^1.1.0" + + stream-to-promise@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-3.0.0.tgz#8934d66dcbc9189394e8b33200da3bb9611db774" + integrity sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA== + dependencies: + any-promise "~1.3.0" + end-of-stream "~1.4.1" + stream-to-array "~2.3.0" + + streamqueue@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/streamqueue/-/streamqueue-0.0.6.tgz#66f5f5ec94e9b8af249e4aec2dd1f741bfe94de3" + integrity sha512-l09LNfTUkmLMckTB1Mm8Um5GMS1uTZ/KTodg/SMf5Nx758IOsmaqIQ/AJumAnNMkDgZBG39btq3LVkN90knq8w== + dependencies: + readable-stream "^1.0.26-2" + + streamroller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.1.tgz#679aae10a4703acdf2740755307df0a05ad752e6" + integrity sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ== + dependencies: + date-format "^4.0.10" + debug "^4.3.4" + fs-extra "^10.1.0" + + strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + + "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + + string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + + string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + + string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + + string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + + string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + + string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + + string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + + "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + + strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + + strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + + strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + + strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + + strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + + strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + + strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + + strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + + supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + + supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + + supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + + sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg== + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + + taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA== + + tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + + terser@^5.17.4: + version "5.18.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.2.tgz#ff3072a0faf21ffd38f99acc9a0ddf7b5f07b948" + integrity sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + + text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + + textextensions@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-3.3.0.tgz#03530d5287b86773c08b77458589148870cc71d3" + integrity sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw== + + through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + + through2@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + + through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg== + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + + through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + + through2@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + + through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + + time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + + timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + + titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + + tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + + to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA== + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + + to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + + to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + + to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + + to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + + to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + + to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + + to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q== + dependencies: + through2 "^2.0.3" + + toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + + topojson-client@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" + integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== + dependencies: + commander "2" + + tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + + trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + + tsd-jsdoc@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tsd-jsdoc/-/tsd-jsdoc-2.5.0.tgz#0677aa952e1a8e3ebbb5bcf7d6e2f0301d71e151" + integrity sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g== + dependencies: + typescript "^3.2.1" + + tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + + tslib@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + + tslib@^2.3.1, tslib@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + + tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + + tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + + type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + + type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + + type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + + type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + + type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + + typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + + typescript@^3.2.1: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + + typescript@^5.0.2: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + + ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + + uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + + unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + + unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + + unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg== + + underscore@~1.13.2: + version "1.13.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" + integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== + + undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw== + + undertaker@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + + union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + + unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + + universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + + unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + + unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + + untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + + upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + + update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + + uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + + urijs@^1.19.7: + version "1.19.11" + resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc" + integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ== + + urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + + url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + + url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== + + url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + + use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + + util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + + util@^0.12.4: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + + utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + + uuid@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" + integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== + + uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + + uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + + v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + + validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + + value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg== + + vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + + verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + + vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + + vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA== + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + + vinyl-sourcemaps-apply@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw== + dependencies: + source-map "^0.5.1" + + vinyl@^2.0.0, vinyl@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + + void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + + web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + + which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + + which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + + which-typed-array@^1.1.2: + version "1.1.8" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f" + integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.9" + + which@^1.2.1, which@^1.2.14, which@^1.2.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + + which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + + word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + + wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + + wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + + wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + + ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + + xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + + xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ== + + xmlcreate@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" + integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== + + "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + + y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + + y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + + yargs-parser@>=5.0.0-security.0, yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + + yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + + yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + + yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + + yargs@^17.0.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + + yargs@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.1" + + yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + + yazl@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + + yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + + yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 62ed777d78f..f3abdb78780 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -1,5 +1,5 @@ { - "name": "@cesium/widgets", + "name": "@propelleraero/cesium-widgets", "version": "2.3.1", "description": "A widgets library for use with CesiumJS. CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "keywords": [ @@ -27,6 +27,11 @@ "engines": { "node": ">=14.0.0" }, + "exports": { + ".": { + "import": "./index.js" + } + }, "dependencies": { "@cesium/engine": "2.4.1", "nosleep.js": "^0.12.0" diff --git a/yarn-error.log b/yarn-error.log new file mode 100644 index 00000000000..d629637b698 --- /dev/null +++ b/yarn-error.log @@ -0,0 +1,8061 @@ +Arguments: + /usr/local/bin/node /usr/local/bin/yarn + +PATH: + /home/katrin/.local/bin:/home/katrin/anaconda3/bin:/home/katrin/anaconda3/condabin:/home/katrin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + +Yarn version: + 1.22.19 + +Node version: + 14.21.1 + +Platform: + linux x64 + +Trace: + SyntaxError: /home/katrin/workspace/cesium_p1/packages/engine/package.json: Unexpected token / in JSON at position 30 + at JSON.parse () + at /usr/local/lib/node_modules/yarn/lib/cli.js:1629:59 + at Generator.next () + at step (/usr/local/lib/node_modules/yarn/lib/cli.js:310:30) + at /usr/local/lib/node_modules/yarn/lib/cli.js:321:13 + +npm manifest: + { + "name": "@propelleraero/cesium", + "version": "1.106.1", + "private" : "true", + "description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", + "homepage": "http://cesium.com/cesiumjs/", + "license": "Apache-2.0", + "author": { + "name": "Cesium GS, Inc.", + "url": "https://cesium.com" + }, + "contributors": [ + { + "name": "CesiumJS community", + "url": "https://github.com/CesiumGS/cesium/blob/main/CONTRIBUTORS.md" + } + ], + "keywords": [ + "3D", + "webgl", + "geospatial", + "map", + "globe" + ], + "repository": { + "type": "git", + "url": "https://github.com/CesiumGS/cesium.git" + }, + "bugs": { + "url": "https://github.com/CesiumGS/cesium/issues", + "email": "cesium-dev@googlegroups.com" + }, + "main": "index.cjs", + "module": "./Source/Cesium.js", + "types": "./Source/Cesium.d.ts", + "exports": { + "./package.json": "./package.json", + "./Source/*": "./Source/*", + "./Source/*.js": null, + "./Build/*": "./Build/*", + "./Build/*.js": null, + ".": { + "require": "./index.cjs", + "import": "./Source/Cesium.js" + }, + "./Source/Scene/CameraFlightPath": "./Source/Scene/CameraFlightPath.js" + }, + "type": "module", + "sideEffects": [ + "./Source/ThirdParty/**/*", + "./Source/Widgets/**/*.css", + "./Source/Workers/*", + "./Specs/**/*" + ], + "dependencies": { + "@cesium/engine": "2.4.1", + "@cesium/widgets": "2.3.1" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^22.0.2", + "@rollup/plugin-node-resolve": "^15.0.1", + "aws-sdk": "^2.1210.0", + "chokidar": "^3.5.3", + "cloc": "^2.8.0", + "compression": "^1.7.4", + "decompress": "^4.2.1", + "download": "^8.0.0", + "draco3d": "^1.5.1", + "esbuild": "^0.17.10", + "eslint": "^8.41.0", + "eslint-config-cesium": "^9.0.1", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-es": "^4.1.0", + "eslint-plugin-html": "^7.1.0", + "eslint-plugin-node": "^11.1.0", + "express": "^4.17.1", + "globby": "^13.1.3", + "glsl-strip-comments": "^1.0.0", + "gulp": "^4.0.2", + "gulp-clean-css": "^4.3.0", + "gulp-cli": "^2.3.0", + "gulp-insert": "^0.5.0", + "gulp-rename": "^2.0.0", + "gulp-replace": "^1.1.3", + "gulp-tap": "^2.0.0", + "gulp-zip": "^5.1.0", + "husky": "^7.0.2", + "install": "^0.13.0", + "istanbul-lib-instrument": "^5.2.0", + "jasmine-core": "^4.0.1", + "jsdoc": "^3.6.7", + "karma": "^6.3.20", + "karma-chrome-launcher": "^3.1.0", + "karma-coverage": "^2.0.3", + "karma-detect-browsers": "^2.3.3", + "karma-edge-launcher": "^0.4.2", + "karma-firefox-launcher": "^2.1.1", + "karma-ie-launcher": "^1.0.0", + "karma-jasmine": "^5.1.0", + "karma-longest-reporter": "^1.1.0", + "karma-safari-launcher": "^1.0.0", + "karma-sourcemap-loader": "^0.4.0", + "karma-spec-reporter": "^0.0.36", + "markdownlint-cli": "^0.34.0", + "merge-stream": "^2.0.0", + "mime": "^3.0.0", + "mkdirp": "^3.0.1", + "node-fetch": "^3.2.10", + "open": "^9.1.0", + "p-limit": "^4.0.0", + "prettier": "2.1.2", + "prismjs": "^1.28.0", + "request": "^2.79.0", + "rimraf": "^3.0.2", + "rollup": "^2.78.0", + "rollup-plugin-strip-pragma": "^1.0.0", + "stream-to-promise": "^3.0.0", + "tsd-jsdoc": "^2.5.0", + "typescript": "^5.0.2", + "yargs": "^17.0.1" + }, + "scripts": { + "prepare": "gulp prepare && husky install", + "start": "node server.js", + "start-public": "node server.js --public", + "build": "gulp build", + "build-release": "gulp buildRelease", + "build-watch": "gulp buildWatch", + "build-ts": "gulp buildTs", + "build-third-party": "gulp buildThirdParty", + "build-apps": "gulp buildApps", + "clean": "gulp clean", + "cloc": "gulp cloc", + "codeship:decrypt": "./deployment/crypto.sh decrypt ./deployment/encrypted ./deployment/secrets", + "codeship:encrypt": "./deployment/crypto.sh encrypt ./deployment/secrets ./deployment/encrypted", + "coverage": "gulp coverage", + "build-docs": "gulp buildDocs", + "build-docs-watch": "gulp buildDocsWatch", + "eslint": "eslint \"./**/*.js\" \"./**/*.cjs\" \"./**/*.html\" --cache --quiet", + "make-zip": "gulp makeZip", + "markdownlint": "markdownlint \"*.md\" \"Documentation/**/*.md\" \"packages/**/*.md\" --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", + "release": "gulp release", + "website-release": "gulp websiteRelease", + "test": "gulp test", + "test-all": "gulp test --all", + "test-webgl": "gulp test --include WebGL", + "test-non-webgl": "gulp test --exclude WebGL", + "test-webgl-validation": "gulp test --webglValidation", + "test-webgl-stub": "gulp test --webglStub", + "test-release": "gulp test --release", + "deploy-s3": "gulp deployS3", + "deploy-status": "gulp deployStatus", + "deploy-set-version": "gulp deploySetVersion", + "prettier": "prettier --write --no-config \"**/*\"", + "prettier-check": "prettier --check --no-config \"**/*\"" + }, + "engines": { + "node": ">=14.0.0" + }, + "lint-staged": { + "*.{js,cjs,html}": [ + "eslint --cache --quiet", + "prettier --write --no-config" + ], + "*.md": [ + "markdownlint --ignore CHANGES.md --ignore \"./**/LICENSE.md\"", + "prettier --write --no-config" + ] + }, + "workspaces": [ + "packages/engine", + "packages/widgets" + ] + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + + "@aws-crypto/crc32@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" + integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/crc32c@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz#016c92da559ef638a84a245eecb75c3e97cb664f" + integrity sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/ie11-detection@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" + integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== + dependencies: + tslib "^1.11.1" + + "@aws-crypto/sha1-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz#f9083c00782b24714f528b1a1fef2174002266a3" + integrity sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-crypto/sha256-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" + integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/sha256-js" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" + integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + + "@aws-crypto/supports-web-crypto@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" + integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== + dependencies: + tslib "^1.11.1" + + "@aws-crypto/util@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" + integrity sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + + "@aws-sdk/abort-controller@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.357.0.tgz#5c5336d18b97781d0b940700375d825f9e20d9be" + integrity sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/chunked-blob-reader@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.310.0.tgz#2ada1b024a2745c2fe7e869606fab781325f981e" + integrity sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/client-s3@^3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.362.0.tgz#3cee09ac6ed6d11e39bf9ef3b0ce327d21337f54" + integrity sha512-ZDQqfZ67ni/FVTGsGLELq2Y7Hq3lMUHf9SxVQn0v6Q8IIJwtmstUFxYPkiJMNAO1Lv93GdPkef1guoECRze70A== + dependencies: + "@aws-crypto/sha1-browser" "3.0.0" + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.362.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/eventstream-serde-browser" "3.357.0" + "@aws-sdk/eventstream-serde-config-resolver" "3.357.0" + "@aws-sdk/eventstream-serde-node" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-blob-browser" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/hash-stream-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/md5-js" "3.357.0" + "@aws-sdk/middleware-bucket-endpoint" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-expect-continue" "3.357.0" + "@aws-sdk/middleware-flexible-checksums" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-location-constraint" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-s3" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-ssec" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/signature-v4-multi-region" "3.357.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-stream" "3.360.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@aws-sdk/util-waiter" "3.357.0" + "@aws-sdk/xml-builder" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + + "@aws-sdk/client-sso-oidc@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.362.0.tgz#a2daad47e44c5cd902079467e9e0ac20bd8d90af" + integrity sha512-/urfavz0BjyeWSahp6oh9DjzV8oM5EPmza7iIZXJaPyK03enjse9A52vse4/EfKWaSHtapIgV3ZUKvYDk8AcKA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/client-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.362.0.tgz#5635380fa552d76cf039076e41611d01e00c31ab" + integrity sha512-11M+S7mlr8MBE8NB2yPZWOeb7BV4pcfQ+2p9EE9jVDbcq7VW21chvnf4F+L11aNV1yNtswsnHOSHLKM6YBMM7w== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/client-sts@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.362.0.tgz#f04ad1b9f0060d9b87aca74cc7199393f9d4064b" + integrity sha512-4Kh6oM2hfJbckuMb9O5eRIG66s/eA0wazXYvCbxSiSi3XgkX9L4m5OSNxlzLPe7uVgkEx8ykuk8Xz6qZrZWJcQ== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-sts" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + + "@aws-sdk/config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.357.0.tgz#7672b3f446ed64025d1763efea0289f7f49833a1" + integrity sha512-cukfg0nX7Tzx/xFyH5F4Eyb8DA1ITCGtSQv4vnEjgUop+bkzckuGLKEeBcBhyZY+aw+2C9CVwIHwIMhRm0ul5w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-config-provider" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-env@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.357.0.tgz#9746b9f958f490db5b1502d36cba7da43da460cb" + integrity sha512-UOecwfqvXgJVqhfWSZ2S44v2Nq2oceW0PQVQp0JAa9opc2rxSVIfyOhPr0yMoPmpyNcP22rgeg6ce70KULYwiA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-imds@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.357.0.tgz#6b5317c79e15a059a2f71623ec673bea03af04f6" + integrity sha512-upw/bfsl7/WydT6gM0lBuR4Ipp4fzYm/E3ObFr0Mg5OkgVPt5ZJE+eeFTvwCpDdBSTKs4JfrK6/iEK8A23Q1jQ== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-ini@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.362.0.tgz#e1f328616d0e4d3e32b109e81969058b3e95c47d" + integrity sha512-56gOo0XrqfEXTYrpWwZEYqrKEyNNpyNNvagfuP29d4aqok7ON5CkL1ymmKhNuDGHbbHXVGOIGdLNJBkGBgwE1g== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-node@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.362.0.tgz#0b5b6b4ed520a519bc5660a2f687ebf697a5db06" + integrity sha512-G/oCGTdN3Gx1HgSX6KlGC71q9EQw9luSgGGIgZHAw9u3IllLEARqxVQ5PUPlhEM4FkNNMpzicUbWeI5NeMRuyA== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-ini" "3.362.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-process@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.357.0.tgz#5e661bd4431a171ee862bb60ff0054d11dea150a" + integrity sha512-qFWWilFPsc2hR7O0KIhwcE78w+pVIK+uQR6MQMfdRyxUndgiuCorJwVjedc3yZtmnoELHF34j+m8whTBXv9E7Q== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.362.0.tgz#655ebe1a7f7f6a6ffc76698c4b7172b78cf8aa25" + integrity sha512-jf5jG8IQXNSTuOPMT0SMOpBi+Tlct+3Ik5njpEECFzo5POzU8DgJkc2ALMNW5j+XojuchwgeqWZclPRoacKjVw== + dependencies: + "@aws-sdk/client-sso" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/token-providers" "3.362.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/credential-provider-web-identity@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.357.0.tgz#32765fc53779d84c078d20e4e1585b8fedfcf61f" + integrity sha512-0KRRAFrXy5HJe2vqnCWCoCS+fQw7IoIj3KQsuURJMW4F+ifisxCgEsh3brJ2LQlN4ElWTRJhlrDHNZ/pd61D4w== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-codec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.357.0.tgz#32b6f0d97f3ea6e479e0d59c0a9b625faf3f887b" + integrity sha512-bqenTHG6GH6aCk/Il+ooWXVVAZuc8lOgVEy9bE2hI49oVqT8zSuXxQB+w1WWyZoAOPcelsjayB1wfPub8VDBxQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.357.0.tgz#fc2074bb7a9d8a358b9e0fb601924094af33c133" + integrity sha512-hBabtmwuspVHGSKnUccDiSIbg+IVoBThx6wYt6i4edbWAITHF3ADVKXy7icV400CAyG0XTZgxjE6FKpiDxj9rQ== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.357.0.tgz#d5db248a17fb22bc95d3088b7d840a065f015251" + integrity sha512-E6rwk+1KFXhKmJ+v7JW5Uyyda1yN5XRVupCnCrtFsHFmhVGQxFacoUZIee3bfuCpC58dLSyESggxGpUd3XOSsw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.357.0.tgz#4fc79eea9eb85c173f44ad8e37550231e81cf144" + integrity sha512-boXDy+JWcPfHc9OIKV6I4Bh2XrLcg+eac+/LldNZFcDIB33/gHIM2CJw8u565Iebdz1NKEkP/QPPZbk2y+abPA== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/eventstream-serde-universal@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.357.0.tgz#b83fb0bbc9623eb3e5a698cb3bfd1b8c502fd351" + integrity sha512-9/Wcdxx38XQAturqOAGYNCaLOzFVnW+xwxd4af9eNOfZfZ5PP5PRKBIpvKDsN26e3l4f3GodHx7MS1WB7BBc2w== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/fetch-http-handler@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.357.0.tgz#8b33b8cefe036fd932b694242893ef3db1a74f02" + integrity sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/hash-blob-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.357.0.tgz#e507929499fe0fe128664b67cd26f63f16ed4d25" + integrity sha512-RDd6UgrGHDmleTnXM9LRSSVa69euSAG2mlNhZMEDWk3OFseXVYqBDaqroVbQ01rM2UAe8MeBFchlV9OmxuVgvw== + dependencies: + "@aws-sdk/chunked-blob-reader" "3.310.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/hash-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.357.0.tgz#70666b0d6a49191cf33ef32b235c33b242de36ce" + integrity sha512-fq3LS9AxHKb7dTZkm6iM1TrGk6XOTZz96iEZPME1+vjiSEXGWuebHt87q92n+KozVGRypn9MId3lHOPBBjygNQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/hash-stream-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.357.0.tgz#a78c6d1ae1c78cb52854311bad50988e8fc12142" + integrity sha512-KZjN1VAw1KHNp+xKVOWBGS+MpaYQTjZFD5f+7QQqW4TfbAkFFwIAEYIHq5Q8Gw+jVh0h61OrV/LyW3J2PVzc+w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/invalid-dependency@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.357.0.tgz#4e86c689a6b0c4d0fe43ba335218d67e9aa652a6" + integrity sha512-HnCYZczf0VdyxMVMMxmA3QJAyyPSFbcMtZzgKbxVTWTG7GKpQe0psWZu/7O2Nk31mKg6vEUdiP1FylqLBsgMOA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/is-array-buffer@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz#f87a79f1b858c88744f07e8d8d0a791df204017e" + integrity sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/md5-js@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.357.0.tgz#61853f562e71af0ec58aeede7883de122177ed55" + integrity sha512-to42sFAL7KgV/X9X40LLfEaNMHMGQL6/7mPMVCL/W2BZf3zw5OTl3lAaNyjXA+gO5Uo4lFEiQKAQVKNbr8b8Nw== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-bucket-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.357.0.tgz#9d19ba4a7971c5302e32d024e477755a1f6185ff" + integrity sha512-ep2T0FJXRDl6nffLqiVZUYfDocZ3B72wvHeozckkLVRX0TK91WEpzv4Zz2vdeBp6CGkM3g8oGjbb6ZqllUZ6TA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + "@aws-sdk/util-config-provider" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-content-length@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.357.0.tgz#eafad2db1816cb5d91cd1e090211f040f29bbdaa" + integrity sha512-zQOFEyzOXAgN4M54tYNWGxKxnyzY0WwYDTFzh9riJRmxN1hTEKHUKmze4nILIf5rkQmOG4kTf1qmfazjkvZAhw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.357.0.tgz#bc94bbf55339aa5220011f4ae8e03a7966ce28be" + integrity sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg== + dependencies: + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-expect-continue@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.357.0.tgz#c392c4f31300695158070223f1e337c7503aca92" + integrity sha512-KeizuiiDmdLeAbiNsJt/rZENY5iJo4wCTl7h81htDC60wSwVwFG03IdgvZlFH6jktYRh4mUDD/6Oljme6yPNxw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-flexible-checksums@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.357.0.tgz#957a383dc66942e63493d2ba182ee775e8139507" + integrity sha512-NNQ/iPN6YyzqgVaV8AeYQMZ8y1OmUW27vmt0R66UUw5H5THGc6X9QXoKfie7OHn80Qv1S8P5jw8z5MpvDtjSnQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-crypto/crc32c" "3.0.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-host-header@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.357.0.tgz#9d4f803fc7d9b1f5582a62844b1d841b3c849fe0" + integrity sha512-HuGLcP7JP1qJ5wGT9GSlEknDaTSnOzHY4T6IPFuvFjAy3PvY5siQNm6+VRqdVS+n6/kzpL3JP5sAVM3aoxHT6Q== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-location-constraint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.357.0.tgz#b147973f70c82cf06d3bafcf32b6b826203bcb69" + integrity sha512-4IsIHhwZ2/o7yjLI1XtGMkJ442cbIN5/NtI/Ml0G5UHYviUm8sqvH2vldFBMK5bPuVdk6GpqXpy6wYc9rLJj2w== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-logger@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.357.0.tgz#851a44a934ad8f33465ae4665a6c07ac967a8bbb" + integrity sha512-dncT3tr+lZ9+duZo52rASgO6AKVwRcsc2/T93gmaYVrJqI6WWAwQ7yML5s72l9ZjQ5LZ+4jjrgtlufavAS0eCg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-recursion-detection@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.357.0.tgz#2d7a8cf43f1299c1ff1e113988bd801e7f527401" + integrity sha512-AXC54IeDS3jC1dbbkYHML4STvBPcKZ4IJTWdjEK1RCOgqXd0Ze1cE1e21wyj1tM6prF03zLyvpBd+3TS++nqfA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.362.0.tgz#0d886a18a4560a05267d841545e64b4ca360c06e" + integrity sha512-ZFsty5fXIdvTTm+GnTtCPre89b2QFZYQmD0L5nhJULDFoU5Fz/bsI5C3b98/wb4YCAIfXBZpx4Kh2RAEKnxkyg== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/service-error-classification" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + tslib "^2.5.0" + uuid "^8.3.2" + + "@aws-sdk/middleware-sdk-s3@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.357.0.tgz#3962e60183930b497599357f42f531578544eb18" + integrity sha512-EFQaPD8SoXcK7RiEOZz0zIX9owQW6txu8vrOOVva9xMts36z/3E7b4FVsgEJ53Ixa1x38ddPJxp4U8EIaf+pvQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-sdk-sts@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.357.0.tgz#8f9be3db8f4fd8563baf66925ee326f579b6ae4d" + integrity sha512-Ng2VjLrPiL02QOcs1qs9jG2boO4Gn+v3VIbOJLG4zXcfbSq55iIWtlmr2ljfw9vP5aLhWtcODfmKHS5Bp+019Q== + dependencies: + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-serde@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.357.0.tgz#2614031c81981580bce4bee502985e28e51dadb2" + integrity sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-signing@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.357.0.tgz#9aee1ad571b092ad0bbd63e0b551ffb575220688" + integrity sha512-yB9ewEqI6Fw1OrmKFrUypbCqN5ijk06UGPochybamMuPxxkwMT3bnrm7eezsCA+TZbJyKhpffpyobwuv+xGNrA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-ssec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.357.0.tgz#c99b9b457cfaee32796110b324d2d5056c86b4df" + integrity sha512-uE3nNvJclcY7SgGoOgDCUgfc7ElXQmWVpks8AZzAjJj7bG5j6Bv3FOOYtGtvtxUzTHaOdn+yQwjssV1cZ6GTQw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/middleware-stack@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.357.0.tgz#51f181691e8c76694b6583561ba0a0a14472506c" + integrity sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/middleware-user-agent@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.357.0.tgz#d4d27549bbcfdc03f5a8db74435a345b05b40373" + integrity sha512-M/CsAXjGblZS4rEbMb0Dn9IXbfq4EjVaTHBfvuILU/dKRppWvjnm2lRtqCZ+LIT3ATbAjA3/dY7dWsjxQWwijA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-endpoints" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/node-config-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.357.0.tgz#2e47aa36e5efae89b65c79b8c27180d3d8a2d901" + integrity sha512-kwBIzKCaW3UWqLdELhy7TcN8itNMOjbzga530nalFILMvn2IxrkdKQhNgxGBXy6QK6kCOtH6OmcrG3/oZkLwig== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/node-http-handler@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.360.0.tgz#6f762b57f98887b5173886f890669e6a60bf792c" + integrity sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/property-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.357.0.tgz#4c1639c2d52aefab4040c2247c126c11b19d8be9" + integrity sha512-im4W0u8WaYxG7J7ko4Xl3OEzK3Mrm1Rz6/txTGe6hTIHlyUISu1ekOQJXK6XYPqNMn8v1G3BiQREoRXUEJFbHg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/protocol-http@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.357.0.tgz#cd47413d6c1ed2d27bc30c7e9da3b262c8804cf4" + integrity sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/querystring-builder@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.357.0.tgz#0d4627620eba4d3cc523c2e1da88dfa561617599" + integrity sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/querystring-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.357.0.tgz#6dfeb42930b2241cda43646d7c1d16ca886c78af" + integrity sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/service-error-classification@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.357.0.tgz#1c6f6e436997a1886d55cfec6d4796129b789076" + integrity sha512-VuXeL4g5vKO9HjgCZlxmH8Uv1FcqUSjmbPpQkbNtYIDck6u0qzM0rG+n0/1EjyQbPSr3MhW/pkWs5nx2Nljlyg== + + "@aws-sdk/shared-ini-file-loader@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.357.0.tgz#af503df79e05bb9ee0e5d689319c9b52cefe1801" + integrity sha512-ceyqM4XxQe0Plb/oQAD2t1UOV2Iy4PFe1oAGM8dfJzYrRKu7zvMwru7/WaB3NYq+/mIY6RU+jjhRmjQ3GySVqA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/signature-v4-multi-region@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.357.0.tgz#100c573029e2b30a65634090e55be4beb50e16a1" + integrity sha512-eyO3GibYLNCPZ/YxM/ZVDh1fTMKvIUj4fpVo0bxQTKNlqNkVumAIOVLoH5um1A9FN7nDdz+40a7jwYSPlkxW6A== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/signature-v4@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.357.0.tgz#31093e87fda10bee92b6b2784cdba9af9af89e7d" + integrity sha512-itt4/Jh9FqnzK30qIjXFBvM4J7zN4S/AAqsRMnaX7U4f/MV+1YxQHmzimpdMnsCXXs2jqFqKVRu6DewxJ3nbxg== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/smithy-client@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.360.0.tgz#59d55eb41eccc22ca2d3d32c11b60135f882e66d" + integrity sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw== + dependencies: + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-stream" "3.360.0" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + + "@aws-sdk/token-providers@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.362.0.tgz#bd0ad974d7a96a06e6f1b574258e63e749e7cbb2" + integrity sha512-w7NTeB2j1CRdvDa7m08KQr12HN6qrOknXhGEMmf67bfdfAdmPWsJXIbxcKH8eze+acOzoimbqv8KyCVmyX/pCQ== + dependencies: + "@aws-sdk/client-sso-oidc" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/types@3.357.0", "@aws-sdk/types@^3.222.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.357.0.tgz#8491da71a4291cc2661c26a75089e86532b6a3b5" + integrity sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/url-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.357.0.tgz#1b197f252d008e201d1e301c8024bed770ef0b2c" + integrity sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg== + dependencies: + "@aws-sdk/querystring-parser" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-arn-parser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz#861ff8810851be52a320ec9e4786f15b5fc74fba" + integrity sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-base64@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz#d0fd49aff358c5a6e771d0001c63b1f97acbe34c" + integrity sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-body-length-browser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz#3fca9d2f73c058edf1907e4a1d99a392fdd23eca" + integrity sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-body-length-node@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz#4846ae72834ab0636f29f89fc1878520f6543fed" + integrity sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-buffer-from@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz#7a72cb965984d3c6a7e256ae6cf1621f52e54a57" + integrity sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw== + dependencies: + "@aws-sdk/is-array-buffer" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-config-provider@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz#ff21f73d4774cfd7bd16ae56f905828600dda95f" + integrity sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-defaults-mode-browser@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.360.0.tgz#fced018e4990220dc31881a5b2b3e425fe08e970" + integrity sha512-/GR8VlK9xo1Q5WbVYuNaZ+XfoCFdWNb4z4mpoEgvEgBH4R0GjqiAqLftUA8Ykq1tJuDAKPYVzUNzK8DC0pt7/g== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + + "@aws-sdk/util-defaults-mode-node@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.360.0.tgz#83e2812474d8807d6d220c5064576e63e4ea8306" + integrity sha512-gR3Ctqpyl7SgStDJ1Jlq6qQDuw/rS9AgbAXx+s3wsmm3fm8lHKkXkDPYVvNDqd6dVXRO6q8MRx00lwkGI4qrpQ== + dependencies: + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-endpoints@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.357.0.tgz#eaa7b4481bbd9fc8f13412b308ba4129d8fa2004" + integrity sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-hex-encoding@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz#19294c78986c90ae33f04491487863dc1d33bd87" + integrity sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-locate-window@^3.0.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz#b071baf050301adee89051032bd4139bba32cc40" + integrity sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-middleware@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.357.0.tgz#1ba478dde5df4e53b231ec6651b8d44c9187f66d" + integrity sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-retry/-/util-retry-3.362.0.tgz#ab4a2bef4fef528cfa58e0840ba28fb5f1c3ca11" + integrity sha512-LDRGKaF2EMcFEa6AlS+ilLiDEeHWyR5FN2+RHdfGQjcqn+Zdd5H6Vc0vUF5Z4PH3hXr5LPZcDh+zM7DlG22KJg== + dependencies: + "@aws-sdk/service-error-classification" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-stream@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream/-/util-stream-3.360.0.tgz#a6cf43cf594540e9d1a4e19b9acbc5c34b3a1225" + integrity sha512-t3naBfNesXwLis29pzSfLx2ifCn2180GiPjRaIsQP14IiVCBOeT1xaU6Dpyk7WeR/jW4cu7wGl+kbeyfNF6QmQ== + dependencies: + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-uri-escape@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz#9f942f09a715d8278875013a416295746b6085ba" + integrity sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q== + dependencies: + tslib "^2.5.0" + + "@aws-sdk/util-user-agent-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.357.0.tgz#21c3e6c1a3d610dd279952d3ce00909775019be5" + integrity sha512-JHaWlNIUkPNvXkqeDOrqFzAlAgdwZK5mZw7FQnCRvf8tdSogpGZSkuyb9Z6rLD9gC40Srbc2nepO1cFpeMsDkA== + dependencies: + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + + "@aws-sdk/util-user-agent-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.357.0.tgz#a656cebce558b602e753e45a3b8174dc7c0f1fcf" + integrity sha512-RdpQoaJWQvcS99TVgSbT451iGrlH4qpWUWFA9U1IRhxOSsmC1hz8ME7xc8nci9SREx/ZlfT3ai6LpoAzAtIEMA== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + + "@aws-sdk/util-utf8@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz#4a7b9dcebb88e830d3811aeb21e9a6df4273afb4" + integrity sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + + "@aws-sdk/util-waiter@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.357.0.tgz#31fdaf289ed60a633178b39e3b258f9b42a1cbe3" + integrity sha512-jQQGA5G8bm0JP5C4U85VzMpkFHdeeT7fOSUncXLG9Sh8Ambzi4XTud8m5/dA7aNJkvPwZeIF9QdgWCOzpkp1xA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + + "@aws-sdk/xml-builder@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz#f0236f2103b438d16117e0939a6305ad69b7ff76" + integrity sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw== + dependencies: + tslib "^2.5.0" + + "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + + "@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + + "@babel/core@^7.12.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + + "@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + + "@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + + "@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + + "@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + + "@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + + "@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + + "@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + + "@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + + "@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + + "@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + + "@babel/parser@^7.14.7", "@babel/parser@^7.18.6", "@babel/parser@^7.18.9", "@babel/parser@^7.9.4": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== + + "@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + + "@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + + "@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + + "@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + + "@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + + "@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + + "@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + + "@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + + "@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + + "@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + + "@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + + "@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + + "@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + + "@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + + "@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + + "@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + + "@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + + "@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + + "@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + + "@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + + "@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + + "@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + + "@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + + "@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + + "@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + + "@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + + "@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + + "@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + + "@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + + "@eslint/js@8.43.0": + version "8.43.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" + integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== + + "@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + + "@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + + "@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + + "@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + + "@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + + "@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + + "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + + "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + + "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + + "@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + + "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + + "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + + "@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + + "@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + + "@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + + "@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + + "@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + + "@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + + "@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + + "@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + + "@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + + "@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + + "@rollup/plugin-commonjs@^22.0.2": + version "22.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz#ee8ca8415cda30d383b4096aad5222435b4b69b6" + integrity sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + + "@rollup/plugin-node-resolve@^15.0.1": + version "15.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz#72be449b8e06f6367168d5b3cd5e2802e0248971" + integrity sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-builtin-module "^3.2.0" + is-module "^1.0.0" + resolve "^1.22.1" + + "@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + + "@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + + "@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + + "@smithy/protocol-http@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-1.1.0.tgz#caf22e01cb825d7490a4915e03d6fa64954ff535" + integrity sha512-H5y/kZOqfJSqRkwtcAoVbqONmhdXwSgYNJ1Glk5Ry8qlhVVy5qUzD9EklaCH8/XLnoCsLO/F/Giee8MIvaBRkg== + dependencies: + "@smithy/types" "^1.1.0" + tslib "^2.5.0" + + "@smithy/types@^1.0.0", "@smithy/types@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.1.0.tgz#f30a23202c97634cca5c1ac955a9bf149c955226" + integrity sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw== + dependencies: + tslib "^2.5.0" + + "@tweenjs/tween.js@^18.6.4": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-18.6.4.tgz#40a3d0a93647124872dec8e0fd1bd5926695b6ca" + integrity sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ== + + "@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + + "@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + + "@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + + "@types/estree@*", "@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + + "@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + + "@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + + "@types/linkify-it@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" + integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== + + "@types/markdown-it@^12.2.3": + version "12.2.3" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" + integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== + dependencies: + "@types/linkify-it" "*" + "@types/mdurl" "*" + + "@types/mdurl@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" + integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== + + "@types/node@*", "@types/node@>=10.0.0": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" + integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== + + "@types/node@>=13.7.0": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39" + integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg== + + "@types/node@^14.14.41": + version "14.18.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.22.tgz#fd2a15dca290fc9ad565b672fde746191cd0c6e6" + integrity sha512-qzaYbXVzin6EPjghf/hTdIbnVW1ErMx8rPzwRNJhlbyJhu2SyqlvjGOY/tbUt6VFyzg56lROcOeSQRInpt63Yw== + + "@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + + "@types/vinyl@^2.0.4": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.6.tgz#b2d134603557a7c3d2b5d3dc23863ea2b5eb29b0" + integrity sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g== + dependencies: + "@types/expect" "^1.20.4" + "@types/node" "*" + + "@zip.js/zip.js@2.4.x": + version "2.4.26" + resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.4.26.tgz#b79bb2055dc6e185890ee01cdb710caba505d5b2" + integrity sha512-I9HBO3BHIxEMQmltmHM3iqUW6IHqi3gsL9wTSXvHTRpOrA6q2OxtR58EDSaOGjHhDVJ+wIOAxZyKq2x00AVmqw== + + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + + acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + + acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + + ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + + ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + + ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + + ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + + ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + + ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + + ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + + ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + + ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + + any-promise@^1.1.0, any-promise@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + + anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + + anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + + append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA== + dependencies: + buffer-equal "^1.0.0" + + archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA== + dependencies: + file-type "^4.2.0" + + archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + + argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + + arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + + arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA== + dependencies: + make-iterator "^1.0.0" + + arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + + arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw== + dependencies: + make-iterator "^1.0.0" + + arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + + array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA== + + array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + + array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw== + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + + array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + + array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + + array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + + array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + + asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + + assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + + assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + + async-done@^1.2.0, async-done@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" + integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^2.0.0" + stream-exhaust "^1.0.1" + + async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + + async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw== + dependencies: + async-done "^1.2.2" + + asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + + atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + + autolinker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-4.0.0.tgz#aa1f9a52786b727b0ecee8cd7d4a97e0e3ef59f1" + integrity sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw== + dependencies: + tslib "^2.3.0" + + available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + + aws-sdk@^2.1210.0: + version "2.1346.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1346.0.tgz#b259748135daec9252ee9f65f0387b32e9b94c9d" + integrity sha512-sLN7DUQ4KGkVCRN9uU5amz+k5qj5HFdwq0itH7WLtFGG63/vG/HnrqHj1G0PyMij0Zz6CGlRBACstWRm0niYhQ== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.16.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + util "^0.12.4" + uuid "8.0.0" + xml2js "0.4.19" + + aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + + aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + + bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg== + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + + balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + + base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + + base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + + base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + + bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + + big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + + binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + + binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + + binaryextensions@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" + integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== + + bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + + bitmap-sdf@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz#e87b8b1d84ee846567cfbb29d60eedd34bca5b6f" + integrity sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg== + + bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + + bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + + body-parser@1.20.0, body-parser@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + + bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + + bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + + brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + + brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + + braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + + braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + + browserslist@^4.20.2: + version "4.21.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + + buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + + buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + + buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + + buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== + + buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + + buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + + buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + + buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + + builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + + bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + + bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + + bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + + cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + + cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ== + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + + call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + + callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + + camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + + caniuse-lite@^1.0.30001366: + version "1.0.30001368" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001368.tgz#c5c06381c6051cd863c45021475434e81936f713" + integrity sha512-wgfRYa9DenEomLG/SdWgQxpIyvdtH3NW8Vq+tB6AwR9e56iOIcu1im5F/wNdDf04XlKHXqIx4N8Jo0PemeBenQ== + + caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + + catharsis@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== + dependencies: + lodash "^4.17.15" + + chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + + chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + + chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + + chokidar@^3.5.1, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + + class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + + clean-css@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + + cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + + cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + + cloc@^2.8.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/cloc/-/cloc-2.10.0.tgz#1dbd3755a9ca8d426e9222b2e8a4feaecf855837" + integrity sha512-iHYXbhKNF+Wy6TNxHozD8WkW0qbZ7WKecyFntyFron4BF4SOX6hp7HEuNJ8iVnjimnf3xpLd81kMwoRj2WiCoA== + + clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== + + clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q== + dependencies: + mimic-response "^1.0.0" + + clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== + + clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + + cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + + code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + + collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA== + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + + collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + + color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + + color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + + color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + + color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + + color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + + colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + + combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + + commander@2, commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + + commander@~10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + + commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + + component-emitter@^1.2.1, component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + + compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + + compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + + concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + + concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + + connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + + content-disposition@0.5.4, content-disposition@^0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + + content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + + convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + + cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + + cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + + cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + + copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + + copy-props@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== + dependencies: + each-props "^1.3.2" + is-plain-object "^5.0.0" + + core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + + core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + + cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + + custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + + d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + + dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + + data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + + date-format@^4.0.10, date-format@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.12.tgz#82c3607e33f8d25fa25b3415b565fe726a34574d" + integrity sha512-L018twW1B6J49/vmoxFSWTwKfUaKJI42cJ2xz1WeNSKaS4uVN5D44f3KfEuYUlZvFybWDJt6YuqVDPZp+IIF/g== + + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + + debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + + decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + + decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + + decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + + decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + + decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + + decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + + decompress@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + + deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + + deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + + deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + + default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + + default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + + default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + + default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ== + + define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + + define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + + define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + + define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + + define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + + delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + + depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + + destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + + detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== + + di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + + dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + + doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + + dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + + dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + + domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + + domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + + dompurify@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.3.tgz#4b115d15a091ddc96f232bcef668550a2f6f1430" + integrity sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ== + + domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + + download@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" + integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== + dependencies: + archive-type "^4.0.0" + content-disposition "^0.5.2" + decompress "^4.2.1" + ext-name "^5.0.0" + file-type "^11.1.0" + filenamify "^3.0.0" + get-stream "^4.1.0" + got "^8.3.1" + make-dir "^2.1.0" + p-event "^2.1.0" + pify "^4.0.1" + + draco3d@^1.5.1: + version "1.5.3" + resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.3.tgz#75dfb3da7d1420571b1ab999191c49fdc2a74571" + integrity sha512-Ahum6SewAd1oVMm6Fk8T/zCE0qbzjohhO5pl1Xp5Outl4JKv7jYicfd5vNtkzImx94XE35fhNXVqHk9ajt+6Tg== + + duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + + duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + + each-props@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + + earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== + + eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + + ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + + edge-launcher@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/edge-launcher/-/edge-launcher-1.2.2.tgz#eb40aafbd067a6ea76efffab0647bcd5509b37b2" + integrity sha512-JcD5WBi3BHZXXVSSeEhl6sYO8g5cuynk/hifBzds2Bp4JdzCGLNMHgMCKu5DvrO1yatMgF0goFsxXRGus0yh1g== + + ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + + electron-to-chromium@^1.4.188: + version "1.4.197" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.197.tgz#172054244cca16320ebc19459bd03d8a9018ff73" + integrity sha512-7EZCIDDraA2NUaHewLaAh6T63cZzgBmgDx/iiaeZ/pjSs36bOFEJ3hLIrn1TKCFhV0PEZZKu6qFPrxa/LGAzLg== + + emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + + emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + + encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@~1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + + engine.io-parser@~5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" + integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== + + engine.io@~6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0" + integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + + ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + + entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + + entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + + entities@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + + error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + + es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0: + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + + es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + + es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + + es6-iterator@^2.0.1, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + + es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + + es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + + esbuild@^0.17.10: + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + + escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + + escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + + escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + + escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + + escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + + eslint-config-cesium@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-cesium/-/eslint-config-cesium-9.0.1.tgz#0104862809cb519d8f275fb4c657e876489e484b" + integrity sha512-9UR1YIdz44bzfXU0cZAH9oUEJ6pZj8CQPFMcMJsg1R9fH1SwSzK+mQSytt6VkvAfURGgb/nrZmncDZEeJ7YV2g== + + eslint-config-prettier@^8.3.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + + eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + + eslint-plugin-es@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" + integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + + eslint-plugin-html@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz#aec2a3772b40ccf51a5be4f972f07600539d3b3e" + integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== + dependencies: + htmlparser2 "^8.0.1" + + eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + + eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + + eslint-utils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + + eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + + eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + + eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + + eslint@^8.41.0: + version "8.43.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" + integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.43.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + + espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + + esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + + esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + + estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + + estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + + estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + + estree-walker@^2.0.1, estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + + esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + + etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + + eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + + events@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== + + execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + + execa@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + + expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== + dependencies: + homedir-polyfill "^1.0.1" + + express@^4.17.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + + ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + + ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + + ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + + extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + + extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + + extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + + extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + + extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + + fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + + fast-glob@^3.2.11: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + + fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + + fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw== + + fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + + fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + + fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + + fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + + fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + + file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + + file-type@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" + integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== + + file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + + file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ== + + file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + + file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + + file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + + filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + + filenamify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" + integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + + fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + + fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + + finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + + finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + + find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + + find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + + findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g== + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + + findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + + fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + + flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + + flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + + flatted@^3.1.0, flatted@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== + + flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + + follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + + for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + + for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + + for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== + dependencies: + for-in "^1.0.1" + + foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + + forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + + form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + + formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + + forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + + fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + + fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + + from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + + fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + + fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + + fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ== + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + + fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + + fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + + fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + + function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + + function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + + functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + + gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + + get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + + get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + + get-stdin@~9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" + integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== + + get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + + get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + + get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + + get-stream@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + + get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + + get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + + get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + + getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + + glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + + glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + + glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + + glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw== + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + + glob-watcher@^5.0.3: + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + normalize-path "^3.0.0" + object.defaults "^1.1.0" + + glob@^7.1.1, glob@^7.1.3, glob@^7.1.6, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@~10.2.2: + version "10.2.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" + integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.7.0" + + global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + + global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + + globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + + globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + + globby@^13.1.3: + version "13.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.0.tgz#7dd5678d765c4680c2e6d106230d86cb727cb1af" + integrity sha512-jWsQfayf13NvqKUIL3Ta+CIqMnvlaIDFveWE/dpOZ9+3AMEJozsxDvKA02zync9UuvOM8rOXzsD5GqKP4OnWPQ== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + + glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + + glsl-strip-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-strip-comments/-/glsl-strip-comments-1.0.0.tgz#bf8d121edb7482c965d24b8da6080310e55a51a5" + integrity sha512-hDzztQDaa/3YIUZVFlrfaCPnll6gdJntgUDj9ohKtPsoRVxQeNd580qW6PxVROPwD/6WAbqUiiLdRfB1NLDbFQ== + dependencies: + glsl-tokenizer "^2.1.2" + + glsl-tokenizer@^2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a" + integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA== + dependencies: + through2 "^0.6.3" + + got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + + graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.6: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + + graceful-fs@^4.1.10, graceful-fs@^4.2.10: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + + grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + + graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + + gulp-clean-css@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz#5b1e73f2fca46703eb636014cdd4553cea65146d" + integrity sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg== + dependencies: + clean-css "4.2.3" + plugin-error "1.0.1" + through2 "3.0.1" + vinyl-sourcemaps-apply "0.2.1" + + gulp-cli@^2.2.0, gulp-cli@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.4.0" + isobject "^3.0.1" + liftoff "^3.1.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.2.0" + yargs "^7.1.0" + + gulp-insert@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/gulp-insert/-/gulp-insert-0.5.0.tgz#32313f13e4a23cf5acca5ce5f0c080923c778602" + integrity sha512-SDKCWmjomAo0N0Bzj9qEKIfURORJR/72p6AbDBIK9yKZw794ROTrQHliBem+NJzS2GsTWSm8dGWJ5L7KtjnMRA== + dependencies: + readable-stream "^1.0.26-4" + streamqueue "0.0.6" + + gulp-rename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-2.0.0.tgz#9bbc3962b0c0f52fc67cd5eaff6c223ec5b9cf6c" + integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ== + + gulp-replace@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-1.1.3.tgz#8641cdca78e683e8573ca4a012e7e4ebb7e4db60" + integrity sha512-HcPHpWY4XdF8zxYkDODHnG2+7a3nD/Y8Mfu3aBgMiCFDW3X2GiOKXllsAmILcxe3KZT2BXoN18WrpEFm48KfLQ== + dependencies: + "@types/node" "^14.14.41" + "@types/vinyl" "^2.0.4" + istextorbinary "^3.0.0" + replacestream "^4.0.3" + yargs-parser ">=5.0.0-security.0" + + gulp-tap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-tap/-/gulp-tap-2.0.0.tgz#6f66b79870dcbfc364cf4ebe0735b6008473200f" + integrity sha512-U5/v1bTozx672QHzrvzPe6fPl2io7Wqyrx2y30AG53eMU/idH4BrY/b2yikOkdyhjDqGgPoMUMnpBg9e9LK8Nw== + dependencies: + through2 "^3.0.1" + + gulp-zip@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-5.1.0.tgz#38cc1d4c61bc2ab06b452ce463cbe2adc52b935e" + integrity sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw== + dependencies: + get-stream "^5.2.0" + plugin-error "^1.0.1" + through2 "^3.0.1" + vinyl "^2.1.0" + yazl "^2.5.1" + + gulp@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" + integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== + dependencies: + glob-watcher "^5.0.3" + gulp-cli "^2.2.0" + undertaker "^1.2.1" + vinyl-fs "^3.0.0" + + gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw== + dependencies: + glogg "^1.0.0" + + har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + + har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + + has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + + has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + + has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + + has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + + has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + + has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + + has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + + has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + + has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + + has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + + has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + + has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + + homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + + hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + + html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + + htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + + http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + + http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + + http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + + http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + + human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + + human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + + husky@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" + integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== + + iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + + ieee754@1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + + ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + + ignore@^5.1.1, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + + ignore@~5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + + import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + + imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + + inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + + inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + + ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + + ini@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.0.tgz#2f6de95006923aa75feed8894f5686165adc08f1" + integrity sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw== + + install@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/install/-/install-0.13.0.tgz#6af6e9da9dd0987de2ab420f78e60d9c17260776" + integrity sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA== + + internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + + interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + + into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ== + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + + invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + + ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + + is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + + is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + + is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + + is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + + is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + + is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + + is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + + is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + + is-builtin-module@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + + is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + + is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + + is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + + is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + + is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + + is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + + is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + + is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + + is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + + is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + + is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + + is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + + is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + + is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + + is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + + is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + + is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + + is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + + is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug== + + is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + + is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + + is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + + is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + + is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + + is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + + is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + + is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + + is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + + is-reference@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + + is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + + is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + + is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + + is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + + is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + + is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + + is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + + is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + + is-typed-array@^1.1.3, is-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67" + integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + + is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + + is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + + is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + + is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA== + + is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + + is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + + is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + + isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + + isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + + isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + + isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + + isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + + isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + + istanbul-lib-instrument@^5.1.0, istanbul-lib-instrument@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + + istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + + istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + + istanbul-reports@^3.0.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + + istextorbinary@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-3.3.0.tgz#06b1c57d948da11461bd237c00ce09e9902964f2" + integrity sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ== + dependencies: + binaryextensions "^2.2.0" + textextensions "^3.2.0" + + isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + + jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + + jasmine-core@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.2.0.tgz#0605bea284d6d78276f43c47de2532ecd4a73b00" + integrity sha512-OcFpBrIhnbmb9wfI8cqPSJ50pv3Wg4/NSgoZIqHzIwO/2a9qivJWzv8hUvaREIMYYJBas6AvfXATFdVuzzCqVw== + + jasmine-core@^4.1.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.6.0.tgz#6884fc3d5b66bf293e422751eed6d6da217c38f5" + integrity sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ== + + jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== + + js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + + js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + + js2xmlparser@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz#2a1fdf01e90585ef2ae872a01bc169c6a8d5e60a" + integrity sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA== + dependencies: + xmlcreate "^2.0.4" + + jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + + jsdoc@^3.6.7: + version "3.6.11" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.11.tgz#8bbb5747e6f579f141a5238cbad4e95e004458ce" + integrity sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg== + dependencies: + "@babel/parser" "^7.9.4" + "@types/markdown-it" "^12.2.3" + bluebird "^3.7.2" + catharsis "^0.9.0" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.2" + klaw "^3.0.0" + markdown-it "^12.3.2" + markdown-it-anchor "^8.4.1" + marked "^4.0.10" + mkdirp "^1.0.4" + requizzle "^0.2.3" + strip-json-comments "^3.1.0" + taffydb "2.6.2" + underscore "~1.13.2" + + jsep@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/jsep/-/jsep-1.3.8.tgz#facb6eb908d085d71d950bd2b24b757c7b8a46d7" + integrity sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ== + + jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + + json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + + json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + + json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + + json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + + json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + + json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + + jsonc-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + + jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + + jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + + just-debounce@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" + integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== + + karma-chrome-launcher@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" + integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== + dependencies: + which "^1.2.1" + + karma-coverage@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.2.0.tgz#64f838b66b71327802e7f6f6c39d569b7024e40c" + integrity sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + + karma-detect-browsers@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/karma-detect-browsers/-/karma-detect-browsers-2.3.3.tgz#e0d8f9c1a1b0cc58d8668c245441eaf9d832c6ee" + integrity sha512-ltFVyA3ijThv9l9TQ+TKnccoMk6YAWn8OMaccL+n8pO2LGwMOcy6tUWy3Mnv9If29jqvVHDCWntj7wBQpPtv7Q== + dependencies: + which "^1.2.4" + + karma-edge-launcher@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz#3d9529b09b13c909c5f3ceee12d00e7f9a989b3d" + integrity sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw== + dependencies: + edge-launcher "1.2.2" + + karma-firefox-launcher@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz#9a38cc783c579a50f3ed2a82b7386186385cfc2d" + integrity sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA== + dependencies: + is-wsl "^2.2.0" + which "^2.0.1" + + karma-ie-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz#497986842c490190346cd89f5494ca9830c6d59c" + integrity sha512-ts71ke8pHvw6qdRtq0+7VY3ANLoZuUNNkA8abRaWV13QRPNm7TtSOqyszjHUtuwOWKcsSz4tbUtrNICrQC+SXQ== + dependencies: + lodash "^4.6.1" + + karma-jasmine@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-5.1.0.tgz#3af4558a6502fa16856a0f346ec2193d4b884b2f" + integrity sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ== + dependencies: + jasmine-core "^4.1.0" + + karma-longest-reporter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/karma-longest-reporter/-/karma-longest-reporter-1.1.0.tgz#37ba11e421334a0d0d5117e24dace8f2caec9919" + integrity sha512-c34tJbZUntkXMWK6S44NHLsYwF6Nu76+57ZGZvGLlbeltYanlKg/cgs1JqxwEdPz3m0Z2WSMhxBW6pcv0ycn1g== + + karma-safari-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz#96982a2cc47d066aae71c553babb28319115a2ce" + integrity sha512-qmypLWd6F2qrDJfAETvXDfxHvKDk+nyIjpH9xIeI3/hENr0U3nuqkxaftq73PfXZ4aOuOChA6SnLW4m4AxfRjQ== + + karma-sourcemap-loader@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + + karma-spec-reporter@^0.0.36: + version "0.0.36" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz#c54dc155dec2ded1f92ea68dbbdd67fcedbef350" + integrity sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w== + dependencies: + colors "1.4.0" + + karma@^6.3.20: + version "6.4.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" + integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + + kdbush@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + + keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + + kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + + kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + + kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + + klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + + ktx-parse@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ktx-parse/-/ktx-parse-0.5.0.tgz#b4025bbc73ac5386ac37e869de455eab915261bc" + integrity sha512-5IZrv5s1byUeDTIee1jjJQBiD5LPDB0w9pJJ0oT9BCKKJf16Tuj123vm1Ps0GOHSHmeWPgKM0zuViCVuTRpqaA== + + last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ== + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + + lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + + lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + + lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow== + dependencies: + flush-write-stream "^1.0.2" + + lerc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lerc/-/lerc-2.0.0.tgz#82feca29ea6202799a815ca38f7b66a370e8cf9b" + integrity sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg== + + levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + + liftoff@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + + linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + + linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + + load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + + locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + + lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + + lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.6.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + + log4js@^6.4.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.6.0.tgz#e8fd00143d1e0ecf1d10959bb69b90b1b30137f3" + integrity sha512-3v8R7fd45UB6THucSht6wN2/7AZEruQbXdjygPZcxt5TA/msO6si9CN5MefUuKXbYnJHTBnYcx4famwcyQd+sA== + dependencies: + date-format "^4.0.11" + debug "^4.3.4" + flatted "^3.2.5" + rfdc "^1.3.0" + streamroller "^3.1.1" + + long@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + + lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A== + + lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + + "lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + + magic-string@^0.25.3, magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + + make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + + make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + + make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + + make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + + map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + + map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + + markdown-it-anchor@^8.4.1: + version "8.6.4" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz#affb8aa0910a504c114e9fcad53ac3a5b907b0e6" + integrity sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img== + + markdown-it@13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" + integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + + markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + + markdownlint-cli@^0.34.0: + version "0.34.0" + resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.34.0.tgz#d7a4ae8e59911de6dfb01782a7cd554e8a245947" + integrity sha512-4G9I++VBTZkaye6Yfc/7dU6HQHcyldZEVB+bYyQJLcpJOHKk/q5ZpGqK80oKMIdlxzsA3aWOJLZ4DkoaoUWXbQ== + dependencies: + commander "~10.0.1" + get-stdin "~9.0.0" + glob "~10.2.2" + ignore "~5.2.4" + js-yaml "^4.1.0" + jsonc-parser "~3.2.0" + markdownlint "~0.28.2" + minimatch "~9.0.0" + run-con "~1.2.11" + + markdownlint-micromark@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz#5520e04febffa46741875a2f297509ffdb561f5c" + integrity sha512-jRxlQg8KpOfM2IbCL9RXM8ZiYWz2rv6DlZAnGv8ASJQpUh6byTBnEsbuMZ6T2/uIgntyf7SKg/mEaEBo1164fQ== + + markdownlint@~0.28.2: + version "0.28.2" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.28.2.tgz#ea31586a02fe3a06403ecafbbe22d77e363c8ed5" + integrity sha512-yYaQXoKKPV1zgrFsyAuZPEQoe+JrY9GDag9ObKpk09twx4OCU5lut+0/kZPrQ3W7w82SmgKhd7D8m34aG1unVw== + dependencies: + markdown-it "13.0.1" + markdownlint-micromark "0.1.2" + + marked@^4.0.10: + version "4.0.18" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" + integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== + + matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA== + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + + mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + + media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + + merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + + merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + + merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + + mersenne-twister@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" + integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA== + + meshoptimizer@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/meshoptimizer/-/meshoptimizer-0.19.0.tgz#1669e6d788ad3ffd238a65184e478355642ca979" + integrity sha512-58qz5Qc/6Geu8Ib3bBWERE5R7pM5ErrJVo16fAtu6ryxVaE3VAtM/u2vurDxaq8AGZ3yWxuM/DnylTga5a4XCQ== + + methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + + micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + + mime-db@1.52.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.28.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + + mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + + mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + + mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + + mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + + mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + + mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + + mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + + minimatch@^9.0.1, minimatch@~9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" + integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== + dependencies: + brace-expansion "^2.0.1" + + minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + + minimist@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + + "minipass@^5.0.0 || ^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" + integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== + + mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + + mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + + mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + + mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + + ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + + ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + + ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + + mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + + nan@^2.12.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + + nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + + negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + + next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + + node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + + node-fetch@^3.2.10: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + + node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + + normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + + normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + + normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + + normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + + nosleep.js@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/nosleep.js/-/nosleep.js-0.12.0.tgz#a01fddab2c13af357d673928b1f40a9013a4dc08" + integrity sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA== + + now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + + npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + + npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + + number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + + oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + + object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + + object-inspect@^1.12.0, object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + + object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + + object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + + object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + + object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA== + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + + object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + + object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + + object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + + on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + + on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + + on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + + once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + + onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + + onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + + open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + + optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + + ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw== + dependencies: + readable-stream "^2.0.1" + + os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + + p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + + p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + + p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + + p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg== + + p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + + p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + + p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + + p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + + pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + + parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + + parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q== + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + + parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + + parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + + parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== + + parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + + pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + + path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + + path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + + path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + + path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + + path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + + path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + + path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + + path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== + + path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== + dependencies: + path-root-regex "^0.1.0" + + path-scurry@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.0.tgz#0ffbd4c1f7de9600f98a1405507d9f9acb438ab3" + integrity sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2" + + path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + + path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + + path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + + pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + + performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + + picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + + pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + + pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + + pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + + pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + + pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + + plugin-error@1.0.1, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + + posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + + prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + + prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + + prettier@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" + integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== + + pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + + prismjs@^1.28.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + + protobufjs@^7.1.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2" + integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + + proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + + psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + + pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + + punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + + punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + + qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + + qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + + qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + + query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + + querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + + queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + + quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + + range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + + raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + + rbush@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf" + integrity sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w== + dependencies: + quickselect "^2.0.0" + + read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + + read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + + "readable-stream@2 || 3": + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + + "readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + + readable-stream@^1.0.26-2, readable-stream@^1.0.26-4: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + + readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readable-stream@^2.3.0: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + + readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + + rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + + regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + + regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + + regexpp@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + + remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + + remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA== + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + + remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + + repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + + repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + + replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + + replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg== + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + + replacestream@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" + integrity sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA== + dependencies: + escape-string-regexp "^1.0.3" + object-assign "^4.0.1" + readable-stream "^2.0.2" + + request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + + require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + + require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + + requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + + requizzle@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" + integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== + dependencies: + lodash "^4.17.14" + + resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + + resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + + resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A== + dependencies: + value-or-function "^3.0.0" + + resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + + resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.22.1, resolve@^1.4.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + + responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + + ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + + reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + + rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + + rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + + rollup-plugin-strip-pragma@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-strip-pragma/-/rollup-plugin-strip-pragma-1.0.0.tgz#dd6d8c76788af460b16f7f1ca0e90a6e672236f7" + integrity sha512-ydv83CoA07wls7ZWwd4HtjjsoR9vM65SFR/B2tR8D2ppXyZajiQlx5cTJadAXMl9NADnXjUTMHW+kFzOkLoNdA== + dependencies: + magic-string "^0.25.3" + rollup-pluginutils "^2.8.2" + + rollup-pluginutils@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + + rollup@^2.78.0: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + + run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + + run-con@~1.2.11: + version "1.2.12" + resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.12.tgz#51c319910e45a3bd71ee773564a89d96635c8c64" + integrity sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg== + dependencies: + deep-extend "^0.6.0" + ini "~3.0.0" + minimist "^1.2.8" + strip-json-comments "~3.1.1" + + run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + + safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + + safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + + "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + + sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== + + sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + + seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + + semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ== + dependencies: + sver-compat "^1.5.0" + + "semver@2 || 3 || 4 || 5", semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + + semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + + send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + + serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + + set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + + set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + + setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + + shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + + shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + + side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + + signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + + signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + + slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + + snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + + snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + + snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + + socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== + + socket.io-parser@~4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.5.tgz#cb404382c32324cc962f27f3a44058cf6e0552df" + integrity sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + + socket.io@^4.4.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029" + integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.2.0" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.0.4" + + sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + + sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + + sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== + dependencies: + is-plain-obj "^1.0.0" + + source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + + source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + + source-map@^0.5.1, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + + source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + + sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + + sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + + spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + + spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + + spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + + spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + + split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + + sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + + stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + + static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + + statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + + statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + + stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + + stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + + stream-to-array@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" + integrity sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA== + dependencies: + any-promise "^1.1.0" + + stream-to-promise@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-3.0.0.tgz#8934d66dcbc9189394e8b33200da3bb9611db774" + integrity sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA== + dependencies: + any-promise "~1.3.0" + end-of-stream "~1.4.1" + stream-to-array "~2.3.0" + + streamqueue@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/streamqueue/-/streamqueue-0.0.6.tgz#66f5f5ec94e9b8af249e4aec2dd1f741bfe94de3" + integrity sha512-l09LNfTUkmLMckTB1Mm8Um5GMS1uTZ/KTodg/SMf5Nx758IOsmaqIQ/AJumAnNMkDgZBG39btq3LVkN90knq8w== + dependencies: + readable-stream "^1.0.26-2" + + streamroller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.1.tgz#679aae10a4703acdf2740755307df0a05ad752e6" + integrity sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ== + dependencies: + date-format "^4.0.10" + debug "^4.3.4" + fs-extra "^10.1.0" + + strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + + "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + + string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + + string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + + string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + + string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + + string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + + string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + + string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + + "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + + strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + + strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + + strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + + strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + + strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + + strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + + strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + + strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + + supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + + supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + + supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + + sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg== + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + + taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA== + + tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + + text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + + textextensions@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-3.3.0.tgz#03530d5287b86773c08b77458589148870cc71d3" + integrity sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw== + + through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + + through2@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + + through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg== + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + + through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + + through2@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + + through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + + time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + + timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + + titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + + tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + + to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA== + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + + to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + + to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + + to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + + to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + + to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + + to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + + to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q== + dependencies: + through2 "^2.0.3" + + toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + + topojson-client@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" + integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== + dependencies: + commander "2" + + tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + + trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + + tsd-jsdoc@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tsd-jsdoc/-/tsd-jsdoc-2.5.0.tgz#0677aa952e1a8e3ebbb5bcf7d6e2f0301d71e151" + integrity sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g== + dependencies: + typescript "^3.2.1" + + tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + + tslib@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + + tslib@^2.3.1, tslib@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + + tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + + tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + + type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + + type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + + type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + + type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + + type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + + typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + + typescript@^3.2.1: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + + typescript@^5.0.2: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + + ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + + uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + + unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + + unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + + unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg== + + underscore@~1.13.2: + version "1.13.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" + integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== + + undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw== + + undertaker@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + + union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + + unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + + universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + + unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + + unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + + untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + + upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + + update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + + uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + + urijs@^1.19.7: + version "1.19.11" + resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc" + integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ== + + urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + + url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + + url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== + + url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + + use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + + util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + + util@^0.12.4: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + + utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + + uuid@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" + integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== + + uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + + uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + + v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + + validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + + value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg== + + vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + + verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + + vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + + vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA== + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + + vinyl-sourcemaps-apply@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw== + dependencies: + source-map "^0.5.1" + + vinyl@^2.0.0, vinyl@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + + void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + + web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + + which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + + which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + + which-typed-array@^1.1.2: + version "1.1.8" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f" + integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.9" + + which@^1.2.1, which@^1.2.14, which@^1.2.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + + which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + + word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + + wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + + wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + + wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + + ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + + xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + + xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ== + + xmlcreate@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" + integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== + + "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + + y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + + y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + + yargs-parser@>=5.0.0-security.0, yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + + yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + + yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + + yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + + yargs@^17.0.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + + yargs@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.1" + + yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + + yazl@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + + yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + + yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000000..9f761d33807 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,7712 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@aws-crypto/crc32@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-3.0.0.tgz#07300eca214409c33e3ff769cd5697b57fdd38fa" + integrity sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/crc32c@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz#016c92da559ef638a84a245eecb75c3e97cb664f" + integrity sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/ie11-detection@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" + integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/sha1-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz#f9083c00782b24714f528b1a1fef2174002266a3" + integrity sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-browser@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" + integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== + dependencies: + "@aws-crypto/ie11-detection" "^3.0.0" + "@aws-crypto/sha256-js" "^3.0.0" + "@aws-crypto/supports-web-crypto" "^3.0.0" + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" + integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== + dependencies: + "@aws-crypto/util" "^3.0.0" + "@aws-sdk/types" "^3.222.0" + tslib "^1.11.1" + +"@aws-crypto/supports-web-crypto@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" + integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== + dependencies: + tslib "^1.11.1" + +"@aws-crypto/util@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" + integrity sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/abort-controller@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/abort-controller/-/abort-controller-3.357.0.tgz#5c5336d18b97781d0b940700375d825f9e20d9be" + integrity sha512-nQYDJon87quPwt2JZJwUN2GFKJnvE5kWb6tZP4xb5biSGUKBqDQo06oYed7yokatCuCMouIXV462aN0fWODtOw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/chunked-blob-reader@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.310.0.tgz#2ada1b024a2745c2fe7e869606fab781325f981e" + integrity sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/client-s3@^3.342.0", "@aws-sdk/client-s3@^3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.362.0.tgz#3cee09ac6ed6d11e39bf9ef3b0ce327d21337f54" + integrity sha512-ZDQqfZ67ni/FVTGsGLELq2Y7Hq3lMUHf9SxVQn0v6Q8IIJwtmstUFxYPkiJMNAO1Lv93GdPkef1guoECRze70A== + dependencies: + "@aws-crypto/sha1-browser" "3.0.0" + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/client-sts" "3.362.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/eventstream-serde-browser" "3.357.0" + "@aws-sdk/eventstream-serde-config-resolver" "3.357.0" + "@aws-sdk/eventstream-serde-node" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-blob-browser" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/hash-stream-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/md5-js" "3.357.0" + "@aws-sdk/middleware-bucket-endpoint" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-expect-continue" "3.357.0" + "@aws-sdk/middleware-flexible-checksums" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-location-constraint" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-s3" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-ssec" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/signature-v4-multi-region" "3.357.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-stream" "3.360.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@aws-sdk/util-waiter" "3.357.0" + "@aws-sdk/xml-builder" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + +"@aws-sdk/client-sso-oidc@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.362.0.tgz#a2daad47e44c5cd902079467e9e0ac20bd8d90af" + integrity sha512-/urfavz0BjyeWSahp6oh9DjzV8oM5EPmza7iIZXJaPyK03enjse9A52vse4/EfKWaSHtapIgV3ZUKvYDk8AcKA== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + +"@aws-sdk/client-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.362.0.tgz#5635380fa552d76cf039076e41611d01e00c31ab" + integrity sha512-11M+S7mlr8MBE8NB2yPZWOeb7BV4pcfQ+2p9EE9jVDbcq7VW21chvnf4F+L11aNV1yNtswsnHOSHLKM6YBMM7w== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + +"@aws-sdk/client-sts@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.362.0.tgz#f04ad1b9f0060d9b87aca74cc7199393f9d4064b" + integrity sha512-4Kh6oM2hfJbckuMb9O5eRIG66s/eA0wazXYvCbxSiSi3XgkX9L4m5OSNxlzLPe7uVgkEx8ykuk8Xz6qZrZWJcQ== + dependencies: + "@aws-crypto/sha256-browser" "3.0.0" + "@aws-crypto/sha256-js" "3.0.0" + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-node" "3.362.0" + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/hash-node" "3.357.0" + "@aws-sdk/invalid-dependency" "3.357.0" + "@aws-sdk/middleware-content-length" "3.357.0" + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/middleware-host-header" "3.357.0" + "@aws-sdk/middleware-logger" "3.357.0" + "@aws-sdk/middleware-recursion-detection" "3.357.0" + "@aws-sdk/middleware-retry" "3.362.0" + "@aws-sdk/middleware-sdk-sts" "3.357.0" + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/middleware-user-agent" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/smithy-client" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-body-length-browser" "3.310.0" + "@aws-sdk/util-body-length-node" "3.310.0" + "@aws-sdk/util-defaults-mode-browser" "3.360.0" + "@aws-sdk/util-defaults-mode-node" "3.360.0" + "@aws-sdk/util-endpoints" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + "@aws-sdk/util-user-agent-browser" "3.357.0" + "@aws-sdk/util-user-agent-node" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + "@smithy/protocol-http" "^1.0.1" + "@smithy/types" "^1.0.0" + fast-xml-parser "4.2.5" + tslib "^2.5.0" + +"@aws-sdk/config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/config-resolver/-/config-resolver-3.357.0.tgz#7672b3f446ed64025d1763efea0289f7f49833a1" + integrity sha512-cukfg0nX7Tzx/xFyH5F4Eyb8DA1ITCGtSQv4vnEjgUop+bkzckuGLKEeBcBhyZY+aw+2C9CVwIHwIMhRm0ul5w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-config-provider" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-env@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.357.0.tgz#9746b9f958f490db5b1502d36cba7da43da460cb" + integrity sha512-UOecwfqvXgJVqhfWSZ2S44v2Nq2oceW0PQVQp0JAa9opc2rxSVIfyOhPr0yMoPmpyNcP22rgeg6ce70KULYwiA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-imds@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.357.0.tgz#6b5317c79e15a059a2f71623ec673bea03af04f6" + integrity sha512-upw/bfsl7/WydT6gM0lBuR4Ipp4fzYm/E3ObFr0Mg5OkgVPt5ZJE+eeFTvwCpDdBSTKs4JfrK6/iEK8A23Q1jQ== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-ini@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.362.0.tgz#e1f328616d0e4d3e32b109e81969058b3e95c47d" + integrity sha512-56gOo0XrqfEXTYrpWwZEYqrKEyNNpyNNvagfuP29d4aqok7ON5CkL1ymmKhNuDGHbbHXVGOIGdLNJBkGBgwE1g== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-node@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.362.0.tgz#0b5b6b4ed520a519bc5660a2f687ebf697a5db06" + integrity sha512-G/oCGTdN3Gx1HgSX6KlGC71q9EQw9luSgGGIgZHAw9u3IllLEARqxVQ5PUPlhEM4FkNNMpzicUbWeI5NeMRuyA== + dependencies: + "@aws-sdk/credential-provider-env" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/credential-provider-ini" "3.362.0" + "@aws-sdk/credential-provider-process" "3.357.0" + "@aws-sdk/credential-provider-sso" "3.362.0" + "@aws-sdk/credential-provider-web-identity" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-process@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.357.0.tgz#5e661bd4431a171ee862bb60ff0054d11dea150a" + integrity sha512-qFWWilFPsc2hR7O0KIhwcE78w+pVIK+uQR6MQMfdRyxUndgiuCorJwVjedc3yZtmnoELHF34j+m8whTBXv9E7Q== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-sso@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.362.0.tgz#655ebe1a7f7f6a6ffc76698c4b7172b78cf8aa25" + integrity sha512-jf5jG8IQXNSTuOPMT0SMOpBi+Tlct+3Ik5njpEECFzo5POzU8DgJkc2ALMNW5j+XojuchwgeqWZclPRoacKjVw== + dependencies: + "@aws-sdk/client-sso" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/token-providers" "3.362.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/credential-provider-web-identity@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.357.0.tgz#32765fc53779d84c078d20e4e1585b8fedfcf61f" + integrity sha512-0KRRAFrXy5HJe2vqnCWCoCS+fQw7IoIj3KQsuURJMW4F+ifisxCgEsh3brJ2LQlN4ElWTRJhlrDHNZ/pd61D4w== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/eventstream-codec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-codec/-/eventstream-codec-3.357.0.tgz#32b6f0d97f3ea6e479e0d59c0a9b625faf3f887b" + integrity sha512-bqenTHG6GH6aCk/Il+ooWXVVAZuc8lOgVEy9bE2hI49oVqT8zSuXxQB+w1WWyZoAOPcelsjayB1wfPub8VDBxQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/eventstream-serde-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.357.0.tgz#fc2074bb7a9d8a358b9e0fb601924094af33c133" + integrity sha512-hBabtmwuspVHGSKnUccDiSIbg+IVoBThx6wYt6i4edbWAITHF3ADVKXy7icV400CAyG0XTZgxjE6FKpiDxj9rQ== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/eventstream-serde-config-resolver@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.357.0.tgz#d5db248a17fb22bc95d3088b7d840a065f015251" + integrity sha512-E6rwk+1KFXhKmJ+v7JW5Uyyda1yN5XRVupCnCrtFsHFmhVGQxFacoUZIee3bfuCpC58dLSyESggxGpUd3XOSsw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/eventstream-serde-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.357.0.tgz#4fc79eea9eb85c173f44ad8e37550231e81cf144" + integrity sha512-boXDy+JWcPfHc9OIKV6I4Bh2XrLcg+eac+/LldNZFcDIB33/gHIM2CJw8u565Iebdz1NKEkP/QPPZbk2y+abPA== + dependencies: + "@aws-sdk/eventstream-serde-universal" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/eventstream-serde-universal@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.357.0.tgz#b83fb0bbc9623eb3e5a698cb3bfd1b8c502fd351" + integrity sha512-9/Wcdxx38XQAturqOAGYNCaLOzFVnW+xwxd4af9eNOfZfZ5PP5PRKBIpvKDsN26e3l4f3GodHx7MS1WB7BBc2w== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/fetch-http-handler@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.357.0.tgz#8b33b8cefe036fd932b694242893ef3db1a74f02" + integrity sha512-5sPloTO8y8fAnS/6/Sfp/aVoL9zuhzkLdWBORNzMazdynVNEzWKWCPZ27RQpgkaCDHiXjqUY4kfuFXAGkvFfDQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/hash-blob-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.357.0.tgz#e507929499fe0fe128664b67cd26f63f16ed4d25" + integrity sha512-RDd6UgrGHDmleTnXM9LRSSVa69euSAG2mlNhZMEDWk3OFseXVYqBDaqroVbQ01rM2UAe8MeBFchlV9OmxuVgvw== + dependencies: + "@aws-sdk/chunked-blob-reader" "3.310.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/hash-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-node/-/hash-node-3.357.0.tgz#70666b0d6a49191cf33ef32b235c33b242de36ce" + integrity sha512-fq3LS9AxHKb7dTZkm6iM1TrGk6XOTZz96iEZPME1+vjiSEXGWuebHt87q92n+KozVGRypn9MId3lHOPBBjygNQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/hash-stream-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/hash-stream-node/-/hash-stream-node-3.357.0.tgz#a78c6d1ae1c78cb52854311bad50988e8fc12142" + integrity sha512-KZjN1VAw1KHNp+xKVOWBGS+MpaYQTjZFD5f+7QQqW4TfbAkFFwIAEYIHq5Q8Gw+jVh0h61OrV/LyW3J2PVzc+w== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/invalid-dependency@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/invalid-dependency/-/invalid-dependency-3.357.0.tgz#4e86c689a6b0c4d0fe43ba335218d67e9aa652a6" + integrity sha512-HnCYZczf0VdyxMVMMxmA3QJAyyPSFbcMtZzgKbxVTWTG7GKpQe0psWZu/7O2Nk31mKg6vEUdiP1FylqLBsgMOA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/is-array-buffer@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/is-array-buffer/-/is-array-buffer-3.310.0.tgz#f87a79f1b858c88744f07e8d8d0a791df204017e" + integrity sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/lib-storage@^3.342.0", "@aws-sdk/lib-storage@^3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.362.0.tgz#734f046cc5ee7727da089efe49c1de6f8f922dc2" + integrity sha512-r3KUIEPLAiZdnxbK+9fgAnxKEjsyeB7wFd0rKuOL+TZouaBSGz2ctni2/tAwN0Om3y8boKWmcUrbUWndN5vjHA== + dependencies: + "@aws-sdk/middleware-endpoint" "3.357.0" + "@aws-sdk/smithy-client" "3.360.0" + buffer "5.6.0" + events "3.3.0" + stream-browserify "3.0.0" + tslib "^2.5.0" + +"@aws-sdk/md5-js@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/md5-js/-/md5-js-3.357.0.tgz#61853f562e71af0ec58aeede7883de122177ed55" + integrity sha512-to42sFAL7KgV/X9X40LLfEaNMHMGQL6/7mPMVCL/W2BZf3zw5OTl3lAaNyjXA+gO5Uo4lFEiQKAQVKNbr8b8Nw== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-bucket-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.357.0.tgz#9d19ba4a7971c5302e32d024e477755a1f6185ff" + integrity sha512-ep2T0FJXRDl6nffLqiVZUYfDocZ3B72wvHeozckkLVRX0TK91WEpzv4Zz2vdeBp6CGkM3g8oGjbb6ZqllUZ6TA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + "@aws-sdk/util-config-provider" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-content-length@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-content-length/-/middleware-content-length-3.357.0.tgz#eafad2db1816cb5d91cd1e090211f040f29bbdaa" + integrity sha512-zQOFEyzOXAgN4M54tYNWGxKxnyzY0WwYDTFzh9riJRmxN1hTEKHUKmze4nILIf5rkQmOG4kTf1qmfazjkvZAhw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-endpoint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.357.0.tgz#bc94bbf55339aa5220011f4ae8e03a7966ce28be" + integrity sha512-ScJi0SL8X/Lyi0Fp5blg0QN/Z6PoRwV/ZJXd8dQkXSznkbSvJHfqPP0xk/w3GcQ1TKsu5YEPfeYy8ejcq+7Pgg== + dependencies: + "@aws-sdk/middleware-serde" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/url-parser" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-expect-continue@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.357.0.tgz#c392c4f31300695158070223f1e337c7503aca92" + integrity sha512-KeizuiiDmdLeAbiNsJt/rZENY5iJo4wCTl7h81htDC60wSwVwFG03IdgvZlFH6jktYRh4mUDD/6Oljme6yPNxw== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-flexible-checksums@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.357.0.tgz#957a383dc66942e63493d2ba182ee775e8139507" + integrity sha512-NNQ/iPN6YyzqgVaV8AeYQMZ8y1OmUW27vmt0R66UUw5H5THGc6X9QXoKfie7OHn80Qv1S8P5jw8z5MpvDtjSnQ== + dependencies: + "@aws-crypto/crc32" "3.0.0" + "@aws-crypto/crc32c" "3.0.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-host-header@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.357.0.tgz#9d4f803fc7d9b1f5582a62844b1d841b3c849fe0" + integrity sha512-HuGLcP7JP1qJ5wGT9GSlEknDaTSnOzHY4T6IPFuvFjAy3PvY5siQNm6+VRqdVS+n6/kzpL3JP5sAVM3aoxHT6Q== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-location-constraint@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.357.0.tgz#b147973f70c82cf06d3bafcf32b6b826203bcb69" + integrity sha512-4IsIHhwZ2/o7yjLI1XtGMkJ442cbIN5/NtI/Ml0G5UHYviUm8sqvH2vldFBMK5bPuVdk6GpqXpy6wYc9rLJj2w== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-logger@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.357.0.tgz#851a44a934ad8f33465ae4665a6c07ac967a8bbb" + integrity sha512-dncT3tr+lZ9+duZo52rASgO6AKVwRcsc2/T93gmaYVrJqI6WWAwQ7yML5s72l9ZjQ5LZ+4jjrgtlufavAS0eCg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-recursion-detection@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.357.0.tgz#2d7a8cf43f1299c1ff1e113988bd801e7f527401" + integrity sha512-AXC54IeDS3jC1dbbkYHML4STvBPcKZ4IJTWdjEK1RCOgqXd0Ze1cE1e21wyj1tM6prF03zLyvpBd+3TS++nqfA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-retry/-/middleware-retry-3.362.0.tgz#0d886a18a4560a05267d841545e64b4ca360c06e" + integrity sha512-ZFsty5fXIdvTTm+GnTtCPre89b2QFZYQmD0L5nhJULDFoU5Fz/bsI5C3b98/wb4YCAIfXBZpx4Kh2RAEKnxkyg== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/service-error-classification" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-retry" "3.362.0" + tslib "^2.5.0" + uuid "^8.3.2" + +"@aws-sdk/middleware-sdk-s3@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.357.0.tgz#3962e60183930b497599357f42f531578544eb18" + integrity sha512-EFQaPD8SoXcK7RiEOZz0zIX9owQW6txu8vrOOVva9xMts36z/3E7b4FVsgEJ53Ixa1x38ddPJxp4U8EIaf+pvQ== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-arn-parser" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-sdk-sts@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.357.0.tgz#8f9be3db8f4fd8563baf66925ee326f579b6ae4d" + integrity sha512-Ng2VjLrPiL02QOcs1qs9jG2boO4Gn+v3VIbOJLG4zXcfbSq55iIWtlmr2ljfw9vP5aLhWtcODfmKHS5Bp+019Q== + dependencies: + "@aws-sdk/middleware-signing" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-serde@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-serde/-/middleware-serde-3.357.0.tgz#2614031c81981580bce4bee502985e28e51dadb2" + integrity sha512-bGI4kYuuEsFjlANbyJLyy4AovETnyf/SukgLOG7Qjbua+ZGuzvRhMsk21mBKKGrnsTO4PmtieJo6xClThGAN8g== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-signing@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.357.0.tgz#9aee1ad571b092ad0bbd63e0b551ffb575220688" + integrity sha512-yB9ewEqI6Fw1OrmKFrUypbCqN5ijk06UGPochybamMuPxxkwMT3bnrm7eezsCA+TZbJyKhpffpyobwuv+xGNrA== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-middleware" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-ssec@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.357.0.tgz#c99b9b457cfaee32796110b324d2d5056c86b4df" + integrity sha512-uE3nNvJclcY7SgGoOgDCUgfc7ElXQmWVpks8AZzAjJj7bG5j6Bv3FOOYtGtvtxUzTHaOdn+yQwjssV1cZ6GTQw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/middleware-stack@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-stack/-/middleware-stack-3.357.0.tgz#51f181691e8c76694b6583561ba0a0a14472506c" + integrity sha512-nNV+jfwGwmbOGZujAY/U8AW3EbVlxa9DJDLz3TPp/39o6Vu5KEzHJyDDNreo2k9V/TMvV+nOzHafufgPdagv7w== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/middleware-user-agent@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.357.0.tgz#d4d27549bbcfdc03f5a8db74435a345b05b40373" + integrity sha512-M/CsAXjGblZS4rEbMb0Dn9IXbfq4EjVaTHBfvuILU/dKRppWvjnm2lRtqCZ+LIT3ATbAjA3/dY7dWsjxQWwijA== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-endpoints" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/node-config-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-config-provider/-/node-config-provider-3.357.0.tgz#2e47aa36e5efae89b65c79b8c27180d3d8a2d901" + integrity sha512-kwBIzKCaW3UWqLdELhy7TcN8itNMOjbzga530nalFILMvn2IxrkdKQhNgxGBXy6QK6kCOtH6OmcrG3/oZkLwig== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/node-http-handler@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/node-http-handler/-/node-http-handler-3.360.0.tgz#6f762b57f98887b5173886f890669e6a60bf792c" + integrity sha512-oMsXdMmNwHpUbebETO44bq0N4SocEMGfPjYNUTRs8md7ita5fuFd2qFuvf+ZRt6iVcGWluIqmF8DidD+b7d+TA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/querystring-builder" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/property-provider@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/property-provider/-/property-provider-3.357.0.tgz#4c1639c2d52aefab4040c2247c126c11b19d8be9" + integrity sha512-im4W0u8WaYxG7J7ko4Xl3OEzK3Mrm1Rz6/txTGe6hTIHlyUISu1ekOQJXK6XYPqNMn8v1G3BiQREoRXUEJFbHg== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/protocol-http@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/protocol-http/-/protocol-http-3.357.0.tgz#cd47413d6c1ed2d27bc30c7e9da3b262c8804cf4" + integrity sha512-w1JHiI50VEea7duDeAspUiKJmmdIQblvRyjVMOqWA6FIQAyDVuEiPX7/MdQr0ScxhtRQxHbP0I4MFyl7ctRQvA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/querystring-builder@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-builder/-/querystring-builder-3.357.0.tgz#0d4627620eba4d3cc523c2e1da88dfa561617599" + integrity sha512-aQcicqB6Y2cNaXPPwunz612a01SMiQQPsdz632F/3Lzn0ua82BJKobHOtaiTUlmVJ5Q4/EAeNfwZgL7tTUNtDQ== + dependencies: + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/querystring-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/querystring-parser/-/querystring-parser-3.357.0.tgz#6dfeb42930b2241cda43646d7c1d16ca886c78af" + integrity sha512-Svvq+atRNP9s2VxiklcUNgCzmt3T5kfs7X2C+yjmxHvOQTPjLNaNGbfC/vhjOK7aoXw0h+lBac48r5ymx1PbQA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/service-error-classification@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/service-error-classification/-/service-error-classification-3.357.0.tgz#1c6f6e436997a1886d55cfec6d4796129b789076" + integrity sha512-VuXeL4g5vKO9HjgCZlxmH8Uv1FcqUSjmbPpQkbNtYIDck6u0qzM0rG+n0/1EjyQbPSr3MhW/pkWs5nx2Nljlyg== + +"@aws-sdk/shared-ini-file-loader@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.357.0.tgz#af503df79e05bb9ee0e5d689319c9b52cefe1801" + integrity sha512-ceyqM4XxQe0Plb/oQAD2t1UOV2Iy4PFe1oAGM8dfJzYrRKu7zvMwru7/WaB3NYq+/mIY6RU+jjhRmjQ3GySVqA== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/signature-v4-multi-region@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.357.0.tgz#100c573029e2b30a65634090e55be4beb50e16a1" + integrity sha512-eyO3GibYLNCPZ/YxM/ZVDh1fTMKvIUj4fpVo0bxQTKNlqNkVumAIOVLoH5um1A9FN7nDdz+40a7jwYSPlkxW6A== + dependencies: + "@aws-sdk/protocol-http" "3.357.0" + "@aws-sdk/signature-v4" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/signature-v4@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4/-/signature-v4-3.357.0.tgz#31093e87fda10bee92b6b2784cdba9af9af89e7d" + integrity sha512-itt4/Jh9FqnzK30qIjXFBvM4J7zN4S/AAqsRMnaX7U4f/MV+1YxQHmzimpdMnsCXXs2jqFqKVRu6DewxJ3nbxg== + dependencies: + "@aws-sdk/eventstream-codec" "3.357.0" + "@aws-sdk/is-array-buffer" "3.310.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-middleware" "3.357.0" + "@aws-sdk/util-uri-escape" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/smithy-client@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/smithy-client/-/smithy-client-3.360.0.tgz#59d55eb41eccc22ca2d3d32c11b60135f882e66d" + integrity sha512-R7wbT2SkgWNEAxMekOTNcPcvBszabW2+qHjrcelbbVJNjx/2yK+MbpZI4WRSncByQMeeoW+aSUP+JgsbpiOWfw== + dependencies: + "@aws-sdk/middleware-stack" "3.357.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-stream" "3.360.0" + "@smithy/types" "^1.0.0" + tslib "^2.5.0" + +"@aws-sdk/token-providers@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.362.0.tgz#bd0ad974d7a96a06e6f1b574258e63e749e7cbb2" + integrity sha512-w7NTeB2j1CRdvDa7m08KQr12HN6qrOknXhGEMmf67bfdfAdmPWsJXIbxcKH8eze+acOzoimbqv8KyCVmyX/pCQ== + dependencies: + "@aws-sdk/client-sso-oidc" "3.362.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/shared-ini-file-loader" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/types@3.357.0", "@aws-sdk/types@^3.222.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.357.0.tgz#8491da71a4291cc2661c26a75089e86532b6a3b5" + integrity sha512-/riCRaXg3p71BeWnShrai0y0QTdXcouPSM0Cn1olZbzTf7s71aLEewrc96qFrL70XhY4XvnxMpqQh+r43XIL3g== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/url-parser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/url-parser/-/url-parser-3.357.0.tgz#1b197f252d008e201d1e301c8024bed770ef0b2c" + integrity sha512-fAaU6cFsaAba01lCRsRJiYR/LfXvX2wudyEyutBVglE4dWSoSeu3QJNxImIzTBULfbiFhz59++NQ1JUVx88IVg== + dependencies: + "@aws-sdk/querystring-parser" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/util-arn-parser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz#861ff8810851be52a320ec9e4786f15b5fc74fba" + integrity sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-base64@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-base64/-/util-base64-3.310.0.tgz#d0fd49aff358c5a6e771d0001c63b1f97acbe34c" + integrity sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/util-body-length-browser@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.310.0.tgz#3fca9d2f73c058edf1907e4a1d99a392fdd23eca" + integrity sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-body-length-node@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-body-length-node/-/util-body-length-node-3.310.0.tgz#4846ae72834ab0636f29f89fc1878520f6543fed" + integrity sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-buffer-from@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-buffer-from/-/util-buffer-from-3.310.0.tgz#7a72cb965984d3c6a7e256ae6cf1621f52e54a57" + integrity sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw== + dependencies: + "@aws-sdk/is-array-buffer" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/util-config-provider@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-config-provider/-/util-config-provider-3.310.0.tgz#ff21f73d4774cfd7bd16ae56f905828600dda95f" + integrity sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-defaults-mode-browser@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.360.0.tgz#fced018e4990220dc31881a5b2b3e425fe08e970" + integrity sha512-/GR8VlK9xo1Q5WbVYuNaZ+XfoCFdWNb4z4mpoEgvEgBH4R0GjqiAqLftUA8Ykq1tJuDAKPYVzUNzK8DC0pt7/g== + dependencies: + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + +"@aws-sdk/util-defaults-mode-node@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.360.0.tgz#83e2812474d8807d6d220c5064576e63e4ea8306" + integrity sha512-gR3Ctqpyl7SgStDJ1Jlq6qQDuw/rS9AgbAXx+s3wsmm3fm8lHKkXkDPYVvNDqd6dVXRO6q8MRx00lwkGI4qrpQ== + dependencies: + "@aws-sdk/config-resolver" "3.357.0" + "@aws-sdk/credential-provider-imds" "3.357.0" + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/property-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/util-endpoints@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.357.0.tgz#eaa7b4481bbd9fc8f13412b308ba4129d8fa2004" + integrity sha512-XHKyS5JClT9su9hDif715jpZiWHQF9gKZXER8tW0gOizU3R9cyWc9EsJ2BRhFNhi7nt/JF/CLUEc5qDx3ETbUw== + dependencies: + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/util-hex-encoding@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.310.0.tgz#19294c78986c90ae33f04491487863dc1d33bd87" + integrity sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-locate-window@^3.0.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz#b071baf050301adee89051032bd4139bba32cc40" + integrity sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-middleware@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-middleware/-/util-middleware-3.357.0.tgz#1ba478dde5df4e53b231ec6651b8d44c9187f66d" + integrity sha512-pV1krjZs7BdahZBfsCJMatE8kcor7GFsBOWrQgQDm9T0We5b5xPpOO2vxAD0RytBpY8Ky2ELs/+qXMv7l5fWIA== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-retry@3.362.0": + version "3.362.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-retry/-/util-retry-3.362.0.tgz#ab4a2bef4fef528cfa58e0840ba28fb5f1c3ca11" + integrity sha512-LDRGKaF2EMcFEa6AlS+ilLiDEeHWyR5FN2+RHdfGQjcqn+Zdd5H6Vc0vUF5Z4PH3hXr5LPZcDh+zM7DlG22KJg== + dependencies: + "@aws-sdk/service-error-classification" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/util-stream@3.360.0": + version "3.360.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-stream/-/util-stream-3.360.0.tgz#a6cf43cf594540e9d1a4e19b9acbc5c34b3a1225" + integrity sha512-t3naBfNesXwLis29pzSfLx2ifCn2180GiPjRaIsQP14IiVCBOeT1xaU6Dpyk7WeR/jW4cu7wGl+kbeyfNF6QmQ== + dependencies: + "@aws-sdk/fetch-http-handler" "3.357.0" + "@aws-sdk/node-http-handler" "3.360.0" + "@aws-sdk/types" "3.357.0" + "@aws-sdk/util-base64" "3.310.0" + "@aws-sdk/util-buffer-from" "3.310.0" + "@aws-sdk/util-hex-encoding" "3.310.0" + "@aws-sdk/util-utf8" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/util-uri-escape@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-uri-escape/-/util-uri-escape-3.310.0.tgz#9f942f09a715d8278875013a416295746b6085ba" + integrity sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q== + dependencies: + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-browser@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.357.0.tgz#21c3e6c1a3d610dd279952d3ce00909775019be5" + integrity sha512-JHaWlNIUkPNvXkqeDOrqFzAlAgdwZK5mZw7FQnCRvf8tdSogpGZSkuyb9Z6rLD9gC40Srbc2nepO1cFpeMsDkA== + dependencies: + "@aws-sdk/types" "3.357.0" + bowser "^2.11.0" + tslib "^2.5.0" + +"@aws-sdk/util-user-agent-node@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.357.0.tgz#a656cebce558b602e753e45a3b8174dc7c0f1fcf" + integrity sha512-RdpQoaJWQvcS99TVgSbT451iGrlH4qpWUWFA9U1IRhxOSsmC1hz8ME7xc8nci9SREx/ZlfT3ai6LpoAzAtIEMA== + dependencies: + "@aws-sdk/node-config-provider" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + +"@aws-sdk/util-utf8@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8/-/util-utf8-3.310.0.tgz#4a7b9dcebb88e830d3811aeb21e9a6df4273afb4" + integrity sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA== + dependencies: + "@aws-sdk/util-buffer-from" "3.310.0" + tslib "^2.5.0" + +"@aws-sdk/util-waiter@3.357.0": + version "3.357.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-waiter/-/util-waiter-3.357.0.tgz#31fdaf289ed60a633178b39e3b258f9b42a1cbe3" + integrity sha512-jQQGA5G8bm0JP5C4U85VzMpkFHdeeT7fOSUncXLG9Sh8Ambzi4XTud8m5/dA7aNJkvPwZeIF9QdgWCOzpkp1xA== + dependencies: + "@aws-sdk/abort-controller" "3.357.0" + "@aws-sdk/types" "3.357.0" + tslib "^2.5.0" + +"@aws-sdk/xml-builder@3.310.0": + version "3.310.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz#f0236f2103b438d16117e0939a6305ad69b7ff76" + integrity sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw== + dependencies: + tslib "^2.5.0" + +"@babel/code-frame@^7.10.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@^7.12.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.14.7", "@babel/parser@^7.18.6", "@babel/parser@^7.18.9", "@babel/parser@^7.9.4": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== + +"@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@cesium/engine@2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@cesium/engine/-/engine-2.4.1.tgz#b9b0395edebff581dbc55b7b9e1929f673dee058" + integrity sha512-8f0hBzhPUSimYLZ+cmQ0rSudm+8zYD3sBMvJcPSVt0wDpLT7tvBt9swC2v5qC2gOwGOeyFnJhXKes3ICE6SaDA== + dependencies: + "@tweenjs/tween.js" "^18.6.4" + "@zip.js/zip.js" "2.4.x" + autolinker "^4.0.0" + bitmap-sdf "^1.0.3" + dompurify "^3.0.2" + earcut "^2.2.4" + grapheme-splitter "^1.0.4" + jsep "^1.3.8" + kdbush "^4.0.1" + ktx-parse "^0.5.0" + lerc "^2.0.0" + mersenne-twister "^1.1.0" + meshoptimizer "^0.19.0" + pako "^2.0.4" + protobufjs "^7.1.0" + rbush "^3.0.1" + topojson-client "^3.1.0" + urijs "^1.19.7" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.43.0": + version "8.43.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" + integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.13": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@rollup/plugin-commonjs@^25.0.0": + version "25.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz#7ed37d00a12fc7fdd3aadba5fa0de52f2372bbbb" + integrity sha512-NGTwaJxIO0klMs+WSFFtBP7b9TdTJ3K76HZkewT8/+yHzMiUGVQgaPtLQxNVYIgT5F7lxkEyVID+yS3K7bhCow== + dependencies: + "@rollup/pluginutils" "^5.0.1" + commondir "^1.0.1" + estree-walker "^2.0.2" + glob "^8.0.3" + is-reference "1.2.1" + magic-string "^0.27.0" + +"@rollup/plugin-node-resolve@^15.1.0": + version "15.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz#9ffcd8e8c457080dba89bb9fcb583a6778dc757e" + integrity sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-builtin-module "^3.2.1" + is-module "^1.0.0" + resolve "^1.22.1" + +"@rollup/plugin-terser@^0.4.0", "@rollup/plugin-terser@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz#c2bde2fe3a85e45fa68a454d48f4e73e57f98b30" + integrity sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA== + dependencies: + serialize-javascript "^6.0.1" + smob "^1.0.0" + terser "^5.17.4" + +"@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@smithy/protocol-http@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-1.1.0.tgz#caf22e01cb825d7490a4915e03d6fa64954ff535" + integrity sha512-H5y/kZOqfJSqRkwtcAoVbqONmhdXwSgYNJ1Glk5Ry8qlhVVy5qUzD9EklaCH8/XLnoCsLO/F/Giee8MIvaBRkg== + dependencies: + "@smithy/types" "^1.1.0" + tslib "^2.5.0" + +"@smithy/types@^1.0.0", "@smithy/types@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-1.1.0.tgz#f30a23202c97634cca5c1ac955a9bf149c955226" + integrity sha512-KzmvisMmuwD2jZXuC9e65JrgsZM97y5NpDU7g347oB+Q+xQLU6hQZ5zFNNbEfwwOJHoOvEVTna+dk1h/lW7alw== + dependencies: + tslib "^2.5.0" + +"@tweenjs/tween.js@^18.6.4": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-18.6.4.tgz#40a3d0a93647124872dec8e0fd1bd5926695b6ca" + integrity sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ== + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/expect@^1.20.4": + version "1.20.4" + resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" + integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== + +"@types/linkify-it@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" + integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== + +"@types/markdown-it@^12.2.3": + version "12.2.3" + resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" + integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== + dependencies: + "@types/linkify-it" "*" + "@types/mdurl" "*" + +"@types/mdurl@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" + integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== + +"@types/node@*", "@types/node@>=10.0.0": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" + integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== + +"@types/node@>=13.7.0": + version "18.6.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39" + integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg== + +"@types/node@^14.14.41": + version "14.18.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.22.tgz#fd2a15dca290fc9ad565b672fde746191cd0c6e6" + integrity sha512-qzaYbXVzin6EPjghf/hTdIbnVW1ErMx8rPzwRNJhlbyJhu2SyqlvjGOY/tbUt6VFyzg56lROcOeSQRInpt63Yw== + +"@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + +"@types/vinyl@^2.0.4": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.6.tgz#b2d134603557a7c3d2b5d3dc23863ea2b5eb29b0" + integrity sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g== + dependencies: + "@types/expect" "^1.20.4" + "@types/node" "*" + +"@zip.js/zip.js@2.4.x": + version "2.4.26" + resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.4.26.tgz#b79bb2055dc6e185890ee01cdb710caba505d5b2" + integrity sha512-I9HBO3BHIxEMQmltmHM3iqUW6IHqi3gsL9wTSXvHTRpOrA6q2OxtR58EDSaOGjHhDVJ+wIOAxZyKq2x00AVmqw== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +acorn@^8.8.2: + version "8.9.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" + integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== + +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + +any-promise@^1.1.0, any-promise@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA== + dependencies: + buffer-equal "^1.0.0" + +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA== + dependencies: + file-type "^4.2.0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA== + dependencies: + make-iterator "^1.0.0" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw== + dependencies: + make-iterator "^1.0.0" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw== + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + +array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +async-done@^1.2.0, async-done@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" + integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^2.0.0" + stream-exhaust "^1.0.1" + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw== + dependencies: + async-done "^1.2.2" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autolinker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-4.0.0.tgz#aa1f9a52786b727b0ecee8cd7d4a97e0e3ef59f1" + integrity sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw== + dependencies: + tslib "^2.3.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg== + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +binaryextensions@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" + integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bitmap-sdf@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/bitmap-sdf/-/bitmap-sdf-1.0.4.tgz#e87b8b1d84ee846567cfbb29d60eedd34bca5b6f" + integrity sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg== + +bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.20.0, body-parser@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.20.2: + version "4.21.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ== + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +caniuse-lite@^1.0.30001366: + version "1.0.30001368" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001368.tgz#c5c06381c6051cd863c45021475434e81936f713" + integrity sha512-wgfRYa9DenEomLG/SdWgQxpIyvdtH3NW8Vq+tB6AwR9e56iOIcu1im5F/wNdDf04XlKHXqIx4N8Jo0PemeBenQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +catharsis@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== + dependencies: + lodash "^4.17.15" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.5.1, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +cloc@^2.8.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/cloc/-/cloc-2.10.0.tgz#1dbd3755a9ca8d426e9222b2e8a4feaecf855837" + integrity sha512-iHYXbhKNF+Wy6TNxHozD8WkW0qbZ7WKecyFntyFron4BF4SOX6hp7HEuNJ8iVnjimnf3xpLd81kMwoRj2WiCoA== + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q== + dependencies: + mimic-response "^1.0.0" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA== + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2, commander@^2.20.0, commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@~10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +component-emitter@^1.2.1, component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-disposition@0.5.4, content-disposition@^0.5.2: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +copy-props@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== + dependencies: + each-props "^1.3.2" + is-plain-object "^5.0.0" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + +date-format@^4.0.10, date-format@^4.0.11: + version "4.0.12" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.12.tgz#82c3607e33f8d25fa25b3415b565fe726a34574d" + integrity sha512-L018twW1B6J49/vmoxFSWTwKfUaKJI42cJ2xz1WeNSKaS4uVN5D44f3KfEuYUlZvFybWDJt6YuqVDPZp+IIF/g== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + +default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + +default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ== + +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + +define-properties@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +dompurify@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.3.tgz#4b115d15a091ddc96f232bcef668550a2f6f1430" + integrity sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ== + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +download@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" + integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== + dependencies: + archive-type "^4.0.0" + content-disposition "^0.5.2" + decompress "^4.2.1" + ext-name "^5.0.0" + file-type "^11.1.0" + filenamify "^3.0.0" + get-stream "^4.1.0" + got "^8.3.1" + make-dir "^2.1.0" + p-event "^2.1.0" + pify "^4.0.1" + +draco3d@^1.5.1: + version "1.5.3" + resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.3.tgz#75dfb3da7d1420571b1ab999191c49fdc2a74571" + integrity sha512-Ahum6SewAd1oVMm6Fk8T/zCE0qbzjohhO5pl1Xp5Outl4JKv7jYicfd5vNtkzImx94XE35fhNXVqHk9ajt+6Tg== + +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + +duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +each-props@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + +earcut@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a" + integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +edge-launcher@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/edge-launcher/-/edge-launcher-1.2.2.tgz#eb40aafbd067a6ea76efffab0647bcd5509b37b2" + integrity sha512-JcD5WBi3BHZXXVSSeEhl6sYO8g5cuynk/hifBzds2Bp4JdzCGLNMHgMCKu5DvrO1yatMgF0goFsxXRGus0yh1g== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.188: + version "1.4.197" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.197.tgz#172054244cca16320ebc19459bd03d8a9018ff73" + integrity sha512-7EZCIDDraA2NUaHewLaAh6T63cZzgBmgDx/iiaeZ/pjSs36bOFEJ3hLIrn1TKCFhV0PEZZKu6qFPrxa/LGAzLg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@~1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +engine.io-parser@~5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" + integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== + +engine.io@~6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0" + integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.3" + ws "~8.2.3" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + +entities@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.1, es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +esbuild@^0.17.10: + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== + optionalDependencies: + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-cesium@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-cesium/-/eslint-config-cesium-9.0.1.tgz#0104862809cb519d8f275fb4c657e876489e484b" + integrity sha512-9UR1YIdz44bzfXU0cZAH9oUEJ6pZj8CQPFMcMJsg1R9fH1SwSzK+mQSytt6VkvAfURGgb/nrZmncDZEeJ7YV2g== + +eslint-config-prettier@^8.3.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-es@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" + integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-html@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz#aec2a3772b40ccf51a5be4f972f07600539d3b3e" + integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== + dependencies: + htmlparser2 "^8.0.1" + +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.41.0: + version "8.43.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" + integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.43.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.17.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.11: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fast-xml-parser@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" + integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== + dependencies: + strnum "^1.0.5" + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-type@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" + integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ== + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + +filenamify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" + integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g== + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0, flatted@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== + +flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg== + dependencies: + for-in "^1.0.1" + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ== + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stdin@~9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" + integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw== + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob-watcher@^5.0.3: + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + normalize-path "^3.0.0" + object.defaults "^1.1.0" + +glob@^10.2.5: + version "10.3.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.1.tgz#9789cb1b994515bedb811a6deca735b5c37d2bf4" + integrity sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.10.0" + +glob@^7.1.1, glob@^7.1.3, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +glob@~10.2.2: + version "10.2.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" + integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2" + path-scurry "^1.7.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^13.1.3: + version "13.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.0.tgz#7dd5678d765c4680c2e6d106230d86cb727cb1af" + integrity sha512-jWsQfayf13NvqKUIL3Ta+CIqMnvlaIDFveWE/dpOZ9+3AMEJozsxDvKA02zync9UuvOM8rOXzsD5GqKP4OnWPQ== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +glsl-strip-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-strip-comments/-/glsl-strip-comments-1.0.0.tgz#bf8d121edb7482c965d24b8da6080310e55a51a5" + integrity sha512-hDzztQDaa/3YIUZVFlrfaCPnll6gdJntgUDj9ohKtPsoRVxQeNd580qW6PxVROPwD/6WAbqUiiLdRfB1NLDbFQ== + dependencies: + glsl-tokenizer "^2.1.2" + +glsl-tokenizer@^2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a" + integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA== + dependencies: + through2 "^0.6.3" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.6: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.1.10, graceful-fs@^4.2.10: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +gulp-clean-css@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz#5b1e73f2fca46703eb636014cdd4553cea65146d" + integrity sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg== + dependencies: + clean-css "4.2.3" + plugin-error "1.0.1" + through2 "3.0.1" + vinyl-sourcemaps-apply "0.2.1" + +gulp-cli@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.4.0" + isobject "^3.0.1" + liftoff "^3.1.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.2.0" + yargs "^7.1.0" + +gulp-insert@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/gulp-insert/-/gulp-insert-0.5.0.tgz#32313f13e4a23cf5acca5ce5f0c080923c778602" + integrity sha512-SDKCWmjomAo0N0Bzj9qEKIfURORJR/72p6AbDBIK9yKZw794ROTrQHliBem+NJzS2GsTWSm8dGWJ5L7KtjnMRA== + dependencies: + readable-stream "^1.0.26-4" + streamqueue "0.0.6" + +gulp-rename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-2.0.0.tgz#9bbc3962b0c0f52fc67cd5eaff6c223ec5b9cf6c" + integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ== + +gulp-replace@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-1.1.3.tgz#8641cdca78e683e8573ca4a012e7e4ebb7e4db60" + integrity sha512-HcPHpWY4XdF8zxYkDODHnG2+7a3nD/Y8Mfu3aBgMiCFDW3X2GiOKXllsAmILcxe3KZT2BXoN18WrpEFm48KfLQ== + dependencies: + "@types/node" "^14.14.41" + "@types/vinyl" "^2.0.4" + istextorbinary "^3.0.0" + replacestream "^4.0.3" + yargs-parser ">=5.0.0-security.0" + +gulp-tap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-tap/-/gulp-tap-2.0.0.tgz#6f66b79870dcbfc364cf4ebe0735b6008473200f" + integrity sha512-U5/v1bTozx672QHzrvzPe6fPl2io7Wqyrx2y30AG53eMU/idH4BrY/b2yikOkdyhjDqGgPoMUMnpBg9e9LK8Nw== + dependencies: + through2 "^3.0.1" + +gulp-zip@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-5.1.0.tgz#38cc1d4c61bc2ab06b452ce463cbe2adc52b935e" + integrity sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw== + dependencies: + get-stream "^5.2.0" + plugin-error "^1.0.1" + through2 "^3.0.1" + vinyl "^2.1.0" + yazl "^2.5.1" + +gulp@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" + integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== + dependencies: + glob-watcher "^5.0.3" + gulp-cli "^2.2.0" + undertaker "^1.2.1" + vinyl-fs "^3.0.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw== + dependencies: + glogg "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.1, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +husky@^8.0.2: + version "8.0.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" + integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.1.1, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +ignore@~5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +ini@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.0.tgz#2f6de95006923aa75feed8894f5686165adc08f1" + integrity sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw== + +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ== + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + +is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-reference@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA== + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isbinaryfile@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.1.0, istanbul-lib-instrument@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +istextorbinary@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-3.3.0.tgz#06b1c57d948da11461bd237c00ce09e9902964f2" + integrity sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ== + dependencies: + binaryextensions "^2.2.0" + textextensions "^3.2.0" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jasmine-core@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.2.0.tgz#0605bea284d6d78276f43c47de2532ecd4a73b00" + integrity sha512-OcFpBrIhnbmb9wfI8cqPSJ50pv3Wg4/NSgoZIqHzIwO/2a9qivJWzv8hUvaREIMYYJBas6AvfXATFdVuzzCqVw== + +jasmine-core@^4.1.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.6.0.tgz#6884fc3d5b66bf293e422751eed6d6da217c38f5" + integrity sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ== + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +js2xmlparser@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz#2a1fdf01e90585ef2ae872a01bc169c6a8d5e60a" + integrity sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA== + dependencies: + xmlcreate "^2.0.4" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsdoc@^3.6.7: + version "3.6.11" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.11.tgz#8bbb5747e6f579f141a5238cbad4e95e004458ce" + integrity sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg== + dependencies: + "@babel/parser" "^7.9.4" + "@types/markdown-it" "^12.2.3" + bluebird "^3.7.2" + catharsis "^0.9.0" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.2" + klaw "^3.0.0" + markdown-it "^12.3.2" + markdown-it-anchor "^8.4.1" + marked "^4.0.10" + mkdirp "^1.0.4" + requizzle "^0.2.3" + strip-json-comments "^3.1.0" + taffydb "2.6.2" + underscore "~1.13.2" + +jsep@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/jsep/-/jsep-1.3.8.tgz#facb6eb908d085d71d950bd2b24b757c7b8a46d7" + integrity sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +jsonc-parser@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +just-debounce@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" + integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== + +karma-chrome-launcher@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" + integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== + dependencies: + which "^1.2.1" + +karma-coverage@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.2.0.tgz#64f838b66b71327802e7f6f6c39d569b7024e40c" + integrity sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + +karma-detect-browsers@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/karma-detect-browsers/-/karma-detect-browsers-2.3.3.tgz#e0d8f9c1a1b0cc58d8668c245441eaf9d832c6ee" + integrity sha512-ltFVyA3ijThv9l9TQ+TKnccoMk6YAWn8OMaccL+n8pO2LGwMOcy6tUWy3Mnv9If29jqvVHDCWntj7wBQpPtv7Q== + dependencies: + which "^1.2.4" + +karma-edge-launcher@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz#3d9529b09b13c909c5f3ceee12d00e7f9a989b3d" + integrity sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw== + dependencies: + edge-launcher "1.2.2" + +karma-firefox-launcher@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz#9a38cc783c579a50f3ed2a82b7386186385cfc2d" + integrity sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA== + dependencies: + is-wsl "^2.2.0" + which "^2.0.1" + +karma-ie-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz#497986842c490190346cd89f5494ca9830c6d59c" + integrity sha512-ts71ke8pHvw6qdRtq0+7VY3ANLoZuUNNkA8abRaWV13QRPNm7TtSOqyszjHUtuwOWKcsSz4tbUtrNICrQC+SXQ== + dependencies: + lodash "^4.6.1" + +karma-jasmine@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-5.1.0.tgz#3af4558a6502fa16856a0f346ec2193d4b884b2f" + integrity sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ== + dependencies: + jasmine-core "^4.1.0" + +karma-longest-reporter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/karma-longest-reporter/-/karma-longest-reporter-1.1.0.tgz#37ba11e421334a0d0d5117e24dace8f2caec9919" + integrity sha512-c34tJbZUntkXMWK6S44NHLsYwF6Nu76+57ZGZvGLlbeltYanlKg/cgs1JqxwEdPz3m0Z2WSMhxBW6pcv0ycn1g== + +karma-safari-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz#96982a2cc47d066aae71c553babb28319115a2ce" + integrity sha512-qmypLWd6F2qrDJfAETvXDfxHvKDk+nyIjpH9xIeI3/hENr0U3nuqkxaftq73PfXZ4aOuOChA6SnLW4m4AxfRjQ== + +karma-sourcemap-loader@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" + integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== + dependencies: + graceful-fs "^4.2.10" + +karma-spec-reporter@^0.0.36: + version "0.0.36" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.36.tgz#c54dc155dec2ded1f92ea68dbbdd67fcedbef350" + integrity sha512-11bvOl1x6ryKZph7kmbmMpbi8vsngEGxGOoeTlIcDaH3ab3j8aPJnZ+r+K/SS0sBSGy5VGkGYO2+hLct7hw/6w== + dependencies: + colors "1.4.0" + +karma@^6.3.20: + version "6.4.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" + integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== + dependencies: + "@colors/colors" "1.5.0" + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.4.1" + mime "^2.5.2" + minimatch "^3.0.4" + mkdirp "^0.5.5" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.4.1" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kdbush@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39" + integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA== + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + +ktx-parse@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/ktx-parse/-/ktx-parse-0.5.0.tgz#b4025bbc73ac5386ac37e869de455eab915261bc" + integrity sha512-5IZrv5s1byUeDTIee1jjJQBiD5LPDB0w9pJJ0oT9BCKKJf16Tuj123vm1Ps0GOHSHmeWPgKM0zuViCVuTRpqaA== + +last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ== + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + +lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow== + dependencies: + flush-write-stream "^1.0.2" + +lerc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lerc/-/lerc-2.0.0.tgz#82feca29ea6202799a815ca38f7b66a370e8cf9b" + integrity sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +liftoff@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + +linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.6.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log4js@^6.4.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.6.0.tgz#e8fd00143d1e0ecf1d10959bb69b90b1b30137f3" + integrity sha512-3v8R7fd45UB6THucSht6wN2/7AZEruQbXdjygPZcxt5TA/msO6si9CN5MefUuKXbYnJHTBnYcx4famwcyQd+sA== + dependencies: + date-format "^4.0.11" + debug "^4.3.4" + flatted "^3.2.5" + rfdc "^1.3.0" + streamroller "^3.1.1" + +long@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A== + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + +magic-string@^0.25.3: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + +magic-string@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" + integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^8.4.1: + version "8.6.4" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz#affb8aa0910a504c114e9fcad53ac3a5b907b0e6" + integrity sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img== + +markdown-it@13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430" + integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +markdownlint-cli@^0.34.0: + version "0.34.0" + resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.34.0.tgz#d7a4ae8e59911de6dfb01782a7cd554e8a245947" + integrity sha512-4G9I++VBTZkaye6Yfc/7dU6HQHcyldZEVB+bYyQJLcpJOHKk/q5ZpGqK80oKMIdlxzsA3aWOJLZ4DkoaoUWXbQ== + dependencies: + commander "~10.0.1" + get-stdin "~9.0.0" + glob "~10.2.2" + ignore "~5.2.4" + js-yaml "^4.1.0" + jsonc-parser "~3.2.0" + markdownlint "~0.28.2" + minimatch "~9.0.0" + run-con "~1.2.11" + +markdownlint-micromark@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz#5520e04febffa46741875a2f297509ffdb561f5c" + integrity sha512-jRxlQg8KpOfM2IbCL9RXM8ZiYWz2rv6DlZAnGv8ASJQpUh6byTBnEsbuMZ6T2/uIgntyf7SKg/mEaEBo1164fQ== + +markdownlint@~0.28.2: + version "0.28.2" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.28.2.tgz#ea31586a02fe3a06403ecafbbe22d77e363c8ed5" + integrity sha512-yYaQXoKKPV1zgrFsyAuZPEQoe+JrY9GDag9ObKpk09twx4OCU5lut+0/kZPrQ3W7w82SmgKhd7D8m34aG1unVw== + dependencies: + markdown-it "13.0.1" + markdownlint-micromark "0.1.2" + +marked@^4.0.10: + version "4.0.18" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" + integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== + +matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA== + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +mersenne-twister@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" + integrity sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA== + +meshoptimizer@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/meshoptimizer/-/meshoptimizer-0.19.0.tgz#1669e6d788ad3ffd238a65184e478355642ca979" + integrity sha512-58qz5Qc/6Geu8Ib3bBWERE5R7pM5ErrJVo16fAtu6ryxVaE3VAtM/u2vurDxaq8AGZ3yWxuM/DnylTga5a4XCQ== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2", mime-db@^1.28.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.1, minimatch@~9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057" + integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +minimist@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" + integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + +nan@^2.12.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@^3.2.10: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +nosleep.js@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/nosleep.js/-/nosleep.js-0.12.0.tgz#a01fddab2c13af357d673928b1f40a9013a4dc08" + integrity sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA== + +now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4, object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA== + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw== + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw== + dependencies: + readable-stream "^2.0.1" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg== + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +pako@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q== + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== + dependencies: + path-root-regex "^0.1.0" + +path-scurry@^1.10.0, path-scurry@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.0.tgz#0ffbd4c1f7de9600f98a1405507d9f9acb438ab3" + integrity sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +plugin-error@1.0.1, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + +prettier@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" + integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + +prismjs@^1.28.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +protobufjs@^7.1.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2" + integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rbush@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf" + integrity sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w== + dependencies: + quickselect "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@2 || 3": + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^1.0.26-2, readable-stream@^1.0.26-4: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^2.3.0: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.5.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA== + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + +replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg== + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + +replacestream@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" + integrity sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA== + dependencies: + escape-string-regexp "^1.0.3" + object-assign "^4.0.1" + readable-stream "^2.0.2" + +request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +requizzle@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" + integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== + dependencies: + lodash "^4.17.14" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A== + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.22.1, resolve@^1.4.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rimraf@^5.0.0, rimraf@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" + integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== + dependencies: + glob "^10.2.5" + +rollup-plugin-strip-pragma@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-strip-pragma/-/rollup-plugin-strip-pragma-1.0.0.tgz#dd6d8c76788af460b16f7f1ca0e90a6e672236f7" + integrity sha512-ydv83CoA07wls7ZWwd4HtjjsoR9vM65SFR/B2tR8D2ppXyZajiQlx5cTJadAXMl9NADnXjUTMHW+kFzOkLoNdA== + dependencies: + magic-string "^0.25.3" + rollup-pluginutils "^2.8.2" + +rollup-plugin-terser@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup-pluginutils@^2.8.2: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + +rollup@^3.23.0: + version "3.25.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.25.3.tgz#f9a8986f0f244bcfde2208da91ba46b8fd252551" + integrity sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw== + optionalDependencies: + fsevents "~2.3.2" + +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + +run-con@~1.2.11: + version "1.2.12" + resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.12.tgz#51c319910e45a3bd71ee773564a89d96635c8c64" + integrity sha512-5257ILMYIF4RztL9uoZ7V9Q97zHtNHn5bN3NobeAnzB1P3ASLgg8qocM2u+R18ttp+VEM78N2LK8XcNVtnSRrg== + dependencies: + deep-extend "^0.6.0" + ini "~3.0.0" + minimist "^1.2.8" + strip-json-comments "~3.1.1" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + +semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ== + dependencies: + sver-compat "^1.5.0" + +"semver@2 || 3 || 4 || 5", semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +smob@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/smob/-/smob-1.4.0.tgz#ac9751fe54b1fc1fc8286a628d4e7f824273b95a" + integrity sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== + +socket.io-parser@~4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.5.tgz#cb404382c32324cc962f27f3a44058cf6e0552df" + integrity sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@^4.4.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029" + integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.2.0" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.0.4" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== + dependencies: + is-plain-obj "^1.0.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.1, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-to-array@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" + integrity sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA== + dependencies: + any-promise "^1.1.0" + +stream-to-promise@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-to-promise/-/stream-to-promise-3.0.0.tgz#8934d66dcbc9189394e8b33200da3bb9611db774" + integrity sha512-h+7wLeFiYegOdgTfTxjRsrT7/Op7grnKEIHWgaO1RTHwcwk7xRreMr3S8XpDfDMesSxzgM2V4CxNCFAGo6ssnA== + dependencies: + any-promise "~1.3.0" + end-of-stream "~1.4.1" + stream-to-array "~2.3.0" + +streamqueue@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/streamqueue/-/streamqueue-0.0.6.tgz#66f5f5ec94e9b8af249e4aec2dd1f741bfe94de3" + integrity sha512-l09LNfTUkmLMckTB1Mm8Um5GMS1uTZ/KTodg/SMf5Nx758IOsmaqIQ/AJumAnNMkDgZBG39btq3LVkN90knq8w== + dependencies: + readable-stream "^1.0.26-2" + +streamroller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.1.tgz#679aae10a4703acdf2740755307df0a05ad752e6" + integrity sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ== + dependencies: + date-format "^4.0.10" + debug "^4.3.4" + fs-extra "^10.1.0" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + name string-width-cjs + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +strnum@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg== + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA== + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +terser@^5.0.0, terser@^5.17.4: + version "5.18.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.2.tgz#ff3072a0faf21ffd38f99acc9a0ddf7b5f07b948" + integrity sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +textextensions@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-3.3.0.tgz#03530d5287b86773c08b77458589148870cc71d3" + integrity sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw== + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + +through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg== + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== + dependencies: + inherits "^2.0.4" + readable-stream "2 || 3" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA== + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q== + dependencies: + through2 "^2.0.3" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +topojson-client@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" + integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== + dependencies: + commander "2" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + +tsd-jsdoc@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tsd-jsdoc/-/tsd-jsdoc-2.5.0.tgz#0677aa952e1a8e3ebbb5bcf7d6e2f0301d71e151" + integrity sha512-80fcJLAiUeerg4xPftp+iEEKWUjJjHk9AvcHwJqA8Zw0R4oASdu3kT/plE/Zj19QUTz8KupyOX25zStlNJjS9g== + dependencies: + typescript "^3.2.1" + +tslib@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^2.3.1, tslib@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +typescript@^3.2.1: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + +typescript@^5.0.2: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg== + +underscore@~1.13.2: + version "1.13.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" + integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== + +undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw== + +undertaker@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urijs@^1.19.7: + version "1.19.11" + resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc" + integrity sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA== + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl-sourcemaps-apply@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw== + dependencies: + source-map "^0.5.1" + +vinyl@^2.0.0, vinyl@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== + +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + +which@^1.2.1, which@^1.2.14, which@^1.2.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +xmlcreate@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" + integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@>=5.0.0-security.0, yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + +yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.0.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yargs@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.1" + +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==